summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp52
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 6106445fbb..472e6d06f6 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