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"
@@ -84,6 +85,23 @@ using namespace llvm;
84
85
85
86
namespace {
86
87
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
+
87
105
// / A little helper class for building
88
106
class CoroCloner {
89
107
public:
@@ -120,21 +138,26 @@ class CoroCloner {
120
138
121
139
TargetTransformInfo &TTI;
122
140
141
+ const MetadataSetTy &GlobalDebugInfo;
142
+
123
143
// / Create a cloner for a switch lowering.
124
144
CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
125
- Kind FKind, TargetTransformInfo &TTI)
145
+ Kind FKind, TargetTransformInfo &TTI,
146
+ const MetadataSetTy &GlobalDebugInfo)
126
147
: 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) {
128
150
assert (Shape.ABI == coro::ABI::Switch);
129
151
}
130
152
131
153
// / Create a cloner for a continuation lowering.
132
154
CoroCloner (Function &OrigF, const Twine &Suffix, coro::Shape &Shape,
133
155
Function *NewF, AnyCoroSuspendInst *ActiveSuspend,
134
- TargetTransformInfo &TTI)
156
+ TargetTransformInfo &TTI, const MetadataSetTy &GlobalDebugInfo )
135
157
: OrigF(OrigF), NewF(NewF), Suffix(Suffix), Shape(Shape),
136
158
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) {
138
161
assert (Shape.ABI == coro::ABI::Retcon ||
139
162
Shape.ABI == coro::ABI::RetconOnce || Shape.ABI == coro::ABI::Async);
140
163
assert (NewF && " need existing function for continuation" );
@@ -145,10 +168,11 @@ class CoroCloner {
145
168
// / Create a clone for a switch lowering.
146
169
static Function *createClone (Function &OrigF, const Twine &Suffix,
147
170
coro::Shape &Shape, Kind FKind,
148
- TargetTransformInfo &TTI) {
171
+ TargetTransformInfo &TTI,
172
+ const MetadataSetTy &GlobalDebugInfo) {
149
173
TimeTraceScope FunctionScope (" CoroCloner" );
150
174
151
- CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI);
175
+ CoroCloner Cloner (OrigF, Suffix, Shape, FKind, TTI, GlobalDebugInfo );
152
176
Cloner.create ();
153
177
return Cloner.getFunction ();
154
178
}
@@ -157,10 +181,12 @@ class CoroCloner {
157
181
static Function *createClone (Function &OrigF, const Twine &Suffix,
158
182
coro::Shape &Shape, Function *NewF,
159
183
AnyCoroSuspendInst *ActiveSuspend,
160
- TargetTransformInfo &TTI) {
184
+ TargetTransformInfo &TTI,
185
+ const MetadataSetTy &GlobalDebugInfo) {
161
186
TimeTraceScope FunctionScope (" CoroCloner" );
162
187
163
- CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI);
188
+ CoroCloner Cloner (OrigF, Suffix, Shape, NewF, ActiveSuspend, TTI,
189
+ GlobalDebugInfo);
164
190
Cloner.create ();
165
191
return Cloner.getFunction ();
166
192
}
@@ -1016,8 +1042,11 @@ void CoroCloner::create() {
1016
1042
auto savedLinkage = NewF->getLinkage ();
1017
1043
NewF->setLinkage (llvm::GlobalValue::ExternalLinkage);
1018
1044
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);
1021
1050
1022
1051
auto &Context = NewF->getContext ();
1023
1052
@@ -1491,16 +1520,22 @@ struct SwitchCoroutineSplitter {
1491
1520
TargetTransformInfo &TTI) {
1492
1521
assert (Shape.ABI == coro::ABI::Switch);
1493
1522
1523
+ MetadataSetTy GlobalDebugInfo;
1524
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1525
+
1494
1526
// Create a resume clone by cloning the body of the original function,
1495
1527
// setting new entry block and replacing coro.suspend an appropriate value
1496
1528
// to force resume or cleanup pass for every suspend point.
1497
1529
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);
1502
1536
auto *CleanupClone = CoroCloner::createClone (
1503
- F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI);
1537
+ F, " .cleanup" , Shape, CoroCloner::Kind::SwitchCleanup, TTI,
1538
+ GlobalDebugInfo);
1504
1539
1505
1540
postSplitCleanup (*ResumeClone);
1506
1541
postSplitCleanup (*DestroyClone);
@@ -1885,12 +1920,16 @@ void coro::AsyncABI::splitCoroutine(Function &F, coro::Shape &Shape,
1885
1920
}
1886
1921
1887
1922
assert (Clones.size () == Shape.CoroSuspends .size ());
1923
+
1924
+ MetadataSetTy GlobalDebugInfo;
1925
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
1926
+
1888
1927
for (auto CS : llvm::enumerate (Shape.CoroSuspends )) {
1889
1928
auto *Suspend = CS.value ();
1890
1929
auto *Clone = Clones[CS.index ()];
1891
1930
1892
1931
CoroCloner::createClone (F, " resume." + Twine (CS.index ()), Shape, Clone,
1893
- Suspend, TTI);
1932
+ Suspend, TTI, GlobalDebugInfo );
1894
1933
}
1895
1934
}
1896
1935
@@ -2016,12 +2055,16 @@ void coro::AnyRetconABI::splitCoroutine(Function &F, coro::Shape &Shape,
2016
2055
}
2017
2056
2018
2057
assert (Clones.size () == Shape.CoroSuspends .size ());
2058
+
2059
+ MetadataSetTy GlobalDebugInfo;
2060
+ collectGlobalDebugInfo (F, GlobalDebugInfo);
2061
+
2019
2062
for (auto CS : llvm::enumerate (Shape.CoroSuspends )) {
2020
2063
auto Suspend = CS.value ();
2021
2064
auto Clone = Clones[CS.index ()];
2022
2065
2023
2066
CoroCloner::createClone (F, " resume." + Twine (CS.index ()), Shape, Clone,
2024
- Suspend, TTI);
2067
+ Suspend, TTI, GlobalDebugInfo );
2025
2068
}
2026
2069
}
2027
2070
0 commit comments