diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-07 02:26:51 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-07 02:26:51 +0000 |
commit | d3ff0f753948e4e595c6cf3d77ac1b05c655b464 (patch) | |
tree | 17de3bb34420626f8eab111aee34a18e3a1f275f | |
parent | 0351a03252ba852c678fade3693ba70f6a75cdf4 (diff) | |
download | gcc-d3ff0f753948e4e595c6cf3d77ac1b05c655b464.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38755 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/flow.c | 24 | ||||
-rw-r--r-- | gcc/jump.c | 18 | ||||
-rw-r--r-- | gcc/reload.c | 12 | ||||
-rw-r--r-- | gcc/reload.h | 4 | ||||
-rw-r--r-- | gcc/reload1.c | 2 | ||||
-rw-r--r-- | gcc/rtl.texi | 9 | ||||
-rw-r--r-- | gcc/rtlanal.c | 6 | ||||
-rw-r--r-- | gcc/sched-rgn.c | 17 | ||||
-rw-r--r-- | gcc/unroll.c | 4 |
10 files changed, 90 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ae2ced5039..e912ed00b91 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 5eaf116238f..a53043dc534 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 1c6c3a633d6..032172d3907 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 7b9b669e09e..11e33f05fc8 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 7841c7ad7d1..b604184a529 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 3a3dab0e7d4..783c8dc9beb 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 15911cd7ce8..0e9d8c48652 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 67c5319dfbf..b0fbcf31063 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 db4cc877b36..c1c215a1ea9 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 0b4a89bfd28..bdd6cb4e781 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)); } |