[Mesa-dev] [PATCH 3/9] glsl: Skip function inlining until we've seen another function defined.

Ian Romanick idr at freedesktop.org
Mon Mar 14 14:25:45 PDT 2011


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

After working on bug #34203, which turned out to now be inlining
related, I had some ideas about the inliner.  Right now the inliner
proceeds in the order that it encounters functions in the IR.  This
results in a number of issues including the OOM failure triggered by
Luca's glsl-fs-inline-explosion.

I think we will also explode if the shader happens to include recursion.

I was thinking of changing to a simple flow-graph directed approach.  I
was thinking of three passes.  The first pass identifies all functions
that can be reached from main.  In the process, it tracks where each
function is called.  This is sort of a ud-chain for functions.  This
pass can also easily detect recursion and generate link errors.

The second repeatedly inlines each inlineable leaf node at all places
where it's called.  This may cause the caller to become a leaf.  Once a
leaf is fully inlined, it is removed from the reachable set.

The third pass removes all functions that are no longer reachable from main.

We can short circuit this be added a flag to linked shaders to indicate
whether or not main includes any function calls.

On 03/11/2011 04:06 PM, Eric Anholt wrote:
> ---
>  src/glsl/opt_function_inlining.cpp |   23 +++++++++++++++++++++--
>  1 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/src/glsl/opt_function_inlining.cpp b/src/glsl/opt_function_inlining.cpp
> index 8fef358..3f63b8d 100644
> --- a/src/glsl/opt_function_inlining.cpp
> +++ b/src/glsl/opt_function_inlining.cpp
> @@ -45,6 +45,7 @@ public:
>     ir_function_inlining_visitor()
>     {
>        progress = false;
> +      seen_another_function_signature = false;
>     }
>  
>     virtual ~ir_function_inlining_visitor()
> @@ -58,7 +59,9 @@ public:
>     virtual ir_visitor_status visit_enter(ir_return *);
>     virtual ir_visitor_status visit_enter(ir_texture *);
>     virtual ir_visitor_status visit_enter(ir_swizzle *);
> +   virtual ir_visitor_status visit_enter(ir_function_signature *);
>  
> +   bool seen_another_function_signature;
>     bool progress;
>  };
>  
> @@ -79,8 +82,6 @@ do_function_inlining(exec_list *instructions)
>  {
>     ir_function_inlining_visitor v;
>  
> -   do_expression_flattening(instructions, automatic_inlining_predicate);
> -
>     v.run(instructions);
>  
>     return v.progress;
> @@ -246,6 +247,24 @@ ir_call::generate_inline(ir_instruction *next_ir)
>        return NULL;
>  }
>  
> +/* Since a function call can only appear to an already-prototyped (at
> + * least) function signature, we can skip all the work of inlining
> + * detection on the first function signature present.  Usually shaders
> + * end up with a single function call, so this almost entirely removes
> + * this pass from profiles.
> + */
> +ir_visitor_status
> +ir_function_inlining_visitor::visit_enter(ir_function_signature *ir)
> +{
> +   if (!this->seen_another_function_signature) {
> +      this->seen_another_function_signature = true;
> +      return visit_continue_with_parent;
> +   } else {
> +      do_expression_flattening(&ir->body, automatic_inlining_predicate);
> +
> +      return visit_continue;
> +   }
> +}
>  
>  ir_visitor_status
>  ir_function_inlining_visitor::visit_enter(ir_expression *ir)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAk1+h9kACgkQX1gOwKyEAw9rkQCfShPOnpRne4FcM3Az2QDNX6KW
SuEAn0fhoHt5TkIWvpdo7TRMGbYOEE0N
=tjpl
-----END PGP SIGNATURE-----


More information about the mesa-dev mailing list