LLVM  8.0.1
NVPTXGenericToNVVM.cpp
Go to the documentation of this file.
1 //===-- GenericToNVVM.cpp - Convert generic module to NVVM module - C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Convert generic global variables into either .global or .const access based
11 // on the variable's "constant" qualifier.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "NVPTX.h"
17 #include "NVPTXUtilities.h"
19 #include "llvm/IR/Constants.h"
20 #include "llvm/IR/DerivedTypes.h"
21 #include "llvm/IR/IRBuilder.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/Intrinsics.h"
25 #include "llvm/IR/Module.h"
26 #include "llvm/IR/Operator.h"
27 #include "llvm/IR/ValueMap.h"
29 
30 using namespace llvm;
31 
32 namespace llvm {
34 }
35 
36 namespace {
37 class GenericToNVVM : public ModulePass {
38 public:
39  static char ID;
40 
41  GenericToNVVM() : ModulePass(ID) {}
42 
43  bool runOnModule(Module &M) override;
44 
45  void getAnalysisUsage(AnalysisUsage &AU) const override {}
46 
47 private:
48  Value *remapConstant(Module *M, Function *F, Constant *C,
49  IRBuilder<> &Builder);
50  Value *remapConstantVectorOrConstantAggregate(Module *M, Function *F,
51  Constant *C,
52  IRBuilder<> &Builder);
53  Value *remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
54  IRBuilder<> &Builder);
55 
57  typedef ValueMap<Constant *, Value *> ConstantToValueMapTy;
58  GVMapTy GVMap;
59  ConstantToValueMapTy ConstantToValueMap;
60 };
61 } // end namespace
62 
63 char GenericToNVVM::ID = 0;
64 
65 ModulePass *llvm::createGenericToNVVMPass() { return new GenericToNVVM(); }
66 
68  GenericToNVVM, "generic-to-nvvm",
69  "Ensure that the global variables are in the global address space", false,
70  false)
71 
72 bool GenericToNVVM::runOnModule(Module &M) {
73  // Create a clone of each global variable that has the default address space.
74  // The clone is created with the global address space specifier, and the pair
75  // of original global variable and its clone is placed in the GVMap for later
76  // use.
77 
78  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
79  I != E;) {
80  GlobalVariable *GV = &*I++;
82  !llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
83  !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
84  GlobalVariable *NewGV = new GlobalVariable(
85  M, GV->getValueType(), GV->isConstant(),
86  GV->getLinkage(),
87  GV->hasInitializer() ? GV->getInitializer() : nullptr,
89  NewGV->copyAttributesFrom(GV);
90  GVMap[GV] = NewGV;
91  }
92  }
93 
94  // Return immediately, if every global variable has a specific address space
95  // specifier.
96  if (GVMap.empty()) {
97  return false;
98  }
99 
100  // Walk through the instructions in function defitinions, and replace any use
101  // of original global variables in GVMap with a use of the corresponding
102  // copies in GVMap. If necessary, promote constants to instructions.
103  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
104  if (I->isDeclaration()) {
105  continue;
106  }
107  IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
108  for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
109  ++BBI) {
110  for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
111  ++II) {
112  for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
113  Value *Operand = II->getOperand(i);
114  if (isa<Constant>(Operand)) {
115  II->setOperand(
116  i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
117  }
118  }
119  }
120  }
121  ConstantToValueMap.clear();
122  }
123 
124  // Copy GVMap over to a standard value map.
126  for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
127  VM[I->first] = I->second;
128 
129  // Walk through the global variable initializers, and replace any use of
130  // original global variables in GVMap with a use of the corresponding copies
131  // in GVMap. The copies need to be bitcast to the original global variable
132  // types, as we cannot use cvta in global variable initializers.
133  for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
134  GlobalVariable *GV = I->first;
135  GlobalVariable *NewGV = I->second;
136 
137  // Remove GV from the map so that it can be RAUWed. Note that
138  // DenseMap::erase() won't invalidate any iterators but this one.
139  auto Next = std::next(I);
140  GVMap.erase(I);
141  I = Next;
142 
143  Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
144  // At this point, the remaining uses of GV should be found only in global
145  // variable initializers, as other uses have been already been removed
146  // while walking through the instructions in function definitions.
147  GV->replaceAllUsesWith(BitCastNewGV);
148  std::string Name = GV->getName();
149  GV->eraseFromParent();
150  NewGV->setName(Name);
151  }
152  assert(GVMap.empty() && "Expected it to be empty by now");
153 
154  return true;
155 }
156 
157 Value *GenericToNVVM::remapConstant(Module *M, Function *F, Constant *C,
158  IRBuilder<> &Builder) {
159  // If the constant C has been converted already in the given function F, just
160  // return the converted value.
161  ConstantToValueMapTy::iterator CTII = ConstantToValueMap.find(C);
162  if (CTII != ConstantToValueMap.end()) {
163  return CTII->second;
164  }
165 
166  Value *NewValue = C;
167  if (isa<GlobalVariable>(C)) {
168  // If the constant C is a global variable and is found in GVMap, substitute
169  //
170  // addrspacecast GVMap[C] to addrspace(0)
171  //
172  // for our use of C.
173  GVMapTy::iterator I = GVMap.find(cast<GlobalVariable>(C));
174  if (I != GVMap.end()) {
175  GlobalVariable *GV = I->second;
176  NewValue = Builder.CreateAddrSpaceCast(
177  GV,
179  }
180  } else if (isa<ConstantAggregate>(C)) {
181  // If any element in the constant vector or aggregate C is or uses a global
182  // variable in GVMap, the constant C needs to be reconstructed, using a set
183  // of instructions.
184  NewValue = remapConstantVectorOrConstantAggregate(M, F, C, Builder);
185  } else if (isa<ConstantExpr>(C)) {
186  // If any operand in the constant expression C is or uses a global variable
187  // in GVMap, the constant expression C needs to be reconstructed, using a
188  // set of instructions.
189  NewValue = remapConstantExpr(M, F, cast<ConstantExpr>(C), Builder);
190  }
191 
192  ConstantToValueMap[C] = NewValue;
193  return NewValue;
194 }
195 
196 Value *GenericToNVVM::remapConstantVectorOrConstantAggregate(
197  Module *M, Function *F, Constant *C, IRBuilder<> &Builder) {
198  bool OperandChanged = false;
199  SmallVector<Value *, 4> NewOperands;
200  unsigned NumOperands = C->getNumOperands();
201 
202  // Check if any element is or uses a global variable in GVMap, and thus
203  // converted to another value.
204  for (unsigned i = 0; i < NumOperands; ++i) {
205  Value *Operand = C->getOperand(i);
206  Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder);
207  OperandChanged |= Operand != NewOperand;
208  NewOperands.push_back(NewOperand);
209  }
210 
211  // If none of the elements has been modified, return C as it is.
212  if (!OperandChanged) {
213  return C;
214  }
215 
216  // If any of the elements has been modified, construct the equivalent
217  // vector or aggregate value with a set instructions and the converted
218  // elements.
219  Value *NewValue = UndefValue::get(C->getType());
220  if (isa<ConstantVector>(C)) {
221  for (unsigned i = 0; i < NumOperands; ++i) {
223  NewValue = Builder.CreateInsertElement(NewValue, NewOperands[i], Idx);
224  }
225  } else {
226  for (unsigned i = 0; i < NumOperands; ++i) {
227  NewValue =
228  Builder.CreateInsertValue(NewValue, NewOperands[i], makeArrayRef(i));
229  }
230  }
231 
232  return NewValue;
233 }
234 
235 Value *GenericToNVVM::remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
236  IRBuilder<> &Builder) {
237  bool OperandChanged = false;
238  SmallVector<Value *, 4> NewOperands;
239  unsigned NumOperands = C->getNumOperands();
240 
241  // Check if any operand is or uses a global variable in GVMap, and thus
242  // converted to another value.
243  for (unsigned i = 0; i < NumOperands; ++i) {
244  Value *Operand = C->getOperand(i);
245  Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder);
246  OperandChanged |= Operand != NewOperand;
247  NewOperands.push_back(NewOperand);
248  }
249 
250  // If none of the operands has been modified, return C as it is.
251  if (!OperandChanged) {
252  return C;
253  }
254 
255  // If any of the operands has been modified, construct the instruction with
256  // the converted operands.
257  unsigned Opcode = C->getOpcode();
258  switch (Opcode) {
259  case Instruction::ICmp:
260  // CompareConstantExpr (icmp)
261  return Builder.CreateICmp(CmpInst::Predicate(C->getPredicate()),
262  NewOperands[0], NewOperands[1]);
263  case Instruction::FCmp:
264  // CompareConstantExpr (fcmp)
265  llvm_unreachable("Address space conversion should have no effect "
266  "on float point CompareConstantExpr (fcmp)!");
267  case Instruction::ExtractElement:
268  // ExtractElementConstantExpr
269  return Builder.CreateExtractElement(NewOperands[0], NewOperands[1]);
270  case Instruction::InsertElement:
271  // InsertElementConstantExpr
272  return Builder.CreateInsertElement(NewOperands[0], NewOperands[1],
273  NewOperands[2]);
274  case Instruction::ShuffleVector:
275  // ShuffleVector
276  return Builder.CreateShuffleVector(NewOperands[0], NewOperands[1],
277  NewOperands[2]);
278  case Instruction::ExtractValue:
279  // ExtractValueConstantExpr
280  return Builder.CreateExtractValue(NewOperands[0], C->getIndices());
281  case Instruction::InsertValue:
282  // InsertValueConstantExpr
283  return Builder.CreateInsertValue(NewOperands[0], NewOperands[1],
284  C->getIndices());
285  case Instruction::GetElementPtr:
286  // GetElementPtrConstantExpr
287  return cast<GEPOperator>(C)->isInBounds()
288  ? Builder.CreateGEP(
289  cast<GEPOperator>(C)->getSourceElementType(),
290  NewOperands[0],
291  makeArrayRef(&NewOperands[1], NumOperands - 1))
292  : Builder.CreateInBoundsGEP(
293  cast<GEPOperator>(C)->getSourceElementType(),
294  NewOperands[0],
295  makeArrayRef(&NewOperands[1], NumOperands - 1));
296  case Instruction::Select:
297  // SelectConstantExpr
298  return Builder.CreateSelect(NewOperands[0], NewOperands[1], NewOperands[2]);
299  default:
300  // BinaryConstantExpr
301  if (Instruction::isBinaryOp(Opcode)) {
302  return Builder.CreateBinOp(Instruction::BinaryOps(C->getOpcode()),
303  NewOperands[0], NewOperands[1]);
304  }
305  // UnaryConstantExpr
306  if (Instruction::isCast(Opcode)) {
307  return Builder.CreateCast(Instruction::CastOps(C->getOpcode()),
308  NewOperands[0], C->getType());
309  }
310  llvm_unreachable("GenericToNVVM encountered an unsupported ConstantExpr");
311  }
312 }
Value * CreateInBoundsGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
Definition: IRBuilder.h:1477
uint64_t CallInst * C
ThreadLocalMode getThreadLocalMode() const
Definition: GlobalValue.h:255
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1949
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
Definition: Constants.h:1210
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1298
Value * CreateAddrSpaceCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1737
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
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:630
F(f)
ModulePass * createGenericToNVVMPass()
unsigned getPredicate() const
Return the ICMP or FCMP predicate value.
Definition: Constants.cpp:1188
amdgpu Simplify well known AMD library false Value Value const Twine & Name
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
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:743
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
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:889
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:451
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:170
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Definition: Constant.h:42
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:2021
void eraseFromParent()
eraseFromParent - This method unlinks &#39;this&#39; from the containing module and deletes it...
Definition: Globals.cpp:359
Represent the analysis usage information of a pass.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:646
bool isBinaryOp() const
Definition: Instruction.h:131
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:495
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2041
static UndefValue * get(Type *T)
Static factory methods - Return an &#39;undef&#39; object of the specified type.
Definition: Constants.cpp:1415
bool isCast() const
Definition: Instruction.h:134
void initializeGenericToNVVMPass(PassRegistry &)
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2083
#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:1458
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
Definition: Constants.cpp:1587
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
Definition: User.h:192
See the file comment.
Definition: ValueMap.h:86
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
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:2054
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition: IRBuilder.h:2068
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:622
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:176
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:386
#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:225
Type * getValueType() const
Definition: GlobalValue.h:276
ArrayRef< unsigned > getIndices() const
Assert that this is an insertvalue or exactvalue expression and return the list of indices...
Definition: Constants.cpp:1180
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1769
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:39
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2091
for(unsigned i=Desc.getNumOperands(), e=OldMI.getNumOperands();i !=e;++i)
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:274