Skip to content

[LoongArch] Revert sp adjustment in prologue #88110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 18 additions & 39 deletions llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,22 +206,19 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF,
if (StackSize == 0 && !MFI.adjustsStack())
return;

uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF, true);
uint64_t SecondSPAdjustAmount = RealStackSize - FirstSPAdjustAmount;
uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
// Split the SP adjustment to reduce the offsets of callee saved spill.
if (FirstSPAdjustAmount)
StackSize = FirstSPAdjustAmount;

// Adjust stack.
adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup);
if (FirstSPAdjustAmount != 2048 || SecondSPAdjustAmount == 0) {
// Emit ".cfi_def_cfa_offset StackSize".
unsigned CFIIndex =
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex)
.setMIFlag(MachineInstr::FrameSetup);
}
// Emit ".cfi_def_cfa_offset StackSize".
unsigned CFIIndex =
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex)
.setMIFlag(MachineInstr::FrameSetup);

const auto &CSI = MFI.getCalleeSavedInfo();

Expand Down Expand Up @@ -258,25 +255,14 @@ void LoongArchFrameLowering::emitPrologue(MachineFunction &MF,
}

// Emit the second SP adjustment after saving callee saved registers.
if (FirstSPAdjustAmount && SecondSPAdjustAmount) {
if (hasFP(MF)) {
assert(SecondSPAdjustAmount > 0 &&
"SecondSPAdjustAmount should be greater than zero");
adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount,
MachineInstr::FrameSetup);
} else {
// FIXME: RegScavenger will place the spill instruction before the
// prologue if a VReg is created in the prologue. This will pollute the
// caller's stack data. Therefore, until there is better way, we just use
// the `addi.w/d` instruction for stack adjustment to ensure that VReg
// will not be created.
for (int Val = SecondSPAdjustAmount; Val > 0; Val -= 2048)
BuildMI(MBB, MBBI, DL,
TII->get(IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W), SPReg)
.addReg(SPReg)
.addImm(Val < 2048 ? -Val : -2048)
.setMIFlag(MachineInstr::FrameSetup);
if (FirstSPAdjustAmount) {
uint64_t SecondSPAdjustAmount = RealStackSize - FirstSPAdjustAmount;
assert(SecondSPAdjustAmount > 0 &&
"SecondSPAdjustAmount should be greater than zero");
adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount,
MachineInstr::FrameSetup);

if (!hasFP(MF)) {
// If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0",
// don't emit an sp-based .cfi_def_cfa_offset
// Emit ".cfi_def_cfa_offset RealStackSize"
Expand Down Expand Up @@ -369,27 +355,20 @@ void LoongArchFrameLowering::emitEpilogue(MachineFunction &MF,
// st.d $ra, $sp, 2024
// st.d $fp, $sp, 2016
// addi.d $sp, $sp, -16
uint64_t
LoongArchFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF,
bool IsPrologue) const {
uint64_t LoongArchFrameLowering::getFirstSPAdjustAmount(
const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();

// Return the FirstSPAdjustAmount if the StackSize can not fit in a signed
// 12-bit and there exists a callee-saved register needing to be pushed.
if (!isInt<12>(MFI.getStackSize())) {
if (!isInt<12>(MFI.getStackSize()) && (CSI.size() > 0)) {
// FirstSPAdjustAmount is chosen as (2048 - StackAlign) because 2048 will
// cause sp = sp + 2048 in the epilogue to be split into multiple
// instructions. Offsets smaller than 2048 can fit in a single load/store
// instruction, and we have to stick with the stack alignment.
// So (2048 - StackAlign) will satisfy the stack alignment.
//
// FIXME: This place may seem odd. When using multiple ADDI instructions to
// adjust the stack in Prologue, and there are no callee-saved registers, we
// can take advantage of the logic of split sp ajustment to reduce code
// changes.
return CSI.size() > 0 ? 2048 - getStackAlign().value()
: (IsPrologue ? 2048 : 0);
return 2048 - getStackAlign().value();
}
return 0;
}
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ class LoongArchFrameLowering : public TargetFrameLowering {
bool hasFP(const MachineFunction &MF) const override;
bool hasBP(const MachineFunction &MF) const;

uint64_t getFirstSPAdjustAmount(const MachineFunction &MF,
bool IsPrologue = false) const;
uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const;

bool enableShrinkWrapping(const MachineFunction &MF) const override;

Expand Down
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/LoongArch/emergency-spill-slot.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
define void @func() {
; CHECK-LABEL: func:
; CHECK: # %bb.0:
; CHECK-NEXT: addi.d $sp, $sp, -2048
; CHECK-NEXT: addi.d $sp, $sp, -2048
; CHECK-NEXT: addi.d $sp, $sp, -16
; CHECK-NEXT: lu12i.w $a0, 1
; CHECK-NEXT: ori $a0, $a0, 16
; CHECK-NEXT: sub.d $sp, $sp, $a0
; CHECK-NEXT: .cfi_def_cfa_offset 4112
; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(var)
; CHECK-NEXT: ld.d $a1, $a0, %got_pc_lo12(var)
Expand Down