This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Tree-data-ref bugfixes necessary for linear loop transforms
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 12 Aug 2004 11:26:15 -0400
- Subject: [PATCH]: Tree-data-ref bugfixes necessary for linear loop transforms
This patch merges bugfixes to tree-data-ref.[ch] from the lno-branch to
the mainline.
These bugfixes and changes are necessary for linear loop transforms to
function properly.
2004-07-29 Sebastian Pop <pop@cri.ensmp.fr>
* tree-data-ref.c (free_dependence_relation, free_dependence_relations,
free_data_refs): New.
(analyze_all_data_dependences): Free datarefs and dependence_relations.
(build_classic_dist_vector, build_classic_dir_vector): Store in
the dependence_relations the
information. Each arc in the dependence_relations graph is labelled
with the distance and direction vectors.
(compute_rw_wr_ww_dependences): Renamed again
compute_all_dependences.
Now computes again the whole dependence graph including read-read
relations.
(compute_data_dependences_for_loop): Now dependence_relations
contains
all the data, and thus it doesn't need to initialize the classic_dir
and classic_dist vectors.
(analyze_all_data_dependences): Adjusted for using the new
interface of
compute_data_dependences_for_loop. Remove the statistics dump.
* tree-data-ref.h: Include lambda.h
(free_dependence_relation, free_dependence_relations,
free_data_refs): Declared here.
2004-07-20 Dorit Naishlos <dorit@il.ibm.com>
* tree-data-ref.h (init_data_ref): Additional argument is_read.
(array_base_name_differ_p): Moved to tree-data-ref.c.
* tree-data-ref.c (array_base_name_differ_p): New more conservative
implementation. Extra argument to return the result.
Add comments, and consider union case.
(initialize_data_dependence_relation): Call array_base_name_differ_p
with extra argument.
(analyze_all_data_dependences): Similarly.
(init_data_ref): Additional argument is_read.
--- /Users/dberlin/gcc/gcc/tree-data-ref.h 2004-07-24
23:24:50.000000000 -0400
+++ tree-data-ref.h 2004-07-30 13:10:34.000000000 -0400
@@ -22,11 +22,10 @@ Software Foundation, 59 Temple Place - S
#ifndef GCC_TREE_DATA_REF_H
#define GCC_TREE_DATA_REF_H
-struct data_reference GTY(())
+#include "lambda.h"
+
+struct data_reference
{
- /* An identifier. */
- unsigned int id;
-
/* A pointer to the statement that contains this DR. */
tree stmt;
@@ -47,7 +46,6 @@ struct data_reference GTY(())
};
-#define DR_ID(DR) DR->id
#define DR_STMT(DR) DR->stmt
#define DR_REF(DR) DR->ref
#define DR_BASE_NAME(DR) DR->base_name
@@ -74,7 +72,7 @@ enum data_dependence_direction {
are stored in the data_dependence_relation structure under the form
of an array of subscripts. */
-struct subscript GTY(())
+struct subscript
{
/* A description of the iterations for which the elements are
accessed twice. */
@@ -91,11 +89,6 @@ struct subscript GTY(())
B. The distance is a tree scalar expression, ie. a constant or a
symbolic expression, but certainly not a chrec function. */
tree distance;
-
- /* Direction (or sign) of the distance. This more abstract (less
- precise) information is extracted from the distance field, for
- the convenience of some analyzers. */
- enum data_dependence_direction direction;
};
#define SUB_CONFLICTS_IN_A(SUB) SUB->conflicting_iterations_in_a
@@ -103,12 +96,11 @@ struct subscript GTY(())
#define SUB_LAST_CONFLICT_IN_A(SUB) SUB->last_conflict_in_a
#define SUB_LAST_CONFLICT_IN_B(SUB) SUB->last_conflict_in_b
#define SUB_DISTANCE(SUB) SUB->distance
-#define SUB_DIRECTION(SUB) SUB->direction
/* A data_dependence_relation represents a relation between two
data_references A and B. */
-struct data_dependence_relation GTY(())
+struct data_dependence_relation
{
struct data_reference *a;
@@ -131,6 +123,12 @@ struct data_dependence_relation GTY(())
this array. This is the attribute that labels the edge A->B of
the data_dependence_relation. */
varray_type subscripts;
+
+ /* The classic direction vector. */
+ lambda_vector dir_vect;
+
+ /* The classic distance vector. */
+ lambda_vector dist_vect;
};
#define DDR_A(DDR) DDR->a
@@ -141,6 +139,8 @@ struct data_dependence_relation GTY(())
VARRAY_GENERIC_PTR_INIT (DDR_SUBSCRIPTS (DDR), N,
"subscripts_vector");
#define DDR_SUBSCRIPT(DDR, I) VARRAY_GENERIC_PTR (DDR_SUBSCRIPTS
(DDR), I)
#define DDR_NUM_SUBSCRIPTS(DDR) VARRAY_ACTIVE_SIZE (DDR_SUBSCRIPTS
(DDR))
+#define DDR_DIR_VECT(DDR) DDR->dir_vect
+#define DDR_DIST_VECT(DDR) DDR->dist_vect
@@ -149,9 +149,8 @@ struct data_dependence_relation *initial
void compute_affine_dependence (struct data_dependence_relation *);
extern void analyze_all_data_dependences (struct loops *);
extern void compute_data_dependences_for_loop (unsigned, struct loop *,
- varray_type *, varray_type *,
varray_type *, varray_type *);
-extern struct data_reference * init_data_ref (tree, tree, tree, tree);
+extern struct data_reference * init_data_ref (tree, tree, tree, tree,
bool);
extern struct data_reference *analyze_array (tree, tree, bool);
extern void dump_data_reference (FILE *, struct data_reference *);
@@ -161,28 +160,13 @@ extern void dump_data_dependence_relatio
extern void dump_data_dependence_relations (FILE *, varray_type);
extern void dump_data_dependence_direction (FILE *,
enum data_dependence_direction);
+extern bool array_base_name_differ_p (struct data_reference *,
+ struct data_reference *, bool *);
+extern void free_dependence_relation (struct data_dependence_relation
*);
+extern void free_dependence_relations (varray_type);
+extern void free_data_refs (varray_type);
-
-
-/* Inline functions. */
-
-/* This is the simplest data dependence test: determines whether the
- data references A and B access the same array. */
-static inline bool
-array_base_name_differ_p (struct data_reference *a,
- struct data_reference *b)
-{
- if (DR_BASE_NAME (a) == DR_BASE_NAME (b))
- return false;
-
- if (TREE_CODE (DR_BASE_NAME (a)) == INDIRECT_REF
- && TREE_CODE (DR_BASE_NAME (b)) == INDIRECT_REF
- && TREE_OPERAND (DR_BASE_NAME (a), 0)
- == TREE_OPERAND (DR_BASE_NAME (b), 0))
- return false;
-
- return true;
-}
+
#endif /* GCC_TREE_DATA_REF_H */
--- /Users/dberlin/gcc/gcc/tree-data-ref.c 2004-07-24
23:24:50.000000000 -0400
+++ tree-data-ref.c 2004-08-11 08:47:56.000000000 -0400
@@ -94,11 +94,111 @@ Software Foundation, 59 Temple Place - S
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "tree-pass.h"
-#include "lambda.h"
-static unsigned int data_ref_id = 0;
+/* This is the simplest data dependence test: determines whether the
+ data references A and B access the same array/region. If can't
determine -
+ return false; Otherwise, return true, and DIFFER_P will record
+ the result. This utility will not be necessary when
alias_sets_conflict_p
+ will be less conservative. */
-
+bool
+array_base_name_differ_p (struct data_reference *a,
+ struct data_reference *b,
+ bool *differ_p)
+{
+ tree base_a = DR_BASE_NAME (a);
+ tree base_b = DR_BASE_NAME (b);
+ tree ta = TREE_TYPE (base_a);
+ tree tb = TREE_TYPE (base_b);
+
+
+ /** Determine if same base **/
+
+ /* array accesses: a[i],b[i] or pointer accesses: *a,*b. bases are
a,b. */
+ if (base_a == base_b)
+ {
+ *differ_p = false;
+ return true;
+ }
+
+ /* pointer based accesses - (*p)[i],(*q)[j]. bases are (*p),(*q) */
+ if (TREE_CODE (base_a) == INDIRECT_REF && TREE_CODE (base_b) ==
INDIRECT_REF
+ && TREE_OPERAND (base_a, 0) == TREE_OPERAND (base_b, 0))
+ {
+ *differ_p = false;
+ return true;
+ }
+
+ /* record/union based accesses - s.a[i], t.b[j]. bases are s.a,t.b.
*/
+ if (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (base_b) ==
COMPONENT_REF
+ && TREE_OPERAND (base_a, 0) == TREE_OPERAND (base_b, 0)
+ && TREE_OPERAND (base_a, 1) == TREE_OPERAND (base_b, 1))
+ {
+ *differ_p = false;
+ return true;
+ }
+
+
+ /** Determine if different bases **/
+
+ /* at this point we know that base_a != base_b. However, pointer
accesses
+ of the form x=(*p) and y=(*q), which bases are p and q, may still
by pointing
+ to the same base. In SSAed GIMPLE p and q will be SSA_NAMES in
this case.
+ Therefore, here we check if it's really two diferent
declarations. */
+ if (TREE_CODE (base_a) == VAR_DECL && TREE_CODE (base_b) == VAR_DECL)
+ {
+ *differ_p = true;
+ return true;
+ }
+
+ /* compare two record/union bases s.a and t.b:
+ s != t or (a != b and s and t are not unions) */
+ if (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (base_b) ==
COMPONENT_REF
+ && ((TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL
+ && TREE_CODE (TREE_OPERAND (base_b, 0)) == VAR_DECL
+ && TREE_OPERAND (base_a, 0) != TREE_OPERAND (base_b, 0))
+ || (TREE_CODE (TREE_TYPE (TREE_OPERAND (base_a, 0))) ==
RECORD_TYPE
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (base_b, 0))) ==
RECORD_TYPE
+ && TREE_OPERAND (base_a, 1) != TREE_OPERAND (base_b,
1))))
+ {
+ *differ_p = true;
+ return true;
+ }
+
+ /* compare a record/union access and an array access. */
+ if ((TREE_CODE (base_a) == VAR_DECL
+ && (TREE_CODE (base_b) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (base_b, 0)) == VAR_DECL))
+ || (TREE_CODE (base_b) == VAR_DECL
+ && (TREE_CODE (base_a) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL)))
+ {
+ *differ_p = true;
+ return true;
+ }
+
+ if (!alias_sets_conflict_p (get_alias_set (base_a), get_alias_set
(base_b)))
+ {
+ *differ_p = true;
+ return true;
+ }
+
+ /* An insn writing through a restricted pointer is "independent" of
any
+ insn reading or writing through a different pointer, in the same
+ block/scope.
+ */
+ if ((TREE_CODE (ta) == POINTER_TYPE && TYPE_RESTRICT (ta)
+ && !DR_IS_READ(a))
+ || (TREE_CODE (tb) == POINTER_TYPE && TYPE_RESTRICT (tb)
+ && !DR_IS_READ(b)))
+ {
+ *differ_p = true;
+ return true;
+ }
+
+ *differ_p = false; /* Don't know, but be conservative. */
+ return false;
+}
/* Returns true iff A divides B. */
@@ -248,7 +348,7 @@ dump_data_reference (FILE *outf,
{
unsigned int i;
- fprintf (outf, "(Data Ref %d: \n stmt: ", DR_ID (dr));
+ fprintf (outf, "(Data Ref: \n stmt: ");
print_generic_stmt (outf, DR_STMT (dr), 0);
fprintf (outf, " ref: ");
print_generic_stmt (outf, DR_REF (dr), 0);
@@ -276,7 +376,7 @@ dump_data_dependence_relation (FILE *out
drb = DDR_B (ddr);
if (dra && drb)
- fprintf (outf, "(Data Dep (A = %d, B = %d):", DR_ID (dra), DR_ID
(drb));
+ fprintf (outf, "(Data Dep:");
else
fprintf (outf, "(Data Dep:");
@@ -443,9 +543,8 @@ analyze_array (tree stmt, tree ref, bool
fprintf (dump_file, ")\n");
}
- res = ggc_alloc (sizeof (struct data_reference));
+ res = xmalloc (sizeof (struct data_reference));
- DR_ID (res) = data_ref_id++;
DR_STMT (res) = stmt;
DR_REF (res) = ref;
VARRAY_TREE_INIT (DR_ACCESS_FNS (res), 3, "access_fns");
@@ -466,7 +565,8 @@ struct data_reference *
init_data_ref (tree stmt,
tree ref,
tree base,
- tree access_fn)
+ tree access_fn,
+ bool is_read)
{
struct data_reference *res;
@@ -478,14 +578,14 @@ init_data_ref (tree stmt,
fprintf (dump_file, ")\n");
}
- res = ggc_alloc (sizeof (struct data_reference));
+ res = xmalloc (sizeof (struct data_reference));
- DR_ID (res) = data_ref_id++;
DR_STMT (res) = stmt;
DR_REF (res) = ref;
VARRAY_TREE_INIT (DR_ACCESS_FNS (res), 5, "access_fns");
DR_BASE_NAME (res) = base;
VARRAY_PUSH_TREE (DR_ACCESS_FNS (res), access_fn);
+ DR_IS_READ (res) = is_read;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
@@ -532,8 +632,9 @@ initialize_data_dependence_relation (str
struct data_reference *b)
{
struct data_dependence_relation *res;
+ bool differ_p;
- res = ggc_alloc (sizeof (struct data_dependence_relation));
+ res = xmalloc (sizeof (struct data_dependence_relation));
DDR_A (res) = a;
DDR_B (res) = b;
@@ -545,7 +646,7 @@ initialize_data_dependence_relation (str
/* When the dimensions of A and B differ, we directly initialize
the relation to "there is no dependence": chrec_known. */
else if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
- || array_base_name_differ_p (a, b))
+ || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
DDR_ARE_DEPENDENT (res) = chrec_known;
else
@@ -558,13 +659,12 @@ initialize_data_dependence_relation (str
{
struct subscript *subscript;
- subscript = ggc_alloc (sizeof (struct subscript));
+ subscript = xmalloc (sizeof (struct subscript));
SUB_CONFLICTS_IN_A (subscript) = chrec_dont_know;
SUB_CONFLICTS_IN_B (subscript) = chrec_dont_know;
SUB_LAST_CONFLICT_IN_A (subscript) = chrec_dont_know;
SUB_LAST_CONFLICT_IN_B (subscript) = chrec_dont_know;
SUB_DISTANCE (subscript) = chrec_dont_know;
- SUB_DIRECTION (subscript) = dir_star;
VARRAY_PUSH_GENERIC_PTR (DDR_SUBSCRIPTS (res), subscript);
}
}
@@ -579,6 +679,13 @@ static inline void
finalize_ddr_dependent (struct data_dependence_relation *ddr,
tree chrec)
{
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "(dependence classified: ");
+ print_generic_expr (dump_file, chrec, 0);
+ fprintf (dump_file, ")\n");
+ }
+
DDR_ARE_DEPENDENT (ddr) = chrec;
varray_clear (DDR_SUBSCRIPTS (ddr));
}
@@ -1322,14 +1429,12 @@ subscript_dependence_tester (struct data
/* Compute the classic per loop distance vector.
- RES is the data dependence relation to build a vector from.
- CLASSIC_DIST is the varray to place the vector in.
+ DDR is the data dependence relation to build a vector from.
NB_LOOPS is the total number of loops we are considering.
FIRST_LOOP is the loop->num of the first loop. */
static void
-build_classic_dist_vector (struct data_dependence_relation *res,
- varray_type *classic_dist,
+build_classic_dist_vector (struct data_dependence_relation *ddr,
int nb_loops, unsigned int first_loop)
{
unsigned i;
@@ -1340,12 +1445,12 @@ build_classic_dist_vector (struct data_d
lambda_vector_clear (dist_v, nb_loops);
lambda_vector_clear (init_v, nb_loops);
- if (DDR_ARE_DEPENDENT (res) != NULL_TREE)
+ if (DDR_ARE_DEPENDENT (ddr) != NULL_TREE)
return;
- for (i = 0; i < DDR_NUM_SUBSCRIPTS (res); i++)
+ for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
{
- struct subscript *subscript = DDR_SUBSCRIPT (res, i);
+ struct subscript *subscript = DDR_SUBSCRIPT (ddr, i);
if (chrec_contains_undetermined (SUB_DISTANCE (subscript)))
return;
@@ -1372,7 +1477,7 @@ build_classic_dist_vector (struct data_d
if (init_v[loop_nb] != 0
&& dist_v[loop_nb] != dist)
{
- finalize_ddr_dependent (res, chrec_known);
+ finalize_ddr_dependent (ddr, chrec_known);
return;
}
@@ -1390,8 +1495,8 @@ build_classic_dist_vector (struct data_d
*/
{
struct loop *lca, *loop_a, *loop_b;
- struct data_reference *a = DDR_A (res);
- struct data_reference *b = DDR_B (res);
+ struct data_reference *a = DDR_A (ddr);
+ struct data_reference *b = DDR_B (ddr);
int lca_nb;
loop_a = loop_containing_stmt (DR_STMT (a));
loop_b = loop_containing_stmt (DR_STMT (b));
@@ -1428,19 +1533,17 @@ build_classic_dist_vector (struct data_d
}
}
- VARRAY_PUSH_GENERIC_PTR (*classic_dist, dist_v);
+ DDR_DIST_VECT (ddr) = dist_v;
}
/* Compute the classic per loop direction vector.
- RES is the data dependence relation to build a vector from.
- CLASSIC_DIR is the varray to place the vector in.
+ DDR is the data dependence relation to build a vector from.
NB_LOOPS is the total number of loops we are considering.
FIRST_LOOP is the loop->num of the first loop. */
static void
-build_classic_dir_vector (struct data_dependence_relation *res,
- varray_type *classic_dir,
+build_classic_dir_vector (struct data_dependence_relation *ddr,
int nb_loops, unsigned int first_loop)
{
unsigned i;
@@ -1451,12 +1554,12 @@ build_classic_dir_vector (struct data_de
lambda_vector_clear (dir_v, nb_loops);
lambda_vector_clear (init_v, nb_loops);
- if (DDR_ARE_DEPENDENT (res) != NULL_TREE)
+ if (DDR_ARE_DEPENDENT (ddr) != NULL_TREE)
return;
- for (i = 0; i < DDR_NUM_SUBSCRIPTS (res); i++)
+ for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
{
- struct subscript *subscript = DDR_SUBSCRIPT (res, i);
+ struct subscript *subscript = DDR_SUBSCRIPT (ddr, i);
if (TREE_CODE (SUB_CONFLICTS_IN_A (subscript)) ==
POLYNOMIAL_CHREC
&& TREE_CODE (SUB_CONFLICTS_IN_B (subscript)) == POLYNOMIAL_CHREC)
@@ -1499,7 +1602,7 @@ build_classic_dir_vector (struct data_de
&& (enum data_dependence_direction) dir_v[loop_nb] != dir
&& (enum data_dependence_direction) dir_v[loop_nb] != dir_star)
{
- finalize_ddr_dependent (res, chrec_known);
+ finalize_ddr_dependent (ddr, chrec_known);
return;
}
@@ -1517,8 +1620,8 @@ build_classic_dir_vector (struct data_de
*/
{
struct loop *lca, *loop_a, *loop_b;
- struct data_reference *a = DDR_A (res);
- struct data_reference *b = DDR_B (res);
+ struct data_reference *a = DDR_A (ddr);
+ struct data_reference *b = DDR_B (ddr);
int lca_nb;
loop_a = loop_containing_stmt (DR_STMT (a));
loop_b = loop_containing_stmt (DR_STMT (b));
@@ -1553,7 +1656,7 @@ build_classic_dir_vector (struct data_de
}
}
- VARRAY_PUSH_GENERIC_PTR (*classic_dir, dir_v);
+ DDR_DIR_VECT (ddr) = dir_v;
}
/* Returns true when all the access functions of A are affine or
@@ -1590,8 +1693,7 @@ compute_affine_dependence (struct data_d
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "(compute_affine_dependence (%d, %d)\n",
- DR_ID (dra), DR_ID (drb));
+ fprintf (dump_file, "(compute_affine_dependence\n");
fprintf (dump_file, " (stmt_a = \n");
print_generic_expr (dump_file, DR_STMT (dra), 0);
fprintf (dump_file, ")\n (stmt_b = \n");
@@ -1624,8 +1726,8 @@ compute_affine_dependence (struct data_d
in DEPENDENCE_RELATIONS. */
static void
-compute_rw_wr_ww_dependences (varray_type datarefs,
- varray_type *dependence_relations)
+compute_all_dependences (varray_type datarefs,
+ varray_type *dependence_relations)
{
unsigned int i, j, N;
@@ -1640,10 +1742,6 @@ compute_rw_wr_ww_dependences (varray_typ
a = VARRAY_GENERIC_PTR (datarefs, i);
b = VARRAY_GENERIC_PTR (datarefs, j);
- /* Don't compute the "read-read" relations. */
- if (DR_IS_READ (a) && DR_IS_READ (b))
- continue;
-
ddr = initialize_data_dependence_relation (a, b);
VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
@@ -1711,17 +1815,13 @@ find_data_references_in_loop (struct loo
/* Given a loop nest LOOP, the following vectors are returned:
*DATAREFS is initialized to all the array elements contained in
this loop,
- *DEPENDENCE_RELATIONS contains the relations between the data
references,
- *CLASSIC_DIST contains the set of distance vectors,
- *CLASSIC_DIR contains the set of direction vectors. */
+ *DEPENDENCE_RELATIONS contains the relations between the data
references. */
void
compute_data_dependences_for_loop (unsigned nb_loops,
struct loop *loop,
varray_type *datarefs,
- varray_type *dependence_relations,
- varray_type *classic_dist,
- varray_type *classic_dir)
+ varray_type *dependence_relations)
{
unsigned int i;
@@ -1735,19 +1835,19 @@ compute_data_dependences_for_loop (unsig
chrec_dont_know. */
ddr = initialize_data_dependence_relation (NULL, NULL);
VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
- build_classic_dist_vector (ddr, classic_dist, nb_loops,
loop->num);
- build_classic_dir_vector (ddr, classic_dir, nb_loops, loop->num);
+ build_classic_dist_vector (ddr, nb_loops, loop->num);
+ build_classic_dir_vector (ddr, nb_loops, loop->num);
return;
}
- compute_rw_wr_ww_dependences (*datarefs, dependence_relations);
+ compute_all_dependences (*datarefs, dependence_relations);
for (i = 0; i < VARRAY_ACTIVE_SIZE (*dependence_relations); i++)
{
struct data_dependence_relation *ddr;
ddr = VARRAY_GENERIC_PTR (*dependence_relations, i);
- build_classic_dist_vector (ddr, classic_dist, nb_loops,
loop->num);
- build_classic_dir_vector (ddr, classic_dir, nb_loops, loop->num);
+ build_classic_dist_vector (ddr, nb_loops, loop->num);
+ build_classic_dir_vector (ddr, nb_loops, loop->num);
}
}
@@ -1779,11 +1879,8 @@ analyze_all_data_dependences (struct loo
unsigned int i;
varray_type datarefs;
varray_type dependence_relations;
- varray_type classic_dist, classic_dir;
int nb_data_refs = 10;
- VARRAY_GENERIC_PTR_INIT (classic_dist, 10, "classic_dist");
- VARRAY_GENERIC_PTR_INIT (classic_dir, 10, "classic_dir");
VARRAY_GENERIC_PTR_INIT (datarefs, nb_data_refs, "datarefs");
VARRAY_GENERIC_PTR_INIT (dependence_relations,
nb_data_refs * nb_data_refs,
@@ -1791,8 +1888,7 @@ analyze_all_data_dependences (struct loo
/* Compute DDs on the whole function. */
compute_data_dependences_for_loop (loops->num, loops->parray[0],
- &datarefs, &dependence_relations,
- &classic_dist, &classic_dir);
+ &datarefs, &dependence_relations);
if (dump_file)
{
@@ -1804,21 +1900,20 @@ analyze_all_data_dependences (struct loo
testsuite. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
- for (i = 0; i < VARRAY_ACTIVE_SIZE (classic_dist); i++)
- {
- fprintf (dump_file, "DISTANCE_V (");
- print_lambda_vector (dump_file,
- VARRAY_GENERIC_PTR (classic_dist, i),
- loops->num);
- fprintf (dump_file, ")\n");
- }
- for (i = 0; i < VARRAY_ACTIVE_SIZE (classic_dir); i++)
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
{
- fprintf (dump_file, "DIRECTION_V (");
- print_lambda_vector (dump_file,
- VARRAY_GENERIC_PTR (classic_dir, i),
- loops->num);
- fprintf (dump_file, ")\n");
+ struct data_dependence_relation *ddr =
+ (struct data_dependence_relation *)
+ VARRAY_GENERIC_PTR (dependence_relations, i);
+ if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
+ {
+ fprintf (dump_file, "DISTANCE_V (");
+ print_lambda_vector (dump_file, DDR_DIST_VECT (ddr),
loops->num);
+ fprintf (dump_file, ")\n");
+ fprintf (dump_file, "DIRECTION_V (");
+ print_lambda_vector (dump_file, DDR_DIR_VECT (ddr), loops->num);
+ fprintf (dump_file, ")\n");
+ }
}
fprintf (dump_file, "\n\n");
}
@@ -1842,9 +1937,10 @@ analyze_all_data_dependences (struct loo
{
struct data_reference *a = DDR_A (ddr);
struct data_reference *b = DDR_B (ddr);
+ bool differ_p;
if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
- || array_base_name_differ_p (a, b))
+ || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
nb_basename_differ++;
else
nb_bot_relations++;
@@ -1854,21 +1950,57 @@ analyze_all_data_dependences (struct loo
nb_chrec_relations++;
}
- fprintf (dump_file, "\n(\n");
- fprintf (dump_file, "%d\tnb_top_relations\n", nb_top_relations);
- fprintf (dump_file, "%d\tnb_bot_relations\n", nb_bot_relations);
- fprintf (dump_file, "%d\tnb_basename_differ\n",
nb_basename_differ);
- fprintf (dump_file, "%d\tnb_distance_relations\n", (int)
VARRAY_ACTIVE_SIZE (classic_dist));
- fprintf (dump_file, "%d\tnb_chrec_relations\n",
nb_chrec_relations);
- fprintf (dump_file, "\n)\n");
-
gather_stats_on_scev_database ();
}
-
+
+ free_dependence_relations (dependence_relations);
+ free_data_refs (datarefs);
+}
+
+/* Free the memory used by a data dependence relation DDR. */
+
+void
+free_dependence_relation (struct data_dependence_relation *ddr)
+{
+ if (ddr == NULL)
+ return;
+
+ if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE && DDR_SUBSCRIPTS (ddr))
+ varray_clear (DDR_SUBSCRIPTS (ddr));
+ free (ddr);
+}
+
+/* Free the memory used by the data dependence relations from
+ DEPENDENCE_RELATIONS. */
+
+void
+free_dependence_relations (varray_type dependence_relations)
+{
+ unsigned int i;
+ if (dependence_relations == NULL)
+ return;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
+ free_dependence_relation (VARRAY_GENERIC_PTR
(dependence_relations, i));
varray_clear (dependence_relations);
- varray_clear (datarefs);
- varray_clear (classic_dist);
- varray_clear (classic_dir);
}
+/* Free the memory used by the data references from DATAREFS. */
+void
+free_data_refs (varray_type datarefs)
+{
+ unsigned int i;
+
+ if (datarefs == NULL)
+ return;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
+ {
+ struct data_reference *dr = (struct data_reference *)
+ VARRAY_GENERIC_PTR (datarefs, i);
+ if (dr && DR_ACCESS_FNS (dr))
+ varray_clear (DR_ACCESS_FNS (dr));
+ }
+ varray_clear (datarefs);
+}