mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-26 22:45:05 +00:00
[Coroutines] Part 15a: Lower coro.subfn.addr in CoroCleanup
Summary: Not all coro.subfn.addr intrinsics can be eliminated in CoroElide through devirtualization. Those that remain need to be lowered in CoroCleanup. Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D24412 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282897 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
baccf617c8
commit
a7eae488f2
@ -10,6 +10,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CoroInternal.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/InstIterator.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Pass.h"
|
||||
@ -22,7 +23,8 @@ using namespace llvm;
|
||||
namespace {
|
||||
// Created on demand if CoroCleanup pass has work to do.
|
||||
struct Lowerer : coro::LowererBase {
|
||||
Lowerer(Module &M) : LowererBase(M) {}
|
||||
IRBuilder<> Builder;
|
||||
Lowerer(Module &M) : LowererBase(M), Builder(Context) {}
|
||||
bool lowerRemainingCoroIntrinsics(Function &F);
|
||||
};
|
||||
}
|
||||
@ -36,6 +38,23 @@ static void simplifyCFG(Function &F) {
|
||||
FPM.doFinalization();
|
||||
}
|
||||
|
||||
static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn) {
|
||||
Builder.SetInsertPoint(SubFn);
|
||||
Value *FrameRaw = SubFn->getFrame();
|
||||
int Index = SubFn->getIndex();
|
||||
|
||||
auto *FrameTy = StructType::get(
|
||||
SubFn->getContext(), {Builder.getInt8PtrTy(), Builder.getInt8PtrTy()});
|
||||
PointerType *FramePtrTy = FrameTy->getPointerTo();
|
||||
|
||||
Builder.SetInsertPoint(SubFn);
|
||||
auto *FramePtr = Builder.CreateBitCast(FrameRaw, FramePtrTy);
|
||||
auto *Gep = Builder.CreateConstInBoundsGEP2_32(FrameTy, FramePtr, 0, Index);
|
||||
auto *Load = Builder.CreateLoad(Gep);
|
||||
|
||||
SubFn->replaceAllUsesWith(Load);
|
||||
}
|
||||
|
||||
bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) {
|
||||
bool Changed = false;
|
||||
|
||||
@ -57,6 +76,9 @@ bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) {
|
||||
case Intrinsic::coro_id:
|
||||
II->replaceAllUsesWith(ConstantTokenNone::get(Context));
|
||||
break;
|
||||
case Intrinsic::coro_subfn_addr:
|
||||
lowerSubFn(Builder, cast<CoroSubFnInst>(II));
|
||||
break;
|
||||
}
|
||||
II->eraseFromParent();
|
||||
Changed = true;
|
||||
@ -87,7 +109,8 @@ struct CoroCleanup : FunctionPass {
|
||||
// in the module.
|
||||
bool doInitialization(Module &M) override {
|
||||
if (coro::declaresIntrinsics(M, {"llvm.coro.alloc", "llvm.coro.begin",
|
||||
"llvm.coro.free", "llvm.coro.id"}))
|
||||
"llvm.coro.subfn.addr", "llvm.coro.free",
|
||||
"llvm.coro.id"}))
|
||||
L = llvm::make_unique<Lowerer>(M);
|
||||
return false;
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ static bool isCoroutineIntrinsicName(StringRef Name) {
|
||||
"llvm.coro.done", "llvm.coro.end", "llvm.coro.frame",
|
||||
"llvm.coro.free", "llvm.coro.id", "llvm.coro.param",
|
||||
"llvm.coro.promise", "llvm.coro.resume", "llvm.coro.save",
|
||||
"llvm.coro.size", "llvm.coro.suspend",
|
||||
"llvm.coro.size", "llvm.coro.subfn.addr", "llvm.coro.suspend",
|
||||
};
|
||||
return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
|
||||
}
|
||||
|
18
test/Transforms/Coroutines/coro-cleanup.ll
Normal file
18
test/Transforms/Coroutines/coro-cleanup.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; Make sure that all library helper coro intrinsics are lowered.
|
||||
; RUN: opt < %s -O0 -enable-coroutines -S | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: @uses_library_support_coro_intrinsics(
|
||||
; CHECK-NOT: @llvm.coro
|
||||
; CHECK: ret void
|
||||
define void @uses_library_support_coro_intrinsics(i8* %hdl) {
|
||||
entry:
|
||||
call void @llvm.coro.resume(i8* %hdl)
|
||||
call void @llvm.coro.destroy(i8* %hdl)
|
||||
call i1 @llvm.coro.done(i8* %hdl)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.coro.resume(i8*)
|
||||
declare void @llvm.coro.destroy(i8*)
|
||||
declare i1 @llvm.coro.done(i8*)
|
||||
|
Loading…
x
Reference in New Issue
Block a user