[llvm-commits] [llvm] r116474 - /llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
Eric Christopher
echristo at apple.com
Thu Oct 14 02:29:41 PDT 2010
Author: echristo
Date: Thu Oct 14 04:29:41 2010
New Revision: 116474
URL: http://llvm.org/viewvc/llvm-project?rev=116474&view=rev
Log:
Handle more complex GEP based loads and add a few TODOs to deal with
GEP + alloca.
Modified:
llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=116474&r1=116473&r2=116474&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Thu Oct 14 04:29:41 2010
@@ -138,6 +138,7 @@
bool ARMEmitLoad(EVT VT, unsigned &ResultReg, unsigned Reg, int Offset);
bool ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Reg, int Offset);
bool ARMComputeRegOffset(const Value *Obj, unsigned &Reg, int &Offset);
+ unsigned ARMSimplifyRegOffset(unsigned Reg, int &Offset);
unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT);
unsigned ARMMaterializeInt(const Constant *C, EVT VT);
unsigned ARMMaterializeGV(const GlobalValue *GV, EVT VT);
@@ -602,7 +603,39 @@
return ARMComputeRegOffset(U->getOperand(0), Reg, Offset);
break;
}
+ case Instruction::GetElementPtr: {
+ int SavedOffset = Offset;
+ int TmpOffset = Offset;
+
+ // Iterate through the GEP folding the constants into offsets where
+ // we can.
+ gep_type_iterator GTI = gep_type_begin(U);
+ for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end();
+ i != e; ++i, ++GTI) {
+ const Value *Op = *i;
+ if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
+ const StructLayout *SL = TD.getStructLayout(STy);
+ unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
+ TmpOffset += SL->getElementOffset(Idx);
+ } else {
+ goto unsupported_gep;
+ }
+ }
+
+ Offset = TmpOffset;
+ if (ARMComputeRegOffset(U->getOperand(0), Reg, Offset)) return true;
+
+ Offset = SavedOffset;
+ break;
+
+ unsupported_gep:
+ // errs() << "GEP: " << *U << "\n";
+ break;
+ }
case Instruction::Alloca: {
+ // TODO: Fix this to do intermediate loads, etc.
+ if (Offset != 0) return false;
+
const AllocaInst *AI = cast<AllocaInst>(Obj);
DenseMap<const AllocaInst*, int>::iterator SI =
FuncInfo.StaticAllocaMap.find(AI);
@@ -629,16 +662,16 @@
}
// Try to get this in a register if nothing else has worked.
- Reg = getRegForValue(Obj);
- if (Reg == 0) return false;
+ if (Reg == 0) Reg = getRegForValue(Obj);
+
+ return Reg != 0;
+}
+
+unsigned ARMFastISel::ARMSimplifyRegOffset(unsigned Reg, int &Offset) {
// Since the offset may be too large for the load instruction
// get the reg+offset into a register.
- // TODO: Verify the additions work, otherwise we'll need to add the
- // offset instead of 0 to the instructions and do all sorts of operand
- // munging.
- // TODO: Optimize this somewhat.
- if (Offset != 0) {
+ if (Reg != ARM::SP && Offset != 0) {
ARMCC::CondCodes Pred = ARMCC::AL;
unsigned PredReg = 0;
@@ -652,8 +685,11 @@
Reg, Reg, Offset, Pred, PredReg,
static_cast<const ARMBaseInstrInfo&>(TII));
}
+
+ Offset = 0;
}
- return true;
+
+ return Reg;
}
bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg,
@@ -731,8 +767,10 @@
if (!ARMComputeRegOffset(I->getOperand(0), Reg, Offset))
return false;
+ unsigned BaseReg = ARMSimplifyRegOffset(Reg, Offset);
+
unsigned ResultReg;
- if (!ARMEmitLoad(VT, ResultReg, Reg, Offset /* 0 */)) return false;
+ if (!ARMEmitLoad(VT, ResultReg, BaseReg, Offset)) return false;
UpdateValueMap(I, ResultReg);
return true;
@@ -808,7 +846,9 @@
if (!ARMComputeRegOffset(I->getOperand(1), Reg, Offset))
return false;
- if (!ARMEmitStore(VT, SrcReg, Reg, Offset /* 0 */)) return false;
+ unsigned BaseReg = ARMSimplifyRegOffset(Reg, Offset);
+
+ if (!ARMEmitStore(VT, SrcReg, BaseReg, Offset)) return false;
return true;
}
More information about the llvm-commits
mailing list