@@ -190,25 +190,29 @@ visitFunctionDecl(ASTWalker &Walker, AbstractFunctionDecl *AFD, F Func) {
190
190
return ASTWalker::Action::SkipChildren ();
191
191
}
192
192
193
- // / Whether to skip visitation of an expression. If the expression should be
194
- // / skipped, a walker action is returned that determines whether or not the
195
- // / children should also be skipped.
196
- static Optional<ASTWalker::PreWalkResult<Expr *>>
197
- shouldSkipExpr (Expr *E, ASTWalker::ParentTy Parent) {
193
+ // / Whether to walk the children of a given expression.
194
+ ASTWalker::PreWalkResult<Expr *>
195
+ shouldWalkIntoExpr (Expr *E, ASTWalker::ParentTy Parent, SILDeclRef Constant) {
198
196
using Action = ASTWalker::Action;
199
- using Result = ASTWalker::PreWalkResult<Expr *>;
200
197
201
198
// Profiling for closures should be handled separately. Do not visit
202
199
// closure expressions twice.
203
- if (isa<AbstractClosureExpr>(E) && !Parent.isNull ())
204
- return Result (Action::SkipChildren (E));
205
-
206
- // Expressions with no location should be skipped, but we still want to visit
207
- // their children.
208
- if (E->getStartLoc ().isInvalid () || E->getEndLoc ().isInvalid ())
209
- return Result (Action::Continue (E));
200
+ if (isa<AbstractClosureExpr>(E)) {
201
+ // A non-null parent means we have a closure child, which we will visit
202
+ // separately. Even if the parent is null, don't walk into a closure if the
203
+ // SILDeclRef is not for a closure, as it could be for a property
204
+ // initializer instead.
205
+ if (!Parent.isNull () || !Constant || !Constant.getAbstractClosureExpr ())
206
+ return Action::SkipChildren (E);
207
+ }
208
+ return Action::Continue (E);
209
+ }
210
210
211
- return None;
211
+ // / Whether to skip visitation of an expression. The children may however still
212
+ // / be visited
213
+ bool shouldSkipExpr (Expr *E) {
214
+ // Expressions with no location should be skipped.
215
+ return E->getStartLoc ().isInvalid () || E->getEndLoc ().isInvalid ();
212
216
}
213
217
214
218
// / Whether the children of a decl that isn't explicitly handled should be
@@ -221,14 +225,18 @@ static bool shouldWalkIntoUnhandledDecl(const Decl *D) {
221
225
222
226
// / An ASTWalker that maps ASTNodes to profiling counters.
223
227
struct MapRegionCounters : public ASTWalker {
228
+ // / The SIL function being profiled.
229
+ SILDeclRef Constant;
230
+
224
231
// / The next counter value to assign.
225
232
unsigned NextCounter = 0 ;
226
233
227
234
// / The map of statements to counters.
228
235
llvm::DenseMap<ASTNode, unsigned > &CounterMap;
229
236
230
- MapRegionCounters (llvm::DenseMap<ASTNode, unsigned > &CounterMap)
231
- : CounterMap(CounterMap) {}
237
+ MapRegionCounters (SILDeclRef Constant,
238
+ llvm::DenseMap<ASTNode, unsigned > &CounterMap)
239
+ : Constant(Constant), CounterMap(CounterMap) {}
232
240
233
241
LazyInitializerWalking getLazyInitializerWalkingBehavior () override {
234
242
// We want to walk lazy initializers present in the synthesized getter for
@@ -287,8 +295,8 @@ struct MapRegionCounters : public ASTWalker {
287
295
}
288
296
289
297
PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
290
- if (auto SkipAction = shouldSkipExpr (E, Parent ))
291
- return *SkipAction ;
298
+ if (shouldSkipExpr (E))
299
+ return shouldWalkIntoExpr (E, Parent, Constant) ;
292
300
293
301
// If AST visitation begins with an expression, the counter map must be
294
302
// empty. Set up a counter for the root.
@@ -304,7 +312,7 @@ struct MapRegionCounters : public ASTWalker {
304
312
if (isa<LazyInitializerExpr>(E))
305
313
mapRegion (E);
306
314
307
- return Action::Continue (E );
315
+ return shouldWalkIntoExpr (E, Parent, Constant );
308
316
}
309
317
};
310
318
@@ -524,6 +532,9 @@ class SourceMappingRegion {
524
532
// / CoverageMapping walker to recompute the correct counter information
525
533
// / for this walker.
526
534
struct PGOMapping : public ASTWalker {
535
+ // / The SIL function being profiled.
536
+ SILDeclRef Constant;
537
+
527
538
// / The counter indices for AST nodes.
528
539
const llvm::DenseMap<ASTNode, unsigned > &CounterMap;
529
540
@@ -534,11 +545,12 @@ struct PGOMapping : public ASTWalker {
534
545
llvm::DenseMap<ASTNode, ProfileCounter> &LoadedCounterMap;
535
546
llvm::DenseMap<ASTNode, ASTNode> &CondToParentMap;
536
547
537
- PGOMapping (const llvm::DenseMap<ASTNode, unsigned > &CounterMap,
548
+ PGOMapping (SILDeclRef Constant,
549
+ const llvm::DenseMap<ASTNode, unsigned > &CounterMap,
538
550
const llvm::InstrProfRecord &LoadedCounts,
539
551
llvm::DenseMap<ASTNode, ProfileCounter> &LoadedCounterMap,
540
552
llvm::DenseMap<ASTNode, ASTNode> &RegionCondToParentMap)
541
- : CounterMap(CounterMap), LoadedCounts(LoadedCounts),
553
+ : Constant(Constant), CounterMap(CounterMap), LoadedCounts(LoadedCounts),
542
554
LoadedCounterMap (LoadedCounterMap),
543
555
CondToParentMap(RegionCondToParentMap) {}
544
556
@@ -674,8 +686,8 @@ struct PGOMapping : public ASTWalker {
674
686
}
675
687
676
688
PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
677
- if (auto SkipAction = shouldSkipExpr (E, Parent ))
678
- return *SkipAction ;
689
+ if (shouldSkipExpr (E))
690
+ return shouldWalkIntoExpr (E, Parent, Constant) ;
679
691
680
692
unsigned parent = getParentCounter ();
681
693
@@ -704,7 +716,7 @@ struct PGOMapping : public ASTWalker {
704
716
if (isa<LazyInitializerExpr>(E))
705
717
setKnownExecutionCount (E);
706
718
707
- return Action::Continue (E );
719
+ return shouldWalkIntoExpr (E, Parent, Constant );
708
720
}
709
721
};
710
722
@@ -715,6 +727,9 @@ struct CoverageMapping : public ASTWalker {
715
727
private:
716
728
const SourceManager &SM;
717
729
730
+ // / The SIL function being profiled.
731
+ SILDeclRef Constant;
732
+
718
733
// / Storage for counter expressions.
719
734
std::forward_list<CounterExpr> Exprs;
720
735
@@ -938,7 +953,8 @@ struct CoverageMapping : public ASTWalker {
938
953
}
939
954
940
955
public:
941
- CoverageMapping (const SourceManager &SM) : SM(SM) {}
956
+ CoverageMapping (const SourceManager &SM, SILDeclRef Constant)
957
+ : SM(SM), Constant(Constant) {}
942
958
943
959
LazyInitializerWalking getLazyInitializerWalkingBehavior () override {
944
960
// We want to walk lazy initializers present in the synthesized getter for
@@ -1177,8 +1193,8 @@ struct CoverageMapping : public ASTWalker {
1177
1193
}
1178
1194
1179
1195
PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
1180
- if (auto SkipAction = shouldSkipExpr (E, Parent ))
1181
- return *SkipAction ;
1196
+ if (shouldSkipExpr (E))
1197
+ return shouldWalkIntoExpr (E, Parent, Constant) ;
1182
1198
1183
1199
// If we're in an 'incomplete' region, update it to include this node. This
1184
1200
// ensures we only create the region if needed.
@@ -1206,11 +1222,19 @@ struct CoverageMapping : public ASTWalker {
1206
1222
assignCounter (IE->getElseExpr (),
1207
1223
CounterExpr::Sub (getCurrentCounter (), ThenCounter));
1208
1224
}
1209
- return Action::Continue (E);
1225
+ auto WalkResult = shouldWalkIntoExpr (E, Parent, Constant);
1226
+ if (WalkResult.Action .Action == PreWalkAction::SkipChildren) {
1227
+ // We need to manually pop the region here as the ASTWalker won't call
1228
+ // the post-visitation.
1229
+ // FIXME: The ASTWalker should do a post-visit.
1230
+ if (hasCounter (E))
1231
+ popRegions (E);
1232
+ }
1233
+ return WalkResult;
1210
1234
}
1211
1235
1212
1236
PostWalkResult<Expr *> walkToExprPost (Expr *E) override {
1213
- if (shouldSkipExpr (E, Parent ))
1237
+ if (shouldSkipExpr (E))
1214
1238
return Action::Continue (E);
1215
1239
1216
1240
if (hasCounter (E))
@@ -1249,7 +1273,7 @@ void SILProfiler::assignRegionCounters() {
1249
1273
1250
1274
CurrentFileName = getCurrentFileName (Root, forDecl);
1251
1275
1252
- MapRegionCounters Mapper (RegionCounterMap);
1276
+ MapRegionCounters Mapper (forDecl, RegionCounterMap);
1253
1277
1254
1278
std::string CurrentFuncName;
1255
1279
FormalLinkage CurrentFuncLinkage;
@@ -1285,7 +1309,7 @@ void SILProfiler::assignRegionCounters() {
1285
1309
PGOFuncHash = 0x0 ;
1286
1310
1287
1311
if (EmitCoverageMapping) {
1288
- CoverageMapping Coverage (SM);
1312
+ CoverageMapping Coverage (SM, forDecl );
1289
1313
Root.walk (Coverage);
1290
1314
CovMap =
1291
1315
Coverage.emitSourceRegions (M, CurrentFuncName, PGOFuncName, PGOFuncHash,
@@ -1302,7 +1326,7 @@ void SILProfiler::assignRegionCounters() {
1302
1326
llvm::dbgs () << PGOFuncName << " \n " ;
1303
1327
return ;
1304
1328
}
1305
- PGOMapping pgoMapper (RegionCounterMap, LoadedCounts.get (),
1329
+ PGOMapping pgoMapper (forDecl, RegionCounterMap, LoadedCounts.get (),
1306
1330
RegionLoadedCounterMap, RegionCondToParentMap);
1307
1331
Root.walk (pgoMapper);
1308
1332
}
0 commit comments