LLVM  14.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)
54  return false;
55  ConstantArray *GA = cast<ConstantArray>(GV->getInitializer());
56  if (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 file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
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:238
llvm::Function
Definition: Function.h:62
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:718
llvm::IRBuilder<>
llvm::GlobalVariable
Definition: GlobalVariable.h:40
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:363
Module.h
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
Constants.h
llvm::ConstantArray
ConstantArray - Constant Array Declarations.
Definition: Constants.h:409
LoopDeletionResult::Modified
@ Modified
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition: GlobalVariable.h:136
llvm::appendToUsed
void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
Definition: ModuleUtils.cpp:106
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:67
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:338
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:244
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
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.cpp:152
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:3013
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:224
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:536
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::IRBuilderBase::getVoidTy
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:556
Value.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::IRBuilderBase::CreateCall
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2395
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37