ifcvt noreturn calls
Richard Henderson
rth@cygnus.com
Wed May 31 17:05:00 GMT 2000
The following change allows us to conditionalize a call to abort.
Bootstrapped on ia64-linux.
r~
* ifcvt.c (merge_if_block): Be prepared for JOIN to have no
remaining edges.
(find_if_block): Allow THEN with no outgoing edges.
* flow.c (merge_blocks_nomove): Remove a barrier not following
a jump as well.
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ifcvt.c,v
retrieving revision 1.26
diff -c -p -d -r1.26 ifcvt.c
*** ifcvt.c 2000/05/31 23:58:46 1.26
--- ifcvt.c 2000/06/01 00:02:07
*************** merge_if_block (test_bb, then_bb, else_b
*** 1356,1363 ****
/* The JOIN block may have had quite a number of other predecessors too.
Since we've already merged the TEST, THEN and ELSE blocks, we should
have only one remaining edge from our if-then-else diamond. If there
! is more than one remaining edge, it must come from elsewhere. */
! else if (join_bb->pred->pred_next == NULL)
{
/* We can merge the JOIN. */
if (combo_bb->global_live_at_end)
--- 1356,1365 ----
/* The JOIN block may have had quite a number of other predecessors too.
Since we've already merged the TEST, THEN and ELSE blocks, we should
have only one remaining edge from our if-then-else diamond. If there
! is more than one remaining edge, it must come from elsewhere. There
! may be zero incoming edges if the THEN block didn't actually join
! back up (as with a call to abort). */
! else if (join_bb->pred == NULL || join_bb->pred->pred_next == NULL)
{
/* We can merge the JOIN. */
if (combo_bb->global_live_at_end)
*************** find_if_block (test_bb, then_edge, else_
*** 1459,1473 ****
if (then_bb->pred->pred_next != NULL_EDGE)
return FALSE;
! /* The THEN block of an IF-THEN combo must have exactly one successor. */
! if (then_succ == NULL_EDGE
! || then_succ->succ_next != NULL_EDGE
! || (then_succ->flags & EDGE_COMPLEX))
return FALSE;
/* If the THEN block's successor is the other edge out of the TEST block,
then we have an IF-THEN combo without an ELSE. */
! if (then_succ->dest == else_bb)
{
join_bb = else_bb;
else_bb = NULL_BLOCK;
--- 1461,1489 ----
if (then_bb->pred->pred_next != NULL_EDGE)
return FALSE;
! /* The THEN block of an IF-THEN combo must have zero or one successors. */
! if (then_succ != NULL_EDGE
! && (then_succ->succ_next != NULL_EDGE
! || (then_succ->flags & EDGE_COMPLEX)))
return FALSE;
+ /* If the THEN block has no successors, conditional execution can still
+ make a conditional call. Don't do this unless the ELSE block has
+ only one incoming edge -- the CFG manipulation is too ugly otherwise. */
+ if (then_succ == NULL)
+ {
+ if (else_bb->pred->pred_next == NULL_EDGE)
+ {
+ join_bb = else_bb;
+ else_bb = NULL_BLOCK;
+ }
+ else
+ return FALSE;
+ }
+
/* If the THEN block's successor is the other edge out of the TEST block,
then we have an IF-THEN combo without an ELSE. */
! else if (then_succ->dest == else_bb)
{
join_bb = else_bb;
else_bb = NULL_BLOCK;
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.297
diff -c -p -d -r1.297 flow.c
*** flow.c 2000/05/31 22:29:38 1.297
--- flow.c 2000/05/31 23:56:00
*************** merge_blocks_nomove (a, b)
*** 2201,2206 ****
--- 2201,2208 ----
a_end = prev;
}
+ else if (GET_CODE (NEXT_INSN (a_end)) == BARRIER)
+ del_first = NEXT_INSN (a_end);
/* Delete everything marked above as well as crap that might be
hanging out between the two blocks. */
More information about the Gcc-patches
mailing list