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