InstrProf: Mark code regions after throw expressions as unreachable
authorJustin Bogner <mail@justinbogner.com>
Tue, 28 Apr 2015 06:31:55 +0000 (06:31 +0000)
committerJustin Bogner <mail@justinbogner.com>
Tue, 28 Apr 2015 06:31:55 +0000 (06:31 +0000)
We weren't setting regions as being unreachable after C++ throw
expressions, leading to incorrect count propagations.

llvm-svn: 235967

clang/lib/CodeGen/CodeGenPGO.cpp
clang/lib/CodeGen/CoverageMappingGen.cpp
clang/test/CoverageMapping/trycatch.cpp
clang/test/Profile/Inputs/cxx-throws.proftext
clang/test/Profile/cxx-throws.cpp

index acc392a0e189d6b339583e5a9ca9fedd0678e6ff..27e4c7fc091610619c1f55b8976f3d33cb8ea37a 100644 (file)
@@ -317,6 +317,14 @@ struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
     RecordNextStmtCount = true;
   }
 
+  void VisitCXXThrowExpr(const CXXThrowExpr *E) {
+    RecordStmtCount(E);
+    if (E->getSubExpr())
+      Visit(E->getSubExpr());
+    PGO.setCurrentRegionUnreachable();
+    RecordNextStmtCount = true;
+  }
+
   void VisitGotoStmt(const GotoStmt *S) {
     RecordStmtCount(S);
     PGO.setCurrentRegionUnreachable();
index 11b9478262acd58a6d58de6439bc0f1dca2dd2d9..73afeda357255b127f99b4d23b25f4092dfd0ced 100644 (file)
@@ -592,6 +592,13 @@ struct CounterCoverageMappingBuilder
     terminateRegion(S);
   }
 
+  void VisitCXXThrowExpr(const CXXThrowExpr *E) {
+    extendRegion(E);
+    if (E->getSubExpr())
+      Visit(E->getSubExpr());
+    terminateRegion(E);
+  }
+
   void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); }
 
   void VisitLabelStmt(const LabelStmt *S) {
index 696df5485b2f80fad59f5094ea7235078cd7a932..2d0f629952dbd295a1599df50f93332be7002ca8 100644 (file)
@@ -10,17 +10,19 @@ class Warning {
 };
 
                                       // CHECK: func
-void func(int i) {                    // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+6]]:2 = #0
-  if(i % 2)                           // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:11 = #0
-    throw Error();                    // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:18 = #1
-                                      // CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+2]]:27 = (#0 - #1)
-  else if(i == 8)                     // CHECK-NEXT: File 0, [[@LINE]]:11 -> [[@LINE]]:17 = (#0 - #1)
+void func(int i) {                    // CHECK-NEXT: File 0, [[@LINE]]:18 -> {{[0-9]+}}:2 = #0
+                                      // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:11 = #0
+  if(i % 2) {                         // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE+4]]:4 = #1
+    throw Error();
+    int j = 0;                        // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = 0
+                                      // CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+2]]:27 = (#0 - #1)
+  } else if(i == 8)                   // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE]]:19 = (#0 - #1)
     throw ImportantError();           // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:27 = #2
 }
 
                                       // CHECK-NEXT: main
 int main() {                          // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+13]]:2 = #0
-  int j = 0;
+  int j = 1;
   try {
     func(j);
   } catch(const Error &e) {           // CHECK-NEXT: File 0, [[@LINE]]:27 -> [[@LINE+2]]:4 = #2
index 4016eca2ac866d4b0fc8ea37af71b8c342bf0f76..1d197b9eae38d72ed598c9bf8f0c0379b9dcf40d 100644 (file)
@@ -11,8 +11,16 @@ _Z6throwsv
 33
 100
 
-main
-0
+_Z11unreachablei
+0x28a
+3
 1
 1
+0
 
+main
+0x2cc
+3
+1
+1
+1
index 0848d8ff9ba0c61bc10ff1dbbb61260079f6d1c1..3e04fb019cbfc3b002f0e981c22451cc27c2736c 100644 (file)
@@ -12,6 +12,7 @@
 
 // PGOGEN: @[[THC:__llvm_profile_counters__Z6throwsv]] = private global [9 x i64] zeroinitializer
 // PGOGEN-EXC: @[[THC:__llvm_profile_counters__Z6throwsv]] = private global [9 x i64] zeroinitializer
+// PGOGEN: @[[UNC:__llvm_profile_counters__Z11unreachablei]] = private global [3 x i64] zeroinitializer
 
 // PGOGEN-LABEL: @_Z6throwsv()
 // PGOUSE-LABEL: @_Z6throwsv()
@@ -60,14 +61,33 @@ void throws() {
   // PGOUSE: ret void
 }
 
+// PGOGEN-LABEL: @_Z11unreachablei(i32 %i)
+// PGOUSE-LABEL: @_Z11unreachablei(i32 %i)
+// PGOGEN: store {{.*}} @[[UNC]], i64 0, i64 0
+void unreachable(int i) {
+  // PGOGEN: store {{.*}} @[[UNC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[UN1:[0-9]+]]
+  if (i)
+    throw i;
+
+  // PGOGEN: store {{.*}} @[[UNC]], i64 0, i64 2
+  // Since we never reach here, the weights should all be zero (and skipped)
+  // PGOUSE-NOT: br {{.*}} !prof !{{.*}}
+  if (i) {}
+}
+
 // PGOUSE-DAG: ![[TH1]] = !{!"branch_weights", i32 101, i32 2}
 // PGOUSE-DAG: ![[TH2]] = !{!"branch_weights", i32 67, i32 35}
 // PGOUSE-DAG: ![[TH3]] = !{!"branch_weights", i32 34, i32 34}
 // PGOUSE-DAG: ![[TH4]] = !{!"branch_weights", i32 18, i32 18}
 // PGOUSE-EXC: ![[TH5]] = !{!"branch_weights", i32 34, i32 18}
 // PGOUSE-DAG: ![[TH6]] = !{!"branch_weights", i32 101, i32 1}
+// PGOUSE-DAG: ![[UN1]] = !{!"branch_weights", i32 2, i32 1}
 
 int main(int argc, const char *argv[]) {
   throws();
+  try {
+    unreachable(1);
+  } catch (int) {}
   return 0;
 }