diff options
Diffstat (limited to 'src/mesa/shader/slang/slang_codegen.c')
-rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index c1664a5ccb..8b2bdd74b5 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -536,7 +536,7 @@ new_not(slang_ir_node *n) static slang_ir_node * new_inlined_function_call(slang_ir_node *code, slang_label *name) { - slang_ir_node *n = new_node1(IR_FUNC, code); + slang_ir_node *n = new_node1(IR_CALL, code); assert(name); if (n) n->Label = name; @@ -1202,17 +1202,29 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, /* non-assembly function */ inlined = slang_inline_function_call(A, fun, oper, dest); if (inlined && _slang_find_node_type(inlined, SLANG_OPER_RETURN)) { - /* This inlined function has one or more 'return' statements. + slang_operation *callOper; + /* The function we're calling has one or more 'return' statements. * So, we can't truly inline this function because we need to * implement 'return' with RET (and CAL). + * Nevertheless, we performed "inlining" to make a new instance + * of the function body to deal with static register allocation. + * * XXX check if there's one 'return' and if it's the very last * statement in the function - we can optimize that case. */ assert(inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE || inlined->type == SLANG_OPER_SEQUENCE); - inlined->type = SLANG_OPER_INLINED_CALL; - inlined->fun = fun; - inlined->label = _slang_label_new_unique((char*) fun->header.a_name); + if (_slang_function_has_return_value(fun) && !dest) { + assert(inlined->children[0].type == SLANG_OPER_VARIABLE_DECL); + assert(inlined->children[2].type == SLANG_OPER_IDENTIFIER); + callOper = &inlined->children[1]; + } + else { + callOper = inlined; + } + callOper->type = SLANG_OPER_INLINED_CALL; + callOper->fun = fun; + callOper->label = _slang_label_new_unique((char*) fun->header.a_name); } } @@ -1949,8 +1961,7 @@ static slang_ir_node * _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) { const GLboolean haveReturnValue - = (oper->num_children == 1 && - oper->children[0].type != SLANG_OPER_VOID); + = (oper->num_children == 1 && oper->children[0].type != SLANG_OPER_VOID); /* error checking */ assert(A->CurFunction); @@ -1960,7 +1971,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) return NULL; } else if (!haveReturnValue && - A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { + A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { slang_info_log_error(A->log, "return statement requires an expression"); return NULL; } |