Skip to content

Commit b7c158e

Browse files
committed
Refactor and add comment
1 parent 4249143 commit b7c158e

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

llvm/lib/Transforms/Coroutines/CoroEarly.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Lowerer : public coro::LowererBase {
3030
void lowerCoroPromise(CoroPromiseInst *Intrin);
3131
void lowerCoroDone(IntrinsicInst *II);
3232
void lowerCoroNoop(IntrinsicInst *II);
33+
void hidePromiseAlloca(CoroIdInst *CoroId, CoroBeginInst *CoroBegin);
3334

3435
public:
3536
Lowerer(Module &M)
@@ -153,6 +154,27 @@ void Lowerer::lowerCoroNoop(IntrinsicInst *II) {
153154
II->eraseFromParent();
154155
}
155156

157+
// Later middle-end passes will assume promise alloca dead after coroutine
158+
// suspend, leading to misoptimizations. We hide promise alloca using
159+
// coro.promise and will lower it back to alloca at CoroSplit.
160+
void Lowerer::hidePromiseAlloca(CoroIdInst *CoroId, CoroBeginInst *CoroBegin) {
161+
auto *PA = CoroId->getPromise();
162+
if (!PA || !CoroBegin)
163+
return;
164+
Builder.SetInsertPoint(*CoroBegin->getInsertionPointAfterDef());
165+
166+
auto *Alignment = Builder.getInt32(PA->getAlign().value());
167+
auto *FromPromise = Builder.getInt1(false);
168+
SmallVector<Value *, 3> Arg{CoroBegin, Alignment, FromPromise};
169+
auto *PI = Builder.CreateIntrinsic(
170+
Builder.getPtrTy(), Intrinsic::coro_promise, Arg, {}, "promise.addr");
171+
PA->replaceUsesWithIf(PI, [CoroId](Use &U) {
172+
bool IsBitcast = U == U.getUser()->stripPointerCasts();
173+
bool IsCoroId = U.getUser() == CoroId;
174+
return !IsBitcast && !IsCoroId;
175+
});
176+
}
177+
156178
// Prior to CoroSplit, calls to coro.begin needs to be marked as NoDuplicate,
157179
// as CoroSplit assumes there is exactly one coro.begin. After CoroSplit,
158180
// NoDuplicate attribute will be removed from coro.begin otherwise, it will
@@ -252,22 +274,7 @@ void Lowerer::lowerEarlyIntrinsics(Function &F) {
252274
for (CoroFreeInst *CF : CoroFrees)
253275
CF->setArgOperand(0, CoroId);
254276

255-
auto *PA = CoroId->getPromise();
256-
if (PA && CoroBegin) {
257-
assert(isa<AllocaInst>(PA) && "Must pass alloca to coro.id");
258-
Builder.SetInsertPoint(*CoroBegin->getInsertionPointAfterDef());
259-
260-
auto *Alignment = Builder.getInt32(PA->getAlign().value());
261-
auto *FromPromise = Builder.getInt1(false);
262-
SmallVector<Value *, 3> Arg{CoroBegin, Alignment, FromPromise};
263-
auto *PI = Builder.CreateIntrinsic(
264-
Builder.getPtrTy(), Intrinsic::coro_promise, Arg, {}, "promise.addr");
265-
PA->replaceUsesWithIf(PI, [CoroId](Use &U) {
266-
bool IsBitcast = U == U.getUser()->stripPointerCasts();
267-
bool IsCoroId = U.getUser() == CoroId;
268-
return !IsBitcast && !IsCoroId;
269-
});
270-
}
277+
hidePromiseAlloca(CoroId, CoroBegin);
271278
}
272279

273280
// Coroutine suspention could potentially lead to any argument modified

0 commit comments

Comments
 (0)