mesa: include mtypes.h less
[mesa.git] / src / compiler / glsl / ir.h
index bd7b550634393b825cf1aea5a11d6d67af41e9f0..471d9e787a711b5842716fbdfaedf5ec3d52a505 100644 (file)
@@ -22,7 +22,6 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#pragma once
 #ifndef IR_H
 #define IR_H
 
@@ -34,7 +33,6 @@
 #include "list.h"
 #include "ir_visitor.h"
 #include "ir_hierarchical_visitor.h"
-#include "main/mtypes.h"
 
 #ifdef __cplusplus
 
@@ -230,11 +228,12 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    ir_rvalue *as_rvalue_to_saturate();
 
-   virtual bool is_lvalue() const
+   virtual bool is_lvalue(const struct _mesa_glsl_parse_state *state = NULL) const
    {
       return false;
    }
@@ -397,7 +396,7 @@ depth_layout_string(ir_depth_layout layout);
  * \sa ir_variable::state_slots
  */
 struct ir_state_slot {
-   int tokens[5];
+   gl_state_index16 tokens[STATE_LENGTH];
    int swizzle;
 };
 
@@ -431,17 +430,6 @@ public:
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
 
-   /**
-    * 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.
-    *
-    * The return value will always be either INTERP_QUALIFIER_SMOOTH,
-    * INTERP_QUALIFIER_NOPERSPECTIVE, or INTERP_QUALIFIER_FLAT.
-    */
-   glsl_interp_qualifier determine_interpolation_mode(bool flat_shade);
-
    /**
     * Determine whether or not a variable is part of a uniform or
     * shader storage block.
@@ -468,7 +456,7 @@ public:
     *
     * 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
+    * \c glsl_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.
@@ -486,6 +474,17 @@ public:
       return this->type->without_array() == this->interface_type;
    }
 
+   /**
+    * Return whether this variable contains a bindless sampler/image.
+    */
+   inline bool contains_bindless() const
+   {
+      if (!this->type->contains_sampler() && !this->type->contains_image())
+         return false;
+
+      return this->data.bindless || this->data.mode != ir_var_uniform;
+   }
+
    /**
     * Set this->interface_type on a newly created variable.
     */
@@ -495,7 +494,10 @@ public:
       this->interface_type = type;
       if (this->is_interface_instance()) {
          this->u.max_ifc_array_access =
-            rzalloc_array(this, unsigned, type->length);
+            ralloc_array(this, int, type->length);
+         for (unsigned i = 0; i < type->length; i++) {
+            this->u.max_ifc_array_access[i] = -1;
+         }
       }
    }
 
@@ -531,7 +533,7 @@ public:
           * zero.
           */
          for (unsigned i = 0; i < this->interface_type->length; i++)
-            assert(this->u.max_ifc_array_access[i] == 0);
+            assert(this->u.max_ifc_array_access[i] == -1);
 #endif
          ralloc_free(this->u.max_ifc_array_access);
          this->u.max_ifc_array_access = NULL;
@@ -545,13 +547,17 @@ public:
       return this->interface_type;
    }
 
+   enum glsl_interface_packing get_interface_type_packing() const
+   {
+     return this->interface_type->get_interface_packing();
+   }
    /**
     * Get the max_ifc_array_access pointer
     *
     * A "set" function is not needed because the array is dynmically allocated
     * as necessary.
     */
-   inline unsigned *get_max_ifc_array_access()
+   inline int *get_max_ifc_array_access()
    {
       assert(this->data._num_state_slots == 0);
       return this->u.max_ifc_array_access;
@@ -594,9 +600,17 @@ public:
       return this->u.state_slots;
    }
 
+   inline bool is_interpolation_flat() const
+   {
+      return this->data.interpolation == INTERP_MODE_FLAT ||
+             this->type->contains_integer() ||
+             this->type->contains_double();
+   }
+
    inline bool is_name_ralloced() const
    {
-      return this->name != ir_variable::tmp_name;
+      return this->name != ir_variable::tmp_name &&
+             this->name != this->name_storage;
    }
 
    /**
@@ -621,6 +635,16 @@ public:
     */
    const char *name;
 
+private:
+   /**
+    * If the name length fits into name_storage, it's used, otherwise
+    * the name is ralloc'd. shader-db mining showed that 70% of variables
+    * fit here. This is a win over ralloc where only ralloc_header has
+    * 20 bytes on 64-bit (28 bytes with DEBUG), and we can also skip malloc.
+    */
+   char name_storage[16];
+
+public:
    struct ir_variable_data {
 
       /**
@@ -683,7 +707,7 @@ public:
       /**
        * Interpolation mode for shader inputs / outputs
        *
-       * \sa ir_variable_interpolation
+       * \sa glsl_interp_mode
        */
       unsigned interpolation:2;
 
@@ -713,6 +737,11 @@ public:
        */
       unsigned explicit_binding:1;
 
+      /**
+       * Was an initial component explicitly set in the shader?
+       */
+      unsigned explicit_component:1;
+
       /**
        * Does this variable have an initializer?
        *
@@ -730,6 +759,28 @@ public:
        */
       unsigned is_unmatched_generic_inout:1;
 
+      /**
+       * Is this varying used only by transform feedback?
+       *
+       * This is used by the linker to decide if its safe to pack the varying.
+       */
+      unsigned is_xfb_only:1;
+
+      /**
+       * Was a transfor feedback buffer set in the shader?
+       */
+      unsigned explicit_xfb_buffer:1;
+
+      /**
+       * Was a transfor feedback offset set in the shader?
+       */
+      unsigned explicit_xfb_offset:1;
+
+      /**
+       * Was a transfor feedback stride set in the shader?
+       */
+      unsigned explicit_xfb_stride: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
@@ -746,21 +797,9 @@ public:
 
       /**
        * 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.
+       * block.
        */
-      unsigned from_named_ifc_block_array:1;
+      unsigned from_named_ifc_block:1;
 
       /**
        * Non-zero if the variable must be a shader input. This is useful for
@@ -799,19 +838,40 @@ public:
       ir_depth_layout depth_layout:3;
 
       /**
-       * ARB_shader_image_load_store qualifiers.
+       * Memory qualifiers.
        */
-      unsigned image_read_only:1; /**< "readonly" qualifier. */
-      unsigned image_write_only:1; /**< "writeonly" qualifier. */
-      unsigned image_coherent:1;
-      unsigned image_volatile:1;
-      unsigned image_restrict:1;
+      unsigned memory_read_only:1; /**< "readonly" qualifier. */
+      unsigned memory_write_only:1; /**< "writeonly" qualifier. */
+      unsigned memory_coherent:1;
+      unsigned memory_volatile:1;
+      unsigned memory_restrict:1;
 
       /**
        * ARB_shader_storage_buffer_object
        */
       unsigned from_ssbo_unsized_array:1; /**< unsized array buffer variable. */
 
+      unsigned implicit_sized_array:1;
+
+      /**
+       * Whether this is a fragment shader output implicitly initialized with
+       * the previous contents of the specified render target at the
+       * framebuffer location corresponding to this shader invocation.
+       */
+      unsigned fb_fetch_output:1;
+
+      /**
+       * Non-zero if this variable is considered bindless as defined by
+       * ARB_bindless_texture.
+       */
+      unsigned bindless:1;
+
+      /**
+       * Non-zero if this variable is considered bound as defined by
+       * ARB_bindless_texture.
+       */
+      unsigned bound:1;
+
       /**
        * Emit a warning if this variable is accessed.
        */
@@ -863,22 +923,43 @@ public:
        */
       int location;
 
+      /**
+       * for glsl->tgsi/mesa IR we need to store the index into the
+       * parameters for uniforms, initially the code overloaded location
+       * but this causes problems with indirect samplers and AoA.
+       * This is assigned in _mesa_generate_parameters_list_for_uniforms.
+       */
+      int param_index;
+
       /**
        * Vertex stream output identifier.
+       *
+       * For packed outputs, bit 31 is set and bits [2*i+1,2*i] indicate the
+       * stream of the i-th component.
        */
       unsigned stream;
 
       /**
-       * Location an atomic counter is stored at.
+       * Atomic, transform feedback or block member offset.
        */
       unsigned offset;
 
       /**
        * Highest element accessed with a constant expression array index
        *
-       * Not used for non-array variables.
+       * Not used for non-array variables. -1 is never accessed.
+       */
+      int max_array_access;
+
+      /**
+       * Transform feedback buffer.
+       */
+      unsigned xfb_buffer;
+
+      /**
+       * Transform feedback stride.
        */
-      unsigned max_array_access;
+      unsigned xfb_stride;
 
       /**
        * Allow (only) ir_variable direct access private members.
@@ -916,7 +997,7 @@ private:
        * For variables whose type is not an interface block, this pointer is
        * NULL.
        */
-      unsigned *max_ifc_array_access;
+      int *max_ifc_array_access;
 
       /**
        * Built-in state that backs this uniform
@@ -968,6 +1049,97 @@ public:
  */
 typedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *);
 
+#define MAKE_INTRINSIC_FOR_TYPE(op, t) \
+   ir_intrinsic_generic_ ## op - ir_intrinsic_generic_load + ir_intrinsic_ ## t ## _ ## load
+
+#define MAP_INTRINSIC_TO_TYPE(i, t) \
+   ir_intrinsic_id(int(i) - int(ir_intrinsic_generic_load) + int(ir_intrinsic_ ## t ## _ ## load))
+
+enum ir_intrinsic_id {
+   ir_intrinsic_invalid = 0,
+
+   /**
+    * \name Generic intrinsics
+    *
+    * Each of these intrinsics has a specific version for shared variables and
+    * SSBOs.
+    */
+   /*@{*/
+   ir_intrinsic_generic_load,
+   ir_intrinsic_generic_store,
+   ir_intrinsic_generic_atomic_add,
+   ir_intrinsic_generic_atomic_and,
+   ir_intrinsic_generic_atomic_or,
+   ir_intrinsic_generic_atomic_xor,
+   ir_intrinsic_generic_atomic_min,
+   ir_intrinsic_generic_atomic_max,
+   ir_intrinsic_generic_atomic_exchange,
+   ir_intrinsic_generic_atomic_comp_swap,
+   /*@}*/
+
+   ir_intrinsic_atomic_counter_read,
+   ir_intrinsic_atomic_counter_increment,
+   ir_intrinsic_atomic_counter_predecrement,
+   ir_intrinsic_atomic_counter_add,
+   ir_intrinsic_atomic_counter_and,
+   ir_intrinsic_atomic_counter_or,
+   ir_intrinsic_atomic_counter_xor,
+   ir_intrinsic_atomic_counter_min,
+   ir_intrinsic_atomic_counter_max,
+   ir_intrinsic_atomic_counter_exchange,
+   ir_intrinsic_atomic_counter_comp_swap,
+
+   ir_intrinsic_image_load,
+   ir_intrinsic_image_store,
+   ir_intrinsic_image_atomic_add,
+   ir_intrinsic_image_atomic_and,
+   ir_intrinsic_image_atomic_or,
+   ir_intrinsic_image_atomic_xor,
+   ir_intrinsic_image_atomic_min,
+   ir_intrinsic_image_atomic_max,
+   ir_intrinsic_image_atomic_exchange,
+   ir_intrinsic_image_atomic_comp_swap,
+   ir_intrinsic_image_size,
+   ir_intrinsic_image_samples,
+
+   ir_intrinsic_ssbo_load,
+   ir_intrinsic_ssbo_store = MAKE_INTRINSIC_FOR_TYPE(store, ssbo),
+   ir_intrinsic_ssbo_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, ssbo),
+   ir_intrinsic_ssbo_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, ssbo),
+   ir_intrinsic_ssbo_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, ssbo),
+   ir_intrinsic_ssbo_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, ssbo),
+   ir_intrinsic_ssbo_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, ssbo),
+   ir_intrinsic_ssbo_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, ssbo),
+   ir_intrinsic_ssbo_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, ssbo),
+   ir_intrinsic_ssbo_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, ssbo),
+
+   ir_intrinsic_memory_barrier,
+   ir_intrinsic_shader_clock,
+   ir_intrinsic_group_memory_barrier,
+   ir_intrinsic_memory_barrier_atomic_counter,
+   ir_intrinsic_memory_barrier_buffer,
+   ir_intrinsic_memory_barrier_image,
+   ir_intrinsic_memory_barrier_shared,
+
+   ir_intrinsic_vote_all,
+   ir_intrinsic_vote_any,
+   ir_intrinsic_vote_eq,
+   ir_intrinsic_ballot,
+   ir_intrinsic_read_invocation,
+   ir_intrinsic_read_first_invocation,
+
+   ir_intrinsic_shared_load,
+   ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),
+   ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared),
+   ir_intrinsic_shared_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, shared),
+   ir_intrinsic_shared_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, shared),
+   ir_intrinsic_shared_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, shared),
+   ir_intrinsic_shared_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, shared),
+   ir_intrinsic_shared_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, shared),
+   ir_intrinsic_shared_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, shared),
+   ir_intrinsic_shared_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, shared),
+};
+
 /*@{*/
 /**
  * The representation of a function instance; may be the full definition or
@@ -998,7 +1170,9 @@ public:
     * 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);
+   ir_constant *constant_expression_value(void *mem_ctx,
+                                          exec_list *actual_parameters,
+                                          struct hash_table *variable_context);
 
    /**
     * Get the name of the function for which this is a signature
@@ -1061,7 +1235,13 @@ public:
     * Whether or not this function is an intrinsic to be implemented
     * by the driver.
     */
-   bool is_intrinsic;
+   inline bool is_intrinsic() const
+   {
+      return intrinsic_id != ir_intrinsic_invalid;
+   }
+
+   /** Indentifier for this intrinsic. */
+   enum ir_intrinsic_id intrinsic_id;
 
    /** Whether or not a built-in is available for this shader. */
    bool is_builtin_available(const _mesa_glsl_parse_state *state) const;
@@ -1095,7 +1275,8 @@ private:
     * 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,
+   bool constant_expression_evaluate_expression_list(void *mem_ctx,
+                                                     const struct exec_list &body,
                                                     struct hash_table *variable_context,
                                                     ir_constant **result);
 };
@@ -1251,7 +1432,8 @@ public:
 
    virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -1316,335 +1498,10 @@ public:
    unsigned write_mask:4;
 };
 
-/* Update ir_expression::get_num_operands() and operator_strs when
- * updating this list.
- */
-enum ir_expression_operation {
-   ir_unop_bit_not,
-   ir_unop_logic_not,
-   ir_unop_neg,
-   ir_unop_abs,
-   ir_unop_sign,
-   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_exp2,
-   ir_unop_log2,
-   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_d2f,         /**< Double-to-float conversion. */
-   ir_unop_f2d,         /**< Float-to-double conversion. */
-   ir_unop_d2i,         /**< Double-to-integer conversion. */
-   ir_unop_i2d,         /**< Integer-to-double conversion. */
-   ir_unop_d2u,         /**< Double-to-unsigned conversion. */
-   ir_unop_u2d,         /**< Unsigned-to-double conversion. */
-   ir_unop_d2b,         /**< Double-to-boolean 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" */
-
-   /**
-    * \name Unary floating-point rounding operations.
-    */
-   /*@{*/
-   ir_unop_trunc,
-   ir_unop_ceil,
-   ir_unop_floor,
-   ir_unop_fract,
-   ir_unop_round_even,
-   /*@}*/
-
-   /**
-    * \name Trigonometric operations.
-    */
-   /*@{*/
-   ir_unop_sin,
-   ir_unop_cos,
-   /*@}*/
-
-   /**
-    * \name Partial derivatives.
-    */
-   /*@{*/
-   ir_unop_dFdx,
-   ir_unop_dFdx_coarse,
-   ir_unop_dFdx_fine,
-   ir_unop_dFdy,
-   ir_unop_dFdy_coarse,
-   ir_unop_dFdy_fine,
-   /*@}*/
-
-   /**
-    * \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,
-   /*@}*/
+#include "ir_expression_operation.h"
 
-   ir_unop_saturate,
-
-   /**
-    * \name Double packing, part of ARB_gpu_shader_fp64.
-    */
-   /*@{*/
-   ir_unop_pack_double_2x32,
-   ir_unop_unpack_double_2x32,
-   /*@}*/
-
-   ir_unop_frexp_sig,
-   ir_unop_frexp_exp,
-
-   ir_unop_noise,
-
-   ir_unop_subroutine_to_int,
-   /**
-    * Interpolate fs input at centroid
-    *
-    * operand0 is the fs input.
-    */
-   ir_unop_interpolate_at_centroid,
-
-   /**
-    * Ask the driver for the total size of a buffer block.
-    *
-    * operand0 is the ir_constant buffer block index in the linked shader.
-    */
-   ir_unop_get_buffer_size,
-
-   /**
-    * Calculate length of an unsized array inside a buffer block.
-    * This opcode is going to be replaced in a lowering pass inside
-    * the linker.
-    *
-    * operand0 is the unsized array's ir_value for the calculation
-    * of its length.
-    */
-   ir_unop_ssbo_unsized_array_length,
-
-   /**
-    * A sentinel marking the last of the unary operations.
-    */
-   ir_last_unop = ir_unop_ssbo_unsized_array_length,
-
-   ir_binop_add,
-   ir_binop_sub,
-   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:
-    *
-    * - mod(vecN, vecN)
-    * - mod(vecN, float)
-    *
-    * Does not take integer types.
-    */
-   ir_binop_mod,
-
-   /**
-    * \name Binary comparison operators which return a boolean vector.
-    * The type of both operands must be equal.
-    */
-   /*@{*/
-   ir_binop_less,
-   ir_binop_greater,
-   ir_binop_lequal,
-   ir_binop_gequal,
-   ir_binop_equal,
-   ir_binop_nequal,
-   /**
-    * Returns single boolean for whether all components of operands[0]
-    * equal the components of operands[1].
-    */
-   ir_binop_all_equal,
-   /**
-    * Returns single boolean for whether any component of operands[0]
-    * is not equal to the corresponding component of operands[1].
-    */
-   ir_binop_any_nequal,
-   /*@}*/
-
-   /**
-    * \name Bit-wise binary operations.
-    */
-   /*@{*/
-   ir_binop_lshift,
-   ir_binop_rshift,
-   ir_binop_bit_and,
-   ir_binop_bit_xor,
-   ir_binop_bit_or,
-   /*@}*/
-
-   ir_binop_logic_and,
-   ir_binop_logic_xor,
-   ir_binop_logic_or,
-
-   ir_binop_dot,
-   ir_binop_min,
-   ir_binop_max,
-
-   ir_binop_pow,
-
-   /**
-    * \name Lowered floating point packing operations.
-    *
-    * \see lower_packing_builtins_visitor::split_pack_half_2x16
-    */
-   /*@{*/
-   ir_binop_pack_half_2x16_split,
-   /*@}*/
-
-   /**
-    * 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,
-
-   /**
-    * Interpolate fs input at offset
-    *
-    * operand0 is the fs input
-    * operand1 is the offset from the pixel center
-    */
-   ir_binop_interpolate_at_offset,
-
-   /**
-    * Interpolate fs input at sample position
-    *
-    * operand0 is the fs input
-    * operand1 is the sample ID
-    */
-   ir_binop_interpolate_at_sample,
-
-   /**
-    * A sentinel marking the last of the binary operations.
-    */
-   ir_last_binop = ir_binop_interpolate_at_sample,
-
-   /**
-    * \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,
-   /*@}*/
-
-   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_quadop_vector
-};
+extern const char *const ir_expression_operation_strings[ir_last_opcode + 1];
+extern const char *const ir_expression_operation_enum_strings[ir_last_opcode + 1];
 
 class ir_expression : public ir_rvalue {
 public:
@@ -1682,21 +1539,14 @@ public:
     * If the expression cannot be constant folded, this method will return
     * \c NULL.
     */
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
-
-   /**
-    * Determine the number of operands used by an expression
-    */
-   static unsigned int get_num_operands(ir_expression_operation);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    /**
-    * Determine the number of operands used by an expression
+    * This is only here for ir_reader to used for testing purposes please use
+    * the precomputed num_operands field if you need the number of operands.
     */
-   unsigned int get_num_operands() const
-   {
-      return (this->operation == ir_quadop_vector)
-        ? this->type->vector_elements : get_num_operands(operation);
-   }
+   static unsigned get_num_operands(ir_expression_operation);
 
    /**
     * Return whether the expression operates on vectors horizontally.
@@ -1708,20 +1558,10 @@ public:
              operation == ir_binop_dot ||
              operation == ir_binop_vector_extract ||
              operation == ir_triop_vector_insert ||
+             operation == ir_binop_ubo_load ||
              operation == ir_quadop_vector;
    }
 
-   /**
-    * Return a string representing this expression's operator.
-    */
-   const char *operator_string();
-
-   /**
-    * Return a string representing this expression's operator.
-    */
-   static const char *operator_string(ir_expression_operation);
-
-
    /**
     * Do a reverse-lookup to translate the given string into an operator.
     */
@@ -1736,8 +1576,21 @@ public:
 
    virtual ir_variable *variable_referenced() const;
 
+   /**
+    * Determine the number of operands used by an expression
+    */
+   void init_num_operands()
+   {
+      if (operation == ir_quadop_vector) {
+         num_operands = this->type->vector_elements;
+      } else {
+         num_operands = get_num_operands(operation);
+      }
+   }
+
    ir_expression_operation operation;
    ir_rvalue *operands[4];
+   uint8_t num_operands;
 };
 
 
