Mesa (master): i965: Add trivial dead code elimination in the new FS backend.

Eric Anholt anholt at kemper.freedesktop.org
Mon Oct 4 23:09:20 UTC 2010


Module: Mesa
Branch: master
Commit: e27c88d8e6c9d18bfa793f884d02ce6011c4bdde
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e27c88d8e6c9d18bfa793f884d02ce6011c4bdde

Author: Eric Anholt <eric at anholt.net>
Date:   Sun Oct  3 15:15:18 2010 -0700

i965: Add trivial dead code elimination in the new FS backend.

The glsl core should be handling most dead code issues for us, but we
generate some things in codegen that may not get used, like the 1/w
value or pixel deltas.  It seems a lot easier this way than trying to
work out up front whether we're going to use those values or not.

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   52 ++++++++++++++++++++++++++++++++-
 1 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 6106445..472e6d0 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -455,6 +455,7 @@ public:
    void assign_regs();
    void assign_regs_trivial();
    void calculate_live_intervals();
+   bool dead_code_eliminate();
    bool virtual_grf_interferes(int a, int b);
    void generate_code();
    void generate_fb_write(fs_inst *inst);
@@ -2289,8 +2290,6 @@ fs_visitor::assign_regs()
    int class_count = 0;
    int aligned_pair_class = -1;
 
-   calculate_live_intervals();
-
    /* Set up the register classes.
     *
     * The base registers store a scalar value.  For texture samples,
@@ -2517,10 +2516,50 @@ fs_visitor::calculate_live_intervals()
       ip++;
    }
 
+   talloc_free(this->virtual_grf_def);
+   talloc_free(this->virtual_grf_use);
    this->virtual_grf_def = def;
    this->virtual_grf_use = use;
 }
 
+/**
+ * Must be called after calculate_live_intervales() to remove unused
+ * writes to registers -- register allocation will fail otherwise
+ * because something deffed but not used won't be considered to
+ * interfere with other regs.
+ */
+bool
+fs_visitor::dead_code_eliminate()
+{
+   bool progress = false;
+   int num_vars = this->virtual_grf_next;
+   bool dead[num_vars];
+
+   for (int i = 0; i < num_vars; i++) {
+      /* This would be ">=", but FS_OPCODE_DISCARD has a src == dst where
+       * it writes dst then reads it as src.
+       */
+      dead[i] = this->virtual_grf_def[i] > this->virtual_grf_use[i];
+
+      if (dead[i]) {
+	 /* Mark off its interval so it won't interfere with anything. */
+	 this->virtual_grf_def[i] = -1;
+	 this->virtual_grf_use[i] = -1;
+      }
+   }
+
+   foreach_iter(exec_list_iterator, iter, this->instructions) {
+      fs_inst *inst = (fs_inst *)iter.get();
+
+      if (inst->dst.file == GRF && dead[inst->dst.reg]) {
+	 inst->remove();
+	 progress = true;
+      }
+   }
+
+   return progress;
+}
+
 bool
 fs_visitor::virtual_grf_interferes(int a, int b)
 {
@@ -2831,6 +2870,15 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
       v.emit_fb_writes();
       v.assign_curb_setup();
       v.assign_urb_setup();
+
+      bool progress;
+      do {
+	 progress = false;
+
+	 v.calculate_live_intervals();
+	 progress = v.dead_code_eliminate() || progress;
+      } while (progress);
+
       if (0)
 	 v.assign_regs_trivial();
       else




More information about the mesa-commit mailing list