11591693c7b415e9869157c711fe11263c95d74eDavid Li/*
21591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation
31591693c7b415e9869157c711fe11263c95d74eDavid Li *
41591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a
51591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"),
61591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation
71591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the
91591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions:
101591693c7b415e9869157c711fe11263c95d74eDavid Li *
111591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next
121591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the
131591693c7b415e9869157c711fe11263c95d74eDavid Li * Software.
141591693c7b415e9869157c711fe11263c95d74eDavid Li *
151591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE.
221591693c7b415e9869157c711fe11263c95d74eDavid Li */
231591693c7b415e9869157c711fe11263c95d74eDavid Li
241591693c7b415e9869157c711fe11263c95d74eDavid Li/**
251591693c7b415e9869157c711fe11263c95d74eDavid Li * \file ir_validate.cpp
261591693c7b415e9869157c711fe11263c95d74eDavid Li *
271591693c7b415e9869157c711fe11263c95d74eDavid Li * Attempts to verify that various invariants of the IR tree are true.
281591693c7b415e9869157c711fe11263c95d74eDavid Li *
291591693c7b415e9869157c711fe11263c95d74eDavid Li * In particular, at the moment it makes sure that no single
301591693c7b415e9869157c711fe11263c95d74eDavid Li * ir_instruction node except for ir_variable appears multiple times
311591693c7b415e9869157c711fe11263c95d74eDavid Li * in the ir tree.  ir_variable does appear multiple times: Once as a
321591693c7b415e9869157c711fe11263c95d74eDavid Li * declaration in an exec_list, and multiple times as the endpoint of
331591693c7b415e9869157c711fe11263c95d74eDavid Li * a dereference chain.
341591693c7b415e9869157c711fe11263c95d74eDavid Li */
351591693c7b415e9869157c711fe11263c95d74eDavid Li
361591693c7b415e9869157c711fe11263c95d74eDavid Li#include <inttypes.h>
371591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h"
381591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_hierarchical_visitor.h"
391591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program/hash_table.h"
401591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_types.h"
411591693c7b415e9869157c711fe11263c95d74eDavid Li
421591693c7b415e9869157c711fe11263c95d74eDavid Liclass ir_validate : public ir_hierarchical_visitor {
431591693c7b415e9869157c711fe11263c95d74eDavid Lipublic:
441591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_validate()
451591693c7b415e9869157c711fe11263c95d74eDavid Li   {
461591693c7b415e9869157c711fe11263c95d74eDavid Li      this->ht = hash_table_ctor(0, hash_table_pointer_hash,
471591693c7b415e9869157c711fe11263c95d74eDavid Li				 hash_table_pointer_compare);
481591693c7b415e9869157c711fe11263c95d74eDavid Li
491591693c7b415e9869157c711fe11263c95d74eDavid Li      this->current_function = NULL;
501591693c7b415e9869157c711fe11263c95d74eDavid Li
511591693c7b415e9869157c711fe11263c95d74eDavid Li      this->callback = ir_validate::validate_ir;
521591693c7b415e9869157c711fe11263c95d74eDavid Li      this->data = ht;
531591693c7b415e9869157c711fe11263c95d74eDavid Li   }
541591693c7b415e9869157c711fe11263c95d74eDavid Li
551591693c7b415e9869157c711fe11263c95d74eDavid Li   ~ir_validate()
561591693c7b415e9869157c711fe11263c95d74eDavid Li   {
571591693c7b415e9869157c711fe11263c95d74eDavid Li      hash_table_dtor(this->ht);
581591693c7b415e9869157c711fe11263c95d74eDavid Li   }
591591693c7b415e9869157c711fe11263c95d74eDavid Li
601591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit(ir_variable *v);
611591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit(ir_dereference_variable *ir);
621591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit(ir_if *ir);
631591693c7b415e9869157c711fe11263c95d74eDavid Li
641591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_leave(ir_loop *ir);
651591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_enter(ir_function *ir);
661591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_leave(ir_function *ir);
671591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_enter(ir_function_signature *ir);
681591693c7b415e9869157c711fe11263c95d74eDavid Li
691591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_leave(ir_expression *ir);
701591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_leave(ir_swizzle *ir);
711591693c7b415e9869157c711fe11263c95d74eDavid Li
721591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_enter(ir_assignment *ir);
731591693c7b415e9869157c711fe11263c95d74eDavid Li
741591693c7b415e9869157c711fe11263c95d74eDavid Li   static void validate_ir(ir_instruction *ir, void *data);
751591693c7b415e9869157c711fe11263c95d74eDavid Li
761591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_function *current_function;
771591693c7b415e9869157c711fe11263c95d74eDavid Li
781591693c7b415e9869157c711fe11263c95d74eDavid Li   struct hash_table *ht;
791591693c7b415e9869157c711fe11263c95d74eDavid Li};
801591693c7b415e9869157c711fe11263c95d74eDavid Li
811591693c7b415e9869157c711fe11263c95d74eDavid Li
821591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
831591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit(ir_dereference_variable *ir)
841591693c7b415e9869157c711fe11263c95d74eDavid Li{
851591693c7b415e9869157c711fe11263c95d74eDavid Li   if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) {
861591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("ir_dereference_variable @ %p does not specify a variable %p\n",
871591693c7b415e9869157c711fe11263c95d74eDavid Li	     (void *) ir, (void *) ir->var);
881591693c7b415e9869157c711fe11263c95d74eDavid Li      abort();
891591693c7b415e9869157c711fe11263c95d74eDavid Li   }
901591693c7b415e9869157c711fe11263c95d74eDavid Li
911591693c7b415e9869157c711fe11263c95d74eDavid Li   if (hash_table_find(ht, ir->var) == NULL) {
921591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("ir_dereference_variable @ %p specifies undeclared variable "
931591693c7b415e9869157c711fe11263c95d74eDavid Li	     "`%s' @ %p\n",
941591693c7b415e9869157c711fe11263c95d74eDavid Li	     (void *) ir, ir->var->name, (void *) ir->var);
951591693c7b415e9869157c711fe11263c95d74eDavid Li      abort();
961591693c7b415e9869157c711fe11263c95d74eDavid Li   }
971591693c7b415e9869157c711fe11263c95d74eDavid Li
981591693c7b415e9869157c711fe11263c95d74eDavid Li   this->validate_ir(ir, this->data);
991591693c7b415e9869157c711fe11263c95d74eDavid Li
1001591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
1011591693c7b415e9869157c711fe11263c95d74eDavid Li}
1021591693c7b415e9869157c711fe11263c95d74eDavid Li
1031591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
1041591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit(ir_if *ir)
1051591693c7b415e9869157c711fe11263c95d74eDavid Li{
1061591693c7b415e9869157c711fe11263c95d74eDavid Li   if (ir->condition->type != glsl_type::bool_type) {
1071591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("ir_if condition %s type instead of bool.\n",
1081591693c7b415e9869157c711fe11263c95d74eDavid Li	     ir->condition->type->name);
1091591693c7b415e9869157c711fe11263c95d74eDavid Li      ir->print();
1101591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("\n");
1111591693c7b415e9869157c711fe11263c95d74eDavid Li      abort();
1121591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1131591693c7b415e9869157c711fe11263c95d74eDavid Li
1141591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
1151591693c7b415e9869157c711fe11263c95d74eDavid Li}
1161591693c7b415e9869157c711fe11263c95d74eDavid Li
1171591693c7b415e9869157c711fe11263c95d74eDavid Li
1181591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
1191591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit_leave(ir_loop *ir)
1201591693c7b415e9869157c711fe11263c95d74eDavid Li{
1211591693c7b415e9869157c711fe11263c95d74eDavid Li   if (ir->counter != NULL) {
1221591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((ir->from == NULL) || (ir->from == NULL) || (ir->increment == NULL)) {
1231591693c7b415e9869157c711fe11263c95d74eDavid Li	 printf("ir_loop has invalid loop controls:\n"
1241591693c7b415e9869157c711fe11263c95d74eDavid Li		"    counter:   %p\n"
1251591693c7b415e9869157c711fe11263c95d74eDavid Li		"    from:      %p\n"
1261591693c7b415e9869157c711fe11263c95d74eDavid Li		"    to:        %p\n"
1271591693c7b415e9869157c711fe11263c95d74eDavid Li		"    increment: %p\n",
1281591693c7b415e9869157c711fe11263c95d74eDavid Li		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
1291591693c7b415e9869157c711fe11263c95d74eDavid Li                (void *) ir->increment);
1301591693c7b415e9869157c711fe11263c95d74eDavid Li	 abort();
1311591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1321591693c7b415e9869157c711fe11263c95d74eDavid Li
1331591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) {
1341591693c7b415e9869157c711fe11263c95d74eDavid Li	 printf("ir_loop has invalid comparitor %d\n", ir->cmp);
1351591693c7b415e9869157c711fe11263c95d74eDavid Li	 abort();
1361591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1371591693c7b415e9869157c711fe11263c95d74eDavid Li   } else {
1381591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((ir->from != NULL) || (ir->from != NULL) || (ir->increment != NULL)) {
1391591693c7b415e9869157c711fe11263c95d74eDavid Li	 printf("ir_loop has invalid loop controls:\n"
1401591693c7b415e9869157c711fe11263c95d74eDavid Li		"    counter:   %p\n"
1411591693c7b415e9869157c711fe11263c95d74eDavid Li		"    from:      %p\n"
1421591693c7b415e9869157c711fe11263c95d74eDavid Li		"    to:        %p\n"
1431591693c7b415e9869157c711fe11263c95d74eDavid Li		"    increment: %p\n",
1441591693c7b415e9869157c711fe11263c95d74eDavid Li		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
1451591693c7b415e9869157c711fe11263c95d74eDavid Li                (void *) ir->increment);
1461591693c7b415e9869157c711fe11263c95d74eDavid Li	 abort();
1471591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1481591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1491591693c7b415e9869157c711fe11263c95d74eDavid Li
1501591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
1511591693c7b415e9869157c711fe11263c95d74eDavid Li}
1521591693c7b415e9869157c711fe11263c95d74eDavid Li
1531591693c7b415e9869157c711fe11263c95d74eDavid Li
1541591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
1551591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit_enter(ir_function *ir)
1561591693c7b415e9869157c711fe11263c95d74eDavid Li{
1571591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Function definitions cannot be nested.
1581591693c7b415e9869157c711fe11263c95d74eDavid Li    */
1591591693c7b415e9869157c711fe11263c95d74eDavid Li   if (this->current_function != NULL) {
1601591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("Function definition nested inside another function "
1611591693c7b415e9869157c711fe11263c95d74eDavid Li	     "definition:\n");
1621591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("%s %p inside %s %p\n",
1631591693c7b415e9869157c711fe11263c95d74eDavid Li	     ir->name, (void *) ir,
1641591693c7b415e9869157c711fe11263c95d74eDavid Li	     this->current_function->name, (void *) this->current_function);
1651591693c7b415e9869157c711fe11263c95d74eDavid Li      abort();
1661591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1671591693c7b415e9869157c711fe11263c95d74eDavid Li
1681591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Store the current function hierarchy being traversed.  This is used
1691591693c7b415e9869157c711fe11263c95d74eDavid Li    * by the function signature visitor to ensure that the signatures are
1701591693c7b415e9869157c711fe11263c95d74eDavid Li    * linked with the correct functions.
1711591693c7b415e9869157c711fe11263c95d74eDavid Li    */
1721591693c7b415e9869157c711fe11263c95d74eDavid Li   this->current_function = ir;
1731591693c7b415e9869157c711fe11263c95d74eDavid Li
1741591693c7b415e9869157c711fe11263c95d74eDavid Li   this->validate_ir(ir, this->data);
1751591693c7b415e9869157c711fe11263c95d74eDavid Li
1761591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
1771591693c7b415e9869157c711fe11263c95d74eDavid Li}
1781591693c7b415e9869157c711fe11263c95d74eDavid Li
1791591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
1801591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit_leave(ir_function *ir)
1811591693c7b415e9869157c711fe11263c95d74eDavid Li{
182d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   assert(hieralloc_parent(ir->name) == ir);
1831591693c7b415e9869157c711fe11263c95d74eDavid Li
1841591693c7b415e9869157c711fe11263c95d74eDavid Li   this->current_function = NULL;
1851591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
1861591693c7b415e9869157c711fe11263c95d74eDavid Li}
1871591693c7b415e9869157c711fe11263c95d74eDavid Li
1881591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
1891591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit_enter(ir_function_signature *ir)
1901591693c7b415e9869157c711fe11263c95d74eDavid Li{
1911591693c7b415e9869157c711fe11263c95d74eDavid Li   if (this->current_function != ir->function()) {
1921591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("Function signature nested inside wrong function "
1931591693c7b415e9869157c711fe11263c95d74eDavid Li	     "definition:\n");
1941591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("%p inside %s %p instead of %s %p\n",
1951591693c7b415e9869157c711fe11263c95d74eDavid Li	     (void *) ir,
1961591693c7b415e9869157c711fe11263c95d74eDavid Li	     this->current_function->name, (void *) this->current_function,
1971591693c7b415e9869157c711fe11263c95d74eDavid Li	     ir->function_name(), (void *) ir->function());
1981591693c7b415e9869157c711fe11263c95d74eDavid Li      abort();
1991591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2001591693c7b415e9869157c711fe11263c95d74eDavid Li
2011591693c7b415e9869157c711fe11263c95d74eDavid Li   this->validate_ir(ir, this->data);
2021591693c7b415e9869157c711fe11263c95d74eDavid Li
2031591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
2041591693c7b415e9869157c711fe11263c95d74eDavid Li}
2051591693c7b415e9869157c711fe11263c95d74eDavid Li
2061591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
2071591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit_leave(ir_expression *ir)
2081591693c7b415e9869157c711fe11263c95d74eDavid Li{
2091591693c7b415e9869157c711fe11263c95d74eDavid Li   switch (ir->operation) {
2101591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_bit_not:
2111591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type == ir->type);
2121591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2131591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_logic_not:
2141591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_BOOL);
2151591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2161591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2171591693c7b415e9869157c711fe11263c95d74eDavid Li
2181591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_neg:
2191591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_abs:
2201591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sign:
2211591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_rcp:
2221591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_rsq:
2231591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sqrt:
2241591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type == ir->operands[0]->type);
2251591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2261591693c7b415e9869157c711fe11263c95d74eDavid Li
2271591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_exp:
2281591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_log:
2291591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_exp2:
2301591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_log2:
2311591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2321591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type == ir->operands[0]->type);
2331591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2341591693c7b415e9869157c711fe11263c95d74eDavid Li
2351591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_f2i:
2361591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2371591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_INT);
2381591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2391591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_i2f:
2401591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
2411591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2421591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2431591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_f2b:
2441591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2451591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_BOOL);
2461591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2471591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_b2f:
2481591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2491591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2501591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2511591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_i2b:
2521591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
2531591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_BOOL);
2541591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2551591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_b2i:
2561591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2571591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_INT);
2581591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2591591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_u2f:
2601591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
2611591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2621591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2631591693c7b415e9869157c711fe11263c95d74eDavid Li
2641591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_any:
2651591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2661591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type == glsl_type::bool_type);
2671591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2681591693c7b415e9869157c711fe11263c95d74eDavid Li
2691591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_trunc:
2701591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_round_even:
2711591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_ceil:
2721591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_floor:
2731591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_fract:
2741591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sin:
2751591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_cos:
2761591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_sin_reduced:
2771591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_cos_reduced:
2781591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_dFdx:
2791591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_dFdy:
2801591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2811591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type == ir->type);
2821591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2831591693c7b415e9869157c711fe11263c95d74eDavid Li
2841591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_unop_noise:
2851591693c7b415e9869157c711fe11263c95d74eDavid Li      /* XXX what can we assert here? */
2861591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
2871591693c7b415e9869157c711fe11263c95d74eDavid Li
2881591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_add:
2891591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_sub:
2901591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_mul:
2911591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_div:
2921591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_mod:
2931591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_min:
2941591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_max:
2951591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_pow:
2961591693c7b415e9869157c711fe11263c95d74eDavid Li      if (ir->operands[0]->type->is_scalar())
2971591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[1]->type == ir->type);
2981591693c7b415e9869157c711fe11263c95d74eDavid Li      else if (ir->operands[1]->type->is_scalar())
2991591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type == ir->type);
3001591693c7b415e9869157c711fe11263c95d74eDavid Li      else if (ir->operands[0]->type->is_vector() &&
3011591693c7b415e9869157c711fe11263c95d74eDavid Li	       ir->operands[1]->type->is_vector()) {
3021591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type == ir->operands[1]->type);
3031591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type == ir->type);
3041591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3051591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3061591693c7b415e9869157c711fe11263c95d74eDavid Li
3071591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_less:
3081591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_greater:
3091591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_lequal:
3101591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_gequal:
3111591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_equal:
3121591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_nequal:
3131591693c7b415e9869157c711fe11263c95d74eDavid Li      /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
3141591693c7b415e9869157c711fe11263c95d74eDavid Li       * ==, and != operators.  The IR operators perform a component-wise
3151591693c7b415e9869157c711fe11263c95d74eDavid Li       * comparison on scalar or vector types and return a boolean scalar or
3161591693c7b415e9869157c711fe11263c95d74eDavid Li       * vector type of the same size.
3171591693c7b415e9869157c711fe11263c95d74eDavid Li       */
3181591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->base_type == GLSL_TYPE_BOOL);
3191591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type == ir->operands[1]->type);
3201591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->is_vector()
3211591693c7b415e9869157c711fe11263c95d74eDavid Li	     || ir->operands[0]->type->is_scalar());
3221591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->vector_elements
3231591693c7b415e9869157c711fe11263c95d74eDavid Li	     == ir->type->vector_elements);
3241591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3251591693c7b415e9869157c711fe11263c95d74eDavid Li
3261591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_all_equal:
3271591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_any_nequal:
3281591693c7b415e9869157c711fe11263c95d74eDavid Li      /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
3291591693c7b415e9869157c711fe11263c95d74eDavid Li       * return a scalar boolean.  The IR matches that.
3301591693c7b415e9869157c711fe11263c95d74eDavid Li       */
3311591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type == glsl_type::bool_type);
3321591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type == ir->operands[1]->type);
3331591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3341591693c7b415e9869157c711fe11263c95d74eDavid Li
3351591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_lshift:
3361591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_rshift:
3371591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->is_integer() &&
3381591693c7b415e9869157c711fe11263c95d74eDavid Li             ir->operands[1]->type->is_integer());
3391591693c7b415e9869157c711fe11263c95d74eDavid Li      if (ir->operands[0]->type->is_scalar()) {
3401591693c7b415e9869157c711fe11263c95d74eDavid Li          assert(ir->operands[1]->type->is_scalar());
3411591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3421591693c7b415e9869157c711fe11263c95d74eDavid Li      if (ir->operands[0]->type->is_vector() &&
3431591693c7b415e9869157c711fe11263c95d74eDavid Li          ir->operands[1]->type->is_vector()) {
3441591693c7b415e9869157c711fe11263c95d74eDavid Li          assert(ir->operands[0]->type->components() ==
3451591693c7b415e9869157c711fe11263c95d74eDavid Li                 ir->operands[1]->type->components());
3461591693c7b415e9869157c711fe11263c95d74eDavid Li      }
3471591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type == ir->operands[0]->type);
3481591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3491591693c7b415e9869157c711fe11263c95d74eDavid Li
3501591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_bit_and:
3511591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_bit_xor:
3521591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_bit_or:
3531591693c7b415e9869157c711fe11263c95d74eDavid Li       assert(ir->operands[0]->type->base_type ==
3541591693c7b415e9869157c711fe11263c95d74eDavid Li              ir->operands[1]->type->base_type);
3551591693c7b415e9869157c711fe11263c95d74eDavid Li       assert(ir->type->is_integer());
3561591693c7b415e9869157c711fe11263c95d74eDavid Li       if (ir->operands[0]->type->is_vector() &&
3571591693c7b415e9869157c711fe11263c95d74eDavid Li           ir->operands[1]->type->is_vector()) {
3581591693c7b415e9869157c711fe11263c95d74eDavid Li           assert(ir->operands[0]->type->vector_elements ==
3591591693c7b415e9869157c711fe11263c95d74eDavid Li                  ir->operands[1]->type->vector_elements);
3601591693c7b415e9869157c711fe11263c95d74eDavid Li       }
3611591693c7b415e9869157c711fe11263c95d74eDavid Li       break;
3621591693c7b415e9869157c711fe11263c95d74eDavid Li
3631591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_logic_and:
3641591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_logic_xor:
3651591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_logic_or:
3661591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type == glsl_type::bool_type);
3671591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type == glsl_type::bool_type);
3681591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[1]->type == glsl_type::bool_type);
3691591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3701591693c7b415e9869157c711fe11263c95d74eDavid Li
3711591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_binop_dot:
3721591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type == glsl_type::float_type);
3731591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
3741591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type->is_vector());
3751591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->operands[0]->type == ir->operands[1]->type);
3761591693c7b415e9869157c711fe11263c95d74eDavid Li      break;
3771591693c7b415e9869157c711fe11263c95d74eDavid Li
3781591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_quadop_vector:
3791591693c7b415e9869157c711fe11263c95d74eDavid Li      /* The vector operator collects some number of scalars and generates a
3801591693c7b415e9869157c711fe11263c95d74eDavid Li       * vector from them.
3811591693c7b415e9869157c711fe11263c95d74eDavid Li       *
3821591693c7b415e9869157c711fe11263c95d74eDavid Li       *  - All of the operands must be scalar.
3831591693c7b415e9869157c711fe11263c95d74eDavid Li       *  - Number of operands must matche the size of the resulting vector.
3841591693c7b415e9869157c711fe11263c95d74eDavid Li       *  - Base type of the operands must match the base type of the result.
3851591693c7b415e9869157c711fe11263c95d74eDavid Li       */
3861591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(ir->type->is_vector());
3871591693c7b415e9869157c711fe11263c95d74eDavid Li      switch (ir->type->vector_elements) {
3881591693c7b415e9869157c711fe11263c95d74eDavid Li      case 2:
3891591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type->is_scalar());
3901591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
3911591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[1]->type->is_scalar());
3921591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
3931591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[2] == NULL);
3941591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[3] == NULL);
3951591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
3961591693c7b415e9869157c711fe11263c95d74eDavid Li      case 3:
3971591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type->is_scalar());
3981591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
3991591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[1]->type->is_scalar());
4001591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
4011591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[2]->type->is_scalar());
4021591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
4031591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[3] == NULL);
4041591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
4051591693c7b415e9869157c711fe11263c95d74eDavid Li      case 4:
4061591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type->is_scalar());
4071591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
4081591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[1]->type->is_scalar());
4091591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
4101591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[2]->type->is_scalar());
4111591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
4121591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[3]->type->is_scalar());
4131591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(ir->operands[3]->type->base_type == ir->type->base_type);
4141591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
4151591693c7b415e9869157c711fe11263c95d74eDavid Li      default:
4161591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* The is_vector assertion above should prevent execution from ever
4171591693c7b415e9869157c711fe11263c95d74eDavid Li	  * getting here.
4181591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
4191591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(!"Should not get here.");
4201591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
4211591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4221591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4231591693c7b415e9869157c711fe11263c95d74eDavid Li
4241591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
4251591693c7b415e9869157c711fe11263c95d74eDavid Li}
4261591693c7b415e9869157c711fe11263c95d74eDavid Li
4271591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
4281591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit_leave(ir_swizzle *ir)
4291591693c7b415e9869157c711fe11263c95d74eDavid Li{
4301591693c7b415e9869157c711fe11263c95d74eDavid Li   int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w};
4311591693c7b415e9869157c711fe11263c95d74eDavid Li
4321591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
4331591693c7b415e9869157c711fe11263c95d74eDavid Li      if (chans[i] >= ir->val->type->vector_elements) {
4341591693c7b415e9869157c711fe11263c95d74eDavid Li	 printf("ir_swizzle @ %p specifies a channel not present "
4351591693c7b415e9869157c711fe11263c95d74eDavid Li		"in the value.\n", (void *) ir);
4361591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir->print();
4371591693c7b415e9869157c711fe11263c95d74eDavid Li	 abort();
4381591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4391591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4401591693c7b415e9869157c711fe11263c95d74eDavid Li
4411591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
4421591693c7b415e9869157c711fe11263c95d74eDavid Li}
4431591693c7b415e9869157c711fe11263c95d74eDavid Li
4441591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
4451591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit(ir_variable *ir)
4461591693c7b415e9869157c711fe11263c95d74eDavid Li{
4471591693c7b415e9869157c711fe11263c95d74eDavid Li   /* An ir_variable is the one thing that can (and will) appear multiple times
4481591693c7b415e9869157c711fe11263c95d74eDavid Li    * in an IR tree.  It is added to the hashtable so that it can be used
4491591693c7b415e9869157c711fe11263c95d74eDavid Li    * in the ir_dereference_variable handler to ensure that a variable is
4501591693c7b415e9869157c711fe11263c95d74eDavid Li    * declared before it is dereferenced.
4511591693c7b415e9869157c711fe11263c95d74eDavid Li    */
4521591693c7b415e9869157c711fe11263c95d74eDavid Li   if (ir->name)
453d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li      assert(hieralloc_parent(ir->name) == ir);
4541591693c7b415e9869157c711fe11263c95d74eDavid Li
4551591693c7b415e9869157c711fe11263c95d74eDavid Li   hash_table_insert(ht, ir, ir);
4561591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
4571591693c7b415e9869157c711fe11263c95d74eDavid Li}
4581591693c7b415e9869157c711fe11263c95d74eDavid Li
4591591693c7b415e9869157c711fe11263c95d74eDavid Liir_visitor_status
4601591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::visit_enter(ir_assignment *ir)
4611591693c7b415e9869157c711fe11263c95d74eDavid Li{
4621591693c7b415e9869157c711fe11263c95d74eDavid Li   const ir_dereference *const lhs = ir->lhs;
4631591693c7b415e9869157c711fe11263c95d74eDavid Li   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
4641591693c7b415e9869157c711fe11263c95d74eDavid Li      if (ir->write_mask == 0) {
4651591693c7b415e9869157c711fe11263c95d74eDavid Li	 printf("Assignment LHS is %s, but write mask is 0:\n",
4661591693c7b415e9869157c711fe11263c95d74eDavid Li		lhs->type->is_scalar() ? "scalar" : "vector");
4671591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir->print();
4681591693c7b415e9869157c711fe11263c95d74eDavid Li	 abort();
4691591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4701591693c7b415e9869157c711fe11263c95d74eDavid Li
4711591693c7b415e9869157c711fe11263c95d74eDavid Li      int lhs_components = 0;
4721591693c7b415e9869157c711fe11263c95d74eDavid Li      for (int i = 0; i < 4; i++) {
4731591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (ir->write_mask & (1 << i))
4741591693c7b415e9869157c711fe11263c95d74eDavid Li	    lhs_components++;
4751591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4761591693c7b415e9869157c711fe11263c95d74eDavid Li
4771591693c7b415e9869157c711fe11263c95d74eDavid Li      if (lhs_components != ir->rhs->type->vector_elements) {
4781591693c7b415e9869157c711fe11263c95d74eDavid Li	 printf("Assignment count of LHS write mask channels enabled not\n"
4791591693c7b415e9869157c711fe11263c95d74eDavid Li		"matching RHS vector size (%d LHS, %d RHS).\n",
4801591693c7b415e9869157c711fe11263c95d74eDavid Li		lhs_components, ir->rhs->type->vector_elements);
4811591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir->print();
4821591693c7b415e9869157c711fe11263c95d74eDavid Li	 abort();
4831591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4841591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4851591693c7b415e9869157c711fe11263c95d74eDavid Li
4861591693c7b415e9869157c711fe11263c95d74eDavid Li   this->validate_ir(ir, this->data);
4871591693c7b415e9869157c711fe11263c95d74eDavid Li
4881591693c7b415e9869157c711fe11263c95d74eDavid Li   return visit_continue;
4891591693c7b415e9869157c711fe11263c95d74eDavid Li}
4901591693c7b415e9869157c711fe11263c95d74eDavid Li
4911591693c7b415e9869157c711fe11263c95d74eDavid Livoid
4921591693c7b415e9869157c711fe11263c95d74eDavid Liir_validate::validate_ir(ir_instruction *ir, void *data)
4931591693c7b415e9869157c711fe11263c95d74eDavid Li{
4941591693c7b415e9869157c711fe11263c95d74eDavid Li   struct hash_table *ht = (struct hash_table *) data;
4951591693c7b415e9869157c711fe11263c95d74eDavid Li
4961591693c7b415e9869157c711fe11263c95d74eDavid Li   if (hash_table_find(ht, ir)) {
4971591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("Instruction node present twice in ir tree:\n");
4981591693c7b415e9869157c711fe11263c95d74eDavid Li      ir->print();
4991591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("\n");
5001591693c7b415e9869157c711fe11263c95d74eDavid Li      abort();
5011591693c7b415e9869157c711fe11263c95d74eDavid Li   }
5021591693c7b415e9869157c711fe11263c95d74eDavid Li   hash_table_insert(ht, ir, ir);
5031591693c7b415e9869157c711fe11263c95d74eDavid Li}
5041591693c7b415e9869157c711fe11263c95d74eDavid Li
5051591693c7b415e9869157c711fe11263c95d74eDavid Livoid
5061591693c7b415e9869157c711fe11263c95d74eDavid Licheck_node_type(ir_instruction *ir, void *data)
5071591693c7b415e9869157c711fe11263c95d74eDavid Li{
5081591693c7b415e9869157c711fe11263c95d74eDavid Li   (void) data;
5091591693c7b415e9869157c711fe11263c95d74eDavid Li
5101591693c7b415e9869157c711fe11263c95d74eDavid Li   if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) {
5111591693c7b415e9869157c711fe11263c95d74eDavid Li      printf("Instruction node with unset type\n");
5121591693c7b415e9869157c711fe11263c95d74eDavid Li      ir->print(); printf("\n");
5131591693c7b415e9869157c711fe11263c95d74eDavid Li   }
5141591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(ir->type != glsl_type::error_type);
5151591693c7b415e9869157c711fe11263c95d74eDavid Li}
5161591693c7b415e9869157c711fe11263c95d74eDavid Li
5171591693c7b415e9869157c711fe11263c95d74eDavid Livoid
5181591693c7b415e9869157c711fe11263c95d74eDavid Livalidate_ir_tree(exec_list *instructions)
5191591693c7b415e9869157c711fe11263c95d74eDavid Li{
5201591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_validate v;
5211591693c7b415e9869157c711fe11263c95d74eDavid Li
5221591693c7b415e9869157c711fe11263c95d74eDavid Li   v.run(instructions);
5231591693c7b415e9869157c711fe11263c95d74eDavid Li
5241591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_iter(exec_list_iterator, iter, *instructions) {
5251591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_instruction *ir = (ir_instruction *)iter.get();
5261591693c7b415e9869157c711fe11263c95d74eDavid Li
5271591693c7b415e9869157c711fe11263c95d74eDavid Li      visit_tree(ir, check_node_type, NULL);
5281591693c7b415e9869157c711fe11263c95d74eDavid Li   }
5291591693c7b415e9869157c711fe11263c95d74eDavid Li}
530