24
24
//
25
25
// ===----------------------------------------------------------------------===//
26
26
27
+ #include " MCTargetDesc/NVPTXBaseInfo.h"
27
28
#include " NVPTX.h"
28
29
#include " NVPTXUtilities.h"
29
- #include " MCTargetDesc/NVPTXBaseInfo.h"
30
30
#include " llvm/IR/Function.h"
31
31
#include " llvm/IR/Instructions.h"
32
32
#include " llvm/IR/IntrinsicInst.h"
@@ -55,8 +55,8 @@ class NVPTXLowerAlloca : public FunctionPass {
55
55
56
56
char NVPTXLowerAlloca::ID = 1 ;
57
57
58
- INITIALIZE_PASS (NVPTXLowerAlloca, " nvptx-lower-alloca" ,
59
- " Lower Alloca " , false , false )
58
+ INITIALIZE_PASS (NVPTXLowerAlloca, " nvptx-lower-alloca" , " Lower Alloca " , false ,
59
+ false )
60
60
61
61
// =============================================================================
62
62
// Main function for this pass.
@@ -70,14 +70,38 @@ bool NVPTXLowerAlloca::runOnFunction(Function &F) {
70
70
for (auto &I : BB) {
71
71
if (auto allocaInst = dyn_cast<AllocaInst>(&I)) {
72
72
Changed = true ;
73
+
74
+ PointerType *AllocInstPtrTy =
75
+ cast<PointerType>(allocaInst->getType ()->getScalarType ());
76
+ unsigned AllocAddrSpace = AllocInstPtrTy->getAddressSpace ();
77
+ assert ((AllocAddrSpace == ADDRESS_SPACE_GENERIC ||
78
+ AllocAddrSpace == ADDRESS_SPACE_LOCAL) &&
79
+ " AllocaInst can only be in Generic or Local address space for "
80
+ " NVPTX." );
81
+
82
+ Instruction *AllocaInLocalAS = allocaInst;
73
83
auto ETy = allocaInst->getAllocatedType ();
74
- auto LocalAddrTy = PointerType::get (ETy, ADDRESS_SPACE_LOCAL);
75
- auto NewASCToLocal = new AddrSpaceCastInst (allocaInst, LocalAddrTy, " " );
76
- auto GenericAddrTy = PointerType::get (ETy, ADDRESS_SPACE_GENERIC);
77
- auto NewASCToGeneric =
78
- new AddrSpaceCastInst (NewASCToLocal, GenericAddrTy, " " );
79
- NewASCToLocal->insertAfter (allocaInst);
80
- NewASCToGeneric->insertAfter (NewASCToLocal);
84
+
85
+ // We need to make sure that LLVM has info that alloca needs to go to
86
+ // ADDRESS_SPACE_LOCAL for InferAddressSpace pass.
87
+ //
88
+ // For allocas in ADDRESS_SPACE_LOCAL, we add addrspacecast to
89
+ // ADDRESS_SPACE_LOCAL and back to ADDRESS_SPACE_GENERIC, so that
90
+ // the alloca's users still use a generic pointer to operate on.
91
+ //
92
+ // For allocas already in ADDRESS_SPACE_LOCAL, we just need
93
+ // addrspacecast to ADDRESS_SPACE_GENERIC.
94
+ if (AllocAddrSpace == ADDRESS_SPACE_GENERIC) {
95
+ auto ASCastToLocalAS = new AddrSpaceCastInst (
96
+ allocaInst, PointerType::get (ETy, ADDRESS_SPACE_LOCAL), " " );
97
+ ASCastToLocalAS->insertAfter (allocaInst);
98
+ AllocaInLocalAS = ASCastToLocalAS;
99
+ }
100
+
101
+ auto AllocaInGenericAS = new AddrSpaceCastInst (
102
+ AllocaInLocalAS, PointerType::get (ETy, ADDRESS_SPACE_GENERIC), " " );
103
+ AllocaInGenericAS->insertAfter (AllocaInLocalAS);
104
+
81
105
for (Use &AllocaUse : llvm::make_early_inc_range (allocaInst->uses ())) {
82
106
// Check Load, Store, GEP, and BitCast Uses on alloca and make them
83
107
// use the converted generic address, in order to expose non-generic
@@ -87,23 +111,23 @@ bool NVPTXLowerAlloca::runOnFunction(Function &F) {
87
111
auto LI = dyn_cast<LoadInst>(AllocaUse.getUser ());
88
112
if (LI && LI->getPointerOperand () == allocaInst &&
89
113
!LI->isVolatile ()) {
90
- LI->setOperand (LI->getPointerOperandIndex (), NewASCToGeneric );
114
+ LI->setOperand (LI->getPointerOperandIndex (), AllocaInGenericAS );
91
115
continue ;
92
116
}
93
117
auto SI = dyn_cast<StoreInst>(AllocaUse.getUser ());
94
118
if (SI && SI->getPointerOperand () == allocaInst &&
95
119
!SI->isVolatile ()) {
96
- SI->setOperand (SI->getPointerOperandIndex (), NewASCToGeneric );
120
+ SI->setOperand (SI->getPointerOperandIndex (), AllocaInGenericAS );
97
121
continue ;
98
122
}
99
123
auto GI = dyn_cast<GetElementPtrInst>(AllocaUse.getUser ());
100
124
if (GI && GI->getPointerOperand () == allocaInst) {
101
- GI->setOperand (GI->getPointerOperandIndex (), NewASCToGeneric );
125
+ GI->setOperand (GI->getPointerOperandIndex (), AllocaInGenericAS );
102
126
continue ;
103
127
}
104
128
auto BI = dyn_cast<BitCastInst>(AllocaUse.getUser ());
105
129
if (BI && BI->getOperand (0 ) == allocaInst) {
106
- BI->setOperand (0 , NewASCToGeneric );
130
+ BI->setOperand (0 , AllocaInGenericAS );
107
131
continue ;
108
132
}
109
133
}
0 commit comments