@@ -37,15 +37,17 @@ static bool isUnmappedDecl(Decl *D) {
37
37
}
38
38
39
39
// / Walk the non-static initializers in \p PBD.
40
- static void walkForProfiling (PatternBindingDecl *PBD, ASTWalker &Walker) {
40
+ static void walkPatternForProfiling (PatternBindingDecl *PBD,
41
+ ASTWalker &Walker) {
41
42
if (PBD && !PBD->isStatic ())
42
43
for (auto E : PBD->getPatternList ())
43
44
if (E.getInit ())
44
45
E.getInit ()->walk (Walker);
45
46
}
46
47
47
48
// / Walk the AST of \c Root and related nodes that are relevant for profiling.
48
- static void walkForProfiling (AbstractFunctionDecl *Root, ASTWalker &Walker) {
49
+ static void walkFunctionForProfiling (AbstractFunctionDecl *Root,
50
+ ASTWalker &Walker) {
49
51
Root->walk (Walker);
50
52
51
53
// We treat class initializers as part of the constructor for profiling.
@@ -55,13 +57,27 @@ static void walkForProfiling(AbstractFunctionDecl *Root, ASTWalker &Walker) {
55
57
for (auto *Member : NominalType->getMembers ()) {
56
58
// Find pattern binding declarations that have initializers.
57
59
if (auto *PBD = dyn_cast<PatternBindingDecl>(Member))
58
- walkForProfiling (PBD, Walker);
60
+ walkPatternForProfiling (PBD, Walker);
59
61
}
60
62
}
61
63
}
62
64
63
- ProfilerRAII::ProfilerRAII (SILGenModule &SGM, AbstractFunctionDecl *D)
65
+ // / Walk \p D for profiling.
66
+ static void walkForProfiling (Decl *D, ASTWalker &Walker) {
67
+ if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
68
+ walkFunctionForProfiling (AFD, Walker);
69
+ else if (auto *PBD = dyn_cast<PatternBindingDecl>(D))
70
+ walkPatternForProfiling (PBD, Walker);
71
+ else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
72
+ TLCD->walk (Walker);
73
+ else
74
+ llvm_unreachable (" Don't know how to walk decl for profiling" );
75
+ }
76
+
77
+ ProfilerRAII::ProfilerRAII (SILGenModule &SGM, Decl *D)
64
78
: SGM(SGM), PreviousProfiler(std::move(SGM.Profiler)) {
79
+ assert (isa<AbstractFunctionDecl>(D) ||
80
+ isa<TopLevelCodeDecl>(D) && " Cannot create profiler for this decl" );
65
81
const auto &Opts = SGM.M .getOptions ();
66
82
if (!Opts.GenerateProfile || isUnmappedDecl (D))
67
83
return ;
@@ -90,6 +106,8 @@ struct MapRegionCounters : public ASTWalker {
90
106
return false ;
91
107
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
92
108
CounterMap[AFD->getBody ()] = NextCounter++;
109
+ if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
110
+ CounterMap[TLCD->getBody ()] = NextCounter++;
93
111
return true ;
94
112
}
95
113
@@ -106,7 +124,7 @@ struct MapRegionCounters : public ASTWalker {
106
124
CounterMap[FS->getBody ()] = NextCounter++;
107
125
} else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
108
126
CounterMap[FES->getBody ()] = NextCounter++;
109
- walkForProfiling (FES->getIterator (), *this );
127
+ walkPatternForProfiling (FES->getIterator (), *this );
110
128
} else if (auto *SS = dyn_cast<SwitchStmt>(S)) {
111
129
CounterMap[SS] = NextCounter++;
112
130
} else if (auto *CS = dyn_cast<CaseStmt>(S)) {
@@ -475,6 +493,8 @@ struct CoverageMapping : public ASTWalker {
475
493
return false ;
476
494
if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
477
495
assignCounter (AFD->getBody ());
496
+ else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
497
+ assignCounter (TLCD->getBody ());
478
498
return true ;
479
499
}
480
500
@@ -522,7 +542,7 @@ struct CoverageMapping : public ASTWalker {
522
542
} else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
523
543
assignCounter (FES, CounterExpr::Zero ());
524
544
assignCounter (FES->getBody ());
525
- walkForProfiling (FES->getIterator (), *this );
545
+ walkPatternForProfiling (FES->getIterator (), *this );
526
546
527
547
} else if (auto *SS = dyn_cast<SwitchStmt>(S)) {
528
548
assignCounter (SS);
@@ -672,22 +692,32 @@ getEquivalentPGOLinkage(FormalLinkage Linkage) {
672
692
}
673
693
}
674
694
675
- void SILGenProfiling::assignRegionCounters (AbstractFunctionDecl *Root) {
676
- CurrentFuncName = SILDeclRef (Root).mangle ();
677
- CurrentFuncLinkage = getDeclLinkage (Root);
695
+ void SILGenProfiling::assignRegionCounters (Decl *Root) {
696
+ const auto &SM = SGM.M .getASTContext ().SourceMgr ;
678
697
679
- if (auto *ParentFile = Root->getParentSourceFile ())
698
+ if (auto *ParentFile = cast<DeclContext>( Root) ->getParentSourceFile ())
680
699
CurrentFileName = ParentFile->getFilename ();
681
700
682
701
MapRegionCounters Mapper (RegionCounterMap);
702
+
703
+ if (auto *AFD = dyn_cast<AbstractFunctionDecl>(Root)) {
704
+ CurrentFuncName = SILDeclRef (AFD).mangle ();
705
+ CurrentFuncLinkage = getDeclLinkage (AFD);
706
+ } else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(Root)) {
707
+ llvm::raw_string_ostream OS{CurrentFuncName};
708
+ OS << " __tlcd_" ;
709
+ TLCD->getStartLoc ().printLineAndColumn (OS, SM);
710
+ CurrentFuncLinkage = FormalLinkage::HiddenUnique;
711
+ }
712
+
683
713
walkForProfiling (Root, Mapper);
684
714
685
715
NumRegionCounters = Mapper.NextCounter ;
686
716
// TODO: Mapper needs to calculate a function hash as it goes.
687
717
FunctionHash = 0x0 ;
688
718
689
719
if (EmitCoverageMapping) {
690
- CoverageMapping Coverage (SGM. M . getASTContext (). SourceMgr );
720
+ CoverageMapping Coverage (SM );
691
721
walkForProfiling (Root, Coverage);
692
722
Coverage.emitSourceRegions (SGM.M , CurrentFuncName,
693
723
!llvm::GlobalValue::isLocalLinkage (
0 commit comments