C++-ify vec_info structures
authorRichard Sandiford <richard.sandiford@linaro.org>
Fri, 4 Aug 2017 10:41:12 +0000 (10:41 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 4 Aug 2017 10:41:12 +0000 (10:41 +0000)
This patch uses new, delete, constructors and desctructors to manage
vec_info.  This includes making ~vec_info free all the data shared
by bb_vec_info and loop_vec_info, whereas previously the code was
duplicated in destroy_bb_vec_info and destroy_loop_vec_info.  This
in turn meant changing the order of:

  FOR_EACH_VEC_ELT (slp_instances, i, instance)
    vect_free_slp_instance (instance);

and:

  gimple_set_uid (stmt, -1);

in destroy_bb_vec_info/~_bb_vec_info, so that now vect_free_slp_instance
could see a uid of -1 as well as 0.  The patch updates vinfo_for_stmt
so that it returns NULL for a uid of -1.

2017-08-04  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* tree-vectorizer.h (vec_info): Add a constructor and destructor.
Add an explicit name for the enum.  Use auto_vec for slp_instances
and grouped_stores.
(_loop_vec_info): Add a constructor and destructor.  Use auto_vec
for all vectors.
(_bb_vec_info): Add a constructor and destructor.
(vinfo_for_stmt): Return NULL for uids of -1 as well.
(destroy_loop_vec_info): Delete.
(vect_destroy_datarefs): Likewise.
* tree-vectorizer.c (vect_destroy_datarefs): Delete.
(vec_info::vec_info): New function.
(vec_info::~vec_info): Likewise.
(vectorize_loops): Use delete instead of destroy_loop_vec_info.
* tree-parloops.c (gather_scalar_reductions): Use delete instead of
destroy_loop_vec_info.
* tree-vect-loop.c (new_loop_vec_info): Replace with...
(_loop_vec_info::_loop_vec_info): ...this.
(destroy_loop_vec_info): Replace with...
(_loop_vec_info::~_loop_vec_info): ...this.  Unconditionally delete
the stmt_vec_infos.  Leave handling of vec_info information to its
destructor.  Remove explicit vector releases.
(vect_analyze_loop_form): Use new instead of new_loop_vec_info.
(vect_analyze_loop): Use delete instead of destroy_loop_vec_info.
* tree-vect-slp.c (new_bb_vec_info): Replace with...
(_bb_vec_info::_bb_vec_info): ...this.  Don't reserve space in
BB_VINFO_GROUPED_STORES or BB_VINFO_SLP_INSTANCES.
(destroy_bb_vec_info): Replace with...
(_bb_vec_info::~_bb_vec_info): ...this.  Leave handling of vec_info
information to its destructor.
(vect_slp_analyze_bb_1): Use new and delete instead of
new_bb_vec_info and destroy_bb_vec_info.
(vect_slp_bb): Replace 2 calls to destroy_bb_vec_info with a
single delete.

From-SVN: r250869

gcc/ChangeLog
gcc/tree-parloops.c
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c
gcc/tree-vectorizer.c
gcc/tree-vectorizer.h

index 7a5a1ebd0bcbd0f5f041613af80d987729c6001f..b39dc47f411cec5ba89d1d5716233a1e12cfad3c 100644 (file)
@@ -1,3 +1,39 @@
+2017-08-04  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * tree-vectorizer.h (vec_info): Add a constructor and destructor.
+       Add an explicit name for the enum.  Use auto_vec for slp_instances
+       and grouped_stores.
+       (_loop_vec_info): Add a constructor and destructor.  Use auto_vec
+       for all vectors.
+       (_bb_vec_info): Add a constructor and destructor.
+       (vinfo_for_stmt): Return NULL for uids of -1 as well.
+       (destroy_loop_vec_info): Delete.
+       (vect_destroy_datarefs): Likewise.
+       * tree-vectorizer.c (vect_destroy_datarefs): Delete.
+       (vec_info::vec_info): New function.
+       (vec_info::~vec_info): Likewise.
+       (vectorize_loops): Use delete instead of destroy_loop_vec_info.
+       * tree-parloops.c (gather_scalar_reductions): Use delete instead of
+       destroy_loop_vec_info.
+       * tree-vect-loop.c (new_loop_vec_info): Replace with...
+       (_loop_vec_info::_loop_vec_info): ...this.
+       (destroy_loop_vec_info): Replace with...
+       (_loop_vec_info::~_loop_vec_info): ...this.  Unconditionally delete
+       the stmt_vec_infos.  Leave handling of vec_info information to its
+       destructor.  Remove explicit vector releases.
+       (vect_analyze_loop_form): Use new instead of new_loop_vec_info.
+       (vect_analyze_loop): Use delete instead of destroy_loop_vec_info.
+       * tree-vect-slp.c (new_bb_vec_info): Replace with...
+       (_bb_vec_info::_bb_vec_info): ...this.  Don't reserve space in
+       BB_VINFO_GROUPED_STORES or BB_VINFO_SLP_INSTANCES.
+       (destroy_bb_vec_info): Replace with...
+       (_bb_vec_info::~_bb_vec_info): ...this.  Leave handling of vec_info
+       information to its destructor.
+       (vect_slp_analyze_bb_1): Use new and delete instead of
+       new_bb_vec_info and destroy_bb_vec_info.
+       (vect_slp_bb): Replace 2 calls to destroy_bb_vec_info with a
+       single delete.
+
 2017-08-04  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * tree-data-ref.h (subscript): Add access_fn field.
index 538932e50bfb8e9761fd6551483f620dcac2cb76..59e261d2aaa35a063cf73d6bf2d94daf718e3d9e 100644 (file)
@@ -2577,7 +2577,7 @@ gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list
 
       build_new_reduction (reduction_list, reduc_stmt, phi);
     }
