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. int def_use::run() {
  33.         run_on(sh.root, true);
  34.         run_on(sh.root, false);
  35.         return 0;
  36. }
  37.  
  38. void def_use::process_phi(container_node *c, bool defs, bool uses) {
  39.  
  40.         for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) {
  41.                 node *n = *I;
  42.                 if (uses)
  43.                         process_uses(n);
  44.                 if (defs)
  45.                         process_defs(n, n->dst, false);
  46.         }
  47. }
  48.  
  49. void def_use::run_on(node* n, bool defs) {
  50.  
  51.         bool is_region = (n->type == NT_REGION);
  52.         bool is_op = (n->type == NT_OP || n->type == NT_IF);
  53.  
  54.         if (is_op) {
  55.  
  56.                 if (0) {
  57.                         sblog << "def_use processing op ";
  58.                         dump::dump_op(n);
  59.                         sblog << "\n";
  60.                 }
  61.  
  62.                 if (defs)
  63.                         process_defs(n, n->dst, false);
  64.                 else
  65.                         process_uses(n);
  66.         } else if (is_region & defs) {
  67.                 region_node *r = static_cast<region_node*>(n);
  68.                 if (r->loop_phi)
  69.                         process_phi(r->loop_phi, true, false);
  70.         }
  71.  
  72.         if (n->is_container() && n->subtype != NST_ALU_PACKED_INST) {
  73.                 container_node *c = static_cast<container_node*>(n);
  74.                 for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) {
  75.                         run_on(*I, defs);
  76.                 }
  77.         }
  78.  
  79.         if (is_region) {
  80.                 region_node *r = static_cast<region_node*>(n);
  81.                 if (r->phi)
  82.                         process_phi(r->phi, defs, !defs);
  83.                 if (r->loop_phi && !defs)
  84.                         process_phi(r->loop_phi, false, true);
  85.         }
  86. }
  87.  
  88. void def_use::process_defs(node *n, vvec &vv, bool arr_def) {
  89.  
  90.         for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
  91.                 value *v = *I;
  92.                 if (!v)
  93.                         continue;
  94.  
  95.                 if (arr_def)
  96.                         v->adef = n;
  97.                 else
  98.                         v->def = n;
  99.  
  100.                 v->delete_uses();
  101.  
  102.                 if (v->is_rel()) {
  103.                         process_defs(n, v->mdef, true);
  104.                 }
  105.         }
  106. }
  107.  
  108. void def_use::process_uses(node* n) {
  109.         unsigned k = 0;
  110.  
  111.         for (vvec::iterator I = n->src.begin(), E = n->src.end(); I != E;
  112.                         ++I, ++k) {
  113.                 value *v = *I;
  114.                 if (!v || v->is_readonly())
  115.                         continue;
  116.  
  117.                 if (v->is_rel()) {
  118.                         if (!v->rel->is_readonly())
  119.                                 v->rel->add_use(n, UK_SRC_REL, k);
  120.  
  121.                         unsigned k2 = 0;
  122.                         for (vvec::iterator I = v->muse.begin(), E = v->muse.end();
  123.                                         I != E; ++I, ++k2) {
  124.                                 value *v = *I;
  125.                                 if (!v)
  126.                                         continue;
  127.  
  128.                                 v->add_use(n, UK_MAYUSE, k2);
  129.                         }
  130.                 } else
  131.                         v->add_use(n, UK_SRC, k);
  132.         }
  133.  
  134.         k = 0;
  135.         for (vvec::iterator I = n->dst.begin(), E = n->dst.end(); I != E;
  136.                         ++I, ++k) {
  137.                 value *v = *I;
  138.                 if (!v || !v->is_rel())
  139.                         continue;
  140.  
  141.                 if (!v->rel->is_readonly())
  142.                         v->rel->add_use(n, UK_DST_REL, k);
  143.                 unsigned k2 = 0;
  144.                 for (vvec::iterator I = v->muse.begin(), E = v->muse.end();
  145.                                 I != E; ++I, ++k2) {
  146.                         value *v = *I;
  147.                         if (!v)
  148.                                 continue;
  149.  
  150.                         v->add_use(n, UK_MAYDEF, k2);
  151.                 }
  152.         }
  153.  
  154.         if (n->pred)
  155.                 n->pred->add_use(n, UK_PRED, 0);
  156.  
  157.         if (n->type == NT_IF) {
  158.                 if_node *i = static_cast<if_node*>(n);
  159.                 if (i->cond)
  160.                         i->cond->add_use(i, UK_COND, 0);
  161.         }
  162. }
  163.  
  164. } // namespace r600_sb
  165.