Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2014 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 DEALINGS
  21.  * IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Connor Abbott (cwabbott0@gmail.com)
  25.  *
  26.  */
  27.  
  28. #include "nir.h"
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31.  
  32. static void
  33. print_tabs(unsigned num_tabs, FILE *fp)
  34. {
  35.    for (unsigned i = 0; i < num_tabs; i++)
  36.       fprintf(fp, "\t");
  37. }
  38.  
  39. typedef struct {
  40.    /** map from nir_variable -> printable name */
  41.    struct hash_table *ht;
  42.  
  43.    /** set of names used so far for nir_variables */
  44.    struct set *syms;
  45.  
  46.    /* an index used to make new non-conflicting names */
  47.    unsigned index;
  48. } print_var_state;
  49.  
  50. static void
  51. print_register(nir_register *reg, FILE *fp)
  52. {
  53.    if (reg->name != NULL)
  54.       fprintf(fp, "/* %s */ ", reg->name);
  55.    if (reg->is_global)
  56.       fprintf(fp, "gr%u", reg->index);
  57.    else
  58.       fprintf(fp, "r%u", reg->index);
  59. }
  60.  
  61. static const char *sizes[] = { "error", "vec1", "vec2", "vec3", "vec4" };
  62.  
  63. static void
  64. print_register_decl(nir_register *reg, FILE *fp)
  65. {
  66.    fprintf(fp, "decl_reg %s ", sizes[reg->num_components]);
  67.    if (reg->is_packed)
  68.       fprintf(fp, "(packed) ");
  69.    print_register(reg, fp);
  70.    if (reg->num_array_elems != 0)
  71.       fprintf(fp, "[%u]", reg->num_array_elems);
  72.    fprintf(fp, "\n");
  73. }
  74.  
  75. static void
  76. print_ssa_def(nir_ssa_def *def, FILE *fp)
  77. {
  78.    if (def->name != NULL)
  79.       fprintf(fp, "/* %s */ ", def->name);
  80.    fprintf(fp, "%s ssa_%u", sizes[def->num_components], def->index);
  81. }
  82.  
  83. static void
  84. print_ssa_use(nir_ssa_def *def, FILE *fp)
  85. {
  86.    if (def->name != NULL)
  87.       fprintf(fp, "/* %s */ ", def->name);
  88.    fprintf(fp, "ssa_%u", def->index);
  89. }
  90.  
  91. static void print_src(nir_src *src, FILE *fp);
  92.  
  93. static void
  94. print_reg_src(nir_reg_src *src, FILE *fp)
  95. {
  96.    print_register(src->reg, fp);
  97.    if (src->reg->num_array_elems != 0) {
  98.       fprintf(fp, "[%u", src->base_offset);
  99.       if (src->indirect != NULL) {
  100.          fprintf(fp, " + ");
  101.          print_src(src->indirect, fp);
  102.       }
  103.       fprintf(fp, "]");
  104.    }
  105. }
  106.  
  107. static void
  108. print_reg_dest(nir_reg_dest *dest, FILE *fp)
  109. {
  110.    print_register(dest->reg, fp);
  111.    if (dest->reg->num_array_elems != 0) {
  112.       fprintf(fp, "[%u", dest->base_offset);
  113.       if (dest->indirect != NULL) {
  114.          fprintf(fp, " + ");
  115.          print_src(dest->indirect, fp);
  116.       }
  117.       fprintf(fp, "]");
  118.    }
  119. }
  120.  
  121. static void
  122. print_src(nir_src *src, FILE *fp)
  123. {
  124.    if (src->is_ssa)
  125.       print_ssa_use(src->ssa, fp);
  126.    else
  127.       print_reg_src(&src->reg, fp);
  128. }
  129.  
  130. static void
  131. print_dest(nir_dest *dest, FILE *fp)
  132. {
  133.    if (dest->is_ssa)
  134.       print_ssa_def(&dest->ssa, fp);
  135.    else
  136.       print_reg_dest(&dest->reg, fp);
  137. }
  138.  
  139. static void
  140. print_alu_src(nir_alu_instr *instr, unsigned src, FILE *fp)
  141. {
  142.    if (instr->src[src].negate)
  143.       fprintf(fp, "-");
  144.    if (instr->src[src].abs)
  145.       fprintf(fp, "abs(");
  146.  
  147.    print_src(&instr->src[src].src, fp);
  148.  
  149.    bool print_swizzle = false;
  150.    for (unsigned i = 0; i < 4; i++) {
  151.       if (!nir_alu_instr_channel_used(instr, src, i))
  152.          continue;
  153.  
  154.       if (instr->src[src].swizzle[i] != i) {
  155.          print_swizzle = true;
  156.          break;
  157.       }
  158.    }
  159.  
  160.    if (print_swizzle) {
  161.       fprintf(fp, ".");
  162.       for (unsigned i = 0; i < 4; i++) {
  163.          if (!nir_alu_instr_channel_used(instr, src, i))
  164.             continue;
  165.  
  166.          fprintf(fp, "%c", "xyzw"[instr->src[src].swizzle[i]]);
  167.       }
  168.    }
  169.  
  170.    if (instr->src[src].abs)
  171.       fprintf(fp, ")");
  172. }
  173.  
  174. static void
  175. print_alu_dest(nir_alu_dest *dest, FILE *fp)
  176. {
  177.    /* we're going to print the saturate modifier later, after the opcode */
  178.  
  179.    print_dest(&dest->dest, fp);
  180.  
  181.    if (!dest->dest.is_ssa &&
  182.        dest->write_mask != (1 << dest->dest.reg.reg->num_components) - 1) {
  183.       fprintf(fp, ".");
  184.       for (unsigned i = 0; i < 4; i++)
  185.          if ((dest->write_mask >> i) & 1)
  186.             fprintf(fp, "%c", "xyzw"[i]);
  187.    }
  188. }
  189.  
  190. static void
  191. print_alu_instr(nir_alu_instr *instr, FILE *fp)
  192. {
  193.    print_alu_dest(&instr->dest, fp);
  194.  
  195.    fprintf(fp, " = %s", nir_op_infos[instr->op].name);
  196.    if (instr->dest.saturate)
  197.       fprintf(fp, ".sat");
  198.    fprintf(fp, " ");
  199.  
  200.    for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
  201.       if (i != 0)
  202.          fprintf(fp, ", ");
  203.  
  204.       print_alu_src(instr, i, fp);
  205.    }
  206. }
  207.  
  208. static void
  209. print_var_decl(nir_variable *var, print_var_state *state, FILE *fp)
  210. {
  211.    fprintf(fp, "decl_var ");
  212.  
  213.    const char *const cent = (var->data.centroid) ? "centroid " : "";
  214.    const char *const samp = (var->data.sample) ? "sample " : "";
  215.    const char *const inv = (var->data.invariant) ? "invariant " : "";
  216.    const char *const mode[] = { "shader_in ", "shader_out ", "", "",
  217.                                 "uniform ", "system " };
  218.    const char *const interp[] = { "", "smooth", "flat", "noperspective" };
  219.  
  220.    fprintf(fp, "%s%s%s%s%s ",
  221.       cent, samp, inv, mode[var->data.mode], interp[var->data.interpolation]);
  222.  
  223.    glsl_print_type(var->type, fp);
  224.  
  225.    struct set_entry *entry = NULL;
  226.    if (state)
  227.       entry = _mesa_set_search(state->syms, var->name);
  228.  
  229.    char *name;
  230.  
  231.    if (entry != NULL) {
  232.       /* we have a collision with another name, append an @ + a unique index */
  233.       name = ralloc_asprintf(state->syms, "%s@%u", var->name, state->index++);
  234.    } else {
  235.       name = var->name;
  236.    }
  237.  
  238.    fprintf(fp, " %s", name);
  239.  
  240.    if (var->data.mode == nir_var_shader_in ||
  241.        var->data.mode == nir_var_shader_out ||
  242.        var->data.mode == nir_var_uniform) {
  243.       fprintf(fp, " (%u, %u)", var->data.location, var->data.driver_location);
  244.    }
  245.  
  246.    fprintf(fp, "\n");
  247.  
  248.    if (state) {
  249.       _mesa_set_add(state->syms, name);
  250.       _mesa_hash_table_insert(state->ht, var, name);
  251.    }
  252. }
  253.  
  254. static void
  255. print_var(nir_variable *var, print_var_state *state, FILE *fp)
  256. {
  257.    const char *name;
  258.    if (state) {
  259.       struct hash_entry *entry = _mesa_hash_table_search(state->ht, var);
  260.  
  261.       assert(entry != NULL);
  262.       name = entry->data;
  263.    } else {
  264.       name = var->name;
  265.    }
  266.  
  267.    fprintf(fp, "%s", name);
  268. }
  269.  
  270. static void
  271. print_deref_var(nir_deref_var *deref, print_var_state *state, FILE *fp)
  272. {
  273.    print_var(deref->var, state, fp);
  274. }
  275.  
  276. static void
  277. print_deref_array(nir_deref_array *deref, print_var_state *state, FILE *fp)
  278. {
  279.    fprintf(fp, "[");
  280.    switch (deref->deref_array_type) {
  281.    case nir_deref_array_type_direct:
  282.       fprintf(fp, "%u", deref->base_offset);
  283.       break;
  284.    case nir_deref_array_type_indirect:
  285.       if (deref->base_offset != 0)
  286.          fprintf(fp, "%u + ", deref->base_offset);
  287.       print_src(&deref->indirect, fp);
  288.       break;
  289.    case nir_deref_array_type_wildcard:
  290.       fprintf(fp, "*");
  291.       break;
  292.    }
  293.    fprintf(fp, "]");
  294. }
  295.  
  296. static void
  297. print_deref_struct(nir_deref_struct *deref, const struct glsl_type *parent_type,
  298.                    print_var_state *state, FILE *fp)
  299. {
  300.    fprintf(fp, ".%s", glsl_get_struct_elem_name(parent_type, deref->index));
  301. }
  302.  
  303. static void
  304. print_deref(nir_deref_var *deref, print_var_state *state, FILE *fp)
  305. {
  306.    nir_deref *tail = &deref->deref;
  307.    nir_deref *pretail = NULL;
  308.    while (tail != NULL) {
  309.       switch (tail->deref_type) {
  310.       case nir_deref_type_var:
  311.          assert(pretail == NULL);
  312.          assert(tail == &deref->deref);
  313.          print_deref_var(deref, state, fp);
  314.          break;
  315.  
  316.       case nir_deref_type_array:
  317.          assert(pretail != NULL);
  318.          print_deref_array(nir_deref_as_array(tail), state, fp);
  319.          break;
  320.  
  321.       case nir_deref_type_struct:
  322.          assert(pretail != NULL);
  323.          print_deref_struct(nir_deref_as_struct(tail),
  324.                             pretail->type, state, fp);
  325.          break;
  326.  
  327.       default:
  328.          unreachable("Invalid deref type");
  329.       }
  330.  
  331.       pretail = tail;
  332.       tail = pretail->child;
  333.    }
  334. }
  335.  
  336. static void
  337. print_intrinsic_instr(nir_intrinsic_instr *instr, print_var_state *state,
  338.                       FILE *fp)
  339. {
  340.    unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs;
  341.  
  342.    if (nir_intrinsic_infos[instr->intrinsic].has_dest) {
  343.       print_dest(&instr->dest, fp);
  344.       fprintf(fp, " = ");
  345.    }
  346.  
  347.    fprintf(fp, "intrinsic %s (", nir_intrinsic_infos[instr->intrinsic].name);
  348.  
  349.    for (unsigned i = 0; i < num_srcs; i++) {
  350.       if (i != 0)
  351.          fprintf(fp, ", ");
  352.  
  353.       print_src(&instr->src[i], fp);
  354.    }
  355.  
  356.    fprintf(fp, ") (");
  357.  
  358.    unsigned num_vars = nir_intrinsic_infos[instr->intrinsic].num_variables;
  359.  
  360.    for (unsigned i = 0; i < num_vars; i++) {
  361.       if (i != 0)
  362.          fprintf(fp, ", ");
  363.  
  364.       print_deref(instr->variables[i], state, fp);
  365.    }
  366.  
  367.    fprintf(fp, ") (");
  368.  
  369.    unsigned num_indices = nir_intrinsic_infos[instr->intrinsic].num_indices;
  370.  
  371.    for (unsigned i = 0; i < num_indices; i++) {
  372.       if (i != 0)
  373.          fprintf(fp, ", ");
  374.  
  375.       fprintf(fp, "%u", instr->const_index[i]);
  376.    }
  377.  
  378.    fprintf(fp, ")");
  379. }
  380.  
  381. static void
  382. print_tex_instr(nir_tex_instr *instr, print_var_state *state, FILE *fp)
  383. {
  384.    print_dest(&instr->dest, fp);
  385.  
  386.    fprintf(fp, " = ");
  387.  
  388.    switch (instr->op) {
  389.    case nir_texop_tex:
  390.       fprintf(fp, "tex ");
  391.       break;
  392.    case nir_texop_txb:
  393.       fprintf(fp, "txb ");
  394.       break;
  395.    case nir_texop_txl:
  396.       fprintf(fp, "txl ");
  397.       break;
  398.    case nir_texop_txd:
  399.       fprintf(fp, "txd ");
  400.       break;
  401.    case nir_texop_txf:
  402.       fprintf(fp, "txf ");
  403.       break;
  404.    case nir_texop_txf_ms:
  405.       fprintf(fp, "txf_ms ");
  406.       break;
  407.    case nir_texop_txs:
  408.       fprintf(fp, "txs ");
  409.       break;
  410.    case nir_texop_lod:
  411.       fprintf(fp, "lod ");
  412.       break;
  413.    case nir_texop_tg4:
  414.       fprintf(fp, "tg4 ");
  415.       break;
  416.    case nir_texop_query_levels:
  417.       fprintf(fp, "query_levels ");
  418.       break;
  419.  
  420.    default:
  421.       unreachable("Invalid texture operation");
  422.       break;
  423.    }
  424.  
  425.    for (unsigned i = 0; i < instr->num_srcs; i++) {
  426.       print_src(&instr->src[i].src, fp);
  427.  
  428.       fprintf(fp, " ");
  429.  
  430.       switch(instr->src[i].src_type) {
  431.       case nir_tex_src_coord:
  432.          fprintf(fp, "(coord)");
  433.          break;
  434.       case nir_tex_src_projector:
  435.          fprintf(fp, "(projector)");
  436.          break;
  437.       case nir_tex_src_comparitor:
  438.          fprintf(fp, "(comparitor)");
  439.          break;
  440.       case nir_tex_src_offset:
  441.          fprintf(fp, "(offset)");
  442.          break;
  443.       case nir_tex_src_bias:
  444.          fprintf(fp, "(bias)");
  445.          break;
  446.       case nir_tex_src_lod:
  447.          fprintf(fp, "(lod)");
  448.          break;
  449.       case nir_tex_src_ms_index:
  450.          fprintf(fp, "(ms_index)");
  451.          break;
  452.       case nir_tex_src_ddx:
  453.          fprintf(fp, "(ddx)");
  454.          break;
  455.       case nir_tex_src_ddy:
  456.          fprintf(fp, "(ddy)");
  457.          break;
  458.       case nir_tex_src_sampler_offset:
  459.          fprintf(fp, "(sampler_offset)");
  460.          break;
  461.  
  462.       default:
  463.          unreachable("Invalid texture source type");
  464.          break;
  465.       }
  466.  
  467.       fprintf(fp, ", ");
  468.    }
  469.  
  470.    bool has_nonzero_offset = false;
  471.    for (unsigned i = 0; i < 4; i++) {
  472.       if (instr->const_offset[i] != 0) {
  473.          has_nonzero_offset = true;
  474.          break;
  475.       }
  476.    }
  477.  
  478.    if (has_nonzero_offset) {
  479.       fprintf(fp, "[%i %i %i %i] (offset), ",
  480.               instr->const_offset[0], instr->const_offset[1],
  481.               instr->const_offset[2], instr->const_offset[3]);
  482.    }
  483.  
  484.    if (instr->op == nir_texop_tg4) {
  485.       fprintf(fp, "%u (gather_component), ", instr->component);
  486.    }
  487.  
  488.    if (instr->sampler) {
  489.       print_deref(instr->sampler, state, fp);
  490.    } else {
  491.       fprintf(fp, "%u", instr->sampler_index);
  492.    }
  493.  
  494.    fprintf(fp, " (sampler)");
  495. }
  496.  
  497. static void
  498. print_call_instr(nir_call_instr *instr, print_var_state *state, FILE *fp)
  499. {
  500.    fprintf(fp, "call %s ", instr->callee->function->name);
  501.  
  502.    for (unsigned i = 0; i < instr->num_params; i++) {
  503.       if (i != 0)
  504.          fprintf(fp, ", ");
  505.  
  506.       print_deref(instr->params[i], state, fp);
  507.    }
  508.  
  509.    if (instr->return_deref != NULL) {
  510.       if (instr->num_params != 0)
  511.          fprintf(fp, ", ");
  512.       fprintf(fp, "returning ");
  513.       print_deref(instr->return_deref, state, fp);
  514.    }
  515. }
  516.  
  517. static void
  518. print_load_const_instr(nir_load_const_instr *instr, unsigned tabs, FILE *fp)
  519. {
  520.    print_ssa_def(&instr->def, fp);
  521.  
  522.    fprintf(fp, " = load_const (");
  523.  
  524.    for (unsigned i = 0; i < instr->def.num_components; i++) {
  525.       if (i != 0)
  526.          fprintf(fp, ", ");
  527.  
  528.       /*
  529.        * we don't really know the type of the constant (if it will be used as a
  530.        * float or an int), so just print the raw constant in hex for fidelity
  531.        * and then print the float in a comment for readability.
  532.        */
  533.  
  534.       fprintf(fp, "0x%08x /* %f */", instr->value.u[i], instr->value.f[i]);
  535.    }
  536.  
  537.    fprintf(fp, ")");
  538. }
  539.  
  540. static void
  541. print_jump_instr(nir_jump_instr *instr, FILE *fp)
  542. {
  543.    switch (instr->type) {
  544.    case nir_jump_break:
  545.       fprintf(fp, "break");
  546.       break;
  547.  
  548.    case nir_jump_continue:
  549.       fprintf(fp, "continue");
  550.       break;
  551.  
  552.    case nir_jump_return:
  553.       fprintf(fp, "return");
  554.       break;
  555.    }
  556. }
  557.  
  558. static void
  559. print_ssa_undef_instr(nir_ssa_undef_instr* instr, FILE *fp)
  560. {
  561.    print_ssa_def(&instr->def, fp);
  562.    fprintf(fp, " = undefined");
  563. }
  564.  
  565. static void
  566. print_phi_instr(nir_phi_instr *instr, FILE *fp)
  567. {
  568.    print_dest(&instr->dest, fp);
  569.    fprintf(fp, " = phi ");
  570.    nir_foreach_phi_src(instr, src) {
  571.       if (&src->node != exec_list_get_head(&instr->srcs))
  572.          fprintf(fp, ", ");
  573.  
  574.       fprintf(fp, "block_%u: ", src->pred->index);
  575.       print_src(&src->src, fp);
  576.    }
  577. }
  578.  
  579. static void
  580. print_parallel_copy_instr(nir_parallel_copy_instr *instr, FILE *fp)
  581. {
  582.    nir_foreach_parallel_copy_entry(instr, entry) {
  583.       if (&entry->node != exec_list_get_head(&instr->entries))
  584.          fprintf(fp, "; ");
  585.  
  586.       print_dest(&entry->dest, fp);
  587.       fprintf(fp, " = ");
  588.       print_src(&entry->src, fp);
  589.    }
  590. }
  591.  
  592. static void
  593. print_instr(const nir_instr *instr, print_var_state *state, unsigned tabs, FILE *fp)
  594. {
  595.    print_tabs(tabs, fp);
  596.  
  597.    switch (instr->type) {
  598.    case nir_instr_type_alu:
  599.       print_alu_instr(nir_instr_as_alu(instr), fp);
  600.       break;
  601.  
  602.    case nir_instr_type_call:
  603.       print_call_instr(nir_instr_as_call(instr), state, fp);
  604.       break;
  605.  
  606.    case nir_instr_type_intrinsic:
  607.       print_intrinsic_instr(nir_instr_as_intrinsic(instr), state, fp);
  608.       break;
  609.  
  610.    case nir_instr_type_tex:
  611.       print_tex_instr(nir_instr_as_tex(instr), state, fp);
  612.       break;
  613.  
  614.    case nir_instr_type_load_const:
  615.       print_load_const_instr(nir_instr_as_load_const(instr), tabs, fp);
  616.       break;
  617.  
  618.    case nir_instr_type_jump:
  619.       print_jump_instr(nir_instr_as_jump(instr), fp);
  620.       break;
  621.  
  622.    case nir_instr_type_ssa_undef:
  623.       print_ssa_undef_instr(nir_instr_as_ssa_undef(instr), fp);
  624.       break;
  625.  
  626.    case nir_instr_type_phi:
  627.       print_phi_instr(nir_instr_as_phi(instr), fp);
  628.       break;
  629.  
  630.    case nir_instr_type_parallel_copy:
  631.       print_parallel_copy_instr(nir_instr_as_parallel_copy(instr), fp);
  632.       break;
  633.  
  634.    default:
  635.       unreachable("Invalid instruction type");
  636.       break;
  637.    }
  638. }
  639.  
  640. static int
  641. compare_block_index(const void *p1, const void *p2)
  642. {
  643.    const nir_block *block1 = *((const nir_block **) p1);
  644.    const nir_block *block2 = *((const nir_block **) p2);
  645.  
  646.    return (int) block1->index - (int) block2->index;
  647. }
  648.  
  649. static void print_cf_node(nir_cf_node *node, print_var_state *state,
  650.                           unsigned tabs, FILE *fp);
  651.  
  652. static void
  653. print_block(nir_block *block, print_var_state *state, unsigned tabs, FILE *fp)
  654. {
  655.    print_tabs(tabs, fp);
  656.    fprintf(fp, "block block_%u:\n", block->index);
  657.  
  658.    /* sort the predecessors by index so we consistently print the same thing */
  659.  
  660.    nir_block **preds =
  661.       malloc(block->predecessors->entries * sizeof(nir_block *));
  662.  
  663.    struct set_entry *entry;
  664.    unsigned i = 0;
  665.    set_foreach(block->predecessors, entry) {
  666.       preds[i++] = (nir_block *) entry->key;
  667.    }
  668.  
  669.    qsort(preds, block->predecessors->entries, sizeof(nir_block *),
  670.          compare_block_index);
  671.  
  672.    print_tabs(tabs, fp);
  673.    fprintf(fp, "/* preds: ");
  674.    for (unsigned i = 0; i < block->predecessors->entries; i++) {
  675.       fprintf(fp, "block_%u ", preds[i]->index);
  676.    }
  677.    fprintf(fp, "*/\n");
  678.  
  679.    free(preds);
  680.  
  681.    nir_foreach_instr(block, instr) {
  682.       print_instr(instr, state, tabs, fp);
  683.       fprintf(fp, "\n");
  684.    }
  685.  
  686.    print_tabs(tabs, fp);
  687.    fprintf(fp, "/* succs: ");
  688.    for (unsigned i = 0; i < 2; i++)
  689.       if (block->successors[i]) {
  690.          fprintf(fp, "block_%u ", block->successors[i]->index);
  691.       }
  692.    fprintf(fp, "*/\n");
  693. }
  694.  
  695. static void
  696. print_if(nir_if *if_stmt, print_var_state *state, unsigned tabs, FILE *fp)
  697. {
  698.    print_tabs(tabs, fp);
  699.    fprintf(fp, "if ");
  700.    print_src(&if_stmt->condition, fp);
  701.    fprintf(fp, " {\n");
  702.    foreach_list_typed(nir_cf_node, node, node, &if_stmt->then_list) {
  703.       print_cf_node(node, state, tabs + 1, fp);
  704.    }
  705.    print_tabs(tabs, fp);
  706.    fprintf(fp, "} else {\n");
  707.    foreach_list_typed(nir_cf_node, node, node, &if_stmt->else_list) {
  708.       print_cf_node(node, state, tabs + 1, fp);
  709.    }
  710.    print_tabs(tabs, fp);
  711.    fprintf(fp, "}\n");
  712. }
  713.  
  714. static void
  715. print_loop(nir_loop *loop, print_var_state *state, unsigned tabs, FILE *fp)
  716. {
  717.    print_tabs(tabs, fp);
  718.    fprintf(fp, "loop {\n");
  719.    foreach_list_typed(nir_cf_node, node, node, &loop->body) {
  720.       print_cf_node(node, state, tabs + 1, fp);
  721.    }
  722.    print_tabs(tabs, fp);
  723.    fprintf(fp, "}\n");
  724. }
  725.  
  726. static void
  727. print_cf_node(nir_cf_node *node, print_var_state *state, unsigned int tabs,
  728.               FILE *fp)
  729. {
  730.    switch (node->type) {
  731.    case nir_cf_node_block:
  732.       print_block(nir_cf_node_as_block(node), state, tabs, fp);
  733.       break;
  734.  
  735.    case nir_cf_node_if:
  736.       print_if(nir_cf_node_as_if(node), state, tabs, fp);
  737.       break;
  738.  
  739.    case nir_cf_node_loop:
  740.       print_loop(nir_cf_node_as_loop(node), state, tabs, fp);
  741.       break;
  742.  
  743.    default:
  744.       unreachable("Invalid CFG node type");
  745.    }
  746. }
  747.  
  748. static void
  749. print_function_impl(nir_function_impl *impl, print_var_state *state, FILE *fp)
  750. {
  751.    fprintf(fp, "\nimpl %s ", impl->overload->function->name);
  752.  
  753.    for (unsigned i = 0; i < impl->num_params; i++) {
  754.       if (i != 0)
  755.          fprintf(fp, ", ");
  756.  
  757.       print_var(impl->params[i], state, fp);
  758.    }
  759.  
  760.    if (impl->return_var != NULL) {
  761.       if (impl->num_params != 0)
  762.          fprintf(fp, ", ");
  763.       fprintf(fp, "returning ");
  764.       print_var(impl->return_var, state, fp);
  765.    }
  766.  
  767.    fprintf(fp, "{\n");
  768.  
  769.    foreach_list_typed(nir_variable, var, node, &impl->locals) {
  770.       fprintf(fp, "\t");
  771.       print_var_decl(var, state, fp);
  772.    }
  773.  
  774.    foreach_list_typed(nir_register, reg, node, &impl->registers) {
  775.       fprintf(fp, "\t");
  776.       print_register_decl(reg, fp);
  777.    }
  778.  
  779.    nir_index_blocks(impl);
  780.  
  781.    foreach_list_typed(nir_cf_node, node, node, &impl->body) {
  782.       print_cf_node(node, state, 1, fp);
  783.    }
  784.  
  785.    fprintf(fp, "\tblock block_%u:\n}\n\n", impl->end_block->index);
  786. }
  787.  
  788. static void
  789. print_function_overload(nir_function_overload *overload,
  790.                         print_var_state *state, FILE *fp)
  791. {
  792.    fprintf(fp, "decl_overload %s ", overload->function->name);
  793.  
  794.    for (unsigned i = 0; i < overload->num_params; i++) {
  795.       if (i != 0)
  796.          fprintf(fp, ", ");
  797.  
  798.       switch (overload->params[i].param_type) {
  799.       case nir_parameter_in:
  800.          fprintf(fp, "in ");
  801.          break;
  802.       case nir_parameter_out:
  803.          fprintf(fp, "out ");
  804.          break;
  805.       case nir_parameter_inout:
  806.          fprintf(fp, "inout ");
  807.          break;
  808.       default:
  809.          unreachable("Invalid parameter type");
  810.       }
  811.  
  812.       glsl_print_type(overload->params[i].type, fp);
  813.    }
  814.  
  815.    if (overload->return_type != NULL) {
  816.       if (overload->num_params != 0)
  817.          fprintf(fp, ", ");
  818.       fprintf(fp, "returning ");
  819.       glsl_print_type(overload->return_type, fp);
  820.    }
  821.  
  822.    fprintf(fp, "\n");
  823.  
  824.    if (overload->impl != NULL) {
  825.       print_function_impl(overload->impl, state, fp);
  826.       return;
  827.    }
  828. }
  829.  
  830. static void
  831. print_function(nir_function *func, print_var_state *state, FILE *fp)
  832. {
  833.    foreach_list_typed(nir_function_overload, overload, node, &func->overload_list) {
  834.       print_function_overload(overload, state, fp);
  835.    }
  836. }
  837.  
  838. static void
  839. init_print_state(print_var_state *state)
  840. {
  841.    state->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
  842.                                        _mesa_key_pointer_equal);
  843.    state->syms = _mesa_set_create(NULL, _mesa_key_hash_string,
  844.                                   _mesa_key_string_equal);
  845.    state->index = 0;
  846. }
  847.  
  848. static void
  849. destroy_print_state(print_var_state *state)
  850. {
  851.    _mesa_hash_table_destroy(state->ht, NULL);
  852.    _mesa_set_destroy(state->syms, NULL);
  853. }
  854.  
  855. void
  856. nir_print_shader(nir_shader *shader, FILE *fp)
  857. {
  858.    print_var_state state;
  859.    init_print_state(&state);
  860.  
  861.    foreach_list_typed(nir_variable, var, node, &shader->uniforms) {
  862.       print_var_decl(var, &state, fp);
  863.    }
  864.  
  865.    foreach_list_typed(nir_variable, var, node, &shader->inputs) {
  866.       print_var_decl(var, &state, fp);
  867.    }
  868.  
  869.    foreach_list_typed(nir_variable, var, node, &shader->outputs) {
  870.       print_var_decl(var, &state, fp);
  871.    }
  872.  
  873.    foreach_list_typed(nir_variable, var, node, &shader->globals) {
  874.       print_var_decl(var, &state, fp);
  875.    }
  876.  
  877.    foreach_list_typed(nir_variable, var, node, &shader->system_values) {
  878.       print_var_decl(var, &state, fp);
  879.    }
  880.  
  881.    foreach_list_typed(nir_register, reg, node, &shader->registers) {
  882.       print_register_decl(reg, fp);
  883.    }
  884.  
  885.    foreach_list_typed(nir_function, func, node, &shader->functions) {
  886.       print_function(func, &state, fp);
  887.    }
  888.  
  889.    destroy_print_state(&state);
  890. }
  891.  
  892. void
  893. nir_print_instr(const nir_instr *instr, FILE *fp)
  894. {
  895.    print_instr(instr, NULL, 0, fp);
  896. }
  897.