diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index acc392a0e189..27e4c7fc0916 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -317,6 +317,14 @@ struct ComputeRegionCounts : public ConstStmtVisitor { 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(); diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 11b9478262ac..73afeda35725 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -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) { diff --git a/clang/test/CoverageMapping/trycatch.cpp b/clang/test/CoverageMapping/trycatch.cpp index 696df5485b2f..2d0f629952db 100644 --- a/clang/test/CoverageMapping/trycatch.cpp +++ b/clang/test/CoverageMapping/trycatch.cpp @@ -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 diff --git a/clang/test/Profile/Inputs/cxx-throws.proftext b/clang/test/Profile/Inputs/cxx-throws.proftext index 4016eca2ac86..1d197b9eae38 100644 --- a/clang/test/Profile/Inputs/cxx-throws.proftext +++ b/clang/test/Profile/Inputs/cxx-throws.proftext @@ -11,8 +11,16 @@ _Z6throwsv 33 100 -main +_Z11unreachablei +0x28a +3 +1 +1 0 -1 -1 +main +0x2cc +3 +1 +1 +1 diff --git a/clang/test/Profile/cxx-throws.cpp b/clang/test/Profile/cxx-throws.cpp index 0848d8ff9ba0..3e04fb019cbf 100644 --- a/clang/test/Profile/cxx-throws.cpp +++ b/clang/test/Profile/cxx-throws.cpp @@ -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; }