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">
---<br>
src/mesa/drivers/dri/i965/brw_eu_compact.c | 111 ++++++++++++++++++++++------<br>
1 file changed, 87 insertions(+), 24 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_eu_compact.c b/src/mesa/drivers/dri/i965/brw_eu_compact.c<br>
index 2c15c85..dd661f5 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_eu_compact.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_eu_compact.c<br>
@@ -324,6 +324,19 @@ brw_try_compact_instruction(struct brw_compile *c,<br>
return false; /* FINISHME: What else needs handling? */<br>
}<br>
<br>
+<br>
+ if (src->header.opcode == BRW_OPCODE_IF ||<br>
+ src->header.opcode == BRW_OPCODE_ELSE ||<br>
+ src->header.opcode == BRW_OPCODE_ENDIF ||<br>
+ src->header.opcode == BRW_OPCODE_DO ||<br>
+ src->header.opcode == BRW_OPCODE_HALT ||<br>
+ src->header.opcode == BRW_OPCODE_WHILE) {<br>
+ /* FINISHME: The fixup code below, and brw_set_uip_jip and friends, needs<br>
+ * to be able to handle flow control.<br>
+ */<br>
+ return false;<br>
+ }<br>
+<br>
/* FINISHME: immediates */<br>
if (src->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE ||<br>
src->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE)<br>
@@ -476,12 +489,40 @@ void brw_debug_compact_uncompact(struct intel_context *intel,<br>
}<br>
}<br>
<br>
+static int<br>
+compressed_between(int old_ip, int old_target_ip, int *compressed_counts)<br>
+{<br>
+ int this_compressed_count = compressed_counts[old_ip];<br>
+ int target_compressed_count = compressed_counts[old_target_ip];<br>
+ return target_compressed_count - this_compressed_count;<br>
+}<br>
+<br>
+static void<br>
+update_uip_jip(struct brw_instruction *insn, int this_old_ip,<br>
+ int *compressed_counts)<br>
+{<br>
+ int target_old_ip;<br>
+<br>
+ target_old_ip = this_old_ip + insn->bits3.break_cont.jip;<br>
+ insn->bits3.break_cont.jip -= compressed_between(this_old_ip,<br>
+ target_old_ip,<br>
+ compressed_counts);<br>
+<br>
+ target_old_ip = this_old_ip + insn->bits3.break_cont.uip;<br>
+ insn->bits3.break_cont.uip -= compressed_between(this_old_ip,<br>
+ target_old_ip,<br>
+ compressed_counts);<br>
+}<br>
+<br>
void<br>
brw_compact_instructions(struct brw_compile *p)<br>
{<br>
struct brw_context *brw = p->brw;<br>
struct intel_context *intel = &brw->intel;<br>
void *store = p->store;<br>
+ /* Control flow fixup information */<br>
+ int compressed_counts[p->next_insn_offset / 8];<br></blockquote><div><br>A comment would have saved me some time in understanding what information is stored in compressed_counts. I think this would be a correct description but I'm not certain: "If an instruction was located at offset 8*i before compaction, compressed_counts[i] is the number of instructions that preceded it which were not previously compressed, but are now."<br>
<br>An alternative way of representing the same information, possibly easier to follow, would be:<br><br>/* If an instruction was located at offset 8*i before compaction, 8*new_ip[i] is the location of the instruction after compaction */<br>
int new_ip[p->next_insn_offset / 8];<br><br>(Of course, update_uip_jip() would need to be reworked)<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ int old_ip[p->next_insn_offset / 8];<br></blockquote><div><br>And, assuming I'm understanding the code correctly, I believe old_ip could be commented:<br><br>/* If an instruction is located at offset 8*i after compaction, 8*old_ip[i] was the location of the instruction before compaction. In the case of NOPs inserted automatically for alignment, 8*old_ip[i] was the old location of the instruction that needed to be aligned. */<br>
<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
assert(gen6_control_index_table[ARRAY_SIZE(gen6_control_index_table) - 1] != 0);<br>
assert(gen6_datatype_table[ARRAY_SIZE(gen6_datatype_table) - 1] != 0);<br>
@@ -491,36 +532,21 @@ brw_compact_instructions(struct brw_compile *p)<br>
if (intel->gen != 6)<br>
return;<br>
<br>
- /* FINISHME: If we are going to compress instructions between flow control,<br>
- * we have to do fixups to flow control offsets to represent the new<br>
- * distances, since flow control uses (virtual address distance)/2, not a<br>
- * logical instruction count.<br>
- */<br>
- bool continue_compressing = true;<br>
- for (int i = 0; i < p->nr_insn; i++) {<br>
- if (p->store[i].header.opcode == BRW_OPCODE_WHILE)<br>
- return;<br>
- }<br>
-<br>
int src_offset;<br>
int offset = 0;<br>
+ int compressed_count = 0;<br>
for (src_offset = 0; src_offset < p->nr_insn * 16;) {<br>
struct brw_instruction *src = store + src_offset;<br>
void *dst = store + offset;<br>
<br>
- switch (src->header.opcode) {<br>
- case BRW_OPCODE_IF:<br>
- case BRW_OPCODE_HALT:<br>
- case BRW_OPCODE_JMPI:<br>
- continue_compressing = false;<br>
- break;<br>
- }<br>
+ old_ip[offset / 8] = src_offset / 8;<br>
+ compressed_counts[src_offset / 8] = compressed_count;<br>
<br>
struct brw_instruction saved = *src;<br>
<br>
- if (continue_compressing &&<br>
- !src->header.cmpt_control &&<br>
+ if (!src->header.cmpt_control &&<br>
brw_try_compact_instruction(p, dst, src)) {<br>
+ compressed_count++;<br>
<br>
/* debug */<br>
struct brw_instruction uncompacted;<br>
@@ -544,6 +570,7 @@ brw_compact_instructions(struct brw_compile *p)<br>
align->dw0.opcode = BRW_OPCODE_NOP;<br>
align->dw0.cmpt_ctrl = 1;<br>
offset += 8;<br>
+ old_ip[offset / 8] = src_offset / 8;<br>
dst = store + offset;<br>
}<br>
<br>
@@ -558,20 +585,56 @@ brw_compact_instructions(struct brw_compile *p)<br>
}<br>
}<br></blockquote><div><br>I'm running out of time to look at this today, so I had to stop reviewing here. I think the stuff that follows is likely correct (because if it weren't, it would probably fail spectacularly :)). I'll try to return to it tomorrow just to make sure.<br>
</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
+ /* Fix up control flow offsets. */<br>
+ p->next_insn_offset = offset;<br>
+ for (offset = 0; offset < p->next_insn_offset;) {<br>
+ struct brw_instruction *insn = store + offset;<br>
+ int this_old_ip = old_ip[offset / 8];<br>
+ int this_compressed_count = compressed_counts[this_old_ip];<br>
+ int target_old_ip, target_compressed_count;<br>
+<br>
+ switch (insn->header.opcode) {<br>
+ case BRW_OPCODE_BREAK:<br>
+ case BRW_OPCODE_CONTINUE:<br>
+ case BRW_OPCODE_HALT:<br>
+ update_uip_jip(insn, this_old_ip, compressed_counts);<br>
+ break;<br>
+<br>
+ case BRW_OPCODE_IF:<br>
+ case BRW_OPCODE_ELSE:<br>
+ case BRW_OPCODE_ENDIF:<br>
+ case BRW_OPCODE_WHILE:<br>
+ if (intel->gen == 6) {<br>
+ target_old_ip = this_old_ip + insn->bits1.branch_gen6.jump_count;<br>
+ target_compressed_count = compressed_counts[target_old_ip];<br>
+ insn->bits1.branch_gen6.jump_count -= (target_compressed_count -<br>
+ this_compressed_count);<br>
+ } else {<br>
+ update_uip_jip(insn, this_old_ip, compressed_counts);<br>
+ }<br>
+ break;<br>
+ }<br>
+<br>
+ if (insn->header.cmpt_control) {<br>
+ offset += 8;<br>
+ } else {<br>
+ offset += 16;<br>
+ }<br>
+ }<br>
+<br>
/* p->nr_insn is counting the number of uncompacted instructions still, so<br>
* divide. We do want to be sure there's a valid instruction in any<br>
* alignment padding, so that the next compression pass (for the FS 8/16<br>
* compile passes) parses correctly.<br>
*/<br>
- if (offset & 8) {<br>
+ if (p->next_insn_offset & 8) {<br>
struct brw_compact_instruction *align = store + offset;<br>
memset(align, 0, sizeof(*align));<br>
align->dw0.opcode = BRW_OPCODE_NOP;<br>
align->dw0.cmpt_ctrl = 1;<br>
- offset += 8;<br>
+ p->next_insn_offset += 8;<br>
}<br>
- p->next_insn_offset = offset;<br>
- p->nr_insn = offset / 16;<br>
+ p->nr_insn = p->next_insn_offset / 16;<br>
<br>
if (0) {<br>
fprintf(stdout, "dumping compacted program\n");<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.10.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">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>