-  destroy_loop_vec_info (simple_loop_info, true);
+  delete simple_loop_info;
 
   if (!double_reduc_phis.is_empty ())
     {
@@ -2613,7 +2613,7 @@ gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list
 
              build_new_reduction (reduction_list, double_reduc_stmts[i], phi);
            }
-         destroy_loop_vec_info (simple_loop_info, true);
+         delete simple_loop_info;
        }
     }
 
index 9723f134a3ce8cf36a245a0f2d023ec15fe1903c..8b2a61e733be4134ecbdfca77b7cd86f1f35318f 100644 (file)
@@ -1098,112 +1098,77 @@ bb_in_loop_p (const_basic_block bb, const void *data)
 }
 
 
-/* Function new_loop_vec_info.
-
-   Create and initialize a new loop_vec_info struct for LOOP, as well as
-   stmt_vec_info structs for all the stmts in LOOP.  */
-
-static loop_vec_info
-new_loop_vec_info (struct loop *loop)
+/* Create and initialize a new loop_vec_info struct for LOOP_IN, as well as
+   stmt_vec_info structs for all the stmts in LOOP_IN.  */
+
+_loop_vec_info::_loop_vec_info (struct loop *loop_in)
+  : vec_info (vec_info::loop, init_cost (loop_in)),
+    loop (loop_in),
+    bbs (XCNEWVEC (basic_block, loop->num_nodes)),
+    num_itersm1 (NULL_TREE),
+    num_iters (NULL_TREE),
+    num_iters_unchanged (NULL_TREE),
+    num_iters_assumptions (NULL_TREE),
+    th (0),
+    vectorization_factor (0),
+    unaligned_dr (NULL),
+    peeling_for_alignment (0),
+    ptr_mask (0),
+    slp_unrolling_factor (1),
+    single_scalar_iteration_cost (0),
+    vectorizable (false),
+    peeling_for_gaps (false),
+    peeling_for_niter (false),
+    operands_swapped (false),
+    no_data_dependencies (false),
+    has_mask_store (false),
+    scalar_loop (NULL),
+    orig_loop_info (NULL)
 {
-  loop_vec_info res;
-  basic_block *bbs;
-  gimple_stmt_iterator si;
-  unsigned int i, nbbs;
-
-  res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
-  res->kind = vec_info::loop;
-  LOOP_VINFO_LOOP (res) = loop;
-
-  bbs = get_loop_body (loop);
-
   /* Create/Update stmt_info for all stmts in the loop.  */
-  for (i = 0; i < loop->num_nodes; i++)
+  basic_block *body = get_loop_body (loop);
+  for (unsigned int i = 0; i < loop->num_nodes; i++)
     {
-      basic_block bb = bbs[i];
+      basic_block bb = body[i];
+      gimple_stmt_iterator si;
 
       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
        {
          gimple *phi = gsi_stmt (si);
          gimple_set_uid (phi, 0);
-         set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, res));
+         set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, this));
        }
 
       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
        {
          gimple *stmt = gsi_stmt (si);
          gimple_set_uid (stmt, 0);
-         set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res));
+         set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, this));
        }
     }
