diff options
author | Bill Wendling <isanbard@gmail.com> | 2010-09-09 20:56:38 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2010-09-09 20:56:38 +0000 |
commit | babf51150b3a00a0ddb4303d961834a0a77296a3 (patch) | |
tree | 861a480a878e2e246c748aa29a6b689ce6230bb7 | |
parent | 587f6ed6864af95997e16df8dcf930822c1416a2 (diff) |
Approved by Evan:
$ svn merge -c 113297 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r113297 into '.':
U lib/Target/ARM/Thumb2SizeReduction.cpp
$ svn merge -c 113322 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r113322 into '.':
U lib/Target/ARM/ARMInstrNEON.td
U lib/Target/ARM/ARMInstrVFP.td
U lib/Target/ARM/ARMInstrFormats.td
$ svn merge -c 113365 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r113365 into '.':
U lib/Target/ARM/ARMBaseRegisterInfo.cpp
$ svn merge -c 113366 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r113366 into '.':
G lib/Target/ARM/ARMBaseRegisterInfo.cpp
$ svn merge -c 113394 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r113394 into '.':
G lib/Target/ARM/ARMBaseRegisterInfo.cpp
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_28@113540 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/ARMBaseRegisterInfo.cpp | 22 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 8 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrNEON.td | 4 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrVFP.td | 16 | ||||
-rw-r--r-- | lib/Target/ARM/Thumb2SizeReduction.cpp | 12 |
5 files changed, 42 insertions, 20 deletions
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index be33ed6427..eceafad63f 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -667,8 +667,14 @@ bool ARMBaseRegisterInfo::hasBasePointer(const MachineFunction &MF) const { } bool ARMBaseRegisterInfo::canRealignStack(const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); - return (RealignStack && !AFI->isThumb1OnlyFunction()); + // We can't realign the stack if: + // 1. Dynamic stack realignment is explicitly disabled, + // 2. This is a Thumb1 function (it's not useful, so we don't bother), or + // 3. There are VLAs in the function and the base pointer is disabled. + return (RealignStack && !AFI->isThumb1OnlyFunction() && + (!MFI->hasVarSizedObjects() || EnableBasePointer)); } bool ARMBaseRegisterInfo:: @@ -1057,8 +1063,11 @@ ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF, if (isFixed) { FrameReg = getFrameRegister(MF); Offset = FPOffset; - } else if (MFI->hasVarSizedObjects()) + } else if (MFI->hasVarSizedObjects()) { + assert(hasBasePointer(MF) && + "VLAs and dynamic stack alignment, but missing base pointer!"); FrameReg = BasePtr; + } return Offset; } @@ -1068,7 +1077,7 @@ ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF, // there are VLAs (and thus the SP isn't reliable as a base). if (isFixed || (MFI->hasVarSizedObjects() && !hasBasePointer(MF))) { FrameReg = getFrameRegister(MF); - Offset = FPOffset; + return FPOffset; } else if (MFI->hasVarSizedObjects()) { assert(hasBasePointer(MF) && "missing base pointer!"); // Use the base register since we have it. @@ -1078,12 +1087,12 @@ ARMBaseRegisterInfo::ResolveFrameIndexReference(const MachineFunction &MF, // out of range references. if (FPOffset >= -255 && FPOffset < 0) { FrameReg = getFrameRegister(MF); - Offset = FPOffset; + return FPOffset; } } else if (Offset > (FPOffset < 0 ? -FPOffset : FPOffset)) { // Otherwise, use SP or FP, whichever is closer to the stack slot. FrameReg = getFrameRegister(MF); - Offset = FPOffset; + return FPOffset; } } // Use the base pointer if we have one. @@ -1887,7 +1896,8 @@ emitPrologue(MachineFunction &MF) const { AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); AFI->setDPRCalleeSavedAreaSize(DPRCSSize); - // If we need dynamic stack realignment, do it here. + // If we need dynamic stack realignment, do it here. Be paranoid and make + // sure if we also have VLAs, we have a base pointer for frame access. if (needsStackRealignment(MF)) { unsigned MaxAlign = MFI->getMaxAlignment(); assert (!AFI->isThumb1OnlyFunction()); diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 1de0fa7acf..113cfffe61 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1332,9 +1332,9 @@ class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops, } // Load / store multiple -class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin, +class AXDI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, string asm, string cstr, list<dag> pattern> - : VFPXI<oops, iops, AddrMode5, Size4Bytes, im, + : VFPXI<oops, iops, AddrMode4, Size4Bytes, im, VFPLdStMulFrm, itin, asm, cstr, pattern> { // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-25} = 0b110; @@ -1344,9 +1344,9 @@ class AXDI5<dag oops, dag iops, IndexMode im, InstrItinClass itin, let D = VFPNeonDomain; } -class AXSI5<dag oops, dag iops, IndexMode im, InstrItinClass itin, +class AXSI4<dag oops, dag iops, IndexMode im, InstrItinClass itin, string asm, string cstr, list<dag> pattern> - : VFPXI<oops, iops, AddrMode5, Size4Bytes, im, + : VFPXI<oops, iops, AddrMode4, Size4Bytes, im, VFPLdStMulFrm, itin, asm, cstr, pattern> { // TODO: Mark the instructions with the appropriate subtarget info. let Inst{27-25} = 0b110; diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 4f7db71ada..4d2f116906 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -133,7 +133,7 @@ def nModImm : Operand<i32> { // This is equivalent to VLDMD except that it has a Q register operand // instead of a pair of D registers. def VLDMQ - : AXDI5<(outs QPR:$dst), (ins addrmode4:$addr, pred:$p), + : AXDI4<(outs QPR:$dst), (ins addrmode4:$addr, pred:$p), IndexModeNone, IIC_fpLoadm, "vldm${addr:submode}${p}\t$addr, ${dst:dregpair}", "", [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]>; @@ -151,7 +151,7 @@ def VLD1q // This is equivalent to VSTMD except that it has a Q register operand // instead of a pair of D registers. def VSTMQ - : AXDI5<(outs), (ins QPR:$src, addrmode4:$addr, pred:$p), + : AXDI4<(outs), (ins QPR:$src, addrmode4:$addr, pred:$p), IndexModeNone, IIC_fpStorem, "vstm${addr:submode}${p}\t$addr, ${src:dregpair}", "", [(store (v2f64 QPR:$src), addrmode4:$addr)]>; diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index 71e2823b2a..c29e09606b 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -77,19 +77,19 @@ def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr), // let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { -def VLDMD : AXDI5<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts, +def VLDMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops), IndexModeNone, IIC_fpLoadm, "vldm${addr:submode}${p}\t$addr, $dsts", "", []> { let Inst{20} = 1; } -def VLDMS : AXSI5<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts, +def VLDMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops), IndexModeNone, IIC_fpLoadm, "vldm${addr:submode}${p}\t$addr, $dsts", "", []> { let Inst{20} = 1; } -def VLDMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, +def VLDMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops), IndexModeUpd, IIC_fpLoadm, "vldm${addr:submode}${p}\t$addr!, $dsts", @@ -97,7 +97,7 @@ def VLDMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, let Inst{20} = 1; } -def VLDMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, +def VLDMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops), IndexModeUpd, IIC_fpLoadm, "vldm${addr:submode}${p}\t$addr!, $dsts", @@ -107,19 +107,19 @@ def VLDMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { -def VSTMD : AXDI5<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs, +def VSTMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops), IndexModeNone, IIC_fpStorem, "vstm${addr:submode}${p}\t$addr, $srcs", "", []> { let Inst{20} = 0; } -def VSTMS : AXSI5<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs, +def VSTMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops), IndexModeNone, IIC_fpStorem, "vstm${addr:submode}${p}\t$addr, $srcs", "", []> { let Inst{20} = 0; } -def VSTMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, +def VSTMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops), IndexModeUpd, IIC_fpStorem, "vstm${addr:submode}${p}\t$addr!, $srcs", @@ -127,7 +127,7 @@ def VSTMD_UPD : AXDI5<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, let Inst{20} = 0; } -def VSTMS_UPD : AXSI5<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, +def VSTMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops), IndexModeUpd, IIC_fpStorem, "vstm${addr:submode}${p}\t$addr!, $srcs", diff --git a/lib/Target/ARM/Thumb2SizeReduction.cpp b/lib/Target/ARM/Thumb2SizeReduction.cpp index 1451c53112..0c3962dd12 100644 --- a/lib/Target/ARM/Thumb2SizeReduction.cpp +++ b/lib/Target/ARM/Thumb2SizeReduction.cpp @@ -315,6 +315,18 @@ Thumb2SizeReduce::ReduceLoadStore(MachineBasicBlock &MBB, MachineInstr *MI, ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm()); if (!isARMLowRegister(BaseReg) || Mode != ARM_AM::ia) return false; + // For the non-writeback version (this one), the base register must be + // one of the registers being loaded. + bool isOK = false; + for (unsigned i = 4; i < MI->getNumOperands(); ++i) { + if (MI->getOperand(i).getReg() == BaseReg) { + isOK = true; + break; + } + } + if (!isOK) + return false; + OpNum = 0; isLdStMul = true; break; |