add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
authorRichard Biener <rguenther@suse.de>
Thu, 6 Aug 2020 12:50:56 +0000 (14:50 +0200)
committerRichard Biener <rguenther@suse.de>
Thu, 24 Sep 2020 13:59:19 +0000 (15:59 +0200)
This adds a move CTOR to auto_vec<T, 0> and makes use of a
auto_vec<edge> return value for get_loop_exit_edges denoting
that lifetime management of the vector is handed to the caller.

The move CTOR prompted the hash_table change because it appearantly
makes the copy CTOR implicitely deleted (good) and hash-table
expansion of the odr_enum_map which is
hash_map <nofree_string_hash, odr_enum> where odr_enum has an
auto_vec<odr_enum_val, 0> member triggers this.  Not sure if
there's a latent bug there before this (I think we're not
invoking DTORs, but we're invoking copy-CTORs).

2020-08-06  Richard Biener  <rguenther@suse.de>

* vec.h (auto_vec<T, 0>::auto_vec (auto_vec &&)): New move CTOR.
(auto_vec<T, 0>::operator=(auto_vec &&)): Delete.
* hash-table.h (hash_table::expand): Use std::move when expanding.
* cfgloop.h (get_loop_exit_edges): Return auto_vec<edge>.
* cfgloop.c (get_loop_exit_edges): Adjust.
* cfgloopmanip.c (fix_loop_placement): Likewise.
* ipa-fnsummary.c (analyze_function_body): Likewise.
* ira-build.c (create_loop_tree_nodes): Likewise.
(create_loop_tree_node_allocnos): Likewise.
(loop_with_complex_edge_p): Likewise.
* ira-color.c (ira_loop_edge_freq): Likewise.
* loop-unroll.c (analyze_insns_in_loop): Likewise.
* predict.c (predict_loops): Likewise.
* tree-predcom.c (last_always_executed_block): Likewise.
* tree-ssa-loop-ch.c (ch_base::copy_headers): Likewise.
* tree-ssa-loop-im.c (store_motion_loop): Likewise.
* tree-ssa-loop-ivcanon.c (loop_edge_to_cancel): Likewise.
(canonicalize_loop_induction_variables): Likewise.
* tree-ssa-loop-manip.c (get_loops_exits): Likewise.
* tree-ssa-loop-niter.c (find_loop_niter): Likewise.
(finite_loop_p): Likewise.
(find_loop_niter_by_eval): Likewise.
(estimate_numbers_of_iterations): Likewise.
* tree-ssa-loop-prefetch.c (emit_mfence_after_loop): Likewise.
(may_use_storent_in_loop_p): Likewise.

17 files changed:
gcc/cfgloop.c
gcc/cfgloop.h
gcc/cfgloopmanip.c
gcc/hash-table.h
gcc/ipa-fnsummary.c
gcc/ira-build.c
gcc/ira-color.c
gcc/loop-unroll.c
gcc/predict.c
gcc/tree-predcom.c
gcc/tree-ssa-loop-ch.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-ivcanon.c
gcc/tree-ssa-loop-manip.c
gcc/tree-ssa-loop-niter.c
gcc/tree-ssa-loop-prefetch.c
gcc/vec.h

index 7720e6e5d2c68c53bdb5a50b3583b369126458ee..33a26cca6a44096502db1a4b8fb6ac34915fd733 100644 (file)
@@ -1202,10 +1202,10 @@ release_recorded_exits (function *fn)
 
 /* Returns the list of the exit edges of a LOOP.  */
 
