From 41465628fe4fb3dea9d45f93b263b4aac2bf1694 Mon Sep 17 00:00:00 2001
From: Vineet Gupta <vineetg@rivosinc.com>
Date: Mon, 9 Sep 2024 13:29:49 -0700
Subject: [RFC] sched1: model pressure deps promotion to be conservative
[PR/114729]
On RISC-V, sched1 triggers a spill pathology for SPEC2017 Cactu adding
an additional 1.2 trillion dynamic icounts (user mode qemu) or almost
half of the total 2.4 trillion.
This is a multitude of various smaller issues.
One of the issues is the "model schedule" building in
model_start_schedule() -> model_choose_insn ().
An insn requires its predecessors to be added to the model first which
is done in model_promote_predecessors ().
However adding all predecessors including the non true deps ones causes
the successor insn to be delayed more than it should, increasing the
pressure.
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
---
gcc/haifa-sched.cc | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
@@ -1862,6 +1862,8 @@ struct model_insn_info {
/* The number of predecessor nodes that must still be scheduled. */
int unscheduled_preds;
+
+ int unscheduled_true_preds;
};
/* Information about the pressure limit for a particular register class.
@@ -3484,7 +3486,18 @@ model_analyze_insns (void)
insn->old_queue = QUEUE_INDEX (iter);
QUEUE_INDEX (iter) = QUEUE_NOWHERE;
- insn->unscheduled_preds = dep_list_size (iter, SD_LIST_HARD_BACK);
+ insn->unscheduled_preds = 0;
+ insn->unscheduled_true_preds = 0;
+ FOR_EACH_DEP (iter, SD_LIST_HARD_BACK, sd_it, dep)
+ {
+ if (!DEBUG_INSN_P (DEP_PRO (dep)))
+ {
+ insn->unscheduled_preds++;
+ if (DEP_TYPE (dep) == REG_DEP_TRUE)
+ insn->unscheduled_true_preds++;
+ }
+ }
+ gcc_assert(insn->unscheduled_preds == dep_list_size (iter, SD_LIST_HARD_BACK));
if (insn->unscheduled_preds == 0)
model_add_to_worklist (insn, NULL, model_worklist);
@@ -3616,6 +3629,9 @@ model_add_successors_to_worklist (struct model_insn_info *insn)
{
con->unscheduled_preds--;
+ if (DEP_TYPE (dep) == REG_DEP_TRUE)
+ con->unscheduled_true_preds--;
+
/* Update the depth field of each true-dependent successor.
Increasing the depth gives them a higher priority than
before. */
@@ -3647,6 +3663,7 @@ model_add_successors_to_worklist (struct model_insn_info *insn)
static void
model_promote_predecessors (struct model_insn_info *insn)
{
+ unsigned int model_new_priority;
struct model_insn_info *pro, *first;
sd_iterator_def sd_it;
dep_t dep;
@@ -3654,7 +3671,9 @@ model_promote_predecessors (struct model_insn_info *insn)
if (sched_verbose >= 7)
fprintf (sched_dump, ";;\t+--- priority of %d = %d, priority of",
INSN_UID (insn->insn), model_next_priority);
- insn->model_priority = model_next_priority++;
+ insn->model_priority = model_next_priority;
+ model_new_priority = model_next_priority + 1;
+
model_remove_from_worklist (insn);
model_add_to_worklist_at (insn, NULL);
@@ -3670,7 +3689,6 @@ model_promote_predecessors (struct model_insn_info *insn)
&& pro->model_priority != model_next_priority
&& QUEUE_INDEX (pro->insn) != QUEUE_SCHEDULED)
{
- pro->model_priority = model_next_priority;
if (sched_verbose >= 7)
fprintf (sched_dump, " %d", INSN_UID (pro->insn));
if (QUEUE_INDEX (pro->insn) == QUEUE_READY)
@@ -3678,6 +3696,10 @@ model_promote_predecessors (struct model_insn_info *insn)
/* PRO is already in the worklist, but it now has
a higher priority than before. Move it at the
appropriate place. */
+ if (DEP_TYPE (dep) == REG_DEP_TRUE)
+ {
+ pro->model_priority = model_new_priority;
+ }
model_remove_from_worklist (pro);
model_add_to_worklist (pro, NULL, model_worklist);
}
@@ -3696,8 +3718,8 @@ model_promote_predecessors (struct model_insn_info *insn)
first = insn->next;
}
if (sched_verbose >= 7)
- fprintf (sched_dump, " = %d\n", model_next_priority);
- model_next_priority++;
+ fprintf (sched_dump, " = %d\n", model_new_priority);
+ model_next_priority = model_new_priority + 1;
}
/* Pick one instruction from model_worklist and process it. */
@@ -3783,7 +3805,8 @@ model_choose_insn (void)
/* INSN isn't yet ready to issue. Give all its predecessors the
highest priority. */
model_promote_predecessors (insn);
- else
+
+ if (!insn->unscheduled_true_preds)
{
/* INSN is ready. Add it to the end of model_schedule and
process its successors. */
--
2.43.0