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]

cfg_cleanup and loop discovery in cfg_layout mode


Hi,
this patch enables some use of CFGLAYOUT CFG manipulation rounties.
The modification of cfglayout is not what I would like to over write - in
cfglayout mode the cfgcleanup is much easier to do.  In fact we can elliminate
the iteration completely - it is enought to do forwarding pass followed by BB
merging pass follows by dead block removal.

I plan to clean this up separately once I separate out the crossjumping that
will probably take some effort.

I also switched loop code to work entirely in cfglayout mode so the loop
datastructure don't need to be preserved during the initialization of cfglayout
so we can remove poor-man's (mines) micro-cfgcleanup inside cfglayout now.

Bootstrapped/regtested i386/mainline.
Honza

Tue Jun 17 23:27:53 CEST 2003  Jan Hubicka  <jh@suse.cz>

	* basic-block.h (CLEANUP_CFGLAYOUT): New flag.
	* bb-reorder.c (cfg_layout_initialize): Update call.
	* cfgcleanup.c (try_optimize_cfg): Supress optimizations of fallthru edges
	in cfglayout mode.
	* cfglayout.c (cleanup_unconditional_jumps): Kill.
	(cfg_layout_initialize): Kill agrument loops; use cfgcleanup.
	* cfglayout.h (cfg_layout_initialize): Update prototype.
	* cfgloop.h (CP_INSIDE_CFGLAYOUT): Kill.
	* cfgloopmanip.c (loop_split_edge_with): Use split_edge.
	* flow.c (propagate_block): Do not crash when basic block ends
	by first insn in the chain.
	* loop-init.c (loop_optimizer_init):  First enter cfglayout mode; later
	do loop discovery.
	* tracer.c (tracer): Update call of cfg_layout_initialize.

*** basic-block.h.old3	Tue Jun 17 17:24:14 2003
--- basic-block.h	Tue Jun 17 17:25:11 2003
*************** enum update_life_extent
*** 500,505 ****
--- 500,506 ----
  #define CLEANUP_THREADING	64	/* Do jump threading.  */
  #define CLEANUP_NO_INSN_DEL	128	/* Do not try to delete trivially dead
  					   insns.  */
+ #define CLEANUP_CFGLAYOUT	256	/* Do cleanup in cfglayout mode.  */
  extern void life_analysis	PARAMS ((rtx, FILE *, int));
  extern int update_life_info	PARAMS ((sbitmap, enum update_life_extent,
  					 int));
*** bb-reorder.c.old3	Tue Jun 17 21:07:20 2003
--- bb-reorder.c	Tue Jun 17 21:07:23 2003
*************** reorder_basic_blocks ()
*** 1093,1099 ****
    if ((* targetm.cannot_modify_jumps_p) ())
      return;
  
!   cfg_layout_initialize (NULL);
  
    set_edge_can_fallthru_flag ();
    mark_dfs_back_edges ();
--- 1093,1099 ----
    if ((* targetm.cannot_modify_jumps_p) ())
      return;
  
!   cfg_layout_initialize ();
  
    set_edge_can_fallthru_flag ();
    mark_dfs_back_edges ();
*** cfgcleanup.c.old3	Tue Jun 17 17:25:26 2003
--- cfgcleanup.c	Tue Jun 17 19:39:54 2003
*************** try_optimize_cfg (mode)
*** 1722,1728 ****
  			     b->index);
  
  		  delete_block (b);
! 		  changed = true;
  		  b = c;
  		}
  
--- 1722,1729 ----
  			     b->index);
  
  		  delete_block (b);
! 		  if (!(mode & CLEANUP_CFGLAYOUT))
! 		    changed = true;
  		  b = c;
  		}
  
*************** try_optimize_cfg (mode)
*** 1756,1762 ****
  		}
  
  	      /* If we fall through an empty block, we can remove it.  */
! 	      if (b->pred->pred_next == NULL
  		  && (b->pred->flags & EDGE_FALLTHRU)
  		  && GET_CODE (b->head) != CODE_LABEL
  		  && FORWARDER_BLOCK_P (b)
--- 1757,1764 ----
  		}
  
  	      /* If we fall through an empty block, we can remove it.  */
! 	      if (!(mode & CLEANUP_CFGLAYOUT)
! 		  && b->pred->pred_next == NULL
  		  && (b->pred->flags & EDGE_FALLTHRU)
  		  && GET_CODE (b->head) != CODE_LABEL
  		  && FORWARDER_BLOCK_P (b)
*************** try_optimize_cfg (mode)
*** 1782,1802 ****
  		  && !(s->flags & EDGE_COMPLEX)
  		  && (c = s->dest) != EXIT_BLOCK_PTR
  		  && c->pred->pred_next == NULL
! 		  && b != c
! 		  /* If the jump insn has side effects,
! 		     we can't kill the edge.  */
! 		  && (GET_CODE (b->end) != JUMP_INSN
! 		      || (flow2_completed
! 			  ? simplejump_p (b->end)
! 			  : onlyjump_p (b->end)))
! 		  && (next = merge_blocks_move (s, b, c, mode)))
! 	        {
! 		  b = next;
! 		  changed_here = true;
  		}
  
  	      /* Simplify branch over branch.  */
! 	      if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
  		changed_here = true;
  
  	      /* If B has a single outgoing edge, but uses a
--- 1784,1822 ----
  		  && !(s->flags & EDGE_COMPLEX)
  		  && (c = s->dest) != EXIT_BLOCK_PTR
  		  && c->pred->pred_next == NULL
! 		  && b != c)
! 		{
! 		  /* When not in cfg_layout mode use code aware of reordering
! 		     INSN.  This code possibly creates new basic blocks so it
! 		     does not fit merge_blocks interface and is kept here in
! 		     hope that it will become useless once more of compiler
! 		     is transformed to use cfg_layout mode.  */
! 		     
! 		  if ((mode & CLEANUP_CFGLAYOUT)
! 		      && can_merge_blocks_p (b, c))
! 		    {
! 		      merge_blocks (b, c);
! 		      update_forwarder_flag (b);
! 		      changed_here = true;
! 		    }
! 		  else if (!(mode & CLEANUP_CFGLAYOUT)
! 			   /* If the jump insn has side effects,
! 			      we can't kill the edge.  */
! 			   && (GET_CODE (b->end) != JUMP_INSN
! 			       || (flow2_completed
! 				   ? simplejump_p (b->end)
! 				   : onlyjump_p (b->end)))
! 			   && (next = merge_blocks_move (s, b, c, mode)))
! 		      {
! 			b = next;
! 			changed_here = true;
! 		      }
  		}
  
  	      /* Simplify branch over branch.  */
