This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Fix label replacement in REG_NOTES (take 2)
- 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: Sun, 29 Jun 2003 22:59:17 -0400 (EDT)
- Subject: [PATCH]: Fix label replacement in REG_NOTES (take 2)
> 1. The documentation should be updated to say this.
Enclosed is the previous patch plus an update to rtl.texi. Tested by
inspecting the generated info file on hppa-unknown-linux-gnu.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2003-06-20 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 semantics for REG_EQUAL notes containing
label_ref's.
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.85
diff -u -3 -p -r1.85 cfgcleanup.c
--- cfgcleanup.c 22 Jun 2003 15:03:25 -0000 1.85
+++ cfgcleanup.c 30 Jun 2003 02:33:49 -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.460
diff -u -3 -p -r1.460 loop.c
--- loop.c 29 Jun 2003 20:42:42 -0000 1.460
+++ loop.c 30 Jun 2003 02:34:04 -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.421
diff -u -3 -p -r1.421 rtl.h
--- rtl.h 28 Jun 2003 05:39:40 -0000 1.421
+++ rtl.h 30 Jun 2003 02:34:07 -0000
@@ -1720,7 +1720,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.162
diff -u -3 -p -r1.162 rtlanal.c
--- rtlanal.c 29 Jun 2003 13:53:10 -0000 1.162
+++ rtlanal.c 30 Jun 2003 02:34:11 -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.58
diff -u -3 -p -r1.58 rtl.texi
--- doc/rtl.texi 22 Jun 2003 15:11:07 -0000 1.58
+++ doc/rtl.texi 30 Jun 2003 02:34:16 -0000
@@ -3332,6 +3332,13 @@ insns such as a library call is used to
this kind of note is attached to the insn that produces or copies the
final value.
+Normally, @var{op} should not contain a @code{label_ref}. This allows
+notes to be added and removed without updating @code{LABEL_NUSES}.
+A @code{REG_EQUAL} note can contain a @code{label_ref} if and only if
+the same @code{label_ref} appears in the body of the instruction and
+@var{op} is not a constant. This ensures that the note will not be
+used for substitution.
+
These two notes are used in different ways by the compiler passes.
@code{REG_EQUAL} is used by passes prior to register allocation (such as
common subexpression elimination and loop optimization) to tell them how