subreg pass

Roman Zippel zippel@linux-m68k.org
Tue Mar 6 13:20:00 GMT 2007



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;
 



More information about the Gcc mailing list