21#define DEBUG_TYPE "coro-cleanup"
29 Lowerer(
Module &M) : LowererBase(M), Builder(Context) {}
39 Builder.SetInsertPoint(SubFn);
44 {Builder.getPtrTy(), Builder.getPtrTy()});
46 Builder.SetInsertPoint(SubFn);
47 auto *Gep = Builder.CreateConstInBoundsGEP2_32(FrameTy,
FramePtr, 0, Index);
48 auto *Load = Builder.CreateLoad(FrameTy->getElementType(Index), Gep);
55 if (M.debug_compile_units().empty())
60 std::array<Metadata *, 2> Params{
nullptr,
nullptr};
61 auto *SubroutineType =
62 DB.createSubroutineType(DB.getOrCreateTypeArray(Params));
64 auto *SP = DB.createFunction(
65 CU, Name, Name,
CU->getFile(),
66 0, SubroutineType, 0, DINode::FlagArtificial,
67 DISubprogram::SPFlagDefinition);
73 bool IsPrivateAndUnprocessed =
F.isPresplitCoroutine() &&
F.hasLocalLinkage();
76 SmallPtrSet<Instruction *, 8> DeadInsts{};
79 switch (
II->getIntrinsicID()) {
82 case Intrinsic::coro_begin:
83 case Intrinsic::coro_begin_custom_abi:
84 II->replaceAllUsesWith(
II->getArgOperand(1));
86 case Intrinsic::coro_free:
87 II->replaceAllUsesWith(
II->getArgOperand(1));
89 case Intrinsic::coro_alloc:
92 case Intrinsic::coro_async_resume:
93 II->replaceAllUsesWith(
96 case Intrinsic::coro_id:
97 case Intrinsic::coro_id_retcon:
98 case Intrinsic::coro_id_retcon_once:
99 case Intrinsic::coro_id_async:
102 case Intrinsic::coro_noop:
104 if (!
II->user_empty())
107 case Intrinsic::coro_subfn_addr:
110 case Intrinsic::coro_suspend_retcon:
111 case Intrinsic::coro_is_in_ramp:
112 if (IsPrivateAndUnprocessed) {
117 case Intrinsic::coro_async_size_replace:
124 auto *TargetSize =
Target->getOperand(1);
125 auto *SourceSize =
Source->getOperand(1);
126 if (TargetSize->isElementWiseEqual(SourceSize)) {
129 auto *TargetRelativeFunOffset =
Target->getOperand(0);
131 Target->getType(), TargetRelativeFunOffset, SourceSize);
132 Target->replaceAllUsesWith(NewFuncPtrStruct);
140 for (
auto *
I : DeadInsts)
141 I->eraseFromParent();
145void Lowerer::elideCoroNoop(IntrinsicInst *
II) {
151 auto *
User = Fn->getUniqueUndroppableUser();
154 Fn->eraseFromParent();
162 Fn->eraseFromParent();
167void Lowerer::lowerCoroNoop(IntrinsicInst *
II) {
173 auto *FnTy = FunctionType::get(Type::getVoidTy(
C), Builder.
getPtrTy(0),
175 auto *FnPtrTy = Builder.
getPtrTy(0);
176 StructType *FrameTy =
181 FnTy, GlobalValue::LinkageTypes::InternalLinkage,
182 M.getDataLayout().getProgramAddressSpace(),
"__NoopCoro_ResumeDestroy",
184 NoopFn->setCallingConv(CallingConv::Fast);
190 Constant *Values[] = {NoopFn, NoopFn};
192 NoopCoro =
new GlobalVariable(
193 M, NoopCoroConst->
getType(),
true,
194 GlobalVariable::PrivateLinkage, NoopCoroConst,
"NoopCoro.Frame.Const");
199 auto *NoopCoroVoidPtr = Builder.
CreateBitCast(NoopCoro, Int8Ptr);
200 II->replaceAllUsesWith(NoopCoroVoidPtr);
206 {Intrinsic::coro_alloc, Intrinsic::coro_begin, Intrinsic::coro_subfn_addr,
207 Intrinsic::coro_free, Intrinsic::coro_id, Intrinsic::coro_id_retcon,
208 Intrinsic::coro_id_async, Intrinsic::coro_id_retcon_once,
209 Intrinsic::coro_noop, Intrinsic::coro_async_size_replace,
210 Intrinsic::coro_async_resume, Intrinsic::coro_begin_custom_abi});
230 FAM.invalidate(
F, FuncPA);
Expand Atomic instructions
static bool declaresCoroCleanupIntrinsics(const Module &M)
static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn)
static void buildDebugInfoForNoopResumeDestroyFunc(Function *NoopFn)
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
static const unsigned FramePtr
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Represents analyses that only rely on functions' control flow.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This is an important base class in LLVM.
This class represents the llvm.coro.subfn.addr instruction.
ResumeKind getIndex() const
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.
Module * getParent()
Get the module that this global value is contained inside of...
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
LLVMContext & getContext() const
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A wrapper class for inspecting calls to intrinsic functions.
A Module instance is used to store all the information related to an LLVM module.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
A pass to simplify and canonicalize the CFG of a function.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
StringRef - Represent a constant reference to a string, i.e.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
@ C
The default llvm calling convention, compatible with C.
bool declaresIntrinsics(const Module &M, ArrayRef< Intrinsic::ID > List)
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)