mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 21:30:09 +01:00
aco/ra: Use std::find_if(_not) to clean up get_reg_simple
This makes for a more self-describing iteration behavior, and it gets rid of the need for the duplicated "final check" at the bottom. Reviewed-by: Daniel Schürmann <daniel@schuermann.dev> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7799>
This commit is contained in:
parent
ebdb362937
commit
2b3b2f7ff5
1 changed files with 23 additions and 21 deletions
|
|
@ -123,6 +123,10 @@ struct PhysRegIterator {
|
|||
bool operator!=(PhysRegIterator oth) const {
|
||||
return reg != oth.reg;
|
||||
}
|
||||
|
||||
bool operator<(PhysRegIterator oth) const {
|
||||
return reg < oth.reg;
|
||||
}
|
||||
};
|
||||
|
||||
/* Half-open register interval used in "sliding window"-style for-loops */
|
||||
|
|
@ -725,42 +729,40 @@ std::pair<PhysReg, bool> get_reg_simple(ra_ctx& ctx,
|
|||
if (stride == 1) {
|
||||
/* best fit algorithm: find the smallest gap to fit in the variable */
|
||||
PhysRegInterval best_gap { 0xFFFF, 0xFFFF };
|
||||
unsigned last_pos = 0xFFFF;
|
||||
const unsigned max_gpr = (rc.type() == RegType::vgpr) ? (256 + ctx.max_used_vgpr) : ctx.max_used_sgpr;
|
||||
|
||||
for (const unsigned current_reg : bounds) {
|
||||
if (reg_file[current_reg] == 0 && !ctx.war_hint[current_reg]) {
|
||||
if (last_pos == 0xFFFF)
|
||||
last_pos = current_reg;
|
||||
PhysRegIterator reg_it = bounds.begin();
|
||||
const PhysRegIterator end_it = std::min(bounds.end(), std::max(PhysRegIterator { max_gpr + 1 }, reg_it));
|
||||
|
||||
/* stop searching after max_used_gpr */
|
||||
if (current_reg == ctx.max_used_sgpr + 1 || current_reg == 256 + ctx.max_used_vgpr + 1)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
auto is_free = [&](unsigned reg_index) { return reg_file[reg_index] == 0 && !ctx.war_hint[reg_index]; };
|
||||
while (reg_it != bounds.end()) {
|
||||
/* Find the next chunk of available register slots */
|
||||
reg_it = std::find_if(reg_it, end_it, is_free);
|
||||
auto next_nonfree_it = std::find_if_not(reg_it, end_it, is_free);
|
||||
if (reg_it == bounds.end()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (last_pos == 0xFFFF)
|
||||
continue;
|
||||
if (next_nonfree_it == end_it) {
|
||||
/* All registers past max_used_gpr are free */
|
||||
next_nonfree_it = bounds.end();
|
||||
}
|
||||
|
||||
/* Below this line, "current_reg" indicates the first non-free register after last_pos */
|
||||
PhysRegInterval gap = PhysRegInterval::from_until(*reg_it, *next_nonfree_it);
|
||||
|
||||
PhysRegInterval gap = PhysRegInterval::from_until(last_pos, current_reg);
|
||||
/* early return on exact matches */
|
||||
if (size == gap.size) {
|
||||
adjust_max_used_regs(ctx, rc, last_pos);
|
||||
return {PhysReg{last_pos}, true};
|
||||
adjust_max_used_regs(ctx, rc, gap.lo());
|
||||
return {PhysReg{gap.lo()}, true};
|
||||
}
|
||||
|
||||
/* check if it fits and the gap size is smaller */
|
||||
if (size < gap.size && gap.size < best_gap.size) {
|
||||
best_gap = gap;
|
||||
}
|
||||
last_pos = 0xFFFF;
|
||||
}
|
||||
|
||||
/* final check */
|
||||
if (last_pos + size <= bounds.hi() && bounds.hi() - last_pos < best_gap.size) {
|
||||
best_gap = { last_pos, bounds.hi() - last_pos };
|
||||
/* Move past the processed chunk */
|
||||
reg_it = next_nonfree_it;
|
||||
}
|
||||
|
||||
if (best_gap.lo() == 0xFFFF)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue