101e04c3fSmrg/* -*- c++ -*- */
201e04c3fSmrg/*
301e04c3fSmrg * Copyright © 2010 Intel Corporation
401e04c3fSmrg *
501e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
601e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
701e04c3fSmrg * to deal in the Software without restriction, including without limitation
801e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
901e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
1001e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1101e04c3fSmrg *
1201e04c3fSmrg * The above copyright notice and this permission notice (including the next
1301e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1401e04c3fSmrg * Software.
1501e04c3fSmrg *
1601e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1701e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1801e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1901e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2001e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2101e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2201e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2301e04c3fSmrg */
2401e04c3fSmrg
2501e04c3fSmrg#ifndef IR_H
2601e04c3fSmrg#define IR_H
2701e04c3fSmrg
2801e04c3fSmrg#include <stdio.h>
2901e04c3fSmrg#include <stdlib.h>
3001e04c3fSmrg
3101e04c3fSmrg#include "util/ralloc.h"
327ec681f3Smrg#include "util/format/u_format.h"
337ec681f3Smrg#include "util/half_float.h"
3401e04c3fSmrg#include "compiler/glsl_types.h"
3501e04c3fSmrg#include "list.h"
3601e04c3fSmrg#include "ir_visitor.h"
3701e04c3fSmrg#include "ir_hierarchical_visitor.h"
3801e04c3fSmrg
3901e04c3fSmrg#ifdef __cplusplus
4001e04c3fSmrg
4101e04c3fSmrg/**
4201e04c3fSmrg * \defgroup IR Intermediate representation nodes
4301e04c3fSmrg *
4401e04c3fSmrg * @{
4501e04c3fSmrg */
4601e04c3fSmrg
4701e04c3fSmrg/**
4801e04c3fSmrg * Class tags
4901e04c3fSmrg *
5001e04c3fSmrg * Each concrete class derived from \c ir_instruction has a value in this
5101e04c3fSmrg * enumerant.  The value for the type is stored in \c ir_instruction::ir_type
5201e04c3fSmrg * by the constructor.  While using type tags is not very C++, it is extremely
5301e04c3fSmrg * convenient.  For example, during debugging you can simply inspect
5401e04c3fSmrg * \c ir_instruction::ir_type to find out the actual type of the object.
5501e04c3fSmrg *
5601e04c3fSmrg * In addition, it is possible to use a switch-statement based on \c
5701e04c3fSmrg * \c ir_instruction::ir_type to select different behavior for different object
5801e04c3fSmrg * types.  For functions that have only slight differences for several object
5901e04c3fSmrg * types, this allows writing very straightforward, readable code.
6001e04c3fSmrg */
6101e04c3fSmrgenum ir_node_type {
6201e04c3fSmrg   ir_type_dereference_array,
6301e04c3fSmrg   ir_type_dereference_record,
6401e04c3fSmrg   ir_type_dereference_variable,
6501e04c3fSmrg   ir_type_constant,
6601e04c3fSmrg   ir_type_expression,
6701e04c3fSmrg   ir_type_swizzle,
6801e04c3fSmrg   ir_type_texture,
6901e04c3fSmrg   ir_type_variable,
7001e04c3fSmrg   ir_type_assignment,
7101e04c3fSmrg   ir_type_call,
7201e04c3fSmrg   ir_type_function,
7301e04c3fSmrg   ir_type_function_signature,
7401e04c3fSmrg   ir_type_if,
7501e04c3fSmrg   ir_type_loop,
7601e04c3fSmrg   ir_type_loop_jump,
7701e04c3fSmrg   ir_type_return,
7801e04c3fSmrg   ir_type_discard,
797ec681f3Smrg   ir_type_demote,
8001e04c3fSmrg   ir_type_emit_vertex,
8101e04c3fSmrg   ir_type_end_primitive,
8201e04c3fSmrg   ir_type_barrier,
8301e04c3fSmrg   ir_type_max, /**< maximum ir_type enum number, for validation */
8401e04c3fSmrg   ir_type_unset = ir_type_max
8501e04c3fSmrg};
8601e04c3fSmrg
8701e04c3fSmrg
8801e04c3fSmrg/**
8901e04c3fSmrg * Base class of all IR instructions
9001e04c3fSmrg */
9101e04c3fSmrgclass ir_instruction : public exec_node {
9201e04c3fSmrgpublic:
9301e04c3fSmrg   enum ir_node_type ir_type;
9401e04c3fSmrg
9501e04c3fSmrg   /**
9601e04c3fSmrg    * GCC 4.7+ and clang warn when deleting an ir_instruction unless
9701e04c3fSmrg    * there's a virtual destructor present.  Because we almost
9801e04c3fSmrg    * universally use ralloc for our memory management of
9901e04c3fSmrg    * ir_instructions, the destructor doesn't need to do any work.
10001e04c3fSmrg    */
10101e04c3fSmrg   virtual ~ir_instruction()
10201e04c3fSmrg   {
10301e04c3fSmrg   }
10401e04c3fSmrg
10501e04c3fSmrg   /** ir_print_visitor helper for debugging. */
10601e04c3fSmrg   void print(void) const;
10701e04c3fSmrg   void fprint(FILE *f) const;
10801e04c3fSmrg
10901e04c3fSmrg   virtual void accept(ir_visitor *) = 0;
11001e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
11101e04c3fSmrg   virtual ir_instruction *clone(void *mem_ctx,
11201e04c3fSmrg				 struct hash_table *ht) const = 0;
11301e04c3fSmrg
11401e04c3fSmrg   bool is_rvalue() const
11501e04c3fSmrg   {
11601e04c3fSmrg      return ir_type == ir_type_dereference_array ||
11701e04c3fSmrg             ir_type == ir_type_dereference_record ||
11801e04c3fSmrg             ir_type == ir_type_dereference_variable ||
11901e04c3fSmrg             ir_type == ir_type_constant ||
12001e04c3fSmrg             ir_type == ir_type_expression ||
12101e04c3fSmrg             ir_type == ir_type_swizzle ||
12201e04c3fSmrg             ir_type == ir_type_texture;
12301e04c3fSmrg   }
12401e04c3fSmrg
12501e04c3fSmrg   bool is_dereference() const
12601e04c3fSmrg   {
12701e04c3fSmrg      return ir_type == ir_type_dereference_array ||
12801e04c3fSmrg             ir_type == ir_type_dereference_record ||
12901e04c3fSmrg             ir_type == ir_type_dereference_variable;
13001e04c3fSmrg   }
13101e04c3fSmrg
13201e04c3fSmrg   bool is_jump() const
13301e04c3fSmrg   {
13401e04c3fSmrg      return ir_type == ir_type_loop_jump ||
13501e04c3fSmrg             ir_type == ir_type_return ||
13601e04c3fSmrg             ir_type == ir_type_discard;
13701e04c3fSmrg   }
13801e04c3fSmrg
13901e04c3fSmrg   /**
14001e04c3fSmrg    * \name IR instruction downcast functions
14101e04c3fSmrg    *
14201e04c3fSmrg    * These functions either cast the object to a derived class or return
14301e04c3fSmrg    * \c NULL if the object's type does not match the specified derived class.
14401e04c3fSmrg    * Additional downcast functions will be added as needed.
14501e04c3fSmrg    */
14601e04c3fSmrg   /*@{*/
14701e04c3fSmrg   #define AS_BASE(TYPE)                                \
14801e04c3fSmrg   class ir_##TYPE *as_##TYPE()                         \
14901e04c3fSmrg   {                                                    \
15001e04c3fSmrg      assume(this != NULL);                             \
15101e04c3fSmrg      return is_##TYPE() ? (ir_##TYPE *) this : NULL;   \
15201e04c3fSmrg   }                                                    \
15301e04c3fSmrg   const class ir_##TYPE *as_##TYPE() const             \
15401e04c3fSmrg   {                                                    \
15501e04c3fSmrg      assume(this != NULL);                             \
15601e04c3fSmrg      return is_##TYPE() ? (ir_##TYPE *) this : NULL;   \
15701e04c3fSmrg   }
15801e04c3fSmrg
15901e04c3fSmrg   AS_BASE(rvalue)
16001e04c3fSmrg   AS_BASE(dereference)
16101e04c3fSmrg   AS_BASE(jump)
16201e04c3fSmrg   #undef AS_BASE
16301e04c3fSmrg
16401e04c3fSmrg   #define AS_CHILD(TYPE) \
16501e04c3fSmrg   class ir_##TYPE * as_##TYPE() \
16601e04c3fSmrg   { \
16701e04c3fSmrg      assume(this != NULL);                                         \
16801e04c3fSmrg      return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL; \
16901e04c3fSmrg   }                                                                      \
17001e04c3fSmrg   const class ir_##TYPE * as_##TYPE() const                              \
17101e04c3fSmrg   {                                                                      \
17201e04c3fSmrg      assume(this != NULL);                                               \
17301e04c3fSmrg      return ir_type == ir_type_##TYPE ? (const ir_##TYPE *) this : NULL; \
17401e04c3fSmrg   }
17501e04c3fSmrg   AS_CHILD(variable)
17601e04c3fSmrg   AS_CHILD(function)
17701e04c3fSmrg   AS_CHILD(dereference_array)
17801e04c3fSmrg   AS_CHILD(dereference_variable)
17901e04c3fSmrg   AS_CHILD(dereference_record)
18001e04c3fSmrg   AS_CHILD(expression)
18101e04c3fSmrg   AS_CHILD(loop)
18201e04c3fSmrg   AS_CHILD(assignment)
18301e04c3fSmrg   AS_CHILD(call)
18401e04c3fSmrg   AS_CHILD(return)
18501e04c3fSmrg   AS_CHILD(if)
18601e04c3fSmrg   AS_CHILD(swizzle)
18701e04c3fSmrg   AS_CHILD(texture)
18801e04c3fSmrg   AS_CHILD(constant)
18901e04c3fSmrg   AS_CHILD(discard)
19001e04c3fSmrg   #undef AS_CHILD
19101e04c3fSmrg   /*@}*/
19201e04c3fSmrg
19301e04c3fSmrg   /**
19401e04c3fSmrg    * IR equality method: Return true if the referenced instruction would
19501e04c3fSmrg    * return the same value as this one.
19601e04c3fSmrg    *
19701e04c3fSmrg    * This intended to be used for CSE and algebraic optimizations, on rvalues
19801e04c3fSmrg    * in particular.  No support for other instruction types (assignments,
19901e04c3fSmrg    * jumps, calls, etc.) is planned.
20001e04c3fSmrg    */
20101e04c3fSmrg   virtual bool equals(const ir_instruction *ir,
20201e04c3fSmrg                       enum ir_node_type ignore = ir_type_unset) const;
20301e04c3fSmrg
20401e04c3fSmrgprotected:
20501e04c3fSmrg   ir_instruction(enum ir_node_type t)
20601e04c3fSmrg      : ir_type(t)
20701e04c3fSmrg   {
20801e04c3fSmrg   }
20901e04c3fSmrg
21001e04c3fSmrgprivate:
21101e04c3fSmrg   ir_instruction()
21201e04c3fSmrg   {
21301e04c3fSmrg      assert(!"Should not get here.");
21401e04c3fSmrg   }
21501e04c3fSmrg};
21601e04c3fSmrg
21701e04c3fSmrg
21801e04c3fSmrg/**
21901e04c3fSmrg * The base class for all "values"/expression trees.
22001e04c3fSmrg */
22101e04c3fSmrgclass ir_rvalue : public ir_instruction {
22201e04c3fSmrgpublic:
22301e04c3fSmrg   const struct glsl_type *type;
22401e04c3fSmrg
22501e04c3fSmrg   virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const;
22601e04c3fSmrg
22701e04c3fSmrg   virtual void accept(ir_visitor *v)
22801e04c3fSmrg   {
22901e04c3fSmrg      v->visit(this);
23001e04c3fSmrg   }
23101e04c3fSmrg
23201e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
23301e04c3fSmrg
23401e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
23501e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
23601e04c3fSmrg
23701e04c3fSmrg   ir_rvalue *as_rvalue_to_saturate();
23801e04c3fSmrg
2397e102996Smaya   virtual bool is_lvalue(const struct _mesa_glsl_parse_state * = NULL) const
24001e04c3fSmrg   {
24101e04c3fSmrg      return false;
24201e04c3fSmrg   }
24301e04c3fSmrg
24401e04c3fSmrg   /**
24501e04c3fSmrg    * Get the variable that is ultimately referenced by an r-value
24601e04c3fSmrg    */
24701e04c3fSmrg   virtual ir_variable *variable_referenced() const
24801e04c3fSmrg   {
24901e04c3fSmrg      return NULL;
25001e04c3fSmrg   }
25101e04c3fSmrg
25201e04c3fSmrg
25301e04c3fSmrg   /**
25401e04c3fSmrg    * If an r-value is a reference to a whole variable, get that variable
25501e04c3fSmrg    *
25601e04c3fSmrg    * \return
25701e04c3fSmrg    * Pointer to a variable that is completely dereferenced by the r-value.  If
25801e04c3fSmrg    * the r-value is not a dereference or the dereference does not access the
25901e04c3fSmrg    * entire variable (i.e., it's just one array element, struct field), \c NULL
26001e04c3fSmrg    * is returned.
26101e04c3fSmrg    */
26201e04c3fSmrg   virtual ir_variable *whole_variable_referenced()
26301e04c3fSmrg   {
26401e04c3fSmrg      return NULL;
26501e04c3fSmrg   }
26601e04c3fSmrg
26701e04c3fSmrg   /**
26801e04c3fSmrg    * Determine if an r-value has the value zero
26901e04c3fSmrg    *
27001e04c3fSmrg    * The base implementation of this function always returns \c false.  The
27101e04c3fSmrg    * \c ir_constant class over-rides this function to return \c true \b only
27201e04c3fSmrg    * for vector and scalar types that have all elements set to the value
27301e04c3fSmrg    * zero (or \c false for booleans).
27401e04c3fSmrg    *
27501e04c3fSmrg    * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one
27601e04c3fSmrg    */
27701e04c3fSmrg   virtual bool is_zero() const;
27801e04c3fSmrg
27901e04c3fSmrg   /**
28001e04c3fSmrg    * Determine if an r-value has the value one
28101e04c3fSmrg    *
28201e04c3fSmrg    * The base implementation of this function always returns \c false.  The
28301e04c3fSmrg    * \c ir_constant class over-rides this function to return \c true \b only
28401e04c3fSmrg    * for vector and scalar types that have all elements set to the value
28501e04c3fSmrg    * one (or \c true for booleans).
28601e04c3fSmrg    *
28701e04c3fSmrg    * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one
28801e04c3fSmrg    */
28901e04c3fSmrg   virtual bool is_one() const;
29001e04c3fSmrg
29101e04c3fSmrg   /**
29201e04c3fSmrg    * Determine if an r-value has the value negative one
29301e04c3fSmrg    *
29401e04c3fSmrg    * The base implementation of this function always returns \c false.  The
29501e04c3fSmrg    * \c ir_constant class over-rides this function to return \c true \b only
29601e04c3fSmrg    * for vector and scalar types that have all elements set to the value
29701e04c3fSmrg    * negative one.  For boolean types, the result is always \c false.
29801e04c3fSmrg    *
29901e04c3fSmrg    * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one
30001e04c3fSmrg    */
30101e04c3fSmrg   virtual bool is_negative_one() const;
30201e04c3fSmrg
30301e04c3fSmrg   /**
30401e04c3fSmrg    * Determine if an r-value is an unsigned integer constant which can be
30501e04c3fSmrg    * stored in 16 bits.
30601e04c3fSmrg    *
30701e04c3fSmrg    * \sa ir_constant::is_uint16_constant.
30801e04c3fSmrg    */
30901e04c3fSmrg   virtual bool is_uint16_constant() const { return false; }
31001e04c3fSmrg
31101e04c3fSmrg   /**
31201e04c3fSmrg    * Return a generic value of error_type.
31301e04c3fSmrg    *
31401e04c3fSmrg    * Allocation will be performed with 'mem_ctx' as ralloc owner.
31501e04c3fSmrg    */
31601e04c3fSmrg   static ir_rvalue *error_value(void *mem_ctx);
31701e04c3fSmrg
31801e04c3fSmrgprotected:
31901e04c3fSmrg   ir_rvalue(enum ir_node_type t);
32001e04c3fSmrg};
32101e04c3fSmrg
32201e04c3fSmrg
32301e04c3fSmrg/**
32401e04c3fSmrg * Variable storage classes
32501e04c3fSmrg */
32601e04c3fSmrgenum ir_variable_mode {
32701e04c3fSmrg   ir_var_auto = 0,             /**< Function local variables and globals. */
32801e04c3fSmrg   ir_var_uniform,              /**< Variable declared as a uniform. */
32901e04c3fSmrg   ir_var_shader_storage,       /**< Variable declared as an ssbo. */
33001e04c3fSmrg   ir_var_shader_shared,        /**< Variable declared as shared. */
33101e04c3fSmrg   ir_var_shader_in,
33201e04c3fSmrg   ir_var_shader_out,
33301e04c3fSmrg   ir_var_function_in,
33401e04c3fSmrg   ir_var_function_out,
33501e04c3fSmrg   ir_var_function_inout,
33601e04c3fSmrg   ir_var_const_in,             /**< "in" param that must be a constant expression */
33701e04c3fSmrg   ir_var_system_value,         /**< Ex: front-face, instance-id, etc. */
33801e04c3fSmrg   ir_var_temporary,            /**< Temporary variable generated during compilation. */
33901e04c3fSmrg   ir_var_mode_count            /**< Number of variable modes */
34001e04c3fSmrg};
34101e04c3fSmrg
34201e04c3fSmrg/**
34301e04c3fSmrg * Enum keeping track of how a variable was declared.  For error checking of
34401e04c3fSmrg * the gl_PerVertex redeclaration rules.
34501e04c3fSmrg */
34601e04c3fSmrgenum ir_var_declaration_type {
34701e04c3fSmrg   /**
34801e04c3fSmrg    * Normal declaration (for most variables, this means an explicit
34901e04c3fSmrg    * declaration.  Exception: temporaries are always implicitly declared, but
35001e04c3fSmrg    * they still use ir_var_declared_normally).
35101e04c3fSmrg    *
35201e04c3fSmrg    * Note: an ir_variable that represents a named interface block uses
35301e04c3fSmrg    * ir_var_declared_normally.
35401e04c3fSmrg    */
35501e04c3fSmrg   ir_var_declared_normally = 0,
35601e04c3fSmrg
35701e04c3fSmrg   /**
35801e04c3fSmrg    * Variable was explicitly declared (or re-declared) in an unnamed
35901e04c3fSmrg    * interface block.
36001e04c3fSmrg    */
36101e04c3fSmrg   ir_var_declared_in_block,
36201e04c3fSmrg
36301e04c3fSmrg   /**
36401e04c3fSmrg    * Variable is an implicitly declared built-in that has not been explicitly
36501e04c3fSmrg    * re-declared by the shader.
36601e04c3fSmrg    */
36701e04c3fSmrg   ir_var_declared_implicitly,
36801e04c3fSmrg
36901e04c3fSmrg   /**
37001e04c3fSmrg    * Variable is implicitly generated by the compiler and should not be
37101e04c3fSmrg    * visible via the API.
37201e04c3fSmrg    */
37301e04c3fSmrg   ir_var_hidden,
37401e04c3fSmrg};
37501e04c3fSmrg
37601e04c3fSmrg/**
37701e04c3fSmrg * \brief Layout qualifiers for gl_FragDepth.
37801e04c3fSmrg *
37901e04c3fSmrg * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared
38001e04c3fSmrg * with a layout qualifier.
38101e04c3fSmrg */
38201e04c3fSmrgenum ir_depth_layout {
38301e04c3fSmrg    ir_depth_layout_none, /**< No depth layout is specified. */
38401e04c3fSmrg    ir_depth_layout_any,
38501e04c3fSmrg    ir_depth_layout_greater,
38601e04c3fSmrg    ir_depth_layout_less,
38701e04c3fSmrg    ir_depth_layout_unchanged
38801e04c3fSmrg};
38901e04c3fSmrg
39001e04c3fSmrg/**
39101e04c3fSmrg * \brief Convert depth layout qualifier to string.
39201e04c3fSmrg */
39301e04c3fSmrgconst char*
39401e04c3fSmrgdepth_layout_string(ir_depth_layout layout);
39501e04c3fSmrg
39601e04c3fSmrg/**
39701e04c3fSmrg * Description of built-in state associated with a uniform
39801e04c3fSmrg *
39901e04c3fSmrg * \sa ir_variable::state_slots
40001e04c3fSmrg */
40101e04c3fSmrgstruct ir_state_slot {
40201e04c3fSmrg   gl_state_index16 tokens[STATE_LENGTH];
40301e04c3fSmrg   int swizzle;
40401e04c3fSmrg};
40501e04c3fSmrg
40601e04c3fSmrg
40701e04c3fSmrg/**
40801e04c3fSmrg * Get the string value for an interpolation qualifier
40901e04c3fSmrg *
41001e04c3fSmrg * \return The string that would be used in a shader to specify \c
41101e04c3fSmrg * mode will be returned.
41201e04c3fSmrg *
41301e04c3fSmrg * This function is used to generate error messages of the form "shader
41401e04c3fSmrg * uses %s interpolation qualifier", so in the case where there is no
41501e04c3fSmrg * interpolation qualifier, it returns "no".
41601e04c3fSmrg *
41701e04c3fSmrg * This function should only be used on a shader input or output variable.
41801e04c3fSmrg */
41901e04c3fSmrgconst char *interpolation_string(unsigned interpolation);
42001e04c3fSmrg
42101e04c3fSmrg
42201e04c3fSmrgclass ir_variable : public ir_instruction {
42301e04c3fSmrgpublic:
42401e04c3fSmrg   ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
42501e04c3fSmrg
42601e04c3fSmrg   virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const;
42701e04c3fSmrg
42801e04c3fSmrg   virtual void accept(ir_visitor *v)
42901e04c3fSmrg   {
43001e04c3fSmrg      v->visit(this);
43101e04c3fSmrg   }
43201e04c3fSmrg
43301e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
43401e04c3fSmrg
43501e04c3fSmrg
43601e04c3fSmrg   /**
43701e04c3fSmrg    * Determine whether or not a variable is part of a uniform or
43801e04c3fSmrg    * shader storage block.
43901e04c3fSmrg    */
44001e04c3fSmrg   inline bool is_in_buffer_block() const
44101e04c3fSmrg   {
44201e04c3fSmrg      return (this->data.mode == ir_var_uniform ||
44301e04c3fSmrg              this->data.mode == ir_var_shader_storage) &&
44401e04c3fSmrg             this->interface_type != NULL;
44501e04c3fSmrg   }
44601e04c3fSmrg
44701e04c3fSmrg   /**
44801e04c3fSmrg    * Determine whether or not a variable is part of a shader storage block.
44901e04c3fSmrg    */
45001e04c3fSmrg   inline bool is_in_shader_storage_block() const
45101e04c3fSmrg   {
45201e04c3fSmrg      return this->data.mode == ir_var_shader_storage &&
45301e04c3fSmrg             this->interface_type != NULL;
45401e04c3fSmrg   }
45501e04c3fSmrg
45601e04c3fSmrg   /**
45701e04c3fSmrg    * Determine whether or not a variable is the declaration of an interface
45801e04c3fSmrg    * block
45901e04c3fSmrg    *
46001e04c3fSmrg    * For the first declaration below, there will be an \c ir_variable named
46101e04c3fSmrg    * "instance" whose type and whose instance_type will be the same
46201e04c3fSmrg    * \c glsl_type.  For the second declaration, there will be an \c ir_variable
46301e04c3fSmrg    * named "f" whose type is float and whose instance_type is B2.
46401e04c3fSmrg    *
46501e04c3fSmrg    * "instance" is an interface instance variable, but "f" is not.
46601e04c3fSmrg    *
46701e04c3fSmrg    * uniform B1 {
46801e04c3fSmrg    *     float f;
46901e04c3fSmrg    * } instance;
47001e04c3fSmrg    *
47101e04c3fSmrg    * uniform B2 {
47201e04c3fSmrg    *     float f;
47301e04c3fSmrg    * };
47401e04c3fSmrg    */
47501e04c3fSmrg   inline bool is_interface_instance() const
47601e04c3fSmrg   {
47701e04c3fSmrg      return this->type->without_array() == this->interface_type;
47801e04c3fSmrg   }
47901e04c3fSmrg
48001e04c3fSmrg   /**
48101e04c3fSmrg    * Return whether this variable contains a bindless sampler/image.
48201e04c3fSmrg    */
48301e04c3fSmrg   inline bool contains_bindless() const
48401e04c3fSmrg   {
48501e04c3fSmrg      if (!this->type->contains_sampler() && !this->type->contains_image())
48601e04c3fSmrg         return false;
48701e04c3fSmrg
48801e04c3fSmrg      return this->data.bindless || this->data.mode != ir_var_uniform;
48901e04c3fSmrg   }
49001e04c3fSmrg
49101e04c3fSmrg   /**
49201e04c3fSmrg    * Set this->interface_type on a newly created variable.
49301e04c3fSmrg    */
49401e04c3fSmrg   void init_interface_type(const struct glsl_type *type)
49501e04c3fSmrg   {
49601e04c3fSmrg      assert(this->interface_type == NULL);
49701e04c3fSmrg      this->interface_type = type;
49801e04c3fSmrg      if (this->is_interface_instance()) {
49901e04c3fSmrg         this->u.max_ifc_array_access =
50001e04c3fSmrg            ralloc_array(this, int, type->length);
50101e04c3fSmrg         for (unsigned i = 0; i < type->length; i++) {
50201e04c3fSmrg            this->u.max_ifc_array_access[i] = -1;
50301e04c3fSmrg         }
50401e04c3fSmrg      }
50501e04c3fSmrg   }
50601e04c3fSmrg
50701e04c3fSmrg   /**
50801e04c3fSmrg    * Change this->interface_type on a variable that previously had a
50901e04c3fSmrg    * different, but compatible, interface_type.  This is used during linking
51001e04c3fSmrg    * to set the size of arrays in interface blocks.
51101e04c3fSmrg    */
51201e04c3fSmrg   void change_interface_type(const struct glsl_type *type)
51301e04c3fSmrg   {
51401e04c3fSmrg      if (this->u.max_ifc_array_access != NULL) {
51501e04c3fSmrg         /* max_ifc_array_access has already been allocated, so make sure the
51601e04c3fSmrg          * new interface has the same number of fields as the old one.
51701e04c3fSmrg          */
51801e04c3fSmrg         assert(this->interface_type->length == type->length);
51901e04c3fSmrg      }
52001e04c3fSmrg      this->interface_type = type;
52101e04c3fSmrg   }
52201e04c3fSmrg
52301e04c3fSmrg   /**
52401e04c3fSmrg    * Change this->interface_type on a variable that previously had a
52501e04c3fSmrg    * different, and incompatible, interface_type. This is used during
52601e04c3fSmrg    * compilation to handle redeclaration of the built-in gl_PerVertex
52701e04c3fSmrg    * interface block.
52801e04c3fSmrg    */
52901e04c3fSmrg   void reinit_interface_type(const struct glsl_type *type)
53001e04c3fSmrg   {
53101e04c3fSmrg      if (this->u.max_ifc_array_access != NULL) {
53201e04c3fSmrg#ifndef NDEBUG
53301e04c3fSmrg         /* Redeclaring gl_PerVertex is only allowed if none of the built-ins
53401e04c3fSmrg          * it defines have been accessed yet; so it's safe to throw away the
53501e04c3fSmrg          * old max_ifc_array_access pointer, since all of its values are
53601e04c3fSmrg          * zero.
53701e04c3fSmrg          */
53801e04c3fSmrg         for (unsigned i = 0; i < this->interface_type->length; i++)
53901e04c3fSmrg            assert(this->u.max_ifc_array_access[i] == -1);
54001e04c3fSmrg#endif
54101e04c3fSmrg         ralloc_free(this->u.max_ifc_array_access);
54201e04c3fSmrg         this->u.max_ifc_array_access = NULL;
54301e04c3fSmrg      }
54401e04c3fSmrg      this->interface_type = NULL;
54501e04c3fSmrg      init_interface_type(type);
54601e04c3fSmrg   }
54701e04c3fSmrg
54801e04c3fSmrg   const glsl_type *get_interface_type() const
54901e04c3fSmrg   {
55001e04c3fSmrg      return this->interface_type;
55101e04c3fSmrg   }
55201e04c3fSmrg
55301e04c3fSmrg   enum glsl_interface_packing get_interface_type_packing() const
55401e04c3fSmrg   {
55501e04c3fSmrg     return this->interface_type->get_interface_packing();
55601e04c3fSmrg   }
55701e04c3fSmrg   /**
55801e04c3fSmrg    * Get the max_ifc_array_access pointer
55901e04c3fSmrg    *
5607ec681f3Smrg    * A "set" function is not needed because the array is dynamically allocated
56101e04c3fSmrg    * as necessary.
56201e04c3fSmrg    */
56301e04c3fSmrg   inline int *get_max_ifc_array_access()
56401e04c3fSmrg   {
56501e04c3fSmrg      assert(this->data._num_state_slots == 0);
56601e04c3fSmrg      return this->u.max_ifc_array_access;
56701e04c3fSmrg   }
56801e04c3fSmrg
56901e04c3fSmrg   inline unsigned get_num_state_slots() const
57001e04c3fSmrg   {
57101e04c3fSmrg      assert(!this->is_interface_instance()
57201e04c3fSmrg             || this->data._num_state_slots == 0);
57301e04c3fSmrg      return this->data._num_state_slots;
57401e04c3fSmrg   }
57501e04c3fSmrg
57601e04c3fSmrg   inline void set_num_state_slots(unsigned n)
57701e04c3fSmrg   {
57801e04c3fSmrg      assert(!this->is_interface_instance()
57901e04c3fSmrg             || n == 0);
58001e04c3fSmrg      this->data._num_state_slots = n;
58101e04c3fSmrg   }
58201e04c3fSmrg
58301e04c3fSmrg   inline ir_state_slot *get_state_slots()
58401e04c3fSmrg   {
58501e04c3fSmrg      return this->is_interface_instance() ? NULL : this->u.state_slots;
58601e04c3fSmrg   }
58701e04c3fSmrg
58801e04c3fSmrg   inline const ir_state_slot *get_state_slots() const
58901e04c3fSmrg   {
59001e04c3fSmrg      return this->is_interface_instance() ? NULL : this->u.state_slots;
59101e04c3fSmrg   }
59201e04c3fSmrg
59301e04c3fSmrg   inline ir_state_slot *allocate_state_slots(unsigned n)
59401e04c3fSmrg   {
59501e04c3fSmrg      assert(!this->is_interface_instance());
59601e04c3fSmrg
59701e04c3fSmrg      this->u.state_slots = ralloc_array(this, ir_state_slot, n);
59801e04c3fSmrg      this->data._num_state_slots = 0;
59901e04c3fSmrg
60001e04c3fSmrg      if (this->u.state_slots != NULL)
60101e04c3fSmrg         this->data._num_state_slots = n;
60201e04c3fSmrg
60301e04c3fSmrg      return this->u.state_slots;
60401e04c3fSmrg   }
60501e04c3fSmrg
60601e04c3fSmrg   inline bool is_interpolation_flat() const
60701e04c3fSmrg   {
60801e04c3fSmrg      return this->data.interpolation == INTERP_MODE_FLAT ||
60901e04c3fSmrg             this->type->contains_integer() ||
61001e04c3fSmrg             this->type->contains_double();
61101e04c3fSmrg   }
61201e04c3fSmrg
61301e04c3fSmrg   inline bool is_name_ralloced() const
61401e04c3fSmrg   {
61501e04c3fSmrg      return this->name != ir_variable::tmp_name &&
61601e04c3fSmrg             this->name != this->name_storage;
61701e04c3fSmrg   }
61801e04c3fSmrg
61901e04c3fSmrg   /**
62001e04c3fSmrg    * Enable emitting extension warnings for this variable
62101e04c3fSmrg    */
62201e04c3fSmrg   void enable_extension_warning(const char *extension);
62301e04c3fSmrg
62401e04c3fSmrg   /**
62501e04c3fSmrg    * Get the extension warning string for this variable
62601e04c3fSmrg    *
62701e04c3fSmrg    * If warnings are not enabled, \c NULL is returned.
62801e04c3fSmrg    */
62901e04c3fSmrg   const char *get_extension_warning() const;
63001e04c3fSmrg
63101e04c3fSmrg   /**
63201e04c3fSmrg    * Declared type of the variable
63301e04c3fSmrg    */
63401e04c3fSmrg   const struct glsl_type *type;
63501e04c3fSmrg
63601e04c3fSmrg   /**
63701e04c3fSmrg    * Declared name of the variable
63801e04c3fSmrg    */
63901e04c3fSmrg   const char *name;
64001e04c3fSmrg
64101e04c3fSmrgprivate:
64201e04c3fSmrg   /**
64301e04c3fSmrg    * If the name length fits into name_storage, it's used, otherwise
64401e04c3fSmrg    * the name is ralloc'd. shader-db mining showed that 70% of variables
64501e04c3fSmrg    * fit here. This is a win over ralloc where only ralloc_header has
64601e04c3fSmrg    * 20 bytes on 64-bit (28 bytes with DEBUG), and we can also skip malloc.
64701e04c3fSmrg    */
64801e04c3fSmrg   char name_storage[16];
64901e04c3fSmrg
65001e04c3fSmrgpublic:
65101e04c3fSmrg   struct ir_variable_data {
65201e04c3fSmrg
65301e04c3fSmrg      /**
65401e04c3fSmrg       * Is the variable read-only?
65501e04c3fSmrg       *
65601e04c3fSmrg       * This is set for variables declared as \c const, shader inputs,
65701e04c3fSmrg       * and uniforms.
65801e04c3fSmrg       */
65901e04c3fSmrg      unsigned read_only:1;
66001e04c3fSmrg      unsigned centroid:1;
66101e04c3fSmrg      unsigned sample:1;
66201e04c3fSmrg      unsigned patch:1;
663993e1d59Smrg      /**
664993e1d59Smrg       * Was an 'invariant' qualifier explicitly set in the shader?
665993e1d59Smrg       *
666993e1d59Smrg       * This is used to cross validate qualifiers.
667993e1d59Smrg       */
668993e1d59Smrg      unsigned explicit_invariant:1;
669993e1d59Smrg      /**
670993e1d59Smrg       * Is the variable invariant?
671993e1d59Smrg       *
672993e1d59Smrg       * It can happen either by having the 'invariant' qualifier
673993e1d59Smrg       * explicitly set in the shader or by being used in calculations
674993e1d59Smrg       * of other invariant variables.
675993e1d59Smrg       */
67601e04c3fSmrg      unsigned invariant:1;
67701e04c3fSmrg      unsigned precise:1;
67801e04c3fSmrg
67901e04c3fSmrg      /**
68001e04c3fSmrg       * Has this variable been used for reading or writing?
68101e04c3fSmrg       *
68201e04c3fSmrg       * Several GLSL semantic checks require knowledge of whether or not a
68301e04c3fSmrg       * variable has been used.  For example, it is an error to redeclare a
68401e04c3fSmrg       * variable as invariant after it has been used.
68501e04c3fSmrg       *
68601e04c3fSmrg       * This is maintained in the ast_to_hir.cpp path and during linking,
68701e04c3fSmrg       * but not in Mesa's fixed function or ARB program paths.
68801e04c3fSmrg       */
68901e04c3fSmrg      unsigned used:1;
69001e04c3fSmrg
69101e04c3fSmrg      /**
69201e04c3fSmrg       * Has this variable been statically assigned?
69301e04c3fSmrg       *
69401e04c3fSmrg       * This answers whether the variable was assigned in any path of
69501e04c3fSmrg       * the shader during ast_to_hir.  This doesn't answer whether it is
69601e04c3fSmrg       * still written after dead code removal, nor is it maintained in
69701e04c3fSmrg       * non-ast_to_hir.cpp (GLSL parsing) paths.
69801e04c3fSmrg       */
69901e04c3fSmrg      unsigned assigned:1;
70001e04c3fSmrg
70101e04c3fSmrg      /**
70201e04c3fSmrg       * When separate shader programs are enabled, only input/outputs between
70301e04c3fSmrg       * the stages of a multi-stage separate program can be safely removed
70401e04c3fSmrg       * from the shader interface. Other input/outputs must remains active.
70501e04c3fSmrg       */
70601e04c3fSmrg      unsigned always_active_io:1;
70701e04c3fSmrg
70801e04c3fSmrg      /**
70901e04c3fSmrg       * Enum indicating how the variable was declared.  See
71001e04c3fSmrg       * ir_var_declaration_type.
71101e04c3fSmrg       *
71201e04c3fSmrg       * This is used to detect certain kinds of illegal variable redeclarations.
71301e04c3fSmrg       */
71401e04c3fSmrg      unsigned how_declared:2;
71501e04c3fSmrg
71601e04c3fSmrg      /**
71701e04c3fSmrg       * Storage class of the variable.
71801e04c3fSmrg       *
71901e04c3fSmrg       * \sa ir_variable_mode
72001e04c3fSmrg       */
72101e04c3fSmrg      unsigned mode:4;
72201e04c3fSmrg
72301e04c3fSmrg      /**
72401e04c3fSmrg       * Interpolation mode for shader inputs / outputs
72501e04c3fSmrg       *
72601e04c3fSmrg       * \sa glsl_interp_mode
72701e04c3fSmrg       */
72801e04c3fSmrg      unsigned interpolation:2;
72901e04c3fSmrg
73001e04c3fSmrg      /**
73101e04c3fSmrg       * Was the location explicitly set in the shader?
73201e04c3fSmrg       *
73301e04c3fSmrg       * If the location is explicitly set in the shader, it \b cannot be changed
73401e04c3fSmrg       * by the linker or by the API (e.g., calls to \c glBindAttribLocation have
73501e04c3fSmrg       * no effect).
73601e04c3fSmrg       */
73701e04c3fSmrg      unsigned explicit_location:1;
73801e04c3fSmrg      unsigned explicit_index:1;
73901e04c3fSmrg
74001e04c3fSmrg      /**
74101e04c3fSmrg       * Was an initial binding explicitly set in the shader?
74201e04c3fSmrg       *
74301e04c3fSmrg       * If so, constant_value contains an integer ir_constant representing the
74401e04c3fSmrg       * initial binding point.
74501e04c3fSmrg       */
74601e04c3fSmrg      unsigned explicit_binding:1;
74701e04c3fSmrg
74801e04c3fSmrg      /**
74901e04c3fSmrg       * Was an initial component explicitly set in the shader?
75001e04c3fSmrg       */
75101e04c3fSmrg      unsigned explicit_component:1;
75201e04c3fSmrg
75301e04c3fSmrg      /**
75401e04c3fSmrg       * Does this variable have an initializer?
75501e04c3fSmrg       *
75601e04c3fSmrg       * This is used by the linker to cross-validiate initializers of global
75701e04c3fSmrg       * variables.
75801e04c3fSmrg       */
75901e04c3fSmrg      unsigned has_initializer:1;
76001e04c3fSmrg
7617ec681f3Smrg      /**
7627ec681f3Smrg       * Is the initializer created by the compiler (glsl_zero_init)
7637ec681f3Smrg       */
7647ec681f3Smrg      unsigned is_implicit_initializer:1;
7657ec681f3Smrg
76601e04c3fSmrg      /**
76701e04c3fSmrg       * Is this variable a generic output or input that has not yet been matched
76801e04c3fSmrg       * up to a variable in another stage of the pipeline?
76901e04c3fSmrg       *
77001e04c3fSmrg       * This is used by the linker as scratch storage while assigning locations
77101e04c3fSmrg       * to generic inputs and outputs.
77201e04c3fSmrg       */
77301e04c3fSmrg      unsigned is_unmatched_generic_inout:1;
77401e04c3fSmrg
7757ec681f3Smrg      /**
7767ec681f3Smrg       * Is this varying used by transform feedback?
7777ec681f3Smrg       *
7787ec681f3Smrg       * This is used by the linker to decide if it's safe to pack the varying.
7797ec681f3Smrg       */
7807ec681f3Smrg      unsigned is_xfb:1;
7817ec681f3Smrg
78201e04c3fSmrg      /**
78301e04c3fSmrg       * Is this varying used only by transform feedback?
78401e04c3fSmrg       *
78501e04c3fSmrg       * This is used by the linker to decide if its safe to pack the varying.
78601e04c3fSmrg       */
78701e04c3fSmrg      unsigned is_xfb_only:1;
78801e04c3fSmrg
78901e04c3fSmrg      /**
7907e102996Smaya       * Was a transform feedback buffer set in the shader?
79101e04c3fSmrg       */
79201e04c3fSmrg      unsigned explicit_xfb_buffer:1;
79301e04c3fSmrg
79401e04c3fSmrg      /**
7957e102996Smaya       * Was a transform feedback offset set in the shader?
79601e04c3fSmrg       */
79701e04c3fSmrg      unsigned explicit_xfb_offset:1;
79801e04c3fSmrg
79901e04c3fSmrg      /**
8007e102996Smaya       * Was a transform feedback stride set in the shader?
80101e04c3fSmrg       */
80201e04c3fSmrg      unsigned explicit_xfb_stride:1;
80301e04c3fSmrg
80401e04c3fSmrg      /**
80501e04c3fSmrg       * If non-zero, then this variable may be packed along with other variables
80601e04c3fSmrg       * into a single varying slot, so this offset should be applied when
80701e04c3fSmrg       * accessing components.  For example, an offset of 1 means that the x
80801e04c3fSmrg       * component of this variable is actually stored in component y of the
80901e04c3fSmrg       * location specified by \c location.
81001e04c3fSmrg       */
81101e04c3fSmrg      unsigned location_frac:2;
81201e04c3fSmrg
81301e04c3fSmrg      /**
81401e04c3fSmrg       * Layout of the matrix.  Uses glsl_matrix_layout values.
81501e04c3fSmrg       */
81601e04c3fSmrg      unsigned matrix_layout:2;
81701e04c3fSmrg
81801e04c3fSmrg      /**
81901e04c3fSmrg       * Non-zero if this variable was created by lowering a named interface
82001e04c3fSmrg       * block.
82101e04c3fSmrg       */
82201e04c3fSmrg      unsigned from_named_ifc_block:1;
82301e04c3fSmrg
82401e04c3fSmrg      /**
82501e04c3fSmrg       * Non-zero if the variable must be a shader input. This is useful for
82601e04c3fSmrg       * constraints on function parameters.
82701e04c3fSmrg       */
82801e04c3fSmrg      unsigned must_be_shader_input:1;
82901e04c3fSmrg
83001e04c3fSmrg      /**
83101e04c3fSmrg       * Output index for dual source blending.
83201e04c3fSmrg       *
83301e04c3fSmrg       * \note
83401e04c3fSmrg       * The GLSL spec only allows the values 0 or 1 for the index in \b dual
83501e04c3fSmrg       * source blending.
83601e04c3fSmrg       */
83701e04c3fSmrg      unsigned index:1;
83801e04c3fSmrg
83901e04c3fSmrg      /**
84001e04c3fSmrg       * Precision qualifier.
84101e04c3fSmrg       *
84201e04c3fSmrg       * In desktop GLSL we do not care about precision qualifiers at all, in
84301e04c3fSmrg       * fact, the spec says that precision qualifiers are ignored.
84401e04c3fSmrg       *
84501e04c3fSmrg       * To make things easy, we make it so that this field is always
84601e04c3fSmrg       * GLSL_PRECISION_NONE on desktop shaders. This way all the variables
84701e04c3fSmrg       * have the same precision value and the checks we add in the compiler
84801e04c3fSmrg       * for this field will never break a desktop shader compile.
84901e04c3fSmrg       */
85001e04c3fSmrg      unsigned precision:2;
85101e04c3fSmrg
85201e04c3fSmrg      /**
85301e04c3fSmrg       * \brief Layout qualifier for gl_FragDepth.
85401e04c3fSmrg       *
85501e04c3fSmrg       * This is not equal to \c ir_depth_layout_none if and only if this
85601e04c3fSmrg       * variable is \c gl_FragDepth and a layout qualifier is specified.
85701e04c3fSmrg       */
85801e04c3fSmrg      ir_depth_layout depth_layout:3;
85901e04c3fSmrg
86001e04c3fSmrg      /**
86101e04c3fSmrg       * Memory qualifiers.
86201e04c3fSmrg       */
86301e04c3fSmrg      unsigned memory_read_only:1; /**< "readonly" qualifier. */
86401e04c3fSmrg      unsigned memory_write_only:1; /**< "writeonly" qualifier. */
86501e04c3fSmrg      unsigned memory_coherent:1;
86601e04c3fSmrg      unsigned memory_volatile:1;
86701e04c3fSmrg      unsigned memory_restrict:1;
86801e04c3fSmrg
86901e04c3fSmrg      /**
87001e04c3fSmrg       * ARB_shader_storage_buffer_object
87101e04c3fSmrg       */
87201e04c3fSmrg      unsigned from_ssbo_unsized_array:1; /**< unsized array buffer variable. */
87301e04c3fSmrg
87401e04c3fSmrg      unsigned implicit_sized_array:1;
87501e04c3fSmrg
87601e04c3fSmrg      /**
87701e04c3fSmrg       * Whether this is a fragment shader output implicitly initialized with
87801e04c3fSmrg       * the previous contents of the specified render target at the
87901e04c3fSmrg       * framebuffer location corresponding to this shader invocation.
88001e04c3fSmrg       */
88101e04c3fSmrg      unsigned fb_fetch_output:1;
88201e04c3fSmrg
88301e04c3fSmrg      /**
88401e04c3fSmrg       * Non-zero if this variable is considered bindless as defined by
88501e04c3fSmrg       * ARB_bindless_texture.
88601e04c3fSmrg       */
88701e04c3fSmrg      unsigned bindless:1;
88801e04c3fSmrg
88901e04c3fSmrg      /**
89001e04c3fSmrg       * Non-zero if this variable is considered bound as defined by
89101e04c3fSmrg       * ARB_bindless_texture.
89201e04c3fSmrg       */
89301e04c3fSmrg      unsigned bound:1;
89401e04c3fSmrg
8957ec681f3Smrg      /**
8967ec681f3Smrg       * Non-zero if the variable shall not be implicitly converted during
8977ec681f3Smrg       * functions matching.
8987ec681f3Smrg       */
8997ec681f3Smrg      unsigned implicit_conversion_prohibited:1;
9007ec681f3Smrg
90101e04c3fSmrg      /**
90201e04c3fSmrg       * Emit a warning if this variable is accessed.
90301e04c3fSmrg       */
90401e04c3fSmrg   private:
90501e04c3fSmrg      uint8_t warn_extension_index;
90601e04c3fSmrg
90701e04c3fSmrg   public:
9087ec681f3Smrg      /**
9097ec681f3Smrg       * Image internal format if specified explicitly, otherwise
9107ec681f3Smrg       * PIPE_FORMAT_NONE.
9117ec681f3Smrg       */
9127ec681f3Smrg      enum pipe_format image_format;
91301e04c3fSmrg
91401e04c3fSmrg   private:
91501e04c3fSmrg      /**
91601e04c3fSmrg       * Number of state slots used
91701e04c3fSmrg       *
91801e04c3fSmrg       * \note
91901e04c3fSmrg       * This could be stored in as few as 7-bits, if necessary.  If it is made
92001e04c3fSmrg       * smaller, add an assertion to \c ir_variable::allocate_state_slots to
92101e04c3fSmrg       * be safe.
92201e04c3fSmrg       */
92301e04c3fSmrg      uint16_t _num_state_slots;
92401e04c3fSmrg
92501e04c3fSmrg   public:
92601e04c3fSmrg      /**
92701e04c3fSmrg       * Initial binding point for a sampler, atomic, or UBO.
92801e04c3fSmrg       *
92901e04c3fSmrg       * For array types, this represents the binding point for the first element.
93001e04c3fSmrg       */
9317ec681f3Smrg      uint16_t binding;
93201e04c3fSmrg
93301e04c3fSmrg      /**
93401e04c3fSmrg       * Storage location of the base of this variable
93501e04c3fSmrg       *
93601e04c3fSmrg       * The precise meaning of this field depends on the nature of the variable.
93701e04c3fSmrg       *
93801e04c3fSmrg       *   - Vertex shader input: one of the values from \c gl_vert_attrib.
93901e04c3fSmrg       *   - Vertex shader output: one of the values from \c gl_varying_slot.
94001e04c3fSmrg       *   - Geometry shader input: one of the values from \c gl_varying_slot.
94101e04c3fSmrg       *   - Geometry shader output: one of the values from \c gl_varying_slot.
94201e04c3fSmrg       *   - Fragment shader input: one of the values from \c gl_varying_slot.
94301e04c3fSmrg       *   - Fragment shader output: one of the values from \c gl_frag_result.
94401e04c3fSmrg       *   - Uniforms: Per-stage uniform slot number for default uniform block.
94501e04c3fSmrg       *   - Uniforms: Index within the uniform block definition for UBO members.
94601e04c3fSmrg       *   - Non-UBO Uniforms: explicit location until linking then reused to
94701e04c3fSmrg       *     store uniform slot number.
94801e04c3fSmrg       *   - Other: This field is not currently used.
94901e04c3fSmrg       *
95001e04c3fSmrg       * If the variable is a uniform, shader input, or shader output, and the
95101e04c3fSmrg       * slot has not been assigned, the value will be -1.
95201e04c3fSmrg       */
95301e04c3fSmrg      int location;
95401e04c3fSmrg
95501e04c3fSmrg      /**
95601e04c3fSmrg       * for glsl->tgsi/mesa IR we need to store the index into the
95701e04c3fSmrg       * parameters for uniforms, initially the code overloaded location
95801e04c3fSmrg       * but this causes problems with indirect samplers and AoA.
95901e04c3fSmrg       * This is assigned in _mesa_generate_parameters_list_for_uniforms.
96001e04c3fSmrg       */
96101e04c3fSmrg      int param_index;
96201e04c3fSmrg
96301e04c3fSmrg      /**
96401e04c3fSmrg       * Vertex stream output identifier.
96501e04c3fSmrg       *
96601e04c3fSmrg       * For packed outputs, bit 31 is set and bits [2*i+1,2*i] indicate the
96701e04c3fSmrg       * stream of the i-th component.
96801e04c3fSmrg       */
96901e04c3fSmrg      unsigned stream;
97001e04c3fSmrg
97101e04c3fSmrg      /**
97201e04c3fSmrg       * Atomic, transform feedback or block member offset.
97301e04c3fSmrg       */
97401e04c3fSmrg      unsigned offset;
97501e04c3fSmrg
97601e04c3fSmrg      /**
97701e04c3fSmrg       * Highest element accessed with a constant expression array index
97801e04c3fSmrg       *
97901e04c3fSmrg       * Not used for non-array variables. -1 is never accessed.
98001e04c3fSmrg       */
98101e04c3fSmrg      int max_array_access;
98201e04c3fSmrg
98301e04c3fSmrg      /**
98401e04c3fSmrg       * Transform feedback buffer.
98501e04c3fSmrg       */
98601e04c3fSmrg      unsigned xfb_buffer;
98701e04c3fSmrg
98801e04c3fSmrg      /**
98901e04c3fSmrg       * Transform feedback stride.
99001e04c3fSmrg       */
99101e04c3fSmrg      unsigned xfb_stride;
99201e04c3fSmrg
99301e04c3fSmrg      /**
99401e04c3fSmrg       * Allow (only) ir_variable direct access private members.
99501e04c3fSmrg       */
99601e04c3fSmrg      friend class ir_variable;
99701e04c3fSmrg   } data;
99801e04c3fSmrg
99901e04c3fSmrg   /**
100001e04c3fSmrg    * Value assigned in the initializer of a variable declared "const"
100101e04c3fSmrg    */
100201e04c3fSmrg   ir_constant *constant_value;
100301e04c3fSmrg
100401e04c3fSmrg   /**
100501e04c3fSmrg    * Constant expression assigned in the initializer of the variable
100601e04c3fSmrg    *
100701e04c3fSmrg    * \warning
100801e04c3fSmrg    * This field and \c ::constant_value are distinct.  Even if the two fields
100901e04c3fSmrg    * refer to constants with the same value, they must point to separate
101001e04c3fSmrg    * objects.
101101e04c3fSmrg    */
101201e04c3fSmrg   ir_constant *constant_initializer;
101301e04c3fSmrg
101401e04c3fSmrgprivate:
101501e04c3fSmrg   static const char *const warn_extension_table[];
101601e04c3fSmrg
101701e04c3fSmrg   union {
101801e04c3fSmrg      /**
101901e04c3fSmrg       * For variables which satisfy the is_interface_instance() predicate,
102001e04c3fSmrg       * this points to an array of integers such that if the ith member of
102101e04c3fSmrg       * the interface block is an array, max_ifc_array_access[i] is the
102201e04c3fSmrg       * maximum array element of that member that has been accessed.  If the
102301e04c3fSmrg       * ith member of the interface block is not an array,
102401e04c3fSmrg       * max_ifc_array_access[i] is unused.
102501e04c3fSmrg       *
102601e04c3fSmrg       * For variables whose type is not an interface block, this pointer is
102701e04c3fSmrg       * NULL.
102801e04c3fSmrg       */
102901e04c3fSmrg      int *max_ifc_array_access;
103001e04c3fSmrg
103101e04c3fSmrg      /**
103201e04c3fSmrg       * Built-in state that backs this uniform
103301e04c3fSmrg       *
103401e04c3fSmrg       * Once set at variable creation, \c state_slots must remain invariant.
103501e04c3fSmrg       *
103601e04c3fSmrg       * If the variable is not a uniform, \c _num_state_slots will be zero
103701e04c3fSmrg       * and \c state_slots will be \c NULL.
103801e04c3fSmrg       */
103901e04c3fSmrg      ir_state_slot *state_slots;
104001e04c3fSmrg   } u;
104101e04c3fSmrg
104201e04c3fSmrg   /**
104301e04c3fSmrg    * For variables that are in an interface block or are an instance of an
104401e04c3fSmrg    * interface block, this is the \c GLSL_TYPE_INTERFACE type for that block.
104501e04c3fSmrg    *
104601e04c3fSmrg    * \sa ir_variable::location
104701e04c3fSmrg    */
104801e04c3fSmrg   const glsl_type *interface_type;
104901e04c3fSmrg
105001e04c3fSmrg   /**
105101e04c3fSmrg    * Name used for anonymous compiler temporaries
105201e04c3fSmrg    */
105301e04c3fSmrg   static const char tmp_name[];
105401e04c3fSmrg
105501e04c3fSmrgpublic:
105601e04c3fSmrg   /**
105701e04c3fSmrg    * Should the construct keep names for ir_var_temporary variables?
105801e04c3fSmrg    *
105901e04c3fSmrg    * When this global is false, names passed to the constructor for
106001e04c3fSmrg    * \c ir_var_temporary variables will be dropped.  Instead, the variable will
106101e04c3fSmrg    * be named "compiler_temp".  This name will be in static storage.
106201e04c3fSmrg    *
106301e04c3fSmrg    * \warning
106401e04c3fSmrg    * \b NEVER change the mode of an \c ir_var_temporary.
106501e04c3fSmrg    *
106601e04c3fSmrg    * \warning
106701e04c3fSmrg    * This variable is \b not thread-safe.  It is global, \b not
106801e04c3fSmrg    * per-context. It begins life false.  A context can, at some point, make
106901e04c3fSmrg    * it true.  From that point on, it will be true forever.  This should be
107001e04c3fSmrg    * okay since it will only be set true while debugging.
107101e04c3fSmrg    */
107201e04c3fSmrg   static bool temporaries_allocate_names;
107301e04c3fSmrg};
107401e04c3fSmrg
107501e04c3fSmrg/**
107601e04c3fSmrg * A function that returns whether a built-in function is available in the
107701e04c3fSmrg * current shading language (based on version, ES or desktop, and extensions).
107801e04c3fSmrg */
107901e04c3fSmrgtypedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *);
108001e04c3fSmrg
108101e04c3fSmrg#define MAKE_INTRINSIC_FOR_TYPE(op, t) \
108201e04c3fSmrg   ir_intrinsic_generic_ ## op - ir_intrinsic_generic_load + ir_intrinsic_ ## t ## _ ## load
108301e04c3fSmrg
108401e04c3fSmrg#define MAP_INTRINSIC_TO_TYPE(i, t) \
108501e04c3fSmrg   ir_intrinsic_id(int(i) - int(ir_intrinsic_generic_load) + int(ir_intrinsic_ ## t ## _ ## load))
108601e04c3fSmrg
108701e04c3fSmrgenum ir_intrinsic_id {
108801e04c3fSmrg   ir_intrinsic_invalid = 0,
108901e04c3fSmrg
109001e04c3fSmrg   /**
109101e04c3fSmrg    * \name Generic intrinsics
109201e04c3fSmrg    *
109301e04c3fSmrg    * Each of these intrinsics has a specific version for shared variables and
109401e04c3fSmrg    * SSBOs.
109501e04c3fSmrg    */
109601e04c3fSmrg   /*@{*/
109701e04c3fSmrg   ir_intrinsic_generic_load,
109801e04c3fSmrg   ir_intrinsic_generic_store,
109901e04c3fSmrg   ir_intrinsic_generic_atomic_add,
110001e04c3fSmrg   ir_intrinsic_generic_atomic_and,
110101e04c3fSmrg   ir_intrinsic_generic_atomic_or,
110201e04c3fSmrg   ir_intrinsic_generic_atomic_xor,
110301e04c3fSmrg   ir_intrinsic_generic_atomic_min,
110401e04c3fSmrg   ir_intrinsic_generic_atomic_max,
110501e04c3fSmrg   ir_intrinsic_generic_atomic_exchange,
110601e04c3fSmrg   ir_intrinsic_generic_atomic_comp_swap,
110701e04c3fSmrg   /*@}*/
110801e04c3fSmrg
110901e04c3fSmrg   ir_intrinsic_atomic_counter_read,
111001e04c3fSmrg   ir_intrinsic_atomic_counter_increment,
111101e04c3fSmrg   ir_intrinsic_atomic_counter_predecrement,
111201e04c3fSmrg   ir_intrinsic_atomic_counter_add,
111301e04c3fSmrg   ir_intrinsic_atomic_counter_and,
111401e04c3fSmrg   ir_intrinsic_atomic_counter_or,
111501e04c3fSmrg   ir_intrinsic_atomic_counter_xor,
111601e04c3fSmrg   ir_intrinsic_atomic_counter_min,
111701e04c3fSmrg   ir_intrinsic_atomic_counter_max,
111801e04c3fSmrg   ir_intrinsic_atomic_counter_exchange,
111901e04c3fSmrg   ir_intrinsic_atomic_counter_comp_swap,
112001e04c3fSmrg
112101e04c3fSmrg   ir_intrinsic_image_load,
112201e04c3fSmrg   ir_intrinsic_image_store,
112301e04c3fSmrg   ir_intrinsic_image_atomic_add,
112401e04c3fSmrg   ir_intrinsic_image_atomic_and,
112501e04c3fSmrg   ir_intrinsic_image_atomic_or,
112601e04c3fSmrg   ir_intrinsic_image_atomic_xor,
112701e04c3fSmrg   ir_intrinsic_image_atomic_min,
112801e04c3fSmrg   ir_intrinsic_image_atomic_max,
112901e04c3fSmrg   ir_intrinsic_image_atomic_exchange,
113001e04c3fSmrg   ir_intrinsic_image_atomic_comp_swap,
113101e04c3fSmrg   ir_intrinsic_image_size,
113201e04c3fSmrg   ir_intrinsic_image_samples,
11337ec681f3Smrg   ir_intrinsic_image_atomic_inc_wrap,
11347ec681f3Smrg   ir_intrinsic_image_atomic_dec_wrap,
113501e04c3fSmrg
113601e04c3fSmrg   ir_intrinsic_ssbo_load,
113701e04c3fSmrg   ir_intrinsic_ssbo_store = MAKE_INTRINSIC_FOR_TYPE(store, ssbo),
113801e04c3fSmrg   ir_intrinsic_ssbo_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, ssbo),
113901e04c3fSmrg   ir_intrinsic_ssbo_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, ssbo),
114001e04c3fSmrg   ir_intrinsic_ssbo_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, ssbo),
114101e04c3fSmrg   ir_intrinsic_ssbo_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, ssbo),
114201e04c3fSmrg   ir_intrinsic_ssbo_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, ssbo),
114301e04c3fSmrg   ir_intrinsic_ssbo_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, ssbo),
114401e04c3fSmrg   ir_intrinsic_ssbo_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, ssbo),
114501e04c3fSmrg   ir_intrinsic_ssbo_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, ssbo),
114601e04c3fSmrg
114701e04c3fSmrg   ir_intrinsic_memory_barrier,
114801e04c3fSmrg   ir_intrinsic_shader_clock,
114901e04c3fSmrg   ir_intrinsic_group_memory_barrier,
115001e04c3fSmrg   ir_intrinsic_memory_barrier_atomic_counter,
115101e04c3fSmrg   ir_intrinsic_memory_barrier_buffer,
115201e04c3fSmrg   ir_intrinsic_memory_barrier_image,
115301e04c3fSmrg   ir_intrinsic_memory_barrier_shared,
115401e04c3fSmrg   ir_intrinsic_begin_invocation_interlock,
115501e04c3fSmrg   ir_intrinsic_end_invocation_interlock,
115601e04c3fSmrg
115701e04c3fSmrg   ir_intrinsic_vote_all,
115801e04c3fSmrg   ir_intrinsic_vote_any,
115901e04c3fSmrg   ir_intrinsic_vote_eq,
116001e04c3fSmrg   ir_intrinsic_ballot,
116101e04c3fSmrg   ir_intrinsic_read_invocation,
116201e04c3fSmrg   ir_intrinsic_read_first_invocation,
116301e04c3fSmrg
11647ec681f3Smrg   ir_intrinsic_helper_invocation,
11657ec681f3Smrg
116601e04c3fSmrg   ir_intrinsic_shared_load,
116701e04c3fSmrg   ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),
116801e04c3fSmrg   ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared),
116901e04c3fSmrg   ir_intrinsic_shared_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, shared),
117001e04c3fSmrg   ir_intrinsic_shared_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, shared),
117101e04c3fSmrg   ir_intrinsic_shared_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, shared),
117201e04c3fSmrg   ir_intrinsic_shared_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, shared),
117301e04c3fSmrg   ir_intrinsic_shared_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, shared),
117401e04c3fSmrg   ir_intrinsic_shared_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, shared),
117501e04c3fSmrg   ir_intrinsic_shared_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, shared),
117601e04c3fSmrg};
117701e04c3fSmrg
117801e04c3fSmrg/*@{*/
117901e04c3fSmrg/**
118001e04c3fSmrg * The representation of a function instance; may be the full definition or
118101e04c3fSmrg * simply a prototype.
118201e04c3fSmrg */
118301e04c3fSmrgclass ir_function_signature : public ir_instruction {
118401e04c3fSmrg   /* An ir_function_signature will be part of the list of signatures in
118501e04c3fSmrg    * an ir_function.
118601e04c3fSmrg    */
118701e04c3fSmrgpublic:
118801e04c3fSmrg   ir_function_signature(const glsl_type *return_type,
118901e04c3fSmrg                         builtin_available_predicate builtin_avail = NULL);
119001e04c3fSmrg
119101e04c3fSmrg   virtual ir_function_signature *clone(void *mem_ctx,
119201e04c3fSmrg					struct hash_table *ht) const;
119301e04c3fSmrg   ir_function_signature *clone_prototype(void *mem_ctx,
119401e04c3fSmrg					  struct hash_table *ht) const;
119501e04c3fSmrg
119601e04c3fSmrg   virtual void accept(ir_visitor *v)
119701e04c3fSmrg   {
119801e04c3fSmrg      v->visit(this);
119901e04c3fSmrg   }
120001e04c3fSmrg
120101e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
120201e04c3fSmrg
120301e04c3fSmrg   /**
120401e04c3fSmrg    * Attempt to evaluate this function as a constant expression,
120501e04c3fSmrg    * given a list of the actual parameters and the variable context.
120601e04c3fSmrg    * Returns NULL for non-built-ins.
120701e04c3fSmrg    */
120801e04c3fSmrg   ir_constant *constant_expression_value(void *mem_ctx,
120901e04c3fSmrg                                          exec_list *actual_parameters,
121001e04c3fSmrg                                          struct hash_table *variable_context);
121101e04c3fSmrg
121201e04c3fSmrg   /**
121301e04c3fSmrg    * Get the name of the function for which this is a signature
121401e04c3fSmrg    */
121501e04c3fSmrg   const char *function_name() const;
121601e04c3fSmrg
121701e04c3fSmrg   /**
121801e04c3fSmrg    * Get a handle to the function for which this is a signature
121901e04c3fSmrg    *
122001e04c3fSmrg    * There is no setter function, this function returns a \c const pointer,
122101e04c3fSmrg    * and \c ir_function_signature::_function is private for a reason.  The
122201e04c3fSmrg    * only way to make a connection between a function and function signature
122301e04c3fSmrg    * is via \c ir_function::add_signature.  This helps ensure that certain
122401e04c3fSmrg    * invariants (i.e., a function signature is in the list of signatures for
122501e04c3fSmrg    * its \c _function) are met.
122601e04c3fSmrg    *
122701e04c3fSmrg    * \sa ir_function::add_signature
122801e04c3fSmrg    */
122901e04c3fSmrg   inline const class ir_function *function() const
123001e04c3fSmrg   {
123101e04c3fSmrg      return this->_function;
123201e04c3fSmrg   }
123301e04c3fSmrg
123401e04c3fSmrg   /**
123501e04c3fSmrg    * Check whether the qualifiers match between this signature's parameters
123601e04c3fSmrg    * and the supplied parameter list.  If not, returns the name of the first
123701e04c3fSmrg    * parameter with mismatched qualifiers (for use in error messages).
123801e04c3fSmrg    */
123901e04c3fSmrg   const char *qualifiers_match(exec_list *params);
124001e04c3fSmrg
124101e04c3fSmrg   /**
124201e04c3fSmrg    * Replace the current parameter list with the given one.  This is useful
124301e04c3fSmrg    * if the current information came from a prototype, and either has invalid
124401e04c3fSmrg    * or missing parameter names.
124501e04c3fSmrg    */
124601e04c3fSmrg   void replace_parameters(exec_list *new_params);
124701e04c3fSmrg
124801e04c3fSmrg   /**
124901e04c3fSmrg    * Function return type.
125001e04c3fSmrg    *
12517ec681f3Smrg    * \note The precision qualifier is stored separately in return_precision.
125201e04c3fSmrg    */
125301e04c3fSmrg   const struct glsl_type *return_type;
125401e04c3fSmrg
125501e04c3fSmrg   /**
125601e04c3fSmrg    * List of ir_variable of function parameters.
125701e04c3fSmrg    *
125801e04c3fSmrg    * This represents the storage.  The paramaters passed in a particular
125901e04c3fSmrg    * call will be in ir_call::actual_paramaters.
126001e04c3fSmrg    */
126101e04c3fSmrg   struct exec_list parameters;
126201e04c3fSmrg
126301e04c3fSmrg   /** Whether or not this function has a body (which may be empty). */
126401e04c3fSmrg   unsigned is_defined:1;
126501e04c3fSmrg
12667ec681f3Smrg   /*
12677ec681f3Smrg    * Precision qualifier for the return type.
12687ec681f3Smrg    *
12697ec681f3Smrg    * See the comment for ir_variable_data::precision for more details.
12707ec681f3Smrg    */
12717ec681f3Smrg   unsigned return_precision:2;
12727ec681f3Smrg
127301e04c3fSmrg   /** Whether or not this function signature is a built-in. */
127401e04c3fSmrg   bool is_builtin() const;
127501e04c3fSmrg
127601e04c3fSmrg   /**
127701e04c3fSmrg    * Whether or not this function is an intrinsic to be implemented
127801e04c3fSmrg    * by the driver.
127901e04c3fSmrg    */
128001e04c3fSmrg   inline bool is_intrinsic() const
128101e04c3fSmrg   {
128201e04c3fSmrg      return intrinsic_id != ir_intrinsic_invalid;
128301e04c3fSmrg   }
128401e04c3fSmrg
12857ec681f3Smrg   /** Identifier for this intrinsic. */
128601e04c3fSmrg   enum ir_intrinsic_id intrinsic_id;
128701e04c3fSmrg
128801e04c3fSmrg   /** Whether or not a built-in is available for this shader. */
128901e04c3fSmrg   bool is_builtin_available(const _mesa_glsl_parse_state *state) const;
129001e04c3fSmrg
129101e04c3fSmrg   /** Body of instructions in the function. */
129201e04c3fSmrg   struct exec_list body;
129301e04c3fSmrg
129401e04c3fSmrgprivate:
129501e04c3fSmrg   /**
129601e04c3fSmrg    * A function pointer to a predicate that answers whether a built-in
129701e04c3fSmrg    * function is available in the current shader.  NULL if not a built-in.
129801e04c3fSmrg    */
129901e04c3fSmrg   builtin_available_predicate builtin_avail;
130001e04c3fSmrg
130101e04c3fSmrg   /** Function of which this signature is one overload. */
130201e04c3fSmrg   class ir_function *_function;
130301e04c3fSmrg
130401e04c3fSmrg   /** Function signature of which this one is a prototype clone */
130501e04c3fSmrg   const ir_function_signature *origin;
130601e04c3fSmrg
130701e04c3fSmrg   friend class ir_function;
130801e04c3fSmrg
130901e04c3fSmrg   /**
131001e04c3fSmrg    * Helper function to run a list of instructions for constant
131101e04c3fSmrg    * expression evaluation.
131201e04c3fSmrg    *
131301e04c3fSmrg    * The hash table represents the values of the visible variables.
131401e04c3fSmrg    * There are no scoping issues because the table is indexed on
131501e04c3fSmrg    * ir_variable pointers, not variable names.
131601e04c3fSmrg    *
131701e04c3fSmrg    * Returns false if the expression is not constant, true otherwise,
131801e04c3fSmrg    * and the value in *result if result is non-NULL.
131901e04c3fSmrg    */
132001e04c3fSmrg   bool constant_expression_evaluate_expression_list(void *mem_ctx,
132101e04c3fSmrg                                                     const struct exec_list &body,
132201e04c3fSmrg						     struct hash_table *variable_context,
132301e04c3fSmrg						     ir_constant **result);
132401e04c3fSmrg};
132501e04c3fSmrg
132601e04c3fSmrg
132701e04c3fSmrg/**
132801e04c3fSmrg * Header for tracking multiple overloaded functions with the same name.
132901e04c3fSmrg * Contains a list of ir_function_signatures representing each of the
133001e04c3fSmrg * actual functions.
133101e04c3fSmrg */
133201e04c3fSmrgclass ir_function : public ir_instruction {
133301e04c3fSmrgpublic:
133401e04c3fSmrg   ir_function(const char *name);
133501e04c3fSmrg
133601e04c3fSmrg   virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const;
133701e04c3fSmrg
133801e04c3fSmrg   virtual void accept(ir_visitor *v)
133901e04c3fSmrg   {
134001e04c3fSmrg      v->visit(this);
134101e04c3fSmrg   }
134201e04c3fSmrg
134301e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
134401e04c3fSmrg
134501e04c3fSmrg   void add_signature(ir_function_signature *sig)
134601e04c3fSmrg   {
134701e04c3fSmrg      sig->_function = this;
134801e04c3fSmrg      this->signatures.push_tail(sig);
134901e04c3fSmrg   }
135001e04c3fSmrg
135101e04c3fSmrg   /**
135201e04c3fSmrg    * Find a signature that matches a set of actual parameters, taking implicit
135301e04c3fSmrg    * conversions into account.  Also flags whether the match was exact.
135401e04c3fSmrg    */
135501e04c3fSmrg   ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
135601e04c3fSmrg                                             const exec_list *actual_param,
135701e04c3fSmrg                                             bool allow_builtins,
135801e04c3fSmrg					     bool *match_is_exact);
135901e04c3fSmrg
136001e04c3fSmrg   /**
136101e04c3fSmrg    * Find a signature that matches a set of actual parameters, taking implicit
136201e04c3fSmrg    * conversions into account.
136301e04c3fSmrg    */
136401e04c3fSmrg   ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
136501e04c3fSmrg                                             const exec_list *actual_param,
136601e04c3fSmrg                                             bool allow_builtins);
136701e04c3fSmrg
136801e04c3fSmrg   /**
136901e04c3fSmrg    * Find a signature that exactly matches a set of actual parameters without
137001e04c3fSmrg    * any implicit type conversions.
137101e04c3fSmrg    */
137201e04c3fSmrg   ir_function_signature *exact_matching_signature(_mesa_glsl_parse_state *state,
137301e04c3fSmrg                                                   const exec_list *actual_ps);
137401e04c3fSmrg
137501e04c3fSmrg   /**
137601e04c3fSmrg    * Name of the function.
137701e04c3fSmrg    */
137801e04c3fSmrg   const char *name;
137901e04c3fSmrg
138001e04c3fSmrg   /** Whether or not this function has a signature that isn't a built-in. */
138101e04c3fSmrg   bool has_user_signature();
138201e04c3fSmrg
138301e04c3fSmrg   /**
138401e04c3fSmrg    * List of ir_function_signature for each overloaded function with this name.
138501e04c3fSmrg    */
138601e04c3fSmrg   struct exec_list signatures;
138701e04c3fSmrg
138801e04c3fSmrg   /**
138901e04c3fSmrg    * is this function a subroutine type declaration
139001e04c3fSmrg    * e.g. subroutine void type1(float arg1);
139101e04c3fSmrg    */
139201e04c3fSmrg   bool is_subroutine;
139301e04c3fSmrg
139401e04c3fSmrg   /**
139501e04c3fSmrg    * is this function associated to a subroutine type
139601e04c3fSmrg    * e.g. subroutine (type1, type2) function_name { function_body };
139701e04c3fSmrg    * would have num_subroutine_types 2,
139801e04c3fSmrg    * and pointers to the type1 and type2 types.
139901e04c3fSmrg    */
140001e04c3fSmrg   int num_subroutine_types;
140101e04c3fSmrg   const struct glsl_type **subroutine_types;
140201e04c3fSmrg
140301e04c3fSmrg   int subroutine_index;
140401e04c3fSmrg};
140501e04c3fSmrg
140601e04c3fSmrginline const char *ir_function_signature::function_name() const
140701e04c3fSmrg{
140801e04c3fSmrg   return this->_function->name;
140901e04c3fSmrg}
141001e04c3fSmrg/*@}*/
141101e04c3fSmrg
141201e04c3fSmrg
141301e04c3fSmrg/**
141401e04c3fSmrg * IR instruction representing high-level if-statements
141501e04c3fSmrg */
141601e04c3fSmrgclass ir_if : public ir_instruction {
141701e04c3fSmrgpublic:
141801e04c3fSmrg   ir_if(ir_rvalue *condition)
141901e04c3fSmrg      : ir_instruction(ir_type_if), condition(condition)
142001e04c3fSmrg   {
142101e04c3fSmrg   }
142201e04c3fSmrg
142301e04c3fSmrg   virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const;
142401e04c3fSmrg
142501e04c3fSmrg   virtual void accept(ir_visitor *v)
142601e04c3fSmrg   {
142701e04c3fSmrg      v->visit(this);
142801e04c3fSmrg   }
142901e04c3fSmrg
143001e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
143101e04c3fSmrg
143201e04c3fSmrg   ir_rvalue *condition;
143301e04c3fSmrg   /** List of ir_instruction for the body of the then branch */
143401e04c3fSmrg   exec_list  then_instructions;
143501e04c3fSmrg   /** List of ir_instruction for the body of the else branch */
143601e04c3fSmrg   exec_list  else_instructions;
143701e04c3fSmrg};
143801e04c3fSmrg
143901e04c3fSmrg
144001e04c3fSmrg/**
144101e04c3fSmrg * IR instruction representing a high-level loop structure.
144201e04c3fSmrg */
144301e04c3fSmrgclass ir_loop : public ir_instruction {
144401e04c3fSmrgpublic:
144501e04c3fSmrg   ir_loop();
144601e04c3fSmrg
144701e04c3fSmrg   virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const;
144801e04c3fSmrg
144901e04c3fSmrg   virtual void accept(ir_visitor *v)
145001e04c3fSmrg   {
145101e04c3fSmrg      v->visit(this);
145201e04c3fSmrg   }
145301e04c3fSmrg
145401e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
145501e04c3fSmrg
145601e04c3fSmrg   /** List of ir_instruction that make up the body of the loop. */
145701e04c3fSmrg   exec_list body_instructions;
145801e04c3fSmrg};
145901e04c3fSmrg
146001e04c3fSmrg
146101e04c3fSmrgclass ir_assignment : public ir_instruction {
146201e04c3fSmrgpublic:
146301e04c3fSmrg   ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL);
146401e04c3fSmrg
146501e04c3fSmrg   /**
146601e04c3fSmrg    * Construct an assignment with an explicit write mask
146701e04c3fSmrg    *
146801e04c3fSmrg    * \note
146901e04c3fSmrg    * Since a write mask is supplied, the LHS must already be a bare
147001e04c3fSmrg    * \c ir_dereference.  The cannot be any swizzles in the LHS.
147101e04c3fSmrg    */
147201e04c3fSmrg   ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition,
147301e04c3fSmrg		 unsigned write_mask);
147401e04c3fSmrg
147501e04c3fSmrg   virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
147601e04c3fSmrg
147701e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
147801e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
147901e04c3fSmrg
148001e04c3fSmrg   virtual void accept(ir_visitor *v)
148101e04c3fSmrg   {
148201e04c3fSmrg      v->visit(this);
148301e04c3fSmrg   }
148401e04c3fSmrg
148501e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
148601e04c3fSmrg
148701e04c3fSmrg   /**
148801e04c3fSmrg    * Get a whole variable written by an assignment
148901e04c3fSmrg    *
149001e04c3fSmrg    * If the LHS of the assignment writes a whole variable, the variable is
149101e04c3fSmrg    * returned.  Otherwise \c NULL is returned.  Examples of whole-variable
149201e04c3fSmrg    * assignment are:
149301e04c3fSmrg    *
149401e04c3fSmrg    *  - Assigning to a scalar
149501e04c3fSmrg    *  - Assigning to all components of a vector
149601e04c3fSmrg    *  - Whole array (or matrix) assignment
149701e04c3fSmrg    *  - Whole structure assignment
149801e04c3fSmrg    */
149901e04c3fSmrg   ir_variable *whole_variable_written();
150001e04c3fSmrg
150101e04c3fSmrg   /**
150201e04c3fSmrg    * Set the LHS of an assignment
150301e04c3fSmrg    */
150401e04c3fSmrg   void set_lhs(ir_rvalue *lhs);
150501e04c3fSmrg
150601e04c3fSmrg   /**
150701e04c3fSmrg    * Left-hand side of the assignment.
150801e04c3fSmrg    *
150901e04c3fSmrg    * This should be treated as read only.  If you need to set the LHS of an
151001e04c3fSmrg    * assignment, use \c ir_assignment::set_lhs.
151101e04c3fSmrg    */
151201e04c3fSmrg   ir_dereference *lhs;
151301e04c3fSmrg
151401e04c3fSmrg   /**
151501e04c3fSmrg    * Value being assigned
151601e04c3fSmrg    */
151701e04c3fSmrg   ir_rvalue *rhs;
151801e04c3fSmrg
151901e04c3fSmrg   /**
152001e04c3fSmrg    * Optional condition for the assignment.
152101e04c3fSmrg    */
152201e04c3fSmrg   ir_rvalue *condition;
152301e04c3fSmrg
152401e04c3fSmrg
152501e04c3fSmrg   /**
152601e04c3fSmrg    * Component mask written
152701e04c3fSmrg    *
152801e04c3fSmrg    * For non-vector types in the LHS, this field will be zero.  For vector
152901e04c3fSmrg    * types, a bit will be set for each component that is written.  Note that
153001e04c3fSmrg    * for \c vec2 and \c vec3 types only the lower bits will ever be set.
153101e04c3fSmrg    *
153201e04c3fSmrg    * A partially-set write mask means that each enabled channel gets
153301e04c3fSmrg    * the value from a consecutive channel of the rhs.  For example,
153401e04c3fSmrg    * to write just .xyw of gl_FrontColor with color:
153501e04c3fSmrg    *
153601e04c3fSmrg    * (assign (constant bool (1)) (xyw)
153701e04c3fSmrg    *     (var_ref gl_FragColor)
153801e04c3fSmrg    *     (swiz xyw (var_ref color)))
153901e04c3fSmrg    */
154001e04c3fSmrg   unsigned write_mask:4;
154101e04c3fSmrg};
154201e04c3fSmrg
154301e04c3fSmrg#include "ir_expression_operation.h"
154401e04c3fSmrg
154501e04c3fSmrgextern const char *const ir_expression_operation_strings[ir_last_opcode + 1];
154601e04c3fSmrgextern const char *const ir_expression_operation_enum_strings[ir_last_opcode + 1];
154701e04c3fSmrg
154801e04c3fSmrgclass ir_expression : public ir_rvalue {
154901e04c3fSmrgpublic:
155001e04c3fSmrg   ir_expression(int op, const struct glsl_type *type,
155101e04c3fSmrg                 ir_rvalue *op0, ir_rvalue *op1 = NULL,
155201e04c3fSmrg                 ir_rvalue *op2 = NULL, ir_rvalue *op3 = NULL);
155301e04c3fSmrg
155401e04c3fSmrg   /**
155501e04c3fSmrg    * Constructor for unary operation expressions
155601e04c3fSmrg    */
155701e04c3fSmrg   ir_expression(int op, ir_rvalue *);
155801e04c3fSmrg
155901e04c3fSmrg   /**
156001e04c3fSmrg    * Constructor for binary operation expressions
156101e04c3fSmrg    */
156201e04c3fSmrg   ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
156301e04c3fSmrg
156401e04c3fSmrg   /**
156501e04c3fSmrg    * Constructor for ternary operation expressions
156601e04c3fSmrg    */
156701e04c3fSmrg   ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2);
156801e04c3fSmrg
156901e04c3fSmrg   virtual bool equals(const ir_instruction *ir,
157001e04c3fSmrg                       enum ir_node_type ignore = ir_type_unset) const;
157101e04c3fSmrg
157201e04c3fSmrg   virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
157301e04c3fSmrg
157401e04c3fSmrg   /**
157501e04c3fSmrg    * Attempt to constant-fold the expression
157601e04c3fSmrg    *
157701e04c3fSmrg    * The "variable_context" hash table links ir_variable * to ir_constant *
157801e04c3fSmrg    * that represent the variables' values.  \c NULL represents an empty
157901e04c3fSmrg    * context.
158001e04c3fSmrg    *
158101e04c3fSmrg    * If the expression cannot be constant folded, this method will return
158201e04c3fSmrg    * \c NULL.
158301e04c3fSmrg    */
158401e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
158501e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
158601e04c3fSmrg
158701e04c3fSmrg   /**
158801e04c3fSmrg    * This is only here for ir_reader to used for testing purposes please use
158901e04c3fSmrg    * the precomputed num_operands field if you need the number of operands.
159001e04c3fSmrg    */
159101e04c3fSmrg   static unsigned get_num_operands(ir_expression_operation);
159201e04c3fSmrg
159301e04c3fSmrg   /**
159401e04c3fSmrg    * Return whether the expression operates on vectors horizontally.
159501e04c3fSmrg    */
159601e04c3fSmrg   bool is_horizontal() const
159701e04c3fSmrg   {
159801e04c3fSmrg      return operation == ir_binop_all_equal ||
159901e04c3fSmrg             operation == ir_binop_any_nequal ||
160001e04c3fSmrg             operation == ir_binop_dot ||
160101e04c3fSmrg             operation == ir_binop_vector_extract ||
160201e04c3fSmrg             operation == ir_triop_vector_insert ||
160301e04c3fSmrg             operation == ir_binop_ubo_load ||
160401e04c3fSmrg             operation == ir_quadop_vector;
160501e04c3fSmrg   }
160601e04c3fSmrg
160701e04c3fSmrg   /**
160801e04c3fSmrg    * Do a reverse-lookup to translate the given string into an operator.
160901e04c3fSmrg    */
161001e04c3fSmrg   static ir_expression_operation get_operator(const char *);
161101e04c3fSmrg
161201e04c3fSmrg   virtual void accept(ir_visitor *v)
161301e04c3fSmrg   {
161401e04c3fSmrg      v->visit(this);
161501e04c3fSmrg   }
161601e04c3fSmrg
161701e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
161801e04c3fSmrg
161901e04c3fSmrg   virtual ir_variable *variable_referenced() const;
162001e04c3fSmrg
162101e04c3fSmrg   /**
162201e04c3fSmrg    * Determine the number of operands used by an expression
162301e04c3fSmrg    */
162401e04c3fSmrg   void init_num_operands()
162501e04c3fSmrg   {
162601e04c3fSmrg      if (operation == ir_quadop_vector) {
162701e04c3fSmrg         num_operands = this->type->vector_elements;
162801e04c3fSmrg      } else {
162901e04c3fSmrg         num_operands = get_num_operands(operation);
163001e04c3fSmrg      }
163101e04c3fSmrg   }
163201e04c3fSmrg
163301e04c3fSmrg   ir_expression_operation operation;
163401e04c3fSmrg   ir_rvalue *operands[4];
163501e04c3fSmrg   uint8_t num_operands;
163601e04c3fSmrg};
163701e04c3fSmrg
163801e04c3fSmrg
163901e04c3fSmrg/**
164001e04c3fSmrg * HIR instruction representing a high-level function call, containing a list
164101e04c3fSmrg * of parameters and returning a value in the supplied temporary.
164201e04c3fSmrg */
164301e04c3fSmrgclass ir_call : public ir_instruction {
164401e04c3fSmrgpublic:
164501e04c3fSmrg   ir_call(ir_function_signature *callee,
164601e04c3fSmrg	   ir_dereference_variable *return_deref,
164701e04c3fSmrg	   exec_list *actual_parameters)
164801e04c3fSmrg      : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(NULL), array_idx(NULL)
164901e04c3fSmrg   {
165001e04c3fSmrg      assert(callee->return_type != NULL);
165101e04c3fSmrg      actual_parameters->move_nodes_to(& this->actual_parameters);
165201e04c3fSmrg   }
165301e04c3fSmrg
165401e04c3fSmrg   ir_call(ir_function_signature *callee,
165501e04c3fSmrg	   ir_dereference_variable *return_deref,
165601e04c3fSmrg	   exec_list *actual_parameters,
165701e04c3fSmrg	   ir_variable *var, ir_rvalue *array_idx)
165801e04c3fSmrg      : ir_instruction(ir_type_call), return_deref(return_deref), callee(callee), sub_var(var), array_idx(array_idx)
165901e04c3fSmrg   {
166001e04c3fSmrg      assert(callee->return_type != NULL);
166101e04c3fSmrg      actual_parameters->move_nodes_to(& this->actual_parameters);
166201e04c3fSmrg   }
166301e04c3fSmrg
166401e04c3fSmrg   virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
166501e04c3fSmrg
166601e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
166701e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
166801e04c3fSmrg
166901e04c3fSmrg   virtual void accept(ir_visitor *v)
167001e04c3fSmrg   {
167101e04c3fSmrg      v->visit(this);
167201e04c3fSmrg   }
167301e04c3fSmrg
167401e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
167501e04c3fSmrg
167601e04c3fSmrg   /**
167701e04c3fSmrg    * Get the name of the function being called.
167801e04c3fSmrg    */
167901e04c3fSmrg   const char *callee_name() const
168001e04c3fSmrg   {
168101e04c3fSmrg      return callee->function_name();
168201e04c3fSmrg   }
168301e04c3fSmrg
168401e04c3fSmrg   /**
168501e04c3fSmrg    * Generates an inline version of the function before @ir,
168601e04c3fSmrg    * storing the return value in return_deref.
168701e04c3fSmrg    */
168801e04c3fSmrg   void generate_inline(ir_instruction *ir);
168901e04c3fSmrg
169001e04c3fSmrg   /**
169101e04c3fSmrg    * Storage for the function's return value.
169201e04c3fSmrg    * This must be NULL if the return type is void.
169301e04c3fSmrg    */
169401e04c3fSmrg   ir_dereference_variable *return_deref;
169501e04c3fSmrg
169601e04c3fSmrg   /**
169701e04c3fSmrg    * The specific function signature being called.
169801e04c3fSmrg    */
169901e04c3fSmrg   ir_function_signature *callee;
170001e04c3fSmrg
170101e04c3fSmrg   /* List of ir_rvalue of paramaters passed in this call. */
170201e04c3fSmrg   exec_list actual_parameters;
170301e04c3fSmrg
170401e04c3fSmrg   /*
170501e04c3fSmrg    * ARB_shader_subroutine support -
170601e04c3fSmrg    * the subroutine uniform variable and array index
170701e04c3fSmrg    * rvalue to be used in the lowering pass later.
170801e04c3fSmrg    */
170901e04c3fSmrg   ir_variable *sub_var;
171001e04c3fSmrg   ir_rvalue *array_idx;
171101e04c3fSmrg};
171201e04c3fSmrg
171301e04c3fSmrg
171401e04c3fSmrg/**
171501e04c3fSmrg * \name Jump-like IR instructions.
171601e04c3fSmrg *
171701e04c3fSmrg * These include \c break, \c continue, \c return, and \c discard.
171801e04c3fSmrg */
171901e04c3fSmrg/*@{*/
172001e04c3fSmrgclass ir_jump : public ir_instruction {
172101e04c3fSmrgprotected:
172201e04c3fSmrg   ir_jump(enum ir_node_type t)
172301e04c3fSmrg      : ir_instruction(t)
172401e04c3fSmrg   {
172501e04c3fSmrg   }
172601e04c3fSmrg};
172701e04c3fSmrg
172801e04c3fSmrgclass ir_return : public ir_jump {
172901e04c3fSmrgpublic:
173001e04c3fSmrg   ir_return()
173101e04c3fSmrg      : ir_jump(ir_type_return), value(NULL)
173201e04c3fSmrg   {
173301e04c3fSmrg   }
173401e04c3fSmrg
173501e04c3fSmrg   ir_return(ir_rvalue *value)
173601e04c3fSmrg      : ir_jump(ir_type_return), value(value)
173701e04c3fSmrg   {
173801e04c3fSmrg   }
173901e04c3fSmrg
174001e04c3fSmrg   virtual ir_return *clone(void *mem_ctx, struct hash_table *) const;
174101e04c3fSmrg
174201e04c3fSmrg   ir_rvalue *get_value() const
174301e04c3fSmrg   {
174401e04c3fSmrg      return value;
174501e04c3fSmrg   }
174601e04c3fSmrg
174701e04c3fSmrg   virtual void accept(ir_visitor *v)
174801e04c3fSmrg   {
174901e04c3fSmrg      v->visit(this);
175001e04c3fSmrg   }
175101e04c3fSmrg
175201e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
175301e04c3fSmrg
175401e04c3fSmrg   ir_rvalue *value;
175501e04c3fSmrg};
175601e04c3fSmrg
175701e04c3fSmrg
175801e04c3fSmrg/**
175901e04c3fSmrg * Jump instructions used inside loops
176001e04c3fSmrg *
176101e04c3fSmrg * These include \c break and \c continue.  The \c break within a loop is
176201e04c3fSmrg * different from the \c break within a switch-statement.
176301e04c3fSmrg *
176401e04c3fSmrg * \sa ir_switch_jump
176501e04c3fSmrg */
176601e04c3fSmrgclass ir_loop_jump : public ir_jump {
176701e04c3fSmrgpublic:
176801e04c3fSmrg   enum jump_mode {
176901e04c3fSmrg      jump_break,
177001e04c3fSmrg      jump_continue
177101e04c3fSmrg   };
177201e04c3fSmrg
177301e04c3fSmrg   ir_loop_jump(jump_mode mode)
177401e04c3fSmrg      : ir_jump(ir_type_loop_jump)
177501e04c3fSmrg   {
177601e04c3fSmrg      this->mode = mode;
177701e04c3fSmrg   }
177801e04c3fSmrg
177901e04c3fSmrg   virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const;
178001e04c3fSmrg
178101e04c3fSmrg   virtual void accept(ir_visitor *v)
178201e04c3fSmrg   {
178301e04c3fSmrg      v->visit(this);
178401e04c3fSmrg   }
178501e04c3fSmrg
178601e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
178701e04c3fSmrg
178801e04c3fSmrg   bool is_break() const
178901e04c3fSmrg   {
179001e04c3fSmrg      return mode == jump_break;
179101e04c3fSmrg   }
179201e04c3fSmrg
179301e04c3fSmrg   bool is_continue() const
179401e04c3fSmrg   {
179501e04c3fSmrg      return mode == jump_continue;
179601e04c3fSmrg   }
179701e04c3fSmrg
179801e04c3fSmrg   /** Mode selector for the jump instruction. */
179901e04c3fSmrg   enum jump_mode mode;
180001e04c3fSmrg};
180101e04c3fSmrg
180201e04c3fSmrg/**
180301e04c3fSmrg * IR instruction representing discard statements.
180401e04c3fSmrg */
180501e04c3fSmrgclass ir_discard : public ir_jump {
180601e04c3fSmrgpublic:
180701e04c3fSmrg   ir_discard()
180801e04c3fSmrg      : ir_jump(ir_type_discard)
180901e04c3fSmrg   {
181001e04c3fSmrg      this->condition = NULL;
181101e04c3fSmrg   }
181201e04c3fSmrg
181301e04c3fSmrg   ir_discard(ir_rvalue *cond)
181401e04c3fSmrg      : ir_jump(ir_type_discard)
181501e04c3fSmrg   {
181601e04c3fSmrg      this->condition = cond;
181701e04c3fSmrg   }
181801e04c3fSmrg
181901e04c3fSmrg   virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const;
182001e04c3fSmrg
182101e04c3fSmrg   virtual void accept(ir_visitor *v)
182201e04c3fSmrg   {
182301e04c3fSmrg      v->visit(this);
182401e04c3fSmrg   }
182501e04c3fSmrg
182601e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
182701e04c3fSmrg
182801e04c3fSmrg   ir_rvalue *condition;
182901e04c3fSmrg};
183001e04c3fSmrg/*@}*/
183101e04c3fSmrg
183201e04c3fSmrg
18337ec681f3Smrg/**
18347ec681f3Smrg * IR instruction representing demote statements from
18357ec681f3Smrg * GL_EXT_demote_to_helper_invocation.
18367ec681f3Smrg */
18377ec681f3Smrgclass ir_demote : public ir_instruction {
18387ec681f3Smrgpublic:
18397ec681f3Smrg   ir_demote()
18407ec681f3Smrg      : ir_instruction(ir_type_demote)
18417ec681f3Smrg   {
18427ec681f3Smrg   }
18437ec681f3Smrg
18447ec681f3Smrg   virtual ir_demote *clone(void *mem_ctx, struct hash_table *ht) const;
18457ec681f3Smrg
18467ec681f3Smrg   virtual void accept(ir_visitor *v)
18477ec681f3Smrg   {
18487ec681f3Smrg      v->visit(this);
18497ec681f3Smrg   }
18507ec681f3Smrg
18517ec681f3Smrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
18527ec681f3Smrg};
18537ec681f3Smrg
18547ec681f3Smrg
185501e04c3fSmrg/**
185601e04c3fSmrg * Texture sampling opcodes used in ir_texture
185701e04c3fSmrg */
185801e04c3fSmrgenum ir_texture_opcode {
185901e04c3fSmrg   ir_tex,		/**< Regular texture look-up */
186001e04c3fSmrg   ir_txb,		/**< Texture look-up with LOD bias */
186101e04c3fSmrg   ir_txl,		/**< Texture look-up with explicit LOD */
18627ec681f3Smrg   ir_txd,		/**< Texture look-up with partial derivatives */
186301e04c3fSmrg   ir_txf,		/**< Texel fetch with explicit LOD */
186401e04c3fSmrg   ir_txf_ms,           /**< Multisample texture fetch */
186501e04c3fSmrg   ir_txs,		/**< Texture size */
186601e04c3fSmrg   ir_lod,		/**< Texture lod query */
186701e04c3fSmrg   ir_tg4,		/**< Texture gather */
186801e04c3fSmrg   ir_query_levels,     /**< Texture levels query */
186901e04c3fSmrg   ir_texture_samples,  /**< Texture samples query */
187001e04c3fSmrg   ir_samples_identical, /**< Query whether all samples are definitely identical. */
187101e04c3fSmrg};
187201e04c3fSmrg
187301e04c3fSmrg
187401e04c3fSmrg/**
187501e04c3fSmrg * IR instruction to sample a texture
187601e04c3fSmrg *
187701e04c3fSmrg * The specific form of the IR instruction depends on the \c mode value
187801e04c3fSmrg * selected from \c ir_texture_opcodes.  In the printed IR, these will
187901e04c3fSmrg * appear as:
188001e04c3fSmrg *
188101e04c3fSmrg *                                    Texel offset (0 or an expression)
188201e04c3fSmrg *                                    | Projection divisor
188301e04c3fSmrg *                                    | |  Shadow comparator
188401e04c3fSmrg *                                    | |  |
188501e04c3fSmrg *                                    v v  v
188601e04c3fSmrg * (tex <type> <sampler> <coordinate> 0 1 ( ))
188701e04c3fSmrg * (txb <type> <sampler> <coordinate> 0 1 ( ) <bias>)
188801e04c3fSmrg * (txl <type> <sampler> <coordinate> 0 1 ( ) <lod>)
188901e04c3fSmrg * (txd <type> <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
189001e04c3fSmrg * (txf <type> <sampler> <coordinate> 0       <lod>)
189101e04c3fSmrg * (txf_ms
189201e04c3fSmrg *      <type> <sampler> <coordinate>         <sample_index>)
189301e04c3fSmrg * (txs <type> <sampler> <lod>)
189401e04c3fSmrg * (lod <type> <sampler> <coordinate>)
189501e04c3fSmrg * (tg4 <type> <sampler> <coordinate> <offset> <component>)
189601e04c3fSmrg * (query_levels <type> <sampler>)
189701e04c3fSmrg * (samples_identical <sampler> <coordinate>)
189801e04c3fSmrg */
189901e04c3fSmrgclass ir_texture : public ir_rvalue {
190001e04c3fSmrgpublic:
190101e04c3fSmrg   ir_texture(enum ir_texture_opcode op)
190201e04c3fSmrg      : ir_rvalue(ir_type_texture),
190301e04c3fSmrg        op(op), sampler(NULL), coordinate(NULL), projector(NULL),
190401e04c3fSmrg        shadow_comparator(NULL), offset(NULL)
190501e04c3fSmrg   {
190601e04c3fSmrg      memset(&lod_info, 0, sizeof(lod_info));
190701e04c3fSmrg   }
190801e04c3fSmrg
190901e04c3fSmrg   virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
191001e04c3fSmrg
191101e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
191201e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
191301e04c3fSmrg
191401e04c3fSmrg   virtual void accept(ir_visitor *v)
191501e04c3fSmrg   {
191601e04c3fSmrg      v->visit(this);
191701e04c3fSmrg   }
191801e04c3fSmrg
191901e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
192001e04c3fSmrg
192101e04c3fSmrg   virtual bool equals(const ir_instruction *ir,
192201e04c3fSmrg                       enum ir_node_type ignore = ir_type_unset) const;
192301e04c3fSmrg
192401e04c3fSmrg   /**
192501e04c3fSmrg    * Return a string representing the ir_texture_opcode.
192601e04c3fSmrg    */
192701e04c3fSmrg   const char *opcode_string();
192801e04c3fSmrg
192901e04c3fSmrg   /** Set the sampler and type. */
193001e04c3fSmrg   void set_sampler(ir_dereference *sampler, const glsl_type *type);
193101e04c3fSmrg
193201e04c3fSmrg   /**
193301e04c3fSmrg    * Do a reverse-lookup to translate a string into an ir_texture_opcode.
193401e04c3fSmrg    */
193501e04c3fSmrg   static ir_texture_opcode get_opcode(const char *);
193601e04c3fSmrg
193701e04c3fSmrg   enum ir_texture_opcode op;
193801e04c3fSmrg
193901e04c3fSmrg   /** Sampler to use for the texture access. */
194001e04c3fSmrg   ir_dereference *sampler;
194101e04c3fSmrg
194201e04c3fSmrg   /** Texture coordinate to sample */
194301e04c3fSmrg   ir_rvalue *coordinate;
194401e04c3fSmrg
194501e04c3fSmrg   /**
194601e04c3fSmrg    * Value used for projective divide.
194701e04c3fSmrg    *
194801e04c3fSmrg    * If there is no projective divide (the common case), this will be
194901e04c3fSmrg    * \c NULL.  Optimization passes should check for this to point to a constant
195001e04c3fSmrg    * of 1.0 and replace that with \c NULL.
195101e04c3fSmrg    */
195201e04c3fSmrg   ir_rvalue *projector;
195301e04c3fSmrg
195401e04c3fSmrg   /**
195501e04c3fSmrg    * Coordinate used for comparison on shadow look-ups.
195601e04c3fSmrg    *
195701e04c3fSmrg    * If there is no shadow comparison, this will be \c NULL.  For the
195801e04c3fSmrg    * \c ir_txf opcode, this *must* be \c NULL.
195901e04c3fSmrg    */
196001e04c3fSmrg   ir_rvalue *shadow_comparator;
196101e04c3fSmrg
196201e04c3fSmrg   /** Texel offset. */
196301e04c3fSmrg   ir_rvalue *offset;
196401e04c3fSmrg
196501e04c3fSmrg   union {
196601e04c3fSmrg      ir_rvalue *lod;		/**< Floating point LOD */
196701e04c3fSmrg      ir_rvalue *bias;		/**< Floating point LOD bias */
196801e04c3fSmrg      ir_rvalue *sample_index;  /**< MSAA sample index */
196901e04c3fSmrg      ir_rvalue *component;     /**< Gather component selector */
197001e04c3fSmrg      struct {
197101e04c3fSmrg	 ir_rvalue *dPdx;	/**< Partial derivative of coordinate wrt X */
197201e04c3fSmrg	 ir_rvalue *dPdy;	/**< Partial derivative of coordinate wrt Y */
197301e04c3fSmrg      } grad;
197401e04c3fSmrg   } lod_info;
197501e04c3fSmrg};
197601e04c3fSmrg
197701e04c3fSmrg
197801e04c3fSmrgstruct ir_swizzle_mask {
197901e04c3fSmrg   unsigned x:2;
198001e04c3fSmrg   unsigned y:2;
198101e04c3fSmrg   unsigned z:2;
198201e04c3fSmrg   unsigned w:2;
198301e04c3fSmrg
198401e04c3fSmrg   /**
198501e04c3fSmrg    * Number of components in the swizzle.
198601e04c3fSmrg    */
198701e04c3fSmrg   unsigned num_components:3;
198801e04c3fSmrg
198901e04c3fSmrg   /**
199001e04c3fSmrg    * Does the swizzle contain duplicate components?
199101e04c3fSmrg    *
199201e04c3fSmrg    * L-value swizzles cannot contain duplicate components.
199301e04c3fSmrg    */
199401e04c3fSmrg   unsigned has_duplicates:1;
199501e04c3fSmrg};
199601e04c3fSmrg
199701e04c3fSmrg
199801e04c3fSmrgclass ir_swizzle : public ir_rvalue {
199901e04c3fSmrgpublic:
200001e04c3fSmrg   ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
200101e04c3fSmrg              unsigned count);
200201e04c3fSmrg
200301e04c3fSmrg   ir_swizzle(ir_rvalue *val, const unsigned *components, unsigned count);
200401e04c3fSmrg
200501e04c3fSmrg   ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
200601e04c3fSmrg
200701e04c3fSmrg   virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
200801e04c3fSmrg
200901e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
201001e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
201101e04c3fSmrg
201201e04c3fSmrg   /**
201301e04c3fSmrg    * Construct an ir_swizzle from the textual representation.  Can fail.
201401e04c3fSmrg    */
201501e04c3fSmrg   static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length);
201601e04c3fSmrg
201701e04c3fSmrg   virtual void accept(ir_visitor *v)
201801e04c3fSmrg   {
201901e04c3fSmrg      v->visit(this);
202001e04c3fSmrg   }
202101e04c3fSmrg
202201e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
202301e04c3fSmrg
202401e04c3fSmrg   virtual bool equals(const ir_instruction *ir,
202501e04c3fSmrg                       enum ir_node_type ignore = ir_type_unset) const;
202601e04c3fSmrg
202701e04c3fSmrg   bool is_lvalue(const struct _mesa_glsl_parse_state *state) const
202801e04c3fSmrg   {
202901e04c3fSmrg      return val->is_lvalue(state) && !mask.has_duplicates;
203001e04c3fSmrg   }
203101e04c3fSmrg
203201e04c3fSmrg   /**
203301e04c3fSmrg    * Get the variable that is ultimately referenced by an r-value
203401e04c3fSmrg    */
203501e04c3fSmrg   virtual ir_variable *variable_referenced() const;
203601e04c3fSmrg
203701e04c3fSmrg   ir_rvalue *val;
203801e04c3fSmrg   ir_swizzle_mask mask;
203901e04c3fSmrg
204001e04c3fSmrgprivate:
204101e04c3fSmrg   /**
204201e04c3fSmrg    * Initialize the mask component of a swizzle
204301e04c3fSmrg    *
204401e04c3fSmrg    * This is used by the \c ir_swizzle constructors.
204501e04c3fSmrg    */
204601e04c3fSmrg   void init_mask(const unsigned *components, unsigned count);
204701e04c3fSmrg};
204801e04c3fSmrg
204901e04c3fSmrg
205001e04c3fSmrgclass ir_dereference : public ir_rvalue {
205101e04c3fSmrgpublic:
205201e04c3fSmrg   virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0;
205301e04c3fSmrg
205401e04c3fSmrg   bool is_lvalue(const struct _mesa_glsl_parse_state *state) const;
205501e04c3fSmrg
205601e04c3fSmrg   /**
205701e04c3fSmrg    * Get the variable that is ultimately referenced by an r-value
205801e04c3fSmrg    */
205901e04c3fSmrg   virtual ir_variable *variable_referenced() const = 0;
206001e04c3fSmrg
20617ec681f3Smrg   /**
20627ec681f3Smrg    * Get the precision. This can either come from the eventual variable that
20637ec681f3Smrg    * is dereferenced, or from a record member.
20647ec681f3Smrg    */
20657ec681f3Smrg   virtual int precision() const = 0;
20667ec681f3Smrg
206701e04c3fSmrgprotected:
206801e04c3fSmrg   ir_dereference(enum ir_node_type t)
206901e04c3fSmrg      : ir_rvalue(t)
207001e04c3fSmrg   {
207101e04c3fSmrg   }
207201e04c3fSmrg};
207301e04c3fSmrg
207401e04c3fSmrg
207501e04c3fSmrgclass ir_dereference_variable : public ir_dereference {
207601e04c3fSmrgpublic:
207701e04c3fSmrg   ir_dereference_variable(ir_variable *var);
207801e04c3fSmrg
207901e04c3fSmrg   virtual ir_dereference_variable *clone(void *mem_ctx,
208001e04c3fSmrg					  struct hash_table *) const;
208101e04c3fSmrg
208201e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
208301e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
208401e04c3fSmrg
208501e04c3fSmrg   virtual bool equals(const ir_instruction *ir,
208601e04c3fSmrg                       enum ir_node_type ignore = ir_type_unset) const;
208701e04c3fSmrg
208801e04c3fSmrg   /**
208901e04c3fSmrg    * Get the variable that is ultimately referenced by an r-value
209001e04c3fSmrg    */
209101e04c3fSmrg   virtual ir_variable *variable_referenced() const
209201e04c3fSmrg   {
209301e04c3fSmrg      return this->var;
209401e04c3fSmrg   }
209501e04c3fSmrg
20967ec681f3Smrg   virtual int precision() const
20977ec681f3Smrg   {
20987ec681f3Smrg      return this->var->data.precision;
20997ec681f3Smrg   }
21007ec681f3Smrg
210101e04c3fSmrg   virtual ir_variable *whole_variable_referenced()
210201e04c3fSmrg   {
210301e04c3fSmrg      /* ir_dereference_variable objects always dereference the entire
210401e04c3fSmrg       * variable.  However, if this dereference is dereferenced by anything
21057ec681f3Smrg       * else, the complete dereference chain is not a whole-variable
210601e04c3fSmrg       * dereference.  This method should only be called on the top most
210701e04c3fSmrg       * ir_rvalue in a dereference chain.
210801e04c3fSmrg       */
210901e04c3fSmrg      return this->var;
211001e04c3fSmrg   }
211101e04c3fSmrg
211201e04c3fSmrg   virtual void accept(ir_visitor *v)
211301e04c3fSmrg   {
211401e04c3fSmrg      v->visit(this);
211501e04c3fSmrg   }
211601e04c3fSmrg
211701e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
211801e04c3fSmrg
211901e04c3fSmrg   /**
212001e04c3fSmrg    * Object being dereferenced.
212101e04c3fSmrg    */
212201e04c3fSmrg   ir_variable *var;
212301e04c3fSmrg};
212401e04c3fSmrg
212501e04c3fSmrg
212601e04c3fSmrgclass ir_dereference_array : public ir_dereference {
212701e04c3fSmrgpublic:
212801e04c3fSmrg   ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index);
212901e04c3fSmrg
213001e04c3fSmrg   ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
213101e04c3fSmrg
213201e04c3fSmrg   virtual ir_dereference_array *clone(void *mem_ctx,
213301e04c3fSmrg				       struct hash_table *) const;
213401e04c3fSmrg
213501e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
213601e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
213701e04c3fSmrg
213801e04c3fSmrg   virtual bool equals(const ir_instruction *ir,
213901e04c3fSmrg                       enum ir_node_type ignore = ir_type_unset) const;
214001e04c3fSmrg
214101e04c3fSmrg   /**
214201e04c3fSmrg    * Get the variable that is ultimately referenced by an r-value
214301e04c3fSmrg    */
214401e04c3fSmrg   virtual ir_variable *variable_referenced() const
214501e04c3fSmrg   {
214601e04c3fSmrg      return this->array->variable_referenced();
214701e04c3fSmrg   }
214801e04c3fSmrg
21497ec681f3Smrg   virtual int precision() const
21507ec681f3Smrg   {
21517ec681f3Smrg      ir_dereference *deref = this->array->as_dereference();
21527ec681f3Smrg
21537ec681f3Smrg      if (deref == NULL)
21547ec681f3Smrg         return GLSL_PRECISION_NONE;
21557ec681f3Smrg      else
21567ec681f3Smrg         return deref->precision();
21577ec681f3Smrg   }
21587ec681f3Smrg
215901e04c3fSmrg   virtual void accept(ir_visitor *v)
216001e04c3fSmrg   {
216101e04c3fSmrg      v->visit(this);
216201e04c3fSmrg   }
216301e04c3fSmrg
216401e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
216501e04c3fSmrg
216601e04c3fSmrg   ir_rvalue *array;
216701e04c3fSmrg   ir_rvalue *array_index;
216801e04c3fSmrg
216901e04c3fSmrgprivate:
217001e04c3fSmrg   void set_array(ir_rvalue *value);
217101e04c3fSmrg};
217201e04c3fSmrg
217301e04c3fSmrg
217401e04c3fSmrgclass ir_dereference_record : public ir_dereference {
217501e04c3fSmrgpublic:
217601e04c3fSmrg   ir_dereference_record(ir_rvalue *value, const char *field);
217701e04c3fSmrg
217801e04c3fSmrg   ir_dereference_record(ir_variable *var, const char *field);
217901e04c3fSmrg
218001e04c3fSmrg   virtual ir_dereference_record *clone(void *mem_ctx,
218101e04c3fSmrg					struct hash_table *) const;
218201e04c3fSmrg
218301e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
218401e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
218501e04c3fSmrg
218601e04c3fSmrg   /**
218701e04c3fSmrg    * Get the variable that is ultimately referenced by an r-value
218801e04c3fSmrg    */
218901e04c3fSmrg   virtual ir_variable *variable_referenced() const
219001e04c3fSmrg   {
219101e04c3fSmrg      return this->record->variable_referenced();
219201e04c3fSmrg   }
219301e04c3fSmrg
21947ec681f3Smrg   virtual int precision() const
21957ec681f3Smrg   {
21967ec681f3Smrg      glsl_struct_field *field = record->type->fields.structure + field_idx;
21977ec681f3Smrg
21987ec681f3Smrg      return field->precision;
21997ec681f3Smrg   }
22007ec681f3Smrg
220101e04c3fSmrg   virtual void accept(ir_visitor *v)
220201e04c3fSmrg   {
220301e04c3fSmrg      v->visit(this);
220401e04c3fSmrg   }
220501e04c3fSmrg
220601e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
220701e04c3fSmrg
220801e04c3fSmrg   ir_rvalue *record;
220901e04c3fSmrg   int field_idx;
221001e04c3fSmrg};
221101e04c3fSmrg
221201e04c3fSmrg
221301e04c3fSmrg/**
221401e04c3fSmrg * Data stored in an ir_constant
221501e04c3fSmrg */
221601e04c3fSmrgunion ir_constant_data {
221701e04c3fSmrg      unsigned u[16];
221801e04c3fSmrg      int i[16];
221901e04c3fSmrg      float f[16];
222001e04c3fSmrg      bool b[16];
222101e04c3fSmrg      double d[16];
22227ec681f3Smrg      uint16_t f16[16];
22237ec681f3Smrg      uint16_t u16[16];
22247ec681f3Smrg      int16_t i16[16];
222501e04c3fSmrg      uint64_t u64[16];
222601e04c3fSmrg      int64_t i64[16];
222701e04c3fSmrg};
222801e04c3fSmrg
222901e04c3fSmrg
223001e04c3fSmrgclass ir_constant : public ir_rvalue {
223101e04c3fSmrgpublic:
223201e04c3fSmrg   ir_constant(const struct glsl_type *type, const ir_constant_data *data);
223301e04c3fSmrg   ir_constant(bool b, unsigned vector_elements=1);
22347ec681f3Smrg   ir_constant(int16_t i16, unsigned vector_elements=1);
22357ec681f3Smrg   ir_constant(uint16_t u16, unsigned vector_elements=1);
223601e04c3fSmrg   ir_constant(unsigned int u, unsigned vector_elements=1);
223701e04c3fSmrg   ir_constant(int i, unsigned vector_elements=1);
22387ec681f3Smrg   ir_constant(float16_t f16, unsigned vector_elements=1);
223901e04c3fSmrg   ir_constant(float f, unsigned vector_elements=1);
224001e04c3fSmrg   ir_constant(double d, unsigned vector_elements=1);
224101e04c3fSmrg   ir_constant(uint64_t u64, unsigned vector_elements=1);
224201e04c3fSmrg   ir_constant(int64_t i64, unsigned vector_elements=1);
224301e04c3fSmrg
224401e04c3fSmrg   /**
224501e04c3fSmrg    * Construct an ir_constant from a list of ir_constant values
224601e04c3fSmrg    */
224701e04c3fSmrg   ir_constant(const struct glsl_type *type, exec_list *values);
224801e04c3fSmrg
224901e04c3fSmrg   /**
225001e04c3fSmrg    * Construct an ir_constant from a scalar component of another ir_constant
225101e04c3fSmrg    *
225201e04c3fSmrg    * The new \c ir_constant inherits the type of the component from the
225301e04c3fSmrg    * source constant.
225401e04c3fSmrg    *
225501e04c3fSmrg    * \note
225601e04c3fSmrg    * In the case of a matrix constant, the new constant is a scalar, \b not
225701e04c3fSmrg    * a vector.
225801e04c3fSmrg    */
225901e04c3fSmrg   ir_constant(const ir_constant *c, unsigned i);
226001e04c3fSmrg
226101e04c3fSmrg   /**
226201e04c3fSmrg    * Return a new ir_constant of the specified type containing all zeros.
226301e04c3fSmrg    */
226401e04c3fSmrg   static ir_constant *zero(void *mem_ctx, const glsl_type *type);
226501e04c3fSmrg
226601e04c3fSmrg   virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
226701e04c3fSmrg
226801e04c3fSmrg   virtual ir_constant *constant_expression_value(void *mem_ctx,
226901e04c3fSmrg                                                  struct hash_table *variable_context = NULL);
227001e04c3fSmrg
227101e04c3fSmrg   virtual void accept(ir_visitor *v)
227201e04c3fSmrg   {
227301e04c3fSmrg      v->visit(this);
227401e04c3fSmrg   }
227501e04c3fSmrg
227601e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
227701e04c3fSmrg
227801e04c3fSmrg   virtual bool equals(const ir_instruction *ir,
227901e04c3fSmrg                       enum ir_node_type ignore = ir_type_unset) const;
228001e04c3fSmrg
228101e04c3fSmrg   /**
228201e04c3fSmrg    * Get a particular component of a constant as a specific type
228301e04c3fSmrg    *
228401e04c3fSmrg    * This is useful, for example, to get a value from an integer constant
228501e04c3fSmrg    * as a float or bool.  This appears frequently when constructors are
228601e04c3fSmrg    * called with all constant parameters.
228701e04c3fSmrg    */
228801e04c3fSmrg   /*@{*/
228901e04c3fSmrg   bool get_bool_component(unsigned i) const;
229001e04c3fSmrg   float get_float_component(unsigned i) const;
22917ec681f3Smrg   uint16_t get_float16_component(unsigned i) const;
229201e04c3fSmrg   double get_double_component(unsigned i) const;
22937ec681f3Smrg   int16_t get_int16_component(unsigned i) const;
22947ec681f3Smrg   uint16_t get_uint16_component(unsigned i) const;
229501e04c3fSmrg   int get_int_component(unsigned i) const;
229601e04c3fSmrg   unsigned get_uint_component(unsigned i) const;
229701e04c3fSmrg   int64_t get_int64_component(unsigned i) const;
229801e04c3fSmrg   uint64_t get_uint64_component(unsigned i) const;
229901e04c3fSmrg   /*@}*/
230001e04c3fSmrg
230101e04c3fSmrg   ir_constant *get_array_element(unsigned i) const;
230201e04c3fSmrg
230301e04c3fSmrg   ir_constant *get_record_field(int idx);
230401e04c3fSmrg
230501e04c3fSmrg   /**
230601e04c3fSmrg    * Copy the values on another constant at a given offset.
230701e04c3fSmrg    *
230801e04c3fSmrg    * The offset is ignored for array or struct copies, it's only for
230901e04c3fSmrg    * scalars or vectors into vectors or matrices.
231001e04c3fSmrg    *
231101e04c3fSmrg    * With identical types on both sides and zero offset it's clone()
231201e04c3fSmrg    * without creating a new object.
231301e04c3fSmrg    */
231401e04c3fSmrg
231501e04c3fSmrg   void copy_offset(ir_constant *src, int offset);
231601e04c3fSmrg
231701e04c3fSmrg   /**
231801e04c3fSmrg    * Copy the values on another constant at a given offset and
231901e04c3fSmrg    * following an assign-like mask.
232001e04c3fSmrg    *
232101e04c3fSmrg    * The mask is ignored for scalars.
232201e04c3fSmrg    *
232301e04c3fSmrg    * Note that this function only handles what assign can handle,
232401e04c3fSmrg    * i.e. at most a vector as source and a column of a matrix as
232501e04c3fSmrg    * destination.
232601e04c3fSmrg    */
232701e04c3fSmrg
232801e04c3fSmrg   void copy_masked_offset(ir_constant *src, int offset, unsigned int mask);
232901e04c3fSmrg
233001e04c3fSmrg   /**
233101e04c3fSmrg    * Determine whether a constant has the same value as another constant
233201e04c3fSmrg    *
233301e04c3fSmrg    * \sa ir_constant::is_zero, ir_constant::is_one,
233401e04c3fSmrg    * ir_constant::is_negative_one
233501e04c3fSmrg    */
233601e04c3fSmrg   bool has_value(const ir_constant *) const;
233701e04c3fSmrg
233801e04c3fSmrg   /**
233901e04c3fSmrg    * Return true if this ir_constant represents the given value.
234001e04c3fSmrg    *
234101e04c3fSmrg    * For vectors, this checks that each component is the given value.
234201e04c3fSmrg    */
234301e04c3fSmrg   virtual bool is_value(float f, int i) const;
234401e04c3fSmrg   virtual bool is_zero() const;
234501e04c3fSmrg   virtual bool is_one() const;
234601e04c3fSmrg   virtual bool is_negative_one() const;
234701e04c3fSmrg
234801e04c3fSmrg   /**
234901e04c3fSmrg    * Return true for constants that could be stored as 16-bit unsigned values.
235001e04c3fSmrg    *
235101e04c3fSmrg    * Note that this will return true even for signed integer ir_constants, as
235201e04c3fSmrg    * long as the value is non-negative and fits in 16-bits.
235301e04c3fSmrg    */
235401e04c3fSmrg   virtual bool is_uint16_constant() const;
235501e04c3fSmrg
235601e04c3fSmrg   /**
235701e04c3fSmrg    * Value of the constant.
235801e04c3fSmrg    *
235901e04c3fSmrg    * The field used to back the values supplied by the constant is determined
236001e04c3fSmrg    * by the type associated with the \c ir_instruction.  Constants may be
236101e04c3fSmrg    * scalars, vectors, or matrices.
236201e04c3fSmrg    */
236301e04c3fSmrg   union ir_constant_data value;
236401e04c3fSmrg
236501e04c3fSmrg   /* Array elements and structure fields */
236601e04c3fSmrg   ir_constant **const_elements;
236701e04c3fSmrg
236801e04c3fSmrgprivate:
236901e04c3fSmrg   /**
237001e04c3fSmrg    * Parameterless constructor only used by the clone method
237101e04c3fSmrg    */
237201e04c3fSmrg   ir_constant(void);
237301e04c3fSmrg};
237401e04c3fSmrg
237501e04c3fSmrg/**
237601e04c3fSmrg * IR instruction to emit a vertex in a geometry shader.
237701e04c3fSmrg */
237801e04c3fSmrgclass ir_emit_vertex : public ir_instruction {
237901e04c3fSmrgpublic:
238001e04c3fSmrg   ir_emit_vertex(ir_rvalue *stream)
238101e04c3fSmrg      : ir_instruction(ir_type_emit_vertex),
238201e04c3fSmrg        stream(stream)
238301e04c3fSmrg   {
238401e04c3fSmrg      assert(stream);
238501e04c3fSmrg   }
238601e04c3fSmrg
238701e04c3fSmrg   virtual void accept(ir_visitor *v)
238801e04c3fSmrg   {
238901e04c3fSmrg      v->visit(this);
239001e04c3fSmrg   }
239101e04c3fSmrg
239201e04c3fSmrg   virtual ir_emit_vertex *clone(void *mem_ctx, struct hash_table *ht) const
239301e04c3fSmrg   {
239401e04c3fSmrg      return new(mem_ctx) ir_emit_vertex(this->stream->clone(mem_ctx, ht));
239501e04c3fSmrg   }
239601e04c3fSmrg
239701e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
239801e04c3fSmrg
239901e04c3fSmrg   int stream_id() const
240001e04c3fSmrg   {
240101e04c3fSmrg      return stream->as_constant()->value.i[0];
240201e04c3fSmrg   }
240301e04c3fSmrg
240401e04c3fSmrg   ir_rvalue *stream;
240501e04c3fSmrg};
240601e04c3fSmrg
240701e04c3fSmrg/**
240801e04c3fSmrg * IR instruction to complete the current primitive and start a new one in a
240901e04c3fSmrg * geometry shader.
241001e04c3fSmrg */
241101e04c3fSmrgclass ir_end_primitive : public ir_instruction {
241201e04c3fSmrgpublic:
241301e04c3fSmrg   ir_end_primitive(ir_rvalue *stream)
241401e04c3fSmrg      : ir_instruction(ir_type_end_primitive),
241501e04c3fSmrg        stream(stream)
241601e04c3fSmrg   {
241701e04c3fSmrg      assert(stream);
241801e04c3fSmrg   }
241901e04c3fSmrg
242001e04c3fSmrg   virtual void accept(ir_visitor *v)
242101e04c3fSmrg   {
242201e04c3fSmrg      v->visit(this);
242301e04c3fSmrg   }
242401e04c3fSmrg
242501e04c3fSmrg   virtual ir_end_primitive *clone(void *mem_ctx, struct hash_table *ht) const
242601e04c3fSmrg   {
242701e04c3fSmrg      return new(mem_ctx) ir_end_primitive(this->stream->clone(mem_ctx, ht));
242801e04c3fSmrg   }
242901e04c3fSmrg
243001e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
243101e04c3fSmrg
243201e04c3fSmrg   int stream_id() const
243301e04c3fSmrg   {
243401e04c3fSmrg      return stream->as_constant()->value.i[0];
243501e04c3fSmrg   }
243601e04c3fSmrg
243701e04c3fSmrg   ir_rvalue *stream;
243801e04c3fSmrg};
243901e04c3fSmrg
244001e04c3fSmrg/**
244101e04c3fSmrg * IR instruction for tessellation control and compute shader barrier.
244201e04c3fSmrg */
244301e04c3fSmrgclass ir_barrier : public ir_instruction {
244401e04c3fSmrgpublic:
244501e04c3fSmrg   ir_barrier()
244601e04c3fSmrg      : ir_instruction(ir_type_barrier)
244701e04c3fSmrg   {
244801e04c3fSmrg   }
244901e04c3fSmrg
245001e04c3fSmrg   virtual void accept(ir_visitor *v)
245101e04c3fSmrg   {
245201e04c3fSmrg      v->visit(this);
245301e04c3fSmrg   }
245401e04c3fSmrg
245501e04c3fSmrg   virtual ir_barrier *clone(void *mem_ctx, struct hash_table *) const
245601e04c3fSmrg   {
245701e04c3fSmrg      return new(mem_ctx) ir_barrier();
245801e04c3fSmrg   }
245901e04c3fSmrg
246001e04c3fSmrg   virtual ir_visitor_status accept(ir_hierarchical_visitor *);
246101e04c3fSmrg};
246201e04c3fSmrg
246301e04c3fSmrg/*@}*/
246401e04c3fSmrg
246501e04c3fSmrg/**
246601e04c3fSmrg * Apply a visitor to each IR node in a list
246701e04c3fSmrg */
246801e04c3fSmrgvoid
246901e04c3fSmrgvisit_exec_list(exec_list *list, ir_visitor *visitor);
247001e04c3fSmrg
247101e04c3fSmrg/**
247201e04c3fSmrg * Validate invariants on each IR node in a list
247301e04c3fSmrg */
247401e04c3fSmrgvoid validate_ir_tree(exec_list *instructions);
247501e04c3fSmrg
247601e04c3fSmrgstruct _mesa_glsl_parse_state;
247701e04c3fSmrgstruct gl_shader_program;
247801e04c3fSmrg
247901e04c3fSmrg/**
248001e04c3fSmrg * Detect whether an unlinked shader contains static recursion
248101e04c3fSmrg *
248201e04c3fSmrg * If the list of instructions is determined to contain static recursion,
248301e04c3fSmrg * \c _mesa_glsl_error will be called to emit error messages for each function
248401e04c3fSmrg * that is in the recursion cycle.
248501e04c3fSmrg */
248601e04c3fSmrgvoid
248701e04c3fSmrgdetect_recursion_unlinked(struct _mesa_glsl_parse_state *state,
248801e04c3fSmrg			  exec_list *instructions);
248901e04c3fSmrg
249001e04c3fSmrg/**
249101e04c3fSmrg * Detect whether a linked shader contains static recursion
249201e04c3fSmrg *
249301e04c3fSmrg * If the list of instructions is determined to contain static recursion,
249401e04c3fSmrg * \c link_error_printf will be called to emit error messages for each function
249501e04c3fSmrg * that is in the recursion cycle.  In addition,
249601e04c3fSmrg * \c gl_shader_program::LinkStatus will be set to false.
249701e04c3fSmrg */
249801e04c3fSmrgvoid
249901e04c3fSmrgdetect_recursion_linked(struct gl_shader_program *prog,
250001e04c3fSmrg			exec_list *instructions);
250101e04c3fSmrg
250201e04c3fSmrg/**
250301e04c3fSmrg * Make a clone of each IR instruction in a list
250401e04c3fSmrg *
250501e04c3fSmrg * \param in   List of IR instructions that are to be cloned
250601e04c3fSmrg * \param out  List to hold the cloned instructions
250701e04c3fSmrg */
250801e04c3fSmrgvoid
250901e04c3fSmrgclone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in);
251001e04c3fSmrg
251101e04c3fSmrgextern void
251201e04c3fSmrg_mesa_glsl_initialize_variables(exec_list *instructions,
251301e04c3fSmrg				struct _mesa_glsl_parse_state *state);
251401e04c3fSmrg
251501e04c3fSmrgextern void
251601e04c3fSmrgreparent_ir(exec_list *list, void *mem_ctx);
251701e04c3fSmrg
251801e04c3fSmrgextern void
251901e04c3fSmrgdo_set_program_inouts(exec_list *instructions, struct gl_program *prog,
252001e04c3fSmrg                      gl_shader_stage shader_stage);
252101e04c3fSmrg
252201e04c3fSmrgextern char *
252301e04c3fSmrgprototype_string(const glsl_type *return_type, const char *name,
252401e04c3fSmrg		 exec_list *parameters);
252501e04c3fSmrg
252601e04c3fSmrgconst char *
252701e04c3fSmrgmode_string(const ir_variable *var);
252801e04c3fSmrg
252901e04c3fSmrg/**
253001e04c3fSmrg * Built-in / reserved GL variables names start with "gl_"
253101e04c3fSmrg */
253201e04c3fSmrgstatic inline bool
253301e04c3fSmrgis_gl_identifier(const char *s)
253401e04c3fSmrg{
253501e04c3fSmrg   return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';
253601e04c3fSmrg}
253701e04c3fSmrg
253801e04c3fSmrgextern "C" {
253901e04c3fSmrg#endif /* __cplusplus */
254001e04c3fSmrg
254101e04c3fSmrgextern void _mesa_print_ir(FILE *f, struct exec_list *instructions,
254201e04c3fSmrg                           struct _mesa_glsl_parse_state *state);
254301e04c3fSmrg
254401e04c3fSmrgextern void
254501e04c3fSmrgfprint_ir(FILE *f, const void *instruction);
254601e04c3fSmrg
254701e04c3fSmrgextern const struct gl_builtin_uniform_desc *
254801e04c3fSmrg_mesa_glsl_get_builtin_uniform_desc(const char *name);
254901e04c3fSmrg
255001e04c3fSmrg#ifdef __cplusplus
255101e04c3fSmrg} /* extern "C" */
255201e04c3fSmrg#endif
255301e04c3fSmrg
255401e04c3fSmrgunsigned
255501e04c3fSmrgvertices_per_prim(GLenum prim);
255601e04c3fSmrg
255701e04c3fSmrg#endif /* IR_H */
2558