+  free (body);
 
   /* CHECKME: We want to visit all BBs before their successors (except for
      latch blocks, for which this assertion wouldn't hold).  In the simple
      case of the loop forms we allow, a dfs order of the BBs would the same
      as reversed postorder traversal, so we are safe.  */
 
-   free (bbs);
-   bbs = XCNEWVEC (basic_block, loop->num_nodes);
-   nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
-                              bbs, loop->num_nodes, loop);
-   gcc_assert (nbbs == loop->num_nodes);
-
-  LOOP_VINFO_BBS (res) = bbs;
-  LOOP_VINFO_NITERSM1 (res) = NULL;
-  LOOP_VINFO_NITERS (res) = NULL;
-  LOOP_VINFO_NITERS_UNCHANGED (res) = NULL;
-  LOOP_VINFO_NITERS_ASSUMPTIONS (res) = NULL;
-  LOOP_VINFO_COST_MODEL_THRESHOLD (res) = 0;
-  LOOP_VINFO_VECTORIZABLE_P (res) = 0;
-  LOOP_VINFO_PEELING_FOR_ALIGNMENT (res) = 0;
-  LOOP_VINFO_VECT_FACTOR (res) = 0;
-  LOOP_VINFO_LOOP_NEST (res) = vNULL;
-  LOOP_VINFO_DATAREFS (res) = vNULL;
-  LOOP_VINFO_DDRS (res) = vNULL;
-  LOOP_VINFO_UNALIGNED_DR (res) = NULL;
-  LOOP_VINFO_MAY_MISALIGN_STMTS (res) = vNULL;
-  LOOP_VINFO_MAY_ALIAS_DDRS (res) = vNULL;
-  LOOP_VINFO_GROUPED_STORES (res) = vNULL;
-  LOOP_VINFO_REDUCTIONS (res) = vNULL;
-  LOOP_VINFO_REDUCTION_CHAINS (res) = vNULL;
-  LOOP_VINFO_SLP_INSTANCES (res) = vNULL;
-  LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
-  LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
-  LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
-  LOOP_VINFO_PEELING_FOR_NITER (res) = false;
-  LOOP_VINFO_OPERANDS_SWAPPED (res) = false;
-  LOOP_VINFO_ORIG_LOOP_INFO (res) = NULL;
-
-  return res;
+  unsigned int nbbs = dfs_enumerate_from (loop->header, 0, bb_in_loop_p,
+                                         bbs, loop->num_nodes, loop);
+  gcc_assert (nbbs == loop->num_nodes);
 }
 
 
-/* Function destroy_loop_vec_info.
-
-   Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the
-   stmts in the loop.  */
+/* Free all memory used by the _loop_vec_info, as well as all the
+   stmt_vec_info structs of all the stmts in the loop.  */
 
