@@ -131,16 +131,6 @@ static bool shouldProfile(SILDeclRef Constant) {
131131 return true ;
132132}
133133
134- static Stmt *getProfilerStmtForCase (CaseStmt *caseStmt) {
135- switch (caseStmt->getParentKind ()) {
136- case CaseParentKind::Switch:
137- return caseStmt;
138- case CaseParentKind::DoCatch:
139- return caseStmt->getBody ();
140- }
141- llvm_unreachable (" invalid parent kind" );
142- }
143-
144134SILProfiler *SILProfiler::create (SILModule &M, SILDeclRef Ref) {
145135 // If profiling isn't enabled, don't profile anything.
146136 const auto &Opts = M.getOptions ();
@@ -347,7 +337,7 @@ struct MapRegionCounters : public ASTWalker {
347337 } else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
348338 mapRegion (FES->getBody ());
349339 } else if (auto *CS = dyn_cast<CaseStmt>(S)) {
350- mapRegion (getProfilerStmtForCase (CS) );
340+ mapRegion (CS );
351341 }
352342 return Action::Continue (S);
353343 }
@@ -807,7 +797,7 @@ struct PGOMapping : public ASTWalker {
807797 setKnownExecutionCount (FES->getBody ());
808798 setExecutionCount (FES, parentCount);
809799 } else if (auto *CS = dyn_cast<CaseStmt>(S)) {
810- setKnownExecutionCount (getProfilerStmtForCase (CS) );
800+ setKnownExecutionCount (CS );
811801 }
812802 return Action::Continue (S);
813803 }
@@ -898,9 +888,6 @@ struct CoverageMapping : public ASTWalker {
898888 // / A stack of active repeat-while loops.
899889 std::vector<RepeatWhileStmt *> RepeatWhileStack;
900890
901- // / A stack of active do-catch statements.
902- std::vector<DoCatchStmt *> DoCatchStack;
903-
904891 llvm::Optional<CounterExpr> ExitCounter;
905892
906893 Stmt *ImplicitTopLevelBody = nullptr ;
@@ -1003,13 +990,16 @@ struct CoverageMapping : public ASTWalker {
1003990 return ;
1004991
1005992 llvm::Optional<CounterExpr> JumpsToLabel;
1006- Stmt *ParentStmt = Parent.getAsStmt ();
1007- if (ParentStmt) {
1008- if (isa<DoCatchStmt>(ParentStmt))
1009- return ;
1010- auto caseStmt = dyn_cast_or_null<CaseStmt>(ParentStmt);
1011- if (caseStmt && caseStmt->getParentKind () == CaseParentKind::DoCatch)
993+ if (auto *ParentStmt = Parent.getAsStmt ()) {
994+ if (auto *DCS = dyn_cast<DoCatchStmt>(ParentStmt)) {
995+ // We need to handle the brace of a DoCatchStmt here specially,
996+ // applying the same logic we apply to the catch clauses (handled by
997+ // the CaseStmt logic), we add on the exit count of the branch to the
998+ // statement's exit count.
999+ addToCounter (DCS, getExitCounter ());
10121000 return ;
1001+ }
1002+
10131003 if (auto *LS = dyn_cast<LabeledStmt>(ParentStmt))
10141004 JumpsToLabel = getCounter (LS);
10151005 }
@@ -1029,11 +1019,14 @@ struct CoverageMapping : public ASTWalker {
10291019 }
10301020
10311021 // / Push a region covering \c Node onto the stack.
1032- void pushRegion (ASTNode Node) {
1022+ void pushRegion (ASTNode Node, SourceRange Range = SourceRange()) {
1023+ if (Range.isInvalid ())
1024+ Range = Node.getSourceRange ();
1025+
10331026 // Note we don't store counters for nodes, as we need to be able to fix
10341027 // them up later.
1035- RegionStack.emplace_back (Node, /* Counter*/ llvm::None, Node. getStartLoc () ,
1036- getEndLoc (Node ));
1028+ RegionStack.emplace_back (Node, /* Counter*/ llvm::None, Range. Start ,
1029+ Lexer::getLocForEndOfToken (SM, Range. End ));
10371030 LLVM_DEBUG ({
10381031 llvm::dbgs () << " Pushed region: " ;
10391032 RegionStack.back ().print (llvm::dbgs (), SM);
@@ -1288,27 +1281,43 @@ struct CoverageMapping : public ASTWalker {
12881281 for (CaseStmt *Case : SS->getCases ())
12891282 assignKnownCounter (Case);
12901283
1291- } else if (auto caseStmt = dyn_cast<CaseStmt>(S)) {
1292- if (caseStmt->getParentKind () == CaseParentKind::Switch)
1293- pushRegion (S);
1284+ } else if (auto *DCS = dyn_cast<DoCatchStmt>(S)) {
1285+ // The counter for the do-catch statement itself tracks the number of
1286+ // jumps to it by break statements, including the implicit breaks at the
1287+ // end of body + catches.
1288+ assignCounter (DCS, CounterExpr::Zero ());
1289+
1290+ // The do-catch body is visited the same number of times as its parent.
1291+ assignCounter (DCS->getBody (), getCurrentCounter ());
1292+
1293+ // The catch clauses are CaseStmts that have their own mapped counters.
1294+ for (CaseStmt *Catch : DCS->getCatches ())
1295+ assignKnownCounter (Catch);
1296+
12941297 } else if (auto *DS = dyn_cast<DoStmt>(S)) {
12951298 // The counter for the do statement itself tracks the number of jumps
12961299 // to it by break statements.
12971300 assignCounter (DS, CounterExpr::Zero ());
12981301
1302+ // The do body is visited the same number of times as its parent.
12991303 assignCounter (DS->getBody (), getCurrentCounter ());
13001304
1301- } else if (auto *DCS = dyn_cast<DoCatchStmt>(S)) {
1302- // The do-catch body is visited the same number of times as its parent.
1303- assignCounter (DCS->getBody (), getCurrentCounter ());
1304-
1305- for (CaseStmt *Catch : DCS->getCatches ())
1306- assignKnownCounter (Catch->getBody ());
1307-
1308- // Initialize the exit count of the do-catch to the entry count, then
1309- // subtract off non-local exits as they are visited.
1310- assignCounter (DCS, getCurrentCounter ());
1311- DoCatchStack.push_back (DCS);
1305+ } else if (auto *CS = dyn_cast<CaseStmt>(S)) {
1306+ SourceRange Range;
1307+ switch (CS->getParentKind ()) {
1308+ case CaseParentKind::DoCatch:
1309+ // For a catch clause, we only want the range to cover the brace.
1310+ Range = CS->getBody ()->getSourceRange ();
1311+ break ;
1312+ case CaseParentKind::Switch:
1313+ // FIXME: We may want to reconsider using the full range here, as it
1314+ // implies the case pattern is evaluated the same number of times as
1315+ // the body, which is not true. We don't currently have a way of
1316+ // tracking the pattern evaluation count though.
1317+ Range = CS->getSourceRange ();
1318+ break ;
1319+ }
1320+ pushRegion (CS, Range);
13121321 }
13131322 return Action::Continue (S);
13141323 }
@@ -1354,39 +1363,28 @@ struct CoverageMapping : public ASTWalker {
13541363 addToCounter (BS->getTarget (), getCurrentCounter ());
13551364 }
13561365
1357- // The break also affects the exit counts of active do-catch statements.
1358- for (auto *DCS : DoCatchStack)
1359- subtractFromCounter (DCS, getCurrentCounter ());
1360-
13611366 terminateRegion (S);
13621367
13631368 } else if (auto *FS = dyn_cast<FallthroughStmt>(S)) {
13641369 addToCounter (FS->getFallthroughDest (), getCurrentCounter ());
13651370 terminateRegion (S);
13661371
1367- } else if (isa<SwitchStmt>(S)) {
1372+ } else if (isa<SwitchStmt>(S) || isa<DoCatchStmt>(S)) {
1373+ // Replace the parent counter with the exit count of the statement.
13681374 replaceCount (getCounter (S), getEndLoc (S));
13691375
1370- } else if (auto caseStmt = dyn_cast<CaseStmt>(S)) {
1371- if (caseStmt->getParentKind () == CaseParentKind::Switch) {
1372- // The end of a case block is an implicit break, update the exit
1373- // counter to reflect this.
1374- addToCounter (caseStmt->getParentStmt (), getCurrentCounter ());
1375- popRegions (S);
1376- }
1377- } else if (auto *DCS = dyn_cast<DoCatchStmt>(S)) {
1378- assert (DoCatchStack.back () == DCS && " Malformed do-catch stack" );
1379- DoCatchStack.pop_back ();
1380- replaceCount (getCounter (S), getEndLoc (S));
1376+ } else if (auto *CS = dyn_cast<CaseStmt>(S)) {
1377+ // The end of a case/catch block is an implicit break, update the exit
1378+ // counter to reflect this.
1379+ addToCounter (CS->getParentStmt (), getCurrentCounter ());
1380+ popRegions (S);
13811381
13821382 } else if (isa<ReturnStmt>(S) || isa<FailStmt>(S) || isa<ThrowStmt>(S)) {
13831383 // When we return, adjust loop condition counts and do-catch exit counts
13841384 // to reflect the early exit.
13851385 if (isa<ReturnStmt>(S) || isa<FailStmt>(S)) {
13861386 for (auto *RWS : RepeatWhileStack)
13871387 subtractFromCounter (RWS->getCond (), getCurrentCounter ());
1388- for (auto *DCS : DoCatchStack)
1389- subtractFromCounter (DCS, getCurrentCounter ());
13901388 }
13911389
13921390 terminateRegion (S);
0 commit comments