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]

flow patch



Here's the final version of my long-ago promised patch. There's more
to come later, but this solves the bootstrapping problem everyone's
been having.

Jim has approved it, and it bootstraps on solaris. I've checked it in.

Andrew

Tue Apr 27 19:50:25 EDT 1999  Andrew MacLeod  <amacleod@cygnus.com>

	* rtl.h (REG_EH_REGION): Update comment to indicate a value of -1
	indicates no throw and no nonlocal gotos.
	* optabs.c (emit_libcall_block): Emit REG_EH_REGION with a value
	of -1 instead of 0 to indicate a nonlocal goto won't happen either.
	* flow.c (count_basic_blocks, find_basic_blocks_1): Ignore libcall
	blocks, look for REG_EH_REGION note exclusively.
	(make_edges): Check for REG_EH_REGION > 0 for specified handlers.

Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.104
diff -c -p -r1.104 rtl.h
*** rtl.h	1999/04/12 02:18:54	1.104
--- rtl.h	1999/04/28 00:07:58
*************** typedef struct rtvec_def{
*** 343,354 ****
     but are too complex for DWARF to interpret what they imply.  The attached
     rtx is used instead of intuition.  */
  /*   REG_EH_REGION is used to indicate what exception region an INSN
!    belongs in. This can be used to indicate what region a call may throw
!    to. a REGION of 0 indicates that a call cannot throw at all.
       REG_EH_RETHROW is used to indicate what that a call is actually a
     call to rethrow, and specifies which region the rethrow is targetting.
     This provides a way to generate the non standard flow edges required 
!    for a rethrow. */
     
  
  #define REG_NOTES(INSN)	((INSN)->fld[6].rtx)
--- 343,356 ----
     but are too complex for DWARF to interpret what they imply.  The attached
     rtx is used instead of intuition.  */
  /*   REG_EH_REGION is used to indicate what exception region an INSN
!    belongs in.  This can be used to indicate what region a call may throw
!    to.  A REGION of 0 indicates that a call cannot throw at all.
!    A REGION  of -1 indicates that it cannot throw, nor will it execute
!    a non-local goto.
       REG_EH_RETHROW is used to indicate what that a call is actually a
     call to rethrow, and specifies which region the rethrow is targetting.
     This provides a way to generate the non standard flow edges required 
!    for a rethrow.  */
     
  
  #define REG_NOTES(INSN)	((INSN)->fld[6].rtx)
Index: optabs.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/optabs.c,v
retrieving revision 1.30
diff -c -p -r1.30 optabs.c
*** optabs.c	1999/04/26 00:15:53	1.30
--- optabs.c	1999/04/28 00:08:10
*************** emit_libcall_block (insns, target, resul
*** 2604,2610 ****
          {
            rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
            if (note == NULL_RTX)
!             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (0),
                                                    REG_NOTES (insn));
          }
      }
--- 2604,2610 ----
          {
            rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
            if (note == NULL_RTX)
!             REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
                                                    REG_NOTES (insn));
          }
      }
Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.119
diff -c -p -r1.119 flow.c
*** flow.c	1999/04/14 20:36:33	1.119
--- flow.c	1999/04/28 00:08:20
*************** count_basic_blocks (f)
*** 435,441 ****
    register RTX_CODE prev_code;
    register int count = 0;
    int eh_region = 0;
-   int in_libcall_block = 0;
    int call_had_abnormal_edge = 0;
    rtx prev_call = NULL_RTX;
  
