mesa/src/intel/compiler/jay/jay_private.h
Alyssa Rosenzweig bc22a37d98 jay: schedule for pressure
Implement a simple pre-RA bottom-up list scheduler with the goal of decreasing
register pressure. On Xe2, this significantly reduces spilling.

SSA form allows us to estimate register demand cheaply and accurately, which
theoretically [1] gives this algorithm the two Hippocratic properties:

1. Shaders with low register pressure are unaffected.
2. Register pressure can only be decreased, never increased.

In other words: first, do no harm.

The heuristic itself is very simple: greedily choose instructions that decrease
liveness using a backwards list scheduler. This is far from optimal! But thanks
to the above properties, even a heuristic that picked random instructions would
be a win overall - by construction, we can only ever win.

In other words: this scheduler is your older brother powering off the game
console any time he's about to lose a game, maintaining a 100% win rate.

[1] In reality, neither property is strictly satisfied due to the messy details
of mapping our clean logical model onto Intel's many weird physical register
files. Nevertheless, the algorithm is well-motivated and the empirical results
on Xe2 are excellent.

SIMD16:

   Totals:
   Instrs: 2754194 -> 2753957 (-0.01%); split: -0.23%, +0.22%
   CodeSize: 41094768 -> 41092768 (-0.00%); split: -0.23%, +0.23%
   Number of spill instructions: 1724 -> 1129 (-34.51%)
   Number of fill instructions: 1912 -> 1119 (-41.47%)

   Totals from 168 (6.35% of 2647) affected shaders:
   Instrs: 850994 -> 850757 (-0.03%); split: -0.75%, +0.73%
   CodeSize: 12825680 -> 12823680 (-0.02%); split: -0.74%, +0.73%
   Number of spill instructions: 1724 -> 1129 (-34.51%)
   Number of fill instructions: 1912 -> 1119 (-41.47%)

SIMD32:

   Totals:
   Instrs: 4688858 -> 4557800 (-2.80%); split: -3.53%, +0.74%
   CodeSize: 70177200 -> 68214816 (-2.80%); split: -3.53%, +0.74%
   Number of spill instructions: 50316 -> 45795 (-8.99%); split: -9.56%, +0.57%
   Number of fill instructions: 51526 -> 45075 (-12.52%); split: -13.23%, +0.71%

   Totals from 819 (30.94% of 2647) affected shaders:
   Instrs: 3810182 -> 3679124 (-3.44%); split: -4.35%, +0.91%
   CodeSize: 57044000 -> 55081616 (-3.44%); split: -4.35%, +0.91%
   Number of spill instructions: 49264 -> 44743 (-9.18%); split: -9.76%, +0.58%
   Number of fill instructions: 50182 -> 43731 (-12.86%); split: -13.58%, +0.73%

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41688>
2026-05-21 15:34:46 +00:00

91 lines
2.7 KiB
C

/*
* Copyright 2026 Intel Corporation
* SPDX-License-Identifier: MIT
*/
#pragma once
#include "jay_ir.h"
#include "nir.h"
#ifdef __cplusplus
extern "C" {
#endif
#define JAY_DBG_NOOPT BITFIELD_BIT(0)
#define JAY_DBG_PRINTDEMAND BITFIELD_BIT(1)
#define JAY_DBG_SPILL BITFIELD_BIT(2)
#define JAY_DBG_SYNC BITFIELD_BIT(3)
#define JAY_DBG_NOACC BITFIELD_BIT(4)
#define JAY_DBG_NOSCHED BITFIELD_BIT(5)
extern int jay_debug;
bool jay_nir_lower_bool(nir_shader *nir);
bool jay_nir_opt_sel_zero(nir_shader *nir);
bool jay_nir_lower_fsign(nir_shader *nir);
void jay_populate_prog_data(const struct intel_device_info *devinfo,
nir_shader *nir,
union brw_any_prog_data *prog_data,
union brw_any_prog_key *key,
unsigned nr_packed_regs);
unsigned jay_process_nir(const struct intel_device_info *devinfo,
nir_shader *nir,
union brw_any_prog_data *prog_data,
union brw_any_prog_key *key);
void jay_compute_liveness(jay_function *f);
void jay_calculate_register_demands(jay_function *f);
void jay_spill(jay_function *func, unsigned limit);
void jay_partition_grf(jay_shader *shader);
void jay_register_allocate(jay_shader *s);
void jay_assign_flags(jay_shader *s);
void jay_assign_accumulators(jay_shader *s);
void jay_repair_ssa(jay_function *func);
const char *jay_file_prefix(enum jay_file file);
void jay_print_type(FILE *f, enum jay_type t);
void jay_print_inst(FILE *f, jay_inst *I);
void jay_print_block(FILE *f, jay_block *block);
void jay_print_func(FILE *fp, jay_function *func);
void jay_print(FILE *f, jay_shader *s);
#ifndef NDEBUG
void jay_validate(jay_shader *s, const char *when);
void jay_validate_ra(jay_function *func);
#else
static inline void
jay_validate(jay_shader *s, const char *when)
{
}
static inline void
jay_validate_ra(jay_function *func)
{
}
#endif
void jay_opt_propagate_forwards(jay_shader *s);
void jay_opt_propagate_backwards(jay_shader *s);
void jay_opt_dead_code(jay_shader *s);
void jay_opt_predicate(jay_shader *s);
void jay_schedule_pressure(jay_shader *s);
void jay_lower_pre_ra(jay_shader *s);
void jay_lower_post_ra(jay_shader *s);
void jay_lower_spill(jay_function *func);
void jay_lower_simd_width(jay_shader *s);
void jay_lower_scoreboard(jay_shader *s);
void jay_lower_scoreboard_trivial(jay_shader *s);
void jay_insert_fp_mode(jay_shader *shader, uint32_t api, uint32_t float_sizes);
struct jay_shader_bin *jay_to_binary(jay_shader *s,
void *const_data,
size_t const_data_size,
bool debug);
#ifdef __cplusplus
} /* extern C */
#endif