On Mon, 2016-02-22 at 11:42 -0800, Ian Romanick wrote: > From: Ian Romanick <ian.d.roman...@intel.com> > > Previously loops like > > do { > // ... > } while (false); > > that did not have any other loop-branch instructions would not be > unrolled. This is commonly used to wrap multiline preprocessor > macros. > > This produces IR like > > (loop ( > ... > break > )) > > Since limiting_terminator was NULL, the loop unroller would > throw up its hands and say, "I don't know how many iterations. How > can I unroll this?" > > We can detect this another way. If there is no limiting_terminator > and the only loop-branch is a break as the last IR, there's only one > iteration. > > On my very old checkout of shader-db,
I ran it on a recent version and this was still the only shader to hit this. > this removes a loop from Orbital > Explorer, but it does not otherwise affect the shader. The loop > removed > is the one the compiler inserts surrounding the switch statement. > > This change does prevent some seriously bad code generation in some > patches to meta shaders that I recently sent out for review. > > Signed-off-by: Ian Romanick <ian.d.roman...@intel.com> Reviewed-by: Timothy Arceri <timothy.arc...@collabora.com> > --- > src/compiler/glsl/loop_unroll.cpp | 30 ++++++++++++++++++++++++++--- > - > 1 file changed, 26 insertions(+), 4 deletions(-) > > diff --git a/src/compiler/glsl/loop_unroll.cpp > b/src/compiler/glsl/loop_unroll.cpp > index aea2743c..bc377df 100644 > --- a/src/compiler/glsl/loop_unroll.cpp > +++ b/src/compiler/glsl/loop_unroll.cpp > @@ -315,11 +315,33 @@ loop_unroll_visitor::visit_leave(ir_loop *ir) > return visit_continue; > } > > - /* Don't try to unroll loops where the number of iterations is > not known > - * at compile-time. > - */ > - if (ls->limiting_terminator == NULL) > + if (ls->limiting_terminator == NULL) { > + ir_instruction *last_ir = > + (ir_instruction *) ir->body_instructions.get_tail(); > + > + /* If a loop has no induction variable and the last > instruction is > + * a break, unroll the loop with a count of 1. This is the > classic > + * > + * do { > + * // ... > + * } while (false) > + * > + * that is used to wrap multi-line macros. > + * > + * If num_loop_jumps is not zero, last_ir cannot be NULL... > there has to > + * be at least num_loop_jumps instructions in the loop. > + */ > + if (ls->num_loop_jumps == 1 && is_break(last_ir)) { > + last_ir->remove(); > + > + simple_unroll(ir, 1); > + } > + > + /* Don't try to unroll loops where the number of iterations is > not known > + * at compile-time. > + */ > return visit_continue; > + } > > iterations = ls->limiting_terminator->iterations; > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev