diff options
Diffstat (limited to 'llvm/lib/Transforms/Coroutines/CoroEarly.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Coroutines/CoroEarly.cpp | 79 |
1 files changed, 19 insertions, 60 deletions
diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp index 1533e1805f17..dd7cb23f3f3d 100644 --- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp @@ -8,10 +8,10 @@ #include "llvm/Transforms/Coroutines/CoroEarly.h" #include "CoroInternal.h" +#include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Module.h" -#include "llvm/Pass.h" using namespace llvm; @@ -35,7 +35,7 @@ public: AnyResumeFnPtrTy(FunctionType::get(Type::getVoidTy(Context), Int8Ptr, /*isVarArg=*/false) ->getPointerTo()) {} - bool lowerEarlyIntrinsics(Function &F); + void lowerEarlyIntrinsics(Function &F); }; } @@ -145,14 +145,16 @@ static void setCannotDuplicate(CoroIdInst *CoroId) { CB->setCannotDuplicate(); } -bool Lowerer::lowerEarlyIntrinsics(Function &F) { - bool Changed = false; +void Lowerer::lowerEarlyIntrinsics(Function &F) { CoroIdInst *CoroId = nullptr; SmallVector<CoroFreeInst *, 4> CoroFrees; bool HasCoroSuspend = false; for (Instruction &I : llvm::make_early_inc_range(instructions(F))) { - if (auto *CB = dyn_cast<CallBase>(&I)) { - switch (CB->getIntrinsicID()) { + auto *CB = dyn_cast<CallBase>(&I); + if (!CB) + continue; + + switch (CB->getIntrinsicID()) { default: continue; case Intrinsic::coro_free: @@ -178,12 +180,9 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) { case Intrinsic::coro_id: if (auto *CII = cast<CoroIdInst>(&I)) { if (CII->getInfo().isPreSplit()) { - assert(F.hasFnAttribute(CORO_PRESPLIT_ATTR) && - F.getFnAttribute(CORO_PRESPLIT_ATTR).getValueAsString() == - UNPREPARED_FOR_SPLIT && + assert(F.isPresplitCoroutine() && "The frontend uses Swtich-Resumed ABI should emit " - "\"coroutine.presplit\" attribute with value \"0\" for the " - "coroutine."); + "\"coroutine.presplit\" attribute for the coroutine."); setCannotDuplicate(CII); CII->setCoroutineSelf(); CoroId = cast<CoroIdInst>(&I); @@ -193,9 +192,7 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) { case Intrinsic::coro_id_retcon: case Intrinsic::coro_id_retcon_once: case Intrinsic::coro_id_async: - // TODO: Remove the line once we support it in the corresponding - // frontend. - F.addFnAttr(CORO_PRESPLIT_ATTR, PREPARED_FOR_SPLIT); + F.setPresplitCoroutine(); break; case Intrinsic::coro_resume: lowerResumeOrDestroy(*CB, CoroSubFnInst::ResumeIndex); @@ -209,16 +206,16 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) { case Intrinsic::coro_done: lowerCoroDone(cast<IntrinsicInst>(&I)); break; - } - Changed = true; } } + // Make sure that all CoroFree reference the coro.id intrinsic. // Token type is not exposed through coroutine C/C++ builtins to plain C, so // we allow specifying none and fixing it up here. if (CoroId) for (CoroFreeInst *CF : CoroFrees) CF->setArgOperand(0, CoroId); + // Coroutine suspention could potentially lead to any argument modified // outside of the function, hence arguments should not have noalias // attributes. @@ -226,7 +223,6 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) { for (Argument &A : F.args()) if (A.hasNoAliasAttr()) A.removeAttr(Attribute::NoAlias); - return Changed; } static bool declaresCoroEarlyIntrinsics(const Module &M) { @@ -238,52 +234,15 @@ static bool declaresCoroEarlyIntrinsics(const Module &M) { "llvm.coro.suspend"}); } -PreservedAnalyses CoroEarlyPass::run(Function &F, FunctionAnalysisManager &) { - Module &M = *F.getParent(); - if (!declaresCoroEarlyIntrinsics(M) || !Lowerer(M).lowerEarlyIntrinsics(F)) +PreservedAnalyses CoroEarlyPass::run(Module &M, ModuleAnalysisManager &) { + if (!declaresCoroEarlyIntrinsics(M)) return PreservedAnalyses::all(); + Lowerer L(M); + for (auto &F : M) + L.lowerEarlyIntrinsics(F); + PreservedAnalyses PA; PA.preserveSet<CFGAnalyses>(); return PA; } - -namespace { - -struct CoroEarlyLegacy : public FunctionPass { - static char ID; // Pass identification, replacement for typeid. - CoroEarlyLegacy() : FunctionPass(ID) { - initializeCoroEarlyLegacyPass(*PassRegistry::getPassRegistry()); - } - - std::unique_ptr<Lowerer> L; - - // 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 (declaresCoroEarlyIntrinsics(M)) - L = std::make_unique<Lowerer>(M); - return false; - } - - bool runOnFunction(Function &F) override { - if (!L) - return false; - - return L->lowerEarlyIntrinsics(F); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - } - StringRef getPassName() const override { - return "Lower early coroutine intrinsics"; - } -}; -} - -char CoroEarlyLegacy::ID = 0; -INITIALIZE_PASS(CoroEarlyLegacy, "coro-early", - "Lower early coroutine intrinsics", false, false) - -Pass *llvm::createCoroEarlyLegacyPass() { return new CoroEarlyLegacy(); } |
