Go to the documentation of this file.
18 #define DEBUG_TYPE "coro-early"
46 void Lowerer::lowerResumeOrDestroy(
CallBase &CB,
69 DL.getStructLayout(SampleStruct)->getElementOffset(2), Alignment);
75 Builder.CreateConstInBoundsGEP1_32(Int8Ty, Operand, Offset);
90 "resume function not at offset zero");
91 auto *FrameTy = Int8Ptr;
95 auto *BCI =
Builder.CreateBitCast(Operand, FramePtrTy);
113 auto *FnPtrTy = FnTy->getPointerTo();
114 FrameTy->
setBody({FnPtrTy, FnPtrTy});
119 "NoopCoro.ResumeDestroy", &M);
125 Constant* Values[] = {NoopFn, NoopFn};
129 "NoopCoro.Frame.Const");
133 auto *NoopCoroVoidPtr =
Builder.CreateBitCast(NoopCoro, Int8Ptr);
144 if (
auto *CB = dyn_cast<CoroBeginInst>(U))
148 void Lowerer::lowerEarlyIntrinsics(
Function &
F) {
151 bool HasCoroSuspend =
false;
153 auto *CB = dyn_cast<CallBase>(&
I);
160 case Intrinsic::coro_free:
161 CoroFrees.push_back(cast<CoroFreeInst>(&
I));
163 case Intrinsic::coro_suspend:
166 if (cast<CoroSuspendInst>(&
I)->isFinal())
168 HasCoroSuspend =
true;
170 case Intrinsic::coro_end_async:
171 case Intrinsic::coro_end:
174 if (cast<AnyCoroEndInst>(&
I)->isFallthrough())
177 case Intrinsic::coro_noop:
178 lowerCoroNoop(cast<IntrinsicInst>(&
I));
180 case Intrinsic::coro_id:
181 if (
auto *CII = cast<CoroIdInst>(&
I)) {
182 if (CII->getInfo().isPreSplit()) {
183 assert(
F.isPresplitCoroutine() &&
184 "The frontend uses Swtich-Resumed ABI should emit "
185 "\"coroutine.presplit\" attribute for the coroutine.");
187 CII->setCoroutineSelf();
188 CoroId = cast<CoroIdInst>(&
I);
192 case Intrinsic::coro_id_retcon:
193 case Intrinsic::coro_id_retcon_once:
194 case Intrinsic::coro_id_async:
195 F.setPresplitCoroutine();
197 case Intrinsic::coro_resume:
200 case Intrinsic::coro_destroy:
203 case Intrinsic::coro_promise:
204 lowerCoroPromise(cast<CoroPromiseInst>(&
I));
206 case Intrinsic::coro_done:
207 lowerCoroDone(cast<IntrinsicInst>(&
I));
217 CF->setArgOperand(0, CoroId);
224 if (
A.hasNoAliasAttr())
225 A.removeAttr(Attribute::NoAlias);
230 M, {
"llvm.coro.id",
"llvm.coro.id.retcon",
"llvm.coro.id.retcon.once",
231 "llvm.coro.id.async",
"llvm.coro.destroy",
"llvm.coro.done",
232 "llvm.coro.end",
"llvm.coro.end.async",
"llvm.coro.noop",
233 "llvm.coro.free",
"llvm.coro.promise",
"llvm.coro.resume",
234 "llvm.coro.suspend"});
243 L.lowerEarlyIntrinsics(
F);
A set of analyses that are preserved following a run of a transformation pass.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This class represents an incoming formal argument to a Function.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
A parsed version of the target data layout string in and methods for querying it.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
void setBody(ArrayRef< Type * > Elements, bool isPacked=false)
Specify a body for an opaque identified type.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
@ Fast
Attempts to make calls as fast as possible (e.g.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
The instances of the Type class are immutable: once they are created, they are never changed.
bool declaresIntrinsics(const Module &M, const std::initializer_list< StringRef >)
This represents the llvm.coro.free instruction.
static void setCannotDuplicate(CoroIdInst *CoroId)
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
(vector float) vec_cmpeq(*A, *B) C
Align getAlignment() const
The required alignment of the promise.
This struct is a compact representation of a valid (non-zero power of two) alignment.
This represents the llvm.coro.promise instruction.
inst_range instructions(Function *F)
This is an important base class in LLVM.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
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...
Class to represent pointers.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A Module instance is used to store all the information related to an LLVM module.
Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
bool isFromPromise() const
Are we translating from the frame to the promise (false) or from the promise to the frame (true)?
Class to represent struct types.
SmallVector< MachineOperand, 4 > Cond
void setCallingConv(CallingConv::ID CC)
Type * getType() const
All values are typed, get the type of this value.
Represents analyses that only rely on functions' control flow.
This represents the llvm.coro.id instruction.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
A wrapper class for inspecting calls to intrinsic functions.
void setCalledOperand(Value *V)
static Type * getVoidTy(LLVMContext &C)
@ PrivateLinkage
Like Internal, but omit from symbol table.
void preserveSet()
Mark an analysis set as preserved.
static bool declaresCoroEarlyIntrinsics(const Module &M)
Value * getArgOperand(unsigned i) const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
A container for analyses that lazily runs them and caches their results.
void setCannotDuplicate()
LLVM Value Representation.
iterator_range< user_iterator > users()
void setCallingConv(CallingConv::ID CC)