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.cpp79
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(); }