From 52a6a97d70c2c39ee498ee4802b5130446e5595e Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Tue, 11 Mar 2014 04:37:49 +0000 Subject: test: Give instrumentation based profiling tests their own directory These tests are logically related, but they're spread about several different CodeGen directories. Consolidate them in one place to make them easier to manage. llvm-svn: 203541 --- clang/test/CodeGen/Inputs/instr-attribute.profdata | 39 -- clang/test/CodeGen/Inputs/instr-profile.profdata | 138 ------ clang/test/CodeGen/instr-attribute.c | 47 -- clang/test/CodeGen/instr-profile.c | 542 --------------------- .../CodeGenCXX/Inputs/instr-profile-class.profdata | 20 - .../Inputs/instr-profile-throws.profdata | 14 - clang/test/CodeGenCXX/instr-profile-class.cpp | 82 ---- clang/test/CodeGenCXX/instr-profile-throws.cpp | 76 --- .../test/CodeGenObjC/Inputs/instr-profile.profdata | 11 - clang/test/CodeGenObjC/instr-profile.m | 74 --- clang/test/Profile/Inputs/c-attributes.profdata | 39 ++ clang/test/Profile/Inputs/c-general.profdata | 138 ++++++ clang/test/Profile/Inputs/cxx-class.profdata | 20 + clang/test/Profile/Inputs/cxx-throws.profdata | 14 + clang/test/Profile/Inputs/objc-general.profdata | 10 + clang/test/Profile/README | 8 + clang/test/Profile/c-attributes.c | 47 ++ clang/test/Profile/c-general.c | 537 ++++++++++++++++++++ clang/test/Profile/cxx-class.cpp | 77 +++ clang/test/Profile/cxx-throws.cpp | 72 +++ clang/test/Profile/objc-general.m | 70 +++ 21 files changed, 1032 insertions(+), 1043 deletions(-) delete mode 100644 clang/test/CodeGen/Inputs/instr-attribute.profdata delete mode 100644 clang/test/CodeGen/Inputs/instr-profile.profdata delete mode 100644 clang/test/CodeGen/instr-attribute.c delete mode 100644 clang/test/CodeGen/instr-profile.c delete mode 100644 clang/test/CodeGenCXX/Inputs/instr-profile-class.profdata delete mode 100644 clang/test/CodeGenCXX/Inputs/instr-profile-throws.profdata delete mode 100644 clang/test/CodeGenCXX/instr-profile-class.cpp delete mode 100644 clang/test/CodeGenCXX/instr-profile-throws.cpp delete mode 100644 clang/test/CodeGenObjC/Inputs/instr-profile.profdata delete mode 100644 clang/test/CodeGenObjC/instr-profile.m create mode 100644 clang/test/Profile/Inputs/c-attributes.profdata create mode 100644 clang/test/Profile/Inputs/c-general.profdata create mode 100644 clang/test/Profile/Inputs/cxx-class.profdata create mode 100644 clang/test/Profile/Inputs/cxx-throws.profdata create mode 100644 clang/test/Profile/Inputs/objc-general.profdata create mode 100644 clang/test/Profile/README create mode 100644 clang/test/Profile/c-attributes.c create mode 100644 clang/test/Profile/c-general.c create mode 100644 clang/test/Profile/cxx-class.cpp create mode 100644 clang/test/Profile/cxx-throws.cpp create mode 100644 clang/test/Profile/objc-general.m diff --git a/clang/test/CodeGen/Inputs/instr-attribute.profdata b/clang/test/CodeGen/Inputs/instr-attribute.profdata deleted file mode 100644 index 0419b3b3bef..00000000000 --- a/clang/test/CodeGen/Inputs/instr-attribute.profdata +++ /dev/null @@ -1,39 +0,0 @@ -hot_100_percent 4 -100000 -4999950000 -0 -0 - -hot_40_percent 4 -40000 -799980000 -0 -0 - -normal_func 4 -20000 -199990000 -0 -0 - -cold_func 4 -500 -124750 -0 -0 - -main 13 -1 -100000 -0 -0 -40000 -0 -0 -20000 -0 -0 -500 -0 -0 - diff --git a/clang/test/CodeGen/Inputs/instr-profile.profdata b/clang/test/CodeGen/Inputs/instr-profile.profdata deleted file mode 100644 index f6337d23329..00000000000 --- a/clang/test/CodeGen/Inputs/instr-profile.profdata +++ /dev/null @@ -1,138 +0,0 @@ -simple_loops 4 -1 -100 -100 -75 - -conditionals 11 -1 -100 -50 -50 -33 -33 -16 -99 -100 -99 -100 - -early_exits 9 -1 -0 -51 -1 -25 -1 -25 -1 -0 - -jumps 22 -1 -1 -0 -1 -0 -0 -1 -0 -1 -2 -3 -2 -0 -3 -0 -1 -1 -1 -10 -0 -10 -9 - -switches 19 -1 -1 -1 -15 -7 -1 -0 -2 -2 -3 -3 -4 -4 -0 -4 -4 -5 -1 -0 - -big_switch 17 -1 -32 -32 -1 -0 -1 -1 -11 -11 -1 -1 -15 -15 -1 -1 -2 -2 - -issue_with_one_counter 1 -0 - -boolean_operators 8 -1 -100 -34 -66 -17 -34 -33 -50 - -boolop_loops 9 -1 -50 -51 -50 -26 -50 -51 -50 -26 - -do_fallthrough 4 -1 -10 -2 -8 - -no_usable_data 5 -1 -1 -1 -1 -1 - -main 1 -1 - -instr-profile.c:static_func 2 -1 -10 - diff --git a/clang/test/CodeGen/instr-attribute.c b/clang/test/CodeGen/instr-attribute.c deleted file mode 100644 index b2399807543..00000000000 --- a/clang/test/CodeGen/instr-attribute.c +++ /dev/null @@ -1,47 +0,0 @@ -// Test that instrumentation based profiling sets function attributes correctly. - -// RUN: %clang %s -o - -mllvm -disable-llvm-optzns -emit-llvm -S -fprofile-instr-use=%S/Inputs/instr-attribute.profdata | FileCheck %s - -extern int atoi(const char *); - -// CHECK: hot_100_percent(i32{{.*}}%i) [[HOT:#[0-9]+]] -void hot_100_percent(int i) { - while (i > 0) - i--; -} - -// CHECK: hot_40_percent(i32{{.*}}%i) [[HOT]] -void hot_40_percent(int i) { - while (i > 0) - i--; -} - -// CHECK: normal_func(i32{{.*}}%i) [[NORMAL:#[0-9]+]] -void normal_func(int i) { - while (i > 0) - i--; -} - -// CHECK: cold_func(i32{{.*}}%i) [[COLD:#[0-9]+]] -void cold_func(int i) { - while (i > 0) - i--; -} - -// CHECK: attributes [[HOT]] = { inlinehint nounwind {{.*}} } -// CHECK: attributes [[NORMAL]] = { nounwind {{.*}} } -// CHECK: attributes [[COLD]] = { cold nounwind {{.*}} } - -int main(int argc, const char *argv[]) { - int max = atoi(argv[1]); - int i; - for (i = 0; i < max; i++) - hot_100_percent(i); - for (i = 0; i < max * 4 / 10; i++) - hot_40_percent(i); - for (i = 0; i < max * 2 / 10; i++) - normal_func(i); - for (i = 0; i < max / 200; i++) - cold_func(i); - return 0; -} diff --git a/clang/test/CodeGen/instr-profile.c b/clang/test/CodeGen/instr-profile.c deleted file mode 100644 index 05656ab508e..00000000000 --- a/clang/test/CodeGen/instr-profile.c +++ /dev/null @@ -1,542 +0,0 @@ -// Test that instrumentation based profiling feeds branch prediction -// correctly. This tests both generation of profile data and use of the same, -// and the input file for the -fprofile-instr-use case is expected to be result -// of running the program generated by the -fprofile-instr-generate case -// (excepting no_usable_data). As such, main() should call every function in -// this test. - -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name instr-profile.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name instr-profile.c %s -o - -emit-llvm -fprofile-instr-use=%S/Inputs/instr-profile.profdata | FileCheck -check-prefix=PGOUSE %s - -// PGOGEN: @[[SLC:__llvm_pgo_ctr[0-9]*]] = private global [4 x i64] zeroinitializer -// PGOGEN: @[[IFC:__llvm_pgo_ctr[0-9]*]] = private global [11 x i64] zeroinitializer -// PGOGEN: @[[EEC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer -// PGOGEN: @[[JMC:__llvm_pgo_ctr[0-9]*]] = private global [22 x i64] zeroinitializer -// PGOGEN: @[[SWC:__llvm_pgo_ctr[0-9]*]] = private global [19 x i64] zeroinitializer -// PGOGEN: @[[BSC:__llvm_pgo_ctr[0-9]*]] = private global [17 x i64] zeroinitializer -// PGOGEN: @[[BOC:__llvm_pgo_ctr[0-9]*]] = private global [8 x i64] zeroinitializer -// PGOGEN: @[[BLC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer -// PGOGEN: @[[NOC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer -// PGOGEN: @[[MAC:__llvm_pgo_ctr[0-9]*]] = private global [1 x i64] zeroinitializer -// PGOGEN: @[[STC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer - -// PGOGEN-LABEL: @simple_loops() -// PGOUSE-LABEL: @simple_loops() -// PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 0 -void simple_loops() { - int i; - // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[SL1:[0-9]+]] - for (i = 0; i < 100; ++i) { - } - // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 2 - // PGOUSE: br {{.*}} !prof ![[SL2:[0-9]+]] - while (i > 0) - i--; - // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 3 - // PGOUSE: br {{.*}} !prof ![[SL3:[0-9]+]] - do {} while (i++ < 75); - - // PGOGEN-NOT: store {{.*}} @[[SLC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -// PGOGEN-LABEL: @conditionals() -// PGOUSE-LABEL: @conditionals() -// PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 0 -void conditionals() { - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[IF1:[0-9]+]] - for (int i = 0; i < 100; ++i) { - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 2 - // PGOUSE: br {{.*}} !prof ![[IF2:[0-9]+]] - if (i % 2) { - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 3 - // PGOUSE: br {{.*}} !prof ![[IF3:[0-9]+]] - if (i) {} - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 4 - // PGOUSE: br {{.*}} !prof ![[IF4:[0-9]+]] - } else if (i % 3) { - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 5 - // PGOUSE: br {{.*}} !prof ![[IF5:[0-9]+]] - if (i) {} - } else { - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 6 - // PGOUSE: br {{.*}} !prof ![[IF6:[0-9]+]] - if (i) {} - } - - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 8 - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 7 - // PGOUSE: br {{.*}} !prof ![[IF7:[0-9]+]] - if (1 && i) {} - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 10 - // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 9 - // PGOUSE: br {{.*}} !prof ![[IF8:[0-9]+]] - if (0 || i) {} - } - - // PGOGEN-NOT: store {{.*}} @[[IFC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -// PGOGEN-LABEL: @early_exits() -// PGOUSE-LABEL: @early_exits() -// PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 0 -void early_exits() { - int i = 0; - - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[EE1:[0-9]+]] - if (i) {} - - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 2 - // PGOUSE: br {{.*}} !prof ![[EE2:[0-9]+]] - while (i < 100) { - i++; - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 3 - // PGOUSE: br {{.*}} !prof ![[EE3:[0-9]+]] - if (i > 50) - break; - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 4 - // PGOUSE: br {{.*}} !prof ![[EE4:[0-9]+]] - if (i % 2) - continue; - } - - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 5 - // PGOUSE: br {{.*}} !prof ![[EE5:[0-9]+]] - if (i) {} - - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 6 - do { - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 7 - // PGOUSE: br {{.*}} !prof ![[EE6:[0-9]+]] - if (i > 75) - return; - else - i++; - // PGOUSE: br {{.*}} !prof ![[EE7:[0-9]+]] - } while (i < 100); - - // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 8 - // Never reached -> no weights - if (i) {} - - // PGOGEN-NOT: store {{.*}} @[[EEC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -// PGOGEN-LABEL: @jumps() -// PGOUSE-LABEL: @jumps() -// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 0 -void jumps() { - int i; - - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[JM1:[0-9]+]] - for (i = 0; i < 2; ++i) { - goto outofloop; - // Never reached -> no weights - if (i) {} - } -// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 3 -outofloop: - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 4 - // PGOUSE: br {{.*}} !prof ![[JM2:[0-9]+]] - if (i) {} - - goto loop1; - - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 5 - // PGOUSE: br {{.*}} !prof ![[JM3:[0-9]+]] - while (i) { - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 6 - loop1: - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 7 - // PGOUSE: br {{.*}} !prof ![[JM4:[0-9]+]] - if (i) {} - } - - goto loop2; -// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 8 -first: -// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 9 -second: -// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 10 -third: - i++; - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 11 - // PGOUSE: br {{.*}} !prof ![[JM5:[0-9]+]] - if (i < 3) - goto loop2; - - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 12 - // PGOUSE: br {{.*}} !prof ![[JM6:[0-9]+]] - while (i < 3) { - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 13 - loop2: - // PGOUSE: switch {{.*}} [ - // PGOUSE: ], !prof ![[JM7:[0-9]+]] - switch (i) { - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 15 - case 0: - goto first; - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 16 - case 1: - goto second; - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 17 - case 2: - goto third; - } - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 14 - } - - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 18 - // PGOUSE: br {{.*}} !prof ![[JM8:[0-9]+]] - for (i = 0; i < 10; ++i) { - goto withinloop; - // never reached -> no weights - if (i) {} - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 20 - withinloop: - // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 21 - // PGOUSE: br {{.*}} !prof ![[JM9:[0-9]+]] - if (i) {} - } - - // PGOGEN-NOT: store {{.*}} @[[JMC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -// PGOGEN-LABEL: @switches() -// PGOUSE-LABEL: @switches() -// PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 0 -void switches() { - static int weights[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5}; - - // No cases -> no weights - switch (weights[0]) { - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 2 - default: - break; - } - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 1 - - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 3 - // PGOUSE: br {{.*}} !prof ![[SW1:[0-9]+]] - for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) { - // PGOUSE: switch {{.*}} [ - // PGOUSE: ], !prof ![[SW2:[0-9]+]] - switch (i[weights]) { - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 5 - case 1: - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 6 - // PGOUSE: br {{.*}} !prof ![[SW3:[0-9]+]] - if (i) {} - // fallthrough - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 7 - case 2: - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 8 - // PGOUSE: br {{.*}} !prof ![[SW4:[0-9]+]] - if (i) {} - break; - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 9 - case 3: - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 10 - // PGOUSE: br {{.*}} !prof ![[SW5:[0-9]+]] - if (i) {} - continue; - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 11 - case 4: - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 12 - // PGOUSE: br {{.*}} !prof ![[SW6:[0-9]+]] - if (i) {} - // PGOUSE: switch {{.*}} [ - // PGOUSE: ], !prof ![[SW7:[0-9]+]] - switch (i) { - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 14 - case 6 ... 9: - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 15 - // PGOUSE: br {{.*}} !prof ![[SW8:[0-9]+]] - if (i) {} - continue; - } - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 13 - - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 16 - default: - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 17 - // PGOUSE: br {{.*}} !prof ![[SW9:[0-9]+]] - if (i == len - 1) - return; - } - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 4 - } - - // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 18 - // Never reached -> no weights - if (weights[0]) {} - - // PGOGEN-NOT: store {{.*}} @[[SWC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -// PGOGEN-LABEL: @big_switch() -// PGOUSE-LABEL: @big_switch() -// PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 0 -void big_switch() { - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[BS1:[0-9]+]] - for (int i = 0; i < 32; ++i) { - // PGOUSE: switch {{.*}} [ - // PGOUSE: ], !prof ![[BS2:[0-9]+]] - switch (1 << i) { - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 3 - case (1 << 0): - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 4 - // PGOUSE: br {{.*}} !prof ![[BS3:[0-9]+]] - if (i) {} - // fallthrough - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 5 - case (1 << 1): - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 6 - // PGOUSE: br {{.*}} !prof ![[BS4:[0-9]+]] - if (i) {} - break; - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 7 - case (1 << 2) ... (1 << 12): - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 8 - // PGOUSE: br {{.*}} !prof ![[BS5:[0-9]+]] - if (i) {} - break; - // The branch for the large case range above appears after the case body - // PGOUSE: br {{.*}} !prof ![[BS6:[0-9]+]] - - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 9 - case (1 << 13): - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 10 - // PGOUSE: br {{.*}} !prof ![[BS7:[0-9]+]] - if (i) {} - break; - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 11 - case (1 << 14) ... (1 << 28): - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 12 - // PGOUSE: br {{.*}} !prof ![[BS8:[0-9]+]] - if (i) {} - break; - // The branch for the large case range above appears after the case body - // PGOUSE: br {{.*}} !prof ![[BS9:[0-9]+]] - - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 13 - case (1 << 29) ... ((1 << 29) + 1): - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 14 - // PGOUSE: br {{.*}} !prof ![[BS10:[0-9]+]] - if (i) {} - break; - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 15 - default: - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 16 - // PGOUSE: br {{.*}} !prof ![[BS11:[0-9]+]] - if (i) {} - break; - } - // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 2 - } - - // PGOGEN-NOT: store {{.*}} @[[BSC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ - // PGOUSE: ret void -} - -// PGOGEN-LABEL: @boolean_operators() -// PGOUSE-LABEL: @boolean_operators() -// PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 0 -void boolean_operators() { - int v; - // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[BO1:[0-9]+]] - for (int i = 0; i < 100; ++i) { - // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 2 - // PGOUSE: br {{.*}} !prof ![[BO2:[0-9]+]] - v = i % 3 || i; - - // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 3 - // PGOUSE: br {{.*}} !prof ![[BO3:[0-9]+]] - v = i % 3 && i; - - // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 5 - // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 4 - // PGOUSE: br {{.*}} !prof ![[BO4:[0-9]+]] - // PGOUSE: br {{.*}} !prof ![[BO5:[0-9]+]] - v = i % 3 || i % 2 || i; - - // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 7 - // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 6 - // PGOUSE: br {{.*}} !prof ![[BO6:[0-9]+]] - // PGOUSE: br {{.*}} !prof ![[BO7:[0-9]+]] - v = i % 2 && i % 3 && i; - } - - // PGOGEN-NOT: store {{.*}} @[[BOC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -// PGOGEN-LABEL: @boolop_loops() -// PGOUSE-LABEL: @boolop_loops() -// PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 0 -void boolop_loops() { - int i = 100; - - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 2 - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[BL1:[0-9]+]] - // PGOUSE: br {{.*}} !prof ![[BL2:[0-9]+]] - while (i && i > 50) - i--; - - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 4 - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 3 - // PGOUSE: br {{.*}} !prof ![[BL3:[0-9]+]] - // PGOUSE: br {{.*}} !prof ![[BL4:[0-9]+]] - while ((i % 2) || (i > 0)) - i--; - - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 6 - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 5 - // PGOUSE: br {{.*}} !prof ![[BL5:[0-9]+]] - // PGOUSE: br {{.*}} !prof ![[BL6:[0-9]+]] - for (i = 100; i && i > 50; --i); - - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 8 - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 7 - // PGOUSE: br {{.*}} !prof ![[BL7:[0-9]+]] - // PGOUSE: br {{.*}} !prof ![[BL8:[0-9]+]] - for (; (i % 2) || (i > 0); --i); - - // PGOGEN-NOT: store {{.*}} @[[BLC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -void do_fallthrough() { - for (int i = 0; i < 10; ++i) { - int j = 0; - do { - // The number of exits out of this do-loop via the break statement - // exceeds the counter value for the loop (which does not include the - // fallthrough count). Make sure that does not violate any assertions. - if (i < 8) break; - j++; - } while (j < 2); - } -} - -// PGOGEN-LABEL: @no_usable_data() -// PGOUSE-LABEL: @no_usable_data() -// PGOGEN: store {{.*}} @[[NOC]], i64 0, i64 0 -void no_usable_data() { - // The input data for PGOUSE is deliberately invalid for this function, so - // that we can test that we reject and ignore it properly. - int i = 0; - - // PGOGEN: store {{.*}} @[[NOC]], i64 0, i64 1 - if (i) {} - - // PGOGEN-NOT: store {{.*}} @[[NOC]], - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ -} - -// PGOGEN-LABEL: @static_func() -// PGOUSE-LABEL: @static_func() -// PGOGEN: store {{.*}} @[[STC]], i64 0, i64 0 -static void static_func() { - // PGOGEN: store {{.*}} @[[STC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[ST1:[0-9]+]] - for (int i = 0; i < 10; ++i) { - } -} - -// PGOUSE-DAG: ![[SL1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} -// PGOUSE-DAG: ![[SL2]] = metadata !{metadata !"branch_weights", i32 101, i32 2} -// PGOUSE-DAG: ![[SL3]] = metadata !{metadata !"branch_weights", i32 76, i32 2} - -// PGOUSE-DAG: ![[EE1]] = metadata !{metadata !"branch_weights", i32 1, i32 2} -// PGOUSE-DAG: ![[EE2]] = metadata !{metadata !"branch_weights", i32 52, i32 1} -// PGOUSE-DAG: ![[EE3]] = metadata !{metadata !"branch_weights", i32 2, i32 51} -// PGOUSE-DAG: ![[EE4]] = metadata !{metadata !"branch_weights", i32 26, i32 26} -// PGOUSE-DAG: ![[EE5]] = metadata !{metadata !"branch_weights", i32 2, i32 1} -// PGOUSE-DAG: ![[EE6]] = metadata !{metadata !"branch_weights", i32 2, i32 26} -// PGOUSE-DAG: ![[EE7]] = metadata !{metadata !"branch_weights", i32 26, i32 1} - -// PGOUSE-DAG: ![[IF1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} -// PGOUSE-DAG: ![[IF2]] = metadata !{metadata !"branch_weights", i32 51, i32 51} -// PGOUSE-DAG: ![[IF3]] = metadata !{metadata !"branch_weights", i32 51, i32 1} -// PGOUSE-DAG: ![[IF4]] = metadata !{metadata !"branch_weights", i32 34, i32 18} -// PGOUSE-DAG: ![[IF5]] = metadata !{metadata !"branch_weights", i32 34, i32 1} -// PGOUSE-DAG: ![[IF6]] = metadata !{metadata !"branch_weights", i32 17, i32 2} -// PGOUSE-DAG: ![[IF7]] = metadata !{metadata !"branch_weights", i32 100, i32 2} -// PGOUSE-DAG: ![[IF8]] = metadata !{metadata !"branch_weights", i32 100, i32 2} - -// PGOUSE-DAG: ![[JM1]] = metadata !{metadata !"branch_weights", i32 2, i32 1} -// PGOUSE-DAG: ![[JM2]] = metadata !{metadata !"branch_weights", i32 1, i32 2} -// PGOUSE-DAG: ![[JM3]] = metadata !{metadata !"branch_weights", i32 1, i32 2} -// PGOUSE-DAG: ![[JM4]] = metadata !{metadata !"branch_weights", i32 1, i32 2} -// PGOUSE-DAG: ![[JM5]] = metadata !{metadata !"branch_weights", i32 3, i32 2} -// PGOUSE-DAG: ![[JM6]] = metadata !{metadata !"branch_weights", i32 1, i32 2} -// PGOUSE-DAG: ![[JM7]] = metadata !{metadata !"branch_weights", i32 1, i32 2, i32 2, i32 2} -// PGOUSE-DAG: ![[JM8]] = metadata !{metadata !"branch_weights", i32 11, i32 2} -// PGOUSE-DAG: ![[JM9]] = metadata !{metadata !"branch_weights", i32 10, i32 2} - -// PGOUSE-DAG: ![[SW1]] = metadata !{metadata !"branch_weights", i32 16, i32 1} -// PGOUSE-DAG: ![[SW2]] = metadata !{metadata !"branch_weights", i32 6, i32 2, i32 3, i32 4, i32 5} -// PGOUSE-DAG: ![[SW3]] = metadata !{metadata !"branch_weights", i32 1, i32 2} -// PGOUSE-DAG: ![[SW4]] = metadata !{metadata !"branch_weights", i32 3, i32 2} -// PGOUSE-DAG: ![[SW5]] = metadata !{metadata !"branch_weights", i32 4, i32 1} -// PGOUSE-DAG: ![[SW6]] = metadata !{metadata !"branch_weights", i32 5, i32 1} -// PGOUSE-DAG: ![[SW7]] = metadata !{metadata !"branch_weights", i32 1, i32 2, i32 2, i32 2, i32 2} -// PGOUSE-DAG: ![[SW8]] = metadata !{metadata !"branch_weights", i32 5, i32 1} -// PGOUSE-DAG: ![[SW9]] = metadata !{metadata !"branch_weights", i32 2, i32 5} - -// PGOUSE-DAG: ![[BS1]] = metadata !{metadata !"branch_weights", i32 33, i32 2} -// PGOUSE-DAG: ![[BS2]] = metadata !{metadata !"branch_weights", i32 29, i32 2, i32 2, i32 2, i32 2, i32 1} -// PGOUSE-DAG: ![[BS3]] = metadata !{metadata !"branch_weights", i32 1, i32 2} -// PGOUSE-DAG: ![[BS4]] = metadata !{metadata !"branch_weights", i32 2, i32 2} -// PGOUSE-DAG: ![[BS5]] = metadata !{metadata !"branch_weights", i32 12, i32 1} -// PGOUSE-DAG: ![[BS6]] = metadata !{metadata !"branch_weights", i32 12, i32 3} -// PGOUSE-DAG: ![[BS7]] = metadata !{metadata !"branch_weights", i32 2, i32 1} -// PGOUSE-DAG: ![[BS8]] = metadata !{metadata !"branch_weights", i32 16, i32 1} -// PGOUSE-DAG: ![[BS9]] = metadata !{metadata !"branch_weights", i32 16, i32 14} -// PGOUSE-DAG: ![[BS10]] = metadata !{metadata !"branch_weights", i32 2, i32 1} -// PGOUSE-DAG: ![[BS11]] = metadata !{metadata !"branch_weights", i32 3, i32 1} - -// PGOUSE-DAG: ![[BO1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} -// PGOUSE-DAG: ![[BO2]] = metadata !{metadata !"branch_weights", i32 67, i32 35} -// PGOUSE-DAG: ![[BO3]] = metadata !{metadata !"branch_weights", i32 67, i32 35} -// PGOUSE-DAG: ![[BO4]] = metadata !{metadata !"branch_weights", i32 67, i32 35} -// PGOUSE-DAG: ![[BO5]] = metadata !{metadata !"branch_weights", i32 18, i32 18} -// PGOUSE-DAG: ![[BO6]] = metadata !{metadata !"branch_weights", i32 51, i32 51} -// PGOUSE-DAG: ![[BO7]] = metadata !{metadata !"branch_weights", i32 34, i32 18} -// PGOUSE-DAG: ![[BL1]] = metadata !{metadata !"branch_weights", i32 52, i32 1} -// PGOUSE-DAG: ![[BL2]] = metadata !{metadata !"branch_weights", i32 51, i32 2} -// PGOUSE-DAG: ![[BL3]] = metadata !{metadata !"branch_weights", i32 26, i32 27} -// PGOUSE-DAG: ![[BL4]] = metadata !{metadata !"branch_weights", i32 51, i32 2} -// PGOUSE-DAG: ![[BL5]] = metadata !{metadata !"branch_weights", i32 52, i32 1} -// PGOUSE-DAG: ![[BL6]] = metadata !{metadata !"branch_weights", i32 51, i32 2} -// PGOUSE-DAG: ![[BL7]] = metadata !{metadata !"branch_weights", i32 26, i32 27} -// PGOUSE-DAG: ![[BL8]] = metadata !{metadata !"branch_weights", i32 51, i32 2} -// PGOUSE-DAG: ![[ST1]] = metadata !{metadata !"branch_weights", i32 11, i32 2} - -int main(int argc, const char *argv[]) { - simple_loops(); - conditionals(); - early_exits(); - jumps(); - switches(); - big_switch(); - boolean_operators(); - boolop_loops(); - do_fallthrough(); - no_usable_data(); - static_func(); - return 0; -} diff --git a/clang/test/CodeGenCXX/Inputs/instr-profile-class.profdata b/clang/test/CodeGenCXX/Inputs/instr-profile-class.profdata deleted file mode 100644 index 6605eb446c7..00000000000 --- a/clang/test/CodeGenCXX/Inputs/instr-profile-class.profdata +++ /dev/null @@ -1,20 +0,0 @@ -_ZN6SimpleC2Ei 2 -100 -99 - -_ZN6Simple6methodEv 2 -100 -99 - -_ZN6SimpleD2Ev 2 -100 -99 - -_ZN14simple_wrapperEv 4 -1 -100 -0 -0 - -main 1 -1 diff --git a/clang/test/CodeGenCXX/Inputs/instr-profile-throws.profdata b/clang/test/CodeGenCXX/Inputs/instr-profile-throws.profdata deleted file mode 100644 index a49522f5584..00000000000 --- a/clang/test/CodeGenCXX/Inputs/instr-profile-throws.profdata +++ /dev/null @@ -1,14 +0,0 @@ -_Z6throwsv 9 -1 -100 -100 -66 -33 -17 -50 -33 -100 - -main 1 -1 - diff --git a/clang/test/CodeGenCXX/instr-profile-class.cpp b/clang/test/CodeGenCXX/instr-profile-class.cpp deleted file mode 100644 index f23aac6f7cb..00000000000 --- a/clang/test/CodeGenCXX/instr-profile-class.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// Test that instrumentation based profiling feeds branch prediction -// correctly. This tests both generation of profile data and use of the same, -// and the input file for the -fprofile-instr-use case is expected to be result -// of running the program generated by the -fprofile-instr-generate case -// (excepting no_usable_data). As such, main() should call every function in -// this test. - -// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-generate -fno-exceptions -target %itanium_abi_triple > %tgen -// RUN: FileCheck --input-file=%tgen -check-prefix=CTRGEN %s -// RUN: FileCheck --input-file=%tgen -check-prefix=DTRGEN %s -// RUN: FileCheck --input-file=%tgen -check-prefix=MTHGEN %s -// RUN: FileCheck --input-file=%tgen -check-prefix=WRPGEN %s - -// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/instr-profile-class.profdata -fno-exceptions -target %itanium_abi_triple > %tuse -// RUN: FileCheck --input-file=%tuse -check-prefix=CTRUSE %s -// RUN: FileCheck --input-file=%tuse -check-prefix=DTRUSE %s -// RUN: FileCheck --input-file=%tuse -check-prefix=MTHUSE %s -// RUN: FileCheck --input-file=%tuse -check-prefix=WRPUSE %s - -class Simple { - int Member; -public: - // CTRGEN-LABEL: define {{.*}} @_ZN6SimpleC2Ei( - // CTRUSE-LABEL: define {{.*}} @_ZN6SimpleC2Ei( - // CTRGEN: store {{.*}} @[[SCC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 - explicit Simple(int Member) : Member(Member) { - // CTRGEN: store {{.*}} @[[SCC]], i64 0, i64 1 - // CTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]] - if (Member) {} - // CTRGEN-NOT: store {{.*}} @[[SCC]], - // CTRUSE-NOT: br {{.*}} !prof ![0-9]+ - // CTRUSE: ret - } - // CTRUSE: ![[SC1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} - - // DTRGEN-LABEL: define {{.*}} @_ZN6SimpleD2Ev( - // DTRUSE-LABEL: define {{.*}} @_ZN6SimpleD2Ev( - // DTRGEN: store {{.*}} @[[SDC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 - ~Simple() { - // DTRGEN: store {{.*}} @[[SDC]], i64 0, i64 1 - // DTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]] - if (Member) {} - // DTRGEN-NOT: store {{.*}} @[[SDC]], - // DTRUSE-NOT: br {{.*}} !prof ![0-9]+ - // DTRUSE: ret - } - // DTRUSE: ![[SD1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} - - // MTHGEN-LABEL: define {{.*}} @_ZN6Simple6methodEv( - // MTHUSE-LABEL: define {{.*}} @_ZN6Simple6methodEv( - // MTHGEN: store {{.*}} @[[SMC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 - void method() { - // MTHGEN: store {{.*}} @[[SMC]], i64 0, i64 1 - // MTHUSE: br {{.*}} !prof ![[SM1:[0-9]+]] - if (Member) {} - // MTHGEN-NOT: store {{.*}} @[[SMC]], - // MTHUSE-NOT: br {{.*}} !prof ![0-9]+ - // MTHUSE: ret - } - // MTHUSE: ![[SM1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} -}; - -// WRPGEN-LABEL: define {{.*}} @_Z14simple_wrapperv( -// WRPUSE-LABEL: define {{.*}} @_Z14simple_wrapperv( -// WRPGEN: store {{.*}} @[[SWC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 -void simple_wrapper() { - // WRPGEN: store {{.*}} @[[SWC]], i64 0, i64 1 - // WRPUSE: br {{.*}} !prof ![[SW1:[0-9]+]] - for (int I = 0; I < 100; ++I) { - Simple S(I); - S.method(); - } - // WRPGEN-NOT: store {{.*}} @[[SWC]], - // WRPUSE-NOT: br {{.*}} !prof ![0-9]+ - // WRPUSE: ret -} -// WRPUSE: ![[SW1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} - -int main(int argc, const char *argv[]) { - simple_wrapper(); - return 0; -} diff --git a/clang/test/CodeGenCXX/instr-profile-throws.cpp b/clang/test/CodeGenCXX/instr-profile-throws.cpp deleted file mode 100644 index d25827c5e00..00000000000 --- a/clang/test/CodeGenCXX/instr-profile-throws.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// Test that instrumentation based profiling feeds branch prediction -// correctly. This tests both generation of profile data and use of the same, -// and the input file for the -fprofile-instr-use case is expected to be result -// of running the program generated by the -fprofile-instr-generate case. As -// such, main() should call every function in this test. - -// FIXME: Don't seek bb labels, like "if.else" -// REQUIRES: asserts - -// RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN %s -// RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN-EXC %s - -// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/instr-profile-throws.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE %s -// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/instr-profile-throws.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE-EXC %s - -// PGOGEN: @[[THC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer -// PGOGEN-EXC: @[[THC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer - -// PGOGEN-LABEL: @_Z6throwsv() -// PGOUSE-LABEL: @_Z6throwsv() -// PGOGEN: store {{.*}} @[[THC]], i64 0, i64 0 -void throws() { - // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[TH1:[0-9]+]] - for (int i = 0; i < 100; ++i) { - try { - // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 3 - // PGOUSE: br {{.*}} !prof ![[TH2:[0-9]+]] - if (i % 3) { - // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 4 - // PGOUSE: br {{.*}} !prof ![[TH3:[0-9]+]] - if (i < 50) - throw 1; - } else { - // The catch block may be emitted after the throw above, we can skip it - // by looking for an else block, but this will break if anyone puts an - // else in the catch - // PGOUSE: if.else{{.*}}: - // PGOGEN: if.else{{.*}}: - - // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 5 - // PGOUSE: br {{.*}} !prof ![[TH4:[0-9]+]] - if (i >= 50) - throw 0; - } - } catch (int e) { - // PGOUSE-EXC: catch{{.*}}: - // PGOGEN-EXC: catch{{.*}}: - - // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 6 - // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 7 - // PGOUSE-EXC: br {{.*}} !prof ![[TH5:[0-9]+]] - if (e) {} - } - // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 2 - - // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 8 - // PGOUSE: br {{.*}} !prof ![[TH6:[0-9]+]] - if (i < 100) {} - } - - // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ - // PGOUSE: ret void -} - -// PGOUSE-DAG: ![[TH1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} -// PGOUSE-DAG: ![[TH2]] = metadata !{metadata !"branch_weights", i32 67, i32 35} -// PGOUSE-DAG: ![[TH3]] = metadata !{metadata !"branch_weights", i32 34, i32 34} -// PGOUSE-DAG: ![[TH4]] = metadata !{metadata !"branch_weights", i32 18, i32 18} -// PGOUSE-EXC: ![[TH5]] = metadata !{metadata !"branch_weights", i32 34, i32 18} -// PGOUSE-DAG: ![[TH6]] = metadata !{metadata !"branch_weights", i32 101, i32 1} - -int main(int argc, const char *argv[]) { - throws(); - return 0; -} diff --git a/clang/test/CodeGenObjC/Inputs/instr-profile.profdata b/clang/test/CodeGenObjC/Inputs/instr-profile.profdata deleted file mode 100644 index 0fe046e5795..00000000000 --- a/clang/test/CodeGenObjC/Inputs/instr-profile.profdata +++ /dev/null @@ -1,11 +0,0 @@ -instr-profile.m:__13+[A foreach:]_block_invoke 2 -2 -1 - -instr-profile.m:+[A foreach:] 2 -1 -2 - -main 1 -1 - diff --git a/clang/test/CodeGenObjC/instr-profile.m b/clang/test/CodeGenObjC/instr-profile.m deleted file mode 100644 index c1bb50574de..00000000000 --- a/clang/test/CodeGenObjC/instr-profile.m +++ /dev/null @@ -1,74 +0,0 @@ -// Test that instrumentation based profiling feeds branch prediction -// correctly. This tests both generation of profile data and use of the same, -// and the input file for the -fprofile-instr-use case is expected to be result -// of running the program generated by the -fprofile-instr-generate case. As -// such, main() should call every function in this test. - -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name instr-profile.m %s -o - -emit-llvm -fblocks -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name instr-profile.m %s -o - -emit-llvm -fblocks -fprofile-instr-use=%S/Inputs/instr-profile.profdata | FileCheck -check-prefix=PGOUSE %s - -#ifdef HAVE_FOUNDATION - -// Use this to build an instrumented version to regenerate the input file. -#import - -#else - -// Minimal definitions to get this to compile without Foundation.h. - -@protocol NSObject -@end - -@interface NSObject -- (id)init; -+ (id)alloc; -@end - -struct NSFastEnumerationState; -@interface NSArray : NSObject -- (unsigned long) countByEnumeratingWithState: (struct NSFastEnumerationState*) state - objects: (id*) buffer - count: (unsigned long) bufferSize; -+(NSArray*) arrayWithObjects: (id) first, ...; -@end; -#endif - -// PGOGEN: @[[FRC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer -// PGOGEN: @[[BLC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer -// PGOGEN: @[[MAC:__llvm_pgo_ctr[0-9]*]] = private global [1 x i64] zeroinitializer - -@interface A : NSObject -+ (void)foreach: (NSArray *)array; -@end - -@implementation A -// PGOGEN: define {{.*}}+[A foreach:] -// PGOUSE: define {{.*}}+[A foreach:] -// PGOGEN: store {{.*}} @[[FRC]], i64 0, i64 0 -+ (void)foreach: (NSArray *)array -{ - __block id result; - // PGOGEN: store {{.*}} @[[FRC]], i64 0, i64 1 - // FIXME: We don't emit branch weights for this yet. - for (id x in array) { - // PGOGEN: define {{.*}}_block_invoke - // PGOUSE: define {{.*}}_block_invoke - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 0 - ^{ static int init = 0; - // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 1 - // PGOUSE: br {{.*}} !prof ![[BL1:[0-9]+]] - if (init) - result = x; - init = 1; }(); - } -} -@end - -// PGOUSE-DAG: ![[BL1]] = metadata !{metadata !"branch_weights", i32 2, i32 2} - -int main(int argc, const char *argv[]) { - A *a = [[A alloc] init]; - NSArray *array = [NSArray arrayWithObjects: @"0", @"1", (void*)0]; - [A foreach: array]; - return 0; -} diff --git a/clang/test/Profile/Inputs/c-attributes.profdata b/clang/test/Profile/Inputs/c-attributes.profdata new file mode 100644 index 00000000000..0419b3b3bef --- /dev/null +++ b/clang/test/Profile/Inputs/c-attributes.profdata @@ -0,0 +1,39 @@ +hot_100_percent 4 +100000 +4999950000 +0 +0 + +hot_40_percent 4 +40000 +799980000 +0 +0 + +normal_func 4 +20000 +199990000 +0 +0 + +cold_func 4 +500 +124750 +0 +0 + +main 13 +1 +100000 +0 +0 +40000 +0 +0 +20000 +0 +0 +500 +0 +0 + diff --git a/clang/test/Profile/Inputs/c-general.profdata b/clang/test/Profile/Inputs/c-general.profdata new file mode 100644 index 00000000000..e87f78e6b56 --- /dev/null +++ b/clang/test/Profile/Inputs/c-general.profdata @@ -0,0 +1,138 @@ +simple_loops 4 +1 +100 +100 +75 + +conditionals 11 +1 +100 +50 +50 +33 +33 +16 +99 +100 +99 +100 + +early_exits 9 +1 +0 +51 +1 +25 +1 +25 +1 +0 + +jumps 22 +1 +1 +0 +1 +0 +0 +1 +0 +1 +2 +3 +2 +0 +3 +0 +1 +1 +1 +10 +0 +10 +9 + +switches 19 +1 +1 +1 +15 +7 +1 +0 +2 +2 +3 +3 +4 +4 +0 +4 +4 +5 +1 +0 + +big_switch 17 +1 +32 +32 +1 +0 +1 +1 +11 +11 +1 +1 +15 +15 +1 +1 +2 +2 + +issue_with_one_counter 1 +0 + +boolean_operators 8 +1 +100 +34 +66 +17 +34 +33 +50 + +boolop_loops 9 +1 +50 +51 +50 +26 +50 +51 +50 +26 + +do_fallthrough 4 +1 +10 +2 +8 + +no_usable_data 5 +1 +1 +1 +1 +1 + +main 1 +1 + +c-general.c:static_func 2 +1 +10 + diff --git a/clang/test/Profile/Inputs/cxx-class.profdata b/clang/test/Profile/Inputs/cxx-class.profdata new file mode 100644 index 00000000000..6605eb446c7 --- /dev/null +++ b/clang/test/Profile/Inputs/cxx-class.profdata @@ -0,0 +1,20 @@ +_ZN6SimpleC2Ei 2 +100 +99 + +_ZN6Simple6methodEv 2 +100 +99 + +_ZN6SimpleD2Ev 2 +100 +99 + +_ZN14simple_wrapperEv 4 +1 +100 +0 +0 + +main 1 +1 diff --git a/clang/test/Profile/Inputs/cxx-throws.profdata b/clang/test/Profile/Inputs/cxx-throws.profdata new file mode 100644 index 00000000000..a49522f5584 --- /dev/null +++ b/clang/test/Profile/Inputs/cxx-throws.profdata @@ -0,0 +1,14 @@ +_Z6throwsv 9 +1 +100 +100 +66 +33 +17 +50 +33 +100 + +main 1 +1 + diff --git a/clang/test/Profile/Inputs/objc-general.profdata b/clang/test/Profile/Inputs/objc-general.profdata new file mode 100644 index 00000000000..da421583b81 --- /dev/null +++ b/clang/test/Profile/Inputs/objc-general.profdata @@ -0,0 +1,10 @@ +objc-general.m:__13+[A foreach:]_block_invoke 2 +2 +1 + +objc-general.m:+[A foreach:] 2 +1 +2 + +main 1 +1 diff --git a/clang/test/Profile/README b/clang/test/Profile/README new file mode 100644 index 00000000000..8cf13c062ff --- /dev/null +++ b/clang/test/Profile/README @@ -0,0 +1,8 @@ +These are tests for instrumentation based profiling. This specifically +means the -fprofile-instr-generate and -fprofile-instr-use driver flags. + +Tests in this directory should test both the generation of profile +data, and the use of that same data. As such, the input source file +should include a main function such that building with -use and +running the resulting program would generate the input data that is +consumed in the -generate case. diff --git a/clang/test/Profile/c-attributes.c b/clang/test/Profile/c-attributes.c new file mode 100644 index 00000000000..81809551fde --- /dev/null +++ b/clang/test/Profile/c-attributes.c @@ -0,0 +1,47 @@ +// Test that instrumentation based profiling sets function attributes correctly. + +// RUN: %clang %s -o - -mllvm -disable-llvm-optzns -emit-llvm -S -fprofile-instr-use=%S/Inputs/c-attributes.profdata | FileCheck %s + +extern int atoi(const char *); + +// CHECK: hot_100_percent(i32{{.*}}%i) [[HOT:#[0-9]+]] +void hot_100_percent(int i) { + while (i > 0) + i--; +} + +// CHECK: hot_40_percent(i32{{.*}}%i) [[HOT]] +void hot_40_percent(int i) { + while (i > 0) + i--; +} + +// CHECK: normal_func(i32{{.*}}%i) [[NORMAL:#[0-9]+]] +void normal_func(int i) { + while (i > 0) + i--; +} + +// CHECK: cold_func(i32{{.*}}%i) [[COLD:#[0-9]+]] +void cold_func(int i) { + while (i > 0) + i--; +} + +// CHECK: attributes [[HOT]] = { inlinehint nounwind {{.*}} } +// CHECK: attributes [[NORMAL]] = { nounwind {{.*}} } +// CHECK: attributes [[COLD]] = { cold nounwind {{.*}} } + +int main(int argc, const char *argv[]) { + int max = atoi(argv[1]); + int i; + for (i = 0; i < max; i++) + hot_100_percent(i); + for (i = 0; i < max * 4 / 10; i++) + hot_40_percent(i); + for (i = 0; i < max * 2 / 10; i++) + normal_func(i); + for (i = 0; i < max / 200; i++) + cold_func(i); + return 0; +} diff --git a/clang/test/Profile/c-general.c b/clang/test/Profile/c-general.c new file mode 100644 index 00000000000..43ebf511827 --- /dev/null +++ b/clang/test/Profile/c-general.c @@ -0,0 +1,537 @@ +// Test instrumentation of general constructs in C. + +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instr-use=%S/Inputs/c-general.profdata | FileCheck -check-prefix=PGOUSE %s + +// PGOGEN: @[[SLC:__llvm_pgo_ctr[0-9]*]] = private global [4 x i64] zeroinitializer +// PGOGEN: @[[IFC:__llvm_pgo_ctr[0-9]*]] = private global [11 x i64] zeroinitializer +// PGOGEN: @[[EEC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer +// PGOGEN: @[[JMC:__llvm_pgo_ctr[0-9]*]] = private global [22 x i64] zeroinitializer +// PGOGEN: @[[SWC:__llvm_pgo_ctr[0-9]*]] = private global [19 x i64] zeroinitializer +// PGOGEN: @[[BSC:__llvm_pgo_ctr[0-9]*]] = private global [17 x i64] zeroinitializer +// PGOGEN: @[[BOC:__llvm_pgo_ctr[0-9]*]] = private global [8 x i64] zeroinitializer +// PGOGEN: @[[BLC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer +// PGOGEN: @[[NOC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer +// PGOGEN: @[[MAC:__llvm_pgo_ctr[0-9]*]] = private global [1 x i64] zeroinitializer +// PGOGEN: @[[STC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer + +// PGOGEN-LABEL: @simple_loops() +// PGOUSE-LABEL: @simple_loops() +// PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 0 +void simple_loops() { + int i; + // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[SL1:[0-9]+]] + for (i = 0; i < 100; ++i) { + } + // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 2 + // PGOUSE: br {{.*}} !prof ![[SL2:[0-9]+]] + while (i > 0) + i--; + // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[SL3:[0-9]+]] + do {} while (i++ < 75); + + // PGOGEN-NOT: store {{.*}} @[[SLC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +// PGOGEN-LABEL: @conditionals() +// PGOUSE-LABEL: @conditionals() +// PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 0 +void conditionals() { + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[IF1:[0-9]+]] + for (int i = 0; i < 100; ++i) { + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 2 + // PGOUSE: br {{.*}} !prof ![[IF2:[0-9]+]] + if (i % 2) { + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[IF3:[0-9]+]] + if (i) {} + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 4 + // PGOUSE: br {{.*}} !prof ![[IF4:[0-9]+]] + } else if (i % 3) { + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 5 + // PGOUSE: br {{.*}} !prof ![[IF5:[0-9]+]] + if (i) {} + } else { + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 6 + // PGOUSE: br {{.*}} !prof ![[IF6:[0-9]+]] + if (i) {} + } + + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 8 + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 7 + // PGOUSE: br {{.*}} !prof ![[IF7:[0-9]+]] + if (1 && i) {} + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 10 + // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 9 + // PGOUSE: br {{.*}} !prof ![[IF8:[0-9]+]] + if (0 || i) {} + } + + // PGOGEN-NOT: store {{.*}} @[[IFC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +// PGOGEN-LABEL: @early_exits() +// PGOUSE-LABEL: @early_exits() +// PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 0 +void early_exits() { + int i = 0; + + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[EE1:[0-9]+]] + if (i) {} + + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 2 + // PGOUSE: br {{.*}} !prof ![[EE2:[0-9]+]] + while (i < 100) { + i++; + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[EE3:[0-9]+]] + if (i > 50) + break; + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 4 + // PGOUSE: br {{.*}} !prof ![[EE4:[0-9]+]] + if (i % 2) + continue; + } + + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 5 + // PGOUSE: br {{.*}} !prof ![[EE5:[0-9]+]] + if (i) {} + + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 6 + do { + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 7 + // PGOUSE: br {{.*}} !prof ![[EE6:[0-9]+]] + if (i > 75) + return; + else + i++; + // PGOUSE: br {{.*}} !prof ![[EE7:[0-9]+]] + } while (i < 100); + + // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 8 + // Never reached -> no weights + if (i) {} + + // PGOGEN-NOT: store {{.*}} @[[EEC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +// PGOGEN-LABEL: @jumps() +// PGOUSE-LABEL: @jumps() +// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 0 +void jumps() { + int i; + + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[JM1:[0-9]+]] + for (i = 0; i < 2; ++i) { + goto outofloop; + // Never reached -> no weights + if (i) {} + } +// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 3 +outofloop: + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 4 + // PGOUSE: br {{.*}} !prof ![[JM2:[0-9]+]] + if (i) {} + + goto loop1; + + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 5 + // PGOUSE: br {{.*}} !prof ![[JM3:[0-9]+]] + while (i) { + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 6 + loop1: + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 7 + // PGOUSE: br {{.*}} !prof ![[JM4:[0-9]+]] + if (i) {} + } + + goto loop2; +// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 8 +first: +// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 9 +second: +// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 10 +third: + i++; + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 11 + // PGOUSE: br {{.*}} !prof ![[JM5:[0-9]+]] + if (i < 3) + goto loop2; + + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 12 + // PGOUSE: br {{.*}} !prof ![[JM6:[0-9]+]] + while (i < 3) { + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 13 + loop2: + // PGOUSE: switch {{.*}} [ + // PGOUSE: ], !prof ![[JM7:[0-9]+]] + switch (i) { + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 15 + case 0: + goto first; + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 16 + case 1: + goto second; + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 17 + case 2: + goto third; + } + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 14 + } + + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 18 + // PGOUSE: br {{.*}} !prof ![[JM8:[0-9]+]] + for (i = 0; i < 10; ++i) { + goto withinloop; + // never reached -> no weights + if (i) {} + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 20 + withinloop: + // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 21 + // PGOUSE: br {{.*}} !prof ![[JM9:[0-9]+]] + if (i) {} + } + + // PGOGEN-NOT: store {{.*}} @[[JMC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +// PGOGEN-LABEL: @switches() +// PGOUSE-LABEL: @switches() +// PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 0 +void switches() { + static int weights[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5}; + + // No cases -> no weights + switch (weights[0]) { + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 2 + default: + break; + } + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 1 + + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[SW1:[0-9]+]] + for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) { + // PGOUSE: switch {{.*}} [ + // PGOUSE: ], !prof ![[SW2:[0-9]+]] + switch (i[weights]) { + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 5 + case 1: + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 6 + // PGOUSE: br {{.*}} !prof ![[SW3:[0-9]+]] + if (i) {} + // fallthrough + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 7 + case 2: + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 8 + // PGOUSE: br {{.*}} !prof ![[SW4:[0-9]+]] + if (i) {} + break; + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 9 + case 3: + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 10 + // PGOUSE: br {{.*}} !prof ![[SW5:[0-9]+]] + if (i) {} + continue; + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 11 + case 4: + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 12 + // PGOUSE: br {{.*}} !prof ![[SW6:[0-9]+]] + if (i) {} + // PGOUSE: switch {{.*}} [ + // PGOUSE: ], !prof ![[SW7:[0-9]+]] + switch (i) { + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 14 + case 6 ... 9: + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 15 + // PGOUSE: br {{.*}} !prof ![[SW8:[0-9]+]] + if (i) {} + continue; + } + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 13 + + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 16 + default: + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 17 + // PGOUSE: br {{.*}} !prof ![[SW9:[0-9]+]] + if (i == len - 1) + return; + } + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 4 + } + + // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 18 + // Never reached -> no weights + if (weights[0]) {} + + // PGOGEN-NOT: store {{.*}} @[[SWC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +// PGOGEN-LABEL: @big_switch() +// PGOUSE-LABEL: @big_switch() +// PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 0 +void big_switch() { + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[BS1:[0-9]+]] + for (int i = 0; i < 32; ++i) { + // PGOUSE: switch {{.*}} [ + // PGOUSE: ], !prof ![[BS2:[0-9]+]] + switch (1 << i) { + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 3 + case (1 << 0): + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 4 + // PGOUSE: br {{.*}} !prof ![[BS3:[0-9]+]] + if (i) {} + // fallthrough + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 5 + case (1 << 1): + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 6 + // PGOUSE: br {{.*}} !prof ![[BS4:[0-9]+]] + if (i) {} + break; + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 7 + case (1 << 2) ... (1 << 12): + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 8 + // PGOUSE: br {{.*}} !prof ![[BS5:[0-9]+]] + if (i) {} + break; + // The branch for the large case range above appears after the case body + // PGOUSE: br {{.*}} !prof ![[BS6:[0-9]+]] + + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 9 + case (1 << 13): + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 10 + // PGOUSE: br {{.*}} !prof ![[BS7:[0-9]+]] + if (i) {} + break; + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 11 + case (1 << 14) ... (1 << 28): + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 12 + // PGOUSE: br {{.*}} !prof ![[BS8:[0-9]+]] + if (i) {} + break; + // The branch for the large case range above appears after the case body + // PGOUSE: br {{.*}} !prof ![[BS9:[0-9]+]] + + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 13 + case (1 << 29) ... ((1 << 29) + 1): + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 14 + // PGOUSE: br {{.*}} !prof ![[BS10:[0-9]+]] + if (i) {} + break; + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 15 + default: + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 16 + // PGOUSE: br {{.*}} !prof ![[BS11:[0-9]+]] + if (i) {} + break; + } + // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 2 + } + + // PGOGEN-NOT: store {{.*}} @[[BSC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ + // PGOUSE: ret void +} + +// PGOGEN-LABEL: @boolean_operators() +// PGOUSE-LABEL: @boolean_operators() +// PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 0 +void boolean_operators() { + int v; + // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[BO1:[0-9]+]] + for (int i = 0; i < 100; ++i) { + // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 2 + // PGOUSE: br {{.*}} !prof ![[BO2:[0-9]+]] + v = i % 3 || i; + + // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[BO3:[0-9]+]] + v = i % 3 && i; + + // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 5 + // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 4 + // PGOUSE: br {{.*}} !prof ![[BO4:[0-9]+]] + // PGOUSE: br {{.*}} !prof ![[BO5:[0-9]+]] + v = i % 3 || i % 2 || i; + + // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 7 + // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 6 + // PGOUSE: br {{.*}} !prof ![[BO6:[0-9]+]] + // PGOUSE: br {{.*}} !prof ![[BO7:[0-9]+]] + v = i % 2 && i % 3 && i; + } + + // PGOGEN-NOT: store {{.*}} @[[BOC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +// PGOGEN-LABEL: @boolop_loops() +// PGOUSE-LABEL: @boolop_loops() +// PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 0 +void boolop_loops() { + int i = 100; + + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 2 + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[BL1:[0-9]+]] + // PGOUSE: br {{.*}} !prof ![[BL2:[0-9]+]] + while (i && i > 50) + i--; + + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 4 + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[BL3:[0-9]+]] + // PGOUSE: br {{.*}} !prof ![[BL4:[0-9]+]] + while ((i % 2) || (i > 0)) + i--; + + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 6 + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 5 + // PGOUSE: br {{.*}} !prof ![[BL5:[0-9]+]] + // PGOUSE: br {{.*}} !prof ![[BL6:[0-9]+]] + for (i = 100; i && i > 50; --i); + + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 8 + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 7 + // PGOUSE: br {{.*}} !prof ![[BL7:[0-9]+]] + // PGOUSE: br {{.*}} !prof ![[BL8:[0-9]+]] + for (; (i % 2) || (i > 0); --i); + + // PGOGEN-NOT: store {{.*}} @[[BLC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +void do_fallthrough() { + for (int i = 0; i < 10; ++i) { + int j = 0; + do { + // The number of exits out of this do-loop via the break statement + // exceeds the counter value for the loop (which does not include the + // fallthrough count). Make sure that does not violate any assertions. + if (i < 8) break; + j++; + } while (j < 2); + } +} + +// PGOGEN-LABEL: @no_usable_data() +// PGOUSE-LABEL: @no_usable_data() +// PGOGEN: store {{.*}} @[[NOC]], i64 0, i64 0 +void no_usable_data() { + // The input data for PGOUSE is deliberately invalid for this function, so + // that we can test that we reject and ignore it properly. + int i = 0; + + // PGOGEN: store {{.*}} @[[NOC]], i64 0, i64 1 + if (i) {} + + // PGOGEN-NOT: store {{.*}} @[[NOC]], + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ +} + +// PGOGEN-LABEL: @static_func() +// PGOUSE-LABEL: @static_func() +// PGOGEN: store {{.*}} @[[STC]], i64 0, i64 0 +static void static_func() { + // PGOGEN: store {{.*}} @[[STC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[ST1:[0-9]+]] + for (int i = 0; i < 10; ++i) { + } +} + +// PGOUSE-DAG: ![[SL1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} +// PGOUSE-DAG: ![[SL2]] = metadata !{metadata !"branch_weights", i32 101, i32 2} +// PGOUSE-DAG: ![[SL3]] = metadata !{metadata !"branch_weights", i32 76, i32 2} + +// PGOUSE-DAG: ![[EE1]] = metadata !{metadata !"branch_weights", i32 1, i32 2} +// PGOUSE-DAG: ![[EE2]] = metadata !{metadata !"branch_weights", i32 52, i32 1} +// PGOUSE-DAG: ![[EE3]] = metadata !{metadata !"branch_weights", i32 2, i32 51} +// PGOUSE-DAG: ![[EE4]] = metadata !{metadata !"branch_weights", i32 26, i32 26} +// PGOUSE-DAG: ![[EE5]] = metadata !{metadata !"branch_weights", i32 2, i32 1} +// PGOUSE-DAG: ![[EE6]] = metadata !{metadata !"branch_weights", i32 2, i32 26} +// PGOUSE-DAG: ![[EE7]] = metadata !{metadata !"branch_weights", i32 26, i32 1} + +// PGOUSE-DAG: ![[IF1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} +// PGOUSE-DAG: ![[IF2]] = metadata !{metadata !"branch_weights", i32 51, i32 51} +// PGOUSE-DAG: ![[IF3]] = metadata !{metadata !"branch_weights", i32 51, i32 1} +// PGOUSE-DAG: ![[IF4]] = metadata !{metadata !"branch_weights", i32 34, i32 18} +// PGOUSE-DAG: ![[IF5]] = metadata !{metadata !"branch_weights", i32 34, i32 1} +// PGOUSE-DAG: ![[IF6]] = metadata !{metadata !"branch_weights", i32 17, i32 2} +// PGOUSE-DAG: ![[IF7]] = metadata !{metadata !"branch_weights", i32 100, i32 2} +// PGOUSE-DAG: ![[IF8]] = metadata !{metadata !"branch_weights", i32 100, i32 2} + +// PGOUSE-DAG: ![[JM1]] = metadata !{metadata !"branch_weights", i32 2, i32 1} +// PGOUSE-DAG: ![[JM2]] = metadata !{metadata !"branch_weights", i32 1, i32 2} +// PGOUSE-DAG: ![[JM3]] = metadata !{metadata !"branch_weights", i32 1, i32 2} +// PGOUSE-DAG: ![[JM4]] = metadata !{metadata !"branch_weights", i32 1, i32 2} +// PGOUSE-DAG: ![[JM5]] = metadata !{metadata !"branch_weights", i32 3, i32 2} +// PGOUSE-DAG: ![[JM6]] = metadata !{metadata !"branch_weights", i32 1, i32 2} +// PGOUSE-DAG: ![[JM7]] = metadata !{metadata !"branch_weights", i32 1, i32 2, i32 2, i32 2} +// PGOUSE-DAG: ![[JM8]] = metadata !{metadata !"branch_weights", i32 11, i32 2} +// PGOUSE-DAG: ![[JM9]] = metadata !{metadata !"branch_weights", i32 10, i32 2} + +// PGOUSE-DAG: ![[SW1]] = metadata !{metadata !"branch_weights", i32 16, i32 1} +// PGOUSE-DAG: ![[SW2]] = metadata !{metadata !"branch_weights", i32 6, i32 2, i32 3, i32 4, i32 5} +// PGOUSE-DAG: ![[SW3]] = metadata !{metadata !"branch_weights", i32 1, i32 2} +// PGOUSE-DAG: ![[SW4]] = metadata !{metadata !"branch_weights", i32 3, i32 2} +// PGOUSE-DAG: ![[SW5]] = metadata !{metadata !"branch_weights", i32 4, i32 1} +// PGOUSE-DAG: ![[SW6]] = metadata !{metadata !"branch_weights", i32 5, i32 1} +// PGOUSE-DAG: ![[SW7]] = metadata !{metadata !"branch_weights", i32 1, i32 2, i32 2, i32 2, i32 2} +// PGOUSE-DAG: ![[SW8]] = metadata !{metadata !"branch_weights", i32 5, i32 1} +// PGOUSE-DAG: ![[SW9]] = metadata !{metadata !"branch_weights", i32 2, i32 5} + +// PGOUSE-DAG: ![[BS1]] = metadata !{metadata !"branch_weights", i32 33, i32 2} +// PGOUSE-DAG: ![[BS2]] = metadata !{metadata !"branch_weights", i32 29, i32 2, i32 2, i32 2, i32 2, i32 1} +// PGOUSE-DAG: ![[BS3]] = metadata !{metadata !"branch_weights", i32 1, i32 2} +// PGOUSE-DAG: ![[BS4]] = metadata !{metadata !"branch_weights", i32 2, i32 2} +// PGOUSE-DAG: ![[BS5]] = metadata !{metadata !"branch_weights", i32 12, i32 1} +// PGOUSE-DAG: ![[BS6]] = metadata !{metadata !"branch_weights", i32 12, i32 3} +// PGOUSE-DAG: ![[BS7]] = metadata !{metadata !"branch_weights", i32 2, i32 1} +// PGOUSE-DAG: ![[BS8]] = metadata !{metadata !"branch_weights", i32 16, i32 1} +// PGOUSE-DAG: ![[BS9]] = metadata !{metadata !"branch_weights", i32 16, i32 14} +// PGOUSE-DAG: ![[BS10]] = metadata !{metadata !"branch_weights", i32 2, i32 1} +// PGOUSE-DAG: ![[BS11]] = metadata !{metadata !"branch_weights", i32 3, i32 1} + +// PGOUSE-DAG: ![[BO1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} +// PGOUSE-DAG: ![[BO2]] = metadata !{metadata !"branch_weights", i32 67, i32 35} +// PGOUSE-DAG: ![[BO3]] = metadata !{metadata !"branch_weights", i32 67, i32 35} +// PGOUSE-DAG: ![[BO4]] = metadata !{metadata !"branch_weights", i32 67, i32 35} +// PGOUSE-DAG: ![[BO5]] = metadata !{metadata !"branch_weights", i32 18, i32 18} +// PGOUSE-DAG: ![[BO6]] = metadata !{metadata !"branch_weights", i32 51, i32 51} +// PGOUSE-DAG: ![[BO7]] = metadata !{metadata !"branch_weights", i32 34, i32 18} +// PGOUSE-DAG: ![[BL1]] = metadata !{metadata !"branch_weights", i32 52, i32 1} +// PGOUSE-DAG: ![[BL2]] = metadata !{metadata !"branch_weights", i32 51, i32 2} +// PGOUSE-DAG: ![[BL3]] = metadata !{metadata !"branch_weights", i32 26, i32 27} +// PGOUSE-DAG: ![[BL4]] = metadata !{metadata !"branch_weights", i32 51, i32 2} +// PGOUSE-DAG: ![[BL5]] = metadata !{metadata !"branch_weights", i32 52, i32 1} +// PGOUSE-DAG: ![[BL6]] = metadata !{metadata !"branch_weights", i32 51, i32 2} +// PGOUSE-DAG: ![[BL7]] = metadata !{metadata !"branch_weights", i32 26, i32 27} +// PGOUSE-DAG: ![[BL8]] = metadata !{metadata !"branch_weights", i32 51, i32 2} +// PGOUSE-DAG: ![[ST1]] = metadata !{metadata !"branch_weights", i32 11, i32 2} + +int main(int argc, const char *argv[]) { + simple_loops(); + conditionals(); + early_exits(); + jumps(); + switches(); + big_switch(); + boolean_operators(); + boolop_loops(); + do_fallthrough(); + no_usable_data(); + static_func(); + return 0; +} diff --git a/clang/test/Profile/cxx-class.cpp b/clang/test/Profile/cxx-class.cpp new file mode 100644 index 00000000000..5934a0adb7d --- /dev/null +++ b/clang/test/Profile/cxx-class.cpp @@ -0,0 +1,77 @@ +// Tests for instrumentation of C++ methods, constructors, and destructors. + +// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-generate -fno-exceptions -target %itanium_abi_triple > %tgen +// RUN: FileCheck --input-file=%tgen -check-prefix=CTRGEN %s +// RUN: FileCheck --input-file=%tgen -check-prefix=DTRGEN %s +// RUN: FileCheck --input-file=%tgen -check-prefix=MTHGEN %s +// RUN: FileCheck --input-file=%tgen -check-prefix=WRPGEN %s + +// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/cxx-class.profdata -fno-exceptions -target %itanium_abi_triple > %tuse +// RUN: FileCheck --input-file=%tuse -check-prefix=CTRUSE %s +// RUN: FileCheck --input-file=%tuse -check-prefix=DTRUSE %s +// RUN: FileCheck --input-file=%tuse -check-prefix=MTHUSE %s +// RUN: FileCheck --input-file=%tuse -check-prefix=WRPUSE %s + +class Simple { + int Member; +public: + // CTRGEN-LABEL: define {{.*}} @_ZN6SimpleC2Ei( + // CTRUSE-LABEL: define {{.*}} @_ZN6SimpleC2Ei( + // CTRGEN: store {{.*}} @[[SCC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 + explicit Simple(int Member) : Member(Member) { + // CTRGEN: store {{.*}} @[[SCC]], i64 0, i64 1 + // CTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]] + if (Member) {} + // CTRGEN-NOT: store {{.*}} @[[SCC]], + // CTRUSE-NOT: br {{.*}} !prof ![0-9]+ + // CTRUSE: ret + } + // CTRUSE: ![[SC1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} + + // DTRGEN-LABEL: define {{.*}} @_ZN6SimpleD2Ev( + // DTRUSE-LABEL: define {{.*}} @_ZN6SimpleD2Ev( + // DTRGEN: store {{.*}} @[[SDC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 + ~Simple() { + // DTRGEN: store {{.*}} @[[SDC]], i64 0, i64 1 + // DTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]] + if (Member) {} + // DTRGEN-NOT: store {{.*}} @[[SDC]], + // DTRUSE-NOT: br {{.*}} !prof ![0-9]+ + // DTRUSE: ret + } + // DTRUSE: ![[SD1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} + + // MTHGEN-LABEL: define {{.*}} @_ZN6Simple6methodEv( + // MTHUSE-LABEL: define {{.*}} @_ZN6Simple6methodEv( + // MTHGEN: store {{.*}} @[[SMC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 + void method() { + // MTHGEN: store {{.*}} @[[SMC]], i64 0, i64 1 + // MTHUSE: br {{.*}} !prof ![[SM1:[0-9]+]] + if (Member) {} + // MTHGEN-NOT: store {{.*}} @[[SMC]], + // MTHUSE-NOT: br {{.*}} !prof ![0-9]+ + // MTHUSE: ret + } + // MTHUSE: ![[SM1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} +}; + +// WRPGEN-LABEL: define {{.*}} @_Z14simple_wrapperv( +// WRPUSE-LABEL: define {{.*}} @_Z14simple_wrapperv( +// WRPGEN: store {{.*}} @[[SWC:__llvm_pgo_ctr[0-9]*]], i64 0, i64 0 +void simple_wrapper() { + // WRPGEN: store {{.*}} @[[SWC]], i64 0, i64 1 + // WRPUSE: br {{.*}} !prof ![[SW1:[0-9]+]] + for (int I = 0; I < 100; ++I) { + Simple S(I); + S.method(); + } + // WRPGEN-NOT: store {{.*}} @[[SWC]], + // WRPUSE-NOT: br {{.*}} !prof ![0-9]+ + // WRPUSE: ret +} +// WRPUSE: ![[SW1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} + +int main(int argc, const char *argv[]) { + simple_wrapper(); + return 0; +} diff --git a/clang/test/Profile/cxx-throws.cpp b/clang/test/Profile/cxx-throws.cpp new file mode 100644 index 00000000000..0a8ebf1558b --- /dev/null +++ b/clang/test/Profile/cxx-throws.cpp @@ -0,0 +1,72 @@ +// Test instrumentation of C++ exception handling constructs. + +// FIXME: Don't seek bb labels, like "if.else" +// REQUIRES: asserts + +// RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN %s +// RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN-EXC %s + +// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/cxx-throws.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE %s +// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%S/Inputs/cxx-throws.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE-EXC %s + +// PGOGEN: @[[THC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer +// PGOGEN-EXC: @[[THC:__llvm_pgo_ctr[0-9]*]] = private global [9 x i64] zeroinitializer + +// PGOGEN-LABEL: @_Z6throwsv() +// PGOUSE-LABEL: @_Z6throwsv() +// PGOGEN: store {{.*}} @[[THC]], i64 0, i64 0 +void throws() { + // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[TH1:[0-9]+]] + for (int i = 0; i < 100; ++i) { + try { + // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[TH2:[0-9]+]] + if (i % 3) { + // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 4 + // PGOUSE: br {{.*}} !prof ![[TH3:[0-9]+]] + if (i < 50) + throw 1; + } else { + // The catch block may be emitted after the throw above, we can skip it + // by looking for an else block, but this will break if anyone puts an + // else in the catch + // PGOUSE: if.else{{.*}}: + // PGOGEN: if.else{{.*}}: + + // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 5 + // PGOUSE: br {{.*}} !prof ![[TH4:[0-9]+]] + if (i >= 50) + throw 0; + } + } catch (int e) { + // PGOUSE-EXC: catch{{.*}}: + // PGOGEN-EXC: catch{{.*}}: + + // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 6 + // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 7 + // PGOUSE-EXC: br {{.*}} !prof ![[TH5:[0-9]+]] + if (e) {} + } + // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 2 + + // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 8 + // PGOUSE: br {{.*}} !prof ![[TH6:[0-9]+]] + if (i < 100) {} + } + + // PGOUSE-NOT: br {{.*}} !prof ![0-9]+ + // PGOUSE: ret void +} + +// PGOUSE-DAG: ![[TH1]] = metadata !{metadata !"branch_weights", i32 101, i32 2} +// PGOUSE-DAG: ![[TH2]] = metadata !{metadata !"branch_weights", i32 67, i32 35} +// PGOUSE-DAG: ![[TH3]] = metadata !{metadata !"branch_weights", i32 34, i32 34} +// PGOUSE-DAG: ![[TH4]] = metadata !{metadata !"branch_weights", i32 18, i32 18} +// PGOUSE-EXC: ![[TH5]] = metadata !{metadata !"branch_weights", i32 34, i32 18} +// PGOUSE-DAG: ![[TH6]] = metadata !{metadata !"branch_weights", i32 101, i32 1} + +int main(int argc, const char *argv[]) { + throws(); + return 0; +} diff --git a/clang/test/Profile/objc-general.m b/clang/test/Profile/objc-general.m new file mode 100644 index 00000000000..b5f2673302c --- /dev/null +++ b/clang/test/Profile/objc-general.m @@ -0,0 +1,70 @@ +// Test instrumentation of general constructs in objective C. + +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name objc-general.m %s -o - -emit-llvm -fblocks -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name objc-general.m %s -o - -emit-llvm -fblocks -fprofile-instr-use=%S/Inputs/objc-general.profdata | FileCheck -check-prefix=PGOUSE %s + +#ifdef HAVE_FOUNDATION + +// Use this to build an instrumented version to regenerate the input file. +#import + +#else + +// Minimal definitions to get this to compile without Foundation.h. + +@protocol NSObject +@end + +@interface NSObject +- (id)init; ++ (id)alloc; +@end + +struct NSFastEnumerationState; +@interface NSArray : NSObject +- (unsigned long) countByEnumeratingWithState: (struct NSFastEnumerationState*) state + objects: (id*) buffer + count: (unsigned long) bufferSize; ++(NSArray*) arrayWithObjects: (id) first, ...; +@end; +#endif + +// PGOGEN: @[[FRC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer +// PGOGEN: @[[BLC:__llvm_pgo_ctr[0-9]*]] = private global [2 x i64] zeroinitializer +// PGOGEN: @[[MAC:__llvm_pgo_ctr[0-9]*]] = private global [1 x i64] zeroinitializer + +@interface A : NSObject ++ (void)foreach: (NSArray *)array; +@end + +@implementation A +// PGOGEN: define {{.*}}+[A foreach:] +// PGOUSE: define {{.*}}+[A foreach:] +// PGOGEN: store {{.*}} @[[FRC]], i64 0, i64 0 ++ (void)foreach: (NSArray *)array +{ + __block id result; + // PGOGEN: store {{.*}} @[[FRC]], i64 0, i64 1 + // FIXME: We don't emit branch weights for this yet. + for (id x in array) { + // PGOGEN: define {{.*}}_block_invoke + // PGOUSE: define {{.*}}_block_invoke + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 0 + ^{ static int init = 0; + // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[BL1:[0-9]+]] + if (init) + result = x; + init = 1; }(); + } +} +@end + +// PGOUSE-DAG: ![[BL1]] = metadata !{metadata !"branch_weights", i32 2, i32 2} + +int main(int argc, const char *argv[]) { + A *a = [[A alloc] init]; + NSArray *array = [NSArray arrayWithObjects: @"0", @"1", (void*)0]; + [A foreach: array]; + return 0; +} -- cgit v1.2.3