• 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 
29 #include "sb_pass.h"
30 
31 namespace r600_sb {
32 
run()33 int dce_cleanup::run() {
34 	int r;
35 
36 	// Run cleanup for as long as there are unused nodes.
37 	do {
38 		nodes_changed = false;
39 		r = vpass::run();
40 	} while (r == 0 && nodes_changed);
41 
42 	return r;
43 }
44 
visit(node & n,bool enter)45 bool dce_cleanup::visit(node& n, bool enter) {
46 	if (enter) {
47 	} else {
48 		if (n.flags & NF_DEAD)
49 			n.remove();
50 		else
51 			cleanup_dst(n);
52 	}
53 	return true;
54 }
55 
visit(alu_group_node & n,bool enter)56 bool dce_cleanup::visit(alu_group_node& n, bool enter) {
57 	if (enter) {
58 	} else {
59 		n.expand();
60 	}
61 	return true;
62 }
63 
visit(cf_node & n,bool enter)64 bool dce_cleanup::visit(cf_node& n, bool enter) {
65 	if (enter) {
66 		if (n.flags & NF_DEAD)
67 			n.remove();
68 		else
69 			cleanup_dst(n);
70 	} else {
71 		if ((sh.dce_flags & DF_EXPAND) &&
72 				(n.bc.op_ptr->flags & (CF_CLAUSE | CF_BRANCH | CF_LOOP)))
73 			n.expand();
74 	}
75 	return true;
76 }
77 
visit(alu_node & n,bool enter)78 bool dce_cleanup::visit(alu_node& n, bool enter) {
79 	if (enter) {
80 	} else {
81 		if (n.flags & NF_DEAD)
82 			n.remove();
83 		else
84 			cleanup_dst(n);
85 	}
86 	return true;
87 }
88 
visit(alu_packed_node & n,bool enter)89 bool dce_cleanup::visit(alu_packed_node& n, bool enter) {
90 	if (enter) {
91 	} else {
92 		if (n.flags & NF_DEAD)
93 			n.remove();
94 		else
95 			cleanup_dst(n);
96 	}
97 	return false;
98 }
99 
visit(fetch_node & n,bool enter)100 bool dce_cleanup::visit(fetch_node& n, bool enter) {
101 	if (enter) {
102 	} else {
103 		if (n.flags & NF_DEAD)
104 			n.remove();
105 		else
106 			cleanup_dst(n);
107 	}
108 	return true;
109 }
110 
visit(region_node & n,bool enter)111 bool dce_cleanup::visit(region_node& n, bool enter) {
112 	if (enter) {
113 		if (n.loop_phi)
114 			run_on(*n.loop_phi);
115 	} else {
116 		if (n.phi)
117 			run_on(*n.phi);
118 	}
119 	return true;
120 }
121 
cleanup_dst(node & n)122 void dce_cleanup::cleanup_dst(node& n) {
123 	if (!cleanup_dst_vec(n.dst) && remove_unused &&
124 			!n.dst.empty() && !(n.flags & NF_DONT_KILL) && n.parent)
125 	{
126 		// Delete use references to the removed node from the src values.
127 		for (vvec::iterator I = n.src.begin(), E = n.src.end(); I != E; ++I) {
128 			value* v = *I;
129 			if (v && v->def && v->uses.size())
130 			{
131 				v->remove_use(&n);
132 			}
133 		}
134 		n.remove();
135 		nodes_changed = true;
136 	}
137 }
138 
visit(container_node & n,bool enter)139 bool dce_cleanup::visit(container_node& n, bool enter) {
140 	if (enter)
141 		cleanup_dst(n);
142 	return true;
143 }
144 
cleanup_dst_vec(vvec & vv)145 bool dce_cleanup::cleanup_dst_vec(vvec& vv) {
146 	bool alive = false;
147 
148 	for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
149 		value* &v = *I;
150 		if (!v)
151 			continue;
152 
153 		if (v->gvn_source && v->gvn_source->is_dead())
154 			v->gvn_source = NULL;
155 
156 		if (v->is_dead() || (remove_unused && !v->is_rel() && !v->uses.size()))
157 			v = NULL;
158 		else
159 			alive = true;
160 	}
161 
162 	return alive;
163 }
164 
165 } // namespace r600_sb
166