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
This commit is contained in:
Alexandre Oliva 2001-01-07 02:26:51 +00:00 committed by Alexandre Oliva
parent 0e2e89fd2e
commit f759eb8bf0
10 changed files with 89 additions and 23 deletions

View File

@ -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> 2001-01-06 Richard Henderson <rth@redhat.com>
* loop.c (scan_loop): Use xcalloc for the regs array. * loop.c (scan_loop): Use xcalloc for the regs array.

View File

@ -640,7 +640,7 @@ find_label_refs (f, lvl)
rtx insn; rtx insn;
for (insn = f; insn; insn = NEXT_INSN (insn)) for (insn = f; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn)) if (INSN_P (insn) && GET_CODE (insn) != JUMP_INSN)
{ {
rtx note; rtx note;
@ -651,7 +651,10 @@ find_label_refs (f, lvl)
as this would be a part of the tablejump setup code. as this would be a part of the tablejump setup code.
Make a special exception for the eh_return_stub_label, which 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)) for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_LABEL) 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 (lab) == NOTE)
; ;
else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
&& find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
;
else else
lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl); lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
} }
@ -862,18 +868,21 @@ find_basic_blocks_1 (f)
break; break;
} }
if (GET_RTX_CLASS (code) == 'i') if (GET_RTX_CLASS (code) == 'i'
&& GET_CODE (insn) != JUMP_INSN)
{ {
rtx note; rtx note;
/* Make a list of all labels referred to other than by jumps /* Make a list of all labels referred to other than by jumps.
(which just don't have the REG_LABEL notes).
Make a special exception for labels followed by an ADDR*VEC, Make a special exception for labels followed by an ADDR*VEC,
as this would be a part of the tablejump setup code. as this would be a part of the tablejump setup code.
Make a special exception for the eh_return_stub_label, which 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)) for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_LABEL) 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 (lab) == NOTE)
; ;
else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
&& find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
;
else else
lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl); lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
} }

View File

@ -863,6 +863,24 @@ mark_all_labels (f, cross_jump)
mark_jump_label (PATTERN (insn), insn, cross_jump, 0); mark_jump_label (PATTERN (insn), insn, cross_jump, 0);
if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN) 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)) if (JUMP_LABEL (insn) != 0 && simplejump_p (insn))
{ {
jump_chain[INSN_UID (insn)] jump_chain[INSN_UID (insn)]

View File

@ -5679,7 +5679,8 @@ find_reloads_subreg_address (x, force_replace, opnum, type,
Return the rtx that X translates into; usually X, but modified. */ Return the rtx that X translates into; usually X, but modified. */
void void
subst_reloads () subst_reloads (insn)
rtx insn;
{ {
register int i; register int i;
@ -5689,6 +5690,15 @@ subst_reloads ()
register rtx reloadreg = rld[r->what].reg_rtx; register rtx reloadreg = rld[r->what].reg_rtx;
if (reloadreg) 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 /* Encapsulate RELOADREG so its machine mode matches what
used to be there. Note that gen_lowpart_common will used to be there. Note that gen_lowpart_common will
do the wrong thing if RELOADREG is multi-word. RELOADREG do the wrong thing if RELOADREG is multi-word. RELOADREG

View File

@ -1,6 +1,6 @@
/* Communication between reload.c and reload1.c. /* Communication between reload.c and reload1.c.
Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 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. 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 /* Substitute into the current INSN the registers into which we have reloaded
the things that need reloading. */ 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 /* 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 to locations in Y, a copy of X. We only look at the highest level of

View File

@ -3830,7 +3830,7 @@ reload_as_needed (live_known)
into the insn's body (or perhaps into the bodies of other into the insn's body (or perhaps into the bodies of other
load and store insn that we just made for reloading load and store insn that we just made for reloading
and that we moved the structure into). */ and that we moved the structure into). */
subst_reloads (); subst_reloads (insn);
/* If this was an ASM, make sure that all the reload insns /* If this was an ASM, make sure that all the reload insns
we have generated are valid. If not, give an error we have generated are valid. If not, give an error

View File

@ -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 This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi. @c For copying conditions, see the file gcc.texi.
@ -2752,8 +2753,10 @@ last insns, respectively.
@findex REG_LABEL @findex REG_LABEL
@item REG_LABEL @item REG_LABEL
This insn uses @var{op}, a @code{code_label}, but is not a 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 @code{jump_insn}, or it is a @code{jump_insn} that required the label to
be aware that @var{op} is, in fact, being used. 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 @end table
The following notes describe attributes of outputs of an insn: The following notes describe attributes of outputs of an insn:

View File

@ -1,6 +1,6 @@
/* Analyze RTL for C-Compiler /* Analyze RTL for C-Compiler
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 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. This file is part of GNU CC.
@ -2285,7 +2285,9 @@ computed_jump_p (insn)
{ {
rtx pat = PATTERN (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 len = XVECLEN (pat, 0);
int has_use_labelref = 0; int has_use_labelref = 0;

View File

@ -1,6 +1,6 @@
/* Instruction scheduling pass. /* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 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, Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com) 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)) for (insn = BLOCK_HEAD (b);; insn = NEXT_INSN (insn))
{ {
code = GET_CODE (insn); code = GET_CODE (insn);
if (GET_RTX_CLASS (code) == 'i') if (GET_RTX_CLASS (code) == 'i' && code != JUMP_INSN)
{ {
rtx note; rtx note = find_reg_note (REG_NOTES (insn), REG_LABEL, NULL_RTX);
for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) if (note
if (REG_NOTE_KIND (note) == REG_LABEL) && ! (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
return 1; && find_reg_note (REG_NOTES (NEXT_INSN (insn)),
REG_LABEL,
XEXP (note, 0))))
return 1;
} }
if (insn == BLOCK_END (b)) if (insn == BLOCK_END (b))

View File

@ -1,5 +1,5 @@
/* Try to unroll loops, and split induction variables. /* 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. Free Software Foundation, Inc.
Contributed by James E. Wilson, Cygnus Support/UC Berkeley. 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)), set_label_in_map (map, CODE_LABEL_NUMBER (XEXP (note, 0)),
XEXP (note, 0)); XEXP (note, 0));
} }