i965/fs: Don't iterate between blocks with inst->next/prev.
authorMatt Turner <mattst88@gmail.com>
Tue, 2 Sep 2014 17:08:24 +0000 (10:08 -0700)
committerMatt Turner <mattst88@gmail.com>
Wed, 24 Sep 2014 16:42:46 +0000 (09:42 -0700)
When instruction lists are per-basic block, this won't work.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_dead_control_flow.cpp
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp
src/mesa/drivers/dri/i965/brw_fs_saturate_propagation.cpp
src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp

index 485ab91b4e6afc8fd79d7739d83b36b440894d20..fad1d423cee95bc863f9fd907017b86dd828a715 100644 (file)
@@ -52,13 +52,14 @@ dead_control_flow_eliminate(backend_visitor *v)
          continue;
 
       backend_instruction *if_inst = NULL, *else_inst = NULL;
-      backend_instruction *prev_inst = (backend_instruction *) endif_inst->prev;
+      backend_instruction *prev_inst = ((bblock_t *)endif_block->link.prev)->end;
       if (prev_inst->opcode == BRW_OPCODE_ELSE) {
          else_inst = prev_inst;
          else_block = (bblock_t *)endif_block->link.prev;
          found = true;
 
-         prev_inst = (backend_instruction *) prev_inst->prev;
+         if (else_block->start_ip == else_block->end_ip)
+            prev_inst = ((bblock_t *)else_block->link.prev)->end;
       }
 
       if (prev_inst->opcode == BRW_OPCODE_IF) {
index e3bb807f9cb43932db9574b6688596f37e0ad966..323abff6744ad1ee9ad66b4d8d5213860d0ff872 100644 (file)
@@ -2213,10 +2213,7 @@ fs_visitor::compute_to_mrf()
       /* Found a move of a GRF to a MRF.  Let's see if we can go
        * rewrite the thing that made this GRF to write into the MRF.
        */
-      fs_inst *scan_inst;
-      for (scan_inst = (fs_inst *)inst->prev;
-           !scan_inst->is_head_sentinel();
-          scan_inst = (fs_inst *)scan_inst->prev) {
+      foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst, block) {
         if (scan_inst->dst.file == GRF &&
             scan_inst->dst.reg == inst->src[0].reg) {
            /* Found the last thing to write our reg we want to turn
@@ -2265,7 +2262,7 @@ fs_visitor::compute_to_mrf()
          * values that end up in MRFs are shortly before the MRF
          * write anyway.
          */
-        if (scan_inst->is_control_flow() && scan_inst->opcode != BRW_OPCODE_IF)
+        if (block->start == scan_inst)
            break;
 
         /* You can't read from an MRF, so if someone else reads our
@@ -2565,14 +2562,11 @@ fs_visitor::insert_gen4_pre_send_dependency_workarounds(bblock_t *block,
     * we assume that there are no outstanding dependencies on entry to the
     * program.
     */
-   for (fs_inst *scan_inst = (fs_inst *)inst->prev;
-        !scan_inst->is_head_sentinel();
-        scan_inst = (fs_inst *)scan_inst->prev) {
-
+   foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst, block) {
       /* If we hit control flow, assume that there *are* outstanding
        * dependencies, and force their cleanup before our instruction.
        */
-      if (scan_inst->is_control_flow()) {
+      if (block->start == scan_inst) {
          for (int i = 0; i < write_len; i++) {
             if (needs_dep[i]) {
                inst->insert_before(block, DEP_RESOLVE_MOV(first_write_grf + i));
@@ -2639,11 +2633,9 @@ fs_visitor::insert_gen4_post_send_dependency_workarounds(bblock_t *block, fs_ins
    /* Walk forwards looking for writes to registers we're writing which aren't
     * read before being written.
     */
-   for (fs_inst *scan_inst = (fs_inst *)inst->next;
-        !scan_inst->is_tail_sentinel();
-        scan_inst = (fs_inst *)scan_inst->next) {
+   foreach_inst_in_block_starting_from(fs_inst, scan_inst, inst, block) {
       /* If we hit control flow, force resolve all remaining dependencies. */
-      if (scan_inst->is_control_flow()) {
+      if (block->end == scan_inst) {
          for (int i = 0; i < write_len; i++) {
             if (needs_dep[i])
                scan_inst->insert_before(block,
index c669fbed9f03d2098300f1d42d0b2aff4f1bce32..5b4cab5390209d8a09a39a6e6d81e0c394bd6616 100644 (file)
@@ -46,6 +46,9 @@ fs_visitor::opt_peephole_predicated_break()
    bool progress = false;
 
    foreach_block (block, cfg) {
+      if (block->start_ip != block->end_ip)
+         continue;
+
       /* BREAK and CONTINUE instructions, by definition, can only be found at
        * the ends of basic blocks.
        */
@@ -54,11 +57,11 @@ fs_visitor::opt_peephole_predicated_break()
           jump_inst->opcode != BRW_OPCODE_CONTINUE)
          continue;
 
-      fs_inst *if_inst = (fs_inst *)jump_inst->prev;
+      fs_inst *if_inst = (fs_inst *)((bblock_t *)block->link.prev)->end;
       if (if_inst->opcode != BRW_OPCODE_IF)
          continue;
 
-      fs_inst *endif_inst = (fs_inst *)jump_inst->next;
+      fs_inst *endif_inst = (fs_inst *)((bblock_t *)block->link.next)->start;
       if (endif_inst->opcode != BRW_OPCODE_ENDIF)
          continue;
 
index d65b2f14e13fb62de7bc7e7b63fc282f0a512b53..4c4b6bf47a817e24e1f9dc8956c898efa2fc5bdb 100644 (file)
@@ -48,13 +48,8 @@ opt_saturate_propagation_local(fs_visitor *v, bblock_t *block)
       int src_var = v->live_intervals->var_from_reg(&inst->src[0]);
       int src_end_ip = v->live_intervals->end[src_var];
 
-      int scan_ip = ip;
       bool interfered = false;
-      for (fs_inst *scan_inst = (fs_inst *) inst->prev;
-           scan_inst != block->start->prev;
-           scan_inst = (fs_inst *) scan_inst->prev) {
-         scan_ip--;
-
+      foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst, block) {
          if (scan_inst->dst.file == GRF &&
              scan_inst->dst.reg == inst->src[0].reg &&
              scan_inst->dst.reg_offset == inst->src[0].reg_offset &&
index 2437a2f2ae1fd26c0146d55e88688a815aac0318..28e41638e038dcf4bce4ccac4e4ab1e97d103987 100644 (file)
@@ -41,9 +41,9 @@
  * Scans forwards from an IF counting consecutive MOV instructions in the
  * "then" and "else" blocks of the if statement.
  *
- * A pointer to the fs_inst* for IF is passed as the <if_inst> argument. The
- * function stores pointers to the MOV instructions in the <then_mov> and
- * <else_mov> arrays.
+ * A pointer to the bblock_t following the IF is passed as the <then_block>
+ * argument. The function stores pointers to the MOV instructions in the
+ * <then_mov> and <else_mov> arrays.
  *
  * \return the minimum number of MOVs found in the two branches or zero if
  *         an error occurred.
  */
 static int
 count_movs_from_if(fs_inst *then_mov[MAX_MOVS], fs_inst *else_mov[MAX_MOVS],
-                   fs_inst *if_inst, fs_inst *else_inst)
+                   bblock_t *then_block, bblock_t *else_block)
 {
-   fs_inst *m = if_inst;
-
-   assert(m->opcode == BRW_OPCODE_IF);
-   m = (fs_inst *) m->next;
-
    int then_movs = 0;
-   while (then_movs < MAX_MOVS && m->opcode == BRW_OPCODE_MOV) {
-      then_mov[then_movs] = m;
-      m = (fs_inst *) m->next;
+   foreach_inst_in_block(fs_inst, inst, then_block) {
+      if (then_movs == MAX_MOVS || inst->opcode != BRW_OPCODE_MOV)
+         break;
+
+      then_mov[then_movs] = inst;
       then_movs++;
    }
 
-   m = (fs_inst *) else_inst->next;
-
    int else_movs = 0;
-   while (else_movs < MAX_MOVS && m->opcode == BRW_OPCODE_MOV) {
-      else_mov[else_movs] = m;
-      m = (fs_inst *) m->next;
+   foreach_inst_in_block(fs_inst, inst, else_block) {
+      if (else_movs == MAX_MOVS || inst->opcode != BRW_OPCODE_MOV)
+         break;
+
+      else_mov[else_movs] = inst;
       else_movs++;
    }
 
@@ -138,13 +135,15 @@ fs_visitor::opt_peephole_sel()
       if (!block->else_block)
          continue;
 
-      fs_inst *else_inst = (fs_inst *) block->else_block->end;
-      assert(else_inst->opcode == BRW_OPCODE_ELSE);
+      assert(block->else_block->end->opcode == BRW_OPCODE_ELSE);
 
       fs_inst *else_mov[MAX_MOVS] = { NULL };
       fs_inst *then_mov[MAX_MOVS] = { NULL };
 
-      int movs = count_movs_from_if(then_mov, else_mov, if_inst, else_inst);
+      bblock_t *then_block = (bblock_t *)block->link.next;
+      bblock_t *else_block = (bblock_t *)block->else_block->link.next;
+
+      int movs = count_movs_from_if(then_mov, else_mov, then_block, else_block);
 
       if (movs == 0)
          continue;
@@ -213,9 +212,6 @@ fs_visitor::opt_peephole_sel()
          if_inst->insert_before(block, cmp_inst);
       }
 
-      bblock_t *then_block = (bblock_t *)block->link.next;
-      bblock_t *else_block = (bblock_t *)block->else_block->link.next;
-
       for (int i = 0; i < movs; i++) {
          if (mov_imm_inst[i])
             if_inst->insert_before(block, mov_imm_inst[i]);