[llvm-commits] CVS: llvm/lib/Target/ARM/ARMInstrInfo.cpp ARMInstrThumb.td ARMRegisterInfo.cpp README-Thumb.txt
Evan Cheng
evan.cheng at apple.com
Tue Feb 6 16:07:21 PST 2007
Changes in directory llvm/lib/Target/ARM:
ARMInstrInfo.cpp updated: 1.15 -> 1.16
ARMInstrThumb.td updated: 1.13 -> 1.14
ARMRegisterInfo.cpp updated: 1.58 -> 1.59
README-Thumb.txt updated: 1.5 -> 1.6
---
Log message:
Spill / restore should avoid modifying the condition register.
---
Diffs of the changes: (+64 -36)
ARMInstrInfo.cpp | 4 +--
ARMInstrThumb.td | 10 +++++++
ARMRegisterInfo.cpp | 69 ++++++++++++++++++++++++++--------------------------
README-Thumb.txt | 17 ++++++++++++
4 files changed, 64 insertions(+), 36 deletions(-)
Index: llvm/lib/Target/ARM/ARMInstrInfo.cpp
diff -u llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.15 llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.16
--- llvm/lib/Target/ARM/ARMInstrInfo.cpp:1.15 Tue Jan 30 02:22:33 2007
+++ llvm/lib/Target/ARM/ARMInstrInfo.cpp Tue Feb 6 18:06:56 2007
@@ -83,7 +83,7 @@
return MI->getOperand(0).getReg();
}
break;
- case ARM::tLDRspi:
+ case ARM::tRestore:
if (MI->getOperand(1).isFrameIndex() &&
MI->getOperand(2).isImmediate() &&
MI->getOperand(2).getImmedValue() == 0) {
@@ -117,7 +117,7 @@
return MI->getOperand(0).getReg();
}
break;
- case ARM::tSTRspi:
+ case ARM::tSpill:
if (MI->getOperand(1).isFrameIndex() &&
MI->getOperand(2).isImmediate() &&
MI->getOperand(2).getImmedValue() == 0) {
Index: llvm/lib/Target/ARM/ARMInstrThumb.td
diff -u llvm/lib/Target/ARM/ARMInstrThumb.td:1.13 llvm/lib/Target/ARM/ARMInstrThumb.td:1.14
--- llvm/lib/Target/ARM/ARMInstrThumb.td:1.13 Wed Jan 31 21:04:49 2007
+++ llvm/lib/Target/ARM/ARMInstrThumb.td Tue Feb 6 18:06:56 2007
@@ -239,6 +239,11 @@
"ldr $dst, $addr",
[(set GPR:$dst, (load t_addrmode_sp:$addr))]>;
+// Special instruction for restore. It cannot clobber condition register
+// when it's expanded by eliminateCallFramePseudoInstr().
+def tRestore : TIs<(ops GPR:$dst, t_addrmode_sp:$addr),
+ "ldr $dst, $addr", []>;
+
// Load tconstpool
def tLDRpci : TIs<(ops GPR:$dst, i32imm:$addr),
"ldr $dst, $addr",
@@ -261,6 +266,11 @@
def tSTRspi : TIs<(ops GPR:$src, t_addrmode_sp:$addr),
"str $src, $addr",
[(store GPR:$src, t_addrmode_sp:$addr)]>;
+
+// Special instruction for spill. It cannot clobber condition register
+// when it's expanded by eliminateCallFramePseudoInstr().
+def tSpill : TIs<(ops GPR:$src, t_addrmode_sp:$addr),
+ "str $src, $addr", []>;
}
//===----------------------------------------------------------------------===//
Index: llvm/lib/Target/ARM/ARMRegisterInfo.cpp
diff -u llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.58 llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.59
--- llvm/lib/Target/ARM/ARMRegisterInfo.cpp:1.58 Tue Feb 6 00:13:29 2007
+++ llvm/lib/Target/ARM/ARMRegisterInfo.cpp Tue Feb 6 18:06:56 2007
@@ -130,7 +130,7 @@
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
if (AFI->isThumbFunction())
- BuildMI(MBB, I, TII.get(ARM::tSTRspi)).addReg(SrcReg)
+ BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg)
.addFrameIndex(FI).addImm(0);
else
BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg)
@@ -153,7 +153,7 @@
MachineFunction &MF = *MBB.getParent();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
if (AFI->isThumbFunction())
- BuildMI(MBB, I, TII.get(ARM::tLDRspi), DestReg)
+ BuildMI(MBB, I, TII.get(ARM::tRestore), DestReg)
.addFrameIndex(FI).addImm(0);
else
BuildMI(MBB, I, TII.get(ARM::LDR), DestReg)
@@ -220,16 +220,16 @@
if (OpNum == 0) { // move -> store
unsigned SrcReg = MI->getOperand(1).getReg();
if (!isLowRegister(SrcReg))
- // tSTRspi cannot take a high register operand.
+ // tSpill cannot take a high register operand.
break;
- NewMI = BuildMI(TII.get(ARM::tSTRspi)).addReg(SrcReg).addFrameIndex(FI)
+ NewMI = BuildMI(TII.get(ARM::tSpill)).addReg(SrcReg).addFrameIndex(FI)
.addImm(0);
} else { // move -> load
unsigned DstReg = MI->getOperand(0).getReg();
if (!isLowRegister(DstReg))
- // tLDRspi cannot target a high register operand.
+ // tRestore cannot target a high register operand.
break;
- NewMI = BuildMI(TII.get(ARM::tLDRspi), DstReg).addFrameIndex(FI)
+ NewMI = BuildMI(TII.get(ARM::tRestore), DstReg).addFrameIndex(FI)
.addImm(0);
}
break;
@@ -412,7 +412,7 @@
if (isSub) Bytes = -NumBytes;
bool isMul4 = (Bytes & 3) == 0;
bool isTwoAddr = false;
- bool DstNeBase = false;
+ bool DstNotEqBase = false;
unsigned NumBits = 1;
unsigned Scale = 1;
int Opc = 0;
@@ -441,14 +441,14 @@
// r1 = sub sp, c
// r8 = sub sp, c
if (DestReg != BaseReg)
- DstNeBase = true;
+ DstNotEqBase = true;
NumBits = 8;
Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
isTwoAddr = true;
}
unsigned NumMIs = calcNumMI(Opc, ExtraOpc, Bytes, NumBits, Scale);
- unsigned Threshold = (DestReg == ARM::SP) ? 4 : 3;
+ unsigned Threshold = (DestReg == ARM::SP) ? 3 : 2;
if (NumMIs > Threshold) {
// This will expand into too many instructions. Load the immediate from a
// constpool entry.
@@ -456,7 +456,7 @@
return;
}
- if (DstNeBase) {
+ if (DstNotEqBase) {
if (isLowRegister(DestReg) && isLowRegister(BaseReg)) {
// If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
unsigned Chunk = (1 << 3) - 1;
@@ -730,27 +730,20 @@
isSub = true;
}
- if (!isSub || !isThumb) {
- MachineOperand &ImmOp = MI.getOperand(ImmIdx);
- int ImmedOffset = Offset / Scale;
- unsigned Mask = (1 << NumBits) - 1;
- if ((unsigned)Offset <= Mask * Scale) {
- // Replace the FrameIndex with sp
- MI.getOperand(i).ChangeToRegister(FrameReg, false);
- if (isSub)
- ImmedOffset |= 1 << NumBits;
- ImmOp.ChangeToImmediate(ImmedOffset);
- return;
- }
+ MachineOperand &ImmOp = MI.getOperand(ImmIdx);
+ int ImmedOffset = Offset / Scale;
+ unsigned Mask = (1 << NumBits) - 1;
+ if ((unsigned)Offset <= Mask * Scale) {
+ // Replace the FrameIndex with sp
+ MI.getOperand(i).ChangeToRegister(FrameReg, false);
+ if (isSub)
+ ImmedOffset |= 1 << NumBits;
+ ImmOp.ChangeToImmediate(ImmedOffset);
+ return;
+ }
+ if (!isThumb) {
// Otherwise, it didn't fit. Pull in what we can to simplify the immed.
- if (AddrMode == ARMII::AddrModeTs) {
- // Thumb tLDRspi, tSTRspi. These will change to instructions that use
- // a different base register.
- NumBits = 5;
- Mask = (1 << NumBits) - 1;
- }
-
ImmedOffset = ImmedOffset & Mask;
if (isSub)
ImmedOffset |= 1 << NumBits;
@@ -768,8 +761,12 @@
if (TII.isLoad(Opcode)) {
// Use the destination register to materialize sp + offset.
unsigned TmpReg = MI.getOperand(0).getReg();
- emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
- isSub ? -Offset : Offset, TII);
+ if (Opcode == ARM::tRestore)
+ emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
+ isSub ? -Offset : Offset, TII);
+ else
+ emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
+ isSub ? -Offset : Offset, TII);
MI.setInstrDescriptor(TII.get(ARM::tLDR));
MI.getOperand(i).ChangeToRegister(TmpReg, false);
MI.addRegOperand(0, false); // tLDR has an extra register operand.
@@ -788,8 +785,12 @@
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
TmpReg = ARM::R2;
}
- emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
- isSub ? -Offset : Offset, TII);
+ if (Opcode == ARM::tSpill)
+ emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
+ isSub ? -Offset : Offset, TII);
+ else
+ emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
+ isSub ? -Offset : Offset, TII);
MI.setInstrDescriptor(TII.get(ARM::tSTR));
MI.getOperand(i).ChangeToRegister(TmpReg, false);
MI.addRegOperand(0, false); // tSTR has an extra register operand.
@@ -1098,7 +1099,7 @@
static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
return ((MI->getOpcode() == ARM::FLDD ||
MI->getOpcode() == ARM::LDR ||
- MI->getOpcode() == ARM::tLDRspi) &&
+ MI->getOpcode() == ARM::tRestore) &&
MI->getOperand(1).isFrameIndex() &&
isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
}
Index: llvm/lib/Target/ARM/README-Thumb.txt
diff -u llvm/lib/Target/ARM/README-Thumb.txt:1.5 llvm/lib/Target/ARM/README-Thumb.txt:1.6
--- llvm/lib/Target/ARM/README-Thumb.txt:1.5 Wed Jan 31 20:46:20 2007
+++ llvm/lib/Target/ARM/README-Thumb.txt Tue Feb 6 18:06:56 2007
@@ -124,3 +124,20 @@
.align 2
L11:
.long 642
+
+//===---------------------------------------------------------------------===//
+
+When spilling in thumb mode and the sp offset is too large to fit in the ldr /
+str offset field, we load the offset from a constpool entry and add it to sp:
+
+ldr r2, LCPI
+add r2, sp
+ldr r2, [r2]
+
+These instructions preserve the condition code which is important if the spill
+is between a cmp and a bcc instruction. However, we can use the (potentially)
+cheaper sequnce if we know it's ok to clobber the condition register.
+
+add r2, sp, #255 * 4
+add r2, #132
+ldr r2, [r2, #7 * 4]
More information about the llvm-commits
mailing list