Fix 'make check' in src/mapi/glapi/tests when builddir != srcdir
[mesa.git] / src / glsl / ir.h
index 04fa97bf56f43594e454ab924404e2f538c42e56..b898d619b3eaf9b61490f3db8f0b6e8d516e07df 100644 (file)
@@ -34,6 +34,9 @@
 #include "list.h"
 #include "ir_visitor.h"
 #include "ir_hierarchical_visitor.h"
+#include "main/mtypes.h"
+
+#ifdef __cplusplus
 
 /**
  * \defgroup IR Intermediate representation nodes
@@ -78,6 +81,8 @@ enum ir_node_type {
    ir_type_return,
    ir_type_swizzle,
    ir_type_texture,
+   ir_type_emit_vertex,
+   ir_type_end_primitive,
    ir_type_max /**< maximum ir_type enum number, for validation */
 };
 
@@ -87,7 +92,16 @@ enum ir_node_type {
 class ir_instruction : public exec_node {
 public:
    enum ir_node_type ir_type;
-   const struct glsl_type *type;
+
+   /**
+    * GCC 4.7+ and clang warn when deleting an ir_instruction unless
+    * there's a virtual destructor present.  Because we almost
+    * universally use ralloc for our memory management of
+    * ir_instructions, the destructor doesn't need to do any work.
+    */
+   virtual ~ir_instruction()
+   {
+   }
 
    /** ir_print_visitor helper for debugging. */
    void print(void) const;
@@ -110,6 +124,7 @@ public:
    virtual class ir_dereference *       as_dereference()      { return NULL; }
    virtual class ir_dereference_array *        as_dereference_array() { return NULL; }
    virtual class ir_dereference_variable *as_dereference_variable() { return NULL; }
+   virtual class ir_dereference_record *as_dereference_record() { return NULL; }
    virtual class ir_expression *        as_expression()       { return NULL; }
    virtual class ir_rvalue *            as_rvalue()           { return NULL; }
    virtual class ir_loop *              as_loop()             { return NULL; }
@@ -118,24 +133,47 @@ public:
    virtual class ir_return *            as_return()           { return NULL; }
    virtual class ir_if *                as_if()               { return NULL; }
    virtual class ir_swizzle *           as_swizzle()          { return NULL; }
+   virtual class ir_texture *           as_texture()          { return NULL; }
    virtual class ir_constant *          as_constant()         { return NULL; }
    virtual class ir_discard *           as_discard()          { return NULL; }
+   virtual class ir_jump *              as_jump()             { return NULL; }
    /*@}*/
 
+   /**
+    * IR equality method: Return true if the referenced instruction would
+    * return the same value as this one.
+    *
+    * This intended to be used for CSE and algebraic optimizations, on rvalues
+    * in particular.  No support for other instruction types (assignments,
+    * jumps, calls, etc.) is planned.
+    */
+   virtual bool equals(ir_instruction *ir);
+
 protected:
    ir_instruction()
    {
       ir_type = ir_type_unset;
-      type = NULL;
    }
 };
 
 
+/**
+ * The base class for all "values"/expression trees.
+ */
 class ir_rvalue : public ir_instruction {
 public:
-   virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0;
+   const struct glsl_type *type;
+
+   virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const;
+
+   virtual void accept(ir_visitor *v)
+   {
+      v->visit(this);
+   }
+
+   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   virtual ir_constant *constant_expression_value() = 0;
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual ir_rvalue * as_rvalue()
    {
@@ -180,7 +218,8 @@ public:
     * for vector and scalar types that have all elements set to the value
     * zero (or \c false for booleans).
     *
-    * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one
+    * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one,
+    *     ir_constant::is_basis
     */
    virtual bool is_zero() const;
 
@@ -192,7 +231,8 @@ public:
     * for vector and scalar types that have all elements set to the value
     * one (or \c true for booleans).
     *
-    * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one
+    * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one,
+    *     ir_constant::is_basis
     */
    virtual bool is_one() const;
 
@@ -202,12 +242,35 @@ public:
     * The base implementation of this function always returns \c false.  The
     * \c ir_constant class over-rides this function to return \c true \b only
     * for vector and scalar types that have all elements set to the value
-    * negative one.  For boolean times, the result is always \c false.
+    * negative one.  For boolean types, the result is always \c false.
     *
     * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one
+    *     ir_constant::is_basis
     */
    virtual bool is_negative_one() const;
 
+   /**
+    * Determine if an r-value is a basis vector
+    *
+    * The base implementation of this function always returns \c false.  The
+    * \c ir_constant class over-rides this function to return \c true \b only
+    * for vector and scalar types that have one element set to the value one,
+    * and the other elements set to the value zero.  For boolean types, the
+    * result is always \c false.
+    *
+    * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one,
+    *     is_constant::is_negative_one
+    */
+   virtual bool is_basis() const;
+
+
+   /**
+    * Return a generic value of error_type.
+    *
+    * Allocation will be performed with 'mem_ctx' as ralloc owner.
+    */
+   static ir_rvalue *error_value(void *mem_ctx);
+
 protected:
    ir_rvalue();
 };
@@ -219,24 +282,49 @@ protected:
 enum ir_variable_mode {
    ir_var_auto = 0,     /**< Function local variables and globals. */
    ir_var_uniform,      /**< Variable declared as a uniform. */
-   ir_var_in,
-   ir_var_out,
-   ir_var_inout,
+   ir_var_shader_in,
+   ir_var_shader_out,
+   ir_var_function_in,
+   ir_var_function_out,
+   ir_var_function_inout,
    ir_var_const_in,    /**< "in" param that must be a constant expression */
    ir_var_system_value, /**< Ex: front-face, instance-id, etc. */
-   ir_var_temporary    /**< Temporary variable generated during compilation. */
+   ir_var_temporary,   /**< Temporary variable generated during compilation. */
+   ir_var_mode_count   /**< Number of variable modes */
 };
 
-enum ir_variable_interpolation {
-   ir_var_smooth = 0,
-   ir_var_flat,
-   ir_var_noperspective
+/**
+ * Enum keeping track of how a variable was declared.  For error checking of
+ * the gl_PerVertex redeclaration rules.
+ */
+enum ir_var_declaration_type {
+   /**
+    * Normal declaration (for most variables, this means an explicit
+    * declaration.  Exception: temporaries are always implicitly declared, but
+    * they still use ir_var_declared_normally).
+    *
+    * Note: an ir_variable that represents a named interface block uses
+    * ir_var_declared_normally.
+    */
+   ir_var_declared_normally = 0,
+
+   /**
+    * Variable was explicitly declared (or re-declared) in an unnamed
+    * interface block.
+    */
+   ir_var_declared_in_block,
+
+   /**
+    * Variable is an implicitly declared built-in that has not been explicitly
+    * re-declared by the shader.
+    */
+   ir_var_declared_implicitly,
 };
 
 /**
  * \brief Layout qualifiers for gl_FragDepth.
  *
- * The AMD_conservative_depth extension allows gl_FragDepth to be redeclared
+ * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared
  * with a layout qualifier.
  */
 enum ir_depth_layout {
@@ -263,6 +351,22 @@ struct ir_state_slot {
    int swizzle;
 };
 
+
+/**
+ * Get the string value for an interpolation qualifier
+ *
+ * \return The string that would be used in a shader to specify \c
+ * mode will be returned.
+ *
+ * This function is used to generate error messages of the form "shader
+ * uses %s interpolation qualifier", so in the case where there is no
+ * interpolation qualifier, it returns "no".
+ *
+ * This function should only be used on a shader input or output variable.
+ */
+const char *interpolation_string(unsigned interpolation);
+
+
 class ir_variable : public ir_instruction {
 public:
    ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
@@ -283,25 +387,117 @@ public:
 
 
    /**
-    * Get the string value for the interpolation qualifier
+    * Determine how this variable should be interpolated based on its
+    * interpolation qualifier (if present), whether it is gl_Color or
+    * gl_SecondaryColor, and whether flatshading is enabled in the current GL
+    * state.
     *
-    * \return The string that would be used in a shader to specify \c
-    * mode will be returned.
-    *
-    * This function should only be used on a shader input or output variable.
+    * The return value will always be either INTERP_QUALIFIER_SMOOTH,
+    * INTERP_QUALIFIER_NOPERSPECTIVE, or INTERP_QUALIFIER_FLAT.
     */
-   const char *interpolation_string() const;
+   glsl_interp_qualifier determine_interpolation_mode(bool flat_shade);
 
    /**
-    * Calculate the number of slots required to hold this variable
+    * Determine whether or not a variable is part of a uniform block.
+    */
+   inline bool is_in_uniform_block() const
+   {
+      return this->mode == ir_var_uniform && this->interface_type != NULL;
+   }
+
+   /**
+    * Determine whether or not a variable is the declaration of an interface
+    * block
+    *
+    * For the first declaration below, there will be an \c ir_variable named
+    * "instance" whose type and whose instance_type will be the same
+    *  \cglsl_type.  For the second declaration, there will be an \c ir_variable
+    * named "f" whose type is float and whose instance_type is B2.
+    *
+    * "instance" is an interface instance variable, but "f" is not.
+    *
+    * uniform B1 {
+    *     float f;
+    * } instance;
     *
-    * This is used to determine how many uniform or varying locations a variable
-    * occupies.  The count is in units of floating point components.
+    * uniform B2 {
+    *     float f;
+    * };
     */
-   unsigned component_slots() const;
+   inline bool is_interface_instance() const
+   {
+      const glsl_type *const t = this->type;
+
+      return (t == this->interface_type)
+         || (t->is_array() && t->fields.array == this->interface_type);
+    }
+
+   /**
+    * Set this->interface_type on a newly created variable.
+    */
+   void init_interface_type(const struct glsl_type *type)
+   {
+      assert(this->interface_type == NULL);
+      this->interface_type = type;
+      if (this->is_interface_instance()) {
+         this->max_ifc_array_access =
+            rzalloc_array(this, unsigned, type->length);
+      }
+   }
+
+   /**
+    * Change this->interface_type on a variable that previously had a
+    * different, but compatible, interface_type.  This is used during linking
+    * to set the size of arrays in interface blocks.
+    */
+   void change_interface_type(const struct glsl_type *type)
+   {
+      if (this->max_ifc_array_access != NULL) {
+         /* max_ifc_array_access has already been allocated, so make sure the
+          * new interface has the same number of fields as the old one.
+          */
+         assert(this->interface_type->length == type->length);
+      }
+      this->interface_type = type;
+   }
 
    /**
-    * Delcared name of the variable
+    * Change this->interface_type on a variable that previously had a
+    * different, and incompatible, interface_type. This is used during
+    * compilation to handle redeclaration of the built-in gl_PerVertex
+    * interface block.
+    */
+   void reinit_interface_type(const struct glsl_type *type)
+   {
+      if (this->max_ifc_array_access != NULL) {
+#ifndef _NDEBUG
+         /* Redeclaring gl_PerVertex is only allowed if none of the built-ins
+          * it defines have been accessed yet; so it's safe to throw away the
+          * old max_ifc_array_access pointer, since all of its values are
+          * zero.
+          */
+         for (unsigned i = 0; i < this->interface_type->length; i++)
+            assert(this->max_ifc_array_access[i] == 0);
+#endif
+         ralloc_free(this->max_ifc_array_access);
+         this->max_ifc_array_access = NULL;
+      }
+      this->interface_type = NULL;
+      init_interface_type(type);
+   }
+
+   const glsl_type *get_interface_type() const
+   {
+      return this->interface_type;
+   }
+
+   /**
+    * Declared type of the variable
+    */
+   const struct glsl_type *type;
+
+   /**
+    * Declared name of the variable
     */
    const char *name;
 
@@ -312,6 +508,19 @@ public:
     */
    unsigned max_array_access;
 
+   /**
+    * For variables which satisfy the is_interface_instance() predicate, this
+    * points to an array of integers such that if the ith member of the
+    * interface block is an array, max_ifc_array_access[i] is the maximum
+    * array element of that member that has been accessed.  If the ith member
+    * of the interface block is not an array, max_ifc_array_access[i] is
+    * unused.
+    *
+    * For variables whose type is not an interface block, this pointer is
+    * NULL.
+    */
+   unsigned *max_ifc_array_access;
+
    /**
     * Is the variable read-only?
     *
@@ -328,15 +537,36 @@ public:
     * Several GLSL semantic checks require knowledge of whether or not a
     * variable has been used.  For example, it is an error to redeclare a
     * variable as invariant after it has been used.
+    *
+    * This is only maintained in the ast_to_hir.cpp path, not in
+    * Mesa's fixed function or ARB program paths.
     */
    unsigned used:1;
 
+   /**
+    * Has this variable been statically assigned?
+    *
+    * This answers whether the variable was assigned in any path of
+    * the shader during ast_to_hir.  This doesn't answer whether it is
+    * still written after dead code removal, nor is it maintained in
+    * non-ast_to_hir.cpp (GLSL parsing) paths.
+    */
+   unsigned assigned:1;
+
+   /**
+    * Enum indicating how the variable was declared.  See
+    * ir_var_declaration_type.
+    *
+    * This is used to detect certain kinds of illegal variable redeclarations.
+    */
+   unsigned how_declared:2;
+
    /**
     * Storage class of the variable.
     *
     * \sa ir_variable_mode
     */
-   unsigned mode:3;
+   unsigned mode:4;
 
    /**
     * Interpolation mode for shader inputs / outputs
@@ -345,14 +575,6 @@ public:
     */
    unsigned interpolation:2;
 
-   /**
-    * Flag that the whole array is assignable
-    *
-    * In GLSL 1.20 and later whole arrays are assignable (and comparable for
-    * equality).  This flag enables this behavior.
-    */
-   unsigned array_lvalue:1;
-
    /**
     * \name ARB_fragment_coord_conventions
     * @{
@@ -361,14 +583,6 @@ public:
    unsigned pixel_center_integer:1;
    /*@}*/
 
-   /**
-    * \brief Layout qualifier for gl_FragDepth.
-    *
-    * This is not equal to \c ir_depth_layout_none if and only if this
-    * variable is \c gl_FragDepth and a layout qualifier is specified.
-    */
-   ir_depth_layout depth_layout;
-
    /**
     * Was the location explicitly set in the shader?
     *
@@ -377,6 +591,67 @@ public:
     * no effect).
     */
    unsigned explicit_location:1;
+   unsigned explicit_index:1;
+
+   /**
+    * Was an initial binding explicitly set in the shader?
+    *
+    * If so, constant_value contains an integer ir_constant representing the
+    * initial binding point.
+    */
+   unsigned explicit_binding:1;
+
+   /**
+    * Does this variable have an initializer?
+    *
+    * This is used by the linker to cross-validiate initializers of global
+    * variables.
+    */
+   unsigned has_initializer:1;
+
+   /**
+    * Is this variable a generic output or input that has not yet been matched
+    * up to a variable in another stage of the pipeline?
+    *
+    * This is used by the linker as scratch storage while assigning locations
+    * to generic inputs and outputs.
+    */
+   unsigned is_unmatched_generic_inout:1;
+
+   /**
+    * If non-zero, then this variable may be packed along with other variables
+    * into a single varying slot, so this offset should be applied when
+    * accessing components.  For example, an offset of 1 means that the x
+    * component of this variable is actually stored in component y of the
+    * location specified by \c location.
+    */
+   unsigned location_frac:2;
+
+   /**
+    * Non-zero if this variable was created by lowering a named interface
+    * block which was not an array.
+    *
+    * Note that this variable and \c from_named_ifc_block_array will never
+    * both be non-zero.
+    */
+   unsigned from_named_ifc_block_nonarray:1;
+
+   /**
+    * Non-zero if this variable was created by lowering a named interface
+    * block which was an array.
+    *
+    * Note that this variable and \c from_named_ifc_block_nonarray will never
+    * both be non-zero.
+    */
+   unsigned from_named_ifc_block_array:1;
+
+   /**
+    * \brief Layout qualifier for gl_FragDepth.
+    *
+    * This is not equal to \c ir_depth_layout_none if and only if this
+    * variable is \c gl_FragDepth and a layout qualifier is specified.
+    */
+   ir_depth_layout depth_layout;
 
    /**
     * Storage location of the base of this variable
@@ -384,10 +659,13 @@ public:
     * The precise meaning of this field depends on the nature of the variable.
     *
     *   - Vertex shader input: one of the values from \c gl_vert_attrib.
-    *   - Vertex shader output: one of the values from \c gl_vert_result.
-    *   - Fragment shader input: one of the values from \c gl_frag_attrib.
+    *   - Vertex shader output: one of the values from \c gl_varying_slot.
+    *   - Geometry shader input: one of the values from \c gl_varying_slot.
+    *   - Geometry shader output: one of the values from \c gl_varying_slot.
+    *   - Fragment shader input: one of the values from \c gl_varying_slot.
     *   - Fragment shader output: one of the values from \c gl_frag_result.
-    *   - Uniforms: Per-stage uniform slot number.
+    *   - Uniforms: Per-stage uniform slot number for default uniform block.
+    *   - Uniforms: Index within the uniform block definition for UBO members.
     *   - Other: This field is not currently used.
     *
     * If the variable is a uniform, shader input, or shader output, and the
@@ -395,6 +673,26 @@ public:
     */
    int location;
 
+   /**
+    * output index for dual source blending.
+    */
+   int index;
+
+   /**
+    * Initial binding point for a sampler or UBO.
+    *
+    * For array types, this represents the binding point for the first element.
+    */
+   int binding;
+
+   /**
+    * Location an atomic counter is stored at.
+    */
+   struct {
+      unsigned buffer_index;
+      unsigned offset;
+   } atomic;
+
    /**
     * Built-in state that backs this uniform
     *
@@ -420,8 +718,32 @@ public:
     * Value assigned in the initializer of a variable declared "const"
     */
    ir_constant *constant_value;
+
+   /**
+    * Constant expression assigned in the initializer of the variable
+    *
+    * \warning
+    * This field and \c ::constant_value are distinct.  Even if the two fields
+    * refer to constants with the same value, they must point to separate
+    * objects.
+    */
+   ir_constant *constant_initializer;
+
+private:
+   /**
+    * For variables that are in an interface block or are an instance of an
+    * interface block, this is the \c GLSL_TYPE_INTERFACE type for that block.
+    *
+    * \sa ir_variable::location
+    */
+   const glsl_type *interface_type;
 };
 
+/**
+ * A function that returns whether a built-in function is available in the
+ * current shading language (based on version, ES or desktop, and extensions).
+ */
+typedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *);
 
 /*@{*/
 /**
@@ -433,7 +755,8 @@ class ir_function_signature : public ir_instruction {
     * an ir_function.
     */
 public:
-   ir_function_signature(const glsl_type *return_type);
+   ir_function_signature(const glsl_type *return_type,
+                         builtin_available_predicate builtin_avail = NULL);
 
    virtual ir_function_signature *clone(void *mem_ctx,
                                        struct hash_table *ht) const;
@@ -447,6 +770,13 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
+   /**
+    * Attempt to evaluate this function as a constant expression,
+    * given a list of the actual parameters and the variable context.
+    * Returns NULL for non-built-ins.
+    */
+   ir_constant *constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context);
+
    /**
     * Get the name of the function for which this is a signature
     */
@@ -502,16 +832,49 @@ public:
    unsigned is_defined:1;
 
    /** Whether or not this function signature is a built-in. */
-   unsigned is_builtin:1;
+   bool is_builtin() const;
+
+   /**
+    * Whether or not this function is an intrinsic to be implemented
+    * by the driver.
+    */
+   bool is_intrinsic;
+
+   /** Whether or not a built-in is available for this shader. */
+   bool is_builtin_available(const _mesa_glsl_parse_state *state) const;
 
    /** Body of instructions in the function. */
    struct exec_list body;
 
 private:
+   /**
+    * A function pointer to a predicate that answers whether a built-in
+    * function is available in the current shader.  NULL if not a built-in.
+    */
+   builtin_available_predicate builtin_avail;
+
    /** Function of which this signature is one overload. */
    class ir_function *_function;
 
+   /** Function signature of which this one is a prototype clone */
+   const ir_function_signature *origin;
+
    friend class ir_function;
+
+   /**
+    * Helper function to run a list of instructions for constant
+    * expression evaluation.
+    *
+    * The hash table represents the values of the visible variables.
+    * There are no scoping issues because the table is indexed on
+    * ir_variable pointers, not variable names.
+    *
+    * Returns false if the expression is not constant, true otherwise,
+    * and the value in *result if result is non-NULL.
+    */
+   bool constant_expression_evaluate_expression_list(const struct exec_list &body,
+                                                    struct hash_table *variable_context,
+                                                    ir_constant **result);
 };
 
 
@@ -552,17 +915,27 @@ public:
       return signatures.iterator();
    }
 
