31#define DEBUG_TYPE "lower-global-dtors"
34class LowerGlobalDtorsLegacyPass final :
public ModulePass {
36 return "Lower @llvm.global_dtors via `__cxa_atexit`";
54char LowerGlobalDtorsLegacyPass::ID = 0;
56 "Lower @llvm.global_dtors via `__cxa_atexit`",
false,
false)
59 return new LowerGlobalDtorsLegacyPass();
63bool LowerGlobalDtorsLegacyPass::runOnModule(
Module &M) {
return runImpl(M); }
87 if (!ETy || ETy->getNumElements() != 3 ||
88 !ETy->getTypeAtIndex(0U)->isIntegerTy() ||
89 !ETy->getTypeAtIndex(1U)->isPointerTy() ||
90 !ETy->getTypeAtIndex(2U)->isPointerTy())
98 std::vector<std::pair<Constant *, std::vector<Constant *>>>
101 auto *CS = dyn_cast<ConstantStruct>(O);
105 auto *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
108 uint16_t PriorityValue = Priority->getLimitedValue(UINT16_MAX);
117 auto &AtThisPriority = DtorFuncs[PriorityValue];
118 if (AtThisPriority.empty() || AtThisPriority.back().first != Associated) {
119 std::vector<Constant *> NewList;
120 NewList.push_back(DtorFunc);
121 AtThisPriority.push_back(std::make_pair(Associated, NewList));
123 AtThisPriority.back().second.push_back(DtorFunc);
126 if (DtorFuncs.empty())
132 Type *AtExitFuncArgs[] = {VoidStar};
147 if (
auto F = dyn_cast<Function>(AtExit.
getCallee())) {
148 if (
F &&
F->hasExactDefinition() &&
F->getArg(0)->getNumUses() == 0) {
156 Constant *DsoHandle = M.getOrInsertGlobal(
"__dso_handle", DsoHandleTy, [&] {
167 for (
auto &PriorityAndMore : DtorFuncs) {
168 uint16_t Priority = PriorityAndMore.first;
170 auto &AtThisPriority = PriorityAndMore.second;
171 for (
auto &AssociatedAndMore : AtThisPriority) {
172 Constant *Associated = AssociatedAndMore.first;
178 (Priority != UINT16_MAX ? (
Twine(
".") +
Twine(Priority))
180 (AtThisPriority.size() > 1 ?
Twine(
"$") +
Twine(ThisId)
189 for (
auto *Dtor :
reverse(AssociatedAndMore.second))
195 "register_call_dtors" +
196 (Priority != UINT16_MAX ? (
Twine(
".") +
Twine(Priority))
198 (AtThisPriority.size() > 1 ?
Twine(
"$") +
Twine(ThisId)
208 Value *Args[] = {CallDtors,
Null, DsoHandle};
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runImpl(Function &F, const TargetLowering &TLI)
static bool runImpl(Module &M)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Type * getElementType() const
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
Represents analyses that only rely on functions' control flow.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
ConstantArray - Constant Array Declarations.
ArrayType * getType() const
Specialize the getType() method to always return an ArrayType, which reduces the amount of casting ne...
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ ExternalWeakLinkage
ExternalWeak linkage description.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This instruction compares its operands according to the predicate given to the constructor.
This is an important class for using LLVM in a threaded context.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
This function has undefined behavior.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
This is an optimization pass for GlobalISel generic memory operations.
auto reverse(ContainerTy &&C)
ModulePass * createLowerGlobalDtorsLegacyPass()
void initializeLowerGlobalDtorsLegacyPassPass(PassRegistry &)
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.