cfg merge part 15 - more cfglayout bits

Jan Hubicka jh@suse.cz
Thu May 9 09:11:00 GMT 2002


Hi,
these support routines are used by the software trace cache implementation.
Basically when cfglayout is in the action, we don't need to have unconditional
jumps in the code at all.  There is also new function that marks edges that
can be made fallthru (this includes the "normal" fallthru edges and branches
of reversible conditional jumps).

Honza

Thu May  9 17:24:24 CEST 2002  Jan Hubicka  <jh@suse.cz>
			       Josef Zlomek <zlomek@matfyz.cz>

	2002-01-14  Josef Zlomek  <zlomek@matfyz.cz>

	cfg.c (dump_edge_info): added dumping of EDGE_CAN_FALLTHRU.
	bb-reorder.c (find_traces_1_round): fixed bug in computing the
	iterations of the loop.

	Wed Jan  9 2002  Josef Zlomek  <zlomj9am@artax.karlin.mff.cuni.cz>

	* basic-block.h: New flag EDGE_CAN_FALLTHRU
	* cfganal.c (set_edge_can_fallthru_flag): New function; marks the edges
	that can be made fallthru.

	Mon Nov 12 16:25:53 CET 2001  Jan Hubicka  <jh@suse.cz>

	* cfglayout.c (cleanup_unconditional_jumps): New static function.
	(cfg_layout_initialize): Use it.

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/basic-block.h,v
retrieving revision 1.139
diff -c -3 -p -r1.139 basic-block.h
*** basic-block.h	8 May 2002 09:17:16 -0000	1.139
--- basic-block.h	9 May 2002 15:18:16 -0000
*************** typedef struct edge_def {
*** 141,146 ****
--- 141,147 ----
  #define EDGE_EH			8
  #define EDGE_FAKE		16
  #define EDGE_DFS_BACK		32
+ #define EDGE_CAN_FALLTHRU	64
  
  #define EDGE_COMPLEX	(EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
  
*************** extern conflict_graph conflict_graph_com
*** 699,704 ****
--- 700,706 ----
                                          PARAMS ((regset,
  						 partition));
  extern bool mark_dfs_back_edges		PARAMS ((void));
+ extern void set_edge_can_fallthru_flag	PARAMS ((void));
  extern void update_br_prob_note		PARAMS ((basic_block));
  extern void fixup_abnormal_edges	PARAMS ((void));
  
Index: cfganal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfganal.c,v
retrieving revision 1.17
diff -c -3 -p -r1.17 cfganal.c
*** cfganal.c	9 May 2002 12:56:47 -0000	1.17
--- cfganal.c	9 May 2002 15:18:17 -0000
*************** mark_dfs_back_edges ()
*** 189,194 ****
--- 189,224 ----
    return found;
  }
  
+ /* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru.  */
+ 
+ void
+ set_edge_can_fallthru_flag ()
+ {
+   int i;
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       basic_block bb = BASIC_BLOCK (i);
+       edge e;
+ 
+       /* The FALLTHRU edge is also CAN_FALLTHRU edge.  */
+       for (e = bb->succ; e; e = e->succ_next)
+ 	if (e->flags & EDGE_FALLTHRU)
+ 	  e->flags |= EDGE_CAN_FALLTHRU;
+ 
+       /* If the BB ends with an invertable condjump all (2) edges are
+ 	 CAN_FALLTHRU edges.  */
+       if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
+ 	continue;
+       if (!any_condjump_p (bb->end))
+ 	continue;
+       if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
+ 	continue;
+       invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
+       bb->succ->flags |= EDGE_CAN_FALLTHRU;
+       bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
+     }
+ }
+ 
  /* Return true if we need to add fake edge to exit.
     Helper function for the flow_call_edges_add.  */
  
*************** flow_call_edges_add (blocks)
*** 326,334 ****
  
  	      /* Note that the following may create a new basic block
  		 and renumber the existing basic blocks.  */
! 	      e = split_block (bb, split_at_insn);
! 	      if (e)
! 		blocks_split++;
  
  	      make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
  	    }
--- 356,367 ----
  
  	      /* Note that the following may create a new basic block
  		 and renumber the existing basic blocks.  */
! 	      if (split_at_insn != bb->end)
! 		{
! 		  e = split_block (bb, split_at_insn);
! 		  if (e)
! 		    blocks_split++;
! 		}
  
  	      make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
  	    }
Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfglayout.c,v
retrieving revision 1.10
diff -c -3 -p -r1.10 cfglayout.c
*** cfglayout.c	8 May 2002 09:17:17 -0000	1.10
--- cfglayout.c	9 May 2002 15:18:18 -0000
*************** static void set_block_levels		PARAMS ((t
*** 46,51 ****
--- 46,52 ----
  static void change_scope		PARAMS ((rtx, tree, tree));
  
  void verify_insn_chain			PARAMS ((void));
+ static void cleanup_unconditional_jumps	PARAMS (());
  static void fixup_fallthru_exit_predecessor PARAMS ((void));
  static rtx unlink_insn_chain PARAMS ((rtx, rtx));
  static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
*************** verify_insn_chain ()
*** 578,583 ****
--- 579,654 ----
      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 ()
+ {
+   int i;
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       basic_block bb = BASIC_BLOCK (i);
+ 
+       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) && i)
+ 	    {
+ 	      basic_block prev = BASIC_BLOCK (--i);
+ 
+ 	      if (rtl_dump_file)
+ 		fprintf (rtl_dump_file, "Removing forwarder BB %i\n",
+ 			 bb->index);
+ 
+ 	      redirect_edge_succ (bb->pred, bb->succ->dest);
+ 	      flow_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;
+ 
+ 	  /* Cleanup barriers and delete ADDR_VECs in a way as they are belonging
+              to removed tablejump anyway.  */
+ 	  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);
+ 	      else if (GET_CODE (insn) == JUMP_INSN)
+ 		delete_insn_chain (PREV_INSN (insn), insn);
+ 	      else if (GET_CODE (insn) == CODE_LABEL)
+ 		;
+ 	      else if (GET_CODE (insn) != NOTE)
+ 		abort ();
+ 
+ 	      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
*************** cfg_layout_redirect_edge (e, dest)
*** 767,772 ****
--- 838,851 ----
      }
    else
      redirect_edge_and_branch (e, dest);
+ 
+   /* We don't want simplejumps in the insn stream during cfglayout.  */
+   if (simplejump_p (src->end))
+     {
+       delete_insn (src->end);
+       delete_barrier (NEXT_INSN (src->end));
+       src->succ->flags |= EDGE_FALLTHRU;
+     }
    dest->index = old_index;
  }
  
*************** cfg_layout_initialize ()
*** 867,872 ****
--- 946,953 ----
    /* Our algorithm depends on fact that there are now dead jumptables
       around the code.  */
    alloc_aux_for_blocks (sizeof (struct reorder_block_def));
+ 
+   cleanup_unconditional_jumps ();
  
    scope_to_insns_initialize ();
  
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgrtl.c,v
retrieving revision 1.43
diff -c -3 -p -r1.43 cfgrtl.c
*** cfgrtl.c	9 May 2002 12:56:47 -0000	1.43
--- cfgrtl.c	9 May 2002 15:18:19 -0000
*************** verify_flow_info ()
*** 1830,1836 ****
  	  if (e->flags & EDGE_FALLTHRU)
  	    n_fallthru++;
  
! 	  if ((e->flags & ~EDGE_DFS_BACK) == 0)
  	    n_branch++;
  
  	  if (e->flags & EDGE_ABNORMAL_CALL)
--- 1830,1836 ----
  	  if (e->flags & EDGE_FALLTHRU)
  	    n_fallthru++;
  
! 	  if ((e->flags & ~(EDGE_DFS_BACK | EDGE_CAN_FALLTHRU)) == 0)
  	    n_branch++;
  
  	  if (e->flags & EDGE_ABNORMAL_CALL)
Index: cfg.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfg.c,v
retrieving revision 1.23
retrieving revision 1.16.2.10
diff -c -3 -p -r1.23 -r1.16.2.10
*** cfg.c	10 Apr 2002 00:15:58 -0000	1.23
--- cfg.c	16 Apr 2002 18:14:28 -0000	1.16.2.10
*************** dump_edge_info (file, e, do_succ)
*** 609,615 ****
    if (e->flags)
      {
        static const char * const bitnames[]
! 	= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back"};
        int comma = 0;
        int i, flags = e->flags;
  
--- 619,625 ----
    if (e->flags)
      {
        static const char * const bitnames[]
! 	= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
        int comma = 0;
        int i, flags = e->flags;
  



More information about the Gcc-patches mailing list