diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/Target/RISCV/RISCVFrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 132 |
1 files changed, 64 insertions, 68 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 6b6f62e18ce96..c60fc3fc6b42b 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -18,6 +18,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/MC/MCDwarf.h" using namespace llvm; @@ -31,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(); @@ -99,22 +107,15 @@ static Register getSPReg(const RISCVSubtarget &STI) { return RISCV::X2; } void RISCVFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { - assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); - MachineFrameInfo &MFI = MF.getFrameInfo(); auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); const RISCVRegisterInfo *RI = STI.getRegisterInfo(); 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. @@ -131,6 +132,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, if (StackSize == 0 && !MFI.adjustsStack()) return; + // If the stack pointer has been marked as reserved, then produce an error if + // the frame requires stack allocation + if (STI.isRegisterReservedByUser(SPReg)) + MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{ + MF.getFunction(), "Stack pointer required, but has been reserved."}); + uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); // Split the SP adjustment to reduce the offsets of callee saved spill. if (FirstSPAdjustAmount) @@ -167,6 +174,10 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // Generate new FP. if (hasFP(MF)) { + if (STI.isRegisterReservedByUser(FPReg)) + MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{ + MF.getFunction(), "Frame pointer required, but has been reserved."}); + adjustReg(MBB, MBBI, DL, FPReg, SPReg, StackSize - RVFI->getVarArgsSaveSize(), MachineInstr::FrameSetup); @@ -184,11 +195,16 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, "SecondSPAdjustAmount should be greater than zero"); adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount, MachineInstr::FrameSetup); - // Emit ".cfi_def_cfa_offset StackSize" - unsigned CFIIndex = MF.addFrameInst( - MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize())); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); + + // 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 + if (!hasFP(MF)) { + // Emit ".cfi_def_cfa_offset StackSize" + unsigned CFIIndex = MF.addFrameInst( + MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize())); + BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex); + } } if (hasFP(MF)) { @@ -213,21 +229,43 @@ 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); + } } } } void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { - MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); const RISCVRegisterInfo *RI = STI.getRegisterInfo(); MachineFrameInfo &MFI = MF.getFrameInfo(); auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>(); - DebugLoc DL = MBBI->getDebugLoc(); - const RISCVInstrInfo *TII = STI.getInstrInfo(); Register FPReg = getFPReg(STI); Register SPReg = getSPReg(STI); + // Get the insert location for the epilogue. If there were no terminators in + // the block, get the last instruction. + MachineBasicBlock::iterator MBBI = MBB.end(); + DebugLoc DL; + if (!MBB.empty()) { + MBBI = MBB.getFirstTerminator(); + if (MBBI == MBB.end()) + MBBI = MBB.getLastNonDebugInstr(); + DL = MBBI->getDebugLoc(); + + // If this is not a terminator, the actual insert location should be after the + // last instruction. + if (!MBBI->isTerminator()) + MBBI = std::next(MBBI); + } + // Skip to before the restores of callee-saved registers // FIXME: assumes exactly one instruction is used to restore each // callee-saved register. @@ -253,46 +291,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount, MachineInstr::FrameDestroy); - - // Emit ".cfi_def_cfa_offset FirstSPAdjustAmount" - unsigned CFIIndex = - MF.addFrameInst( - MCCFIInstruction::createDefCfaOffset(nullptr, - -FirstSPAdjustAmount)); - BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); - } - - if (hasFP(MF)) { - // To find the instruction restoring FP from stack. - for (auto &I = LastFrameDestroy; I != MBBI; ++I) { - if (I->mayLoad() && I->getOperand(0).isReg()) { - Register DestReg = I->getOperand(0).getReg(); - if (DestReg == FPReg) { - // If there is frame pointer, after restoring $fp registers, we - // need adjust CFA to ($sp - FPOffset). - // Emit ".cfi_def_cfa $sp, -FPOffset" - unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa( - nullptr, RI->getDwarfRegNum(SPReg, true), -FPOffset)); - BuildMI(MBB, std::next(I), DL, - TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); - break; - } - } - } - } - - // Add CFI directives for callee-saved registers. - const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); - // Iterate over list of callee-saved registers and emit .cfi_restore - // directives. - for (const auto &Entry : CSI) { - Register Reg = Entry.getReg(); - unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore( - nullptr, RI->getDwarfRegNum(Reg, true))); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); } if (FirstSPAdjustAmount) @@ -300,13 +298,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, // Deallocate stack adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); - - // After restoring $sp, we need to adjust CFA to $(sp + 0) - // Emit ".cfi_def_cfa_offset 0" - unsigned CFIIndex = - MF.addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, 0)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex); } int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, @@ -340,12 +331,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); @@ -367,6 +360,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 |