lima/ppir: handle write to dead registers in ppir
authorErico Nunes <nunes.erico@gmail.com>
Mon, 20 Jan 2020 00:33:07 +0000 (01:33 +0100)
committerErico Nunes <nunes.erico@gmail.com>
Sat, 25 Jan 2020 13:48:02 +0000 (14:48 +0100)
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 <nunes.erico@gmail.com>
Reviewed-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3502>

.gitlab-ci/deqp-lima-fails.txt
src/gallium/drivers/lima/ir/pp/liveness.c

index 3f88017c6c19f6db8f0ab0cf78ad1a914621e969..c298e8b7f44171d06dd5dac122cfe662a2a555b3 100644 (file)
@@ -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
index 2684025675323ff7c898c9589440d2015467be94..1bc1dc812c6fe9ba7fd25607e7fd016e8e9b4a40 100644 (file)
@@ -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;