42
42
#include " llvm/IR/CallingConv.h"
43
43
#include " llvm/IR/Constants.h"
44
44
#include " llvm/IR/DataLayout.h"
45
+ #include " llvm/IR/DebugInfo.h"
45
46
#include " llvm/IR/DerivedTypes.h"
46
47
#include " llvm/IR/Dominators.h"
47
48
#include " llvm/IR/Function.h"
@@ -81,6 +82,23 @@ using namespace llvm;
81
82
82
83
namespace {
83
84
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
+
84
102
// / A little helper class for building
85
103
class CoroCloner {
86
104
public:
@@ -117,21 +135,26 @@ class CoroCloner {
117
135
118
136
TargetTransformInfo &TTI;
119
137
138
+ const MetadataSetTy &GlobalDebugInfo;
139
+
120
140
// / Create a cloner for a switch lowering.
121
141
CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
122
- Kind FKind, TargetTransformInfo &TTI)
142
+ Kind FKind, TargetTransformInfo &TTI,
143
+ const MetadataSetTy &GlobalDebugInfo)
123
144
: 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) {
125
147
assert (Shape.ABI == coro::ABI::Switch);
126
148
}
127
149
128
150
// / Create a cloner for a continuation lowering.
129
151
CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
130
152
Function *NewF, AnyCoroSuspendInst *ActiveSuspend,
131
- TargetTransformInfo &TTI)
153
+ TargetTransformInfo &TTI, const MetadataSetTy &GlobalDebugInfo )
132
154
: OrigF(OrigF), NewF(NewF), Suffix(Suffix), Shape(Shape),
133
155
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) {
135
158
assert (Shape.ABI == coro::ABI::Retcon ||
136
159
Shape.ABI == coro::ABI::RetconOnce || Shape.ABI == coro::ABI::Async);
137
160
assert (NewF && " need existing function for continuation" );
@@ -142,10 +165,11 @@ class CoroCloner {
142
165
// / Create a clone for a switch lowering.
143
166
static Function *createClone (Function &OrigF, const Twine &Suffix,
144
167
coro::Shape &Shape, Kind FKind,
145
- TargetTransformInfo &TTI) {
168
+ TargetTransformInfo &TTI,
169
+ const MetadataSetTy &GlobalDebugInfo) {
146
170
TimeTraceScope FunctionScope (" CoroCloner" );
147
171
148
- CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI);
172
+ CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI, GlobalDebugInfo );
149
173
Cloner.create ();
150
174
return Cloner.getFunction ();
151
175
}
@@ -154,10 +178,12 @@ class CoroCloner {
154
178
static Function *createClone (Function &OrigF, const Twine &Suffix,
155
179
coro::Shape &Shape, Function *NewF,
156
180
AnyCoroSuspendInst *ActiveSuspend,
157
- TargetTransformInfo &TTI) {
181
+ TargetTransformInfo &TTI,
182
+ const MetadataSetTy &GlobalDebugInfo) {
158
183
TimeTraceScope FunctionScope (" CoroCloner" );
159
184
160
- CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI);
185
+ CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI,
186
+ GlobalDebugInfo);
161
187
Cloner.create ();
162
188
return Cloner.getFunction ();
163
189
}
@@ -1013,8 +1039,11 @@ void CoroCloner::create() {
1013
1039
auto savedLinkage = NewF->getLinkage ();
1014
1040
NewF->setLinkage (llvm::GlobalValue::ExternalLinkage);
1015
1041
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);
1018
1047
1019
1048
auto &Context = NewF->getContext ();
1020
1049
@@ -1488,16 +1517,22 @@ struct SwitchCoroutineSplitter {
1488
1517
TargetTransformInfo &TTI) {
1489
1518
assert (Shape.ABI == coro::ABI::Switch);
1490
1519
1520
+ MetadataSetTy GlobalDebugInfo;
1521
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1522
+
1491
1523
// Create a resume clone by cloning the body of the original function,
1492
1524
// setting new entry block and replacing coro.suspend an appropriate value
1493
1525
// to force resume or cleanup pass for every suspend point.
1494
1526
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);
1499
1533
auto *CleanupClone = CoroCloner::createClone (
1500
- F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI);
1534
+ F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI,
1535
+ GlobalDebugInfo);
1501
1536
1502
1537
postSplitCleanup (*ResumeClone);
1503
1538
postSplitCleanup (*DestroyClone);
@@ -1882,12 +1917,16 @@ static void splitAsyncCoroutine(Function &F, coro::Shape &Shape,
1882
1917
}
1883
1918
1884
1919
assert (Clones.size () == Shape.CoroSuspends .size ());
1920
+
1921
+ MetadataSetTy GlobalDebugInfo;
1922
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1923
+
1885
1924
for (size_t Idx = 0 , End = Shape.CoroSuspends .size (); Idx != End; ++Idx) {
1886
1925
auto *Suspend = Shape.CoroSuspends [Idx];
1887
1926
auto *Clone = Clones[Idx];
1888
1927
1889
1928
CoroCloner::createClone (F, " resume." + Twine (Idx), Shape, Clone, Suspend,
1890
- TTI);
1929
+ TTI, GlobalDebugInfo );
1891
1930
}
1892
1931
}
1893
1932
@@ -2012,12 +2051,16 @@ static void splitRetconCoroutine(Function &F, coro::Shape &Shape,
2012
2051
}
2013
2052
2014
2053
assert (Clones.size () == Shape.CoroSuspends .size ());
2054
+
2055
+ MetadataSetTy GlobalDebugInfo;
2056
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
2057
+
2015
2058
for (size_t i = 0 , e = Shape.CoroSuspends .size (); i != e; ++i) {
2016
2059
auto Suspend = Shape.CoroSuspends [i];
2017
2060
auto Clone = Clones[i];
2018
2061
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 );
2021
2064
}
2022
2065
}
2023
2066
0 commit comments