On 31 August 2012 11:32, Eric Anholt <span dir="ltr"><<a href="mailto:eric@anholt.net" target="_blank">eric@anholt.net</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">




The first cut at instruction compaction won't compact things that<br>
would change control flow jump distances, but we do need to still be<br>
able to walk the instruction stream, which involves jumping by 8 or 16<br>
bytes between instructions.<br></blockquote><div><br>I'm not thrilled by the fact that after instruction compaction, p->store still has type struct brw_instruction *, but the data it points to doesn't always make sense as an array of struct brw_instruction.  It seems like there's a risk that we will later come along and add a p->store[...] reference somewhere it doesn't belong, and get ourselves into trouble.  But I don't really have a better suggestion to offer.<br>




 </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
 src/mesa/drivers/dri/i965/brw_eu_emit.c |   57 +++++++++++++++++++++++--------<br>
 1 file changed, 43 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c<br>
index 4d7b76d..c36742a 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c<br>
@@ -2476,12 +2476,24 @@ void brw_urb_WRITE(struct brw_compile *p,<br>
 }<br>
<br>
 static int<br>
+next_ip(struct brw_compile *p, int ip)<br>
+{<br>
+   struct brw_instruction *insn = (void *)p->store + ip;<br>
+<br>
+   if (insn->header.cmpt_control)<br>
+      return ip + 8;<br>
+   else<br>
+      return ip + 16;<br>
+}<br>
+<br>
+static int<br>
 brw_find_next_block_end(struct brw_compile *p, int start)<br>
 {<br>
    int ip;<br>
+   void *store = p->store;<br>
<br>
-   for (ip = start + 1; ip < p->nr_insn; ip++) {<br>
-      struct brw_instruction *insn = &p->store[ip];<br>
+   for (ip = next_ip(p, start); ip < p->next_insn_offset; ip = next_ip(p, ip)) {<br>
+      struct brw_instruction *insn = store + ip;<br>
<br>
       switch (insn->header.opcode) {<br>
       case BRW_OPCODE_ENDIF:<br>
@@ -2503,20 +2515,24 @@ brw_find_loop_end(struct brw_compile *p, int start)<br>
 {<br>
    struct intel_context *intel = &p->brw->intel;<br>
    int ip;<br>
-   int br = 2;<br>
+   int scale = 8;<br>
+   void *store = p->store;<br>
<br>
-   for (ip = start + 1; ip < p->nr_insn; ip++) {<br>
-      struct brw_instruction *insn = &p->store[ip];<br>
+   /* Always start after the instruction (such as a WHILE) we're trying to fix<br>
+    * up.<br>
+    */<br>
+   for (ip = next_ip(p, start); ip < p->next_insn_offset; ip = next_ip(p, ip)) {<br>
+      struct brw_instruction *insn = store + ip;<br>
<br>
       if (insn->header.opcode == BRW_OPCODE_WHILE) {<br>
         int jip = intel->gen == 6 ? insn->bits1.branch_gen6.jump_count<br>
                                   : insn->bits3.break_cont.jip;<br>
-        if (ip + jip / br <= start)<br>
+        if (ip + jip * scale <= start)<br>
            return ip;<br>
       }<br>
    }<br>
    assert(!"not reached");<br>
-   return start + 1;<br>
+   return start;<br>
 }<br>
<br>
 /* After program generation, go back and update the UIP and JIP of<br>
@@ -2527,24 +2543,37 @@ brw_set_uip_jip(struct brw_compile *p)<br>
 {<br>
    struct intel_context *intel = &p->brw->intel;<br>
    int ip;<br>
-   int br = 2;<br>
+   int scale = 8;<br>
+   void *store = p->store;<br>
<br>
    if (intel->gen < 6)<br>
       return;<br>
<br>
-   for (ip = 0; ip < p->nr_insn; ip++) {<br>
-      struct brw_instruction *insn = &p->store[ip];<br>
+   for (ip = 0; ip < p->next_insn_offset; ip = next_ip(p, ip)) {<br>
+      struct brw_instruction *insn = store + ip;<br>
+<br>
+      if (insn->header.cmpt_control) {<br>
+        /* Fixups for compacted BREAK/CONTINUE not supported yet. */<br>
+        assert(insn->header.opcode != BRW_OPCODE_BREAK &&<br>
+               insn->header.opcode != BRW_OPCODE_CONTINUE &&<br>
+               insn->header.opcode != BRW_OPCODE_HALT);<br>
+        continue;<br>
+      }<br>
<br>
       switch (insn->header.opcode) {<br>
       case BRW_OPCODE_BREAK:<br>
-        insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);<br>
+        insn->bits3.break_cont.jip =<br>
+            (brw_find_next_block_end(p, ip) - ip) / scale;<br>
         /* Gen7 UIP points to WHILE; Gen6 points just after it */<br>
         insn->bits3.break_cont.uip =<br>
-           br * (brw_find_loop_end(p, ip) - ip + (intel->gen == 6 ? 1 : 0));<br>
+           (brw_find_loop_end(p, ip) - ip +<br>
+             (intel->gen == 6 ? 16 : 0)) / scale;<br></blockquote><div><br>It looks from patch 7/8 like the WHILE instruction is never compacted, so I believe this is correct.  However, if we ever decide to compact the WHILE instruction this will be wrong for gen6.  Would it be possible to add an assertion here (or at the very least a comment) to alert us to the fact that this will need to be fixed when we get around to compacting WHILE?<br>



 </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
         break;<br>
       case BRW_OPCODE_CONTINUE:<br>
-        insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);<br>
-        insn->bits3.break_cont.uip = br * (brw_find_loop_end(p, ip) - ip);<br>
+        insn->bits3.break_cont.jip =<br>
+            (brw_find_next_block_end(p, ip) - ip) / scale;<br>
+        insn->bits3.break_cont.uip =<br>
+            (brw_find_loop_end(p, ip) - ip) / scale;<br>
<br>
         assert(insn->bits3.break_cont.uip != 0);<br>
         assert(insn->bits3.break_cont.jip != 0);<br>
<span><font color="#888888">--<br>
1.7.10.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br>