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]

[patch] Move loop structures to gc memory


Hello,

all the loop structures are now malloc-ed.  Since trees may be
referenced from the loop structures, this prevents garbage collection
from being run while loop structures are present.  This is going to be
impossible once we preserve the loop information across larger portion
of middle-end.

This patch makes all loop structures gc-allocated.  In addition to
the changes in GTY markup and replacing XNEW with GGC_NEW, the following
change was necessary:  Head of the exits double linked list is currently
stored as a part of the struct loop structure; gc marking would not like
that, so the patch makes this head to be allocated separately, and we
only keep a pointer to it in struct loop.

Since all the loop structures used to be deallocated manually, I have
just rewritten all the frees to ggc_frees; I hope this won't cause any
problems (in general, we are pretty sure what the life ranges of loop
structures and associated objects are).

Bootstrapped & regtested on i686 and ppc64-linux.  I have also run
a c-only bootstrap on i686 with --enable-checking=gc,gcac
I will wait for some time for comments before commiting this patch.

Zdenek

	* tree-ssa-loop-niter.c (record_estimate): Use GGC_NEW to allocate
	struct nb_iter_bound.
	(free_numbers_of_iterations_estimates_loop): Use ggc_free.
	* gengtype.c (open_base_files): Add cfhloop.h to the list of includes.
	* cfgloopmanip.c (place_new_loop): Vector larray is gc-allocated.
	* tree-scalar-evolution.c: Include gt-tree-scalar-evolution.h.
	(struct scev_info_str, scalar_evolution_info): Add GTY markers.
	(new_scev_info_str): Use GGC_NEW to allocate struct scev_info_str.
	(del_scev_info): Use ggc_free.
	(scev_initialize): Allocate scalar_evolution_info in gc memory.
	* loop-init.c: Include ggc.h.
	(loop_optimizer_init): Use GGC_CNEW to allocate struct loops.
	(loop_optimizer_finalize): Use ggc_free.
	* tree-ssa-loop.c (pass_tree_unswitch, pass_vectorize,
	pass_linear_transfom, pass_empty_loop, pass_complete_unroll,
	pass_iv_optimize): Add TODO_ggc_collect.
	* function.h (struct function): Remove skip marker from x_current_loops.
	* cfgloop.c: Include ggc.h.
	(flow_loops_free, flow_loop_free): Free the loop descriptions in gc
	memory.
	(establish_preds): Vector superloops is gc allocated.
	(alloc_loop): Allocate loop using GGC_CNEW.  Allocate head of
	loop->exits list.
	(flow_loops_find): Vector larray is gc allocated.
	(loop_exit_free): Use ggc_free.
	(rescan_loop_exit): Use GGC_NEW to allocate struct loop_exit.  Reflect
	that head of exits list is now not a part of struct loop.
	(record_loop_exits): Allocate exits table in gc memory.
	(get_loop_exit_edges, verify_loop_structure, single_exit): Reflect that
	head of exits list is now not a part of struct loop.
	* cfgloop.h (struct lpt_decision, struct nb_iter_bound,
	struct loop_exit): Add GTY marker.
	(struct loop): Add GTY marker.  Make superloops vector gc allocated.
	Add skip marker to aux field.  Make head of exits list a separate
	object.
	(struct loops): Add GTY marker.  Make larray vector gc allocated.
	Add param marker to exits table.
	(get_loops): Type changed.
	* Makefile.in (tree-scalar-evolution.o): Add gt-tree-scalar-evolution.h
	dependency.
	(cfgloop.o, loop-init.o): Add ggc.h dependency.
	(GTFILES): Add cfgloop.h and tree-scalar-evolution.c.
	* basic-block.h (struct basic_block_def): Remove skip marker from
	loop_father field.

