aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErico Nunes <[email protected]>2020-01-20 01:33:07 +0100
committerErico Nunes <[email protected]>2020-01-25 14:48:02 +0100
commitd6b1917c01765b21180ebecb4ca9aa80746ef560 (patch)
treea9b16667cbca84ebbe20ad17db300e67528b38e7
parenteb7cd575da02f3ae60d05112ca86ce6c2cd27e3c (diff)
lima/ppir: handle write to dead registers in ppir
nir can output writes to dead registers when expanding vec4 operations to non-ssa registers. In that case, some components of the vec4 may be assigned but never read. These are also not currently removed by a nir dead code elimination pass as they are not ssa. In order to prevent regalloc from allocating a live register for this operation, an interference must be assigned to it during liveness analysis. This workaround may be removed in the future if the assignments to dead components can be removed earlier in ppir or nir. Signed-off-by: Erico Nunes <[email protected]> Reviewed-by: Vasily Khoruzhick <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3502>
-rw-r--r--.gitlab-ci/deqp-lima-fails.txt1
-rw-r--r--src/gallium/drivers/lima/ir/pp/liveness.c17
2 files changed, 12 insertions, 6 deletions
diff --git a/.gitlab-ci/deqp-lima-fails.txt b/.gitlab-ci/deqp-lima-fails.txt
index 3f88017c6c1..c298e8b7f44 100644
--- a/.gitlab-ci/deqp-lima-fails.txt
+++ b/.gitlab-ci/deqp-lima-fails.txt
@@ -184,7 +184,6 @@ dEQP-GLES2.functional.shaders.random.exponential.fragment.37
dEQP-GLES2.functional.shaders.random.exponential.fragment.5
dEQP-GLES2.functional.shaders.random.exponential.fragment.74
dEQP-GLES2.functional.shaders.random.texture.fragment.28
-dEQP-GLES2.functional.shaders.random.texture.fragment.106
dEQP-GLES2.functional.shaders.random.trigonometric.fragment.1
dEQP-GLES2.functional.shaders.random.trigonometric.fragment.65
dEQP-GLES2.functional.shaders.random.trigonometric.fragment.69
diff --git a/src/gallium/drivers/lima/ir/pp/liveness.c b/src/gallium/drivers/lima/ir/pp/liveness.c
index 26840256753..1bc1dc812c6 100644
--- a/src/gallium/drivers/lima/ir/pp/liveness.c
+++ b/src/gallium/drivers/lima/ir/pp/liveness.c
@@ -194,9 +194,17 @@ ppir_liveness_instr_dest(ppir_compiler *comp, ppir_instr *instr)
struct set_entry *live = _mesa_set_search(instr->live_in_set,
&instr->live_in[reg->regalloc_index]);
+
+ /* If a register is written but wasn't read in a later instruction, it is
+ * either dead code or a bug. For now, assign an interference to it to
+ * ensure it doesn't get assigned a live register and overwrites it. */
+ if (!live) {
+ instr->live_out[reg->regalloc_index].reg = reg;
+ _mesa_set_add(instr->live_out_set, &instr->live_out[reg->regalloc_index]);
+ continue;
+ }
+
if (dest->type == ppir_target_ssa) {
- if (!live)
- continue;
/* reg is written and ssa, is not live before instr */
_mesa_set_remove_key(instr->live_in_set, &instr->live_in[reg->regalloc_index]);
}
@@ -204,9 +212,8 @@ ppir_liveness_instr_dest(ppir_compiler *comp, ppir_instr *instr)
unsigned int mask = ppir_src_get_mask(node);
/* written reg is type register, need to check if this clears
* the remaining mask to remove it from the live set */
- if (!live ||
- instr->live_in[reg->regalloc_index].mask ==
- (instr->live_in[reg->regalloc_index].mask & ~mask))
+ if (instr->live_in[reg->regalloc_index].mask ==
+ (instr->live_in[reg->regalloc_index].mask & ~mask))
continue;
instr->live_in[reg->regalloc_index].mask &= ~mask;