This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: alternate jump.c patch
> An alternate solution is to modify jump like so. I guess I'd actually
> prefer this sort of thing short-term over opening some other can of
> worms with lots more flow changes.
Another alternate patch. It has 3 staged, regression testing is in
progress.
Only obstackle seems to be tail recursive labels, so I've added test
of that, additionally I am now allowing removal of unneeded labels
before sibcall and merging over tail recursive label after sibcall,
also I've simplified the condition for removing fallthru block
be requiring the code_label to be removed by previous simplifier.
What patch do you consider as better one? Is this one too still too
dangerous?
Tue Jul 17 22:32:46 CEST 2001 Jan Hubicka <jh@suse.cz>
* flow.c (merge_blocks): Conditionalize the tail_recursion_label
test by CLEANUP_PRE_SIBCALL.
(try_optimize_cfg): Make removal of unneeded labels first;
avoid removal of tail_recursion_labels in PRE_SIBCALL mode;
remove fallthru block only if it has no label.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/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/17 20:28:53
*************** merge_blocks (e, b, c, mode)
*** 2940,2946 ****
edge recorded from the call_placeholder back to this label, as
that would make optimize_sibling_and_tail_recursive_calls more
complex for no gain. */
! if (GET_CODE (c->head) == CODE_LABEL
&& tail_recursion_label_p (c->head))
return 0;
--- 2943,2950 ----
edge recorded from the call_placeholder back to this label, as
that would make optimize_sibling_and_tail_recursive_calls more
complex for no gain. */
! if ((mode & CLEANUP_PRE_SIBCALL)
! && GET_CODE (c->head) == CODE_LABEL
&& tail_recursion_label_p (c->head))
return 0;
*************** 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
--- 3687,3701 ----
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 ****
--- 3708,3738 ----
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. */