+2010-12-23 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR tree-optimization/47002
+ * tree-data-ref.c (compute_data_dependences_for_loop): Pass in a
+ pointer to the loop_nest.
+ (analyze_all_data_dependences): Initialize and free the loop_nest.
+ (free_dependence_relations): Do not free loop_nest.
+ (build_rdg): Pass in the loop_nest, datarefs, and dependence_relations.
+ (free_rdg): Also free the data on edges.
+ * tree-data-ref.h (build_rdg): Update declaration.
+ (compute_data_dependences_for_loop): Same.
+ * tree-if-conv.c (if_convertible_loop_p_1): Pass in the loop_nest.
+ (if_convertible_loop_p): Allocate and free loop_nest.
+ * tree-loop-distribution.c (rdg_flag_loop_exits): Free conds.
+ (free_rdg_components): VEC_free components.
+ (distribute_loop): Update call to build_rdg. Allocate and free
+ loop_nest, datarefs, and dependence_relations.
+ * tree-loop-linear.c (linear_transform_loops): Allocate and free
+ loop_nest.
+ * tree-parloops.c (loop_parallel_p): Same.
+ * tree-predcom.c (tree_predictive_commoning_loop): Same.
+ * tree-vect-data-refs.c (vect_analyze_data_refs): Pass to
+ compute_data_dependences_for_loop a pointer to LOOP_VINFO_LOOP_NEST.
+ * tree-vect-loop.c (new_loop_vec_info): Initialize LOOP_VINFO_LOOP_NEST.
+ (destroy_loop_vec_info): Free LOOP_VINFO_MAY_ALIAS_DDRS and
+ LOOP_VINFO_LOOP_NEST.
+ * tree-vect-slp.c (destroy_bb_vec_info): Call free_data_refs and
+ free_dependence_relations.
+ * tree-vectorizer.h (struct _loop_vec_info): Add a field loop_nest.
+ (LOOP_VINFO_LOOP_NEST): New.
+
2010-12-23 Martin Jambor <mjambor@suse.cz>
* ipa.c (cgraph_remove_unreachable_nodes): Update former_clone_of even
bool
compute_data_dependences_for_loop (struct loop *loop,
bool compute_self_and_read_read_dependences,
+ VEC (loop_p, heap) **loop_nest,
VEC (data_reference_p, heap) **datarefs,
VEC (ddr_p, heap) **dependence_relations)
{
bool res = true;
- VEC (loop_p, heap) *vloops = VEC_alloc (loop_p, heap, 3);
memset (&dependence_stats, 0, sizeof (dependence_stats));
is not computable, give up without spending time to compute other
dependences. */
if (!loop
- || !find_loop_nest (loop, &vloops)
+ || !find_loop_nest (loop, loop_nest)
|| find_data_references_in_loop (loop, datarefs) == chrec_dont_know)
{
struct data_dependence_relation *ddr;
/* Insert a single relation into dependence_relations:
chrec_dont_know. */
- ddr = initialize_data_dependence_relation (NULL, NULL, vloops);
+ ddr = initialize_data_dependence_relation (NULL, NULL, *loop_nest);
VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
res = false;
}
else
- compute_all_dependences (*datarefs, dependence_relations, vloops,
+ compute_all_dependences (*datarefs, dependence_relations, *loop_nest,
compute_self_and_read_read_dependences);
if (dump_file && (dump_flags & TDF_STATS))
VEC_alloc (data_reference_p, heap, nb_data_refs);
VEC (ddr_p, heap) *dependence_relations =
VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs);
+ VEC (loop_p, heap) *loop_nest = VEC_alloc (loop_p, heap, 3);
/* Compute DDs on the whole function. */
- compute_data_dependences_for_loop (loop, false, &datarefs,
+ compute_data_dependences_for_loop (loop, false, &loop_nest, &datarefs,
&dependence_relations);
if (dump_file)
}
}
+ VEC_free (loop_p, heap, loop_nest);
free_dependence_relations (dependence_relations);
free_data_refs (datarefs);
}
{
unsigned int i;
struct data_dependence_relation *ddr;
- VEC (loop_p, heap) *loop_nest = NULL;
FOR_EACH_VEC_ELT (ddr_p, dependence_relations, i, ddr)
- {
- if (ddr == NULL)
- continue;
- if (loop_nest == NULL)
- loop_nest = DDR_LOOP_NEST (ddr);
- else
- gcc_assert (DDR_LOOP_NEST (ddr) == NULL
- || DDR_LOOP_NEST (ddr) == loop_nest);
+ if (ddr)
free_dependence_relation (ddr);
- }
- if (loop_nest)
- VEC_free (loop_p, heap, loop_nest);
VEC_free (ddr_p, heap, dependence_relations);
}
scalar dependence. */
struct graph *
-build_rdg (struct loop *loop)
+build_rdg (struct loop *loop,
+ VEC (loop_p, heap) **loop_nest,
+ VEC (ddr_p, heap) **dependence_relations,
+ VEC (data_reference_p, heap) **datarefs)
{
- int nb_data_refs = 10;
struct graph *rdg = NULL;
- VEC (ddr_p, heap) *dependence_relations;
- VEC (data_reference_p, heap) *datarefs;
- VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, nb_data_refs);
-
- dependence_relations = VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs) ;
- datarefs = VEC_alloc (data_reference_p, heap, nb_data_refs);
- compute_data_dependences_for_loop (loop,
- false,
- &datarefs,
- &dependence_relations);
-
- if (!known_dependences_p (dependence_relations))
- {
- free_dependence_relations (dependence_relations);
- free_data_refs (datarefs);
- VEC_free (gimple, heap, stmts);
-
- return rdg;
- }
+ VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, 10);
- stmts_from_loop (loop, &stmts);
- rdg = build_empty_rdg (VEC_length (gimple, stmts));
+ compute_data_dependences_for_loop (loop, false, loop_nest, datarefs,
+ dependence_relations);
- rdg->indices = htab_create (nb_data_refs, hash_stmt_vertex_info,
- eq_stmt_vertex_info, hash_stmt_vertex_del);
- create_rdg_vertices (rdg, stmts);
- create_rdg_edges (rdg, dependence_relations);
+ if (known_dependences_p (*dependence_relations))
+ {
+ stmts_from_loop (loop, &stmts);
+ rdg = build_empty_rdg (VEC_length (gimple, stmts));
+ create_rdg_vertices (rdg, stmts);
+ create_rdg_edges (rdg, *dependence_relations);
+ }
VEC_free (gimple, heap, stmts);
return rdg;
int i;
for (i = 0; i < rdg->n_vertices; i++)
- free (rdg->vertices[i].data);
+ {
+ struct vertex *v = &(rdg->vertices[i]);
+ struct graph_edge *e;
+
+ for (e = v->succ; e; e = e->succ_next)
+ if (e->data)
+ free (e->data);
+
+ if (v->data)
+ free (v->data);
+ }
htab_delete (rdg->indices);
free_graph (rdg);
bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **);
bool dr_analyze_innermost (struct data_reference *);
extern bool compute_data_dependences_for_loop (struct loop *, bool,
+ VEC (loop_p, heap) **,
VEC (data_reference_p, heap) **,
VEC (ddr_p, heap) **);
extern bool compute_data_dependences_for_bb (basic_block, bool,
#define RDGE_LEVEL(E) ((struct rdg_edge *) ((E)->data))->level
#define RDGE_RELATION(E) ((struct rdg_edge *) ((E)->data))->relation
-struct graph *build_rdg (struct loop *);
+struct graph *build_rdg (struct loop *,
+ VEC (loop_p, heap) **,
+ VEC (ddr_p, heap) **,
+ VEC (data_reference_p, heap) **);
struct graph *build_empty_rdg (int);
void free_rdg (struct graph *);
static bool
if_convertible_loop_p_1 (struct loop *loop,
+ VEC (loop_p, heap) **loop_nest,
VEC (data_reference_p, heap) **refs,
VEC (ddr_p, heap) **ddrs)
{
/* Don't if-convert the loop when the data dependences cannot be
computed: the loop won't be vectorized in that case. */
- res = compute_data_dependences_for_loop (loop, true, refs, ddrs);
+ res = compute_data_dependences_for_loop (loop, true, loop_nest, refs, ddrs);
if (!res)
return false;
bool res = false;
VEC (data_reference_p, heap) *refs;
VEC (ddr_p, heap) *ddrs;
+ VEC (loop_p, heap) *loop_nest;
/* Handle only innermost loop. */
if (!loop || loop->inner)
refs = VEC_alloc (data_reference_p, heap, 5);
ddrs = VEC_alloc (ddr_p, heap, 25);
- res = if_convertible_loop_p_1 (loop, &refs, &ddrs);
+ loop_nest = VEC_alloc (loop_p, heap, 3);
+ res = if_convertible_loop_p_1 (loop, &loop_nest, &refs, &ddrs);
if (flag_tree_loop_if_convert_stores)
{
free (dr->aux);
}
+ VEC_free (loop_p, heap, loop_nest);
free_data_refs (refs);
free_dependence_relations (ddrs);
return res;
BITMAP_FREE (new_loops);
}
+
+ VEC_free (gimple, heap, conds);
}
/* Returns a bitmap in which all the statements needed for computing
VEC_free (int, heap, x->vertices);
free (x);
}
+
+ VEC_free (rdgc, heap, components);
}
/* Build the COMPONENTS vector with the strongly connected components
gimple s;
unsigned i;
VEC (int, heap) *vertices;
+ VEC (ddr_p, heap) *dependence_relations;
+ VEC (data_reference_p, heap) *datarefs;
+ VEC (loop_p, heap) *loop_nest;
if (loop->num_nodes > 2)
{
return res;
}
- rdg = build_rdg (loop);
+ datarefs = VEC_alloc (data_reference_p, heap, 10);
+ dependence_relations = VEC_alloc (ddr_p, heap, 100);
+ loop_nest = VEC_alloc (loop_p, heap, 3);
+ rdg = build_rdg (loop, &loop_nest, &dependence_relations, &datarefs);
if (!rdg)
{
"FIXME: Loop %d not distributed: failed to build the RDG.\n",
loop->num);
+ free_dependence_relations (dependence_relations);
+ free_data_refs (datarefs);
+ VEC_free (loop_p, heap, loop_nest);
return res;
}
res = ldist_gen (loop, rdg, vertices);
VEC_free (int, heap, vertices);
free_rdg (rdg);
-
+ free_dependence_relations (dependence_relations);
+ free_data_refs (datarefs);
+ VEC_free (loop_p, heap, loop_nest);
return res;
}
lambda_trans_matrix trans;
struct obstack lambda_obstack;
struct loop *loop;
- VEC(loop_p,heap) *nest;
+ VEC (loop_p, heap) *nest;
+ VEC (loop_p, heap) *ln;
depth = perfect_loop_nest_depth (loop_nest);
if (depth == 0)
datarefs = VEC_alloc (data_reference_p, heap, 10);
dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
- if (!compute_data_dependences_for_loop (loop_nest, true, &datarefs,
+ ln = VEC_alloc (loop_p, heap, 3);
+ if (!compute_data_dependences_for_loop (loop_nest, true, &ln, &datarefs,
&dependence_relations))
goto free_and_continue;
free_dependence_relations (dependence_relations);
free_data_refs (datarefs);
VEC_free (loop_p, heap, nest);
+ VEC_free (loop_p, heap, ln);
}
FOR_EACH_VEC_ELT (gimple, remove_ivs, i, oldiv_stmt)
static bool
loop_parallel_p (struct loop *loop, struct obstack * parloop_obstack)
{
- VEC (ddr_p, heap) * dependence_relations;
+ VEC (loop_p, heap) *loop_nest;
+ VEC (ddr_p, heap) *dependence_relations;
VEC (data_reference_p, heap) *datarefs;
lambda_trans_matrix trans;
bool ret = false;
the iterations are independent. */
datarefs = VEC_alloc (data_reference_p, heap, 10);
dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
- compute_data_dependences_for_loop (loop, true, &datarefs,
+ loop_nest = VEC_alloc (loop_p, heap, 3);
+ compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
&dependence_relations);
if (dump_file && (dump_flags & TDF_DETAILS))
dump_data_dependence_relations (dump_file, dependence_relations);
fprintf (dump_file,
" FAILED: data dependencies exist across iterations\n");
+ VEC_free (loop_p, heap, loop_nest);
free_dependence_relations (dependence_relations);
free_data_refs (datarefs);
static bool
tree_predictive_commoning_loop (struct loop *loop)
{
+ VEC (loop_p, heap) *loop_nest;
VEC (data_reference_p, heap) *datarefs;
VEC (ddr_p, heap) *dependences;
struct component *components;
dependence relations. */
datarefs = VEC_alloc (data_reference_p, heap, 10);
dependences = VEC_alloc (ddr_p, heap, 10);
- compute_data_dependences_for_loop (loop, true, &datarefs, &dependences);
+ loop_nest = VEC_alloc (loop_p, heap, 3);
+ compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
+ &dependences);
if (dump_file && (dump_flags & TDF_DETAILS))
dump_data_dependence_relations (dump_file, dependences);
components = split_data_refs_to_components (loop, datarefs, dependences);
+ VEC_free (loop_p, heap, loop_nest);
free_dependence_relations (dependences);
if (!components)
{
{
loop = LOOP_VINFO_LOOP (loop_vinfo);
res = compute_data_dependences_for_loop
- (loop, true, &LOOP_VINFO_DATAREFS (loop_vinfo),
+ (loop, true,
+ &LOOP_VINFO_LOOP_NEST (loop_vinfo),
+ &LOOP_VINFO_DATAREFS (loop_vinfo),
&LOOP_VINFO_DDRS (loop_vinfo));
if (!res)
LOOP_VINFO_VECTORIZABLE_P (res) = 0;
LOOP_PEELING_FOR_ALIGNMENT (res) = 0;
LOOP_VINFO_VECT_FACTOR (res) = 0;
+ LOOP_VINFO_LOOP_NEST (res) = VEC_alloc (loop_p, heap, 3);
LOOP_VINFO_DATAREFS (res) = VEC_alloc (data_reference_p, heap, 10);
LOOP_VINFO_DDRS (res) = VEC_alloc (ddr_p, heap, 10 * 10);
LOOP_VINFO_UNALIGNED_DR (res) = NULL;
free (LOOP_VINFO_BBS (loop_vinfo));
free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
+ VEC_free (loop_p, heap, LOOP_VINFO_LOOP_NEST (loop_vinfo));
VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
+ VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
free (loop_vinfo);
loop->aux = NULL;
free (LOOP_VINFO_BBS (loop_vinfo));
free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
+ VEC_free (loop_p, heap, LOOP_VINFO_LOOP_NEST (loop_vinfo));
VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
free_stmt_vec_info (stmt);
}
+ free_data_refs (BB_VINFO_DATAREFS (bb_vinfo));
+ free_dependence_relations (BB_VINFO_DDRS (bb_vinfo));
VEC_free (gimple, heap, BB_VINFO_STRIDED_STORES (bb_vinfo));
VEC_free (slp_instance, heap, BB_VINFO_SLP_INSTANCES (bb_vinfo));
free (bb_vinfo);
/* The mask used to check the alignment of pointers or arrays. */
int ptr_mask;
+ /* The loop nest in which the data dependences are computed. */
+ VEC (loop_p, heap) *loop_nest;
+
/* All data references in the loop. */
VEC (data_reference_p, heap) *datarefs;
#define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable
#define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor
#define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask
+#define LOOP_VINFO_LOOP_NEST(L) (L)->loop_nest
#define LOOP_VINFO_DATAREFS(L) (L)->datarefs
#define LOOP_VINFO_DDRS(L) (L)->ddrs
#define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters))