• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <string.h>
24 #include "main/core.h" /* for MAX2 */
25 #include "ir.h"
26 #include "ir_visitor.h"
27 #include "glsl_types.h"
28 
ir_rvalue()29 ir_rvalue::ir_rvalue()
30 {
31    this->type = glsl_type::error_type;
32 }
33 
is_zero() const34 bool ir_rvalue::is_zero() const
35 {
36    return false;
37 }
38 
is_one() const39 bool ir_rvalue::is_one() const
40 {
41    return false;
42 }
43 
is_negative_one() const44 bool ir_rvalue::is_negative_one() const
45 {
46    return false;
47 }
48 
49 /**
50  * Modify the swizzle make to move one component to another
51  *
52  * \param m    IR swizzle to be modified
53  * \param from Component in the RHS that is to be swizzled
54  * \param to   Desired swizzle location of \c from
55  */
56 static void
update_rhs_swizzle(ir_swizzle_mask & m,unsigned from,unsigned to)57 update_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
58 {
59    switch (to) {
60    case 0: m.x = from; break;
61    case 1: m.y = from; break;
62    case 2: m.z = from; break;
63    case 3: m.w = from; break;
64    default: assert(!"Should not get here.");
65    }
66 
67    m.num_components = MAX2(m.num_components, (to + 1));
68 }
69 
70 void
set_lhs(ir_rvalue * lhs)71 ir_assignment::set_lhs(ir_rvalue *lhs)
72 {
73    void *mem_ctx = this;
74    bool swizzled = false;
75 
76    while (lhs != NULL) {
77       ir_swizzle *swiz = lhs->as_swizzle();
78 
79       if (swiz == NULL)
80 	 break;
81 
82       unsigned write_mask = 0;
83       ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
84 
85       for (unsigned i = 0; i < swiz->mask.num_components; i++) {
86 	 unsigned c = 0;
87 
88 	 switch (i) {
89 	 case 0: c = swiz->mask.x; break;
90 	 case 1: c = swiz->mask.y; break;
91 	 case 2: c = swiz->mask.z; break;
92 	 case 3: c = swiz->mask.w; break;
93 	 default: assert(!"Should not get here.");
94 	 }
95 
96 	 write_mask |= (((this->write_mask >> i) & 1) << c);
97 	 update_rhs_swizzle(rhs_swiz, i, c);
98       }
99 
100       this->write_mask = write_mask;
101       lhs = swiz->val;
102 
103       this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
104       swizzled = true;
105    }
106 
107    if (swizzled) {
108       /* Now, RHS channels line up with the LHS writemask.  Collapse it
109        * to just the channels that will be written.
110        */
111       ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
112       int rhs_chan = 0;
113       for (int i = 0; i < 4; i++) {
114 	 if (write_mask & (1 << i))
115 	    update_rhs_swizzle(rhs_swiz, i, rhs_chan++);
116       }
117       this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
118    }
119 
120    assert((lhs == NULL) || lhs->as_dereference());
121 
122    this->lhs = (ir_dereference *) lhs;
123 }
124 
125 ir_variable *
whole_variable_written()126 ir_assignment::whole_variable_written()
127 {
128    ir_variable *v = this->lhs->whole_variable_referenced();
129 
130    if (v == NULL)
131       return NULL;
132 
133    if (v->type->is_scalar())
134       return v;
135 
136    if (v->type->is_vector()) {
137       const unsigned mask = (1U << v->type->vector_elements) - 1;
138 
139       if (mask != this->write_mask)
140 	 return NULL;
141    }
142 
143    /* Either all the vector components are assigned or the variable is some
144     * composite type (and the whole thing is assigned.
145     */
146    return v;
147 }
148 
ir_assignment(ir_dereference * lhs,ir_rvalue * rhs,ir_rvalue * condition,unsigned write_mask)149 ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
150 			     ir_rvalue *condition, unsigned write_mask)
151 {
152    this->ir_type = ir_type_assignment;
153    this->condition = condition;
154    this->rhs = rhs;
155    this->lhs = lhs;
156    this->write_mask = write_mask;
157 
158    if (lhs->type->is_scalar() || lhs->type->is_vector()) {
159       int lhs_components = 0;
160       for (int i = 0; i < 4; i++) {
161 	 if (write_mask & (1 << i))
162 	    lhs_components++;
163       }
164 
165       assert(lhs_components == this->rhs->type->vector_elements);
166    }
167 }
168 
ir_assignment(ir_rvalue * lhs,ir_rvalue * rhs,ir_rvalue * condition)169 ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
170 			     ir_rvalue *condition)
171 {
172    this->ir_type = ir_type_assignment;
173    this->condition = condition;
174    this->rhs = rhs;
175 
176    /* If the RHS is a vector type, assume that all components of the vector
177     * type are being written to the LHS.  The write mask comes from the RHS
178     * because we can have a case where the LHS is a vec4 and the RHS is a
179     * vec3.  In that case, the assignment is:
180     *
181     *     (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
182     */
183    if (rhs->type->is_vector())
184       this->write_mask = (1U << rhs->type->vector_elements) - 1;
185    else if (rhs->type->is_scalar())
186       this->write_mask = 1;
187    else // TODO: write masking for matrix
188       this->write_mask = 0;
189 
190    this->set_lhs(lhs);
191 }
192 
193 
ir_expression(int op,const struct glsl_type * type,ir_rvalue * op0)194 ir_expression::ir_expression(int op, const struct glsl_type *type,
195 			     ir_rvalue *op0)
196 {
197    assert(get_num_operands(ir_expression_operation(op)) == 1);
198    this->ir_type = ir_type_expression;
199    this->type = type;
200    this->operation = ir_expression_operation(op);
201    this->operands[0] = op0;
202    this->operands[1] = NULL;
203    this->operands[2] = NULL;
204    this->operands[3] = NULL;
205 }
206 
ir_expression(int op,const struct glsl_type * type,ir_rvalue * op0,ir_rvalue * op1)207 ir_expression::ir_expression(int op, const struct glsl_type *type,
208 			     ir_rvalue *op0, ir_rvalue *op1)
209 {
210    assert(((op1 == NULL) && (get_num_operands(ir_expression_operation(op)) == 1))
211 	  || (get_num_operands(ir_expression_operation(op)) == 2));
212    this->ir_type = ir_type_expression;
213    this->type = type;
214    this->operation = ir_expression_operation(op);
215    this->operands[0] = op0;
216    this->operands[1] = op1;
217    this->operands[2] = NULL;
218    this->operands[3] = NULL;
219 }
220 
ir_expression(int op,const struct glsl_type * type,ir_rvalue * op0,ir_rvalue * op1,ir_rvalue * op2,ir_rvalue * op3)221 ir_expression::ir_expression(int op, const struct glsl_type *type,
222 			     ir_rvalue *op0, ir_rvalue *op1,
223 			     ir_rvalue *op2, ir_rvalue *op3)
224 {
225    this->ir_type = ir_type_expression;
226    this->type = type;
227    this->operation = ir_expression_operation(op);
228    this->operands[0] = op0;
229    this->operands[1] = op1;
230    this->operands[2] = op2;
231    this->operands[3] = op3;
232 }
233 
ir_expression(int op,ir_rvalue * op0)234 ir_expression::ir_expression(int op, ir_rvalue *op0)
235 {
236    this->ir_type = ir_type_expression;
237 
238    this->operation = ir_expression_operation(op);
239    this->operands[0] = op0;
240    this->operands[1] = NULL;
241    this->operands[2] = NULL;
242    this->operands[3] = NULL;
243 
244    assert(op <= ir_last_unop);
245 
246    switch (this->operation) {
247    case ir_unop_bit_not:
248    case ir_unop_logic_not:
249    case ir_unop_neg:
250    case ir_unop_abs:
251    case ir_unop_sign:
252    case ir_unop_rcp:
253    case ir_unop_rsq:
254    case ir_unop_sqrt:
255    case ir_unop_exp:
256    case ir_unop_log:
257    case ir_unop_exp2:
258    case ir_unop_log2:
259    case ir_unop_trunc:
260    case ir_unop_ceil:
261    case ir_unop_floor:
262    case ir_unop_fract:
263    case ir_unop_round_even:
264    case ir_unop_cos:
265    case ir_unop_dFdx:
266    case ir_unop_dFdy:
267       this->type = op0->type;
268       break;
269 
270    case ir_unop_any:
271       this->type = glsl_type::bool_type;
272       break;
273 
274    default:
275       assert(!"not reached: missing automatic type setup for ir_expression");
276       this->type = op0->type;
277       break;
278    }
279 }
280 
ir_expression(int op,ir_rvalue * op0,ir_rvalue * op1)281 ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
282 {
283    this->ir_type = ir_type_expression;
284 
285    this->operation = ir_expression_operation(op);
286    this->operands[0] = op0;
287    this->operands[1] = op1;
288    this->operands[2] = NULL;
289    this->operands[3] = NULL;
290 
291    assert(op > ir_last_unop);
292 
293    switch (this->operation) {
294    case ir_binop_all_equal:
295    case ir_binop_any_nequal:
296       this->type = glsl_type::bool_type;
297       break;
298 
299    case ir_binop_add:
300    case ir_binop_sub:
301    case ir_binop_min:
302    case ir_binop_max:
303    case ir_binop_pow:
304    case ir_binop_mul:
305       if (op0->type->is_scalar()) {
306 	 this->type = op1->type;
307       } else if (op1->type->is_scalar()) {
308 	 this->type = op0->type;
309       } else {
310 	 /* FINISHME: matrix types */
311 	 assert(!op0->type->is_matrix() && !op1->type->is_matrix());
312 	 assert(op0->type == op1->type);
313 	 this->type = op0->type;
314       }
315       break;
316 
317    case ir_binop_logic_and:
318    case ir_binop_logic_or:
319       if (op0->type->is_scalar()) {
320 	 this->type = op1->type;
321       } else if (op1->type->is_scalar()) {
322 	 this->type = op0->type;
323       }
324       break;
325 
326    case ir_binop_dot:
327       this->type = glsl_type::float_type;
328       break;
329 
330    default:
331       assert(!"not reached: missing automatic type setup for ir_expression");
332       this->type = glsl_type::float_type;
333    }
334 }
335 
336 unsigned int
get_num_operands(ir_expression_operation op)337 ir_expression::get_num_operands(ir_expression_operation op)
338 {
339    assert(op <= ir_last_opcode);
340 
341    if (op <= ir_last_unop)
342       return 1;
343 
344    if (op <= ir_last_binop)
345       return 2;
346 
347    if (op == ir_quadop_vector)
348       return 4;
349 
350    assert(false);
351    return 0;
352 }
353 
354 static const char *const operator_strs[] = {
355    "~",
356    "!",
357    "neg",
358    "abs",
359    "sign",
360    "rcp",
361    "rsq",
362    "sqrt",
363    "exp",
364    "log",
365    "exp2",
366    "log2",
367    "f2i",
368    "i2f",
369    "f2b",
370    "b2f",
371    "i2b",
372    "b2i",
373    "u2f",
374    "any",
375    "trunc",
376    "ceil",
377    "floor",
378    "fract",
379    "round_even",
380    "sin",
381    "cos",
382    "sin_reduced",
383    "cos_reduced",
384    "dFdx",
385    "dFdy",
386    "noise",
387    "+",
388    "-",
389    "*",
390    "/",
391    "%",
392    "<",
393    ">",
394    "<=",
395    ">=",
396    "==",
397    "!=",
398    "all_equal",
399    "any_nequal",
400    "<<",
401    ">>",
402    "&",
403    "^",
404    "|",
405    "&&",
406    "^^",
407    "||",
408    "dot",
409    "min",
410    "max",
411    "pow",
412    "vector",
413 };
414 
operator_string(ir_expression_operation op)415 const char *ir_expression::operator_string(ir_expression_operation op)
416 {
417    assert((unsigned int) op < Elements(operator_strs));
418    assert(Elements(operator_strs) == (ir_quadop_vector + 1));
419    return operator_strs[op];
420 }
421 
operator_string()422 const char *ir_expression::operator_string()
423 {
424    return operator_string(this->operation);
425 }
426 
427 ir_expression_operation
get_operator(const char * str)428 ir_expression::get_operator(const char *str)
429 {
430    const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]);
431    for (int op = 0; op < operator_count; op++) {
432       if (strcmp(str, operator_strs[op]) == 0)
433 	 return (ir_expression_operation) op;
434    }
435    return (ir_expression_operation) -1;
436 }
437 
ir_constant()438 ir_constant::ir_constant()
439 {
440    this->ir_type = ir_type_constant;
441 }
442 
ir_constant(const struct glsl_type * type,const ir_constant_data * data)443 ir_constant::ir_constant(const struct glsl_type *type,
444 			 const ir_constant_data *data)
445 {
446    assert((type->base_type >= GLSL_TYPE_UINT)
447 	  && (type->base_type <= GLSL_TYPE_BOOL));
448 
449    this->ir_type = ir_type_constant;
450    this->type = type;
451    memcpy(& this->value, data, sizeof(this->value));
452 }
453 
ir_constant(float f)454 ir_constant::ir_constant(float f)
455 {
456    this->ir_type = ir_type_constant;
457    this->type = glsl_type::float_type;
458    this->value.f[0] = f;
459    for (int i = 1; i < 16; i++)  {
460       this->value.f[i] = 0;
461    }
462 }
463 
ir_constant(unsigned int u)464 ir_constant::ir_constant(unsigned int u)
465 {
466    this->ir_type = ir_type_constant;
467    this->type = glsl_type::uint_type;
468    this->value.u[0] = u;
469    for (int i = 1; i < 16; i++) {
470       this->value.u[i] = 0;
471    }
472 }
473 
ir_constant(int i)474 ir_constant::ir_constant(int i)
475 {
476    this->ir_type = ir_type_constant;
477    this->type = glsl_type::int_type;
478    this->value.i[0] = i;
479    for (int i = 1; i < 16; i++) {
480       this->value.i[i] = 0;
481    }
482 }
483 
ir_constant(bool b)484 ir_constant::ir_constant(bool b)
485 {
486    this->ir_type = ir_type_constant;
487    this->type = glsl_type::bool_type;
488    this->value.b[0] = b;
489    for (int i = 1; i < 16; i++) {
490       this->value.b[i] = false;
491    }
492 }
493 
ir_constant(const ir_constant * c,unsigned i)494 ir_constant::ir_constant(const ir_constant *c, unsigned i)
495 {
496    this->ir_type = ir_type_constant;
497    this->type = c->type->get_base_type();
498 
499    switch (this->type->base_type) {
500    case GLSL_TYPE_UINT:  this->value.u[0] = c->value.u[i]; break;
501    case GLSL_TYPE_INT:   this->value.i[0] = c->value.i[i]; break;
502    case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
503    case GLSL_TYPE_BOOL:  this->value.b[0] = c->value.b[i]; break;
504    default:              assert(!"Should not get here."); break;
505    }
506 }
507 
ir_constant(const struct glsl_type * type,exec_list * value_list)508 ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
509 {
510    this->ir_type = ir_type_constant;
511    this->type = type;
512 
513    assert(type->is_scalar() || type->is_vector() || type->is_matrix()
514 	  || type->is_record() || type->is_array());
515 
516    if (type->is_array()) {
517       this->array_elements = hieralloc_array(this, ir_constant *, type->length);
518       unsigned i = 0;
519       foreach_list(node, value_list) {
520 	 ir_constant *value = (ir_constant *) node;
521 	 assert(value->as_constant() != NULL);
522 
523 	 this->array_elements[i++] = value;
524       }
525       return;
526    }
527 
528    /* If the constant is a record, the types of each of the entries in
529     * value_list must be a 1-for-1 match with the structure components.  Each
530     * entry must also be a constant.  Just move the nodes from the value_list
531     * to the list in the ir_constant.
532     */
533    /* FINISHME: Should there be some type checking and / or assertions here? */
534    /* FINISHME: Should the new constant take ownership of the nodes from
535     * FINISHME: value_list, or should it make copies?
536     */
537    if (type->is_record()) {
538       value_list->move_nodes_to(& this->components);
539       return;
540    }
541 
542    for (unsigned i = 0; i < 16; i++) {
543       this->value.u[i] = 0;
544    }
545 
546    ir_constant *value = (ir_constant *) (value_list->head);
547 
548    /* Constructors with exactly one scalar argument are special for vectors
549     * and matrices.  For vectors, the scalar value is replicated to fill all
550     * the components.  For matrices, the scalar fills the components of the
551     * diagonal while the rest is filled with 0.
552     */
553    if (value->type->is_scalar() && value->next->is_tail_sentinel()) {
554       if (type->is_matrix()) {
555 	 /* Matrix - fill diagonal (rest is already set to 0) */
556 	 assert(type->base_type == GLSL_TYPE_FLOAT);
557 	 for (unsigned i = 0; i < type->matrix_columns; i++)
558 	    this->value.f[i * type->vector_elements + i] = value->value.f[0];
559       } else {
560 	 /* Vector or scalar - fill all components */
561 	 switch (type->base_type) {
562 	 case GLSL_TYPE_UINT:
563 	 case GLSL_TYPE_INT:
564 	    for (unsigned i = 0; i < type->components(); i++)
565 	       this->value.u[i] = value->value.u[0];
566 	    break;
567 	 case GLSL_TYPE_FLOAT:
568 	    for (unsigned i = 0; i < type->components(); i++)
569 	       this->value.f[i] = value->value.f[0];
570 	    break;
571 	 case GLSL_TYPE_BOOL:
572 	    for (unsigned i = 0; i < type->components(); i++)
573 	       this->value.b[i] = value->value.b[0];
574 	    break;
575 	 default:
576 	    assert(!"Should not get here.");
577 	    break;
578 	 }
579       }
580       return;
581    }
582 
583    if (type->is_matrix() && value->type->is_matrix()) {
584       assert(value->next->is_tail_sentinel());
585 
586       /* From section 5.4.2 of the GLSL 1.20 spec:
587        * "If a matrix is constructed from a matrix, then each component
588        *  (column i, row j) in the result that has a corresponding component
589        *  (column i, row j) in the argument will be initialized from there."
590        */
591       unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
592       unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
593       for (unsigned i = 0; i < cols; i++) {
594 	 for (unsigned j = 0; j < rows; j++) {
595 	    const unsigned src = i * value->type->vector_elements + j;
596 	    const unsigned dst = i * type->vector_elements + j;
597 	    this->value.f[dst] = value->value.f[src];
598 	 }
599       }
600 
601       /* "All other components will be initialized to the identity matrix." */
602       for (unsigned i = cols; i < type->matrix_columns; i++)
603 	 this->value.f[i * type->vector_elements + i] = 1.0;
604 
605       return;
606    }
607 
608    /* Use each component from each entry in the value_list to initialize one
609     * component of the constant being constructed.
610     */
611    for (unsigned i = 0; i < type->components(); /* empty */) {
612       assert(value->as_constant() != NULL);
613       assert(!value->is_tail_sentinel());
614 
615       for (unsigned j = 0; j < value->type->components(); j++) {
616 	 switch (type->base_type) {
617 	 case GLSL_TYPE_UINT:
618 	    this->value.u[i] = value->get_uint_component(j);
619 	    break;
620 	 case GLSL_TYPE_INT:
621 	    this->value.i[i] = value->get_int_component(j);
622 	    break;
623 	 case GLSL_TYPE_FLOAT:
624 	    this->value.f[i] = value->get_float_component(j);
625 	    break;
626 	 case GLSL_TYPE_BOOL:
627 	    this->value.b[i] = value->get_bool_component(j);
628 	    break;
629 	 default:
630 	    /* FINISHME: What to do?  Exceptions are not the answer.
631 	     */
632 	    break;
633 	 }
634 
635 	 i++;
636 	 if (i >= type->components())
637 	    break;
638       }
639 
640       value = (ir_constant *) value->next;
641    }
642 }
643 
644 ir_constant *
zero(void * mem_ctx,const glsl_type * type)645 ir_constant::zero(void *mem_ctx, const glsl_type *type)
646 {
647    assert(type->is_numeric() || type->is_boolean());
648 
649    ir_constant *c = new(mem_ctx) ir_constant;
650    c->type = type;
651    memset(&c->value, 0, sizeof(c->value));
652 
653    return c;
654 }
655 
656 bool
get_bool_component(unsigned i) const657 ir_constant::get_bool_component(unsigned i) const
658 {
659    switch (this->type->base_type) {
660    case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
661    case GLSL_TYPE_INT:   return this->value.i[i] != 0;
662    case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
663    case GLSL_TYPE_BOOL:  return this->value.b[i];
664    default:              assert(!"Should not get here."); break;
665    }
666 
667    /* Must return something to make the compiler happy.  This is clearly an
668     * error case.
669     */
670    return false;
671 }
672 
673 float
get_float_component(unsigned i) const674 ir_constant::get_float_component(unsigned i) const
675 {
676    switch (this->type->base_type) {
677    case GLSL_TYPE_UINT:  return (float) this->value.u[i];
678    case GLSL_TYPE_INT:   return (float) this->value.i[i];
679    case GLSL_TYPE_FLOAT: return this->value.f[i];
680    case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
681    default:              assert(!"Should not get here."); break;
682    }
683 
684    /* Must return something to make the compiler happy.  This is clearly an
685     * error case.
686     */
687    return 0.0;
688 }
689 
690 int
get_int_component(unsigned i) const691 ir_constant::get_int_component(unsigned i) const
692 {
693    switch (this->type->base_type) {
694    case GLSL_TYPE_UINT:  return this->value.u[i];
695    case GLSL_TYPE_INT:   return this->value.i[i];
696    case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
697    case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
698    default:              assert(!"Should not get here."); break;
699    }
700 
701    /* Must return something to make the compiler happy.  This is clearly an
702     * error case.
703     */
704    return 0;
705 }
706 
707 unsigned
get_uint_component(unsigned i) const708 ir_constant::get_uint_component(unsigned i) const
709 {
710    switch (this->type->base_type) {
711    case GLSL_TYPE_UINT:  return this->value.u[i];
712    case GLSL_TYPE_INT:   return this->value.i[i];
713    case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
714    case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
715    default:              assert(!"Should not get here."); break;
716    }
717 
718    /* Must return something to make the compiler happy.  This is clearly an
719     * error case.
720     */
721    return 0;
722 }
723 
724 ir_constant *
get_array_element(unsigned i) const725 ir_constant::get_array_element(unsigned i) const
726 {
727    assert(this->type->is_array());
728 
729    /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
730     *
731     *     "Behavior is undefined if a shader subscripts an array with an index
732     *     less than 0 or greater than or equal to the size the array was
733     *     declared with."
734     *
735     * Most out-of-bounds accesses are removed before things could get this far.
736     * There are cases where non-constant array index values can get constant
737     * folded.
738     */
739    if (int(i) < 0)
740       i = 0;
741    else if (i >= this->type->length)
742       i = this->type->length - 1;
743 
744    return array_elements[i];
745 }
746 
747 ir_constant *
get_record_field(const char * name)748 ir_constant::get_record_field(const char *name)
749 {
750    int idx = this->type->field_index(name);
751 
752    if (idx < 0)
753       return NULL;
754 
755    if (this->components.is_empty())
756       return NULL;
757 
758    exec_node *node = this->components.head;
759    for (int i = 0; i < idx; i++) {
760       node = node->next;
761 
762       /* If the end of the list is encountered before the element matching the
763        * requested field is found, return NULL.
764        */
765       if (node->is_tail_sentinel())
766 	 return NULL;
767    }
768 
769    return (ir_constant *) node;
770 }
771 
772 
773 bool
has_value(const ir_constant * c) const774 ir_constant::has_value(const ir_constant *c) const
775 {
776    if (this->type != c->type)
777       return false;
778 
779    if (this->type->is_array()) {
780       for (unsigned i = 0; i < this->type->length; i++) {
781 	 if (!this->array_elements[i]->has_value(c->array_elements[i]))
782 	    return false;
783       }
784       return true;
785    }
786 
787    if (this->type->base_type == GLSL_TYPE_STRUCT) {
788       const exec_node *a_node = this->components.head;
789       const exec_node *b_node = c->components.head;
790 
791       while (!a_node->is_tail_sentinel()) {
792 	 assert(!b_node->is_tail_sentinel());
793 
794 	 const ir_constant *const a_field = (ir_constant *) a_node;
795 	 const ir_constant *const b_field = (ir_constant *) b_node;
796 
797 	 if (!a_field->has_value(b_field))
798 	    return false;
799 
800 	 a_node = a_node->next;
801 	 b_node = b_node->next;
802       }
803 
804       return true;
805    }
806 
807    for (unsigned i = 0; i < this->type->components(); i++) {
808       switch (this->type->base_type) {
809       case GLSL_TYPE_UINT:
810 	 if (this->value.u[i] != c->value.u[i])
811 	    return false;
812 	 break;
813       case GLSL_TYPE_INT:
814 	 if (this->value.i[i] != c->value.i[i])
815 	    return false;
816 	 break;
817       case GLSL_TYPE_FLOAT:
818 	 if (this->value.f[i] != c->value.f[i])
819 	    return false;
820 	 break;
821       case GLSL_TYPE_BOOL:
822 	 if (this->value.b[i] != c->value.b[i])
823 	    return false;
824 	 break;
825       default:
826 	 assert(!"Should not get here.");
827 	 return false;
828       }
829    }
830 
831    return true;
832 }
833 
834 bool
is_zero() const835 ir_constant::is_zero() const
836 {
837    if (!this->type->is_scalar() && !this->type->is_vector())
838       return false;
839 
840    for (unsigned c = 0; c < this->type->vector_elements; c++) {
841       switch (this->type->base_type) {
842       case GLSL_TYPE_FLOAT:
843 	 if (this->value.f[c] != 0.0)
844 	    return false;
845 	 break;
846       case GLSL_TYPE_INT:
847 	 if (this->value.i[c] != 0)
848 	    return false;
849 	 break;
850       case GLSL_TYPE_UINT:
851 	 if (this->value.u[c] != 0)
852 	    return false;
853 	 break;
854       case GLSL_TYPE_BOOL:
855 	 if (this->value.b[c] != false)
856 	    return false;
857 	 break;
858       default:
859 	 /* The only other base types are structures, arrays, and samplers.
860 	  * Samplers cannot be constants, and the others should have been
861 	  * filtered out above.
862 	  */
863 	 assert(!"Should not get here.");
864 	 return false;
865       }
866    }
867 
868    return true;
869 }
870 
871 bool
is_one() const872 ir_constant::is_one() const
873 {
874    if (!this->type->is_scalar() && !this->type->is_vector())
875       return false;
876 
877    for (unsigned c = 0; c < this->type->vector_elements; c++) {
878       switch (this->type->base_type) {
879       case GLSL_TYPE_FLOAT:
880 	 if (this->value.f[c] != 1.0)
881 	    return false;
882 	 break;
883       case GLSL_TYPE_INT:
884 	 if (this->value.i[c] != 1)
885 	    return false;
886 	 break;
887       case GLSL_TYPE_UINT:
888 	 if (this->value.u[c] != 1)
889 	    return false;
890 	 break;
891       case GLSL_TYPE_BOOL:
892 	 if (this->value.b[c] != true)
893 	    return false;
894 	 break;
895       default:
896 	 /* The only other base types are structures, arrays, and samplers.
897 	  * Samplers cannot be constants, and the others should have been
898 	  * filtered out above.
899 	  */
900 	 assert(!"Should not get here.");
901 	 return false;
902       }
903    }
904 
905    return true;
906 }
907 
908 bool
is_negative_one() const909 ir_constant::is_negative_one() const
910 {
911    if (!this->type->is_scalar() && !this->type->is_vector())
912       return false;
913 
914    if (this->type->is_boolean())
915       return false;
916 
917    for (unsigned c = 0; c < this->type->vector_elements; c++) {
918       switch (this->type->base_type) {
919       case GLSL_TYPE_FLOAT:
920 	 if (this->value.f[c] != -1.0)
921 	    return false;
922 	 break;
923       case GLSL_TYPE_INT:
924 	 if (this->value.i[c] != -1)
925 	    return false;
926 	 break;
927       case GLSL_TYPE_UINT:
928 	 if (int(this->value.u[c]) != -1)
929 	    return false;
930 	 break;
931       default:
932 	 /* The only other base types are structures, arrays, samplers, and
933 	  * booleans.  Samplers cannot be constants, and the others should
934 	  * have been filtered out above.
935 	  */
936 	 assert(!"Should not get here.");
937 	 return false;
938       }
939    }
940 
941    return true;
942 }
943 
ir_loop()944 ir_loop::ir_loop()
945 {
946    this->ir_type = ir_type_loop;
947    this->cmp = ir_unop_neg;
948    this->from = NULL;
949    this->to = NULL;
950    this->increment = NULL;
951    this->counter = NULL;
952 }
953 
954 
ir_dereference_variable(ir_variable * var)955 ir_dereference_variable::ir_dereference_variable(ir_variable *var)
956 {
957    this->ir_type = ir_type_dereference_variable;
958    this->var = var;
959    this->type = (var != NULL) ? var->type : glsl_type::error_type;
960 }
961 
962 
ir_dereference_array(ir_rvalue * value,ir_rvalue * array_index)963 ir_dereference_array::ir_dereference_array(ir_rvalue *value,
964 					   ir_rvalue *array_index)
965 {
966    this->ir_type = ir_type_dereference_array;
967    this->array_index = array_index;
968    this->set_array(value);
969 }
970 
971 
ir_dereference_array(ir_variable * var,ir_rvalue * array_index)972 ir_dereference_array::ir_dereference_array(ir_variable *var,
973 					   ir_rvalue *array_index)
974 {
975    void *ctx = hieralloc_parent(var);
976 
977    this->ir_type = ir_type_dereference_array;
978    this->array_index = array_index;
979    this->set_array(new(ctx) ir_dereference_variable(var));
980 }
981 
982 
983 void
set_array(ir_rvalue * value)984 ir_dereference_array::set_array(ir_rvalue *value)
985 {
986    this->array = value;
987    this->type = glsl_type::error_type;
988 
989    if (this->array != NULL) {
990       const glsl_type *const vt = this->array->type;
991 
992       if (vt->is_array()) {
993 	 type = vt->element_type();
994       } else if (vt->is_matrix()) {
995 	 type = vt->column_type();
996       } else if (vt->is_vector()) {
997 	 type = vt->get_base_type();
998       }
999    }
1000 }
1001 
1002 
ir_dereference_record(ir_rvalue * value,const char * field)1003 ir_dereference_record::ir_dereference_record(ir_rvalue *value,
1004 					     const char *field)
1005 {
1006    this->ir_type = ir_type_dereference_record;
1007    this->record = value;
1008    this->field = hieralloc_strdup(this, field);
1009    this->type = (this->record != NULL)
1010       ? this->record->type->field_type(field) : glsl_type::error_type;
1011 }
1012 
1013 
ir_dereference_record(ir_variable * var,const char * field)1014 ir_dereference_record::ir_dereference_record(ir_variable *var,
1015 					     const char *field)
1016 {
1017    void *ctx = hieralloc_parent(var);
1018 
1019    this->ir_type = ir_type_dereference_record;
1020    this->record = new(ctx) ir_dereference_variable(var);
1021    this->field = hieralloc_strdup(this, field);
1022    this->type = (this->record != NULL)
1023       ? this->record->type->field_type(field) : glsl_type::error_type;
1024 }
1025 
type_contains_sampler(const glsl_type * type)1026 bool type_contains_sampler(const glsl_type *type)
1027 {
1028    if (type->is_array()) {
1029       return type_contains_sampler(type->fields.array);
1030    } else if (type->is_record()) {
1031       for (unsigned int i = 0; i < type->length; i++) {
1032 	 if (type_contains_sampler(type->fields.structure[i].type))
1033 	    return true;
1034       }
1035       return false;
1036    } else {
1037       return type->is_sampler();
1038    }
1039 }
1040 
1041 bool
is_lvalue()1042 ir_dereference::is_lvalue()
1043 {
1044    ir_variable *var = this->variable_referenced();
1045 
1046    /* Every l-value derference chain eventually ends in a variable.
1047     */
1048    if ((var == NULL) || var->read_only)
1049       return false;
1050 
1051    if (this->type->is_array() && !var->array_lvalue)
1052       return false;
1053 
1054    /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
1055     *
1056     *    "Samplers cannot be treated as l-values; hence cannot be used
1057     *     as out or inout function parameters, nor can they be
1058     *     assigned into."
1059     */
1060    if (type_contains_sampler(this->type))
1061       return false;
1062 
1063    return true;
1064 }
1065 
1066 
1067 const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
1068 
opcode_string()1069 const char *ir_texture::opcode_string()
1070 {
1071    assert((unsigned int) op <=
1072 	  sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]));
1073    return tex_opcode_strs[op];
1074 }
1075 
1076 ir_texture_opcode
get_opcode(const char * str)1077 ir_texture::get_opcode(const char *str)
1078 {
1079    const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
1080    for (int op = 0; op < count; op++) {
1081       if (strcmp(str, tex_opcode_strs[op]) == 0)
1082 	 return (ir_texture_opcode) op;
1083    }
1084    return (ir_texture_opcode) -1;
1085 }
1086 
1087 
1088 void
set_sampler(ir_dereference * sampler)1089 ir_texture::set_sampler(ir_dereference *sampler)
1090 {
1091    assert(sampler != NULL);
1092    this->sampler = sampler;
1093 
1094    switch (sampler->type->sampler_type) {
1095    case GLSL_TYPE_FLOAT:
1096       this->type = glsl_type::vec4_type;
1097       break;
1098    case GLSL_TYPE_INT:
1099       this->type = glsl_type::ivec4_type;
1100       break;
1101    case GLSL_TYPE_UINT:
1102       this->type = glsl_type::uvec4_type;
1103       break;
1104    }
1105 }
1106 
1107 
1108 void
init_mask(const unsigned * comp,unsigned count)1109 ir_swizzle::init_mask(const unsigned *comp, unsigned count)
1110 {
1111    assert((count >= 1) && (count <= 4));
1112 
1113    memset(&this->mask, 0, sizeof(this->mask));
1114    this->mask.num_components = count;
1115 
1116    unsigned dup_mask = 0;
1117    switch (count) {
1118    case 4:
1119       assert(comp[3] <= 3);
1120       dup_mask |= (1U << comp[3])
1121 	 & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
1122       this->mask.w = comp[3];
1123 
1124    case 3:
1125       assert(comp[2] <= 3);
1126       dup_mask |= (1U << comp[2])
1127 	 & ((1U << comp[0]) | (1U << comp[1]));
1128       this->mask.z = comp[2];
1129 
1130    case 2:
1131       assert(comp[1] <= 3);
1132       dup_mask |= (1U << comp[1])
1133 	 & ((1U << comp[0]));
1134       this->mask.y = comp[1];
1135 
1136    case 1:
1137       assert(comp[0] <= 3);
1138       this->mask.x = comp[0];
1139    }
1140 
1141    this->mask.has_duplicates = dup_mask != 0;
1142 
1143    /* Based on the number of elements in the swizzle and the base type
1144     * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
1145     * generate the type of the resulting value.
1146     */
1147    type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
1148 }
1149 
ir_swizzle(ir_rvalue * val,unsigned x,unsigned y,unsigned z,unsigned w,unsigned count)1150 ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
1151 		       unsigned w, unsigned count)
1152    : val(val)
1153 {
1154    const unsigned components[4] = { x, y, z, w };
1155    this->ir_type = ir_type_swizzle;
1156    this->init_mask(components, count);
1157 }
1158 
ir_swizzle(ir_rvalue * val,const unsigned * comp,unsigned count)1159 ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
1160 		       unsigned count)
1161    : val(val)
1162 {
1163    this->ir_type = ir_type_swizzle;
1164    this->init_mask(comp, count);
1165 }
1166 
ir_swizzle(ir_rvalue * val,ir_swizzle_mask mask)1167 ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
1168 {
1169    this->ir_type = ir_type_swizzle;
1170    this->val = val;
1171    this->mask = mask;
1172    this->type = glsl_type::get_instance(val->type->base_type,
1173 					mask.num_components, 1);
1174 }
1175 
1176 #define X 1
1177 #define R 5
1178 #define S 9
1179 #define I 13
1180 
1181 ir_swizzle *
create(ir_rvalue * val,const char * str,unsigned vector_length)1182 ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
1183 {
1184    void *ctx = hieralloc_parent(val);
1185 
1186    /* For each possible swizzle character, this table encodes the value in
1187     * \c idx_map that represents the 0th element of the vector.  For invalid
1188     * swizzle characters (e.g., 'k'), a special value is used that will allow
1189     * detection of errors.
1190     */
1191    static const unsigned char base_idx[26] = {
1192    /* a  b  c  d  e  f  g  h  i  j  k  l  m */
1193       R, R, I, I, I, I, R, I, I, I, I, I, I,
1194    /* n  o  p  q  r  s  t  u  v  w  x  y  z */
1195       I, I, S, S, R, S, S, I, I, X, X, X, X
1196    };
1197 
1198    /* Each valid swizzle character has an entry in the previous table.  This
1199     * table encodes the base index encoded in the previous table plus the actual
1200     * index of the swizzle character.  When processing swizzles, the first
1201     * character in the string is indexed in the previous table.  Each character
1202     * in the string is indexed in this table, and the value found there has the
1203     * value form the first table subtracted.  The result must be on the range
1204     * [0,3].
1205     *
1206     * For example, the string "wzyx" will get X from the first table.  Each of
1207     * the charcaters will get X+3, X+2, X+1, and X+0 from this table.  After
1208     * subtraction, the swizzle values are { 3, 2, 1, 0 }.
1209     *
1210     * The string "wzrg" will get X from the first table.  Each of the characters
1211     * will get X+3, X+2, R+0, and R+1 from this table.  After subtraction, the
1212     * swizzle values are { 3, 2, 4, 5 }.  Since 4 and 5 are outside the range
1213     * [0,3], the error is detected.
1214     */
1215    static const unsigned char idx_map[26] = {
1216    /* a    b    c    d    e    f    g    h    i    j    k    l    m */
1217       R+3, R+2, 0,   0,   0,   0,   R+1, 0,   0,   0,   0,   0,   0,
1218    /* n    o    p    q    r    s    t    u    v    w    x    y    z */
1219       0,   0,   S+2, S+3, R+0, S+0, S+1, 0,   0,   X+3, X+0, X+1, X+2
1220    };
1221 
1222    int swiz_idx[4] = { 0, 0, 0, 0 };
1223    unsigned i;
1224 
1225 
1226    /* Validate the first character in the swizzle string and look up the base
1227     * index value as described above.
1228     */
1229    if ((str[0] < 'a') || (str[0] > 'z'))
1230       return NULL;
1231 
1232    const unsigned base = base_idx[str[0] - 'a'];
1233 
1234 
1235    for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
1236       /* Validate the next character, and, as described above, convert it to a
1237        * swizzle index.
1238        */
1239       if ((str[i] < 'a') || (str[i] > 'z'))
1240 	 return NULL;
1241 
1242       swiz_idx[i] = idx_map[str[i] - 'a'] - base;
1243       if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
1244 	 return NULL;
1245    }
1246 
1247    if (str[i] != '\0')
1248 	 return NULL;
1249 
1250    return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
1251 			      swiz_idx[3], i);
1252 }
1253 
1254 #undef X
1255 #undef R
1256 #undef S
1257 #undef I
1258 
1259 ir_variable *
variable_referenced()1260 ir_swizzle::variable_referenced()
1261 {
1262    return this->val->variable_referenced();
1263 }
1264 
1265 
ir_variable(const struct glsl_type * type,const char * name,ir_variable_mode mode)1266 ir_variable::ir_variable(const struct glsl_type *type, const char *name,
1267 			 ir_variable_mode mode)
1268    : max_array_access(0), read_only(false), centroid(false), invariant(false),
1269      mode(mode), interpolation(ir_var_smooth), array_lvalue(false)
1270 {
1271    this->ir_type = ir_type_variable;
1272    this->type = type;
1273    this->name = hieralloc_strdup(this, name);
1274    this->explicit_location = false;
1275    this->location = -1;
1276    this->warn_extension = NULL;
1277    this->constant_value = NULL;
1278    this->origin_upper_left = false;
1279    this->pixel_center_integer = false;
1280 
1281    if (type && type->base_type == GLSL_TYPE_SAMPLER)
1282       this->read_only = true;
1283 }
1284 
1285 
1286 const char *
interpolation_string() const1287 ir_variable::interpolation_string() const
1288 {
1289    switch (this->interpolation) {
1290    case ir_var_smooth:        return "smooth";
1291    case ir_var_flat:          return "flat";
1292    case ir_var_noperspective: return "noperspective";
1293    }
1294 
1295    assert(!"Should not get here.");
1296    return "";
1297 }
1298 
1299 
1300 unsigned
component_slots() const1301 ir_variable::component_slots() const
1302 {
1303    /* FINISHME: Sparsely accessed arrays require fewer slots. */
1304    return this->type->component_slots();
1305 }
1306 
1307 
ir_function_signature(const glsl_type * return_type)1308 ir_function_signature::ir_function_signature(const glsl_type *return_type)
1309    : return_type(return_type), is_defined(false), _function(NULL)
1310 {
1311    this->ir_type = ir_type_function_signature;
1312    this->is_builtin = false;
1313 }
1314 
1315 
1316 const char *
qualifiers_match(exec_list * params)1317 ir_function_signature::qualifiers_match(exec_list *params)
1318 {
1319    exec_list_iterator iter_a = parameters.iterator();
1320    exec_list_iterator iter_b = params->iterator();
1321 
1322    /* check that the qualifiers match. */
1323    while (iter_a.has_next()) {
1324       ir_variable *a = (ir_variable *)iter_a.get();
1325       ir_variable *b = (ir_variable *)iter_b.get();
1326 
1327       if (a->read_only != b->read_only ||
1328 	  a->mode != b->mode ||
1329 	  a->interpolation != b->interpolation ||
1330 	  a->centroid != b->centroid) {
1331 
1332 	 /* parameter a's qualifiers don't match */
1333 	 return a->name;
1334       }
1335 
1336       iter_a.next();
1337       iter_b.next();
1338    }
1339    return NULL;
1340 }
1341 
1342 
1343 void
replace_parameters(exec_list * new_params)1344 ir_function_signature::replace_parameters(exec_list *new_params)
1345 {
1346    /* Destroy all of the previous parameter information.  If the previous
1347     * parameter information comes from the function prototype, it may either
1348     * specify incorrect parameter names or not have names at all.
1349     */
1350    foreach_iter(exec_list_iterator, iter, parameters) {
1351       assert(((ir_instruction *) iter.get())->as_variable() != NULL);
1352 
1353       iter.remove();
1354    }
1355 
1356    new_params->move_nodes_to(&parameters);
1357 }
1358 
1359 
ir_function(const char * name)1360 ir_function::ir_function(const char *name)
1361 {
1362    this->ir_type = ir_type_function;
1363    this->name = hieralloc_strdup(this, name);
1364 }
1365 
1366 
1367 bool
has_user_signature()1368 ir_function::has_user_signature()
1369 {
1370    foreach_list(n, &this->signatures) {
1371       ir_function_signature *const sig = (ir_function_signature *) n;
1372       if (!sig->is_builtin)
1373 	 return true;
1374    }
1375    return false;
1376 }
1377 
1378 
1379 ir_call *
get_error_instruction(void * ctx)1380 ir_call::get_error_instruction(void *ctx)
1381 {
1382    ir_call *call = new(ctx) ir_call;
1383 
1384    call->type = glsl_type::error_type;
1385    return call;
1386 }
1387 
1388 void
set_callee(ir_function_signature * sig)1389 ir_call::set_callee(ir_function_signature *sig)
1390 {
1391    assert((this->type == NULL) || (this->type == sig->return_type));
1392 
1393    this->callee = sig;
1394 }
1395 
1396 void
visit_exec_list(exec_list * list,ir_visitor * visitor)1397 visit_exec_list(exec_list *list, ir_visitor *visitor)
1398 {
1399    foreach_iter(exec_list_iterator, iter, *list) {
1400       ((ir_instruction *)iter.get())->accept(visitor);
1401    }
1402 }
1403 
1404 
1405 static void
steal_memory(ir_instruction * ir,void * new_ctx)1406 steal_memory(ir_instruction *ir, void *new_ctx)
1407 {
1408    ir_variable *var = ir->as_variable();
1409    ir_constant *constant = ir->as_constant();
1410    if (var != NULL && var->constant_value != NULL)
1411       steal_memory(var->constant_value, ir);
1412 
1413    /* The components of aggregate constants are not visited by the normal
1414     * visitor, so steal their values by hand.
1415     */
1416    if (constant != NULL) {
1417       if (constant->type->is_record()) {
1418 	 foreach_iter(exec_list_iterator, iter, constant->components) {
1419 	    ir_constant *field = (ir_constant *)iter.get();
1420 	    steal_memory(field, ir);
1421 	 }
1422       } else if (constant->type->is_array()) {
1423 	 for (unsigned int i = 0; i < constant->type->length; i++) {
1424 	    steal_memory(constant->array_elements[i], ir);
1425 	 }
1426       }
1427    }
1428 
1429    hieralloc_steal(new_ctx, ir);
1430 }
1431 
1432 
1433 void
reparent_ir(exec_list * list,void * mem_ctx)1434 reparent_ir(exec_list *list, void *mem_ctx)
1435 {
1436    foreach_list(node, list) {
1437       visit_tree((ir_instruction *) node, steal_memory, mem_ctx);
1438    }
1439 }
1440 
1441 
1442 static ir_rvalue *
try_min_one(ir_rvalue * ir)1443 try_min_one(ir_rvalue *ir)
1444 {
1445    ir_expression *expr = ir->as_expression();
1446 
1447    if (!expr || expr->operation != ir_binop_min)
1448       return NULL;
1449 
1450    if (expr->operands[0]->is_one())
1451       return expr->operands[1];
1452 
1453    if (expr->operands[1]->is_one())
1454       return expr->operands[0];
1455 
1456    return NULL;
1457 }
1458 
1459 static ir_rvalue *
try_max_zero(ir_rvalue * ir)1460 try_max_zero(ir_rvalue *ir)
1461 {
1462    ir_expression *expr = ir->as_expression();
1463 
1464    if (!expr || expr->operation != ir_binop_max)
1465       return NULL;
1466 
1467    if (expr->operands[0]->is_zero())
1468       return expr->operands[1];
1469 
1470    if (expr->operands[1]->is_zero())
1471       return expr->operands[0];
1472 
1473    return NULL;
1474 }
1475 
1476 ir_rvalue *
as_rvalue_to_saturate()1477 ir_rvalue::as_rvalue_to_saturate()
1478 {
1479    ir_expression *expr = this->as_expression();
1480 
1481    if (!expr)
1482       return NULL;
1483 
1484    ir_rvalue *max_zero = try_max_zero(expr);
1485    if (max_zero) {
1486       return try_min_one(max_zero);
1487    } else {
1488       ir_rvalue *min_one = try_min_one(expr);
1489       if (min_one) {
1490 	 return try_max_zero(min_one);
1491       }
1492    }
1493 
1494    return NULL;
1495 }
1496