diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index e0abc2d812ccf..74762470b5786 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -27,6 +27,64 @@ using namespace llvm; +namespace { + +class CFISaveRegisterEmitter { + MachineFunction &MF; + MachineFrameInfo &MFI; + +public: + CFISaveRegisterEmitter(MachineFunction &MF) + : MF{MF}, MFI{MF.getFrameInfo()} {}; + + void emit(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + const RISCVRegisterInfo &RI, const RISCVInstrInfo &TII, + const DebugLoc &DL, const CalleeSavedInfo &CS) const { + int FrameIdx = CS.getFrameIdx(); + int64_t Offset = MFI.getObjectOffset(FrameIdx); + Register Reg = CS.getReg(); + unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( + nullptr, RI.getDwarfRegNum(Reg, true), Offset)); + BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); + } +}; + +class CFIRestoreRegisterEmitter { + MachineFunction &MF; + +public: + CFIRestoreRegisterEmitter(MachineFunction &MF) : MF{MF} {}; + + void emit(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + const RISCVRegisterInfo &RI, const RISCVInstrInfo &TII, + const DebugLoc &DL, const CalleeSavedInfo &CS) const { + Register Reg = CS.getReg(); + unsigned CFIIndex = MF.addFrameInst( + MCCFIInstruction::createRestore(nullptr, RI.getDwarfRegNum(Reg, true))); + BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameDestroy); + } +}; + +} // namespace + +template +void RISCVFrameLowering::emitCFIForCSI( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + const SmallVector &CSI) const { + MachineFunction *MF = MBB.getParent(); + const RISCVRegisterInfo *RI = STI.getRegisterInfo(); + const RISCVInstrInfo *TII = STI.getInstrInfo(); + DebugLoc DL = MBB.findDebugLoc(MBBI); + + Emitter E{*MF}; + for (const auto &CS : CSI) + E.emit(MBB, MBBI, *RI, *TII, DL, CS); +} + static Align getABIStackAlignment(RISCVABI::ABI ABI) { if (ABI == RISCVABI::ABI_ILP32E) return Align(4); @@ -418,18 +476,18 @@ getPushOrLibCallsSavedInfo(const MachineFunction &MF, const std::vector &CSI) { auto *RVFI = MF.getInfo(); - SmallVector PushPopOrLibCallsCSI; + SmallVector PushOrLibCallsCSI; if (!RVFI->useSaveRestoreLibCalls(MF) && !RVFI->isPushable(MF)) - return PushPopOrLibCallsCSI; + return PushOrLibCallsCSI; - for (auto &CS : CSI) { + for (const auto &CS : CSI) { const auto *FII = llvm::find_if( FixedCSRFIMap, [&](auto P) { return P.first == CS.getReg(); }); if (FII != std::end(FixedCSRFIMap)) - PushPopOrLibCallsCSI.push_back(CS); + PushOrLibCallsCSI.push_back(CS); } - return PushPopOrLibCallsCSI; + return PushOrLibCallsCSI; } void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF, @@ -610,16 +668,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, .addCFIIndex(CFIIndex) .setMIFlag(MachineInstr::FrameSetup); - for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, CSI)) { - int FrameIdx = Entry.getFrameIdx(); - int64_t Offset = MFI.getObjectOffset(FrameIdx); - Register Reg = Entry.getReg(); - unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, RI->getDwarfRegNum(Reg, true), Offset)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlag(MachineInstr::FrameSetup); - } + emitCFIForCSI(MBB, MBBI, + getPushOrLibCallsSavedInfo(MF, CSI)); } // FIXME (note copied from Lanai): This appears to be overallocating. Needs @@ -651,7 +701,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // stack space. Align the stack size down to a multiple of 16. This is // needed for RVE. // FIXME: Can we increase the stack size to a multiple of 16 instead? - uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48); + uint64_t Spimm = + std::min(alignDown(StackSize, 16), static_cast(48)); FirstFrameSetup->getOperand(1).setImm(Spimm); StackSize -= Spimm; @@ -661,16 +712,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, .addCFIIndex(CFIIndex) .setMIFlag(MachineInstr::FrameSetup); - for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, CSI)) { - int FrameIdx = Entry.getFrameIdx(); - int64_t Offset = MFI.getObjectOffset(FrameIdx); - Register Reg = Entry.getReg(); - unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, RI->getDwarfRegNum(Reg, true), Offset)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlag(MachineInstr::FrameSetup); - } + emitCFIForCSI(MBB, MBBI, + getPushOrLibCallsSavedInfo(MF, CSI)); } if (StackSize != 0) { @@ -697,20 +740,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF, // Iterate over list of callee-saved registers and emit .cfi_offset // directives. - for (const auto &Entry : getUnmanagedCSI(MF, CSI)) { - int FrameIdx = Entry.getFrameIdx(); - if (FrameIdx >= 0 && - MFI.getStackID(FrameIdx) == TargetStackID::ScalableVector) - continue; - - int64_t Offset = MFI.getObjectOffset(FrameIdx); - Register Reg = Entry.getReg(); - unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, RI->getDwarfRegNum(Reg, true), Offset)); - BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlag(MachineInstr::FrameSetup); - } + emitCFIForCSI(MBB, MBBI, getUnmanagedCSI(MF, CSI)); // Generate new FP. if (hasFP(MF)) { @@ -960,14 +990,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, } // Recover callee-saved registers. - for (const auto &Entry : getUnmanagedCSI(MF, 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) - .setMIFlag(MachineInstr::FrameDestroy); - } + emitCFIForCSI(MBB, MBBI, getUnmanagedCSI(MF, CSI)); bool ApplyPop = RVFI->isPushable(MF) && MBBI != MBB.end() && MBBI->getOpcode() == RISCV::CM_POP; @@ -976,7 +999,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, // space. Align the stack size down to a multiple of 16. This is needed for // RVE. // FIXME: Can we increase the stack size to a multiple of 16 instead? - uint64_t Spimm = std::min(alignDown(StackSize, 16), (uint64_t)48); + uint64_t Spimm = + std::min(alignDown(StackSize, 16), static_cast(48)); MBBI->getOperand(1).setImm(Spimm); StackSize -= Spimm; @@ -988,14 +1012,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, if (NextI == MBB.end() || NextI->getOpcode() != RISCV::PseudoRET) { ++MBBI; - for (const auto &Entry : getPushOrLibCallsSavedInfo(MF, 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) - .setMIFlag(MachineInstr::FrameDestroy); - } + emitCFIForCSI( + MBB, MBBI, getPushOrLibCallsSavedInfo(MF, CSI)); // Update CFA offset. After CM_POP SP should be equal to CFA, so CFA // offset should be a zero. @@ -1695,7 +1713,7 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters( return true; } -static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) { +static unsigned getCalleeSavedRVVNumRegs(const Register &BaseReg) { return RISCV::VRRegClass.contains(BaseReg) ? 1 : RISCV::VRM2RegClass.contains(BaseReg) ? 2 : RISCV::VRM4RegClass.contains(BaseReg) ? 4 @@ -1737,16 +1755,14 @@ void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI( for (auto &CS : RVVCSI) { // Insert the spill to the stack frame. int FI = CS.getFrameIdx(); - if (FI >= 0 && MFI.getStackID(FI) == TargetStackID::ScalableVector) { - MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg()); - unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg()); - for (unsigned i = 0; i < NumRegs; ++i) { - unsigned CFIIndex = MF->addFrameInst(createDefCFAOffset( - TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset(FI) / 8 + i)); - BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlag(MachineInstr::FrameSetup); - } + MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg()); + unsigned NumRegs = getCalleeSavedRVVNumRegs(CS.getReg()); + for (unsigned i = 0; i < NumRegs; ++i) { + unsigned CFIIndex = MF->addFrameInst(createDefCFAOffset( + TRI, BaseReg + i, -FixedSize, MFI.getObjectOffset(FI) / 8 + i)); + BuildMI(MBB, MI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameSetup); } } } @@ -1763,7 +1779,7 @@ void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI( const auto &RVVCSI = getRVVCalleeSavedInfo(*MF, MFI.getCalleeSavedInfo()); for (auto &CS : RVVCSI) { MCRegister BaseReg = getRVVBaseRegister(TRI, CS.getReg()); - unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg()); + unsigned NumRegs = getCalleeSavedRVVNumRegs(CS.getReg()); for (unsigned i = 0; i < NumRegs; ++i) { unsigned CFIIndex = MF->addFrameInst(MCCFIInstruction::createRestore( nullptr, RI->getDwarfRegNum(BaseReg + i, true))); diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h index 04dac7d70ce96..c106b7b675465 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h @@ -93,6 +93,9 @@ class RISCVFrameLowering : public TargetFrameLowering { bool HasFP) const; void emitCalleeSavedRVVEpilogCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const; + template + void emitCFIForCSI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + const SmallVector &CSI) const; void deallocateStack(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, uint64_t &StackSize, int64_t CFAOffset) const;