From ee3f6745723856419d7f5ecb17652e19855c4caa Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 5 Jul 2014 22:10:41 -0700 Subject: [PATCH] i965: Remove redundant discard jumps. 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 Reviewed-by: Matt Turner Reviewed-by: Eric Anholt --- src/mesa/drivers/dri/i965/brw_fs.cpp | 42 ++++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/brw_fs.h | 1 + 2 files changed, 43 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 9df16507125..0354f5698dc 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 748069e7b00..70098d8451a 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -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(); -- 2.30.2