summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2014-03-27 10:15:19 -0700
committerMatt Turner <mattst88@gmail.com>2014-04-07 10:29:22 -0700
commit99437b730f53dfa5d74f601415d8e2b66b68a3fd (patch)
tree91c4156ab751f3381b7b150344b80babbb6721bc /src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp
parent70285f607ce2a0680c3e51b3717fed6a8dd19e72 (diff)
downloadexternal_mesa3d-99437b730f53dfa5d74f601415d8e2b66b68a3fd.zip
external_mesa3d-99437b730f53dfa5d74f601415d8e2b66b68a3fd.tar.gz
external_mesa3d-99437b730f53dfa5d74f601415d8e2b66b68a3fd.tar.bz2
i965/fs: Check for interference after finding all channels.
It's more likely that we won't find writes to all channels than one will interfere, and calculating interference is more expensive. This change will also help prepare for coalescing load_payload instructions' operands. Also update the live intervals for all channels, and not just the last that we saw. Reviewed-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp b/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp
index 5c16798..c71fd47 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_register_coalesce.cpp
@@ -122,6 +122,8 @@ fs_visitor::register_coalesce()
int reg_from = -1, reg_to = -1;
int reg_to_offset[MAX_SAMPLER_MESSAGE_SIZE];
fs_inst *mov[MAX_SAMPLER_MESSAGE_SIZE];
+ int var_to[MAX_SAMPLER_MESSAGE_SIZE];
+ int var_from[MAX_SAMPLER_MESSAGE_SIZE];
foreach_list(node, &this->instructions) {
fs_inst *inst = (fs_inst *)node;
@@ -129,12 +131,6 @@ fs_visitor::register_coalesce()
if (!is_coalesce_candidate(inst, virtual_grf_sizes))
continue;
- int var_from = live_intervals->var_from_reg(&inst->src[0]);
- int var_to = live_intervals->var_from_reg(&inst->dst);
-
- if (!can_coalesce_vars(live_intervals, &instructions, inst, var_to, var_from))
- continue;
-
if (reg_from != inst->src[0].reg) {
reg_from = inst->src[0].reg;
@@ -158,6 +154,21 @@ fs_visitor::register_coalesce()
if (channels_remaining)
continue;
+ bool can_coalesce = true;
+ for (int i = 0; i < src_size; i++) {
+ var_to[i] = live_intervals->var_from_vgrf[reg_to] + reg_to_offset[i];
+ var_from[i] = live_intervals->var_from_vgrf[reg_from] + i;
+
+ if (!can_coalesce_vars(live_intervals, &instructions, inst,
+ var_to[i], var_from[i])) {
+ can_coalesce = false;
+ break;
+ }
+ }
+
+ if (!can_coalesce)
+ continue;
+
bool removed = false;
for (int i = 0; i < src_size; i++) {
if (mov[i]) {
@@ -196,11 +207,15 @@ fs_visitor::register_coalesce()
}
if (removed) {
- live_intervals->start[var_to] = MIN2(live_intervals->start[var_to],
- live_intervals->start[var_from]);
- live_intervals->end[var_to] = MAX2(live_intervals->end[var_to],
- live_intervals->end[var_from]);
- reg_from = -1;
+ for (int i = 0; i < src_size; i++) {
+ live_intervals->start[var_to[i]] =
+ MIN2(live_intervals->start[var_to[i]],
+ live_intervals->start[var_from[i]]);
+ live_intervals->end[var_to[i]] =
+ MAX2(live_intervals->end[var_to[i]],
+ live_intervals->end[var_from[i]]);
+ reg_from = -1;
+ }
}
}