Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | 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. #include "ir_print_visitor.h"
  25. #include "glsl_types.h"
  26. #include "glsl_parser_extras.h"
  27. #include "main/macros.h"
  28. #include "program/hash_table.h"
  29.  
  30. static void print_type(const glsl_type *t);
  31.  
  32. void
  33. ir_instruction::print(void) const
  34. {
  35.    ir_instruction *deconsted = const_cast<ir_instruction *>(this);
  36.  
  37.    ir_print_visitor v;
  38.    deconsted->accept(&v);
  39. }
  40.  
  41. extern "C" {
  42. void
  43. _mesa_print_ir(exec_list *instructions,
  44.                struct _mesa_glsl_parse_state *state)
  45. {
  46.    if (state) {
  47.       for (unsigned i = 0; i < state->num_user_structures; i++) {
  48.          const glsl_type *const s = state->user_structures[i];
  49.  
  50.          printf("(structure (%s) (%s@%p) (%u) (\n",
  51.                 s->name, s->name, (void *) s, s->length);
  52.  
  53.          for (unsigned j = 0; j < s->length; j++) {
  54.             printf("\t((");
  55.             print_type(s->fields.structure[j].type);
  56.             printf(")(%s))\n", s->fields.structure[j].name);
  57.          }
  58.  
  59.          printf(")\n");
  60.       }
  61.    }
  62.  
  63.    printf("(\n");
  64.    foreach_iter(exec_list_iterator, iter, *instructions) {
  65.       ir_instruction *ir = (ir_instruction *)iter.get();
  66.       ir->print();
  67.       if (ir->ir_type != ir_type_function)
  68.          printf("\n");
  69.    }
  70.    printf("\n)");
  71. }
  72.  
  73. } /* extern "C" */
  74.  
  75. ir_print_visitor::ir_print_visitor()
  76. {
  77.    indentation = 0;
  78.    printable_names =
  79.       hash_table_ctor(32, hash_table_pointer_hash, hash_table_pointer_compare);
  80.    symbols = _mesa_symbol_table_ctor();
  81.    mem_ctx = ralloc_context(NULL);
  82. }
  83.  
  84. ir_print_visitor::~ir_print_visitor()
  85. {
  86.    hash_table_dtor(printable_names);
  87.    _mesa_symbol_table_dtor(symbols);
  88.    ralloc_free(mem_ctx);
  89. }
  90.  
  91. void ir_print_visitor::indent(void)
  92. {
  93.    for (int i = 0; i < indentation; i++)
  94.       printf("  ");
  95. }
  96.  
  97. const char *
  98. ir_print_visitor::unique_name(ir_variable *var)
  99. {
  100.    /* var->name can be NULL in function prototypes when a type is given for a
  101.     * parameter but no name is given.  In that case, just return an empty
  102.     * string.  Don't worry about tracking the generated name in the printable
  103.     * names hash because this is the only scope where it can ever appear.
  104.     */
  105.    if (var->name == NULL) {
  106.       static unsigned arg = 1;
  107.       return ralloc_asprintf(this->mem_ctx, "parameter@%u", arg++);
  108.    }
  109.  
  110.    /* Do we already have a name for this variable? */
  111.    const char *name = (const char *) hash_table_find(this->printable_names, var);
  112.    if (name != NULL)
  113.       return name;
  114.  
  115.    /* If there's no conflict, just use the original name */
  116.    if (_mesa_symbol_table_find_symbol(this->symbols, -1, var->name) == NULL) {
  117.       name = var->name;
  118.    } else {
  119.       static unsigned i = 1;
  120.       name = ralloc_asprintf(this->mem_ctx, "%s@%u", var->name, ++i);
  121.    }
  122.    hash_table_insert(this->printable_names, (void *) name, var);
  123.    _mesa_symbol_table_add_symbol(this->symbols, -1, name, var);
  124.    return name;
  125. }
  126.  
  127. static void
  128. print_type(const glsl_type *t)
  129. {
  130.    if (t->base_type == GLSL_TYPE_ARRAY) {
  131.       printf("(array ");
  132.       print_type(t->fields.array);
  133.       printf(" %u)", t->length);
  134.    } else if ((t->base_type == GLSL_TYPE_STRUCT)
  135.               && (strncmp("gl_", t->name, 3) != 0)) {
  136.       printf("%s@%p", t->name, (void *) t);
  137.    } else {
  138.       printf("%s", t->name);
  139.    }
  140. }
  141.  
  142. void ir_print_visitor::visit(ir_rvalue *ir)
  143. {
  144.    printf("error");
  145. }
  146.  
  147. void ir_print_visitor::visit(ir_variable *ir)
  148. {
  149.    printf("(declare ");
  150.  
  151.    const char *const cent = (ir->centroid) ? "centroid " : "";
  152.    const char *const inv = (ir->invariant) ? "invariant " : "";
  153.    const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
  154.                                 "in ", "out ", "inout ",
  155.                                 "const_in ", "sys ", "temporary " };
  156.    STATIC_ASSERT(ARRAY_SIZE(mode) == ir_var_mode_count);
  157.    const char *const interp[] = { "", "smooth", "flat", "noperspective" };
  158.    STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
  159.  
  160.    printf("(%s%s%s%s) ",
  161.           cent, inv, mode[ir->mode], interp[ir->interpolation]);
  162.  
  163.    print_type(ir->type);
  164.    printf(" %s)", unique_name(ir));
  165. }
  166.  
  167.  
  168. void ir_print_visitor::visit(ir_function_signature *ir)
  169. {
  170.    _mesa_symbol_table_push_scope(symbols);
  171.    printf("(signature ");
  172.    indentation++;
  173.  
  174.    print_type(ir->return_type);
  175.    printf("\n");
  176.    indent();
  177.  
  178.    printf("(parameters\n");
  179.    indentation++;
  180.  
  181.    foreach_iter(exec_list_iterator, iter, ir->parameters) {
  182.       ir_variable *const inst = (ir_variable *) iter.get();
  183.  
  184.       indent();
  185.       inst->accept(this);
  186.       printf("\n");
  187.    }
  188.    indentation--;
  189.  
  190.    indent();
  191.    printf(")\n");
  192.  
  193.    indent();
  194.  
  195.    printf("(\n");
  196.    indentation++;
  197.  
  198.    foreach_iter(exec_list_iterator, iter, ir->body) {
  199.       ir_instruction *const inst = (ir_instruction *) iter.get();
  200.  
  201.       indent();
  202.       inst->accept(this);
  203.       printf("\n");
  204.    }
  205.    indentation--;
  206.    indent();
  207.    printf("))\n");
  208.    indentation--;
  209.    _mesa_symbol_table_pop_scope(symbols);
  210. }
  211.  
  212.  
  213. void ir_print_visitor::visit(ir_function *ir)
  214. {
  215.    printf("(function %s\n", ir->name);
  216.    indentation++;
  217.    foreach_iter(exec_list_iterator, iter, *ir) {
  218.       ir_function_signature *const sig = (ir_function_signature *) iter.get();
  219.       indent();
  220.       sig->accept(this);
  221.       printf("\n");
  222.    }
  223.    indentation--;
  224.    indent();
  225.    printf(")\n\n");
  226. }
  227.  
  228.  
  229. void ir_print_visitor::visit(ir_expression *ir)
  230. {
  231.    printf("(expression ");
  232.  
  233.    print_type(ir->type);
  234.  
  235.    printf(" %s ", ir->operator_string());
  236.  
  237.    for (unsigned i = 0; i < ir->get_num_operands(); i++) {
  238.       ir->operands[i]->accept(this);
  239.    }
  240.  
  241.    printf(") ");
  242. }
  243.  
  244.  
  245. void ir_print_visitor::visit(ir_texture *ir)
  246. {
  247.    printf("(%s ", ir->opcode_string());
  248.  
  249.    print_type(ir->type);
  250.    printf(" ");
  251.  
  252.    ir->sampler->accept(this);
  253.    printf(" ");
  254.  
  255.    if (ir->op != ir_txs) {
  256.       ir->coordinate->accept(this);
  257.  
  258.       printf(" ");
  259.  
  260.       if (ir->offset != NULL) {
  261.          ir->offset->accept(this);
  262.       } else {
  263.          printf("0");
  264.       }
  265.  
  266.       printf(" ");
  267.    }
  268.  
  269.    if (ir->op != ir_txf && ir->op != ir_txf_ms && ir->op != ir_txs) {
  270.       if (ir->projector)
  271.          ir->projector->accept(this);
  272.       else
  273.          printf("1");
  274.  
  275.       if (ir->shadow_comparitor) {
  276.          printf(" ");
  277.          ir->shadow_comparitor->accept(this);
  278.       } else {
  279.          printf(" ()");
  280.       }
  281.    }
  282.  
  283.    printf(" ");
  284.    switch (ir->op)
  285.    {
  286.    case ir_tex:
  287.    case ir_lod:
  288.       break;
  289.    case ir_txb:
  290.       ir->lod_info.bias->accept(this);
  291.       break;
  292.    case ir_txl:
  293.    case ir_txf:
  294.    case ir_txs:
  295.       ir->lod_info.lod->accept(this);
  296.       break;
  297.    case ir_txf_ms:
  298.       ir->lod_info.sample_index->accept(this);
  299.       break;
  300.    case ir_txd:
  301.       printf("(");
  302.       ir->lod_info.grad.dPdx->accept(this);
  303.       printf(" ");
  304.       ir->lod_info.grad.dPdy->accept(this);
  305.       printf(")");
  306.       break;
  307.    };
  308.    printf(")");
  309. }
  310.  
  311.  
  312. void ir_print_visitor::visit(ir_swizzle *ir)
  313. {
  314.    const unsigned swiz[4] = {
  315.       ir->mask.x,
  316.       ir->mask.y,
  317.       ir->mask.z,
  318.       ir->mask.w,
  319.    };
  320.  
  321.    printf("(swiz ");
  322.    for (unsigned i = 0; i < ir->mask.num_components; i++) {
  323.       printf("%c", "xyzw"[swiz[i]]);
  324.    }
  325.    printf(" ");
  326.    ir->val->accept(this);
  327.    printf(")");
  328. }
  329.  
  330.  
  331. void ir_print_visitor::visit(ir_dereference_variable *ir)
  332. {
  333.    ir_variable *var = ir->variable_referenced();
  334.    printf("(var_ref %s) ", unique_name(var));
  335. }
  336.  
  337.  
  338. void ir_print_visitor::visit(ir_dereference_array *ir)
  339. {
  340.    printf("(array_ref ");
  341.    ir->array->accept(this);
  342.    ir->array_index->accept(this);
  343.    printf(") ");
  344. }
  345.  
  346.  
  347. void ir_print_visitor::visit(ir_dereference_record *ir)
  348. {
  349.    printf("(record_ref ");
  350.    ir->record->accept(this);
  351.    printf(" %s) ", ir->field);
  352. }
  353.  
  354.  
  355. void ir_print_visitor::visit(ir_assignment *ir)
  356. {
  357.    printf("(assign ");
  358.  
  359.    if (ir->condition)
  360.       ir->condition->accept(this);
  361.  
  362.    char mask[5];
  363.    unsigned j = 0;
  364.  
  365.    for (unsigned i = 0; i < 4; i++) {
  366.       if ((ir->write_mask & (1 << i)) != 0) {
  367.          mask[j] = "xyzw"[i];
  368.          j++;
  369.       }
  370.    }
  371.    mask[j] = '\0';
  372.  
  373.    printf(" (%s) ", mask);
  374.  
  375.    ir->lhs->accept(this);
  376.  
  377.    printf(" ");
  378.  
  379.    ir->rhs->accept(this);
  380.    printf(") ");
  381. }
  382.  
  383.  
  384. void ir_print_visitor::visit(ir_constant *ir)
  385. {
  386.    printf("(constant ");
  387.    print_type(ir->type);
  388.    printf(" (");
  389.  
  390.    if (ir->type->is_array()) {
  391.       for (unsigned i = 0; i < ir->type->length; i++)
  392.          ir->get_array_element(i)->accept(this);
  393.    } else if (ir->type->is_record()) {
  394.       ir_constant *value = (ir_constant *) ir->components.get_head();
  395.       for (unsigned i = 0; i < ir->type->length; i++) {
  396.          printf("(%s ", ir->type->fields.structure[i].name);
  397.          value->accept(this);
  398.          printf(")");
  399.  
  400.          value = (ir_constant *) value->next;
  401.       }
  402.    } else {
  403.       for (unsigned i = 0; i < ir->type->components(); i++) {
  404.          if (i != 0)
  405.             printf(" ");
  406.          switch (ir->type->base_type) {
  407.          case GLSL_TYPE_UINT:  printf("%u", ir->value.u[i]); break;
  408.          case GLSL_TYPE_INT:   printf("%d", ir->value.i[i]); break;
  409.          case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
  410.          case GLSL_TYPE_BOOL:  printf("%d", ir->value.b[i]); break;
  411.          default: assert(0);
  412.          }
  413.       }
  414.    }
  415.    printf(")) ");
  416. }
  417.  
  418.  
  419. void
  420. ir_print_visitor::visit(ir_call *ir)
  421. {
  422.    printf("(call %s ", ir->callee_name());
  423.    if (ir->return_deref)
  424.       ir->return_deref->accept(this);
  425.    printf(" (");
  426.    foreach_iter(exec_list_iterator, iter, *ir) {
  427.       ir_instruction *const inst = (ir_instruction *) iter.get();
  428.  
  429.       inst->accept(this);
  430.    }
  431.    printf("))\n");
  432. }
  433.  
  434.  
  435. void
  436. ir_print_visitor::visit(ir_return *ir)
  437. {
  438.    printf("(return");
  439.  
  440.    ir_rvalue *const value = ir->get_value();
  441.    if (value) {
  442.       printf(" ");
  443.       value->accept(this);
  444.    }
  445.  
  446.    printf(")");
  447. }
  448.  
  449.  
  450. void
  451. ir_print_visitor::visit(ir_discard *ir)
  452. {
  453.    printf("(discard ");
  454.  
  455.    if (ir->condition != NULL) {
  456.       printf(" ");
  457.       ir->condition->accept(this);
  458.    }
  459.  
  460.    printf(")");
  461. }
  462.  
  463.  
  464. void
  465. ir_print_visitor::visit(ir_if *ir)
  466. {
  467.    printf("(if ");
  468.    ir->condition->accept(this);
  469.  
  470.    printf("(\n");
  471.    indentation++;
  472.  
  473.    foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
  474.       ir_instruction *const inst = (ir_instruction *) iter.get();
  475.  
  476.       indent();
  477.       inst->accept(this);
  478.       printf("\n");
  479.    }
  480.  
  481.    indentation--;
  482.    indent();
  483.    printf(")\n");
  484.  
  485.    indent();
  486.    if (!ir->else_instructions.is_empty()) {
  487.       printf("(\n");
  488.       indentation++;
  489.  
  490.       foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
  491.          ir_instruction *const inst = (ir_instruction *) iter.get();
  492.  
  493.          indent();
  494.          inst->accept(this);
  495.          printf("\n");
  496.       }
  497.       indentation--;
  498.       indent();
  499.       printf("))\n");
  500.    } else {
  501.       printf("())\n");
  502.    }
  503. }
  504.  
  505.  
  506. void
  507. ir_print_visitor::visit(ir_loop *ir)
  508. {
  509.    printf("(loop (");
  510.    if (ir->counter != NULL)
  511.       ir->counter->accept(this);
  512.    printf(") (");
  513.    if (ir->from != NULL)
  514.       ir->from->accept(this);
  515.    printf(") (");
  516.    if (ir->to != NULL)
  517.       ir->to->accept(this);
  518.    printf(") (");
  519.    if (ir->increment != NULL)
  520.       ir->increment->accept(this);
  521.    printf(") (\n");
  522.    indentation++;
  523.  
  524.    foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
  525.       ir_instruction *const inst = (ir_instruction *) iter.get();
  526.  
  527.       indent();
  528.       inst->accept(this);
  529.       printf("\n");
  530.    }
  531.    indentation--;
  532.    indent();
  533.    printf("))\n");
  534. }
  535.  
  536.  
  537. void
  538. ir_print_visitor::visit(ir_loop_jump *ir)
  539. {
  540.    printf("%s", ir->is_break() ? "break" : "continue");
  541. }
  542.