2 * Copyright © 2013 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 opt_flatten_nested_if_blocks.cpp
27 * Flattens nested if blocks such as:
35 * into a single if block with a combined condition:
43 #include "ir_builder.h"
45 using namespace ir_builder
;
49 class nested_if_flattener
: public ir_hierarchical_visitor
{
56 ir_visitor_status
visit_leave(ir_if
*);
57 ir_visitor_status
visit_enter(ir_assignment
*);
62 } /* unnamed namespace */
64 /* We only care about the top level "if" instructions, so don't
65 * descend into expressions.
68 nested_if_flattener::visit_enter(ir_assignment
*ir
)
71 return visit_continue_with_parent
;
75 opt_flatten_nested_if_blocks(exec_list
*instructions
)
77 nested_if_flattener v
;
85 nested_if_flattener::visit_leave(ir_if
*ir
)
87 /* Only handle a single ir_if within the then clause of an ir_if. No extra
88 * instructions, no else clauses, nothing.
90 if (ir
->then_instructions
.is_empty() || !ir
->else_instructions
.is_empty())
91 return visit_continue
;
93 ir_if
*inner
= ((ir_instruction
*) ir
->then_instructions
.head
)->as_if();
94 if (!inner
|| !inner
->next
->is_tail_sentinel() ||
95 !inner
->else_instructions
.is_empty())
96 return visit_continue
;
98 ir
->condition
= logic_and(ir
->condition
, inner
->condition
);
99 inner
->then_instructions
.move_nodes_to(&ir
->then_instructions
);
102 return visit_continue
;