89
89
//
90
90
// ===----------------------------------------------------------------------===//
91
91
92
- #include " NVPTX .h"
92
+ #include " llvm/Transforms/Scalar .h"
93
93
#include " llvm/ADT/DenseSet.h"
94
94
#include " llvm/ADT/Optional.h"
95
95
#include " llvm/ADT/SetVector.h"
103
103
#include " llvm/Transforms/Utils/Local.h"
104
104
#include " llvm/Transforms/Utils/ValueMapper.h"
105
105
106
- #define DEBUG_TYPE " nvptx- infer-addrspace "
106
+ #define DEBUG_TYPE " infer-address-spaces "
107
107
108
108
using namespace llvm ;
109
109
@@ -112,16 +112,16 @@ static const unsigned UnknownAddressSpace = ~0u;
112
112
113
113
using ValueToAddrSpaceMapTy = DenseMap<const Value *, unsigned >;
114
114
115
- // / \brief NVPTXInferAddressSpaces
116
- class NVPTXInferAddressSpaces : public FunctionPass {
115
+ // / \brief InferAddressSpaces
116
+ class InferAddressSpaces : public FunctionPass {
117
117
// / Target specific address space which uses of should be replaced if
118
118
// / possible.
119
119
unsigned FlatAddrSpace;
120
120
121
121
public:
122
122
static char ID;
123
123
124
- NVPTXInferAddressSpaces () : FunctionPass(ID) {}
124
+ InferAddressSpaces () : FunctionPass(ID) {}
125
125
126
126
void getAnalysisUsage (AnalysisUsage &AU) const override {
127
127
AU.setPreservesCFG ();
@@ -162,13 +162,13 @@ class NVPTXInferAddressSpaces: public FunctionPass {
162
162
};
163
163
} // end anonymous namespace
164
164
165
- char NVPTXInferAddressSpaces ::ID = 0 ;
165
+ char InferAddressSpaces ::ID = 0 ;
166
166
167
167
namespace llvm {
168
- void initializeNVPTXInferAddressSpacesPass (PassRegistry &);
168
+ void initializeInferAddressSpacesPass (PassRegistry &);
169
169
}
170
- INITIALIZE_PASS (NVPTXInferAddressSpaces, " nvptx-infer-addrspace " ,
171
- " Infer address spaces" ,
170
+
171
+ INITIALIZE_PASS (InferAddressSpaces, DEBUG_TYPE, " Infer address spaces" ,
172
172
false , false )
173
173
174
174
// Returns true if V is an address expression.
@@ -212,9 +212,9 @@ static SmallVector<Value *, 2> getPointerOperands(const Value &V) {
212
212
213
213
// If V is an unvisited flat address expression, appends V to PostorderStack
214
214
// and marks it as visited.
215
- void NVPTXInferAddressSpaces ::appendsFlatAddressExpressionToPostorderStack (
216
- Value *V, std::vector<std::pair<Value *, bool >> *PostorderStack,
217
- DenseSet<Value *> *Visited) const {
215
+ void InferAddressSpaces ::appendsFlatAddressExpressionToPostorderStack (
216
+ Value *V, std::vector<std::pair<Value *, bool >> *PostorderStack,
217
+ DenseSet<Value *> *Visited) const {
218
218
assert (V->getType ()->isPointerTy ());
219
219
if (isAddressExpression (*V) &&
220
220
V->getType ()->getPointerAddressSpace () == FlatAddrSpace) {
@@ -226,7 +226,7 @@ void NVPTXInferAddressSpaces::appendsFlatAddressExpressionToPostorderStack(
226
226
// Returns all flat address expressions in function F. The elements are ordered
227
227
// in postorder.
228
228
std::vector<Value *>
229
- NVPTXInferAddressSpaces ::collectFlatAddressExpressions (Function &F) const {
229
+ InferAddressSpaces ::collectFlatAddressExpressions (Function &F) const {
230
230
// This function implements a non-recursive postorder traversal of a partial
231
231
// use-def graph of function F.
232
232
std::vector<std::pair<Value*, bool >> PostorderStack;
@@ -237,10 +237,10 @@ NVPTXInferAddressSpaces::collectFlatAddressExpressions(Function &F) const {
237
237
for (Instruction &I : instructions (F)) {
238
238
if (isa<LoadInst>(I)) {
239
239
appendsFlatAddressExpressionToPostorderStack (
240
- I.getOperand (0 ), &PostorderStack, &Visited);
240
+ I.getOperand (0 ), &PostorderStack, &Visited);
241
241
} else if (isa<StoreInst>(I)) {
242
242
appendsFlatAddressExpressionToPostorderStack (
243
- I.getOperand (1 ), &PostorderStack, &Visited);
243
+ I.getOperand (1 ), &PostorderStack, &Visited);
244
244
}
245
245
}
246
246
@@ -257,7 +257,7 @@ NVPTXInferAddressSpaces::collectFlatAddressExpressions(Function &F) const {
257
257
PostorderStack.back ().second = true ;
258
258
for (Value *PtrOperand : getPointerOperands (*PostorderStack.back ().first )) {
259
259
appendsFlatAddressExpressionToPostorderStack (
260
- PtrOperand, &PostorderStack, &Visited);
260
+ PtrOperand, &PostorderStack, &Visited);
261
261
}
262
262
}
263
263
return Postorder;
@@ -267,16 +267,16 @@ NVPTXInferAddressSpaces::collectFlatAddressExpressions(Function &F) const {
267
267
// of OperandUse.get() in the new address space. If the clone is not ready yet,
268
268
// returns an undef in the new address space as a placeholder.
269
269
static Value *operandWithNewAddressSpaceOrCreateUndef (
270
- const Use &OperandUse, unsigned NewAddrSpace,
271
- const ValueToValueMapTy &ValueWithNewAddrSpace,
272
- SmallVectorImpl<const Use *> *UndefUsesToFix) {
270
+ const Use &OperandUse, unsigned NewAddrSpace,
271
+ const ValueToValueMapTy &ValueWithNewAddrSpace,
272
+ SmallVectorImpl<const Use *> *UndefUsesToFix) {
273
273
Value *Operand = OperandUse.get ();
274
274
if (Value *NewOperand = ValueWithNewAddrSpace.lookup (Operand))
275
275
return NewOperand;
276
276
277
277
UndefUsesToFix->push_back (&OperandUse);
278
278
return UndefValue::get (
279
- Operand->getType ()->getPointerElementType ()->getPointerTo (NewAddrSpace));
279
+ Operand->getType ()->getPointerElementType ()->getPointerTo (NewAddrSpace));
280
280
}
281
281
282
282
// Returns a clone of `I` with its operands converted to those specified in
@@ -289,11 +289,11 @@ static Value *operandWithNewAddressSpaceOrCreateUndef(
289
289
// from a pointer whose type already matches. Therefore, this function returns a
290
290
// Value* instead of an Instruction*.
291
291
static Value *cloneInstructionWithNewAddressSpace (
292
- Instruction *I, unsigned NewAddrSpace,
293
- const ValueToValueMapTy &ValueWithNewAddrSpace,
294
- SmallVectorImpl<const Use *> *UndefUsesToFix) {
292
+ Instruction *I, unsigned NewAddrSpace,
293
+ const ValueToValueMapTy &ValueWithNewAddrSpace,
294
+ SmallVectorImpl<const Use *> *UndefUsesToFix) {
295
295
Type *NewPtrType =
296
- I->getType ()->getPointerElementType ()->getPointerTo (NewAddrSpace);
296
+ I->getType ()->getPointerElementType ()->getPointerTo (NewAddrSpace);
297
297
298
298
if (I->getOpcode () == Instruction::AddrSpaceCast) {
299
299
Value *Src = I->getOperand (0 );
@@ -313,7 +313,7 @@ static Value *cloneInstructionWithNewAddressSpace(
313
313
NewPointerOperands.push_back (nullptr );
314
314
else
315
315
NewPointerOperands.push_back (operandWithNewAddressSpaceOrCreateUndef (
316
- OperandUse, NewAddrSpace, ValueWithNewAddrSpace, UndefUsesToFix));
316
+ OperandUse, NewAddrSpace, ValueWithNewAddrSpace, UndefUsesToFix));
317
317
}
318
318
319
319
switch (I->getOpcode ()) {
@@ -333,8 +333,8 @@ static Value *cloneInstructionWithNewAddressSpace(
333
333
case Instruction::GetElementPtr: {
334
334
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
335
335
GetElementPtrInst *NewGEP = GetElementPtrInst::Create (
336
- GEP->getSourceElementType (), NewPointerOperands[0 ],
337
- SmallVector<Value *, 4 >(GEP->idx_begin (), GEP->idx_end ()));
336
+ GEP->getSourceElementType (), NewPointerOperands[0 ],
337
+ SmallVector<Value *, 4 >(GEP->idx_begin (), GEP->idx_end ()));
338
338
NewGEP->setIsInBounds (GEP->isInBounds ());
339
339
return NewGEP;
340
340
}
@@ -347,10 +347,10 @@ static Value *cloneInstructionWithNewAddressSpace(
347
347
// constant expression `CE` with its operands replaced as specified in
348
348
// ValueWithNewAddrSpace.
349
349
static Value *cloneConstantExprWithNewAddressSpace (
350
- ConstantExpr *CE, unsigned NewAddrSpace,
351
- const ValueToValueMapTy &ValueWithNewAddrSpace) {
350
+ ConstantExpr *CE, unsigned NewAddrSpace,
351
+ const ValueToValueMapTy &ValueWithNewAddrSpace) {
352
352
Type *TargetType =
353
- CE->getType ()->getPointerElementType ()->getPointerTo (NewAddrSpace);
353
+ CE->getType ()->getPointerElementType ()->getPointerTo (NewAddrSpace);
354
354
355
355
if (CE->getOpcode () == Instruction::AddrSpaceCast) {
356
356
// Because CE is flat, the source address space must be specific.
@@ -382,8 +382,8 @@ static Value *cloneConstantExprWithNewAddressSpace(
382
382
// Needs to specify the source type while constructing a getelementptr
383
383
// constant expression.
384
384
return CE->getWithOperands (
385
- NewOperands, TargetType, /* OnlyIfReduced=*/ false ,
386
- NewOperands[0 ]->getType ()->getPointerElementType ());
385
+ NewOperands, TargetType, /* OnlyIfReduced=*/ false ,
386
+ NewOperands[0 ]->getType ()->getPointerElementType ());
387
387
}
388
388
389
389
return CE->getWithOperands (NewOperands, TargetType);
@@ -394,7 +394,7 @@ static Value *cloneConstantExprWithNewAddressSpace(
394
394
// expression whose address space needs to be modified, in postorder.
395
395
//
396
396
// See cloneInstructionWithNewAddressSpace for the meaning of UndefUsesToFix.
397
- Value *NVPTXInferAddressSpaces ::cloneValueWithNewAddressSpace (
397
+ Value *InferAddressSpaces ::cloneValueWithNewAddressSpace (
398
398
Value *V, unsigned NewAddrSpace,
399
399
const ValueToValueMapTy &ValueWithNewAddrSpace,
400
400
SmallVectorImpl<const Use *> *UndefUsesToFix) const {
@@ -404,7 +404,7 @@ Value *NVPTXInferAddressSpaces::cloneValueWithNewAddressSpace(
404
404
405
405
if (Instruction *I = dyn_cast<Instruction>(V)) {
406
406
Value *NewV = cloneInstructionWithNewAddressSpace (
407
- I, NewAddrSpace, ValueWithNewAddrSpace, UndefUsesToFix);
407
+ I, NewAddrSpace, ValueWithNewAddrSpace, UndefUsesToFix);
408
408
if (Instruction *NewI = dyn_cast<Instruction>(NewV)) {
409
409
if (NewI->getParent () == nullptr ) {
410
410
NewI->insertBefore (I);
@@ -415,13 +415,13 @@ Value *NVPTXInferAddressSpaces::cloneValueWithNewAddressSpace(
415
415
}
416
416
417
417
return cloneConstantExprWithNewAddressSpace (
418
- cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace);
418
+ cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace);
419
419
}
420
420
421
421
// Defines the join operation on the address space lattice (see the file header
422
422
// comments).
423
- unsigned NVPTXInferAddressSpaces ::joinAddressSpaces (unsigned AS1,
424
- unsigned AS2) const {
423
+ unsigned InferAddressSpaces ::joinAddressSpaces (unsigned AS1,
424
+ unsigned AS2) const {
425
425
if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
426
426
return FlatAddrSpace;
427
427
@@ -434,7 +434,7 @@ unsigned NVPTXInferAddressSpaces::joinAddressSpaces(unsigned AS1,
434
434
return (AS1 == AS2) ? AS1 : FlatAddrSpace;
435
435
}
436
436
437
- bool NVPTXInferAddressSpaces ::runOnFunction (Function &F) {
437
+ bool InferAddressSpaces ::runOnFunction (Function &F) {
438
438
if (skipFunction (F))
439
439
return false ;
440
440
@@ -456,9 +456,9 @@ bool NVPTXInferAddressSpaces::runOnFunction(Function &F) {
456
456
return rewriteWithNewAddressSpaces (Postorder, InferredAddrSpace, &F);
457
457
}
458
458
459
- void NVPTXInferAddressSpaces ::inferAddressSpaces (
460
- const std::vector<Value *> &Postorder,
461
- ValueToAddrSpaceMapTy *InferredAddrSpace) const {
459
+ void InferAddressSpaces ::inferAddressSpaces (
460
+ const std::vector<Value *> &Postorder,
461
+ ValueToAddrSpaceMapTy *InferredAddrSpace) const {
462
462
SetVector<Value *> Worklist (Postorder.begin (), Postorder.end ());
463
463
// Initially, all expressions are in the uninitialized address space.
464
464
for (Value *V : Postorder)
@@ -490,8 +490,8 @@ void NVPTXInferAddressSpaces::inferAddressSpaces(
490
490
continue ;
491
491
492
492
// Function updateAddressSpace moves the address space down a lattice
493
- // path. Therefore, nothing to do if User is already inferred as flat
494
- // (the bottom element in the lattice).
493
+ // path. Therefore, nothing to do if User is already inferred as flat (the
494
+ // bottom element in the lattice).
495
495
if (Pos->second == FlatAddrSpace)
496
496
continue ;
497
497
@@ -500,8 +500,8 @@ void NVPTXInferAddressSpaces::inferAddressSpaces(
500
500
}
501
501
}
502
502
503
- Optional<unsigned > NVPTXInferAddressSpaces ::updateAddressSpace (
504
- const Value &V, const ValueToAddrSpaceMapTy &InferredAddrSpace) const {
503
+ Optional<unsigned > InferAddressSpaces ::updateAddressSpace (
504
+ const Value &V, const ValueToAddrSpaceMapTy &InferredAddrSpace) const {
505
505
assert (InferredAddrSpace.count (&V));
506
506
507
507
// The new inferred address space equals the join of the address spaces
@@ -514,7 +514,8 @@ Optional<unsigned> NVPTXInferAddressSpaces::updateAddressSpace(
514
514
else
515
515
OperandAS = PtrOperand->getType ()->getPointerAddressSpace ();
516
516
NewAS = joinAddressSpaces (NewAS, OperandAS);
517
- // join(flat, *) = flat. So we can break if NewAS is already generic.
517
+
518
+ // join(flat, *) = flat. So we can break if NewAS is already flat.
518
519
if (NewAS == FlatAddrSpace)
519
520
break ;
520
521
}
@@ -526,9 +527,9 @@ Optional<unsigned> NVPTXInferAddressSpaces::updateAddressSpace(
526
527
return NewAS;
527
528
}
528
529
529
- bool NVPTXInferAddressSpaces ::rewriteWithNewAddressSpaces (
530
- const std::vector<Value *> &Postorder,
531
- const ValueToAddrSpaceMapTy &InferredAddrSpace, Function *F) const {
530
+ bool InferAddressSpaces ::rewriteWithNewAddressSpaces (
531
+ const std::vector<Value *> &Postorder,
532
+ const ValueToAddrSpaceMapTy &InferredAddrSpace, Function *F) const {
532
533
// For each address expression to be modified, creates a clone of it with its
533
534
// pointer operands converted to the new address space. Since the pointer
534
535
// operands are converted, the clone is naturally in the new address space by
@@ -539,7 +540,7 @@ bool NVPTXInferAddressSpaces::rewriteWithNewAddressSpaces(
539
540
unsigned NewAddrSpace = InferredAddrSpace.lookup (V);
540
541
if (V->getType ()->getPointerAddressSpace () != NewAddrSpace) {
541
542
ValueWithNewAddrSpace[V] = cloneValueWithNewAddressSpace (
542
- V, NewAddrSpace, ValueWithNewAddrSpace, &UndefUsesToFix);
543
+ V, NewAddrSpace, ValueWithNewAddrSpace, &UndefUsesToFix);
543
544
}
544
545
}
545
546
@@ -577,15 +578,15 @@ bool NVPTXInferAddressSpaces::rewriteWithNewAddressSpaces(
577
578
// so the resultant load/store is still valid.
578
579
U->set (NewV);
579
580
} else if (isa<Instruction>(U->getUser ())) {
580
- // Otherwise, replaces the use with generic (NewV).
581
+ // Otherwise, replaces the use with flat (NewV).
581
582
// TODO: Some optimization opportunities are missed. For example, in
582
583
// %0 = icmp eq float* %p, %q
583
584
// if both p and q are inferred to be shared, we can rewrite %0 as
584
585
// %0 = icmp eq float addrspace(3)* %new_p, %new_q
585
586
// instead of currently
586
- // %generic_p = addrspacecast float addrspace(3)* %new_p to float*
587
- // %generic_q = addrspacecast float addrspace(3)* %new_q to float*
588
- // %0 = icmp eq float* %generic_p , %generic_q
587
+ // %flat_p = addrspacecast float addrspace(3)* %new_p to float*
588
+ // %flat_q = addrspacecast float addrspace(3)* %new_q to float*
589
+ // %0 = icmp eq float* %flat_p , %flat_q
589
590
if (Instruction *I = dyn_cast<Instruction>(V)) {
590
591
BasicBlock::iterator InsertPos = std::next (I->getIterator ());
591
592
while (isa<PHINode>(InsertPos))
@@ -604,6 +605,6 @@ bool NVPTXInferAddressSpaces::rewriteWithNewAddressSpaces(
604
605
return true ;
605
606
}
606
607
607
- FunctionPass *llvm::createNVPTXInferAddressSpacesPass () {
608
- return new NVPTXInferAddressSpaces ();
608
+ FunctionPass *llvm::createInferAddressSpacesPass () {
609
+ return new InferAddressSpaces ();
609
610
}
0 commit comments