diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 74cc9cefb6d..da31b3e5eb9 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -2063,11 +2063,16 @@ fs_visitor::register_coalesce_2() inst->src[0].smear != -1 || inst->dst.file != GRF || inst->dst.type != inst->src[0].type || - virtual_grf_sizes[inst->src[0].reg] != 1 || - virtual_grf_interferes(inst->dst.reg, inst->src[0].reg)) { + virtual_grf_sizes[inst->src[0].reg] != 1) { continue; } + int var_from = live_intervals->var_from_reg(&inst->src[0]); + int var_to = live_intervals->var_from_reg(&inst->dst); + + if (live_intervals->vars_interfere(var_from, var_to)) + continue; + int reg_from = inst->src[0].reg; assert(inst->src[0].reg_offset == 0); int reg_to = inst->dst.reg; @@ -2091,31 +2096,13 @@ fs_visitor::register_coalesce_2() } inst->remove(); - - /* We don't need to recalculate live intervals inside the loop despite - * invalidating them; we only use them for the interferes test, and we - * must have had a situation where the intervals were: - * - * from to - * ^ - * | - * v - * ^ - * | - * v - * - * Some register R that might get coalesced with one of these two could - * only be referencing "to", otherwise "from"'s range would have been - * longer. R's range could also only start at the end of "to" or later, - * otherwise it will conflict with "to" when we try to coalesce "to" - * into Rw anyway. - */ - invalidate_live_intervals(); - progress = true; continue; } + if (progress) + invalidate_live_intervals(); + return progress; } diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp index 41176c74236..50aa7a62ae3 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp @@ -244,6 +244,12 @@ fs_live_variables::compute_start_end() } } +int +fs_live_variables::var_from_reg(fs_reg *reg) +{ + return var_from_vgrf[reg->reg] + reg->reg_offset; +} + fs_live_variables::fs_live_variables(fs_visitor *v, cfg_t *cfg) : v(v), cfg(cfg) { @@ -334,6 +340,13 @@ fs_visitor::calculate_live_intervals() } } +bool +fs_live_variables::vars_interfere(int a, int b) +{ + return !(end[b] <= start[a] || + end[a] <= start[b]); +} + bool fs_visitor::virtual_grf_interferes(int a, int b) { diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h index fa14eecd897..82575d8287f 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h +++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h @@ -66,6 +66,9 @@ public: void compute_live_variables(); void compute_start_end(); + bool vars_interfere(int a, int b); + int var_from_reg(fs_reg *reg); + fs_visitor *v; cfg_t *cfg; void *mem_ctx;