Index: tree-ssa-loop-niter.c
===================================================================
*** tree-ssa-loop-niter.c	(revision 124655)
--- tree-ssa-loop-niter.c	(working copy)
*************** record_estimate (struct loop *loop, tree
*** 2364,2370 ****
       list.  */
    if (upper)
      {
!       struct nb_iter_bound *elt = XNEW (struct nb_iter_bound);
  
        elt->bound = i_bound;
        elt->stmt = at_stmt;
--- 2364,2370 ----
       list.  */
    if (upper)
      {
!       struct nb_iter_bound *elt = GGC_NEW (struct nb_iter_bound);
  
        elt->bound = i_bound;
        elt->stmt = at_stmt;
*************** free_numbers_of_iterations_estimates_loo
*** 3023,3029 ****
    for (bound = loop->bounds; bound; bound = next)
      {
        next = bound->next;
!       free (bound);
      }
  
    loop->bounds = NULL;
--- 3023,3029 ----
    for (bound = loop->bounds; bound; bound = next)
      {
        next = bound->next;
!       ggc_free (bound);
      }
  
    loop->bounds = NULL;
Index: gengtype.c
===================================================================
*** gengtype.c	(revision 124655)
--- gengtype.c	(working copy)
*************** open_base_files (void)
*** 1535,1541 ****
        "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
        "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
        "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
!       "cfglayout.h", "except.h", "output.h", NULL
      };
      const char *const *ifp;
      outf_p gtype_desc_c;
--- 1535,1541 ----
        "hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
        "optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
        "tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
!       "cfglayout.h", "except.h", "output.h", "cfgloop.h", NULL
      };
      const char *const *ifp;
      outf_p gtype_desc_c;
Index: cfgloopmanip.c
===================================================================
*** cfgloopmanip.c	(revision 124655)
--- cfgloopmanip.c	(working copy)
*************** static void
*** 399,405 ****
  place_new_loop (struct loop *loop)
  {
    loop->num = number_of_loops ();
!   VEC_safe_push (loop_p, heap, current_loops->larray, loop);
  }
  
  /* Given LOOP structure with filled header and latch, find the body of the
--- 399,405 ----
  place_new_loop (struct loop *loop)
  {
    loop->num = number_of_loops ();
!   VEC_safe_push (loop_p, gc, current_loops->larray, loop);
  }
  
  /* Given LOOP structure with filled header and latch, find the body of the
Index: tree-scalar-evolution.c
===================================================================
*** tree-scalar-evolution.c	(revision 124655)
--- tree-scalar-evolution.c	(working copy)
*************** static tree analyze_scalar_evolution_1 (
*** 258,264 ****
  /* The cached information about a ssa name VAR, claiming that inside LOOP,
     the value of VAR can be expressed as CHREC.  */
  
! struct scev_info_str
  {
    tree var;
    tree chrec;
--- 258,264 ----
  /* The cached information about a ssa name VAR, claiming that inside LOOP,
     the value of VAR can be expressed as CHREC.  */
  
! struct scev_info_str GTY(())
  {
    tree var;
    tree chrec;
*************** tree chrec_known;
*** 285,291 ****
  
  static bitmap already_instantiated;
  
! static htab_t scalar_evolution_info;
  
  
  /* Constructs a new SCEV_INFO_STR structure.  */
--- 285,291 ----
  
  static bitmap already_instantiated;
  
! static GTY ((param_is (struct scev_info_str))) htab_t scalar_evolution_info;
  
  
  /* Constructs a new SCEV_INFO_STR structure.  */
*************** new_scev_info_str (tree var)
*** 295,301 ****
  {
    struct scev_info_str *res;
    
!   res = XNEW (struct scev_info_str);
    res->var = var;
    res->chrec = chrec_not_analyzed_yet;
    
--- 295,301 ----
  {
    struct scev_info_str *res;
    
!   res = GGC_NEW (struct scev_info_str);
    res->var = var;
    res->chrec = chrec_not_analyzed_yet;
    
*************** eq_scev_info (const void *e1, const void
*** 326,332 ****
  static void
  del_scev_info (void *e)
  {
!   free (e);
  }
  
  /* Get the index corresponding to VAR in the current LOOP.  If
--- 326,332 ----
  static void
  del_scev_info (void *e)
  {
!   ggc_free (e);
  }
  
  /* Get the index corresponding to VAR in the current LOOP.  If
*************** scev_initialize (void)
*** 2746,2753 ****
    loop_iterator li;
    struct loop *loop;
  
!   scalar_evolution_info = htab_create (100, hash_scev_info,
! 				       eq_scev_info, del_scev_info);
    already_instantiated = BITMAP_ALLOC (NULL);
    
    initialize_scalar_evolutions_analyzer ();
--- 2746,2757 ----
    loop_iterator li;
    struct loop *loop;
  
!   scalar_evolution_info = htab_create_alloc (100,
! 					     hash_scev_info,
! 					     eq_scev_info,
! 					     del_scev_info,
! 					     ggc_calloc,
! 					     ggc_free);
    already_instantiated = BITMAP_ALLOC (NULL);
    
    initialize_scalar_evolutions_analyzer ();
*************** scev_const_prop (void)
*** 3008,3010 ****
--- 3012,3016 ----
      }
    return 0;
  }
+ 
+ #include "gt-tree-scalar-evolution.h"
Index: loop-init.c
===================================================================
*** loop-init.c	(revision 124655)
--- loop-init.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 31,36 ****
--- 31,37 ----
  #include "tree-pass.h"
  #include "timevar.h"
  #include "flags.h"
+ #include "ggc.h"
  
  
  /* Initialize loop structures.  This is used by the tree and RTL loop
*************** loop_optimizer_init (unsigned flags)
*** 43,49 ****
    struct loops *loops;
  
    gcc_assert (!current_loops);
!   loops = XCNEW (struct loops);
  
    /* Find the loops.  */
  
--- 44,50 ----
    struct loops *loops;
  
    gcc_assert (!current_loops);
!   loops = GGC_CNEW (struct loops);
  
    /* Find the loops.  */
  
*************** loop_optimizer_finalize (void)
*** 116,122 ****
    if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
      release_recorded_exits ();
    flow_loops_free (current_loops);
!   free (current_loops);
    current_loops = NULL;
  
    FOR_ALL_BB (bb)
--- 117,123 ----
    if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
      release_recorded_exits ();
    flow_loops_free (current_loops);
!   ggc_free (current_loops);
    current_loops = NULL;
  
    FOR_ALL_BB (bb)
Index: tree-ssa-loop.c
===================================================================
*** tree-ssa-loop.c	(revision 124655)
--- tree-ssa-loop.c	(working copy)
*************** struct tree_opt_pass pass_tree_unswitch 
*** 171,177 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops,	/* todo_flags_finish */
    0					/* letter */
  };
  
--- 171,178 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_ggc_collect | TODO_dump_func
!     | TODO_verify_loops,		/* todo_flags_finish */
    0					/* letter */
  };
  
*************** struct tree_opt_pass pass_vectorize =
*** 202,208 ****
    0,                                    /* properties_provided */
    0,                                    /* properties_destroyed */
    TODO_verify_loops,			/* todo_flags_start */
!   TODO_dump_func | TODO_update_ssa,	/* todo_flags_finish */
    0					/* letter */
  };
  
--- 203,210 ----
    0,                                    /* properties_provided */
    0,                                    /* properties_destroyed */
    TODO_verify_loops,			/* todo_flags_start */
!   TODO_dump_func | TODO_update_ssa
!     | TODO_ggc_collect,			/* todo_flags_finish */
    0					/* letter */
  };
  
*************** struct tree_opt_pass pass_linear_transfo
*** 237,243 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops,	/* todo_flags_finish */
    0				        /* letter */	
  };
  
--- 239,246 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops
!     | TODO_ggc_collect,			/* todo_flags_finish */
    0				        /* letter */	
  };
  
