diff options
author | Kenneth Graunke <[email protected]> | 2012-03-20 15:56:37 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2012-04-02 14:15:41 -0700 |
commit | d884f60861f270cdcf7d9d47765efcf1e1de30b6 (patch) | |
tree | 9041472738a13510a6cce1073cf64064eea294ec /src/glsl/ir.h | |
parent | 622eed075092a0325e0927bf2f9ef29f20bbf416 (diff) |
glsl: Convert ir_call to be a statement rather than a value.
Aside from ir_call, our IR is cleanly split into two classes:
- Statements (typeless; used for side effects, control flow)
- Values (deeply nestable, pure, typed expression trees)
Unfortunately, ir_call confused all this:
- For void functions, we placed ir_call directly in the instruction
stream, treating it as an untyped statement. Yet, it was a subclass
of ir_rvalue, and no other ir_rvalue could be used in this way.
- For functions with a return value, ir_call could be placed in
arbitrary expression trees. While this fit naturally with the source
language, it meant that expressions might not be pure, making it
difficult to transform and optimize them. To combat this, we always
emitted ir_call directly in the RHS of an ir_assignment, only using
a temporary variable in expression trees. Many passes relied on this
assumption; the acos and atan built-ins violated it.
This patch makes ir_call a statement (ir_instruction) rather than a
value (ir_rvalue). Non-void calls now take a ir_dereference of a
variable, and store the return value there---effectively a call and
assignment rolled into one. They cannot be embedded in expressions.
All expression trees are now pure, without exception.
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/ir.h')
-rw-r--r-- | src/glsl/ir.h | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/glsl/ir.h b/src/glsl/ir.h index bb4f7759b30..054e2acaadb 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1023,16 +1023,18 @@ public: /** - * IR instruction representing a function call + * HIR instruction representing a high-level function call, containing a list + * of parameters and returning a value in the supplied temporary. */ -class ir_call : public ir_rvalue { +class ir_call : public ir_instruction { public: - ir_call(ir_function_signature *callee, exec_list *actual_parameters) - : callee(callee) + ir_call(ir_function_signature *callee, + ir_dereference_variable *return_deref, + exec_list *actual_parameters) + : return_deref(return_deref), callee(callee) { ir_type = ir_type_call; assert(callee->return_type != NULL); - type = callee->return_type; actual_parameters->move_nodes_to(& this->actual_parameters); this->use_builtin = callee->is_builtin; } @@ -1084,9 +1086,15 @@ public: /** * Generates an inline version of the function before @ir, - * returning the return value of the function. + * storing the return value in return_deref. */ - ir_rvalue *generate_inline(ir_instruction *ir); + void generate_inline(ir_instruction *ir); + + /** + * Storage for the function's return value. + * This must be NULL if the return type is void. + */ + ir_dereference_variable *return_deref; /* List of ir_rvalue of paramaters passed in this call. */ exec_list actual_parameters; |