Go to the documentation of this file.
19 #define DEBUG_TYPE "coro-cleanup"
26 bool lowerRemainingCoroIntrinsics(
Function &
F);
45 SubFn->
getContext(), {Builder.getInt8PtrTy(), Builder.getInt8PtrTy()});
49 auto *FramePtr =
Builder.CreateBitCast(FrameRaw, FramePtrTy);
50 auto *Gep =
Builder.CreateConstInBoundsGEP2_32(FrameTy, FramePtr, 0,
Index);
56 bool Lowerer::lowerRemainingCoroIntrinsics(
Function &
F) {
61 if (
auto *II = dyn_cast<IntrinsicInst>(&
I)) {
62 switch (II->getIntrinsicID()) {
65 case Intrinsic::coro_begin:
66 II->replaceAllUsesWith(II->getArgOperand(1));
68 case Intrinsic::coro_free:
69 II->replaceAllUsesWith(II->getArgOperand(1));
71 case Intrinsic::coro_alloc:
74 case Intrinsic::coro_id:
75 case Intrinsic::coro_id_retcon:
76 case Intrinsic::coro_id_retcon_once:
77 case Intrinsic::coro_id_async:
80 case Intrinsic::coro_subfn_addr:
83 case Intrinsic::coro_async_size_replace:
84 auto *
Target = cast<ConstantStruct>(
85 cast<GlobalVariable>(II->getArgOperand(0)->stripPointerCasts())
87 auto *
Source = cast<ConstantStruct>(
88 cast<GlobalVariable>(II->getArgOperand(1)->stripPointerCasts())
90 auto *TargetSize =
Target->getOperand(1);
91 auto *SourceSize =
Source->getOperand(1);
92 if (TargetSize->isElementWiseEqual(SourceSize)) {
95 auto *TargetRelativeFunOffset =
Target->getOperand(0);
97 Target->getType(), TargetRelativeFunOffset, SourceSize);
98 Target->replaceAllUsesWith(NewFuncPtrStruct);
101 II->eraseFromParent();
116 M, {
"llvm.coro.alloc",
"llvm.coro.begin",
"llvm.coro.subfn.addr",
117 "llvm.coro.free",
"llvm.coro.id",
"llvm.coro.id.retcon",
118 "llvm.coro.id.retcon.once",
"llvm.coro.async.size.replace"});
123 auto &
M = *
F.getParent();
125 !Lowerer(
M).lowerRemainingCoroIntrinsics(
F))
140 std::unique_ptr<Lowerer> L;
144 bool doInitialization(
Module &M)
override {
146 L = std::make_unique<Lowerer>(M);
152 return L->lowerRemainingCoroIntrinsics(
F);
159 StringRef getPassName()
const override {
return "Coroutine Cleanup"; }
165 "Lower all coroutine related intrinsics",
false,
false)
A set of analyses that are preserved following a run of a transformation pass.
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
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)
Target - Wrapper for Target specific information.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
bool declaresIntrinsics(const Module &M, const std::initializer_list< StringRef >)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
void initializeCoroCleanupLegacyPass(PassRegistry &)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool doFinalization()
doFinalization - Run all of the finalizers for the function passes.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
This class represents the llvm.coro.subfn.addr instruction.
ResumeKind getIndex() const
Class to represent pointers.
bool doInitialization()
doInitialization - Run all of the initializers for the function passes.
A Module instance is used to store all the information related to an LLVM module.
void add(Pass *P) override
Add a pass to the queue of passes to run.
bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, DomTreeUpdater *DTU=nullptr, const SimplifyCFGOptions &Options={}, ArrayRef< WeakVH > LoopHeaders={})
StringRef - Represent a constant reference to a string, i.e.
INITIALIZE_PASS(CoroCleanupLegacy, "coro-cleanup", "Lower all coroutine related intrinsics", false, false) Pass *llvm
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.
Pass * createCoroCleanupLegacyPass()
Lower all remaining coroutine intrinsics.
static bool runOnFunction(Function &F, bool PostInlining)
static ConstantInt * getTrue(LLVMContext &Context)
bool run(Function &F)
run - Execute all of the passes scheduled for execution.
void setPreservesAll()
Set by analyses that do not transform their input at all.
static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
inst_iterator inst_end(Function *F)
static bool declaresCoroCleanupIntrinsics(const Module &M)
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Pass interface - Implemented by all 'passes'.
FunctionPassManager manages FunctionPasses.
A container for analyses that lazily runs them and caches their results.
FunctionPass class - This class is used to implement most global optimizations.
inst_iterator inst_begin(Function *F)
LLVM Value Representation.