Add new abstract ir_rvalue class; rework accordingly.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 26 Mar 2010 07:25:36 +0000 (00:25 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 26 Mar 2010 20:58:48 +0000 (13:58 -0700)
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
ast.h
ast_function.cpp
ast_to_hir.cpp
glsl_types.cpp
hir_field_selection.cpp
ir.cpp
ir.h
ir_print_visitor.cpp

diff --git a/ast.h b/ast.h
index 5fd69695c1aff2d8c35e986f6922928d64df220f..a158910421d427ae1db1ed2ce86cb0f48d46694c 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -39,8 +39,8 @@ class ast_node : public simple_node {
 public:
    virtual ~ast_node();
    virtual void print(void) const;
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    /**
     * Retrieve the source location of an AST node
@@ -162,8 +162,8 @@ public:
 
    static const char *operator_string(enum ast_operators op);
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    virtual void print(void) const;
 
@@ -219,8 +219,8 @@ public:
       return cons;
    }
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
 private:
    /**
@@ -245,8 +245,8 @@ public:
    ast_compound_statement(int new_scope, ast_node *statements);
    virtual void print(void) const;
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    int new_scope;
    struct simple_node statements;
@@ -401,8 +401,8 @@ public:
    ast_declarator_list(ast_fully_specified_type *);
    virtual void print(void) const;
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    ast_fully_specified_type *type;
    struct simple_node declarations;
@@ -422,8 +422,8 @@ class ast_parameter_declarator : public ast_node {
 public:
    virtual void print(void) const;
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    ast_fully_specified_type *type;
    char *identifier;
@@ -469,8 +469,8 @@ public:
    ast_expression_statement(ast_expression *);
    virtual void print(void) const;
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    ast_expression *expression;
 };
@@ -531,8 +531,8 @@ public:
    ast_jump_statement(int mode, ast_expression *return_value);
    virtual void print(void) const;
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    enum ast_jump_modes {
       ast_continue,
@@ -549,8 +549,8 @@ class ast_function_definition : public ast_node {
 public:
    virtual void print(void) const;
 
-   virtual ir_instruction *hir(exec_list *instructions,
-                              struct _mesa_glsl_parse_state *state);
+   virtual ir_rvalue *hir(exec_list *instructions,
+                         struct _mesa_glsl_parse_state *state);
 
    ast_function *prototype;
    ast_compound_statement *body;
@@ -560,7 +560,7 @@ public:
 extern void
 _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state);
 
-extern struct ir_instruction *
+extern struct ir_rvalue *
 _mesa_ast_field_selection_to_hir(const struct ast_expression *expr,
                                 exec_list *instructions,
                                 struct _mesa_glsl_parse_state *state);
index 7082ed3c1402f92e35dd674943fb8ff5d1494114..f774a2fd776abc07a58cd358572b82348e636b99 100644 (file)
@@ -27,7 +27,7 @@
 #include "glsl_types.h"
 #include "ir.h"
 
-static ir_instruction *
+static ir_rvalue *
 match_function_by_name(exec_list *instructions, const char *name,
                       YYLTYPE *loc, simple_node *parameters,
                       struct _mesa_glsl_parse_state *state)
@@ -78,7 +78,7 @@ match_function_by_name(exec_list *instructions, const char *name,
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_function_expression::hir(exec_list *instructions,
                             struct _mesa_glsl_parse_state *state)
 {
index 5b577d1f56d432eca36370c267e5dbb5d32bfe57..2fd2e53fda307e4a9a20011b44220eb9b1fb4709 100644 (file)
@@ -338,8 +338,8 @@ relational_result_type(const struct glsl_type *type_a,
  * In addition to being used for assignments, this function is used to
  * type-check return values.
  */
-ir_instruction *
-validate_assignment(const glsl_type *lhs_type, ir_instruction *rhs)
+ir_rvalue *
+validate_assignment(const glsl_type *lhs_type, ir_rvalue *rhs)
 {
    const glsl_type *const rhs_type = rhs->type;
 
@@ -361,7 +361,7 @@ validate_assignment(const glsl_type *lhs_type, ir_instruction *rhs)
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_node::hir(exec_list *instructions,
              struct _mesa_glsl_parse_state *state)
 {
@@ -372,7 +372,7 @@ ast_node::hir(exec_list *instructions,
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_expression::hir(exec_list *instructions,
                    struct _mesa_glsl_parse_state *state)
 {
@@ -431,8 +431,8 @@ ast_expression::hir(exec_list *instructions,
       -1,               /* ast_bool_constant doesn't conv to ir_expression. */
       -1,               /* ast_sequence doesn't convert to ir_expression. */
    };
-   ir_instruction *result = NULL;
-   ir_instruction *op[2];
+   ir_rvalue *result = NULL;
+   ir_rvalue *op[2];
    struct simple_node op_list;
    const struct glsl_type *type = glsl_error_type;
    bool error_emitted = false;
@@ -589,8 +589,6 @@ ast_expression::hir(exec_list *instructions,
    case ast_div_assign:
    case ast_add_assign:
    case ast_sub_assign: {
-      struct ir_instruction *temp_rhs;
-
       op[0] = this->subexpressions[0]->hir(instructions, state);
       op[1] = this->subexpressions[1]->hir(instructions, state);
 
@@ -601,8 +599,8 @@ ast_expression::hir(exec_list *instructions,
                                    (this->oper == ast_mul_assign),
                                    state);
 
-      temp_rhs = new ir_expression(operations[this->oper], type,
-                                  op[0], op[1]);
+      ir_rvalue *temp_rhs = new ir_expression(operations[this->oper], type,
+                                             op[0], op[1]);
 
       /* FINISHME: This is copied from ast_assign above.  It should
        * FINISHME: probably be consolidated.
@@ -635,7 +633,7 @@ ast_expression::hir(exec_list *instructions,
         }
       }
 
-      ir_instruction *rhs = validate_assignment(op[0]->type, temp_rhs);
+      ir_rvalue *rhs = validate_assignment(op[0]->type, temp_rhs);
       if (rhs == NULL) {
         type = glsl_error_type;
         rhs = temp_rhs;
@@ -759,7 +757,7 @@ ast_expression::hir(exec_list *instructions,
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_expression_statement::hir(exec_list *instructions,
                              struct _mesa_glsl_parse_state *state)
 {
@@ -781,7 +779,7 @@ ast_expression_statement::hir(exec_list *instructions,
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_compound_statement::hir(exec_list *instructions,
                            struct _mesa_glsl_parse_state *state)
 {
@@ -863,7 +861,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_declarator_list::hir(exec_list *instructions,
                         struct _mesa_glsl_parse_state *state)
 {
@@ -951,7 +949,7 @@ ast_declarator_list::hir(exec_list *instructions,
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_parameter_declarator::hir(exec_list *instructions,
                              struct _mesa_glsl_parse_state *state)
 {
@@ -1038,7 +1036,7 @@ parameter_lists_match(exec_list *list_a, exec_list *list_b)
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_function_definition::hir(exec_list *instructions,
                             struct _mesa_glsl_parse_state *state)
 {
@@ -1183,7 +1181,7 @@ ast_function_definition::hir(exec_list *instructions,
 }
 
 
-ir_instruction *
+ir_rvalue *
 ast_jump_statement::hir(exec_list *instructions,
                        struct _mesa_glsl_parse_state *state)
 {
index f7ef4a302b9152423d8630b2b6fad05c79606376..846761fff678c467f98ae7cfd909bc0ca18b5433 100644 (file)
@@ -190,7 +190,7 @@ generate_vec_body_from_scalar(exec_list *instructions,
 
    retval->set_swizzle(0, 0, 0, 0, declarations[16]->type->vector_elements);
 
-   inst = new ir_return((ir_expression *) retval);
+   inst = new ir_return(retval);
    instructions->push_tail(inst);
 }
 
@@ -222,7 +222,7 @@ generate_vec_body_from_N_scalars(exec_list *instructions,
 
    ir_dereference *retval = new ir_dereference(declarations[16]);
 
-   inst = new ir_return((ir_expression *) retval);
+   inst = new ir_return(retval);
    instructions->push_tail(inst);
 }
 
@@ -300,7 +300,7 @@ generate_mat_body_from_scalar(exec_list *instructions,
    }
 
    ir_dereference *const retval = new ir_dereference(declarations[16]);
-   inst = new ir_return((ir_expression *) retval);
+   inst = new ir_return(retval);
    instructions->push_tail(inst);
 }
 
@@ -342,7 +342,7 @@ generate_mat_body_from_N_scalars(exec_list *instructions,
 
    ir_dereference *retval = new ir_dereference(declarations[16]);
 
-   inst = new ir_return((ir_expression *) retval);
+   inst = new ir_return(retval);
    instructions->push_tail(inst);
 }
 
index 5f548bfa0f87f55e669e3f1f6df4f2475eab4cba..41dbd42d3bf21f7552b60ac44c5b25f6aeec0130 100644 (file)
@@ -106,12 +106,12 @@ generate_swizzle(const char *str, ir_dereference *deref,
 }
 
 
-struct ir_instruction *
+struct ir_rvalue *
 _mesa_ast_field_selection_to_hir(const ast_expression *expr,
                                 exec_list *instructions,
                                 struct _mesa_glsl_parse_state *state)
 {
-   ir_instruction *op;
+   ir_rvalue *op;
    ir_dereference *deref;
    YYLTYPE loc;
 
@@ -128,7 +128,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
     * now.  Doing so prevents spurious error messages from being logged below.
     */
    if (is_error_type(op->type))
-      return (struct ir_instruction *) deref;
+      return deref;
 
    /* There are two kinds of field selection.  There is the selection of a
     * specific field from a structure, and there is the selection of a
@@ -164,5 +164,5 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
                       expr->primary_expression.identifier);
    }
 
-   return (struct ir_instruction *) deref;
+   return deref;
 }
diff --git a/ir.cpp b/ir.cpp
index 0e98f0c8d99b4a8fe8a37f41074eab18b3a25edb..8051fb41330e91a7db60bc3c81af2156b7895f0a 100644 (file)
--- a/ir.cpp
+++ b/ir.cpp
 #include "ir.h"
 #include "glsl_types.h"
 
-ir_assignment::ir_assignment(ir_instruction *lhs, ir_instruction *rhs,
-                            ir_expression *condition)
-   : ir_instruction()
+ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
+                            ir_rvalue *condition)
+   : ir_rvalue()
 {
-   this->lhs = (ir_dereference *) lhs;
+   this->lhs = lhs;
    this->rhs = rhs;
    this->condition = condition;
 }
 
 
 ir_expression::ir_expression(int op, const struct glsl_type *type,
-                            ir_instruction *op0, ir_instruction *op1)
-   : ir_instruction()
+                            ir_rvalue *op0, ir_rvalue *op1)
+   : ir_rvalue()
 {
    this->type = type;
    this->operation = ir_expression_operation(op);
@@ -55,7 +55,7 @@ ir_label::ir_label(const char *label)
 
 
 ir_constant::ir_constant(const struct glsl_type *type, const void *data)
-   : ir_instruction()
+   : ir_rvalue()
 {
    const unsigned elements = 
       ((type->vector_elements == 0) ? 1 : type->vector_elements)
@@ -79,7 +79,7 @@ ir_constant::ir_constant(const struct glsl_type *type, const void *data)
 
 
 ir_dereference::ir_dereference(ir_instruction *var)
-   : ir_instruction()
+   : ir_rvalue()
 {
    this->mode = ir_reference_variable;
    this->var = var;
@@ -88,8 +88,8 @@ ir_dereference::ir_dereference(ir_instruction *var)
 
 
 ir_dereference::ir_dereference(ir_instruction *var,
-                              ir_instruction *array_index)
-   : ir_instruction(), mode(ir_reference_array),
+                              ir_rvalue *array_index)
+   : ir_rvalue(), mode(ir_reference_array),
      var(var)
 {
    this->type = (var != NULL) ? var->type : glsl_error_type;
diff --git a/ir.h b/ir.h
index c21b26a460e8946cc06c8e0ad861c0649a9b74bb..29bc055dd7ab2485ac817ac791b9276df949afc1 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -52,6 +52,7 @@ public:
    /*@{*/
    virtual class ir_variable *          as_variable()         { return NULL; }
    virtual class ir_dereference *       as_dereference()      { return NULL; }
+   virtual class ir_rvalue *            as_rvalue()           { return NULL; }
    /*@}*/
 
 protected:
@@ -62,6 +63,23 @@ protected:
 };
 
 
+class ir_rvalue : public ir_instruction {
+public:
+   virtual ir_rvalue * as_rvalue()
+   {
+      return this;
+   }
+
+   virtual bool is_lvalue()
+   {
+      return false;
+   }
+
+protected:
+   ir_rvalue() : ir_instruction() { }
+};
+
+
 enum ir_variable_mode {
    ir_var_auto = 0,
    ir_var_uniform,
@@ -76,6 +94,7 @@ enum ir_varaible_interpolation {
    ir_var_noperspective
 };
 
+
 class ir_variable : public ir_instruction {
 public:
    ir_variable(const struct glsl_type *, const char *);
@@ -173,10 +192,9 @@ public:
 /*@}*/
 
 
-class ir_assignment : public ir_instruction {
+class ir_assignment : public ir_rvalue {
 public:
-   ir_assignment(ir_instruction *lhs, ir_instruction *rhs,
-                ir_expression *condition);
+   ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
 
    virtual void accept(ir_visitor *v)
    {
@@ -186,19 +204,17 @@ public:
    /**
     * Left-hand side of the assignment.
     */
-   ir_dereference *lhs;
+   ir_rvalue *lhs;
 
    /**
     * Value being assigned
-    *
-    * This should be either \c ir_op_expression or \c ir_op_dereference.
     */
-   ir_instruction *rhs;
+   ir_rvalue *rhs;
 
    /**
     * Optional condition for the assignment.
     */
-   ir_expression *condition;
+   ir_rvalue *condition;
 };
 
 
@@ -264,10 +280,10 @@ enum ir_expression_operation {
    ir_binop_pow
 };
 
-class ir_expression : public ir_instruction {
+class ir_expression : public ir_rvalue {
 public:
    ir_expression(int op, const struct glsl_type *type,
-                ir_instruction *, ir_instruction *);
+                ir_rvalue *, ir_rvalue *);
 
    virtual void accept(ir_visitor *v)
    {
@@ -275,17 +291,17 @@ public:
    }
 
    ir_expression_operation operation;
-   ir_instruction *operands[2];
+   ir_rvalue *operands[2];
 };
 
 
 /**
  * IR instruction representing a function call
  */
-class ir_call : public ir_instruction {
+class ir_call : public ir_rvalue {
 public:
    ir_call(const ir_function_signature *callee, exec_list *actual_parameters)
-      : ir_instruction(), callee(callee)
+      : ir_rvalue(), callee(callee)
    {
       assert(callee->return_type != NULL);
       type = callee->return_type;
@@ -304,7 +320,7 @@ public:
 
 private:
    ir_call()
-      : ir_instruction(), callee(NULL)
+      : ir_rvalue(), callee(NULL)
    {
       /* empty */
    }
@@ -337,13 +353,13 @@ public:
       /* empty */
    }
 
-   ir_return(ir_expression *value)
+   ir_return(ir_rvalue *value)
       : value(value)
    {
       /* empty */
    }
 
-   ir_expression *get_value() const
+   ir_rvalue *get_value() const
    {
       return value;
    }
@@ -354,7 +370,7 @@ public:
    }
 
 private:
-   ir_expression *value;
+   ir_rvalue *value;
 };
 /*@}*/
 
@@ -378,11 +394,11 @@ struct ir_swizzle_mask {
    unsigned has_duplicates:1;
 };
 
-class ir_dereference : public ir_instruction {
+class ir_dereference : public ir_rvalue {
 public:
    ir_dereference(struct ir_instruction *);
 
-   ir_dereference(ir_instruction *variable, ir_instruction *array_index);
+   ir_dereference(ir_instruction *variable, ir_rvalue *array_index);
 
    virtual ir_dereference *as_dereference()
    {
@@ -394,6 +410,11 @@ public:
       v->visit(this);
    }
 
+   bool is_lvalue()
+   {
+      return var != NULL;
+   }
+
    /**
     * Setting the swizzle of a derefernce
     */
@@ -410,19 +431,19 @@ public:
    /**
     * Object being dereferenced.
     *
-    * Must be either an \c ir_variable or an \c ir_dereference.
+    * Must be either an \c ir_variable or an \c ir_rvalue.
     */
    ir_instruction *var;
 
    union {
-      ir_instruction *array_index;
+      ir_rvalue *array_index;
       const char *field;
       struct ir_swizzle_mask swizzle;
    } selector;
 };
 
 
-class ir_constant : public ir_instruction {
+class ir_constant : public ir_rvalue {
 public:
    ir_constant(const struct glsl_type *type, const void *data);
 
index ca9f75925200c0d01d5416326d3d0843481ec0ec..8941d3c7b9fa694842d97217368de14e2304eeab 100644 (file)
@@ -205,7 +205,7 @@ ir_print_visitor::visit(ir_return *ir)
 {
    printf("(return");
 
-   ir_expression *const value = ir->get_value();
+   ir_rvalue *const value = ir->get_value();
    if (value) {
       printf(" ");
       value->accept(this);