|
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 |
|
@@ -137,49 +139,42 @@ bool DataScalarizerVisitor::visitAllocaInst(AllocaInst &AI) { |
137 | 139 | } |
138 | 140 |
|
139 | 141 | bool DataScalarizerVisitor::visitLoadInst(LoadInst &LI) { |
140 | | - unsigned NumOperands = LI.getNumOperands(); |
141 | | - for (unsigned I = 0; I < NumOperands; ++I) { |
142 | | - Value *CurrOpperand = LI.getOperand(I); |
143 | | - ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand); |
144 | | - if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
145 | | - GetElementPtrInst *OldGEP = |
146 | | - cast<GetElementPtrInst>(CE->getAsInstruction()); |
147 | | - OldGEP->insertBefore(LI.getIterator()); |
148 | | - IRBuilder<> Builder(&LI); |
149 | | - LoadInst *NewLoad = |
150 | | - Builder.CreateLoad(LI.getType(), OldGEP, LI.getName()); |
151 | | - NewLoad->setAlignment(LI.getAlign()); |
152 | | - LI.replaceAllUsesWith(NewLoad); |
153 | | - LI.eraseFromParent(); |
154 | | - visitGetElementPtrInst(*OldGEP); |
155 | | - return true; |
156 | | - } |
157 | | - if (GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand)) |
158 | | - LI.setOperand(I, NewGlobal); |
| 142 | + Value *PtrOperand = LI.getPointerOperand(); |
| 143 | + ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand); |
| 144 | + if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
| 145 | + GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction()); |
| 146 | + OldGEP->insertBefore(LI.getIterator()); |
| 147 | + IRBuilder<> Builder(&LI); |
| 148 | + LoadInst *NewLoad = Builder.CreateLoad(LI.getType(), OldGEP, LI.getName()); |
| 149 | + NewLoad->setAlignment(LI.getAlign()); |
| 150 | + LI.replaceAllUsesWith(NewLoad); |
| 151 | + LI.eraseFromParent(); |
| 152 | + visitGetElementPtrInst(*OldGEP); |
| 153 | + return true; |
159 | 154 | } |
| 155 | + if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand)) |
| 156 | + LI.setOperand(LI.getPointerOperandIndex(), NewGlobal); |
160 | 157 | return false; |
161 | 158 | } |
162 | 159 |
|
163 | 160 | bool DataScalarizerVisitor::visitStoreInst(StoreInst &SI) { |
164 | | - unsigned NumOperands = SI.getNumOperands(); |
165 | | - for (unsigned I = 0; I < NumOperands; ++I) { |
166 | | - Value *CurrOpperand = SI.getOperand(I); |
167 | | - ConstantExpr *CE = dyn_cast<ConstantExpr>(CurrOpperand); |
168 | | - if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
169 | | - GetElementPtrInst *OldGEP = |
170 | | - cast<GetElementPtrInst>(CE->getAsInstruction()); |
171 | | - OldGEP->insertBefore(SI.getIterator()); |
172 | | - IRBuilder<> Builder(&SI); |
173 | | - StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP); |
174 | | - NewStore->setAlignment(SI.getAlign()); |
175 | | - SI.replaceAllUsesWith(NewStore); |
176 | | - SI.eraseFromParent(); |
177 | | - visitGetElementPtrInst(*OldGEP); |
178 | | - return true; |
179 | | - } |
180 | | - if (GlobalVariable *NewGlobal = lookupReplacementGlobal(CurrOpperand)) |
181 | | - SI.setOperand(I, NewGlobal); |
| 161 | + |
| 162 | + Value *PtrOperand = SI.getPointerOperand(); |
| 163 | + ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOperand); |
| 164 | + if (CE && CE->getOpcode() == Instruction::GetElementPtr) { |
| 165 | + GetElementPtrInst *OldGEP = cast<GetElementPtrInst>(CE->getAsInstruction()); |
| 166 | + OldGEP->insertBefore(SI.getIterator()); |
| 167 | + IRBuilder<> Builder(&SI); |
| 168 | + StoreInst *NewStore = Builder.CreateStore(SI.getValueOperand(), OldGEP); |
| 169 | + NewStore->setAlignment(SI.getAlign()); |
| 170 | + SI.replaceAllUsesWith(NewStore); |
| 171 | + SI.eraseFromParent(); |
| 172 | + visitGetElementPtrInst(*OldGEP); |
| 173 | + return true; |
182 | 174 | } |
| 175 | + if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand)) |
| 176 | + SI.setOperand(SI.getPointerOperandIndex(), NewGlobal); |
| 177 | + |
183 | 178 | return false; |
184 | 179 | } |
185 | 180 |
|
@@ -302,24 +297,35 @@ bool DataScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) { |
302 | 297 | } |
303 | 298 |
|
304 | 299 | bool DataScalarizerVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) { |
305 | | - |
306 | | - unsigned NumOperands = GEPI.getNumOperands(); |
307 | | - GlobalVariable *NewGlobal = nullptr; |
308 | | - for (unsigned I = 0; I < NumOperands; ++I) { |
309 | | - Value *CurrOpperand = GEPI.getOperand(I); |
310 | | - NewGlobal = lookupReplacementGlobal(CurrOpperand); |
311 | | - if (NewGlobal) |
312 | | - break; |
| 300 | + Value *PtrOperand = GEPI.getPointerOperand(); |
| 301 | + Type *OrigGEPType = GEPI.getPointerOperandType(); |
| 302 | + Type *NewGEPType = OrigGEPType; |
| 303 | + bool NeedsTransform = false; |
| 304 | + |
| 305 | + if (GlobalVariable *NewGlobal = lookupReplacementGlobal(PtrOperand)) { |
| 306 | + NewGEPType = NewGlobal->getValueType(); |
| 307 | + PtrOperand = NewGlobal; |
| 308 | + NeedsTransform = true; |
| 309 | + } else if (AllocaInst *Alloca = dyn_cast<AllocaInst>(PtrOperand)) { |
| 310 | + Type *AllocatedType = Alloca->getAllocatedType(); |
| 311 | + // OrigGEPType might just be a pointer lets make sure |
| 312 | + // to add the allocated type so we have a size |
| 313 | + if (AllocatedType != OrigGEPType) { |
| 314 | + NewGEPType = AllocatedType; |
| 315 | + NeedsTransform = true; |
| 316 | + } |
313 | 317 | } |
314 | | - if (!NewGlobal) |
| 318 | + |
| 319 | + // Note: We bail if this isn't a gep touched via alloca or global |
| 320 | + // transformations |
| 321 | + if (!NeedsTransform) |
315 | 322 | return false; |
316 | 323 |
|
317 | 324 | IRBuilder<> Builder(&GEPI); |
318 | 325 | SmallVector<Value *, MaxVecSize> Indices(GEPI.indices()); |
319 | 326 |
|
320 | | - Value *NewGEP = |
321 | | - Builder.CreateGEP(NewGlobal->getValueType(), NewGlobal, Indices, |
322 | | - GEPI.getName(), GEPI.getNoWrapFlags()); |
| 327 | + Value *NewGEP = Builder.CreateGEP(NewGEPType, PtrOperand, Indices, |
| 328 | + GEPI.getName(), GEPI.getNoWrapFlags()); |
323 | 329 | GEPI.replaceAllUsesWith(NewGEP); |
324 | 330 | GEPI.eraseFromParent(); |
325 | 331 | return true; |
|
0 commit comments