LLVM  10.0.0svn
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,
48  IRBuilder<> &Builder);
49  Value *remapConstantVectorOrConstantAggregate(Module *M, Function *F,
50  Constant *C,
51  IRBuilder<> &Builder);
52  Value *remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
53  IRBuilder<> &Builder);
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 = 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(
196  Module *M, Function *F, Constant *C, IRBuilder<> &Builder) {
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) {
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 }
Value * CreateInBoundsGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
Definition: IRBuilder.h:1696
uint64_t CallInst * C
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:258
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2198
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
Definition: Constants.h:1209
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1458
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1963
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:256
bool isTexture(const Value &val)
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:632
F(f)
ModulePass * createGenericToNVVMPass()
unsigned getPredicate() const
Return the ICMP or FCMP predicate value.
Definition: Constants.cpp:1206
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:450
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:244
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:779
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:285
INITIALIZE_PASS(GenericToNVVM, "generic-to-nvvm", "Ensure that the global variables are in the global address space", false, false) bool GenericToNVVM
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:888
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
bool isSurface(const Value &val)
LinkageTypes getLinkage() const
Definition: GlobalValue.h:460
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:429
bool isSampler(const Value &val)
Value * getOperand(unsigned i) const
Definition: User.h:169
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Definition: Constant.h:41
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition: IRBuilder.h:2271
void eraseFromParent()
eraseFromParent - This method unlinks &#39;this&#39; from the containing module and deletes it...
Definition: Globals.cpp:384
Represent the analysis usage information of a pass.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:732
bool isBinaryOp() const
Definition: Instruction.h:130
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:572
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2293
static UndefValue * get(Type *T)
Static factory methods - Return an &#39;undef&#39; object of the specified type.
Definition: Constants.cpp:1433
bool isCast() const
Definition: Instruction.h:133
void initializeGenericToNVVMPass(PassRegistry &)
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2335
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Value * CreateGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
Definition: IRBuilder.h:1677
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
Definition: Constants.cpp:1605
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
Definition: User.h:191
See the file comment.
Definition: ValueMap.h:85
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
Module.h This file contains the declarations for the Module class.
Value * CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2306
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition: IRBuilder.h:2320
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:640
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:175
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
void copyAttributesFrom(const GlobalVariable *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a GlobalVariable) fro...
Definition: Globals.cpp:411
#define I(x, y, z)
Definition: MD5.cpp:58
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:224
Type * getValueType() const
Definition: GlobalValue.h:279
ArrayRef< unsigned > getIndices() const
Assert that this is an insertvalue or exactvalue expression and return the list of indices...
Definition: Constants.cpp:1198
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1995
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
bool hasInitializer() const
Definitions have initializers, declarations don&#39;t.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2343
for(unsigned i=Desc.getNumOperands(), e=OldMI.getNumOperands();i !=e;++i)
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:277