diff options
author | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2013-05-29 04:46:31 +0000 |
---|---|---|
committer | Venkatraman Govindaraju <venkatra@cs.wisc.edu> | 2013-05-29 04:46:31 +0000 |
commit | 530086925695f074b0e1e38a0d88ee6a4c91c54c (patch) | |
tree | 3f0208636976c50c5a15795252265ff6a59225e6 /lib/Target/Sparc/SparcFrameLowering.cpp | |
parent | 0cf4adbcef584cb56254e253b47315b4c3d073ec (diff) | |
download | external_llvm-530086925695f074b0e1e38a0d88ee6a4c91c54c.zip external_llvm-530086925695f074b0e1e38a0d88ee6a4c91c54c.tar.gz external_llvm-530086925695f074b0e1e38a0d88ee6a4c91c54c.tar.bz2 |
[Sparc] Add support for leaf functions in sparc backend.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182822 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc/SparcFrameLowering.cpp')
-rw-r--r-- | lib/Target/Sparc/SparcFrameLowering.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/Target/Sparc/SparcFrameLowering.cpp b/lib/Target/Sparc/SparcFrameLowering.cpp index afa8411..3832c10 100644 --- a/lib/Target/Sparc/SparcFrameLowering.cpp +++ b/lib/Target/Sparc/SparcFrameLowering.cpp @@ -26,7 +26,18 @@ using namespace llvm; +static cl::opt<bool> +DisableLeafProc("disable-sparc-leaf-proc", + cl::init(true), + cl::desc("Disable Sparc leaf procedure optimization."), + cl::Hidden); + + void SparcFrameLowering::emitPrologue(MachineFunction &MF) const { + SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); + if (FuncInfo->isLeafProc()) + return; + MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); const SparcInstrInfo &TII = @@ -97,6 +108,9 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, void SparcFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { + SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); + if (FuncInfo->isLeafProc()) + return; MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); const SparcInstrInfo &TII = *static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo()); @@ -121,3 +135,65 @@ bool SparcFrameLowering::hasFP(const MachineFunction &MF) const { MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); } + +static bool verifyLeafProcRegUse(MachineRegisterInfo *MRI) +{ + + for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) + if (MRI->isPhysRegUsed(reg)) + return false; + + for (unsigned reg = SP::L0; reg <= SP::L7; ++reg) + if (MRI->isPhysRegUsed(reg)) + return false; + + return true; +} + +bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const +{ + + MachineRegisterInfo &MRI = MF.getRegInfo(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + return !(MFI->hasCalls() // has calls + || MRI.isPhysRegUsed(SP::L0) // Too many registers needed + || MRI.isPhysRegUsed(SP::O6) // %SP is used + || hasFP(MF)); // need %FP +} + +void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const { + + MachineRegisterInfo &MRI = MF.getRegInfo(); + + //remap %i[0-7] to %o[0-7] + for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) { + if (!MRI.isPhysRegUsed(reg)) + continue; + unsigned mapped_reg = (reg - SP::I0 + SP::O0); + assert(!MRI.isPhysRegUsed(mapped_reg)); + + //Replace I register with O register + MRI.replaceRegWith(reg, mapped_reg); + + //mark the reg unused. + MRI.setPhysRegUnused(reg); + } + + assert(verifyLeafProcRegUse(&MRI)); +#ifdef XDEBUG + MF.verify(0, "After LeafProc Remapping"); +#endif +} + +void SparcFrameLowering::processFunctionBeforeCalleeSavedScan + (MachineFunction &MF, RegScavenger *RS) const { + + if (!DisableLeafProc && isLeafProc(MF)) { + SparcMachineFunctionInfo *MFI = MF.getInfo<SparcMachineFunctionInfo>(); + MFI->setLeafProc(true); + + remapRegsForLeafProc(MF); + } + +} |