This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: subreg pass
On Tue, 6 Mar 2007, Roman Zippel wrote:
> Reload has now to match (reg %d0) and (reg 38) above in insn 32 and after
> pseudo register replacement it looks like this:
>
> (insn 32 10 30 2 (parallel [
> (set (strict_low_part (reg:SI 1 %d1 [orig:38+4 ] [38]))
> (mult:SI (reg/v:SI 0 %d0 [ a ])
> (reg/v:SI 1 %d1 [ b ])))
> (set (strict_low_part (reg:SI 0 %d0 [37]))
> (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (reg/v:SI 0 %d0 [ a ]))
> (zero_extend:DI (reg/v:SI 1 %d1 [ b ])))
> (const_int 32 [0x20]))))
> ]) 181 {*umulsidi3_subreg} (nil)
> (expr_list:REG_DEAD (reg/v:SI 0 %d0 [ a ])
> (expr_list:REG_DEAD (reg/v:SI 1 %d1 [ b ])
> (nil))))
>
> Notice that the REG_DEAD notes are not correct anymore,
>
[..]
>
> %d0 is used in both set destinations and postreload dies because of it.
> The question is now, who is responsible for telling reload that %d0/%d1
> are not really dead anymore after register allocation?
Below is possible approach, I hijacked mark_not_eliminable to scan all
register stores and remove the obsolete REG_DEAD notes. With this reload
produces the correct reload.
bye, Roman
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c (revision 122519)
+++ gcc/reload1.c (working copy)
@@ -842,7 +842,7 @@
cannot be done. */
for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn))
if (INSN_P (insn))
- note_stores (PATTERN (insn), mark_not_eliminable, NULL);
+ note_stores (PATTERN (insn), mark_not_eliminable, insn);
maybe_fix_stack_asms ();
@@ -3398,8 +3398,9 @@
the insns of the function. */
static void
-mark_not_eliminable (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
+mark_not_eliminable (rtx dest, rtx x, void *data)
{
+ rtx note, insn = data;
unsigned int i;
/* A SUBREG of a hard register here is just changing its mode. We should
@@ -3408,6 +3409,9 @@
if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
+ if (REG_P (dest) && (note = find_regno_note (insn, REG_DEAD, REGNO (dest))))
+ remove_note (insn, note);
+
if (dest == hard_frame_pointer_rtx)
return;