* a dereference chain.
*/
-#include <inttypes.h>
#include "ir.h"
#include "ir_hierarchical_visitor.h"
#include "program/hash_table.h"
virtual ir_visitor_status visit(ir_variable *v);
virtual ir_visitor_status visit(ir_dereference_variable *ir);
- virtual ir_visitor_status visit(ir_if *ir);
+
+ virtual ir_visitor_status visit_enter(ir_if *ir);
virtual ir_visitor_status visit_leave(ir_loop *ir);
virtual ir_visitor_status visit_enter(ir_function *ir);
virtual ir_visitor_status visit_leave(ir_swizzle *ir);
virtual ir_visitor_status visit_enter(ir_assignment *ir);
+ virtual ir_visitor_status visit_enter(ir_call *ir);
static void validate_ir(ir_instruction *ir, void *data);
}
ir_visitor_status
-ir_validate::visit(ir_if *ir)
+ir_validate::visit_enter(ir_if *ir)
{
if (ir->condition->type != glsl_type::bool_type) {
printf("ir_if condition %s type instead of bool.\n",
this->validate_ir(ir, this->data);
+ /* Verify that all of the things stored in the list of signatures are,
+ * in fact, function signatures.
+ */
+ foreach_list(node, &ir->signatures) {
+ ir_instruction *sig = (ir_instruction *) node;
+
+ if (sig->ir_type != ir_type_function_signature) {
+ printf("Non-signature in signature list of function `%s'\n",
+ ir->name);
+ abort();
+ }
+ }
+
return visit_continue;
}
ir_visitor_status
ir_validate::visit_leave(ir_function *ir)
{
- assert(talloc_parent(ir->name) == ir);
+ assert(ralloc_parent(ir->name) == ir);
this->current_function = NULL;
return visit_continue;
abort();
}
+ if (ir->return_type == NULL) {
+ printf("Function signature %p for function %s has NULL return type.\n",
+ (void *) ir, ir->function_name());
+ abort();
+ }
+
this->validate_ir(ir, this->data);
return visit_continue;
assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
break;
+ case ir_unop_i2u:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+ assert(ir->type->base_type == GLSL_TYPE_UINT);
+ break;
+ case ir_unop_u2i:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+ assert(ir->type->base_type == GLSL_TYPE_INT);
+ break;
case ir_unop_any:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
* declared before it is dereferenced.
*/
if (ir->name)
- assert(talloc_parent(ir->name) == ir);
+ assert(ralloc_parent(ir->name) == ir);
hash_table_insert(ht, ir, ir);
+
+
+ /* If a variable is an array, verify that the maximum array index is in
+ * bounds. There was once an error in AST-to-HIR conversion that set this
+ * to be out of bounds.
+ */
+ if (ir->type->array_size() > 0) {
+ if (ir->max_array_access >= ir->type->length) {
+ printf("ir_variable has maximum access out of bounds (%d vs %d)\n",
+ ir->max_array_access, ir->type->length - 1);
+ ir->print();
+ abort();
+ }
+ }
+
+ if (ir->constant_initializer != NULL && !ir->has_initializer) {
+ printf("ir_variable didn't have an initializer, but has a constant "
+ "initializer value.\n");
+ ir->print();
+ abort();
+ }
+
return visit_continue;
}
return visit_continue;
}
+ir_visitor_status
+ir_validate::visit_enter(ir_call *ir)
+{
+ ir_function_signature *const callee = ir->get_callee();
+
+ if (callee->ir_type != ir_type_function_signature) {
+ printf("IR called by ir_call is not ir_function_signature!\n");
+ abort();
+ }
+
+ const exec_node *formal_param_node = callee->parameters.head;
+ const exec_node *actual_param_node = ir->actual_parameters.head;
+ while (true) {
+ if (formal_param_node->is_tail_sentinel()
+ != actual_param_node->is_tail_sentinel()) {
+ printf("ir_call has the wrong number of parameters:\n");
+ goto dump_ir;
+ }
+ if (formal_param_node->is_tail_sentinel()) {
+ break;
+ }
+ const ir_variable *formal_param
+ = (const ir_variable *) formal_param_node;
+ const ir_rvalue *actual_param
+ = (const ir_rvalue *) actual_param_node;
+ if (formal_param->type != actual_param->type) {
+ printf("ir_call parameter type mismatch:\n");
+ goto dump_ir;
+ }
+ if (formal_param->mode == ir_var_out
+ || formal_param->mode == ir_var_inout) {
+ if (!actual_param->is_lvalue()) {
+ printf("ir_call out/inout parameters must be lvalues:\n");
+ goto dump_ir;
+ }
+ }
+ formal_param_node = formal_param_node->next;
+ actual_param_node = actual_param_node->next;
+ }
+
+ return visit_continue;
+
+dump_ir:
+ ir->print();
+ printf("callee:\n");
+ callee->print();
+ abort();
+ return visit_stop;
+}
+
void
ir_validate::validate_ir(ir_instruction *ir, void *data)
{