-vec<edge> 
+auto_vec<edge>
 get_loop_exit_edges (const class loop *loop, basic_block *body)
 {
-  vec<edge> edges = vNULL;
+  auto_vec<edge> edges;
   edge e;
   unsigned i;
   edge_iterator ei;
index be978288aabfcd7a70dfc6aeaa0594ebb750a9d2..d14689dc31fcd9922c39ed75c5118c6cf9e9b06d 100644 (file)
@@ -383,7 +383,7 @@ extern basic_block *get_loop_body_in_custom_order (const class loop *,
 extern basic_block *get_loop_body_in_custom_order (const class loop *, void *,
                               int (*) (const void *, const void *, void *));
 
-extern vec<edge> get_loop_exit_edges (const class loop *, basic_block * = NULL);
+extern auto_vec<edge> get_loop_exit_edges (const class loop *, basic_block * = NULL);
 extern edge single_exit (const class loop *);
 extern edge single_likely_exit (class loop *loop, vec<edge>);
 extern unsigned num_loop_branches (const class loop *);
index 73134a20e3376b5d41ceb2820fb4827d3a9d5fac..3c9e2a0a99c266da61531a9be561da69877ca174 100644 (file)
@@ -126,7 +126,7 @@ fix_loop_placement (class loop *loop, bool *irred_invalidated)
 {
   unsigned i;
   edge e;
-  vec<edge> exits = get_loop_exit_edges (loop);
+  auto_vec<edge> exits = get_loop_exit_edges (loop);
   class loop *father = current_loops->tree_root, *act;
   bool ret = false;
 
@@ -157,7 +157,6 @@ fix_loop_placement (class loop *loop, bool *irred_invalidated)
       ret = true;
     }
 
-  exits.release ();
   return ret;
 }
 
index 32f3a634e1ed7bef91741cdc7327b383516fa0db..487003c3acf5c7c12162f3c9dfb50c0443306382 100644 (file)
@@ -819,7 +819,7 @@ hash_table<Descriptor, Lazy, Allocator>::expand ()
       if (!is_empty (x) && !is_deleted (x))
         {
           value_type *q = find_empty_slot_for_expand (Descriptor::hash (x));
-         new ((void*) q) value_type (x);
+         new ((void*) q) value_type (std::move (x));
         }
 
       p++;
index bb703f62206a92d96e26514771c1f2b12a36f75b..cbcf0c4c95c8cafaf0548e6575e33e7be2b39a6e 100644 (file)
@@ -2808,7 +2808,6 @@ analyze_function_body (struct cgraph_node *node, bool early)
       scev_initialize ();
       FOR_EACH_LOOP (loop, 0)
        {
-         vec<edge> exits;
          edge ex;
          unsigned int j;
          class tree_niter_desc niter_desc;
@@ -2817,7 +2816,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
          else
            bb_predicate = false;
 
-         exits = get_loop_exit_edges (loop);
+         auto_vec<edge> exits = get_loop_exit_edges (loop);
          FOR_EACH_VEC_ELT (exits, j, ex)
            if (number_of_iterations_exit (loop, ex, &niter_desc, false)
                && !is_gimple_min_invariant (niter_desc.niter))
@@ -2835,7 +2834,6 @@ analyze_function_body (struct cgraph_node *node, bool early)
                   loop with independent predicate.  */
                loop_iterations &= will_be_nonconstant;
            }
-         exits.release ();
        }
 
       /* To avoid quadratic behavior we analyze stride predicates only
index 0bbdb4d0c4b93fe55c9b2c6f1636074210ec21d3..9b35d0e83a967a2a38e9f65498690973876a7c88 100644 (file)
@@ -128,7 +128,6 @@ create_loop_tree_nodes (void)
   bool skip_p;
   edge_iterator ei;
   edge e;
-  vec<edge> edges;
   loop_p loop;
 
   ira_bb_nodes
@@ -173,14 +172,13 @@ create_loop_tree_nodes (void)
              }
          if (skip_p)
            continue;
-         edges = get_loop_exit_edges (loop);
+         auto_vec<edge> edges = get_loop_exit_edges (loop);
          FOR_EACH_VEC_ELT (edges, j, e)
            if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
              {
                skip_p = true;
                break;
              }
-         edges.release ();
          if (skip_p)
            continue;
        }
@@ -1964,17 +1962,15 @@ create_loop_tree_node_allocnos (ira_loop_tree_node_t loop_node)
       int i;
       edge_iterator ei;
       edge e;
-      vec<edge> edges;
 
       ira_assert (current_loops != NULL);
       FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
        if (e->src != loop_node->loop->latch)
          create_loop_allocnos (e);
 
-      edges = get_loop_exit_edges (loop_node->loop);
+      auto_vec<edge> edges = get_loop_exit_edges (loop_node->loop);
       FOR_EACH_VEC_ELT (edges, i, e)
        create_loop_allocnos (e);
-      edges.release ();
     }
 }
 
@@ -2167,13 +2163,12 @@ loop_with_complex_edge_p (class loop *loop)
   int i;
   edge_iterator ei;
   edge e;
-  vec<edge> edges;
   bool res;
 
   FOR_EACH_EDGE (e, ei, loop->header->preds)
     if (e->flags & EDGE_EH)
       return true;
-  edges = get_loop_exit_edges (loop);
+  auto_vec<edge> edges = get_loop_exit_edges (loop);
   res = false;
   FOR_EACH_VEC_ELT (edges, i, e)
     if (e->flags & EDGE_COMPLEX)
@@ -2181,7 +2176,6 @@ loop_with_complex_edge_p (class loop *loop)
        res = true;
        break;
       }
-  edges.release ();
   return res;
 }
 #endif
index dbb3b7a2a519bf1d9ae7630d93c127708bf7129c..d3f8e23faff61cab63a3ccb56f0cd464793ba3c4 100644 (file)
@@ -2539,7 +2539,6 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
   int freq, i;
   edge_iterator ei;
   edge e;
-  vec<edge> edges;
 
   ira_assert (current_loops != NULL && loop_node->loop != NULL
              && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
@@ -2555,13 +2554,12 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
     }
   else
     {
-      edges = get_loop_exit_edges (loop_node->loop);
+      auto_vec<edge> edges = get_loop_exit_edges (loop_node->loop);
       FOR_EACH_VEC_ELT (edges, i, e)
        if (regno < 0
            || (bitmap_bit_p (df_get_live_out (e->src), regno)
                && bitmap_bit_p (df_get_live_in (e->dest), regno)))
          freq += EDGE_FREQUENCY (e);
-      edges.release ();
     }
 
   return REG_FREQ_FROM_EDGE_FREQ (freq);
index 693c77688688f2e2c5daba0af5abd79c5671ce52..e1efe6243610aebb886642569dfcae70fe4db110 100644 (file)
@@ -1580,7 +1580,7 @@ analyze_insns_in_loop (class loop *loop)
   struct var_to_expand *ves = NULL;
   iv_to_split **slot1;
   var_to_expand **slot2;
-  vec<edge> edges = get_loop_exit_edges (loop);
+  auto_vec<edge> edges = get_loop_exit_edges (loop);
   edge exit;
   bool can_apply = false;
 
@@ -1656,7 +1656,6 @@ analyze_insns_in_loop (class loop *loop)
       }
     }
 
-  edges.release ();
   free (body);
   return opt_info;
 }
index 3c7b46f4c747deb5b2a2eddae062a8f331fb8edf..5983889209ffb8e0c6b35e09f4f45ce2c01d055e 100644 (file)
@@ -1916,7 +1916,6 @@ predict_loops (void)
     {
       basic_block bb, *bbs;
       unsigned j, n_exits = 0;
-      vec<edge> exits;
       class tree_niter_desc niter_desc;
       edge ex;
       class nb_iter_bound *nb_iter;
@@ -1927,15 +1926,12 @@ predict_loops (void)
       gcond *stmt = NULL;
       bool recursion = with_recursion.contains (loop);
 
-      exits = get_loop_exit_edges (loop);
+      auto_vec<edge> exits = get_loop_exit_edges (loop);
       FOR_EACH_VEC_ELT (exits, j, ex)
        if (!unlikely_executed_edge_p (ex) && !(ex->flags & EDGE_ABNORMAL_CALL))
          n_exits ++;
       if (!n_exits)
-       {
-          exits.release ();
-         continue;
-       }
+       continue;
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        fprintf (dump_file, "Predicting loop %i%s with %i exits.\n",
@@ -2049,7 +2045,6 @@ predict_loops (void)
          probability = RDIV (REG_BR_PROB_BASE, nitercst);
          predict_edge (ex, predictor, probability);
        }
-      exits.release ();
 
       /* Find information about loop bound variables.  */
       for (nb_iter = loop->bounds; nb_iter;
index b1d6e63559c732d2f518ff6ef008cf3ebb11c1b2..7a5990ac609affe8260dd98ee3ad2284faeca8dd 100644 (file)
@@ -737,13 +737,12 @@ static basic_block
 last_always_executed_block (class loop *loop)
 {
   unsigned i;
-  vec<edge> exits = get_loop_exit_edges (loop);
+  auto_vec<edge> exits = get_loop_exit_edges (loop);
   edge ex;
   basic_block last = loop->latch;
 
   FOR_EACH_VEC_ELT (exits, i, ex)
     last = nearest_common_dominator (CDI_DOMINATORS, last, ex->src);
-  exits.release ();
 
   return last;
 }
index b9002d8e294dc0a39fdc60985e60d031e312795f..b86acf7c39dd660b92c1850349b71e70cd63d043 100644 (file)
@@ -504,14 +504,13 @@ ch_base::copy_headers (function *fun)
        {
          edge entry = copied[i].first;
          loop_p loop = copied[i].second;
-         vec<edge> exit_edges = get_loop_exit_edges (loop);
+         auto_vec<edge> exit_edges = get_loop_exit_edges (loop);
          bitmap exit_bbs = BITMAP_ALLOC (NULL);
          for (unsigned j = 0; j < exit_edges.length (); ++j)
            bitmap_set_bit (exit_bbs, exit_edges[j]->dest->index);
          bitmap_set_bit (exit_bbs, loop->header->index);
          do_rpo_vn (cfun, entry, exit_bbs);
          BITMAP_FREE (exit_bbs);
-         exit_edges.release ();
        }
     }
   free (bbs);
