[Mesa-dev] [PATCH 1/4] Revert "glsl: Skip processing the first function's body in do_dead_functions()."

Ian Romanick idr at freedesktop.org
Tue Aug 2 18:11:01 PDT 2011


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/02/2011 11:41 AM, Paul Berry wrote:
> On 1 August 2011 22:16, Paul Berry <stereotype441 at gmail.com> wrote:
>>
>> I will investigate things further in the morning and let you know what I find.
>>
> 
> Ok, I've spent a while looking through the linker code, and the rabbit
> hole goes deeper than I expected.  There are a number of reasons why
> the linker, as currently implemented, isn't guaranteed to be produce
> topologically sorted output:
> 
> 1. Linking doesn't actually start with an empty shader.  It starts
> with a clone of the compilation unit that defines main() (see
> linker.cpp around line 836).  This means that the order of functions
> defined in that compilation unit will be preserved regardless of the
> call graph.
> 
> 2. When resolving a function that's declared in the compilation unit
> that defines main(), but defined in some other compilation unit, the
> linker inserts the IR for that function wherever the declaration
> existed.  This means that the order of functions _declared_ in the
> compilation unit that defines main will be preserved too.
> 
> Problems 1 and 2 could be addressed by not cloning the IR for the
> compilation unit containing main, and instead using the algorithm you
> described.  But even if we did that, there's an additional problem:
> 
> 3. Linking is performed depth first.  This means that if main calls f
> which calls h, and main also calls g which calls h, then the linker
> first tries to pull in f, then h, and then finally g.  Since the
> linker emits functions at the head of the final linked program, the
> final order (assuming problems 1 and 2 are fixed) would be g, h, f,
> main.  This is the wrong order because g calls h.
> 
> This problem could be addressed by making the linker operate breadth
> first instead of depth first.  But even if we did that, there's still
> another problem:
> 
> 4. Since the linker emits functions at the head of the final linked
> program, if the linker brings in a function (let's call it f()) that
> wasn't declared in the compilation unit that defined main, it winds up
> at the beginning of the linked output, _before_ any global
> declarations.  If f() refers to a global variable, then the IR is
> invalid, because ir_dereference_variable nodes need to occur _after_
> the variables they declare (see ir_validate.cpp line 96).

It seems like it would be worth constructing a test case for this.  A
piglit test would be preferable.  If that's not possible, a unit test
would do.

There was a similar issue long, long ago, but I believe that it was
fixed.  I don't recall the details.

> This problem could be addressed by having the linker emit functions at
> the tail of the final linked program rather than at the head, but that
> would defeat the effort to make callees appear before their callers in
> the linker output.
> 
> There's one final problem, and this to me is the clincher:
> 
> 5. Since our IR groups together all overloaded functions that share
> the same name, there are (admittedly contrived) cases that would be
> impossible to topologically sort.  For example: if main calls f(int)
> which calls g(int), and main also calls g(float) which calls f(float),
> this is a valid program (there's no static recursion), but there's no
> way to order f and g such that callees come before their respective
> callers.
> 
> We could only address this problem by changing our IR format, or
> dropping the topological sort requirement.
> 
> In light of everything I've discovered this morning, my recommendation
> is to drop the topological sort requirement.  I haven't been able to
> find any code other than opt_dead_functions that relies on functions
> being topologically sorted, so unless I'm missing something, dropping
> the requirement is a simple matter of committing this patch.
> 
> In addition, I think we should change link_functions.cpp so that it
> emits functions at the tail of the final linked program rather than at
> the head, to fix problem #4.
> 
> Does this analysis seem right to you, Ian?

Paul, you continue to impress me.  Yeah, that all sounds right.  I had a
hard time believing #1 because I really thought I had implemented the
algorithm from my previous post.  Of course, the code and commit logs
don't lie.  I had thought of #5 shortly after hitting send, but I
decided it was too contrived to post a follow-up.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAk44oCUACgkQX1gOwKyEAw/TbgCfWTFDif+gDJmIwB1uCNn8U92k
a6sAn1BYZeJg3ZZE2B2aH2/3HO/sT2tf
=eLx4
-----END PGP SIGNATURE-----


More information about the mesa-dev mailing list