+   /**
+    * Find a signature that matches a set of actual parameters, taking implicit
+    * conversions into account.  Also flags whether the match was exact.
+    */
+   ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
+                                             const exec_list *actual_param,
+                                            bool *match_is_exact);
+
    /**
     * Find a signature that matches a set of actual parameters, taking implicit
     * conversions into account.
     */
-   ir_function_signature *matching_signature(const exec_list *actual_param);
+   ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
+                                             const exec_list *actual_param);
 
    /**
     * Find a signature that exactly matches a set of actual parameters without
     * any implicit type conversions.
     */
-   ir_function_signature *exact_matching_signature(const exec_list *actual_ps);
+   ir_function_signature *exact_matching_signature(_mesa_glsl_parse_state *state,
+                                                   const exec_list *actual_ps);
 
    /**
     * Name of the function.
@@ -659,13 +1032,33 @@ public:
     * If \c from and \c to are the same value, the loop will execute once.
     */
    /*@{*/
-   ir_rvalue *from;             /** Value of the loop counter on the first
-                                * iteration of the loop.
-                                */
-   ir_rvalue *to;               /** Value of the loop counter on the last
-                                * iteration of the loop.
-                                */
+
+   /**
+    * Value which should be assigned to \c counter before the first iteration
+    * of the loop.  Must be non-null whenever \c counter is non-null, and vice
+    * versa.
+    */
+   ir_rvalue *from;
+
+   /**
+    * Value which \c counter should be compared to in order to determine
+    * whether to exit the loop.  Must be non-null whenever \c counter is
+    * non-null, and vice versa.
+    */
+   ir_rvalue *to;
+
+   /**
+    * Value which should be added to \c counter at the end of each loop
+    * iteration.  Must be non-null whenever \c counter is non-null, and vice
+    * versa.
+    */
    ir_rvalue *increment;