index 139c7e76e6626cb8a9d242d63ecec0a4b3d6dba8..6bb07e133cdb316adc09f17d0d5a4b9e1b7adc41 100644 (file)
@@ -2868,7 +2868,7 @@ loop_suitable_for_sm (class loop *loop ATTRIBUTE_UNUSED,
 static void
 store_motion_loop (class loop *loop, bitmap sm_executed)
 {
-  vec<edge> exits = get_loop_exit_edges (loop);
+  auto_vec<edge> exits = get_loop_exit_edges (loop);
   class loop *subloop;
   bitmap sm_in_loop = BITMAP_ALLOC (&lim_bitmap_obstack);
 
@@ -2878,7 +2878,6 @@ store_motion_loop (class loop *loop, bitmap sm_executed)
       if (!bitmap_empty_p (sm_in_loop))
        hoist_memory_references (loop, sm_in_loop, exits);
     }
-  exits.release ();
 
   bitmap_ior_into (sm_executed, sm_in_loop);
   for (subloop = loop->inner; subloop != NULL; subloop = subloop->next)
index 298ab2155301b08710d0be67ac63699e1748000d..5bb781dc7fadb0fa4e0ccd419ef2f31ba2f5623a 100644 (file)
@@ -444,7 +444,6 @@ estimated_unrolled_size (struct loop_size *size,
 static edge
 loop_edge_to_cancel (class loop *loop)
 {
-  vec<edge> exits;
   unsigned i;
   edge edge_to_cancel;
   gimple_stmt_iterator gsi;
@@ -453,7 +452,7 @@ loop_edge_to_cancel (class loop *loop)
   if (EDGE_COUNT (loop->latch->preds) > 1)
     return NULL;
 
-  exits = get_loop_exit_edges (loop);
+  auto_vec<edge> exits = get_loop_exit_edges (loop);
 
   FOR_EACH_VEC_ELT (exits, i, edge_to_cancel)
     {
@@ -477,8 +476,6 @@ loop_edge_to_cancel (class loop *loop)
       if (edge_to_cancel->dest != loop->latch)
         continue;
 
-      exits.release ();
-
       /* Verify that the code in loop latch does nothing that may end program
          execution without really reaching the exit.  This may include
         non-pure/const function calls, EH statements, volatile ASMs etc.  */
@@ -487,7 +484,6 @@ loop_edge_to_cancel (class loop *loop)
           return NULL;
       return edge_to_cancel;
     }
-  exits.release ();
   return NULL;
 }
 
@@ -1222,10 +1218,9 @@ canonicalize_loop_induction_variables (class loop *loop,
      by find_loop_niter_by_eval.  Be sure to keep it for future.  */
   if (niter && TREE_CODE (niter) == INTEGER_CST)
     {
-      vec<edge> exits = get_loop_exit_edges  (loop);
+      auto_vec<edge> exits = get_loop_exit_edges  (loop);
       record_niter_bound (loop, wi::to_widest (niter),
                          exit == single_likely_exit (loop, exits), true);
-      exits.release ();
     }
 
   /* Force re-computation of loop bounds so we can remove redundant exits.  */
index a2717a411a32184f5a609d8aff3b7e83711a7f3e..cdd1ac7683321a3e38a43fc9eb59779a205ab9fa 100644 (file)
@@ -368,11 +368,10 @@ get_loops_exits (bitmap *loop_exits)
 
   FOR_EACH_LOOP (loop, 0)
     {
-      vec<edge> exit_edges = get_loop_exit_edges (loop);
+      auto_vec<edge> exit_edges = get_loop_exit_edges (loop);
       loop_exits[loop->num] = BITMAP_ALLOC (&loop_renamer_obstack);
       FOR_EACH_VEC_ELT (exit_edges, j, e)
         bitmap_set_bit (loop_exits[loop->num], e->dest->index);
-      exit_edges.release ();
     }
 }
 
index b3647d9efcac0b30a5d5b424fdc93095c27f73a9..45747e150f43c346d62ff894a35bd31998ab88f0 100644 (file)
@@ -2752,7 +2752,7 @@ tree
 find_loop_niter (class loop *loop, edge *exit)
 {
   unsigned i;
-  vec<edge> exits = get_loop_exit_edges (loop);
+  auto_vec<edge> exits = get_loop_exit_edges (loop);
   edge ex;
   tree niter = NULL_TREE, aniter;
   class tree_niter_desc desc;
@@ -2803,7 +2803,6 @@ find_loop_niter (class loop *loop, edge *exit)
          continue;
        }
     }
-  exits.release ();
 
   return niter ? niter : chrec_dont_know;
 }
