[Mesa-dev] [PATCH 2/2] prog_optimize: Add reads without writes optimization pass
Ian Romanick
idr at freedesktop.org
Wed Mar 30 10:09:58 PDT 2011
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 03/29/2011 08:27 PM, Tom Stellard wrote:
> On Tue, Mar 29, 2011 at 02:16:39PM -0700, Eric Anholt wrote:
>
>> On Tue, 29 Mar 2011 11:35:33 -0700, Tom Stellard <tstellar at gmail.com> wrote:
>>> On Tue, Mar 29, 2011 at 10:19:13AM -0700, Eric Anholt wrote:
>>>> On Mon, 28 Mar 2011 22:59:31 -0700, Tom Stellard <tstellar at gmail.com> wrote:
>>>>> This pass scans programs for instructions that read registers that have
>>>>> not been written and replaces these reads with a read from a constant
>>>>> register with the value of zero. This pass prevents phantom
>>>>> dependencies from being introduced by the register allocator and
>>>>> improves the efficiency of subsequent optimization passes.
>>>>
>>>> I'm not sure why optimizing a program with undefined behavior (using
>>>> undefined register values) is interesting. It just seems like an
>>>> opportunity to make a mistake and break programs that should have
>>>> defined behavior.
>>>
>>> The main problem I am trying to fix with this is that these reads
>>> from undefined register values are causing the Mesa IR register allocator
>>> to alter the structure of the program by adding dependencies between
>>> instructions that should not be there. This is limiting the number of
>>> optimization opportunities that are available to drivers, especially
>>> on architectures like r300 that need IFs lowered and thus use a lot of
>>> CMP instructions.
>>
>> Why do you have programs reading undefined values? Why are these
>> programs interesting?
>
> 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;
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk2TY+YACgkQX1gOwKyEAw8wAgCeM+GU/Ums9WeTTzvaGpimGasK
WKEAnjhmoWClU4Gg6rzopczOf1v82gAS
=yBOF
-----END PGP SIGNATURE-----
More information about the mesa-dev
mailing list