|
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