This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RTL sharing tester (for testing)
Jan Hubicka <jh@suse.cz> writes:
> The users of df_set_note all just take the registers from dataflow
> information and call the function to produce REG_DEAD/REG_UNUSED notes.
> This all is going to introduce invalid sharing for subregs in all cases
> and if we are going to produce the note with SUBREG, we simply must
> produce the copy. (If we are very very cautious, we probably can have
> some cache since we are probably recomputing those notes quite often,
> but I doubt it is worth the extra complexity and we can see it easilly
> from memory tester)
>
> Note that copy_rtx does nothing for REG, since registers are shared, so
> it should not be overly expensive and we simply must produce the
> duplicate for the case of SUBREG or any other unshared RTL expression.
>
> However I now wonder why do we want to see subregs there at all.
> Originally I assumed that we now do partial liveness for multiple word
> values, but it is not the case. Perhaps the right thing to do is to
> simply strip away the SUBREG and keep only the REG itself?
> At least before dataflow, I don't think we produced SUBREGs in those
> notes, I might be wrong.
FWIW, I agree. Several places in gcc seem to assume that REG_DEAD
and REG_UNUSED notes are plain REGs, and access REGNO unconditionally.
It even looks like df_ref_record was written with that in mind;
there's an "oldreg" variable alongside "reg", presumably so that
"reg" could be turned into "SUBREG_REG (oldreg)" if necessary,
but the two variables stay the same throughout.
This was causing a segmentation fault while building libjava
for mipsel-linux-gnu. We had a REG_DEAD (subreg:DI (reg:DF $f0))
note, and some code was applying REGNO to that subreg.
Also, there seems to be some redundancy in df_mw_hardreg.
It has both a mw_reg field and a loc field, but it looks like
all uses of loc can be replaced with uses of mw_reg.
I'm testing the patch below. I wouldn't normally post a patch
before it has finished testing, but since the question is being
actively debated, I thought I might as well.
Richard
Index: gcc/df-scan.c
===================================================================
--- gcc/df-scan.c (revision 126079)
+++ gcc/df-scan.c (working copy)
@@ -2647,6 +2647,7 @@ df_ref_record (struct df_collection_rec
regno += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
SUBREG_BYTE (reg), GET_MODE (reg));
endregno = regno + subreg_nregs (reg);
+ reg = SUBREG_REG (reg);
}
else
endregno = END_HARD_REGNO (reg);
@@ -2666,7 +2667,6 @@ df_ref_record (struct df_collection_rec
hardreg->type = ref_type;
hardreg->flags = ref_flags;
hardreg->mw_reg = reg;
- hardreg->loc = loc;
hardreg->start_regno = regno;
hardreg->end_regno = endregno - 1;
hardreg->mw_order = df->ref_order++;
Index: gcc/df.h
===================================================================
--- gcc/df.h (revision 126079)
+++ gcc/df.h (working copy)
@@ -311,8 +311,7 @@ struct dataflow
REG_UNUSED notes. */
struct df_mw_hardreg
{
- rtx mw_reg; /* The multiword hardreg. */
- rtx *loc; /* The location of the reg. */
+ rtx mw_reg; /* The multiword REG. */
enum df_ref_type type; /* Used to see if the ref is read or write. */
enum df_ref_flags flags; /* Various flags. */
unsigned int start_regno; /* First word of the multi word subreg. */
Index: gcc/df-problems.c
===================================================================
--- gcc/df-problems.c (revision 126079)
+++ gcc/df-problems.c (working copy)
@@ -3748,7 +3748,7 @@ df_set_unused_notes_for_mw (rtx insn, rt
if (all_dead)
{
unsigned int regno = mws->start_regno;
- old = df_set_note (REG_UNUSED, insn, old, *(mws->loc));
+ old = df_set_note (REG_UNUSED, insn, old, mws->mw_reg);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 1: ", insn, REG_NOTES (insn));
@@ -3814,7 +3814,7 @@ df_set_dead_notes_for_mw (rtx insn, rtx
if (!bitmap_bit_p (do_not_gen, mws->start_regno))
{
/* Add a dead note for the entire multi word register. */
- old = df_set_note (REG_DEAD, insn, old, *(mws->loc));
+ old = df_set_note (REG_DEAD, insn, old, mws->mw_reg);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 1: ", insn, REG_NOTES (insn));
#endif