CALL_INSNs and LIBCALLs

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Fri Apr 14 15:06:00 GMT 2000


Some CALL_INSNs end a basic block, but they must not do so if they are
in a LIBCALL.  This fixes that.

Fri Apr 14 18:07:30 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* flow.c (count_basic_blocks): Remove unused var PREV_CALL.
	Never have a LIBCALL end a basic block.
	(find_basic_blocks_1): Likewise.
	Reorganize CALL_INSN cases.

*** flow.c	2000/04/12 01:38:15	1.251
--- flow.c	2000/04/14 17:01:38
*************** count_basic_blocks (f)
*** 463,467 ****
    int eh_region = 0;
    int call_had_abnormal_edge = 0;
!   rtx prev_call = NULL_RTX;
  
    prev_code = JUMP_INSN;
--- 463,467 ----
    int eh_region = 0;
    int call_had_abnormal_edge = 0;
!   int in_libcall = 0;
  
    prev_code = JUMP_INSN;
*************** count_basic_blocks (f)
*** 474,481 ****
  	      && (prev_code == JUMP_INSN
  		  || prev_code == BARRIER
! 		  || (prev_code == CALL_INSN && call_had_abnormal_edge))))
! 	{
! 	  count++;
! 	}
  
        /* Record whether this call created an edge.  */
--- 474,487 ----
  	      && (prev_code == JUMP_INSN
  		  || prev_code == BARRIER
! 		  || (prev_code == CALL_INSN
! 		      && call_had_abnormal_edge && in_libcall == 0))))
! 	count++;
! 
!       /* Track whether or not we are in a LIBCALL block.  These must
! 	 all be within the same basic block.  */
!       if (find_reg_note (insn, REG_LIBCALL, NULL_RTX) != 0)
! 	in_libcall++;
!       else if (find_reg_note (insn, REG_RETVAL, NULL_RTX) != 0)
! 	in_libcall--;
  
        /* Record whether this call created an edge.  */
*************** count_basic_blocks (f)
*** 484,488 ****
  	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
  	  int region = (note ? INTVAL (XEXP (note, 0)) : 1);
! 	  prev_call = insn;
  	  call_had_abnormal_edge = 0;
  
--- 490,494 ----
  	  rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
  	  int region = (note ? INTVAL (XEXP (note, 0)) : 1);
! 
  	  call_had_abnormal_edge = 0;
  
*************** count_basic_blocks (f)
*** 491,505 ****
  	      || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
  	    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;
! 	    }
  	}
-       else if (code != NOTE)
- 	prev_call = NULL_RTX;
  
        if (code != NOTE)
--- 497,506 ----
  	      || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
  	    call_had_abnormal_edge = 1;
! 	  else if (nonlocal_goto_handler_labels && region >= 0)
! 	    /* 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).  */
! 	    call_had_abnormal_edge = 1;
  	}
  
        if (code != NOTE)
*************** count_basic_blocks (f)
*** 509,513 ****
        else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
  	--eh_region;
- 
      }
  
--- 510,513 ----
*************** find_basic_blocks_1 (f)
*** 533,537 ****
  {
    register rtx insn, next;
-   int call_has_abnormal_edge = 0;
    int i = 0;
    rtx bb_note = NULL_RTX;
--- 533,536 ----
*************** find_basic_blocks_1 (f)
*** 540,543 ****
--- 539,543 ----
    rtx head = NULL_RTX;
    rtx end = NULL_RTX;
+   int in_libcall = 0;
    
    /* We process the instructions in a slightly different way than we did
*************** find_basic_blocks_1 (f)
*** 553,577 ****
        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 ? INTVAL (XEXP (note, 0)) : 1);
- 	  call_has_abnormal_edge = 0;
- 
- 	  /* If there is an EH region or rethrow, we have an edge.  */
- 	  if ((eh_list && region > 0)
- 	      || find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
- 	    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;
- 	    }
- 	}
- 
        switch (code)
  	{
--- 553,556 ----
*************** find_basic_blocks_1 (f)
*** 586,589 ****
--- 565,569 ----
  	      {
  		rtx t = eh_list;
+ 
  		eh_list = XEXP (eh_list, 1);
  		free_INSN_LIST_node (t);
*************** find_basic_blocks_1 (f)
*** 598,604 ****
  		if (bb_note == NULL_RTX)
  		  bb_note = insn;
  		next = flow_delete_insn (insn);
  	      }
- 
  	    break;
  	  }
--- 578,584 ----
  		if (bb_note == NULL_RTX)
  		  bb_note = insn;
+ 
  		next = flow_delete_insn (insn);
  	      }
  	    break;
  	  }
*************** find_basic_blocks_1 (f)
*** 614,619 ****
  		 everything can be updated.  So continue to emit a noop at
  		 the end of such a block.  */