+
+   /**
+    * Variable which counts loop iterations.  This is a brand new ir_variable
+    * declaration (not a reference to a previously declared ir_variable, as in
+    * ir_dereference_variable).
+    */
    ir_variable *counter;
 
    /**
@@ -674,6 +1067,8 @@ public:
     * If any of the loop control fields are non-\c NULL, this field must be
     * one of \c ir_binop_less, \c ir_binop_greater, \c ir_binop_lequal,
     * \c ir_binop_gequal, \c ir_binop_equal, or \c ir_binop_nequal.
+    *
+    * Ignored if \c counter is NULL.
     */
    int cmp;
    /*@}*/
@@ -696,7 +1091,7 @@ public:
 
    virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -766,7 +1161,7 @@ public:
    unsigned write_mask:4;
 };
 
-/* Update ir_expression::num_operands() and operator_strs when
+/* Update ir_expression::get_num_operands() and operator_strs when
  * updating this list.
  */
 enum ir_expression_operation {
@@ -778,19 +1173,24 @@ enum ir_expression_operation {
    ir_unop_rcp,
    ir_unop_rsq,
    ir_unop_sqrt,
-   ir_unop_exp,      /**< Log base e on gentype */
-   ir_unop_log,             /**< Natural log on gentype */
+   ir_unop_exp,         /**< Log base e on gentype */
+   ir_unop_log,                /**< Natural log on gentype */
    ir_unop_exp2,
    ir_unop_log2,
-   ir_unop_f2i,      /**< Float-to-integer conversion. */
-   ir_unop_i2f,      /**< Integer-to-float conversion. */
-   ir_unop_f2b,      /**< Float-to-boolean conversion */
-   ir_unop_b2f,      /**< Boolean-to-float conversion */
-   ir_unop_i2b,      /**< int-to-boolean conversion */
-   ir_unop_b2i,      /**< Boolean-to-int conversion */
-   ir_unop_u2f,      /**< Unsigned-to-float conversion. */
-   ir_unop_i2u,      /**< Integer-to-unsigned conversion. */
-   ir_unop_u2i,      /**< Unsigned-to-integer conversion. */
+   ir_unop_f2i,         /**< Float-to-integer conversion. */
+   ir_unop_f2u,         /**< Float-to-unsigned conversion. */
+   ir_unop_i2f,         /**< Integer-to-float conversion. */
+   ir_unop_f2b,         /**< Float-to-boolean conversion */
+   ir_unop_b2f,         /**< Boolean-to-float conversion */
+   ir_unop_i2b,         /**< int-to-boolean conversion */
+   ir_unop_b2i,         /**< Boolean-to-int conversion */
+   ir_unop_u2f,         /**< Unsigned-to-float conversion. */
+   ir_unop_i2u,         /**< Integer-to-unsigned conversion. */
+   ir_unop_u2i,         /**< Unsigned-to-integer conversion. */
+   ir_unop_bitcast_i2f, /**< Bit-identical int-to-float "conversion" */
+   ir_unop_bitcast_f2i, /**< Bit-identical float-to-int "conversion" */
+   ir_unop_bitcast_u2f, /**< Bit-identical uint-to-float "conversion" */
+   ir_unop_bitcast_f2u, /**< Bit-identical float-to-uint "conversion" */
    ir_unop_any,
 
    /**
@@ -822,6 +1222,42 @@ enum ir_expression_operation {
    ir_unop_dFdy,
    /*@}*/
 
+   /**
+    * \name Floating point pack and unpack operations.
+    */
+   /*@{*/
+   ir_unop_pack_snorm_2x16,
+   ir_unop_pack_snorm_4x8,
+   ir_unop_pack_unorm_2x16,
+   ir_unop_pack_unorm_4x8,
+   ir_unop_pack_half_2x16,
+   ir_unop_unpack_snorm_2x16,
+   ir_unop_unpack_snorm_4x8,
+   ir_unop_unpack_unorm_2x16,
+   ir_unop_unpack_unorm_4x8,
+   ir_unop_unpack_half_2x16,
+   /*@}*/
+
+   /**
+    * \name Lowered floating point unpacking operations.
+    *
+    * \see lower_packing_builtins_visitor::split_unpack_half_2x16
+    */
+   /*@{*/
+   ir_unop_unpack_half_2x16_split_x,
+   ir_unop_unpack_half_2x16_split_y,
+   /*@}*/
+
+   /**
+    * \name Bit operations, part of ARB_gpu_shader5.
+    */
+   /*@{*/
+   ir_unop_bitfield_reverse,
+   ir_unop_bit_count,
+   ir_unop_find_msb,
+   ir_unop_find_lsb,
+   /*@}*/
+
    ir_unop_noise,
 
    /**
@@ -831,9 +1267,25 @@ enum ir_expression_operation {
 
    ir_binop_add,
    ir_binop_sub,
-   ir_binop_mul,
+   ir_binop_mul,       /**< Floating-point or low 32-bit integer multiply. */
+   ir_binop_imul_high, /**< Calculates the high 32-bits of a 64-bit multiply. */
    ir_binop_div,
 
+   /**
+    * Returns the carry resulting from the addition of the two arguments.
+    */
+   /*@{*/
+   ir_binop_carry,
+   /*@}*/
+
+   /**
+    * Returns the borrow resulting from the subtraction of the second argument
+    * from the first argument.
+    */
+   /*@{*/
+   ir_binop_borrow,
+   /*@}*/
+
    /**
     * Takes one of two combinations of arguments:
     *
@@ -888,54 +1340,154 @@ enum ir_expression_operation {
 
    ir_binop_pow,
 
+   /**
+    * \name Lowered floating point packing operations.
+    *
+    * \see lower_packing_builtins_visitor::split_pack_half_2x16
+    */
+   /*@{*/
+   ir_binop_pack_half_2x16_split,
+   /*@}*/
+
+   /**
+    * \name First half of a lowered bitfieldInsert() operation.
+    *
+    * \see lower_instructions::bitfield_insert_to_bfm_bfi
+    */
+   /*@{*/
+   ir_binop_bfm,
+   /*@}*/
+
+   /**
+    * Load a value the size of a given GLSL type from a uniform block.
+    *
+    * operand0 is the ir_constant uniform block index in the linked shader.
+    * operand1 is a byte offset within the uniform block.
+    */
+   ir_binop_ubo_load,
+
+   /**
+    * \name Multiplies a number by two to a power, part of ARB_gpu_shader5.
+    */
+   /*@{*/
+   ir_binop_ldexp,
+   /*@}*/
+
+   /**
+    * Extract a scalar from a vector
+    *
+    * operand0 is the vector
+    * operand1 is the index of the field to read from operand0
+    */
+   ir_binop_vector_extract,
+
    /**
     * A sentinel marking the last of the binary operations.
     */
-   ir_last_binop = ir_binop_pow,
+   ir_last_binop = ir_binop_vector_extract,
+
+   /**
+    * \name Fused floating-point multiply-add, part of ARB_gpu_shader5.
+    */
+   /*@{*/
+   ir_triop_fma,
+   /*@}*/
+
+   ir_triop_lrp,
+
+   /**
+    * \name Conditional Select
+    *
+    * A vector conditional select instruction (like ?:, but operating per-
+    * component on vectors).
+    *
+    * \see lower_instructions_visitor::ldexp_to_arith
+    */
+   /*@{*/
+   ir_triop_csel,
+   /*@}*/
+
+   /**
+    * \name Second half of a lowered bitfieldInsert() operation.
+    *
+    * \see lower_instructions::bitfield_insert_to_bfm_bfi
+    */
+   /*@{*/
+   ir_triop_bfi,
+   /*@}*/
+
+   ir_triop_bitfield_extract,
+
+   /**
+    * Generate a value with one field of a vector changed
+    *
+    * operand0 is the vector
+    * operand1 is the value to write into the vector result
+    * operand2 is the index in operand0 to be modified
+    */
+   ir_triop_vector_insert,
+
+   /**
+    * A sentinel marking the last of the ternary operations.
+    */
+   ir_last_triop = ir_triop_vector_insert,
+
+   ir_quadop_bitfield_insert,
 
    ir_quadop_vector,
 
+   /**
+    * A sentinel marking the last of the ternary operations.
+    */
+   ir_last_quadop = ir_quadop_vector,
+
    /**
     * A sentinel marking the last of all operations.
     */
-   ir_last_opcode = ir_last_binop
+   ir_last_opcode = ir_quadop_vector
 };
 
 class ir_expression : public ir_rvalue {
 public:
+   ir_expression(int op, const struct glsl_type *type,
+                 ir_rvalue *op0, ir_rvalue *op1 = NULL,
+                 ir_rvalue *op2 = NULL, ir_rvalue *op3 = NULL);
+
    /**
     * Constructor for unary operation expressions
     */
-   ir_expression(int op, const struct glsl_type *type, ir_rvalue *);
    ir_expression(int op, ir_rvalue *);
 
    /**
     * Constructor for binary operation expressions
     */
-   ir_expression(int op, const struct glsl_type *type,
-                ir_rvalue *, ir_rvalue *);
    ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
 
    /**
-    * Constructor for quad operator expressions
+    * Constructor for ternary operation expressions
     */
-   ir_expression(int op, const struct glsl_type *type,
-                ir_rvalue *, ir_rvalue *, ir_rvalue *, ir_rvalue *);
+   ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2);
 
    virtual ir_expression *as_expression()
    {
       return this;
    }
 
+   virtual bool equals(ir_instruction *ir);
+
    virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
 
    /**
     * Attempt to constant-fold the expression
     *
+    * The "variable_context" hash table links ir_variable * to ir_constant *
+    * that represent the variables' values.  \c NULL represents an empty
+    * context.
+    *
     * If the expression cannot be constant folded, this method will return
     * \c NULL.
     */
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    /**
     * Determine the number of operands used by an expression
@@ -980,23 +1532,25 @@ public:
 
 
 /**
- * IR instruction representing a function call
+ * HIR instruction representing a high-level function call, containing a list
+ * of parameters and returning a value in the supplied temporary.
  */
-class ir_call : public ir_rvalue {
+class ir_call : public ir_instruction {
 public:
-   ir_call(ir_function_signature *callee, exec_list *actual_parameters)
-      : callee(callee)
+   ir_call(ir_function_signature *callee,
+          ir_dereference_variable *return_deref,
+          exec_list *actual_parameters)
+      : return_deref(return_deref), callee(callee)
    {
       ir_type = ir_type_call;
       assert(callee->return_type != NULL);
-      type = callee->return_type;
       actual_parameters->move_nodes_to(& this->actual_parameters);
-      this->use_builtin = callee->is_builtin;
+      this->use_builtin = callee->is_builtin();
    }
 
    virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual ir_call *as_call()
    {
@@ -1010,13 +1564,6 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   /**
-    * Get a generic ir_call object when an error occurs
-    *
-    * Any allocation will be performed with 'ctx' as ralloc owner.
-    */
-   static ir_call *get_error_instruction(void *ctx);
-
    /**
     * Get an iterator for the set of acutal parameters
     */
@@ -1034,38 +1581,27 @@ public:
    }
 
    /**
-    * Get the function signature bound to this function call
+    * Generates an inline version of the function before @ir,
+    * storing the return value in return_deref.
     */
-   ir_function_signature *get_callee()
-   {
-      return callee;
-   }
+   void generate_inline(ir_instruction *ir);
 
    /**
-    * Set the function call target
+    * Storage for the function's return value.
+    * This must be NULL if the return type is void.
     */
-   void set_callee(ir_function_signature *sig);
+   ir_dereference_variable *return_deref;
 
    /**
-    * Generates an inline version of the function before @ir,
-    * returning the return value of the function.
+    * The specific function signature being called.
     */
-   ir_rvalue *generate_inline(ir_instruction *ir);
+   ir_function_signature *callee;
 
    /* List of ir_rvalue of paramaters passed in this call. */
    exec_list actual_parameters;
 
    /** Should this call only bind to a built-in function? */
    bool use_builtin;
-
-private:
-   ir_call()
-      : callee(NULL)
-   {
-      this->ir_type = ir_type_call;
-   }
-
-   ir_function_signature *callee;
 };
 
 
@@ -1081,6 +1617,12 @@ protected:
    {
       ir_type = ir_type_unset;
    }
+
+public:
+   virtual ir_jump *as_jump()
+   {
+      return this;
+   }
 };
 
 class ir_return : public ir_jump {
@@ -1139,7 +1681,6 @@ public:
    {
       this->ir_type = ir_type_loop_jump;
       this->mode = mode;
-      this->loop = loop;
    }
 
    virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const;
@@ -1163,9 +1704,6 @@ public:
 
    /** Mode selector for the jump instruction. */
    enum jump_mode mode;
-private:
-   /** Loop containing this break instruction. */
-   ir_loop *loop;
 };
 
 /**
@@ -1212,7 +1750,12 @@ enum ir_texture_opcode {
    ir_txb,             /**< Texture look-up with LOD bias */
    ir_txl,             /**< Texture look-up with explicit LOD */
    ir_txd,             /**< Texture look-up with partial derivatvies */
-   ir_txf              /**< Texel fetch with explicit LOD */
+   ir_txf,             /**< Texel fetch with explicit LOD */
+   ir_txf_ms,           /**< Multisample texture fetch */
+   ir_txs,             /**< Texture size */
+   ir_lod,             /**< Texture lod query */
+   ir_tg4,             /**< Texture gather */
+   ir_query_levels      /**< Texture levels query */
 };
 
 
