This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch for the nonlocal_goto_handler_labels problems
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com
- Subject: Patch for the nonlocal_goto_handler_labels problems
- From: Jan Hubicka <jh at suse dot cz>
- Date: Wed, 18 Jul 2001 18:50:21 +0200
Hi,
just to summarize situation from yesterday, here is the patch I've tested on
i686/ppc (thanks to F. Sirl)/Mips to bootstrap/regtest and solve the failures
introduced by the unneeded branch removal patch.
Wed Jul 18 18:46:30 CEST 2001 Richard Henderson <rth@cygnus.com>
Jan Hubicka <jh@suse.cz>
* flow.c (redirect_edge_and_branch): Bail out on complex edges.
(try_optimize_cfg): Do not remove tail recursive labels before sibcall.
* jump.c (mark_jump_label): Do not forward branches.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.429
diff -c -3 -p -r1.429 flow.c
*** flow.c 2001/07/17 04:55:23 1.429
--- flow.c 2001/07/18 16:43:30
*************** redirect_edge_and_branch (e, target)
*** 1777,1782 ****
--- 1776,1784 ----
basic_block src = e->src;
rtx insn = src->end;
+ if (e->flags & EDGE_COMPLEX)
+ return false;
+
if (try_redirect_by_replacing_jump (e, target))
return true;
/* Do this fast path late, as we want above code to simplify for cases
*************** try_optimize_cfg (mode)
*** 3683,3712 ****
changed = 1;
b = c;
}
- /* The fallthru forwarder block can be deleted. */
- if (b->pred->pred_next == NULL
- && forwarder_block_p (b)
- && n_basic_blocks > 1
- && (b->pred->flags & EDGE_FALLTHRU)
- && (b->succ->flags & EDGE_FALLTHRU))
- {
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
- b->index);
- c = BASIC_BLOCK (i ? i - 1 : i + 1);
- redirect_edge_succ (b->pred, b->succ->dest);
- flow_delete_block (b);
- changed = 1;
- b = c;
- }
-
/* Remove code labels no longer used.
Don't do the optimization before sibling calls are discovered,
as some branches may be hidden inside CALL_PLACEHOLDERs. */
! if (!(mode & CLEANUP_PRE_SIBCALL)
! && b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& GET_CODE (b->head) == CODE_LABEL
/* If previous block does end with condjump jumping to next BB,
we can't delete the label. */
&& (b->pred->src == ENTRY_BLOCK_PTR
--- 3686,3700 ----
changed = 1;
b = c;
}
/* Remove code labels no longer used.
Don't do the optimization before sibling calls are discovered,
as some branches may be hidden inside CALL_PLACEHOLDERs. */
! if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
+ && !(b->pred->flags & EDGE_COMPLEX)
&& GET_CODE (b->head) == CODE_LABEL
+ && (!(mode & CLEANUP_PRE_SIBCALL)
+ || !tail_recursion_label_p (b->head))
/* If previous block does end with condjump jumping to next BB,
we can't delete the label. */
&& (b->pred->src == ENTRY_BLOCK_PTR
*************** try_optimize_cfg (mode)
*** 3719,3730 ****
--- 3707,3737 ----
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
b->index);
}
+ /* The fallthru forwarder block can be deleted. */
+ if (b->pred->pred_next == NULL
+ && forwarder_block_p (b)
+ && n_basic_blocks > 1
+ && (b->pred->flags & EDGE_FALLTHRU)
+ && (b->succ->flags & EDGE_FALLTHRU)
+ && GET_CODE (b->head) != CODE_LABEL)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
+ b->index);
+ c = BASIC_BLOCK (i ? i - 1 : i + 1);
+ redirect_edge_succ (b->pred, b->succ->dest);
+ flow_delete_block (b);
+ changed = 1;
+ b = c;
+ }
+
/* A loop because chains of blocks might be combineable. */
while ((s = b->succ) != NULL
&& s->succ_next == NULL
&& (s->flags & EDGE_EH) == 0
&& (c = s->dest) != EXIT_BLOCK_PTR
+ && !(s->flags & EDGE_COMPLEX)
&& c->pred->pred_next == NULL
/* If the jump insn has side effects,
we can't kill the edge. */
Index: jump.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/jump.c,v
retrieving revision 1.184
diff -c -3 -p -r1.184 jump.c
*** jump.c 2001/07/14 22:52:48 1.184
--- jump.c 2001/07/18 16:43:31
*************** mark_jump_label (x, insn, in_mem)
*** 1999,2006 ****
case LABEL_REF:
{
rtx label = XEXP (x, 0);
- rtx olabel = label;
- rtx next;
/* Ignore remaining references to unreachable labels that
have been deleted. */
--- 1999,2004 ----
*************** mark_jump_label (x, insn, in_mem)
*** 2015,2037 ****
if (LABEL_REF_NONLOCAL_P (x))
break;
- /* If there are other labels following this one,
- replace it with the last of the consecutive labels. */
- for (next = NEXT_INSN (label); next; next = NEXT_INSN (next))
- {
- if (GET_CODE (next) == CODE_LABEL)
- label = next;
- else if (GET_CODE (next) != NOTE)
- break;
- else if ((NOTE_LINE_NUMBER (next) == NOTE_INSN_LOOP_BEG
- || NOTE_LINE_NUMBER (next) == NOTE_INSN_FUNCTION_END
- /* ??? Optional. Disables some optimizations, but
- makes gcov output more accurate with -O. */
- || (flag_test_coverage
- && NOTE_LINE_NUMBER (next) > 0)))
- break;
- }
-
XEXP (x, 0) = label;
if (! insn || ! INSN_DELETED_P (insn))
++LABEL_NUSES (label);
--- 2013,2018 ----
*************** mark_jump_label (x, insn, in_mem)
*** 2042,2068 ****
JUMP_LABEL (insn) = label;
else
{
- /* If we've changed the label, update notes accordingly. */
- if (label != olabel)
- {
- rtx note;
-
- /* We may have a REG_LABEL note to indicate that this
- instruction uses the label. */
- note = find_reg_note (insn, REG_LABEL, olabel);
- if (note)
- XEXP (note, 0) = label;
-
- /* We may also have a REG_EQUAL note to indicate that
- a register is being set to the address of the
- label. */
- note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
- if (note
- && GET_CODE (XEXP (note, 0)) == LABEL_REF
- && XEXP (XEXP (note, 0), 0) == olabel)
- XEXP (XEXP (note, 0), 0) = label;
- }
-
/* Add a REG_LABEL note for LABEL unless there already
is one. All uses of a label, except for labels
that are the targets of jumps, must have a
--- 2023,2028 ----