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@amd.com> Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
This commit is contained in:
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user