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"
@@ -81,6 +82,23 @@ using namespace llvm;
8182
8283namespace {
8384
85+ // / Collect (a known) subset of global debug info metadata potentially used by
86+ // / the function \p F.
87+ // /
88+ // / This metadata set can be used to avoid cloning debug info not owned by \p F
89+ // / and is shared among all potential clones \p F.
90+ void collectGlobalDebugInfo (Function &F, MetadataSetTy &GlobalDebugInfo) {
91+ TimeTraceScope FunctionScope (" CollectGlobalDebugInfo" );
92+
93+ DebugInfoFinder DIFinder;
94+ DISubprogram *SPClonedWithinModule = ProcessSubprogramAttachment (
95+ F, CloneFunctionChangeType::LocalChangesOnly, DIFinder);
96+
97+ FindDebugInfoToIdentityMap (GlobalDebugInfo,
98+ CloneFunctionChangeType::LocalChangesOnly,
99+ DIFinder, SPClonedWithinModule);
100+ }
101+
84102// / A little helper class for building
85103class CoroCloner {
86104public:
@@ -117,21 +135,26 @@ class CoroCloner {
117135
118136 TargetTransformInfo &TTI;
119137
138+ const MetadataSetTy &GlobalDebugInfo;
139+
120140 // / Create a cloner for a switch lowering.
121141 CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
122- Kind FKind, TargetTransformInfo &TTI)
142+ Kind FKind, TargetTransformInfo &TTI,
143+ const MetadataSetTy &GlobalDebugInfo)
123144 : OrigF(OrigF), NewF(nullptr ), Suffix(Suffix), Shape(Shape), FKind(FKind),
124- Builder (OrigF.getContext()), TTI(TTI) {
145+ Builder (OrigF.getContext()), TTI(TTI),
146+ GlobalDebugInfo(GlobalDebugInfo) {
125147 assert (Shape.ABI == coro::ABI::Switch);
126148 }
127149
128150 // / Create a cloner for a continuation lowering.
129151 CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
130152 Function *NewF, AnyCoroSuspendInst *ActiveSuspend,
131- TargetTransformInfo &TTI)
153+ TargetTransformInfo &TTI, const MetadataSetTy &GlobalDebugInfo )
132154 : OrigF(OrigF), NewF(NewF), Suffix(Suffix), Shape(Shape),
133155 FKind(Shape.ABI == coro::ABI::Async ? Kind::Async : Kind::Continuation),
134- Builder(OrigF.getContext()), ActiveSuspend(ActiveSuspend), TTI(TTI) {
156+ Builder(OrigF.getContext()), ActiveSuspend(ActiveSuspend), TTI(TTI),
157+ GlobalDebugInfo(GlobalDebugInfo) {
135158 assert (Shape.ABI == coro::ABI::Retcon ||
136159 Shape.ABI == coro::ABI::RetconOnce || Shape.ABI == coro::ABI::Async);
137160 assert (NewF && " need existing function for continuation" );
@@ -142,10 +165,11 @@ class CoroCloner {
142165 // / Create a clone for a switch lowering.
143166 static Function *createClone (Function &OrigF, const Twine &Suffix,
144167 coro::Shape &Shape, Kind FKind,
145- TargetTransformInfo &TTI) {
168+ TargetTransformInfo &TTI,
169+ const MetadataSetTy &GlobalDebugInfo) {
146170 TimeTraceScope FunctionScope (" CoroCloner" );
147171
148- CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI);
172+ CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI, GlobalDebugInfo );
149173 Cloner.create ();
150174 return Cloner.getFunction ();
151175 }
@@ -154,10 +178,12 @@ class CoroCloner {
154178 static Function *createClone (Function &OrigF, const Twine &Suffix,
155179 coro::Shape &Shape, Function *NewF,
156180 AnyCoroSuspendInst *ActiveSuspend,
157- TargetTransformInfo &TTI) {
181+ TargetTransformInfo &TTI,
182+ const MetadataSetTy &GlobalDebugInfo) {
158183 TimeTraceScope FunctionScope (" CoroCloner" );
159184
160- CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI);
185+ CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI,
186+ GlobalDebugInfo);
161187 Cloner.create ();
162188 return Cloner.getFunction ();
163189 }
@@ -1013,8 +1039,11 @@ void CoroCloner::create() {
10131039 auto savedLinkage = NewF->getLinkage ();
10141040 NewF->setLinkage (llvm::GlobalValue::ExternalLinkage);
10151041
1016- CloneFunctionInto (NewF, &OrigF, VMap,
1017- CloneFunctionChangeType::LocalChangesOnly, Returns);
1042+ CloneFunctionAttributesInto (NewF, &OrigF, VMap, false );
1043+ CloneFunctionMetadataInto (NewF, &OrigF, VMap, RF_None, nullptr , nullptr ,
1044+ &GlobalDebugInfo);
1045+ CloneFunctionBodyInto (NewF, &OrigF, VMap, RF_None, Returns, " " , nullptr ,
1046+ nullptr , nullptr , &GlobalDebugInfo);
10181047
10191048 auto &Context = NewF->getContext ();
10201049
@@ -1488,16 +1517,22 @@ struct SwitchCoroutineSplitter {
14881517 TargetTransformInfo &TTI) {
14891518 assert (Shape.ABI == coro::ABI::Switch);
14901519
1520+ MetadataSetTy GlobalDebugInfo;
1521+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1522+
14911523 // Create a resume clone by cloning the body of the original function,
14921524 // setting new entry block and replacing coro.suspend an appropriate value
14931525 // to force resume or cleanup pass for every suspend point.
14941526 createResumeEntryBlock (F, Shape);
1495- auto *ResumeClone = CoroCloner::createClone (
1496- F, " .resume" , Shape, CoroCloner::Kind::SwitchResume, TTI);
1497- auto *DestroyClone = CoroCloner::createClone (
1498- F, " .destroy" , Shape, CoroCloner::Kind::SwitchUnwind, TTI);
1527+ auto *ResumeClone = CoroCloner::createClone (F, " .resume" , Shape,
1528+ CoroCloner::Kind::SwitchResume,
1529+ TTI, GlobalDebugInfo);
1530+ auto *DestroyClone = CoroCloner::createClone (F, " .destroy" , Shape,
1531+ CoroCloner::Kind::SwitchUnwind,
1532+ TTI, GlobalDebugInfo);
14991533 auto *CleanupClone = CoroCloner::createClone (
1500- F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI);
1534+ F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI,
1535+ GlobalDebugInfo);
15011536
15021537 postSplitCleanup (*ResumeClone);
15031538 postSplitCleanup (*DestroyClone);
@@ -1882,12 +1917,16 @@ static void splitAsyncCoroutine(Function &F, coro::Shape &Shape,
18821917 }
18831918
18841919 assert (Clones.size () == Shape.CoroSuspends .size ());
1920+
1921+ MetadataSetTy GlobalDebugInfo;
1922+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1923+
18851924 for (size_t Idx = 0 , End = Shape.CoroSuspends .size (); Idx != End; ++Idx) {
18861925 auto *Suspend = Shape.CoroSuspends [Idx];
18871926 auto *Clone = Clones[Idx];
18881927
18891928 CoroCloner::createClone (F, " resume." + Twine (Idx), Shape, Clone, Suspend,
1890- TTI);
1929+ TTI, GlobalDebugInfo );
18911930 }
18921931}
18931932
@@ -2012,12 +2051,16 @@ static void splitRetconCoroutine(Function &F, coro::Shape &Shape,
20122051 }
20132052
20142053 assert (Clones.size () == Shape.CoroSuspends .size ());
2054+
2055+ MetadataSetTy GlobalDebugInfo;
2056+ collectGlobalDebugInfo (F, GlobalDebugInfo);
2057+
20152058 for (size_t i = 0 , e = Shape.CoroSuspends .size (); i != e; ++i) {
20162059 auto Suspend = Shape.CoroSuspends [i];
20172060 auto Clone = Clones[i];
20182061
2019- CoroCloner::createClone (F, " resume." + Twine (i), Shape, Clone, Suspend,
2020- TTI );
2062+ CoroCloner::createClone (F, " resume." + Twine (i), Shape, Clone, Suspend, TTI,
2063+ GlobalDebugInfo );
20212064 }
20222065}
20232066
0 commit comments