aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-02-07 02:44:23 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-02-07 02:44:23 +0000
commita01faf4a7ac34b2b89c93d62d3159a5c9c421149 (patch)
treef503d09c540da5d58c027d515253aa8f26a3ac26
parentdfb22c35215521e8ae9f27863b554949558bc4c1 (diff)
downloadexternal_llvm-a01faf4a7ac34b2b89c93d62d3159a5c9c421149.zip
external_llvm-a01faf4a7ac34b2b89c93d62d3159a5c9c421149.tar.gz
external_llvm-a01faf4a7ac34b2b89c93d62d3159a5c9c421149.tar.bz2
eliminateFrameIndex() is even more complicated if frame ptr is used instead of SP when there are dynamic alloca's.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33975 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.cpp54
1 files changed, 34 insertions, 20 deletions
diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp
index 2eb9eea..547e22c 100644
--- a/lib/Target/ARM/ARMRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMRegisterInfo.cpp
@@ -366,27 +366,35 @@ static
void emitThumbRegPlusConstPool(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
unsigned DestReg, unsigned BaseReg,
- int NumBytes, const TargetInstrInfo &TII) {
+ int NumBytes, bool CanChangeCC,
+ const TargetInstrInfo &TII) {
MachineFunction &MF = *MBB.getParent();
MachineConstantPool *ConstantPool = MF.getConstantPool();
bool isHigh = !isLowRegister(DestReg) || !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.
- if (NumBytes < 0 && !isHigh) {
+ // if either base or dest register is a high register. Also, if do not
+ // issue sub as part of the sequence if condition register is to be
+ // preserved.
+ if (NumBytes < 0 && !isHigh && CanChangeCC) {
isSub = true;
NumBytes = -NumBytes;
}
- Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
- unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
unsigned LdReg = DestReg;
if (DestReg == ARM::SP) {
assert(BaseReg == ARM::SP && "Unexpected!");
LdReg = ARM::R3;
BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R3);
}
- // Load the constant.
- BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), LdReg).addConstantPoolIndex(Idx);
+
+ 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);
+ }
// Emit add / sub.
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg);
@@ -452,7 +460,7 @@ void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
if (NumMIs > Threshold) {
// This will expand into too many instructions. Load the immediate from a
// constpool entry.
- emitThumbRegPlusConstPool(MBB, MBBI, DestReg, BaseReg, NumBytes, TII);
+ emitThumbRegPlusConstPool(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII);
return;
}
@@ -713,8 +721,8 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
case ARMII::AddrModeTs: {
ImmIdx = i+1;
InstrOffs = MI.getOperand(ImmIdx).getImm();
- NumBits = (FrameReg == ARM::SP) ? 8 : 5;
- Scale = 4;
+ NumBits = isSub ? 3 : ((FrameReg == ARM::SP) ? 8 : 5);
+ Scale = isSub ? 1 : 4;
break;
}
default:
@@ -725,11 +733,12 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
Offset += InstrOffs * Scale;
assert((Offset & (Scale-1)) == 0 && "Can't encode this offset!");
- if (Offset < 0) {
+ if (Offset < 0 && !isThumb) {
Offset = -Offset;
isSub = true;
}
+ // Common case: small offset, fits into instruction.
MachineOperand &ImmOp = MI.getOperand(ImmIdx);
int ImmedOffset = Offset / Scale;
unsigned Mask = (1 << NumBits) - 1;
@@ -742,7 +751,16 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
return;
}
- if (!isThumb) {
+ // 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) {
+ // Thumb tLDRspi, tSTRspi. These will change to instructions that use
+ // a different base register.
+ NumBits = 5;
+ Mask = (1 << NumBits) - 1;
+ }
// Otherwise, it didn't fit. Pull in what we can to simplify the immed.
ImmedOffset = ImmedOffset & Mask;
if (isSub)
@@ -762,11 +780,9 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
// Use the destination register to materialize sp + offset.
unsigned TmpReg = MI.getOperand(0).getReg();
if (Opcode == ARM::tRestore)
- emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
- isSub ? -Offset : Offset, TII);
+ emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg, Offset, false, TII);
else
- emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
- isSub ? -Offset : Offset, TII);
+ emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
MI.setInstrDescriptor(TII.get(ARM::tLDR));
MI.getOperand(i).ChangeToRegister(TmpReg, false);
MI.addRegOperand(0, false); // tLDR has an extra register operand.
@@ -786,11 +802,9 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
TmpReg = ARM::R2;
}
if (Opcode == ARM::tSpill)
- emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,
- isSub ? -Offset : Offset, TII);
+ emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg, Offset, false, TII);
else
- emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
- isSub ? -Offset : Offset, TII);
+ 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.