[llvm-commits] CVS: llvm/lib/Target/ARM/ARMRegisterInfo.cpp

Evan Cheng evan.cheng at apple.com
Wed Feb 7 00:37:56 PST 2007



Changes in directory llvm/lib/Target/ARM:

ARMRegisterInfo.cpp updated: 1.60 -> 1.61
---
Log message:

- If fp (r7) is used to reference stack objects, use [r, r] address mode.
- If there is a dynamic alloca, in the epilogue, restore the value of sp
  using r7 - offset.
- Other bug fixes.


---
Diffs of the changes:  (+67 -28)

 ARMRegisterInfo.cpp |   95 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 67 insertions(+), 28 deletions(-)


Index: llvm/lib/Target/ARM/ARMRegisterInfo.cpp
diff -u llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.60 llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.61
--- llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.60	Tue Feb  6 20:44:23 2007
+++ llvm/lib/Target/ARM/ARMRegisterInfo.cpp	Wed Feb  7 02:37:31 2007
@@ -359,6 +359,19 @@
   return NumMIs;
 }
 
+/// emitLoadConstPool - Emits a load from constpool to materialize NumBytes
+/// immediate.
+static void emitLoadConstPool(MachineBasicBlock &MBB,
+                              MachineBasicBlock::iterator &MBBI,
+                              unsigned DestReg, int NumBytes, 
+                              const TargetInstrInfo &TII) {
+  MachineFunction &MF = *MBB.getParent();
+  MachineConstantPool *ConstantPool = MF.getConstantPool();
+  Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
+  unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
+  BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), DestReg).addConstantPoolIndex(Idx);
+}
+
 /// emitThumbRegPlusConstPool - Emits a series of instructions to materialize
 /// a destreg = basereg + immediate in Thumb code. Load the immediate from a
 /// constpool entry.
@@ -368,9 +381,8 @@
                                unsigned DestReg, unsigned BaseReg,
                                int NumBytes, bool CanChangeCC,
                                const TargetInstrInfo &TII) {
-    MachineFunction &MF = *MBB.getParent();
-    MachineConstantPool *ConstantPool = MF.getConstantPool();
-    bool isHigh = !isLowRegister(DestReg) || !isLowRegister(BaseReg);
+    bool isHigh = !isLowRegister(DestReg) ||
+                  (BaseReg != 0 && !isLowRegister(BaseReg));
     bool isSub = false;
     // Subtract doesn't have high register version. Load the negative value
     // if either base or dest register is a high register. Also, if do not
@@ -389,12 +401,9 @@
 
     if (NumBytes <= 255 && NumBytes >= 0)
       BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
-    else {
-      // Load the constant.
-      Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
-      unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
-      BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), LdReg).addConstantPoolIndex(Idx);
-    }
+    else
+      emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII);
+
     // Emit add / sub.
     int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
     const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg);
@@ -721,8 +730,8 @@
     case ARMII::AddrModeTs: {
       ImmIdx = i+1;
       InstrOffs = MI.getOperand(ImmIdx).getImm();
-      NumBits = isSub ? 3 : ((FrameReg == ARM::SP) ? 8 : 5);
-      Scale = isSub ? 1 : 4;
+      NumBits = (FrameReg == ARM::SP) ? 8 : 5;
+      Scale = 4;
       break;
     }
     default:
@@ -754,7 +763,7 @@
     // If this is a thumb spill / restore, we will be using a constpool load to
     // materialize the offset.
     bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
-    if (AddrMode == ARMII::AddrModeTs || !isThumSpillRestore) {
+    if (AddrMode == ARMII::AddrModeTs && !isThumSpillRestore) {
       if (AddrMode == ARMII::AddrModeTs) {
         // Thumb tLDRspi, tSTRspi. These will change to instructions that use
         // a different base register.
@@ -779,12 +788,21 @@
     if (TII.isLoad(Opcode)) {
       // Use the destination register to materialize sp + offset.
       unsigned TmpReg = MI.getOperand(0).getReg();
-      if (Opcode == ARM::tRestore)
-        emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg, Offset, false, TII);
-      else
+      bool UseRR = false;
+      if (Opcode == ARM::tRestore) {
+        if (FrameReg == ARM::SP)
+          emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
+        else {
+          emitLoadConstPool(MBB, II, TmpReg, Offset, TII);
+          UseRR = true;
+        }
+      } else
         emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
       MI.setInstrDescriptor(TII.get(ARM::tLDR));
       MI.getOperand(i).ChangeToRegister(TmpReg, false);
+      if (UseRR)
+        MI.addRegOperand(FrameReg, false);  // Use [reg, reg] addrmode.
+      else
       MI.addRegOperand(0, false); // tLDR has an extra register operand.
     } else if (TII.isStore(Opcode)) {
       // FIXME! This is horrific!!! We need register scavenging.
@@ -797,19 +815,30 @@
       // r2 = r12
       unsigned ValReg = MI.getOperand(0).getReg();
       unsigned TmpReg = ARM::R3;
+      bool UseRR = false;
       if (ValReg == ARM::R3) {
         BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
         TmpReg = ARM::R2;
       }
-      if (Opcode == ARM::tSpill)
-        emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg, Offset, false, TII);
-      else
+      if (Opcode == ARM::tSpill) {
+        if (FrameReg == ARM::SP)
+          emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
+        else {
+          emitLoadConstPool(MBB, II, TmpReg, Offset, TII);
+          UseRR = true;
+        }
+      } else
         emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
       MI.setInstrDescriptor(TII.get(ARM::tSTR));
       MI.getOperand(i).ChangeToRegister(TmpReg, false);
-      MI.addRegOperand(0, false); // tSTR has an extra register operand.
-      if (ValReg == ARM::R3)
-        BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
+      if (UseRR)
+        MI.addRegOperand(FrameReg, false);  // Use [reg, reg] addrmode.
+      else
+        MI.addRegOperand(0, false); // tSTR has an extra register operand.
+      if (ValReg == ARM::R3) {
+        MachineBasicBlock::iterator NII = next(II);
+        BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
+      }
     } else
       assert(false && "Unexpected opcode!");
   } else {
@@ -1152,13 +1181,23 @@
                AFI->getGPRCalleeSavedArea2Size() +
                AFI->getDPRCalleeSavedAreaSize());
   if (isThumb) {
-    if (MBBI->getOpcode() == ARM::tBX_RET &&
-        &MBB.front() != MBBI &&
-        prior(MBBI)->getOpcode() == ARM::tPOP) {
-      MachineBasicBlock::iterator PMBBI = prior(MBBI);
-      emitSPUpdate(MBB, PMBBI, NumBytes, isThumb, TII);
-    } else
-      emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
+    if (hasFP(MF)) {
+      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
+      // Reset SP based on frame pointer only if the stack frame extends beyond
+      // frame pointer stack slot or target is ELF and the function has FP.
+      if (NumBytes)
+        emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes, TII);
+      else
+        BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), ARM::SP).addReg(FramePtr);
+    } else {
+      if (MBBI->getOpcode() == ARM::tBX_RET &&
+          &MBB.front() != MBBI &&
+          prior(MBBI)->getOpcode() == ARM::tPOP) {
+        MachineBasicBlock::iterator PMBBI = prior(MBBI);
+        emitSPUpdate(MBB, PMBBI, NumBytes, isThumb, TII);
+      } else
+        emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
+    }
   } else {
     // Darwin ABI requires FP to point to the stack slot that contains the
     // previous FP.






More information about the llvm-commits mailing list