Thanks to visit codestin.com
Credit goes to llvm.org

LLVM 22.0.0git
CoroCleanup.cpp
Go to the documentation of this file.
1//===- CoroCleanup.cpp - Coroutine Cleanup Pass ---------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "CoroInternal.h"
11#include "llvm/IR/Function.h"
12#include "llvm/IR/IRBuilder.h"
14#include "llvm/IR/Module.h"
15#include "llvm/IR/PassManager.h"
17
18using namespace llvm;
19
20#define DEBUG_TYPE "coro-cleanup"
21
22namespace {
23// Created on demand if CoroCleanup pass has work to do.
24struct Lowerer : coro::LowererBase {
25 IRBuilder<> Builder;
26 Lowerer(Module &M) : LowererBase(M), Builder(Context) {}
27 bool lower(Function &F);
28};
29}
30
31static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn) {
32 Builder.SetInsertPoint(SubFn);
33 Value *FramePtr = SubFn->getFrame();
34 int Index = SubFn->getIndex();
35
36 auto *FrameTy = StructType::get(SubFn->getContext(),
37 {Builder.getPtrTy(), Builder.getPtrTy()});
38
39 Builder.SetInsertPoint(SubFn);
40 auto *Gep = Builder.CreateConstInBoundsGEP2_32(FrameTy, FramePtr, 0, Index);
41 auto *Load = Builder.CreateLoad(FrameTy->getElementType(Index), Gep);
42
43 SubFn->replaceAllUsesWith(Load);
44}
45
46bool Lowerer::lower(Function &F) {
47 bool IsPrivateAndUnprocessed = F.isPresplitCoroutine() && F.hasLocalLinkage();
48 bool Changed = false;
49
50 for (Instruction &I : llvm::make_early_inc_range(instructions(F))) {
51 if (auto *II = dyn_cast<IntrinsicInst>(&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:
63 II->replaceAllUsesWith(ConstantInt::getTrue(Context));
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:
73 II->replaceAllUsesWith(ConstantTokenNone::get(Context));
74 break;
75 case Intrinsic::coro_subfn_addr:
77 break;
78 case Intrinsic::coro_end:
79 case Intrinsic::coro_suspend_retcon:
80 if (IsPrivateAndUnprocessed) {
81 II->replaceAllUsesWith(PoisonValue::get(II->getType()));
82 } else
83 continue;
84 break;
85 case Intrinsic::coro_async_size_replace:
87 cast<GlobalVariable>(II->getArgOperand(0)->stripPointerCasts())
88 ->getInitializer());
90 cast<GlobalVariable>(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);
98 auto *NewFuncPtrStruct = ConstantStruct::get(
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, {Intrinsic::coro_alloc, Intrinsic::coro_begin,
114 Intrinsic::coro_subfn_addr, Intrinsic::coro_free, Intrinsic::coro_id,
115 Intrinsic::coro_id_retcon, Intrinsic::coro_id_async,
116 Intrinsic::coro_id_retcon_once, Intrinsic::coro_async_size_replace,
117 Intrinsic::coro_async_resume, Intrinsic::coro_begin_custom_abi});
118}
119
123 return PreservedAnalyses::all();
124
126 MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
127
130
131 PreservedAnalyses FuncPA;
132 FuncPA.preserveSet<CFGAnalyses>();
133
134 Lowerer L(M);
135 for (auto &F : M) {
136 if (L.lower(F)) {
137 FAM.invalidate(F, FuncPA);
138 FPM.run(F, FAM);
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.
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
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
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
This class represents the llvm.coro.subfn.addr instruction.
Definition CoroInstr.h:36
Value * getFrame() const
Definition CoroInstr.h:49
ResumeKind getIndex() const
Definition CoroInstr.h:50
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2780
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
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 LLVM_ABI 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.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
A pass to simplify and canonicalize the CFG of a function.
Definition SimplifyCFG.h:30
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.
Definition Type.cpp:414
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:546
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.cpp:1101
Changed
bool declaresIntrinsics(const Module &M, ArrayRef< Intrinsic::ID > List)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
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...
Definition STLExtras.h:634
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)