return state.regs_freed;
}
+/**
+ * Chooses an instruction that will minimise the register pressure as much as
+ * possible. This should only be used as a fallback when the regular scheduling
+ * generates a shader whose register allocation fails.
+ */
+static nir_schedule_node *
+nir_schedule_choose_instruction_fallback(nir_schedule_scoreboard *scoreboard)
+{
+ nir_schedule_node *chosen = NULL;
+
+ /* Find the leader in the ready (shouldn't-stall) set with the mininum
+ * cost.
+ */
+ list_for_each_entry(nir_schedule_node, n, &scoreboard->dag->heads, dag.link) {
+ if (scoreboard->time < n->ready_time)
+ continue;
+
+ if (!chosen || chosen->max_delay > n->max_delay)
+ chosen = n;
+ }
+ if (chosen) {
+ if (debug) {
+ fprintf(stderr, "chose (ready fallback): ");
+ nir_print_instr(chosen->instr, stderr);
+ fprintf(stderr, "\n");
+ }
+
+ return chosen;
+ }
+
+ /* Otherwise, choose the leader with the minimum cost. */
+ list_for_each_entry(nir_schedule_node, n, &scoreboard->dag->heads, dag.link) {
+ if (!chosen || chosen->max_delay > n->max_delay)
+ chosen = n;
+ }
+ if (debug) {
+ fprintf(stderr, "chose (leader fallback): ");
+ nir_print_instr(chosen->instr, stderr);
+ fprintf(stderr, "\n");
+ }
+
+ return chosen;
+}
+
/**
* Chooses an instruction to schedule using the Goodman/Hsu (1988) CSP (Code
* Scheduling for Parallelism) heuristic.
}
nir_schedule_node *chosen;
- if (scoreboard->pressure < scoreboard->options->threshold)
+ if (scoreboard->options->fallback)
+ chosen = nir_schedule_choose_instruction_fallback(scoreboard);
+ else if (scoreboard->pressure < scoreboard->options->threshold)
chosen = nir_schedule_choose_instruction_csp(scoreboard);
else
chosen = nir_schedule_choose_instruction_csr(scoreboard);
* will try to reduce register usage.
*/
int threshold;
+ /* If set, instead of trying to optimise parallelism, the scheduler will try
+ * to always minimise register pressure. This can be used as a fallback when
+ * register allocation fails so that it can at least try to generate a
+ * working shader even if it’s inefficient.
+ */
+ bool fallback;
/* Callback used to add custom dependencies on intrinsics. If it returns
* true then a dependency should be added and dep is filled in to describe
* it.