i965: Remove redundant discard jumps.
authorKenneth Graunke <kenneth@whitecape.org>
Sun, 6 Jul 2014 05:10:41 +0000 (22:10 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 24 Feb 2015 23:24:53 +0000 (15:24 -0800)
With the previous optimization in place, some shaders wind up with
multiple discard jumps in a row, or jumps directly to the next
instruction.  We can remove those.

Without NIR on Haswell:
total instructions in shared programs: 5777258 -> 5775872 (-0.02%)
instructions in affected programs:     20312 -> 18926 (-6.82%)
helped:                                716

With NIR on Haswell:
total instructions in shared programs: 5773163 -> 5771785 (-0.02%)
instructions in affected programs:     21040 -> 19662 (-6.55%)
helped:                                717

v2: Use the CFG rather than the old instructions list.  Presumably
    the placeholder halt will be in the last basic block.

v3: Make sure placeholder_halt->prev isn't the head sentinel (caught
    twice by Eric Anholt).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h

index 9df16507125a2fe90d6ad62d575b317fcab8d13b..0354f5698dcbee7b08f2ea39ce2cdef0fcf48127 100644 (file)
@@ -2558,6 +2558,47 @@ fs_visitor::opt_register_renaming()
    return progress;
 }
 
+/**
+ * Remove redundant or useless discard jumps.
+ *
+ * For example, we can eliminate jumps in the following sequence:
+ *
+ * discard-jump       (redundant with the next jump)
+ * discard-jump       (useless; jumps to the next instruction)
+ * placeholder-halt
+ */
+bool
+fs_visitor::opt_redundant_discard_jumps()
+{
+   bool progress = false;
+
+   bblock_t *last_bblock = cfg->blocks[cfg->num_blocks - 1];
+
+   fs_inst *placeholder_halt = NULL;
+   foreach_inst_in_block_reverse(fs_inst, inst, last_bblock) {
+      if (inst->opcode == FS_OPCODE_PLACEHOLDER_HALT) {
+         placeholder_halt = inst;
+         break;
+      }
+   }
+
+   if (!placeholder_halt)
+      return false;
+
+   /* Delete any HALTs immediately before the placeholder halt. */
+   for (fs_inst *prev = (fs_inst *) placeholder_halt->prev;
+        !prev->is_head_sentinel() && prev->opcode == FS_OPCODE_DISCARD_JUMP;
+        prev = (fs_inst *) placeholder_halt->prev) {
+      prev->remove(last_bblock);
+      progress = true;
+   }
+
+   if (progress)
+      invalidate_live_intervals();
+
+   return progress;
+}
+
 bool
 fs_visitor::compute_to_mrf()
 {
@@ -3661,6 +3702,7 @@ fs_visitor::optimize()
       OPT(opt_peephole_sel);
       OPT(dead_control_flow_eliminate, this);
       OPT(opt_register_renaming);
+      OPT(opt_redundant_discard_jumps);
       OPT(opt_saturate_propagation);
       OPT(register_coalesce);
       OPT(compute_to_mrf);
index 748069e7b000fe01fae54d7b41afae4d8f1406fe..70098d8451ad3113e62d6dd9e4bfe2457f41f302 100644 (file)
@@ -218,6 +218,7 @@ public:
    void calculate_live_intervals();
    void calculate_register_pressure();
    bool opt_algebraic();
+   bool opt_redundant_discard_jumps();
    bool opt_cse();
    bool opt_cse_local(bblock_t *block);
    bool opt_copy_propagate();