aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Coroutines/CoroEarly.cpp')
-rw-r--r--llvm/lib/Transforms/Coroutines/CoroEarly.cpp67
1 files changed, 33 insertions, 34 deletions
diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
index e73fb9eeb1e9..242e6c3f6b23 100644
--- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -5,13 +5,9 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
-// This pass lowers coroutine intrinsics that hide the details of the exact
-// calling convention for coroutine resume and destroy functions and details of
-// the structure of the coroutine frame.
-//===----------------------------------------------------------------------===//
+#include "llvm/Transforms/Coroutines/CoroEarly.h"
#include "CoroInternal.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Module.h"
@@ -28,7 +24,7 @@ class Lowerer : public coro::LowererBase {
PointerType *const AnyResumeFnPtrTy;
Constant *NoopCoro = nullptr;
- void lowerResumeOrDestroy(CallSite CS, CoroSubFnInst::ResumeKind);
+ void lowerResumeOrDestroy(CallBase &CB, CoroSubFnInst::ResumeKind);
void lowerCoroPromise(CoroPromiseInst *Intrin);
void lowerCoroDone(IntrinsicInst *II);
void lowerCoroNoop(IntrinsicInst *II);
@@ -47,12 +43,11 @@ public:
// an address returned by coro.subfn.addr intrinsic. This is done so that
// CGPassManager recognizes devirtualization when CoroElide pass replaces a call
// to coro.subfn.addr with an appropriate function address.
-void Lowerer::lowerResumeOrDestroy(CallSite CS,
+void Lowerer::lowerResumeOrDestroy(CallBase &CB,
CoroSubFnInst::ResumeKind Index) {
- Value *ResumeAddr =
- makeSubFnCall(CS.getArgOperand(0), Index, CS.getInstruction());
- CS.setCalledFunction(ResumeAddr);
- CS.setCallingConv(CallingConv::Fast);
+ Value *ResumeAddr = makeSubFnCall(CB.getArgOperand(0), Index, &CB);
+ CB.setCalledOperand(ResumeAddr);
+ CB.setCallingConv(CallingConv::Fast);
}
// Coroutine promise field is always at the fixed offset from the beginning of
@@ -64,14 +59,14 @@ void Lowerer::lowerResumeOrDestroy(CallSite CS,
// TODO: Handle the case when coroutine promise alloca has align override.
void Lowerer::lowerCoroPromise(CoroPromiseInst *Intrin) {
Value *Operand = Intrin->getArgOperand(0);
- unsigned Alignement = Intrin->getAlignment();
+ Align Alignment = Intrin->getAlignment();
Type *Int8Ty = Builder.getInt8Ty();
auto *SampleStruct =
StructType::get(Context, {AnyResumeFnPtrTy, AnyResumeFnPtrTy, Int8Ty});
const DataLayout &DL = TheModule.getDataLayout();
int64_t Offset = alignTo(
- DL.getStructLayout(SampleStruct)->getElementOffset(2), Alignement);
+ DL.getStructLayout(SampleStruct)->getElementOffset(2), Alignment);
if (Intrin->isFromPromise())
Offset = -Offset;
@@ -98,7 +93,7 @@ void Lowerer::lowerCoroDone(IntrinsicInst *II) {
Builder.SetInsertPoint(II);
auto *BCI = Builder.CreateBitCast(Operand, FramePtrTy);
- auto *Load = Builder.CreateLoad(BCI);
+ auto *Load = Builder.CreateLoad(FrameTy, BCI);
auto *Cond = Builder.CreateICmpEQ(Load, NullPtr);
II->replaceAllUsesWith(Cond);
@@ -156,8 +151,8 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
SmallVector<CoroFreeInst *, 4> CoroFrees;
for (auto IB = inst_begin(F), IE = inst_end(F); IB != IE;) {
Instruction &I = *IB++;
- if (auto CS = CallSite(&I)) {
- switch (CS.getIntrinsicID()) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ switch (CB->getIntrinsicID()) {
default:
continue;
case Intrinsic::coro_free:
@@ -167,13 +162,13 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
// Make sure that final suspend point is not duplicated as CoroSplit
// pass expects that there is at most one final suspend point.
if (cast<CoroSuspendInst>(&I)->isFinal())
- CS.setCannotDuplicate();
+ CB->setCannotDuplicate();
break;
case Intrinsic::coro_end:
// Make sure that fallthrough coro.end is not duplicated as CoroSplit
// pass expects that there is at most one fallthrough coro.end.
if (cast<CoroEndInst>(&I)->isFallthrough())
- CS.setCannotDuplicate();
+ CB->setCannotDuplicate();
break;
case Intrinsic::coro_noop:
lowerCoroNoop(cast<IntrinsicInst>(&I));
@@ -195,10 +190,10 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
F.addFnAttr(CORO_PRESPLIT_ATTR, PREPARED_FOR_SPLIT);
break;
case Intrinsic::coro_resume:
- lowerResumeOrDestroy(CS, CoroSubFnInst::ResumeIndex);
+ lowerResumeOrDestroy(*CB, CoroSubFnInst::ResumeIndex);
break;
case Intrinsic::coro_destroy:
- lowerResumeOrDestroy(CS, CoroSubFnInst::DestroyIndex);
+ lowerResumeOrDestroy(*CB, CoroSubFnInst::DestroyIndex);
break;
case Intrinsic::coro_promise:
lowerCoroPromise(cast<CoroPromiseInst>(&I));
@@ -219,9 +214,23 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
return Changed;
}
-//===----------------------------------------------------------------------===//
-// Top Level Driver
-//===----------------------------------------------------------------------===//
+static bool declaresCoroEarlyIntrinsics(const Module &M) {
+ return coro::declaresIntrinsics(
+ M, {"llvm.coro.id", "llvm.coro.id.retcon", "llvm.coro.id.retcon.once",
+ "llvm.coro.destroy", "llvm.coro.done", "llvm.coro.end",
+ "llvm.coro.noop", "llvm.coro.free", "llvm.coro.promise",
+ "llvm.coro.resume", "llvm.coro.suspend"});
+}
+
+PreservedAnalyses CoroEarlyPass::run(Function &F, FunctionAnalysisManager &) {
+ Module &M = *F.getParent();
+ if (!declaresCoroEarlyIntrinsics(M) || !Lowerer(M).lowerEarlyIntrinsics(F))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA;
+ PA.preserveSet<CFGAnalyses>();
+ return PA;
+}
namespace {
@@ -236,17 +245,7 @@ struct CoroEarlyLegacy : public FunctionPass {
// This pass has work to do only if we find intrinsics we are going to lower
// in the module.
bool doInitialization(Module &M) override {
- if (coro::declaresIntrinsics(M, {"llvm.coro.id",
- "llvm.coro.id.retcon",
- "llvm.coro.id.retcon.once",
- "llvm.coro.destroy",
- "llvm.coro.done",
- "llvm.coro.end",
- "llvm.coro.noop",
- "llvm.coro.free",
- "llvm.coro.promise",
- "llvm.coro.resume",
- "llvm.coro.suspend"}))
+ if (declaresCoroEarlyIntrinsics(M))
L = std::make_unique<Lowerer>(M);
return false;
}