broadcom/compiler: do not DCE ldunifa
authorIago Toral Quiroga <itoral@igalia.com>
Thu, 11 Feb 2021 11:18:38 +0000 (12:18 +0100)
committerMarge Bot <eric+marge@anholt.net>
Fri, 12 Feb 2021 08:24:21 +0000 (08:24 +0000)
ldunifa reads a uniform from the unifa address and updates the unifa
address implicitly, so if we dead-code-eliminate one a follow-up
ldunifa will not read from the appropriate address.

We could avoid this if the compiler ensures that every ldunifa is
paired with an explicit unifa, so for example if we are reading a
vec4, we could emit:

unifa (addrr)
ldunifa
unifa (addr+4)
ldunifa
unifa (addr+8)
ldunifa
unifa (addr+12)
ldunifa

instead of:

unifa (addr)
ldunifa
ldunifa
ldunifa
ldunifa

But since each unifa has a 3 delay slot before we can do ldunifa,
that would end up being quite expensive.

Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8980>

src/broadcom/compiler/vir.c

index 6c79b2d..a3db921 100644 (file)
@@ -84,6 +84,17 @@ vir_has_side_effects(struct v3d_compile *c, struct qinst *inst)
                 return true;
         }
 
+        /* ldunifa works like ldunif: it reads an element and advances the
+         * pointer, so each read has a side effect (we don't care for ldunif
+         * because we reconstruct the uniform stream buffer after compiling
+         * with the surviving uniforms), so allowing DCE to remove
+         * one would break follow-up loads. We could fix this by emiting a
+         * unifa for each ldunifa, but each unifa requires 3 delay slots
+         * before a ldunifa, so that would be quite expensive.
+         */
+        if (inst->qpu.sig.ldunifa || inst->qpu.sig.ldunifarf)
+                return true;
+
         return false;
 }