Home | History | Annotate | Download | only in sb
      1 /*
      2  * Copyright 2013 Vadim Girlin <vadimgirlin (at) 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