From 75df61e93d22c5225469142bf79592bce4ffb3de Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 3 Mar 2021 11:29:19 -0800 Subject: [PATCH] [test] Improve PGO tests --- .../profile/Linux/Inputs/instrprof-value-merge.c | 70 +++++++++++++++++ .../test/profile/Linux/instrprof-value-merge-lld.c | 11 +++ .../test/profile/Linux/instrprof-value-merge.c | 91 +++++----------------- .../Instrumentation/InstrProfiling/profiling.ll | 18 ++++- 4 files changed, 117 insertions(+), 73 deletions(-) create mode 100644 compiler-rt/test/profile/Linux/Inputs/instrprof-value-merge.c create mode 100644 compiler-rt/test/profile/Linux/instrprof-value-merge-lld.c diff --git a/compiler-rt/test/profile/Linux/Inputs/instrprof-value-merge.c b/compiler-rt/test/profile/Linux/Inputs/instrprof-value-merge.c new file mode 100644 index 0000000..6f5b479 --- /dev/null +++ b/compiler-rt/test/profile/Linux/Inputs/instrprof-value-merge.c @@ -0,0 +1,70 @@ +#include + +void (*f0)(); +void (*f1)(); +void (*f2)(); + +char dst[200]; +char src[200]; +volatile int n; + +__attribute__((noinline)) void foo() {} + +__attribute__((noinline)) void bar() { + f0 = foo; + f1 = foo; + f2 = foo; + n = 4; +} +int main(int argc, char *argv[]) { + int i; + bar(); + if (argc == 1) { + f0(); + for (i = 0; i < 9; i++) + f1(); + for (i = 0; i < 99; i++) + f2(); + } else { + memcpy((void *)dst, (void *)src, n); + for (i = 0; i < 6; i++) + memcpy((void *)(dst + 2), (void *)src, n + 1); + for (i = 0; i < 66; i++) + memcpy((void *)(dst + 9), (void *)src, n + 2); + } +} + +// CHECK: Counters: +// CHECK-NEXT: main: +// CHECK-NEXT: Hash: 0x0a9bd81e87ab6e87 +// CHECK-NEXT: Counters: 6 +// CHECK-NEXT: Indirect Call Site Count: 3 +// CHECK-NEXT: Number of Memory Intrinsics Calls: 3 +// CHECK-NEXT: Block counts: [27, 297, 12, 132, 3, 2] +// CHECK-NEXT: Indirect Target Results: +// CHECK-NEXT: [ 0, foo, 3 ] +// CHECK-NEXT: [ 1, foo, 27 ] +// CHECK-NEXT: [ 2, foo, 297 ] +// CHECK-NEXT: Memory Intrinsic Size Results: +// CHECK-NEXT: [ 0, 4, 2 ] +// CHECK-NEXT: [ 1, 5, 12 ] +// CHECK-NEXT: [ 2, 6, 132 ] +// CHECK-NEXT: Instrumentation level: IR entry_first = 0 +// CHECK-NEXT: Functions shown: 1 +// CHECK-NEXT: Total functions: 3 +// CHECK-NEXT: Maximum function count: 327 +// CHECK-NEXT: Maximum internal block count: 297 +// CHECK-NEXT: Statistics for indirect call sites profile: +// CHECK-NEXT: Total number of sites: 3 +// CHECK-NEXT: Total number of sites with values: 3 +// CHECK-NEXT: Total number of profiled values: 3 +// CHECK-NEXT: Value sites histogram: +// CHECK-NEXT: NumTargets, SiteCount +// CHECK-NEXT: 1, 3 +// CHECK-NEXT: Statistics for memory intrinsic calls sizes profile: +// CHECK-NEXT: Total number of sites: 3 +// CHECK-NEXT: Total number of sites with values: 3 +// CHECK-NEXT: Total number of profiled values: 3 +// CHECK-NEXT: Value sites histogram: +// CHECK-NEXT: NumTargets, SiteCount +// CHECK-NEXT: 1, 3 diff --git a/compiler-rt/test/profile/Linux/instrprof-value-merge-lld.c b/compiler-rt/test/profile/Linux/instrprof-value-merge-lld.c new file mode 100644 index 0000000..fda6b97 --- /dev/null +++ b/compiler-rt/test/profile/Linux/instrprof-value-merge-lld.c @@ -0,0 +1,11 @@ +// REQUIRES: lld-available +/// Test ld with GC. + +// RUN: %clang_pgogen -o %t -O3 %S/Inputs/instrprof-value-merge.c -fuse-ld=lld -ffunction-sections -fdata-sections -Wl,--gc-sections +// RUN: rm -rf %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 +// RUN: llvm-profdata show -counts -function=main -ic-targets -memop-sizes %t.profdir/default_*.profraw | FileCheck %S/Inputs/instrprof-value-merge.c diff --git a/compiler-rt/test/profile/Linux/instrprof-value-merge.c b/compiler-rt/test/profile/Linux/instrprof-value-merge.c index 2619a1d0..ccc4287 100644 --- a/compiler-rt/test/profile/Linux/instrprof-value-merge.c +++ b/compiler-rt/test/profile/Linux/instrprof-value-merge.c @@ -1,79 +1,28 @@ -// RUN: %clang_pgogen -o %t -O3 %s +// RUN: %clang_pgogen -o %t -O3 %S/Inputs/instrprof-value-merge.c // RUN: rm -rf %t.profdir // RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t // RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t // RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t // RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 // RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 -// RUN: llvm-profdata show -counts -function=main -ic-targets -memop-sizes %t.profdir/default_*.profraw | FileCheck %s +// RUN: llvm-profdata show -counts -function=main -ic-targets -memop-sizes %t.profdir/default_*.profraw | FileCheck %S/Inputs/instrprof-value-merge.c -#include - -void (*f0)(); -void (*f1)(); -void (*f2)(); - -char dst[200]; -char src[200]; -volatile int n; - -__attribute__((noinline)) void foo() {} - -__attribute__((noinline)) void bar() { - f0 = foo; - f1 = foo; - f2 = foo; - n = 4; -} -int main(int argc, char *argv[]) { - int i; - bar(); - if (argc == 1) { - f0(); - for (i = 0; i < 9; i++) - f1(); - for (i = 0; i < 99; i++) - f2(); - } else { - memcpy((void *)dst, (void *)src, n); - for (i = 0; i < 6; i++) - memcpy((void *)(dst + 2), (void *)src, n + 1); - for (i = 0; i < 66; i++) - memcpy((void *)(dst + 9), (void *)src, n + 2); - } -} +/// -z start-stop-gc requires binutils 2.37. Don't test the option for now. +/// TODO: Add -Wl,--gc-sections. +// RUN: %clang_pgogen -o %t -O3 %S/Inputs/instrprof-value-merge.c -fuse-ld=bfd -ffunction-sections -fdata-sections +// RUN: rm -rf %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 +// RUN: llvm-profdata show -counts -function=main -ic-targets -memop-sizes %t.profdir/default_*.profraw | FileCheck %S/Inputs/instrprof-value-merge.c -// CHECK: Counters: -// CHECK: main: -// CHECK: Hash: 0x0a9bd81e87ab6e87 -// CHECK: Counters: 6 -// CHECK: Indirect Call Site Count: 3 -// CHECK: Number of Memory Intrinsics Calls: 3 -// CHECK: Block counts: [27, 297, 12, 132, 3, 2] -// CHECK: Indirect Target Results: -// CHECK: [ 0, foo, 3 ] -// CHECK: [ 1, foo, 27 ] -// CHECK: [ 2, foo, 297 ] -// CHECK: Memory Intrinsic Size Results: -// CHECK: [ 0, 4, 2 ] -// CHECK: [ 1, 5, 12 ] -// CHECK: [ 2, 6, 132 ] -// CHECK: Instrumentation level: IR -// CHECK: Functions shown: 1 -// CHECK: Total functions: 3 -// CHECK: Maximum function count: 327 -// CHECK: Maximum internal block count: 297 -// CHECK: Statistics for indirect call sites profile: -// CHECK: Total number of sites: 3 -// CHECK: Total number of sites with values: 3 -// CHECK: Total number of profiled values: 3 -// CHECK: Value sites histogram: -// CHECK: NumTargets, SiteCount -// CHECK: 1, 3 -// CHECK: Statistics for memory intrinsic calls sizes profile: -// CHECK: Total number of sites: 3 -// CHECK: Total number of sites with values: 3 -// CHECK: Total number of profiled values: 3 -// CHECK: Value sites histogram: -// CHECK: NumTargets, SiteCount -// CHECK: 1, 3 +// RUN: %clang_pgogen -o %t -O3 %S/Inputs/instrprof-value-merge.c -fuse-ld=gold -ffunction-sections -fdata-sections +// RUN: rm -rf %t.profdir +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 +// RUN: env LLVM_PROFILE_FILE=%t.profdir/default_%m.profraw %run %t 1 +// RUN: llvm-profdata show -counts -function=main -ic-targets -memop-sizes %t.profdir/default_*.profraw | FileCheck %S/Inputs/instrprof-value-merge.c diff --git a/llvm/test/Instrumentation/InstrProfiling/profiling.ll b/llvm/test/Instrumentation/InstrProfiling/profiling.ll index 8c43c42..a1f1424 100644 --- a/llvm/test/Instrumentation/InstrProfiling/profiling.ll +++ b/llvm/test/Instrumentation/InstrProfiling/profiling.ll @@ -1,10 +1,14 @@ -; RUN: opt < %s -mtriple=x86_64 -passes=instrprof -S | FileCheck %s --check-prefixes=CHECK,ELF +; RUN: opt < %s -mtriple=x86_64 -passes=instrprof -S | FileCheck %s --check-prefixes=CHECK,ELF,ELF_GENERIC +; RUN: opt < %s -mtriple=x86_64-linux -passes=instrprof -S | FileCheck %s --check-prefixes=CHECK,ELF_LINUX ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -passes=instrprof -S | FileCheck %s --check-prefixes=CHECK,MACHO ; RUN: opt < %s -mtriple=x86_64-windows -passes=instrprof -S | FileCheck %s --check-prefixes=CHECK,WIN ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -instrprof -S | FileCheck %s -; CHECK: @__llvm_profile_runtime = external global i32 +; ELF_GENERIC: @__llvm_profile_runtime = external global i32 +; ELF_LINUX-NOT: @__llvm_profile_runtime +; MACHO: @__llvm_profile_runtime = external global i32 +; WIN: @__llvm_profile_runtime = external global i32 @__profn_foo = hidden constant [3 x i8] c"foo" ; CHECK-NOT: __profn_foo @@ -53,3 +57,13 @@ declare void @llvm.instrprof.increment(i8*, i64, i32, i32) ; ELF: @llvm.compiler.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz ; MACHO: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz ; WIN: @llvm.used = appending global {{.*}} @__llvm_profile_runtime_user {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz + +; ELF_GENERIC: define internal void @__llvm_profile_register_functions() unnamed_addr { +; ELF_GENERIC-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_foo to i8*)) +; ELF_GENERIC-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_bar to i8*)) +; ELF_GENERIC-NEXT: call void @__llvm_profile_register_function(i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [2 x i16] }* @__profd_baz to i8*)) +; ELF_GENERIC-NEXT: call void @__llvm_profile_register_names_function(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @__llvm_prf_nm, i32 0, i32 0), i64 19) +; ELF_GENERIC-NEXT: ret void +; ELF_GENERIC-NEXT: } + +; ELF_LINUX-NOT: @__llvm_profile_register_functions() -- 2.7.4