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