! 	      if ((mode & CLEANUP_EXPENSIVE)
! 		   && !(mode & CLEANUP_CFGLAYOUT)
! 		   && try_simplify_condjump (b))
  		changed_here = true;
  
  	      /* If B has a single outgoing edge, but uses a
*** cfglayout.c.old3	Tue Jun 17 18:12:58 2003
--- cfglayout.c	Tue Jun 17 22:24:21 2003
*************** static void set_block_levels		PARAMS ((t
*** 54,60 ****
  static void change_scope		PARAMS ((rtx, tree, tree));
  
  void verify_insn_chain			PARAMS ((void));
- static void cleanup_unconditional_jumps	PARAMS ((struct loops *));
  static void fixup_fallthru_exit_predecessor PARAMS ((void));
  static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
  static void break_superblocks PARAMS ((void));
--- 54,59 ----
*************** verify_insn_chain ()
*** 803,890 ****
      abort ();
  }
  
- /* Remove any unconditional jumps and forwarder block creating fallthru
-    edges instead.  During BB reordering, fallthru edges are not required
-    to target next basic block in the linear CFG layout, so the unconditional
-    jumps are not needed.  If LOOPS is not null, also update loop structure &
-    dominators.  */
- 
- static void
- cleanup_unconditional_jumps (loops)
-      struct loops *loops;
- {
-   basic_block bb;
- 
-   FOR_EACH_BB (bb)
-     {
-       if (!bb->succ)
- 	continue;
-       if (bb->succ->flags & EDGE_FALLTHRU)
- 	continue;
-       if (!bb->succ->succ_next)
- 	{
- 	  rtx insn;
- 	  if (GET_CODE (bb->head) != CODE_LABEL && forwarder_block_p (bb)
- 	      && bb->prev_bb != ENTRY_BLOCK_PTR)
- 	    {
- 	      basic_block prev = bb->prev_bb;
- 
- 	      if (rtl_dump_file)
- 		fprintf (rtl_dump_file, "Removing forwarder BB %i\n",
- 			 bb->index);
- 
- 	      if (loops)
- 		{
- 		  /* bb cannot be loop header, as it only has one entry
- 		     edge.  It could be a loop latch.  */
- 		  if (bb->loop_father->header == bb)
- 		    abort ();
- 
- 		  if (bb->loop_father->latch == bb)
- 		    bb->loop_father->latch = bb->pred->src;
- 
- 		  if (get_immediate_dominator
- 		      (loops->cfg.dom, bb->succ->dest) == bb)
- 		    set_immediate_dominator
- 		      (loops->cfg.dom, bb->succ->dest, bb->pred->src);
- 
- 		  remove_bb_from_loops (bb);
- 		  delete_from_dominance_info (loops->cfg.dom, bb);
- 		}
- 
- 	      redirect_edge_succ_nodup (bb->pred, bb->succ->dest);
- 	      delete_block (bb);
- 	      bb = prev;
- 	    }
- 	  else if (simplejump_p (bb->end))
- 	    {
- 	      rtx jump = bb->end;
- 
- 	      if (rtl_dump_file)
- 		fprintf (rtl_dump_file, "Removing jump %i in BB %i\n",
- 			 INSN_UID (jump), bb->index);
- 	      delete_insn (jump);
- 	      bb->succ->flags |= EDGE_FALLTHRU;
- 	    }
- 	  else
- 	    continue;
- 
- 	  insn = NEXT_INSN (bb->end);
- 	  while (insn
- 		 && (GET_CODE (insn) != NOTE
- 		     || NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
- 	    {
- 	      rtx next = NEXT_INSN (insn);
- 
- 	      if (GET_CODE (insn) == BARRIER)
- 		delete_barrier (insn);
- 
- 	      insn = next;
- 	    }
- 	}
-     }
- }
- 
  /* The block falling through to exit must be the last one in the
     reordered chain.  Ensure that this condition is met.  */
  static void
--- 830,835 ----
*************** cfg_layout_initialize_rbi (bb)
*** 1151,1158 ****
     CFG layout changes.  It keeps LOOPS up-to-date if not null.  */
  
  void
! cfg_layout_initialize (loops)
!      struct loops *loops;
  {
    basic_block bb;
  
--- 1096,1102 ----
     CFG layout changes.  It keeps LOOPS up-to-date if not null.  */
  
  void
! cfg_layout_initialize ()
  {
    basic_block bb;
  
*************** cfg_layout_initialize (loops)
*** 1166,1174 ****
  
    cfg_layout_rtl_register_cfg_hooks ();
  
-   cleanup_unconditional_jumps (loops);
- 
    record_effective_endpoints ();
  }
  
  /* Splits superblocks.  */
--- 1110,1118 ----
  
    cfg_layout_rtl_register_cfg_hooks ();
  
    record_effective_endpoints ();
+ 
+   cleanup_cfg (CLEANUP_CFGLAYOUT);
  }
  
  /* Splits superblocks.  */
*** cfglayout.h.old3	Tue Jun 17 21:06:54 2003
--- cfglayout.h	Tue Jun 17 21:08:40 2003
*************** typedef struct reorder_block_def
*** 35,41 ****
  
  extern rtx cfg_layout_function_footer;
  
! extern void cfg_layout_initialize	PARAMS ((struct loops *));
  extern void cfg_layout_finalize		PARAMS ((void));
  extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
  extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
--- 35,41 ----
  
  extern rtx cfg_layout_function_footer;
  
! extern void cfg_layout_initialize	PARAMS ((void));
  extern void cfg_layout_finalize		PARAMS ((void));
  extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
  extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
*** cfgloop.h.old3	Tue Jun 17 21:02:28 2003
--- cfgloop.h	Tue Jun 17 21:02:55 2003
*************** extern int fix_loop_placement		PARAMS ((
*** 299,306 ****
  
  enum
  {
!   CP_SIMPLE_PREHEADERS = 1,
!   CP_INSIDE_CFGLAYOUT = 2
  };
  
  extern void create_preheaders		PARAMS ((struct loops *, int));
--- 299,305 ----
  
  enum
  {
!   CP_SIMPLE_PREHEADERS = 1
  };
  
  extern void create_preheaders		PARAMS ((struct loops *, int));
*** cfgloopmanip.c.old3	Tue Jun 17 20:50:45 2003
--- cfgloopmanip.c	Tue Jun 17 20:58:35 2003
*************** loop_split_edge_with (e, insns, loops)
*** 1497,1527 ****
  
    /* Create basic block for it.  */
  
!   new_bb = create_basic_block (NULL_RTX, NULL_RTX, EXIT_BLOCK_PTR->prev_bb);
    add_to_dominance_info (loops->cfg.dom, new_bb);
    add_bb_to_loop (new_bb, loop_c);
    new_bb->flags = insns ? BB_SUPERBLOCK : 0;
  
!   new_e = make_edge (new_bb, dest, EDGE_FALLTHRU);
!   new_e->probability = REG_BR_PROB_BASE;
!   new_e->count = e->count;
    if (e->flags & EDGE_IRREDUCIBLE_LOOP)
      {
        new_bb->flags |= BB_IRREDUCIBLE_LOOP;
        new_e->flags |= EDGE_IRREDUCIBLE_LOOP;
      }
  
-   new_bb->count = e->count;
-   new_bb->frequency = EDGE_FREQUENCY (e);
-   redirect_edge_and_branch_force (e, new_bb);
    if (insns)
!     {
!       start_sequence ();
!       emit_insn (insns);
!       insns = get_insns ();
!       end_sequence ();
!       emit_insn_after (insns, new_bb->end);
!     }
  
    set_immediate_dominator (loops->cfg.dom, new_bb, src);
    set_immediate_dominator (loops->cfg.dom, dest,
--- 1497,1516 ----
  
    /* Create basic block for it.  */
  
!   new_bb = split_edge (e);
    add_to_dominance_info (loops->cfg.dom, new_bb);
    add_bb_to_loop (new_bb, loop_c);
    new_bb->flags = insns ? BB_SUPERBLOCK : 0;
  
!   new_e = new_bb->succ;
    if (e->flags & EDGE_IRREDUCIBLE_LOOP)
      {
        new_bb->flags |= BB_IRREDUCIBLE_LOOP;
        new_e->flags |= EDGE_IRREDUCIBLE_LOOP;
      }
  
    if (insns)
!     emit_insn_after (insns, new_bb->end);
  
    set_immediate_dominator (loops->cfg.dom, new_bb, src);
    set_immediate_dominator (loops->cfg.dom, dest,
*** flow.c.old3	Tue Jun 17 22:34:27 2003
--- flow.c	Tue Jun 17 22:35:17 2003
*************** propagate_block (bb, live, local_set, co
*** 2104,2110 ****
  	IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
  
        prev = propagate_one_insn (pbi, insn);
!       changed |= NEXT_INSN (prev) != insn;
  
        if (insn == bb->head)
  	break;
--- 2104,2113 ----
  	IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
  
        prev = propagate_one_insn (pbi, insn);
!       if (!prev)
!         changed |= insn != get_insns ();
!       else
!         changed |= NEXT_INSN (prev) != insn;
  
        if (insn == bb->head)
  	break;
*** loop-init.c.old3	Tue Jun 17 21:03:15 2003
--- loop-init.c	Tue Jun 17 21:57:04 2003
*************** loop_optimizer_init (dumpfile)
*** 37,42 ****
--- 37,45 ----
    struct loops *loops = xcalloc (1, sizeof (struct loops));
    edge e;
  
+   /* Initialize structures for layout changes.  */
+   cfg_layout_initialize ();
+ 
    /* Avoid annoying special cases of edges going to exit
       block.  */
    for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
*************** loop_optimizer_init (dumpfile)
*** 47,55 ****
--- 50,65 ----
  
    if (flow_loops_find (loops, LOOP_TREE) <= 1)
      {
+       basic_block bb;
+ 
        /* No loops.  */
        flow_loops_free (loops);
        free (loops);
+       /* Make chain.  */
+       FOR_EACH_BB (bb)
+ 	if (bb->next_bb != EXIT_BLOCK_PTR)
+ 	  bb->rbi->next = bb->next_bb;
+ 	  cfg_layout_finalize ();
        return NULL;
      }
  
*************** loop_optimizer_init (dumpfile)
*** 59,69 ****
    free (loops->cfg.dfs_order);
    loops->cfg.dfs_order = NULL;
  
-   /* Initialize structures for layout changes.  */
-   cfg_layout_initialize (loops);
- 
    /* Create pre-headers.  */
!   create_preheaders (loops, CP_SIMPLE_PREHEADERS | CP_INSIDE_CFGLAYOUT);
  
    /* Force all latches to have only single successor.  */
    force_single_succ_latches (loops);
--- 69,76 ----
    free (loops->cfg.dfs_order);
    loops->cfg.dfs_order = NULL;
  
    /* Create pre-headers.  */
!   create_preheaders (loops, CP_SIMPLE_PREHEADERS);
  
    /* Force all latches to have only single successor.  */
    force_single_succ_latches (loops);
*** tracer.c.old3	Tue Jun 17 17:37:41 2003
--- tracer.c	Tue Jun 17 21:08:04 2003
*************** tracer ()
*** 366,372 ****
  {
    if (n_basic_blocks <= 1)
      return;
!   cfg_layout_initialize (NULL);
    mark_dfs_back_edges ();
    if (rtl_dump_file)
      dump_flow_info (rtl_dump_file);
--- 371,377 ----
  {
    if (n_basic_blocks <= 1)
      return;
!   cfg_layout_initialize ();
    mark_dfs_back_edges ();
    if (rtl_dump_file)
      dump_flow_info (rtl_dump_file);


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