@@ -2837,21 +2836,18 @@ finite_loop_p (class loop *loop)
   if (loop->finite_p)
     {
       unsigned i;
-      vec<edge> exits = get_loop_exit_edges (loop);
+      auto_vec<edge> exits = get_loop_exit_edges (loop);
       edge ex;
 
       /* If the loop has a normal exit, we can assume it will terminate.  */
       FOR_EACH_VEC_ELT (exits, i, ex)
        if (!(ex->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_FAKE)))
          {
-           exits.release ();
            if (dump_file)
              fprintf (dump_file, "Assume loop %i to be finite: it has an exit "
                       "and -ffinite-loops is on.\n", loop->num);
            return true;
          }
-
-      exits.release ();
     }
 
   return false;
@@ -3114,7 +3110,7 @@ tree
 find_loop_niter_by_eval (class loop *loop, edge *exit)
 {
   unsigned i;
-  vec<edge> exits = get_loop_exit_edges (loop);
+  auto_vec<edge> exits = get_loop_exit_edges (loop);
   edge ex;
   tree niter = NULL_TREE, aniter;
 
@@ -3123,10 +3119,7 @@ find_loop_niter_by_eval (class loop *loop, edge *exit)
   /* Loops with multiple exits are expensive to handle and less important.  */
   if (!flag_expensive_optimizations
       && exits.length () > 1)
-    {
-      exits.release ();
-      return chrec_dont_know;
-    }
+    return chrec_dont_know;
 
   FOR_EACH_VEC_ELT (exits, i, ex)
     {
@@ -3144,7 +3137,6 @@ find_loop_niter_by_eval (class loop *loop, edge *exit)
       niter = aniter;
       *exit = ex;
     }
-  exits.release ();
 
   return niter ? niter : chrec_dont_know;
 }
