[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