[Mesa-dev] [PATCH 06/11] glsl: Refactor logic for determining whether to lower return statements.

Kenneth Graunke kenneth at whitecape.org
Thu Jul 7 10:53:24 PDT 2011

On 07/07/2011 09:56 AM, Paul Berry wrote:
> On 7 July 2011 01:16, Kenneth Graunke <kenneth at whitecape.org> wrote:
>> What exactly is the difference between lowering returns in "main" and
>> lowering them in other subroutines?  void vs. non-void is definitely
>> different, but I don't see why main is special.  Looking at the code, it
>> doesn't actually seem to use lower_main_return anywhere...
> There's no difference in how returns are lowered in "main" and in
> subroutines.  The difference is in whether or not we lower returns.
> For instance, when _mesa_ir_link_shader() calls do_lower_jumps(), it
> always asks it to lower returns in subroutines (presumably to
> facilitate inlining), but it only asks it to lower returns in main if
> options->EmitNoMainReturn is true.

You're right of course, sorry...I somehow missed that
lower_main_return/lower_sub_return were options to the lowering pass.

I didn't realize that lower_jumps was needed for inlining (though it
sure makes sense).  opt_function_inlining.cpp has its own code for
this---the "replace_return_with_assignment" function.  Looking at that
again, it's fairly limited...it doesn't do any guarding in the case of
conditional returns...so it's really only useful for replacing the
canonical jump at the end of a non-void function.

Yet, we're using visit_tree with replace_return_with_assignment.  I
believe that this means we're actually walking over the whole IR tree
for the function (including all the expression trees!) looking for
returns.  That seems wasteful---if we're using lower_jumps, we know
exactly where it is...it's the last instruction.

Furthermore, I think can_inline probably ought to be altered.  Right now
it returns true if there's only one "return".  But it doesn't seem to be
checking that it's the _canonical_ return.

Without lower_jumps, I think the following code would be incorrectly

uniform bool b;
float foo() {
    if (b)
        return 0.0;
    gl_FragColor = vec4(1, 0, 0, 1);
    return 1.0;

IOW, opt_function_inlining has broken code, but we're not seeing any
ill-effects because we run lower_jumps first, which fixes things.  We
should probably make that dependency explicitly clear.

More information about the mesa-dev mailing list