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]

REG_EH_REGION patch



This patch has been applied to egcs. 

REG_EH_REGION notes can be used to indicate what region a call is in, 
specifically at the moment, a value of 0 indicate that a call cannot
throw. When we generate a REG_LIBCALL sequence, we attach this note
to any calls in the sequence, then we no longer have to
figure out if we're within a libcall block when building 
the flow graph and adding edges to handlers.


	* optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all
	calls within a libcall block to indicate no throws are possible.
	* flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for 
	libcall blocks. Don't add edges to exception handlers if we see 
	a REG_EH_REGION note with a value of 0.
	(make_edges): Override active_eh_region vector if the call has a note
	indicating the call does not throw.


Index: optabs.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/optabs.c,v
retrieving revision 1.21
diff -c -p -r1.21 optabs.c
*** optabs.c	1999/01/03 22:03:47	1.21
--- optabs.c	1999/01/11 22:46:39
*************** emit_libcall_block (insns, target, resul
*** 2596,2601 ****
--- 2596,2616 ----
  {
    rtx prev, next, first, last, insn;
  
+   /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
+      reg note to indicate that this call cannot throw. (Unless there is
+      already a REG_EH_REGION note.) */
+ 
+   for (insn = insns; insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == CALL_INSN)
+         {
+           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));
+         }
+     }
+ 
    /* First emit all insns that set pseudos.  Remove them from the list as
       we go.  Avoid insns that set pseudos which were referenced in previous
       insns.  These can be generated by move_by_pieces, for example,
Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.91
diff -c -p -r1.91 flow.c
*** flow.c	1998/12/16 20:55:43	1.91
--- flow.c	1999/01/11 22:46:43
*************** find_basic_blocks (f, nregs, file)
*** 309,315 ****
    register rtx insn;
    register int i;
    rtx nonlocal_label_list = nonlocal_label_rtx_list ();
-   int in_libcall_block = 0;
  
    /* Avoid leaking memory if this is called multiple times per compiled
       function.  */
--- 309,314 ----
*************** find_basic_blocks (f, nregs, file)
*** 326,336 ****
  
      for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
        {
- 	/* Track when we are inside in LIBCALL block.  */
- 	if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- 	    && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- 	  in_libcall_block = 1;
- 
  	code = GET_CODE (insn);
  
  	/* A basic block starts at label, or after something that can jump.  */
--- 325,330 ----
*************** find_basic_blocks (f, nregs, file)
*** 354,370 ****
  		emit_insn_after (nop, prev_call);
  	      }
  	  }
- 	/* We change the code of the CALL_INSN, so that it won't start a
- 	   new block.  */
- 	if (code == CALL_INSN && in_libcall_block)
- 	  code = INSN;
  
- 	/* Record whether this call created an edge.  */
  	if (code == CALL_INSN)
! 	  {
! 	    prev_call = insn;
! 	    call_had_abnormal_edge = (nonlocal_label_list != 0 || eh_region);
! 	  }
  	else if (code != NOTE && code != BARRIER)
  	  prev_call = 0;
  
--- 348,370 ----
  		emit_insn_after (nop, prev_call);
  	      }
  	  }
  
  	if (code == CALL_INSN)
!           {
!             rtx note = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
! 
!             /* We change the code of the CALL_INSN, so that it won't start a
!                new block.  */
!             if (note && XINT (XEXP (note, 0), 0) == 0)
!               code = INSN;
!             else
!               {
!                 prev_call = insn;
!                 call_had_abnormal_edge = (nonlocal_label_list != 0
!                                           || eh_region);
!               }
!           }
! 
  	else if (code != NOTE && code != BARRIER)
  	  prev_call = 0;
  
*************** find_basic_blocks (f, nregs, file)
*** 374,383 ****
  	  ++eh_region;
  	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;
        }
    }
  
--- 374,379 ----
*************** find_basic_blocks_1 (f, nonlocal_labels)
*** 447,453 ****
    rtx note, eh_note;
    enum rtx_code prev_code, code;
    int depth;
-   int in_libcall_block = 0;
    int call_had_abnormal_edge = 0;
  
    active_eh_region = (int *) alloca ((max_uid_for_flow + 1) * sizeof (int));
--- 443,448 ----
*************** find_basic_blocks_1 (f, nonlocal_labels)
*** 475,486 ****
    for (eh_note = NULL_RTX, insn = f, i = -1, prev_code = JUMP_INSN, depth = 1;
         insn; insn = NEXT_INSN (insn))
      {
- 
-       /* Track when we are inside in LIBCALL block.  */
-       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- 	  && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
- 	in_libcall_block = 1;
- 
        code = GET_CODE (insn);
        if (code == NOTE)
  	{
--- 470,475 ----
*************** find_basic_blocks_1 (f, nonlocal_labels)
*** 550,565 ****
  	 for every insn, since most insns can throw.  */
        else if (eh_note
  	       && (asynchronous_exceptions
! 		   || (GET_CODE (insn) == CALL_INSN
! 		       && ! in_libcall_block)))
  	active_eh_region[INSN_UID (insn)] =
                                          NOTE_BLOCK_NUMBER (XEXP (eh_note, 0));
        BLOCK_NUM (insn) = i;
  
        /* We change the code of the CALL_INSN, so that it won't start a
! 	 new block.  */
!       if (code == CALL_INSN && in_libcall_block)
! 	code = INSN;
  
        /* Record whether this call created an edge.  */
        if (code == CALL_INSN)
--- 539,557 ----
  	 for every insn, since most insns can throw.  */
        else if (eh_note
  	       && (asynchronous_exceptions
! 		   || (GET_CODE (insn) == CALL_INSN)))
  	active_eh_region[INSN_UID (insn)] =
                                          NOTE_BLOCK_NUMBER (XEXP (eh_note, 0));
        BLOCK_NUM (insn) = i;
  
        /* We change the code of the CALL_INSN, so that it won't start a
! 	 new block if it doesn't throw.  */
!       if (code == CALL_INSN)
!         {
!           rtx rnote = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
!           if (rnote && XINT (XEXP (rnote, 0), 0) == 0)
!             code = INSN;
!         }
  
        /* Record whether this call created an edge.  */
        if (code == CALL_INSN)
*************** find_basic_blocks_1 (f, nonlocal_labels)
*** 568,576 ****
        if (code != NOTE)
  	prev_code = code;
  
-       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
- 	  && find_reg_note (insn, REG_RETVAL, NULL_RTX))
- 	in_libcall_block = 0;
      }
  
    if (i + 1 != n_basic_blocks)
--- 560,565 ----
*************** make_edges (i)
*** 839,847 ****
  		   || (GET_CODE (insn) == CALL_INSN
  		       && ! find_reg_note (insn, REG_RETVAL, NULL_RTX)))
  	    {
! 	      if (active_eh_region[INSN_UID (insn)]) 
  		{
- 		  int region;
  		  handler_info *ptr;
  		  region = active_eh_region[INSN_UID (insn)];
  		  for ( ; region; region = nested_eh_region[region])
--- 828,842 ----
  		   || (GET_CODE (insn) == CALL_INSN
  		       && ! find_reg_note (insn, REG_RETVAL, NULL_RTX)))
  	    {
!               int region = active_eh_region[INSN_UID (insn)];
!               note = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
! 
!               /* Override region if we see a REG_EH_REGION note. */
!               if (note)
!                 region = XINT (XEXP (note, 0), 0);
! 
! 	      if (region)
  		{
  		  handler_info *ptr;
  		  region = active_eh_region[INSN_UID (insn)];
  		  for ( ; region; region = nested_eh_region[region])




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