Skip to content

Commit 1fb2206

Browse files
committed
Improve lowering
1 parent f713b05 commit 1fb2206

File tree

3 files changed

+49
-65
lines changed

3 files changed

+49
-65
lines changed

llvm/lib/Transforms/Coroutines/CoroInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct LLVM_LIBRARY_VISIBILITY Shape {
8383
SmallVector<CoroAlignInst *, 2> CoroAligns;
8484
SmallVector<AnyCoroSuspendInst *, 4> CoroSuspends;
8585
SmallVector<CallInst*, 2> SwiftErrorOps;
86+
SmallVector<CoroAwaitSuspendInst *, 4> CoroAwaitSuspends;
8687

8788
// Field indexes for special fields in the switch lowering.
8889
struct SwitchFieldIndex {

llvm/lib/Transforms/Coroutines/CoroSplit.cpp

Lines changed: 42 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -79,68 +79,6 @@ using namespace llvm;
7979

8080
namespace {
8181

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-
14482
/// A little helper class for building
14583
class CoroCloner {
14684
public:
@@ -229,6 +167,45 @@ class CoroCloner {
229167

230168
} // end anonymous namespace
231169

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+
232209
static void maybeFreeRetconStorage(IRBuilder<> &Builder,
233210
const coro::Shape &Shape, Value *FramePtr,
234211
CallGraph *CG) {
@@ -1595,8 +1572,9 @@ struct SwitchCoroutineSplitter {
15951572

15961573
createResumeEntryBlock(F, Shape);
15971574

1598-
Lowerer lowerer(M);
1599-
lowerer.lowerAwaitSuspends(F);
1575+
IRBuilder<> Builder(M.getContext());
1576+
for (auto *AWS : Shape.CoroAwaitSuspends)
1577+
lowerAwaitSuspend(Builder, AWS);
16001578

16011579
auto *ResumeClone =
16021580
createClone(F, ".resume", Shape, CoroCloner::Kind::SwitchResume);

llvm/lib/Transforms/Coroutines/Coroutines.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ static const char *const CoroIntrinsics[] = {
6767
"llvm.coro.async.resume",
6868
"llvm.coro.async.size.replace",
6969
"llvm.coro.async.store_resume",
70-
"llvm.coro.await.suspend.void",
7170
"llvm.coro.await.suspend.bool",
7271
"llvm.coro.await.suspend.handle",
72+
"llvm.coro.await.suspend.void",
7373
"llvm.coro.begin",
7474
"llvm.coro.destroy",
7575
"llvm.coro.done",
@@ -258,6 +258,11 @@ void coro::Shape::buildFrom(Function &F) {
258258
}
259259
}
260260
break;
261+
case Intrinsic::coro_await_suspend_void:
262+
case Intrinsic::coro_await_suspend_bool:
263+
case Intrinsic::coro_await_suspend_handle:
264+
CoroAwaitSuspends.push_back(cast<CoroAwaitSuspendInst>(II));
265+
break;
261266
}
262267
}
263268
}

0 commit comments

Comments
 (0)