summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2014-12-20 11:50:31 -0800
committerMatt Turner <[email protected]>2014-12-29 10:08:18 -0800
commit44573458bdc52acc304fb75d6df502312b8e149c (patch)
treee048aa005f92dd79a277098712b11dda44c61c5a
parent7bc6e455e231076bfac6c678c375ea4aca94ebf0 (diff)
i965/vec4: Add pass to gather constants into a vector-float MOV.
Currently only handles consecutive instructions with the same destination that collectively write all channels. total instructions in shared programs: 5879798 -> 5869011 (-0.18%) instructions in affected programs: 465236 -> 454449 (-2.32%) Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp61
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.h1
2 files changed, 62 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 36de76ae404..4a0f5120c10 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -336,6 +336,66 @@ src_reg::equals(const src_reg &r) const
sizeof(fixed_hw_reg)) == 0);
}
+bool
+vec4_visitor::opt_vector_float()
+{
+ bool progress = false;
+
+ int last_reg = -1;
+ int remaining_channels;
+ uint8_t imm[4];
+ int inst_count;
+ vec4_instruction *imm_inst[4];
+
+ foreach_block_and_inst_safe(block, vec4_instruction, inst, cfg) {
+ if (last_reg != inst->dst.reg) {
+ last_reg = inst->dst.reg;
+ remaining_channels = WRITEMASK_XYZW;
+
+ inst_count = 0;
+ }
+
+ if (inst->opcode != BRW_OPCODE_MOV ||
+ inst->dst.writemask == WRITEMASK_XYZW ||
+ inst->src[0].file != IMM)
+ continue;
+
+ int vf = brw_float_to_vf(inst->src[0].fixed_hw_reg.dw1.f);
+ if (vf == -1)
+ continue;
+
+ if ((inst->dst.writemask & WRITEMASK_X) != 0)
+ imm[0] = vf;
+ if ((inst->dst.writemask & WRITEMASK_Y) != 0)
+ imm[1] = vf;
+ if ((inst->dst.writemask & WRITEMASK_Z) != 0)
+ imm[2] = vf;
+ if ((inst->dst.writemask & WRITEMASK_W) != 0)
+ imm[3] = vf;
+
+ imm_inst[inst_count++] = inst;
+
+ remaining_channels &= ~inst->dst.writemask;
+ if (remaining_channels == 0) {
+ vec4_instruction *mov = MOV(inst->dst, imm);
+ mov->dst.type = BRW_REGISTER_TYPE_F;
+ mov->dst.writemask = WRITEMASK_XYZW;
+ inst->insert_after(block, mov);
+ last_reg = -1;
+
+ for (int i = 0; i < inst_count; i++) {
+ imm_inst[i]->remove(block);
+ }
+ progress = true;
+ }
+ }
+
+ if (progress)
+ invalidate_live_intervals();
+
+ return progress;
+}
+
/* Replaces unused channels of a swizzle with channels that are used.
*
* For instance, this pass transforms
@@ -1738,6 +1798,7 @@ vec4_visitor::run()
OPT(opt_register_coalesce);
} while (progress);
+ opt_vector_float();
if (failed)
return false;
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
index 0c44ad3123d..4a8a4676d65 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.h
+++ b/src/mesa/drivers/dri/i965/brw_vec4.h
@@ -365,6 +365,7 @@ public:
void calculate_live_intervals();
void invalidate_live_intervals();
void split_virtual_grfs();
+ bool opt_vector_float();
bool opt_reduce_swizzle();
bool dead_code_eliminate();
bool virtual_grf_interferes(int a, int b);