[Mesa-dev] [PATCH v3] i965/vec4: Change types as needed to propagate source modifiers using from instruction
Jason Ekstrand
jason at jlekstrand.net
Sat Sep 19 07:34:44 PDT 2015
On Sep 18, 2015 10:12 AM, "Alejandro PiƱeiro" <apinheiro at igalia.com> wrote:
>
> SEL and MOV instructions, as long as they don't have source modifiers, are
> just copying bits around. So those kind of instruction could be
propagated
> even if there are type mismatches. This is needed because NIR generates
> integer SEL and MOV instructions whenever it doesn't know what else to
> generate.
>
> This commit adds support for copy propagation using previous instruction
> as reference.
>
> v2: using 'arg' index to get the from inst was wrong, as pointed
> by Jason Ekstrand
> v3: rebased against last change on the previous patch of theh series
> ---
>
> v3 is just a rebase against the first patch on the series. I also
> realized that yesterday I did a mess when I sent the v2 of this
> patch (answering to the wrong email, not including v3 on the subject),
> so I will copy the text I had on that email here. Sorry for the noise.
>
> From the review:
> >> if (has_source_modifiers &&
> >> value.type != inst->src[arg].type &&
> >> - !can_change_source_types(inst))
> >> + !can_change_source_types(inst) &&
> >> + !can_change_source_types(entry->inst[arg]))
>
> > This isn't right. The entry->inst array is indexed on vec4 component
> > but arg is the argument of the instruction. I think what you want to
> > do is add something to the loop above to loop over 0...3 and check
> > them all.
>
> Yes you are right. At that moment I misunderstood 'arg' as the channel
> being used at that moment, and as piglit didn't correct me with a
> regression I never realized that I was wrong. This v2 computes
> the instruction we are looking for corrrectly, with the a loop
> as suggested.
>
> > Also, how this is different from has_source_modifiers?
>
> It is different because at that moment has_source_modifiers has
> been computed using the src_reg value that had their modifiers
> changed to the ones at the current string:
>
> if (inst->src[arg].abs) {
> value.negate = false;
> value.abs = true;
> }
> if (inst->src[arg].negate)
> value.negate = !value.negate;
>
> bool has_source_modifiers = value.negate || value.abs;
>
> While can_change_source_types with the from instruction is
> using the original ones, and checking that is a mov, so "safe"
> to going on with the propagation.
>
> That means that there is an alternative to track the instructions
> at copy_entry. I could maintain a copy of value without being
> modified, or compute has_source_modifiers (ie:
original_has_source_modifiers).
I think I would prefer that if we can make it work.
> But I would still need to check if the opcode is a MOV on the from
> instruction, so I would need to track opcode on the copy_entry struct.
> Tracking inst also have the advantage that I can reuse the
> function can_change_source_types.
The copy_entry struct shouldn't get filled out. In particular, we only set
the source if is_direct_copy() returns true.
>
> > Obviously, it is (the shader-db numbers say so) but I'm not seeing it.
> > Could you please provide an example.
>
> Ok. On a shader like this:
>
> uniform vec4 inData;
>
> void main(void)
> {
> gl_Position = gl_Vertex - inData;
> }
>
> VS-0001-00-start is like this:
> 0: mov vgrf0.0:F, attr0.xyzw:F
> 1: mov vgrf1.0:UD, u0.xyzw:UD
> 2: add vgrf2.0:F, vgrf0.xyzw:F, -vgrf1.xyzw:F
> 3: mov m2:D, 0D
> 4: mov m3:F, vgrf2.xyzw:F
> 5: vs_urb_write (null):UD
>
> When we are at instruction #2, has_source_modifiers is true
> even for the value u0 because as I mentioned, it is copying the
> modifiers at the same instruction (the modifiers of
> vgrf1 at #2). But in any case, it is "safe" to do the copy
> propagation from instruction #1 to instruction #2.
Thanks, that makes sense.
--Jason
>
> .../drivers/dri/i965/brw_vec4_copy_propagation.cpp | 47
++++++++++++++++------
> 1 file changed, 35 insertions(+), 12 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
> index 1522eea..dabc25f 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp
> @@ -39,6 +39,7 @@ namespace brw {
>
> struct copy_entry {
> src_reg *value[4];
> + vec4_instruction *inst[4];
> int saturatemask;
> };
>
> @@ -251,7 +252,8 @@ try_constant_propagate(const struct brw_device_info
*devinfo,
> static bool
> can_change_source_types(vec4_instruction *inst)
> {
> - return inst->dst.type == inst->src[0].type &&
> + return inst != NULL &&
> + inst->dst.type == inst->src[0].type &&
> !inst->src[0].abs && !inst->src[0].negate && !inst->saturate &&
> (inst->opcode == BRW_OPCODE_MOV ||
> (inst->opcode == BRW_OPCODE_SEL &&
> @@ -271,6 +273,8 @@ try_copy_propagate(const struct brw_device_info
*devinfo,
> * vectors better.
> */
> src_reg value = *entry->value[0];
> + vec4_instruction *from_inst = entry->inst[0];
> +
> for (int i = 1; i < 4; i++) {
> /* This is equals() except we don't care about the swizzle. */
> if (value.file != entry->value[i]->file ||
> @@ -283,6 +287,13 @@ try_copy_propagate(const struct brw_device_info
*devinfo,
> }
> }
>
> + for (int i = 1; i < 4; i++) {
> + if (from_inst != entry->inst[i]) {
> + from_inst = NULL;
> + break;
> + }
> + }
> +
> /* Compute the swizzle of the original register by swizzling the
> * component loaded from each value according to the swizzle of
> * operand we're going to change.
> @@ -322,7 +333,8 @@ try_copy_propagate(const struct brw_device_info
*devinfo,
>
> if (has_source_modifiers &&
> value.type != inst->src[arg].type &&
> - !can_change_source_types(inst))
> + !can_change_source_types(inst) &&
> + !can_change_source_types(from_inst))
> return false;
>
> if (has_source_modifiers &&
> @@ -340,7 +352,8 @@ try_copy_propagate(const struct brw_device_info
*devinfo,
> * instead. See also resolve_ud_negate().
> */
> if (value.negate &&
> - value.type == BRW_REGISTER_TYPE_UD)
> + value.type == BRW_REGISTER_TYPE_UD &&
> + !can_change_source_types(from_inst))
> return false;
>
> /* Don't report progress if this is a noop. */
> @@ -378,17 +391,25 @@ try_copy_propagate(const struct brw_device_info
*devinfo,
>
> if (has_source_modifiers &&
> value.type != inst->src[arg].type) {
> - /* We are propagating source modifiers from a MOV with a different
> - * type. If we got here, then we can just change the source and
> - * destination types of the instruction and keep going.
> + /* We are propagating source modifiers from a safe instruction
with a
> + * different type. If we got here, then we can just change the
source
> + * and destination types of the current instruction or the
instruction
> + * from we are propagating.
> */
> - assert(can_change_source_types(inst));
> - for (int i = 0; i < 3; i++) {
> - inst->src[i].type = value.type;
> + assert(can_change_source_types(inst) ||
> + can_change_source_types(from_inst));
> +
> + if (can_change_source_types(inst)) {
> + for (int i = 0; i < 3; i++) {
> + inst->src[i].type = value.type;
> + }
> + inst->dst.type = value.type;
> + } else {
> + value.type = inst->src[arg].type;
> }
> - inst->dst.type = value.type;
> - } else
> + } else {
> value.type = inst->src[arg].type;
> + }
> inst->src[arg] = value;
> return true;
> }
> @@ -441,7 +462,7 @@ vec4_visitor::opt_copy_propagation(bool
do_constant_prop)
> for (c = 0; c < 4; c++) {
> int channel = BRW_GET_SWZ(inst->src[i].swizzle, c);
> entry.value[c] = entries[reg].value[channel];
> -
> + entry.inst[c] = entries[reg].inst[channel];
> /* If there's no available copy for this channel, bail.
> * We could be more aggressive here -- some channels might
> * not get used based on the destination writemask.
> @@ -486,6 +507,7 @@ vec4_visitor::opt_copy_propagation(bool
do_constant_prop)
> entries[reg].value[i] = direct_copy ? &inst->src[0] :
NULL;
> entries[reg].saturatemask |=
> inst->saturate && direct_copy ? 1 << i : 0;
> + entries[reg].inst[i] = direct_copy ? inst : NULL;
> }
> }
>
> @@ -500,6 +522,7 @@ vec4_visitor::opt_copy_propagation(bool
do_constant_prop)
> if (is_channel_updated(inst, entries[i].value, j)) {
> entries[i].value[j] = NULL;
> entries[i].saturatemask &= ~(1 << j);
> + entries[i].inst[j] = NULL;
> }
> }
> }
> --
> 2.1.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150919/91bd25fd/attachment-0001.html>
More information about the mesa-dev
mailing list