4141#include " llvm/IR/CallingConv.h"
4242#include " llvm/IR/Constants.h"
4343#include " llvm/IR/DataLayout.h"
44+ #include " llvm/IR/DebugInfo.h"
4445#include " llvm/IR/DerivedTypes.h"
4546#include " llvm/IR/Dominators.h"
4647#include " llvm/IR/Function.h"
@@ -83,6 +84,23 @@ using namespace llvm;
8384
8485namespace {
8586
87+ // / Collect (a known) subset of global debug info metadata potentially used by
88+ // / the function \p F.
89+ // /
90+ // / This metadata set can be used to avoid cloning debug info not owned by \p F
91+ // / and is shared among all potential clones \p F.
92+ void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo) {
93+ TimeTraceScope FunctionScope (" CollectGlobalDebugInfo" );
94+
95+ DebugInfoFinder DIFinder;
96+ DISubprogram *SPClonedWithinModule = ProcessSubprogramAttachment (
97+ F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
98+
99+ FindDebugInfoToIdentityMap (GlobalDebugInfo,
100+ CloneFunctionChangeType::LocalChangesOnly,
101+ DIFinder, SPClonedWithinModule);
102+ }
103+
86104// / A little helper class for building
87105class CoroCloner {
88106public:
@@ -119,21 +137,26 @@ class CoroCloner {
119137
120138 TargetTransformInfo &TTI;
121139
140+ const MetadataSetTy &GlobalDebugInfo;
141+
122142 // / Create a cloner for a switch lowering.
123143 CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
124- Kind FKind, TargetTransformInfo &TTI)
144+ Kind FKind, TargetTransformInfo &TTI,
145+ const MetadataSetTy &GlobalDebugInfo)
125146 : OrigF(OrigF), NewF(nullptr ), Suffix(Suffix), Shape(Shape), FKind(FKind),
126- Builder (OrigF.getContext()), TTI(TTI) {
147+ Builder (OrigF.getContext()), TTI(TTI),
148+ GlobalDebugInfo(GlobalDebugInfo) {
127149 assert (Shape.ABI == coro::ABI::Switch);
128150 }
129151
130152 // / Create a cloner for a continuation lowering.
131153 CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
132154 Function *NewF, AnyCoroSuspendInst *ActiveSuspend,
133- TargetTransformInfo &TTI)
155+ TargetTransformInfo &TTI, const MetadataSetTy &GlobalDebugInfo )
134156 : OrigF(OrigF), NewF(NewF), Suffix(Suffix), Shape(Shape),
135157 FKind(Shape.ABI == coro::ABI::Async ? Kind::Async : Kind::Continuation),
136- Builder(OrigF.getContext()), ActiveSuspend(ActiveSuspend), TTI(TTI) {
158+ Builder(OrigF.getContext()), ActiveSuspend(ActiveSuspend), TTI(TTI),
159+ GlobalDebugInfo(GlobalDebugInfo) {
137160 assert (Shape.ABI == coro::ABI::Retcon ||
138161 Shape.ABI == coro::ABI::RetconOnce || Shape.ABI == coro::ABI::Async);
139162 assert (NewF && " need existing function for continuation" );
@@ -144,10 +167,11 @@ class CoroCloner {
144167 // / Create a clone for a switch lowering.
145168 static Function *createClone (Function &OrigF, const Twine &Suffix,
146169 coro::Shape &Shape, Kind FKind,
147- TargetTransformInfo &TTI) {
170+ TargetTransformInfo &TTI,
171+ const MetadataSetTy &GlobalDebugInfo) {
148172 TimeTraceScope FunctionScope (" CoroCloner" );
149173
150- CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI);
174+ CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI, GlobalDebugInfo );
151175 Cloner.create ();
152176 return Cloner.getFunction ();
153177 }
@@ -156,10 +180,12 @@ class CoroCloner {
156180 static Function *createClone (Function &OrigF, const Twine &Suffix,
157181 coro::Shape &Shape, Function *NewF,
158182 AnyCoroSuspendInst *ActiveSuspend,
159- TargetTransformInfo &TTI) {
183+ TargetTransformInfo &TTI,
184+ const MetadataSetTy &GlobalDebugInfo) {
160185 TimeTraceScope FunctionScope (" CoroCloner" );
161186
162- CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI);
187+ CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI,
188+ GlobalDebugInfo);
163189 Cloner.create ();
164190 return Cloner.getFunction ();
165191 }
@@ -1015,8 +1041,11 @@ void CoroCloner::create() {
10151041 auto savedLinkage = NewF->getLinkage ();
10161042 NewF->setLinkage (llvm::GlobalValue::ExternalLinkage);
10171043
1018- CloneFunctionInto (NewF, &OrigF, VMap,
1019- CloneFunctionChangeType::LocalChangesOnly, Returns);
1044+ CloneFunctionAttributesInto (NewF, &OrigF, VMap, false );
1045+ CloneFunctionMetadataInto (NewF, &OrigF, VMap, RF_None, nullptr , nullptr ,
1046+ &GlobalDebugInfo);
1047+ CloneFunctionBodyInto (NewF, &OrigF, VMap, RF_None, Returns, " " , nullptr ,
1048+ nullptr , nullptr , &GlobalDebugInfo);
10201049
10211050 auto &Context = NewF->getContext ();
10221051
@@ -1490,16 +1519,22 @@ struct SwitchCoroutineSplitter {
14901519 TargetTransformInfo &TTI) {
14911520 assert (Shape.ABI == coro::ABI::Switch);
14921521
1522+ MetadataSetTy GlobalDebugInfo;
1523+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1524+
14931525 // Create a resume clone by cloning the body of the original function,
14941526 // setting new entry block and replacing coro.suspend an appropriate value
14951527 // to force resume or cleanup pass for every suspend point.
14961528 createResumeEntryBlock (F, Shape);
1497- auto *ResumeClone = CoroCloner::createClone (
1498- F, " .resume" , Shape, CoroCloner::Kind::SwitchResume, TTI);
1499- auto *DestroyClone = CoroCloner::createClone (
1500- F, " .destroy" , Shape, CoroCloner::Kind::SwitchUnwind, TTI);
1529+ auto *ResumeClone = CoroCloner::createClone (F, " .resume" , Shape,
1530+ CoroCloner::Kind::SwitchResume,
1531+ TTI, GlobalDebugInfo);
1532+ auto *DestroyClone = CoroCloner::createClone (F, " .destroy" , Shape,
1533+ CoroCloner::Kind::SwitchUnwind,
1534+ TTI, GlobalDebugInfo);
15011535 auto *CleanupClone = CoroCloner::createClone (
1502- F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI);
1536+ F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI,
1537+ GlobalDebugInfo);
15031538
15041539 postSplitCleanup (*ResumeClone);
15051540 postSplitCleanup (*DestroyClone);
@@ -1884,12 +1919,16 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
18841919 }
18851920
18861921 assert (Clones.size () == Shape.CoroSuspends .size ());
1922+
1923+ MetadataSetTy GlobalDebugInfo;
1924+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1925+
18871926 for (size_t Idx = 0 , End = Shape.CoroSuspends .size (); Idx != End; ++Idx) {
18881927 auto *Suspend = Shape.CoroSuspends [Idx];
18891928 auto *Clone = Clones[Idx];
18901929
18911930 CoroCloner::createClone (F, " resume." + Twine (Idx), Shape, Clone, Suspend,
1892- TTI);
1931+ TTI, GlobalDebugInfo );
18931932 }
18941933}
18951934
@@ -2014,12 +2053,16 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
20142053 }
20152054
20162055 assert (Clones.size () == Shape.CoroSuspends .size ());
2056+
2057+ MetadataSetTy GlobalDebugInfo;
2058+ collectGlobalDebugInfo (F, GlobalDebugInfo);
2059+
20172060 for (size_t i = 0 , e = Shape.CoroSuspends .size (); i != e; ++i) {
20182061 auto Suspend = Shape.CoroSuspends [i];
20192062 auto Clone = Clones[i];
20202063
2021- CoroCloner::createClone (F, " resume." + Twine (i), Shape, Clone, Suspend,
2022- TTI );
2064+ CoroCloner::createClone (F, " resume." + Twine (i), Shape, Clone, Suspend, TTI,
2065+ GlobalDebugInfo );
20232066 }
20242067}
20252068
0 commit comments