summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2011-07-22 16:45:15 -0700
committerEric Anholt <[email protected]>2011-07-29 12:17:03 -0700
commita8b86459a1bb74cfdf0d63572a9fe194b2b5b53f (patch)
tree0f1ba8a1a1de73ccb611f1648e7a1966a71d9425 /src/mesa/drivers
parent6d8d6b41b85a18685351f3023a4cd41266ba9e68 (diff)
i965/fs: Optimize a * 1.0 -> a.
This appears in our instruction stream as a result of the brw_vs_constval.c handling.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp43
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
2 files changed, 44 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 351d1dd283e..a9617c56e12 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1067,6 +1067,7 @@ fs_visitor::propagate_constants()
if (inst->src[0].imm.f != 0.0f) {
scan_inst->opcode = BRW_OPCODE_MOV;
scan_inst->src[0] = inst->src[0];
+ scan_inst->src[0].imm.f = 1.0f / scan_inst->src[0].imm.f;
progress = true;
}
break;
@@ -1087,6 +1088,47 @@ fs_visitor::propagate_constants()
return progress;
}
+
+
+/**
+ * Attempts to move immediate constants into the immediate
+ * constant slot of following instructions.
+ *
+ * Immediate constants are a bit tricky -- they have to be in the last
+ * operand slot, you can't do abs/negate on them,
+ */
+
+bool
+fs_visitor::opt_algebraic()
+{
+ bool progress = false;
+
+ calculate_live_intervals();
+
+ foreach_list(node, &this->instructions) {
+ fs_inst *inst = (fs_inst *)node;
+
+ switch (inst->opcode) {
+ case BRW_OPCODE_MUL:
+ if (inst->src[1].file != IMM)
+ continue;
+
+ /* a * 1.0 = a */
+ if (inst->src[1].type == BRW_REGISTER_TYPE_F &&
+ inst->src[1].imm.f == 1.0) {
+ inst->opcode = BRW_OPCODE_MOV;
+ inst->src[1] = reg_undef;
+ progress = true;
+ break;
+ }
+
+ break;
+ }
+ }
+
+ return progress;
+}
+
/**
* Must be called after calculate_live_intervales() to remove unused
* writes to registers -- register allocation will fail otherwise
@@ -1572,6 +1614,7 @@ fs_visitor::run()
progress = remove_duplicate_mrf_writes() || progress;
progress = propagate_constants() || progress;
+ progress = opt_algebraic() || progress;
progress = register_coalesce() || progress;
progress = compute_to_mrf() || progress;
progress = dead_code_eliminate() || progress;
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 2bf850e5dea..89d6cda7e4f 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -485,6 +485,7 @@ public:
void setup_pull_constants();
void calculate_live_intervals();
bool propagate_constants();
+ bool opt_algebraic();
bool register_coalesce();
bool compute_to_mrf();
bool dead_code_eliminate();