"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/compiler/glsl/ir_constant_expression.cpp" (16 Sep 2020, 31637 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ir_constant_expression.cpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 20.1.5_vs_20.2.0-rc1.

    1 /*
    2  * Copyright © 2010 Intel Corporation
    3  *
    4  * Permission is hereby granted, free of charge, to any person obtaining a
    5  * copy of this software and associated documentation files (the "Software"),
    6  * to deal in the Software without restriction, including without limitation
    7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    8  * and/or sell copies of the Software, and to permit persons to whom the
    9  * Software is furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice (including the next
   12  * paragraph) shall be included in all copies or substantial portions of the
   13  * Software.
   14  *
   15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   21  * DEALINGS IN THE SOFTWARE.
   22  */
   23 
   24 /**
   25  * \file ir_constant_expression.cpp
   26  * Evaluate and process constant valued expressions
   27  *
   28  * In GLSL, constant valued expressions are used in several places.  These
   29  * must be processed and evaluated very early in the compilation process.
   30  *
   31  *    * Sizes of arrays
   32  *    * Initializers for uniforms
   33  *    * Initializers for \c const variables
   34  */
   35 
   36 #include <math.h>
   37 #include "util/rounding.h" /* for _mesa_roundeven */
   38 #include "util/half_float.h"
   39 #include "ir.h"
   40 #include "compiler/glsl_types.h"
   41 #include "util/hash_table.h"
   42 #include "util/u_math.h"
   43 
   44 static float
   45 dot_f(ir_constant *op0, ir_constant *op1)
   46 {
   47    assert(op0->type->is_float() && op1->type->is_float());
   48 
   49    float result = 0;
   50    for (unsigned c = 0; c < op0->type->components(); c++)
   51       result += op0->value.f[c] * op1->value.f[c];
   52 
   53    return result;
   54 }
   55 
   56 static double
   57 dot_d(ir_constant *op0, ir_constant *op1)
   58 {
   59    assert(op0->type->is_double() && op1->type->is_double());
   60 
   61    double result = 0;
   62    for (unsigned c = 0; c < op0->type->components(); c++)
   63       result += op0->value.d[c] * op1->value.d[c];
   64 
   65    return result;
   66 }
   67 
   68 /* This method is the only one supported by gcc.  Unions in particular
   69  * are iffy, and read-through-converted-pointer is killed by strict
   70  * aliasing.  OTOH, the compiler sees through the memcpy, so the
   71  * resulting asm is reasonable.
   72  */
   73 static float
   74 bitcast_u2f(unsigned int u)
   75 {
   76    static_assert(sizeof(float) == sizeof(unsigned int),
   77                  "float and unsigned int size mismatch");
   78    float f;
   79    memcpy(&f, &u, sizeof(f));
   80    return f;
   81 }
   82 
   83 static unsigned int
   84 bitcast_f2u(float f)
   85 {
   86    static_assert(sizeof(float) == sizeof(unsigned int),
   87                  "float and unsigned int size mismatch");
   88    unsigned int u;
   89    memcpy(&u, &f, sizeof(f));
   90    return u;
   91 }
   92 
   93 static double
   94 bitcast_u642d(uint64_t u)
   95 {
   96    static_assert(sizeof(double) == sizeof(uint64_t),
   97                  "double and uint64_t size mismatch");
   98    double d;
   99    memcpy(&d, &u, sizeof(d));
  100    return d;
  101 }
  102 
  103 static double
  104 bitcast_i642d(int64_t i)
  105 {
  106    static_assert(sizeof(double) == sizeof(int64_t),
  107                  "double and int64_t size mismatch");
  108    double d;
  109    memcpy(&d, &i, sizeof(d));
  110    return d;
  111 }
  112 
  113 static uint64_t
  114 bitcast_d2u64(double d)
  115 {
  116    static_assert(sizeof(double) == sizeof(uint64_t),
  117                  "double and uint64_t size mismatch");
  118    uint64_t u;
  119    memcpy(&u, &d, sizeof(d));
  120    return u;
  121 }
  122 
  123 static int64_t
  124 bitcast_d2i64(double d)
  125 {
  126    static_assert(sizeof(double) == sizeof(int64_t),
  127                  "double and int64_t size mismatch");
  128    int64_t i;
  129    memcpy(&i, &d, sizeof(d));
  130    return i;
  131 }
  132 
  133 /**
  134  * Evaluate one component of a floating-point 4x8 unpacking function.
  135  */
  136 typedef uint8_t
  137 (*pack_1x8_func_t)(float);
  138 
  139 /**
  140  * Evaluate one component of a floating-point 2x16 unpacking function.
  141  */
  142 typedef uint16_t
  143 (*pack_1x16_func_t)(float);
  144 
  145 /**
  146  * Evaluate one component of a floating-point 4x8 unpacking function.
  147  */
  148 typedef float
  149 (*unpack_1x8_func_t)(uint8_t);
  150 
  151 /**
  152  * Evaluate one component of a floating-point 2x16 unpacking function.
  153  */
  154 typedef float
  155 (*unpack_1x16_func_t)(uint16_t);
  156 
  157 /**
  158  * Evaluate a 2x16 floating-point packing function.
  159  */
  160 static uint32_t
  161 pack_2x16(pack_1x16_func_t pack_1x16,
  162           float x, float y)
  163 {
  164    /* From section 8.4 of the GLSL ES 3.00 spec:
  165     *
  166     *    packSnorm2x16
  167     *    -------------
  168     *    The first component of the vector will be written to the least
  169     *    significant bits of the output; the last component will be written to
  170     *    the most significant bits.
  171     *
  172     * The specifications for the other packing functions contain similar
  173     * language.
  174     */
  175    uint32_t u = 0;
  176    u |= ((uint32_t) pack_1x16(x) << 0);
  177    u |= ((uint32_t) pack_1x16(y) << 16);
  178    return u;
  179 }
  180 
  181 /**
  182  * Evaluate a 4x8 floating-point packing function.
  183  */
  184 static uint32_t
  185 pack_4x8(pack_1x8_func_t pack_1x8,
  186          float x, float y, float z, float w)
  187 {
  188    /* From section 8.4 of the GLSL 4.30 spec:
  189     *
  190     *    packSnorm4x8
  191     *    ------------
  192     *    The first component of the vector will be written to the least
  193     *    significant bits of the output; the last component will be written to
  194     *    the most significant bits.
  195     *
  196     * The specifications for the other packing functions contain similar
  197     * language.
  198     */
  199    uint32_t u = 0;
  200    u |= ((uint32_t) pack_1x8(x) << 0);
  201    u |= ((uint32_t) pack_1x8(y) << 8);
  202    u |= ((uint32_t) pack_1x8(z) << 16);
  203    u |= ((uint32_t) pack_1x8(w) << 24);
  204    return u;
  205 }
  206 
  207 /**
  208  * Evaluate a 2x16 floating-point unpacking function.
  209  */
  210 static void
  211 unpack_2x16(unpack_1x16_func_t unpack_1x16,
  212             uint32_t u,
  213             float *x, float *y)
  214 {
  215     /* From section 8.4 of the GLSL ES 3.00 spec:
  216      *
  217      *    unpackSnorm2x16
  218      *    ---------------
  219      *    The first component of the returned vector will be extracted from
  220      *    the least significant bits of the input; the last component will be
  221      *    extracted from the most significant bits.
  222      *
  223      * The specifications for the other unpacking functions contain similar
  224      * language.
  225      */
  226    *x = unpack_1x16((uint16_t) (u & 0xffff));
  227    *y = unpack_1x16((uint16_t) (u >> 16));
  228 }
  229 
  230 /**
  231  * Evaluate a 4x8 floating-point unpacking function.
  232  */
  233 static void
  234 unpack_4x8(unpack_1x8_func_t unpack_1x8, uint32_t u,
  235            float *x, float *y, float *z, float *w)
  236 {
  237     /* From section 8.4 of the GLSL 4.30 spec:
  238      *
  239      *    unpackSnorm4x8
  240      *    --------------
  241      *    The first component of the returned vector will be extracted from
  242      *    the least significant bits of the input; the last component will be
  243      *    extracted from the most significant bits.
  244      *
  245      * The specifications for the other unpacking functions contain similar
  246      * language.
  247      */
  248    *x = unpack_1x8((uint8_t) (u & 0xff));
  249    *y = unpack_1x8((uint8_t) (u >> 8));
  250    *z = unpack_1x8((uint8_t) (u >> 16));
  251    *w = unpack_1x8((uint8_t) (u >> 24));
  252 }
  253 
  254 /**
  255  * Evaluate one component of packSnorm4x8.
  256  */
  257 static uint8_t
  258 pack_snorm_1x8(float x)
  259 {
  260     /* From section 8.4 of the GLSL 4.30 spec:
  261      *
  262      *    packSnorm4x8
  263      *    ------------
  264      *    The conversion for component c of v to fixed point is done as
  265      *    follows:
  266      *
  267      *      packSnorm4x8: round(clamp(c, -1, +1) * 127.0)
  268      */
  269    return (uint8_t)
  270           _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 127.0f);
  271 }
  272 
  273 /**
  274  * Evaluate one component of packSnorm2x16.
  275  */
  276 static uint16_t
  277 pack_snorm_1x16(float x)
  278 {
  279     /* From section 8.4 of the GLSL ES 3.00 spec:
  280      *
  281      *    packSnorm2x16
  282      *    -------------
  283      *    The conversion for component c of v to fixed point is done as
  284      *    follows:
  285      *
  286      *      packSnorm2x16: round(clamp(c, -1, +1) * 32767.0)
  287      */
  288    return (uint16_t)
  289           _mesa_lroundevenf(CLAMP(x, -1.0f, +1.0f) * 32767.0f);
  290 }
  291 
  292 /**
  293  * Evaluate one component of unpackSnorm4x8.
  294  */
  295 static float
  296 unpack_snorm_1x8(uint8_t u)
  297 {
  298     /* From section 8.4 of the GLSL 4.30 spec:
  299      *
  300      *    unpackSnorm4x8
  301      *    --------------
  302      *    The conversion for unpacked fixed-point value f to floating point is
  303      *    done as follows:
  304      *
  305      *       unpackSnorm4x8: clamp(f / 127.0, -1, +1)
  306      */
  307    return CLAMP((int8_t) u / 127.0f, -1.0f, +1.0f);
  308 }
  309 
  310 /**
  311  * Evaluate one component of unpackSnorm2x16.
  312  */
  313 static float
  314 unpack_snorm_1x16(uint16_t u)
  315 {
  316     /* From section 8.4 of the GLSL ES 3.00 spec:
  317      *
  318      *    unpackSnorm2x16
  319      *    ---------------
  320      *    The conversion for unpacked fixed-point value f to floating point is
  321      *    done as follows:
  322      *
  323      *       unpackSnorm2x16: clamp(f / 32767.0, -1, +1)
  324      */
  325    return CLAMP((int16_t) u / 32767.0f, -1.0f, +1.0f);
  326 }
  327 
  328 /**
  329  * Evaluate one component packUnorm4x8.
  330  */
  331 static uint8_t
  332 pack_unorm_1x8(float x)
  333 {
  334     /* From section 8.4 of the GLSL 4.30 spec:
  335      *
  336      *    packUnorm4x8
  337      *    ------------
  338      *    The conversion for component c of v to fixed point is done as
  339      *    follows:
  340      *
  341      *       packUnorm4x8: round(clamp(c, 0, +1) * 255.0)
  342      */
  343    return (uint8_t) (int) _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 255.0f);
  344 }
  345 
  346 /**
  347  * Evaluate one component packUnorm2x16.
  348  */
  349 static uint16_t
  350 pack_unorm_1x16(float x)
  351 {
  352     /* From section 8.4 of the GLSL ES 3.00 spec:
  353      *
  354      *    packUnorm2x16
  355      *    -------------
  356      *    The conversion for component c of v to fixed point is done as
  357      *    follows:
  358      *
  359      *       packUnorm2x16: round(clamp(c, 0, +1) * 65535.0)
  360      */
  361    return (uint16_t) (int)
  362           _mesa_roundevenf(CLAMP(x, 0.0f, 1.0f) * 65535.0f);
  363 }
  364 
  365 /**
  366  * Evaluate one component of unpackUnorm4x8.
  367  */
  368 static float
  369 unpack_unorm_1x8(uint8_t u)
  370 {
  371     /* From section 8.4 of the GLSL 4.30 spec:
  372      *
  373      *    unpackUnorm4x8
  374      *    --------------
  375      *    The conversion for unpacked fixed-point value f to floating point is
  376      *    done as follows:
  377      *
  378      *       unpackUnorm4x8: f / 255.0
  379      */
  380    return (float) u / 255.0f;
  381 }
  382 
  383 /**
  384  * Evaluate one component of unpackUnorm2x16.
  385  */
  386 static float
  387 unpack_unorm_1x16(uint16_t u)
  388 {
  389     /* From section 8.4 of the GLSL ES 3.00 spec:
  390      *
  391      *    unpackUnorm2x16
  392      *    ---------------
  393      *    The conversion for unpacked fixed-point value f to floating point is
  394      *    done as follows:
  395      *
  396      *       unpackUnorm2x16: f / 65535.0
  397      */
  398    return (float) u / 65535.0f;
  399 }
  400 
  401 /**
  402  * Evaluate one component of packHalf2x16.
  403  */
  404 static uint16_t
  405 pack_half_1x16(float x)
  406 {
  407    return _mesa_float_to_half(x);
  408 }
  409 
  410 /**
  411  * Evaluate one component of unpackHalf2x16.
  412  */
  413 static float
  414 unpack_half_1x16(uint16_t u)
  415 {
  416    return _mesa_half_to_float(u);
  417 }
  418 
  419 static int32_t
  420 iadd_saturate(int32_t a, int32_t b)
  421 {
  422    return CLAMP(int64_t(a) + int64_t(b), INT32_MIN, INT32_MAX);
  423 }
  424 
  425 static int64_t
  426 iadd64_saturate(int64_t a, int64_t b)
  427 {
  428    if (a < 0 && b < INT64_MIN - a)
  429       return INT64_MIN;
  430 
  431    if (a > 0 && b > INT64_MAX - a)
  432       return INT64_MAX;
  433 
  434    return a + b;
  435 }
  436 
  437 static int32_t
  438 isub_saturate(int32_t a, int32_t b)
  439 {
  440    return CLAMP(int64_t(a) - int64_t(b), INT32_MIN, INT32_MAX);
  441 }
  442 
  443 static int64_t
  444 isub64_saturate(int64_t a, int64_t b)
  445 {
  446    if (b > 0 && a < INT64_MIN + b)
  447       return INT64_MIN;
  448 
  449    if (b < 0 && a > INT64_MAX + b)
  450       return INT64_MAX;
  451 
  452    return a - b;
  453 }
  454 
  455 static uint64_t
  456 pack_2x32(uint32_t a, uint32_t b)
  457 {
  458    uint64_t v = a;
  459    v |= (uint64_t)b << 32;
  460    return v;
  461 }
  462 
  463 static void
  464 unpack_2x32(uint64_t p, uint32_t *a, uint32_t *b)
  465 {
  466    *a = p & 0xffffffff;
  467    *b = (p >> 32);
  468 }
  469 
  470 /**
  471  * Get the constant that is ultimately referenced by an r-value, in a constant
  472  * expression evaluation context.
  473  *
  474  * The offset is used when the reference is to a specific column of a matrix.
  475  */
  476 static bool
  477 constant_referenced(const ir_dereference *deref,
  478                     struct hash_table *variable_context,
  479                     ir_constant *&store, int &offset)
  480 {
  481    store = NULL;
  482    offset = 0;
  483 
  484    if (variable_context == NULL)
  485       return false;
  486 
  487    switch (deref->ir_type) {
  488    case ir_type_dereference_array: {
  489       const ir_dereference_array *const da =
  490          (const ir_dereference_array *) deref;
  491 
  492       ir_constant *const index_c =
  493          da->array_index->constant_expression_value(variable_context);
  494 
  495       if (!index_c || !index_c->type->is_scalar() ||
  496           !index_c->type->is_integer_32())
  497          break;
  498 
  499       const int index = index_c->type->base_type == GLSL_TYPE_INT ?
  500          index_c->get_int_component(0) :
  501          index_c->get_uint_component(0);
  502 
  503       ir_constant *substore;
  504       int suboffset;
  505 
  506       const ir_dereference *const deref = da->array->as_dereference();
  507       if (!deref)
  508          break;
  509 
  510       if (!constant_referenced(deref, variable_context, substore, suboffset))
  511          break;
  512 
  513       const glsl_type *const vt = da->array->type;
  514       if (vt->is_array()) {
  515          store = substore->get_array_element(index);
  516          offset = 0;
  517       } else if (vt->is_matrix()) {
  518          store = substore;
  519          offset = index * vt->vector_elements;
  520       } else if (vt->is_vector()) {
  521          store = substore;
  522          offset = suboffset + index;
  523       }
  524 
  525       break;
  526    }
  527 
  528    case ir_type_dereference_record: {
  529       const ir_dereference_record *const dr =
  530          (const ir_dereference_record *) deref;
  531 
  532       const ir_dereference *const deref = dr->record->as_dereference();
  533       if (!deref)
  534          break;
  535 
  536       ir_constant *substore;
  537       int suboffset;
  538 
  539       if (!constant_referenced(deref, variable_context, substore, suboffset))
  540          break;
  541 
  542       /* Since we're dropping it on the floor...
  543        */
  544       assert(suboffset == 0);
  545 
  546       store = substore->get_record_field(dr->field_idx);
  547       break;
  548    }
  549 
  550    case ir_type_dereference_variable: {
  551       const ir_dereference_variable *const dv =
  552          (const ir_dereference_variable *) deref;
  553 
  554       hash_entry *entry = _mesa_hash_table_search(variable_context, dv->var);
  555       if (entry)
  556          store = (ir_constant *) entry->data;
  557       break;
  558    }
  559 
  560    default:
  561       assert(!"Should not get here.");
  562       break;
  563    }
  564 
  565    return store != NULL;
  566 }
  567 
  568 
  569 ir_constant *
  570 ir_rvalue::constant_expression_value(void *, struct hash_table *)
  571 {
  572    assert(this->type->is_error());
  573    return NULL;
  574 }
  575 
  576 static uint32_t
  577 bitfield_reverse(uint32_t v)
  578 {
  579    /* http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious */
  580    uint32_t r = v; // r will be reversed bits of v; first get LSB of v
  581    int s = sizeof(v) * CHAR_BIT - 1; // extra shift needed at end
  582 
  583    for (v >>= 1; v; v >>= 1) {
  584       r <<= 1;
  585       r |= v & 1;
  586       s--;
  587    }
  588    r <<= s; // shift when v's highest bits are zero
  589 
  590    return r;
  591 }
  592 
  593 static int
  594 find_msb_uint(uint32_t v)
  595 {
  596    int count = 0;
  597 
  598    /* If v == 0, then the loop will terminate when count == 32.  In that case
  599     * 31-count will produce the -1 result required by GLSL findMSB().
  600     */
  601    while (((v & (1u << 31)) == 0) && count != 32) {
  602       count++;
  603       v <<= 1;
  604    }
  605 
  606    return 31 - count;
  607 }
  608 
  609 static int
  610 find_msb_int(int32_t v)
  611 {
  612    /* If v is signed, findMSB() returns the position of the most significant
  613     * zero bit.
  614     */
  615    return find_msb_uint(v < 0 ? ~v : v);
  616 }
  617 
  618 static float
  619 ldexpf_flush_subnormal(float x, int exp)
  620 {
  621    const float result = ldexpf(x, exp);
  622 
  623    /* Flush subnormal values to zero. */
  624    return !isnormal(result) ? copysignf(0.0f, x) : result;
  625 }
  626 
  627 static double
  628 ldexp_flush_subnormal(double x, int exp)
  629 {
  630    const double result = ldexp(x, exp);
  631 
  632    /* Flush subnormal values to zero. */
  633    return !isnormal(result) ? copysign(0.0, x) : result;
  634 }
  635 
  636 static uint32_t
  637 bitfield_extract_uint(uint32_t value, int offset, int bits)
  638 {
  639    if (bits == 0)
  640       return 0;
  641    else if (offset < 0 || bits < 0)
  642       return 0; /* Undefined, per spec. */
  643    else if (offset + bits > 32)
  644       return 0; /* Undefined, per spec. */
  645    else {
  646       value <<= 32 - bits - offset;
  647       value >>= 32 - bits;
  648       return value;
  649    }
  650 }
  651 
  652 static int32_t
  653 bitfield_extract_int(int32_t value, int offset, int bits)
  654 {
  655    if (bits == 0)
  656       return 0;
  657    else if (offset < 0 || bits < 0)
  658       return 0; /* Undefined, per spec. */
  659    else if (offset + bits > 32)
  660       return 0; /* Undefined, per spec. */
  661    else {
  662       value <<= 32 - bits - offset;
  663       value >>= 32 - bits;
  664       return value;
  665    }
  666 }
  667 
  668 static uint32_t
  669 bitfield_insert(uint32_t base, uint32_t insert, int offset, int bits)
  670 {
  671    if (bits == 0)
  672       return base;
  673    else if (offset < 0 || bits < 0)
  674       return 0; /* Undefined, per spec. */
  675    else if (offset + bits > 32)
  676       return 0; /* Undefined, per spec. */
  677    else {
  678       unsigned insert_mask = ((1ull << bits) - 1) << offset;
  679 
  680       insert <<= offset;
  681       insert &= insert_mask;
  682       base &= ~insert_mask;
  683 
  684       return base | insert;
  685    }
  686 }
  687 
  688 ir_constant *
  689 ir_expression::constant_expression_value(void *mem_ctx,
  690                                          struct hash_table *variable_context)
  691 {
  692    assert(mem_ctx);
  693 
  694    if (this->type->is_error())
  695       return NULL;
  696 
  697    ir_constant *op[ARRAY_SIZE(this->operands)] = { NULL, };
  698    ir_constant_data data;
  699 
  700    memset(&data, 0, sizeof(data));
  701 
  702    for (unsigned operand = 0; operand < this->num_operands; operand++) {
  703       op[operand] =
  704          this->operands[operand]->constant_expression_value(mem_ctx,
  705                                                             variable_context);
  706       if (!op[operand])
  707          return NULL;
  708    }
  709 
  710    for (unsigned operand = 0; operand < this->num_operands; operand++) {
  711       if (op[operand]->type->base_type == GLSL_TYPE_FLOAT16) {
  712          const struct glsl_type *float_type =
  713             glsl_type::get_instance(GLSL_TYPE_FLOAT,
  714                                     op[operand]->type->vector_elements,
  715                                     op[operand]->type->matrix_columns,
  716                                     op[operand]->type->explicit_stride,
  717                                     op[operand]->type->interface_row_major);
  718 
  719          ir_constant_data f;
  720          for (unsigned i = 0; i < ARRAY_SIZE(f.f); i++)
  721             f.f[i] = _mesa_half_to_float(op[operand]->value.f16[i]);
  722 
  723          op[operand] = new(mem_ctx) ir_constant(float_type, &f);
  724       }
  725    }
  726 
  727    if (op[1] != NULL)
  728       switch (this->operation) {
  729       case ir_binop_lshift:
  730       case ir_binop_rshift:
  731       case ir_binop_ldexp:
  732       case ir_binop_interpolate_at_offset:
  733       case ir_binop_interpolate_at_sample:
  734       case ir_binop_vector_extract:
  735       case ir_triop_csel:
  736       case ir_triop_bitfield_extract:
  737          break;
  738 
  739       default:
  740          assert(op[0]->type->base_type == op[1]->type->base_type);
  741          break;
  742       }
  743 
  744    bool op0_scalar = op[0]->type->is_scalar();
  745    bool op1_scalar = op[1] != NULL && op[1]->type->is_scalar();
  746 
  747    /* When iterating over a vector or matrix's components, we want to increase
  748     * the loop counter.  However, for scalars, we want to stay at 0.
  749     */
  750    unsigned c0_inc = op0_scalar ? 0 : 1;
  751    unsigned c1_inc = op1_scalar ? 0 : 1;
  752    unsigned components;
  753    if (op1_scalar || !op[1]) {
  754       components = op[0]->type->components();
  755    } else {
  756       components = op[1]->type->components();
  757    }
  758 
  759    /* Handle array operations here, rather than below. */
  760    if (op[0]->type->is_array()) {
  761       assert(op[1] != NULL && op[1]->type->is_array());
  762       switch (this->operation) {
  763       case ir_binop_all_equal:
  764          return new(mem_ctx) ir_constant(op[0]->has_value(op[1]));
  765       case ir_binop_any_nequal:
  766          return new(mem_ctx) ir_constant(!op[0]->has_value(op[1]));
  767       default:
  768          break;
  769       }
  770       return NULL;
  771    }
  772 
  773 #include "ir_expression_operation_constant.h"
  774 
  775    if (this->type->base_type == GLSL_TYPE_FLOAT16) {
  776       ir_constant_data f;
  777       for (unsigned i = 0; i < ARRAY_SIZE(f.f16); i++)
  778          f.f16[i] = _mesa_float_to_half(data.f[i]);
  779 
  780       return new(mem_ctx) ir_constant(this->type, &f);
  781    }
  782 
  783 
  784    return new(mem_ctx) ir_constant(this->type, &data);
  785 }
  786 
  787 
  788 ir_constant *
  789 ir_texture::constant_expression_value(void *, struct hash_table *)
  790 {
  791    /* texture lookups aren't constant expressions */
  792    return NULL;
  793 }
  794 
  795 
  796 ir_constant *
  797 ir_swizzle::constant_expression_value(void *mem_ctx,
  798                                       struct hash_table *variable_context)
  799 {
  800    assert(mem_ctx);
  801 
  802    ir_constant *v = this->val->constant_expression_value(mem_ctx,
  803                                                          variable_context);
  804 
  805    if (v != NULL) {
  806       ir_constant_data data = { { 0 } };
  807 
  808       const unsigned swiz_idx[4] = {
  809          this->mask.x, this->mask.y, this->mask.z, this->mask.w
  810       };
  811 
  812       for (unsigned i = 0; i < this->mask.num_components; i++) {
  813          switch (v->type->base_type) {
  814          case GLSL_TYPE_UINT:
  815          case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
  816          case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
  817          case GLSL_TYPE_FLOAT16: data.f16[i] = v->value.f16[swiz_idx[i]]; break;
  818          case GLSL_TYPE_BOOL:  data.b[i] = v->value.b[swiz_idx[i]]; break;
  819          case GLSL_TYPE_DOUBLE:data.d[i] = v->value.d[swiz_idx[i]]; break;
  820          case GLSL_TYPE_UINT64:data.u64[i] = v->value.u64[swiz_idx[i]]; break;
  821          case GLSL_TYPE_INT64: data.i64[i] = v->value.i64[swiz_idx[i]]; break;
  822          default:              assert(!"Should not get here."); break;
  823          }
  824       }
  825 
  826       return new(mem_ctx) ir_constant(this->type, &data);
  827    }
  828    return NULL;
  829 }
  830 
  831 
  832 ir_constant *
  833 ir_dereference_variable::constant_expression_value(void *mem_ctx,
  834                                                    struct hash_table *variable_context)
  835 {
  836    assert(var);
  837    assert(mem_ctx);
  838 
  839    /* Give priority to the context hashtable, if it exists */
  840    if (variable_context) {
  841       hash_entry *entry = _mesa_hash_table_search(variable_context, var);
  842 
  843       if(entry)
  844          return (ir_constant *) entry->data;
  845    }
  846 
  847    /* The constant_value of a uniform variable is its initializer,
  848     * not the lifetime constant value of the uniform.
  849     */
  850    if (var->data.mode == ir_var_uniform)
  851       return NULL;
  852 
  853    if (!var->constant_value)
  854       return NULL;
  855 
  856    return var->constant_value->clone(mem_ctx, NULL);
  857 }
  858 
  859 
  860 ir_constant *
  861 ir_dereference_array::constant_expression_value(void *mem_ctx,
  862                                                 struct hash_table *variable_context)
  863 {
  864    assert(mem_ctx);
  865 
  866    ir_constant *array = this->array->constant_expression_value(mem_ctx, variable_context);
  867    ir_constant *idx = this->array_index->constant_expression_value(mem_ctx, variable_context);
  868 
  869    if ((array != NULL) && (idx != NULL)) {
  870       if (array->type->is_matrix()) {
  871          /* Array access of a matrix results in a vector.
  872           */
  873          const unsigned column = idx->value.u[0];
  874 
  875          const glsl_type *const column_type = array->type->column_type();
  876 
  877          /* Offset in the constant matrix to the first element of the column
  878           * to be extracted.
  879           */
  880          const unsigned mat_idx = column * column_type->vector_elements;
  881 
  882          ir_constant_data data = { { 0 } };
  883 
  884          switch (column_type->base_type) {
  885          case GLSL_TYPE_UINT:
  886          case GLSL_TYPE_INT:
  887             for (unsigned i = 0; i < column_type->vector_elements; i++)
  888                data.u[i] = array->value.u[mat_idx + i];
  889 
  890             break;
  891 
  892          case GLSL_TYPE_FLOAT:
  893             for (unsigned i = 0; i < column_type->vector_elements; i++)
  894                data.f[i] = array->value.f[mat_idx + i];
  895 
  896             break;
  897 
  898          case GLSL_TYPE_DOUBLE:
  899             for (unsigned i = 0; i < column_type->vector_elements; i++)
  900                data.d[i] = array->value.d[mat_idx + i];
  901 
  902             break;
  903 
  904          default:
  905             assert(!"Should not get here.");
  906             break;
  907          }
  908 
  909          return new(mem_ctx) ir_constant(column_type, &data);
  910       } else if (array->type->is_vector()) {
  911          const unsigned component = idx->value.u[0];
  912 
  913          return new(mem_ctx) ir_constant(array, component);
  914       } else if (array->type->is_array()) {
  915          const unsigned index = idx->value.u[0];
  916          return array->get_array_element(index)->clone(mem_ctx, NULL);
  917       }
  918    }
  919    return NULL;
  920 }
  921 
  922 
  923 ir_constant *
  924 ir_dereference_record::constant_expression_value(void *mem_ctx,
  925                                                  struct hash_table *)
  926 {
  927    assert(mem_ctx);
  928 
  929    ir_constant *v = this->record->constant_expression_value(mem_ctx);
  930 
  931    return (v != NULL) ? v->get_record_field(this->field_idx) : NULL;
  932 }
  933 
  934 
  935 ir_constant *
  936 ir_assignment::constant_expression_value(void *, struct hash_table *)
  937 {
  938    /* FINISHME: Handle CEs involving assignment (return RHS) */
  939    return NULL;
  940 }
  941 
  942 
  943 ir_constant *
  944 ir_constant::constant_expression_value(void *, struct hash_table *)
  945 {
  946    return this;
  947 }
  948 
  949 
  950 ir_constant *
  951 ir_call::constant_expression_value(void *mem_ctx, struct hash_table *variable_context)
  952 {
  953    assert(mem_ctx);
  954 
  955    return this->callee->constant_expression_value(mem_ctx,
  956                                                   &this->actual_parameters,
  957                                                   variable_context);
  958 }
  959 
  960 
  961 bool ir_function_signature::constant_expression_evaluate_expression_list(void *mem_ctx,
  962                                                                         const struct exec_list &body,
  963                                                                          struct hash_table *variable_context,
  964                                                                          ir_constant **result)
  965 {
  966    assert(mem_ctx);
  967 
  968    foreach_in_list(ir_instruction, inst, &body) {
  969       switch(inst->ir_type) {
  970 
  971          /* (declare () type symbol) */
  972       case ir_type_variable: {
  973          ir_variable *var = inst->as_variable();
  974          _mesa_hash_table_insert(variable_context, var, ir_constant::zero(this, var->type));
  975          break;
  976       }
  977 
  978          /* (assign [condition] (write-mask) (ref) (value)) */
  979       case ir_type_assignment: {
  980          ir_assignment *asg = inst->as_assignment();
  981          if (asg->condition) {
  982             ir_constant *cond =
  983                asg->condition->constant_expression_value(mem_ctx,
  984                                                          variable_context);
  985             if (!cond)
  986                return false;
  987             if (!cond->get_bool_component(0))
  988                break;
  989          }
  990 
  991          ir_constant *store = NULL;
  992          int offset = 0;
  993 
  994          if (!constant_referenced(asg->lhs, variable_context, store, offset))
  995             return false;
  996 
  997          ir_constant *value =
  998             asg->rhs->constant_expression_value(mem_ctx, variable_context);
  999 
 1000          if (!value)
 1001             return false;
 1002 
 1003          store->copy_masked_offset(value, offset, asg->write_mask);
 1004          break;
 1005       }
 1006 
 1007          /* (return (expression)) */
 1008       case ir_type_return:
 1009          assert (result);
 1010          *result =
 1011             inst->as_return()->value->constant_expression_value(mem_ctx,
 1012                                                                 variable_context);
 1013          return *result != NULL;
 1014 
 1015          /* (call name (ref) (params))*/
 1016       case ir_type_call: {
 1017          ir_call *call = inst->as_call();
 1018 
 1019          /* Just say no to void functions in constant expressions.  We
 1020           * don't need them at that point.
 1021           */
 1022 
 1023          if (!call->return_deref)
 1024             return false;
 1025 
 1026          ir_constant *store = NULL;
 1027          int offset = 0;
 1028 
 1029          if (!constant_referenced(call->return_deref, variable_context,
 1030                                   store, offset))
 1031             return false;
 1032 
 1033          ir_constant *value =
 1034             call->constant_expression_value(mem_ctx, variable_context);
 1035 
 1036          if(!value)
 1037             return false;
 1038 
 1039          store->copy_offset(value, offset);
 1040          break;
 1041       }
 1042 
 1043          /* (if condition (then-instructions) (else-instructions)) */
 1044       case ir_type_if: {
 1045          ir_if *iif = inst->as_if();
 1046 
 1047          ir_constant *cond =
 1048             iif->condition->constant_expression_value(mem_ctx,
 1049                                                       variable_context);
 1050          if (!cond || !cond->type->is_boolean())
 1051             return false;
 1052 
 1053          exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions;
 1054 
 1055          *result = NULL;
 1056          if (!constant_expression_evaluate_expression_list(mem_ctx, branch,
 1057                                                            variable_context,
 1058                                                            result))
 1059             return false;
 1060 
 1061          /* If there was a return in the branch chosen, drop out now. */
 1062          if (*result)
 1063             return true;
 1064 
 1065          break;
 1066       }
 1067 
 1068          /* Every other expression type, we drop out. */
 1069       default:
 1070          return false;
 1071       }
 1072    }
 1073 
 1074    /* Reaching the end of the block is not an error condition */
 1075    if (result)
 1076       *result = NULL;
 1077 
 1078    return true;
 1079 }
 1080 
 1081 ir_constant *
 1082 ir_function_signature::constant_expression_value(void *mem_ctx,
 1083                                                  exec_list *actual_parameters,
 1084                                                  struct hash_table *variable_context)
 1085 {
 1086    assert(mem_ctx);
 1087 
 1088    const glsl_type *type = this->return_type;
 1089    if (type == glsl_type::void_type)
 1090       return NULL;
 1091 
 1092    /* From the GLSL 1.20 spec, page 23:
 1093     * "Function calls to user-defined functions (non-built-in functions)
 1094     *  cannot be used to form constant expressions."
 1095     */
 1096    if (!this->is_builtin())
 1097       return NULL;
 1098 
 1099    /*
 1100     * Of the builtin functions, only the texture lookups and the noise
 1101     * ones must not be used in constant expressions.  Texture instructions
 1102     * include special ir_texture opcodes which can't be constant-folded (see
 1103     * ir_texture::constant_expression_value).  Noise functions, however, we
 1104     * have to special case here.
 1105     */
 1106    if (strcmp(this->function_name(), "noise1") == 0 ||
 1107        strcmp(this->function_name(), "noise2") == 0 ||
 1108        strcmp(this->function_name(), "noise3") == 0 ||
 1109        strcmp(this->function_name(), "noise4") == 0)
 1110       return NULL;
 1111 
 1112    /* Initialize the table of dereferencable names with the function
 1113     * parameters.  Verify their const-ness on the way.
 1114     *
 1115     * We expect the correctness of the number of parameters to have
 1116     * been checked earlier.
 1117     */
 1118    hash_table *deref_hash = _mesa_pointer_hash_table_create(NULL);
 1119 
 1120    /* If "origin" is non-NULL, then the function body is there.  So we
 1121     * have to use the variable objects from the object with the body,
 1122     * but the parameter instanciation on the current object.
 1123     */
 1124    const exec_node *parameter_info = origin ? origin->parameters.get_head_raw() : parameters.get_head_raw();
 1125 
 1126    foreach_in_list(ir_rvalue, n, actual_parameters) {
 1127       ir_constant *constant =
 1128          n->constant_expression_value(mem_ctx, variable_context);
 1129       if (constant == NULL) {
 1130          _mesa_hash_table_destroy(deref_hash, NULL);
 1131          return NULL;
 1132       }
 1133 
 1134 
 1135       ir_variable *var = (ir_variable *)parameter_info;
 1136       _mesa_hash_table_insert(deref_hash, var, constant);
 1137 
 1138       parameter_info = parameter_info->next;
 1139    }
 1140 
 1141    ir_constant *result = NULL;
 1142 
 1143    /* Now run the builtin function until something non-constant
 1144     * happens or we get the result.
 1145     */
 1146    if (constant_expression_evaluate_expression_list(mem_ctx, origin ? origin->body : body, deref_hash, &result) &&
 1147        result)
 1148       result = result->clone(mem_ctx, NULL);
 1149 
 1150    _mesa_hash_table_destroy(deref_hash, NULL);
 1151 
 1152    return result;
 1153 }