@@ -131,16 +131,6 @@ static bool shouldProfile(SILDeclRef Constant) {
131
131
return true ;
132
132
}
133
133
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
-
144
134
SILProfiler *SILProfiler::create (SILModule &M, SILDeclRef Ref) {
145
135
// If profiling isn't enabled, don't profile anything.
146
136
const auto &Opts = M.getOptions ();
@@ -347,7 +337,7 @@ struct MapRegionCounters : public ASTWalker {
347
337
} else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
348
338
mapRegion (FES->getBody ());
349
339
} else if (auto *CS = dyn_cast<CaseStmt>(S)) {
350
- mapRegion (getProfilerStmtForCase (CS) );
340
+ mapRegion (CS );
351
341
}
352
342
return Action::Continue (S);
353
343
}
@@ -807,7 +797,7 @@ struct PGOMapping : public ASTWalker {
807
797
setKnownExecutionCount (FES->getBody ());
808
798
setExecutionCount (FES, parentCount);
809
799
} else if (auto *CS = dyn_cast<CaseStmt>(S)) {
810
- setKnownExecutionCount (getProfilerStmtForCase (CS) );
800
+ setKnownExecutionCount (CS );
811
801
}
812
802
return Action::Continue (S);
813
803
}
@@ -898,9 +888,6 @@ struct CoverageMapping : public ASTWalker {
898
888
// / A stack of active repeat-while loops.
899
889
std::vector<RepeatWhileStmt *> RepeatWhileStack;
900
890
901
- // / A stack of active do-catch statements.
902
- std::vector<DoCatchStmt *> DoCatchStack;
903
-
904
891
llvm::Optional<CounterExpr> ExitCounter;
905
892
906
893
Stmt *ImplicitTopLevelBody = nullptr ;
@@ -1003,13 +990,16 @@ struct CoverageMapping : public ASTWalker {
1003
990
return ;
1004
991
1005
992
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 ());
1012
1000
return ;
1001
+ }
1002
+
1013
1003
if (auto *LS = dyn_cast<LabeledStmt>(ParentStmt))
1014
1004
JumpsToLabel = getCounter (LS);
1015
1005
}
@@ -1029,11 +1019,14 @@ struct CoverageMapping : public ASTWalker {
1029
1019
}
1030
1020
1031
1021
// / 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
+
1033
1026
// Note we don't store counters for nodes, as we need to be able to fix
1034
1027
// 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 ));
1037
1030
LLVM_DEBUG ({
1038
1031
llvm::dbgs () << " Pushed region: " ;
1039
1032
RegionStack.back ().print (llvm::dbgs (), SM);
@@ -1288,27 +1281,43 @@ struct CoverageMapping : public ASTWalker {
1288
1281
for (CaseStmt *Case : SS->getCases ())
1289
1282
assignKnownCounter (Case);
1290
1283
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
+
1294
1297
} else if (auto *DS = dyn_cast<DoStmt>(S)) {
1295
1298
// The counter for the do statement itself tracks the number of jumps
1296
1299
// to it by break statements.
1297
1300
assignCounter (DS, CounterExpr::Zero ());
1298
1301
1302
+ // The do body is visited the same number of times as its parent.
1299
1303
assignCounter (DS->getBody (), getCurrentCounter ());
1300
1304
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);
1312
1321
}
1313
1322
return Action::Continue (S);
1314
1323
}
@@ -1354,39 +1363,28 @@ struct CoverageMapping : public ASTWalker {
1354
1363
addToCounter (BS->getTarget (), getCurrentCounter ());
1355
1364
}
1356
1365
1357
- // The break also affects the exit counts of active do-catch statements.
1358
- for (auto *DCS : DoCatchStack)
1359
- subtractFromCounter (DCS, getCurrentCounter ());
1360
-
1361
1366
terminateRegion (S);
1362
1367
1363
1368
} else if (auto *FS = dyn_cast<FallthroughStmt>(S)) {
1364
1369
addToCounter (FS->getFallthroughDest (), getCurrentCounter ());
1365
1370
terminateRegion (S);
1366
1371
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.
1368
1374
replaceCount (getCounter (S), getEndLoc (S));
1369
1375
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);
1381
1381
1382
1382
} else if (isa<ReturnStmt>(S) || isa<FailStmt>(S) || isa<ThrowStmt>(S)) {
1383
1383
// When we return, adjust loop condition counts and do-catch exit counts
1384
1384
// to reflect the early exit.
1385
1385
if (isa<ReturnStmt>(S) || isa<FailStmt>(S)) {
1386
1386
for (auto *RWS : RepeatWhileStack)
1387
1387
subtractFromCounter (RWS->getCond (), getCurrentCounter ());
1388
- for (auto *DCS : DoCatchStack)
1389
- subtractFromCounter (DCS, getCurrentCounter ());
1390
1388
}
1391
1389
1392
1390
terminateRegion (S);
0 commit comments