This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Unreviewed fix for bootstrap failure
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: geoffk at geoffk dot org (Geoff Keating)
- Cc: rth at redhat dot com, gcc-patches at gcc dot gnu dot org
- Date: Wed, 2 Jul 2003 16:33:52 -0400 (EDT)
- Subject: Re: Unreviewed fix for bootstrap failure
> > Do you really think there is a use for notes that indicate that a
> > set is equal/equivalent to a label_ref?
>
> Yes. How is a LABEL_REF different to any other kind of thing you
> might want to indicate a register is equal to?
I don't see any difference but I fail to see how this relates
to the issue of whether or not to track LABEL_NUSES for LABEL_REFs
in REG_NOTES. As far as I can tell, the fix to the label replacement
code doesn't restrict or change the use of LABEL_REFs in any way.
Notes are a little bit of commentary, miscellaneous information, that
the compiler adds to help it process rtl. From this standpoint, any
information present in the notes of an instruction doesn't constitute
an actual use of the information. For example, the presence of a
constant in a note doesn't actually indicate that the actual constant
is used somewhere. The note simply describes the attributes of
the output of the insn.
LABEL_NUSES is a count of the number of LABEL_REFs that point to it.
If a register is equal/equivalent to a LABEL_REF, there must be code
to setup this equivalence. Thus, the label has to have a nonzero
count when such an equivalence is present in a register note.
I'm fairly certain that there is code that will break or not work
as expected if we include LABEL_REFs in REG_NOTES in the LABEL_NUSES
count. For example, the following code from unroll.c would appear
to malfunction if last_loop_insn has a note on it contributing to
the LABEL_NUSES count:
/* If there is a more than a single jump to the top of the loop
we cannot (easily) determine the iteration count. */
if (LABEL_NUSES (JUMP_LABEL (last_loop_insn)) > 1)
> > It might be useful on a
> > port that wanted to load a label_ref to a register and it was a two
> > or more step process. As we apparently don't add these notes now,
> > I'm not convinced that it's useful.
>
> Consider a port that has to store label addresses in the constant pool
> to load them into registers. Such a port would probably want to add
> REG_EQUIV notes to the load...
A comment in replace_label says:
/* Create a copy of constant C; replace the label inside
but do not update LABEL_NUSES because uses in constant pool
are not counted. */
So, we wouldn't want to track LABEL_NUSES for LABEL_REFs that refer
to labels in the constant pool even if we did this for other LABEL_REFs.
Thus, tracking LABEL_NUSES counts for LABEL_REFs in REG_NOTES would be
messy.
I have updated the documentation portion of my patch.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2003-07-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* cfgcleanup.c (outgoing_edges_match, try_crossjump_to_edge): Use
replace_labels.
* loop.c (load_mems): Likewise.
* rtl.h (replace_label): Delete declaration.
(replace_labels): Add declaration.
* rtlanal.c (replace_label): Make static.
(replace_labels): New function.
* doc/rtl.texi: Document that LABEL_REFs in REG_NOTES don't contibute
to LABEL_NUSES.
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.86
diff -u -3 -p -r1.86 cfgcleanup.c
--- cfgcleanup.c 1 Jul 2003 12:17:47 -0000 1.86
+++ cfgcleanup.c 2 Jul 2003 18:41:51 -0000
@@ -1279,7 +1279,7 @@ outgoing_edges_match (int mode, basic_bl
rr.r1 = label1;
rr.r2 = label2;
rr.update_label_nuses = false;
- for_each_rtx (&bb1->end, replace_label, &rr);
+ replace_labels (bb1->end, &rr);
match = insns_match_p (mode, bb1->end, bb2->end);
if (rtl_dump_file && match)
@@ -1292,7 +1292,7 @@ outgoing_edges_match (int mode, basic_bl
from the instruction is deleted too. */
rr.r1 = label2;
rr.r2 = label1;
- for_each_rtx (&bb1->end, replace_label, &rr);
+ replace_labels (bb1->end, &rr);
return match;
}
@@ -1441,7 +1441,7 @@ try_crossjump_to_edge (int mode, edge e1
a block whose end is a tablejump, the tablejump referenced
from the instruction is deleted too. */
if (insn != src1->end)
- for_each_rtx (&insn, replace_label, &rr);
+ replace_labels (insn, &rr);
}
}
}
Index: loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.461
diff -u -3 -p -r1.461 loop.c
--- loop.c 1 Jul 2003 12:17:54 -0000 1.461
+++ loop.c 2 Jul 2003 18:41:51 -0000
@@ -10194,7 +10194,7 @@ load_mems (loop)
for (p = loop->start; p != loop->end; p = NEXT_INSN (p))
{
- for_each_rtx (&p, replace_label, &rr);
+ replace_labels (p, &rr);
}
}
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.423
diff -u -3 -p -r1.423 rtl.h
--- rtl.h 1 Jul 2003 09:17:51 -0000 1.423
+++ rtl.h 2 Jul 2003 18:41:52 -0000
@@ -1715,7 +1715,7 @@ extern int inequality_comparisons_p PARA
extern rtx replace_rtx PARAMS ((rtx, rtx, rtx));
extern rtx replace_regs PARAMS ((rtx, rtx *, unsigned int,
int));
-extern int replace_label PARAMS ((rtx *, void *));
+extern void replace_labels PARAMS ((rtx, replace_label_data *));
extern int rtx_referenced_p PARAMS ((rtx, rtx));
extern bool tablejump_p PARAMS ((rtx, rtx *, rtx *));
extern int computed_jump_p PARAMS ((rtx));
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.163
diff -u -3 -p -r1.163 rtlanal.c
--- rtlanal.c 1 Jul 2003 12:18:00 -0000 1.163
+++ rtlanal.c 2 Jul 2003 18:41:52 -0000
@@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - S
static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
static void set_of_1 PARAMS ((rtx, rtx, void *));
static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
+static int replace_label PARAMS ((rtx *, void *));
static int rtx_referenced_p_1 PARAMS ((rtx *, void *));
static int computed_jump_p_1 PARAMS ((rtx));
static void parms_set PARAMS ((rtx, rtx, void *));
@@ -2790,10 +2791,38 @@ replace_regs (x, reg_map, nregs, replace
return x;
}
+/* Replace all occurrences of the old label in INSN with the new one.
+ DATA points to the replacement label data for the old and new labels. */
+
+void
+replace_labels (insn, data)
+ rtx insn;
+ replace_label_data *data;
+{
+ /* Labels in REG_NOTES are not recorded in LABEL_NUSES. */
+ if (data->update_label_nuses && INSN_P (insn))
+ {
+ rtx note = REG_NOTES (insn);
+
+ if (note)
+ {
+ REG_NOTES (insn) = NULL_RTX;
+ data->update_label_nuses = false;
+ for_each_rtx (¬e, replace_label, data);
+ data->update_label_nuses = true;
+ for_each_rtx (&insn, replace_label, data);
+ REG_NOTES (insn) = note;
+ return;
+ }
+ }
+
+ for_each_rtx (&insn, replace_label, data);
+}
+
/* Replace occurrences of the old label in *X with the new one.
DATA is a REPLACE_LABEL_DATA containing the old and new labels. */
-int
+static int
replace_label (x, data)
rtx *x;
void *data;
Index: doc/rtl.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/rtl.texi,v
retrieving revision 1.59
diff -u -3 -p -r1.59 rtl.texi
--- doc/rtl.texi 1 Jul 2003 01:15:07 -0000 1.59
+++ doc/rtl.texi 2 Jul 2003 18:41:52 -0000
@@ -3298,7 +3298,8 @@ value which the insn explicitly copies i
different from @var{op}, but they will be equal at run time. If the
output of the single @code{set} is a @code{strict_low_part} expression,
the note refers to the register that is contained in @code{SUBREG_REG}
-of the @code{subreg} expression.
+of the @code{subreg} expression. If @var{op} contains a @code{LABEL_REF},
+it does not contribute to the @code{LABEL_NUSES} count for the label.
For @code{REG_EQUIV}, the register is equivalent to @var{op} throughout
the entire function, and could validly be replaced in all its