This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch for the nonlocal_goto_handler_labels problems



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 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]