From: Matt Turner Date: Wed, 12 Aug 2015 18:35:17 +0000 (-0700) Subject: i965/vec4/nir: Emit single MOV to generate a scalar constant. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2450cbfcbc3671056afad9e858acadbb6edea068;p=mesa.git i965/vec4/nir: Emit single MOV to generate a scalar constant. If an immediate is written to multiple channels, we can load it in a single writemasked MOV. total instructions in shared programs: 6285144 -> 6261991 (-0.37%) instructions in affected programs: 718991 -> 695838 (-3.22%) helped: 5762 Reviewed-by: Jason Ekstrand --- diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index 923e2d30a4c..632e409fdf4 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -458,13 +458,28 @@ vec4_visitor::nir_emit_load_const(nir_load_const_instr *instr) dst_reg reg = dst_reg(GRF, alloc.allocate(1)); reg.type = BRW_REGISTER_TYPE_F; + unsigned remaining = brw_writemask_for_size(instr->def.num_components); + /* @FIXME: consider emitting vector operations to save some MOVs in * cases where the components are representable in 8 bits. - * By now, we emit a MOV for each component. + * For now, we emit a MOV for each distinct value. */ - for (unsigned i = 0; i < instr->def.num_components; ++i) { - reg.writemask = 1 << i; + for (unsigned i = 0; i < instr->def.num_components; i++) { + unsigned writemask = 1 << i; + + if ((remaining & writemask) == 0) + continue; + + for (unsigned j = i; j < instr->def.num_components; j++) { + if (instr->value.u[i] == instr->value.u[j]) { + writemask |= 1 << j; + } + } + + reg.writemask = writemask; emit(MOV(reg, src_reg(instr->value.f[i]))); + + remaining &= ~writemask; } /* Set final writemask */