diff options
author | Emil Velikov <emil.velikov@collabora.com> | 2016-01-18 12:16:48 +0200 |
---|---|---|
committer | Emil Velikov <emil.l.velikov@gmail.com> | 2016-01-26 16:08:33 +0000 |
commit | eb63640c1d38a200a7b1540405051d3ff79d0d8a (patch) | |
tree | da46321a41f309b1d02aeb14d5d5487791c45aeb /src/compiler/glsl/opt_flatten_nested_if_blocks.cpp | |
parent | a39a8fbbaa129f4e52f2a3ad2747182e9a74d910 (diff) | |
download | external_mesa3d-eb63640c1d38a200a7b1540405051d3ff79d0d8a.zip external_mesa3d-eb63640c1d38a200a7b1540405051d3ff79d0d8a.tar.gz external_mesa3d-eb63640c1d38a200a7b1540405051d3ff79d0d8a.tar.bz2 |
glsl: move to compiler/
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Acked-by: Matt Turner <mattst88@gmail.com>
Acked-by: Jose Fonseca <jfonseca@vmware.com>
Diffstat (limited to 'src/compiler/glsl/opt_flatten_nested_if_blocks.cpp')
-rw-r--r-- | src/compiler/glsl/opt_flatten_nested_if_blocks.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/compiler/glsl/opt_flatten_nested_if_blocks.cpp b/src/compiler/glsl/opt_flatten_nested_if_blocks.cpp new file mode 100644 index 0000000..c702102 --- /dev/null +++ b/src/compiler/glsl/opt_flatten_nested_if_blocks.cpp @@ -0,0 +1,103 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file opt_flatten_nested_if_blocks.cpp + * + * Flattens nested if blocks such as: + * + * if (x) { + * if (y) { + * ... + * } + * } + * + * into a single if block with a combined condition: + * + * if (x && y) { + * ... + * } + */ + +#include "ir.h" +#include "ir_builder.h" + +using namespace ir_builder; + +namespace { + +class nested_if_flattener : public ir_hierarchical_visitor { +public: + nested_if_flattener() + { + progress = false; + } + + ir_visitor_status visit_leave(ir_if *); + ir_visitor_status visit_enter(ir_assignment *); + + bool progress; +}; + +} /* unnamed namespace */ + +/* We only care about the top level "if" instructions, so don't + * descend into expressions. + */ +ir_visitor_status +nested_if_flattener::visit_enter(ir_assignment *ir) +{ + (void) ir; + return visit_continue_with_parent; +} + +bool +opt_flatten_nested_if_blocks(exec_list *instructions) +{ + nested_if_flattener v; + + v.run(instructions); + return v.progress; +} + + +ir_visitor_status +nested_if_flattener::visit_leave(ir_if *ir) +{ + /* Only handle a single ir_if within the then clause of an ir_if. No extra + * instructions, no else clauses, nothing. + */ + if (ir->then_instructions.is_empty() || !ir->else_instructions.is_empty()) + return visit_continue; + + ir_if *inner = ((ir_instruction *) ir->then_instructions.head)->as_if(); + if (!inner || !inner->next->is_tail_sentinel() || + !inner->else_instructions.is_empty()) + return visit_continue; + + ir->condition = logic_and(ir->condition, inner->condition); + inner->then_instructions.move_nodes_to(&ir->then_instructions); + + progress = true; + return visit_continue; +} |