From: Tony Wasserka Date: Wed, 28 Oct 2020 18:39:03 +0000 (+0100) Subject: aco/ra: Add iterator interface for PhysRegInterval X-Git-Tag: upstream/21.2.3~9562 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ebdb362937a2a038aba2e86b43dd0a1fa60c5202;p=platform%2Fupstream%2Fmesa.git aco/ra: Add iterator interface for PhysRegInterval This enables various loops to use range-based for. Reviewed-by: Daniel Schürmann Part-of: --- diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 6bc8e07..2992010 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -92,6 +92,39 @@ struct ra_ctx { } }; +/* Iterator type for making PhysRegInterval compatible with range-based for */ +struct PhysRegIterator { + using difference_type = int; + using value_type = unsigned; + using reference = const unsigned&; + using pointer = const unsigned*; + using iterator_category = std::bidirectional_iterator_tag; + + unsigned reg; + + unsigned operator*() const { + return reg; + } + + PhysRegIterator& operator++() { + reg++; + return *this; + } + + PhysRegIterator& operator--() { + reg--; + return *this; + } + + 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 */ struct PhysRegInterval { unsigned lo_; @@ -120,6 +153,14 @@ struct PhysRegInterval { static PhysRegInterval from_until(unsigned first, unsigned end) { return { first, end - first }; } + + PhysRegIterator begin() const { + return { lo_ }; + } + + PhysRegIterator end() const { + return { lo_ + size }; + } }; struct DefInfo { @@ -686,7 +727,7 @@ std::pair get_reg_simple(ra_ctx& ctx, PhysRegInterval best_gap { 0xFFFF, 0xFFFF }; unsigned last_pos = 0xFFFF; - for (unsigned current_reg = bounds.lo(); current_reg < bounds.hi(); current_reg++) { + 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; @@ -906,7 +947,7 @@ bool get_regs_for_copies(ra_ctx& ctx, unsigned n = 0; unsigned last_var = 0; bool found = true; - for (unsigned j = reg_win.lo(); found && j < reg_win.hi(); j++) { + for (const unsigned j : reg_win) { if (reg_file[j] == 0 || reg_file[j] == last_var) continue; @@ -1046,7 +1087,7 @@ std::pair get_reg_impl(ra_ctx& ctx, unsigned last_var = 0; bool found = true; bool aligned = rc == RegClass::v4 && reg_win.lo() % 4 == 0; - for (unsigned j = reg_win.lo(); j < reg_win.hi(); j++) { + for (const unsigned j : reg_win) { /* dead operands effectively reduce the number of estimated moves */ if (is_killed_operand[j & 0xFF]) { if (remaining_op_moves) { @@ -1359,7 +1400,11 @@ PhysReg get_reg_create_vector(ra_ctx& ctx, /* count variables to be moved and check war_hint */ bool war_hint = false; bool linear_vgpr = false; - for (unsigned j = reg_win.lo(); j < reg_win.hi() && !linear_vgpr; j++) { + for (unsigned j : reg_win) { + if (linear_vgpr) { + break; + } + if (reg_file[j] != 0) { if (reg_file[j] == 0xF0000000) { PhysReg reg;