From: Kenneth Graunke Date: Wed, 12 Dec 2012 10:20:05 +0000 (-0800) Subject: i965: Jump to the end of the next outer conditional block on ENDIFs. X-Git-Tag: mesa-9.1-rc1~776 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2702202290b55a9c8b61f02f7ae0af8f4a53f0e2;p=platform%2Fupstream%2Fmesa.git i965: Jump to the end of the next outer conditional block on ENDIFs. From the Ivybridge PRM, Volume 4, Part 3, section 6.24 (page 172): "The endif instruction is also used to hop out of nested conditionals by jumping to the end of the next outer conditional block when all channels are disabled." Also: "Pseudocode: Evaluate(WrEn); if ( WrEn == 0 ) { // all channels false Jump(IP + JIP); }" First, ENDIF re-enables any channels that were disabled because they didn't match the conditional. If any channels are active, it proceeds to the next instruction (IP + 16). However, if they're all disabled, there's no point in walking through all of the instructions that have no effect---it can jump to the next instruction that might re-enable some channels (an ELSE, ENDIF, or WHILE). Previously, we always set JIP on ENDIF instructions to 2 (which is measured in 8-byte units). This made it do Jump(IP + 16), which just meant it would go to the next instruction even if all channels were off. It turns out that walking over instructions while all the channels are disabled like this is worse than just instruction dispatch overhead: if there are texturing messages, it still costs a couple hundred cycles to not-actually-read from the texture results. This patch finds the next instruction that could re-enable channels and sets JIP accordingly. Reviewed-by: Eric Anholt --- diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index dd91a30..c294bae 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -2396,7 +2396,14 @@ brw_set_uip_jip(struct brw_compile *p) assert(insn->bits3.break_cont.uip != 0); assert(insn->bits3.break_cont.jip != 0); + + case BRW_OPCODE_ENDIF: + if (block_end_ip == 0) + insn->bits3.break_cont.jip = 2; + else + insn->bits3.break_cont.jip = (block_end_ip - ip) / scale; break; + case BRW_OPCODE_HALT: /* From the Sandy Bridge PRM (volume 4, part 2, section 8.3.19): *