LLVM  15.0.0git
AMDGPUCtorDtorLowering.cpp
Go to the documentation of this file.
1 //===-- AMDGPUCtorDtorLowering.cpp - Handle global ctors and dtors --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This pass creates a unified init and fini kernel with the required metadata
11 //===----------------------------------------------------------------------===//
12 
13 #include "AMDGPU.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/GlobalVariable.h"
17 #include "llvm/IR/IRBuilder.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/IR/Value.h"
20 #include "llvm/Pass.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "amdgpu-lower-ctor-dtor"
26 
27 namespace {
28 class AMDGPUCtorDtorLowering final : public ModulePass {
29  bool runOnModule(Module &M) override;
30 
31 public:
32  Function *createInitOrFiniKernelFunction(Module &M, bool IsCtor) {
33  StringRef InitOrFiniKernelName = "amdgcn.device.init";
34  if (!IsCtor)
35  InitOrFiniKernelName = "amdgcn.device.fini";
36 
37  Function *InitOrFiniKernel = Function::createWithDefaultAttr(
38  FunctionType::get(Type::getVoidTy(M.getContext()), false),
39  GlobalValue::ExternalLinkage, 0, InitOrFiniKernelName, &M);
40  BasicBlock *InitOrFiniKernelBB =
41  BasicBlock::Create(M.getContext(), "", InitOrFiniKernel);
42  ReturnInst::Create(M.getContext(), InitOrFiniKernelBB);
43 
44  InitOrFiniKernel->setCallingConv(CallingConv::AMDGPU_KERNEL);
45  if (IsCtor)
46  InitOrFiniKernel->addFnAttr("device-init");
47  else
48  InitOrFiniKernel->addFnAttr("device-fini");
49  return InitOrFiniKernel;
50  }
51 
52  bool createInitOrFiniKernel(Module &M, GlobalVariable *GV, bool IsCtor) {
53  if (!GV || !GV->hasInitializer())
54  return false;
55  ConstantArray *GA = dyn_cast<ConstantArray>(GV->getInitializer());
56  if (!GA || GA->getNumOperands() == 0)
57  return false;
58  Function *InitOrFiniKernel = createInitOrFiniKernelFunction(M, IsCtor);
59  IRBuilder<> IRB(InitOrFiniKernel->getEntryBlock().getTerminator());
60  for (Value *V : GA->operands()) {
61  auto *CS = cast<ConstantStruct>(V);
62  if (Function *F = dyn_cast<Function>(CS->getOperand(1))) {
63  FunctionCallee Ctor =
64  M.getOrInsertFunction(F->getName(), IRB.getVoidTy());
65  IRB.CreateCall(Ctor);
66  }
67  }
68  appendToUsed(M, {InitOrFiniKernel});
69  return true;
70  }
71 
72  static char ID;
73  AMDGPUCtorDtorLowering() : ModulePass(ID) {}
74 };
75 } // End anonymous namespace
76 
79 INITIALIZE_PASS(AMDGPUCtorDtorLowering, DEBUG_TYPE,
80  "Lower ctors and dtors for AMDGPU", false, false)
81 
83  return new AMDGPUCtorDtorLowering();
84 }
85 
86 bool AMDGPUCtorDtorLowering::runOnModule(Module &M) {
87  bool Modified = false;
88  Modified |=
89  createInitOrFiniKernel(M, M.getGlobalVariable("llvm.global_ctors"),
90  /*IsCtor =*/true);
91  Modified |=
92  createInitOrFiniKernel(M, M.getGlobalVariable("llvm.global_dtors"),
93  /*IsCtor =*/false);
94  return Modified;
95 }
llvm::createAMDGPUCtorDtorLoweringPass
ModulePass * createAMDGPUCtorDtorLoweringPass()
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::User::operands
op_range operands()
Definition: User.h:242
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
llvm::Function
Definition: Function.h:60
Pass.h
INITIALIZE_PASS
INITIALIZE_PASS(AMDGPUCtorDtorLowering, DEBUG_TYPE, "Lower ctors and dtors for AMDGPU", false, false) ModulePass *llvm
Definition: AMDGPUCtorDtorLowering.cpp:79
llvm::Function::getEntryBlock
const BasicBlock & getEntryBlock() const
Definition: Function.h:710
llvm::IRBuilder<>
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:361
Module.h
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::GlobalVariable::hasInitializer
bool hasInitializer() const
Definitions have initializers, declarations don't.
Definition: GlobalVariable.h:91
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
Constants.h
llvm::ConstantArray
ConstantArray - Constant Array Declarations.
Definition: Constants.h:410
LoopDeletionResult::Modified
@ Modified
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition: GlobalVariable.h:135
llvm::appendToUsed
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
Definition: ModuleUtils.cpp:105
IRBuilder.h
llvm::AMDGPUCtorDtorLoweringID
char & AMDGPUCtorDtorLoweringID
Definition: AMDGPUCtorDtorLowering.cpp:78
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::Function::createWithDefaultAttr
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 applied.
Definition: Function.cpp:336
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
AMDGPU.h
llvm::Function::setCallingConv
void setCallingConv(CallingConv::ID CC)
Definition: Function.h:242
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:97
llvm::CallingConv::AMDGPU_KERNEL
@ AMDGPU_KERNEL
Calling convention for AMDGPU code object kernels.
Definition: CallingConv.h:216
GlobalVariable.h
Function.h
llvm::ReturnInst::Create
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Definition: Instructions.h:3031
DEBUG_TYPE
#define DEBUG_TYPE
Definition: AMDGPUCtorDtorLowering.cpp:25
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:222
llvm::User::getNumOperands
unsigned getNumOperands() const
Definition: User.h:191
ModuleUtils.h
llvm::Function::addFnAttr
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:535
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
llvm::BasicBlock::getTerminator
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:119
llvm::IRBuilderBase::getVoidTy
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:539
Value.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::IRBuilderBase::CreateCall
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2235
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38