LLVM: lib/Target/NVPTX/NVPTXCtorDtorLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

28

29using namespace llvm;

30

31#define DEBUG_TYPE "nvptx-lower-ctor-dtor"

32

34 GlobalStr("nvptx-lower-global-ctor-dtor-id",

35 cl::desc("Override unique ID of ctor/dtor globals."),

37

40 cl::desc("Emit kernels to call ctor/dtor globals."),

42

43namespace {

44

45static std::string getHash(StringRef Str) {

49 Hasher.final(Hash);

51}

52

53static void addKernelAttrs(Function *F) {

54 F->addFnAttr("nvvm.maxclusterrank", "1");

55 F->addFnAttr("nvvm.maxntid", "1");

57}

58

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

61 IsCtor ? "nvptx$device$init" : "nvptx$device$fini";

62 if (M.getFunction(InitOrFiniKernelName))

63 return nullptr;

64

68 addKernelAttrs(InitOrFiniKernel);

69

70 return InitOrFiniKernel;

71}

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

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

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

99

104

105 auto *Begin = M.getOrInsertGlobal(

106 IsCtor ? "__init_array_start" : "__fini_array_start",

112 IsCtor ? "__init_array_start" : "__fini_array_start",

116 return GV;

117 });

118 auto *End = M.getOrInsertGlobal(

119 IsCtor ? "__init_array_end" : "__fini_array_end", PointerType::get(C, 0),

120 [&]() {

125 IsCtor ? "__init_array_end" : "__fini_array_end",

129 return GV;

130 });

131

132

133

135

136

137

138 Value *BeginVal = IRB.CreateLoad(Begin->getType(), Begin, "begin");

139 Value *EndVal = IRB.CreateLoad(Begin->getType(), End, "stop");

140 if (!IsCtor) {

143 auto *SubInst = IRB.CreateSub(EndInt, BeginInt);

144 auto *Offset = IRB.CreateAShr(

146 true);

149 EndVal = BeginVal;

150 BeginVal =

154 "start");

155 }

156 IRB.CreateCondBr(

158 EndVal),

159 LoopBB, ExitBB);

160 IRB.SetInsertPoint(LoopBB);

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

162 auto *CallBack = IRB.CreateLoad(IRB.getPtrTy(F.getAddressSpace()),

163 CallBackPHI, "callback");

164 IRB.CreateCall(CallBackTy, CallBack);

165 auto *NewCallBack =

166 IRB.CreateConstGEP1_64(PtrTy, CallBackPHI, IsCtor ? 1 : -1, "next");

168 NewCallBack, EndVal, "end");

169 CallBackPHI->addIncoming(BeginVal, &F.getEntryBlock());

170 CallBackPHI->addIncoming(NewCallBack, LoopBB);

171 IRB.CreateCondBr(EndCmp, ExitBB, LoopBB);

172 IRB.SetInsertPoint(ExitBB);

173 IRB.CreateRetVoid();

174}

175

177 bool IsCtor) {

180 return false;

181

182

183

184

189 std::string PriorityStr = "." + std::to_string(Priority);

190

193 std::string NameStr =

194 ((IsCtor ? "__init_array_object_" : "__fini_array_object_") +

195 F->getName() + "_" + GlobalID + "_" + std::to_string(Priority))

196 .str();

197

199 [](char c) { return c == '.' ? '_' : c; });

200

201 auto *GV = new GlobalVariable(M, F->getType(), true,

204 4);

205

206 GV->setSection(IsCtor ? ".init_array" + PriorityStr

207 : ".fini_array" + PriorityStr);

210 }

211

212 return true;

213}

214

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

216 bool IsCtor) {

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

219 return false;

220

221 if (!createInitOrFiniGlobals(M, GV, IsCtor))

222 return false;

223

225 return true;

226

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

228 if (!InitOrFiniKernel)

229 return false;

230

231 createInitOrFiniCalls(*InitOrFiniKernel, IsCtor);

232

234 return true;

235}

236

237static bool lowerCtorsAndDtors(Module &M) {

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

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

242}

243

244class NVPTXCtorDtorLoweringLegacy final : public ModulePass {

245public:

246 static char ID;

247 NVPTXCtorDtorLoweringLegacy() : ModulePass(ID) {}

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

249};

250

251}

252

258

259char NVPTXCtorDtorLoweringLegacy::ID = 0;

261 "Lower ctors and dtors for NVPTX", false, false)

262

264 return new NVPTXCtorDtorLoweringLegacy();

265}

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.

Machine Check Debug Module

static cl::opt< bool > CreateKernels("nvptx-emit-init-fini-kernel", cl::desc("Emit kernels to call ctor/dtor globals."), cl::init(true), cl::Hidden)

static cl::opt< std::string > GlobalStr("nvptx-lower-global-ctor-dtor-id", cl::desc("Override unique ID of ctor/dtor globals."), cl::init(""), cl::Hidden)

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

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

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 Constant * getAllOnesValue(Type *Ty)

static LLVM_ABI Constant * getNullValue(Type *Ty)

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

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

LLVM_ABI void setSection(StringRef S)

Change the section for this global.

@ ProtectedVisibility

The GV is protected.

void setVisibility(VisibilityTypes V)

@ WeakODRLinkage

Same, but only replaced by something equivalent.

@ ExternalLinkage

Externally visible function.

@ WeakAnyLinkage

Keep one copy of named function when linking (weak)

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

LLVM_ABI void update(ArrayRef< uint8_t > Data)

Updates the hash for the byte stream provided.

LLVM_ABI void final(MD5Result &Result)

Finishes off the hash and puts the result in result.

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.

PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition NVPTXCtorDtorLowering.cpp:253

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

@ PTX_Kernel

Call to a PTX kernel. Passes all arguments in parameter space.

@ C

The default llvm calling convention, compatible with C.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

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

std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)

OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)

Wrapper function around std::transform to apply a function to a range and store the result elsewhere.

ModulePass * createNVPTXCtorDtorLoweringLegacyPass()

decltype(auto) cast(const From &Val)

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.