This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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....


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]