Remove ir_label since it is no longer used.
[mesa.git] / ir_if_simplification.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 /**
25 * \file ir_function_inlining.cpp
26 *
27 * Moves constant branches of if statements out to the surrounding
28 * instruction stream.
29 */
30
31 #define NULL 0
32 #include "ir.h"
33 #include "ir_visitor.h"
34 #include "ir_function_inlining.h"
35 #include "glsl_types.h"
36
37 class ir_if_simplification_visitor : public ir_visitor {
38 public:
39 ir_if_simplification_visitor()
40 {
41 /* empty */
42 }
43
44 virtual ~ir_if_simplification_visitor()
45 {
46 /* empty */
47 }
48
49 /**
50 * \name Visit methods
51 *
52 * As typical for the visitor pattern, there must be one \c visit method for
53 * each concrete subclass of \c ir_instruction. Virtual base classes within
54 * the hierarchy should not have \c visit methods.
55 */
56 /*@{*/
57 virtual void visit(ir_variable *);
58 virtual void visit(ir_loop *);
59 virtual void visit(ir_loop_jump *);
60 virtual void visit(ir_function_signature *);
61 virtual void visit(ir_function *);
62 virtual void visit(ir_expression *);
63 virtual void visit(ir_swizzle *);
64 virtual void visit(ir_dereference *);
65 virtual void visit(ir_assignment *);
66 virtual void visit(ir_constant *);
67 virtual void visit(ir_call *);
68 virtual void visit(ir_return *);
69 virtual void visit(ir_if *);
70 /*@}*/
71 };
72
73 bool
74 do_if_simplification(exec_list *instructions)
75 {
76 bool progress = false;
77
78 foreach_iter(exec_list_iterator, iter, *instructions) {
79 ir_instruction *ir = (ir_instruction *)iter.get();
80 ir_if *conditional = ir->as_if();
81
82 if (conditional) {
83 ir_constant *condition_constant;
84
85 condition_constant =
86 conditional->condition->constant_expression_value();
87 if (condition_constant) {
88 /* Move the contents of the one branch of the conditional
89 * that matters out.
90 */
91 if (condition_constant->value.b[0]) {
92 foreach_iter(exec_list_iterator, then_iter,
93 conditional->then_instructions) {
94 ir_instruction *then_ir = (ir_instruction *)then_iter.get();
95 ir->insert_before(then_ir);
96 }
97 } else {
98 foreach_iter(exec_list_iterator, else_iter,
99 conditional->else_instructions) {
100 ir_instruction *else_ir = (ir_instruction *)else_iter.get();
101 ir->insert_before(else_ir);
102 }
103 }
104 ir->remove();
105 progress = true;
106 /* It would be nice to move the iterator back up to the point
107 * that we just spliced in contents.
108 */
109 } else {
110 ir_if_simplification_visitor v;
111 ir->accept(&v);
112 }
113 } else {
114 ir_if_simplification_visitor v;
115 ir->accept(&v);
116 }
117 }
118
119 return progress;
120 }
121
122 class variable_remap : public exec_node {
123 public:
124 variable_remap(const ir_variable *old_var, ir_variable *new_var)
125 : old_var(old_var), new_var(new_var)
126 {
127 /* empty */
128 }
129 const ir_variable *old_var;
130 ir_variable *new_var;
131 };
132
133 void
134 ir_if_simplification_visitor::visit(ir_variable *ir)
135 {
136 (void) ir;
137 }
138
139
140 void
141 ir_if_simplification_visitor::visit(ir_loop *ir)
142 {
143 do_if_simplification(&ir->body_instructions);
144 }
145
146 void
147 ir_if_simplification_visitor::visit(ir_loop_jump *ir)
148 {
149 (void) ir;
150 }
151
152
153 void
154 ir_if_simplification_visitor::visit(ir_function_signature *ir)
155 {
156 do_if_simplification(&ir->body);
157 }
158
159
160 void
161 ir_if_simplification_visitor::visit(ir_function *ir)
162 {
163 foreach_iter(exec_list_iterator, iter, *ir) {
164 ir_function_signature *const sig = (ir_function_signature *) iter.get();
165 sig->accept(this);
166 }
167 }
168
169 void
170 ir_if_simplification_visitor::visit(ir_expression *ir)
171 {
172 unsigned int operand;
173
174 for (operand = 0; operand < ir->get_num_operands(); operand++) {
175 ir->operands[operand]->accept(this);
176 }
177 }
178
179
180 void
181 ir_if_simplification_visitor::visit(ir_swizzle *ir)
182 {
183 ir->val->accept(this);
184 }
185
186
187 void
188 ir_if_simplification_visitor::visit(ir_dereference *ir)
189 {
190 if (ir->mode == ir_dereference::ir_reference_array) {
191 ir->selector.array_index->accept(this);
192 }
193 ir->var->accept(this);
194 }
195
196 void
197 ir_if_simplification_visitor::visit(ir_assignment *ir)
198 {
199 ir->rhs->accept(this);
200 }
201
202
203 void
204 ir_if_simplification_visitor::visit(ir_constant *ir)
205 {
206 (void) ir;
207 }
208
209
210 void
211 ir_if_simplification_visitor::visit(ir_call *ir)
212 {
213 (void) ir;
214 }
215
216
217 void
218 ir_if_simplification_visitor::visit(ir_return *ir)
219 {
220 (void) ir;
221 }
222
223
224 void
225 ir_if_simplification_visitor::visit(ir_if *ir)
226 {
227 ir->condition->accept(this);
228
229 do_if_simplification(&ir->then_instructions);
230 do_if_simplification(&ir->else_instructions);
231 }