4242#include " llvm/IR/CallingConv.h"
4343#include " llvm/IR/Constants.h"
4444#include " llvm/IR/DataLayout.h"
45+ #include " llvm/IR/DebugInfo.h"
4546#include " llvm/IR/DerivedTypes.h"
4647#include " llvm/IR/Dominators.h"
4748#include " llvm/IR/Function.h"
@@ -84,6 +85,23 @@ using namespace llvm;
8485
8586namespace {
8687
88+ // / Collect (a known) subset of global debug info metadata potentially used by
89+ // / the function \p F.
90+ // /
91+ // / This metadata set can be used to avoid cloning debug info not owned by \p F
92+ // / and is shared among all potential clones \p F.
93+ void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo) {
94+ TimeTraceScope FunctionScope (" CollectGlobalDebugInfo" );
95+
96+ DebugInfoFinder DIFinder;
97+ DISubprogram *SPClonedWithinModule = CollectDebugInfoForCloning (
98+ F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
99+
100+ FindDebugInfoToIdentityMap (GlobalDebugInfo,
101+ CloneFunctionChangeType::LocalChangesOnly,
102+ DIFinder, SPClonedWithinModule);
103+ }
104+
87105// / A little helper class for building
88106class CoroCloner {
89107public:
@@ -120,21 +138,26 @@ class CoroCloner {
120138
121139 TargetTransformInfo &TTI;
122140
141+ const MetadataSetTy &GlobalDebugInfo;
142+
123143 // / Create a cloner for a switch lowering.
124144 CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
125- Kind FKind, TargetTransformInfo &TTI)
145+ Kind FKind, TargetTransformInfo &TTI,
146+ const MetadataSetTy &GlobalDebugInfo)
126147 : OrigF(OrigF), NewF(nullptr ), Suffix(Suffix), Shape(Shape), FKind(FKind),
127- Builder (OrigF.getContext()), TTI(TTI) {
148+ Builder (OrigF.getContext()), TTI(TTI),
149+ GlobalDebugInfo(GlobalDebugInfo) {
128150 assert (Shape.ABI == coro::ABI::Switch);
129151 }
130152
131153 // / Create a cloner for a continuation lowering.
132154 CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
133155 Function *NewF, AnyCoroSuspendInst *ActiveSuspend,
134- TargetTransformInfo &TTI)
156+ TargetTransformInfo &TTI, const MetadataSetTy &GlobalDebugInfo )
135157 : OrigF(OrigF), NewF(NewF), Suffix(Suffix), Shape(Shape),
136158 FKind(Shape.ABI == coro::ABI::Async ? Kind::Async : Kind::Continuation),
137- Builder(OrigF.getContext()), ActiveSuspend(ActiveSuspend), TTI(TTI) {
159+ Builder(OrigF.getContext()), ActiveSuspend(ActiveSuspend), TTI(TTI),
160+ GlobalDebugInfo(GlobalDebugInfo) {
138161 assert (Shape.ABI == coro::ABI::Retcon ||
139162 Shape.ABI == coro::ABI::RetconOnce || Shape.ABI == coro::ABI::Async);
140163 assert (NewF && " need existing function for continuation" );
@@ -145,10 +168,11 @@ class CoroCloner {
145168 // / Create a clone for a switch lowering.
146169 static Function *createClone (Function &OrigF, const Twine &Suffix,
147170 coro::Shape &Shape, Kind FKind,
148- TargetTransformInfo &TTI) {
171+ TargetTransformInfo &TTI,
172+ const MetadataSetTy &GlobalDebugInfo) {
149173 TimeTraceScope FunctionScope (" CoroCloner" );
150174
151- CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI);
175+ CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI, GlobalDebugInfo );
152176 Cloner.create ();
153177 return Cloner.getFunction ();
154178 }
@@ -157,10 +181,12 @@ class CoroCloner {
157181 static Function *createClone (Function &OrigF, const Twine &Suffix,
158182 coro::Shape &Shape, Function *NewF,
159183 AnyCoroSuspendInst *ActiveSuspend,
160- TargetTransformInfo &TTI) {
184+ TargetTransformInfo &TTI,
185+ const MetadataSetTy &GlobalDebugInfo) {
161186 TimeTraceScope FunctionScope (" CoroCloner" );
162187
163- CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI);
188+ CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI,
189+ GlobalDebugInfo);
164190 Cloner.create ();
165191 return Cloner.getFunction ();
166192 }
@@ -1016,8 +1042,11 @@ void CoroCloner::create() {
10161042 auto savedLinkage = NewF->getLinkage ();
10171043 NewF->setLinkage (llvm::GlobalValue::ExternalLinkage);
10181044
1019- CloneFunctionInto (NewF, &OrigF, VMap,
1020- CloneFunctionChangeType::LocalChangesOnly, Returns);
1045+ CloneFunctionAttributesInto (NewF, &OrigF, VMap, false );
1046+ CloneFunctionMetadataInto (NewF, &OrigF, VMap, RF_None, nullptr , nullptr ,
1047+ &GlobalDebugInfo);
1048+ CloneFunctionBodyInto (NewF, &OrigF, VMap, RF_None, Returns, " " , nullptr ,
1049+ nullptr , nullptr , &GlobalDebugInfo);
10211050
10221051 auto &Context = NewF->getContext ();
10231052
@@ -1491,16 +1520,22 @@ struct SwitchCoroutineSplitter {
14911520 TargetTransformInfo &TTI) {
14921521 assert (Shape.ABI == coro::ABI::Switch);
14931522
1523+ MetadataSetTy GlobalDebugInfo;
1524+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1525+
14941526 // Create a resume clone by cloning the body of the original function,
14951527 // setting new entry block and replacing coro.suspend an appropriate value
14961528 // to force resume or cleanup pass for every suspend point.
14971529 createResumeEntryBlock (F, Shape);
1498- auto *ResumeClone = CoroCloner::createClone (
1499- F, " .resume" , Shape, CoroCloner::Kind::SwitchResume, TTI);
1500- auto *DestroyClone = CoroCloner::createClone (
1501- F, " .destroy" , Shape, CoroCloner::Kind::SwitchUnwind, TTI);
1530+ auto *ResumeClone = CoroCloner::createClone (F, " .resume" , Shape,
1531+ CoroCloner::Kind::SwitchResume,
1532+ TTI, GlobalDebugInfo);
1533+ auto *DestroyClone = CoroCloner::createClone (F, " .destroy" , Shape,
1534+ CoroCloner::Kind::SwitchUnwind,
1535+ TTI, GlobalDebugInfo);
15021536 auto *CleanupClone = CoroCloner::createClone (
1503- F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI);
1537+ F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI,
1538+ GlobalDebugInfo);
15041539
15051540 postSplitCleanup (*ResumeClone);
15061541 postSplitCleanup (*DestroyClone);
@@ -1885,12 +1920,16 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
18851920 }
18861921
18871922 assert (Clones.size () == Shape.CoroSuspends .size ());
1923+
1924+ MetadataSetTy GlobalDebugInfo;
1925+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1926+
18881927 for (auto CS : llvm::enumerate (Shape.CoroSuspends )) {
18891928 auto *Suspend = CS.value ();
18901929 auto *Clone = Clones[CS.index ()];
18911930
18921931 CoroCloner::createClone (F, " resume." + Twine (CS.index ()), Shape, Clone,
1893- Suspend, TTI);
1932+ Suspend, TTI, GlobalDebugInfo );
18941933 }
18951934}
18961935
@@ -2016,12 +2055,16 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
20162055 }
20172056
20182057 assert (Clones.size () == Shape.CoroSuspends .size ());
2058+
2059+ MetadataSetTy GlobalDebugInfo;
2060+ collectGlobalDebugInfo (F, GlobalDebugInfo);
2061+
20192062 for (auto CS : llvm::enumerate (Shape.CoroSuspends )) {
20202063 auto Suspend = CS.value ();
20212064 auto Clone = Clones[CS.index ()];
20222065
20232066 CoroCloner::createClone (F, " resume." + Twine (CS.index ()), Shape, Clone,
2024- Suspend, TTI);
2067+ Suspend, TTI, GlobalDebugInfo );
20252068 }
20262069}
20272070
0 commit comments