--- 435,440 ----
*************** count_basic_blocks (f)
*** 444,454 ****
      {
        register RTX_CODE code = GET_CODE (insn);
  
-       /* Track when we are inside in LIBCALL block.  */
-       if (GET_RTX_CLASS (code) == 'i'
- 	  && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- 	in_libcall_block = 1;
- 
        if (code == CODE_LABEL
  	  || (GET_RTX_CLASS (code) == 'i'
  	      && (prev_code == JUMP_INSN
--- 443,448 ----
*************** count_basic_blocks (f)
*** 473,486 ****
        /* Record whether this call created an edge.  */
        if (code == CALL_INSN)
  	{
  	  prev_call = insn;
  	  call_had_abnormal_edge = 0;
! 	  if (nonlocal_goto_handler_labels)
! 	    call_had_abnormal_edge = !in_libcall_block;
! 	  else if (eh_region)
  	    {
! 	      rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
! 	      if (!note || XINT (XEXP (note, 0), 0) != 0)
  		call_had_abnormal_edge = 1;
  	    }
  	}
--- 467,486 ----
        /* Record whether this call created an edge.  */
        if (code == CALL_INSN)
  	{
+ 	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ 	  int region = (note ? XINT (XEXP (note, 0), 0) : 1);
  	  prev_call = insn;
  	  call_had_abnormal_edge = 0;
! 
! 	  /* If there is a specified EH region, we have an edge.  */
! 	  if (eh_region && region > 0)
! 	    call_had_abnormal_edge = 1;
! 	  else
  	    {
! 	      /* If there is a nonlocal goto label and the specified
! 		 region number isn't -1, we have an edge. (0 means
! 		 no throw, but might have a nonlocal goto).  */
! 	      if (nonlocal_goto_handler_labels && region >= 0)
  		call_had_abnormal_edge = 1;
  	    }
  	}
*************** count_basic_blocks (f)
*** 494,502 ****
        else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
  	--eh_region;
  
-       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- 	  && find_reg_note (insn, REG_RETVAL, NULL_RTX))
- 	in_libcall_block = 0;
      }
  
    /* The rest of the compiler works a bit smoother when we don't have to
--- 494,499 ----
*************** find_basic_blocks_1 (f, bb_eh_end)
*** 527,533 ****
       rtx *bb_eh_end;
  {
    register rtx insn, next;
-   int in_libcall_block = 0;
    int call_has_abnormal_edge = 0;
    int i = 0;
    rtx bb_note = NULL_RTX;
--- 524,529 ----
*************** find_basic_blocks_1 (f, bb_eh_end)
*** 548,568 ****
  
        next = NEXT_INSN (insn);
  
-       /* Track when we are inside in LIBCALL block.  */
-       if (GET_RTX_CLASS (code) == 'i'
- 	  && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- 	in_libcall_block = 1;
- 
        if (code == CALL_INSN)
  	{
  	  /* Record whether this call created an edge.  */
  	  call_has_abnormal_edge = 0;
! 	  if (nonlocal_goto_handler_labels)
! 	    call_has_abnormal_edge = !in_libcall_block;
! 	  else if (eh_list)
  	    {
! 	      rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
! 	      if (!note || XINT (XEXP (note, 0), 0) != 0)
  		call_has_abnormal_edge = 1;
  	    }
  	}
--- 544,565 ----
  
        next = NEXT_INSN (insn);
  
        if (code == CALL_INSN)
  	{
  	  /* Record whether this call created an edge.  */
+ 	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+ 	  int region = (note ? XINT (XEXP (note, 0), 0) : 1);
  	  call_has_abnormal_edge = 0;
! 
! 	  /* If there is an EH region, we have an edge.  */
! 	  if (eh_list && region > 0)
! 	    call_has_abnormal_edge = 1;
! 	  else
  	    {
! 	      /* If there is a nonlocal goto label and the specified
! 		 region number isn't -1, we have an edge. (0 means
! 		 no throw, but might have a nonlocal goto).  */
! 	      if (nonlocal_goto_handler_labels && region >= 0)
  		call_has_abnormal_edge = 1;
  	    }
  	}
*************** find_basic_blocks_1 (f, bb_eh_end)
*** 722,730 ****
  		    = gen_rtx_EXPR_LIST (VOIDmode, XEXP (note, 0),
  				         label_value_list);
  	      }
- 
- 	  if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
- 	    in_libcall_block = 0;
  	}
      }
  
--- 719,724 ----
*************** make_edges (label_value_list, bb_eh_end)
*** 996,1002 ****
  	    x = find_reg_note (insn, REG_EH_REGION, 0);
  	  if (x)
  	    {
! 	      if (XINT (XEXP (x, 0), 0) != 0)
  		{
  		  ptr = get_first_handler (XINT (XEXP (x, 0), 0));
  		  while (ptr)
--- 990,996 ----
  	    x = find_reg_note (insn, REG_EH_REGION, 0);
  	  if (x)
  	    {
! 	      if (XINT (XEXP (x, 0), 0) > 0)
  		{
  		  ptr = get_first_handler (XINT (XEXP (x, 0), 0));
  		  while (ptr)


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