LLVM API Documentation

SparcFrameLowering.cpp
Go to the documentation of this file.
00001 //===-- SparcFrameLowering.cpp - Sparc Frame Information ------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the Sparc implementation of TargetFrameLowering class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "SparcFrameLowering.h"
00015 #include "SparcInstrInfo.h"
00016 #include "SparcMachineFunctionInfo.h"
00017 #include "SparcSubtarget.h"
00018 #include "llvm/CodeGen/MachineFrameInfo.h"
00019 #include "llvm/CodeGen/MachineFunction.h"
00020 #include "llvm/CodeGen/MachineInstrBuilder.h"
00021 #include "llvm/CodeGen/MachineModuleInfo.h"
00022 #include "llvm/CodeGen/MachineRegisterInfo.h"
00023 #include "llvm/IR/DataLayout.h"
00024 #include "llvm/IR/Function.h"
00025 #include "llvm/Support/CommandLine.h"
00026 #include "llvm/Target/TargetOptions.h"
00027 
00028 using namespace llvm;
00029 
00030 static cl::opt<bool>
00031 DisableLeafProc("disable-sparc-leaf-proc",
00032                 cl::init(false),
00033                 cl::desc("Disable Sparc leaf procedure optimization."),
00034                 cl::Hidden);
00035 
00036 SparcFrameLowering::SparcFrameLowering(const SparcSubtarget &ST)
00037     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
00038                           ST.is64Bit() ? 16 : 8, 0, ST.is64Bit() ? 16 : 8) {}
00039 
00040 void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF,
00041                                           MachineBasicBlock &MBB,
00042                                           MachineBasicBlock::iterator MBBI,
00043                                           int NumBytes,
00044                                           unsigned ADDrr,
00045                                           unsigned ADDri) const {
00046 
00047   DebugLoc dl = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc();
00048   const SparcInstrInfo &TII =
00049       *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
00050 
00051   if (NumBytes >= -4096 && NumBytes < 4096) {
00052     BuildMI(MBB, MBBI, dl, TII.get(ADDri), SP::O6)
00053       .addReg(SP::O6).addImm(NumBytes);
00054     return;
00055   }
00056 
00057   // Emit this the hard way.  This clobbers G1 which we always know is
00058   // available here.
00059   if (NumBytes >= 0) {
00060     // Emit nonnegative numbers with sethi + or.
00061     // sethi %hi(NumBytes), %g1
00062     // or %g1, %lo(NumBytes), %g1
00063     // add %sp, %g1, %sp
00064     BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1)
00065       .addImm(HI22(NumBytes));
00066     BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1)
00067       .addReg(SP::G1).addImm(LO10(NumBytes));
00068     BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6)
00069       .addReg(SP::O6).addReg(SP::G1);
00070     return ;
00071   }
00072 
00073   // Emit negative numbers with sethi + xor.
00074   // sethi %hix(NumBytes), %g1
00075   // xor %g1, %lox(NumBytes), %g1
00076   // add %sp, %g1, %sp
00077   BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1)
00078     .addImm(HIX22(NumBytes));
00079   BuildMI(MBB, MBBI, dl, TII.get(SP::XORri), SP::G1)
00080     .addReg(SP::G1).addImm(LOX10(NumBytes));
00081   BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6)
00082     .addReg(SP::O6).addReg(SP::G1);
00083 }
00084 
00085 void SparcFrameLowering::emitPrologue(MachineFunction &MF) const {
00086   SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
00087 
00088   MachineBasicBlock &MBB = MF.front();
00089   MachineFrameInfo *MFI = MF.getFrameInfo();
00090   const SparcInstrInfo &TII =
00091       *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
00092   MachineBasicBlock::iterator MBBI = MBB.begin();
00093   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
00094 
00095   // Get the number of bytes to allocate from the FrameInfo
00096   int NumBytes = (int) MFI->getStackSize();
00097 
00098   unsigned SAVEri = SP::SAVEri;
00099   unsigned SAVErr = SP::SAVErr;
00100   if (FuncInfo->isLeafProc()) {
00101     if (NumBytes == 0)
00102       return;
00103     SAVEri = SP::ADDri;
00104     SAVErr = SP::ADDrr;
00105   }
00106   NumBytes =
00107       -MF.getTarget().getSubtarget<SparcSubtarget>().getAdjustedFrameSize(
00108           NumBytes);
00109   emitSPAdjustment(MF, MBB, MBBI, NumBytes, SAVErr, SAVEri);
00110 
00111   MachineModuleInfo &MMI = MF.getMMI();
00112   const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
00113   unsigned regFP = MRI->getDwarfRegNum(SP::I6, true);
00114 
00115   // Emit ".cfi_def_cfa_register 30".
00116   unsigned CFIIndex =
00117       MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP));
00118   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
00119       .addCFIIndex(CFIIndex);
00120 
00121   // Emit ".cfi_window_save".
00122   CFIIndex = MMI.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
00123   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
00124       .addCFIIndex(CFIIndex);
00125 
00126   unsigned regInRA = MRI->getDwarfRegNum(SP::I7, true);
00127   unsigned regOutRA = MRI->getDwarfRegNum(SP::O7, true);
00128   // Emit ".cfi_register 15, 31".
00129   CFIIndex = MMI.addFrameInst(
00130       MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA));
00131   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
00132       .addCFIIndex(CFIIndex);
00133 }
00134 
00135 void SparcFrameLowering::
00136 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00137                               MachineBasicBlock::iterator I) const {
00138   if (!hasReservedCallFrame(MF)) {
00139     MachineInstr &MI = *I;
00140     int Size = MI.getOperand(0).getImm();
00141     if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
00142       Size = -Size;
00143 
00144     if (Size)
00145       emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri);
00146   }
00147   MBB.erase(I);
00148 }
00149 
00150 
00151 void SparcFrameLowering::emitEpilogue(MachineFunction &MF,
00152                                   MachineBasicBlock &MBB) const {
00153   SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>();
00154   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
00155   const SparcInstrInfo &TII =
00156       *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
00157   DebugLoc dl = MBBI->getDebugLoc();
00158   assert(MBBI->getOpcode() == SP::RETL &&
00159          "Can only put epilog before 'retl' instruction!");
00160   if (!FuncInfo->isLeafProc()) {
00161     BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0)
00162       .addReg(SP::G0);
00163     return;
00164   }
00165   MachineFrameInfo *MFI = MF.getFrameInfo();
00166 
00167   int NumBytes = (int) MFI->getStackSize();
00168   if (NumBytes == 0)
00169     return;
00170 
00171   NumBytes = MF.getTarget().getSubtarget<SparcSubtarget>().getAdjustedFrameSize(
00172       NumBytes);
00173   emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri);
00174 }
00175 
00176 bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
00177   // Reserve call frame if there are no variable sized objects on the stack.
00178   return !MF.getFrameInfo()->hasVarSizedObjects();
00179 }
00180 
00181 // hasFP - Return true if the specified function should have a dedicated frame
00182 // pointer register.  This is true if the function has variable sized allocas or
00183 // if frame pointer elimination is disabled.
00184 bool SparcFrameLowering::hasFP(const MachineFunction &MF) const {
00185   const MachineFrameInfo *MFI = MF.getFrameInfo();
00186   return MF.getTarget().Options.DisableFramePointerElim(MF) ||
00187     MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken();
00188 }
00189 
00190 
00191 static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI)
00192 {
00193 
00194   for (unsigned reg = SP::I0; reg <= SP::I7; ++reg)
00195     if (MRI->isPhysRegUsed(reg))
00196       return false;
00197 
00198   for (unsigned reg = SP::L0; reg <= SP::L7; ++reg)
00199     if (MRI->isPhysRegUsed(reg))
00200       return false;
00201 
00202   return true;
00203 }
00204 
00205 bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const
00206 {
00207 
00208   MachineRegisterInfo &MRI = MF.getRegInfo();
00209   MachineFrameInfo    *MFI = MF.getFrameInfo();
00210 
00211   return !(MFI->hasCalls()              // has calls
00212            || MRI.isPhysRegUsed(SP::L0) // Too many registers needed
00213            || MRI.isPhysRegUsed(SP::O6) // %SP is used
00214            || hasFP(MF));               // need %FP
00215 }
00216 
00217 void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const {
00218 
00219   MachineRegisterInfo &MRI = MF.getRegInfo();
00220 
00221   // Remap %i[0-7] to %o[0-7].
00222   for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
00223     if (!MRI.isPhysRegUsed(reg))
00224       continue;
00225     unsigned mapped_reg = (reg - SP::I0 + SP::O0);
00226     assert(!MRI.isPhysRegUsed(mapped_reg));
00227 
00228     // Replace I register with O register.
00229     MRI.replaceRegWith(reg, mapped_reg);
00230 
00231     // Mark the reg unused.
00232     MRI.setPhysRegUnused(reg);
00233   }
00234 
00235   // Rewrite MBB's Live-ins.
00236   for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
00237        MBB != E; ++MBB) {
00238     for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
00239       if (!MBB->isLiveIn(reg))
00240         continue;
00241       MBB->removeLiveIn(reg);
00242       MBB->addLiveIn(reg - SP::I0 + SP::O0);
00243     }
00244   }
00245 
00246   assert(verifyLeafProcRegUse(&MRI));
00247 #ifdef XDEBUG
00248   MF.verify(0, "After LeafProc Remapping");
00249 #endif
00250 }
00251 
00252 void SparcFrameLowering::processFunctionBeforeCalleeSavedScan
00253                   (MachineFunction &MF, RegScavenger *RS) const {
00254 
00255   if (!DisableLeafProc && isLeafProc(MF)) {
00256     SparcMachineFunctionInfo *MFI = MF.getInfo<SparcMachineFunctionInfo>();
00257     MFI->setLeafProc(true);
00258 
00259     remapRegsForLeafProc(MF);
00260   }
00261 
00262 }