diff options
author | Kenneth Graunke <[email protected]> | 2012-12-12 02:20:05 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2012-12-14 15:42:34 -0800 |
commit | 2702202290b55a9c8b61f02f7ae0af8f4a53f0e2 (patch) | |
tree | d6ceee097eab7dadc1bac9933e35ff9d0da8e994 | |
parent | 2f7f095a801311bf62aa1204b5a9940509753cff (diff) |
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 <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_eu_emit.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index dd91a3087c8..c294bae74d9 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): * |