PATCH: (applied) defect removal and cleanup in bb-reorder

Jason Eckhardt jle@cygnus.com
Fri Mar 24 18:46:00 GMT 2000


this patch removes a couple of defects (that appeared on hppa port) and perhaps
helps readability in a few places as well.
also contains some --enable-checking fixes that graham found in which notes
were referred to before checking that they were indeed notes.


Fri Mar 24 20:13:49 2000  Jason Eckhardt  <jle@cygnus.com>

	* bb-reorder.c (REORDER_MOVED_BLOCK_END): Removed.
	(reorder_block_def): New members eff_head and eff_end.
	(REORDER_BLOCK_EFF_HEAD, REORDER_BLOCK_EFF_END): New macros.
	(verify_insn_chain): New function.
	(skip_insns_between_block): Add code to skip deleted insns.
	Check for note before using.
	(chain_reorder_blocks): Replace calls to skip_insns_between_block
	with references to REORDER_BLOCK_EFF_HEAD and REORDER_BLOCK_EFF_END.
	Check for note before using.
	(make_reorder_chain): Use INTVAL rather than XINT to get REG_BR_PROB.
	(fixup_reorder_chain): Restructure, clean up, defect removal.
	(reorder_basic_blocks): Remove last_insn and references to it.
	Moved insn chain verification code into a new function (see above).
	Delete defective code that sets last insn.
	Initialize REORDER_BLOCK_EFF_HEAD and REORDER_BLOCK_EFF_END for
	all blocks.

Index: bb-reorder.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/bb-reorder.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 bb-reorder.c
*** bb-reorder.c	2000/03/18 20:40:38	1.2
--- bb-reorder.c	2000/03/25 02:11:43
*************** typedef struct reorder_block_def {
*** 60,70 ****
    rtx end;
    int block_begin;
    int block_end;
  } *reorder_block_def;
  
  #define REORDER_BLOCK_HEAD	0x1
  #define REORDER_BLOCK_VISITED	0x2
- #define REORDER_MOVED_BLOCK_END 0x3
    
  #define REORDER_BLOCK_FLAGS(bb) \
    ((reorder_block_def) (bb)->aux)->flags
--- 60,85 ----
    rtx end;
    int block_begin;
    int block_end;
+   rtx eff_head;
+   rtx eff_end;
  } *reorder_block_def;
  
+ static struct reorder_block_def rbd_init
+ = {
+     0,			/* flags */
+     0,			/* index */
+     NULL,		/* add_jump */
+     NULL,		/* succ */
+     NULL_RTX,		/* end */
+     0,			/* block_begin */
+     0,			/* block_end */
+     NULL_RTX,		/* eff_head */
+     NULL_RTX		/* eff_end */
+ };
+ 
+ 
  #define REORDER_BLOCK_HEAD	0x1
  #define REORDER_BLOCK_VISITED	0x2
    
  #define REORDER_BLOCK_FLAGS(bb) \
    ((reorder_block_def) (bb)->aux)->flags
*************** typedef struct reorder_block_def {
*** 87,93 ****
--- 102,114 ----
  #define REORDER_BLOCK_END(bb) \
    ((reorder_block_def) (bb)->aux)->block_end
  
+ #define REORDER_BLOCK_EFF_HEAD(bb) \
+   ((reorder_block_def) (bb)->aux)->eff_head
+ 
+ #define REORDER_BLOCK_EFF_END(bb) \
+   ((reorder_block_def) (bb)->aux)->eff_end
  
+ 
  static int reorder_index;
  static basic_block reorder_last_visited;
  
*************** static basic_block get_common_dest	PARAM
*** 102,107 ****
--- 123,129 ----
  static basic_block chain_reorder_blocks	PARAMS ((edge, basic_block));
  static void make_reorder_chain		PARAMS ((basic_block));
  static void fixup_reorder_chain		PARAMS ((void));
+ static void verify_insn_chain		PARAMS ((void));
  
  
  /* Skip over insns BEFORE or AFTER BB which are typically associated with
*************** skip_insns_between_block (bb, skip_type)
*** 136,142 ****
  	  break;
  	}
      }
- 
    else
      {
        last_insn = bb->end;
--- 158,163 ----
*************** skip_insns_between_block (bb, skip_type)
*** 153,159 ****
  	    break;
  
  	  if (GET_CODE (insn) == BARRIER
! 	      || GET_CODE (insn) == JUMP_INSN
  	      || (GET_CODE (insn) == NOTE
  		  && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
  		      || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)))
--- 174,180 ----
  	    break;
  
  	  if (GET_CODE (insn) == BARRIER
! 	      || GET_CODE (insn) == JUMP_INSN 
  	      || (GET_CODE (insn) == NOTE
  		  && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
  		      || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)))
*************** skip_insns_between_block (bb, skip_type)
*** 168,173 ****
--- 189,201 ----
  	      insn = NEXT_INSN (insn);
  	      continue;
  	    }
+ 
+ 	  /* Skip to next non-deleted insn.  */
+ 	  if (GET_CODE (insn) == NOTE
+ 	      && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED
+ 		  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
+ 	    continue; 
+ 
  	  break;
  	}
  
*************** skip_insns_between_block (bb, skip_type)
*** 181,198 ****
  		  && insn == BASIC_BLOCK (bb->index + 1)->head)
  		break;
  
