From: Justin Bogner Date: Thu, 30 Apr 2015 22:58:28 +0000 (+0000) Subject: InstrProf: Fix handling of profile counters in the body of range based for X-Git-Tag: llvmorg-3.7.0-rc1~5580 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2e5d484597ff0ab232f8db03c5e2bb2933cdb88e;p=platform%2Fupstream%2Fllvm.git InstrProf: Fix handling of profile counters in the body of range based for We were assigning the counter for the body of the loop to the loop variable initialization for some reason here, but our tests completely lacked coverage for range-for loops. This fixes that and makes the logic generally more similar to the logic for a regular for. llvm-svn: 236277 --- diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 27e4c7f..c90b025 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -447,6 +447,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor { void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { RecordStmtCount(S); + Visit(S->getLoopVarStmt()); Visit(S->getRangeStmt()); Visit(S->getBeginEndStmt()); // Counter tracks the body of the loop. @@ -455,8 +456,7 @@ struct ComputeRegionCounts : public ConstStmtVisitor { // Visit the body region first. (This is basically the same as a while // loop; see further comments in VisitWhileStmt.) Cnt.beginRegion(); - CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount(); - Visit(S->getLoopVarStmt()); + CountMap[S->getBody()] = PGO.getCurrentRegionCount(); Visit(S->getBody()); Cnt.adjustForControlFlow(); @@ -475,7 +475,6 @@ struct ComputeRegionCounts : public ConstStmtVisitor { BC.ContinueCount); CountMap[S->getCond()] = PGO.getCurrentRegionCount(); Visit(S->getCond()); - Cnt.adjustForControlFlow(); Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount); RecordNextStmtCount = true; } diff --git a/clang/test/Profile/Inputs/cxx-rangefor.proftext b/clang/test/Profile/Inputs/cxx-rangefor.proftext new file mode 100644 index 0000000..7d2d1ef --- /dev/null +++ b/clang/test/Profile/Inputs/cxx-rangefor.proftext @@ -0,0 +1,13 @@ +_Z9range_forv +0x000000000014a28a +5 +1 +4 +1 +1 +1 + +main +0 +1 +1 diff --git a/clang/test/Profile/cxx-rangefor.cpp b/clang/test/Profile/cxx-rangefor.cpp new file mode 100644 index 0000000..f30cdc7 --- /dev/null +++ b/clang/test/Profile/cxx-rangefor.cpp @@ -0,0 +1,44 @@ +// Tests for instrumentation of C++11 range-for + +// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-rangefor.cpp -std=c++11 -o - -emit-llvm -fprofile-instr-generate > %tgen +// RUN: FileCheck --input-file=%tgen -check-prefix=CHECK -check-prefix=PGOGEN %s + +// RUN: llvm-profdata merge %S/Inputs/cxx-rangefor.proftext -o %t.profdata +// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-rangefor.cpp -std=c++11 -o - -emit-llvm -fprofile-instr-use=%t.profdata > %tuse +// RUN: FileCheck --input-file=%tuse -check-prefix=CHECK -check-prefix=PGOUSE %s + +// PGOGEN: @[[RFC:__llvm_profile_counters__Z9range_forv]] = private global [5 x i64] zeroinitializer + +// CHECK-LABEL: define void @_Z9range_forv() +// PGOGEN: store {{.*}} @[[RFC]], i64 0, i64 0 +void range_for() { + int arr[] = {1, 2, 3, 4, 5}; + int sum = 0; + // PGOGEN: store {{.*}} @[[RFC]], i64 0, i64 1 + // PGOUSE: br {{.*}} !prof ![[RF1:[0-9]+]] + for (auto i : arr) { + // PGOGEN: store {{.*}} @[[RFC]], i64 0, i64 2 + // PGOUSE: br {{.*}} !prof ![[RF2:[0-9]+]] + if (i == 3) + continue; + sum += i; + // PGOGEN: store {{.*}} @[[RFC]], i64 0, i64 3 + // PGOUSE: br {{.*}} !prof ![[RF3:[0-9]+]] + if (sum >= 7) + break; + } + + // PGOGEN: store {{.*}} @[[RFC]], i64 0, i64 4 + // PGOUSE: br {{.*}} !prof ![[RF4:[0-9]+]] + if (sum) {} +} + +// PGOUSE-DAG: ![[RF1]] = !{!"branch_weights", i32 5, i32 1} +// PGOUSE-DAG: ![[RF2]] = !{!"branch_weights", i32 2, i32 4} +// PGOUSE-DAG: ![[RF3]] = !{!"branch_weights", i32 2, i32 3} +// PGOUSE-DAG: ![[RF4]] = !{!"branch_weights", i32 2, i32 1} + +int main(int argc, const char *argv[]) { + range_for(); + return 0; +}