ir_validate.cpp revision f37b1ad937dd2c420f4c9fd9aa5887942bd31f3f
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
3653cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt#include "ir.h"
37865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick#include "ir_hierarchical_visitor.h"
3831747155ea3a24190277b125bd188ac8689af719Aras Pranckevicius#include "program/hash_table.h"
39f141fa63a4391621cc92cd2c39724a952b297a58Eric Anholt#include "glsl_types.h"
4053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
41865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickclass ir_validate : public ir_hierarchical_visitor {
42865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickpublic:
43865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   ir_validate()
44865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   {
45d1a1ee583e7e8338243b3e9768d2fc5312a1145dIan Romanick      this->ht = hash_table_ctor(0, hash_table_pointer_hash,
46d1a1ee583e7e8338243b3e9768d2fc5312a1145dIan Romanick				 hash_table_pointer_compare);
4753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
48c67016de960c988c748ffdb11247072543a8f328Ian Romanick      this->current_function = NULL;
49c67016de960c988c748ffdb11247072543a8f328Ian Romanick
50865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      this->callback = ir_validate::validate_ir;
51865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      this->data = ht;
52865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   }
5353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
54865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   ~ir_validate()
55865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   {
56865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      hash_table_dtor(this->ht);
57865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   }
5853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
59865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   virtual ir_visitor_status visit(ir_variable *v);
608baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   virtual ir_visitor_status visit(ir_dereference_variable *ir);
616c8ea1eed66e9da82fb2b49b1e7f6d7f6064dbc4Kenneth Graunke
626c8ea1eed66e9da82fb2b49b1e7f6d7f6064dbc4Kenneth Graunke   virtual ir_visitor_status visit_enter(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);
738bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   virtual ir_visitor_status visit_enter(ir_call *ir);
746235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
75865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   static void validate_ir(ir_instruction *ir, void *data);
7653cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
77c67016de960c988c748ffdb11247072543a8f328Ian Romanick   ir_function *current_function;
78c67016de960c988c748ffdb11247072543a8f328Ian Romanick
79865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   struct hash_table *ht;
80865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick};
8153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
828baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
838baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanickir_visitor_status
848baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanickir_validate::visit(ir_dereference_variable *ir)
858baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick{
868baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) {
878baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      printf("ir_dereference_variable @ %p does not specify a variable %p\n",
889f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     (void *) ir, (void *) ir->var);
898baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      abort();
908baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   }
918baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
928baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   if (hash_table_find(ht, ir->var) == NULL) {
938baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      printf("ir_dereference_variable @ %p specifies undeclared variable "
948baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick	     "`%s' @ %p\n",
959f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     (void *) ir, ir->var->name, (void *) ir->var);
968baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick      abort();
978baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   }
988baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
99506880bc32e7bb98fd1896a9b2fe3614abab904fIan Romanick   this->validate_ir(ir, this->data);
100506880bc32e7bb98fd1896a9b2fe3614abab904fIan Romanick
1018baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   return visit_continue;
1028baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick}
1038baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
104432b787b29202301dbfc139c3289521b0bfc3decEric Anholtir_visitor_status
1056c8ea1eed66e9da82fb2b49b1e7f6d7f6064dbc4Kenneth Graunkeir_validate::visit_enter(ir_if *ir)
106432b787b29202301dbfc139c3289521b0bfc3decEric Anholt{
107432b787b29202301dbfc139c3289521b0bfc3decEric Anholt   if (ir->condition->type != glsl_type::bool_type) {
108432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      printf("ir_if condition %s type instead of bool.\n",
109432b787b29202301dbfc139c3289521b0bfc3decEric Anholt	     ir->condition->type->name);
110432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      ir->print();
111432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      printf("\n");
112432b787b29202301dbfc139c3289521b0bfc3decEric Anholt      abort();
113432b787b29202301dbfc139c3289521b0bfc3decEric Anholt   }
1146a1401eb889b5e535c212c414743cc7ea07f6622Eric Anholt
1156a1401eb889b5e535c212c414743cc7ea07f6622Eric Anholt   return visit_continue;
116432b787b29202301dbfc139c3289521b0bfc3decEric Anholt}
117432b787b29202301dbfc139c3289521b0bfc3decEric Anholt
1188baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick
11953cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholtir_visitor_status
12053acbd87d712555f9e7a1c304843be7b39641413Ian Romanickir_validate::visit_leave(ir_loop *ir)
12153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick{
12253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   if (ir->counter != NULL) {
12353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      if ((ir->from == NULL) || (ir->from == NULL) || (ir->increment == NULL)) {
12453acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 printf("ir_loop has invalid loop controls:\n"
12553acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    counter:   %p\n"
12653acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    from:      %p\n"
12753acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    to:        %p\n"
12853acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    increment: %p\n",
12917391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
13017391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul                (void *) ir->increment);
13153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 abort();
13253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      }
13353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
13453acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) {
13553acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 printf("ir_loop has invalid comparitor %d\n", ir->cmp);
13653acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 abort();
13753acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      }
13853acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   } else {
13953acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      if ((ir->from != NULL) || (ir->from != NULL) || (ir->increment != NULL)) {
14053acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 printf("ir_loop has invalid loop controls:\n"
14153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    counter:   %p\n"
14253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    from:      %p\n"
14353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    to:        %p\n"
14453acbd87d712555f9e7a1c304843be7b39641413Ian Romanick		"    increment: %p\n",
14517391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
14617391241599137b9729e9ee6c5487d05e04d8aeeBrian Paul                (void *) ir->increment);
14753acbd87d712555f9e7a1c304843be7b39641413Ian Romanick	 abort();
14853acbd87d712555f9e7a1c304843be7b39641413Ian Romanick      }
14953acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   }
15053acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
15153acbd87d712555f9e7a1c304843be7b39641413Ian Romanick   return visit_continue;
15253acbd87d712555f9e7a1c304843be7b39641413Ian Romanick}
15353acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
15453acbd87d712555f9e7a1c304843be7b39641413Ian Romanick
15553acbd87d712555f9e7a1c304843be7b39641413Ian Romanickir_visitor_status
156c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_validate::visit_enter(ir_function *ir)
157c67016de960c988c748ffdb11247072543a8f328Ian Romanick{
158c67016de960c988c748ffdb11247072543a8f328Ian Romanick   /* Function definitions cannot be nested.
159c67016de960c988c748ffdb11247072543a8f328Ian Romanick    */
160c67016de960c988c748ffdb11247072543a8f328Ian Romanick   if (this->current_function != NULL) {
161c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("Function definition nested inside another function "
162c67016de960c988c748ffdb11247072543a8f328Ian Romanick	     "definition:\n");
163c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("%s %p inside %s %p\n",
1649f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     ir->name, (void *) ir,
1659f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     this->current_function->name, (void *) this->current_function);
166c67016de960c988c748ffdb11247072543a8f328Ian Romanick      abort();
167c67016de960c988c748ffdb11247072543a8f328Ian Romanick   }
168c67016de960c988c748ffdb11247072543a8f328Ian Romanick
169c67016de960c988c748ffdb11247072543a8f328Ian Romanick   /* Store the current function hierarchy being traversed.  This is used
170c67016de960c988c748ffdb11247072543a8f328Ian Romanick    * by the function signature visitor to ensure that the signatures are
171c67016de960c988c748ffdb11247072543a8f328Ian Romanick    * linked with the correct functions.
172c67016de960c988c748ffdb11247072543a8f328Ian Romanick    */
173c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->current_function = ir;
174c67016de960c988c748ffdb11247072543a8f328Ian Romanick
175c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->validate_ir(ir, this->data);
176c67016de960c988c748ffdb11247072543a8f328Ian Romanick
1778bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   /* Verify that all of the things stored in the list of signatures are,
1788bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick    * in fact, function signatures.
1798bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick    */
1808bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   foreach_list(node, &ir->signatures) {
1818bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick      ir_instruction *sig = (ir_instruction *) node;
1828bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick
1838bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick      if (sig->ir_type != ir_type_function_signature) {
1848bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick	 printf("Non-signature in signature list of function `%s'\n",
1858bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick		ir->name);
1868bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick	 abort();
1878bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick      }
1888bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   }
1898bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick
190c67016de960c988c748ffdb11247072543a8f328Ian Romanick   return visit_continue;
191c67016de960c988c748ffdb11247072543a8f328Ian Romanick}
192c67016de960c988c748ffdb11247072543a8f328Ian Romanick
193c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_visitor_status
194c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_validate::visit_leave(ir_function *ir)
195c67016de960c988c748ffdb11247072543a8f328Ian Romanick{
196d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke   assert(ralloc_parent(ir->name) == ir);
197c67016de960c988c748ffdb11247072543a8f328Ian Romanick
198c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->current_function = NULL;
199c67016de960c988c748ffdb11247072543a8f328Ian Romanick   return visit_continue;
200c67016de960c988c748ffdb11247072543a8f328Ian Romanick}
201c67016de960c988c748ffdb11247072543a8f328Ian Romanick
202c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_visitor_status
203c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_validate::visit_enter(ir_function_signature *ir)
204c67016de960c988c748ffdb11247072543a8f328Ian Romanick{
205c67016de960c988c748ffdb11247072543a8f328Ian Romanick   if (this->current_function != ir->function()) {
206c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("Function signature nested inside wrong function "
207c67016de960c988c748ffdb11247072543a8f328Ian Romanick	     "definition:\n");
208c67016de960c988c748ffdb11247072543a8f328Ian Romanick      printf("%p inside %s %p instead of %s %p\n",
2099f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     (void *) ir,
2109f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     this->current_function->name, (void *) this->current_function,
2119f9386d22aca8d14d1b1e6d4de9b24dcb183ca10Brian Paul	     ir->function_name(), (void *) ir->function());
212c67016de960c988c748ffdb11247072543a8f328Ian Romanick      abort();
213c67016de960c988c748ffdb11247072543a8f328Ian Romanick   }
214c67016de960c988c748ffdb11247072543a8f328Ian Romanick
2152df56b002dcc5d7e91515bd0ca741677f0172b38Ian Romanick   if (ir->return_type == NULL) {
2162df56b002dcc5d7e91515bd0ca741677f0172b38Ian Romanick      printf("Function signature %p for function %s has NULL return type.\n",
2170eab3a8a976ea282063710d5aa7d1709abc182c5Brian Paul	     (void *) ir, ir->function_name());
2182df56b002dcc5d7e91515bd0ca741677f0172b38Ian Romanick      abort();
2192df56b002dcc5d7e91515bd0ca741677f0172b38Ian Romanick   }
2202df56b002dcc5d7e91515bd0ca741677f0172b38Ian Romanick
221c67016de960c988c748ffdb11247072543a8f328Ian Romanick   this->validate_ir(ir, this->data);
222c67016de960c988c748ffdb11247072543a8f328Ian Romanick
223c67016de960c988c748ffdb11247072543a8f328Ian Romanick   return visit_continue;
224c67016de960c988c748ffdb11247072543a8f328Ian Romanick}
225c67016de960c988c748ffdb11247072543a8f328Ian Romanick
226c67016de960c988c748ffdb11247072543a8f328Ian Romanickir_visitor_status
2275533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholtir_validate::visit_leave(ir_expression *ir)
2285533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt{
2295533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   switch (ir->operation) {
2305533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_bit_not:
2315533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->type);
2325533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2335533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_logic_not:
234e75dbf66d011d76b6944dc4ee55e339ee285510cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_BOOL);
235e75dbf66d011d76b6944dc4ee55e339ee285510cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2365533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2375533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
2385533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_neg:
2395533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_abs:
2405533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_sign:
2415533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_rcp:
2425533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_rsq:
2435533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_sqrt:
244bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt      assert(ir->type == ir->operands[0]->type);
245bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt      break;
246bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt
2475533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_exp:
2485533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_log:
2495533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_exp2:
2505533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_log2:
251bc4034b243975089c06c4415d4e26edaaaec7a46Eric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2525533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == ir->operands[0]->type);
2535533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2545533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
2555533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_f2i:
2565533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2573283e362e313f8a45fd6ee812efb737c0becc38cKenneth Graunke      assert(ir->type->base_type == GLSL_TYPE_INT);
2585533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2595533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_i2f:
2605533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
2615533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2625533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2635533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_f2b:
2645533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
2655533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_BOOL);
2665533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2675533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_b2f:
2685533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2695533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2705533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2715533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_i2b:
2723283e362e313f8a45fd6ee812efb737c0becc38cKenneth Graunke      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
2735533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_BOOL);
2745533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2755533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_b2i:
2765533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2773283e362e313f8a45fd6ee812efb737c0becc38cKenneth Graunke      assert(ir->type->base_type == GLSL_TYPE_INT);
2785533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
2795533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_u2f:
2805533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
2815533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
2825533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
28320ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain   case ir_unop_i2u:
28420ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
28520ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain      assert(ir->type->base_type == GLSL_TYPE_UINT);
28620ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain      break;
28720ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain   case ir_unop_u2i:
28820ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
28920ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain      assert(ir->type->base_type == GLSL_TYPE_INT);
29020ef96c7ff3f17fbf97e0452a37553249b2b005cBryan Cain      break;
2915533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
2925e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt   case ir_unop_any:
2935e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
2945e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      assert(ir->type == glsl_type::bool_type);
2955e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt      break;
2965e9ac94cc44ef4f97063d7b696411b2a4be16f36Eric Anholt
2975533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_trunc:
298b2578ef873c4c9dd831a23501a677bf523de90fcBrian Paul   case ir_unop_round_even:
2995533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_ceil:
3005533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_floor:
3015533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_fract:
3025533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_sin:
3035533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_cos:
304f2616e56de8a48360cae8f269727b58490555f4dIan Romanick   case ir_unop_sin_reduced:
305f2616e56de8a48360cae8f269727b58490555f4dIan Romanick   case ir_unop_cos_reduced:
3065533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_dFdx:
3075533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_unop_dFdy:
3085533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
3095533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->type);
3105533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3115533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3121c0644e9dac946131594216e23953a9c85335282Brian Paul   case ir_unop_noise:
3131c0644e9dac946131594216e23953a9c85335282Brian Paul      /* XXX what can we assert here? */
3141c0644e9dac946131594216e23953a9c85335282Brian Paul      break;
3151c0644e9dac946131594216e23953a9c85335282Brian Paul
3165533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_add:
3175533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_sub:
3185533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_mul:
3195533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_div:
3205533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_mod:
3215533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_min:
3225533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_max:
3235533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_pow:
3245533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      if (ir->operands[0]->type->is_scalar())
3255533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[1]->type == ir->type);
3265533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      else if (ir->operands[1]->type->is_scalar())
3275533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[0]->type == ir->type);
3285533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      else if (ir->operands[0]->type->is_vector() &&
3295533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	       ir->operands[1]->type->is_vector()) {
3305533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[0]->type == ir->operands[1]->type);
3315533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt	 assert(ir->operands[0]->type == ir->type);
3325533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      }
3335533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3344dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri
3355533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_less:
3365533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_greater:
3375533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_lequal:
3385533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_gequal:
3394dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_equal:
3404dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_nequal:
3414dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
3424dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * ==, and != operators.  The IR operators perform a component-wise
3434dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * comparison on scalar or vector types and return a boolean scalar or
3444dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * vector type of the same size.
3455533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt       */
3464dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      assert(ir->type->base_type == GLSL_TYPE_BOOL);
3475533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->operands[1]->type);
3484dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      assert(ir->operands[0]->type->is_vector()
3494dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri	     || ir->operands[0]->type->is_scalar());
3504dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      assert(ir->operands[0]->type->vector_elements
3514dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri	     == ir->type->vector_elements);
3525533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3535533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3544dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_all_equal:
3554dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri   case ir_binop_any_nequal:
3564dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri      /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
3574dfb89904c0a3d2166e9a3fc0253a254680e91bcLuca Barbieri       * return a scalar boolean.  The IR matches that.
3585533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt       */
3595533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == glsl_type::bool_type);
3605533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->operands[1]->type);
3615533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3625533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3635533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_lshift:
3645533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_rshift:
3655c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      assert(ir->operands[0]->type->is_integer() &&
3665c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace             ir->operands[1]->type->is_integer());
3675c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      if (ir->operands[0]->type->is_scalar()) {
3685c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace          assert(ir->operands[1]->type->is_scalar());
3695c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      }
3705c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      if (ir->operands[0]->type->is_vector() &&
3715c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace          ir->operands[1]->type->is_vector()) {
3725c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace          assert(ir->operands[0]->type->components() ==
3735c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace                 ir->operands[1]->type->components());
3745c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      }
3755c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      assert(ir->type == ir->operands[0]->type);
3765c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace      break;
3775c4c36f7f3842e287b303b1eca8d260c37e3580bChad Versace
3785533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_bit_and:
3795533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_bit_xor:
3805533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_bit_or:
381e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       assert(ir->operands[0]->type->base_type ==
382e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace              ir->operands[1]->type->base_type);
383e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       assert(ir->type->is_integer());
384e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       if (ir->operands[0]->type->is_vector() &&
385e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace           ir->operands[1]->type->is_vector()) {
386e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace           assert(ir->operands[0]->type->vector_elements ==
387e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace                  ir->operands[1]->type->vector_elements);
388e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       }
389e2c1fe3eb0fa47f5501b4ec8cd6b732db7ca84beChad Versace       break;
3905533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3915533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_logic_and:
3925533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_logic_xor:
3935533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_logic_or:
3945533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == glsl_type::bool_type);
3955533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == glsl_type::bool_type);
3965533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[1]->type == glsl_type::bool_type);
3975533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
3985533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
3995533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   case ir_binop_dot:
4005533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->type == glsl_type::float_type);
4015533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
402368dc76f04e19f5070d1f41795ea8cde2964639fKenneth Graunke      assert(ir->operands[0]->type->is_vector());
4035533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      assert(ir->operands[0]->type == ir->operands[1]->type);
4045533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt      break;
40511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick
40611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick   case ir_quadop_vector:
40711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      /* The vector operator collects some number of scalars and generates a
40811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick       * vector from them.
40911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick       *
41011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick       *  - All of the operands must be scalar.
41111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick       *  - Number of operands must matche the size of the resulting vector.
41211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick       *  - Base type of the operands must match the base type of the result.
41311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick       */
41411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      assert(ir->type->is_vector());
41511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      switch (ir->type->vector_elements) {
41611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      case 2:
41711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[0]->type->is_scalar());
41811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
41911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[1]->type->is_scalar());
42011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
42111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[2] == NULL);
42211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[3] == NULL);
42311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 break;
42411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      case 3:
42511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[0]->type->is_scalar());
42611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
42711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[1]->type->is_scalar());
42811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
42911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[2]->type->is_scalar());
43011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
43111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[3] == NULL);
43211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 break;
43311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      case 4:
43411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[0]->type->is_scalar());
43511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
43611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[1]->type->is_scalar());
43711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
43811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[2]->type->is_scalar());
43911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
44011d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[3]->type->is_scalar());
44111d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(ir->operands[3]->type->base_type == ir->type->base_type);
44211d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 break;
44311d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      default:
44411d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 /* The is_vector assertion above should prevent execution from ever
44511d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	  * getting here.
44611d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	  */
44711d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 assert(!"Should not get here.");
44811d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick	 break;
44911d6f1c69871d0b7edc28f639256460839fccd2dIan Romanick      }
4505533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   }
4515533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
4525533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt   return visit_continue;
4535533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt}
4545533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholt
4555533c6e38030ff6e26375a1a4e4bfa9ab2204d4cEric Anholtir_visitor_status
4565e8ed7a79b381d559b059987bd99c68d40f641caEric Anholtir_validate::visit_leave(ir_swizzle *ir)
4575e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt{
4585e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w};
4595e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt
4605e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
4615e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt      if (chans[i] >= ir->val->type->vector_elements) {
4625e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt	 printf("ir_swizzle @ %p specifies a channel not present "
4635e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt		"in the value.\n", (void *) ir);
4645e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt	 ir->print();
4655e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt	 abort();
4665e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt      }
4675e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   }
4685e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt
4695e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt   return visit_continue;
4705e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt}
4715e8ed7a79b381d559b059987bd99c68d40f641caEric Anholt
4725e8ed7a79b381d559b059987bd99c68d40f641caEric Anholtir_visitor_status
473865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickir_validate::visit(ir_variable *ir)
47453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt{
475865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   /* An ir_variable is the one thing that can (and will) appear multiple times
4768baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick    * in an IR tree.  It is added to the hashtable so that it can be used
4778baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick    * in the ir_dereference_variable handler to ensure that a variable is
4788baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick    * declared before it is dereferenced.
479865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick    */
480c22dee721695402d9f2678c100d2fff5c0c3f21fEric Anholt   if (ir->name)
481d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke      assert(ralloc_parent(ir->name) == ir);
482ee7666b5ac2fc7de64baf60835271e15baf89474Eric Anholt
4838baf21b1a4d50efca086679cc43bb0cfc3fee03aIan Romanick   hash_table_insert(ht, ir, ir);
484bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick
485bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick
486bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick   /* If a variable is an array, verify that the maximum array index is in
487bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick    * bounds.  There was once an error in AST-to-HIR conversion that set this
488bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick    * to be out of bounds.
489bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick    */
490bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick   if (ir->type->array_size() > 0) {
491bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick      if (ir->max_array_access >= ir->type->length) {
492bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick	 printf("ir_variable has maximum access out of bounds (%d vs %d)\n",
493bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick		ir->max_array_access, ir->type->length - 1);
494bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick	 ir->print();
495bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick	 abort();
496bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick      }
497bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick   }
498bc83f6bd585bba6dee3fa2264d32ab59e9a9c99eIan Romanick
499f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick   if (ir->constant_initializer != NULL && !ir->has_initializer) {
500f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick      printf("ir_variable didn't have an initializer, but has a constant "
501f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick	     "initializer value.\n");
502f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick      ir->print();
503f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick      abort();
504f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick   }
505f37b1ad937dd2c420f4c9fd9aa5887942bd31f3fIan Romanick
50653cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt   return visit_continue;
50753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt}
50853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
5096235c6a83855fe2818affda3c82e1a245bd0232eIan Romanickir_visitor_status
5106235c6a83855fe2818affda3c82e1a245bd0232eIan Romanickir_validate::visit_enter(ir_assignment *ir)
5116235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick{
5126235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   const ir_dereference *const lhs = ir->lhs;
5136235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
5146235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick      if (ir->write_mask == 0) {
5156235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 printf("Assignment LHS is %s, but write mask is 0:\n",
5166235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick		lhs->type->is_scalar() ? "scalar" : "vector");
5176235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 ir->print();
5186235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 abort();
5196235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick      }
5206235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
521b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      int lhs_components = 0;
522b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      for (int i = 0; i < 4; i++) {
523b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt	 if (ir->write_mask & (1 << i))
524b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt	    lhs_components++;
525b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      }
5266235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
527b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt      if (lhs_components != ir->rhs->type->vector_elements) {
528b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt	 printf("Assignment count of LHS write mask channels enabled not\n"
529b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt		"matching RHS vector size (%d LHS, %d RHS).\n",
530b39e6f33b60ef9bbaf81f320aaca6a440d8a6a8fEric Anholt		lhs_components, ir->rhs->type->vector_elements);
5316235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 ir->print();
5326235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick	 abort();
5336235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick      }
5346235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   }
5356235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
5366235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   this->validate_ir(ir, this->data);
5376235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
5386235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick   return visit_continue;
5396235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick}
5406235c6a83855fe2818affda3c82e1a245bd0232eIan Romanick
5418bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanickir_visitor_status
5428bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanickir_validate::visit_enter(ir_call *ir)
5438bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick{
5448bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   ir_function_signature *const callee = ir->get_callee();
5458bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick
5468bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   if (callee->ir_type != ir_type_function_signature) {
5478bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick      printf("IR called by ir_call is not ir_function_signature!\n");
5488bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick      abort();
5498bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   }
5508bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick
551303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   const exec_node *formal_param_node = callee->parameters.head;
552303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   const exec_node *actual_param_node = ir->actual_parameters.head;
553303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   while (true) {
554303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      if (formal_param_node->is_tail_sentinel()
555303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry          != actual_param_node->is_tail_sentinel()) {
556303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         printf("ir_call has the wrong number of parameters:\n");
557303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         goto dump_ir;
558303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      }
559303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      if (formal_param_node->is_tail_sentinel()) {
560303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         break;
561303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      }
562303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      const ir_variable *formal_param
563303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         = (const ir_variable *) formal_param_node;
564303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      const ir_rvalue *actual_param
565303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         = (const ir_rvalue *) actual_param_node;
566303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      if (formal_param->type != actual_param->type) {
567303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         printf("ir_call parameter type mismatch:\n");
568303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         goto dump_ir;
569303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      }
570303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      if (formal_param->mode == ir_var_out
571303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry          || formal_param->mode == ir_var_inout) {
572303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         if (!actual_param->is_lvalue()) {
573303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry            printf("ir_call out/inout parameters must be lvalues:\n");
574303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry            goto dump_ir;
575303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry         }
576303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      }
577303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      formal_param_node = formal_param_node->next;
578303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry      actual_param_node = actual_param_node->next;
579303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   }
580303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry
5818bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick   return visit_continue;
582303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry
583303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berrydump_ir:
584303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   ir->print();
585303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   printf("callee:\n");
586303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   callee->print();
587303e05cc249df3baeb3ed7654b0de00e7b9358fcPaul Berry   abort();
5888bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick}
5898bbfbb14eee53e42a488ba24c0cfc9ffa1cf6318Ian Romanick
590865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickvoid
591865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanickir_validate::validate_ir(ir_instruction *ir, void *data)
59253cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt{
593865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   struct hash_table *ht = (struct hash_table *) data;
59453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
595865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   if (hash_table_find(ht, ir)) {
596865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      printf("Instruction node present twice in ir tree:\n");
597865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      ir->print();
598865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      printf("\n");
599865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick      abort();
600865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   }
601865cf2d1f5e499916d360a246ad85554f3ff5b02Ian Romanick   hash_table_insert(ht, ir, ir);
60253cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt}
60353cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
60453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholtvoid
605d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholtcheck_node_type(ir_instruction *ir, void *data)
606d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt{
6077ffe40532f6b22d9b80caeac0fc3b9495619186aIan Romanick   (void) data;
6087ffe40532f6b22d9b80caeac0fc3b9495619186aIan Romanick
609d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) {
610d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      printf("Instruction node with unset type\n");
611d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      ir->print(); printf("\n");
612d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   }
613f141fa63a4391621cc92cd2c39724a952b297a58Eric Anholt   assert(ir->type != glsl_type::error_type);
614d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt}
615d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
616d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholtvoid
61753cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholtvalidate_ir_tree(exec_list *instructions)
61853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt{
61953cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt   ir_validate v;
62053cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt
62153cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt   v.run(instructions);
622d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
623d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   foreach_iter(exec_list_iterator, iter, *instructions) {
624d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      ir_instruction *ir = (ir_instruction *)iter.get();
625d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt
626d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt      visit_tree(ir, check_node_type, NULL);
627d16044ad4d6176fec6164f96450a25f76b7677f1Eric Anholt   }
62853cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt}
629