@@ -4236,7 +4228,6 @@ get_upper_bound_based_on_builtin_expr_with_prob (gcond *cond)
 void
 estimate_numbers_of_iterations (class loop *loop)
 {
-  vec<edge> exits;
   tree niter, type;
   unsigned i;
   class tree_niter_desc niter_desc;
@@ -4275,7 +4266,7 @@ estimate_numbers_of_iterations (class loop *loop)
   number_of_latch_executions (loop);
 
   basic_block *body = get_loop_body (loop);
-  exits = get_loop_exit_edges (loop, body);
+  auto_vec<edge> exits = get_loop_exit_edges (loop, body);
   likely_exit = single_likely_exit (loop, exits);
   FOR_EACH_VEC_ELT (exits, i, ex)
     {
@@ -4311,7 +4302,6 @@ estimate_numbers_of_iterations (class loop *loop)
                       true, ex == likely_exit, true);
       record_control_iv (loop, &niter_desc);
     }
-  exits.release ();
 
   if (flag_aggressive_loop_optimizations)
     infer_loop_bounds_from_undefined (loop, body);
index d19ece6410d395cdf869e3e4fcb096d68d8017c1..5e94a19c964b197d207d7a34642a04959d2ab230 100644 (file)
@@ -1289,7 +1289,7 @@ mark_nontemporal_store (struct mem_ref *ref)
 static void
 emit_mfence_after_loop (class loop *loop)
 {
-  vec<edge> exits = get_loop_exit_edges (loop);
+  auto_vec<edge> exits = get_loop_exit_edges (loop);
   edge exit;
   gcall *call;
   gimple_stmt_iterator bsi;
@@ -1309,7 +1309,6 @@ emit_mfence_after_loop (class loop *loop)
       gsi_insert_before (&bsi, call, GSI_NEW_STMT);
     }
 