! 	      if (GET_CODE (end) == CALL_INSN
! 		  && ! SIBLING_CALL_P (end))
  		{
  		  rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
--- 594,598 ----
  		 everything can be updated.  So continue to emit a noop at
  		 the end of such a block.  */
! 	      if (GET_CODE (end) == CALL_INSN && ! SIBLING_CALL_P (end))
  		{
  		  rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
*************** find_basic_blocks_1 (f)
*** 624,627 ****
--- 603,607 ----
  	      bb_note = NULL_RTX;
  	    }
+ 
  	  head = end = insn;
  	  break;
*************** find_basic_blocks_1 (f)
*** 667,672 ****
  	     be updated.  So continue to emit a noop at the end of such a
  	     block.  */
! 	  if (GET_CODE (end) == CALL_INSN
! 	      && ! SIBLING_CALL_P (end))
  	    {
  	      rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
--- 647,651 ----
  	     be updated.  So continue to emit a noop at the end of such a
  	     block.  */
! 	  if (GET_CODE (end) == CALL_INSN && ! SIBLING_CALL_P (end))
  	    {
  	      rtx nop = gen_rtx_USE (VOIDmode, const0_rtx);
*************** find_basic_blocks_1 (f)
*** 676,693 ****
  
  	case CALL_INSN:
! 	  /* A basic block ends at a call that can either throw or
! 	     do a non-local goto.  */
! 	  if (call_has_abnormal_edge)
! 	    {
! 	    new_bb_inclusive:
! 	      if (head == NULL_RTX)
! 		head = insn;
! 	      end = insn;
  
! 	    new_bb_exclusive:
! 	      create_basic_block (i++, head, end, bb_note);
! 	      head = end = NULL_RTX;
! 	      bb_note = NULL_RTX;
! 	      break;
  	    }
  	  /* FALLTHRU */
--- 655,690 ----
  
  	case CALL_INSN:
! 	  {
! 	    /* Record whether this call created an edge.  */
! 	    rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
! 	    int region = (note ? INTVAL (XEXP (note, 0)) : 1);
! 	    int call_has_abnormal_edge = 0;
! 
! 	    /* If there is an EH region or rethrow, we have an edge.  */
! 	    if ((eh_list && region > 0)
! 		|| find_reg_note (insn, REG_EH_RETHROW, NULL_RTX))
! 	      call_has_abnormal_edge = 1;
! 	    else if (nonlocal_goto_handler_labels && region >= 0)
! 	      /* 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).  */
! 	      call_has_abnormal_edge = 1;
  
! 	    /* A basic block ends at a call that can either throw or
! 	       do a non-local goto.  LIBCALLs must reside totally in one
! 	       basic block, so don't end a block after them.  */
! 	    if (call_has_abnormal_edge && in_libcall == 0)
! 	      {
! 	      new_bb_inclusive:
! 		if (head == NULL_RTX)
! 		  head = insn;
! 		end = insn;
! 
! 	      new_bb_exclusive:
! 		create_basic_block (i++, head, end, bb_note);
! 		head = end = NULL_RTX;
! 		bb_note = NULL_RTX;
! 		break;
! 	      }
  	    }
  	  /* FALLTHRU */
*************** find_basic_blocks_1 (f)
*** 717,735 ****
  	     
  	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
! 	    if (REG_NOTE_KIND (note) == REG_LABEL)
! 	      {
! 	        rtx lab = XEXP (note, 0), next;
  
! 		if (lab == eh_return_stub_label)
! 		  ;
! 		else if ((next = next_nonnote_insn (lab)) != NULL
! 			 && GET_CODE (next) == JUMP_INSN
! 			 && (GET_CODE (PATTERN (next)) == ADDR_VEC
! 			     || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
! 		  ;
! 		else
! 		  label_value_list
! 		    = alloc_EXPR_LIST (0, XEXP (note, 0), label_value_list);
! 	      }
  	}
      }
--- 714,738 ----
  	     
  	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
! 	    {
! 	      if (REG_NOTE_KIND (note) == REG_LABEL)
! 		{
! 		  rtx lab = XEXP (note, 0), next;
  
! 		  if (lab == eh_return_stub_label)
! 		    ;
! 		  else if ((next = next_nonnote_insn (lab)) != NULL
! 			   && GET_CODE (next) == JUMP_INSN
! 			   && (GET_CODE (PATTERN (next)) == ADDR_VEC
! 			       || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
! 		    ;
! 		  else
! 		    label_value_list
! 		      = alloc_EXPR_LIST (0, XEXP (note, 0), label_value_list);
! 		}
! 	      else if (REG_NOTE_KIND (note) == REG_LIBCALL)
! 		in_libcall++;
! 	      else if (REG_NOTE_KIND (note) == REG_RETVAL)
! 		in_libcall--;
! 	    }
  	}
      }


More information about the Gcc-patches mailing list