*************** struct tree_opt_pass pass_empty_loop =
*** 361,367 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops,	/* todo_flags_finish */
    0					/* letter */
  };
  
--- 364,371 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops 
!     | TODO_ggc_collect,			/* todo_flags_finish */
    0					/* letter */
  };
  
*************** struct tree_opt_pass pass_complete_unrol
*** 427,433 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops,	/* todo_flags_finish */
    0					/* letter */
  };
  
--- 431,438 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops
!     | TODO_ggc_collect,			/* todo_flags_finish */
    0					/* letter */
  };
  
*************** struct tree_opt_pass pass_iv_optimize =
*** 496,504 ****
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func
!   | TODO_verify_loops
!   | TODO_update_ssa,			/* todo_flags_finish */
    0					/* letter */
  };
  
--- 501,508 ----
    0,					/* properties_provided */
    0,					/* properties_destroyed */
    0,					/* todo_flags_start */
!   TODO_dump_func | TODO_verify_loops
!   | TODO_update_ssa | TODO_ggc_collect,	/* todo_flags_finish */
    0					/* letter */
  };
  
Index: function.h
===================================================================
*** function.h	(revision 124655)
--- function.h	(working copy)
*************** struct function GTY(())
*** 191,197 ****
    struct gimple_df *gimple_df;
  
    /* The loops in this function.  */
!   struct loops * GTY((skip)) x_current_loops;
  
    /* Value histograms attached to particular statements.  */
    htab_t GTY((skip)) value_histograms;
--- 191,197 ----
    struct gimple_df *gimple_df;
  
    /* The loops in this function.  */
!   struct loops *x_current_loops;
  
    /* Value histograms attached to particular statements.  */
    htab_t GTY((skip)) value_histograms;
Index: cfgloop.c
===================================================================
*** cfgloop.c	(revision 124655)
--- cfgloop.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 34,39 ****
--- 34,40 ----
  #include "tree-flow.h"
  #include "pointer-set.h"
  #include "output.h"
+ #include "ggc.h"
  
  static void flow_loops_cfg_dump (FILE *);
  
*************** flow_loops_dump (FILE *file, void (*loop
*** 174,198 ****
  }
  
  /* Free data allocated for LOOP.  */
  void
  flow_loop_free (struct loop *loop)
  {
    struct loop_exit *exit, *next;
  
!   VEC_free (loop_p, heap, loop->superloops);
  
    /* Break the list of the loop exit records.  They will be freed when the
       corresponding edge is rescanned or removed, and this avoids
       accessing the (already released) head of the list stored in the
       loop structure.  */
!   for (exit = loop->exits.next; exit != &loop->exits; exit = next)
      {
        next = exit->next;
        exit->next = exit;
        exit->prev = exit;
      }
!     
!   free (loop);
  }
  
  /* Free all the memory allocated for LOOPS.  */
--- 175,201 ----
  }
  
  /* Free data allocated for LOOP.  */
+ 
  void
  flow_loop_free (struct loop *loop)
  {
    struct loop_exit *exit, *next;
  
!   VEC_free (loop_p, gc, loop->superloops);
  
    /* Break the list of the loop exit records.  They will be freed when the
       corresponding edge is rescanned or removed, and this avoids
       accessing the (already released) head of the list stored in the
       loop structure.  */
!   for (exit = loop->exits->next; exit != loop->exits; exit = next)
      {
        next = exit->next;
        exit->next = exit;
        exit->prev = exit;
      }
! 
!   ggc_free (loop->exits);
!   ggc_free (loop);
  }
  
  /* Free all the memory allocated for LOOPS.  */
*************** flow_loops_free (struct loops *loops)
*** 214,221 ****
  	  flow_loop_free (loop);
  	}
  
!       VEC_free (loop_p, heap, loops->larray);
!       loops->larray = NULL;
      }
  }
  
--- 217,223 ----
  	  flow_loop_free (loop);
  	}
  
!       VEC_free (loop_p, gc, loops->larray);
      }
  }
  
*************** establish_preds (struct loop *loop, stru
*** 286,292 ****
    cfun->max_loop_depth = MAX (cfun->max_loop_depth, (int) depth);
  
    VEC_truncate (loop_p, loop->superloops, 0);
!   VEC_reserve (loop_p, heap, loop->superloops, depth);
    for (i = 0; VEC_iterate (loop_p, father->superloops, i, ploop); i++)
      VEC_quick_push (loop_p, loop->superloops, ploop);
    VEC_quick_push (loop_p, loop->superloops, father);
--- 288,294 ----
    cfun->max_loop_depth = MAX (cfun->max_loop_depth, (int) depth);
  
    VEC_truncate (loop_p, loop->superloops, 0);
!   VEC_reserve (loop_p, gc, loop->superloops, depth);
    for (i = 0; VEC_iterate (loop_p, father->superloops, i, ploop); i++)
      VEC_quick_push (loop_p, loop->superloops, ploop);
    VEC_quick_push (loop_p, loop->superloops, father);
*************** flow_loop_tree_node_remove (struct loop 
*** 335,343 ****
  struct loop *
  alloc_loop (void)
  {
!   struct loop *loop = XCNEW (struct loop);
  
-   loop->exits.next = loop->exits.prev = &loop->exits;
    return loop;
  }
  
--- 337,347 ----
  struct loop *
  alloc_loop (void)
  {
!   struct loop *loop = GGC_CNEW (struct loop);
! 
!   loop->exits = GGC_CNEW (struct loop_exit);
!   loop->exits->next = loop->exits->prev = loop->exits;
  
    return loop;
  }
  
*************** flow_loops_find (struct loops *loops)
*** 417,423 ****
      }
  
    /* Allocate loop structures.  */
!   loops->larray = VEC_alloc (loop_p, heap, num_loops + 1);
  
    /* Dummy loop containing whole function.  */
    root = alloc_loop ();
--- 421,427 ----
      }
  
    /* Allocate loop structures.  */
