i965: Add a basic-block aware backend_instruction::remove method.
authorMatt Turner <mattst88@gmail.com>
Sun, 13 Jul 2014 04:16:34 +0000 (21:16 -0700)
committerMatt Turner <mattst88@gmail.com>
Fri, 22 Aug 2014 17:23:33 +0000 (10:23 -0700)
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/drivers/dri/i965/brw_shader.h

index 28db29ac0767b3596a6cbacb31004799dd28a1b7..464790af9dd2a780afe83274af03b935336371d2 100644 (file)
@@ -732,6 +732,52 @@ backend_instruction::has_side_effects() const
    }
 }
 
+#ifndef NDEBUG
+static bool
+inst_is_in_block(const bblock_t *block, const backend_instruction *inst)
+{
+   bool found = false;
+   foreach_inst_in_block (backend_instruction, i, block) {
+      if (inst == i) {
+         found = true;
+      }
+   }
+   return found;
+}
+#endif
+
+static void
+adjust_later_block_ips(bblock_t *start_block, int ip_adjustment)
+{
+   for (bblock_t *block_iter = (bblock_t *)start_block->link.next;
+        !block_iter->link.is_tail_sentinel();
+        block_iter = (bblock_t *)block_iter->link.next) {
+      block_iter->start_ip += ip_adjustment;
+      block_iter->end_ip += ip_adjustment;
+   }
+}
+
+void
+backend_instruction::remove(bblock_t *block)
+{
+   assert(inst_is_in_block(block, this) || !"Instruction not in block");
+
+   adjust_later_block_ips(block, -1);
+
+   if (block->start_ip == block->end_ip) {
+      block->cfg->remove_block(block);
+   } else {
+      block->end_ip--;
+
+      if (block->start == this)
+         block->start = (backend_instruction *)this->next;
+      if (block->end == this)
+         block->end = (backend_instruction *)this->prev;
+   }
+
+   exec_node::remove();
+}
+
 void
 backend_visitor::dump_instructions()
 {
index 5980cf0cd688a5e3caad9aa53ea360256f283980..f5af4fd44e158cbaedb0815d40e7cbe5bbed3a9b 100644 (file)
@@ -78,6 +78,7 @@ struct backend_reg
 };
 
 struct cfg_t;
+struct bblock_t;
 
 #ifdef __cplusplus
 struct backend_instruction : public exec_node {
@@ -89,6 +90,9 @@ struct backend_instruction : public exec_node {
    bool reads_accumulator_implicitly() const;
    bool writes_accumulator_implicitly(struct brw_context *brw) const;
 
+   using exec_node::remove;
+   void remove(bblock_t *block);
+
    /**
     * True if the instruction has side effects other than writing to
     * its destination registers.  You are expected not to reorder or