This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] fix broken dead notes after register renaming
- From: Christian BRUEL <christian dot bruel at st dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 14 Sep 2009 16:49:31 +0200
- Subject: [PATCH] fix broken dead notes after register renaming
Hello,
The dead notes are not propagated anymore after register renaming,
probably since the new dataflow merge, as a update_life_info used be called.
compiling the attached red.i example on a SH target with -funroll-loops
-fno-schedule-insns2 -O2 -fomit-frame-pointer red.i , I see on .rnreg dump :
(Note a side effect here of -funroll-loops flag that have an effect on
register renaming, although no loops are involved.)
(call_insn:HI 8 22 9 2 red.i:13 (parallel [
(call (mem:SI (reg:SI 0 r0 [161]) [0 S4 A32])
(const_int 0 [0x0]))
(use (reg:PSI 151 ))
(clobber (reg:SI 146 pr))
]) 222 {calli} (expr_list:REG_DEAD (reg:PSI 151 )
(expr_list:REG_DEAD (reg/f:SI 1 r1 [161])
(nil)))
(nil))
on SH, this confuses at best the .use insertion sh_reorg pass for
relaxation since it relies on this information, at worse this could lead
to invalid code. I suspect this can impact all other post-rename code
that rely this notes too.
This patch propagates the REG_DEAD # after renaming.
2009-09-11 Christian Bruel <christian.bruel@st.com>
* regrename.c (do_replace): Update REG_DEAD notes.
regtested on sh-superh-elf and i686-pc-linux-gnu
comments ? OK for trunk ?
thanks,
-c
typedef struct record
{
struct record *Ptr_Comp;
int Int_Comp;
} Rec_Type, *Rec_Pointer;
void Proc_3();
void Proc_1 (Ptr_Val_Par)
Rec_Pointer Ptr_Val_Par;
{
Proc_3 ();
Ptr_Val_Par->Int_Comp = 6;
}
Index: gcc/regrename.c
===================================================================
--- gcc/regrename.c (revision 151628)
+++ gcc/regrename.c (working copy)
@@ -376,11 +376,26 @@
INSN_VAR_LOCATION_LOC (chain->insn) = gen_rtx_UNKNOWN_VAR_LOC ();
else
{
+ rtx x;
+
*chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
if (regno >= FIRST_PSEUDO_REGISTER)
ORIGINAL_REGNO (*chain->loc) = regno;
REG_ATTRS (*chain->loc) = attr;
REG_POINTER (*chain->loc) = reg_ptr;
+
+ for (x = REG_NOTES (chain->insn); x; x = XEXP (x, 1))
+ {
+ if (REG_NOTE_KIND (x) == REG_DEAD
+ || REG_NOTE_KIND (x) == REG_UNUSED)
+ {
+ rtx note = XEXP (x, 0);
+ gcc_assert (GET_CODE (note) == REG);
+
+ if (REGNO (note) == base_regno)
+ XEXP (x, 0) = *chain->loc;
+ }
+ }
}
df_insn_rescan (chain->insn);