Mesa (master): i965/fs: Extend predicated break pass to predicate WHILE.

Matt Turner mattst88 at kemper.freedesktop.org
Wed Oct 1 00:10:02 UTC 2014


Module: Mesa
Branch: master
Commit: d13bcdb3a9f9b43010fe8cbb4efbfe7eec0b705b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d13bcdb3a9f9b43010fe8cbb4efbfe7eec0b705b

Author: Matt Turner <mattst88 at gmail.com>
Date:   Thu Sep  4 13:25:15 2014 -0700

i965/fs: Extend predicated break pass to predicate WHILE.

Helps a handful of programs in Serious Sam 3 that use do-while loops.

instructions in affected programs:     16114 -> 16075 (-0.24%)

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

---

 .../dri/i965/brw_fs_peephole_predicated_break.cpp  |   36 ++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp b/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp
index 31b287a..b7a1d7e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp
@@ -38,6 +38,18 @@
  *
  * This peephole pass removes the IF and ENDIF instructions and predicates the
  * BREAK, dropping two instructions from the loop body.
+ *
+ * If the loop was a DO { ... } WHILE loop, it looks like
+ *
+ * loop:
+ *    ...
+ *    CMP.f0
+ *    (+f0) IF
+ *    BREAK
+ *    ENDIF
+ *    WHILE loop
+ *
+ * and we can remove the BREAK instruction and predicate the WHILE.
  */
 
 bool
@@ -107,6 +119,30 @@ fs_visitor::opt_peephole_predicated_break()
          block = earlier_block;
       }
 
+      /* Now look at the first instruction of the block following the BREAK. If
+       * it's a WHILE, we can delete the break, predicate the WHILE, and join
+       * the two basic blocks.
+       */
+      bblock_t *while_block = earlier_block->next();
+      fs_inst *while_inst = (fs_inst *)while_block->start();
+
+      if (jump_inst->opcode == BRW_OPCODE_BREAK &&
+          while_inst->opcode == BRW_OPCODE_WHILE &&
+          while_inst->predicate == BRW_PREDICATE_NONE) {
+         jump_inst->remove(earlier_block);
+         while_inst->predicate = jump_inst->predicate;
+         while_inst->predicate_inverse = !jump_inst->predicate_inverse;
+
+         earlier_block->children.make_empty();
+         earlier_block->add_successor(cfg->mem_ctx, while_block);
+
+         assert(earlier_block->can_combine_with(while_block));
+         earlier_block->combine_with(while_block);
+
+         earlier_block->next()->parents.make_empty();
+         earlier_block->add_successor(cfg->mem_ctx, earlier_block->next());
+      }
+
       progress = true;
    }
 




More information about the mesa-commit mailing list