-  exits.release ();
   update_ssa (TODO_update_ssa_only_virtuals);
 }
 
@@ -1327,7 +1326,7 @@ may_use_storent_in_loop_p (class loop *loop)
      is a suitable place for it at each of the loop exits.  */
   if (FENCE_FOLLOWING_MOVNT != NULL_TREE)
     {
-      vec<edge> exits = get_loop_exit_edges (loop);
+      auto_vec<edge> exits = get_loop_exit_edges (loop);
       unsigned i;
       edge exit;
 
@@ -1335,8 +1334,6 @@ may_use_storent_in_loop_p (class loop *loop)
        if ((exit->flags & EDGE_ABNORMAL)
            && exit->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
          ret = false;
-
-      exits.release ();
     }
 
   return ret;
index 48e756ebdf34843973feb944df59e62e898dc920..d73d865cff264ff5b70a0d2dd389c74e4c426be8 100644 (file)
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1540,6 +1540,13 @@ public:
   auto_vec () { this->m_vec = NULL; }
   auto_vec (size_t n) { this->create (n); }
   ~auto_vec () { this->release (); }
+
+  auto_vec (auto_vec&& r)
+    {
+      this->m_vec = r.m_vec;
+      r.m_vec = NULL;
+    }
+  void operator= (auto_vec&&) = delete;
 };