Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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(ralloc_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(ralloc_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.