• 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 	for (vvec::iterator I = n->src.begin(), E = n->src.end(); I != E; ++I) {
110 		value *v = *I;
111 		if (!v || v->is_readonly())
112 			continue;
113 
114 		if (v->is_rel()) {
115 			if (!v->rel->is_readonly())
116 				v->rel->add_use(n);
117 
118 			for (vvec::iterator I = v->muse.begin(), E = v->muse.end();
119 					I != E; ++I) {
120 				value *v = *I;
121 				if (!v)
122 					continue;
123 
124 				v->add_use(n);
125 			}
126 		} else
127 			v->add_use(n);
128 	}
129 
130 	for (vvec::iterator I = n->dst.begin(), E = n->dst.end(); I != E; ++I) {
131 		value *v = *I;
132 		if (!v || !v->is_rel())
133 			continue;
134 
135 		if (!v->rel->is_readonly())
136 			v->rel->add_use(n);
137 		for (vvec::iterator I = v->muse.begin(), E = v->muse.end();
138 				I != E; ++I) {
139 			value *v = *I;
140 			if (!v)
141 				continue;
142 
143 			v->add_use(n);
144 		}
145 	}
146 
147 	if (n->pred)
148 		n->pred->add_use(n);
149 
150 	if (n->type == NT_IF) {
151 		if_node *i = static_cast<if_node*>(n);
152 		if (i->cond)
153 			i->cond->add_use(i);
154 	}
155 }
156 
157 } // namespace r600_sb
158