summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2012-12-12 02:20:05 -0800
committerEric Anholt <[email protected]>2012-12-14 15:42:34 -0800
commit2702202290b55a9c8b61f02f7ae0af8f4a53f0e2 (patch)
treed6ceee097eab7dadc1bac9933e35ff9d0da8e994
parent2f7f095a801311bf62aa1204b5a9940509753cff (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.c7
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):
*