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