-void
-destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
+_loop_vec_info::~_loop_vec_info ()
 {
-  struct loop *loop;
-  basic_block *bbs;
   int nbbs;
   gimple_stmt_iterator si;
   int j;
-  vec<slp_instance> slp_instances;
-  slp_instance instance;
-  bool swapped;
-
-  if (!loop_vinfo)
-    return;
-
-  loop = LOOP_VINFO_LOOP (loop_vinfo);
-
-  bbs = LOOP_VINFO_BBS (loop_vinfo);
-  nbbs = clean_stmts ? loop->num_nodes : 0;
-  swapped = LOOP_VINFO_OPERANDS_SWAPPED (loop_vinfo);
 
+  nbbs = loop->num_nodes;
   for (j = 0; j < nbbs; j++)
     {
       basic_block bb = bbs[j];
@@ -1216,7 +1181,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
 
          /* We may have broken canonical form by moving a constant
             into RHS1 of a commutative op.  Fix such occurrences.  */
-         if (swapped && is_gimple_assign (stmt))
+         if (operands_swapped && is_gimple_assign (stmt))
            {
              enum tree_code code = gimple_assign_rhs_code (stmt);
 
@@ -1256,28 +1221,8 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
         }
     }
 
-  free (LOOP_VINFO_BBS (loop_vinfo));
-  vect_destroy_datarefs (loop_vinfo);
-  free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
-  LOOP_VINFO_LOOP_NEST (loop_vinfo).release ();
-  LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).release ();
-  LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo).release ();
-  LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo).release ();
-  slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
-  FOR_EACH_VEC_ELT (slp_instances, j, instance)
-    vect_free_slp_instance (instance);
-
-  LOOP_VINFO_SLP_INSTANCES (loop_vinfo).release ();
-  LOOP_VINFO_GROUPED_STORES (loop_vinfo).release ();
-  LOOP_VINFO_REDUCTIONS (loop_vinfo).release ();
-  LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).release ();
-
-  destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
-  loop_vinfo->scalar_cost_vec.release ();
-
-  LOOP_VINFO_CHECK_UNEQUAL_ADDRS (loop_vinfo).release ();
+  free (bbs);
 
-  free (loop_vinfo);
   loop->aux = NULL;
 }
 
@@ -1564,7 +1509,7 @@ vect_analyze_loop_form (struct loop *loop)
                                  &number_of_iterations, &inner_loop_cond))
     return NULL;
 
-  loop_vec_info loop_vinfo = new_loop_vec_info (loop);
+  loop_vec_info loop_vinfo = new _loop_vec_info (loop);
   LOOP_VINFO_NITERSM1 (loop_vinfo) = number_of_iterationsm1;
   LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
   LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = number_of_iterations;
@@ -2412,7 +2357,7 @@ vect_analyze_loop (struct loop *loop, loop_vec_info orig_loop_vinfo)
          return loop_vinfo;
        }
 
-      destroy_loop_vec_info (loop_vinfo, true);
+      delete loop_vinfo;
 
       vector_sizes &= ~current_vector_size;
       if (fatal
index 032a9444a5a92db284d4258c1ba13bb07d1e6f30..c713745b920ab886812c857b18b2fe11970cd552 100644 (file)
@@ -2378,62 +2378,37 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
 }
 
 
