1 //===-- SparcFrameLowering.cpp - Sparc Frame Information ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the Sparc implementation of TargetFrameLowering class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "SparcFrameLowering.h" 15 #include "SparcInstrInfo.h" 16 #include "SparcMachineFunctionInfo.h" 17 #include "SparcSubtarget.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineModuleInfo.h" 22 #include "llvm/CodeGen/MachineRegisterInfo.h" 23 #include "llvm/IR/DataLayout.h" 24 #include "llvm/IR/Function.h" 25 #include "llvm/Support/CommandLine.h" 26 #include "llvm/Target/TargetOptions.h" 27 28 using namespace llvm; 29 30 static cl::opt<bool> 31 DisableLeafProc("disable-sparc-leaf-proc", 32 cl::init(false), 33 cl::desc("Disable Sparc leaf procedure optimization."), 34 cl::Hidden); 35 36 SparcFrameLowering::SparcFrameLowering(const SparcSubtarget &ST) 37 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 38 ST.is64Bit() ? 16 : 8, 0, ST.is64Bit() ? 16 : 8) {} 39 40 void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF, 41 MachineBasicBlock &MBB, 42 MachineBasicBlock::iterator MBBI, 43 int NumBytes, 44 unsigned ADDrr, 45 unsigned ADDri) const { 46 47 DebugLoc dl = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc(); 48 const SparcInstrInfo &TII = 49 *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo()); 50 51 if (NumBytes >= -4096 && NumBytes < 4096) { 52 BuildMI(MBB, MBBI, dl, TII.get(ADDri), SP::O6) 53 .addReg(SP::O6).addImm(NumBytes); 54 return; 55 } 56 57 // Emit this the hard way. This clobbers G1 which we always know is 58 // available here. 59 if (NumBytes >= 0) { 60 // Emit nonnegative numbers with sethi + or. 61 // sethi %hi(NumBytes), %g1 62 // or %g1, %lo(NumBytes), %g1 63 // add %sp, %g1, %sp 64 BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1) 65 .addImm(HI22(NumBytes)); 66 BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1) 67 .addReg(SP::G1).addImm(LO10(NumBytes)); 68 BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6) 69 .addReg(SP::O6).addReg(SP::G1); 70 return ; 71 } 72 73 // Emit negative numbers with sethi + xor. 74 // sethi %hix(NumBytes), %g1 75 // xor %g1, %lox(NumBytes), %g1 76 // add %sp, %g1, %sp 77 BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1) 78 .addImm(HIX22(NumBytes)); 79 BuildMI(MBB, MBBI, dl, TII.get(SP::XORri), SP::G1) 80 .addReg(SP::G1).addImm(LOX10(NumBytes)); 81 BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6) 82 .addReg(SP::O6).addReg(SP::G1); 83 } 84 85 void SparcFrameLowering::emitPrologue(MachineFunction &MF) const { 86 SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 87 88 MachineBasicBlock &MBB = MF.front(); 89 MachineFrameInfo *MFI = MF.getFrameInfo(); 90 const SparcInstrInfo &TII = 91 *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo()); 92 MachineBasicBlock::iterator MBBI = MBB.begin(); 93 DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 94 95 // Get the number of bytes to allocate from the FrameInfo 96 int NumBytes = (int) MFI->getStackSize(); 97 98 unsigned SAVEri = SP::SAVEri; 99 unsigned SAVErr = SP::SAVErr; 100 if (FuncInfo->isLeafProc()) { 101 if (NumBytes == 0) 102 return; 103 SAVEri = SP::ADDri; 104 SAVErr = SP::ADDrr; 105 } 106 NumBytes = -MF.getSubtarget<SparcSubtarget>().getAdjustedFrameSize(NumBytes); 107 emitSPAdjustment(MF, MBB, MBBI, NumBytes, SAVErr, SAVEri); 108 109 MachineModuleInfo &MMI = MF.getMMI(); 110 const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 111 unsigned regFP = MRI->getDwarfRegNum(SP::I6, true); 112 113 // Emit ".cfi_def_cfa_register 30". 114 unsigned CFIIndex = 115 MMI.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP)); 116 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 117 .addCFIIndex(CFIIndex); 118 119 // Emit ".cfi_window_save". 120 CFIIndex = MMI.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); 121 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 122 .addCFIIndex(CFIIndex); 123 124 unsigned regInRA = MRI->getDwarfRegNum(SP::I7, true); 125 unsigned regOutRA = MRI->getDwarfRegNum(SP::O7, true); 126 // Emit ".cfi_register 15, 31". 127 CFIIndex = MMI.addFrameInst( 128 MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA)); 129 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 130 .addCFIIndex(CFIIndex); 131 } 132 133 void SparcFrameLowering:: 134 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 135 MachineBasicBlock::iterator I) const { 136 if (!hasReservedCallFrame(MF)) { 137 MachineInstr &MI = *I; 138 int Size = MI.getOperand(0).getImm(); 139 if (MI.getOpcode() == SP::ADJCALLSTACKDOWN) 140 Size = -Size; 141 142 if (Size) 143 emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri); 144 } 145 MBB.erase(I); 146 } 147 148 149 void SparcFrameLowering::emitEpilogue(MachineFunction &MF, 150 MachineBasicBlock &MBB) const { 151 SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 152 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 153 const SparcInstrInfo &TII = 154 *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo()); 155 DebugLoc dl = MBBI->getDebugLoc(); 156 assert(MBBI->getOpcode() == SP::RETL && 157 "Can only put epilog before 'retl' instruction!"); 158 if (!FuncInfo->isLeafProc()) { 159 BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0) 160 .addReg(SP::G0); 161 return; 162 } 163 MachineFrameInfo *MFI = MF.getFrameInfo(); 164 165 int NumBytes = (int) MFI->getStackSize(); 166 if (NumBytes == 0) 167 return; 168 169 NumBytes = MF.getSubtarget<SparcSubtarget>().getAdjustedFrameSize(NumBytes); 170 emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri); 171 } 172 173 bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 174 // Reserve call frame if there are no variable sized objects on the stack. 175 return !MF.getFrameInfo()->hasVarSizedObjects(); 176 } 177 178 // hasFP - Return true if the specified function should have a dedicated frame 179 // pointer register. This is true if the function has variable sized allocas or 180 // if frame pointer elimination is disabled. 181 bool SparcFrameLowering::hasFP(const MachineFunction &MF) const { 182 const MachineFrameInfo *MFI = MF.getFrameInfo(); 183 return MF.getTarget().Options.DisableFramePointerElim(MF) || 184 MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); 185 } 186 187 188 static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI) 189 { 190 191 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) 192 if (MRI->isPhysRegUsed(reg)) 193 return false; 194 195 for (unsigned reg = SP::L0; reg <= SP::L7; ++reg) 196 if (MRI->isPhysRegUsed(reg)) 197 return false; 198 199 return true; 200 } 201 202 bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const 203 { 204 205 MachineRegisterInfo &MRI = MF.getRegInfo(); 206 MachineFrameInfo *MFI = MF.getFrameInfo(); 207 208 return !(MFI->hasCalls() // has calls 209 || MRI.isPhysRegUsed(SP::L0) // Too many registers needed 210 || MRI.isPhysRegUsed(SP::O6) // %SP is used 211 || hasFP(MF)); // need %FP 212 } 213 214 void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const { 215 216 MachineRegisterInfo &MRI = MF.getRegInfo(); 217 218 // Remap %i[0-7] to %o[0-7]. 219 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) { 220 if (!MRI.isPhysRegUsed(reg)) 221 continue; 222 unsigned mapped_reg = (reg - SP::I0 + SP::O0); 223 assert(!MRI.isPhysRegUsed(mapped_reg)); 224 225 // Replace I register with O register. 226 MRI.replaceRegWith(reg, mapped_reg); 227 228 // Mark the reg unused. 229 MRI.setPhysRegUnused(reg); 230 } 231 232 // Rewrite MBB's Live-ins. 233 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 234 MBB != E; ++MBB) { 235 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) { 236 if (!MBB->isLiveIn(reg)) 237 continue; 238 MBB->removeLiveIn(reg); 239 MBB->addLiveIn(reg - SP::I0 + SP::O0); 240 } 241 } 242 243 assert(verifyLeafProcRegUse(&MRI)); 244 #ifdef XDEBUG 245 MF.verify(0, "After LeafProc Remapping"); 246 #endif 247 } 248 249 void SparcFrameLowering::processFunctionBeforeCalleeSavedScan 250 (MachineFunction &MF, RegScavenger *RS) const { 251 252 if (!DisableLeafProc && isLeafProc(MF)) { 253 SparcMachineFunctionInfo *MFI = MF.getInfo<SparcMachineFunctionInfo>(); 254 MFI->setLeafProc(true); 255 256 remapRegsForLeafProc(MF); 257 } 258 259 } 260