diff options
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 6 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/Inputs/instr-profile-class.pgodata | 20 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/instr-profile-class.cpp | 82 |
3 files changed, 108 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index d3a1f391f77..8577c3e034a 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -721,6 +721,9 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { if (IsTryBody) EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); + RegionCounter Cnt = getPGORegionCounter(Body); + Cnt.beginRegion(Builder); + RunCleanupsScope RunCleanups(*this); // TODO: in restricted cases, we can emit the vbase initializers of @@ -1319,6 +1322,9 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { case Dtor_Base: assert(Body); + RegionCounter Cnt = getPGORegionCounter(Body); + Cnt.beginRegion(Builder); + // Enter the cleanup scopes for fields and non-virtual bases. EnterDtorCleanups(Dtor, Dtor_Base); diff --git a/clang/test/CodeGenCXX/Inputs/instr-profile-class.pgodata b/clang/test/CodeGenCXX/Inputs/instr-profile-class.pgodata new file mode 100644 index 00000000000..6605eb446c7 --- /dev/null +++ b/clang/test/CodeGenCXX/Inputs/instr-profile-class.pgodata @@ -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/CodeGenCXX/instr-profile-class.cpp b/clang/test/CodeGenCXX/instr-profile-class.cpp new file mode 100644 index 00000000000..d731e1a675a --- /dev/null +++ b/clang/test/CodeGenCXX/instr-profile-class.cpp @@ -0,0 +1,82 @@ +// 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.pgodata -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 void + } + // 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 void + } + // 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 void + } + // 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 void +} +// WRPUSE: ![[SW1]] = metadata !{metadata !"branch_weights", i32 100, i32 2} + +int main(int argc, const char *argv[]) { + simple_wrapper(); + return 0; +} |