-/* Create and initialize a new bb_vec_info struct for BB, as well as
-   stmt_vec_info structs for all the stmts in it.  */
-
-static bb_vec_info
-new_bb_vec_info (gimple_stmt_iterator region_begin,
-                gimple_stmt_iterator region_end)
+/* Initialize a bb_vec_info struct for the statements between
+   REGION_BEGIN_IN (inclusive) and REGION_END_IN (exclusive).  */
+
+_bb_vec_info::_bb_vec_info (gimple_stmt_iterator region_begin_in,
+                           gimple_stmt_iterator region_end_in)
+  : vec_info (vec_info::bb, init_cost (NULL)),
+    bb (gsi_bb (region_begin_in)),
+    region_begin (region_begin_in),
+    region_end (region_end_in)
 {
-  basic_block bb = gsi_bb (region_begin);
-  bb_vec_info res = NULL;
   gimple_stmt_iterator gsi;
 
-  res = (bb_vec_info) xcalloc (1, sizeof (struct _bb_vec_info));
-  res->kind = vec_info::bb;
-  BB_VINFO_BB (res) = bb;
-  res->region_begin = region_begin;
-  res->region_end = region_end;
-
   for (gsi = region_begin; gsi_stmt (gsi) != gsi_stmt (region_end);
        gsi_next (&gsi))
     {
       gimple *stmt = gsi_stmt (gsi);
       gimple_set_uid (stmt, 0);
-      set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res));
+      set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, this));
     }
 
-  BB_VINFO_GROUPED_STORES (res).create (10);
-  BB_VINFO_SLP_INSTANCES (res).create (2);
-  BB_VINFO_TARGET_COST_DATA (res) = init_cost (NULL);
-
-  bb->aux = res;
-  return res;
+  bb->aux = this;
 }
 
 
 /* Free BB_VINFO struct, as well as all the stmt_vec_info structs of all the
    stmts in the basic block.  */
 
-static void
-destroy_bb_vec_info (bb_vec_info bb_vinfo)
+_bb_vec_info::~_bb_vec_info ()
 {
-  slp_instance instance;
-  unsigned i;
-
-  if (!bb_vinfo)
-    return;
-
-  vect_destroy_datarefs (bb_vinfo);
-  free_dependence_relations (BB_VINFO_DDRS (bb_vinfo));
-  BB_VINFO_GROUPED_STORES (bb_vinfo).release ();
-  FOR_EACH_VEC_ELT (BB_VINFO_SLP_INSTANCES (bb_vinfo), i, instance)
-    vect_free_slp_instance (instance);
-  BB_VINFO_SLP_INSTANCES (bb_vinfo).release ();
-  destroy_cost_data (BB_VINFO_TARGET_COST_DATA (bb_vinfo));
-
-  for (gimple_stmt_iterator si = bb_vinfo->region_begin;
-       gsi_stmt (si) != gsi_stmt (bb_vinfo->region_end); gsi_next (&si))
+  for (gimple_stmt_iterator si = region_begin;
+       gsi_stmt (si) != gsi_stmt (region_end); gsi_next (&si))
     {
       gimple *stmt = gsi_stmt (si);
       stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -2446,8 +2421,7 @@ destroy_bb_vec_info (bb_vec_info bb_vinfo)
       gimple_set_uid (stmt, -1);
     }
 
-  BB_VINFO_BB (bb_vinfo)->aux = NULL;
-  free (bb_vinfo);
+  bb->aux = NULL;
 }
 
 
@@ -2729,7 +2703,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
       return NULL;
     }
 
-  bb_vinfo = new_bb_vec_info (region_begin, region_end);
+  bb_vinfo = new _bb_vec_info (region_begin, region_end);
   if (!bb_vinfo)
     return NULL;
 
@@ -2744,7 +2718,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
                         "not vectorized: unhandled data-ref in basic "
                         "block.\n");
 
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2755,7 +2729,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
                         "not vectorized: not enough data-refs in "
                         "basic block.\n");
 
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2766,7 +2740,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
                        "not vectorized: unhandled data access in "
                        "basic block.\n");
 
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2780,7 +2754,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
                         "not vectorized: no grouped stores in "
                         "basic block.\n");
 
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2802,7 +2776,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
                           "in basic block.\n");
        }
 
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2832,7 +2806,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
     }
   if (! BB_VINFO_SLP_INSTANCES (bb_vinfo).length ())
     {
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2843,7 +2817,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
         dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
                         "not vectorized: bad operation in basic block.\n");
 
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2856,7 +2830,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
                         "not vectorized: vectorization is not "
                         "profitable.\n");
 
