summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2014-04-14 15:01:37 -0700
committerMatt Turner <mattst88@gmail.com>2014-08-14 23:50:12 -0700
commit35ca28816509a887538a6d0c62c96279b38ef8e4 (patch)
treeccd08b02cfead74fd6e1745d003eceeaf3d7fdef
parent650c3313786cab6f96bb480685e7b32dfcb9291c (diff)
i965/fs: Add pass to rename registers to break live ranges.
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: 4337879 -> 4335014 (-0.07%) instructions in affected programs: 343865 -> 341000 (-0.83%) GAINED: 46 LOST: 1 [mattst88]: Make pass not break in presence of control flow. invalidate_live_intervals() only if progress. Fix up delta_x/delta_y. Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp67
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
2 files changed, 68 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 43aee66f410..ed7a0bce8ca 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -2056,6 +2056,72 @@ 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_in_list(fs_inst, inst, &this->instructions) {
+ 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 < inst->sources; 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;
+ }
+ }
+
+ const 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(1);
+ 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;
+ }
+ }
+
+ if (progress) {
+ invalidate_live_intervals();
+
+ for (unsigned i = 0; i < ARRAY_SIZE(delta_x); i++) {
+ if (delta_x[i].file == GRF && remap[delta_x[i].reg] != -1) {
+ delta_x[i].reg = remap[delta_x[i].reg];
+ }
+ }
+ for (unsigned i = 0; i < ARRAY_SIZE(delta_y); i++) {
+ if (delta_y[i].file == GRF && remap[delta_y[i].reg] != -1) {
+ delta_y[i].reg = remap[delta_y[i].reg];
+ }
+ }
+ }
+
+ return progress;
+}
+
+bool
fs_visitor::compute_to_mrf()
{
bool progress = false;
@@ -3080,6 +3146,7 @@ fs_visitor::run()
OPT(dead_code_eliminate);
OPT(opt_peephole_sel);
OPT(dead_control_flow_eliminate, this);
+ OPT(opt_register_renaming);
OPT(opt_saturate_propagation);
OPT(register_coalesce);
OPT(compute_to_mrf);
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index a838e74d8b6..5aa0ca661fe 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -339,6 +339,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_register_renaming();
bool register_coalesce();
bool compute_to_mrf();
bool dead_code_eliminate();