[llvm] [RISCV] Implement foward inserting save/restore FRM instructions. (PR #77744)
Yeting Kuo via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 17 23:17:33 PST 2024
================
@@ -55,6 +61,107 @@ char RISCVInsertReadWriteCSR::ID = 0;
INITIALIZE_PASS(RISCVInsertReadWriteCSR, DEBUG_TYPE,
RISCV_INSERT_READ_WRITE_CSR_NAME, false, false)
+// TODO: Use more accurate rounding mode at the start of MBB.
+bool RISCVInsertReadWriteCSR::emitWriteRoundingModeOpt(MachineBasicBlock &MBB) {
+ bool Changed = false;
+ MachineInstr *LastFRMChanger = nullptr;
+ std::optional<unsigned> CurrentRM = RISCVFPRndMode::DYN;
+ std::optional<Register> SavedFRM;
+
+ for (MachineInstr &MI : MBB) {
+ if (MI.getOpcode() == RISCV::SwapFRMImm ||
+ MI.getOpcode() == RISCV::WriteFRMImm) {
+ CurrentRM = MI.getOperand(0).getImm();
+ SavedFRM = std::nullopt;
+ continue;
+ }
+
+ if (MI.getOpcode() == RISCV::WriteFRM) {
+ CurrentRM = RISCVFPRndMode::DYN;
+ SavedFRM = std::nullopt;
+ continue;
+ }
+
+ if (MI.isCall() || MI.isInlineAsm() || MI.readsRegister(RISCV::FRM)) {
+ // Restore FRM before unknown operations.
+ if (SavedFRM.has_value())
+ BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::WriteFRM))
+ .addReg(*SavedFRM);
+ CurrentRM = RISCVFPRndMode::DYN;
+ SavedFRM = std::nullopt;
+ continue;
+ }
+
+ assert(!MI.modifiesRegister(RISCV::FRM) &&
+ "Expected that MI could not modify FRM.");
+
+ auto getInstructionRM = [](MachineInstr &MI) -> std::optional<unsigned> {
+ int FRMIdx = RISCVII::getFRMOpNum(MI.getDesc());
+ if (FRMIdx >= 0)
+ return MI.getOperand(FRMIdx).getImm();
+
+ if (!MI.hasRegisterImplicitUseOperand(RISCV::FRM))
+ return std::nullopt;
+
+ return RISCVFPRndMode::DYN;
+ };
+
+ std::optional<unsigned> InstrRM = getInstructionRM(MI);
+
+ // Skip if MI does not need FRM.
+ if (!InstrRM.has_value())
+ continue;
+
+ if (InstrRM != RISCVFPRndMode::DYN)
+ LastFRMChanger = &MI;
+
+ if (!MI.readsRegister(RISCV::FRM))
+ MI.addOperand(MachineOperand::CreateReg(RISCV::FRM, /*IsDef*/ false,
+ /*IsImp*/ true));
+
+ // Skip if MI uses same rounding mode as FRM.
+ if (InstrRM == CurrentRM)
+ continue;
+
+ if (InstrRM == RISCVFPRndMode::DYN) {
+ if (!SavedFRM.has_value())
+ continue;
+ // SavedFRM not having a value means current FRM has correct rounding
+ // mode.
+ BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(RISCV::WriteFRM))
+ .addReg(*SavedFRM);
----------------
yetingk wrote:
I moved the set of changed before adding implicit use of frm.
https://github.com/llvm/llvm-project/pull/77744
More information about the llvm-commits
mailing list