Mesa (master): aco/ra: Use std::find_if(_not) to clean up get_reg_simple

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jan 13 18:31:39 UTC 2021


Module: Mesa
Branch: master
Commit: 2b3b2f7ff5b6883be78b38b55e6cf19de0914106
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2b3b2f7ff5b6883be78b38b55e6cf19de0914106

Author: Tony Wasserka <tony.wasserka at gmx.de>
Date:   Wed Oct 28 20:00:18 2020 +0100

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 at schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7799>

---

 src/amd/compiler/aco_register_allocation.cpp | 44 +++++++++++++++-------------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp
index 2992010b00a..e54369749e6 100644
--- a/src/amd/compiler/aco_register_allocation.cpp
+++ b/src/amd/compiler/aco_register_allocation.cpp
@@ -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)



More information about the mesa-commit mailing list