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]

find_sub_basic_blocks improvements



Hi,
this patch makes find_sub_basic_blocks useable in more general way,
than it was till now.

Now it should be able to fixup almost any emit of new insns,
as it uses directly make_edges to wire in the CFG.

Bootstrapped/regtested i686 together with next patch.

Tue Jul 17 17:06:10 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* basic-block.h (find_sub_basic_block): Declare.
	* flow.c (make_edges): New arguments MIN and MAX;
	(find_sub_basic_blocks): Revamp to use make_edges
	and purge_dead_edges.
	(find_basic_blocks): Update call of find_sub_basic_block.

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.102
diff -c -3 -p -r1.102 basic-block.h
*** basic-block.h	2001/07/16 20:54:42	1.102
--- basic-block.h	2001/07/17 14:57:07
*************** extern void debug_regset		PARAMS ((regse
*** 597,602 ****
--- 599,605 ----
  extern void allocate_reg_life_data      PARAMS ((void));
  extern void allocate_bb_life_data	PARAMS ((void));
  extern void find_unreachable_blocks	PARAMS ((void));
+ extern void find_sub_basic_blocks	PARAMS ((basic_block));
  
  /* This function is always defined so it can be called from the
     debugger, and it is declared extern so we don't get warnings about
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/17 14:57:11
*************** static int flow_find_cross_jump		PARAMS 
*** 374,380 ****
  static int count_basic_blocks		PARAMS ((rtx));
  static void find_basic_blocks_1		PARAMS ((rtx));
  static rtx find_label_refs		PARAMS ((rtx, rtx));
! static void make_edges			PARAMS ((rtx));
  static void make_label_edge		PARAMS ((sbitmap *, basic_block,
  						 rtx, int));
  static void make_eh_edge		PARAMS ((sbitmap *, basic_block, rtx));
--- 374,380 ----
  static int count_basic_blocks		PARAMS ((rtx));
  static void find_basic_blocks_1		PARAMS ((rtx));
  static rtx find_label_refs		PARAMS ((rtx, rtx));
! static void make_edges			PARAMS ((rtx, int, int));
  static void make_label_edge		PARAMS ((sbitmap *, basic_block,
  						 rtx, int));
  static void make_eh_edge		PARAMS ((sbitmap *, basic_block, rtx));
*************** static void flow_loop_tree_node_add	PARA
*** 484,490 ****
  static void flow_loops_tree_build	PARAMS ((struct loops *));
  static int flow_loop_level_compute	PARAMS ((struct loop *, int));
  static int flow_loops_level_compute	PARAMS ((struct loops *));
- static void find_sub_basic_blocks	PARAMS ((basic_block));
  static bool redirect_edge_and_branch 	PARAMS ((edge, basic_block));
  static basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
  static rtx block_label			PARAMS ((basic_block));
--- 484,489 ----
*************** find_basic_blocks (f, nregs, file)
*** 547,553 ****
    compute_bb_for_insn (max_uid);
  
    /* Discover the edges of our cfg.  */
!   make_edges (label_value_list);
  
    /* Do very simple cleanup now, for the benefit of code that runs between
       here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns.  */
--- 546,552 ----
    compute_bb_for_insn (max_uid);
  
    /* Discover the edges of our cfg.  */
!   make_edges (label_value_list, 0, n_basic_blocks - 1);
  
    /* Do very simple cleanup now, for the benefit of code that runs between
       here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns.  */
*************** find_label_refs (f, lvl)
*** 709,747 ****
  
  /* Assume that someone emitted code with control flow instructions to the
     basic block.  Update the data structure.  */
! static void
  find_sub_basic_blocks (bb)
       basic_block bb;
  {
!   rtx first_insn = bb->head, insn;
    rtx end = bb->end;
-   edge succ_list = bb->succ;
    rtx jump_insn = NULL_RTX;
    int created = 0;
    int barrier = 0;
    edge falltru = 0;
!   basic_block first_bb = bb, last_bb;
!   int i;
  
!   if (GET_CODE (first_insn) == LABEL_REF)
!     first_insn = NEXT_INSN (first_insn);
!   first_insn = NEXT_INSN (first_insn);
!   bb->succ = NULL;
  
-   insn = first_insn;
    /* Scan insn chain and try to find new basic block boundaries.  */
!   while (insn != end)
      {
        enum rtx_code code = GET_CODE (insn);
        switch (code)
  	{
- 	case JUMP_INSN:
- 	  /* We need some special care for those expressions.  */
- 	  if (GET_CODE (PATTERN (insn)) == ADDR_VEC
- 	      || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
- 	    abort();
- 	  jump_insn = insn;
- 	  break;
  	case BARRIER:
  	  if (!jump_insn)
  	    abort ();
--- 708,737 ----
  
  /* Assume that someone emitted code with control flow instructions to the
     basic block.  Update the data structure.  */
! void
  find_sub_basic_blocks (bb)
       basic_block bb;
  {
!   rtx insn = bb->head;
    rtx end = bb->end;
    rtx jump_insn = NULL_RTX;
    int created = 0;
    int barrier = 0;
    edge falltru = 0;
!   basic_block first_bb = bb;
  
!   if (insn == bb->end)
!     return;
! 
!   if (GET_CODE (insn) == CODE_LABEL)
!     insn = NEXT_INSN (insn);
  
    /* Scan insn chain and try to find new basic block boundaries.  */
!   while (1)
      {
        enum rtx_code code = GET_CODE (insn);
        switch (code)
  	{
  	case BARRIER:
  	  if (!jump_insn)
  	    abort ();
*************** find_sub_basic_blocks (bb)
*** 753,760 ****
  	  if (jump_insn)
  	    bb->end = jump_insn;
  	  bb = falltru->dest;
! 	  if (barrier)
! 	    remove_edge (falltru);
  	  barrier = 0;
  	  jump_insn = 0;
  	  created = 1;
--- 743,749 ----
  	  if (jump_insn)
  	    bb->end = jump_insn;
  	  bb = falltru->dest;
! 	  remove_edge (falltru);
  	  barrier = 0;
  	  jump_insn = 0;
  	  created = 1;
*************** find_sub_basic_blocks (bb)
*** 762,767 ****
--- 751,757 ----
  	    make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
  	  break;
  	case INSN:
+ 	case JUMP_INSN:
  	  /* In case we've previously split insn on the JUMP_INSN, move the
  	     block header to proper place.  */
  	  if (jump_insn)
*************** find_sub_basic_blocks (bb)
*** 769,810 ****
  	      falltru = split_block (bb, PREV_INSN (insn));
  	      bb->end = jump_insn;
  	      bb = falltru->dest;
! 	      if (barrier)
! 		abort ();
  	      jump_insn = 0;
  	    }
  	default:
  	  break;
  	}
        insn = NEXT_INSN (insn);
      }
-   /* Last basic block must end in the original BB end.  */
-   if (jump_insn)
-     abort ();
  
!   /* Wire in the original edges for last basic block.  */
!   if (created)
!     {
!       bb->succ = succ_list;
!       while (succ_list)
! 	succ_list->src = bb, succ_list = succ_list->succ_next;
!     }
!   else
!     bb->succ = succ_list;
  
    /* Now re-scan and wire in all edges.  This expect simple (conditional)
       jumps at the end of each new basic blocks.  */
!   last_bb = bb;
!   for (i = first_bb->index; i < last_bb->index; i++)
!     {
!       bb = BASIC_BLOCK (i);
!       if (GET_CODE (bb->end) == JUMP_INSN)
! 	{
! 	  mark_jump_label (PATTERN (bb->end), bb->end, 0);
! 	  make_label_edge (NULL, bb, JUMP_LABEL (bb->end), 0);
! 	}
!       insn = NEXT_INSN (insn);
!     }
  }
  
  /* Find all basic blocks of the function whose first insn is F.
--- 759,792 ----
  	      falltru = split_block (bb, PREV_INSN (insn));
  	      bb->end = jump_insn;
  	      bb = falltru->dest;
! 	      remove_edge (falltru);
  	      jump_insn = 0;
  	    }
+ 	  /* We need some special care for those expressions.  */
+ 	  if (GET_CODE (insn) == JUMP_INSN)
+ 	    {
+ 	      if (GET_CODE (PATTERN (insn)) == ADDR_VEC
+ 		  || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
+ 		abort();
+ 	      jump_insn = insn;
+ 	    }
+ 	  break;
  	default:
  	  break;
  	}
+       if (insn == end)
+ 	break;
        insn = NEXT_INSN (insn);
      }
  
!   /* We've possibly replaced the conditional jump by conditional jump
!      followed by cleanup at fallthru edge, so the outgoing edges may
!      be dead.  */
!   purge_dead_edges (bb);
  
    /* Now re-scan and wire in all edges.  This expect simple (conditional)
       jumps at the end of each new basic blocks.  */
!   make_edges (NULL, first_bb->index, bb->index - 1);
  }
  
  /* Find all basic blocks of the function whose first insn is F.
*************** clear_edges ()
*** 1170,1176 ****
    n_edges = 0;
  }
  
! /* Identify the edges between basic blocks.
  
     NONLOCAL_LABEL_LIST is a list of non-local labels in the function.  Blocks
     that are otherwise unreachable may be reachable with a non-local goto.
--- 1152,1158 ----
    n_edges = 0;
  }
  
! /* Identify the edges between basic blocks MIN to MAX.
  
     NONLOCAL_LABEL_LIST is a list of non-local labels in the function.  Blocks
     that are otherwise unreachable may be reachable with a non-local goto.
*************** clear_edges ()
*** 1179,1186 ****
     the list of exception regions active at the end of the basic block.  */
  
  static void
! make_edges (label_value_list)
       rtx label_value_list;
  {
    int i;
    sbitmap *edge_cache = NULL;
--- 1161,1169 ----
     the list of exception regions active at the end of the basic block.  */
  
  static void
! make_edges (label_value_list, min, max)
       rtx label_value_list;
+      int min, max;
  {
    int i;
    sbitmap *edge_cache = NULL;
*************** make_edges (label_value_list)
*** 1200,1206 ****
    /* By nature of the way these get numbered, block 0 is always the entry.  */
    make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
  
!   for (i = 0; i < n_basic_blocks; ++i)
      {
        basic_block bb = BASIC_BLOCK (i);
        rtx insn, x;
--- 1183,1189 ----
    /* By nature of the way these get numbered, block 0 is always the entry.  */
    make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
  
!   for (i = min; i <= max; ++i)
      {
        basic_block bb = BASIC_BLOCK (i);
        rtx insn, x;


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