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