ir_validate.cpp revision f2616e56de8a48360cae8f269727b58490555f4d
153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt/*
253cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * Copyright © 2010 Intel Corporation
353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt *
453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
553cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * copy of this software and associated documentation files (the "Software"),
653cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * to deal in the Software without restriction, including without limitation
753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
953cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * Software is furnished to do so, subject to the following conditions:
1053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt *
1153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * The above copyright notice and this permission notice (including the next
1253cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * paragraph) shall be included in all copies or substantial portions of the
1353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * Software.
1453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt *
1553cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1653cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1953cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * DEALINGS IN THE SOFTWARE.
2253cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt */
2353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
2453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt/**
2553cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * \file ir_validate.cpp
2653cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt *
2753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * Attempts to verify that various invariants of the IR tree are true.
2853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt *
2953cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * In particular, at the moment it makes sure that no single
3053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * ir_instruction node except for ir_variable appears multiple times
3153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * in the ir tree.  ir_variable does appear multiple times: Once as a
3253cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * declaration in an exec_list, and multiple times as the endpoint of
3353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt * a dereference chain.
3453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt */
3553cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
369349379d1acca23e7a2442549e49e9b58515d731José Fonseca#include <inttypes.h>
3753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt#include "ir.h"
38865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick#include "ir_hierarchical_visitor.h"
3931747155ea3a24190277b125bd188ac8689af719Aras Pranckevicius#include "program/hash_table.h"
40f141fa63a4391621cc92cd2c39724a952b297a58Eric Anholt#include "glsl_types.h"
4153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
42865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickclass ir_validate : public ir_hierarchical_visitor {
43865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickpublic:
44865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   ir_validate()
45865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   {
46d1a1ee583e7e8338243b3e9768d2fc5312a1145dIan Romanick      this->ht = hash_table_ctor(0, hash_table_pointer_hash,
47d1a1ee583e7e8338243b3e9768d2fc5312a1145dIan Romanick				 hash_table_pointer_compare);
4853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
49c67016de960c988c748ffdb11247072543a8f328Ian Romanick      this->current_function = NULL;
50c67016de960c988c748ffdb11247072543a8f328Ian Romanick
51865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      this->callback = ir_validate::validate_ir;
52865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      this->data = ht;
53865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   }
5453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
55865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   ~ir_validate()
56865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   {
57865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      hash_table_dtor(this->ht);
58865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   }
5953cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
60865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   virtual ir_visitor_status visit(ir_variable *v);
618baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   virtual ir_visitor_status visit(ir_dereference_variable *ir);
62432b787b29202301dbfc139c3289521b0bfc3decEric Anholt   virtual ir_visitor_status visit(ir_if *ir);
6353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
6453acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   virtual ir_visitor_status visit_leave(ir_loop *ir);
65c67016de960c988c748ffdb11247072543a8f328Ian Romanick   virtual ir_visitor_status visit_enter(ir_function *ir);
66c67016de960c988c748ffdb11247072543a8f328Ian Romanick   virtual ir_visitor_status visit_leave(ir_function *ir);
67c67016de960c988c748ffdb11247072543a8f328Ian Romanick   virtual ir_visitor_status visit_enter(ir_function_signature *ir);
68c67016de960c988c748ffdb11247072543a8f328Ian Romanick
695533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   virtual ir_visitor_status visit_leave(ir_expression *ir);
705e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   virtual ir_visitor_status visit_leave(ir_swizzle *ir);
715533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
726235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   virtual ir_visitor_status visit_enter(ir_assignment *ir);
736235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
74865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   static void validate_ir(ir_instruction *ir, void *data);
7553cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
76c67016de960c988c748ffdb11247072543a8f328Ian Romanick   ir_function *current_function;
77c67016de960c988c748ffdb11247072543a8f328Ian Romanick
78865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   struct hash_table *ht;
79865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick};
8053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
818baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
828baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanickir_visitor_status
838baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanickir_validate::visit(ir_dereference_variable *ir)
848baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick{
858baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) {
868baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      printf("ir_dereference_variable @ %p does not specify a variable %p\n",
879f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     (void *) ir, (void *) ir->var);
888baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      abort();
898baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   }
908baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
918baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   if (hash_table_find(ht, ir->var) == NULL) {
928baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      printf("ir_dereference_variable @ %p specifies undeclared variable "
938baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick	     "`%s' @ %p\n",
949f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     (void *) ir, ir->var->name, (void *) ir->var);
958baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      abort();
968baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   }
978baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
98506880bc32e7bb98fd1896a9b2fe3614abab904fIan Romanick   this->validate_ir(ir, this->data);
99506880bc32e7bb98fd1896a9b2fe3614abab904fIan Romanick
1008baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   return visit_continue;
1018baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick}
1028baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
103432b787b29202301dbfc139c3289521b0bfc3decEric Anholtir_visitor_status
104432b787b29202301dbfc139c3289521b0bfc3decEric Anholtir_validate::visit(ir_if *ir)
105432b787b29202301dbfc139c3289521b0bfc3decEric Anholt{
106432b787b29202301dbfc139c3289521b0bfc3decEric Anholt   if (ir->condition->type != glsl_type::bool_type) {
107432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      printf("ir_if condition %s type instead of bool.\n",
108432b787b29202301dbfc139c3289521b0bfc3decEric Anholt	     ir->condition->type->name);
109432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      ir->print();
110432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      printf("\n");
111432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      abort();
112432b787b29202301dbfc139c3289521b0bfc3decEric Anholt   }
1136a1401eb889b5e535c212c414743cc7ea07f6622Eric Anholt
1146a1401eb889b5e535c212c414743cc7ea07f6622Eric Anholt   return visit_continue;
115432b787b29202301dbfc139c3289521b0bfc3decEric Anholt}
116432b787b29202301dbfc139c3289521b0bfc3decEric Anholt
1178baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
11853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholtir_visitor_status
11953acbd87d712555f9e7a1c304843be7b39641413Ian Romanickir_validate::visit_leave(ir_loop *ir)
12053acbd87d712555f9e7a1c304843be7b39641413Ian Romanick{
12153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   if (ir->counter != NULL) {
12253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      if ((ir->from == NULL) || (ir->from == NULL) || (ir->increment == NULL)) {
12353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 printf("ir_loop has invalid loop controls:\n"
12453acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    counter:   %p\n"
12553acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    from:      %p\n"
12653acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    to:        %p\n"
12753acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    increment: %p\n",
12817391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
12917391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul                (void *) ir->increment);
13053acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 abort();
13153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      }
13253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
13353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) {
13453acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 printf("ir_loop has invalid comparitor %d\n", ir->cmp);
13553acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 abort();
13653acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      }
13753acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   } else {
13853acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      if ((ir->from != NULL) || (ir->from != NULL) || (ir->increment != NULL)) {
13953acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 printf("ir_loop has invalid loop controls:\n"
14053acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    counter:   %p\n"
14153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    from:      %p\n"
14253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    to:        %p\n"
14353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    increment: %p\n",
14417391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
14517391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul                (void *) ir->increment);
14653acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 abort();
14753acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      }
14853acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   }
14953acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
15053acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   return visit_continue;
15153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick}
15253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
15353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
15453acbd87d712555f9e7a1c304843be7b39641413Ian Romanickir_visitor_status
155c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_validate::visit_enter(ir_function *ir)
156c67016de960c988c748ffdb11247072543a8f328Ian Romanick{
157c67016de960c988c748ffdb11247072543a8f328Ian Romanick   /* Function definitions cannot be nested.
158c67016de960c988c748ffdb11247072543a8f328Ian Romanick    */
159c67016de960c988c748ffdb11247072543a8f328Ian Romanick   if (this->current_function != NULL) {
160c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("Function definition nested inside another function "
161c67016de960c988c748ffdb11247072543a8f328Ian Romanick	     "definition:\n");
162c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("%s %p inside %s %p\n",
1639f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     ir->name, (void *) ir,
1649f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     this->current_function->name, (void *) this->current_function);
165c67016de960c988c748ffdb11247072543a8f328Ian Romanick      abort();
166c67016de960c988c748ffdb11247072543a8f328Ian Romanick   }
167c67016de960c988c748ffdb11247072543a8f328Ian Romanick
168c67016de960c988c748ffdb11247072543a8f328Ian Romanick   /* Store the current function hierarchy being traversed.  This is used
169c67016de960c988c748ffdb11247072543a8f328Ian Romanick    * by the function signature visitor to ensure that the signatures are
170c67016de960c988c748ffdb11247072543a8f328Ian Romanick    * linked with the correct functions.
171c67016de960c988c748ffdb11247072543a8f328Ian Romanick    */
172c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->current_function = ir;
173c67016de960c988c748ffdb11247072543a8f328Ian Romanick
174c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->validate_ir(ir, this->data);
175c67016de960c988c748ffdb11247072543a8f328Ian Romanick
176c67016de960c988c748ffdb11247072543a8f328Ian Romanick   return visit_continue;
177c67016de960c988c748ffdb11247072543a8f328Ian Romanick}
178c67016de960c988c748ffdb11247072543a8f328Ian Romanick
179c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_visitor_status
180c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_validate::visit_leave(ir_function *ir)
181c67016de960c988c748ffdb11247072543a8f328Ian Romanick{
182ee7666b5ac2fc7de64baf60835271e15baf89474Eric Anholt   assert(talloc_parent(ir->name) == ir);
183c67016de960c988c748ffdb11247072543a8f328Ian Romanick
184c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->current_function = NULL;
185c67016de960c988c748ffdb11247072543a8f328Ian Romanick   return visit_continue;
186c67016de960c988c748ffdb11247072543a8f328Ian Romanick}
187c67016de960c988c748ffdb11247072543a8f328Ian Romanick
188c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_visitor_status
189c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_validate::visit_enter(ir_function_signature *ir)
190c67016de960c988c748ffdb11247072543a8f328Ian Romanick{
191c67016de960c988c748ffdb11247072543a8f328Ian Romanick   if (this->current_function != ir->function()) {
192c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("Function signature nested inside wrong function "
193c67016de960c988c748ffdb11247072543a8f328Ian Romanick	     "definition:\n");
194c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("%p inside %s %p instead of %s %p\n",
1959f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     (void *) ir,
1969f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     this->current_function->name, (void *) this->current_function,
1979f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     ir->function_name(), (void *) ir->function());
198c67016de960c988c748ffdb11247072543a8f328Ian Romanick      abort();
199c67016de960c988c748ffdb11247072543a8f328Ian Romanick   }
200c67016de960c988c748ffdb11247072543a8f328Ian Romanick
201c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->validate_ir(ir, this->data);
202c67016de960c988c748ffdb11247072543a8f328Ian Romanick
203c67016de960c988c748ffdb11247072543a8f328Ian Romanick   return visit_continue;
204c67016de960c988c748ffdb11247072543a8f328Ian Romanick}
205c67016de960c988c748ffdb11247072543a8f328Ian Romanick
206c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_visitor_status
2075533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholtir_validate::visit_leave(ir_expression *ir)
2085533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt{
2095533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   switch (ir->operation) {
2105533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_bit_not:
2115533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->type);
2125533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2135533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_logic_not:
214e75dbf66d011d76b6944dc4ee55e339ee285510cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_BOOL);
215e75dbf66d011d76b6944dc4ee55e339ee285510cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2165533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2175533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
2185533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_neg:
2195533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_abs:
2205533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_sign:
2215533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_rcp:
2225533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_rsq:
2235533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_sqrt:
224bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt      assert(ir->type == ir->operands[0]->type);
225bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt      break;
226bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt
2275533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_exp:
2285533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_log:
2295533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_exp2:
2305533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_log2:
231bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2325533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == ir->operands[0]->type);
2335533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2345533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
2355533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_f2i:
2365533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2375533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_INT);
2385533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2395533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_i2f:
2405533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
2415533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2425533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2435533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_f2b:
2445533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2455533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_BOOL);
2465533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2475533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_b2f:
2485533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2495533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2505533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2515533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_i2b:
2525533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
2535533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_BOOL);
2545533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2555533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_b2i:
2565533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2575533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_INT);
2585533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2595533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_u2f:
2605533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
2615533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2625533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2635533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
2645e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt   case ir_unop_any:
2655e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2665e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      assert(ir->type == glsl_type::bool_type);
2675e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      break;
2685e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt
2695533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_trunc:
270b2578ef873c4c9dd831a23501a677bf523de90fcBrian Paul   case ir_unop_round_even:
2715533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_ceil:
2725533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_floor:
2735533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_fract:
2745533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_sin:
2755533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_cos:
276f2616e56de8a48360cae8f269727b58490555f4dIan Romanick   case ir_unop_sin_reduced:
277f2616e56de8a48360cae8f269727b58490555f4dIan Romanick   case ir_unop_cos_reduced:
2785533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_dFdx:
2795533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_dFdy:
2805533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2815533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->type);
2825533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2835533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
2841c0644e9dac946131594216e23953a9c85335282Brian Paul   case ir_unop_noise:
2851c0644e9dac946131594216e23953a9c85335282Brian Paul      /* XXX what can we assert here? */
2861c0644e9dac946131594216e23953a9c85335282Brian Paul      break;
2871c0644e9dac946131594216e23953a9c85335282Brian Paul
2885533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_add:
2895533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_sub:
2905533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_mul:
2915533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_div:
2925533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_mod:
2935533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_min:
2945533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_max:
2955533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_pow:
2965533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      if (ir->operands[0]->type->is_scalar())
2975533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[1]->type == ir->type);
2985533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      else if (ir->operands[1]->type->is_scalar())
2995533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[0]->type == ir->type);
3005533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      else if (ir->operands[0]->type->is_vector() &&
3015533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	       ir->operands[1]->type->is_vector()) {
3025533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[0]->type == ir->operands[1]->type);
3035533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[0]->type == ir->type);
3045533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      }
3055533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3064dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri
3075533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_less:
3085533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_greater:
3095533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_lequal:
3105533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_gequal:
3114dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_equal:
3124dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_nequal:
3134dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
3144dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * ==, and != operators.  The IR operators perform a component-wise
3154dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * comparison on scalar or vector types and return a boolean scalar or
3164dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * vector type of the same size.
3175533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt       */
3184dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      assert(ir->type->base_type == GLSL_TYPE_BOOL);
3195533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->operands[1]->type);
3204dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      assert(ir->operands[0]->type->is_vector()
3214dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri	     || ir->operands[0]->type->is_scalar());
3224dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      assert(ir->operands[0]->type->vector_elements
3234dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri	     == ir->type->vector_elements);
3245533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3255533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3264dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_all_equal:
3274dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_any_nequal:
3284dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
3294dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * return a scalar boolean.  The IR matches that.
3305533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt       */
3315533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == glsl_type::bool_type);
3325533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->operands[1]->type);
3335533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3345533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3355533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_lshift:
3365533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_rshift:
3375c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      assert(ir->operands[0]->type->is_integer() &&
3385c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace             ir->operands[1]->type->is_integer());
3395c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      if (ir->operands[0]->type->is_scalar()) {
3405c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace          assert(ir->operands[1]->type->is_scalar());
3415c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      }
3425c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      if (ir->operands[0]->type->is_vector() &&
3435c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace          ir->operands[1]->type->is_vector()) {
3445c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace          assert(ir->operands[0]->type->components() ==
3455c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace                 ir->operands[1]->type->components());
3465c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      }
3475c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      assert(ir->type == ir->operands[0]->type);
3485c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      break;
3495c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace
3505533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_bit_and:
3515533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_bit_xor:
3525533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_bit_or:
353e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       assert(ir->operands[0]->type->base_type ==
354e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace              ir->operands[1]->type->base_type);
355e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       assert(ir->type->is_integer());
356e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       if (ir->operands[0]->type->is_vector() &&
357e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace           ir->operands[1]->type->is_vector()) {
358e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace           assert(ir->operands[0]->type->vector_elements ==
359e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace                  ir->operands[1]->type->vector_elements);
360e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       }
361e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       break;
3625533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3635533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_logic_and:
3645533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_logic_xor:
3655533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_logic_or:
3665533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == glsl_type::bool_type);
3675533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == glsl_type::bool_type);
3685533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[1]->type == glsl_type::bool_type);
3695533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3705533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3715533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_dot:
3725533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == glsl_type::float_type);
3735533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
374368dc76f04e19f5070d1f41795ea8cde2964639fKenneth Graunke      assert(ir->operands[0]->type->is_vector());
3755533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->operands[1]->type);
3765533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3775533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   }
3785533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3795533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   return visit_continue;
3805533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt}
3815533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3825533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholtir_visitor_status
3835e8ed7a79b381d559b059987bd99c68d40f641caEric Anholtir_validate::visit_leave(ir_swizzle *ir)
3845e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt{
3855e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w};
3865e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt
3875e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
3885e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt      if (chans[i] >= ir->val->type->vector_elements) {
3895e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt	 printf("ir_swizzle @ %p specifies a channel not present "
3905e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt		"in the value.\n", (void *) ir);
3915e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt	 ir->print();
3925e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt	 abort();
3935e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt      }
3945e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   }
3955e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt
3965e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   return visit_continue;
3975e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt}
3985e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt
3995e8ed7a79b381d559b059987bd99c68d40f641caEric Anholtir_visitor_status
400865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickir_validate::visit(ir_variable *ir)
40153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt{
402865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   /* An ir_variable is the one thing that can (and will) appear multiple times
4038baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick    * in an IR tree.  It is added to the hashtable so that it can be used
4048baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick    * in the ir_dereference_variable handler to ensure that a variable is
4058baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick    * declared before it is dereferenced.
406865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick    */
407c22dee721695402d9f2678c100d2fff5c0c3f21fEric Anholt   if (ir->name)
408c22dee721695402d9f2678c100d2fff5c0c3f21fEric Anholt      assert(talloc_parent(ir->name) == ir);
409ee7666b5ac2fc7de64baf60835271e15baf89474Eric Anholt
4108baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   hash_table_insert(ht, ir, ir);
41153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt   return visit_continue;
41253cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt}
41353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
4146235c6a83855fe2818affda3c82e1a245bd0232eIan Romanickir_visitor_status
4156235c6a83855fe2818affda3c82e1a245bd0232eIan Romanickir_validate::visit_enter(ir_assignment *ir)
4166235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick{
4176235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   const ir_dereference *const lhs = ir->lhs;
4186235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
4196235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick      if (ir->write_mask == 0) {
4206235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 printf("Assignment LHS is %s, but write mask is 0:\n",
4216235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick		lhs->type->is_scalar() ? "scalar" : "vector");
4226235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 ir->print();
4236235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 abort();
4246235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick      }
4256235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
426b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      int lhs_components = 0;
427b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      for (int i = 0; i < 4; i++) {
428b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt	 if (ir->write_mask & (1 << i))
429b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt	    lhs_components++;
430b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      }
4316235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
432b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      if (lhs_components != ir->rhs->type->vector_elements) {
433b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt	 printf("Assignment count of LHS write mask channels enabled not\n"
434b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt		"matching RHS vector size (%d LHS, %d RHS).\n",
435b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt		lhs_components, ir->rhs->type->vector_elements);
4366235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 ir->print();
4376235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 abort();
4386235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick      }
4396235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   }
4406235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
4416235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   this->validate_ir(ir, this->data);
4426235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
4436235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   return visit_continue;
4446235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick}
4456235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
446865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickvoid
447865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickir_validate::validate_ir(ir_instruction *ir, void *data)
44853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt{
449865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   struct hash_table *ht = (struct hash_table *) data;
45053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
451865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   if (hash_table_find(ht, ir)) {
452865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      printf("Instruction node present twice in ir tree:\n");
453865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      ir->print();
454865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      printf("\n");
455865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      abort();
456865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   }
457865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   hash_table_insert(ht, ir, ir);
45853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt}
45953cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
46053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholtvoid
461d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholtcheck_node_type(ir_instruction *ir, void *data)
462d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt{
4637ffe40532f6b22d9b80caeac0fc3b9495619186aIan Romanick   (void) data;
4647ffe40532f6b22d9b80caeac0fc3b9495619186aIan Romanick
465d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) {
466d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      printf("Instruction node with unset type\n");
467d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      ir->print(); printf("\n");
468d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   }
469f141fa63a4391621cc92cd2c39724a952b297a58Eric Anholt   assert(ir->type != glsl_type::error_type);
470d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt}
471d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
472d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholtvoid
47353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholtvalidate_ir_tree(exec_list *instructions)
47453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt{
47553cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt   ir_validate v;
47653cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
47753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt   v.run(instructions);
478d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
479d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   foreach_iter(exec_list_iterator, iter, *instructions) {
480d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      ir_instruction *ir = (ir_instruction *)iter.get();
481d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
482d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      visit_tree(ir, check_node_type, NULL);
483d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   }
48453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt}
485