-      destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
       return NULL;
     }
 
@@ -2936,12 +2910,9 @@ vect_slp_bb (basic_block bb)
            dump_printf_loc (MSG_NOTE, vect_location,
                             "basic block part vectorized\n");
 
-         destroy_bb_vec_info (bb_vinfo);
-
          vectorized = true;
        }
-      else
-       destroy_bb_vec_info (bb_vinfo);
+      delete bb_vinfo;
 
       any_vectorized |= vectorized;
 
index 33a1f580474cb93ccc4f2f43631bf7a90623c2ad..129129f6b68dbaaba9227c3d86edfabe98ac3800 100644 (file)
@@ -354,22 +354,36 @@ shrink_simd_arrays
   delete simd_array_to_simduid_htab;
 }
 \f
-/* A helper function to free data refs.  */
+/* Initialize the vec_info with kind KIND_IN and target cost data
+   TARGET_COST_DATA_IN.  */
+
+vec_info::vec_info (vec_info::vec_kind kind_in, void *target_cost_data_in)
+  : kind (kind_in),
+    datarefs (vNULL),
+    ddrs (vNULL),
+    target_cost_data (target_cost_data_in)
+{
+}
 
-void
-vect_destroy_datarefs (vec_info *vinfo)
+vec_info::~vec_info ()
 {
+  slp_instance instance;
   struct data_reference *dr;
   unsigned int i;
 
-  FOR_EACH_VEC_ELT (vinfo->datarefs, i, dr)
+  FOR_EACH_VEC_ELT (datarefs, i, dr)
     if (dr->aux)
       {
         free (dr->aux);
         dr->aux = NULL;
       }
 
-  free_data_refs (vinfo->datarefs);
+  FOR_EACH_VEC_ELT (slp_instances, i, instance)
+    vect_free_slp_instance (instance);
+
+  free_data_refs (datarefs);
+  free_dependence_relations (ddrs);
+  destroy_cost_data (target_cost_data);
 }
 
 /* A helper function to free scev and LOOP niter information, as well as
@@ -830,7 +844,7 @@ vectorize_loops (void)
       has_mask_store = false;
       if (loop_vinfo)
        has_mask_store = LOOP_VINFO_HAS_MASK_STORE (loop_vinfo);
-      destroy_loop_vec_info (loop_vinfo, true);
+      delete loop_vinfo;
       if (has_mask_store)
        optimize_mask_stores (loop);
       loop->aux = NULL;
index 01c416c7cbfd1e977e5c9e6fe29228a2095ac090..e8acf6687b79c4ab0dafc501b86618d51fff280b 100644 (file)
@@ -155,20 +155,27 @@ typedef std::pair<tree, tree> vec_object_pair;
 
 /* Vectorizer state common between loop and basic-block vectorization.  */
 struct vec_info {
-  enum { bb, loop } kind;
+  enum vec_kind { bb, loop };
+
+  vec_info (vec_kind, void *);
+  ~vec_info ();
+
+  /* The type of vectorization.  */
+  vec_kind kind;
 
   /* All SLP instances.  */
-  vec<slp_instance> slp_instances;
+  auto_vec<slp_instance> slp_instances;
 
-  /* All data references.  */
+  /* All data references.  Freed by free_data_refs, so not an auto_vec.  */
   vec<data_reference_p> datarefs;
 
-  /* All data dependences.  */
+  /* All data dependences.  Freed by free_dependence_relations, so not
+     an auto_vec.  */
   vec<ddr_p> ddrs;
 
   /* All interleaving chains of stores, represented by the first
      stmt in the chain.  */
-  vec<gimple *> grouped_stores;
+  auto_vec<gimple *> grouped_stores;
 
   /* Cost data used by the target cost model.  */
   void *target_cost_data;
@@ -198,6 +205,8 @@ is_a_helper <_bb_vec_info *>::test (vec_info *i)
 /* Info on vectorized loops.                                       */
 /*-----------------------------------------------------------------*/
 typedef struct _loop_vec_info : public vec_info {
+  _loop_vec_info (struct loop *);
+  ~_loop_vec_info ();
 
   /* The loop to which this info struct refers to.  */
   struct loop *loop;
@@ -239,32 +248,32 @@ typedef struct _loop_vec_info : public vec_info {
   int ptr_mask;
 
   /* The loop nest in which the data dependences are computed.  */
-  vec<loop_p> loop_nest;
+  auto_vec<loop_p> loop_nest;
 
   /* Data Dependence Relations defining address ranges that are candidates
      for a run-time aliasing check.  */
-  vec<ddr_p> may_alias_ddrs;
+  auto_vec<ddr_p> may_alias_ddrs;
 
   /* Data Dependence Relations defining address ranges together with segment
      lengths from which the run-time aliasing check is built.  */
-  vec<dr_with_seg_len_pair_t> comp_alias_ddrs;
+  auto_vec<dr_with_seg_len_pair_t> comp_alias_ddrs;
 
   /* Check that the addresses of each pair of objects is unequal.  */
-  vec<vec_object_pair> check_unequal_addrs;
+  auto_vec<vec_object_pair> check_unequal_addrs;
 
   /* Statements in the loop that have data references that are candidates for a
      runtime (loop versioning) misalignment check.  */
-  vec<gimple *> may_misalign_stmts;
+  auto_vec<gimple *> may_misalign_stmts;
 
   /* Reduction cycles detected in the loop. Used in loop-aware SLP.  */
-  vec<gimple *> reductions;
+  auto_vec<gimple *> reductions;
 
   /* All reduction chains in the loop, represented by the first
      stmt in the chain.  */
-  vec<gimple *> reduction_chains;
+  auto_vec<gimple *> reduction_chains;
 
   /* Cost vector for a single scalar iteration.  */
-  vec<stmt_info_for_cost> scalar_cost_vec;
+  auto_vec<stmt_info_for_cost> scalar_cost_vec;
 
   /* The unrolling factor needed to SLP the loop. In case of that pure SLP is
      applied to the loop, i.e., no unrolling is needed, this is 1.  */
@@ -399,6 +408,9 @@ nested_in_vect_loop_p (struct loop *loop, gimple *stmt)
 
 typedef struct _bb_vec_info : public vec_info
 {
+  _bb_vec_info (gimple_stmt_iterator, gimple_stmt_iterator);
+  ~_bb_vec_info ();
+
   basic_block bb;
   gimple_stmt_iterator region_begin;
   gimple_stmt_iterator region_end;
@@ -802,8 +814,8 @@ void free_stmt_vec_info_vec (void);
 static inline stmt_vec_info
 vinfo_for_stmt (gimple *stmt)
 {
-  unsigned int uid = gimple_uid (stmt);
-  if (uid == 0)
+  int uid = gimple_uid (stmt);
+  if (uid <= 0)
     return NULL;
 
   return stmt_vec_info_vec[uid - 1];
@@ -1177,7 +1189,6 @@ extern tree vect_create_addr_base_for_vector_ref (gimple *, gimple_seq *,
 
 /* In tree-vect-loop.c.  */
 /* FORNOW: Used in tree-parloops.c.  */
-extern void destroy_loop_vec_info (loop_vec_info, bool);
 extern gimple *vect_force_simple_reduction (loop_vec_info, gimple *,
                                            bool *, bool);
 /* Drive for loop analysis stage.  */
@@ -1226,7 +1237,6 @@ void vect_pattern_recog (vec_info *);
 
 /* In tree-vectorizer.c.  */
 unsigned vectorize_loops (void);
-void vect_destroy_datarefs (vec_info *);
 bool vect_stmt_in_region_p (vec_info *, gimple *);
 void vect_free_loop_info_assumptions (struct loop *);