X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMRegisterInfo.cpp;h=2fae432633b63012a092d7350a6abc7fef9e42a5;hb=c69d56f1154342a57c9bdd4c17a10333e3520127;hp=bf6adbd95f379e0317db99a358cf4ec2bd517287;hpb=b03eacdbf39b37a98b65b936046b22cca8215d8d;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index bf6adbd95f3..2fae432633b 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -2,13 +2,12 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the "Instituto Nokia de Tecnologia" and -// is distributed under the University of Illinois Open Source +// This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file contains the ARM implementation of the MRegisterInfo class. +// This file contains the ARM implementation of the TargetRegisterInfo class. // //===----------------------------------------------------------------------===// @@ -25,6 +24,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLocation.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetMachine.h" @@ -81,155 +81,126 @@ unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) { } } -ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii, - const ARMSubtarget &sti) - : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), - TII(tii), STI(sti), - FramePtr(STI.useThumbBacktraces() ? ARM::R7 : ARM::R11) { -} - -bool ARMRegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - if (!AFI->isThumbFunction() || CSI.empty()) - return false; - - MachineInstrBuilder MIB = BuildMI(MBB, MI, TII.get(ARM::tPUSH)); - for (unsigned i = CSI.size(); i != 0; --i) { - unsigned Reg = CSI[i-1].getReg(); - // Add the callee-saved register as live-in. It's killed at the spill. - MBB.addLiveIn(Reg); - MIB.addReg(Reg, false/*isDef*/,false/*isImp*/,true/*isKill*/); - } - return true; -} +unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum, + bool &isSPVFP) { + isSPVFP = false; -bool ARMRegisterInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - if (!AFI->isThumbFunction() || CSI.empty()) - return false; - - bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; - MachineInstr *PopMI = new MachineInstr(TII.get(ARM::tPOP)); - MBB.insert(MI, PopMI); - for (unsigned i = CSI.size(); i != 0; --i) { - unsigned Reg = CSI[i-1].getReg(); - if (Reg == ARM::LR) { - // Special epilogue for vararg functions. See emitEpilogue - if (isVarArg) - continue; - Reg = ARM::PC; - PopMI->setInstrDescriptor(TII.get(ARM::tPOP_RET)); - MBB.erase(MI); + using namespace ARM; + switch (RegEnum) { + default: + assert(0 && "Unknown ARM register!"); + abort(); + case R0: case D0: return 0; + case R1: case D1: return 1; + case R2: case D2: return 2; + case R3: case D3: return 3; + case R4: case D4: return 4; + case R5: case D5: return 5; + case R6: case D6: return 6; + case R7: case D7: return 7; + case R8: case D8: return 8; + case R9: case D9: return 9; + case R10: case D10: return 10; + case R11: case D11: return 11; + case R12: case D12: return 12; + case SP: case D13: return 13; + case LR: case D14: return 14; + case PC: case D15: return 15; + + case S0: case S1: case S2: case S3: + case S4: case S5: case S6: case S7: + case S8: case S9: case S10: case S11: + case S12: case S13: case S14: case S15: + case S16: case S17: case S18: case S19: + case S20: case S21: case S22: case S23: + case S24: case S25: case S26: case S27: + case S28: case S29: case S30: case S31: { + isSPVFP = true; + switch (RegEnum) { + default: return 0; // Avoid compile time warning. + case S0: return 0; + case S1: return 1; + case S2: return 2; + case S3: return 3; + case S4: return 4; + case S5: return 5; + case S6: return 6; + case S7: return 7; + case S8: return 8; + case S9: return 9; + case S10: return 10; + case S11: return 11; + case S12: return 12; + case S13: return 13; + case S14: return 14; + case S15: return 15; + case S16: return 16; + case S17: return 17; + case S18: return 18; + case S19: return 19; + case S20: return 20; + case S21: return 21; + case S22: return 22; + case S23: return 23; + case S24: return 24; + case S25: return 25; + case S26: return 26; + case S27: return 27; + case S28: return 28; + case S29: return 29; + case S30: return 30; + case S31: return 31; } - PopMI->addRegOperand(Reg, true); } - return true; + } } -void ARMRegisterInfo:: -storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FI, - const TargetRegisterClass *RC) const { - if (RC == ARM::GPRRegisterClass) { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - if (AFI->isThumbFunction()) - BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg, false, false, true) - .addFrameIndex(FI).addImm(0); - else - BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg, false, false, true) - .addFrameIndex(FI).addReg(0).addImm(0); - } else if (RC == ARM::DPRRegisterClass) { - BuildMI(MBB, I, TII.get(ARM::FSTD)).addReg(SrcReg, false, false, true) - .addFrameIndex(FI).addImm(0); - } else { - assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); - BuildMI(MBB, I, TII.get(ARM::FSTS)).addReg(SrcReg, false, false, true) - .addFrameIndex(FI).addImm(0); - } +ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii, + const ARMSubtarget &sti) + : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP), + TII(tii), STI(sti), + FramePtr((STI.useThumbBacktraces() || STI.isThumb()) ? ARM::R7 : ARM::R11) { } -void ARMRegisterInfo:: -loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, int FI, - const TargetRegisterClass *RC) const { - if (RC == ARM::GPRRegisterClass) { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - if (AFI->isThumbFunction()) - BuildMI(MBB, I, TII.get(ARM::tRestore), DestReg) - .addFrameIndex(FI).addImm(0); - else - BuildMI(MBB, I, TII.get(ARM::LDR), DestReg) - .addFrameIndex(FI).addReg(0).addImm(0); - } else if (RC == ARM::DPRRegisterClass) { - BuildMI(MBB, I, TII.get(ARM::FLDD), DestReg) - .addFrameIndex(FI).addImm(0); - } else { - assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); - BuildMI(MBB, I, TII.get(ARM::FLDS), DestReg) - .addFrameIndex(FI).addImm(0); - } +static inline +const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { + return MIB.addImm((int64_t)ARMCC::AL).addReg(0); } -void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { - if (RC == ARM::GPRRegisterClass) { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - BuildMI(MBB, I, TII.get(AFI->isThumbFunction() ? ARM::tMOVr : ARM::MOVr), - DestReg).addReg(SrcReg); - } else if (RC == ARM::SPRRegisterClass) - BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg); - else if (RC == ARM::DPRRegisterClass) - BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg).addReg(SrcReg); - else - abort(); +static inline +const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { + return MIB.addReg(0); } /// emitLoadConstPool - Emits a load from constpool to materialize the /// specified immediate. -static void emitLoadConstPool(MachineBasicBlock &MBB, - MachineBasicBlock::iterator &MBBI, - unsigned DestReg, int Val, - const TargetInstrInfo &TII, bool isThumb) { +void ARMRegisterInfo::emitLoadConstPool(MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MBBI, + unsigned DestReg, int Val, + unsigned Pred, unsigned PredReg, + const TargetInstrInfo *TII, + bool isThumb, + DebugLoc dl) const { MachineFunction &MF = *MBB.getParent(); MachineConstantPool *ConstantPool = MF.getConstantPool(); Constant *C = ConstantInt::get(Type::Int32Ty, Val); - unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2); + unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); if (isThumb) - BuildMI(MBB, MBBI, TII.get(ARM::tLDRcp), DestReg).addConstantPoolIndex(Idx); + BuildMI(MBB, MBBI, dl, + TII->get(ARM::tLDRcp),DestReg).addConstantPoolIndex(Idx); else - BuildMI(MBB, MBBI, TII.get(ARM::LDRcp), DestReg).addConstantPoolIndex(Idx) - .addReg(0).addImm(0); + BuildMI(MBB, MBBI, dl, TII->get(ARM::LDRcp), DestReg) + .addConstantPoolIndex(Idx) + .addReg(0).addImm(0).addImm(Pred).addReg(PredReg); } -void ARMRegisterInfo::reMaterialize(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, - const MachineInstr *Orig) const { - if (Orig->getOpcode() == ARM::MOVi2pieces) { - emitLoadConstPool(MBB, I, DestReg, Orig->getOperand(1).getImmedValue(), - TII, false); - return; - } - - MachineInstr *MI = Orig->clone(); - MI->getOperand(0).setReg(DestReg); - MBB.insert(I, MI); +const TargetRegisterClass *ARMRegisterInfo::getPointerRegClass() const { + return &ARM::GPRRegClass; } /// isLowRegister - Returns true if the register is low register r0-r7. /// -static bool isLowRegister(unsigned Reg) { +bool ARMRegisterInfo::isLowRegister(unsigned Reg) const { using namespace ARM; switch (Reg) { case R0: case R1: case R2: case R3: @@ -240,72 +211,24 @@ static bool isLowRegister(unsigned Reg) { } } -MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr *MI, - unsigned OpNum, int FI) const { - unsigned Opc = MI->getOpcode(); - MachineInstr *NewMI = NULL; - switch (Opc) { - default: break; - case ARM::MOVr: { - if (OpNum == 0) { // move -> store - unsigned SrcReg = MI->getOperand(1).getReg(); - NewMI = BuildMI(TII.get(ARM::STR)).addReg(SrcReg).addFrameIndex(FI) - .addReg(0).addImm(0); - } else { // move -> load - unsigned DstReg = MI->getOperand(0).getReg(); - NewMI = BuildMI(TII.get(ARM::LDR), DstReg).addFrameIndex(FI).addReg(0) - .addImm(0); - } - break; - } - case ARM::tMOVr: { - if (OpNum == 0) { // move -> store - unsigned SrcReg = MI->getOperand(1).getReg(); - if (isPhysicalRegister(SrcReg) && !isLowRegister(SrcReg)) - // tSpill cannot take a high register operand. - break; - NewMI = BuildMI(TII.get(ARM::tSpill)).addReg(SrcReg).addFrameIndex(FI) - .addImm(0); - } else { // move -> load - unsigned DstReg = MI->getOperand(0).getReg(); - if (isPhysicalRegister(DstReg) && !isLowRegister(DstReg)) - // tRestore cannot target a high register operand. - break; - NewMI = BuildMI(TII.get(ARM::tRestore), DstReg).addFrameIndex(FI) - .addImm(0); - } - break; - } - case ARM::FCPYS: { - if (OpNum == 0) { // move -> store - unsigned SrcReg = MI->getOperand(1).getReg(); - NewMI = BuildMI(TII.get(ARM::FSTS)).addReg(SrcReg).addFrameIndex(FI) - .addImm(0); - } else { // move -> load - unsigned DstReg = MI->getOperand(0).getReg(); - NewMI = BuildMI(TII.get(ARM::FLDS), DstReg).addFrameIndex(FI).addImm(0); - } - break; - } - case ARM::FCPYD: { - if (OpNum == 0) { // move -> store - unsigned SrcReg = MI->getOperand(1).getReg(); - NewMI = BuildMI(TII.get(ARM::FSTD)).addReg(SrcReg).addFrameIndex(FI) - .addImm(0); - } else { // move -> load - unsigned DstReg = MI->getOperand(0).getReg(); - NewMI = BuildMI(TII.get(ARM::FLDD), DstReg).addFrameIndex(FI).addImm(0); +const TargetRegisterClass* +ARMRegisterInfo::getPhysicalRegisterRegClass(unsigned Reg, MVT VT) const { + if (STI.isThumb()) { + if (isLowRegister(Reg)) + return ARM::tGPRRegisterClass; + switch (Reg) { + default: + break; + case ARM::R8: case ARM::R9: case ARM::R10: case ARM::R11: + case ARM::R12: case ARM::SP: case ARM::LR: case ARM::PC: + return ARM::GPRRegisterClass; } - break; - } } - - if (NewMI) - NewMI->copyKillDeadInfo(MI); - return NewMI; + return TargetRegisterInfo::getPhysicalRegisterRegClass(Reg, VT); } -const unsigned* ARMRegisterInfo::getCalleeSavedRegs() const { +const unsigned* +ARMRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { static const unsigned CalleeSavedRegs[] = { ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8, ARM::R7, ARM::R6, ARM::R5, ARM::R4, @@ -327,7 +250,7 @@ const unsigned* ARMRegisterInfo::getCalleeSavedRegs() const { } const TargetRegisterClass* const * -ARMRegisterInfo::getCalleeSavedRegClasses() const { +ARMRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { static const TargetRegisterClass * const CalleeSavedRegClasses[] = { &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, @@ -337,7 +260,16 @@ ARMRegisterInfo::getCalleeSavedRegClasses() const { &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, 0 }; - return CalleeSavedRegClasses; + static const TargetRegisterClass * const ThumbCalleeSavedRegClasses[] = { + &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass, + &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::tGPRRegClass, + &ARM::tGPRRegClass,&ARM::tGPRRegClass,&ARM::tGPRRegClass, + + &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, + &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, + 0 + }; + return STI.isThumb() ? ThumbCalleeSavedRegClasses : CalleeSavedRegClasses; } BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const { @@ -350,9 +282,6 @@ BitVector ARMRegisterInfo::getReservedRegs(const MachineFunction &MF) const { // Some targets reserve R9. if (STI.isR9Reserved()) Reserved.set(ARM::R9); - // At PEI time, if LR is used, it will be spilled upon entry. - if (MF.getUsedPhysregs() && !MF.isPhysRegUsed((unsigned)ARM::LR)) - Reserved.set(ARM::LR); return Reserved; } @@ -386,7 +315,31 @@ ARMRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { /// or if frame pointer elimination is disabled. /// bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const { - return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects(); + const MachineFrameInfo *MFI = MF.getFrameInfo(); + return NoFramePointerElim || MFI->hasVarSizedObjects(); +} + +// hasReservedCallFrame - Under normal circumstances, when a frame pointer is +// not required, we reserve argument space for call sites in the function +// immediately on entry to the current function. This eliminates the need for +// add/sub sp brackets around call sites. Returns true if the call frame is +// included as part of the stack frame. +bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { + const MachineFrameInfo *FFI = MF.getFrameInfo(); + unsigned CFSize = FFI->getMaxCallFrameSize(); + ARMFunctionInfo *AFI = MF.getInfo(); + // It's not always a good idea to include the call frame as part of the + // stack frame. ARM (especially Thumb) has small immediate offset to + // address the stack frame. So a large call frame can cause poor codegen + // and may even makes it impossible to scavenge a register. + if (AFI->isThumbFunction()) { + if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4 + return false; + } else { + if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12 + return false; + } + return !MF.getFrameInfo()->hasVarSizedObjects(); } /// emitARMRegPlusImmediate - Emits a series of instructions to materialize @@ -394,8 +347,10 @@ bool ARMRegisterInfo::hasFP(const MachineFunction &MF) const { static void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, - unsigned DestReg, unsigned BaseReg, - int NumBytes, const TargetInstrInfo &TII) { + unsigned DestReg, unsigned BaseReg, int NumBytes, + ARMCC::CondCodes Pred, unsigned PredReg, + const TargetInstrInfo &TII, + DebugLoc dl) { bool isSub = NumBytes < 0; if (isSub) NumBytes = -NumBytes; @@ -412,8 +367,9 @@ void emitARMRegPlusImmediate(MachineBasicBlock &MBB, assert(SOImmVal != -1 && "Bit extraction didn't work?"); // Build the new ADD / SUB. - BuildMI(MBB, MBBI, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) - .addReg(BaseReg, false, false, true).addImm(SOImmVal); + BuildMI(MBB, MBBI, dl, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg) + .addReg(BaseReg, false, false, true).addImm(SOImmVal) + .addImm((unsigned)Pred).addReg(PredReg).addReg(0); BaseReg = DestReg; } } @@ -448,12 +404,14 @@ static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes, /// constpool entry. static void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator &MBBI, - unsigned DestReg, unsigned BaseReg, - int NumBytes, bool CanChangeCC, - const TargetInstrInfo &TII) { - bool isHigh = !isLowRegister(DestReg) || - (BaseReg != 0 && !isLowRegister(BaseReg)); + MachineBasicBlock::iterator &MBBI, + unsigned DestReg, unsigned BaseReg, + int NumBytes, bool CanChangeCC, + const TargetInstrInfo &TII, + const ARMRegisterInfo& MRI, + DebugLoc dl) { + bool isHigh = !MRI.isLowRegister(DestReg) || + (BaseReg != 0 && !MRI.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 @@ -467,28 +425,30 @@ void emitThumbRegPlusImmInReg(MachineBasicBlock &MBB, if (DestReg == ARM::SP) { assert(BaseReg == ARM::SP && "Unexpected!"); LdReg = ARM::R3; - BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), ARM::R12) + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) .addReg(ARM::R3, false, false, true); } if (NumBytes <= 255 && NumBytes >= 0) - BuildMI(MBB, MBBI, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); else if (NumBytes < 0 && NumBytes >= -255) { - BuildMI(MBB, MBBI, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); - BuildMI(MBB, MBBI, TII.get(ARM::tNEG), LdReg) + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), LdReg).addImm(NumBytes); + BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), LdReg) .addReg(LdReg, false, false, true); } else - emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII, true); + MRI.emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, ARMCC::AL, 0, &TII, + true, dl); // Emit add / sub. int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr); - const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg); + const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, + TII.get(Opc), DestReg); if (DestReg == ARM::SP || isSub) MIB.addReg(BaseReg).addReg(LdReg, false, false, true); else MIB.addReg(LdReg).addReg(BaseReg, false, false, true); if (DestReg == ARM::SP) - BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), ARM::R3) + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) .addReg(ARM::R12, false, false, true); } @@ -498,7 +458,9 @@ static void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, unsigned DestReg, unsigned BaseReg, - int NumBytes, const TargetInstrInfo &TII) { + int NumBytes, const TargetInstrInfo &TII, + const ARMRegisterInfo& MRI, + DebugLoc dl) { bool isSub = NumBytes < 0; unsigned Bytes = (unsigned)NumBytes; if (isSub) Bytes = -NumBytes; @@ -544,20 +506,21 @@ void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, if (NumMIs > Threshold) { // This will expand into too many instructions. Load the immediate from a // constpool entry. - emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII); + emitThumbRegPlusImmInReg(MBB, MBBI, DestReg, BaseReg, NumBytes, true, TII, + MRI, dl); return; } if (DstNotEqBase) { - if (isLowRegister(DestReg) && isLowRegister(BaseReg)) { + if (MRI.isLowRegister(DestReg) && MRI.isLowRegister(BaseReg)) { // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7) unsigned Chunk = (1 << 3) - 1; unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes; Bytes -= ThisVal; - BuildMI(MBB, MBBI, TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg) + BuildMI(MBB, MBBI, dl,TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg) .addReg(BaseReg, false, false, true).addImm(ThisVal); } else { - BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), DestReg) + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg) .addReg(BaseReg, false, false, true); } BaseReg = DestReg; @@ -570,10 +533,11 @@ void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, ThisVal /= Scale; // Build the new tADD / tSUB. if (isTwoAddr) - BuildMI(MBB, MBBI, TII.get(Opc), DestReg).addReg(DestReg).addImm(ThisVal); + BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) + .addReg(DestReg).addImm(ThisVal); else { bool isKill = BaseReg != ARM::SP; - BuildMI(MBB, MBBI, TII.get(Opc), DestReg) + BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg) .addReg(BaseReg, false, false, isKill).addImm(ThisVal); BaseReg = DestReg; @@ -591,29 +555,35 @@ void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, } if (ExtraOpc) - BuildMI(MBB, MBBI, TII.get(ExtraOpc), DestReg) + BuildMI(MBB, MBBI, dl, TII.get(ExtraOpc), DestReg) .addReg(DestReg, false, false, true) .addImm(((unsigned)NumBytes) & 3); } static void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, - int NumBytes, bool isThumb, const TargetInstrInfo &TII) { + int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, + bool isThumb, const TargetInstrInfo &TII, + const ARMRegisterInfo& MRI, + DebugLoc dl) { if (isThumb) - emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII); + emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII, + MRI, dl); else - emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII); + emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, + Pred, PredReg, TII, dl); } void ARMRegisterInfo:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { - if (hasFP(MF)) { + if (!hasReservedCallFrame(MF)) { // If we have alloca, convert as follows: // ADJCALLSTACKDOWN -> sub, sp, sp, amount // ADJCALLSTACKUP -> add, sp, sp, amount MachineInstr *Old = I; - unsigned Amount = Old->getOperand(0).getImmedValue(); + DebugLoc dl = Old->getDebugLoc(); + unsigned Amount = Old->getOperand(0).getImm(); if (Amount != 0) { ARMFunctionInfo *AFI = MF.getInfo(); // We need to keep the stack aligned properly. To do this, we round the @@ -623,11 +593,19 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, Amount = (Amount+Align-1)/Align*Align; // Replace the pseudo instruction with a new instruction... - if (Old->getOpcode() == ARM::ADJCALLSTACKDOWN) { - emitSPUpdate(MBB, I, -Amount, AFI->isThumbFunction(), TII); + unsigned Opc = Old->getOpcode(); + bool isThumb = AFI->isThumbFunction(); + ARMCC::CondCodes Pred = isThumb + ? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(1).getImm(); + if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { + // Note: PredReg is operand 2 for ADJCALLSTACKDOWN. + unsigned PredReg = isThumb ? 0 : Old->getOperand(2).getReg(); + emitSPUpdate(MBB, I, -Amount, Pred, PredReg, isThumb, TII, *this, dl); } else { - assert(Old->getOpcode() == ARM::ADJCALLSTACKUP); - emitSPUpdate(MBB, I, Amount, AFI->isThumbFunction(), TII); + // Note: PredReg is operand 3 for ADJCALLSTACKUP. + unsigned PredReg = isThumb ? 0 : Old->getOperand(3).getReg(); + assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); + emitSPUpdate(MBB, I, Amount, Pred, PredReg, isThumb, TII, *this, dl); } } } @@ -639,18 +617,20 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, static void emitThumbConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, unsigned DestReg, int Imm, - const TargetInstrInfo &TII) { + const TargetInstrInfo &TII, + const ARMRegisterInfo& MRI, + DebugLoc dl) { bool isSub = Imm < 0; if (isSub) Imm = -Imm; int Chunk = (1 << 8) - 1; int ThisVal = (Imm > Chunk) ? Chunk : Imm; Imm -= ThisVal; - BuildMI(MBB, MBBI, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal); + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVi8), DestReg).addImm(ThisVal); if (Imm > 0) - emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII); + emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII, MRI, dl); if (isSub) - BuildMI(MBB, MBBI, TII.get(ARM::tNEG), DestReg) + BuildMI(MBB, MBBI, dl, TII.get(ARM::tNEG), DestReg) .addReg(DestReg, false, false, true); } @@ -661,6 +641,7 @@ static unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, ARMFunctionInfo *AFI) { unsigned Reg = RS ? RS->FindUnusedReg(RC, true) : (unsigned) ARM::R12; + assert (!AFI->isThumbFunction()); if (Reg == 0) // Try a already spilled CS register. Reg = RS->FindUnusedReg(RC, AFI->getSpilledCSRegisters()); @@ -669,23 +650,24 @@ unsigned findScratchRegister(RegScavenger *RS, const TargetRegisterClass *RC, } void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - RegScavenger *RS) const{ + int SPAdj, RegScavenger *RS) const{ unsigned i = 0; MachineInstr &MI = *II; MachineBasicBlock &MBB = *MI.getParent(); MachineFunction &MF = *MBB.getParent(); ARMFunctionInfo *AFI = MF.getInfo(); bool isThumb = AFI->isThumbFunction(); + DebugLoc dl = MI.getDebugLoc(); - while (!MI.getOperand(i).isFrameIndex()) { + while (!MI.getOperand(i).isFI()) { ++i; assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); } unsigned FrameReg = ARM::SP; - int FrameIndex = MI.getOperand(i).getFrameIndex(); + int FrameIndex = MI.getOperand(i).getIndex(); int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + - MF.getFrameInfo()->getStackSize(); + MF.getFrameInfo()->getStackSize() + SPAdj; if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex)) Offset -= AFI->getGPRCalleeSavedArea1Offset(); @@ -694,6 +676,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex)) Offset -= AFI->getDPRCalleeSavedAreaOffset(); else if (hasFP(MF)) { + assert(SPAdj == 0 && "Unexpected"); // There is alloca()'s in this function, must reference off the frame // pointer instead. FrameReg = getFrameRegister(MF); @@ -701,7 +684,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, } unsigned Opcode = MI.getOpcode(); - const TargetInstrDescriptor &Desc = TII.get(Opcode); + const TargetInstrDesc &Desc = MI.getDesc(); unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); bool isSub = false; @@ -709,14 +692,14 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, Offset += MI.getOperand(i+1).getImm(); if (Offset == 0) { // Turn it into a move. - MI.setInstrDescriptor(TII.get(ARM::MOVr)); + MI.setDesc(TII.get(ARM::MOVr)); MI.getOperand(i).ChangeToRegister(FrameReg, false); MI.RemoveOperand(i+1); return; } else if (Offset < 0) { Offset = -Offset; isSub = true; - MI.setInstrDescriptor(TII.get(ARM::SUBri)); + MI.setDesc(TII.get(ARM::SUBri)); } // Common case: small offset, fits into instruction. @@ -749,7 +732,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, unsigned Scale = 1; if (FrameReg != ARM::SP) { Opcode = ARM::tADDi3; - MI.setInstrDescriptor(TII.get(ARM::tADDi3)); + MI.setDesc(TII.get(ARM::tADDi3)); NumBits = 3; } else { NumBits = 8; @@ -760,7 +743,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, if (Offset == 0) { // Turn it into a move. - MI.setInstrDescriptor(TII.get(ARM::tMOVr)); + MI.setDesc(TII.get(ARM::tMOVhir2lor)); MI.getOperand(i).ChangeToRegister(FrameReg, false); MI.RemoveOperand(i+1); return; @@ -781,7 +764,8 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // MI would expand into a large number of instructions. Don't try to // simplify the immediate. if (NumMIs > 2) { - emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII); + emitThumbRegPlusImmediate(MBB, II, DestReg, FrameReg, Offset, TII, + *this, dl); MBB.erase(II); return; } @@ -794,13 +778,14 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(i+1).ChangeToImmediate(Mask); Offset = (Offset - Mask * Scale); MachineBasicBlock::iterator NII = next(II); - emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII); + emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII, + *this, dl); } else { // Translate r0 = add sp, -imm to // r0 = -imm (this is then translated into a series of instructons) // r0 = add r0, sp - emitThumbConstant(MBB, II, DestReg, Offset, TII); - MI.setInstrDescriptor(TII.get(ARM::tADDhirr)); + emitThumbConstant(MBB, II, DestReg, Offset, TII, *this, dl); + MI.setDesc(TII.get(ARM::tADDhirr)); MI.getOperand(i).ChangeToRegister(DestReg, false, false, true); MI.getOperand(i+1).ChangeToRegister(FrameReg, false); } @@ -896,26 +881,30 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, assert(Offset && "This code isn't needed if offset already handled!"); if (isThumb) { - if (TII.isLoad(Opcode)) { + if (Desc.mayLoad()) { // Use the destination register to materialize sp + offset. unsigned TmpReg = MI.getOperand(0).getReg(); bool UseRR = false; if (Opcode == ARM::tRestore) { if (FrameReg == ARM::SP) - emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,Offset,false,TII); + emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, + Offset, false, TII, *this, dl); else { - emitLoadConstPool(MBB, II, TmpReg, Offset, TII, true); + emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, + true, dl); UseRR = true; } } else - emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII); - MI.setInstrDescriptor(TII.get(ARM::tLDR)); + emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, + *this, dl); + MI.setDesc(TII.get(ARM::tLDR)); MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); 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)) { + // Use [reg, reg] addrmode. + MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); + else // tLDR has an extra register operand. + MI.addOperand(MachineOperand::CreateReg(0, false)); + } else if (Desc.mayStore()) { // FIXME! This is horrific!!! We need register scavenging. // Our temporary workaround has marked r3 unavailable. Of course, r3 is // also a ABI register so it's possible that is is the register that is @@ -928,35 +917,38 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, unsigned TmpReg = ARM::R3; bool UseRR = false; if (ValReg == ARM::R3) { - BuildMI(MBB, II, TII.get(ARM::tMOVr), ARM::R12) + BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) .addReg(ARM::R2, false, false, true); TmpReg = ARM::R2; } if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) - BuildMI(MBB, II, TII.get(ARM::tMOVr), ARM::R12) + BuildMI(MBB, II, dl, TII.get(ARM::tMOVlor2hir), ARM::R12) .addReg(ARM::R3, false, false, true); if (Opcode == ARM::tSpill) { if (FrameReg == ARM::SP) - emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg,Offset,false,TII); + emitThumbRegPlusImmInReg(MBB, II, TmpReg, FrameReg, + Offset, false, TII, *this, dl); else { - emitLoadConstPool(MBB, II, TmpReg, Offset, TII, true); + emitLoadConstPool(MBB, II, TmpReg, Offset, ARMCC::AL, 0, &TII, + true, dl); UseRR = true; } } else - emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII); - MI.setInstrDescriptor(TII.get(ARM::tSTR)); + emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII, + *this, dl); + MI.setDesc(TII.get(ARM::tSTR)); MI.getOperand(i).ChangeToRegister(TmpReg, false, false, true); - if (UseRR) - MI.addRegOperand(FrameReg, false); // Use [reg, reg] addrmode. - else - MI.addRegOperand(0, false); // tSTR has an extra register operand. + if (UseRR) // Use [reg, reg] addrmode. + MI.addOperand(MachineOperand::CreateReg(FrameReg, false)); + else // tSTR has an extra register operand. + MI.addOperand(MachineOperand::CreateReg(0, false)); MachineBasicBlock::iterator NII = next(II); if (ValReg == ARM::R3) - BuildMI(MBB, NII, TII.get(ARM::tMOVr), ARM::R2) + BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R2) .addReg(ARM::R12, false, false, true); if (TmpReg == ARM::R3 && AFI->isR3LiveIn()) - BuildMI(MBB, NII, TII.get(ARM::tMOVr), ARM::R3) + BuildMI(MBB, NII, dl, TII.get(ARM::tMOVhir2lor), ARM::R3) .addReg(ARM::R12, false, false, true); } else assert(false && "Unexpected opcode!"); @@ -968,9 +960,13 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI); if (ScratchReg == 0) // No register is "free". Scavenge a register. - ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II); + ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II, SPAdj); + int PIdx = MI.findFirstPredOperandIdx(); + ARMCC::CondCodes Pred = (PIdx == -1) + ? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm(); + unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg(); emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg, - isSub ? -Offset : Offset, TII); + isSub ? -Offset : Offset, Pred, PredReg, TII, dl); MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true); } } @@ -983,6 +979,8 @@ static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) { if (FixedOff > Offset) Offset = FixedOff; } for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) { + if (FFI->isDeadObjectIndex(i)) + continue; Offset += FFI->getObjectSize(i); unsigned Align = FFI->getObjectAlignment(i); // Adjust to alignment boundary @@ -1013,14 +1011,14 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, for (unsigned i = 0; CSRegs[i]; ++i) { unsigned Reg = CSRegs[i]; bool Spilled = false; - if (MF.isPhysRegUsed(Reg)) { + if (MF.getRegInfo().isPhysRegUsed(Reg)) { AFI->setCSRegisterIsSpilled(Reg); Spilled = true; CanEliminateFrame = false; } else { // Check alias registers too. for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) { - if (MF.isPhysRegUsed(*Aliases)) { + if (MF.getRegInfo().isPhysRegUsed(*Aliases)) { Spilled = true; CanEliminateFrame = false; } @@ -1034,8 +1032,7 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, if (!STI.isTargetDarwin()) { if (Reg == ARM::LR) LRSpilled = true; - else - CS1Spilled = true; + CS1Spilled = true; continue; } @@ -1077,7 +1074,7 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, bool ForceLRSpill = false; if (!LRSpilled && AFI->isThumbFunction()) { - unsigned FnSize = ARM::GetFunctionSize(MF); + unsigned FnSize = TII.GetFunctionSizeInBytes(MF); // Force LR to be spilled if the Thumb function size is > 2048. This enables // use of BL to implement far jump. If it turns out that it's not needed // then the branch fix up path will undo it. @@ -1094,7 +1091,7 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled. // Spill LR as well so we can fold BX_RET to the registers restore (LDM). if (!LRSpilled && CS1Spilled) { - MF.changePhyRegUsed(ARM::LR, true); + MF.getRegInfo().setPhysRegUsed(ARM::LR); AFI->setCSRegisterIsSpilled(ARM::LR); NumGPRSpills++; UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(), @@ -1106,7 +1103,7 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, // Darwin ABI requires FP to point to the stack slot that contains the // previous FP. if (STI.isTargetDarwin() || hasFP(MF)) { - MF.changePhyRegUsed(FramePtr, true); + MF.getRegInfo().setPhysRegUsed(FramePtr); NumGPRSpills++; } @@ -1116,14 +1113,21 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment(); if (TargetAlign == 8 && (NumGPRSpills & 1)) { if (CS1Spilled && !UnspilledCS1GPRs.empty()) { - unsigned Reg = UnspilledCS1GPRs.front(); - MF.changePhyRegUsed(Reg, true); - AFI->setCSRegisterIsSpilled(Reg); - if (!isReservedReg(MF, Reg)) - ExtraCSSpill = true; - } else if (!UnspilledCS2GPRs.empty()) { + for (unsigned i = 0, e = UnspilledCS1GPRs.size(); i != e; ++i) { + unsigned Reg = UnspilledCS1GPRs[i]; + // Don't spiil high register if the function is thumb + if (!AFI->isThumbFunction() || isLowRegister(Reg) || Reg == ARM::LR) { + MF.getRegInfo().setPhysRegUsed(Reg); + AFI->setCSRegisterIsSpilled(Reg); + if (!isReservedReg(MF, Reg)) + ExtraCSSpill = true; + break; + } + } + } else if (!UnspilledCS2GPRs.empty() && + !AFI->isThumbFunction()) { unsigned Reg = UnspilledCS2GPRs.front(); - MF.changePhyRegUsed(Reg, true); + MF.getRegInfo().setPhysRegUsed(Reg); AFI->setCSRegisterIsSpilled(Reg); if (!isReservedReg(MF, Reg)) ExtraCSSpill = true; @@ -1141,16 +1145,17 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB) for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) { for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (I->getOperand(i).isFrameIndex()) { + if (I->getOperand(i).isFI()) { unsigned Opcode = I->getOpcode(); - const TargetInstrDescriptor &Desc = TII.get(Opcode); + const TargetInstrDesc &Desc = TII.get(Opcode); unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask); if (AddrMode == ARMII::AddrMode3) { Limit = (1 << 8) - 1; goto DoneEstimating; } else if (AddrMode == ARMII::AddrMode5) { - Limit = ((1 << 8) - 1) * 4; - goto DoneEstimating; + unsigned ThisLimit = ((1 << 8) - 1) * 4; + if (ThisLimit < Limit) + Limit = ThisLimit; } } } @@ -1178,7 +1183,7 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, } if (Extras.size() && NumExtras == 0) { for (unsigned i = 0, e = Extras.size(); i != e; ++i) { - MF.changePhyRegUsed(Extras[i], true); + MF.getRegInfo().setPhysRegUsed(Extras[i]); AFI->setCSRegisterIsSpilled(Extras[i]); } } else { @@ -1192,7 +1197,7 @@ ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, } if (ForceLRSpill) { - MF.changePhyRegUsed(ARM::LR, true); + MF.getRegInfo().setPhysRegUsed(ARM::LR); AFI->setCSRegisterIsSpilled(ARM::LR); AFI->setLRIsSpilledForFarJump(true); } @@ -1206,7 +1211,7 @@ static void movePastCSLoadStoreOps(MachineBasicBlock &MBB, int Opc, unsigned Area, const ARMSubtarget &STI) { while (MBBI != MBB.end() && - MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFrameIndex()) { + MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFI()) { if (Area != 0) { bool Done = false; unsigned Category = 0; @@ -1241,15 +1246,16 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { ARMFunctionInfo *AFI = MF.getInfo(); bool isThumb = AFI->isThumbFunction(); unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); unsigned NumBytes = MFI->getStackSize(); const std::vector &CSI = MFI->getCalleeSavedInfo(); + DebugLoc dl = (MBBI != MBB.end() ? + MBBI->getDebugLoc() : DebugLoc::getUnknownLoc()); if (isThumb) { // Check if R3 is live in. It might have to be used as a scratch register. - for (MachineFunction::livein_iterator I=MF.livein_begin(),E=MF.livein_end(); - I != E; ++I) { - if ((*I).first == ARM::R3) { + for (MachineRegisterInfo::livein_iterator I =MF.getRegInfo().livein_begin(), + E = MF.getRegInfo().livein_end(); I != E; ++I) { + if (I->first == ARM::R3) { AFI->setR3IsLiveIn(true); break; } @@ -1266,11 +1272,12 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { int FramePtrSpillFI = 0; if (VARegSaveSize) - emitSPUpdate(MBB, MBBI, -VARegSaveSize, isThumb, TII); + emitSPUpdate(MBB, MBBI, -VARegSaveSize, ARMCC::AL, 0, isThumb, TII, + *this, dl); if (!AFI->hasStackFrame()) { if (NumBytes != 0) - emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII); + emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); return; } @@ -1308,30 +1315,33 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { } } - if (Align == 8 && (GPRCS1Size & 7) != 0) - // Pad CS1 to ensure proper alignment. - GPRCS1Size += 4; - if (!isThumb) { // Build the new SUBri to adjust SP for integer callee-save spill area 1. - emitSPUpdate(MBB, MBBI, -GPRCS1Size, isThumb, TII); + emitSPUpdate(MBB, MBBI, -GPRCS1Size, ARMCC::AL, 0, isThumb, TII, *this, dl); movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI); - } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) + } else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) { ++MBBI; + if (MBBI != MBB.end()) + dl = MBBI->getDebugLoc(); + } // Darwin ABI requires FP to point to the stack slot that contains the // previous FP. - if (STI.isTargetDarwin() || hasFP(MF)) - BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri), FramePtr) + if (STI.isTargetDarwin() || hasFP(MF)) { + MachineInstrBuilder MIB = + BuildMI(MBB, MBBI, dl, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri), + FramePtr) .addFrameIndex(FramePtrSpillFI).addImm(0); + if (!isThumb) AddDefaultCC(AddDefaultPred(MIB)); + } if (!isThumb) { // Build the new SUBri to adjust SP for integer callee-save spill area 2. - emitSPUpdate(MBB, MBBI, -GPRCS2Size, false, TII); + emitSPUpdate(MBB, MBBI, -GPRCS2Size, ARMCC::AL, 0, false, TII, *this, dl); // Build the new SUBri to adjust SP for FP callee-save spill area. movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI); - emitSPUpdate(MBB, MBBI, -DPRCSSize, false, TII); + emitSPUpdate(MBB, MBBI, -DPRCSSize, ARMCC::AL, 0, false, TII, *this, dl); } // Determine starting offsets of spill areas. @@ -1348,7 +1358,12 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { // Insert it after all the callee-save spills. if (!isThumb) movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI); - emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII); + emitSPUpdate(MBB, MBBI, -NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); + } + + if(STI.isTargetELF() && hasFP(MF)) { + MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - + AFI->getFramePtrSpillOffset()); } AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); @@ -1367,26 +1382,27 @@ static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) { return ((MI->getOpcode() == ARM::FLDD || MI->getOpcode() == ARM::LDR || MI->getOpcode() == ARM::tRestore) && - MI->getOperand(1).isFrameIndex() && + MI->getOperand(1).isFI() && isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); } void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { + MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = prior(MBB.end()); assert((MBBI->getOpcode() == ARM::BX_RET || MBBI->getOpcode() == ARM::tBX_RET || MBBI->getOpcode() == ARM::tPOP_RET) && "Can only insert epilog into returning blocks"); - + DebugLoc dl = MBBI->getDebugLoc(); MachineFrameInfo *MFI = MF.getFrameInfo(); ARMFunctionInfo *AFI = MF.getInfo(); bool isThumb = AFI->isThumbFunction(); unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize(); int NumBytes = (int)MFI->getStackSize(); + if (!AFI->hasStackFrame()) { if (NumBytes != 0) - emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII); + emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, *this, dl); } else { // Unwind MBBI to point to first LDR / FLDD. const unsigned *CSRegs = getCalleeSavedRegs(); @@ -1408,17 +1424,21 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, // 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); + emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes, + TII, *this, dl); else - BuildMI(MBB, MBBI, TII.get(ARM::tMOVr), ARM::SP).addReg(FramePtr); + BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVlor2hir), 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); + emitSPUpdate(MBB, PMBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, + *this, dl); } else - emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII); + emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, isThumb, TII, + *this, dl); } } else { // Darwin ABI requires FP to point to the stack slot that contains the @@ -1430,27 +1450,33 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, if (AFI->getGPRCalleeSavedArea2Size() || AFI->getDPRCalleeSavedAreaSize() || AFI->getDPRCalleeSavedAreaOffset()|| - hasFP(MF)) + hasFP(MF)) { if (NumBytes) - BuildMI(MBB, MBBI, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) - .addImm(NumBytes); + BuildMI(MBB, MBBI, dl, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr) + .addImm(NumBytes) + .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); else - BuildMI(MBB, MBBI, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr); + BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP).addReg(FramePtr) + .addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); + } } else if (NumBytes) { - emitSPUpdate(MBB, MBBI, NumBytes, false, TII); + emitSPUpdate(MBB, MBBI, NumBytes, ARMCC::AL, 0, false, TII, *this, dl); } // Move SP to start of integer callee save spill area 2. movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI); - emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), false, TII); + emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), ARMCC::AL, 0, + false, TII, *this, dl); // Move SP to start of integer callee save spill area 1. movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI); - emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), false, TII); + emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), ARMCC::AL, 0, + false, TII, *this, dl); // Move SP to SP upon entry to the function. movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI); - emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), false, TII); + emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), ARMCC::AL, 0, + false, TII, *this, dl); } } @@ -1458,12 +1484,13 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF, if (isThumb) // Epilogue for vararg functions: pop LR to R3 and branch off it. // FIXME: Verify this is still ok when R3 is no longer being reserved. - BuildMI(MBB, MBBI, TII.get(ARM::tPOP)).addReg(ARM::R3); + BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP)).addReg(ARM::R3); - emitSPUpdate(MBB, MBBI, VARegSaveSize, isThumb, TII); + emitSPUpdate(MBB, MBBI, VARegSaveSize, ARMCC::AL, 0, isThumb, TII, + *this, dl); if (isThumb) { - BuildMI(MBB, MBBI, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3); + BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)).addReg(ARM::R3); MBB.erase(MBBI); } } @@ -1474,7 +1501,10 @@ unsigned ARMRegisterInfo::getRARegister() const { } unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const { - return STI.useThumbBacktraces() ? ARM::R7 : ARM::R11; + if (STI.isTargetDarwin() || hasFP(MF)) + return (STI.useThumbBacktraces() || STI.isThumb()) ? ARM::R7 : ARM::R11; + else + return ARM::SP; } unsigned ARMRegisterInfo::getEHExceptionRegister() const { @@ -1487,5 +1517,8 @@ unsigned ARMRegisterInfo::getEHHandlerRegister() const { return 0; } -#include "ARMGenRegisterInfo.inc" +int ARMRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { + return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); +} +#include "ARMGenRegisterInfo.inc"