diff options
| author | Shiva Chen <shiva@andestech.com> | 2019-10-15 15:11:35 +0800 |
|---|---|---|
| committer | shiva <shiva0217@gmail.com> | 2019-11-16 12:39:53 +0800 |
| commit | cf6cf0cd147ac2524c3533fd7c7ada7f95f6da60 (patch) | |
| tree | 3d0a037b9119bd6c991651c9ea2265d289935dce /llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | |
| parent | 77cfcd75092b57693d40123a013e59295634a945 (diff) | |
| download | bcm5719-llvm-cf6cf0cd147ac2524c3533fd7c7ada7f95f6da60.tar.gz bcm5719-llvm-cf6cf0cd147ac2524c3533fd7c7ada7f95f6da60.zip | |
[RISCV] Handle variable sized objects with the stack need to be realigned
Differential Revision: https://reviews.llvm.org/D68979
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVFrameLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 4ba4606612b..61516960b39 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -32,6 +32,13 @@ bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { MFI.isFrameAddressTaken(); } +bool RISCVFrameLowering::hasBP(const MachineFunction &MF) const { + const MachineFrameInfo &MFI = MF.getFrameInfo(); + const TargetRegisterInfo *TRI = STI.getRegisterInfo(); + + return MFI.hasVarSizedObjects() && TRI->needsStackRealignment(MF); +} + // Determines the size of the frame and maximum call frame size. void RISCVFrameLowering::determineFrameLayout(MachineFunction &MF) const { MachineFrameInfo &MFI = MF.getFrameInfo(); @@ -108,14 +115,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, const RISCVInstrInfo *TII = STI.getInstrInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); - if (RI->needsStackRealignment(MF) && MFI.hasVarSizedObjects()) { - report_fatal_error( - "RISC-V backend can't currently handle functions that need stack " - "realignment and have variable sized objects"); - } - Register FPReg = getFPReg(STI); Register SPReg = getSPReg(STI); + Register BPReg = RISCVABI::getBPReg(); // Debug location must be unknown since the first debug location is used // to determine the end of the prologue. @@ -229,6 +231,15 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, .addReg(VR) .addImm(ShiftAmount); } + // FP will be used to restore the frame in the epilogue, so we need + // another base register BP to record SP after re-alignment. SP will + // track the current stack after allocating variable sized objects. + if (hasBP(MF)) { + // move BP, SP + BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), BPReg) + .addReg(SPReg) + .addImm(0); + } } } } @@ -308,12 +319,14 @@ int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, Offset += FirstSPAdjustAmount; else Offset += MF.getFrameInfo().getStackSize(); - } else if (RI->needsStackRealignment(MF)) { - assert(!MFI.hasVarSizedObjects() && - "Unexpected combination of stack realignment and varsized objects"); + } else if (RI->needsStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) { // If the stack was realigned, the frame pointer is set in order to allow - // SP to be restored, but we still access stack objects using SP. - FrameReg = RISCV::X2; + // SP to be restored, so we need another base register to record the stack + // after realignment. + if (hasBP(MF)) + FrameReg = RISCVABI::getBPReg(); + else + FrameReg = RISCV::X2; Offset += MF.getFrameInfo().getStackSize(); } else { FrameReg = RI->getFrameRegister(MF); @@ -335,6 +348,9 @@ void RISCVFrameLowering::determineCalleeSaves(MachineFunction &MF, SavedRegs.set(RISCV::X1); SavedRegs.set(RISCV::X8); } + // Mark BP as used if function has dedicated base pointer. + if (hasBP(MF)) + SavedRegs.set(RISCVABI::getBPReg()); // If interrupt is enabled and there are calls in the handler, // unconditionally save all Caller-saved registers and |

