LLVM: lib/Transforms/Coroutines/CoroCleanup.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17
18using namespace llvm;
19
20#define DEBUG_TYPE "coro-cleanup"
21
22namespace {
23
26 Lowerer(Module &M) : LowererBase(M), Builder(Context) {}
28};
29}
30
34 int Index = SubFn->getIndex();
35
37 {Builder.getPtrTy(), Builder.getPtrTy()});
38
41 auto *Load = Builder.CreateLoad(FrameTy->getElementType(Index), Gep);
42
44}
45
47 bool IsPrivateAndUnprocessed = F.isPresplitCoroutine() && F.hasLocalLinkage();
48 bool Changed = false;
49
51 if (auto *II = dyn_cast(&I)) {
52 switch (II->getIntrinsicID()) {
53 default:
54 continue;
55 case Intrinsic::coro_begin:
56 case Intrinsic::coro_begin_custom_abi:
57 II->replaceAllUsesWith(II->getArgOperand(1));
58 break;
59 case Intrinsic::coro_free:
60 II->replaceAllUsesWith(II->getArgOperand(1));
61 break;
62 case Intrinsic::coro_alloc:
64 break;
65 case Intrinsic::coro_async_resume:
66 II->replaceAllUsesWith(
68 break;
69 case Intrinsic::coro_id:
70 case Intrinsic::coro_id_retcon:
71 case Intrinsic::coro_id_retcon_once:
72 case Intrinsic::coro_id_async:
74 break;
75 case Intrinsic::coro_subfn_addr:
77 break;
78 case Intrinsic::coro_end:
79 case Intrinsic::coro_suspend_retcon:
80 if (IsPrivateAndUnprocessed) {
82 } else
83 continue;
84 break;
85 case Intrinsic::coro_async_size_replace:
86 auto *Target = cast(
87 cast(II->getArgOperand(0)->stripPointerCasts())
88 ->getInitializer());
89 auto *Source = cast(
90 cast(II->getArgOperand(1)->stripPointerCasts())
91 ->getInitializer());
92 auto *TargetSize = Target->getOperand(1);
93 auto *SourceSize = Source->getOperand(1);
94 if (TargetSize->isElementWiseEqual(SourceSize)) {
95 break;
96 }
97 auto *TargetRelativeFunOffset = Target->getOperand(0);
99 Target->getType(), TargetRelativeFunOffset, SourceSize);
100 Target->replaceAllUsesWith(NewFuncPtrStruct);
101 break;
102 }
103 II->eraseFromParent();
104 Changed = true;
105 }
106 }
107
108 return Changed;
109}
110
113 M, {"llvm.coro.alloc", "llvm.coro.begin", "llvm.coro.subfn.addr",
114 "llvm.coro.free", "llvm.coro.id", "llvm.coro.id.retcon",
115 "llvm.coro.id.async", "llvm.coro.id.retcon.once",
116 "llvm.coro.async.size.replace", "llvm.coro.async.resume",
117 "llvm.coro.begin.custom.abi"});
118}
119
124
127
130
133
134 Lowerer L(M);
135 for (auto &F : M) {
136 if (L.lower(F)) {
139 }
140 }
141
143}
Expand Atomic instructions
static bool declaresCoroCleanupIntrinsics(const Module &M)
static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn)
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
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
A container for analyses that lazily runs them and caches their results.
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represents analyses that only rely on functions' control flow.
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
static ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This class represents the llvm.coro.subfn.addr instruction.
ResumeKind getIndex() const
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateConstInBoundsGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name="")
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...
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
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 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.
void preserveSet()
Mark an analysis set as preserved.
A pass to simplify and canonicalize the CFG of a function.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Target - Wrapper for Target specific information.
LLVM Value Representation.
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.
bool declaresIntrinsics(const Module &M, const std::initializer_list< StringRef >)
This is an optimization pass for GlobalISel generic memory operations.
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...
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)