Commit 2c515559 by Richard Sandiford Committed by Richard Sandiford

C++-ify vec_info structures

This patch uses new, delete, constructors and desctructors to manage
vec_info.  This includes making ~vec_info free all the data shared
by bb_vec_info and loop_vec_info, whereas previously the code was
duplicated in destroy_bb_vec_info and destroy_loop_vec_info.  This
in turn meant changing the order of:

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

and:

  gimple_set_uid (stmt, -1);

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

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

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

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