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