diff options
author | Eric Anholt <eric@anholt.net> | 2010-07-20 15:50:48 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-07-20 15:59:04 -0700 |
commit | 02d3711a21f5766d286b09fbe1eda5d8520d151a (patch) | |
tree | 8c6c2edc767bc912a3a0d5984cb7d6a47ab0b533 /src | |
parent | f8946699ecfa5bc6566821fb855072bbdbd716b2 (diff) |
glsl2: Always insert function calls into the instruction stream.
If they have a return value, this means putting it into a temporary
and making a deref of the temp be the rvalue, since we don't know if
the rvalue will be used or not.
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/ast_function.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index aaf1e57ae28..643eb229a77 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -104,7 +104,30 @@ process_call(exec_list *instructions, ir_function *f, formal_iter.next(); } - return new(ctx) ir_call(sig, actual_parameters); + /* Always insert the call in the instruction stream, and return a deref + * of its return val if it returns a value, since we don't know if + * the rvalue is going to be assigned to anything or not. + */ + ir_call *call = new(ctx) ir_call(sig, actual_parameters); + if (!sig->return_type->is_void()) { + ir_variable *var; + ir_dereference_variable *deref; + + var = new(ctx) ir_variable(sig->return_type, + talloc_asprintf(ctx, "%s_retval", + sig->function_name())); + instructions->push_tail(var); + + deref = new(ctx) ir_dereference_variable(var); + ir_assignment *assign = new(ctx) ir_assignment(deref, call, NULL); + instructions->push_tail(assign); + + deref = new(ctx) ir_dereference_variable(var); + return deref; + } else { + instructions->push_tail(call); + return NULL; + } } else { /* FINISHME: Log a better error message here. G++ will show the types * FINISHME: of the actual parameters and the set of candidate |