[Mesa-dev] [PATCH] i965/fs: Add pass to rename registers to break live ranges.

Matt Turner mattst88 at gmail.com
Mon Apr 14 15:01:37 PDT 2014


From: Kenneth Graunke <kenneth at whitecape.org>

The pass breaks live ranges of virtual registers by allocating new
registers when it sees an assignment to a virtual GRF it's already seen
written.

total instructions in shared programs: 1656292 -> 1651898 (-0.27%)
instructions in affected programs:     466836 -> 462442 (-0.94%)
GAINED:                                173
LOST:                                  3
---
[mattst88]: Perform renaming at control flow level 0, rather than bailing
            at first sight of control flow.

 src/mesa/drivers/dri/i965/brw_fs.cpp | 56 ++++++++++++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/brw_fs.h   |  1 +
 2 files changed, 57 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index dbce167..aa957cc 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -2076,6 +2076,61 @@ fs_visitor::opt_algebraic()
 }
 
 bool
+fs_visitor::opt_register_renaming()
+{
+   bool progress = false;
+   int depth = 0;
+
+   int remap[virtual_grf_count];
+   memset(remap, -1, sizeof(int) * virtual_grf_count);
+
+   foreach_list(node, &this->instructions) {
+      fs_inst *inst = (fs_inst *) node;
+
+      if (inst->opcode == BRW_OPCODE_IF || inst->opcode == BRW_OPCODE_DO) {
+         depth++;
+      } else if (inst->opcode == BRW_OPCODE_ENDIF ||
+                 inst->opcode == BRW_OPCODE_WHILE) {
+         depth--;
+      }
+
+      /* Rewrite instruction sources. */
+      for (int i = 0; i < 3; i++) {
+         if (inst->src[i].file == GRF &&
+             remap[inst->src[i].reg] != -1 &&
+             remap[inst->src[i].reg] != inst->src[i].reg) {
+            inst->src[i].reg = remap[inst->src[i].reg];
+            progress = true;
+         }
+      }
+
+      int dst = inst->dst.reg;
+
+      if (depth == 0 &&
+          inst->dst.file == GRF &&
+          virtual_grf_sizes[inst->dst.reg] == 1 &&
+          !inst->is_partial_write()) {
+         if (remap[dst] == -1) {
+            remap[dst] = dst;
+         } else {
+            remap[dst] = virtual_grf_alloc(virtual_grf_sizes[dst]);
+            inst->dst.reg = remap[dst];
+            progress = true;
+         }
+      } else if (inst->dst.file == GRF &&
+                 remap[dst] != -1 &&
+                 remap[dst] != dst) {
+         inst->dst.reg = remap[dst];
+         progress = true;
+      }
+   }
+
+   invalidate_live_intervals();
+
+   return progress;
+}
+
+bool
 fs_visitor::compute_to_mrf()
 {
    bool progress = false;
@@ -3031,6 +3086,7 @@ fs_visitor::run()
          progress = opt_peephole_sel() || progress;
          progress = dead_control_flow_eliminate(this) || progress;
          progress = opt_saturate_propagation() || progress;
+         progress = opt_register_renaming() || progress;
          progress = register_coalesce() || progress;
 	 progress = compute_to_mrf() || progress;
       } while (progress);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index acf6a11..3f368c2 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -371,6 +371,7 @@ public:
    bool opt_copy_propagate_local(void *mem_ctx, bblock_t *block,
                                  exec_list *acp);
    void opt_drop_redundant_mov_to_flags();
+   bool opt_split_live_ranges();
    bool register_coalesce();
    bool compute_to_mrf();
    bool dead_code_eliminate();
-- 
1.8.3.2



More information about the mesa-dev mailing list