diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 36d8a0797085..b023379e7ba8 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -208,10 +208,8 @@ ARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, DebugLoc DL; if (MI != MBB.end()) DL = MI->getDebugLoc(); - MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, get(ARM::tPUSH)); - AddDefaultPred(MIB); - for (unsigned i = CSI.size(); i != 0; --i) { - unsigned Reg = CSI[i-1].getReg(); + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); bool isKill = true; // Add the callee-saved register as live-in unless it's LR and @@ -227,58 +225,15 @@ ARMBaseInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, if (isKill) MBB.addLiveIn(Reg); - if (!isARMPushRegister(Reg)) { - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - storeRegToStackSlot(MBB, MI, Reg, isKill, - CSI[i-1].getFrameIdx(), RC, TRI); - } else - MIB.addReg(Reg, getKillRegState(isKill)); + // Insert the spill to the stack frame. The register is killed at the spill + // + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + storeRegToStackSlot(MBB, MI, Reg, isKill, + CSI[i].getFrameIdx(), RC, TRI); } return true; } -bool -ARMBaseInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const { - MachineFunction &MF = *MBB.getParent(); - ARMFunctionInfo *AFI = MF.getInfo(); - if (CSI.empty()) - return false; - - bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; - DebugLoc DL = MI->getDebugLoc(); - MachineInstrBuilder MIB = BuildMI(MF, DL, get(ARM::tPOP)); - AddDefaultPred(MIB); - - bool NumRegs = false; - for (unsigned i = CSI.size(); i != 0; --i) { - unsigned Reg = CSI[i-1].getReg(); - if (Reg == ARM::LR && !isVarArg) { - Reg = ARM::PC; - (*MIB).setDesc(get(ARM::tPOP_RET)); - MI = MBB.erase(MI); - } - - if (!isARMPushRegister(Reg)) { - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - loadRegFromStackSlot(MBB, MI, Reg, CSI[i-1].getFrameIdx(), RC, TRI); - } else - MIB.addReg(Reg, getDefRegState(true)); - NumRegs = true; - } - - // It's illegal to emit pop instruction without operands. - if (NumRegs) - MBB.insert(MI, &*MIB); - else - MF.DeleteMachineInstr(MIB); - - return true; -} - - // Branch analysis. bool ARMBaseInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, @@ -2091,7 +2046,7 @@ int ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, case ARM::VLDMQ: case ARM::VSTMQ: return 2; - } + } } bool ARMBaseInstrInfo:: diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index 065e04af5e0b..c11f02ccb109 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -211,11 +211,6 @@ public: const std::vector &CSI, const TargetRegisterInfo *TRI) const; - bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const; - // Branch analysis. virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 9969de94e54e..f72713325ad6 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -1667,9 +1667,9 @@ static void movePastCSLoadStoreOps(MachineBasicBlock &MBB, int Opc1, int Opc2, unsigned Area, const ARMSubtarget &STI) { while (MBBI != MBB.end() && - ((MBBI->getOpcode() == Opc1) || (MBBI->getOpcode() == Opc2))) { - - if (Area == 3) { + ((MBBI->getOpcode() == Opc1) || (MBBI->getOpcode() == Opc2)) && + MBBI->getOperand(1).isFI()) { + if (Area != 0) { bool Done = false; unsigned Category = 0; switch (MBBI->getOperand(0).getReg()) { @@ -1759,7 +1759,9 @@ emitPrologue(MachineFunction &MF) const { } } - movePastCSLoadStoreOps(MBB, MBBI, ARM::tPUSH, 0, 1, STI); + // Build the new SUBri to adjust SP for integer callee-save spill area 1. + emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS1Size); + movePastCSLoadStoreOps(MBB, MBBI, ARM::STRi12, ARM::t2STRi12, 1, STI); // Set FP to point to the stack slot that contains the previous FP. // For Darwin, FP is R7, which has now been stored in spill area 1. @@ -1779,7 +1781,7 @@ emitPrologue(MachineFunction &MF) const { emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCS2Size); // Build the new SUBri to adjust SP for FP callee-save spill area. - movePastCSLoadStoreOps(MBB, MBBI, ARM::tPUSH, 0, 2, STI); + movePastCSLoadStoreOps(MBB, MBBI, ARM::STRi12, ARM::t2STRi12, 2, STI); emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRCSSize); // Determine starting offsets of spill areas. @@ -1873,25 +1875,11 @@ static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) { static bool isCSRestore(MachineInstr *MI, const ARMBaseInstrInfo &TII, const unsigned *CSRegs) { - - // Integer spill area is handled with pop. - if (MI->getOpcode() == ARM::tRestore || - MI->getOpcode() == ARM::tPOP) { - // The first two operands are predicates. The last two are - // imp-def and imp-use of SP. Check everything in between. - for (int i = 2, e = MI->getNumOperands() - 2; i != e; ++i) - if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs)) - return false; - return true; - } - - // Or if this is a fp reg spill. - if (MI->getOpcode() == (int)ARM::VLDRD && - MI->getOperand(1).isFI() && - isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)) - return true; - - return false; + return ((MI->getOpcode() == (int)ARM::VLDRD || + MI->getOpcode() == (int)ARM::LDRi12 || + MI->getOpcode() == (int)ARM::t2LDRi12) && + MI->getOperand(1).isFI() && + isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)); } void ARMBaseRegisterInfo:: @@ -1957,8 +1945,12 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getDPRCalleeSavedAreaSize()); // Move SP to start of integer callee save spill area 1. - movePastCSLoadStoreOps(MBB, MBBI, ARM::tPOP, 0, 2, STI); + movePastCSLoadStoreOps(MBB, MBBI, ARM::LDRi12, ARM::t2LDRi12, 2, STI); emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea2Size()); + + // Move SP to SP upon entry to the function. + movePastCSLoadStoreOps(MBB, MBBI, ARM::LDRi12, ARM::t2LDRi12, 1, STI); + emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getGPRCalleeSavedArea1Size()); } if (RetOpcode == ARM::TCRETURNdi || RetOpcode == ARM::TCRETURNdiND || diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h index 2bf7a91c910e..4907f01f448e 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -44,20 +44,6 @@ static inline bool isARMLowRegister(unsigned Reg) { } } -/// isARMPushRegister - Returns true if the register is a low register (r0-r7) -/// or a stack/pc register that we should push/pop. -static inline bool isARMPushRegister(unsigned Reg) { - using namespace ARM; - switch (Reg) { - case R0: case R1: case R2: case R3: - case R4: case R5: case R6: case R7: - case LR: case SP: case PC: - return true; - default: - return false; - } -} - class ARMBaseRegisterInfo : public ARMGenRegisterInfo { protected: const ARMBaseInstrInfo &TII; diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index 81279d257c01..d15963986c77 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -148,7 +148,7 @@ bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM, bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel) { // FIXME: temporarily disabling load / store optimization pass for Thumb1. - if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only()) + if (!Subtarget.isThumb1Only()) PM.add(createARMLoadStoreOptimizationPass(true)); return true; @@ -157,12 +157,11 @@ bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM, bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM, CodeGenOpt::Level OptLevel) { // FIXME: temporarily disabling load / store optimization pass for Thumb1. - if (OptLevel != CodeGenOpt::None) { - if (!Subtarget.isThumb1Only()) - PM.add(createARMLoadStoreOptimizationPass()); - if (Subtarget.hasNEON()) - PM.add(createNEONMoveFixPass()); - } + if (!Subtarget.isThumb1Only()) + PM.add(createARMLoadStoreOptimizationPass()); + + if (OptLevel != CodeGenOpt::None && Subtarget.hasNEON()) + PM.add(createNEONMoveFixPass()); // Expand some pseudo instructions into multiple instructions to allow // proper scheduling.