@@ -1754,7 +1607,6 @@ public:
    {
       assert(callee->return_type != NULL);
       actual_parameters->move_nodes_to(& this->actual_parameters);
-      this->use_builtin = callee->is_builtin();
    }
 
    ir_call(ir_function_signature *callee,
@@ -1765,12 +1617,12 @@ public:
    {
       assert(callee->return_type != NULL);
       actual_parameters->move_nodes_to(& this->actual_parameters);
-      this->use_builtin = callee->is_builtin();
    }
 
    virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -1807,9 +1659,6 @@ public:
    /* 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;
-
    /*
     * ARB_shader_subroutine support -
     * the subroutine uniform variable and array index
@@ -1967,7 +1816,7 @@ enum ir_texture_opcode {
  *
  *                                    Texel offset (0 or an expression)
  *                                    | Projection divisor
- *                                    | |  Shadow comparitor
+ *                                    | |  Shadow comparator
  *                                    | |  |
  *                                    v v  v
  * (tex <type> <sampler> <coordinate> 0 1 ( ))
@@ -1988,14 +1837,15 @@ public:
    ir_texture(enum ir_texture_opcode op)
       : ir_rvalue(ir_type_texture),
         op(op), sampler(NULL), coordinate(NULL), projector(NULL),
-        shadow_comparitor(NULL), offset(NULL)
+        shadow_comparator(NULL), offset(NULL)
    {
       memset(&lod_info, 0, sizeof(lod_info));
    }
 
    virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -2043,7 +1893,7 @@ public:
     * If there is no shadow comparison, this will be \c NULL.  For the
     * \c ir_txf opcode, this *must* be \c NULL.
     */
-   ir_rvalue *shadow_comparitor;
+   ir_rvalue *shadow_comparator;
 
    /** Texel offset. */
    ir_rvalue *offset;
@@ -2092,7 +1942,8 @@ public:
 
    virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    /**
     * Construct an ir_swizzle from the textual representation.  Can fail.
@@ -2109,9 +1960,9 @@ public:
    virtual bool equals(const ir_instruction *ir,
                        enum ir_node_type ignore = ir_type_unset) const;
 
-   bool is_lvalue() const
+   bool is_lvalue(const struct _mesa_glsl_parse_state *state) const
    {
-      return val->is_lvalue() && !mask.has_duplicates;
+      return val->is_lvalue(state) && !mask.has_duplicates;
    }
 
    /**
@@ -2136,7 +1987,7 @@ class ir_dereference : public ir_rvalue {
 public:
    virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0;
 
-   bool is_lvalue() const;
+   bool is_lvalue(const struct _mesa_glsl_parse_state *state) const;
 
    /**
     * Get the variable that is ultimately referenced by an r-value
@@ -2158,7 +2009,8 @@ public:
    virtual ir_dereference_variable *clone(void *mem_ctx,
                                          struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual bool equals(const ir_instruction *ir,
                        enum ir_node_type ignore = ir_type_unset) const;
@@ -2205,7 +2057,8 @@ public:
    virtual ir_dereference_array *clone(void *mem_ctx,
                                       struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual bool equals(const ir_instruction *ir,
                        enum ir_node_type ignore = ir_type_unset) const;
@@ -2242,7 +2095,8 @@ public:
    virtual ir_dereference_record *clone(void *mem_ctx,
                                        struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    /**
     * Get the variable that is ultimately referenced by an r-value
@@ -2260,7 +2114,7 @@ public:
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
    ir_rvalue *record;
-   const char *field;
+   int field_idx;
 };
 
 
@@ -2273,6 +2127,8 @@ union ir_constant_data {
       float f[16];
       bool b[16];
       double d[16];
+      uint64_t u64[16];
+      int64_t i64[16];
 };
 
 
@@ -2284,6 +2140,8 @@ public:
    ir_constant(int i, unsigned vector_elements=1);
    ir_constant(float f, unsigned vector_elements=1);
    ir_constant(double d, unsigned vector_elements=1);
+   ir_constant(uint64_t u64, unsigned vector_elements=1);
+   ir_constant(int64_t i64, unsigned vector_elements=1);
 
    /**
     * Construct an ir_constant from a list of ir_constant values
@@ -2309,7 +2167,8 @@ public:
 
    virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -2334,11 +2193,13 @@ public:
    double get_double_component(unsigned i) const;
    int get_int_component(unsigned i) const;
    unsigned get_uint_component(unsigned i) const;
+   int64_t get_int64_component(unsigned i) const;
+   uint64_t get_uint64_component(unsigned i) const;
    /*@}*/
 
    ir_constant *get_array_element(unsigned i) const;
 
-   ir_constant *get_record_field(const char *name);
+   ir_constant *get_record_field(int idx);
 
    /**
     * Copy the values on another constant at a given offset.
@@ -2400,11 +2261,8 @@ public:
     */
    union ir_constant_data value;
 
-   /* Array elements */
-   ir_constant **array_elements;
-
-   /* Structure fields */
-   exec_list components;
+   /* Array elements and structure fields */
+   ir_constant **const_elements;
 
 private:
    /**
@@ -2553,46 +2411,9 @@ extern void
 _mesa_glsl_initialize_variables(exec_list *instructions,
                                struct _mesa_glsl_parse_state *state);
 
-extern void
-_mesa_glsl_initialize_derived_variables(gl_shader *shader);
-
-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 ir_function *
-_mesa_glsl_find_builtin_function_by_name(const char *name);
-
-extern gl_shader *
-_mesa_glsl_get_builtin_function_shader(void);
-
-extern ir_function_signature *
-_mesa_get_main_function_signature(gl_shader *sh);
-
-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);
 
-struct glsl_symbol_table;
-
-extern void
-import_prototypes(const exec_list *source, exec_list *dest,
-                 struct glsl_symbol_table *symbols, void *mem_ctx);
-
-extern bool
-ir_has_call(ir_instruction *ir);
-
 extern void
 do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
                       gl_shader_stage shader_stage);
@@ -2622,6 +2443,9 @@ extern void _mesa_print_ir(FILE *f, struct exec_list *instructions,
 extern void
 fprint_ir(FILE *f, const void *instruction);
 
+extern const struct gl_builtin_uniform_desc *
+_mesa_glsl_get_builtin_uniform_desc(const char *name);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif