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]
Other format: [Raw text]

find_many_sub_basic_blocks improvements


Hi,
This is first change I need for CFG transparent tree expansion.

This patch extends find_many_sub_basic_block to deal with all cases as
find_basic_block_1 did.  This include little bit of code duplication in
handling of labels whose address has been taken, but I hope that soonish we
will be able to elliminate find_basic_blocks completely.

Bootstrapped/regtested i686-pc-gnu-linux
OK for mainline?
Honza

	* cfgbuild.c (find_bb_boundaries): Add extra argumentl
	collect list of labels whose address has been taken
	(control_flow_insn_p): Recognize noreturn call instructions
	and EH instructions followed by barrier as control flow insns.

Index: cfgbuild.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgbuild.c,v
retrieving revision 1.41
diff -c -3 -p -r1.41 cfgbuild.c
*** cfgbuild.c	11 Dec 2003 00:20:36 -0000	1.41
--- cfgbuild.c	30 Jan 2004 13:16:43 -0000
*************** static rtx find_label_refs (rtx, rtx);
*** 54,60 ****
  static void make_edges (rtx, basic_block, basic_block, int);
  static void make_label_edge (sbitmap *, basic_block, rtx, int);
  static void make_eh_edge (sbitmap *, basic_block, rtx);
- static void find_bb_boundaries (basic_block);
  static void compute_outgoing_frequencies (basic_block);
  
  /* Return true if insn is something that should be contained inside basic
--- 54,59 ----
*************** control_flow_insn_p (rtx insn)
*** 109,114 ****
--- 108,115 ----
  	      && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
  
      case CALL_INSN:
+       if (find_reg_note (insn, REG_NORETURN, 0))
+ 	return true;
        /* Call insn may return to the nonlocal goto handler.  */
        return ((nonlocal_goto_handler_labels
  	       && (0 == (note = find_reg_note (insn, REG_EH_REGION,
*************** control_flow_insn_p (rtx insn)
*** 118,123 ****
--- 119,129 ----
  	      || can_throw_internal (insn));
  
      case INSN:
+       /* We represent EH manipulation via unspec followed by barrier.
+          Such instruction is control flow instruction even when there is
+          no other clue specifying it.  */
+       if (NEXT_INSN (insn) && GET_CODE (NEXT_INSN (insn)) == BARRIER)
+ 	return true;
        return (flag_non_call_exceptions && can_throw_internal (insn));
  
      case BARRIER:
*************** enum state {BLOCK_NEW = 0, BLOCK_ORIGINA
*** 645,654 ****
  #define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
  
  /* Scan basic block BB for possible BB boundaries inside the block
!    and create new basic blocks in the progress.  */
  
! static void
! find_bb_boundaries (basic_block bb)
  {
    rtx insn = BB_HEAD (bb);
    rtx end = BB_END (bb);
--- 651,663 ----
  #define SET_STATE(BB, STATE) ((BB)->aux = (void *) (size_t) (STATE))
  
  /* Scan basic block BB for possible BB boundaries inside the block
!    and create new basic blocks in the progress. 
  
!    Collect and return a list of labels whose addresses are taken.  This
!    will be used in make_edges for use with computed gotos.  */
! 
! static rtx
! find_bb_boundaries (rtx lvl, basic_block bb)
  {
    rtx insn = BB_HEAD (bb);
    rtx end = BB_END (bb);
*************** find_bb_boundaries (basic_block bb)
*** 656,662 ****
    edge fallthru = NULL;
  
    if (insn == BB_END (bb))
!     return;
  
    if (GET_CODE (insn) == CODE_LABEL)
      insn = NEXT_INSN (insn);
--- 665,671 ----
    edge fallthru = NULL;
  
    if (insn == BB_END (bb))
!     return lvl;
  
    if (GET_CODE (insn) == CODE_LABEL)
      insn = NEXT_INSN (insn);
*************** find_bb_boundaries (basic_block bb)
*** 666,671 ****
--- 675,704 ----
      {
        enum rtx_code code = GET_CODE (insn);
  
+       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ 	{
+ 	  rtx note;
+ 
+ 	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ 	    if (REG_NOTE_KIND (note) == REG_LABEL)
+ 	      {
+ 		rtx lab = XEXP (note, 0), next;
+ 
+ 		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 if (GET_CODE (lab) == NOTE)
+ 		  ;
+ 		else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
+ 			 && find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
+ 		  ;
+ 		else
+ 		  lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
+ 	      }
+ 	}
+ 
        /* On code label, split current basic block.  */
        if (code == CODE_LABEL)
  	{
*************** find_bb_boundaries (basic_block bb)
*** 708,713 ****
--- 741,747 ----
       followed by cleanup at fallthru edge, so the outgoing edges may
       be dead.  */
    purge_dead_edges (bb);
+   return lvl;
  }
  
  /*  Assume that frequency of basic block B is known.  Compute frequencies
*************** void
*** 751,756 ****
--- 785,791 ----
  find_many_sub_basic_blocks (sbitmap blocks)
  {
    basic_block bb, min, max;
+   rtx label_value_list = NULL;
  
    FOR_EACH_BB (bb)
      SET_STATE (bb,
*************** find_many_sub_basic_blocks (sbitmap bloc
*** 758,764 ****
  
    FOR_EACH_BB (bb)
      if (STATE (bb) == BLOCK_TO_SPLIT)
!       find_bb_boundaries (bb);
  
    FOR_EACH_BB (bb)
      if (STATE (bb) != BLOCK_ORIGINAL)
--- 793,799 ----
  
    FOR_EACH_BB (bb)
      if (STATE (bb) == BLOCK_TO_SPLIT)
!       label_value_list = find_bb_boundaries (label_value_list, bb);
  
    FOR_EACH_BB (bb)
      if (STATE (bb) != BLOCK_ORIGINAL)
*************** find_many_sub_basic_blocks (sbitmap bloc
*** 771,777 ****
  
    /* Now re-scan and wire in all edges.  This expect simple (conditional)
       jumps at the end of each new basic blocks.  */
!   make_edges (NULL, min, max, 1);
  
    /* Update branch probabilities.  Expect only (un)conditional jumps
       to be created with only the forward edges.  */
--- 806,812 ----
  
    /* Now re-scan and wire in all edges.  This expect simple (conditional)
       jumps at the end of each new basic blocks.  */
!   make_edges (label_value_list, min, max, 1);
  
    /* Update branch probabilities.  Expect only (un)conditional jumps
       to be created with only the forward edges.  */
*************** find_sub_basic_blocks (basic_block bb)
*** 808,814 ****
    basic_block next = bb->next_bb;
  
    min = bb;
!   find_bb_boundaries (bb);
    max = next->prev_bb;
  
    /* Now re-scan and wire in all edges.  This expect simple (conditional)
--- 843,849 ----
    basic_block next = bb->next_bb;
  
    min = bb;
!   find_bb_boundaries (NULL, bb);
    max = next->prev_bb;
  
    /* Now re-scan and wire in all edges.  This expect simple (conditional)
	(find_many_sub_basic_block): Deal correctly with abnormal edges.


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