glsl/loops: Simplify loop unrolling logic by breaking into functions.
authorPaul Berry <stereotype441@gmail.com>
Fri, 29 Nov 2013 06:12:08 +0000 (22:12 -0800)
committerPaul Berry <stereotype441@gmail.com>
Mon, 9 Dec 2013 18:54:59 +0000 (10:54 -0800)
commite734c9f677ef3e9e2e4f207e4e794651ea6643b4
tree9e9c1f04d86bb1994b36121829a989eedc4fbaac
parentffc29120c402551fe9a7fa36e8ee5476bad27738
glsl/loops: Simplify loop unrolling logic by breaking into functions.

The old logic of loop_unroll_visitor::visit_leave(ir_loop *) was:

    heuristics to skip unrolling in various circumstances;
    if (loop contains more than one jump)
      return;
    else if (loop contains one jump) {
      if (the jump is an unconditional "break" at the end of the loop) {
        remove the break and set iteration count to 1;
        fall through to simple loop unrolling code;
      } else {
        for (each "if" statement in the loop body)
          see if the jump is a "break" at the end of one of its forks;
        if (the "break" wasn't found)
          return;
        splice the remainder of the loop into the other fork of the "if";
        remove the "break";
        complex loop unrolling code;
        return;
      }
    }
    simple loop unrolling code;
    return;

These tasks have been moved to their own functions:
- splice the remainder of the loop into the other fork of the "if"
- simple loop unrolling code
- complex loop unrolling code

And the logic has been flattened to:

    heuristics to skip unrolling in various circumstances;
    if (loop contains more than one jump)
      return;
    if (loop contains no jumps) {
      simple loop unroll;
      return;
    }
    if (the jump is an unconditional "break" at the end of the loop) {
      remove the break;
      simple loop unroll with iteration count of 1;
      return;
    }
    for (each "if" statement in the loop body) {
      if (the jump is a "break" at the end of one of its forks) {
        splice the remainder of the loop into the other fork of the "if";
        remove the "break";
        complex loop unroll;
        return;
      }
    }

This will make it easier to modify the loop unrolling algorithm in a
future patch.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/loop_unroll.cpp