[PATCH v5 20/22] RISC-V: Return the matched macro-fusion operation
Jin Ma <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
Ready-list scheduling must probe potential pairs without emitting dump records. Add a helper that returns the matched fusion operation and keep dumping in TARGET_SCHED_MACRO_FUSION_PAIR_P. gcc/ChangeLog: * config/riscv/riscv-fusion.cc (riscv_fusion_type_name): New function. (riscv_get_fusion_pair_type): Likewise. (riscv_macro_fusion_pair_p): Use riscv_get_fusion_pair_type and emit the matched operation. * config/riscv/riscv-protos.h (riscv_get_fusion_pair_type): Declare. Signed-off-by: Jin Ma <[email protected]> --- gcc/config/riscv/riscv-fusion.cc | 55 +++++++++++++++++++++----------- gcc/config/riscv/riscv-protos.h | 2 ++ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/gcc/config/riscv/riscv-fusion.cc b/gcc/config/riscv/riscv-fusion.cc index 06cdab5694d..aca5e757463 100644 --- a/gcc/config/riscv/riscv-fusion.cc +++ b/gcc/config/riscv/riscv-fusion.cc @@ -2028,38 +2028,57 @@ static const struct riscv_fusion_entry riscv_fusion_table[] = riscv_fuse_logic_logic, "RISCV_FUSE_LOGIC_LOGIC" }, }; -/* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR - should be kept together during scheduling. */ +/* Return the name of fusion operation OP. */ -bool -riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) +static const char * +riscv_fusion_type_name (enum riscv_fusion_pairs op) +{ + for (size_t i = 0; i < ARRAY_SIZE (riscv_fusion_table); i++) + if (riscv_fusion_table[i].op == op) + return riscv_fusion_table[i].fusion_type; + + gcc_unreachable (); +} + +/* Return the enabled fusion operation matched by PREV and CURR, or + RISCV_FUSE_NOTHING if the instructions do not form a fusion pair. */ + +enum riscv_fusion_pairs +riscv_get_fusion_pair_type (rtx_insn *prev, rtx_insn *curr) { - /* If fusion is not enabled, then there's nothing to do. */ if (!riscv_macro_fusion_p ()) - return false; + return RISCV_FUSE_NOTHING; - /* If PREV is already marked as fused, then we can't fuse CURR with PREV - and if we were to fuse them we'd end up with a blob of insns that - essentially are an atomic unit which is bad for scheduling. */ + /* Do not extend an existing fusion group. */ if (SCHED_GROUP_P (prev)) - return false; + return RISCV_FUSE_NOTHING; for (size_t i = 0; i < ARRAY_SIZE (riscv_fusion_table); i++) { const struct riscv_fusion_entry *entry = &riscv_fusion_table[i]; - /* Check if this fusion type is enabled. */ if (!riscv_fusion_enabled_p (entry->op)) continue; if (entry->checker (prev, curr)) - { - if (dump_file) - fprintf (dump_file, ";; macro fusion: insn %d + insn %d -> %s\n", - INSN_UID (prev), INSN_UID (curr), entry->fusion_type); - return true; - } + return entry->op; } - return false; + return RISCV_FUSE_NOTHING; +} + +/* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR + should be kept together during scheduling. */ + +bool +riscv_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) +{ + enum riscv_fusion_pairs op = riscv_get_fusion_pair_type (prev, curr); + if (op == RISCV_FUSE_NOTHING) + return false; + + if (dump_file) + fprintf (dump_file, ";; macro fusion: insn %d + insn %d -> %s\n", + INSN_UID (prev), INSN_UID (curr), riscv_fusion_type_name (op)); + return true; } diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 0921b3a7618..9a775b7b32c 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -884,6 +884,8 @@ enum riscv_fusion_pairs extern bool riscv_macro_fusion_p (void); extern bool riscv_macro_fusion_pair_p (rtx_insn *, rtx_insn *); +extern enum riscv_fusion_pairs riscv_get_fusion_pair_type (rtx_insn *, + rtx_insn *); extern void riscv_sched_fusion_priority (rtx_insn *, int, int *, int *); extern unsigned HOST_WIDE_INT riscv_get_fusible_ops (void); -- 2.52.0