LLVM  13.0.0git
NVPTXGenericToNVVM.cpp
Go to the documentation of this file.
1 //===-- GenericToNVVM.cpp - Convert generic module to NVVM module - C++ -*-===//
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 // Convert generic global variables into either .global or .const access based
10 // on the variable's "constant" qualifier.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "NVPTX.h"
16 #include "NVPTXUtilities.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/Instructions.h"
22 #include "llvm/IR/Intrinsics.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/Operator.h"
26 #include "llvm/IR/ValueMap.h"
28 
29 using namespace llvm;
30 
31 namespace llvm {
33 }
34 
35 namespace {
36 class GenericToNVVM : public ModulePass {
37 public:
38  static char ID;
39 
40  GenericToNVVM() : ModulePass(ID) {}
41 
42  bool runOnModule(Module &M) override;
43 
44  void getAnalysisUsage(AnalysisUsage &AU) const override {}
45 
46 private:
47  Value *remapConstant(Module *M, Function *F, Constant *C,
49  Value *remapConstantVectorOrConstantAggregate(Module *M, Function *F,
50  Constant *C,
52  Value *remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
54 
56  typedef ValueMap<Constant *, Value *> ConstantToValueMapTy;
57  GVMapTy GVMap;
58  ConstantToValueMapTy ConstantToValueMap;
59 };
60 } // end namespace
61 
62 char GenericToNVVM::ID = 0;
63 
64 ModulePass *llvm::createGenericToNVVMPass() { return new GenericToNVVM(); }
65 
67  GenericToNVVM, "generic-to-nvvm",
68  "Ensure that the global variables are in the global address space", false,
69  false)
70 
71 bool GenericToNVVM::runOnModule(Module &M) {
72  // Create a clone of each global variable that has the default address space.
73  // The clone is created with the global address space specifier, and the pair
74  // of original global variable and its clone is placed in the GVMap for later
75  // use.
76 
77  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
78  I != E;) {
79  GlobalVariable *GV = &*I++;
81  !llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
82  !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
83  GlobalVariable *NewGV = new GlobalVariable(
84  M, GV->getValueType(), GV->isConstant(),
85  GV->getLinkage(),
86  GV->hasInitializer() ? GV->getInitializer() : nullptr,
88  NewGV->copyAttributesFrom(GV);
89  GVMap[GV] = NewGV;
90  }
91  }
92 
93  // Return immediately, if every global variable has a specific address space
94  // specifier.
95  if (GVMap.empty()) {
96  return false;
97  }
98 
99  // Walk through the instructions in function defitinions, and replace any use
100  // of original global variables in GVMap with a use of the corresponding
101  // copies in GVMap. If necessary, promote constants to instructions.
102  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
103  if (I->isDeclaration()) {
104  continue;
105  }
106  IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
107  for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
108  ++BBI) {
109  for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
110  ++II) {
111  for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
112  Value *Operand = II->getOperand(i);
113  if (isa<Constant>(Operand)) {
114  II->setOperand(
115  i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
116  }
117  }
118  }
119  }
120  ConstantToValueMap.clear();
121  }
122 
123  // Copy GVMap over to a standard value map.
125  for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
126  VM[I->first] = I->second;
127 
128  // Walk through the global variable initializers, and replace any use of
129  // original global variables in GVMap with a use of the corresponding copies
130  // in GVMap. The copies need to be bitcast to the original global variable
131  // types, as we cannot use cvta in global variable initializers.
132  for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
133  GlobalVariable *GV = I->first;
134  GlobalVariable *NewGV = I->second;
135 
136  // Remove GV from the map so that it can be RAUWed. Note that
137  // DenseMap::erase() won't invalidate any iterators but this one.
138  auto Next = std::next(I);
139  GVMap.erase(I);
140  I = Next;
141 
142  Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
143  // At this point, the remaining uses of GV should be found only in global
144  // variable initializers, as other uses have been already been removed
145  // while walking through the instructions in function definitions.
146  GV->replaceAllUsesWith(BitCastNewGV);
147  std::string Name = std::string(GV->getName());
148  GV->eraseFromParent();
149  NewGV->setName(Name);
150  }
151  assert(GVMap.empty() && "Expected it to be empty by now");
152 
153  return true;
154 }
155 
156 Value *GenericToNVVM::remapConstant(Module *M, Function *F, Constant *C,
157  IRBuilder<> &Builder) {
158  // If the constant C has been converted already in the given function F, just
159  // return the converted value.
160  ConstantToValueMapTy::iterator CTII = ConstantToValueMap.find(C);
161  if (CTII != ConstantToValueMap.end()) {
162  return CTII->second;
163  }
164 
165  Value *NewValue = C;
166  if (isa<GlobalVariable>(C)) {
167  // If the constant C is a global variable and is found in GVMap, substitute
168  //
169  // addrspacecast GVMap[C] to addrspace(0)
170  //
171  // for our use of C.
172  GVMapTy::iterator I = GVMap.find(cast<GlobalVariable>(C));
173  if (I != GVMap.end()) {
174  GlobalVariable *GV = I->second;
175  NewValue = Builder.CreateAddrSpaceCast(
176  GV,
178  }
179  } else if (isa<ConstantAggregate>(C)) {
180  // If any element in the constant vector or aggregate C is or uses a global
181  // variable in GVMap, the constant C needs to be reconstructed, using a set
182  // of instructions.
183  NewValue = remapConstantVectorOrConstantAggregate(M, F, C, Builder);
184  } else if (isa<ConstantExpr>(C)) {
185  // If any operand in the constant expression C is or uses a global variable
186  // in GVMap, the constant expression C needs to be reconstructed, using a
187  // set of instructions.
188  NewValue = remapConstantExpr(M, F, cast<ConstantExpr>(C), Builder);
189  }
190 
191  ConstantToValueMap[C] = NewValue;
192  return NewValue;
193 }
194 
195 Value *GenericToNVVM::remapConstantVectorOrConstantAggregate(
197  bool OperandChanged = false;
198  SmallVector<Value *, 4> NewOperands;
199  unsigned NumOperands = C->getNumOperands();
200 
201  // Check if any element is or uses a global variable in GVMap, and thus
202  // converted to another value.
203  for (unsigned i = 0; i < NumOperands; ++i) {
204  Value *Operand = C->getOperand(i);
205  Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder);
206  OperandChanged |= Operand != NewOperand;
207  NewOperands.push_back(NewOperand);
208  }
209 
210  // If none of the elements has been modified, return C as it is.
211  if (!OperandChanged) {
212  return C;
213  }
214 
215  // If any of the elements has been modified, construct the equivalent
216  // vector or aggregate value with a set instructions and the converted
217  // elements.
218  Value *NewValue = UndefValue::get(C->getType());
219  if (isa<ConstantVector>(C)) {
220  for (unsigned i = 0; i < NumOperands; ++i) {
221  Value *Idx = ConstantInt::get(Type::getInt32Ty(M->getContext()), i);
222  NewValue = Builder.CreateInsertElement(NewValue, NewOperands[i], Idx);
223  }
224  } else {
225  for (unsigned i = 0; i < NumOperands; ++i) {
226  NewValue =
227  Builder.CreateInsertValue(NewValue, NewOperands[i], makeArrayRef(i));
228  }
229  }
230 
231  return NewValue;
232 }
233 
234 Value *GenericToNVVM::remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
235  IRBuilder<> &Builder) {
236  bool OperandChanged = false;
237  SmallVector<Value *, 4> NewOperands;
238  unsigned NumOperands = C->getNumOperands();
239 
240  // Check if any operand is or uses a global variable in GVMap, and thus
241  // converted to another value.
242  for (unsigned i = 0; i < NumOperands; ++i) {
243  Value *Operand = C->getOperand(i);
244  Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder);
245  OperandChanged |= Operand != NewOperand;
246  NewOperands.push_back(NewOperand);
247  }
248 
249  // If none of the operands has been modified, return C as it is.
250  if (!OperandChanged) {
251  return C;
252  }
253 
254  // If any of the operands has been modified, construct the instruction with
255  // the converted operands.
256  unsigned Opcode = C->getOpcode();
257  switch (Opcode) {
258  case Instruction::ICmp:
259  // CompareConstantExpr (icmp)
260  return Builder.CreateICmp(CmpInst::Predicate(C->getPredicate()),
261  NewOperands[0], NewOperands[1]);
262  case Instruction::FCmp:
263  // CompareConstantExpr (fcmp)
264  llvm_unreachable("Address space conversion should have no effect "
265  "on float point CompareConstantExpr (fcmp)!");
266  case Instruction::ExtractElement:
267  // ExtractElementConstantExpr
268  return Builder.CreateExtractElement(NewOperands[0], NewOperands[1]);
269  case Instruction::InsertElement:
270  // InsertElementConstantExpr
271  return Builder.CreateInsertElement(NewOperands[0], NewOperands[1],
272  NewOperands[2]);
273  case Instruction::ShuffleVector:
274  // ShuffleVector
275  return Builder.CreateShuffleVector(NewOperands[0], NewOperands[1],
276  NewOperands[2]);
277  case Instruction::ExtractValue:
278  // ExtractValueConstantExpr
279  return Builder.CreateExtractValue(NewOperands[0], C->getIndices());
280  case Instruction::InsertValue:
281  // InsertValueConstantExpr
282  return Builder.CreateInsertValue(NewOperands[0], NewOperands[1],
283  C->getIndices());
284  case Instruction::GetElementPtr:
285  // GetElementPtrConstantExpr
286  return cast<GEPOperator>(C)->isInBounds()
287  ? Builder.CreateGEP(
288  cast<GEPOperator>(C)->getSourceElementType(),
289  NewOperands[0],
290  makeArrayRef(&NewOperands[1], NumOperands - 1))
291  : Builder.CreateInBoundsGEP(
292  cast<GEPOperator>(C)->getSourceElementType(),
293  NewOperands[0],
294  makeArrayRef(&NewOperands[1], NumOperands - 1));
295  case Instruction::Select:
296  // SelectConstantExpr
297  return Builder.CreateSelect(NewOperands[0], NewOperands[1], NewOperands[2]);
298  default:
299  // BinaryConstantExpr
300  if (Instruction::isBinaryOp(Opcode)) {
301  return Builder.CreateBinOp(Instruction::BinaryOps(C->getOpcode()),
302  NewOperands[0], NewOperands[1]);
303  }
304  // UnaryConstantExpr
305  if (Instruction::isCast(Opcode)) {
306  return Builder.CreateCast(Instruction::CastOps(C->getOpcode()),
307  NewOperands[0], C->getType());
308  }
309  llvm_unreachable("GenericToNVVM encountered an unsupported ConstantExpr");
310  }
311 }
i
i
Definition: README.txt:29
ValueTypes.h
llvm::GlobalVariable::eraseFromParent
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Globals.cpp:385
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:289
llvm
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
ValueMapper.h
llvm::CmpInst::Predicate
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:722
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:90
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::Module::iterator
FunctionListType::iterator iterator
The Function iterators.
Definition: Module.h:92
llvm::GlobalVariable::copyAttributesFrom
void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
Definition: Globals.cpp:412
llvm::GlobalValue::getLinkage
LinkageTypes getLinkage() const
Definition: GlobalValue.h:461
llvm::Function
Definition: Function.h:61
llvm::Instruction::isCast
bool isCast() const
Definition: Instruction.h:168
llvm::PointerType::get
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
Definition: Type.cpp:687
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::IRBuilder<>
llvm::GlobalVariable
Definition: GlobalVariable.h:40
llvm::PointerType::getAddressSpace
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:662
Module.h
Operator.h
LegacyPassManager.h
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:197
llvm::isTexture
bool isTexture(const Value &val)
Definition: NVPTXUtilities.cpp:133
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::GlobalVariable::hasInitializer
bool hasInitializer() const
Definitions have initializers, declarations don't.
Definition: GlobalVariable.h:92
NVPTX.h
llvm::ConstantExpr::getPointerCast
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
Definition: Constants.cpp:2019
llvm::isSampler
bool isSampler(const Value &val)
Definition: NVPTXUtilities.cpp:155
NVPTXUtilities.h
Constants.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::ADDRESS_SPACE_GLOBAL
@ ADDRESS_SPACE_GLOBAL
Definition: NVPTXBaseInfo.h:23
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::GlobalValue::getThreadLocalMode
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:252
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::Instruction::CastOps
CastOps
Definition: Instruction.h:782
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::Module::global_iterator
GlobalListType::iterator global_iterator
The Global Variable iterator.
Definition: Module.h:87
llvm::Value::setName
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:371
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1770
llvm::ConstantInt::get
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:885
llvm::ARM_PROC::IE
@ IE
Definition: ARMBaseInfo.h:27
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition: GlobalVariable.h:136
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
NVPTXBaseInfo.h
I
#define I(x, y, z)
Definition: MD5.cpp:59
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Instruction::isBinaryOp
bool isBinaryOp() const
Definition: Instruction.h:165
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
INITIALIZE_PASS
INITIALIZE_PASS(GenericToNVVM, "generic-to-nvvm", "Ensure that the global variables are in the global address space", false, false) bool GenericToNVVM
Definition: NVPTXGenericToNVVM.cpp:66
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:527
llvm::ADDRESS_SPACE_GENERIC
@ ADDRESS_SPACE_GENERIC
Definition: NVPTXBaseInfo.h:22
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:299
llvm::ValueMap
See the file comment.
Definition: ValueMap.h:85
ValueMap.h
llvm::initializeGenericToNVVMPass
void initializeGenericToNVVMPass(PassRegistry &)
llvm::MCID::Select
@ Select
Definition: MCInstrDesc.h:162
llvm::ConstantExpr
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:931
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::isSurface
bool isSurface(const Value &val)
Definition: NVPTXUtilities.cpp:144
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:474
llvm::Instruction::BinaryOps
BinaryOps
Definition: Instruction.h:768
Instructions.h
llvm::createGenericToNVVMPass
ModulePass * createGenericToNVVMPass()
Definition: NVPTXGenericToNVVM.cpp:64
llvm::GlobalVariable::isConstant
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
Definition: GlobalVariable.h:153
llvm::GlobalValue::getType
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:271
DerivedTypes.h
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition: GlobalValue.h:273
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::Function::iterator
BasicBlockListType::iterator iterator
Definition: Function.h:66
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38