1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2010 Intel Corporation
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DEALINGS IN THE SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file ir_validate.cpp
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Attempts to verify that various invariants of the IR tree are true.
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * In particular, at the moment it makes sure that no single
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ir_instruction node except for ir_variable appears multiple times
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in the ir tree.  ir_variable does appear multiple times: Once as a
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * declaration in an exec_list, and multiple times as the endpoint of
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a dereference chain.
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "ir_hierarchical_visitor.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "program/hash_table.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "glsl_types.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass ir_validate : public ir_hierarchical_visitor {
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_validate()
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->ht = hash_table_ctor(0, hash_table_pointer_hash,
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 hash_table_pointer_compare);
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->current_function = NULL;
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->callback = ir_validate::validate_ir;
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      this->data = ht;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ~ir_validate()
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   {
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      hash_table_dtor(this->ht);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit(ir_variable *v);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit(ir_dereference_variable *ir);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_enter(ir_if *ir);
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_leave(ir_loop *ir);
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_enter(ir_function *ir);
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_leave(ir_function *ir);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_enter(ir_function_signature *ir);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_leave(ir_expression *ir);
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_leave(ir_swizzle *ir);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_enter(ir_assignment *ir);
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   virtual ir_visitor_status visit_enter(ir_call *ir);
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   static void validate_ir(ir_instruction *ir, void *data);
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_function *current_function;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct hash_table *ht;
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit(ir_dereference_variable *ir)
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((ir->var == NULL) || (ir->var->as_variable() == NULL)) {
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("ir_dereference_variable @ %p does not specify a variable %p\n",
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     (void *) ir, (void *) ir->var);
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (hash_table_find(ht, ir->var) == NULL) {
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("ir_dereference_variable @ %p specifies undeclared variable "
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     "`%s' @ %p\n",
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     (void *) ir, ir->var->name, (void *) ir->var);
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->validate_ir(ir, this->data);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_enter(ir_if *ir)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->condition->type != glsl_type::bool_type) {
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("ir_if condition %s type instead of bool.\n",
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ir->condition->type->name);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->print();
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("\n");
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_leave(ir_loop *ir)
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->counter != NULL) {
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((ir->from == NULL) || (ir->to == NULL) || (ir->increment == NULL)) {
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("ir_loop has invalid loop controls:\n"
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    counter:   %p\n"
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    from:      %p\n"
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    to:        %p\n"
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    increment: %p\n",
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                (void *) ir->increment);
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) {
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("ir_loop has invalid comparitor %d\n", ir->cmp);
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((ir->from != NULL) || (ir->to != NULL) || (ir->increment != NULL)) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("ir_loop has invalid loop controls:\n"
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    counter:   %p\n"
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    from:      %p\n"
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    to:        %p\n"
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"    increment: %p\n",
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		(void *) ir->counter, (void *) ir->from, (void *) ir->to,
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                (void *) ir->increment);
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_enter(ir_function *ir)
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Function definitions cannot be nested.
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->current_function != NULL) {
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("Function definition nested inside another function "
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     "definition:\n");
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("%s %p inside %s %p\n",
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ir->name, (void *) ir,
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     this->current_function->name, (void *) this->current_function);
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Store the current function hierarchy being traversed.  This is used
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * by the function signature visitor to ensure that the signatures are
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * linked with the correct functions.
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->current_function = ir;
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->validate_ir(ir, this->data);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Verify that all of the things stored in the list of signatures are,
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * in fact, function signatures.
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_list(node, &ir->signatures) {
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_instruction *sig = (ir_instruction *) node;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (sig->ir_type != ir_type_function_signature) {
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("Non-signature in signature list of function `%s'\n",
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ir->name);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_leave(ir_function *ir)
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(ralloc_parent(ir->name) == ir);
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->current_function = NULL;
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_enter(ir_function_signature *ir)
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (this->current_function != ir->function()) {
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("Function signature nested inside wrong function "
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     "definition:\n");
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("%p inside %s %p instead of %s %p\n",
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     (void *) ir,
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     this->current_function->name, (void *) this->current_function,
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     ir->function_name(), (void *) ir->function());
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->return_type == NULL) {
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("Function signature %p for function %s has NULL return type.\n",
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     (void *) ir, ir->function_name());
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->validate_ir(ir, this->data);
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_leave(ir_expression *ir)
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (ir->operation) {
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bit_not:
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == ir->type);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_logic_not:
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_BOOL);
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_neg:
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_abs:
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sign:
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_rcp:
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_rsq:
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sqrt:
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type == ir->operands[0]->type);
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_exp:
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_log:
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_exp2:
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_log2:
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type == ir->operands[0]->type);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2i:
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_INT);
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2u:
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_UINT);
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2f:
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_f2b:
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_BOOL);
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_b2f:
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2b:
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_BOOL);
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_b2i:
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_INT);
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_u2f:
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_i2u:
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_UINT);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_u2i:
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_INT);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_i2f:
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_f2i:
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_INT);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_u2f:
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_FLOAT);
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_bitcast_f2u:
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_UINT);
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_any:
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type == glsl_type::bool_type);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_trunc:
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_round_even:
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_ceil:
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_floor:
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_fract:
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sin:
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_cos:
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_sin_reduced:
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_cos_reduced:
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_dFdx:
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_dFdy:
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == ir->type);
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_unop_noise:
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* XXX what can we assert here? */
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_add:
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_sub:
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mul:
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_div:
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_mod:
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_min:
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_max:
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_pow:
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->operands[0]->type->is_scalar())
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[1]->type == ir->type);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (ir->operands[1]->type->is_scalar())
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type == ir->type);
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else if (ir->operands[0]->type->is_vector() &&
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	       ir->operands[1]->type->is_vector()) {
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type == ir->operands[1]->type);
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type == ir->type);
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_less:
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_greater:
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_lequal:
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_gequal:
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_equal:
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_nequal:
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The semantics of the IR operators differ from the GLSL <, >, <=, >=,
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * ==, and != operators.  The IR operators perform a component-wise
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * comparison on scalar or vector types and return a boolean scalar or
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * vector type of the same size.
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->base_type == GLSL_TYPE_BOOL);
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == ir->operands[1]->type);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->is_vector()
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     || ir->operands[0]->type->is_scalar());
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->vector_elements
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     == ir->type->vector_elements);
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_all_equal:
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_any_nequal:
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* GLSL == and != operate on scalars, vectors, matrices and arrays, and
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * return a scalar boolean.  The IR matches that.
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type == glsl_type::bool_type);
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == ir->operands[1]->type);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_lshift:
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_rshift:
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->is_integer() &&
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             ir->operands[1]->type->is_integer());
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->operands[0]->type->is_scalar()) {
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          assert(ir->operands[1]->type->is_scalar());
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->operands[0]->type->is_vector() &&
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          ir->operands[1]->type->is_vector()) {
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          assert(ir->operands[0]->type->components() ==
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 ir->operands[1]->type->components());
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type == ir->operands[0]->type);
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_and:
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_xor:
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_bit_or:
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       assert(ir->operands[0]->type->base_type ==
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              ir->operands[1]->type->base_type);
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       assert(ir->type->is_integer());
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (ir->operands[0]->type->is_vector() &&
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           ir->operands[1]->type->is_vector()) {
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           assert(ir->operands[0]->type->vector_elements ==
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  ir->operands[1]->type->vector_elements);
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       break;
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_and:
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_xor:
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_logic_or:
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type == glsl_type::bool_type);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == glsl_type::bool_type);
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[1]->type == glsl_type::bool_type);
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_dot:
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type == glsl_type::float_type);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type->is_vector());
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == ir->operands[1]->type);
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_binop_ubo_load:
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->as_constant());
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[0]->type == glsl_type::uint_type);
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->operands[1]->type == glsl_type::uint_type);
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case ir_quadop_vector:
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* The vector operator collects some number of scalars and generates a
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * vector from them.
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *  - All of the operands must be scalar.
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *  - Number of operands must matche the size of the resulting vector.
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *  - Base type of the operands must match the base type of the result.
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ir->type->is_vector());
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (ir->type->vector_elements) {
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case 2:
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type->is_scalar());
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[1]->type->is_scalar());
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[2] == NULL);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[3] == NULL);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case 3:
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type->is_scalar());
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[1]->type->is_scalar());
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[2]->type->is_scalar());
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[3] == NULL);
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case 4:
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type->is_scalar());
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[0]->type->base_type == ir->type->base_type);
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[1]->type->is_scalar());
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[1]->type->base_type == ir->type->base_type);
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[2]->type->is_scalar());
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[2]->type->base_type == ir->type->base_type);
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[3]->type->is_scalar());
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(ir->operands[3]->type->base_type == ir->type->base_type);
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 /* The is_vector assertion above should prevent execution from ever
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  * getting here.
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  */
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 assert(!"Should not get here.");
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 break;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_leave(ir_swizzle *ir)
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int chans[4] = {ir->mask.x, ir->mask.y, ir->mask.z, ir->mask.w};
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned int i = 0; i < ir->type->vector_elements; i++) {
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (chans[i] >= ir->val->type->vector_elements) {
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("ir_swizzle @ %p specifies a channel not present "
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"in the value.\n", (void *) ir);
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir->print();
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit(ir_variable *ir)
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* An ir_variable is the one thing that can (and will) appear multiple times
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * in an IR tree.  It is added to the hashtable so that it can be used
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * in the ir_dereference_variable handler to ensure that a variable is
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * declared before it is dereferenced.
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->name)
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(ralloc_parent(ir->name) == ir);
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   hash_table_insert(ht, ir, ir);
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* If a variable is an array, verify that the maximum array index is in
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * bounds.  There was once an error in AST-to-HIR conversion that set this
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * to be out of bounds.
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    */
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->type->array_size() > 0) {
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->max_array_access >= ir->type->length) {
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("ir_variable has maximum access out of bounds (%d vs %d)\n",
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ir->max_array_access, ir->type->length - 1);
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir->print();
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->constant_initializer != NULL && !ir->has_initializer) {
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("ir_variable didn't have an initializer, but has a constant "
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     "initializer value.\n");
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->print();
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_enter(ir_assignment *ir)
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const ir_dereference *const lhs = ir->lhs;
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->write_mask == 0) {
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("Assignment LHS is %s, but write mask is 0:\n",
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		lhs->type->is_scalar() ? "scalar" : "vector");
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir->print();
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int lhs_components = 0;
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (int i = 0; i < 4; i++) {
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (ir->write_mask & (1 << i))
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    lhs_components++;
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (lhs_components != ir->rhs->type->vector_elements) {
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("Assignment count of LHS write mask channels enabled not\n"
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		"matching RHS vector size (%d LHS, %d RHS).\n",
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		lhs_components, ir->rhs->type->vector_elements);
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 ir->print();
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   this->validate_ir(ir, this->data);
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_visitor_status
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::visit_enter(ir_call *ir)
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_function_signature *const callee = ir->callee;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (callee->ir_type != ir_type_function_signature) {
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("IR called by ir_call is not ir_function_signature!\n");
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->return_deref) {
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ir->return_deref->type != callee->return_type) {
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 printf("callee type %s does not match return storage type %s\n",
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	        callee->return_type->name, ir->return_deref->type->name);
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 abort();
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else if (callee->return_type != glsl_type::void_type) {
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("ir_call has non-void callee but no return storage\n");
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const exec_node *formal_param_node = callee->parameters.head;
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const exec_node *actual_param_node = ir->actual_parameters.head;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (true) {
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (formal_param_node->is_tail_sentinel()
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          != actual_param_node->is_tail_sentinel()) {
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         printf("ir_call has the wrong number of parameters:\n");
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto dump_ir;
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (formal_param_node->is_tail_sentinel()) {
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const ir_variable *formal_param
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         = (const ir_variable *) formal_param_node;
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const ir_rvalue *actual_param
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         = (const ir_rvalue *) actual_param_node;
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (formal_param->type != actual_param->type) {
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         printf("ir_call parameter type mismatch:\n");
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         goto dump_ir;
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (formal_param->mode == ir_var_out
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          || formal_param->mode == ir_var_inout) {
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!actual_param->is_lvalue()) {
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            printf("ir_call out/inout parameters must be lvalues:\n");
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto dump_ir;
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      formal_param_node = formal_param_node->next;
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      actual_param_node = actual_param_node->next;
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_continue;
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdump_ir:
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir->print();
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   printf("callee:\n");
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   callee->print();
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   abort();
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return visit_stop;
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgir_validate::validate_ir(ir_instruction *ir, void *data)
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct hash_table *ht = (struct hash_table *) data;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (hash_table_find(ht, ir)) {
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("Instruction node present twice in ir tree:\n");
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->print();
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("\n");
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   hash_table_insert(ht, ir, ir);
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcheck_node_type(ir_instruction *ir, void *data)
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) data;
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ir->ir_type <= ir_type_unset || ir->ir_type >= ir_type_max) {
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      printf("Instruction node with unset type\n");
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir->print(); printf("\n");
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_rvalue *value = ir->as_rvalue();
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (value != NULL)
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(value->type != glsl_type::error_type);
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvalidate_ir_tree(exec_list *instructions)
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ir_validate v;
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   v.run(instructions);
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   foreach_iter(exec_list_iterator, iter, *instructions) {
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ir_instruction *ir = (ir_instruction *)iter.get();
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      visit_tree(ir, check_node_type, NULL);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
670