[Mesa-dev] [PATCH 2/4] glsl: Emit function signatures at toplevel, even for built-ins.
Ian Romanick
idr at freedesktop.org
Mon Aug 1 18:08:09 PDT 2011
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 08/01/2011 04:07 PM, Paul Berry wrote:
> The ast-to-hir conversion needs to emit function signatures in two
> circumstances: when a function declaration (or definition) is
> encountered, and when a built-in function is encountered.
>
> To avoid emitting a function signature in an illegal place (such as
> inside a function), emit_function() checked whether we were inside a
> function definition, and if so, emitted the signature before the
> function definition.
>
> However, this didn't cover the case of emitting function signatures
> for built-in functions when those built-in functions are called from
> global scope (e.g. a built-in function called from inside the constant
> integer expression that specifies the length of an array).
>
> This patch changes emit_function() so that it emits function
> signatures at toplevel in all cases.
There's something about this patch that I don't grok. The
state->current_function test in emit function exists specifically to
handle calls to functions (built-in or otherwise) at global scope.
Without that, code such as the snippet below would not work, and text in
the commit log seems to indicate that it shouldn't work. However, I
verified that it does.
#version 120
const float x = cos(3.14159 / 2.0);
> ---
> src/glsl/ast.h | 3 +--
> src/glsl/ast_function.cpp | 2 +-
> src/glsl/ast_to_hir.cpp | 31 ++++++++++++++-----------------
> src/glsl/glsl_parser_extras.h | 6 ++++++
> 4 files changed, 22 insertions(+), 20 deletions(-)
>
> diff --git a/src/glsl/ast.h b/src/glsl/ast.h
> index 878f48b..d1de227 100644
> --- a/src/glsl/ast.h
> +++ b/src/glsl/ast.h
> @@ -730,7 +730,6 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
> struct _mesa_glsl_parse_state *state);
>
> void
> -emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
> - ir_function *f);
> +emit_function(_mesa_glsl_parse_state *state, ir_function *f);
>
> #endif /* AST_H */
> diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
> index 8bcf48d..34a82f8 100644
> --- a/src/glsl/ast_function.cpp
> +++ b/src/glsl/ast_function.cpp
> @@ -125,7 +125,7 @@ match_function_by_name(exec_list *instructions, const char *name,
> if (f == NULL) {
> f = new(ctx) ir_function(name);
> state->symbols->add_global_function(f);
> - emit_function(state, instructions, f);
> + emit_function(state, f);
> }
>
> f->add_signature(sig->clone_prototype(f, NULL));
> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
> index c0524bf..c1f160e 100644
> --- a/src/glsl/ast_to_hir.cpp
> +++ b/src/glsl/ast_to_hir.cpp
> @@ -66,6 +66,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
>
> state->current_function = NULL;
>
> + state->toplevel_ir = instructions;
> +
> /* Section 4.2 of the GLSL 1.20 specification states:
> * "The built-in functions are scoped in a scope outside the global scope
> * users declare global variables in. That is, a shader's global scope,
> @@ -85,6 +87,8 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state)
> ast->hir(instructions, state);
>
> detect_recursion_unlinked(state, instructions);
> +
> + state->toplevel_ir = NULL;
> }
>
>
> @@ -2926,23 +2930,16 @@ ast_parameter_declarator::parameters_to_hir(exec_list *ast_parameters,
>
>
> void
> -emit_function(_mesa_glsl_parse_state *state, exec_list *instructions,
> - ir_function *f)
> +emit_function(_mesa_glsl_parse_state *state, ir_function *f)
> {
> - /* Emit the new function header */
> - if (state->current_function == NULL) {
> - instructions->push_tail(f);
> - } else {
> - /* IR invariants disallow function declarations or definitions nested
> - * within other function definitions. Insert the new ir_function
> - * block in the instruction sequence before the ir_function block
> - * containing the current ir_function_signature.
> - */
> - ir_function *const curr =
> - const_cast<ir_function *>(state->current_function->function());
> -
> - curr->insert_before(f);
> - }
> + /* IR invariants disallow function declarations or definitions
> + * nested within other function definitions. But there is no
> + * requirement about the relative order of function declarations
> + * and definitions with respect to one another. So simply insert
> + * the new ir_function block at the end of the toplevel instruction
> + * list.
> + */
> + state->toplevel_ir->push_tail(f);
> }
>
>
> @@ -3069,7 +3066,7 @@ ast_function::hir(exec_list *instructions,
> return NULL;
> }
>
> - emit_function(state, instructions, f);
> + emit_function(state, f);
> }
>
> /* Verify the return type of main() */
> diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
> index 2f4d3cb..fc392da 100644
> --- a/src/glsl/glsl_parser_extras.h
> +++ b/src/glsl/glsl_parser_extras.h
> @@ -129,6 +129,12 @@ struct _mesa_glsl_parse_state {
> */
> class ir_function_signature *current_function;
>
> + /**
> + * During AST to IR conversion, pointer to the toplevel IR
> + * instruction list being generated.
> + */
> + exec_list *toplevel_ir;
> +
> /** Have we found a return statement in this function? */
> bool found_return;
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk43TfgACgkQX1gOwKyEAw+IrwCfYvuuQJtoS8RpI0lICMoTgYsm
RrcAn0h9erWBQTPL4i8AkXR+J+Byfawi
=oPRj
-----END PGP SIGNATURE-----
More information about the mesa-dev
mailing list