LLVM: lib/Transforms/Utils/LowerGlobalDtors.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

19

28#include

29

30using namespace llvm;

31

32#define DEBUG_TYPE "lower-global-dtors"

33

34namespace {

35class LowerGlobalDtorsLegacyPass final : public ModulePass {

36 StringRef getPassName() const override {

37 return "Lower @llvm.global_dtors via `__cxa_atexit`";

38 }

39

40 void getAnalysisUsage(AnalysisUsage &AU) const override {

43 }

44

45 bool runOnModule(Module &M) override;

46

47public:

48 static char ID;

49 LowerGlobalDtorsLegacyPass() : ModulePass(ID) {

51 }

52};

53}

54

55char LowerGlobalDtorsLegacyPass::ID = 0;

57 "Lower @llvm.global_dtors via `__cxa_atexit`", false, false)

58

60 return new LowerGlobalDtorsLegacyPass();

61}

62

64bool LowerGlobalDtorsLegacyPass::runOnModule(Module &M) { return runImpl(M); }

65

76

78 GlobalVariable *GV = M.getGlobalVariable("llvm.global_dtors");

80 return false;

81

83 if (!InitList)

84 return false;

85

86

88 if (!ETy || ETy->getNumElements() != 3 ||

89 !ETy->getTypeAtIndex(0U)->isIntegerTy() ||

90 !ETy->getTypeAtIndex(1U)->isPointerTy() ||

91 !ETy->getTypeAtIndex(2U)->isPointerTy())

92 return false;

93

94

95

96

97 std::map<

99 std::vector<std::pair<Constant *, std::vector<Constant *>>>

100 > DtorFuncs;

103 if (!CS)

104 continue;

105

107 if (!Priority)

108 continue;

109 uint16_t PriorityValue = Priority->getLimitedValue(UINT16_MAX);

110

113 break;

114

117

118 auto &AtThisPriority = DtorFuncs[PriorityValue];

119 if (AtThisPriority.empty() || AtThisPriority.back().first != Associated) {

120 std::vector<Constant *> NewList;

121 NewList.push_back(DtorFunc);

122 AtThisPriority.push_back(std::make_pair(Associated, NewList));

123 } else {

124 AtThisPriority.back().second.push_back(DtorFunc);

125 }

126 }

127 if (DtorFuncs.empty())

128 return false;

129

130

133 Type *AtExitFuncArgs[] = {VoidStar};

136 false);

137

139 "__cxa_atexit",

142 false));

143

144

145

146

147

149 if (F && F->hasExactDefinition() && F->getArg(0)->use_empty()) {

151 return true;

152 }

153 }

154

155

157 Constant *DsoHandle = M.getOrInsertGlobal("__dso_handle", DsoHandleTy, [&] {

158 auto *GV = new GlobalVariable(M, DsoHandleTy, true,

160 "__dso_handle");

162 return GV;

163 });

164

165

166

167

168 for (auto &PriorityAndMore : DtorFuncs) {

169 uint16_t Priority = PriorityAndMore.first;

171 auto &AtThisPriority = PriorityAndMore.second;

172 for (auto &AssociatedAndMore : AtThisPriority) {

173 Constant *Associated = AssociatedAndMore.first;

174 auto ThisId = Id++;

175

178 "call_dtors" +

179 (Priority != UINT16_MAX ? (Twine(".") + Twine(Priority))

181 (AtThisPriority.size() > 1 ? Twine("$") + Twine(ThisId)

185 &M);

188 false);

189

190 for (auto *Dtor : reverse(AssociatedAndMore.second))

193

196 "register_call_dtors" +

197 (Priority != UINT16_MAX ? (Twine(".") + Twine(Priority))

199 (AtThisPriority.size() > 1 ? Twine("$") + Twine(ThisId)

203 &M);

207

209 Value *Args[] = {CallDtors, Null, DsoHandle};

214

215

216

217

219 "", FailBB);

221

223

224

226 }

227 }

228

229

231

232 return true;

233}

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)

Module.h This file contains the declarations for the Module class.

static bool runImpl(Module &M)

Definition LowerGlobalDtors.cpp:77

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

Represent the analysis usage information of a pass.

LLVM_ABI 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, InsertPosition InsertBefore=nullptr)

Represents analyses that only rely on functions' control flow.

static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition 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 LLVM_ABI 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 LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

LLVM_ABI 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 LLVM_ABI 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.

LLVM_ABI 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)

Definition LowerGlobalDtors.cpp:66

ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...

A Module instance is used to store all the information related to an LLVM module.

static LLVM_ABI 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...

static PointerType * getUnqual(Type *ElementType)

This constructs a pointer to an object of the specified type in the default address space (address sp...

static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)

This constructs a pointer to an object of the specified type in a numbered address space.

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.

PreservedAnalyses & preserveSet()

Mark an analysis set as preserved.

static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition 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 LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

static LLVM_ABI Type * getVoidTy(LLVMContext &C)

static LLVM_ABI IntegerType * getInt8Ty(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.

LLVM_ABI 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.

LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})

Look up the Function declaration of the intrinsic id in the Module M.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI ModulePass * createLowerGlobalDtorsLegacyPass()

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto reverse(ContainerTy &&C)

LLVM_ABI void initializeLowerGlobalDtorsLegacyPassPass(PassRegistry &)

LLVM_ABI 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.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.