mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-22 04:28:10 +02:00
Fix function call bug 11731. Also, fix up IR_CALL/IR_FUNC confusion.
This commit is contained in:
parent
a57c5a417b
commit
33814a55f8
4 changed files with 45 additions and 34 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.0.1
|
||||
* Version: 7.1
|
||||
*
|
||||
* Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
|
||||
*
|
||||
|
|
@ -37,13 +37,13 @@
|
|||
|
||||
|
||||
|
||||
#include "imports.h"
|
||||
#include "macros.h"
|
||||
#include "mtypes.h"
|
||||
#include "program.h"
|
||||
#include "prog_instruction.h"
|
||||
#include "prog_parameter.h"
|
||||
#include "prog_statevars.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_statevars.h"
|
||||
#include "slang_typeinfo.h"
|
||||
#include "slang_codegen.h"
|
||||
#include "slang_compile.h"
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@
|
|||
***/
|
||||
|
||||
|
||||
#include "imports.h"
|
||||
#include "context.h"
|
||||
#include "macros.h"
|
||||
#include "program.h"
|
||||
#include "prog_instruction.h"
|
||||
#include "prog_parameter.h"
|
||||
#include "prog_print.h"
|
||||
#include "main/imports.h"
|
||||
#include "main/context.h"
|
||||
#include "main/macros.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
#include "slang_builtin.h"
|
||||
#include "slang_emit.h"
|
||||
#include "slang_mem.h"
|
||||
|
|
@ -780,16 +780,18 @@ emit_label(slang_emit_info *emitInfo, const slang_ir_node *n)
|
|||
|
||||
|
||||
/**
|
||||
* Emit code for an inlined function call (subroutine).
|
||||
* Emit code for a function call.
|
||||
* Note that for each time a function is called, we emit the function's
|
||||
* body code again because the set of available registers may be different.
|
||||
*/
|
||||
static struct prog_instruction *
|
||||
emit_func(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
{
|
||||
struct gl_program *progSave;
|
||||
struct prog_instruction *inst;
|
||||
GLuint subroutineId;
|
||||
|
||||
assert(n->Opcode == IR_FUNC);
|
||||
assert(n->Opcode == IR_CALL);
|
||||
assert(n->Label);
|
||||
|
||||
/* save/push cur program */
|
||||
|
|
@ -1687,10 +1689,10 @@ emit(slang_emit_info *emitInfo, slang_ir_node *n)
|
|||
case IR_KILL:
|
||||
return emit_kill(emitInfo);
|
||||
|
||||
case IR_FUNC:
|
||||
/* new variable scope for subroutines/function calls*/
|
||||
case IR_CALL:
|
||||
/* new variable scope for subroutines/function calls */
|
||||
_slang_push_var_table(emitInfo->vt);
|
||||
inst = emit_func(emitInfo, n);
|
||||
inst = emit_fcall(emitInfo, n);
|
||||
_slang_pop_var_table(emitInfo->vt);
|
||||
return inst;
|
||||
|
||||
|
|
@ -1782,7 +1784,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo)
|
|||
emitInfo->NumSubroutines = 0;
|
||||
|
||||
/* Examine CAL instructions.
|
||||
* At this point, the BranchTarget field of the CAL instructions is
|
||||
* At this point, the BranchTarget field of the CAL instruction is
|
||||
* the number/id of the subroutine to call (an index into the
|
||||
* emitInfo->Subroutines list).
|
||||
* Translate that into an actual instruction location now.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include "context.h"
|
||||
#include "slang_ir.h"
|
||||
#include "slang_mem.h"
|
||||
#include "prog_print.h"
|
||||
#include "shader/prog_print.h"
|
||||
|
||||
|
||||
static const slang_ir_info IrInfo[] = {
|
||||
|
|
@ -311,7 +311,7 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent)
|
|||
printf("RETURN\n");
|
||||
break;
|
||||
case IR_CALL:
|
||||
printf("CALL\n");
|
||||
printf("CALL %s\n", n->Label->Name);
|
||||
break;
|
||||
|
||||
case IR_LOOP:
|
||||
|
|
|
|||
|
|
@ -62,8 +62,6 @@ typedef enum
|
|||
IR_RETURN, /* return from subroutine */
|
||||
IR_CALL, /* call subroutine */
|
||||
|
||||
IR_FUNC, /* inlined function code */
|
||||
|
||||
IR_LOOP, /* high-level loop-begin / loop-end */
|
||||
/* Children[0] = loop body */
|
||||
/* Children[1] = loop tail code, or NULL */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue