NOTE_INSN_BLOCK/code reordering+duplicating changes

Jan Hubicka jh@suse.cz
Tue Nov 13 15:03:00 GMT 2001


> On Sun, Nov 11, 2001 at 05:30:14PM +0100, Jan Hubicka wrote:
> > Alternatively I can make the code bb-reorder only for now (and use the full
> > change on branch) THis is much less intrusive and we can still do the
> > dupplication that is quite easy to do and brings quite considerable speedups.
> 
> This might be ok for mainline.
OK, here is the updated patch.  I am going to install it to cfg-branch for now
so I will be able to produce incremental patches for BB duplication and I will
put the full previous change to the branch later.

Bootstrapped/regtested i386

Mon Nov 12 14:19:07 CET 2001  Jan Hubicka  <jh@suse.cz>
	* cfglayout.c (struct scope_def): Kill fields note_beg, note_end,
	bb_beg, bb_end, bbs, num_bbs; add block.
	(scope_forest_info): Kill.
	(forest): Rename to scope_tree.	
	(relate_bbs_with_scope, insert_intra_1, insert_intra_bb_scope_notes,
	insert_inter_bb_scope_notes): Kill.
	(rebuild_scope_notes): Take scope parameter; rewrite.
	(dump_scope_forest): Rename to dump_scope_tree.
	(dump_scope_forest_1): Rename to dump_scope_tree_1.
	(free_scope_forest): Rename to free_scope_tree; rewrite.
	(free_scope_forest_1): Kill.
	(get_next_bb_note, get_prev_bb_note): Kill.
	(set_insn_scopes, regenerate_block_notes): New.
	(INSN_SCOPE): New.
	(insn_scope): New varray.

Index: cfglayout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfglayout.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 cfglayout.c
*** cfglayout.c	2001/11/11 11:25:14	1.2
--- cfglayout.c	2001/11/12 13:15:10
*************** struct scope_def
*** 41,64 ****
  {
    int level;
  
!   /* The NOTE_INSN_BLOCK_BEG that started this scope.  */
!   rtx note_beg;
  
-   /* The NOTE_INSN_BLOCK_END that ended this scope.  */
-   rtx note_end;
- 
-   /* The bb containing note_beg (if any).  */
-   basic_block bb_beg;
- 
-   /* The bb containing note_end (if any).  */
-   basic_block bb_end;
- 
-   /* List of basic blocks contained within this scope.  */
-   basic_block *bbs;
- 
-   /* Number of blocks contained within this scope.  */
-   int num_bbs;
- 
    /* The outer scope or NULL if outermost scope.  */
    struct scope_def *outer;
  
--- 41,49 ----
  {
    int level;
  
!   /* Tree representation of the given scope block.  */
!   tree block;
  
    /* The outer scope or NULL if outermost scope.  */
    struct scope_def *outer;
  
*************** struct scope_def
*** 72,115 ****
    struct scope_def *next;
  };
  
- /* Structure to hold information about the scope forest.  */
- typedef struct
- {
-   /* Number of trees in forest.  */
-   int num_trees;
- 
-   /* List of tree roots.  */
-   scope *trees;
- } scope_forest_info;
- 
  /* Holds the interesting trailing notes for the function.  */
  static rtx function_tail_eff_head;
  
! /* The scope forest of current function.  */
! static scope_forest_info forest;
  
  static rtx skip_insns_after_block	PARAMS ((basic_block));
  static void record_effective_endpoints	PARAMS ((void));
  static rtx label_for_bb			PARAMS ((basic_block));
  static void fixup_reorder_chain		PARAMS ((void));
  
- static void relate_bbs_with_scopes	PARAMS ((scope));
  static scope make_new_scope		PARAMS ((int, rtx));
! static void build_scope_forest		PARAMS ((scope_forest_info *));
  static void remove_scope_notes		PARAMS ((void));
! static void insert_intra_1		PARAMS ((scope, rtx *, basic_block));
! static void insert_intra_bb_scope_notes PARAMS ((basic_block));
! static void insert_inter_bb_scope_notes PARAMS ((basic_block, basic_block));
! static void rebuild_scope_notes		PARAMS ((scope_forest_info *));
! static void free_scope_forest_1		PARAMS ((scope));
! static void free_scope_forest		PARAMS ((scope_forest_info *));
! void dump_scope_forest			PARAMS ((scope_forest_info *));
! static void dump_scope_forest_1		PARAMS ((scope, int));
  
- static rtx get_next_bb_note		PARAMS ((rtx));
- static rtx get_prev_bb_note		PARAMS ((rtx));
- 
  void verify_insn_chain			PARAMS ((void));
  
  /* Skip over inter-block insns occurring after BB which are typically
     associated with BB (e.g., barriers). If there are any such insns,
--- 57,88 ----
    struct scope_def *next;
  };
  
  /* Holds the interesting trailing notes for the function.  */
  static rtx function_tail_eff_head;
+ 
+ /* The scope forst of current function.  */
+ static scope scope_tree;
+ 
+ /* Holds scope of each insn.  Indexed by INSN_UID.  */
+ static varray_type insn_scope;
  
! #define INSN_SCOPE(I) (VARRAY_GENERIC_PTR (insn_scope, INSN_UID (I)))
  
  static rtx skip_insns_after_block	PARAMS ((basic_block));
  static void record_effective_endpoints	PARAMS ((void));
  static rtx label_for_bb			PARAMS ((basic_block));
  static void fixup_reorder_chain		PARAMS ((void));
  
  static scope make_new_scope		PARAMS ((int, rtx));
! static scope build_scope_tree		PARAMS ((void));
  static void remove_scope_notes		PARAMS ((void));
! static void rebuild_scope_notes		PARAMS ((scope));
! static void free_scope_tree		PARAMS ((scope));
! void dump_scope_tree			PARAMS ((FILE *, scope));
! static void dump_scope_tree_1		PARAMS ((FILE *, scope, int));
  
  void verify_insn_chain			PARAMS ((void));
+ void change_scope			PARAMS ((rtx, scope, scope));
  
  /* Skip over inter-block insns occurring after BB which are typically
     associated with BB (e.g., barriers). If there are any such insns,
*************** record_effective_endpoints ()
*** 245,413 ****
    function_tail_eff_head = next_insn;
  }
  
- static rtx
- get_next_bb_note (x)
-      rtx x;
- {
-   while (x)
-     {
-       if (NOTE_INSN_BASIC_BLOCK_P (x))
- 	return x;
-       x = NEXT_INSN (x);
-     }
-   return NULL;
- }
- 
- static rtx
- get_prev_bb_note (x)
-      rtx x;
- {
-   while (x)
-     {
-       if (NOTE_INSN_BASIC_BLOCK_P (x))
- 	return x;
-       x = PREV_INSN (x);
-     }
-   return NULL;
- }
- 
- /* Determine and record the relationships between basic blocks and
-    scopes in scope tree S.  */
- 
- static void
- relate_bbs_with_scopes (s)
-      scope s;
- {
-   scope p;
-   int i, bbi1, bbi2, bbs_spanned;
-   rtx bbnote;
- 
-   for (p = s->inner; p; p = p->next)
-     relate_bbs_with_scopes (p);
- 
-   bbi1 = bbi2 = -1;
-   bbs_spanned = 0;
- 
-   /* If the begin and end notes are both inside the same basic block,
-      or if they are both outside of basic blocks, then we know immediately
-      how they are related. Otherwise, we need to poke around to make the
-      determination.  */
-   if (s->bb_beg != s->bb_end)
-     {
-       if (s->bb_beg && s->bb_end)
-         {
- 	  /* Both notes are in different bbs. This implies that all the
- 	     basic blocks spanned by the pair of notes are contained in
-              this scope.  */
- 	  bbi1 = s->bb_beg->index;
- 	  bbi2 = s->bb_end->index;
- 	  bbs_spanned = 1;
- 	}
-       else if (! s->bb_beg)
-         {
- 	  /* First note is outside of a bb. If the scope spans more than
- 	     one basic block, then they all are contained within this
-              scope. Otherwise, this scope is contained within the basic
- 	     block.  */
- 	  bbnote = get_next_bb_note (s->note_beg);
- 	  if (! bbnote)
- 	    abort ();
- 	  if (NOTE_BASIC_BLOCK (bbnote) == s->bb_end)
- 	    {
- 	      bbs_spanned = 0;
- 	      s->bb_beg = NOTE_BASIC_BLOCK (bbnote);
- 	    }
- 	  else
- 	    {
- 	      bbi1 = NOTE_BASIC_BLOCK (bbnote)->index;
- 	      bbi2 = s->bb_end->index;
- 	      s->bb_end = NULL;
- 	      bbs_spanned = 1;
- 	    }
- 	}
-       else /* ! s->bb_end */
-         {
- 	  /* Second note is outside of a bb. If the scope spans more than
- 	     one basic block, then they all are contained within this
-              scope. Otherwise, this scope is contained within the basic
- 	     block.  */
- 	  bbnote = get_prev_bb_note (s->note_end);
- 	  if (! bbnote)
- 	    abort ();
- 	  if (NOTE_BASIC_BLOCK (bbnote) == s->bb_beg)
- 	    {
- 	      bbs_spanned = 0;
- 	      s->bb_end = NOTE_BASIC_BLOCK (bbnote);
- 	    }
- 	  else
- 	    {
- 	      bbi1 = s->bb_beg->index;
- 	      bbi2 = NOTE_BASIC_BLOCK (bbnote)->index;
- 	      s->bb_beg = NULL;
- 	      bbs_spanned = 1;
- 	    }
- 	}
-     }
-   else
-     {
-       if (s->bb_beg)
-         /* Both notes are in the same bb, which implies the block
- 	   contains this scope.  */
- 	bbs_spanned = 0;
-       else
- 	{
-           rtx x1, x2;
- 	  /* Both notes are outside of any bbs. This implies that all the
- 	     basic blocks spanned by the pair of notes are contained in
-              this scope. 
- 	     There is a degenerate case to consider. If the notes do not
- 	     span any basic blocks, then it is an empty scope that can
- 	     safely be deleted or ignored. Mark these with level = -1.  */
- 
- 	  x1 = get_next_bb_note (s->note_beg);
- 	  x2 = get_prev_bb_note (s->note_end);
- 	  if (! (x1 && x2))
- 	    {
- 	      s->level = -1; 
- 	      bbs_spanned = 0; 
- 	    }
- 	  else
- 	    {
- 	      bbi1 = NOTE_BASIC_BLOCK (x1)->index;
- 	      bbi2 = NOTE_BASIC_BLOCK (x2)->index;
- 	      bbs_spanned = 1;
- 	    }
- 	}
-     }
- 
-   /* If the scope spans one or more basic blocks, we record them. We
-      only record the bbs that are immediately contained within this
-      scope. Note that if a scope is contained within a bb, we can tell
-      by checking that bb_beg = bb_end and that they are non-null.  */
-   if (bbs_spanned)
-     {
-       int j = 0;
- 
-       s->num_bbs = 0;
-       for (i = bbi1; i <= bbi2; i++)
- 	if (! RBI (BASIC_BLOCK (i))->scope)
- 	  s->num_bbs++;
- 
-       s->bbs = xmalloc (s->num_bbs * sizeof (basic_block));
-       for (i = bbi1; i <= bbi2; i++)
- 	{
- 	  basic_block curr_bb = BASIC_BLOCK (i);
- 	  if (! RBI (curr_bb)->scope)
- 	    {
- 	      s->bbs[j++] = curr_bb;
- 	      RBI (curr_bb)->scope = s;
- 	    }
- 	}
-     }
-   else
-     s->num_bbs = 0;
- }
- 
  /* Allocate and initialize a new scope structure with scope level LEVEL,
     and record the NOTE beginning the scope.  */
  
--- 218,223 ----
*************** make_new_scope (level, note)
*** 418,444 ****
  {
    scope new_scope = xcalloc (1, sizeof (struct scope_def));
    new_scope->level = level;
!   new_scope->note_beg = note;
    return new_scope;
  }
  
  
! /* Build a forest representing the scope structure of the function.
!    Return a pointer to a structure describing the forest.  */
  
! static void
! build_scope_forest (forest)
!     scope_forest_info *forest;
  {
    rtx x;
!   int level, bbi, i;
    basic_block curr_bb;
!   scope root, curr_scope = 0;
  
!   forest->num_trees = 0;
!   forest->trees = NULL;
    level = -1;
-   root = NULL;
    curr_bb = NULL;
    bbi = 0;
    for (x = get_insns (); x; x = NEXT_INSN (x))
--- 228,251 ----
  {
    scope new_scope = xcalloc (1, sizeof (struct scope_def));
    new_scope->level = level;
!   new_scope->block = note ? NOTE_BLOCK (note) : NULL;
    return new_scope;
  }
  
  
! /* Build a tree representing the scope structure of the function.
!    Return a pointer to a root of tree.  */
  
! static scope
! build_scope_tree ()
  {
    rtx x;
!   int level, bbi;
    basic_block curr_bb;
!   scope root, curr_scope;
  
!   root = curr_scope = make_new_scope (-1, NULL);
    level = -1;
    curr_bb = NULL;
    bbi = 0;
    for (x = get_insns (); x; x = NEXT_INSN (x))
*************** build_scope_forest (forest)
*** 446,496 ****
        if (bbi < n_basic_blocks && x == BASIC_BLOCK (bbi)->head)
  	curr_bb = BASIC_BLOCK (bbi);
  
        if (GET_CODE (x) == NOTE)
  	{
  	  if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG)
  	    {
! 	      if (root)
  		{
! 		  scope new_scope;
! 		  if (! curr_scope)
! 		    abort();
! 		  level++;
! 		  new_scope = make_new_scope (level, x);
! 		  new_scope->outer = curr_scope;
! 		  new_scope->next = NULL;
! 		  if (! curr_scope->inner)
! 		    {
! 		      curr_scope->inner = new_scope;
! 		      curr_scope->inner_last = new_scope;
! 		    }
! 		  else
! 		    {
! 		      curr_scope->inner_last->next = new_scope;
! 		      curr_scope->inner_last = new_scope;
! 		    }
! 		  curr_scope = curr_scope->inner_last;
  		}
  	      else
  		{
! 		  int ntrees = forest->num_trees;
! 		  level++;
! 	          curr_scope = make_new_scope (level, x);
! 		  root = curr_scope;
! 		  forest->trees = xrealloc (forest->trees,
! 					    sizeof (scope) * (ntrees + 1));
! 		  forest->trees[forest->num_trees++] = root;
  		}
! 	      curr_scope->bb_beg = curr_bb;
  	    }
  	  else if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END)
  	    {
! 	      curr_scope->bb_end = curr_bb;
! 	      curr_scope->note_end = x;
  	      level--;
  	      curr_scope = curr_scope->outer;
- 	      if (level == -1)
- 		root = NULL;
  	    }
  	} /* if note */
  
--- 253,290 ----
        if (bbi < n_basic_blocks && x == BASIC_BLOCK (bbi)->head)
  	curr_bb = BASIC_BLOCK (bbi);
  
+       if (INSN_P (x))
+ 	INSN_SCOPE (x) = curr_scope;
+ 
        if (GET_CODE (x) == NOTE)
  	{
  	  if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_BEG)
  	    {
! 	      scope new_scope;
! 	      if (! curr_scope)
! 		abort();
! 	      level++;
! 	      new_scope = make_new_scope (level, x);
! 	      new_scope->outer = curr_scope;
! 	      new_scope->next = NULL;
! 	      if (! curr_scope->inner)
  		{
! 		  curr_scope->inner = new_scope;
! 		  curr_scope->inner_last = new_scope;
  		}
  	      else
  		{
! 		  curr_scope->inner_last->next = new_scope;
! 		  curr_scope->inner_last = new_scope;
  		}
! 	      curr_scope = curr_scope->inner_last;
  	    }
  	  else if (NOTE_LINE_NUMBER (x) == NOTE_INSN_BLOCK_END)
  	    {
! 	      if (NOTE_BLOCK (x) != curr_scope->block)
! 		abort ();
  	      level--;
  	      curr_scope = curr_scope->outer;
  	    }
  	} /* if note */
  
*************** build_scope_forest (forest)
*** 501,509 ****
  	}
  
      } /* for */
! 
!   for (i = 0; i < forest->num_trees; i++)
!     relate_bbs_with_scopes (forest->trees[i]);
  }
  
  /* Remove all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes from
--- 295,301 ----
  	}
  
      } /* for */
!   return root;
  }
  
  /* Remove all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes from
*************** remove_scope_notes ()
*** 545,727 ****
      }
  }
  
! /* Insert scope note pairs for a contained scope tree S after insn IP.  */
! 
! static void
! insert_intra_1 (s, ip, bb)
!      scope s;
!      rtx *ip;
!      basic_block bb;
! {
!   scope p;
! 
!   if (NOTE_BLOCK (s->note_beg))
!     {  
!       *ip = emit_note_after (NOTE_INSN_BLOCK_BEG, *ip);
!       NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_beg);
!     } 
  
!   for (p = s->inner; p; p = p->next)
!     insert_intra_1 (p, ip, bb);
! 
!   if (NOTE_BLOCK (s->note_beg))
!     {  
!       *ip = emit_note_after (NOTE_INSN_BLOCK_END, *ip);
!       NOTE_BLOCK (*ip) = NOTE_BLOCK (s->note_end);
!     }
! }
! 
! 
! /* Insert NOTE_INSN_BLOCK_END notes and NOTE_INSN_BLOCK_BEG notes for
!    scopes that are contained within BB.  */
! 
! static void
! insert_intra_bb_scope_notes (bb)
!      basic_block bb;
! {
!   scope s = RBI (bb)->scope;
!   scope p;
!   rtx ip;
! 
!   if (! s)
!     return;
! 
!   ip = bb->head;
!   if (GET_CODE (ip) == CODE_LABEL)
!     ip = NEXT_INSN (ip);
! 
!   for (p = s->inner; p; p = p->next)
!     {
!       if (p->bb_beg != NULL && p->bb_beg == p->bb_end && p->bb_beg == bb)
! 	insert_intra_1 (p, &ip, bb);
!     }
! }
! 
! 
! /* Given two consecutive basic blocks BB1 and BB2 with different scopes,
!    insert NOTE_INSN_BLOCK_END notes after BB1 and NOTE_INSN_BLOCK_BEG
!    notes before BB2 such that the notes are correctly balanced. If BB1 or
!    BB2 is NULL, we are inserting scope notes for the first and last basic
!    blocks, respectively.  */
! 
! static void
! insert_inter_bb_scope_notes (bb1, bb2)
!      basic_block bb1;
!      basic_block bb2;
! {
!   rtx ip;
!   scope com;
! 
!   /* It is possible that a basic block is not contained in any scope.
!      In that case, we either open or close a scope but not both.  */
!   if (bb1 && bb2)
!     {
!       scope s1 = RBI (bb1)->scope;
!       scope s2 = RBI (bb2)->scope;
!       if (! s1 && ! s2)
! 	return;
!       if (! s1)
! 	bb1 = NULL;
!       else if (! s2)
! 	bb2 = NULL;
!     }
! 
!   /* Find common ancestor scope.  */
!   if (bb1 && bb2)
!     {
!       scope s1 = RBI (bb1)->scope;
!       scope s2 = RBI (bb2)->scope;
!       while (s1 != s2)
  	{
!           if (! (s1 && s2))
! 	    abort ();
! 	  if (s1->level > s2->level)
! 	    s1 = s1->outer;
! 	  else if (s2->level > s1->level)
! 	    s2 = s2->outer;
! 	  else
! 	    {
! 	      s1 = s1->outer;
! 	      s2 = s2->outer;
! 	    }
  	}
-       com = s1;
      }
!   else
!     com = NULL;
  
    /* Close scopes.  */
!   if (bb1)
      {
!       rtx end = bb1->end;
! 
!       scope s = RBI (bb1)->scope;
!       ip = RBI (bb1)->eff_end;
!       while (s != com)
  	{
! 	  if (NOTE_BLOCK (s->note_beg))
! 	    {  
! 	      ip = emit_note_after (NOTE_INSN_BLOCK_END, ip);
! 	      NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_end);
! 	    }
! 	  s = s->outer;
  	}
!       /* Emitting note may move the end of basic block to unwanted place.  */
!       bb1->end = end;
      }
  
    /* Open scopes.  */
!   if (bb2)
      {
!       scope s = RBI (bb2)->scope;
!       ip = bb2->head;
!       while (s != com)
  	{
! 	  if (NOTE_BLOCK (s->note_beg))
! 	    {  
! 	      ip = emit_note_before (NOTE_INSN_BLOCK_BEG, ip);
! 	      NOTE_BLOCK (ip) = NOTE_BLOCK (s->note_beg);
! 	    }
! 	  s = s->outer;
  	}
      }
  }
  
- 
  /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
!    on the scope forest and the newly reordered basic blocks.  */
  
  static void
! rebuild_scope_notes (forest)
!     scope_forest_info *forest;
  {
!   int i;
  
!   if (forest->num_trees == 0)
!     return;
! 
!   /* Start by opening the scopes before the first basic block.  */
!   insert_inter_bb_scope_notes (NULL, BASIC_BLOCK (0));
! 
!   /* Then, open and close scopes as needed between blocks.  */
!   for (i = 0; i < n_basic_blocks - 1; i++)
      {
!       basic_block bb1 = BASIC_BLOCK (i);
!       basic_block bb2 = BASIC_BLOCK (i + 1);
!       if (RBI (bb1)->scope != RBI (bb2)->scope)
! 	insert_inter_bb_scope_notes (bb1, bb2);
!       insert_intra_bb_scope_notes (bb1);
      }
! 
!   /* Finally, close the scopes after the last basic block.  */
!   insert_inter_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1), NULL);
!   insert_intra_bb_scope_notes (BASIC_BLOCK (n_basic_blocks - 1));
  }
  
  /* Free the storage associated with the scope tree at S.  */
  
  static void
! free_scope_forest_1 (s)
      scope s;
  {
    scope p, next;
--- 337,423 ----
      }
  }
  
! /* Emit BASIC_BLOCK notes needed to change scope from S1 to S2.  */
  
! void
! change_scope (orig_insn, s1, s2)
!      scope s1, s2;
!      rtx orig_insn;
! {
!   rtx insn = orig_insn;
!   scope com = NULL;
!   scope s;
!   scope ts1 = s1, ts2 = s2;
! 
!   while (ts1 != ts2)
!     {
!       if (!(ts1 && ts2))
! 	abort ();
!       if (ts1->level > ts2->level)
! 	ts1 = ts1->outer;
!       else if (ts2->level > ts1->level)
! 	ts2 = ts2->outer;
!       else
  	{
! 	  ts1 = ts1->outer;
! 	  ts2 = ts2->outer;
  	}
      }
!   com = ts1;
  
    /* Close scopes.  */
!   s = s1;
!   while (s != com)
      {
!       if (s->block)
  	{
! 	  rtx note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
! 	  NOTE_BLOCK (note) = s->block;
  	}
!       s = s->outer;
      }
  
    /* Open scopes.  */
!   s = s2;
!   while (s != com)
      {
!       if (s->block)
  	{
! 	  insn = emit_note_before (NOTE_INSN_BLOCK_BEG, insn);
! 	  NOTE_BLOCK (insn) = s->block;
  	}
+       s = s->outer;
      }
  }
  
  /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
!    on the scope tree and the newly reordered basic blocks.  */
  
  static void
! rebuild_scope_notes (root)
!     scope root;
  {
!   scope scope = root;
!   rtx insn = get_insns ();
  
!   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
      {
!       if (active_insn_p (insn)
! 	  && INSN_UID (insn) < insn_scope->num_elements
! 	  && INSN_SCOPE (insn)
! 	  && INSN_SCOPE (insn) != scope)
! 	{
! 	  change_scope (insn, scope, INSN_SCOPE (insn));
! 	  scope = INSN_SCOPE (insn);
! 	}
      }
!   change_scope (get_last_insn (), scope, root);
  }
  
  /* Free the storage associated with the scope tree at S.  */
  
  static void
! free_scope_tree (s)
      scope s;
  {
    scope p, next;
*************** free_scope_forest_1 (s)
*** 729,802 ****
    for (p = s->inner; p; p = next)
      {
        next = p->next;
!       free_scope_forest_1 (p);
      }
  
-   if (s->bbs)
-     free (s->bbs);
    free (s);
  }
- 
- /* Free the storage associated with the scope forest.  */
- 
- static void
- free_scope_forest (forest)
-     scope_forest_info *forest;
- {
-   int i;
-   for (i = 0; i < forest->num_trees; i++)
-     free_scope_forest_1 (forest->trees[i]);
- }
  
! /* Visualize the scope forest.  */
  
  void
! dump_scope_forest (forest)
!     scope_forest_info *forest;
  {
!   if (forest->num_trees == 0)
!     fprintf (stderr, "\n< Empty scope forest >\n");
!   else
!     {
!       int i;
!       fprintf (stderr, "\n< Scope forest >\n");
!       for (i = 0; i < forest->num_trees; i++)
! 	dump_scope_forest_1 (forest->trees[i], 0);
!     }
  }
  
! /* Recursive portion of dump_scope_forest.  */
  
  static void
! dump_scope_forest_1 (s, indent)
       scope s;
       int indent;
  {
    scope p;
-   int i;
- 
-   if (s->bb_beg != NULL && s->bb_beg == s->bb_end
-       && RBI (s->bb_beg)->scope
-       && RBI (s->bb_beg)->scope->level + 1 == s->level)
-     {
-       fprintf (stderr, "%*s", indent, "");
-       fprintf (stderr, "BB%d:\n", s->bb_beg->index);
-     }
  
!   fprintf (stderr, "%*s", indent, "");
!   fprintf (stderr, "{ level %d (block %p)\n", s->level,
! 	   (PTR) NOTE_BLOCK (s->note_beg));
! 
!   fprintf (stderr, "%*s%s", indent, "", "bbs:");
!   for (i = 0; i < s->num_bbs; i++)
!     fprintf (stderr, " %d", s->bbs[i]->index);
!   fprintf (stderr, "\n");
    
    for (p = s->inner; p; p = p->next)
!     dump_scope_forest_1 (p, indent + 2);
! 
!   fprintf (stderr, "%*s", indent, "");
!   fprintf (stderr, "}\n");
  }
  
  /* Given a reorder chain, rearrange the code to match.  */
--- 425,464 ----
    for (p = s->inner; p; p = next)
      {
        next = p->next;
!       free_scope_tree (p);
      }
  
    free (s);
  }
  
! /* Visualize the scope tree.  */
  
  void
! dump_scope_tree (file, root)
!     FILE *file;
!     scope root;
  {
!   fprintf (file, "\n< Scope tree >\n");
!   dump_scope_tree_1 (file, root, 0);
  }
  
! /* Recursive portion of dump_scope_tree.  */
  
  static void
! dump_scope_tree_1 (file, s, indent)
!      FILE *file;
       scope s;
       int indent;
  {
    scope p;
  
!   fprintf (file, "%*s", indent, "");
!   if (s->level >= 0)
!     fprintf (file, "level %d (block %p)\n", s->level,
! 	     (PTR) s->block);
    
    for (p = s->inner; p; p = p->next)
!     dump_scope_tree_1 (file, p, indent + 2);
  }
  
  /* Given a reorder chain, rearrange the code to match.  */
*************** verify_insn_chain ()
*** 1048,1063 ****
  void
  cfg_layout_initialize ()
  {
!   alloc_aux_for_blocks (sizeof (struct reorder_block_def));
! 
!   build_scope_forest (&forest);
    remove_scope_notes ();
  
    record_effective_endpoints ();
  }
  
  /* Finalize the changes - reorder insn list according to the sequence,
!    enter compensation code, rebuild scope forest.  */
  
  void
  cfg_layout_finalize ()
--- 710,727 ----
  void
  cfg_layout_initialize ()
  {
!   VARRAY_GENERIC_PTR_INIT (insn_scope, get_max_uid (), "insn scopes");
!   scope_tree = build_scope_tree ();
!   if (rtl_dump_file)
!     dump_scope_tree (rtl_dump_file, scope_tree);
    remove_scope_notes ();
  
+   alloc_aux_for_blocks (sizeof (struct reorder_block_def));
    record_effective_endpoints ();
  }
  
  /* Finalize the changes - reorder insn list according to the sequence,
!    enter compensation code.  */
  
  void
  cfg_layout_finalize ()
*************** cfg_layout_finalize ()
*** 1067,1079 ****
    verify_insn_chain ();
  #endif
  
-   rebuild_scope_notes (&forest);
-   free_scope_forest (&forest);
-   reorder_blocks ();
- 
    free_aux_for_blocks ();
  
  #ifdef ENABLE_CHECKING
    verify_flow_info ();
  #endif
  }
--- 731,753 ----
    verify_insn_chain ();
  #endif
  
    free_aux_for_blocks ();
  
  #ifdef ENABLE_CHECKING
    verify_flow_info ();
  #endif
+ 
+   rebuild_scope_notes (scope_tree);
+   free_scope_tree (scope_tree);
+   reorder_blocks ();
+   /* Dump the newly formed tree - this makes visible the changes
+      done by reorder_blocks - it should contain duplicated regions when
+      needed.  */
+   if (rtl_dump_file)
+     {
+       scope_tree = build_scope_tree ();
+       dump_scope_tree (rtl_dump_file, scope_tree);
+       free_scope_tree (scope_tree);
+     }
+   VARRAY_FREE (insn_scope);
  }



More information about the Gcc-patches mailing list