@@ -157,6 +157,33 @@ std::pair<bool, Expr *> visitClosureExpr(ASTWalker &Walker,
157
157
return {true , CE};
158
158
}
159
159
160
+ // / Special logic for handling function visitation.
161
+ // /
162
+ // / To avoid creating duplicate mappings, a function decl is only profiled if
163
+ // / it hasn't been reached via recursive walk, or if it's a constructor for a
164
+ // / nominal type (these are profiled in a group).
165
+ // /
166
+ // / Apply \p Func is the function can be visited.
167
+ template <typename F>
168
+ bool visitFunctionDecl (ASTWalker &Walker, AbstractFunctionDecl *AFD, F Func) {
169
+ bool continueWalk = Walker.Parent .isNull () || isa<ConstructorDecl>(AFD);
170
+ if (continueWalk)
171
+ Func ();
172
+ return continueWalk;
173
+ }
174
+
175
+ // / Special logic for handling nominal type visitation.
176
+ // /
177
+ // / Apply \p Func if the nominal type can be visited (i.e it has not been
178
+ // / reached via recursive walk).
179
+ template <typename F>
180
+ bool visitNominalTypeDecl (ASTWalker &Walker, NominalTypeDecl *NTD, F Func) {
181
+ bool continueWalk = Walker.Parent .isNull ();
182
+ if (continueWalk)
183
+ Func ();
184
+ return continueWalk;
185
+ }
186
+
160
187
// / An ASTWalker that maps ASTNodes to profiling counters.
161
188
struct MapRegionCounters : public ASTWalker {
162
189
// / The next counter value to assign.
@@ -176,18 +203,13 @@ struct MapRegionCounters : public ASTWalker {
176
203
return false ;
177
204
178
205
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
179
- // Don't map a nested function unless it's a constructor.
180
- bool continueWalk = Parent.isNull () || isa<ConstructorDecl>(AFD);
181
- if (continueWalk)
182
- CounterMap[AFD->getBody ()] = NextCounter++;
183
- return continueWalk;
206
+ return visitFunctionDecl (
207
+ *this , AFD, [&] { CounterMap[AFD->getBody ()] = NextCounter++; });
184
208
} else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
185
209
CounterMap[TLCD->getBody ()] = NextCounter++;
186
- } else if (isa<NominalTypeDecl>(D)) {
187
- bool continueWalk = Parent.isNull ();
188
- if (continueWalk)
189
- WithinNominalType = true ;
190
- return continueWalk;
210
+ } else if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
211
+ return visitNominalTypeDecl (*this , NTD,
212
+ [&] { WithinNominalType = true ; });
191
213
}
192
214
return true ;
193
215
}
@@ -411,17 +433,22 @@ struct PGOMapping : public ASTWalker {
411
433
if (isUnmapped (D))
412
434
return false ;
413
435
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
414
- auto node = AFD->getBody ();
415
- CounterMap[node] = NextCounter++;
416
- auto count = loadExecutionCount (node);
417
- LoadedCounterMap[node] = count;
436
+ return visitFunctionDecl (*this , AFD, [&] {
437
+ auto node = AFD->getBody ();
438
+ CounterMap[node] = NextCounter++;
439
+ auto count = loadExecutionCount (node);
440
+ LoadedCounterMap[node] = count;
441
+ });
418
442
}
419
443
if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
420
444
auto node = TLCD->getBody ();
421
445
CounterMap[node] = NextCounter++;
422
446
auto count = loadExecutionCount (node);
423
447
LoadedCounterMap[node] = count;
424
448
}
449
+ if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
450
+ return visitNominalTypeDecl (*this , NTD, [&] {});
451
+ }
425
452
return true ;
426
453
}
427
454
@@ -768,26 +795,21 @@ struct CoverageMapping : public ASTWalker {
768
795
return false ;
769
796
770
797
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
771
- // Don't map a nested function unless it's a constructor.
772
- bool continueWalk = Parent.isNull () || isa<ConstructorDecl>(AFD);
773
- if (continueWalk) {
798
+ return visitFunctionDecl (*this , AFD, [&] {
774
799
CounterExpr &funcCounter = assignCounter (AFD->getBody ());
775
800
776
801
if (isa<ConstructorDecl>(AFD))
777
802
addToCounter (ParentNominalType, funcCounter);
778
- }
779
- return continueWalk;
803
+ });
780
804
} else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
781
805
assignCounter (TLCD->getBody ());
782
806
ImplicitTopLevelBody = TLCD->getBody ();
783
807
} else if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
784
- bool continueWalk = Parent.isNull ();
785
- if (continueWalk) {
808
+ return visitNominalTypeDecl (*this , NTD, [&] {
786
809
ParentNominalType = NTD;
787
810
assignCounter (NTD, CounterExpr::Zero ());
788
811
pushRegion (NTD);
789
- }
790
- return continueWalk;
812
+ });
791
813
}
792
814
return true ;
793
815
}
0 commit comments