@@ -1233,26 +1776,41 @@ enum ir_texture_opcode {
  * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>)
  * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
  * (txf <type> <sampler> <coordinate> 0       <lod>)
+ * (txf_ms
+ *      <type> <sampler> <coordinate>         <sample_index>)
+ * (txs <type> <sampler> <lod>)
+ * (lod <type> <sampler> <coordinate>)
+ * (tg4 <type> <sampler> <coordinate> <offset> <component>)
+ * (query_levels <type> <sampler>)
  */
 class ir_texture : public ir_rvalue {
 public:
    ir_texture(enum ir_texture_opcode op)
-      : op(op), projector(NULL), shadow_comparitor(NULL), offset(NULL)
+      : op(op), sampler(NULL), coordinate(NULL), projector(NULL),
+        shadow_comparitor(NULL), offset(NULL)
    {
       this->ir_type = ir_type_texture;
+      memset(&lod_info, 0, sizeof(lod_info));
    }
 
    virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
    }
 
+   virtual ir_texture *as_texture()
+   {
+      return this;
+   }
+
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
+   virtual bool equals(ir_instruction *ir);
+
    /**
     * Return a string representing the ir_texture_opcode.
     */
@@ -1297,6 +1855,8 @@ public:
    union {
       ir_rvalue *lod;          /**< Floating point LOD */
       ir_rvalue *bias;         /**< Floating point LOD bias */
+      ir_rvalue *sample_index;  /**< MSAA sample index */
+      ir_rvalue *component;     /**< Gather component selector */
       struct {
         ir_rvalue *dPdx;       /**< Partial derivative of coordinate wrt X */
         ir_rvalue *dPdy;       /**< Partial derivative of coordinate wrt Y */
@@ -1336,7 +1896,7 @@ public:
 
    virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual ir_swizzle *as_swizzle()
    {
@@ -1355,6 +1915,8 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
+   virtual bool equals(ir_instruction *ir);
+
    bool is_lvalue() const
    {
       return val->is_lvalue() && !mask.has_duplicates;
@@ -1393,6 +1955,15 @@ public:
     * Get the variable that is ultimately referenced by an r-value
     */
    virtual ir_variable *variable_referenced() const = 0;
+
+   /**
+    * Get the constant that is ultimately referenced by an r-value,
+    * in a constant expression evaluation context.
+    *
+    * The offset is used when the reference is to a specific column of
+    * a matrix.
+    */
+  virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const = 0;
 };
 
 
@@ -1403,13 +1974,15 @@ public:
    virtual ir_dereference_variable *clone(void *mem_ctx,
                                          struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual ir_dereference_variable *as_dereference_variable()
    {
       return this;
    }
 
+   virtual bool equals(ir_instruction *ir);
+
    /**
     * Get the variable that is ultimately referenced by an r-value
     */
@@ -1418,6 +1991,15 @@ public:
       return this->var;
    }
 
+   /**
+    * Get the constant that is ultimately referenced by an r-value,
+    * in a constant expression evaluation context.
+    *
+    * The offset is used when the reference is to a specific column of
+    * a matrix.
+    */
+   virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const;
+
    virtual ir_variable *whole_variable_referenced()
    {
       /* ir_dereference_variable objects always dereference the entire
@@ -1452,13 +2034,15 @@ public:
    virtual ir_dereference_array *clone(void *mem_ctx,
                                       struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual ir_dereference_array *as_dereference_array()
    {
       return this;
    }
 
+   virtual bool equals(ir_instruction *ir);
+
    /**
     * Get the variable that is ultimately referenced by an r-value
     */
@@ -1467,6 +2051,15 @@ public:
       return this->array->variable_referenced();
    }
 
+   /**
+    * Get the constant that is ultimately referenced by an r-value,
+    * in a constant expression evaluation context.
+    *
+    * The offset is used when the reference is to a specific column of
+    * a matrix.
+    */
+   virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const;
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -1491,7 +2084,12 @@ public:
    virtual ir_dereference_record *clone(void *mem_ctx,
                                        struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+
+   virtual ir_dereference_record *as_dereference_record()
+   {
+      return this;
+   }
 
    /**
     * Get the variable that is ultimately referenced by an r-value
@@ -1501,6 +2099,15 @@ public:
       return this->record->variable_referenced();
    }
 
+   /**
+    * Get the constant that is ultimately referenced by an r-value,
+    * in a constant expression evaluation context.
+    *
+    * The offset is used when the reference is to a specific column of
+    * a matrix.
+    */
+   virtual void constant_referenced(struct hash_table *variable_context, ir_constant *&store, int &offset) const;
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -1527,10 +2134,10 @@ union ir_constant_data {
 class ir_constant : public ir_rvalue {
 public:
    ir_constant(const struct glsl_type *type, const ir_constant_data *data);
-   ir_constant(bool b);
-   ir_constant(unsigned int u);
-   ir_constant(int i);
-   ir_constant(float f);
+   ir_constant(bool b, unsigned vector_elements=1);
+   ir_constant(unsigned int u, unsigned vector_elements=1);
+   ir_constant(int i, unsigned vector_elements=1);
+   ir_constant(float f, unsigned vector_elements=1);
 
    /**
     * Construct an ir_constant from a list of ir_constant values
@@ -1556,7 +2163,7 @@ public:
 
    virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value();
+   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
 
    virtual ir_constant *as_constant()
    {
@@ -1570,6 +2177,8 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
+   virtual bool equals(ir_instruction *ir);
+
    /**
     * Get a particular component of a constant as a specific type
     *
@@ -1588,17 +2197,43 @@ public:
 
    ir_constant *get_record_field(const char *name);
 
+   /**
+    * Copy the values on another constant at a given offset.
+    *
+    * The offset is ignored for array or struct copies, it's only for
+    * scalars or vectors into vectors or matrices.
+    *
+    * With identical types on both sides and zero offset it's clone()
+    * without creating a new object.
+    */
+
+   void copy_offset(ir_constant *src, int offset);
+
+   /**
+    * Copy the values on another constant at a given offset and
+    * following an assign-like mask.
+    *
+    * The mask is ignored for scalars.
+    *
+    * Note that this function only handles what assign can handle,
+    * i.e. at most a vector as source and a column of a matrix as
+    * destination.
+    */
+
+   void copy_masked_offset(ir_constant *src, int offset, unsigned int mask);
+
    /**
     * Determine whether a constant has the same value as another constant
     *
     * \sa ir_constant::is_zero, ir_constant::is_one,
-    * ir_constant::is_negative_one
+    * ir_constant::is_negative_one, ir_constant::is_basis
     */
    bool has_value(const ir_constant *) const;
 
    virtual bool is_zero() const;
    virtual bool is_one() const;
    virtual bool is_negative_one() const;
+   virtual bool is_basis() const;
 
    /**
     * Value of the constant.
@@ -1624,6 +2259,53 @@ private:
 
 /*@}*/
 
+/**
+ * IR instruction to emit a vertex in a geometry shader.
+ */
+class ir_emit_vertex : public ir_instruction {
+public:
+   ir_emit_vertex()
+   {
+      ir_type = ir_type_emit_vertex;
+   }
+
+   virtual void accept(ir_visitor *v)
+   {
+      v->visit(this);
+   }
+
+   virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *) const
+   {
+      return new(mem_ctx) ir_emit_vertex();
+   }
+
+   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+};
+
+/**
+ * IR instruction to complete the current primitive and start a new one in a
+ * geometry shader.
+ */
+class ir_end_primitive : public ir_instruction {
+public:
+   ir_end_primitive()
+   {
+      ir_type = ir_type_end_primitive;
+   }
+
+   virtual void accept(ir_visitor *v)
+   {
+      v->visit(this);
+   }
+
+   virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *) const
+   {
+      return new(mem_ctx) ir_end_primitive();
+   }
+
+   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
+};
+
 /**
  * Apply a visitor to each IR node in a list
  */
@@ -1677,9 +2359,19 @@ _mesa_glsl_initialize_variables(exec_list *instructions,
 extern void
 _mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state);
 
+extern void
+_mesa_glsl_initialize_builtin_functions();
+
+extern ir_function_signature *
+_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
+                                 const char *name, exec_list *actual_parameters);
+
 extern void
 _mesa_glsl_release_functions(void);
 
+extern void
+_mesa_glsl_release_builtin_functions(void);
+
 extern void
 reparent_ir(exec_list *list, void *mem_ctx);
 
@@ -1693,10 +2385,27 @@ extern bool
 ir_has_call(ir_instruction *ir);
 
 extern void
-do_set_program_inouts(exec_list *instructions, struct gl_program *prog);
+do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
+                      GLenum shader_type);
 
 extern char *
 prototype_string(const glsl_type *return_type, const char *name,
                 exec_list *parameters);
 
+const char *
+mode_string(const ir_variable *var);
+
+extern "C" {
+#endif /* __cplusplus */
+
+extern void _mesa_print_ir(struct exec_list *instructions,
+                           struct _mesa_glsl_parse_state *state);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+unsigned
+vertices_per_prim(GLenum prim);
+
 #endif /* IR_H */