glsl2: Add and use new variable mode ir_var_temporary
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 20 Jul 2010 00:12:42 +0000 (17:12 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 21 Jul 2010 00:48:24 +0000 (17:48 -0700)
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'.

18 files changed:
src/glsl/ast_function.cpp
src/glsl/ast_to_hir.cpp
src/glsl/glsl_types.cpp
src/glsl/ir.cpp
src/glsl/ir.h
src/glsl/ir_clone.cpp
src/glsl/ir_expression_flattening.cpp
src/glsl/ir_function.cpp
src/glsl/ir_function_inlining.cpp
src/glsl/ir_if_return.cpp
src/glsl/ir_if_to_cond_assign.cpp
src/glsl/ir_mat_op_to_vec.cpp
src/glsl/ir_mod_to_fract.cpp
src/glsl/ir_reader.cpp
src/glsl/ir_variable.cpp
src/glsl/ir_vec_index_to_cond_assign.cpp
src/glsl/linker.cpp
src/mesa/shader/ir_to_mesa.cpp

index 643eb229a77dbbdaf240d98923237f76b1fc302c..14c36af9116eb7980ba9f989f2cce836daaaeb3a 100644 (file)
@@ -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));
index f20c7ead336686fcf7d84ceab75987cdfb5976c1..c68e136256ca5bc7fbb766c3f6cf921d61dc8dbb 100644 (file)
@@ -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);
 
index 77c591ed691fed32fbaade30a9b5b60c3b5d4b4e..5cb327c89d580ea409b3f6e5906895ba0e07bedb 100644 (file)
@@ -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++) {
index ba8ee7b9ac9aeeb926ce417ee3b6829e48e5aa05..146ff17af3113057d7384344e7caa79ed9c4b838 100644 (file)
@@ -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;
index 3be096270d809fddebadb662e3010669229abb5a..9fd9850391f084f725440b5f6cab2db093b7ac70 100644 (file)
@@ -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;
 
index 91d6977354d5fc3bc68d5d2ccba26bc4265b9a38..f7e8794728c6fa192cdce99a24ac2faa1aaf6b7c 100644 (file)
@@ -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;
index f18659342f5bcabed8207a8c3ab22749e2cdbaa5..6dbebc63780f19a623bdbdcfaa0ffb64b06604ea 100644 (file)
@@ -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),
index e85b18ce021a39b0fed0bef6d33431d0fbedcde2..28a5c399f15f461ed724b2b1e094ad2c827e8016 100644 (file)
@@ -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.
index a3f7089cdc86fcfd23f2b5405b294e07239e4d9d..05dd83f7ffd2bd2fe646ba8123ff1a45b5363203 100644 (file)
@@ -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);
    }
 
index f68dcfb50108ecdc3373ab9e14b399bb94652995..a9af7166b96e98ea3d778c945d3d4f90a7894474 100644 (file)
@@ -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),
index 274874bbb7673502b6df4b6906f006e6ac731cfa..0b87413941a2c2f4b3c52a3fc84e641c785b938b 100644 (file)
@@ -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);
index 7bdb9057d8281a819f7eb15f8f43c845fefc9e3b..742fc2a2952c517a8dcfb196a9316b504d9a8199 100644 (file)
@@ -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]);
index ec1e65092d9980018e5b968b3556364e7d6460c6..71c9472b12bdf3112c6dec633743c9d441468bef 100644 (file)
@@ -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;
index a1e5a7ad74b57e4404b9463bc472ac9bd4b75abb..ed68496587a5a132bfbae17f53119371d285bdc7 100644 (file)
@@ -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());
index 4593c1811278c2d23d024ad1e5b9137a3657d39b..700c5de648d1e338c0fe463facca4b5601a2f750 100644 (file)
@@ -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;
index ac420454e8801149cb018533bdaaf36ba340ef16..7e04389b5f9b804f787777966f47dcd0de746053 100644 (file)
@@ -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);
index 4869dbe1ca554d326f98e4333082e6d356ba3d97..eb4eb9d20e12249da2b26de8a7b3fa59fc58d369 100644 (file)
@@ -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;
+
+      ir_variable *var = inst->as_variable();
+      if ((var != NULL) && (var->mode != ir_var_temporary))
         continue;
 
-      assert(inst->as_assignment());
+      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;
 }
 
index 352b496625d97ecaa91a8e88d3b1546b93238e2e..7cc469f3a726d81f94412a2b4072a1f64a3d4ee4 100644 (file)
@@ -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);