LLVM: lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

23

24using namespace llvm;

25

26#define DEBUG_TYPE "amdgpu-lower-ctor-dtor"

27

28namespace {

29

30static Function *createInitOrFiniKernelFunction(Module &M, bool IsCtor) {

31 StringRef InitOrFiniKernelName = "amdgcn.device.init";

32 if (!IsCtor)

33 InitOrFiniKernelName = "amdgcn.device.fini";

34 if (M.getFunction(InitOrFiniKernelName))

35 return nullptr;

36

41 InitOrFiniKernel->addFnAttr("amdgpu-flat-work-group-size", "1,1");

42 if (IsCtor)

43 InitOrFiniKernel->addFnAttr("device-init");

44 else

45 InitOrFiniKernel->addFnAttr("device-fini");

46 return InitOrFiniKernel;

47}

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72static void createInitOrFiniCalls(Function &F, bool IsCtor) {

73 Module &M = *F.getParent();

75

81

82 auto *Begin = M.getOrInsertGlobal(

83 IsCtor ? "__init_array_start" : "__fini_array_start", PtrArrayTy, [&]() {

85 M, PtrArrayTy,

87 nullptr,

88 IsCtor ? "__init_array_start" : "__fini_array_start",

91 });

92 auto *End = M.getOrInsertGlobal(

93 IsCtor ? "__init_array_end" : "__fini_array_end", PtrArrayTy, [&]() {

95 M, PtrArrayTy,

97 nullptr,

98 IsCtor ? "__init_array_end" : "__fini_array_end",

101 });

102

103

104

106

107 Value *Start = Begin;

108 Value *Stop = End;

109

110

111 if (!IsCtor) {

115 auto *ByteSize = IRB.CreateSub(EndPtr, BeginPtr, "", true,

116 true);

117 auto *Size = IRB.CreateAShr(ByteSize, ConstantInt::get(Int64Ty, 3), "",

118 true);

120 IRB.CreateSub(Size, ConstantInt::get(Int64Ty, 1), "", true,

121 true);

123 PtrArrayTy, Begin,

125 Stop = Begin;

126 }

127

130 Stop),

131 LoopBB, ExitBB);

133 auto *CallBackPHI = IRB.CreatePHI(PtrTy, 2, "ptr");

134 auto *CallBack = IRB.CreateLoad(F.getType(), CallBackPHI, "callback");

135 IRB.CreateCall(CallBackTy, CallBack);

136 auto *NewCallBack =

139 NewCallBack, Stop, "end");

140 CallBackPHI->addIncoming(Start, &F.getEntryBlock());

141 CallBackPHI->addIncoming(NewCallBack, LoopBB);

145}

146

147static bool createInitOrFiniKernel(Module &M, StringRef GlobalName,

148 bool IsCtor) {

149 GlobalVariable *GV = M.getGlobalVariable(GlobalName);

151 return false;

154 return false;

155

156 Function *InitOrFiniKernel = createInitOrFiniKernelFunction(M, IsCtor);

157 if (!InitOrFiniKernel)

158 return false;

159

160 createInitOrFiniCalls(*InitOrFiniKernel, IsCtor);

161

163 return true;

164}

165

166static bool lowerCtorsAndDtors(Module &M) {

168 Modified |= createInitOrFiniKernel(M, "llvm.global_ctors", true);

169 Modified |= createInitOrFiniKernel(M, "llvm.global_dtors", false);

171}

172

173class AMDGPUCtorDtorLoweringLegacy final : public ModulePass {

174public:

175 static char ID;

176 AMDGPUCtorDtorLoweringLegacy() : ModulePass(ID) {}

177 bool runOnModule(Module &M) override { return lowerCtorsAndDtors(M); }

178};

179

180}

181

187

188char AMDGPUCtorDtorLoweringLegacy::ID = 0;

190 AMDGPUCtorDtorLoweringLegacy::ID;

192 "Lower ctors and dtors for AMDGPU", false, false)

193

195 return new AMDGPUCtorDtorLoweringLegacy();

196}

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

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

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

PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition AMDGPUCtorDtorLowering.cpp:182

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)

This static method is the primary way to construct an ArrayType.

static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)

Creates a new BasicBlock.

@ ICMP_UGE

unsigned greater or equal

@ ICMP_ULT

unsigned less than

ConstantArray - Constant Array Declarations.

static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)

This static method is the primary way of constructing a FunctionType.

void addFnAttr(Attribute::AttrKind Kind)

Add function attributes to this function.

static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)

Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.

void setCallingConv(CallingConv::ID CC)

@ WeakODRLinkage

Same, but only replaced by something equivalent.

@ ExternalLinkage

Externally visible function.

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

bool hasInitializer() const

Definitions have initializers, declarations don't.

Value * CreateConstGEP1_64(Type *Ty, Value *Ptr, uint64_t Idx0, const Twine &Name="")

Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")

Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)

PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")

Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)

BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)

Create a conditional 'br Cond, TrueDest, FalseDest' instruction.

LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)

Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...

ReturnInst * CreateRetVoid()

Create a 'ret void' instruction.

Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")

CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)

PointerType * getPtrTy(unsigned AddrSpace=0)

Fetch the type representing a pointer.

void SetInsertPoint(BasicBlock *TheBB)

This specifies that created instructions should be appended to the end of the specified block.

Type * getVoidTy()

Fetch the type representing void.

Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)

This provides a uniform API for creating instructions and inserting them into a basic block: either a...

This is an important class for using LLVM in a threaded context.

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.

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.

StringRef - Represent a constant reference to a string, i.e.

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)

static LLVM_ABI Type * getVoidTy(LLVMContext &C)

unsigned getNumOperands() const

LLVM Value Representation.

@ GLOBAL_ADDRESS

Address space for global memory (RAT0, VTX0).

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ AMDGPU_KERNEL

Used for AMDGPU code object kernels.

@ C

The default llvm calling convention, compatible with C.

This is an optimization pass for GlobalISel generic memory operations.

char & AMDGPUCtorDtorLoweringLegacyPassID

Definition AMDGPUCtorDtorLowering.cpp:189

ModulePass * createAMDGPUCtorDtorLoweringLegacyPass()

decltype(auto) dyn_cast(const From &Val)

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

LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)

Adds global values to the llvm.used list.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.