Mesa (master): glsl: don' t drop instructions from unreachable terminators continue branch
Timothy Arceri
tarceri at kemper.freedesktop.org
Mon Oct 9 23:05:48 UTC 2017
Module: Mesa
Branch: master
Commit: ab23b759f241a4e2247efa28bd28a5f20149c70b
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=ab23b759f241a4e2247efa28bd28a5f20149c70b
Author: Timothy Arceri <tarceri at itsqueeze.com>
Date: Tue Sep 5 15:59:07 2017 +1000
glsl: don't drop instructions from unreachable terminators continue branch
These instructions will be executed on every iteration of the loop
we cannot drop them.
V2:
- move removal of unreachable terminators from the terminator list
to the same place they are removed from the IR as suggested by
Nicolai.
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
Tested-by: Dieter Nützel <Dieter at nuetzel-hh.de>
---
src/compiler/glsl/loop_analysis.h | 7 +++++++
src/compiler/glsl/loop_unroll.cpp | 28 ++++++++++++++++++++--------
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/src/compiler/glsl/loop_analysis.h b/src/compiler/glsl/loop_analysis.h
index 8f82404694..99b6bf7563 100644
--- a/src/compiler/glsl/loop_analysis.h
+++ b/src/compiler/glsl/loop_analysis.h
@@ -34,6 +34,13 @@
extern class loop_state *
analyze_loop_variables(exec_list *instructions);
+static inline bool
+is_break(ir_instruction *ir)
+{
+ return ir != NULL && ir->ir_type == ir_type_loop_jump &&
+ ((ir_loop_jump *) ir)->is_break();
+}
+
extern bool
unroll_loops(exec_list *instructions, loop_state *ls,
diff --git a/src/compiler/glsl/loop_unroll.cpp b/src/compiler/glsl/loop_unroll.cpp
index 7eea439454..358cbf10af 100644
--- a/src/compiler/glsl/loop_unroll.cpp
+++ b/src/compiler/glsl/loop_unroll.cpp
@@ -53,13 +53,6 @@ public:
} /* anonymous namespace */
-static bool
-is_break(ir_instruction *ir)
-{
- return ir != NULL && ir->ir_type == ir_type_loop_jump
- && ((ir_loop_jump *) ir)->is_break();
-}
-
class loop_unroll_count : public ir_hierarchical_visitor {
public:
int nodes;
@@ -333,16 +326,35 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
* bound, then that terminates the loop, so we don't even need the limiting
* terminator.
*/
- foreach_in_list(loop_terminator, t, &ls->terminators) {
+ foreach_in_list_safe(loop_terminator, t, &ls->terminators) {
if (t->iterations < 0)
continue;
+ exec_list *branch_instructions;
if (t != ls->limiting_terminator) {
+ ir_instruction *ir_if_last = (ir_instruction *)
+ t->ir->then_instructions.get_tail();
+ if (is_break(ir_if_last)) {
+ branch_instructions = &t->ir->else_instructions;
+ } else {
+ branch_instructions = &t->ir->then_instructions;
+ assert(is_break((ir_instruction *)
+ t->ir->else_instructions.get_tail()));
+ }
+
+ exec_list copy_list;
+ copy_list.make_empty();
+ clone_ir_list(ir, ©_list, branch_instructions);
+
+ t->ir->insert_before(©_list);
t->ir->remove();
assert(ls->num_loop_jumps > 0);
ls->num_loop_jumps--;
+ /* Also remove it from the terminator list */
+ t->remove();
+
this->progress = true;
}
}
More information about the mesa-commit
mailing list