+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.
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;
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)
;
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);
}
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)
;
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);
}
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)]
Return the rtx that X translates into; usually X, but modified. */
void
-subst_reloads ()
+subst_reloads (insn)
+ rtx insn;
{
register int i;
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
/* 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.
/* 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
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
-@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.
@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:
/* 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.
{
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;
/* 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)
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))
/* 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.
}
}
}
- 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));
}