aco: don't update register demand during RA validation

It isn't intended to be accurate after RA, so num_waves can become zero,
breaking the sgpr_limit calculation.

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10315>
(cherry picked from commit 655ba1e3a9)
This commit is contained in:
Rhys Perry 2021-04-19 11:24:03 +01:00 committed by Eric Engestrom
parent a87b2fcfbc
commit 7ab251c71a
4 changed files with 15 additions and 10 deletions

View file

@ -256,7 +256,7 @@
"description": "aco: don't update register demand during RA validation",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"master_sha": null,
"because_sha": null
},

View file

@ -1983,7 +1983,7 @@ void select_trap_handler_shader(Program *program, struct nir_shader *shader,
void lower_phis(Program* program);
void calc_min_waves(Program* program);
void update_vgpr_sgpr_demand(Program* program, const RegisterDemand new_demand);
live live_var_analysis(Program* program);
live live_var_analysis(Program* program, bool update_register_demand=true);
std::vector<uint16_t> dead_code_analysis(Program *program);
void dominator_tree(Program* program);
void insert_exec_mask(Program *program);

View file

@ -82,13 +82,14 @@ RegisterDemand get_demand_before(RegisterDemand demand, aco_ptr<Instruction>& in
namespace {
void process_live_temps_per_block(Program *program, live& lives, Block* block,
std::set<unsigned>& worklist, std::vector<uint16_t>& phi_sgpr_ops)
std::set<unsigned>& worklist, std::vector<uint16_t>& phi_sgpr_ops,
bool update_register_demand)
{
std::vector<RegisterDemand>& register_demand = lives.register_demand[block->index];
RegisterDemand new_demand;
register_demand.resize(block->instructions.size());
block->register_demand = RegisterDemand();
RegisterDemand block_register_demand;
IDSet live = lives.live_out[block->index];
/* initialize register demand */
@ -159,11 +160,13 @@ void process_live_temps_per_block(Program *program, live& lives, Block* block,
}
}
block->register_demand.update(register_demand[idx]);
block_register_demand.update(register_demand[idx]);
}
/* update block's register demand for a last time */
block->register_demand.update(new_demand);
block_register_demand.update(new_demand);
if (update_register_demand)
block->register_demand = block_register_demand;
/* handle phi definitions */
int phi_idx = idx;
@ -362,7 +365,7 @@ void update_vgpr_sgpr_demand(Program* program, const RegisterDemand new_demand)
}
}
live live_var_analysis(Program* program)
live live_var_analysis(Program* program, bool update_register_demand)
{
live result;
result.live_out.resize(program->blocks.size());
@ -380,12 +383,14 @@ live live_var_analysis(Program* program)
std::set<unsigned>::reverse_iterator b_it = worklist.rbegin();
unsigned block_idx = *b_it;
worklist.erase(block_idx);
process_live_temps_per_block(program, result, &program->blocks[block_idx], worklist, phi_sgpr_ops);
process_live_temps_per_block(program, result, &program->blocks[block_idx], worklist,
phi_sgpr_ops, update_register_demand);
new_demand.update(program->blocks[block_idx].register_demand);
}
/* calculate the program's register demand and number of waves */
update_vgpr_sgpr_demand(program, new_demand);
if (update_register_demand)
update_vgpr_sgpr_demand(program, new_demand);
return result;
}

View file

@ -677,7 +677,7 @@ bool validate_ra(Program *program) {
return false;
bool err = false;
aco::live live_vars = aco::live_var_analysis(program);
aco::live live_vars = aco::live_var_analysis(program, false);
std::vector<std::vector<Temp>> phi_sgpr_ops(program->blocks.size());
uint16_t sgpr_limit = get_addr_sgpr_from_waves(program, program->num_waves);