mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 04:38:03 +02:00
glsl2: Add and use new variable mode ir_var_temporary
This is quite a large patch because breaking it into smaller pieces
would result in the tree being intermitently broken. The big changes
are:
* Add the ir_var_temporary variable mode
* Change the ir_variable constructor to take the mode as a
parameter and correctly specify the mode for all ir_varables.
* Change the linker to not cross validate ir_var_temporary
variables.
* Change the linker to pull all ir_var_temporary variables from
global scope into 'main'.
This commit is contained in:
parent
1124e5a3cb
commit
7e2aa91507
18 changed files with 109 additions and 47 deletions
|
|
@ -115,7 +115,8 @@ process_call(exec_list *instructions, ir_function *f,
|
|||
|
||||
var = new(ctx) ir_variable(sig->return_type,
|
||||
talloc_asprintf(ctx, "%s_retval",
|
||||
sig->function_name()));
|
||||
sig->function_name()),
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(var);
|
||||
|
||||
deref = new(ctx) ir_dereference_variable(var);
|
||||
|
|
@ -509,7 +510,8 @@ emit_inline_vector_constructor(const glsl_type *type,
|
|||
assert(!parameters->is_empty());
|
||||
|
||||
ir_variable *var = new(ctx) ir_variable(type,
|
||||
talloc_strdup(ctx, "vec_ctor"));
|
||||
talloc_strdup(ctx, "vec_ctor"),
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(var);
|
||||
|
||||
/* There are two kinds of vector constructors.
|
||||
|
|
@ -621,7 +623,8 @@ emit_inline_matrix_constructor(const glsl_type *type,
|
|||
assert(!parameters->is_empty());
|
||||
|
||||
ir_variable *var = new(ctx) ir_variable(type,
|
||||
talloc_strdup(ctx, "mat_ctor"));
|
||||
talloc_strdup(ctx, "mat_ctor"),
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(var);
|
||||
|
||||
/* There are three kinds of matrix constructors.
|
||||
|
|
@ -645,7 +648,8 @@ emit_inline_matrix_constructor(const glsl_type *type,
|
|||
*/
|
||||
ir_variable *rhs_var =
|
||||
new(ctx) ir_variable(glsl_type::vec4_type,
|
||||
talloc_strdup(ctx, "mat_ctor_vec"));
|
||||
talloc_strdup(ctx, "mat_ctor_vec"),
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(rhs_var);
|
||||
|
||||
ir_constant_data zero;
|
||||
|
|
@ -759,7 +763,8 @@ emit_inline_matrix_constructor(const glsl_type *type,
|
|||
*/
|
||||
ir_variable *const rhs_var =
|
||||
new(ctx) ir_variable(first_param->type,
|
||||
talloc_strdup(ctx, "mat_ctor_mat"));
|
||||
talloc_strdup(ctx, "mat_ctor_mat"),
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(rhs_var);
|
||||
|
||||
ir_dereference *const rhs_var_ref =
|
||||
|
|
@ -825,7 +830,8 @@ emit_inline_matrix_constructor(const glsl_type *type,
|
|||
*/
|
||||
ir_variable *rhs_var =
|
||||
new(ctx) ir_variable(rhs->type,
|
||||
talloc_strdup(ctx, "mat_ctor_vec"));
|
||||
talloc_strdup(ctx, "mat_ctor_vec"),
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(rhs_var);
|
||||
|
||||
ir_dereference *rhs_var_ref =
|
||||
|
|
@ -1036,7 +1042,8 @@ ast_function_expression::hir(exec_list *instructions,
|
|||
continue;
|
||||
|
||||
/* Create a temporary containing the matrix. */
|
||||
ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp");
|
||||
ir_variable *var = new(ctx) ir_variable(matrix->type, "matrix_tmp",
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(var);
|
||||
instructions->push_tail(new(ctx) ir_assignment(new(ctx)
|
||||
ir_dereference_variable(var), matrix, NULL));
|
||||
|
|
|
|||
|
|
@ -527,7 +527,8 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
|
|||
* temporary and return a deref of that temporary. If the rvalue
|
||||
* ends up not being used, the temp will get copy-propagated out.
|
||||
*/
|
||||
ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp");
|
||||
ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
|
||||
ir_var_temporary);
|
||||
ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var);
|
||||
instructions->push_tail(var);
|
||||
instructions->push_tail(new(ctx) ir_assignment(deref_var,
|
||||
|
|
@ -549,7 +550,8 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
|
|||
ir_variable *var;
|
||||
|
||||
/* FINISHME: Give unique names to the temporaries. */
|
||||
var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp");
|
||||
var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(var);
|
||||
var->mode = ir_var_auto;
|
||||
|
||||
|
|
@ -806,7 +808,8 @@ ast_expression::hir(exec_list *instructions,
|
|||
type = glsl_type::bool_type;
|
||||
} else {
|
||||
ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
|
||||
"and_tmp");
|
||||
"and_tmp",
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(tmp);
|
||||
|
||||
ir_if *const stmt = new(ctx) ir_if(op[0]);
|
||||
|
|
@ -870,7 +873,8 @@ ast_expression::hir(exec_list *instructions,
|
|||
type = glsl_type::bool_type;
|
||||
} else {
|
||||
ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
|
||||
"or_tmp");
|
||||
"or_tmp",
|
||||
ir_var_temporary);
|
||||
instructions->push_tail(tmp);
|
||||
|
||||
ir_if *const stmt = new(ctx) ir_if(op[0]);
|
||||
|
|
@ -1049,7 +1053,8 @@ ast_expression::hir(exec_list *instructions,
|
|||
&& (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
|
||||
result = (cond_val->value.b[0]) ? then_val : else_val;
|
||||
} else {
|
||||
ir_variable *const tmp = new(ctx) ir_variable(type, "conditional_tmp");
|
||||
ir_variable *const tmp =
|
||||
new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
|
||||
instructions->push_tail(tmp);
|
||||
|
||||
ir_if *const stmt = new(ctx) ir_if(op[0]);
|
||||
|
|
@ -1474,6 +1479,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
|||
}
|
||||
}
|
||||
|
||||
/* If there is no qualifier that changes the mode of the variable, leave
|
||||
* the setting alone.
|
||||
*/
|
||||
if (qual->in && qual->out)
|
||||
var->mode = ir_var_inout;
|
||||
else if (qual->attribute || qual->in
|
||||
|
|
@ -1483,8 +1491,6 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
|||
var->mode = ir_var_out;
|
||||
else if (qual->uniform)
|
||||
var->mode = ir_var_uniform;
|
||||
else
|
||||
var->mode = ir_var_auto;
|
||||
|
||||
if (qual->uniform)
|
||||
var->shader_in = true;
|
||||
|
|
@ -1633,7 +1639,7 @@ ast_declarator_list::hir(exec_list *instructions,
|
|||
var_type = decl_type;
|
||||
}
|
||||
|
||||
var = new(ctx) ir_variable(var_type, decl->identifier);
|
||||
var = new(ctx) ir_variable(var_type, decl->identifier, ir_var_auto);
|
||||
|
||||
/* From page 22 (page 28 of the PDF) of the GLSL 1.10 specification;
|
||||
*
|
||||
|
|
@ -1993,7 +1999,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
|
|||
}
|
||||
|
||||
is_void = false;
|
||||
ir_variable *var = new(ctx) ir_variable(type, this->identifier);
|
||||
ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in);
|
||||
|
||||
/* FINISHME: Handle array declarations. Note that this requires
|
||||
* FINISHME: complete handling of constant expressions.
|
||||
|
|
@ -2003,8 +2009,6 @@ ast_parameter_declarator::hir(exec_list *instructions,
|
|||
* for function parameters the default mode is 'in'.
|
||||
*/
|
||||
apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc);
|
||||
if (var->mode == ir_var_auto)
|
||||
var->mode = ir_var_in;
|
||||
|
||||
instructions->push_tail(var);
|
||||
|
||||
|
|
|
|||
|
|
@ -251,10 +251,9 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const
|
|||
snprintf(param_name, 10, "p%08X", i);
|
||||
|
||||
ir_variable *var = (this->base_type == GLSL_TYPE_ARRAY)
|
||||
? new(ctx) ir_variable(fields.array, param_name)
|
||||
: new(ctx) ir_variable(fields.structure[i].type, param_name);
|
||||
? new(ctx) ir_variable(fields.array, param_name, ir_var_in)
|
||||
: new(ctx) ir_variable(fields.structure[i].type, param_name, ir_var_in);
|
||||
|
||||
var->mode = ir_var_in;
|
||||
declarations[i] = var;
|
||||
sig->parameters.push_tail(var);
|
||||
}
|
||||
|
|
@ -264,7 +263,7 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const
|
|||
* the same type as the constructor. After initializing __retval,
|
||||
* __retval is returned.
|
||||
*/
|
||||
ir_variable *retval = new(ctx) ir_variable(this, "__retval");
|
||||
ir_variable *retval = new(ctx) ir_variable(this, "__retval", ir_var_auto);
|
||||
sig->body.push_tail(retval);
|
||||
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
|
|
|
|||
|
|
@ -748,10 +748,12 @@ ir_swizzle::variable_referenced()
|
|||
return this->val->variable_referenced();
|
||||
}
|
||||
|
||||
ir_variable::ir_variable(const struct glsl_type *type, const char *name)
|
||||
|
||||
ir_variable::ir_variable(const struct glsl_type *type, const char *name,
|
||||
ir_variable_mode mode)
|
||||
: max_array_access(0), read_only(false), centroid(false), invariant(false),
|
||||
shader_in(false), shader_out(false),
|
||||
mode(ir_var_auto), interpolation(ir_var_smooth), array_lvalue(false)
|
||||
mode(mode), interpolation(ir_var_smooth), array_lvalue(false)
|
||||
{
|
||||
this->ir_type = ir_type_variable;
|
||||
this->type = type;
|
||||
|
|
|
|||
|
|
@ -162,7 +162,8 @@ enum ir_variable_mode {
|
|||
ir_var_uniform,
|
||||
ir_var_in,
|
||||
ir_var_out,
|
||||
ir_var_inout
|
||||
ir_var_inout,
|
||||
ir_var_temporary /**< Temporary variable generated during compilation. */
|
||||
};
|
||||
|
||||
enum ir_variable_interpolation {
|
||||
|
|
@ -174,7 +175,7 @@ enum ir_variable_interpolation {
|
|||
|
||||
class ir_variable : public ir_instruction {
|
||||
public:
|
||||
ir_variable(const struct glsl_type *, const char *);
|
||||
ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
|
||||
|
||||
virtual ir_variable *clone(struct hash_table *ht) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ ir_variable *
|
|||
ir_variable::clone(struct hash_table *ht) const
|
||||
{
|
||||
void *ctx = talloc_parent(this);
|
||||
ir_variable *var = new(ctx) ir_variable(type, name);
|
||||
ir_variable *var = new(ctx) ir_variable(this->type, this->name,
|
||||
(ir_variable_mode) this->mode);
|
||||
|
||||
var->max_array_access = this->max_array_access;
|
||||
var->read_only = this->read_only;
|
||||
|
|
@ -47,7 +48,6 @@ ir_variable::clone(struct hash_table *ht) const
|
|||
var->invariant = this->invariant;
|
||||
var->shader_in = this->shader_in;
|
||||
var->shader_out = this->shader_out;
|
||||
var->mode = this->mode;
|
||||
var->interpolation = this->interpolation;
|
||||
var->array_lvalue = this->array_lvalue;
|
||||
var->location = this->location;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ ir_expression_flattening_visitor::operand_to_temp(ir_rvalue *ir)
|
|||
if (!this->predicate(ir))
|
||||
return ir;
|
||||
|
||||
var = new(ctx) ir_variable(ir->type, "flattening_tmp");
|
||||
var = new(ctx) ir_variable(ir->type, "flattening_tmp", ir_var_temporary);
|
||||
base_ir->insert_before(var);
|
||||
|
||||
assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b)
|
|||
switch ((enum ir_variable_mode)(param->mode)) {
|
||||
case ir_var_auto:
|
||||
case ir_var_uniform:
|
||||
case ir_var_temporary:
|
||||
/* These are all error conditions. It is invalid for a parameter to
|
||||
* a function to be declared as auto (not in, out, or inout) or
|
||||
* as uniform.
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ ir_call::generate_inline(ir_instruction *next_ir)
|
|||
|
||||
/* Generate storage for the return value. */
|
||||
if (this->callee->return_type) {
|
||||
retval = new(ctx) ir_variable(this->callee->return_type, "__retval");
|
||||
retval = new(ctx) ir_variable(this->callee->return_type, "__retval",
|
||||
ir_var_auto);
|
||||
next_ir->insert_before(retval);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ ir_if_return_visitor::visit_enter(ir_if *ir)
|
|||
} else {
|
||||
ir_assignment *assign;
|
||||
ir_variable *new_var = new(ir) ir_variable(then_return->value->type,
|
||||
"if_return_tmp");
|
||||
"if_return_tmp",
|
||||
ir_var_temporary);
|
||||
ir->insert_before(new_var);
|
||||
|
||||
assign = new(ir) ir_assignment(new(ir) ir_dereference_variable(new_var),
|
||||
|
|
|
|||
|
|
@ -145,7 +145,8 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
|
|||
* simpler.
|
||||
*/
|
||||
cond_var = new(mem_ctx) ir_variable(glsl_type::bool_type,
|
||||
"if_to_cond_assign_condition");
|
||||
"if_to_cond_assign_condition",
|
||||
ir_var_temporary);
|
||||
ir->insert_before(cond_var);
|
||||
|
||||
deref = new(mem_ctx) ir_dereference_variable(cond_var);
|
||||
|
|
|
|||
|
|
@ -298,7 +298,8 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *assign)
|
|||
ir_assignment *assign;
|
||||
|
||||
op_var[i] = new(base_ir) ir_variable(expr->operands[i]->type,
|
||||
"mat_op_to_vec");
|
||||
"mat_op_to_vec",
|
||||
ir_var_temporary);
|
||||
base_ir->insert_before(op_var[i]);
|
||||
|
||||
lhs_deref = new(base_ir) ir_dereference_variable(op_var[i]);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ ir_mod_to_fract_visitor::visit_leave(ir_expression *ir)
|
|||
if (ir->operation != ir_binop_mod)
|
||||
return visit_continue;
|
||||
|
||||
ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b");
|
||||
ir_variable *temp = new(ir) ir_variable(ir->operands[1]->type, "mod_b",
|
||||
ir_var_temporary);
|
||||
this->base_ir->insert_before(temp);
|
||||
|
||||
ir_assignment *assign;
|
||||
|
|
|
|||
|
|
@ -401,7 +401,8 @@ read_declaration(_mesa_glsl_parse_state *st, s_list *list)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ir_variable *var = new(ctx) ir_variable(type, var_name->value());
|
||||
ir_variable *var = new(ctx) ir_variable(type, var_name->value(),
|
||||
ir_var_auto);
|
||||
|
||||
foreach_iter(exec_list_iterator, it, quals->subexpressions) {
|
||||
s_symbol *qualifier = SX_AS_SYMBOL(it.get());
|
||||
|
|
|
|||
|
|
@ -39,9 +39,8 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot,
|
|||
const glsl_type *type, exec_list *instructions,
|
||||
glsl_symbol_table *symtab)
|
||||
{
|
||||
ir_variable *var = new(symtab) ir_variable(type, name);
|
||||
ir_variable *var = new(symtab) ir_variable(type, name, mode);
|
||||
|
||||
var->mode = mode;
|
||||
switch (var->mode) {
|
||||
case ir_var_auto:
|
||||
var->read_only = true;
|
||||
|
|
|
|||
|
|
@ -86,14 +86,16 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue
|
|||
|
||||
/* Store the index to a temporary to avoid reusing its tree. */
|
||||
index = new(base_ir) ir_variable(glsl_type::int_type,
|
||||
"vec_index_tmp_i");
|
||||
"vec_index_tmp_i",
|
||||
ir_var_temporary);
|
||||
base_ir->insert_before(index);
|
||||
deref = new(base_ir) ir_dereference_variable(index);
|
||||
assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL);
|
||||
base_ir->insert_before(assign);
|
||||
|
||||
/* Temporary where we store whichever value we swizzle out. */
|
||||
var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v");
|
||||
var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v",
|
||||
ir_var_temporary);
|
||||
base_ir->insert_before(var);
|
||||
|
||||
/* Generate a conditional move of each vector element to the temp. */
|
||||
|
|
@ -166,14 +168,16 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
|
|||
assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
|
||||
|
||||
/* Store the index to a temporary to avoid reusing its tree. */
|
||||
index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i");
|
||||
index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i",
|
||||
ir_var_temporary);
|
||||
ir->insert_before(index);
|
||||
deref = new(ir) ir_dereference_variable(index);
|
||||
assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL);
|
||||
ir->insert_before(assign);
|
||||
|
||||
/* Store the RHS to a temporary to avoid reusing its tree. */
|
||||
var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v");
|
||||
var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v",
|
||||
ir_var_temporary);
|
||||
ir->insert_before(var);
|
||||
deref = new(ir) ir_dereference_variable(var);
|
||||
assign = new(ir) ir_assignment(deref, ir->rhs, NULL);
|
||||
|
|
|
|||
|
|
@ -246,6 +246,8 @@ mode_string(const ir_variable *var)
|
|||
case ir_var_in: return "shader input";
|
||||
case ir_var_out: return "shader output";
|
||||
case ir_var_inout: return "shader inout";
|
||||
|
||||
case ir_var_temporary:
|
||||
default:
|
||||
assert(!"Should not get here.");
|
||||
return "invalid variable";
|
||||
|
|
@ -276,6 +278,12 @@ cross_validate_globals(struct gl_shader_program *prog,
|
|||
if (uniforms_only && (var->mode != ir_var_uniform))
|
||||
continue;
|
||||
|
||||
/* Don't cross validate temporaries that are at global scope. These
|
||||
* will eventually get pulled into the shaders 'main'.
|
||||
*/
|
||||
if (var->mode == ir_var_temporary)
|
||||
continue;
|
||||
|
||||
/* If a global with this name has already been seen, verify that the
|
||||
* new instance has the same type. In addition, if the globals have
|
||||
* initializers, the values of the initializers must be the same.
|
||||
|
|
@ -480,18 +488,28 @@ populate_symbol_table(gl_shader *sh)
|
|||
*/
|
||||
void
|
||||
remap_variables(ir_instruction *inst, glsl_symbol_table *symbols,
|
||||
exec_list *instructions)
|
||||
exec_list *instructions, hash_table *temps)
|
||||
{
|
||||
class remap_visitor : public ir_hierarchical_visitor {
|
||||
public:
|
||||
remap_visitor(glsl_symbol_table *symbols, exec_list *instructions)
|
||||
remap_visitor(glsl_symbol_table *symbols, exec_list *instructions,
|
||||
hash_table *temps)
|
||||
{
|
||||
this->symbols = symbols;
|
||||
this->instructions = instructions;
|
||||
this->temps = temps;
|
||||
}
|
||||
|
||||
virtual ir_visitor_status visit(ir_dereference_variable *ir)
|
||||
{
|
||||
if (ir->var->mode == ir_var_temporary) {
|
||||
ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var);
|
||||
|
||||
assert(var != NULL);
|
||||
ir->var = var;
|
||||
return visit_continue;
|
||||
}
|
||||
|
||||
ir_variable *const existing =
|
||||
this->symbols->get_variable(ir->var->name);
|
||||
if (existing != NULL)
|
||||
|
|
@ -501,6 +519,7 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols,
|
|||
|
||||
this->symbols->add_variable(copy->name, copy);
|
||||
this->instructions->push_head(copy);
|
||||
ir->var = copy;
|
||||
}
|
||||
|
||||
return visit_continue;
|
||||
|
|
@ -509,9 +528,10 @@ remap_variables(ir_instruction *inst, glsl_symbol_table *symbols,
|
|||
private:
|
||||
glsl_symbol_table *symbols;
|
||||
exec_list *instructions;
|
||||
hash_table *temps;
|
||||
};
|
||||
|
||||
remap_visitor v(symbols, instructions);
|
||||
remap_visitor v(symbols, instructions, temps);
|
||||
|
||||
inst->accept(&v);
|
||||
}
|
||||
|
|
@ -542,17 +562,32 @@ exec_node *
|
|||
move_non_declarations(exec_list *instructions, exec_node *last,
|
||||
bool make_copies, gl_shader *target)
|
||||
{
|
||||
hash_table *temps = NULL;
|
||||
|
||||
if (make_copies)
|
||||
temps = hash_table_ctor(0, hash_table_pointer_hash,
|
||||
hash_table_pointer_compare);
|
||||
|
||||
foreach_list_safe(node, instructions) {
|
||||
ir_instruction *inst = (ir_instruction *) node;
|
||||
|
||||
if (inst->as_variable() || inst->as_function())
|
||||
if (inst->as_function())
|
||||
continue;
|
||||
|
||||
assert(inst->as_assignment());
|
||||
ir_variable *var = inst->as_variable();
|
||||
if ((var != NULL) && (var->mode != ir_var_temporary))
|
||||
continue;
|
||||
|
||||
assert(inst->as_assignment()
|
||||
|| ((var != NULL) && (var->mode == ir_var_temporary)));
|
||||
|
||||
if (make_copies) {
|
||||
inst = inst->clone(NULL);
|
||||
remap_variables(inst, target->symbols, target->ir);
|
||||
|
||||
if (var != NULL)
|
||||
hash_table_insert(temps, inst, var);
|
||||
else
|
||||
remap_variables(inst, target->symbols, target->ir, temps);
|
||||
} else {
|
||||
inst->remove();
|
||||
}
|
||||
|
|
@ -561,6 +596,9 @@ move_non_declarations(exec_list *instructions, exec_node *last,
|
|||
last = inst;
|
||||
}
|
||||
|
||||
if (make_copies)
|
||||
hash_table_dtor(temps);
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1133,6 +1133,7 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
|
|||
|
||||
break;
|
||||
case ir_var_auto:
|
||||
case ir_var_temporary:
|
||||
entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
|
||||
this->next_temp);
|
||||
this->variables.push_tail(entry);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue