@@ -79,68 +79,6 @@ using namespace llvm;
79
79
80
80
namespace {
81
81
82
- // Created on demand if the coro-early pass has work to do.
83
- class Lowerer : public coro ::LowererBase {
84
- IRBuilder<> Builder;
85
- void lowerAwaitSuspend (CoroAwaitSuspendInst *CB);
86
-
87
- public:
88
- Lowerer (Module &M) : LowererBase(M), Builder(Context) {}
89
-
90
- void lowerAwaitSuspends (Function &F);
91
- };
92
-
93
- void Lowerer::lowerAwaitSuspend (CoroAwaitSuspendInst *CB) {
94
- auto Helper = CB->getHelperFunction ();
95
- auto Awaiter = CB->getAwaiter ();
96
- auto FramePtr = CB->getFrame ();
97
-
98
- Builder.SetInsertPoint (CB);
99
-
100
- CallBase *NewCall = nullptr ;
101
- if (auto Invoke = dyn_cast<InvokeInst>(CB)) {
102
- auto HelperInvoke =
103
- Builder.CreateInvoke (Helper, Invoke->getNormalDest (),
104
- Invoke->getUnwindDest (), {Awaiter, FramePtr});
105
-
106
- HelperInvoke->setCallingConv (Invoke->getCallingConv ());
107
- std::copy (Invoke->bundle_op_info_begin (), Invoke->bundle_op_info_end (),
108
- HelperInvoke->bundle_op_info_begin ());
109
- AttributeList NewAttributes =
110
- Invoke->getAttributes ().removeParamAttributes (Context, 2 );
111
- HelperInvoke->setAttributes (NewAttributes);
112
- HelperInvoke->setDebugLoc (Invoke->getDebugLoc ());
113
- NewCall = HelperInvoke;
114
- } else if (auto Call = dyn_cast<CallInst>(CB)) {
115
- auto HelperCall = Builder.CreateCall (Helper, {Awaiter, FramePtr});
116
-
117
- AttributeList NewAttributes =
118
- Call->getAttributes ().removeParamAttributes (Context, 2 );
119
- HelperCall->setAttributes (NewAttributes);
120
- HelperCall->setDebugLoc (Call->getDebugLoc ());
121
- NewCall = HelperCall;
122
- }
123
-
124
- CB->replaceAllUsesWith (NewCall);
125
- CB->eraseFromParent ();
126
- }
127
-
128
- void Lowerer::lowerAwaitSuspends (Function &F) {
129
- SmallVector<CoroAwaitSuspendInst *, 4 > AwaitSuspends;
130
-
131
- for (Instruction &I : llvm::make_early_inc_range (instructions (F))) {
132
- auto *CB = dyn_cast<CallBase>(&I);
133
- if (!CB)
134
- continue ;
135
-
136
- if (auto *AWS = dyn_cast<CoroAwaitSuspendInst>(CB))
137
- AwaitSuspends.push_back (AWS);
138
- }
139
-
140
- for (auto *AWS : AwaitSuspends)
141
- lowerAwaitSuspend (AWS);
142
- }
143
-
144
82
// / A little helper class for building
145
83
class CoroCloner {
146
84
public:
@@ -229,6 +167,45 @@ class CoroCloner {
229
167
230
168
} // end anonymous namespace
231
169
170
+ // FIXME:
171
+ // Lower the intrinisc earlier if coroutine frame doesn't escape
172
+ static void lowerAwaitSuspend (IRBuilder<> &Builder, CoroAwaitSuspendInst *CB) {
173
+ auto Helper = CB->getHelperFunction ();
174
+ auto Awaiter = CB->getAwaiter ();
175
+ auto FramePtr = CB->getFrame ();
176
+
177
+ Builder.SetInsertPoint (CB);
178
+
179
+ CallBase *NewCall = nullptr ;
180
+ if (auto Invoke = dyn_cast<InvokeInst>(CB)) {
181
+ auto HelperInvoke =
182
+ Builder.CreateInvoke (Helper, Invoke->getNormalDest (),
183
+ Invoke->getUnwindDest (), {Awaiter, FramePtr});
184
+
185
+ HelperInvoke->setCallingConv (Invoke->getCallingConv ());
186
+ std::copy (Invoke->bundle_op_info_begin (), Invoke->bundle_op_info_end (),
187
+ HelperInvoke->bundle_op_info_begin ());
188
+ AttributeList NewAttributes =
189
+ Invoke->getAttributes ().removeParamAttributes (Invoke->getContext (), 2 );
190
+ HelperInvoke->setAttributes (NewAttributes);
191
+ HelperInvoke->setDebugLoc (Invoke->getDebugLoc ());
192
+ NewCall = HelperInvoke;
193
+ } else if (auto Call = dyn_cast<CallInst>(CB)) {
194
+ auto HelperCall = Builder.CreateCall (Helper, {Awaiter, FramePtr});
195
+
196
+ AttributeList NewAttributes =
197
+ Call->getAttributes ().removeParamAttributes (Call->getContext (), 2 );
198
+ HelperCall->setAttributes (NewAttributes);
199
+ HelperCall->setDebugLoc (Call->getDebugLoc ());
200
+ NewCall = HelperCall;
201
+ } else {
202
+ llvm_unreachable (" Unexpected coro_await_suspend invocation method" );
203
+ }
204
+
205
+ CB->replaceAllUsesWith (NewCall);
206
+ CB->eraseFromParent ();
207
+ }
208
+
232
209
static void maybeFreeRetconStorage (IRBuilder<> &Builder,
233
210
const coro::Shape &Shape, Value *FramePtr,
234
211
CallGraph *CG) {
@@ -1595,8 +1572,9 @@ struct SwitchCoroutineSplitter {
1595
1572
1596
1573
createResumeEntryBlock (F, Shape);
1597
1574
1598
- Lowerer lowerer (M);
1599
- lowerer.lowerAwaitSuspends (F);
1575
+ IRBuilder<> Builder (M.getContext ());
1576
+ for (auto *AWS : Shape.CoroAwaitSuspends )
1577
+ lowerAwaitSuspend (Builder, AWS);
1600
1578
1601
1579
auto *ResumeClone =
1602
1580
createClone (F, " .resume" , Shape, CoroCloner::Kind::SwitchResume);
0 commit comments