diff options
| author | Anton Korobeynikov <asl@math.spbu.ru> | 2010-11-27 23:05:03 +0000 |
|---|---|---|
| committer | Anton Korobeynikov <asl@math.spbu.ru> | 2010-11-27 23:05:03 +0000 |
| commit | d08fbd19f5b05b8dfff5ae13726301618c62a4d0 (patch) | |
| tree | 71b65a3ebf6940e12b4dcf1ab09847711cf620bb /llvm/lib/Target/SystemZ | |
| parent | 056356d50204f035c381b8004a3a66c60e314115 (diff) | |
| download | bcm5719-llvm-d08fbd19f5b05b8dfff5ae13726301618c62a4d0.tar.gz bcm5719-llvm-d08fbd19f5b05b8dfff5ae13726301618c62a4d0.zip | |
Move callee-saved regs spills / reloads to TFI
llvm-svn: 120228
Diffstat (limited to 'llvm/lib/Target/SystemZ')
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp | 154 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZFrameInfo.h | 15 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 150 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.h | 10 |
4 files changed, 166 insertions, 163 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp b/llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp index 331b917415b..7fde9a0144f 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp @@ -27,6 +27,31 @@ using namespace llvm; +SystemZFrameInfo::SystemZFrameInfo(const SystemZSubtarget &sti) + : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160), STI(sti) { + // Fill the spill offsets map + static const unsigned SpillOffsTab[][2] = { + { SystemZ::R2D, 0x10 }, + { SystemZ::R3D, 0x18 }, + { SystemZ::R4D, 0x20 }, + { SystemZ::R5D, 0x28 }, + { SystemZ::R6D, 0x30 }, + { SystemZ::R7D, 0x38 }, + { SystemZ::R8D, 0x40 }, + { SystemZ::R9D, 0x48 }, + { SystemZ::R10D, 0x50 }, + { SystemZ::R11D, 0x58 }, + { SystemZ::R12D, 0x60 }, + { SystemZ::R13D, 0x68 }, + { SystemZ::R14D, 0x70 }, + { SystemZ::R15D, 0x78 } + }; + + RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS); + + for (unsigned i = 0, e = array_lengthof(SpillOffsTab); i != e; ++i) + RegSpillOffsets[SpillOffsTab[i][0]] = SpillOffsTab[i][1]; +} /// needsFP - Return true if the specified function should have a dedicated /// frame pointer register. This is true if the function has variable sized @@ -197,3 +222,132 @@ int SystemZFrameInfo::getFrameIndexOffset(const MachineFunction &MF, return Offset; } + +bool +SystemZFrameInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector<CalleeSavedInfo> &CSI, + const TargetRegisterInfo *TRI) const { + if (CSI.empty()) + return false; + + DebugLoc DL; + if (MI != MBB.end()) DL = MI->getDebugLoc(); + + MachineFunction &MF = *MBB.getParent(); + const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); + unsigned CalleeFrameSize = 0; + + // Scan the callee-saved and find the bounds of register spill area. + unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0; + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + if (!SystemZ::FP64RegClass.contains(Reg)) { + unsigned Offset = RegSpillOffsets[Reg]; + CalleeFrameSize += 8; + if (StartOffset > Offset) { + LowReg = Reg; StartOffset = Offset; + } + if (EndOffset < Offset) { + HighReg = Reg; EndOffset = RegSpillOffsets[Reg]; + } + } + } + + // Save information for epilogue inserter. + MFI->setCalleeSavedFrameSize(CalleeFrameSize); + MFI->setLowReg(LowReg); MFI->setHighReg(HighReg); + + // Save GPRs + if (StartOffset) { + // Build a store instruction. Use STORE MULTIPLE instruction if there are many + // registers to store, otherwise - just STORE. + MachineInstrBuilder MIB = + BuildMI(MBB, MI, DL, TII.get((LowReg == HighReg ? + SystemZ::MOV64mr : SystemZ::MOV64mrm))); + + // Add store operands. + MIB.addReg(SystemZ::R15D).addImm(StartOffset); + if (LowReg == HighReg) + MIB.addReg(0); + MIB.addReg(LowReg, RegState::Kill); + if (LowReg != HighReg) + MIB.addReg(HighReg, RegState::Kill); + + // Do a second scan adding regs as being killed by instruction + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + // Add the callee-saved register as live-in. It's killed at the spill. + MBB.addLiveIn(Reg); + if (Reg != LowReg && Reg != HighReg) + MIB.addReg(Reg, RegState::ImplicitKill); + } + } + + // Save FPRs + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + if (SystemZ::FP64RegClass.contains(Reg)) { + MBB.addLiveIn(Reg); + TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), + &SystemZ::FP64RegClass, TRI); + } + } + + return true; +} + +bool +SystemZFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector<CalleeSavedInfo> &CSI, + const TargetRegisterInfo *TRI) const { + if (CSI.empty()) + return false; + + DebugLoc DL; + if (MI != MBB.end()) DL = MI->getDebugLoc(); + + MachineFunction &MF = *MBB.getParent(); + const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); + + // Restore FP registers + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + if (SystemZ::FP64RegClass.contains(Reg)) + TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), + &SystemZ::FP64RegClass, TRI); + } + + // Restore GP registers + unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg(); + unsigned StartOffset = RegSpillOffsets[LowReg]; + + if (StartOffset) { + // Build a load instruction. Use LOAD MULTIPLE instruction if there are many + // registers to load, otherwise - just LOAD. + MachineInstrBuilder MIB = + BuildMI(MBB, MI, DL, TII.get((LowReg == HighReg ? + SystemZ::MOV64rm : SystemZ::MOV64rmm))); + // Add store operands. + MIB.addReg(LowReg, RegState::Define); + if (LowReg != HighReg) + MIB.addReg(HighReg, RegState::Define); + + MIB.addReg(hasFP(MF) ? SystemZ::R11D : SystemZ::R15D); + MIB.addImm(StartOffset); + if (LowReg == HighReg) + MIB.addReg(0); + + // Do a second scan adding regs as being defined by instruction + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + if (Reg != LowReg && Reg != HighReg) + MIB.addReg(Reg, RegState::ImplicitDefine); + } + } + + return true; +} diff --git a/llvm/lib/Target/SystemZ/SystemZFrameInfo.h b/llvm/lib/Target/SystemZ/SystemZFrameInfo.h index 85782f86f05..a977502d65b 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZFrameInfo.h @@ -17,24 +17,33 @@ #include "SystemZ.h" #include "SystemZSubtarget.h" #include "llvm/Target/TargetFrameInfo.h" +#include "llvm/ADT/IndexedMap.h" namespace llvm { class SystemZSubtarget; class SystemZFrameInfo : public TargetFrameInfo { + IndexedMap<unsigned> RegSpillOffsets; protected: const SystemZSubtarget &STI; public: - explicit SystemZFrameInfo(const SystemZSubtarget &sti) - : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160), STI(sti) { - } + explicit SystemZFrameInfo(const SystemZSubtarget &sti); /// emitProlog/emitEpilog - These methods insert prolog and epilog code into /// the function. void emitPrologue(MachineFunction &MF) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector<CalleeSavedInfo> &CSI, + const TargetRegisterInfo *TRI) const; + bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector<CalleeSavedInfo> &CSI, + const TargetRegisterInfo *TRI) const; + bool hasReservedCallFrame(const MachineFunction &MF) const { return true; } bool hasFP(const MachineFunction &MF) const; int getFrameIndexOffset(const MachineFunction &MF, int FI) const; diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index c145ce08458..be5280323c3 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -28,28 +28,6 @@ using namespace llvm; SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) : TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)), RI(tm, *this), TM(tm) { - // Fill the spill offsets map - static const unsigned SpillOffsTab[][2] = { - { SystemZ::R2D, 0x10 }, - { SystemZ::R3D, 0x18 }, - { SystemZ::R4D, 0x20 }, - { SystemZ::R5D, 0x28 }, - { SystemZ::R6D, 0x30 }, - { SystemZ::R7D, 0x38 }, - { SystemZ::R8D, 0x40 }, - { SystemZ::R9D, 0x48 }, - { SystemZ::R10D, 0x50 }, - { SystemZ::R11D, 0x58 }, - { SystemZ::R12D, 0x60 }, - { SystemZ::R13D, 0x68 }, - { SystemZ::R14D, 0x70 }, - { SystemZ::R15D, 0x78 } - }; - - RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS); - - for (unsigned i = 0, e = array_lengthof(SpillOffsTab); i != e; ++i) - RegSpillOffsets[SpillOffsTab[i][0]] = SpillOffsTab[i][1]; } /// isGVStub - Return true if the GV requires an extra load to get the @@ -211,134 +189,6 @@ unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI, return 0; } -bool -SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, - const TargetRegisterInfo *TRI) const { - if (CSI.empty()) - return false; - - DebugLoc DL; - if (MI != MBB.end()) DL = MI->getDebugLoc(); - - MachineFunction &MF = *MBB.getParent(); - SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); - unsigned CalleeFrameSize = 0; - - // Scan the callee-saved and find the bounds of register spill area. - unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0; - for (unsigned i = 0, e = CSI.size(); i != e; ++i) { - unsigned Reg = CSI[i].getReg(); - if (!SystemZ::FP64RegClass.contains(Reg)) { - unsigned Offset = RegSpillOffsets[Reg]; - CalleeFrameSize += 8; - if (StartOffset > Offset) { - LowReg = Reg; StartOffset = Offset; - } - if (EndOffset < Offset) { - HighReg = Reg; EndOffset = RegSpillOffsets[Reg]; - } - } - } - - // Save information for epilogue inserter. - MFI->setCalleeSavedFrameSize(CalleeFrameSize); - MFI->setLowReg(LowReg); MFI->setHighReg(HighReg); - - // Save GPRs - if (StartOffset) { - // Build a store instruction. Use STORE MULTIPLE instruction if there are many - // registers to store, otherwise - just STORE. - MachineInstrBuilder MIB = - BuildMI(MBB, MI, DL, get((LowReg == HighReg ? - SystemZ::MOV64mr : SystemZ::MOV64mrm))); - - // Add store operands. - MIB.addReg(SystemZ::R15D).addImm(StartOffset); - if (LowReg == HighReg) - MIB.addReg(0); - MIB.addReg(LowReg, RegState::Kill); - if (LowReg != HighReg) - MIB.addReg(HighReg, RegState::Kill); - - // Do a second scan adding regs as being killed by instruction - for (unsigned i = 0, e = CSI.size(); i != e; ++i) { - unsigned Reg = CSI[i].getReg(); - // Add the callee-saved register as live-in. It's killed at the spill. - MBB.addLiveIn(Reg); - if (Reg != LowReg && Reg != HighReg) - MIB.addReg(Reg, RegState::ImplicitKill); - } - } - - // Save FPRs - for (unsigned i = 0, e = CSI.size(); i != e; ++i) { - unsigned Reg = CSI[i].getReg(); - if (SystemZ::FP64RegClass.contains(Reg)) { - MBB.addLiveIn(Reg); - storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(), - &SystemZ::FP64RegClass, &RI); - } - } - - return true; -} - -bool -SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, - const TargetRegisterInfo *TRI) const { - if (CSI.empty()) - return false; - - DebugLoc DL; - if (MI != MBB.end()) DL = MI->getDebugLoc(); - - MachineFunction &MF = *MBB.getParent(); - const TargetFrameInfo *TFI = MF.getTarget().getFrameInfo(); - SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>(); - - // Restore FP registers - for (unsigned i = 0, e = CSI.size(); i != e; ++i) { - unsigned Reg = CSI[i].getReg(); - if (SystemZ::FP64RegClass.contains(Reg)) - loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(), - &SystemZ::FP64RegClass, &RI); - } - - // Restore GP registers - unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg(); - unsigned StartOffset = RegSpillOffsets[LowReg]; - - if (StartOffset) { - // Build a load instruction. Use LOAD MULTIPLE instruction if there are many - // registers to load, otherwise - just LOAD. - MachineInstrBuilder MIB = - BuildMI(MBB, MI, DL, get((LowReg == HighReg ? - SystemZ::MOV64rm : SystemZ::MOV64rmm))); - // Add store operands. - MIB.addReg(LowReg, RegState::Define); - if (LowReg != HighReg) - MIB.addReg(HighReg, RegState::Define); - - MIB.addReg(TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D); - MIB.addImm(StartOffset); - if (LowReg == HighReg) - MIB.addReg(0); - - // Do a second scan adding regs as being defined by instruction - for (unsigned i = 0, e = CSI.size(); i != e; ++i) { - unsigned Reg = CSI[i].getReg(); - if (Reg != LowReg && Reg != HighReg) - MIB.addReg(Reg, RegState::ImplicitDefine); - } - } - - return true; -} - bool SystemZInstrInfo:: ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { assert(Cond.size() == 1 && "Invalid Xbranch condition!"); diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h index c248f2489c4..6cb72001020 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -50,7 +50,6 @@ namespace SystemZII { class SystemZInstrInfo : public TargetInstrInfoImpl { const SystemZRegisterInfo RI; SystemZTargetMachine &TM; - IndexedMap<unsigned> RegSpillOffsets; public: explicit SystemZInstrInfo(SystemZTargetMachine &TM); @@ -80,15 +79,6 @@ public: const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const; - virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, - const TargetRegisterInfo *TRI) const; - virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, - const TargetRegisterInfo *TRI) const; - bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const; virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const; virtual bool AnalyzeBranch(MachineBasicBlock &MBB, |

