1 // Tests for instrumentation of C++ methods, constructors, and destructors. 2 3 // RUN: %clang_cc1 %s -o - -emit-llvm -fprofile-instrument=clang -triple %itanium_abi_triple > %tgen 4 // RUN: FileCheck --input-file=%tgen -check-prefix=CTRGEN %s 5 // RUN: FileCheck --input-file=%tgen -check-prefix=DTRGEN %s 6 // RUN: FileCheck --input-file=%tgen -check-prefix=MTHGEN %s 7 // RUN: FileCheck --input-file=%tgen -check-prefix=WRPGEN %s 8 // RUN: FileCheck --input-file=%tgen -check-prefix=VCTRGEN %s 9 // RUN: FileCheck --input-file=%tgen -check-prefix=VDTRGEN %s 10 11 // RUN: llvm-profdata merge %S/Inputs/cxx-class.proftext -o %t.profdata 12 // RUN: %clang_cc1 %s -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata -triple %itanium_abi_triple > %tuse 13 // RUN: FileCheck --input-file=%tuse -check-prefix=CTRUSE %s 14 // RUN: FileCheck --input-file=%tuse -check-prefix=DTRUSE %s 15 // RUN: FileCheck --input-file=%tuse -check-prefix=MTHUSE %s 16 // RUN: FileCheck --input-file=%tuse -check-prefix=WRPUSE %s 17 // RUN: FileCheck --input-file=%tuse -check-prefix=VCTRUSE %s 18 // RUN: FileCheck --input-file=%tuse -check-prefix=VDTRUSE %s 19 20 class Simple { 21 public: 22 int Member; 23 // CTRGEN-LABEL: define {{.*}} @_ZN6SimpleC2Ei( 24 // CTRUSE-LABEL: define {{.*}} @_ZN6SimpleC2Ei( 25 // CTRGEN: store {{.*}} @[[SCC:__profc__ZN6SimpleC2Ei]], i32 0, i32 0 26 explicit Simple(int Member) : Member(Member) { 27 // CTRGEN: store {{.*}} @[[SCC]], i32 0, i32 1 28 // CTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]] 29 if (Member) {} 30 // CTRGEN-NOT: store {{.*}} @[[SCC]], 31 // CTRUSE-NOT: br {{.*}} !prof ![0-9]+ 32 // CTRUSE: ret 33 } 34 // CTRUSE: ![[SC1]] = !{!"branch_weights", i32 100, i32 2} 35 36 // DTRGEN-LABEL: define {{.*}} @_ZN6SimpleD2Ev( 37 // DTRUSE-LABEL: define {{.*}} @_ZN6SimpleD2Ev( 38 // DTRGEN: store {{.*}} @[[SDC:__profc__ZN6SimpleD2Ev]], i32 0, i32 0 39 ~Simple() { 40 // DTRGEN: store {{.*}} @[[SDC]], i32 0, i32 1 41 // DTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]] 42 if (Member) {} 43 // DTRGEN-NOT: store {{.*}} @[[SDC]], 44 // DTRUSE-NOT: br {{.*}} !prof ![0-9]+ 45 // DTRUSE: ret 46 } 47 // DTRUSE: ![[SD1]] = !{!"branch_weights", i32 100, i32 2} 48 49 // MTHGEN-LABEL: define {{.*}} @_ZN6Simple6methodEv( 50 // MTHUSE-LABEL: define {{.*}} @_ZN6Simple6methodEv( 51 // MTHGEN: store {{.*}} @[[SMC:__profc__ZN6Simple6methodEv]], i32 0, i32 0 52 void method() { 53 // MTHGEN: store {{.*}} @[[SMC]], i32 0, i32 1 54 // MTHUSE: br {{.*}} !prof ![[SM1:[0-9]+]] 55 if (Member) {} 56 // MTHGEN-NOT: store {{.*}} @[[SMC]], 57 // MTHUSE-NOT: br {{.*}} !prof ![0-9]+ 58 // MTHUSE: ret 59 } 60 // MTHUSE: ![[SM1]] = !{!"branch_weights", i32 100, i32 2} 61 }; 62 63 class Derived : virtual public Simple { 64 public: 65 // VCTRGEN-LABEL: define {{.*}} @_ZN7DerivedC1Ev( 66 // VCTRUSE-LABEL: define {{.*}} @_ZN7DerivedC1Ev( 67 // VCTRGEN: store {{.*}} @[[SCC:__profc__ZN7DerivedC1Ev]], i32 0, i32 0 68 Derived() : Simple(0) { 69 // VCTRGEN: store {{.*}} @[[SCC]], i32 0, i32 1 70 // VCTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]] 71 if (Member) {} 72 // VCTRGEN-NOT: store {{.*}} @[[SCC]], 73 // VCTRUSE-NOT: br {{.*}} !prof ![0-9]+ 74 // VCTRUSE: ret 75 } 76 // VCTRUSE: ![[SC1]] = !{!"branch_weights", i32 100, i32 2} 77 78 // VDTRGEN-LABEL: define {{.*}} @_ZN7DerivedD2Ev( 79 // VDTRUSE-LABEL: define {{.*}} @_ZN7DerivedD2Ev( 80 // VDTRGEN: store {{.*}} @[[SDC:__profc__ZN7DerivedD2Ev]], i32 0, i32 0 81 ~Derived() { 82 // VDTRGEN: store {{.*}} @[[SDC]], i32 0, i32 1 83 // VDTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]] 84 if (Member) {} 85 // VDTRGEN-NOT: store {{.*}} @[[SDC]], 86 // VDTRUSE-NOT: br {{.*}} !prof ![0-9]+ 87 // VDTRUSE: ret 88 } 89 // VDTRUSE: ![[SD1]] = !{!"branch_weights", i32 100, i32 2} 90 }; 91 92 // WRPGEN-LABEL: define {{.*}} @_Z14simple_wrapperv( 93 // WRPUSE-LABEL: define {{.*}} @_Z14simple_wrapperv( 94 // WRPGEN: store {{.*}} @[[SWC:__profc__Z14simple_wrapperv]], i32 0, i32 0 95 void simple_wrapper() { 96 // WRPGEN: store {{.*}} @[[SWC]], i32 0, i32 1 97 // WRPUSE: br {{.*}} !prof ![[SW1:[0-9]+]] 98 for (int I = 0; I < 100; ++I) { 99 Derived d; 100 Simple S(I); 101 S.method(); 102 } 103 // WRPGEN-NOT: store {{.*}} @[[SWC]], 104 // WRPUSE-NOT: br {{.*}} !prof ![0-9]+ 105 // WRPUSE: ret 106 } 107 // WRPUSE: ![[SW1]] = !{!"branch_weights", i32 101, i32 2} 108 109 int main(int argc, const char *argv[]) { 110 simple_wrapper(); 111 return 0; 112 } 113