41
41
#include " llvm/IR/CallingConv.h"
42
42
#include " llvm/IR/Constants.h"
43
43
#include " llvm/IR/DataLayout.h"
44
+ #include " llvm/IR/DebugInfo.h"
44
45
#include " llvm/IR/DerivedTypes.h"
45
46
#include " llvm/IR/Dominators.h"
46
47
#include " llvm/IR/Function.h"
@@ -83,6 +84,23 @@ using namespace llvm;
83
84
84
85
namespace {
85
86
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
+
86
104
// / A little helper class for building
87
105
class CoroCloner {
88
106
public:
@@ -119,21 +137,26 @@ class CoroCloner {
119
137
120
138
TargetTransformInfo &TTI;
121
139
140
+ const MetadataSetTy &GlobalDebugInfo;
141
+
122
142
// / Create a cloner for a switch lowering.
123
143
CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
124
- Kind FKind, TargetTransformInfo &TTI)
144
+ Kind FKind, TargetTransformInfo &TTI,
145
+ const MetadataSetTy &GlobalDebugInfo)
125
146
: 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) {
127
149
assert (Shape.ABI == coro::ABI::Switch);
128
150
}
129
151
130
152
// / Create a cloner for a continuation lowering.
131
153
CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
132
154
Function *NewF, AnyCoroSuspendInst *ActiveSuspend,
133
- TargetTransformInfo &TTI)
155
+ TargetTransformInfo &TTI, const MetadataSetTy &GlobalDebugInfo )
134
156
: OrigF(OrigF), NewF(NewF), Suffix(Suffix), Shape(Shape),
135
157
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) {
137
160
assert (Shape.ABI == coro::ABI::Retcon ||
138
161
Shape.ABI == coro::ABI::RetconOnce || Shape.ABI == coro::ABI::Async);
139
162
assert (NewF && " need existing function for continuation" );
@@ -144,10 +167,11 @@ class CoroCloner {
144
167
// / Create a clone for a switch lowering.
145
168
static Function *createClone (Function &OrigF, const Twine &Suffix,
146
169
coro::Shape &Shape, Kind FKind,
147
- TargetTransformInfo &TTI) {
170
+ TargetTransformInfo &TTI,
171
+ const MetadataSetTy &GlobalDebugInfo) {
148
172
TimeTraceScope FunctionScope (" CoroCloner" );
149
173
150
- CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI);
174
+ CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI, GlobalDebugInfo );
151
175
Cloner.create ();
152
176
return Cloner.getFunction ();
153
177
}
@@ -156,10 +180,12 @@ class CoroCloner {
156
180
static Function *createClone (Function &OrigF, const Twine &Suffix,
157
181
coro::Shape &Shape, Function *NewF,
158
182
AnyCoroSuspendInst *ActiveSuspend,
159
- TargetTransformInfo &TTI) {
183
+ TargetTransformInfo &TTI,
184
+ const MetadataSetTy &GlobalDebugInfo) {
160
185
TimeTraceScope FunctionScope (" CoroCloner" );
161
186
162
- CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI);
187
+ CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI,
188
+ GlobalDebugInfo);
163
189
Cloner.create ();
164
190
return Cloner.getFunction ();
165
191
}
@@ -1015,8 +1041,11 @@ void CoroCloner::create() {
1015
1041
auto savedLinkage = NewF->getLinkage ();
1016
1042
NewF->setLinkage (llvm::GlobalValue::ExternalLinkage);
1017
1043
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);
1020
1049
1021
1050
auto &Context = NewF->getContext ();
1022
1051
@@ -1490,16 +1519,22 @@ struct SwitchCoroutineSplitter {
1490
1519
TargetTransformInfo &TTI) {
1491
1520
assert (Shape.ABI == coro::ABI::Switch);
1492
1521
1522
+ MetadataSetTy GlobalDebugInfo;
1523
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1524
+
1493
1525
// Create a resume clone by cloning the body of the original function,
1494
1526
// setting new entry block and replacing coro.suspend an appropriate value
1495
1527
// to force resume or cleanup pass for every suspend point.
1496
1528
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);
1501
1535
auto *CleanupClone = CoroCloner::createClone (
1502
- F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI);
1536
+ F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI,
1537
+ GlobalDebugInfo);
1503
1538
1504
1539
postSplitCleanup (*ResumeClone);
1505
1540
postSplitCleanup (*DestroyClone);
@@ -1884,12 +1919,16 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
1884
1919
}
1885
1920
1886
1921
assert (Clones.size () == Shape.CoroSuspends .size ());
1922
+
1923
+ MetadataSetTy GlobalDebugInfo;
1924
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1925
+
1887
1926
for (size_t Idx = 0 , End = Shape.CoroSuspends .size (); Idx != End; ++Idx) {
1888
1927
auto *Suspend = Shape.CoroSuspends [Idx];
1889
1928
auto *Clone = Clones[Idx];
1890
1929
1891
1930
CoroCloner::createClone (F, " resume." + Twine (Idx), Shape, Clone, Suspend,
1892
- TTI);
1931
+ TTI, GlobalDebugInfo );
1893
1932
}
1894
1933
}
1895
1934
@@ -2014,12 +2053,16 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
2014
2053
}
2015
2054
2016
2055
assert (Clones.size () == Shape.CoroSuspends .size ());
2056
+
2057
+ MetadataSetTy GlobalDebugInfo;
2058
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
2059
+
2017
2060
for (size_t i = 0 , e = Shape.CoroSuspends .size (); i != e; ++i) {
2018
2061
auto Suspend = Shape.CoroSuspends [i];
2019
2062
auto Clone = Clones[i];
2020
2063
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 );
2023
2066
}
2024
2067
}
2025
2068
0 commit comments