!   loops->larray = VEC_alloc (loop_p, gc, num_loops + 1);
  
    /* Dummy loop containing whole function.  */
    root = alloc_loop ();
*************** loop_exit_free (void *ex)
*** 961,967 ****
        exit->next->prev = exit->prev;
        exit->prev->next = exit->next;
  
!       free (exit);
      }
  }
  
--- 965,971 ----
        exit->next->prev = exit->prev;
        exit->prev->next = exit->next;
  
!       ggc_free (exit);
      }
  }
  
*************** rescan_loop_exit (edge e, bool new_edge,
*** 1000,1010 ****
  	   aloop != cloop;
  	   aloop = loop_outer (aloop))
  	{
! 	  exit = XNEW (struct loop_exit);
  	  exit->e = e;
  
! 	  exit->next = aloop->exits.next;
! 	  exit->prev = &aloop->exits;
  	  exit->next->prev = exit;
  	  exit->prev->next = exit;
  
--- 1004,1014 ----
  	   aloop != cloop;
  	   aloop = loop_outer (aloop))
  	{
! 	  exit = GGC_NEW (struct loop_exit);
  	  exit->e = e;
  
! 	  exit->next = aloop->exits->next;
! 	  exit->prev = aloop->exits;
  	  exit->next->prev = exit;
  	  exit->prev->next = exit;
  
*************** record_loop_exits (void)
*** 1050,1059 ****
    current_loops->state |= LOOPS_HAVE_RECORDED_EXITS;
  
    gcc_assert (current_loops->exits == NULL);
!   current_loops->exits = htab_create (2 * number_of_loops (),
! 				      loop_exit_hash,
! 				      loop_exit_eq,
! 				      loop_exit_free);
  
    FOR_EACH_BB (bb)
      {
--- 1054,1064 ----
    current_loops->state |= LOOPS_HAVE_RECORDED_EXITS;
  
    gcc_assert (current_loops->exits == NULL);
!   current_loops->exits = htab_create_alloc (2 * number_of_loops (),
! 					    loop_exit_hash,
! 					    loop_exit_eq,
! 					    loop_exit_free,
! 					    ggc_calloc, ggc_free);
  
    FOR_EACH_BB (bb)
      {
*************** get_loop_exit_edges (const struct loop *
*** 1123,1129 ****
       scan the body of the loop.  */
    if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
      {
!       for (exit = loop->exits.next; exit->e; exit = exit->next)
  	VEC_safe_push (edge, heap, edges, exit->e);
      }
    else
--- 1128,1134 ----
       scan the body of the loop.  */
    if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS)
      {
!       for (exit = loop->exits->next; exit->e; exit = exit->next)
  	VEC_safe_push (edge, heap, edges, exit->e);
      }
    else
*************** verify_loop_structure (void)
*** 1441,1447 ****
    /* Check the recorded loop exits.  */
    FOR_EACH_LOOP (li, loop, 0)
      {
!       if (loop->exits.e != NULL)
  	{
  	  error ("corrupted head of the exits list of loop %d",
  		 loop->num);
--- 1446,1452 ----
    /* Check the recorded loop exits.  */
    FOR_EACH_LOOP (li, loop, 0)
      {
!       if (!loop->exits || loop->exits->e != NULL)
  	{
  	  error ("corrupted head of the exits list of loop %d",
  		 loop->num);
*************** verify_loop_structure (void)
*** 1451,1457 ****
  	{
  	  /* Check that the list forms a cycle, and all elements except
  	     for the head are nonnull.  */
! 	  for (mexit = &loop->exits, exit = mexit->next, i = 0;
  	       exit->e && exit != mexit;
  	       exit = exit->next)
  	    {
--- 1456,1462 ----
  	{
  	  /* Check that the list forms a cycle, and all elements except
  	     for the head are nonnull.  */
! 	  for (mexit = loop->exits, exit = mexit->next, i = 0;
  	       exit->e && exit != mexit;
  	       exit = exit->next)
  	    {
*************** verify_loop_structure (void)
*** 1459,1465 ****
  		mexit = mexit->next;
  	    }
  
! 	  if (exit != &loop->exits)
  	    {
  	      error ("corrupted exits list of loop %d", loop->num);
  	      err = 1;
--- 1464,1470 ----
  		mexit = mexit->next;
  	    }
  
! 	  if (exit != loop->exits)
  	    {
  	      error ("corrupted exits list of loop %d", loop->num);
  	      err = 1;
*************** verify_loop_structure (void)
*** 1468,1474 ****
  
        if ((current_loops->state & LOOPS_HAVE_RECORDED_EXITS) == 0)
  	{
! 	  if (loop->exits.next != &loop->exits)
  	    {
  	      error ("nonempty exits list of loop %d, but exits are not recorded",
  		     loop->num);
--- 1473,1479 ----
  
        if ((current_loops->state & LOOPS_HAVE_RECORDED_EXITS) == 0)
  	{
! 	  if (loop->exits->next != loop->exits)
  	    {
  	      error ("nonempty exits list of loop %d, but exits are not recorded",
  		     loop->num);
*************** verify_loop_structure (void)
*** 1530,1536 ****
        FOR_EACH_LOOP (li, loop, 0)
  	{
  	  eloops = 0;
! 	  for (exit = loop->exits.next; exit->e; exit = exit->next)
  	    eloops++;
  	  if (eloops != sizes[loop->num])
  	    {
--- 1535,1541 ----
        FOR_EACH_LOOP (li, loop, 0)
  	{
  	  eloops = 0;
! 	  for (exit = loop->exits->next; exit->e; exit = exit->next)
  	    eloops++;
  	  if (eloops != sizes[loop->num])
  	    {
*************** loop_exit_edge_p (const struct loop *loo
*** 1585,1596 ****
  edge
  single_exit (const struct loop *loop)
  {
!   struct loop_exit *exit = loop->exits.next;
  
    if ((current_loops->state & LOOPS_HAVE_RECORDED_EXITS) == 0)
      return NULL;
  
!   if (exit->e && exit->next == &loop->exits)
      return exit->e;
    else
      return NULL;
--- 1590,1601 ----
  edge
  single_exit (const struct loop *loop)
  {
!   struct loop_exit *exit = loop->exits->next;
  
    if ((current_loops->state & LOOPS_HAVE_RECORDED_EXITS) == 0)
      return NULL;
  
!   if (exit->e && exit->next == loop->exits)
      return exit->e;
    else
      return NULL;
Index: cfgloop.h
===================================================================
*** cfgloop.h	(revision 124655)
--- cfgloop.h	(working copy)
*************** enum lpt_dec
*** 39,45 ****
    LPT_UNROLL_STUPID
  };
  
! struct lpt_decision
  {
    enum lpt_dec decision;
    unsigned times;
--- 39,45 ----
    LPT_UNROLL_STUPID
  };
  
! struct lpt_decision GTY (())
  {
    enum lpt_dec decision;
    unsigned times;
*************** struct lpt_decision
*** 47,53 ****
  
  /* The structure describing a bound on number of iterations of a loop.  */
  
! struct nb_iter_bound
  {
    /* The statement STMT is executed at most ...  */
    tree stmt;
--- 47,53 ----
  
  /* The structure describing a bound on number of iterations of a loop.  */
  
! struct nb_iter_bound GTY ((chain_next ("%h.next")))
  {
    /* The statement STMT is executed at most ...  */
    tree stmt;
*************** struct nb_iter_bound
*** 72,81 ****
  
  /* Description of the loop exit.  */
  
! struct loop_exit
  {
    /* The exit edge.  */
!   edge e;
  
    /* Previous and next exit in the list of the exits of the loop.  */
    struct loop_exit *prev;
--- 72,81 ----
  
  /* Description of the loop exit.  */
  
! struct loop_exit GTY (())
  {
    /* The exit edge.  */
!   struct edge_def *e;
  
    /* Previous and next exit in the list of the exits of the loop.  */
    struct loop_exit *prev;
*************** struct loop_exit
*** 88,105 ****
  typedef struct loop *loop_p;
  DEF_VEC_P (loop_p);
  DEF_VEC_ALLOC_P (loop_p, heap);
  
  /* Structure to hold information for each natural loop.  */
! struct loop
  {
    /* Index into loops array.  */
    int num;
  
    /* Basic block of loop header.  */
!   basic_block header;
  
    /* Basic block of loop latch.  */
!   basic_block latch;
  
    /* For loop unrolling/peeling decision.  */
    struct lpt_decision lpt_decision;
--- 88,106 ----
  typedef struct loop *loop_p;
  DEF_VEC_P (loop_p);
  DEF_VEC_ALLOC_P (loop_p, heap);
+ DEF_VEC_ALLOC_P (loop_p, gc);
  
  /* Structure to hold information for each natural loop.  */
! struct loop GTY ((chain_next ("%h.next")))
  {
    /* Index into loops array.  */
    int num;
  
    /* Basic block of loop header.  */
!   struct basic_block_def *header;
  
    /* Basic block of loop latch.  */
!   struct basic_block_def *latch;
  
    /* For loop unrolling/peeling decision.  */
    struct lpt_decision lpt_decision;
*************** struct loop
*** 114,120 ****
    unsigned num_nodes;
  
    /* Superloops of the loop, starting with the outermost loop.  */
!   VEC (loop_p, heap) *superloops;
  
    /* The first inner (child) loop or NULL if innermost loop.  */
    struct loop *inner;
--- 115,121 ----
    unsigned num_nodes;
  
    /* Superloops of the loop, starting with the outermost loop.  */
!   VEC (loop_p, gc) *superloops;
  
    /* The first inner (child) loop or NULL if innermost loop.  */
    struct loop *inner;
*************** struct loop
*** 126,132 ****
    struct loop *copy;
  
    /* Auxiliary info specific to a pass.  */
!   void *aux;
  
    /* The number of times the latch of the loop is executed.
       This is an INTEGER_CST or an expression containing symbolic
--- 127,133 ----
    struct loop *copy;
  
    /* Auxiliary info specific to a pass.  */
!   PTR GTY ((skip (""))) aux;
  
    /* The number of times the latch of the loop is executed.
       This is an INTEGER_CST or an expression containing symbolic
*************** struct loop
*** 158,164 ****
    struct nb_iter_bound *bounds;
  
    /* Head of the cyclic list of the exits of the loop.  */
!   struct loop_exit exits;
  };
  
  /* Flags for state of loop structure.  */
--- 159,165 ----
    struct nb_iter_bound *bounds;
  
    /* Head of the cyclic list of the exits of the loop.  */
!   struct loop_exit *exits;
  };
  
  /* Flags for state of loop structure.  */
*************** enum
*** 177,194 ****
  #define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
  
  /* Structure to hold CFG information about natural loops within a function.  */
! struct loops
  {
    /* State of loops.  */
    int state;
  
    /* Array of the loops.  */
!   VEC (loop_p, heap) *larray;
  
    /* Maps edges to the list of their descriptions as loop exits.  Edges
       whose sources or destinations have loop_father == NULL (which may
       happen during the cfg manipulations) should not appear in EXITS.  */
!   htab_t exits;
  
    /* Pointer to root of loop hierarchy tree.  */
    struct loop *tree_root;
--- 178,195 ----
  #define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
  
  /* Structure to hold CFG information about natural loops within a function.  */
! struct loops GTY (())
  {
    /* State of loops.  */
    int state;
  
    /* Array of the loops.  */
!   VEC (loop_p, gc) *larray;
  
    /* Maps edges to the list of their descriptions as loop exits.  Edges
       whose sources or destinations have loop_father == NULL (which may
       happen during the cfg manipulations) should not appear in EXITS.  */
!   htab_t GTY((param_is (struct loop_exit))) exits;
  
    /* Pointer to root of loop hierarchy tree.  */
    struct loop *tree_root;
*************** loop_outer (const struct loop *loop)
*** 428,434 ****
  
  /* Returns the list of loops in current_loops.  */
  
! static inline VEC (loop_p, heap) *
  get_loops (void)
  {
    if (!current_loops)
--- 429,435 ----
  
  /* Returns the list of loops in current_loops.  */
  
! static inline VEC (loop_p, gc) *
  get_loops (void)
  {
    if (!current_loops)
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 124655)
--- Makefile.in	(working copy)
*************** tree-chrec.o: tree-chrec.c $(CONFIG_H) $
*** 2188,2194 ****
  tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
     coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(REAL_H) $(RTL_H) \
     $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
!    $(TIMEVAR_H) $(CFGLOOP_H) $(SCEV_H) tree-pass.h $(FLAGS_H) tree-chrec.h
  tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
--- 2188,2195 ----
  tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
     coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(REAL_H) $(RTL_H) \
     $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
!    $(TIMEVAR_H) $(CFGLOOP_H) $(SCEV_H) tree-pass.h $(FLAGS_H) tree-chrec.h \
!    gt-tree-scalar-evolution.h
  tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
     $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
*************** cfgcleanup.o : cfgcleanup.c $(CONFIG_H) 
*** 2571,2577 ****
     $(REGS_H) $(EMIT_RTL_H) $(CFGLAYOUT_H) tree-pass.h $(CFGLOOP_H) $(EXPR_H)
  cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(FLAGS_H) $(FUNCTION_H) \
!    $(OBSTACK_H) toplev.h $(TREE_FLOW_H) $(TREE_H) pointer-set.h output.h
  cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) \
     $(OBSTACK_H) output.h
--- 2572,2579 ----
     $(REGS_H) $(EMIT_RTL_H) $(CFGLAYOUT_H) tree-pass.h $(CFGLOOP_H) $(EXPR_H)
  cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(FLAGS_H) $(FUNCTION_H) \
!    $(OBSTACK_H) toplev.h $(TREE_FLOW_H) $(TREE_H) pointer-set.h output.h \
!    $(GGC_H)
  cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) \
     $(OBSTACK_H) output.h
*************** loop-invariant.o : loop-invariant.c $(CO
*** 2589,2595 ****
  cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) output.h \
     coretypes.h $(TM_H) cfghooks.h $(OBSTACK_H)
! loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) \
     coretypes.h $(TM_H) $(OBSTACK_H) tree-pass.h $(TIMEVAR_H) $(FLAGS_H)
  loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
--- 2591,2597 ----
  cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) output.h \
     coretypes.h $(TM_H) cfghooks.h $(OBSTACK_H)
! loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(GGC_H) \
     $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) \
     coretypes.h $(TM_H) $(OBSTACK_H) tree-pass.h $(TIMEVAR_H) $(FLAGS_H)
  loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 2977,2983 ****
    $(srcdir)/coverage.c $(srcdir)/rtl.h \
    $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/function.h $(srcdir)/libfuncs.h $(SYMTAB_H) \
    $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
!   $(srcdir)/ipa-reference.h $(srcdir)/output.h \
    $(srcdir)/cselib.h $(srcdir)/basic-block.h  $(srcdir)/cgraph.h \
    $(srcdir)/reload.h \
    $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
--- 2979,2985 ----
    $(srcdir)/coverage.c $(srcdir)/rtl.h \
    $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/function.h $(srcdir)/libfuncs.h $(SYMTAB_H) \
    $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
!   $(srcdir)/ipa-reference.h $(srcdir)/output.h $(srcdir)/cfgloop.h \
    $(srcdir)/cselib.h $(srcdir)/basic-block.h  $(srcdir)/cgraph.h \
    $(srcdir)/reload.h \
    $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 2991,2997 ****
    $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/cfglayout.h \
    $(srcdir)/sdbout.c $(srcdir)/stor-layout.c \
    $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
!   $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
    $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
    $(srcdir)/tree-phinodes.c $(srcdir)/tree-cfg.c \
    $(srcdir)/tree-dfa.c $(srcdir)/tree-ssa-propagate.c \
--- 2993,2999 ----
    $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/cfglayout.h \
    $(srcdir)/sdbout.c $(srcdir)/stor-layout.c \
    $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
!   $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h $(srcdir)/tree-scalar-evolution.c \
    $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
    $(srcdir)/tree-phinodes.c $(srcdir)/tree-cfg.c \
    $(srcdir)/tree-dfa.c $(srcdir)/tree-ssa-propagate.c \
Index: basic-block.h
===================================================================
*** basic-block.h	(revision 124655)
--- basic-block.h	(working copy)
*************** struct basic_block_def GTY((chain_next (
*** 221,227 ****
    PTR GTY ((skip (""))) aux;
  
    /* Innermost loop containing the block.  */
!   struct loop * GTY ((skip (""))) loop_father;
  
    /* The dominance and postdominance information node.  */
    struct et_node * GTY ((skip (""))) dom[2];
--- 221,227 ----
    PTR GTY ((skip (""))) aux;
  
    /* Innermost loop containing the block.  */
!   struct loop *loop_father;
  
    /* The dominance and postdominance information node.  */
    struct et_node * GTY ((skip (""))) dom[2];


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