static cl::opt<bool>
DisableLeafProc("disable-sparc-leaf-proc",
- cl::init(true),
+ cl::init(false),
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();
// Get the number of bytes to allocate from the FrameInfo
int NumBytes = (int) MFI->getStackSize();
- if (SubTarget.is64Bit()) {
- // All 64-bit stack frames must be 16-byte aligned, and must reserve space
- // for spilling the 16 window registers at %sp+BIAS..%sp+BIAS+128.
- NumBytes += 128;
- // Frames with calls must also reserve space for 6 outgoing arguments
- // whether they are used or not. LowerCall_64 takes care of that.
- assert(NumBytes % 16 == 0 && "Stack size not 16-byte aligned");
- } else {
- // Emit the correct save instruction based on the number of bytes in
- // the frame. Minimum stack frame size according to V8 ABI is:
- // 16 words for register window spill
- // 1 word for address of returned aggregate-value
- // + 6 words for passing parameters on the stack
- // ----------
- // 23 words * 4 bytes per word = 92 bytes
- NumBytes += 92;
-
- // Round up to next doubleword boundary -- a double-word boundary
- // is required by the ABI.
- NumBytes = RoundUpToAlignment(NumBytes, 8);
+ unsigned SAVEri = SP::SAVEri;
+ unsigned SAVErr = SP::SAVErr;
+ if (FuncInfo->isLeafProc()) {
+ if (NumBytes == 0)
+ return;
+ SAVEri = SP::ADDri;
+ SAVErr = SP::ADDrr;
}
- NumBytes = -NumBytes;
+ NumBytes = - SubTarget.getAdjustedFrameSize(NumBytes);
if (NumBytes >= -4096) {
- BuildMI(MBB, MBBI, dl, TII.get(SP::SAVEri), SP::O6)
+ BuildMI(MBB, MBBI, dl, TII.get(SAVEri), SP::O6)
.addReg(SP::O6).addImm(NumBytes);
} else {
// Emit this the hard way. This clobbers G1 which we always know is
// Emit G1 = G1 + I6
BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1)
.addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1));
- BuildMI(MBB, MBBI, dl, TII.get(SP::SAVErr), SP::O6)
+ BuildMI(MBB, MBBI, dl, TII.get(SAVErr), SP::O6)
.addReg(SP::O6).addReg(SP::G1);
}
}
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());
DebugLoc dl = MBBI->getDebugLoc();
assert(MBBI->getOpcode() == SP::RETL &&
"Can only put epilog before 'retl' instruction!");
- BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0)
- .addReg(SP::G0);
+ if (!FuncInfo->isLeafProc()) {
+ BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0)
+ .addReg(SP::G0);
+ return;
+ }
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+
+ int NumBytes = (int) MFI->getStackSize();
+ if (NumBytes == 0)
+ return;
+
+ NumBytes = SubTarget.getAdjustedFrameSize(NumBytes);
+
+ if (NumBytes < 4096) {
+ BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), SP::O6)
+ .addReg(SP::O6).addImm(NumBytes);
+ } else {
+ // Emit this the hard way. This clobbers G1 which we always know is
+ // available here.
+ unsigned OffHi = (unsigned)NumBytes >> 10U;
+ BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi);
+ // Emit G1 = G1 + I6
+ BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1)
+ .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1));
+ BuildMI(MBB, MBBI, dl, TII.get(SP::ADDrr), SP::O6)
+ .addReg(SP::O6).addReg(SP::G1);
+ }
}
bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
- //Reserve call frame if there are no variable sized objects on the stack
+ // Reserve call frame if there are no variable sized objects on the stack.
return !MF.getFrameInfo()->hasVarSizedObjects();
}
}
-static bool verifyLeafProcRegUse(MachineRegisterInfo *MRI)
+static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI)
{
for (unsigned reg = SP::I0; reg <= SP::I7; ++reg)
MachineRegisterInfo &MRI = MF.getRegInfo();
- //remap %i[0-7] to %o[0-7]
+ // 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
+ // Replace I register with O register.
MRI.replaceRegWith(reg, mapped_reg);
- //mark the reg unused.
+ // Mark the reg unused.
MRI.setPhysRegUnused(reg);
}