[Mesa-dev] [PATCH 20/20] i965/fs: Preserve CFG in predicated break pass.

Matt Turner mattst88 at gmail.com
Thu Jul 24 19:54:27 PDT 2014


Operating on this code,

B0: ...
    cmp.ne.f0(8)
    (+f0) if(8)
B1: break(8)
B2: endif(8)

We can delete B2 without attempting to merge any blocks, since the
break/continue instruction necessarily ends the previous block.

After deleting the if instruction, we attempt to merge blocks B0 and B1.
---
 .../dri/i965/brw_fs_peephole_predicated_break.cpp  | 29 +++++++++++++++++++---
 1 file changed, 25 insertions(+), 4 deletions(-)

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 445d10e..ab197ee 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
@@ -64,27 +64,48 @@ fs_visitor::opt_peephole_predicated_break()
       if (endif_inst->opcode != BRW_OPCODE_ENDIF)
          continue;
 
+      bblock_t *jump_block = block;
+      bblock_t *if_block = (bblock_t *)jump_block->link.prev;
+      bblock_t *endif_block = (bblock_t *)jump_block->link.next;
+
       /* For Sandybridge with IF with embedded comparison we need to emit an
        * instruction to set the flag register.
        */
       if (brw->gen == 6 && if_inst->conditional_mod) {
          fs_inst *cmp_inst = CMP(reg_null_d, if_inst->src[0], if_inst->src[1],
                                  if_inst->conditional_mod);
-         if_inst->insert_before(cmp_inst);
+         if_inst->insert_before(if_block, cmp_inst);
          jump_inst->predicate = BRW_PREDICATE_NORMAL;
       } else {
          jump_inst->predicate = if_inst->predicate;
          jump_inst->predicate_inverse = if_inst->predicate_inverse;
       }
 
-      if_inst->remove();
-      endif_inst->remove();
+      bblock_t *earlier_block = if_block;
+      if (if_block->start_ip == if_block->end_ip) {
+         earlier_block = (bblock_t *)if_block->link.prev;
+      }
+
+      if_inst->remove(if_block);
+      endif_inst->remove(endif_block);
+
+      if_block->children.make_empty();
+      endif_block->parents.make_empty();
+
+      if_block->add_successor(cfg->mem_ctx, jump_block);
+      jump_block->add_successor(cfg->mem_ctx, endif_block);
+
+      if (earlier_block->can_combine_with(jump_block)) {
+         earlier_block->combine_with(jump_block);
+
+         block = earlier_block;
+      }
 
       progress = true;
    }
 
    if (progress)
-      invalidate_live_intervals();
+      invalidate_live_intervals(false);
 
    return progress;
 }
-- 
1.8.5.5



More information about the mesa-dev mailing list