Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 2013 Vadim Girlin <vadimgirlin@gmail.com>
  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.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Vadim Girlin
  25.  */
  26.  
  27. #include "sb_shader.h"
  28. #include "sb_pass.h"
  29.  
  30. namespace r600_sb {
  31.  
  32. bool dump::visit(node& n, bool enter) {
  33.         if (enter) {
  34.                 indent();
  35.                 dump_flags(n);
  36.  
  37.                 switch (n.subtype) {
  38.                         case NST_PHI:
  39.                                 dump_op(n, "* phi");
  40.                                 break;
  41.                         case NST_PSI:
  42.                                 dump_op(n, "* psi");
  43.                                 break;
  44.                         case NST_COPY:
  45.                                 dump_op(n, "* copy");
  46.                                 break;
  47.                         default:
  48.                                 assert(!"invalid node subtype");
  49.                                 break;
  50.                 }
  51.                 sblog << "\n";
  52.         }
  53.         return false;
  54. }
  55.  
  56. bool dump::visit(container_node& n, bool enter) {
  57.         if (enter) {
  58.                 if (!n.empty()) {
  59.                         indent();
  60.                         dump_flags(n);
  61.                         sblog << "{  ";
  62.                         if (!n.dst.empty()) {
  63.                                 sblog << " preloaded inputs [";
  64.                                 dump_vec(n.dst);
  65.                                 sblog << "]  ";
  66.                         }
  67.                         dump_live_values(n, true);
  68.                 }
  69.                 ++level;
  70.         } else {
  71.                 --level;
  72.                 if (!n.empty()) {
  73.                         indent();
  74.                         sblog << "}  ";
  75.                         if (!n.src.empty()) {
  76.                                 sblog << " results [";
  77.                                 dump_vec(n.src);
  78.                                 sblog << "]  ";
  79.                         }
  80.                         dump_live_values(n, false);
  81.                 }
  82.         }
  83.         return true;
  84. }
  85.  
  86. bool dump::visit(bb_node& n, bool enter) {
  87.         if (enter) {
  88.                 indent();
  89.                 dump_flags(n);
  90.                 sblog << "{ BB_" << n.id << "    loop_level = " << n.loop_level << "  ";
  91.                 dump_live_values(n, true);
  92.                 ++level;
  93.         } else {
  94.                 --level;
  95.                 indent();
  96.                 sblog << "} end BB_" << n.id << "  ";
  97.                 dump_live_values(n, false);
  98.         }
  99.         return true;
  100. }
  101.  
  102. bool dump::visit(alu_group_node& n, bool enter) {
  103.         if (enter) {
  104.                 indent();
  105.                 dump_flags(n);
  106.                 sblog << "[  ";
  107.                 dump_live_values(n, true);
  108.  
  109.                 ++level;
  110.         } else {
  111.                 --level;
  112.  
  113.                 indent();
  114.                 sblog << "]  ";
  115.                 dump_live_values(n, false);
  116.         }
  117.         return true;
  118. }
  119.  
  120. bool dump::visit(cf_node& n, bool enter) {
  121.         if (enter) {
  122.                 indent();
  123.                 dump_flags(n);
  124.                 dump_op(n, n.bc.op_ptr->name);
  125.  
  126.                 if (n.bc.op_ptr->flags & CF_BRANCH) {
  127.                         sblog << " @" << (n.bc.addr << 1);
  128.                 }
  129.  
  130.                 dump_common(n);
  131.                 sblog << "\n";
  132.  
  133.                 if (!n.empty()) {
  134.                         indent();
  135.                         sblog << "<  ";
  136.                         dump_live_values(n, true);
  137.                 }
  138.  
  139.                 ++level;
  140.         } else {
  141.                 --level;
  142.                 if (!n.empty()) {
  143.                         indent();
  144.                         sblog << ">  ";
  145.                         dump_live_values(n, false);
  146.                 }
  147.         }
  148.         return true;
  149. }
  150.  
  151. bool dump::visit(alu_node& n, bool enter) {
  152.         if (enter) {
  153.                 indent();
  154.                 dump_flags(n);
  155.                 dump_alu(&n);
  156.                 dump_common(n);
  157.                 sblog << "\n";
  158.  
  159.                 ++level;
  160.         } else {
  161.                 --level;
  162.  
  163.         }
  164.         return true;
  165. }
  166.  
  167. bool dump::visit(alu_packed_node& n, bool enter) {
  168.         if (enter) {
  169.                 indent();
  170.                 dump_flags(n);
  171.                 dump_op(n, n.op_ptr()->name);
  172.                 sblog << "  ";
  173.                 dump_live_values(n, true);
  174.  
  175.                 ++level;
  176.         } else {
  177.                 --level;
  178.                 if (!n.live_after.empty()) {
  179.                         indent();
  180.                         dump_live_values(n, false);
  181.                 }
  182.  
  183.         }
  184.         // proccess children only if their src/dst aren't moved to this node yet
  185.         return n.src.empty();
  186. }
  187.  
  188. bool dump::visit(fetch_node& n, bool enter) {
  189.         if (enter) {
  190.                 indent();
  191.                 dump_flags(n);
  192.                 dump_op(n, n.bc.op_ptr->name);
  193.                 sblog << "\n";
  194.  
  195.                 ++level;
  196.         } else {
  197.                 --level;
  198.         }
  199.         return true;
  200. }
  201.  
  202. bool dump::visit(region_node& n, bool enter) {
  203.         if (enter) {
  204.                 indent();
  205.                 dump_flags(n);
  206.                 sblog << "region #" << n.region_id << "   ";
  207.                 dump_common(n);
  208.  
  209.                 if (!n.vars_defined.empty()) {
  210.                         sblog << "vars_defined: ";
  211.                         dump_set(sh, n.vars_defined);
  212.                 }
  213.  
  214.                 dump_live_values(n, true);
  215.  
  216.                 ++level;
  217.  
  218.                 if (n.loop_phi)
  219.                         run_on(*n.loop_phi);
  220.         } else {
  221.                 --level;
  222.  
  223.                 if (n.phi)
  224.                         run_on(*n.phi);
  225.  
  226.                 indent();
  227.                 dump_live_values(n, false);
  228.         }
  229.         return true;
  230. }
  231.  
  232. bool dump::visit(repeat_node& n, bool enter) {
  233.         if (enter) {
  234.                 indent();
  235.                 dump_flags(n);
  236.                 sblog << "repeat region #" << n.target->region_id;
  237.                 sblog << (n.empty() ? "   " : " after {  ");
  238.                 dump_common(n);
  239.                 sblog << "   ";
  240.                 dump_live_values(n, true);
  241.  
  242.                 ++level;
  243.         } else {
  244.                 --level;
  245.  
  246.                 if (!n.empty()) {
  247.                         indent();
  248.                         sblog << "} end_repeat   ";
  249.                         dump_live_values(n, false);
  250.                 }
  251.         }
  252.         return true;
  253. }
  254.  
  255. bool dump::visit(depart_node& n, bool enter) {
  256.         if (enter) {
  257.                 indent();
  258.                 dump_flags(n);
  259.                 sblog << "depart region #" << n.target->region_id;
  260.                 sblog << (n.empty() ? "   " : " after {  ");
  261.                 dump_common(n);
  262.                 sblog << "  ";
  263.                 dump_live_values(n, true);
  264.  
  265.                 ++level;
  266.         } else {
  267.                 --level;
  268.                 if (!n.empty()) {
  269.                         indent();
  270.                         sblog << "} end_depart   ";
  271.                         dump_live_values(n, false);
  272.                 }
  273.         }
  274.         return true;
  275. }
  276.  
  277. bool dump::visit(if_node& n, bool enter) {
  278.         if (enter) {
  279.                 indent();
  280.                 dump_flags(n);
  281.                 sblog << "if " << *n.cond << "    ";
  282.                 dump_common(n);
  283.                 sblog << "   ";
  284.                 dump_live_values(n, true);
  285.  
  286.                 indent();
  287.                 sblog <<"{\n";
  288.  
  289.                 ++level;
  290.         } else {
  291.                 --level;
  292.                 indent();
  293.                 sblog << "} endif   ";
  294.                 dump_live_values(n, false);
  295.         }
  296.         return true;
  297. }
  298.  
  299. void dump::indent() {
  300.         sblog.print_wl("", level * 4);
  301. }
  302.  
  303. void dump::dump_vec(const vvec & vv) {
  304.         bool first = true;
  305.         for(vvec::const_iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
  306.                 value *v = *I;
  307.                 if (!first)
  308.                         sblog << ", ";
  309.                 else
  310.                         first = false;
  311.  
  312.                 if (v) {
  313.                         sblog << *v;
  314.                 } else {
  315.                         sblog << "__";
  316.                 }
  317.         }
  318. }
  319.  
  320. void dump::dump_rels(vvec & vv) {
  321.         for(vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
  322.                 value *v = *I;
  323.  
  324.                 if (!v || !v->is_rel())
  325.                         continue;
  326.  
  327.                 sblog << "\n\t\t\t\t\t";
  328.                 sblog << "    rels: " << *v << " : ";
  329.                 dump_vec(v->mdef);
  330.                 sblog << " <= ";
  331.                 dump_vec(v->muse);
  332.         }
  333. }
  334.  
  335. void dump::dump_op(node &n, const char *name) {
  336.  
  337.         if (n.pred) {
  338.                 alu_node &a = static_cast<alu_node&>(n);
  339.                 sblog << (a.bc.pred_sel-2) << " [" << *a.pred << "] ";
  340.         }
  341.  
  342.         sblog << name;
  343.  
  344.         bool has_dst = !n.dst.empty();
  345.  
  346.         if (n.subtype == NST_CF_INST) {
  347.                 cf_node *c = static_cast<cf_node*>(&n);
  348.                 if (c->bc.op_ptr->flags & CF_EXP) {
  349.                         static const char *exp_type[] = {"PIXEL", "POS  ", "PARAM"};
  350.                         sblog << "  " << exp_type[c->bc.type] << " " << c->bc.array_base;
  351.                         has_dst = false;
  352.                 } else if (c->bc.op_ptr->flags & CF_STRM) {
  353.                         static const char *exp_type[] = {"WRITE", "WRITE_IND", "WRITE_ACK",
  354.                                         "WRITE_IND_ACK"};
  355.                         sblog << "  " << exp_type[c->bc.type] << " " << c->bc.array_base
  356.                                         << "   ES:" << c->bc.elem_size;
  357.                         has_dst = false;
  358.                 }
  359.         }
  360.  
  361.         sblog << "     ";
  362.  
  363.         if (has_dst) {
  364.                 dump_vec(n.dst);
  365.                 sblog << ",       ";
  366.         }
  367.  
  368.         dump_vec(n.src);
  369. }
  370.  
  371. void dump::dump_set(shader &sh, val_set& v) {
  372.         sblog << "[";
  373.         for(val_set::iterator I = v.begin(sh), E = v.end(sh); I != E; ++I) {
  374.                 value *val = *I;
  375.                 sblog << *val << " ";
  376.         }
  377.         sblog << "]";
  378. }
  379.  
  380. void dump::dump_common(node& n) {
  381. }
  382.  
  383. void dump::dump_flags(node &n) {
  384.         if (n.flags & NF_DEAD)
  385.                 sblog << "### DEAD  ";
  386.         if (n.flags & NF_REG_CONSTRAINT)
  387.                 sblog << "R_CONS  ";
  388.         if (n.flags & NF_CHAN_CONSTRAINT)
  389.                 sblog << "CH_CONS  ";
  390.         if (n.flags & NF_ALU_4SLOT)
  391.                 sblog << "4S  ";
  392. }
  393.  
  394. void dump::dump_val(value* v) {
  395.         sblog << *v;
  396. }
  397.  
  398. void dump::dump_alu(alu_node *n) {
  399.  
  400.         if (n->is_copy_mov())
  401.                 sblog << "(copy) ";
  402.  
  403.         if (n->pred) {
  404.                 sblog << (n->bc.pred_sel-2) << " [" << *n->pred << "] ";
  405.         }
  406.  
  407.         sblog << n->bc.op_ptr->name;
  408.  
  409.         if (n->bc.omod) {
  410.                 static const char *omod_str[] = {"", "*2", "*4", "/2"};
  411.                 sblog << omod_str[n->bc.omod];
  412.         }
  413.  
  414.         if (n->bc.clamp) {
  415.                 sblog << "_sat";
  416.         }
  417.  
  418.         bool has_dst = !n->dst.empty();
  419.  
  420.         sblog << "     ";
  421.  
  422.         if (has_dst) {
  423.                 dump_vec(n->dst);
  424.                 sblog << ",    ";
  425.         }
  426.  
  427.         unsigned s = 0;
  428.         for (vvec::iterator I = n->src.begin(), E = n->src.end(); I != E;
  429.                         ++I, ++s) {
  430.  
  431.                 bc_alu_src &src = n->bc.src[s];
  432.  
  433.                 if (src.neg)
  434.                         sblog << "-";
  435.  
  436.                 if (src.abs)
  437.                         sblog << "|";
  438.  
  439.                 dump_val(*I);
  440.  
  441.                 if (src.abs)
  442.                         sblog << "|";
  443.  
  444.                 if (I + 1 != E)
  445.                         sblog << ", ";
  446.         }
  447.  
  448.         dump_rels(n->dst);
  449.         dump_rels(n->src);
  450.  
  451. }
  452.  
  453. void dump::dump_op(node* n) {
  454.         if (n->type == NT_IF) {
  455.                 dump_op(*n, "IF ");
  456.                 return;
  457.         }
  458.  
  459.         switch(n->subtype) {
  460.         case NST_ALU_INST:
  461.                 dump_alu(static_cast<alu_node*>(n));
  462.                 break;
  463.         case NST_FETCH_INST:
  464.                 dump_op(*n, static_cast<fetch_node*>(n)->bc.op_ptr->name);
  465.                 break;
  466.         case NST_CF_INST:
  467.         case NST_ALU_CLAUSE:
  468.         case NST_TEX_CLAUSE:
  469.         case NST_VTX_CLAUSE:
  470.                 dump_op(*n, static_cast<cf_node*>(n)->bc.op_ptr->name);
  471.                 break;
  472.         case NST_ALU_PACKED_INST:
  473.                 dump_op(*n, static_cast<alu_packed_node*>(n)->op_ptr()->name);
  474.                 break;
  475.         case NST_PHI:
  476.                 dump_op(*n, "PHI");
  477.                 break;
  478.         case NST_PSI:
  479.                 dump_op(*n, "PSI");
  480.                 break;
  481.         case NST_COPY:
  482.                 dump_op(*n, "COPY");
  483.                 break;
  484.         default:
  485.                 dump_op(*n, "??unknown_op");
  486.         }
  487. }
  488.  
  489. void dump::dump_op_list(container_node* c) {
  490.         for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) {
  491.                 dump_op(*I);
  492.                 sblog << "\n";
  493.         }
  494. }
  495.  
  496. void dump::dump_queue(sched_queue& q) {
  497.         for (sched_queue::iterator I = q.begin(), E = q.end(); I != E; ++I) {
  498.                 dump_op(*I);
  499.                 sblog << "\n";
  500.         }
  501. }
  502.  
  503. void dump::dump_live_values(container_node &n, bool before) {
  504.         if (before) {
  505.                 if (!n.live_before.empty()) {
  506.                         sblog << "live_before: ";
  507.                         dump_set(sh, n.live_before);
  508.                 }
  509.         } else {
  510.                 if (!n.live_after.empty()) {
  511.                         sblog << "live_after: ";
  512.                         dump_set(sh, n.live_after);
  513.                 }
  514.         }
  515.         sblog << "\n";
  516. }
  517.  
  518. } // namespace r600_sb
  519.