[Mesa-dev] [PATCH 2/2] prog_optimize: Add reads without writes optimization pass
Tom Stellard
tstellar at gmail.com
Wed Mar 30 21:34:49 PDT 2011
On Wed, Mar 30, 2011 at 10:09:58AM -0700, Ian Romanick wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 03/29/2011 08:27 PM, Tom Stellard wrote:
> >
> > The reason there are reads of undefined values is because of all the
> > conditional assignments generated by the IF to conditional assignment
> > lowering pass. ir_to_mesa transforms conditional assignments to
> > CMP DST, COND SRC0 DST, with the assumption that if the condition fails
> > assigning DST to itself will be a noop. This is normally a safe assumption
> > to make since all bug-free programs should initialize a value before using
> > it in a conditional assignment, if the value is going to be used later
> > in the program.
> >
> > However, the conditional assignments that are generated by the IF
> > lowering pass don't follow this pattern and the DST register is usually
> > uninitialized when the instruction is executed, leading to a read from
> > an undefined value.
>
> Ah, that makes sense. It would probably be good to replace the examples
> in the current header comment with one of these cases.
>
> > It seems like the real problem is that there is no good way to translate
> > a GLSL IR conditional assignment to a MESA IR instruction. From what
> > I can tell, the semantics of conditional assignment are:
> > if (cond)
> > assign value
> > else
> > do nothing;
>
> Correct.
>
> > and the closest equivalent Mesa IR instruction (CMP) is:
> > if (cond)
> > assign value0
> > else
> > assign value1
> >
> > Since this is only an issue on architectures that don't support flow
> > control, I should modify my patch so the 'reads without writes' pass
> > only runs on architectures that don't support flow control. I'm also
> > interested in hearing alternate solutions if anyone has other ideas,
> > because I would really like to get this fixed.
>
> It seems like there are two possible cases, and this doesn't really fix
> either of them.
>
> Case 1:
>
> if (cond)
> x = y;
>
> This gets lowered to a conditional move to x. If there is no 'else',
> why do a conditional move at all? In this case, replace the CMP (which
> may be lowered to as many as 3 instructions in some vertex shaders) with
> a MOV.
>
> If x is used when cond is false before another assignment to x, the
> result is undefined. Reading y qualifies as much as reading 0s. Right? :)
>
> Case 2:
>
> if (cond)
> x = y;
> else
> x = z;
>
> In this case we end up with two CMP instructions. The first of the CMP
> instructions will be potentially read from an uninitialized source.
>
> CMP x, cond, y, x;
> CMP x, cond, x, z;
>
> In this case, the two CMP instructions should be fused into a single CMP.
>
> CMP x, cond, y, z;
>
> Now that I think about it, the way the copy propagation works,
> converting the first CMP to a MOV will make this happen automatically.
>
> CMP x, cond, y, x;
> CMP x, cond, x, z;
>
> becomes
>
> MOV x, y;
> CMP x, cond, x, z;
>
> becomes
>
> MOV x, y;
> CMP x, cond, y, z;
>
> becomes
>
> CMP x, cond, y, z;
Ok, this makes sense. It would be pretty easy to modify my original patch
to do this, but maybe it's better change the way ir_to_mesa.cpp converts
conditional assignments to Mesa IR. Do you have any suggestions for how
to determine if the left hand side of an ir_assignment has already been
written to?
-Tom
More information about the mesa-dev
mailing list