diff options
author | Matt Turner <[email protected]> | 2014-12-20 11:50:31 -0800 |
---|---|---|
committer | Matt Turner <[email protected]> | 2014-12-29 10:08:18 -0800 |
commit | 44573458bdc52acc304fb75d6df502312b8e149c (patch) | |
tree | e048aa005f92dd79a277098712b11dda44c61c5a | |
parent | 7bc6e455e231076bfac6c678c375ea4aca94ebf0 (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.cpp | 61 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4.h | 1 |
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); |