96 : TheModule(M),
Context(M.getContext()),
115 "makeSubFnCall: Index value out of range");
126 static const char *
const CoroIntrinsics[] = {
127 "llvm.coro.alloc",
"llvm.coro.begin",
"llvm.coro.destroy",
128 "llvm.coro.done",
"llvm.coro.end",
"llvm.coro.frame",
129 "llvm.coro.free",
"llvm.coro.id",
"llvm.coro.noop",
130 "llvm.coro.param",
"llvm.coro.promise",
"llvm.coro.resume",
131 "llvm.coro.save",
"llvm.coro.size",
"llvm.coro.subfn.addr",
141 std::initializer_list<StringRef>
List) {
156 if (
auto CF = dyn_cast<CoroFreeInst>(U))
159 if (CoroFrees.
empty())
168 CF->eraseFromParent();
197 auto *ParentNode = CG[&ParentFunc];
198 ParentNode->removeAllCalledFunctions();
205 Nodes.push_back(Callee);
239 size_t FinalSuspendIndex = 0;
245 if (
auto II = dyn_cast<IntrinsicInst>(&
I)) {
246 switch (II->getIntrinsicID()) {
250 CoroSizes.push_back(cast<CoroSizeInst>(II));
253 CoroFrames.
push_back(cast<CoroFrameInst>(II));
259 UnusedCoroSaves.
push_back(cast<CoroSaveInst>(II));
262 CoroSuspends.push_back(cast<CoroSuspendInst>(II));
263 if (CoroSuspends.back()->isFinal()) {
266 "Only one suspend point can be marked as final");
267 HasFinalSuspend =
true;
268 FinalSuspendIndex = CoroSuspends.size() - 1;
272 auto CB = cast<CoroBeginInst>(II);
273 if (CB->getId()->getInfo().isPreSplit()) {
276 "coroutine should have exactly one defining @llvm.coro.begin");
286 CoroEnds.push_back(cast<CoroEndInst>(II));
287 if (CoroEnds.back()->isFallthrough()) {
290 if (CoroEnds.size() > 1) {
291 if (CoroEnds.front()->isFallthrough())
293 "Only one coro.end can be marked as fallthrough");
294 std::swap(CoroEnds.front(), CoroEnds.back());
308 CF->replaceAllUsesWith(
Undef);
309 CF->eraseFromParent();
316 CS->eraseFromParent();
317 if (
auto *CoroSave = CS->getCoroSave())
318 CoroSave->eraseFromParent();
330 CF->replaceAllUsesWith(CoroBegin);
331 CF->eraseFromParent();
336 if (!CS->getCoroSave())
340 if (HasFinalSuspend &&
341 FinalSuspendIndex != CoroSuspends.size() - 1)
342 std::swap(CoroSuspends[FinalSuspendIndex], CoroSuspends.back());
346 CoroSave->eraseFromParent();
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
PassManagerBuilder - This class is used to set up a standard optimization sequence for languages like...
CoroBeginInst * CoroBegin
This represents the llvm.coro.alloc instruction.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
void initializeCoroEarlyPass(PassRegistry &)
A Module instance is used to store all the information related to an LLVM module. ...
void initializeCoroElidePass(PassRegistry &)
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
void push_back(const T &Elt)
Pass * createCoroSplitPass()
Split up coroutines into multiple functions driving their state machines.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
static void buildCGN(CallGraph &CG, CallGraphNode *Node)
EP_ScalarOptimizerLate - This extension point allows adding optimization passes after most of the mai...
static void addCoroutineSCCPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
LLVMContext & getContext() const
All values hold a context through their type.
virtual void add(Pass *P)=0
Add a pass to the queue of passes to run.
void setArgOperand(unsigned i, Value *v)
Pass * createCoroEarlyPass()
Lower coroutine intrinsics that are not needed by later passes.
A node in the call graph for a module.
static bool isCoroutineIntrinsicName(StringRef Name)
void addCalledFunction(CallSite CS, CallGraphNode *M)
Adds a function to the list of functions called by this one.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
Attribute unwrap(LLVMAttributeRef Attr)
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
This represents the llvm.coro.suspend instruction.
This file contains the simple types necessary to represent the attributes associated with functions a...
void buildFrom(Function &F)
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
Class to represent function types.
void initializeCoroSplitPass(PassRegistry &)
EP_EnabledOnOptLevel0 - This extension point allows adding passes that should not be disabled by O0 o...
FunctionType *const ResumeFnType
SmallVector< CoroSizeInst *, 2 > CoroSizes
static void addCoroutineOptimizerLastPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
This class represents a no-op cast from one type to another.
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type. ...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
SmallVector< CoroSuspendInst *, 4 > CoroSuspends
amdgpu Simplify well known AMD library false Value * Callee
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
static void addCoroutineScalarOptimizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
bool isLeaf(ID id)
Returns true if the intrinsic is a leaf, i.e.
CallGraphNode * getCallsExternalNode() const
The instances of the Type class are immutable: once they are created, they are never changed...
Pass * createCoroCleanupPass()
Lower all remaining coroutine intrinsics.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Pass * createCoroElidePass()
Analyze coroutines use sites, devirtualize resume/destroy calls and elide heap allocation for corouti...
This represents the llvm.coro.end instruction.
ModulePass * createBarrierNoopPass()
createBarrierNoopPass - This pass is purely a module pass barrier in a pass manager.
This represents the llvm.coro.save instruction.
void initialize(ArrayRef< CallGraphNode *> NewNodes)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
EP_OptimizerLast – This extension point allows adding passes that run after everything else...
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
EP_EarlyAsPossible - This extension point allows adding passes before any other transformations, allowing them to see the code as it is coming out of the frontend.
This represents the llvm.coro.free instruction.
Function * getFunction() const
Returns the function that this call graph node represents.
EP_CGSCCOptimizerLate - This extension point allows adding CallGraphSCC passes at the end of the main...
static void addCoroutineOpt0Passes(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
void initializeCoroutines(PassRegistry &)
Initialize all passes linked into the Coroutines library.
static CoroSaveInst * createCoroSave(CoroBeginInst *CoroBegin, CoroSuspendInst *SuspendInst)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
A constant pointer value that points to null.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static void addCoroutineEarlyPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM)
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
struct LLVMOpaquePassManager * LLVMPassManagerRef
This class represents the llvm.coro.begin instruction.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Value * makeSubFnCall(Value *Arg, int Index, Instruction *InsertPt)
iterator_range< user_iterator > users()
static void clear(coro::Shape &Shape)
amdgpu Simplify well known AMD library false Value Value * Arg
void initializeCoroCleanupPass(PassRegistry &)
The basic data container for the call graph of a Module of IR.
LLVM_NODISCARD bool empty() const
SwitchInst * ResumeSwitch
void replaceCoroFree(CoroIdInst *CoroId, bool Elide)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SmallVector< CoroEndInst *, 4 > CoroEnds
AllocaInst * PromiseAlloca
This represents the llvm.coro.frame instruction.
LLVM Value Representation.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
CallGraphNode * getOrInsertFunction(const Function *F)
Similar to operator[], but this will insert a new CallGraphNode for F if one does not already exist...
void addCoroutinePassesToExtensionPoints(PassManagerBuilder &Builder)
Add all coroutine passes to appropriate extension points.
bool declaresIntrinsics(Module &M, std::initializer_list< StringRef >)
StringRef - Represent a constant reference to a string, i.e.
inst_range instructions(Function *F)
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
int lookupLLVMIntrinsicByName(ArrayRef< const char *> NameTable, StringRef Name)
Looks up Name in NameTable via binary search.
BasicBlock * AllocaSpillBlock
void addExtension(ExtensionPointTy Ty, ExtensionFn Fn)
static IntegerType * getInt8Ty(LLVMContext &C)
CoroSaveInst * getCoroSave() const
void updateCallGraph(Function &Caller, ArrayRef< Function *> Funcs, CallGraph &CG, CallGraphSCC &SCC)