Skip to content

Commit 74f7387

Browse files
lenaryIcohedron
authored andcommitted
[RISCV] Allow spilling to unused Zcmp Stack (llvm#125959)
This is a tiny change that can save up to 16 bytes of stack allocation, which is more beneficial on RV32 than RV64. cm.push allocates multiples of 16 bytes, but only uses a subset of those bytes for pushing callee-saved registers. Up to 12 (rv32) or 8 (rv64) bytes are left unused, depending on how many registers are pushed. Before this change, we told LLVM that the entire allocation was used, by creating a fixed stack object which covered the whole allocation. This change instead gives an accurate extent to the fixed stack object, to only cover the registers that have been pushed. This allows the PrologEpilogInserter to use any unused bytes for spills. Potentially this saves an extra move of the stack pointer after the push, because the push can allocate up to 48 more bytes than it needs for registers. We cannot do the same change for save/restore, because the restore routines restore in batches of `stackalign/(xlen/8)` registers, and we don't want to clobber the saved values of registers that we didn't tell the compiler we were saving/restoring - for instance `__riscv_restore_0` is used by the compiler when it only wants to save `ra`, but will end up restoring `ra` and `s0`.
1 parent 8fe03b0 commit 74f7387

File tree

6 files changed

+662
-669
lines changed

6 files changed

+662
-669
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -1847,11 +1847,16 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots(
18471847
MFI.setStackID(FrameIdx, TargetStackID::ScalableVector);
18481848
}
18491849

1850-
// Allocate a fixed object that covers the full push or libcall size.
18511850
if (RVFI->isPushable(MF)) {
1852-
if (int64_t PushSize = RVFI->getRVPushStackSize())
1853-
MFI.CreateFixedSpillStackObject(PushSize, -PushSize);
1851+
// Allocate a fixed object that covers all the registers that are pushed.
1852+
if (unsigned PushedRegs = RVFI->getRVPushRegs()) {
1853+
int64_t PushedRegsBytes =
1854+
static_cast<int64_t>(PushedRegs) * (STI.getXLen() / 8);
1855+
MFI.CreateFixedSpillStackObject(PushedRegsBytes, -PushedRegsBytes);
1856+
}
18541857
} else if (int LibCallRegs = getLibCallID(MF, CSI) + 1) {
1858+
// Allocate a fixed object that covers all of the stack allocated by the
1859+
// libcall.
18551860
int64_t LibCallFrameSize =
18561861
alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
18571862
MFI.CreateFixedSpillStackObject(LibCallFrameSize, -LibCallFrameSize);

0 commit comments

Comments
 (0)