intel/compiler: Move all live interval analysis results into fs_live_variables
This moves the following methods that are currently defined in fs_visitor (even though they are side products of the liveness analysis computation) and are already implemented in brw_fs_live_variables.cpp: > bool virtual_grf_interferes(int a, int b) const; > int *virtual_grf_start; > int *virtual_grf_end; It makes sense for them to be part of the fs_live_variables object, because they have the same lifetime as other liveness analysis results and because this will allow some extra validation to happen wherever they are accessed in order to make sure that we only ever use up-to-date liveness analysis results. This shortens the virtual_grf prefix in order to compensate for the slightly increased lexical overhead from the live_intervals pointer dereference. Reviewed-by: Matt Turner <mattst88@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4012>
This commit is contained in:
parent
3ceb496cdf
commit
ba73e606f6
|
@ -2037,7 +2037,7 @@ fs_visitor::split_virtual_grfs()
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove unused virtual GRFs and compact the virtual_grf_* arrays.
|
||||
* Remove unused virtual GRFs and compact the vgrf_* arrays.
|
||||
*
|
||||
* During code generation, we create tons of temporary variables, many of
|
||||
* which get immediately killed and are never used again. Yet, in later
|
||||
|
@ -3117,7 +3117,7 @@ fs_visitor::compute_to_mrf()
|
|||
/* Can't compute-to-MRF this GRF if someone else was going to
|
||||
* read it later.
|
||||
*/
|
||||
if (this->virtual_grf_end[inst->src[0].nr] > ip)
|
||||
if (live_intervals->vgrf_end[inst->src[0].nr] > ip)
|
||||
continue;
|
||||
|
||||
/* Found a move of a GRF to a MRF. Let's see if we can go rewrite the
|
||||
|
@ -7372,7 +7372,8 @@ fs_visitor::calculate_register_pressure()
|
|||
regs_live_at_ip = rzalloc_array(mem_ctx, int, num_instructions);
|
||||
|
||||
for (unsigned reg = 0; reg < alloc.count; reg++) {
|
||||
for (int ip = virtual_grf_start[reg]; ip <= virtual_grf_end[reg]; ip++)
|
||||
for (int ip = live_intervals->vgrf_start[reg];
|
||||
ip <= live_intervals->vgrf_end[reg]; ip++)
|
||||
regs_live_at_ip[ip] += alloc.sizes[reg];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,6 @@ public:
|
|||
bool remove_extra_rounding_modes();
|
||||
|
||||
bool opt_sampler_eot();
|
||||
bool virtual_grf_interferes(int a, int b) const;
|
||||
void schedule_instructions(instruction_scheduler_mode mode);
|
||||
void insert_gen4_send_dependency_workarounds();
|
||||
void insert_gen4_pre_send_dependency_workarounds(bblock_t *block,
|
||||
|
@ -320,8 +319,8 @@ public:
|
|||
|
||||
const struct brw_vue_map *input_vue_map;
|
||||
|
||||
int *virtual_grf_start;
|
||||
int *virtual_grf_end;
|
||||
int *param_size;
|
||||
|
||||
brw::fs_live_variables *live_intervals;
|
||||
|
||||
int *regs_live_at_ip;
|
||||
|
|
|
@ -1035,8 +1035,8 @@ fs_visitor::opt_copy_propagation()
|
|||
for (unsigned a = 0; a < ACP_HASH_SIZE; a++) {
|
||||
foreach_in_list_safe(acp_entry, entry, &out_acp[block->num][a]) {
|
||||
assert(entry->dst.file == VGRF);
|
||||
if (block->start_ip <= virtual_grf_start[entry->dst.nr] &&
|
||||
virtual_grf_end[entry->dst.nr] <= block->end_ip)
|
||||
if (block->start_ip <= live_intervals->vgrf_start[entry->dst.nr] &&
|
||||
live_intervals->vgrf_end[entry->dst.nr] <= block->end_ip)
|
||||
entry->remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -360,7 +360,8 @@ fs_visitor::opt_cse_local(bblock_t *block, int &ip)
|
|||
/* Kill any AEB entries using registers that don't get reused any
|
||||
* more -- a sure sign they'll fail operands_match().
|
||||
*/
|
||||
if (src_reg->file == VGRF && virtual_grf_end[src_reg->nr] < ip) {
|
||||
if (src_reg->file == VGRF &&
|
||||
live_intervals->vgrf_end[src_reg->nr] < ip) {
|
||||
entry->remove();
|
||||
ralloc_free(entry);
|
||||
break;
|
||||
|
|
|
@ -282,6 +282,13 @@ fs_live_variables::fs_live_variables(fs_visitor *v, const cfg_t *cfg)
|
|||
end[i] = -1;
|
||||
}
|
||||
|
||||
vgrf_start = ralloc_array(mem_ctx, int, num_vgrfs);
|
||||
vgrf_end = ralloc_array(mem_ctx, int, num_vgrfs);
|
||||
for (int i = 0; i < num_vgrfs; i++) {
|
||||
vgrf_start[i] = MAX_INSTRUCTION;
|
||||
vgrf_end[i] = -1;
|
||||
}
|
||||
|
||||
block_data = rzalloc_array(mem_ctx, struct block_data, cfg->num_blocks);
|
||||
|
||||
bitset_words = BITSET_WORDS(num_vars);
|
||||
|
@ -302,6 +309,13 @@ fs_live_variables::fs_live_variables(fs_visitor *v, const cfg_t *cfg)
|
|||
setup_def_use();
|
||||
compute_live_variables();
|
||||
compute_start_end();
|
||||
|
||||
/* Merge the per-component live ranges to whole VGRF live ranges. */
|
||||
for (int i = 0; i < num_vars; i++) {
|
||||
const unsigned vgrf = vgrf_from_var[i];
|
||||
vgrf_start[vgrf] = MIN2(vgrf_start[vgrf], start[i]);
|
||||
vgrf_end[vgrf] = MAX2(vgrf_end[vgrf], end[i]);
|
||||
}
|
||||
}
|
||||
|
||||
fs_live_variables::~fs_live_variables()
|
||||
|
@ -328,27 +342,7 @@ fs_visitor::calculate_live_intervals()
|
|||
if (this->live_intervals)
|
||||
return;
|
||||
|
||||
int num_vgrfs = this->alloc.count;
|
||||
ralloc_free(this->virtual_grf_start);
|
||||
ralloc_free(this->virtual_grf_end);
|
||||
virtual_grf_start = ralloc_array(mem_ctx, int, num_vgrfs);
|
||||
virtual_grf_end = ralloc_array(mem_ctx, int, num_vgrfs);
|
||||
|
||||
for (int i = 0; i < num_vgrfs; i++) {
|
||||
virtual_grf_start[i] = MAX_INSTRUCTION;
|
||||
virtual_grf_end[i] = -1;
|
||||
}
|
||||
|
||||
this->live_intervals = new(mem_ctx) fs_live_variables(this, cfg);
|
||||
|
||||
/* Merge the per-component live ranges to whole VGRF live ranges. */
|
||||
for (int i = 0; i < live_intervals->num_vars; i++) {
|
||||
int vgrf = live_intervals->vgrf_from_var[i];
|
||||
virtual_grf_start[vgrf] = MIN2(virtual_grf_start[vgrf],
|
||||
live_intervals->start[i]);
|
||||
virtual_grf_end[vgrf] = MAX2(virtual_grf_end[vgrf],
|
||||
live_intervals->end[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -359,8 +353,8 @@ fs_live_variables::vars_interfere(int a, int b) const
|
|||
}
|
||||
|
||||
bool
|
||||
fs_visitor::virtual_grf_interferes(int a, int b) const
|
||||
fs_live_variables::vgrfs_interfere(int a, int b) const
|
||||
{
|
||||
return !(virtual_grf_end[a] <= virtual_grf_start[b] ||
|
||||
virtual_grf_end[b] <= virtual_grf_start[a]);
|
||||
return !(vgrf_end[a] <= vgrf_start[b] ||
|
||||
vgrf_end[b] <= vgrf_start[a]);
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ public:
|
|||
~fs_live_variables();
|
||||
|
||||
bool vars_interfere(int a, int b) const;
|
||||
bool vgrfs_interfere(int a, int b) const;
|
||||
int var_from_reg(const fs_reg ®) const
|
||||
{
|
||||
return var_from_vgrf[reg.nr] + reg.offset / REG_SIZE;
|
||||
|
@ -110,6 +111,13 @@ public:
|
|||
int *end;
|
||||
/** @} */
|
||||
|
||||
/** @{
|
||||
* Final computed live ranges for each VGRF.
|
||||
*/
|
||||
int *vgrf_start;
|
||||
int *vgrf_end;
|
||||
/** @} */
|
||||
|
||||
/** Per-basic-block information on live variables */
|
||||
struct block_data *block_data;
|
||||
|
||||
|
|
|
@ -567,7 +567,7 @@ fs_reg_alloc::setup_live_interference(unsigned node,
|
|||
if (payload_last_use_ip[i] == -1)
|
||||
continue;
|
||||
|
||||
/* Note that we use a <= comparison, unlike virtual_grf_interferes(),
|
||||
/* Note that we use a <= comparison, unlike vgrfs_interfere(),
|
||||
* in order to not have to worry about the uniform issue described in
|
||||
* calculate_live_intervals().
|
||||
*/
|
||||
|
@ -590,8 +590,8 @@ fs_reg_alloc::setup_live_interference(unsigned node,
|
|||
for (unsigned n2 = first_vgrf_node;
|
||||
n2 < (unsigned)first_spill_node && n2 < node; n2++) {
|
||||
unsigned vgrf = n2 - first_vgrf_node;
|
||||
if (!(node_end_ip <= fs->virtual_grf_start[vgrf] ||
|
||||
fs->virtual_grf_end[vgrf] <= node_start_ip))
|
||||
if (!(node_end_ip <= fs->live_intervals->vgrf_start[vgrf] ||
|
||||
fs->live_intervals->vgrf_end[vgrf] <= node_start_ip))
|
||||
ra_add_node_interference(g, node, n2);
|
||||
}
|
||||
}
|
||||
|
@ -812,8 +812,8 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
|
|||
/* Add interference based on the live range of the register */
|
||||
for (unsigned i = 0; i < fs->alloc.count; i++) {
|
||||
setup_live_interference(first_vgrf_node + i,
|
||||
fs->virtual_grf_start[i],
|
||||
fs->virtual_grf_end[i]);
|
||||
fs->live_intervals->vgrf_start[i],
|
||||
fs->live_intervals->vgrf_end[i]);
|
||||
}
|
||||
|
||||
/* Add interference based on the instructions in which a register is used.
|
||||
|
@ -953,7 +953,7 @@ fs_reg_alloc::set_spill_costs()
|
|||
if (no_spill[i])
|
||||
continue;
|
||||
|
||||
int live_length = fs->virtual_grf_end[i] - fs->virtual_grf_start[i];
|
||||
int live_length = fs->live_intervals->vgrf_end[i] - fs->live_intervals->vgrf_start[i];
|
||||
if (live_length <= 0)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -933,8 +933,6 @@ fs_visitor::init()
|
|||
this->first_non_payload_grf = 0;
|
||||
this->max_grf = devinfo->gen >= 7 ? GEN7_MRF_HACK_START : BRW_MAX_GRF;
|
||||
|
||||
this->virtual_grf_start = NULL;
|
||||
this->virtual_grf_end = NULL;
|
||||
this->live_intervals = NULL;
|
||||
this->regs_live_at_ip = NULL;
|
||||
|
||||
|
|
|
@ -754,8 +754,8 @@ fs_instruction_scheduler::setup_liveness(cfg_t *cfg)
|
|||
*/
|
||||
for (int block = 0; block < cfg->num_blocks - 1; block++) {
|
||||
for (int i = 0; i < grf_count; i++) {
|
||||
if (v->virtual_grf_start[i] <= cfg->blocks[block]->end_ip &&
|
||||
v->virtual_grf_end[i] >= cfg->blocks[block + 1]->start_ip) {
|
||||
if (v->live_intervals->vgrf_start[i] <= cfg->blocks[block]->end_ip &&
|
||||
v->live_intervals->vgrf_end[i] >= cfg->blocks[block + 1]->start_ip) {
|
||||
if (!BITSET_TEST(livein[block + 1], i)) {
|
||||
reg_pressure_in[block + 1] += v->alloc.sizes[i];
|
||||
BITSET_SET(livein[block + 1], i);
|
||||
|
|
Loading…
Reference in New Issue