19#define DEBUG_TYPE "coro-early"
34 : LowererBase(M), Builder(Context),
44void Lowerer::lowerResumeOrDestroy(
CallBase &CB,
58void Lowerer::lowerCoroPromise(CoroPromiseInst *Intrin) {
65 const DataLayout &
DL = TheModule.getDataLayout();
67 DL.getStructLayout(SampleStruct)->getElementOffset(2), Alignment);
83void Lowerer::lowerCoroDone(IntrinsicInst *
II) {
84 Value *Operand =
II->getArgOperand(0);
88 "resume function not at offset zero");
89 auto *FrameTy = Int8Ptr;
95 II->replaceAllUsesWith(
Cond);
96 II->eraseFromParent();
102void Lowerer::hidePromiseAlloca(CoroIdInst *CoroId, CoroBeginInst *CoroBegin) {
104 if (!PA || !CoroBegin)
108 auto *Alignment = Builder.
getInt32(PA->getAlign().value());
109 auto *FromPromise = Builder.
getInt1(
false);
112 Builder.
getPtrTy(), Intrinsic::coro_promise, Arg, {},
"promise.addr");
117 if (
I->isLifetimeStartOrEnd())
118 I->eraseFromParent();
120 PA->replaceUsesWithIf(PI, [CoroId](Use &U) {
121 bool IsBitcast =
U ==
U.getUser()->stripPointerCasts();
122 bool IsCoroId =
U.getUser() == CoroId;
123 return !IsBitcast && !IsCoroId;
137void Lowerer::lowerEarlyIntrinsics(Function &
F) {
138 CoroIdInst *CoroId =
nullptr;
139 CoroBeginInst *CoroBegin =
nullptr;
141 bool HasCoroSuspend =
false;
150 case Intrinsic::coro_begin:
151 case Intrinsic::coro_begin_custom_abi:
154 "coroutine should have exactly one defining @llvm.coro.begin");
157 case Intrinsic::coro_free:
160 case Intrinsic::coro_suspend:
165 HasCoroSuspend =
true;
167 case Intrinsic::coro_end_async:
168 case Intrinsic::coro_end:
174 case Intrinsic::coro_id:
176 if (CII->getInfo().isPreSplit()) {
177 assert(
F.isPresplitCoroutine() &&
178 "The frontend uses Switch-Resumed ABI should emit "
179 "\"presplitcoroutine\" attribute for the coroutine.");
181 CII->setCoroutineSelf();
186 case Intrinsic::coro_id_retcon:
187 case Intrinsic::coro_id_retcon_once:
188 case Intrinsic::coro_id_async:
189 F.setPresplitCoroutine();
191 case Intrinsic::coro_resume:
194 case Intrinsic::coro_destroy:
197 case Intrinsic::coro_promise:
200 case Intrinsic::coro_done:
210 for (CoroFreeInst *CF : CoroFrees)
211 CF->setArgOperand(0, CoroId);
213 hidePromiseAlloca(CoroId, CoroBegin);
220 for (Argument &
A :
F.args())
221 if (
A.hasNoAliasAttr())
222 A.removeAttr(Attribute::NoAlias);
228 M, {Intrinsic::coro_id, Intrinsic::coro_id_retcon,
229 Intrinsic::coro_id_retcon_once, Intrinsic::coro_id_async,
230 Intrinsic::coro_destroy, Intrinsic::coro_done, Intrinsic::coro_end,
231 Intrinsic::coro_end_async, Intrinsic::coro_free,
232 Intrinsic::coro_promise, Intrinsic::coro_resume});
241 L.lowerEarlyIntrinsics(
F);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static void setCannotDuplicate(CoroIdInst *CoroId)
static bool declaresCoroEarlyIntrinsics(const Module &M)
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
Represents analyses that only rely on functions' control flow.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
Value * getArgOperand(unsigned i) const
void setCannotDuplicate()
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
void setCalledOperand(Value *V)
This class represents the llvm.coro.begin or llvm.coro.begin.custom.abi instructions.
This represents the llvm.coro.id instruction.
AllocaInst * getPromise() const
This represents the llvm.coro.promise instruction.
Align getAlignment() const
The required alignment of the promise.
bool isFromPromise() const
Are we translating from the frame to the promise (false) or from the promise to the frame (true)?
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Value * CreateConstInBoundsGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
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.
LLVM_ABI std::optional< InstListType::iterator > getInsertionPointAfterDef()
Get the first insertion point at which the result of this instruction is defined.
A wrapper class for inspecting calls to intrinsic functions.
A Module instance is used to store all the information related to an LLVM module.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
void push_back(const T &Elt)
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.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool declaresIntrinsics(const Module &M, ArrayRef< Intrinsic::ID > List)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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...
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)