mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 13:50:09 +01:00
aco/ra: Handle callee ABI preserved register constraints
Block preserved register ranges while they can't yet be overwritten, i.e. before p_spill_preserved and after the last p_reload_preserved. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37381>
This commit is contained in:
parent
75b89f233f
commit
86a8b1753a
1 changed files with 43 additions and 0 deletions
|
|
@ -1196,6 +1196,20 @@ collect_vars(ra_ctx& ctx, RegisterFile& reg_file, const PhysRegInterval reg_inte
|
|||
return ids;
|
||||
}
|
||||
|
||||
std::vector<unsigned>
|
||||
collect_vars_from_bitset(ra_ctx& ctx, RegisterFile& reg_file, const BITSET_DECLARE(set, 512))
|
||||
{
|
||||
std::vector<unsigned> vars, vars2;
|
||||
unsigned start, end;
|
||||
BITSET_FOREACH_RANGE(start, end, set, 512) {
|
||||
PhysRegInterval interval = PhysRegInterval{PhysReg{start}, end - start};
|
||||
vars2 = collect_vars(ctx, reg_file, interval);
|
||||
vars.insert(vars.end(), vars2.begin(), vars2.end());
|
||||
}
|
||||
assert(std::unique(vars.begin(), vars.end()) == vars.end());
|
||||
return vars;
|
||||
}
|
||||
|
||||
std::optional<PhysReg>
|
||||
get_reg_for_create_vector_copy(ra_ctx& ctx, RegisterFile& reg_file,
|
||||
std::vector<parallelcopy>& parallelcopies,
|
||||
|
|
@ -3580,6 +3594,27 @@ emit_parallel_copy(ra_ctx& ctx, std::vector<parallelcopy>& copies,
|
|||
register_file);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
handle_last_reload_preserved(ra_ctx& ctx, aco_ptr<Instruction>& instr,
|
||||
std::vector<parallelcopy>& parallelcopy, RegisterFile& register_file)
|
||||
{
|
||||
BITSET_DECLARE(preserved_regs, 512);
|
||||
ctx.program->callee_abi.preservedRegisters(preserved_regs);
|
||||
|
||||
std::vector<unsigned> vars = collect_vars_from_bitset(ctx, register_file, preserved_regs);
|
||||
|
||||
unsigned start, end;
|
||||
BITSET_FOREACH_RANGE (start, end, preserved_regs, 512)
|
||||
register_file.block(PhysRegInterval{PhysReg{start}, end - start});
|
||||
|
||||
ASSERTED bool success = false;
|
||||
success = get_regs_for_copies(ctx, register_file, parallelcopy, vars, instr, PhysRegInterval{});
|
||||
assert(success);
|
||||
|
||||
update_renames(ctx, register_file, parallelcopy, instr, false, false);
|
||||
}
|
||||
|
||||
} /* end namespace */
|
||||
|
||||
void
|
||||
|
|
@ -3685,6 +3720,14 @@ register_allocation(Program* program, ra_test_policy policy)
|
|||
register_file.clear(op);
|
||||
}
|
||||
|
||||
/* If this is the last p_reload_preserved, we have no more opportunities to restore
|
||||
* overwritten ABI-preserved registers. Make sure all remaining temporaries are outside
|
||||
* preserved registers, then block the preserved registers to mark them unusable.
|
||||
*/
|
||||
if (instr->opcode == aco_opcode::p_reload_preserved && block.linear_succs.empty()) {
|
||||
handle_last_reload_preserved(ctx, instr, parallelcopy, register_file);
|
||||
}
|
||||
|
||||
/* handle fixed definitions first */
|
||||
for (unsigned i = 0; i < instr->definitions.size(); ++i) {
|
||||
auto& definition = instr->definitions[i];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue