|
14 | 14 | #include "llvm/IR/GlobalVariable.h"
|
15 | 15 | #include "llvm/IR/IRBuilder.h"
|
16 | 16 | #include "llvm/IR/InstVisitor.h"
|
| 17 | +#include "llvm/IR/Instructions.h" |
17 | 18 | #include "llvm/IR/Module.h"
|
18 | 19 | #include "llvm/IR/Operator.h"
|
19 | 20 | #include "llvm/IR/PassManager.h"
|
20 | 21 | #include "llvm/IR/ReplaceConstant.h"
|
21 | 22 | #include "llvm/IR/Type.h"
|
| 23 | +#include "llvm/Support/Casting.h" |
22 | 24 | #include "llvm/Transforms/Utils/Cloning.h"
|
23 | 25 | #include "llvm/Transforms/Utils/Local.h"
|
24 | 26 |
|
@@ -127,71 +129,75 @@ bool DataScalarizerVisitor::visitAllocaInst(AllocaInst &AI) {
|
127 | 129 | }
|
128 | 130 |
|
129 | 131 | bool DataScalarizerVisitor::visitLoadInst(LoadInst &LI) {
|
130 |
| - unsigned NumOperands = LI.getNumOperands(); |
131 |
| - for (unsigned I = 0; I < NumOperands; ++I) { |
132 |
| - Value *CurrOpperand = LI.getOperand(I); |
133 |
| - ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand); |
134 |
| - if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
135 |
| - GetElementPtrInst *OldGEP = |
136 |
| - cast<GetElementPtrInst>(CE->getAsInstruction()); |
137 |
| - OldGEP->insertBefore(LI.getIterator()); |
138 |
| - IRBuilder<> Builder(&LI); |
139 |
| - LoadInst *NewLoad = |
140 |
| - Builder.CreateLoad(LI.getType(), OldGEP, LI.getName()); |
141 |
| - NewLoad->setAlignment(LI.getAlign()); |
142 |
| - LI.replaceAllUsesWith(NewLoad); |
143 |
| - LI.eraseFromParent(); |
144 |
| - visitGetElementPtrInst(*OldGEP); |
145 |
| - return true; |
146 |
| - } |
147 |
| - if (GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand)) |
148 |
| - LI.setOperand(I, NewGlobal); |
| 132 | + Value *PtrOperand = LI.getPointerOperand(); |
| 133 | + ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand); |
| 134 | + if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
| 135 | + GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction()); |
| 136 | + OldGEP->insertBefore(LI.getIterator()); |
| 137 | + IRBuilder<> Builder(&LI); |
| 138 | + LoadInst *NewLoad = Builder.CreateLoad(LI.getType(), OldGEP, LI.getName()); |
| 139 | + NewLoad->setAlignment(LI.getAlign()); |
| 140 | + LI.replaceAllUsesWith(NewLoad); |
| 141 | + LI.eraseFromParent(); |
| 142 | + visitGetElementPtrInst(*OldGEP); |
| 143 | + return true; |
149 | 144 | }
|
| 145 | + if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand)) |
| 146 | + LI.setOperand(LI.getPointerOperandIndex(), NewGlobal); |
150 | 147 | return false;
|
151 | 148 | }
|
152 | 149 |
|
153 | 150 | bool DataScalarizerVisitor::visitStoreInst(StoreInst &SI) {
|
154 |
| - unsigned NumOperands = SI.getNumOperands(); |
155 |
| - for (unsigned I = 0; I < NumOperands; ++I) { |
156 |
| - Value *CurrOpperand = SI.getOperand(I); |
157 |
| - ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand); |
158 |
| - if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
159 |
| - GetElementPtrInst *OldGEP = |
160 |
| - cast<GetElementPtrInst>(CE->getAsInstruction()); |
161 |
| - OldGEP->insertBefore(SI.getIterator()); |
162 |
| - IRBuilder<> Builder(&SI); |
163 |
| - StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP); |
164 |
| - NewStore->setAlignment(SI.getAlign()); |
165 |
| - SI.replaceAllUsesWith(NewStore); |
166 |
| - SI.eraseFromParent(); |
167 |
| - visitGetElementPtrInst(*OldGEP); |
168 |
| - return true; |
169 |
| - } |
170 |
| - if (GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand)) |
171 |
| - SI.setOperand(I, NewGlobal); |
| 151 | + |
| 152 | + Value *PtrOperand = SI.getPointerOperand(); |
| 153 | + ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand); |
| 154 | + if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
| 155 | + GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction()); |
| 156 | + OldGEP->insertBefore(SI.getIterator()); |
| 157 | + IRBuilder<> Builder(&SI); |
| 158 | + StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP); |
| 159 | + NewStore->setAlignment(SI.getAlign()); |
| 160 | + SI.replaceAllUsesWith(NewStore); |
| 161 | + SI.eraseFromParent(); |
| 162 | + visitGetElementPtrInst(*OldGEP); |
| 163 | + return true; |
172 | 164 | }
|
| 165 | + if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand)) |
| 166 | + SI.setOperand(SI.getPointerOperandIndex(), NewGlobal); |
| 167 | + |
173 | 168 | return false;
|
174 | 169 | }
|
175 | 170 |
|
176 | 171 | bool DataScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
|
177 |
| - |
178 |
| - unsigned NumOperands = GEPI.getNumOperands(); |
179 |
| - GlobalVariable *NewGlobal = nullptr; |
180 |
| - for (unsigned I = 0; I < NumOperands; ++I) { |
181 |
| - Value *CurrOpperand = GEPI.getOperand(I); |
182 |
| - NewGlobal = lookupReplacementGlobal(CurrOpperand); |
183 |
| - if (NewGlobal) |
184 |
| - break; |
| 172 | + Value *PtrOperand = GEPI.getPointerOperand(); |
| 173 | + Type *OrigGEPType = GEPI.getPointerOperandType(); |
| 174 | + Type *NewGEPType = OrigGEPType; |
| 175 | + bool NeedsTransform = false; |
| 176 | + |
| 177 | + if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand)) { |
| 178 | + NewGEPType = NewGlobal->getValueType(); |
| 179 | + PtrOperand = NewGlobal; |
| 180 | + NeedsTransform = true; |
| 181 | + } else if (AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrOperand)) { |
| 182 | + Type *AllocatedType = Alloca->getAllocatedType(); |
| 183 | + // OrigGEPType might just be a pointer lets make sure |
| 184 | + // to add the allocated type so we have a size |
| 185 | + if (AllocatedType != OrigGEPType) { |
| 186 | + NewGEPType = AllocatedType; |
| 187 | + NeedsTransform = true; |
| 188 | + } |
185 | 189 | }
|
186 |
| - if (!NewGlobal) |
| 190 | + |
| 191 | + // Note: We bail if this isn't a gep touched via alloca or global |
| 192 | + // transformations |
| 193 | + if (!NeedsTransform) |
187 | 194 | return false;
|
188 | 195 |
|
189 | 196 | IRBuilder<> Builder(&GEPI);
|
190 | 197 | SmallVector<Value *, MaxVecSize> Indices(GEPI.indices());
|
191 | 198 |
|
192 |
| - Value *NewGEP = |
193 |
| - Builder.CreateGEP(NewGlobal->getValueType(), NewGlobal, Indices, |
194 |
| - GEPI.getName(), GEPI.getNoWrapFlags()); |
| 199 | + Value *NewGEP = Builder.CreateGEP(NewGEPType, PtrOperand, Indices, |
| 200 | + GEPI.getName(), GEPI.getNoWrapFlags()); |
195 | 201 | GEPI.replaceAllUsesWith(NewGEP);
|
196 | 202 | GEPI.eraseFromParent();
|
197 | 203 | return true;
|
|
0 commit comments