================ @@ -27,6 +27,102 @@ using namespace llvm; +static unsigned getCaleeSavedRVVNumRegs(const Register &BaseReg) { + return RISCV::VRRegClass.contains(BaseReg) ? 1 + : RISCV::VRM2RegClass.contains(BaseReg) ? 2 + : RISCV::VRM4RegClass.contains(BaseReg) ? 4 + : 8; +} + +static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, + const Register &Reg) { + MCRegister BaseReg = TRI.getSubReg(Reg, RISCV::sub_vrm1_0); + // If it's not a grouped vector register, it doesn't have subregister, so + // the base register is just itself. + if (BaseReg == RISCV::NoRegister) + BaseReg = Reg; + return BaseReg; +} + +namespace { + +struct CFIRestoreRegisterEmitter { + CFIRestoreRegisterEmitter(MachineFunction &, const RISCVSubtarget &) {}; + + void emit(MachineFunction &MF, 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); + } +}; + +class CFIStoreRegisterEmitter { + MachineFrameInfo &MFI; + +public: + CFIStoreRegisterEmitter(MachineFunction &MF, const RISCVSubtarget &) + : MFI{MF.getFrameInfo()} {}; + + void emit(MachineFunction &MF, 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 CFIRestoreRVVRegisterEmitter { + const llvm::RISCVRegisterInfo *TRI; + +public: + CFIRestoreRVVRegisterEmitter(MachineFunction &, const RISCVSubtarget &STI) + : TRI{STI.getRegisterInfo()} {}; + + void emit(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator MBBI, const RISCVRegisterInfo &RI, + const RISCVInstrInfo &TII, const DebugLoc &DL, + const CalleeSavedInfo &CS) const { + MCRegister BaseReg = getRVVBaseRegister(*TRI, CS.getReg()); + unsigned NumRegs = getCaleeSavedRVVNumRegs(CS.getReg()); + for (unsigned i = 0; i < NumRegs; ++i) { + unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore( + nullptr, RI.getDwarfRegNum(BaseReg + i, true))); + BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlag(MachineInstr::FrameDestroy); + } + } +}; + +} // namespace + +template <typename Emitter> +void RISCVFrameLowering::emitCFIForCSI( + MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, + const SmallVector<CalleeSavedInfo, 8> &CSI) const { + MachineFunction *MF = MBB.getParent(); + const RISCVRegisterInfo *RI = STI.getRegisterInfo(); + const RISCVInstrInfo *TII = STI.getInstrInfo(); + DebugLoc DL = MBB.findDebugLoc(MBBI); + + Emitter E{*MF, STI}; + for (const auto &CS : CSI) + E.emit(*MF, MBB, MBBI, *RI, *TII, DL, CS); ---------------- lenary wrote:
I don't quite know why `*MF` needs to be passed into both the constructor and into `emit`? Would it not be simpler to just pass it into the constructor and cache the reference? https://github.com/llvm/llvm-project/pull/114227 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits