Begin refactoring ir_dereference
authorIan Romanick <ian.d.romanick@intel.com>
Wed, 19 May 2010 09:37:35 +0000 (11:37 +0200)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 26 May 2010 22:23:19 +0000 (15:23 -0700)
Create separate subclasses of ir_dereference for variable, array, and
record dereferences.  As a side effect, array and record dereferences
no longer point to ir_variable objects directly.  Instead they each
point to an ir_dereference_variable object.

This is the first of several steps in the refactoring process.  The
intention is that ir_dereference will eventually become an abstract
base class.

ast_function.cpp
ast_to_hir.cpp
glsl_types.cpp
hir_field_selection.cpp
ir.cpp
ir.h
ir_expression_flattening.cpp
ir_function_inlining.cpp
ir_reader.cpp

index 7931633c5a1f3c0a3fb45e9b8161c62b46394ca9..300108cb73e46202203d9dca24b0a2d4a296430b 100644 (file)
@@ -200,7 +200,7 @@ dereference_component(ir_rvalue *src, unsigned component)
       const int c = component / src->type->column_type()->vector_elements;
       const int r = component % src->type->column_type()->vector_elements;
       ir_constant *const col_index = new ir_constant(glsl_type::int_type, &c);
-      ir_dereference *const col = new ir_dereference(src, col_index);
+      ir_dereference *const col = new ir_dereference_array(src, col_index);
 
       col->type = src->type->column_type();
 
index 2243d644032f3365984452ddf40b02c209f642ca..b8128fa8a778fb5ab7c6f6b4b1e7120405ff0c16 100644 (file)
@@ -535,7 +535,7 @@ get_lvalue_copy(exec_list *instructions, struct _mesa_glsl_parse_state *state,
    var = new ir_variable(lvalue->type, "_internal_tmp");
    var->mode = ir_var_auto;
 
-   var_deref = new ir_dereference(var);
+   var_deref = new ir_dereference_variable(var);
    do_assignment(instructions, state, var_deref, lvalue, loc);
 
    /* Once we've created this temporary, mark it read only so it's no
@@ -803,17 +803,17 @@ ast_expression::hir(exec_list *instructions,
         ir_variable *const tmp = generate_temporary(glsl_type::bool_type,
                                                     instructions, state);
 
-        ir_dereference *const then_deref = new ir_dereference(tmp);
+        ir_dereference *const then_deref = new ir_dereference_variable(tmp);
         ir_assignment *const then_assign =
            new ir_assignment(then_deref, op[1], NULL);
         stmt->then_instructions.push_tail(then_assign);
 
-        ir_dereference *const else_deref = new ir_dereference(tmp);
+        ir_dereference *const else_deref = new ir_dereference_variable(tmp);
         ir_assignment *const else_assign =
            new ir_assignment(else_deref, new ir_constant(false), NULL);
         stmt->else_instructions.push_tail(else_assign);
 
-        result = new ir_dereference(tmp);
+        result = new ir_dereference_variable(tmp);
         type = tmp->type;
       }
       break;
@@ -865,17 +865,17 @@ ast_expression::hir(exec_list *instructions,
            error_emitted = true;
         }
 
-        ir_dereference *const then_deref = new ir_dereference(tmp);
+        ir_dereference *const then_deref = new ir_dereference_variable(tmp);
         ir_assignment *const then_assign =
            new ir_assignment(then_deref, new ir_constant(true), NULL);
         stmt->then_instructions.push_tail(then_assign);
 
-        ir_dereference *const else_deref = new ir_dereference(tmp);
+        ir_dereference *const else_deref = new ir_dereference_variable(tmp);
         ir_assignment *const else_assign =
            new ir_assignment(else_deref, op[1], NULL);
         stmt->else_instructions.push_tail(else_assign);
 
-        result = new ir_dereference(tmp);
+        result = new ir_dereference_variable(tmp);
         type = tmp->type;
       }
       break;
@@ -996,13 +996,13 @@ ast_expression::hir(exec_list *instructions,
       instructions->push_tail(stmt);
 
       op[1] = this->subexpressions[1]->hir(& stmt->then_instructions, state);
-      ir_dereference *const then_deref = new ir_dereference(tmp);
+      ir_dereference *const then_deref = new ir_dereference_variable(tmp);
       ir_assignment *const then_assign =
         new ir_assignment(then_deref, op[1], NULL);
       stmt->then_instructions.push_tail(then_assign);
 
       op[2] = this->subexpressions[2]->hir(& stmt->else_instructions, state);
-      ir_dereference *const else_deref = new ir_dereference(tmp);
+      ir_dereference *const else_deref = new ir_dereference_variable(tmp);
       ir_assignment *const else_assign =
         new ir_assignment(else_deref, op[2], NULL);
       stmt->else_instructions.push_tail(else_assign);
@@ -1028,7 +1028,7 @@ ast_expression::hir(exec_list *instructions,
         tmp->type = op[1]->type;
       }
 
-      result = new ir_dereference(tmp);
+      result = new ir_dereference_variable(tmp);
       type = tmp->type;
       break;
    }
@@ -1097,18 +1097,9 @@ ast_expression::hir(exec_list *instructions,
 
       error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
 
-      ir_dereference *const lhs = op[0]->as_dereference();
-      ir_instruction *array;
-      if ((lhs != NULL)
-         && (lhs->mode == ir_dereference::ir_reference_variable)) {
-        result = new ir_dereference(lhs->var, op[1]);
+      ir_instruction *const array = op[0];
 
-        delete op[0];
-        array = lhs->var;
-      } else {
-        result = new ir_dereference(op[0], op[1]);
-        array = op[0];
-      }
+      result = new ir_dereference_array(op[0], op[1]);
 
       /* Do not use op[0] after this point.  Use array.
        */
@@ -1218,7 +1209,7 @@ ast_expression::hir(exec_list *instructions,
       ir_variable *var = 
         state->symbols->get_variable(this->primary_expression.identifier);
 
-      result = new ir_dereference(var);
+      result = new ir_dereference_variable(var);
 
       if (var != NULL) {
         type = result->type;
@@ -1722,7 +1713,7 @@ ast_declarator_list::hir(exec_list *instructions,
                             ? "attribute" : "varying");
         }
 
-        ir_dereference *const lhs = new ir_dereference(var);
+        ir_dereference *const lhs = new ir_dereference_variable(var);
         ir_rvalue *rhs = decl->initializer->hir(instructions, state);
 
         /* Calculate the constant value if this is a const
index a293ce728602a90a674fdeb35686b7b6d98646b0..e1beeefe89172835951465d89b91aba5a4b24976 100644 (file)
@@ -171,10 +171,10 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const
 
    for (unsigned i = 0; i < length; i++) {
       ir_dereference *const lhs = (this->base_type == GLSL_TYPE_ARRAY)
-        ? new ir_dereference(retval, new ir_constant(i))
-        : new ir_dereference(retval, fields.structure[i].name);
+        ? (ir_dereference *) new ir_dereference_array(retval, new ir_constant(i))
+        : (ir_dereference *) new ir_dereference_record(retval, fields.structure[i].name);
 
-      ir_dereference *const rhs = new ir_dereference(declarations[i]);
+      ir_dereference *const rhs = new ir_dereference_variable(declarations[i]);
       ir_instruction *const assign = new ir_assignment(lhs, rhs, NULL);
 
       sig->body.push_tail(assign);
@@ -182,7 +182,7 @@ glsl_type::generate_constructor(glsl_symbol_table *symtab) const
 
    free(declarations);
 
-   ir_dereference *const retref = new ir_dereference(retval);
+   ir_dereference *const retref = new ir_dereference_variable(retval);
    ir_instruction *const inst = new ir_return(retref);
    sig->body.push_tail(inst);
 
@@ -250,15 +250,16 @@ generate_vec_body_from_scalar(exec_list *instructions,
    /* Generate a single assignment of the parameter to __retval.x and return
     * __retval.xxxx for however many vector components there are.
     */
-   ir_dereference *const lhs_ref = new ir_dereference(declarations[16]);
-   ir_dereference *const rhs = new ir_dereference(declarations[0]);
+   ir_dereference *const lhs_ref =
+      new ir_dereference_variable(declarations[16]);
+   ir_dereference *const rhs = new ir_dereference_variable(declarations[0]);
 
    ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
 
    inst = new ir_assignment(lhs, rhs, NULL);
    instructions->push_tail(inst);
 
-   ir_dereference *const retref = new ir_dereference(declarations[16]);
+   ir_dereference *const retref = new ir_dereference_variable(declarations[16]);
 
    ir_swizzle *retval = new ir_swizzle(retref, 0, 0, 0, 0,
                                        declarations[16]->type->vector_elements);
@@ -283,8 +284,9 @@ generate_vec_body_from_N_scalars(exec_list *instructions,
     * __retval.x and return __retval.
     */
    for (unsigned i = 0; i < vec_type->vector_elements; i++) {
-      ir_dereference *const lhs_ref = new ir_dereference(declarations[16]);
-      ir_dereference *const rhs = new ir_dereference(declarations[i]);
+      ir_dereference *const lhs_ref =
+        new ir_dereference_variable(declarations[16]);
+      ir_dereference *const rhs = new ir_dereference_variable(declarations[i]);
 
       ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
 
@@ -292,7 +294,7 @@ generate_vec_body_from_N_scalars(exec_list *instructions,
       instructions->push_tail(inst);
    }
 
-   ir_dereference *retval = new ir_dereference(declarations[16]);
+   ir_dereference *retval = new ir_dereference_variable(declarations[16]);
 
    inst = new ir_return(retval);
    instructions->push_tail(inst);
@@ -334,8 +336,8 @@ generate_mat_body_from_scalar(exec_list *instructions,
 
    instructions->push_tail(column);
 
-   ir_dereference *const lhs_ref = new ir_dereference(column);
-   ir_dereference *const rhs = new ir_dereference(declarations[0]);
+   ir_dereference *const lhs_ref = new ir_dereference_variable(column);
+   ir_dereference *const rhs = new ir_dereference_variable(declarations[0]);
 
    ir_swizzle *lhs = new ir_swizzle(lhs_ref, 0, 0, 0, 0, 1);
 
@@ -346,7 +348,7 @@ generate_mat_body_from_scalar(exec_list *instructions,
    ir_constant *const zero = new ir_constant(glsl_type::float_type, &z);
 
    for (unsigned i = 1; i < column_type->vector_elements; i++) {
-      ir_dereference *const lhs_ref = new ir_dereference(column);
+      ir_dereference *const lhs_ref = new ir_dereference_variable(column);
 
       ir_swizzle *lhs = new ir_swizzle(lhs_ref, i, 0, 0, 0, 1);
 
@@ -357,7 +359,7 @@ generate_mat_body_from_scalar(exec_list *instructions,
 
    for (unsigned i = 0; i < row_type->vector_elements; i++) {
       static const unsigned swiz[] = { 1, 1, 1, 0, 1, 1, 1 };
-      ir_dereference *const rhs_ref = new ir_dereference(column);
+      ir_dereference *const rhs_ref = new ir_dereference_variable(column);
 
       /* This will be .xyyy when i=0, .yxyy when i=1, etc.
        */
@@ -366,13 +368,14 @@ generate_mat_body_from_scalar(exec_list *instructions,
                                       column_type->vector_elements);
 
       ir_constant *const idx = new ir_constant(glsl_type::int_type, &i);
-      ir_dereference *const lhs = new ir_dereference(declarations[16], idx);
+      ir_dereference *const lhs =
+        new ir_dereference_array(declarations[16], idx);
 
       inst = new ir_assignment(lhs, rhs, NULL);
       instructions->push_tail(inst);
    }
 
-   ir_dereference *const retval = new ir_dereference(declarations[16]);
+   ir_dereference *const retval = new ir_dereference_variable(declarations[16]);
    inst = new ir_return(retval);
    instructions->push_tail(inst);
 }
@@ -397,20 +400,21 @@ generate_mat_body_from_N_scalars(exec_list *instructions,
       for (unsigned j = 0; j < row_type->vector_elements; j++) {
         ir_constant *row_index = new ir_constant(glsl_type::int_type, &i);
         ir_dereference *const row_access =
-           new ir_dereference(declarations[16], row_index);
+           new ir_dereference_array(declarations[16], row_index);
 
         ir_swizzle *component_access = new ir_swizzle(row_access,
                                                       j, 0, 0, 0, 1);
 
         const unsigned param = (i * row_type->vector_elements) + j;
-        ir_dereference *const rhs = new ir_dereference(declarations[param]);
+        ir_dereference *const rhs =
+           new ir_dereference_variable(declarations[param]);
 
         inst = new ir_assignment(component_access, rhs, NULL);
         instructions->push_tail(inst);
       }
    }
 
-   ir_dereference *retval = new ir_dereference(declarations[16]);
+   ir_dereference *retval = new ir_dereference_variable(declarations[16]);
 
    inst = new ir_return(retval);
    instructions->push_tail(inst);
index 685cf75dcf033cffd04f8c8d4f9c328e1c463a29..f0be84dab4ce1955109d064b15ce3bdc4ab48d26 100644 (file)
@@ -62,7 +62,8 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
                          expr->primary_expression.identifier);
       }
    } else if (op->type->base_type == GLSL_TYPE_STRUCT) {
-      result = new ir_dereference(op, expr->primary_expression.identifier);
+      result = new ir_dereference_record(op,
+                                        expr->primary_expression.identifier);
 
       if (result->type->is_error()) {
         _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
diff --git a/ir.cpp b/ir.cpp
index 696feb23f6fb431eca4f8c36e2640e4b1b0d1b4b..f6f2558bc06bb5dfd7bcae019cbb289ea0f062d9 100644 (file)
--- a/ir.cpp
+++ b/ir.cpp
@@ -223,22 +223,40 @@ ir_constant::ir_constant(bool b)
 }
 
 
-ir_dereference::ir_dereference(ir_instruction *var)
+ir_dereference_variable::ir_dereference_variable(ir_variable *var)
+   : ir_dereference(ir_reference_variable)
 {
-   this->mode = ir_reference_variable;
    this->var = var;
    this->type = (var != NULL) ? var->type : glsl_type::error_type;
 }
 
 
-ir_dereference::ir_dereference(ir_instruction *var,
-                              ir_rvalue *array_index)
-   : mode(ir_reference_array), var(var)
+ir_dereference_array::ir_dereference_array(ir_rvalue *value,
+                                          ir_rvalue *array_index)
+   : ir_dereference(ir_reference_array)
 {
-   type = glsl_type::error_type;
+   this->selector.array_index = array_index;
+   this->set_array(value);
+}
+
+
+ir_dereference_array::ir_dereference_array(ir_variable *var,
+                                          ir_rvalue *array_index)
+   : ir_dereference(ir_reference_array)
+{
+   this->selector.array_index = array_index;
+   this->set_array(new ir_dereference_variable(var));
+}
+
+
+void
+ir_dereference_array::set_array(ir_rvalue *value)
+{
+   this->var = value;
+   this->type = glsl_type::error_type;
 
-   if (var != NULL) {
-      const glsl_type *const vt = var->type;
+   if (this->var != NULL) {
+      const glsl_type *const vt = this->var->type;
 
       if (vt->is_array()) {
         type = vt->element_type();
@@ -248,68 +266,45 @@ ir_dereference::ir_dereference(ir_instruction *var,
         type = vt->get_base_type();
       }
    }
+}
 
-   this->selector.array_index = array_index;
+
+ir_dereference_record::ir_dereference_record(ir_rvalue *value,
+                                            const char *field)
+   : ir_dereference(ir_reference_record)
+{
+   this->var = value;
+   this->selector.field = field;
+   this->type = (this->var != NULL)
+      ? this->var->type->field_type(field) : glsl_type::error_type;
 }
 
-ir_dereference::ir_dereference(ir_instruction *variable, const char *field)
-   : mode(ir_reference_record), var(variable)
+
+ir_dereference_record::ir_dereference_record(ir_variable *var,
+                                            const char *field)
+   : ir_dereference(ir_reference_record)
 {
+   this->var = new ir_dereference_variable(var);
    this->selector.field = field;
-   this->type = (var != NULL)
-      ? var->type->field_type(field) : glsl_type::error_type;
+   this->type = (this->var != NULL)
+      ? this->var->type->field_type(field) : glsl_type::error_type;
 }
 
+
 bool
 ir_dereference::is_lvalue()
 {
-   if (var == NULL)
-      return false;
-
-   ir_variable *const as_var = var->as_variable();
-   if (mode == ir_reference_variable) {
-      if (as_var == NULL)
-        return false;
-
-      if (as_var->type->is_array() && !as_var->array_lvalue)
-        return false;
-   }
-
-   if (as_var != NULL)
-      return !as_var->read_only;
+   ir_variable *var = this->variable_referenced();
 
-   /* Walk up the dereference chain and figure out if the variable is read-only.
+   /* Every l-value derference chain eventually ends in a variable.
     */
-   return this->var->as_rvalue()->is_lvalue();
-}
-
+   if ((var == NULL) || var->read_only)
+      return false;
 
-ir_variable *
-ir_dereference::variable_referenced()
-{
-   /* Walk down the dereference chain to find the variable at the end.
-    *
-    * This could be implemented recurrsively, but it would still need to call
-    * as_variable and as_rvalue, so the code wouldn't be any cleaner.
-    */
-   for (ir_instruction *current = this->var; current != NULL; /* empty */ ) {
-      ir_dereference *deref;
-      ir_variable *v;
-
-      if ((deref = current->as_dereference())) {
-        current = deref->var;
-      } else if ((v = current->as_variable())) {
-        return v;
-      } else {
-        /* This is the case of, for example, an array dereference of the
-         * value returned by a function call.
-         */
-        return NULL;
-      }
-   }
+   if (this->type->is_array() && !var->array_lvalue)
+      return false;
 
-   assert(!"Should not get here.");
-   return NULL;
+   return true;
 }
 
 
diff --git a/ir.h b/ir.h
index 93b4c2b66aba855fd5880a140e29b9c2fefbe0ea..70fe9f9db6f82addd96bed5d9a3001eadd1405bb 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -788,12 +788,6 @@ public:
 
 class ir_dereference : public ir_rvalue {
 public:
-   ir_dereference(struct ir_instruction *);
-
-   ir_dereference(ir_instruction *variable, ir_rvalue *array_index);
-
-   ir_dereference(ir_instruction *variable, const char *field);
-
    virtual ir_dereference *as_dereference()
    {
       return this;
@@ -811,9 +805,9 @@ public:
    /**
     * Get the variable that is ultimately referenced by an r-value
     */
-   virtual ir_variable *variable_referenced();
+   virtual ir_variable *variable_referenced() = 0;
 
-   enum {
+   enum ir_deref_mode {
       ir_reference_variable,
       ir_reference_array,
       ir_reference_record
@@ -830,6 +824,63 @@ public:
       ir_rvalue *array_index;
       const char *field;
    } selector;
+
+protected:
+   ir_dereference(ir_deref_mode mode)
+      : mode(mode)
+   {
+      /* empty */
+   }
+};
+
+
+class ir_dereference_variable : public ir_dereference {
+public:
+   ir_dereference_variable(ir_variable *var);
+
+   /**
+    * Get the variable that is ultimately referenced by an r-value
+    */
+   virtual ir_variable *variable_referenced()
+   {
+      return (ir_variable *) this->var;
+   }
+};
+
+
+class ir_dereference_array : public ir_dereference {
+public:
+   ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index);
+
+   ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
+
+   /**
+    * Get the variable that is ultimately referenced by an r-value
+    */
+   virtual ir_variable *variable_referenced()
+   {
+      return ((ir_rvalue *) this->var)->variable_referenced();
+   }
+
+
+private:
+   void set_array(ir_rvalue *value);
+};
+
+
+class ir_dereference_record : public ir_dereference {
+public:
+   ir_dereference_record(ir_rvalue *value, const char *field);
+
+   ir_dereference_record(ir_variable *var, const char *field);
+
+   /**
+    * Get the variable that is ultimately referenced by an r-value
+    */
+   virtual ir_variable *variable_referenced()
+   {
+      return ((ir_rvalue *) this->var)->variable_referenced();
+   }
 };
 
 
index 28c96a787ded19521a8515fd78ead41a9c2518bb..9494786d4e4d4226a6e93e5b2c5e375752df364d 100644 (file)
@@ -143,12 +143,12 @@ ir_expression_flattening_visitor::visit(ir_expression *ir)
         var = new ir_variable(ir->operands[operand]->type, "flattening_tmp");
         this->base_ir->insert_before(var);
 
-        assign = new ir_assignment(new ir_dereference(var),
+        assign = new ir_assignment(new ir_dereference_variable(var),
                                    ir->operands[operand],
                                    NULL);
         this->base_ir->insert_before(assign);
 
-        ir->operands[operand] = new ir_dereference(var);
+        ir->operands[operand] = new ir_dereference_variable(var);
       }
    }
 }
index 09604c04df9e71f5ba0d42ccc3a9e909896d2421..499ce5f1dc2f6ab4aa6fa5f4edfaea6a6f6ef771 100644 (file)
@@ -220,28 +220,27 @@ ir_function_cloning_visitor::visit(ir_swizzle *ir)
 void
 ir_function_cloning_visitor::visit(ir_dereference *ir)
 {
-   ir_variable *old_var = ir->var->as_variable();
-   ir_instruction *var;
-
-   if (old_var)
-      var = this->get_remapped_variable(old_var);
-   else {
-      ir->var->accept(this);
-      var = this->result;
-   }
-
    if (ir->mode == ir_dereference::ir_reference_variable) {
-      this->result = new ir_dereference(var);
+      ir_variable *var = this->get_remapped_variable(ir->variable_referenced());
+      this->result = new ir_dereference_variable(var);
    } else if (ir->mode == ir_dereference::ir_reference_array) {
-      ir_rvalue *index;
+      ir->var->accept(this);
+
+      ir_rvalue *var = this->result->as_rvalue();
 
       ir->selector.array_index->accept(this);
-      index = this->result->as_rvalue();
 
-      this->result = new ir_dereference(var, index);
+      ir_rvalue *index = this->result->as_rvalue();
+
+      this->result = new ir_dereference_array(var, index);
    } else {
       assert(ir->mode == ir_dereference::ir_reference_record);
-      this->result = new ir_dereference(var, strdup(ir->selector.field));
+
+      ir->var->accept(this);
+
+      ir_rvalue *var = this->result->as_rvalue();
+
+      this->result = new ir_dereference_record(var, strdup(ir->selector.field));
    }
 }
 
@@ -300,7 +299,8 @@ ir_function_cloning_visitor::visit(ir_return *ir)
    rval = this->result->as_rvalue();
    assert(rval);
 
-   result = new ir_assignment(new ir_dereference(this->retval), rval, NULL);
+   result = new ir_assignment(new ir_dereference_variable(this->retval), rval,
+                             NULL);
 }
 
 
@@ -406,7 +406,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
          parameters[i]->mode == ir_var_inout) {
         ir_assignment *assign;
 
-        assign = new ir_assignment(new ir_dereference(parameters[i]),
+        assign = new ir_assignment(new ir_dereference_variable(parameters[i]),
                                    param, NULL);
         next_ir->insert_before(assign);
       }
@@ -438,7 +438,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
         ir_assignment *assign;
 
         assign = new ir_assignment(param->as_rvalue(),
-                                   new ir_dereference(parameters[i]),
+                                   new ir_dereference_variable(parameters[i]),
                                    NULL);
         next_ir->insert_before(assign);
       }
@@ -449,7 +449,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
    delete(parameters);
 
    if (retval)
-      return new ir_dereference(retval);
+      return new ir_dereference_variable(retval);
    else
       return NULL;
 }
index 1bf5363f52a084205bbade327b04c268cc7dc1d0..744606d4f2c7a7f0b43e82f1f5c984d05eef1fa1 100644 (file)
@@ -817,7 +817,7 @@ read_constant(_mesa_glsl_parse_state *st, s_list *list)
    return NULL; // should not be reached
 }
 
-static ir_instruction *
+static ir_variable *
 read_dereferencable(_mesa_glsl_parse_state *st, s_expression *expr)
 {
    // Read the subject of a dereference - either a variable name or a swizzle
@@ -828,15 +828,8 @@ read_dereferencable(_mesa_glsl_parse_state *st, s_expression *expr)
         ir_read_error(st, expr, "undeclared variable: %s", var_name->value());
       }
       return var;
-   } else {
-      // Hopefully a (swiz ...)
-      s_list *list = SX_AS_LIST(expr);
-      if (list != NULL && !list->subexpressions.is_empty()) {
-        s_symbol *tag = SX_AS_SYMBOL(list->subexpressions.head);
-        if (tag != NULL && strcmp(tag->value(), "swiz") == 0)
-           return read_swizzle(st, list);
-      }
    }
+
    ir_read_error(st, expr, "expected variable name or (swiz ...)");
    return NULL;
 }
@@ -849,10 +842,10 @@ read_var_ref(_mesa_glsl_parse_state *st, s_list *list)
       return NULL;
    }
    s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
-   ir_instruction *subject = read_dereferencable(st, subj_expr);
+   ir_variable *subject = read_dereferencable(st, subj_expr);
    if (subject == NULL)
       return NULL;
-   return new ir_dereference(subject);
+   return new ir_dereference_variable(subject);
 }
 
 static ir_dereference *
@@ -865,13 +858,13 @@ read_array_ref(_mesa_glsl_parse_state *st, s_list *list)
    }
 
    s_expression *subj_expr = (s_expression*) list->subexpressions.head->next;
-   ir_instruction *subject = read_dereferencable(st, subj_expr);
+   ir_variable *subject = read_dereferencable(st, subj_expr);
    if (subject == NULL)
       return NULL;
 
    s_expression *idx_expr = (s_expression*) subj_expr->next;
    ir_rvalue *idx = read_rvalue(st, idx_expr);
-   return new ir_dereference(subject, idx);
+   return new ir_dereference_array(subject, idx);
 }
 
 static ir_dereference *