* [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
@ 2020-08-06 12:58 Richard Biener
2020-08-06 14:15 ` Richard Biener
0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2020-08-06 12:58 UTC (permalink / raw)
To: gcc-patches; +Cc: jwakely
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).
Bootstrap / regtest running on x86_64-unknown-linux-gnu.
Does this all look sensible and is it a good change
(the get_loop_exit_edges one)?
Thanks,
Richard.
2020-08-06 Richard Biener <rguenther@suse.de>
* vec.h (auto_vec<T, 0>::auto_vec<T, 0> (auto_vec<T, 0> &&):
New move CTOR.
* hash-table.h (): Use std::move when expanding.
* cfgloop.h (get_loop_exit_edges): Return auto_vec<edge>.
* cfgloop.c (get_loop_exit_edges): Adjust.
---
gcc/cfgloop.c | 4 ++--
gcc/cfgloop.h | 2 +-
gcc/cfgloopmanip.c | 3 +--
gcc/hash-table.h | 2 +-
gcc/ipa-fnsummary.c | 4 +---
gcc/ira-build.c | 12 +++---------
gcc/ira-color.c | 4 +---
gcc/loop-unroll.c | 3 +--
gcc/predict.c | 9 ++-------
gcc/tree-predcom.c | 3 +--
gcc/tree-ssa-loop-ch.c | 3 +--
gcc/tree-ssa-loop-im.c | 3 +--
gcc/tree-ssa-loop-ivcanon.c | 9 ++-------
gcc/tree-ssa-loop-manip.c | 3 +--
gcc/tree-ssa-loop-niter.c | 20 +++++---------------
gcc/tree-ssa-loop-prefetch.c | 7 ++-----
gcc/vec.h | 6 ++++++
17 files changed, 32 insertions(+), 65 deletions(-)
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 7720e6e5d2c..33a26cca6a4 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -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;
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 18b404e292f..f1687f37401 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -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 *);
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 73134a20e33..3c9e2a0a99c 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -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;
}
diff --git a/gcc/hash-table.h b/gcc/hash-table.h
index 32f3a634e1e..487003c3acf 100644
--- a/gcc/hash-table.h
+++ b/gcc/hash-table.h
@@ -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++;
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 59e52927151..f750ec1725c 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -2767,7 +2767,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;
@@ -2776,7 +2775,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))
@@ -2794,7 +2793,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
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 0bbdb4d0c4b..9b35d0e83a9 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -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
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index dbb3b7a2a51..d3f8e23faff 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -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);
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 693c7768868..e1efe624361 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -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;
}
diff --git a/gcc/predict.c b/gcc/predict.c
index 0a317a7a4ac..a847b9b4045 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1915,7 +1915,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;
@@ -1926,15 +1925,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",
@@ -2048,7 +2044,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;
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index d2dcfe7f42d..93e6da1e2ab 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -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;
}
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index b9002d8e294..b86acf7c39d 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -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);
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 35da1fb26a6..8b7eb57514f 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -2866,7 +2866,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);
@@ -2876,7 +2876,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)
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 298ab215530..5bb781dc7fa 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -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. */
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index a2717a411a3..cdd1ac76833 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -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 ();
}
}
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 7d61ef080eb..8bb29c2470f 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -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);
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index d19ece6410d..5e94a19c964 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -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;
diff --git a/gcc/vec.h b/gcc/vec.h
index 3ad99b83690..38478bffc6b 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1533,6 +1533,12 @@ 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;
+ }
};
--
2.26.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
2020-08-06 12:58 [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges Richard Biener
@ 2020-08-06 14:15 ` Richard Biener
2020-08-26 12:33 ` Richard Biener
0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2020-08-06 14:15 UTC (permalink / raw)
To: gcc-patches; +Cc: jwakely, Jakub Jelinek
On Thu, 6 Aug 2020, Richard Biener wrote:
> 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).
>
> Bootstrap / regtest running on x86_64-unknown-linux-gnu.
>
> Does this all look sensible and is it a good change
> (the get_loop_exit_edges one)?
Regtest went OK, here's an update with a complete ChangeLog
(how useful..) plus the move assign operator deleted, copy
assign wouldn't work as auto-generated and at the moment
there's no use of assigning. I guess if we'd have functions
that take an auto_vec<> argument meaning they will destroy
the vector that will become useful and we can implement it.
OK for trunk?
Thanks,
Richard.
From d74c346e95ff967d930b7c83daabc26b0227aea3 Mon Sep 17 00:00:00 2001
From: Richard Biener <rguenther@suse.de>
Date: Thu, 6 Aug 2020 14:50:56 +0200
Subject: [PATCH] add move CTOR to auto_vec, use auto_vec for
get_loop_exit_edges
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.
---
gcc/cfgloop.c | 4 ++--
gcc/cfgloop.h | 2 +-
gcc/cfgloopmanip.c | 3 +--
gcc/hash-table.h | 2 +-
gcc/ipa-fnsummary.c | 4 +---
gcc/ira-build.c | 12 +++---------
gcc/ira-color.c | 4 +---
gcc/loop-unroll.c | 3 +--
gcc/predict.c | 9 ++-------
gcc/tree-predcom.c | 3 +--
gcc/tree-ssa-loop-ch.c | 3 +--
gcc/tree-ssa-loop-im.c | 3 +--
gcc/tree-ssa-loop-ivcanon.c | 9 ++-------
gcc/tree-ssa-loop-manip.c | 3 +--
gcc/tree-ssa-loop-niter.c | 20 +++++---------------
gcc/tree-ssa-loop-prefetch.c | 7 ++-----
gcc/vec.h | 7 +++++++
17 files changed, 33 insertions(+), 65 deletions(-)
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 7720e6e5d2c..33a26cca6a4 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -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;
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 18b404e292f..f1687f37401 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -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 *);
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index 73134a20e33..3c9e2a0a99c 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -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;
}
diff --git a/gcc/hash-table.h b/gcc/hash-table.h
index 32f3a634e1e..487003c3acf 100644
--- a/gcc/hash-table.h
+++ b/gcc/hash-table.h
@@ -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++;
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 59e52927151..f750ec1725c 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -2767,7 +2767,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;
@@ -2776,7 +2775,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))
@@ -2794,7 +2793,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
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 0bbdb4d0c4b..9b35d0e83a9 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -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
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index dbb3b7a2a51..d3f8e23faff 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -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);
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 693c7768868..e1efe624361 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -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;
}
diff --git a/gcc/predict.c b/gcc/predict.c
index 0a317a7a4ac..a847b9b4045 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1915,7 +1915,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;
@@ -1926,15 +1925,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",
@@ -2048,7 +2044,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;
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index d2dcfe7f42d..93e6da1e2ab 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -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;
}
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index b9002d8e294..b86acf7c39d 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -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);
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 35da1fb26a6..8b7eb57514f 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -2866,7 +2866,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);
@@ -2876,7 +2876,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)
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 298ab215530..5bb781dc7fa 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -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. */
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index a2717a411a3..cdd1ac76833 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -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 ();
}
}
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 7d61ef080eb..8bb29c2470f 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -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);
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index d19ece6410d..5e94a19c964 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -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;
diff --git a/gcc/vec.h b/gcc/vec.h
index 3ad99b83690..4f18116e1b8 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1533,6 +1533,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;
};
--
2.26.2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
2020-08-06 14:15 ` Richard Biener
@ 2020-08-26 12:33 ` Richard Biener
2020-09-24 9:11 ` Richard Biener
0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2020-08-26 12:33 UTC (permalink / raw)
To: gcc-patches; +Cc: jwakely, Jakub Jelinek
On Thu, 6 Aug 2020, Richard Biener wrote:
> On Thu, 6 Aug 2020, Richard Biener wrote:
>
> > 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).
> >
> > Bootstrap / regtest running on x86_64-unknown-linux-gnu.
> >
> > Does this all look sensible and is it a good change
> > (the get_loop_exit_edges one)?
>
> Regtest went OK, here's an update with a complete ChangeLog
> (how useful..) plus the move assign operator deleted, copy
> assign wouldn't work as auto-generated and at the moment
> there's no use of assigning. I guess if we'd have functions
> that take an auto_vec<> argument meaning they will destroy
> the vector that will become useful and we can implement it.
>
> OK for trunk?
Ping.
> Thanks,
> Richard.
>
>
> From d74c346e95ff967d930b7c83daabc26b0227aea3 Mon Sep 17 00:00:00 2001
> From: Richard Biener <rguenther@suse.de>
> Date: Thu, 6 Aug 2020 14:50:56 +0200
> Subject: [PATCH] add move CTOR to auto_vec, use auto_vec for
> get_loop_exit_edges
>
> 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.
> ---
> gcc/cfgloop.c | 4 ++--
> gcc/cfgloop.h | 2 +-
> gcc/cfgloopmanip.c | 3 +--
> gcc/hash-table.h | 2 +-
> gcc/ipa-fnsummary.c | 4 +---
> gcc/ira-build.c | 12 +++---------
> gcc/ira-color.c | 4 +---
> gcc/loop-unroll.c | 3 +--
> gcc/predict.c | 9 ++-------
> gcc/tree-predcom.c | 3 +--
> gcc/tree-ssa-loop-ch.c | 3 +--
> gcc/tree-ssa-loop-im.c | 3 +--
> gcc/tree-ssa-loop-ivcanon.c | 9 ++-------
> gcc/tree-ssa-loop-manip.c | 3 +--
> gcc/tree-ssa-loop-niter.c | 20 +++++---------------
> gcc/tree-ssa-loop-prefetch.c | 7 ++-----
> gcc/vec.h | 7 +++++++
> 17 files changed, 33 insertions(+), 65 deletions(-)
>
> diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
> index 7720e6e5d2c..33a26cca6a4 100644
> --- a/gcc/cfgloop.c
> +++ b/gcc/cfgloop.c
> @@ -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;
> diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
> index 18b404e292f..f1687f37401 100644
> --- a/gcc/cfgloop.h
> +++ b/gcc/cfgloop.h
> @@ -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 *);
> diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
> index 73134a20e33..3c9e2a0a99c 100644
> --- a/gcc/cfgloopmanip.c
> +++ b/gcc/cfgloopmanip.c
> @@ -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;
> }
>
> diff --git a/gcc/hash-table.h b/gcc/hash-table.h
> index 32f3a634e1e..487003c3acf 100644
> --- a/gcc/hash-table.h
> +++ b/gcc/hash-table.h
> @@ -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++;
> diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
> index 59e52927151..f750ec1725c 100644
> --- a/gcc/ipa-fnsummary.c
> +++ b/gcc/ipa-fnsummary.c
> @@ -2767,7 +2767,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;
> @@ -2776,7 +2775,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))
> @@ -2794,7 +2793,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
> diff --git a/gcc/ira-build.c b/gcc/ira-build.c
> index 0bbdb4d0c4b..9b35d0e83a9 100644
> --- a/gcc/ira-build.c
> +++ b/gcc/ira-build.c
> @@ -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
> diff --git a/gcc/ira-color.c b/gcc/ira-color.c
> index dbb3b7a2a51..d3f8e23faff 100644
> --- a/gcc/ira-color.c
> +++ b/gcc/ira-color.c
> @@ -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);
> diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
> index 693c7768868..e1efe624361 100644
> --- a/gcc/loop-unroll.c
> +++ b/gcc/loop-unroll.c
> @@ -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;
> }
> diff --git a/gcc/predict.c b/gcc/predict.c
> index 0a317a7a4ac..a847b9b4045 100644
> --- a/gcc/predict.c
> +++ b/gcc/predict.c
> @@ -1915,7 +1915,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;
> @@ -1926,15 +1925,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",
> @@ -2048,7 +2044,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;
> diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
> index d2dcfe7f42d..93e6da1e2ab 100644
> --- a/gcc/tree-predcom.c
> +++ b/gcc/tree-predcom.c
> @@ -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;
> }
> diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
> index b9002d8e294..b86acf7c39d 100644
> --- a/gcc/tree-ssa-loop-ch.c
> +++ b/gcc/tree-ssa-loop-ch.c
> @@ -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);
> diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
> index 35da1fb26a6..8b7eb57514f 100644
> --- a/gcc/tree-ssa-loop-im.c
> +++ b/gcc/tree-ssa-loop-im.c
> @@ -2866,7 +2866,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);
>
> @@ -2876,7 +2876,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)
> diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
> index 298ab215530..5bb781dc7fa 100644
> --- a/gcc/tree-ssa-loop-ivcanon.c
> +++ b/gcc/tree-ssa-loop-ivcanon.c
> @@ -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. */
> diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
> index a2717a411a3..cdd1ac76833 100644
> --- a/gcc/tree-ssa-loop-manip.c
> +++ b/gcc/tree-ssa-loop-manip.c
> @@ -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 ();
> }
> }
>
> diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
> index 7d61ef080eb..8bb29c2470f 100644
> --- a/gcc/tree-ssa-loop-niter.c
> +++ b/gcc/tree-ssa-loop-niter.c
> @@ -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);
> diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
> index d19ece6410d..5e94a19c964 100644
> --- a/gcc/tree-ssa-loop-prefetch.c
> +++ b/gcc/tree-ssa-loop-prefetch.c
> @@ -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;
> diff --git a/gcc/vec.h b/gcc/vec.h
> index 3ad99b83690..4f18116e1b8 100644
> --- a/gcc/vec.h
> +++ b/gcc/vec.h
> @@ -1533,6 +1533,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;
> };
>
>
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
2020-08-26 12:33 ` Richard Biener
@ 2020-09-24 9:11 ` Richard Biener
2020-09-24 13:16 ` Jonathan Wakely
0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2020-09-24 9:11 UTC (permalink / raw)
To: gcc-patches; +Cc: jwakely, Jakub Jelinek
On Wed, 26 Aug 2020, Richard Biener wrote:
> On Thu, 6 Aug 2020, Richard Biener wrote:
>
> > On Thu, 6 Aug 2020, Richard Biener wrote:
> >
> > > 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).
> > >
> > > Bootstrap / regtest running on x86_64-unknown-linux-gnu.
> > >
> > > Does this all look sensible and is it a good change
> > > (the get_loop_exit_edges one)?
> >
> > Regtest went OK, here's an update with a complete ChangeLog
> > (how useful..) plus the move assign operator deleted, copy
> > assign wouldn't work as auto-generated and at the moment
> > there's no use of assigning. I guess if we'd have functions
> > that take an auto_vec<> argument meaning they will destroy
> > the vector that will become useful and we can implement it.
> >
> > OK for trunk?
>
> Ping.
Ping^2.
Thanks,
Richard.
> > Thanks,
> > Richard.
> >
> >
> > From d74c346e95ff967d930b7c83daabc26b0227aea3 Mon Sep 17 00:00:00 2001
> > From: Richard Biener <rguenther@suse.de>
> > Date: Thu, 6 Aug 2020 14:50:56 +0200
> > Subject: [PATCH] add move CTOR to auto_vec, use auto_vec for
> > get_loop_exit_edges
> >
> > 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.
> > ---
> > gcc/cfgloop.c | 4 ++--
> > gcc/cfgloop.h | 2 +-
> > gcc/cfgloopmanip.c | 3 +--
> > gcc/hash-table.h | 2 +-
> > gcc/ipa-fnsummary.c | 4 +---
> > gcc/ira-build.c | 12 +++---------
> > gcc/ira-color.c | 4 +---
> > gcc/loop-unroll.c | 3 +--
> > gcc/predict.c | 9 ++-------
> > gcc/tree-predcom.c | 3 +--
> > gcc/tree-ssa-loop-ch.c | 3 +--
> > gcc/tree-ssa-loop-im.c | 3 +--
> > gcc/tree-ssa-loop-ivcanon.c | 9 ++-------
> > gcc/tree-ssa-loop-manip.c | 3 +--
> > gcc/tree-ssa-loop-niter.c | 20 +++++---------------
> > gcc/tree-ssa-loop-prefetch.c | 7 ++-----
> > gcc/vec.h | 7 +++++++
> > 17 files changed, 33 insertions(+), 65 deletions(-)
> >
> > diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
> > index 7720e6e5d2c..33a26cca6a4 100644
> > --- a/gcc/cfgloop.c
> > +++ b/gcc/cfgloop.c
> > @@ -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;
> > diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
> > index 18b404e292f..f1687f37401 100644
> > --- a/gcc/cfgloop.h
> > +++ b/gcc/cfgloop.h
> > @@ -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 *);
> > diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
> > index 73134a20e33..3c9e2a0a99c 100644
> > --- a/gcc/cfgloopmanip.c
> > +++ b/gcc/cfgloopmanip.c
> > @@ -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;
> > }
> >
> > diff --git a/gcc/hash-table.h b/gcc/hash-table.h
> > index 32f3a634e1e..487003c3acf 100644
> > --- a/gcc/hash-table.h
> > +++ b/gcc/hash-table.h
> > @@ -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++;
> > diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
> > index 59e52927151..f750ec1725c 100644
> > --- a/gcc/ipa-fnsummary.c
> > +++ b/gcc/ipa-fnsummary.c
> > @@ -2767,7 +2767,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;
> > @@ -2776,7 +2775,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))
> > @@ -2794,7 +2793,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
> > diff --git a/gcc/ira-build.c b/gcc/ira-build.c
> > index 0bbdb4d0c4b..9b35d0e83a9 100644
> > --- a/gcc/ira-build.c
> > +++ b/gcc/ira-build.c
> > @@ -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
> > diff --git a/gcc/ira-color.c b/gcc/ira-color.c
> > index dbb3b7a2a51..d3f8e23faff 100644
> > --- a/gcc/ira-color.c
> > +++ b/gcc/ira-color.c
> > @@ -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);
> > diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
> > index 693c7768868..e1efe624361 100644
> > --- a/gcc/loop-unroll.c
> > +++ b/gcc/loop-unroll.c
> > @@ -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;
> > }
> > diff --git a/gcc/predict.c b/gcc/predict.c
> > index 0a317a7a4ac..a847b9b4045 100644
> > --- a/gcc/predict.c
> > +++ b/gcc/predict.c
> > @@ -1915,7 +1915,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;
> > @@ -1926,15 +1925,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",
> > @@ -2048,7 +2044,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;
> > diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
> > index d2dcfe7f42d..93e6da1e2ab 100644
> > --- a/gcc/tree-predcom.c
> > +++ b/gcc/tree-predcom.c
> > @@ -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;
> > }
> > diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
> > index b9002d8e294..b86acf7c39d 100644
> > --- a/gcc/tree-ssa-loop-ch.c
> > +++ b/gcc/tree-ssa-loop-ch.c
> > @@ -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);
> > diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
> > index 35da1fb26a6..8b7eb57514f 100644
> > --- a/gcc/tree-ssa-loop-im.c
> > +++ b/gcc/tree-ssa-loop-im.c
> > @@ -2866,7 +2866,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);
> >
> > @@ -2876,7 +2876,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)
> > diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
> > index 298ab215530..5bb781dc7fa 100644
> > --- a/gcc/tree-ssa-loop-ivcanon.c
> > +++ b/gcc/tree-ssa-loop-ivcanon.c
> > @@ -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. */
> > diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
> > index a2717a411a3..cdd1ac76833 100644
> > --- a/gcc/tree-ssa-loop-manip.c
> > +++ b/gcc/tree-ssa-loop-manip.c
> > @@ -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 ();
> > }
> > }
> >
> > diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
> > index 7d61ef080eb..8bb29c2470f 100644
> > --- a/gcc/tree-ssa-loop-niter.c
> > +++ b/gcc/tree-ssa-loop-niter.c
> > @@ -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);
> > diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
> > index d19ece6410d..5e94a19c964 100644
> > --- a/gcc/tree-ssa-loop-prefetch.c
> > +++ b/gcc/tree-ssa-loop-prefetch.c
> > @@ -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;
> > diff --git a/gcc/vec.h b/gcc/vec.h
> > index 3ad99b83690..4f18116e1b8 100644
> > --- a/gcc/vec.h
> > +++ b/gcc/vec.h
> > @@ -1533,6 +1533,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;
> > };
> >
> >
> >
>
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imend
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
2020-09-24 9:11 ` Richard Biener
@ 2020-09-24 13:16 ` Jonathan Wakely
2020-09-24 15:05 ` Richard Biener
0 siblings, 1 reply; 7+ messages in thread
From: Jonathan Wakely @ 2020-09-24 13:16 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches, Jakub Jelinek
On 24/09/20 11:11 +0200, Richard Biener wrote:
>On Wed, 26 Aug 2020, Richard Biener wrote:
>
>> On Thu, 6 Aug 2020, Richard Biener wrote:
>>
>> > On Thu, 6 Aug 2020, Richard Biener wrote:
>> >
>> > > 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).
>> > >
>> > > Bootstrap / regtest running on x86_64-unknown-linux-gnu.
>> > >
>> > > Does this all look sensible and is it a good change
>> > > (the get_loop_exit_edges one)?
>> >
>> > Regtest went OK, here's an update with a complete ChangeLog
>> > (how useful..) plus the move assign operator deleted, copy
>> > assign wouldn't work as auto-generated and at the moment
>> > there's no use of assigning. I guess if we'd have functions
>> > that take an auto_vec<> argument meaning they will destroy
>> > the vector that will become useful and we can implement it.
>> >
>> > OK for trunk?
>>
>> Ping.
>
>Ping^2.
Looks good to me as far as the use of C++ features goes.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
2020-09-24 13:16 ` Jonathan Wakely
@ 2020-09-24 15:05 ` Richard Biener
2020-09-25 11:40 ` Tom de Vries
0 siblings, 1 reply; 7+ messages in thread
From: Richard Biener @ 2020-09-24 15:05 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: gcc-patches, Jakub Jelinek
On Thu, 24 Sep 2020, Jonathan Wakely wrote:
> On 24/09/20 11:11 +0200, Richard Biener wrote:
> >On Wed, 26 Aug 2020, Richard Biener wrote:
> >
> >> On Thu, 6 Aug 2020, Richard Biener wrote:
> >>
> >> > On Thu, 6 Aug 2020, Richard Biener wrote:
> >> >
> >> > > 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).
> >> > >
> >> > > Bootstrap / regtest running on x86_64-unknown-linux-gnu.
> >> > >
> >> > > Does this all look sensible and is it a good change
> >> > > (the get_loop_exit_edges one)?
> >> >
> >> > Regtest went OK, here's an update with a complete ChangeLog
> >> > (how useful..) plus the move assign operator deleted, copy
> >> > assign wouldn't work as auto-generated and at the moment
> >> > there's no use of assigning. I guess if we'd have functions
> >> > that take an auto_vec<> argument meaning they will destroy
> >> > the vector that will become useful and we can implement it.
> >> >
> >> > OK for trunk?
> >>
> >> Ping.
> >
> >Ping^2.
>
> Looks good to me as far as the use of C++ features goes.
Thanks, now pushed after re-testing.
Richard.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges
2020-09-24 15:05 ` Richard Biener
@ 2020-09-25 11:40 ` Tom de Vries
0 siblings, 0 replies; 7+ messages in thread
From: Tom de Vries @ 2020-09-25 11:40 UTC (permalink / raw)
To: Richard Biener, Jonathan Wakely; +Cc: Jakub Jelinek, gcc-patches
On 9/24/20 5:05 PM, Richard Biener wrote:
> On Thu, 24 Sep 2020, Jonathan Wakely wrote:
>
>> On 24/09/20 11:11 +0200, Richard Biener wrote:
>>> On Wed, 26 Aug 2020, Richard Biener wrote:
>>>
>>>> On Thu, 6 Aug 2020, Richard Biener wrote:
>>>>
>>>>> On Thu, 6 Aug 2020, Richard Biener wrote:
>>>>>
>>>>>> 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).
>>>>>>
>>>>>> Bootstrap / regtest running on x86_64-unknown-linux-gnu.
>>>>>>
>>>>>> Does this all look sensible and is it a good change
>>>>>> (the get_loop_exit_edges one)?
>>>>>
>>>>> Regtest went OK, here's an update with a complete ChangeLog
>>>>> (how useful..) plus the move assign operator deleted, copy
>>>>> assign wouldn't work as auto-generated and at the moment
>>>>> there's no use of assigning. I guess if we'd have functions
>>>>> that take an auto_vec<> argument meaning they will destroy
>>>>> the vector that will become useful and we can implement it.
>>>>>
>>>>> OK for trunk?
>>>>
>>>> Ping.
>>>
>>> Ping^2.
>>
>> Looks good to me as far as the use of C++ features goes.
>
> Thanks, now pushed after re-testing.
Ran into a build breaker after this commit, reported here (
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97207 ).
Thanks,
- Tom
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2020-09-25 11:40 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-06 12:58 [PATCH] add move CTOR to auto_vec, use auto_vec for get_loop_exit_edges Richard Biener
2020-08-06 14:15 ` Richard Biener
2020-08-26 12:33 ` Richard Biener
2020-09-24 9:11 ` Richard Biener
2020-09-24 13:16 ` Jonathan Wakely
2020-09-24 15:05 ` Richard Biener
2020-09-25 11:40 ` Tom de Vries
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).