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
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: dave at hiauly1 dot hia dot nrc dot ca (John David Anglin)
- Cc: gcc-patches at gcc dot gnu dot org, roger at eyesopen dot com
- Date: Fri, 20 Jun 2003 16:25:09 -0400 (EDT)
- Subject: [PATCH]: Fix label replacement in REG_NOTES
This patches fixes the bootstrap failure reported in this message:
<http://gcc.gnu.org/ml/gcc-patches/2003-05/msg01841.html>.
The bootstrap failure occurs because of the presence of the following
instruction in a loop:
(jump_insn 66 65 70 4 0x40978750 (set (pc)
(if_then_else (ne (reg:SI 105)
(reg:SI 131))
(label_ref 80)
(pc))) 25 {*pa.md:1674} (nil)
(expr_list:REG_EQUAL (if_then_else (ne (reg:SI 105)
(const_int 112 [0x70]))
(label_ref 80)
(pc))
(nil)))
The target of this conditional branch gets redirected to a new code_label.
However, the presence of a REG_EQUAL note causes the LABEL_NUSES count to
be incremented once too may times for the new label and decremented once
too many times for the old label. This occurs in load_mems.
The enclosed patch fixes this by not updating LABEL_NUSES for label
references in REG_NOTES. The semantics of label references is that
they don't contribute to the usage count. This allows register notes
to be removed without having to worry about updating the the usage
counts.
Tested on hppa-unknown-linux-gnu and hppa2.0w-hp-hpux11.11 with no
regressions.
Ok for main?
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.
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.84
diff -u -3 -p -r1.84 cfgcleanup.c
--- cfgcleanup.c 6 Jun 2003 09:24:23 -0000 1.84
+++ cfgcleanup.c 20 Jun 2003 13:48:55 -0000
@@ -1310,7 +1310,7 @@ outgoing_edges_match (mode, bb1, bb2)
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)
@@ -1323,7 +1323,7 @@ outgoing_edges_match (mode, bb1, bb2)
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;
}
@@ -1474,7 +1474,7 @@ try_crossjump_to_edge (mode, e1, e2)
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.459
diff -u -3 -p -r1.459 loop.c
--- loop.c 16 Jun 2003 21:41:05 -0000 1.459
+++ loop.c 20 Jun 2003 13:49:57 -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.418
diff -u -3 -p -r1.418 rtl.h
--- rtl.h 19 Jun 2003 12:25:35 -0000 1.418
+++ rtl.h 20 Jun 2003 13:50:07 -0000
@@ -1721,7 +1721,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.158
diff -u -3 -p -r1.158 rtlanal.c
--- rtlanal.c 13 Jun 2003 05:30:33 -0000 1.158
+++ rtlanal.c 20 Jun 2003 13:50:12 -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 *));
@@ -2792,10 +2793,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;