Thank Juzhe for review. Sure, let me hold the v3 for kito's comments. Pan From: juzhe.zhong@rivai.ai Sent: Wednesday, July 12, 2023 2:11 PM To: Li, Pan2 ; gcc-patches Cc: Robin Dapp ; jeffreyalaw ; Li, Pan2 ; Wang, Yanzhang ; kito.cheng Subject: Re: [PATCH v2] RISC-V: Refactor riscv mode after for VXRM and FRM +regnum_definition_p (rtx_insn *insn, unsigned int regno) I prefer it to be reg_set_p. +insn_asm_p (rtx_insn *insn) asm_insn_p +global_vxrm_state_unknown_p vxrm_unknown_p +global_frm_state_unknown_p (rtx_insn *insn) FRM of CALL function is not "UNKNOWN" unlike VXRM. It just change into another unknown(may be same or different from previous dynamic mode) Dynamic mode. frm_unknown_dynamic_p The reset refactoring looks good. Let's see whether kito has more comments. Thanks. ________________________________ juzhe.zhong@rivai.ai From: pan2.li Date: 2023-07-12 13:50 To: gcc-patches CC: juzhe.zhong; rdapp.gcc; jeffreyalaw; pan2.li; yanzhang.wang; kito.cheng Subject: [PATCH v2] RISC-V: Refactor riscv mode after for VXRM and FRM From: Pan Li > When investigate the FRM dynmaic rounding mode, we find the global unknown status is quite different between the fixed-point and floating-point. Thus, we separate the unknown function with extracting some inner common functions. We will also prepare more test cases in another PATCH. Signed-off-by: Pan Li > gcc/ChangeLog: * config/riscv/riscv.cc (regnum_definition_p): New function. (insn_asm_p): Ditto. (riscv_vxrm_mode_after): New function for fixed-point. (global_vxrm_state_unknown_p): Ditto. (riscv_frm_mode_after): New function for floating-point. (global_frm_state_unknown_p): Ditto. (riscv_mode_after): Leverage new functions. (riscv_entity_mode_after): Removed. --- gcc/config/riscv/riscv.cc | 96 +++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 14 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 38d8eb2fcf5..553fbb4435a 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7742,19 +7742,91 @@ global_state_unknown_p (rtx_insn *insn, unsigned int regno) return false; } +static bool +regnum_definition_p (rtx_insn *insn, unsigned int regno) +{ + df_ref ref; + struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); + + /* Return true if there is a definition of regno. */ + for (ref = DF_INSN_INFO_DEFS (insn_info); ref; ref = DF_REF_NEXT_LOC (ref)) + if (DF_REF_REGNO (ref) == regno) + return true; + + return false; +} + +static bool +insn_asm_p (rtx_insn *insn) +{ + extract_insn (insn); + + return recog_data.is_asm; +} + +static bool +global_vxrm_state_unknown_p (rtx_insn *insn) +{ + /* Return true if there is a definition of VXRM. */ + if (regnum_definition_p (insn, VXRM_REGNUM)) + return true; + + /* A CALL function may contain an instruction that modifies the VXRM, + return true in this situation. */ + if (CALL_P (insn)) + return true; + + /* Return true for all assembly since users may hardcode a assembly + like this: asm volatile ("csrwi vxrm, 0"). */ + if (insn_asm_p (insn)) + return true; + + return false; +} + +static bool +global_frm_state_unknown_p (rtx_insn *insn) +{ + /* Return true if there is a definition of FRM. */ + if (regnum_definition_p (insn, FRM_REGNUM)) + return true; + + /* A CALL function may contain an instruction that modifies the FRM, + return true in this situation. */ + if (CALL_P (insn)) + return true; + + return false; +} + static int -riscv_entity_mode_after (int regnum, rtx_insn *insn, int mode, - int (*get_attr_mode) (rtx_insn *), int default_mode) +riscv_vxrm_mode_after (rtx_insn *insn, int mode) { - if (global_state_unknown_p (insn, regnum)) - return default_mode; - else if (recog_memoized (insn) < 0) + if (global_vxrm_state_unknown_p (insn)) + return VXRM_MODE_NONE; + + if (recog_memoized (insn) < 0) + return mode; + + if (reg_mentioned_p (gen_rtx_REG (SImode, VXRM_REGNUM), PATTERN (insn))) + return get_attr_vxrm_mode (insn); + else return mode; +} - rtx reg = gen_rtx_REG (SImode, regnum); - bool mentioned_p = reg_mentioned_p (reg, PATTERN (insn)); +static int +riscv_frm_mode_after (rtx_insn *insn, int mode) +{ + if (global_frm_state_unknown_p (insn)) + return FRM_MODE_NONE; - return mentioned_p ? get_attr_mode (insn): mode; + if (recog_memoized (insn) < 0) + return mode; + + if (reg_mentioned_p (gen_rtx_REG (SImode, FRM_REGNUM), PATTERN (insn))) + return get_attr_frm_mode (insn); + else + return mode; } /* Return the mode that an insn results in. */ @@ -7765,13 +7837,9 @@ riscv_mode_after (int entity, int mode, rtx_insn *insn) switch (entity) { case RISCV_VXRM: - return riscv_entity_mode_after (VXRM_REGNUM, insn, mode, - (int (*)(rtx_insn *)) get_attr_vxrm_mode, - VXRM_MODE_NONE); + return riscv_vxrm_mode_after (insn, mode); case RISCV_FRM: - return riscv_entity_mode_after (FRM_REGNUM, insn, mode, - (int (*)(rtx_insn *)) get_attr_frm_mode, - FRM_MODE_DYN); + return riscv_frm_mode_after (insn, mode); default: gcc_unreachable (); } -- 2.34.1