This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: Bogus REG_EQUIV note generation [was RE: Deep CSE bug!]
- From: "Dave Korn" <dk at artimi dot com>
- To: <law at redhat dot com>
- Cc: "'Roger Sayle'" <roger at eyesopen dot com>,"'Jie Zhang'" <zhangjie at magima dot com dot cn>,"'Alexandre Oliva'" <aoliva at redhat dot com>,<gcc at gcc dot gnu dot org>
- Date: Wed, 23 Jun 2004 15:31:31 +0100
- Subject: RE: Bogus REG_EQUIV note generation [was RE: Deep CSE bug!]
> -----Original Message-----
> From: Jeffrey A Law
> Sent: 23 June 2004 06:04
> In the case of a multi-word move the right way to describe this is
> to have a REG_EQUAL note on the various insns which set components
> of the multi-word value. Those REG_EQUAL notes (of course) refer
> to the destination in the specific insn they appear.
>
> At the end of the multi-word move sequence we should have a nop move
> of the multi-word value to itself with a REG_EQUAL for the multi-word
> value as a whole.
>
> So if we go back to your example, insn 11 and insn 12 ought to have
> REG_EQUAL notes which refer to the appropriate sub-components of
> (const_double -1).
>
> We should then
> (set (reg:DI 40) (reg:DI 40) (REG_EQUAL (const_double -1)))
>
>
> That allows us to optimize the components correctly using their
> REG_EQUAL notes and to optimize the sequence as a whole using the
> REG_EQUAL note on the nop move.
>
> I'm not sure the best way to fix this, but I'm pretty sure that
> if we break a move into components, that each component's REG_EQUAL
> note must refer to the destination that's set in each insn and
> if we want to refer to the ultimate destination as a whole, then
> we need to have a nop move insn with a REG_EQUAL note at the end
> of the multi-word move sequence.
Right, gotcha. What I've done so far is part 1) of the above - passing
down the constant equivalent cst_y from emit_move_insn to emit_move_insn_1 -
and then using operand_subword on it in just the same way as the loop that
breaks up the move operation:
---------->snip!<----------
@@ -3467,6 +3473,7 @@ emit_move_insn_1 (x, y)
{
rtx xpart = operand_subword (x, i, 1, mode);
rtx ypart = operand_subword (y, i, 1, mode);
+ rtx y_cstpart = 0;
/* If we can't get a part of Y, put Y into memory if it is a
constant. Otherwise, force it into a register. If we still
@@ -3485,6 +3492,14 @@ emit_move_insn_1 (x, y)
need_clobber |= (GET_CODE (xpart) == SUBREG);
last_insn = emit_move_insn (xpart, ypart);
+
+ /* Will we attach a REG_EQUAL note? */
+ if (y_cst && GET_CODE (xpart) == SUBREG && GET_CODE (XEXP (xpart,
0)) == REG)
+ {
+ y_cstpart = operand_subword (y_cst, i, 1, mode);
+ if (y_cstpart)
+ set_unique_reg_note (last_insn, REG_EQUAL, y_cstpart);
+ }
}
seq = get_insns ();
---------->snip!<----------
And that fixes the failing testcase all by itself, since the REG_EQUAL
notes now contain only the value in the subreg - 0 or -1, according to which
subword it was - and that gives us the correct value for src_eqv in CSE, and
the equivalence chains don't get mixed up.
I'm not 100% sure how to emit the nop move, though. I can't recursively
call emit_move_insn{_1} (x, y) or we'll just recurse and start re-emitting
the move-by-words infinitely. I presume I have to do something like
rtx nop_move = gen_rtx_SET (mode, x, y);
last_insn = emit_insn (nop_move);
yes? I'll be giving that a go after I hit send on this post, anyway.
cheers,
DaveK
--
Can't think of a witty .sigline today....