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 | 59 +++++++++++++++++++++-----------
gcc/config/riscv/riscv-protos.h | 2 ++
2 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/gcc/config/riscv/riscv-fusion.cc b/gcc/config/riscv/riscv-fusion.cc
index 608cd2e7a38..3761f6b7045 100644
--- a/gcc/config/riscv/riscv-fusion.cc
+++ b/gcc/config/riscv/riscv-fusion.cc
@@ -2102,38 +2102,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)
{
- /* If fusion is not enabled, then there's nothing to do. */
- if (!riscv_macro_fusion_p ())
- return false;
+ 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;
- /* 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. */
- if (SCHED_GROUP_P (prev))
- return false;
+ 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 (!riscv_macro_fusion_p ())
+ 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)
+{
+ /* Do not extend an existing fusion group. */
+ if (SCHED_GROUP_P (prev))
+ return false;
+
+ 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 0a0ba6a0442..99ed79305b7 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -894,6 +894,8 @@ enum riscv_fusion_direction
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 enum riscv_fusion_direction riscv_fuse_mem_direction (rtx_insn *);
extern unsigned HOST_WIDE_INT riscv_get_fusible_ops (void);
--
2.52.0