LLVM  14.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 (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) {
78  if (GV.getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
79  !llvm::isTexture(GV) && !llvm::isSurface(GV) && !llvm::isSampler(GV) &&
80  !GV.getName().startswith("llvm.")) {
81  GlobalVariable *NewGV = new GlobalVariable(
82  M, GV.getValueType(), GV.isConstant(), GV.getLinkage(),
83  GV.hasInitializer() ? GV.getInitializer() : nullptr, "", &GV,
84  GV.getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
85  NewGV->copyAttributesFrom(&GV);
86  GVMap[&GV] = NewGV;
87  }
88  }
89 
90  // Return immediately, if every global variable has a specific address space
91  // specifier.
92  if (GVMap.empty()) {
93  return false;
94  }
95 
96  // Walk through the instructions in function defitinions, and replace any use
97  // of original global variables in GVMap with a use of the corresponding
98  // copies in GVMap. If necessary, promote constants to instructions.
99  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
100  if (I->isDeclaration()) {
101  continue;
102  }
103  IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
104  for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
105  ++BBI) {
106  for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
107  ++II) {
108  for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
109  Value *Operand = II->getOperand(i);
110  if (isa<Constant>(Operand)) {
111  II->setOperand(
112  i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
113  }
114  }
115  }
116  }
117  ConstantToValueMap.clear();
118  }
119 
120  // Copy GVMap over to a standard value map.
122  for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
123  VM[I->first] = I->second;
124 
125  // Walk through the global variable initializers, and replace any use of
126  // original global variables in GVMap with a use of the corresponding copies
127  // in GVMap. The copies need to be bitcast to the original global variable
128  // types, as we cannot use cvta in global variable initializers.
129  for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
130  GlobalVariable *GV = I->first;
131  GlobalVariable *NewGV = I->second;
132 
133  // Remove GV from the map so that it can be RAUWed. Note that
134  // DenseMap::erase() won't invalidate any iterators but this one.
135  auto Next = std::next(I);
136  GVMap.erase(I);
137  I = Next;
138 
139  Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
140  // At this point, the remaining uses of GV should be found only in global
141  // variable initializers, as other uses have been already been removed
142  // while walking through the instructions in function definitions.
143  GV->replaceAllUsesWith(BitCastNewGV);
144  std::string Name = std::string(GV->getName());
145  GV->eraseFromParent();
146  NewGV->setName(Name);
147  }
148  assert(GVMap.empty() && "Expected it to be empty by now");
149 
150  return true;
151 }
152 
153 Value *GenericToNVVM::remapConstant(Module *M, Function *F, Constant *C,
154  IRBuilder<> &Builder) {
155  // If the constant C has been converted already in the given function F, just
156  // return the converted value.
157  ConstantToValueMapTy::iterator CTII = ConstantToValueMap.find(C);
158  if (CTII != ConstantToValueMap.end()) {
159  return CTII->second;
160  }
161 
162  Value *NewValue = C;
163  if (isa<GlobalVariable>(C)) {
164  // If the constant C is a global variable and is found in GVMap, substitute
165  //
166  // addrspacecast GVMap[C] to addrspace(0)
167  //
168  // for our use of C.
169  GVMapTy::iterator I = GVMap.find(cast<GlobalVariable>(C));
170  if (I != GVMap.end()) {
171  GlobalVariable *GV = I->second;
172  NewValue = Builder.CreateAddrSpaceCast(
173  GV,
175  }
176  } else if (isa<ConstantAggregate>(C)) {
177  // If any element in the constant vector or aggregate C is or uses a global
178  // variable in GVMap, the constant C needs to be reconstructed, using a set
179  // of instructions.
180  NewValue = remapConstantVectorOrConstantAggregate(M, F, C, Builder);
181  } else if (isa<ConstantExpr>(C)) {
182  // If any operand in the constant expression C is or uses a global variable
183  // in GVMap, the constant expression C needs to be reconstructed, using a
184  // set of instructions.
185  NewValue = remapConstantExpr(M, F, cast<ConstantExpr>(C), Builder);
186  }
187 
188  ConstantToValueMap[C] = NewValue;
189  return NewValue;
190 }
191 
192 Value *GenericToNVVM::remapConstantVectorOrConstantAggregate(
194  bool OperandChanged = false;
195  SmallVector<Value *, 4> NewOperands;
196  unsigned NumOperands = C->getNumOperands();
197 
198  // Check if any element is or uses a global variable in GVMap, and thus
199  // converted to another value.
200  for (unsigned i = 0; i < NumOperands; ++i) {
201  Value *Operand = C->getOperand(i);
202  Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder);
203  OperandChanged |= Operand != NewOperand;
204  NewOperands.push_back(NewOperand);
205  }
206 
207  // If none of the elements has been modified, return C as it is.
208  if (!OperandChanged) {
209  return C;
210  }
211 
212  // If any of the elements has been modified, construct the equivalent
213  // vector or aggregate value with a set instructions and the converted
214  // elements.
215  Value *NewValue = UndefValue::get(C->getType());
216  if (isa<ConstantVector>(C)) {
217  for (unsigned i = 0; i < NumOperands; ++i) {
218  Value *Idx = ConstantInt::get(Type::getInt32Ty(M->getContext()), i);
219  NewValue = Builder.CreateInsertElement(NewValue, NewOperands[i], Idx);
220  }
221  } else {
222  for (unsigned i = 0; i < NumOperands; ++i) {
223  NewValue =
224  Builder.CreateInsertValue(NewValue, NewOperands[i], makeArrayRef(i));
225  }
226  }
227 
228  return NewValue;
229 }
230 
231 Value *GenericToNVVM::remapConstantExpr(Module *M, Function *F, ConstantExpr *C,
232  IRBuilder<> &Builder) {
233  bool OperandChanged = false;
234  SmallVector<Value *, 4> NewOperands;
235  unsigned NumOperands = C->getNumOperands();
236 
237  // Check if any operand is or uses a global variable in GVMap, and thus
238  // converted to another value.
239  for (unsigned i = 0; i < NumOperands; ++i) {
240  Value *Operand = C->getOperand(i);
241  Value *NewOperand = remapConstant(M, F, cast<Constant>(Operand), Builder);
242  OperandChanged |= Operand != NewOperand;
243  NewOperands.push_back(NewOperand);
244  }
245 
246  // If none of the operands has been modified, return C as it is.
247  if (!OperandChanged) {
248  return C;
249  }
250 
251  // If any of the operands has been modified, construct the instruction with
252  // the converted operands.
253  unsigned Opcode = C->getOpcode();
254  switch (Opcode) {
255  case Instruction::ICmp:
256  // CompareConstantExpr (icmp)
257  return Builder.CreateICmp(CmpInst::Predicate(C->getPredicate()),
258  NewOperands[0], NewOperands[1]);
259  case Instruction::FCmp:
260  // CompareConstantExpr (fcmp)
261  llvm_unreachable("Address space conversion should have no effect "
262  "on float point CompareConstantExpr (fcmp)!");
263  case Instruction::ExtractElement:
264  // ExtractElementConstantExpr
265  return Builder.CreateExtractElement(NewOperands[0], NewOperands[1]);
266  case Instruction::InsertElement:
267  // InsertElementConstantExpr
268  return Builder.CreateInsertElement(NewOperands[0], NewOperands[1],
269  NewOperands[2]);
270  case Instruction::ShuffleVector:
271  // ShuffleVector
272  return Builder.CreateShuffleVector(NewOperands[0], NewOperands[1],
273  NewOperands[2]);
274  case Instruction::ExtractValue:
275  // ExtractValueConstantExpr
276  return Builder.CreateExtractValue(NewOperands[0], C->getIndices());
277  case Instruction::InsertValue:
278  // InsertValueConstantExpr
279  return Builder.CreateInsertValue(NewOperands[0], NewOperands[1],
280  C->getIndices());
281  case Instruction::GetElementPtr:
282  // GetElementPtrConstantExpr
283  return cast<GEPOperator>(C)->isInBounds()
284  ? Builder.CreateGEP(
285  cast<GEPOperator>(C)->getSourceElementType(),
286  NewOperands[0],
287  makeArrayRef(&NewOperands[1], NumOperands - 1))
288  : Builder.CreateInBoundsGEP(
289  cast<GEPOperator>(C)->getSourceElementType(),
290  NewOperands[0],
291  makeArrayRef(&NewOperands[1], NumOperands - 1));
292  case Instruction::Select:
293  // SelectConstantExpr
294  return Builder.CreateSelect(NewOperands[0], NewOperands[1], NewOperands[2]);
295  default:
296  // BinaryConstantExpr
297  if (Instruction::isBinaryOp(Opcode)) {
298  return Builder.CreateBinOp(Instruction::BinaryOps(C->getOpcode()),
299  NewOperands[0], NewOperands[1]);
300  }
301  // UnaryConstantExpr
302  if (Instruction::isCast(Opcode)) {
303  return Builder.CreateCast(Instruction::CastOps(C->getOpcode()),
304  NewOperands[0], C->getType());
305  }
306  llvm_unreachable("GenericToNVVM encountered an unsupported ConstantExpr");
307  }
308 }
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
---------------------— PointerInfo ------------------------------------—
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:720
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::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:691
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
Module.h
Operator.h
LegacyPassManager.h
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:203
llvm::isTexture
bool isTexture(const Value &val)
Definition: NVPTXUtilities.cpp:133
F
#define F(x, y, z)
Definition: MD5.cpp:56
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:2020
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::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::Instruction::CastOps
CastOps
Definition: Instruction.h:799
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:38
llvm::Value::setName
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:376
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1771
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:900
llvm::ARM_PROC::IE
@ IE
Definition: ARMBaseInfo.h:27
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
llvm::make_early_inc_range
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:576
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:532
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:309
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:936
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:476
llvm::Instruction::BinaryOps
BinaryOps
Definition: Instruction.h:785
Instructions.h
llvm::createGenericToNVVMPass
ModulePass * createGenericToNVVMPass()
Definition: NVPTXGenericToNVVM.cpp:64
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:67
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37