On Tue, Feb 24, 2015 at 2:19 AM, Kenneth Graunke <kenn...@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 <kenn...@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. _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev