2 * Copyright © 2010 Intel Corporation
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:
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
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.
25 * \file ir_function_inlining.cpp
27 * Moves constant branches of if statements out to the surrounding
33 #include "ir_visitor.h"
34 #include "ir_function_inlining.h"
35 #include "glsl_types.h"
37 class ir_if_simplification_visitor
: public ir_visitor
{
39 ir_if_simplification_visitor()
44 virtual ~ir_if_simplification_visitor()
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.
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
*);
74 do_if_simplification(exec_list
*instructions
)
76 bool progress
= false;
78 foreach_iter(exec_list_iterator
, iter
, *instructions
) {
79 ir_instruction
*ir
= (ir_instruction
*)iter
.get();
80 ir_if
*conditional
= ir
->as_if();
83 ir_constant
*condition_constant
;
86 conditional
->condition
->constant_expression_value();
87 if (condition_constant
) {
88 /* Move the contents of the one branch of the conditional
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
);
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
);
106 /* It would be nice to move the iterator back up to the point
107 * that we just spliced in contents.
110 ir_if_simplification_visitor v
;
114 ir_if_simplification_visitor v
;
122 class variable_remap
: public exec_node
{
124 variable_remap(const ir_variable
*old_var
, ir_variable
*new_var
)
125 : old_var(old_var
), new_var(new_var
)
129 const ir_variable
*old_var
;
130 ir_variable
*new_var
;
134 ir_if_simplification_visitor::visit(ir_variable
*ir
)
141 ir_if_simplification_visitor::visit(ir_loop
*ir
)
143 do_if_simplification(&ir
->body_instructions
);
147 ir_if_simplification_visitor::visit(ir_loop_jump
*ir
)
154 ir_if_simplification_visitor::visit(ir_function_signature
*ir
)
156 do_if_simplification(&ir
->body
);
161 ir_if_simplification_visitor::visit(ir_function
*ir
)
163 foreach_iter(exec_list_iterator
, iter
, *ir
) {
164 ir_function_signature
*const sig
= (ir_function_signature
*) iter
.get();
170 ir_if_simplification_visitor::visit(ir_expression
*ir
)
172 unsigned int operand
;
174 for (operand
= 0; operand
< ir
->get_num_operands(); operand
++) {
175 ir
->operands
[operand
]->accept(this);
181 ir_if_simplification_visitor::visit(ir_swizzle
*ir
)
183 ir
->val
->accept(this);
188 ir_if_simplification_visitor::visit(ir_dereference
*ir
)
190 if (ir
->mode
== ir_dereference::ir_reference_array
) {
191 ir
->selector
.array_index
->accept(this);
193 ir
->var
->accept(this);
197 ir_if_simplification_visitor::visit(ir_assignment
*ir
)
199 ir
->rhs
->accept(this);
204 ir_if_simplification_visitor::visit(ir_constant
*ir
)
211 ir_if_simplification_visitor::visit(ir_call
*ir
)
218 ir_if_simplification_visitor::visit(ir_return
*ir
)
225 ir_if_simplification_visitor::visit(ir_if
*ir
)
227 ir
->condition
->accept(this);
229 do_if_simplification(&ir
->then_instructions
);
230 do_if_simplification(&ir
->else_instructions
);