aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-01-07 02:26:51 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2001-01-07 02:26:51 +0000
commitf759eb8bf0d98603f2e6930126e517ed995a64a8 (patch)
tree17de3bb34420626f8eab111aee34a18e3a1f275f /gcc
parent0e2e89fd2e117555f71be7a28e41f5f7663c3395 (diff)
downloadgcc-f759eb8bf0d98603f2e6930126e517ed995a64a8.zip
gcc-f759eb8bf0d98603f2e6930126e517ed995a64a8.tar.gz
gcc-f759eb8bf0d98603f2e6930126e517ed995a64a8.tar.bz2
reload.c (subst_reloads): Take INSN argument.
* reload.c (subst_reloads): Take INSN argument. When replacing a LABEL_REF in a JUMP_INSN, add a REG_LABEL note. * reload.h (subst_reloads): Adjust prototype. * reload1.c (reload_as_needed): Pass INSN to subst_reloads. * jump.c (mark_all_labels): Canonicalize any REG_LABEL notes present in JUMP_INSNs and copy them to JUMP_LABEL. * flow.c (find_label_refs, find_basic_blocks_1): Skip JUMP_INSNs and insns with REG_LABELs that are followed by JUMP_INSNs with the same REG_LABEL. * sched-rgn.c (is_cfg_nonregular): Likewise. * rtlanal.c (computed_jump_p): Make it false if a REG_LABEL note is available. * unroll.c (unroll_loop): Look for REG_LABEL notes in JUMP_INSNs too. * rtl.texi (REG_LABEL): Document usage in JUMP_INSNs. From-SVN: r38755
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/flow.c24
-rw-r--r--gcc/jump.c18
-rw-r--r--gcc/reload.c12
-rw-r--r--gcc/reload.h4
-rw-r--r--gcc/reload1.c2
-rw-r--r--gcc/rtl.texi9
-rw-r--r--gcc/rtlanal.c6
-rw-r--r--gcc/sched-rgn.c17
-rw-r--r--gcc/unroll.c4
10 files changed, 90 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2ae2ced..e912ed0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+2001-01-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * reload.c (subst_reloads): Take INSN argument. When
+ replacing a LABEL_REF in a JUMP_INSN, add a REG_LABEL note.
+ * reload.h (subst_reloads): Adjust prototype.
+ * reload1.c (reload_as_needed): Pass INSN to subst_reloads.
+ * jump.c (mark_all_labels): Canonicalize any REG_LABEL notes
+ present in JUMP_INSNs and copy them to JUMP_LABEL.
+ * flow.c (find_label_refs, find_basic_blocks_1): Skip
+ JUMP_INSNs and insns with REG_LABELs that are followed by
+ JUMP_INSNs with the same REG_LABEL.
+ * sched-rgn.c (is_cfg_nonregular): Likewise.
+ * rtlanal.c (computed_jump_p): Make it false if a REG_LABEL
+ note is available.
+ * unroll.c (unroll_loop): Look for REG_LABEL notes in
+ JUMP_INSNs too.
+ * rtl.texi (REG_LABEL): Document usage in JUMP_INSNs.
+
2001-01-06 Richard Henderson <rth@redhat.com>
* loop.c (scan_loop): Use xcalloc for the regs array.
diff --git a/gcc/flow.c b/gcc/flow.c
index 5eaf116..a53043d 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -640,7 +640,7 @@ find_label_refs (f, lvl)
rtx insn;
for (insn = f; insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn))
+ if (INSN_P (insn) && GET_CODE (insn) != JUMP_INSN)
{
rtx note;
@@ -651,7 +651,10 @@ find_label_refs (f, lvl)
as this would be a part of the tablejump setup code.
Make a special exception for the eh_return_stub_label, which
- we know isn't part of any otherwise visible control flow. */
+ we know isn't part of any otherwise visible control flow.
+
+ Make a special exception to registers loaded with label
+ values just before jump insns that use them. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_LABEL)
@@ -667,6 +670,9 @@ find_label_refs (f, lvl)
;
else if (GET_CODE (lab) == NOTE)
;
+ else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
+ && find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
+ ;
else
lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
}
@@ -862,18 +868,21 @@ find_basic_blocks_1 (f)
break;
}
- if (GET_RTX_CLASS (code) == 'i')
+ if (GET_RTX_CLASS (code) == 'i'
+ && GET_CODE (insn) != JUMP_INSN)
{
rtx note;
- /* Make a list of all labels referred to other than by jumps
- (which just don't have the REG_LABEL notes).
+ /* Make a list of all labels referred to other than by jumps.
Make a special exception for labels followed by an ADDR*VEC,
as this would be a part of the tablejump setup code.
Make a special exception for the eh_return_stub_label, which
- we know isn't part of any otherwise visible control flow. */
+ we know isn't part of any otherwise visible control flow.
+
+ Make a special exception to registers loaded with label
+ values just before jump insns that use them. */
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_LABEL)
@@ -889,6 +898,9 @@ find_basic_blocks_1 (f)
;
else if (GET_CODE (lab) == NOTE)
;
+ else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
+ && find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
+ ;
else
lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
}
diff --git a/gcc/jump.c b/gcc/jump.c
index 1c6c3a6..032172d 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -863,6 +863,24 @@ mark_all_labels (f, cross_jump)
mark_jump_label (PATTERN (insn), insn, cross_jump, 0);
if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
{
+ /* When we know the LABEL_REF contained in a REG used in
+ an indirect jump, we'll have a REG_LABEL note so that
+ flow can tell where it's going. */
+ if (JUMP_LABEL (insn) == 0)
+ {
+ rtx label_note = find_reg_note (insn, REG_LABEL, NULL_RTX);
+ if (label_note)
+ {
+ /* But a LABEL_REF around the REG_LABEL note, so
+ that we can canonicalize it. */
+ rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
+ XEXP (label_note, 0));
+
+ mark_jump_label (label_ref, insn, cross_jump, 0);
+ XEXP (label_note, 0) = XEXP (label_ref, 0);
+ JUMP_LABEL (insn) = XEXP (label_note, 0);
+ }
+ }
if (JUMP_LABEL (insn) != 0 && simplejump_p (insn))
{
jump_chain[INSN_UID (insn)]
diff --git a/gcc/reload.c b/gcc/reload.c
index 7b9b669..11e33f0 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -5679,7 +5679,8 @@ find_reloads_subreg_address (x, force_replace, opnum, type,
Return the rtx that X translates into; usually X, but modified. */
void
-subst_reloads ()
+subst_reloads (insn)
+ rtx insn;
{
register int i;
@@ -5689,6 +5690,15 @@ subst_reloads ()
register rtx reloadreg = rld[r->what].reg_rtx;
if (reloadreg)
{
+ /* If we're replacing a LABEL_REF with a register, add a
+ REG_LABEL note to indicate to flow which label this
+ register refers to. */
+ if (GET_CODE (*r->where) == LABEL_REF
+ && GET_CODE (insn) == JUMP_INSN)
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LABEL,
+ XEXP (*r->where, 0),
+ REG_NOTES (insn));
+
/* Encapsulate RELOADREG so its machine mode matches what
used to be there. Note that gen_lowpart_common will
do the wrong thing if RELOADREG is multi-word. RELOADREG
diff --git a/gcc/reload.h b/gcc/reload.h
index 7841c7a..b604184 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -1,6 +1,6 @@
/* Communication between reload.c and reload1.c.
Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -302,7 +302,7 @@ extern rtx form_sum PARAMS ((rtx, rtx));
/* Substitute into the current INSN the registers into which we have reloaded
the things that need reloading. */
-extern void subst_reloads PARAMS ((void));
+extern void subst_reloads PARAMS ((rtx));
/* Make a copy of any replacements being done into X and move those copies
to locations in Y, a copy of X. We only look at the highest level of
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 3a3dab0..783c8dc 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -3830,7 +3830,7 @@ reload_as_needed (live_known)
into the insn's body (or perhaps into the bodies of other
load and store insn that we just made for reloading
and that we moved the structure into). */
- subst_reloads ();
+ subst_reloads (insn);
/* If this was an ASM, make sure that all the reload insns
we have generated are valid. If not, give an error
diff --git a/gcc/rtl.texi b/gcc/rtl.texi
index 15911cd..0e9d8c4 100644
--- a/gcc/rtl.texi
+++ b/gcc/rtl.texi
@@ -1,4 +1,5 @@
-@c Copyright (C) 1988, 89, 92, 94, 97, 1998, 1999, 2000 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 1989, 1992, 1994, 1997, 1998, 1999, 2000, 2001
+@c Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -2752,8 +2753,10 @@ last insns, respectively.
@findex REG_LABEL
@item REG_LABEL
This insn uses @var{op}, a @code{code_label}, but is not a
-@code{jump_insn}. The presence of this note allows jump optimization to
-be aware that @var{op} is, in fact, being used.
+@code{jump_insn}, or it is a @code{jump_insn} that required the label to
+be held in a register. The presence of this note allows jump
+optimization to be aware that @var{op} is, in fact, being used, and flow
+optimization to build an accurate flow graph.
@end table
The following notes describe attributes of outputs of an insn:
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 67c5319..b0fbcf3 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1,6 +1,6 @@
/* Analyze RTL for C-Compiler
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -2285,7 +2285,9 @@ computed_jump_p (insn)
{
rtx pat = PATTERN (insn);
- if (GET_CODE (pat) == PARALLEL)
+ if (find_reg_note (insn, REG_LABEL, NULL_RTX))
+ return 0;
+ else if (GET_CODE (pat) == PARALLEL)
{
int len = XVECLEN (pat, 0);
int has_use_labelref = 0;
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index db4cc87..c1c215a 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -1,6 +1,6 @@
/* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -349,13 +349,16 @@ is_cfg_nonregular ()
for (insn = BLOCK_HEAD (b);; insn = NEXT_INSN (insn))
{
code = GET_CODE (insn);
- if (GET_RTX_CLASS (code) == 'i')
+ if (GET_RTX_CLASS (code) == 'i' && code != JUMP_INSN)
{
- rtx note;
-
- for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_LABEL)
- return 1;
+ rtx note = find_reg_note (REG_NOTES (insn), REG_LABEL, NULL_RTX);
+
+ if (note
+ && ! (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
+ && find_reg_note (REG_NOTES (NEXT_INSN (insn)),
+ REG_LABEL,
+ XEXP (note, 0))))
+ return 1;
}
if (insn == BLOCK_END (b))
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 0b4a89b..bdd6cb4 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -1,5 +1,5 @@
/* Try to unroll loops, and split induction variables.
- Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000
+ Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Contributed by James E. Wilson, Cygnus Support/UC Berkeley.
@@ -768,7 +768,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
}
}
}
- else if ((note = find_reg_note (insn, REG_LABEL, NULL_RTX)))
+ if ((note = find_reg_note (insn, REG_LABEL, NULL_RTX)))
set_label_in_map (map, CODE_LABEL_NUMBER (XEXP (note, 0)),
XEXP (note, 0));
}