[Mesa-dev] [PATCH 1/5] i965/fs: Extend predicated break pass to predicate WHILE.

Ian Romanick idr at freedesktop.org
Thu Sep 25 08:25:43 PDT 2014


How did you test this?  Do we have piglit execution tests that actually
hit this path?  I'm assuming you didn't play Serious Sam 3 looking for
rendering errors. ;)

On 09/08/2014 12:21 PM, Matt Turner wrote:
> Helps a handful of programs in Serious Sam 3 that use do-while loops.
> 
> instructions in affected programs:     16114 -> 16075 (-0.24%)
> ---
> This patch depends on the save-cfg series.
> 
>  .../dri/i965/brw_fs_peephole_predicated_break.cpp  | 37 ++++++++++++++++++++++
>  1 file changed, 37 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..66440d4 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,31 @@ 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-dev mailing list