! 	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
  		{
  		  found_block_end = 1;
  		  continue;
  		}
  
! 	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
  		continue;
  
  	      if (GET_CODE (insn) == NOTE
  		  && NOTE_LINE_NUMBER (insn) >= 0
  		  && NEXT_INSN (insn)
  		  && (NOTE_LINE_NUMBER (NEXT_INSN (insn))
  		      == NOTE_INSN_BLOCK_END))
  		continue;
--- 209,229 ----
  		  && insn == BASIC_BLOCK (bb->index + 1)->head)
  		break;
  
! 	      if (GET_CODE (insn) == NOTE
! 		  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
  		{
  		  found_block_end = 1;
  		  continue;
  		}
  
! 	      if (GET_CODE (insn) == NOTE
! 		  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
  		continue;
  
  	      if (GET_CODE (insn) == NOTE
  		  && NOTE_LINE_NUMBER (insn) >= 0
  		  && NEXT_INSN (insn)
+ 		  && GET_CODE (NEXT_INSN (insn)) == NOTE
  		  && (NOTE_LINE_NUMBER (NEXT_INSN (insn))
  		      == NOTE_INSN_BLOCK_END))
  		continue;
*************** chain_reorder_blocks (e, ceb)
*** 255,262 ****
  	     "Edge from basic block %d to basic block %d last visited %d\n",
  	     sb->index, db->index, ceb->index);
  
!   dbh_insn = skip_insns_between_block (db, REORDER_SKIP_BEFORE);
!   cebe_insn = skip_insns_between_block (ceb, REORDER_SKIP_AFTER);
    cebbe_insn = skip_insns_between_block (ceb, REORDER_SKIP_BLOCK_END);
  
    {
--- 286,293 ----
  	     "Edge from basic block %d to basic block %d last visited %d\n",
  	     sb->index, db->index, ceb->index);
  
!   dbh_insn = REORDER_BLOCK_EFF_HEAD (db);
!   cebe_insn = REORDER_BLOCK_EFF_END (ceb);
    cebbe_insn = skip_insns_between_block (ceb, REORDER_SKIP_BLOCK_END);
  
    {
*************** chain_reorder_blocks (e, ceb)
*** 265,271 ****
  
      for (insn = dbh_insn; insn && insn != db->end; insn = NEXT_INSN (insn))
        {
! 	if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
  	  {
  	    block_begins += 1;
  	    break;
--- 296,303 ----
  
      for (insn = dbh_insn; insn && insn != db->end; insn = NEXT_INSN (insn))
        {
! 	if (GET_CODE (insn) == NOTE
! 	    && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
  	  {
  	    block_begins += 1;
  	    break;
*************** chain_reorder_blocks (e, ceb)
*** 283,289 ****
  	{
  	  if (PREV_INSN (insn) == cebbe_insn)
  	    break;
! 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
  	    {
  	      block_ends += 1;
  	      continue;
--- 315,322 ----
  	{
  	  if (PREV_INSN (insn) == cebbe_insn)
  	    break;
! 	  if (GET_CODE (insn) == NOTE
! 	      && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
  	    {
  	      block_ends += 1;
  	      continue;
*************** chain_reorder_blocks (e, ceb)
*** 438,446 ****
        REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
      }
  
!   dbh_insn = skip_insns_between_block (db, REORDER_SKIP_BEFORE);
!   cebe_insn = skip_insns_between_block (ceb, REORDER_SKIP_AFTER);
!   dbe_insn = skip_insns_between_block (db, REORDER_SKIP_AFTER);
  
    /* Leave behind any lexical block markers.  */
    if (debug_info_level > DINFO_LEVEL_TERSE
--- 471,479 ----
        REORDER_BLOCK_ADD_JUMP (db) = last_edge->dest;
      }
  
!   dbh_insn = REORDER_BLOCK_EFF_HEAD (db);
!   cebe_insn = REORDER_BLOCK_EFF_END (ceb);
!   dbe_insn = REORDER_BLOCK_EFF_END (db);
  
    /* Leave behind any lexical block markers.  */
    if (debug_info_level > DINFO_LEVEL_TERSE
*************** chain_reorder_blocks (e, ceb)
*** 484,490 ****
  }
  
  
! /* Reorder blocks starting at block B.  */
  
  static void
  make_reorder_chain (bb)
--- 517,523 ----
  }
  
  
! /* Reorder blocks starting at block BB.  */
  
  static void
  make_reorder_chain (bb)
*************** make_reorder_chain (bb)
*** 506,512 ****
        rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
  
        if (note) 
! 	probability = XINT (XEXP (note, 0), 0);
        else
  	probability = 0;
  
--- 539,545 ----
        rtx note = find_reg_note (block_end, REG_BR_PROB, 0);
  
        if (note) 
! 	probability = INTVAL (XEXP (note, 0));
        else
  	probability = 0;
  
*************** fixup_reorder_chain ()
*** 577,626 ****
  {
    int i, j;
    rtx insn;
  
    /* Set the new last insn.  */
!   for (i = 0;
!        i < n_basic_blocks - 1
! 	 && REORDER_BLOCK_INDEX (BASIC_BLOCK (i)) != n_basic_blocks;
!        i++)
!     continue;
! 
!   for (insn = BASIC_BLOCK (i)->head;
!        NEXT_INSN (insn) != 0;
!        insn = NEXT_INSN (insn))
!     continue;
! 
!   set_last_insn (insn);
  
    /* Add jumps and labels to fixup blocks.  */
!   for (i = 0; i < n_basic_blocks - 1; i++)
      {
        basic_block bbi = BASIC_BLOCK (i);
        if (REORDER_BLOCK_ADD_JUMP (bbi))
  	{
  	  rtx label_insn, jump_insn, barrier_insn;
  
! 	  if (GET_CODE (REORDER_BLOCK_ADD_JUMP (bbi)->head)
! 	      == CODE_LABEL)
  	    label_insn  = REORDER_BLOCK_ADD_JUMP (bbi)->head;
  	  else
  	    {
  	      rtx new_label = gen_label_rtx ();
  	      label_insn = emit_label_before (new_label,
  			      REORDER_BLOCK_ADD_JUMP (bbi)->head);
  	    }
- 	  REORDER_BLOCK_ADD_JUMP (bbi)->head = label_insn;	 
  
- 	  jump_insn = emit_jump_insn_after (gen_jump (label_insn),
- 					    bbi->end);
  	  JUMP_LABEL (jump_insn) = label_insn;
  	  ++LABEL_NUSES (label_insn);
  	  barrier_insn = emit_barrier_after (jump_insn);
! 	  if (GET_CODE (bbi->end) != JUMP_INSN)
! 	    bbi->end = jump_insn;
  	  /* Add block for jump.  Typically this is when a then is not
  	     predicted and we are jumping to the moved then block.  */
! 	  else	
  	    {
  	      basic_block nb;
  
--- 610,675 ----
  {
    int i, j;
    rtx insn;
+   int orig_num_blocks = n_basic_blocks;
  
    /* Set the new last insn.  */
!   {
!     int max_val = 0;
!     int max_index = 0;
!     for (j = 0; j < n_basic_blocks; j++) 
!       {
! 	int val = REORDER_BLOCK_INDEX (BASIC_BLOCK (j));
! 	if (val > max_val)
! 	  {
! 	    max_val = val;
! 	    max_index = j;
! 	  }
!       }
!     insn = REORDER_BLOCK_EFF_END (BASIC_BLOCK (max_index));
!     NEXT_INSN (insn) = NULL_RTX;
!     set_last_insn (insn);
!   }
  
    /* Add jumps and labels to fixup blocks.  */
!   for (i = 0; i < orig_num_blocks; i++)
      {
+       int need_block = 0;
        basic_block bbi = BASIC_BLOCK (i);
        if (REORDER_BLOCK_ADD_JUMP (bbi))
  	{
  	  rtx label_insn, jump_insn, barrier_insn;
  
! 	  if (GET_CODE (REORDER_BLOCK_ADD_JUMP (bbi)->head) == CODE_LABEL)
  	    label_insn  = REORDER_BLOCK_ADD_JUMP (bbi)->head;
  	  else
  	    {
  	      rtx new_label = gen_label_rtx ();
  	      label_insn = emit_label_before (new_label,
  			      REORDER_BLOCK_ADD_JUMP (bbi)->head);
+ 	      REORDER_BLOCK_ADD_JUMP (bbi)->head = label_insn;	 
+ 	    }
+ 
+ 	  if (GET_CODE (bbi->end) != JUMP_INSN)
+ 	    {
+ 	      jump_insn = emit_jump_insn_after (gen_jump (label_insn),
+ 						bbi->end);
+ 	      bbi->end = jump_insn;
+ 	      need_block = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      jump_insn = emit_jump_insn_after (gen_jump (label_insn),
+ 						REORDER_BLOCK_EFF_END (bbi));
+ 	      need_block = 1;
  	    }
  
  	  JUMP_LABEL (jump_insn) = label_insn;
  	  ++LABEL_NUSES (label_insn);
  	  barrier_insn = emit_barrier_after (jump_insn);
! 
  	  /* Add block for jump.  Typically this is when a then is not
  	     predicted and we are jumping to the moved then block.  */
! 	  if (need_block)
  	    {
  	      basic_block nb;
  
*************** fixup_reorder_chain ()
*** 664,669 ****
--- 713,782 ----
  }
  
  
+ /* Perform sanity checks on the insn chain.
+    1. Check that next/prev pointers are consistent in both the forward and
+       reverse direction.
+    2. Count insns in chain, going both directions, and check if equal.
+    3. Check that get_last_insn () returns the actual end of chain.  */
+ 
+ static void
+ verify_insn_chain ()
+ {
+   rtx x,
+       prevx,
+       nextx;
+   int insn_cnt1,
+       insn_cnt2;
+ 
+   prevx = NULL;
+   insn_cnt1 = 1;
+   for (x = get_insns (); x; x = NEXT_INSN (x))
+     {
+       if (PREV_INSN (x) != prevx)
+ 	{
+ 	  fprintf (stderr, "Forward traversal: insn chain corrupt.\n");
+ 	  fprintf (stderr, "previous insn:\n");
+ 	  debug_rtx (prevx);
+ 	  fprintf (stderr, "current insn:\n");
+ 	  debug_rtx (x);
+ 	  abort ();
+ 	}
+       ++insn_cnt1;
+       prevx = x;
+     }
+ 
+   if (prevx != get_last_insn ())
+     {
+       fprintf (stderr, "last_insn corrupt.\n");
+       abort ();
+     }
+ 
+   nextx = NULL;
+   insn_cnt2 = 1;
+   for (x = get_last_insn (); x; x = PREV_INSN (x))
+     {
+       if (NEXT_INSN (x) != nextx)
+ 	{
+ 	  fprintf (stderr, "Reverse traversal: insn chain corrupt.\n");
+ 	  fprintf (stderr, "current insn:\n");
+ 	  debug_rtx (x);
+ 	  fprintf (stderr, "next insn:\n");
+ 	  debug_rtx (nextx);
+ 	  abort ();
+ 	}
+       ++insn_cnt2;
+       nextx = x;
+     }
+ 
+   if (insn_cnt1 != insn_cnt2)
+     {
+       fprintf (stderr, "insn_cnt1 (%d) not equal to insn_cnt2 (%d).\n",
+ 	       insn_cnt1, insn_cnt2);
+       abort ();
+     }
+ }
+ 
+ 
  /* Reorder basic blocks.  */
  
  void
*************** reorder_basic_blocks ()
*** 672,678 ****
    int i, j;
    struct loops loops_info;
    int num_loops;
-   rtx last_insn;
  
    if (profile_arc_flag)
      return;
--- 785,790 ----
*************** reorder_basic_blocks ()
*** 708,742 ****
    reorder_last_visited = BASIC_BLOCK (0);
  
    for (i = 0; i < n_basic_blocks; i++)
!     BASIC_BLOCK (i)->aux = xcalloc (1, sizeof (struct reorder_block_def));
        
-   last_insn
-     = NEXT_INSN (skip_insns_between_block (BASIC_BLOCK (n_basic_blocks - 1),
- 					   REORDER_SKIP_AFTER));
- 
    make_reorder_chain (BASIC_BLOCK (0));
  
    fixup_reorder_chain ();
  
  #ifdef ENABLE_CHECKING
!     {
!       rtx insn, last_insn;
!       last_insn = get_insns ();
!       for (insn = NEXT_INSN (get_insns ());
! 	   insn && PREV_INSN (insn) == last_insn
! 	     && NEXT_INSN (PREV_INSN (insn)) == insn;
! 	   last_insn = insn,
! 	     insn = NEXT_INSN (insn))
! 	continue;
! 
!       if (insn)
! 	{
! 	  if (rtl_dump_file)
! 	    fprintf (rtl_dump_file, "insn chaining error at %d\n",
! 		     INSN_UID (last_insn));
! 	  abort();
! 	}
!     }
  #endif
  
    /* Put basic_block_info in new order.  */
--- 820,846 ----
    reorder_last_visited = BASIC_BLOCK (0);
  
    for (i = 0; i < n_basic_blocks; i++)
!     {
!       basic_block bbi = BASIC_BLOCK (i);
!       bbi->aux = xcalloc (1, sizeof (struct reorder_block_def));
!       *((struct reorder_block_def *)bbi->aux) = rbd_init;
!       REORDER_BLOCK_EFF_END (bbi)
! 	= skip_insns_between_block (bbi, REORDER_SKIP_AFTER);
!       if (i == 0)
! 	REORDER_BLOCK_EFF_HEAD (bbi) = get_insns ();
!       else 
! 	{
! 	  rtx prev_eff_end = REORDER_BLOCK_EFF_END (BASIC_BLOCK (i - 1));
! 	  REORDER_BLOCK_EFF_HEAD (bbi) = NEXT_INSN (prev_eff_end);
! 	}
!     }
        
    make_reorder_chain (BASIC_BLOCK (0));
  
    fixup_reorder_chain ();
  
  #ifdef ENABLE_CHECKING
!   verify_insn_chain ();
  #endif
  
    /* Put basic_block_info in new order.  */
*************** reorder_basic_blocks ()
*** 760,784 ****
  	  BASIC_BLOCK (j) = tempbb;
  	}
      }
-      
-     {
-       rtx xafter = skip_insns_between_block (BASIC_BLOCK (n_basic_blocks - 1),
- 					     REORDER_SKIP_AFTER);
-       if (xafter)
- 	{
- 	  NEXT_INSN (xafter) = last_insn;
- 	  if (last_insn)
- 	    {
- 	      rtx x = last_insn;
- 	      PREV_INSN (last_insn) = xafter;
- 	      while (NEXT_INSN (x))
- 		x = NEXT_INSN (x);
- 	      set_last_insn (x);
- 	    }
- 	}
-       else
- 	abort();
-     }
  
  #ifdef ENABLE_CHECKING
    verify_flow_info ();
--- 864,869 ----
*************** reorder_basic_blocks ()
*** 789,793 ****
--- 874,879 ----
  
    /* Free loop information.  */
    flow_loops_free (&loops_info);
+ 
  }
  




More information about the Gcc-patches mailing list