diff options
Diffstat (limited to 'llvm/lib/Transforms/Coroutines/CoroEarly.cpp')
-rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroEarly.cpp | 67 |
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; } |