• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
run()32 int def_use::run() {
33 	run_on(sh.root, true);
34 	run_on(sh.root, false);
35 	return 0;
36 }
37 
process_phi(container_node * c,bool defs,bool uses)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 
run_on(node * n,bool defs)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 
process_defs(node * n,vvec & vv,bool arr_def)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 
process_uses(node * n)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