intel/compiler: Move register pressure calculation into IR analysis object
This defines a new BRW_ANALYSIS object which wraps the register pressure computation code along with its result. For the rationale see the previous commits converting the liveness and dominance analysis passes to the IR analysis framework. Reviewed-by: Matt Turner <mattst88@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4012>
This commit is contained in:

committed by
Matt Turner

parent
f6cdf66cd6
commit
e5e4d016b9
@@ -6975,11 +6975,11 @@ fs_visitor::dump_instructions(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cfg) {
|
if (cfg) {
|
||||||
calculate_register_pressure();
|
const register_pressure &rp = regpressure_analysis.require();
|
||||||
int ip = 0, max_pressure = 0;
|
unsigned ip = 0, max_pressure = 0;
|
||||||
foreach_block_and_inst(block, backend_instruction, inst, cfg) {
|
foreach_block_and_inst(block, backend_instruction, inst, cfg) {
|
||||||
max_pressure = MAX2(max_pressure, regs_live_at_ip[ip]);
|
max_pressure = MAX2(max_pressure, rp.regs_live_at_ip[ip]);
|
||||||
fprintf(file, "{%3d} %4d: ", regs_live_at_ip[ip], ip);
|
fprintf(file, "{%3d} %4d: ", rp.regs_live_at_ip[ip], ip);
|
||||||
dump_instruction(inst, file);
|
dump_instruction(inst, file);
|
||||||
ip++;
|
ip++;
|
||||||
}
|
}
|
||||||
@@ -7359,28 +7359,32 @@ fs_visitor::setup_cs_payload()
|
|||||||
payload.num_regs = 1;
|
payload.num_regs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
brw::register_pressure::register_pressure(const fs_visitor *v)
|
||||||
fs_visitor::calculate_register_pressure()
|
|
||||||
{
|
{
|
||||||
const fs_live_variables &live = live_analysis.require();
|
const fs_live_variables &live = v->live_analysis.require();
|
||||||
|
|
||||||
unsigned num_instructions = 0;
|
unsigned num_instructions = 0;
|
||||||
foreach_block(block, cfg)
|
foreach_block(block, v->cfg)
|
||||||
num_instructions += block->instructions.length();
|
num_instructions += block->instructions.length();
|
||||||
|
|
||||||
regs_live_at_ip = rzalloc_array(mem_ctx, int, num_instructions);
|
regs_live_at_ip = new unsigned[num_instructions]();
|
||||||
|
|
||||||
for (unsigned reg = 0; reg < alloc.count; reg++) {
|
for (unsigned reg = 0; reg < v->alloc.count; reg++) {
|
||||||
for (int ip = live.vgrf_start[reg]; ip <= live.vgrf_end[reg]; ip++)
|
for (int ip = live.vgrf_start[reg]; ip <= live.vgrf_end[reg]; ip++)
|
||||||
regs_live_at_ip[ip] += alloc.sizes[reg];
|
regs_live_at_ip[ip] += v->alloc.sizes[reg];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brw::register_pressure::~register_pressure()
|
||||||
|
{
|
||||||
|
delete[] regs_live_at_ip;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fs_visitor::invalidate_analysis(brw::analysis_dependency_class c)
|
fs_visitor::invalidate_analysis(brw::analysis_dependency_class c)
|
||||||
{
|
{
|
||||||
backend_shader::invalidate_analysis(c);
|
backend_shader::invalidate_analysis(c);
|
||||||
live_analysis.invalidate(c);
|
live_analysis.invalidate(c);
|
||||||
|
regpressure_analysis.invalidate(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -39,7 +39,34 @@ namespace {
|
|||||||
struct acp_entry;
|
struct acp_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class fs_visitor;
|
||||||
|
|
||||||
namespace brw {
|
namespace brw {
|
||||||
|
/**
|
||||||
|
* Register pressure analysis of a shader. Estimates how many registers
|
||||||
|
* are live at any point of the program in GRF units.
|
||||||
|
*/
|
||||||
|
struct register_pressure {
|
||||||
|
register_pressure(const fs_visitor *v);
|
||||||
|
~register_pressure();
|
||||||
|
|
||||||
|
analysis_dependency_class
|
||||||
|
dependency_class() const
|
||||||
|
{
|
||||||
|
return (DEPENDENCY_INSTRUCTION_IDENTITY |
|
||||||
|
DEPENDENCY_INSTRUCTION_DATA_FLOW |
|
||||||
|
DEPENDENCY_VARIABLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
validate(const fs_visitor *) const
|
||||||
|
{
|
||||||
|
/* FINISHME */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned *regs_live_at_ip;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct brw_gs_compile;
|
struct brw_gs_compile;
|
||||||
@@ -126,7 +153,6 @@ public:
|
|||||||
unsigned *out_pull_index);
|
unsigned *out_pull_index);
|
||||||
void lower_constant_loads();
|
void lower_constant_loads();
|
||||||
virtual void invalidate_analysis(brw::analysis_dependency_class c);
|
virtual void invalidate_analysis(brw::analysis_dependency_class c);
|
||||||
void calculate_register_pressure();
|
|
||||||
void validate();
|
void validate();
|
||||||
bool opt_algebraic();
|
bool opt_algebraic();
|
||||||
bool opt_redundant_discard_jumps();
|
bool opt_redundant_discard_jumps();
|
||||||
@@ -322,8 +348,8 @@ public:
|
|||||||
|
|
||||||
BRW_ANALYSIS(live_analysis, brw::fs_live_variables,
|
BRW_ANALYSIS(live_analysis, brw::fs_live_variables,
|
||||||
backend_shader *) live_analysis;
|
backend_shader *) live_analysis;
|
||||||
|
BRW_ANALYSIS(regpressure_analysis, brw::register_pressure,
|
||||||
int *regs_live_at_ip;
|
fs_visitor *) regpressure_analysis;
|
||||||
|
|
||||||
/** Number of uniform variable components visited. */
|
/** Number of uniform variable components visited. */
|
||||||
unsigned uniforms;
|
unsigned uniforms;
|
||||||
|
@@ -886,7 +886,7 @@ fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data,
|
|||||||
: backend_shader(compiler, log_data, mem_ctx, shader, prog_data),
|
: backend_shader(compiler, log_data, mem_ctx, shader, prog_data),
|
||||||
key(key), gs_compile(NULL), prog_data(prog_data),
|
key(key), gs_compile(NULL), prog_data(prog_data),
|
||||||
input_vue_map(input_vue_map),
|
input_vue_map(input_vue_map),
|
||||||
live_analysis(this),
|
live_analysis(this), regpressure_analysis(this),
|
||||||
dispatch_width(dispatch_width),
|
dispatch_width(dispatch_width),
|
||||||
shader_time_index(shader_time_index),
|
shader_time_index(shader_time_index),
|
||||||
bld(fs_builder(this, dispatch_width).at_end())
|
bld(fs_builder(this, dispatch_width).at_end())
|
||||||
@@ -904,7 +904,7 @@ fs_visitor::fs_visitor(const struct brw_compiler *compiler, void *log_data,
|
|||||||
&prog_data->base.base),
|
&prog_data->base.base),
|
||||||
key(&c->key.base), gs_compile(c),
|
key(&c->key.base), gs_compile(c),
|
||||||
prog_data(&prog_data->base.base),
|
prog_data(&prog_data->base.base),
|
||||||
live_analysis(this),
|
live_analysis(this), regpressure_analysis(this),
|
||||||
dispatch_width(8),
|
dispatch_width(8),
|
||||||
shader_time_index(shader_time_index),
|
shader_time_index(shader_time_index),
|
||||||
bld(fs_builder(this, dispatch_width).at_end())
|
bld(fs_builder(this, dispatch_width).at_end())
|
||||||
@@ -935,8 +935,6 @@ fs_visitor::init()
|
|||||||
this->first_non_payload_grf = 0;
|
this->first_non_payload_grf = 0;
|
||||||
this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;
|
this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;
|
||||||
|
|
||||||
this->regs_live_at_ip = NULL;
|
|
||||||
|
|
||||||
this->uniforms = 0;
|
this->uniforms = 0;
|
||||||
this->last_scratch = 0;
|
this->last_scratch = 0;
|
||||||
this->pull_constant_loc = NULL;
|
this->pull_constant_loc = NULL;
|
||||||
|
Reference in New Issue
Block a user