[Mesa-dev] [PATCH 8/8] i965: Remove redundant discard jumps.

Matt Turner mattst88 at gmail.com
Tue Feb 24 08:48:27 PST 2015


On Tue, Feb 24, 2015 at 2:19 AM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> 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.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
>  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 9df1650..21e1e82 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->opcode == FS_OPCODE_DISCARD_JUMP;
> +        prev = (fs_inst *) placeholder_halt->prev) {
> +      prev->remove(last_bblock);
> +      progress = true;

I've read this code about four times and finally gotten what's going
on. We're not really iterating over the instructions and removing
them, we're just always deleting the one immediately previous the
placeholder halt while it's a discard jump. Tricky, but cool.

Yeah, seems like Eric's comment is valid -- should probably add a
!prev->is_head_sentinel() && to the condition.


More information about the mesa-dev mailing list