Subversion Repositories Kolibri OS

Rev

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