31#define DEBUG_TYPE "nvptx-lower-ctor-dtor"
35static std::string getHash(
StringRef Str) {
49static Function *createInitOrFiniKernelFunction(
Module &M,
bool IsCtor) {
51 IsCtor ?
"nvptx$device$init" :
"nvptx$device$fini";
52 if (M.getFunction(InitOrFiniKernelName))
58 addKernelAttrs(InitOrFiniKernel);
60 return InitOrFiniKernel;
86static void createInitOrFiniCalls(
Function &
F,
bool IsCtor) {
96 auto *Begin = M.getOrInsertGlobal(
97 IsCtor ?
"__init_array_start" :
"__fini_array_start",
103 IsCtor ?
"__init_array_start" :
"__fini_array_start",
109 auto *
End = M.getOrInsertGlobal(
116 IsCtor ?
"__init_array_end" :
"__fini_array_end",
132 Value *OldBeginVal = BeginVal;
138 EndVal = OldBeginVal;
145 auto *CallBackPHI = IRB.
CreatePHI(PtrTy, 2,
"ptr");
147 CallBackPHI,
"callback");
152 NewCallBack, EndVal,
"end");
153 CallBackPHI->addIncoming(BeginVal, &
F.getEntryBlock());
154 CallBackPHI->addIncoming(NewCallBack, LoopBB);
161 const NVPTXOptions &CLOpts) {
173 std::string PriorityStr =
"." + std::to_string(Priority);
175 std::string GlobalID = CLOpts.lower_global_ctor_dtor_id.empty()
176 ? getHash(M.getSourceFileName())
177 : CLOpts.lower_global_ctor_dtor_id.str();
178 std::string NameStr =
179 ((IsCtor ?
"__init_array_object_" :
"__fini_array_object_") +
180 F->getName() +
"_" + GlobalID +
"_" + std::to_string(Priority))
184 [](
char c) { return c ==
'.' ?
'_' : c; });
191 GV->
setSection(IsCtor ?
".init_array" + PriorityStr
192 :
".fini_array" + PriorityStr);
200static bool createInitOrFiniKernel(
Module &M,
StringRef GlobalName,
bool IsCtor,
201 const NVPTXOptions &CLOpts) {
206 if (!createInitOrFiniGlobals(M, GV, IsCtor, CLOpts))
209 if (!CLOpts.emit_init_fini_kernel)
212 Function *InitOrFiniKernel = createInitOrFiniKernelFunction(M, IsCtor);
213 if (!InitOrFiniKernel)
216 createInitOrFiniCalls(*InitOrFiniKernel, IsCtor);
222static bool lowerCtorsAndDtors(
Module &M) {
226 createInitOrFiniKernel(M,
"llvm.global_ctors",
true, CLOpts);
228 createInitOrFiniKernel(M,
"llvm.global_dtors",
false, CLOpts);
232class NVPTXCtorDtorLoweringLegacy final :
public ModulePass {
235 NVPTXCtorDtorLoweringLegacy() :
ModulePass(ID) {}
236 bool runOnModule(
Module &M)
override {
return lowerCtorsAndDtors(M); }
247char NVPTXCtorDtorLoweringLegacy::ID = 0;
249 "Lower ctors and dtors for NVPTX",
false,
false)
252 return new NVPTXCtorDtorLoweringLegacy();
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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.
Value * CreateConstGEP1_64(Type *Ty, Value *Ptr, uint64_t Idx0, const Twine &Name="")
CondBrInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Value * CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
void disableGEPCanonicalization()
Disable canonicalization of getelementptr instructions to ptradd form.
Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
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.
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.
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 &MAM)
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object 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.
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.
constexpr StringLiteral MaxNTID("nvvm.maxntid")
constexpr StringLiteral MaxClusterRank("nvvm.maxclusterrank")
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.
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()
const NVPTXOptions & getNVPTXOptions(const LLVMContext &C)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
@ End
Run the machine verifier once, at the end of the pipeline.
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.