/* This pass walks a given loop structure searching for array
references. The information about the array accesses is recorded
- in DATA_REFERENCE structures.
-
- The basic test for determining the dependences is:
- given two access functions chrec1 and chrec2 to a same array, and
- x and y two vectors from the iteration domain, the same element of
+ in DATA_REFERENCE structures.
+
+ The basic test for determining the dependences is:
+ given two access functions chrec1 and chrec2 to a same array, and
+ x and y two vectors from the iteration domain, the same element of
the array is accessed twice at iterations x and y if and only if:
| chrec1 (x) == chrec2 (y).
-
+
The goals of this analysis are:
-
+
- to determine the independence: the relation between two
independent accesses is qualified with the chrec_known (this
information allows a loop parallelization),
-
+
- when two data references access the same data, to qualify the
dependence relation with classic dependence representations:
-
+
- distance vectors
- direction vectors
- loop carried level dependence
- polyhedron dependence
or with the chains of recurrences based representation,
-
- - to define a knowledge base for storing the data dependence
+
+ - to define a knowledge base for storing the data dependence
information,
-
+
- to define an interface to access this data.
-
-
+
+
Definitions:
-
+
- subscript: given two array accesses a subscript is the tuple
composed of the access functions for a given dimension. Example:
Given A[f1][f2][f3] and B[g1][g2][g3], there are three subscripts:
(f1, g1), (f2, g2), (f3, g3).
- Diophantine equation: an equation whose coefficients and
- solutions are integer constants, for example the equation
+ solutions are integer constants, for example the equation
| 3*x + 2*y = 1
has an integer solution x = 1 and y = -1.
-
+
References:
-
+
- "Advanced Compilation for High Performance Computing" by Randy
Allen and Ken Kennedy.
- http://citeseer.ist.psu.edu/goff91practical.html
-
- - "Loop Transformations for Restructuring Compilers - The Foundations"
+ http://citeseer.ist.psu.edu/goff91practical.html
+
+ - "Loop Transformations for Restructuring Compilers - The Foundations"
by Utpal Banerjee.
-
+
*/
#include "config.h"
struct loop *);
/* Returns true iff A divides B. */
-static inline bool
+static inline bool
tree_fold_divides_p (const_tree a, const_tree b)
{
gcc_assert (TREE_CODE (a) == INTEGER_CST);
/* Returns true iff A divides B. */
-static inline bool
+static inline bool
int_divides_p (int a, int b)
{
return ((b % a) == 0);
\f
-/* Dump into FILE all the data references from DATAREFS. */
+/* Dump into FILE all the data references from DATAREFS. */
-void
+void
dump_data_references (FILE *file, VEC (data_reference_p, heap) *datarefs)
{
unsigned int i;
dump_data_reference (file, dr);
}
-/* Dump into STDERR all the data references from DATAREFS. */
+/* Dump into STDERR all the data references from DATAREFS. */
-void
+void
debug_data_references (VEC (data_reference_p, heap) *datarefs)
{
dump_data_references (stderr, datarefs);
}
-/* Dump to STDERR all the dependence relations from DDRS. */
+/* Dump to STDERR all the dependence relations from DDRS. */
-void
+void
debug_data_dependence_relations (VEC (ddr_p, heap) *ddrs)
{
dump_data_dependence_relations (stderr, ddrs);
}
-/* Dump into FILE all the dependence relations from DDRS. */
+/* Dump into FILE all the dependence relations from DDRS. */
-void
-dump_data_dependence_relations (FILE *file,
+void
+dump_data_dependence_relations (FILE *file,
VEC (ddr_p, heap) *ddrs)
{
unsigned int i;
/* Print to STDERR the data_reference DR. */
-void
+void
debug_data_reference (struct data_reference *dr)
{
dump_data_reference (stderr, dr);
/* Dump function for a DATA_REFERENCE structure. */
-void
-dump_data_reference (FILE *outf,
+void
+dump_data_reference (FILE *outf,
struct data_reference *dr)
{
unsigned int i;
-
+
fprintf (outf, "(Data Ref: \n stmt: ");
print_gimple_stmt (outf, DR_STMT (dr), 0, 0);
fprintf (outf, " ref: ");
print_generic_stmt (outf, DR_REF (dr), 0);
fprintf (outf, " base_object: ");
print_generic_stmt (outf, DR_BASE_OBJECT (dr), 0);
-
+
for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++)
{
fprintf (outf, " Access function %d: ", i);
/* Dump function for a SUBSCRIPT structure. */
-void
+void
dump_subscript (FILE *outf, struct subscript *subscript)
{
conflict_function *cf = SUB_CONFLICTS_IN_A (subscript);
fprintf (outf, " last_conflict: ");
print_generic_stmt (outf, last_iteration, 0);
}
-
+
cf = SUB_CONFLICTS_IN_B (subscript);
fprintf (outf, " iterations_that_access_an_element_twice_in_B: ");
dump_conflict_function (outf, cf);
/* Debug version. */
-void
+void
debug_data_dependence_relation (struct data_dependence_relation *ddr)
{
dump_data_dependence_relation (stderr, ddr);
/* Dump function for a DATA_DEPENDENCE_RELATION structure. */
-void
-dump_data_dependence_relation (FILE *outf,
+void
+dump_data_dependence_relation (FILE *outf,
struct data_dependence_relation *ddr)
{
struct data_reference *dra, *drb;
if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
fprintf (outf, " (no dependence)\n");
-
+
else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
{
unsigned int i;
/* Dump function for a DATA_DEPENDENCE_DIRECTION structure. */
void
-dump_data_dependence_direction (FILE *file,
+dump_data_dependence_direction (FILE *file,
enum data_dependence_direction dir)
{
switch (dir)
{
- case dir_positive:
+ case dir_positive:
fprintf (file, "+");
break;
-
+
case dir_negative:
fprintf (file, "-");
break;
-
+
case dir_equal:
fprintf (file, "=");
break;
-
+
case dir_positive_or_negative:
fprintf (file, "+-");
break;
-
- case dir_positive_or_equal:
+
+ case dir_positive_or_equal:
fprintf (file, "+=");
break;
-
- case dir_negative_or_equal:
+
+ case dir_negative_or_equal:
fprintf (file, "-=");
break;
-
- case dir_star:
- fprintf (file, "*");
+
+ case dir_star:
+ fprintf (file, "*");
break;
-
- default:
+
+ default:
break;
}
}
dependence vectors, or in other words the number of loops in the
considered nest. */
-void
+void
dump_dist_dir_vectors (FILE *file, VEC (ddr_p, heap) *ddrs)
{
unsigned int i, j;
/* Dumps the data dependence relations DDRS in FILE. */
-void
+void
dump_ddrs (FILE *file, VEC (ddr_p, heap) *ddrs)
{
unsigned int i;
return build_fold_addr_expr (TREE_OPERAND (addr, 0));
}
-/* Analyzes the behavior of the memory reference DR in the innermost loop or
+/* Analyzes the behavior of the memory reference DR in the innermost loop or
basic block that contains it. Returns true if analysis succeed or false
otherwise. */
base = build_fold_addr_expr (base);
if (in_loop)
{
- if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv,
+ if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv,
false))
{
if (dump_file && (dump_flags & TDF_DETAILS))
tree ref = unshare_expr (DR_REF (dr)), aref = ref, op;
tree base, off, access_fn = NULL_TREE;
basic_block before_loop = NULL;
-
+
if (nest)
before_loop = block_before_loop (nest);
-
+
while (handled_component_p (aref))
{
if (TREE_CODE (aref) == ARRAY_REF)
TREE_OPERAND (aref, 1) = build_int_cst (TREE_TYPE (op), 0);
}
-
+
aref = TREE_OPERAND (aref, 0);
}
fprintf (dump_file, "\n");
}
- return dr;
+ return dr;
}
/* Returns true if FNA == FNB. */
VEC_quick_push (tree, ret,
fold_build2 (op, type,
- VEC_index (tree, fna, i),
+ VEC_index (tree, fna, i),
VEC_index (tree, fnb, i)));
}
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
{
unsigned int i;
-
+
for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
{
struct subscript *subscript;
-
+
subscript = DDR_SUBSCRIPT (ddr, i);
cf_a = SUB_CONFLICTS_IN_A (subscript);
cf_b = SUB_CONFLICTS_IN_B (subscript);
return;
}
diff = affine_fn_minus (fn_a, fn_b);
-
+
if (affine_function_constant_p (diff))
SUB_DISTANCE (subscript) = affine_function_base (diff);
else
&& TREE_CODE (addr_b) == ADDR_EXPR)
return TREE_OPERAND (addr_a, 0) == TREE_OPERAND (addr_b, 0);
- /* An instruction writing through a restricted pointer is "independent" of any
- instruction reading or writing through a different restricted pointer,
+ /* An instruction writing through a restricted pointer is "independent" of any
+ instruction reading or writing through a different restricted pointer,
in the same block/scope. */
type_a = TREE_TYPE (addr_a);
if (TREE_CODE (addr_b) == SSA_NAME)
decl_b = SSA_NAME_VAR (addr_b);
- if (TYPE_RESTRICT (type_a) && TYPE_RESTRICT (type_b)
+ if (TYPE_RESTRICT (type_a) && TYPE_RESTRICT (type_b)
&& (!DR_IS_READ (a) || !DR_IS_READ (b))
&& decl_a && DECL_P (decl_a)
&& decl_b && DECL_P (decl_b)
size of the classic distance/direction vectors. */
static struct data_dependence_relation *
-initialize_data_dependence_relation (struct data_reference *a,
+initialize_data_dependence_relation (struct data_reference *a,
struct data_reference *b,
VEC (loop_p, heap) *loop_nest)
{
struct data_dependence_relation *res;
unsigned int i;
-
+
res = XNEW (struct data_dependence_relation);
DDR_A (res) = a;
DDR_B (res) = b;
if (a == NULL || b == NULL)
{
- DDR_ARE_DEPENDENT (res) = chrec_dont_know;
+ DDR_ARE_DEPENDENT (res) = chrec_dont_know;
return res;
- }
+ }
/* If the data references do not alias, then they are independent. */
if (!dr_may_alias_p (a, b))
{
- DDR_ARE_DEPENDENT (res) = chrec_known;
+ DDR_ARE_DEPENDENT (res) = chrec_known;
return res;
}
whether they alias or not. */
if (!operand_equal_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b), 0))
{
- DDR_ARE_DEPENDENT (res) = chrec_dont_know;
+ DDR_ARE_DEPENDENT (res) = chrec_dont_know;
return res;
}
/* If the base of the object is not invariant in the loop nest, we cannot
analyze it. TODO -- in fact, it would suffice to record that there may
be arbitrary dependences in the loops where the base object varies. */
- if (loop_nest
+ if (loop_nest
&& !object_address_invariant_in_loop_p (VEC_index (loop_p, loop_nest, 0),
DR_BASE_OBJECT (a)))
{
- DDR_ARE_DEPENDENT (res) = chrec_dont_know;
+ DDR_ARE_DEPENDENT (res) = chrec_dont_know;
return res;
}
for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
{
struct subscript *subscript;
-
+
subscript = XNEW (struct subscript);
SUB_CONFLICTS_IN_A (subscript) = conflict_fn_not_known ();
SUB_CONFLICTS_IN_B (subscript) = conflict_fn_not_known ();
description. */
static inline void
-finalize_ddr_dependent (struct data_dependence_relation *ddr,
+finalize_ddr_dependent (struct data_dependence_relation *ddr,
tree chrec)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
}
- DDR_ARE_DEPENDENT (ddr) = chrec;
+ DDR_ARE_DEPENDENT (ddr) = chrec;
free_subscripts (DDR_SUBSCRIPTS (ddr));
DDR_SUBSCRIPTS (ddr) = NULL;
}
|| (evolution_function_is_constant_p (chrec_b)
&& evolution_function_is_univariate_p (chrec_a)))
return true;
-
+
if (evolution_function_is_univariate_p (chrec_a)
&& evolution_function_is_univariate_p (chrec_b))
{
case POLYNOMIAL_CHREC:
if (CHREC_VARIABLE (chrec_a) != CHREC_VARIABLE (chrec_b))
return false;
-
+
default:
return true;
}
-
+
default:
return true;
}
}
-
+
return false;
}
gcc_assert (0 < n && n <= MAX_DIM);
va_start(ap, n);
-
+
ret->n = n;
for (i = 0; i < n; i++)
ret->fns[i] = va_arg (ap, affine_fn);
CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)). */
-static void
-analyze_ziv_subscript (tree chrec_a,
- tree chrec_b,
+static void
+analyze_ziv_subscript (tree chrec_a,
+ tree chrec_b,
conflict_function **overlaps_a,
- conflict_function **overlaps_b,
+ conflict_function **overlaps_b,
tree *last_conflicts)
{
tree type, difference;
dependence_stats.num_ziv++;
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(analyze_ziv_subscript \n");
chrec_a = chrec_convert (type, chrec_a, NULL);
chrec_b = chrec_convert (type, chrec_b, NULL);
difference = chrec_fold_minus (type, chrec_a, chrec_b);
-
+
switch (TREE_CODE (difference))
{
case INTEGER_CST:
dependence_stats.num_ziv_independent++;
}
break;
-
+
default:
- /* We're not sure whether the indexes overlap. For the moment,
+ /* We're not sure whether the indexes overlap. For the moment,
conservatively answer "don't know". */
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "ziv test failed: difference is non-integer.\n");
dependence_stats.num_ziv_unimplemented++;
break;
}
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
}
return hwi_nit < 0 ? -1 : hwi_nit;
}
-
+
/* Similar to estimated_loop_iterations, but returns the estimate as a tree,
and only if it fits to the int type. If this is not the case, or the
estimate on the number of iterations of LOOP could not be derived, returns
CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)). */
static void
-analyze_siv_subscript_cst_affine (tree chrec_a,
+analyze_siv_subscript_cst_affine (tree chrec_a,
tree chrec_b,
- conflict_function **overlaps_a,
- conflict_function **overlaps_b,
+ conflict_function **overlaps_a,
+ conflict_function **overlaps_b,
tree *last_conflicts)
{
bool value0, value1, value2;
chrec_a = chrec_convert (type, chrec_a, NULL);
chrec_b = chrec_convert (type, chrec_b, NULL);
difference = chrec_fold_minus (type, initial_condition (chrec_b), chrec_a);
-
+
if (!chrec_is_positive (initial_condition (difference), &value0))
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "siv test failed: chrec is not positive.\n");
+ fprintf (dump_file, "siv test failed: chrec is not positive.\n");
dependence_stats.num_siv_unimplemented++;
*overlaps_a = conflict_fn_not_known ();
fprintf (dump_file, "siv test failed: chrec not positive.\n");
*overlaps_a = conflict_fn_not_known ();
- *overlaps_b = conflict_fn_not_known ();
+ *overlaps_b = conflict_fn_not_known ();
*last_conflicts = chrec_dont_know;
dependence_stats.num_siv_unimplemented++;
return;
{
if (value1 == true)
{
- /* Example:
+ /* Example:
chrec_a = 12
chrec_b = {10, +, 1}
*/
-
+
if (tree_fold_divides_p (CHREC_RIGHT (chrec_b), difference))
{
HOST_WIDE_INT numiter;
CHREC_RIGHT (chrec_b));
*overlaps_b = conflict_fn (1, affine_fn_cst (tmp));
*last_conflicts = integer_one_node;
-
+
/* Perform weak-zero siv test to see if overlap is
outside the loop bounds. */
*last_conflicts = integer_zero_node;
dependence_stats.num_siv_independent++;
return;
- }
+ }
dependence_stats.num_siv_dependent++;
return;
}
-
+
/* When the step does not divide the difference, there are
no overlaps. */
else
{
*overlaps_a = conflict_fn_no_dependence ();
- *overlaps_b = conflict_fn_no_dependence ();
+ *overlaps_b = conflict_fn_no_dependence ();
*last_conflicts = integer_zero_node;
dependence_stats.num_siv_independent++;
return;
}
}
-
+
else
{
- /* Example:
+ /* Example:
chrec_a = 12
chrec_b = {10, +, -1}
-
+
In this case, chrec_a will not overlap with chrec_b. */
*overlaps_a = conflict_fn_no_dependence ();
*overlaps_b = conflict_fn_no_dependence ();
}
}
}
- else
+ else
{
if (!chrec_is_positive (CHREC_RIGHT (chrec_b), &value2))
{
fprintf (dump_file, "siv test failed: chrec not positive.\n");
*overlaps_a = conflict_fn_not_known ();
- *overlaps_b = conflict_fn_not_known ();
+ *overlaps_b = conflict_fn_not_known ();
*last_conflicts = chrec_dont_know;
dependence_stats.num_siv_unimplemented++;
return;
{
if (value2 == false)
{
- /* Example:
+ /* Example:
chrec_a = 3
chrec_b = {10, +, -1}
*/
*last_conflicts = integer_zero_node;
dependence_stats.num_siv_independent++;
return;
- }
+ }
dependence_stats.num_siv_dependent++;
return;
}
-
+
/* When the step does not divide the difference, there
are no overlaps. */
else
{
*overlaps_a = conflict_fn_no_dependence ();
- *overlaps_b = conflict_fn_no_dependence ();
+ *overlaps_b = conflict_fn_no_dependence ();
*last_conflicts = integer_zero_node;
dependence_stats.num_siv_independent++;
return;
}
else
{
- /* Example:
- chrec_a = 3
+ /* Example:
+ chrec_a = 3
chrec_b = {4, +, 1}
-
+
In this case, chrec_a will not overlap with chrec_b. */
*overlaps_a = conflict_fn_no_dependence ();
*overlaps_b = conflict_fn_no_dependence ();
#define FLOOR_DIV(x,y) ((x) / (y))
-/* Solves the special case of the Diophantine equation:
+/* Solves the special case of the Diophantine equation:
| {0, +, STEP_A}_x (OVERLAPS_A) = {0, +, STEP_B}_y (OVERLAPS_B)
Computes the descriptions OVERLAPS_A and OVERLAPS_B. NITER is the
constructed as evolutions in dimension DIM. */
static void
-compute_overlap_steps_for_affine_univar (int niter, int step_a, int step_b,
+compute_overlap_steps_for_affine_univar (int niter, int step_a, int step_b,
affine_fn *overlaps_a,
- affine_fn *overlaps_b,
+ affine_fn *overlaps_b,
tree *last_conflicts, int dim)
{
if (((step_a > 0 && step_b > 0)
else
*last_conflicts = chrec_dont_know;
- *overlaps_a = affine_fn_univar (integer_zero_node, dim,
+ *overlaps_a = affine_fn_univar (integer_zero_node, dim,
build_int_cst (NULL_TREE,
step_overlaps_a));
- *overlaps_b = affine_fn_univar (integer_zero_node, dim,
- build_int_cst (NULL_TREE,
+ *overlaps_b = affine_fn_univar (integer_zero_node, dim,
+ build_int_cst (NULL_TREE,
step_overlaps_b));
}
/* Solves the special case of a Diophantine equation where CHREC_A is
an affine bivariate function, and CHREC_B is an affine univariate
- function. For example,
+ function. For example,
| {{0, +, 1}_x, +, 1335}_y = {0, +, 1336}_z
-
- has the following overlapping functions:
+
+ has the following overlapping functions:
| x (t, u, v) = {{0, +, 1336}_t, +, 1}_v
| y (t, u, v) = {{0, +, 1336}_u, +, 1}_v
a common benchmark. Implement the general algorithm. */
static void
-compute_overlap_steps_for_affine_1_2 (tree chrec_a, tree chrec_b,
+compute_overlap_steps_for_affine_1_2 (tree chrec_a, tree chrec_b,
conflict_function **overlaps_a,
- conflict_function **overlaps_b,
+ conflict_function **overlaps_b,
tree *last_conflicts)
{
bool xz_p, yz_p, xyz_p;
step_y = int_cst_value (CHREC_RIGHT (chrec_a));
step_z = int_cst_value (CHREC_RIGHT (chrec_b));
- niter_x =
+ niter_x =
estimated_loop_iterations_int (get_chrec_loop (CHREC_LEFT (chrec_a)),
false);
niter_y = estimated_loop_iterations_int (get_chrec_loop (chrec_a), false);
niter_z = estimated_loop_iterations_int (get_chrec_loop (chrec_b), false);
-
+
if (niter_x < 0 || niter_y < 0 || niter_z < 0)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "overlap steps test failed: no iteration counts.\n");
-
+
*overlaps_a = conflict_fn_not_known ();
*overlaps_b = conflict_fn_not_known ();
*last_conflicts = chrec_dont_know;
parameters, because it uses lambda matrices of integers. */
static void
-analyze_subscript_affine_affine (tree chrec_a,
+analyze_subscript_affine_affine (tree chrec_a,
tree chrec_b,
- conflict_function **overlaps_a,
- conflict_function **overlaps_b,
+ conflict_function **overlaps_a,
+ conflict_function **overlaps_b,
tree *last_conflicts)
{
unsigned nb_vars_a, nb_vars_b, dim;
}
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(analyze_subscript_affine_affine \n");
-
+
/* For determining the initial intersection, we have to solve a
Diophantine equation. This is the most time consuming part.
-
+
For answering to the question: "Is there a dependence?" we have
to prove that there exists a solution to the Diophantine
equation, and that the solution is in the iteration domain,
gamma = init_b - init_a;
/* Don't do all the hard work of solving the Diophantine equation
- when we already know the solution: for example,
+ when we already know the solution: for example,
| {3, +, 1}_1
| {3, +, 4}_2
| gamma = 3 - 3 = 0.
- Then the first overlap occurs during the first iterations:
+ Then the first overlap occurs during the first iterations:
| {3, +, 1}_1 ({0, +, 4}_x) = {3, +, 4}_2 ({0, +, 1}_x)
*/
if (gamma == 0)
step_a = int_cst_value (CHREC_RIGHT (chrec_a));
step_b = int_cst_value (CHREC_RIGHT (chrec_b));
- compute_overlap_steps_for_affine_univar (niter, step_a, step_b,
- &ova, &ovb,
+ compute_overlap_steps_for_affine_univar (niter, step_a, step_b,
+ &ova, &ovb,
last_conflicts, 1);
*overlaps_a = conflict_fn (1, ova);
*overlaps_b = conflict_fn (1, ovb);
|| (A[0][0] < 0 && -A[1][0] < 0)))
{
/* The solutions are given by:
- |
+ |
| [GAMMA/GCD_ALPHA_BETA t].[u11 u12] = [x0]
| [u21 u22] [y0]
-
+
For a given integer t. Using the following variables,
-
+
| i0 = u11 * gamma / gcd_alpha_beta
| j0 = u12 * gamma / gcd_alpha_beta
| i1 = u21
| j1 = u22
-
+
the solutions are:
-
- | x0 = i0 + i1 * t,
+
+ | x0 = i0 + i1 * t,
| y0 = j0 + j1 * t. */
HOST_WIDE_INT i0, j0, i1, j1;
if ((i1 == 0 && i0 < 0)
|| (j1 == 0 && j0 < 0))
{
- /* There is no solution.
- FIXME: The case "i0 > nb_iterations, j0 > nb_iterations"
- falls in here, but for the moment we don't look at the
+ /* There is no solution.
+ FIXME: The case "i0 > nb_iterations, j0 > nb_iterations"
+ falls in here, but for the moment we don't look at the
upper bound of the iteration domain. */
*overlaps_a = conflict_fn_no_dependence ();
*overlaps_b = conflict_fn_no_dependence ();
*last_conflicts = chrec_dont_know;
}
-end_analyze_subs_aa:
+end_analyze_subs_aa:
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " (overlaps_a = ");
determining the dependence relation between chrec_a and chrec_b,
that contain symbols. This function modifies chrec_a and chrec_b
such that the analysis result is the same, and such that they don't
- contain symbols, and then can safely be passed to the analyzer.
+ contain symbols, and then can safely be passed to the analyzer.
Example: The analysis of the following tuples of evolutions produce
the same results: {x+1, +, 1}_1 vs. {x+3, +, 1}_1, and {-2, +, 1}_1
vs. {0, +, 1}_1
-
+
{x+1, +, 1}_1 ({2, +, 1}_1) = {x+3, +, 1}_1 ({0, +, 1}_1)
{-2, +, 1}_1 ({2, +, 1}_1) = {0, +, 1}_1 ({0, +, 1}_1)
*/
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "can_use_subscript_aff_aff_for_symbolic \n");
- *chrec_a = build_polynomial_chrec (CHREC_VARIABLE (*chrec_a),
+ *chrec_a = build_polynomial_chrec (CHREC_VARIABLE (*chrec_a),
diff, CHREC_RIGHT (*chrec_a));
right_b = chrec_convert (type, CHREC_RIGHT (*chrec_b), NULL);
*chrec_b = build_polynomial_chrec (CHREC_VARIABLE (*chrec_b),
CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)). */
static void
-analyze_siv_subscript (tree chrec_a,
+analyze_siv_subscript (tree chrec_a,
tree chrec_b,
- conflict_function **overlaps_a,
- conflict_function **overlaps_b,
+ conflict_function **overlaps_a,
+ conflict_function **overlaps_b,
tree *last_conflicts,
int loop_nest_num)
{
dependence_stats.num_siv++;
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(analyze_siv_subscript \n");
-
+
if (evolution_function_is_constant_p (chrec_a)
&& evolution_function_is_affine_in_loop (chrec_b, loop_nest_num))
- analyze_siv_subscript_cst_affine (chrec_a, chrec_b,
+ analyze_siv_subscript_cst_affine (chrec_a, chrec_b,
overlaps_a, overlaps_b, last_conflicts);
-
+
else if (evolution_function_is_affine_in_loop (chrec_a, loop_nest_num)
&& evolution_function_is_constant_p (chrec_b))
- analyze_siv_subscript_cst_affine (chrec_b, chrec_a,
+ analyze_siv_subscript_cst_affine (chrec_b, chrec_a,
overlaps_b, overlaps_a, last_conflicts);
-
+
else if (evolution_function_is_affine_in_loop (chrec_a, loop_nest_num)
&& evolution_function_is_affine_in_loop (chrec_b, loop_nest_num))
{
if (!chrec_contains_symbols (chrec_a)
&& !chrec_contains_symbols (chrec_b))
{
- analyze_subscript_affine_affine (chrec_a, chrec_b,
- overlaps_a, overlaps_b,
+ analyze_subscript_affine_affine (chrec_a, chrec_b,
+ overlaps_a, overlaps_b,
last_conflicts);
if (CF_NOT_KNOWN_P (*overlaps_a)
else
dependence_stats.num_siv_dependent++;
}
- else if (can_use_analyze_subscript_affine_affine (&chrec_a,
+ else if (can_use_analyze_subscript_affine_affine (&chrec_a,
&chrec_b))
{
- analyze_subscript_affine_affine (chrec_a, chrec_b,
- overlaps_a, overlaps_b,
+ analyze_subscript_affine_affine (chrec_a, chrec_b,
+ overlaps_a, overlaps_b,
last_conflicts);
if (CF_NOT_KNOWN_P (*overlaps_a)
*last_conflicts = chrec_dont_know;
dependence_stats.num_siv_unimplemented++;
}
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
}
CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)). */
static void
-analyze_miv_subscript (tree chrec_a,
- tree chrec_b,
- conflict_function **overlaps_a,
- conflict_function **overlaps_b,
+analyze_miv_subscript (tree chrec_a,
+ tree chrec_b,
+ conflict_function **overlaps_a,
+ conflict_function **overlaps_b,
tree *last_conflicts,
struct loop *loop_nest)
{
/* FIXME: This is a MIV subscript, not yet handled.
- Example: (A[{1, +, 1}_1] vs. A[{1, +, 1}_2]) that comes from
- (A[i] vs. A[j]).
-
+ Example: (A[{1, +, 1}_1] vs. A[{1, +, 1}_2]) that comes from
+ (A[i] vs. A[j]).
+
In the SIV test we had to solve a Diophantine equation with two
variables. In the MIV case we have to solve a Diophantine
equation with 2*n variables (if the subscript uses n IVs).
chrec_a = chrec_convert (type, chrec_a, NULL);
chrec_b = chrec_convert (type, chrec_b, NULL);
difference = chrec_fold_minus (type, chrec_a, chrec_b);
-
+
if (eq_evolutions_p (chrec_a, chrec_b))
{
/* Access functions are the same: all the elements are accessed
(get_chrec_loop (chrec_a), true);
dependence_stats.num_miv_dependent++;
}
-
+
else if (evolution_function_is_constant_p (difference)
/* For the moment, the following is verified:
evolution_function_is_affine_multivariate_p (chrec_a,
&& !gcd_of_steps_may_divide_p (chrec_a, difference))
{
/* testsuite/.../ssa-chrec-33.c
- {{21, +, 2}_1, +, -2}_2 vs. {{20, +, 2}_1, +, -2}_2
-
+ {{21, +, 2}_1, +, -2}_2 vs. {{20, +, 2}_1, +, -2}_2
+
The difference is 1, and all the evolution steps are multiples
of 2, consequently there are no overlapping elements. */
*overlaps_a = conflict_fn_no_dependence ();
*last_conflicts = integer_zero_node;
dependence_stats.num_miv_independent++;
}
-
+
else if (evolution_function_is_affine_multivariate_p (chrec_a, loop_nest->num)
&& !chrec_contains_symbols (chrec_a)
&& evolution_function_is_affine_multivariate_p (chrec_b, loop_nest->num)
/* testsuite/.../ssa-chrec-35.c
{0, +, 1}_2 vs. {0, +, 1}_3
the overlapping elements are respectively located at iterations:
- {0, +, 1}_x and {0, +, 1}_x,
- in other words, we have the equality:
+ {0, +, 1}_x and {0, +, 1}_x,
+ in other words, we have the equality:
{0, +, 1}_2 ({0, +, 1}_x) = {0, +, 1}_3 ({0, +, 1}_x)
-
- Other examples:
- {{0, +, 1}_1, +, 2}_2 ({0, +, 1}_x, {0, +, 1}_y) =
+
+ Other examples:
+ {{0, +, 1}_1, +, 2}_2 ({0, +, 1}_x, {0, +, 1}_y) =
{0, +, 1}_1 ({{0, +, 1}_x, +, 2}_y)
- {{0, +, 2}_1, +, 3}_2 ({0, +, 1}_y, {0, +, 1}_x) =
+ {{0, +, 2}_1, +, 3}_2 ({0, +, 1}_y, {0, +, 1}_x) =
{{0, +, 3}_1, +, 2}_2 ({0, +, 1}_x, {0, +, 1}_y)
*/
- analyze_subscript_affine_affine (chrec_a, chrec_b,
+ analyze_subscript_affine_affine (chrec_a, chrec_b,
overlaps_a, overlaps_b, last_conflicts);
if (CF_NOT_KNOWN_P (*overlaps_a)
else
dependence_stats.num_miv_dependent++;
}
-
+
else
{
/* When the analysis is too difficult, answer "don't know". */
*last_conflicts = chrec_dont_know;
dependence_stats.num_miv_unimplemented++;
}
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
}
with respect to LOOP_NEST. OVERLAP_ITERATIONS_A and
OVERLAP_ITERATIONS_B are initialized with two functions that
describe the iterations that contain conflicting elements.
-
+
Remark: For an integer k >= 0, the following equality is true:
-
+
CHREC_A (OVERLAP_ITERATIONS_A (k)) == CHREC_B (OVERLAP_ITERATIONS_B (k)).
*/
-static void
-analyze_overlapping_iterations (tree chrec_a,
- tree chrec_b,
- conflict_function **overlap_iterations_a,
- conflict_function **overlap_iterations_b,
+static void
+analyze_overlapping_iterations (tree chrec_a,
+ tree chrec_b,
+ conflict_function **overlap_iterations_a,
+ conflict_function **overlap_iterations_b,
tree *last_conflicts, struct loop *loop_nest)
{
unsigned int lnn = loop_nest->num;
dependence_stats.num_subscript_tests++;
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "(analyze_overlapping_iterations \n");
|| chrec_contains_undetermined (chrec_b))
{
dependence_stats.num_subscript_undetermined++;
-
+
*overlap_iterations_a = conflict_fn_not_known ();
*overlap_iterations_b = conflict_fn_not_known ();
}
- /* If they are the same chrec, and are affine, they overlap
+ /* If they are the same chrec, and are affine, they overlap
on every iteration. */
else if (eq_evolutions_p (chrec_a, chrec_b)
&& evolution_function_is_affine_multivariate_p (chrec_a, lnn))
/* If they aren't the same, and aren't affine, we can't do anything
yet. */
- else if ((chrec_contains_symbols (chrec_a)
+ else if ((chrec_contains_symbols (chrec_a)
|| chrec_contains_symbols (chrec_b))
&& (!evolution_function_is_affine_multivariate_p (chrec_a, lnn)
|| !evolution_function_is_affine_multivariate_p (chrec_b, lnn)))
}
else if (ziv_subscript_p (chrec_a, chrec_b))
- analyze_ziv_subscript (chrec_a, chrec_b,
+ analyze_ziv_subscript (chrec_a, chrec_b,
overlap_iterations_a, overlap_iterations_b,
last_conflicts);
-
+
else if (siv_subscript_p (chrec_a, chrec_b))
- analyze_siv_subscript (chrec_a, chrec_b,
- overlap_iterations_a, overlap_iterations_b,
+ analyze_siv_subscript (chrec_a, chrec_b,
+ overlap_iterations_a, overlap_iterations_b,
last_conflicts, lnn);
-
+
else
- analyze_miv_subscript (chrec_a, chrec_b,
+ analyze_miv_subscript (chrec_a, chrec_b,
overlap_iterations_a, overlap_iterations_b,
last_conflicts, loop_nest);
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " (overlap_iterations_a = ");
access_fn_a = DR_ACCESS_FN (ddr_a, i);
access_fn_b = DR_ACCESS_FN (ddr_b, i);
- if (TREE_CODE (access_fn_a) == POLYNOMIAL_CHREC
+ if (TREE_CODE (access_fn_a) == POLYNOMIAL_CHREC
&& TREE_CODE (access_fn_b) == POLYNOMIAL_CHREC)
{
int dist, index;
non_affine_dependence_relation (ddr);
return false;
}
-
+
dist = int_cst_value (SUB_DISTANCE (subscript));
/* This is the subscript coupling test. If we have already
| T[j][i] = t + 2; // B
| }
- the vectors are:
+ the vectors are:
(0, 1, -1)
(1, 1, -1)
(1, -1, 1)
{
conflict_function *overlaps_a, *overlaps_b;
- analyze_overlapping_iterations (DR_ACCESS_FN (dra, i),
+ analyze_overlapping_iterations (DR_ACCESS_FN (dra, i),
DR_ACCESS_FN (drb, i),
- &overlaps_a, &overlaps_b,
+ &overlaps_a, &overlaps_b,
&last_conflicts, loop_nest);
if (CF_NOT_KNOWN_P (overlaps_a)
subscript_dependence_tester (struct data_dependence_relation *ddr,
struct loop *loop_nest)
{
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(subscript_dependence_tester \n");
-
+
if (subscript_dependence_tester_1 (ddr, DDR_A (ddr), DDR_B (ddr), loop_nest))
dependence_stats.num_dependence_dependent++;
/* Returns true when all the access functions of A are affine or
constant with respect to LOOP_NEST. */
-static bool
+static bool
access_functions_are_affine_or_constant_p (const struct data_reference *a,
const struct loop *loop_nest)
{
if (!evolution_function_is_invariant_p (t, loop_nest->num)
&& !evolution_function_is_affine_multivariate_p (t, loop_nest->num))
return false;
-
+
return true;
}
ACCESS_FUN is expected to be an affine chrec. */
static bool
-init_omega_eq_with_af (omega_pb pb, unsigned eq,
- unsigned int offset, tree access_fun,
+init_omega_eq_with_af (omega_pb pb, unsigned eq,
+ unsigned int offset, tree access_fun,
struct data_dependence_relation *ddr)
{
switch (TREE_CODE (access_fun))
DDR_INNER_LOOP (ddr) = MAX (DDR_INNER_LOOP (ddr), var_idx);
if (offset == 0)
- pb->eqs[eq].coef[var_idx + DDR_NB_LOOPS (ddr) + 1]
+ pb->eqs[eq].coef[var_idx + DDR_NB_LOOPS (ddr) + 1]
+= int_cst_value (right);
switch (TREE_CODE (left))
/* Set a new problem for each loop in the nest. The basis is the
problem that we have initialized until now. On top of this we
add new constraints. */
- for (i = 0; i <= DDR_INNER_LOOP (ddr)
+ for (i = 0; i <= DDR_INNER_LOOP (ddr)
&& VEC_iterate (loop_p, DDR_LOOP_NEST (ddr), i, loopi); i++)
{
int dist = 0;
/* Reduce the constraint system, and test that the current
problem is feasible. */
res = omega_simplify_problem (copy);
- if (res == omega_false
+ if (res == omega_false
|| res == omega_unknown
|| copy->num_geqs > (int) DDR_NB_LOOPS (ddr))
goto next_problem;
copy->eqs[eq].coef[0] = -1;
res = omega_simplify_problem (copy);
- if (res == omega_false
+ if (res == omega_false
|| res == omega_unknown
|| copy->num_geqs > (int) DDR_NB_LOOPS (ddr))
goto next_problem;
/* GCD test. */
if (DDR_NB_LOOPS (ddr) != 0 && pb->eqs[eq].coef[0]
- && !int_divides_p (lambda_vector_gcd
+ && !int_divides_p (lambda_vector_gcd
((lambda_vector) &(pb->eqs[eq].coef[1]),
2 * DDR_NB_LOOPS (ddr)),
pb->eqs[eq].coef[0]))
removed by the solver: the "dx"
- coef[nb_loops + 1, 2*nb_loops] are the loop variables: "loop_x".
*/
- for (i = 0; i <= DDR_INNER_LOOP (ddr)
+ for (i = 0; i <= DDR_INNER_LOOP (ddr)
&& VEC_iterate (loop_p, DDR_LOOP_NEST (ddr), i, loopi); i++)
{
HOST_WIDE_INT nbi = estimated_loop_iterations_int (loopi, false);
set MAYBE_DEPENDENT to true.
Example: for setting up the dependence system corresponding to the
- conflicting accesses
+ conflicting accesses
| loop_i
| loop_j
| ... A[2*j, 2*(i + j)]
| endloop_j
| endloop_i
-
+
the following constraints come from the iteration domain:
0 <= i <= Ni
}
}
- return true;
+ return true;
}
/* This computes the affine dependence relation between A and B with
respect to LOOP_NEST. CHREC_KNOWN is used for representing the
independence between two accesses, while CHREC_DONT_KNOW is used
for representing the unknown relation.
-
+
Note that it is possible to stop the computation of the dependence
relation the first time we detect a CHREC_KNOWN element for a given
subscript. */
{
struct data_reference *dra = DDR_A (ddr);
struct data_reference *drb = DDR_B (ddr);
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "(compute_affine_dependence\n");
else
subscript_dependence_tester (ddr, loop_nest);
}
-
+
/* As a last case, if the dependence cannot be determined, or if
the dependence is considered too difficult to determine, answer
"don't know". */
finalize_ddr_dependent (ddr, chrec_dont_know);
}
}
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
}
COMPUTE_SELF_AND_RR is FALSE, don't compute read-read and self
relations. */
-void
+void
compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
VEC (ddr_p, heap) **dependence_relations,
VEC (loop_p, heap) *loop_nest,
tree base;
op0 = gimple_assign_lhs_ptr (stmt);
op1 = gimple_assign_rhs1_ptr (stmt);
-
+
if (DECL_P (*op1)
|| (REFERENCE_CLASS_P (*op1)
&& (base = get_base_address (*op1))
{
dr = create_data_ref (nest, *ref->pos, stmt, ref->is_read);
gcc_assert (dr != NULL);
-
- /* FIXME -- data dependence analysis does not work correctly for objects
+
+ /* FIXME -- data dependence analysis does not work correctly for objects
with invariant addresses in loop nests. Let us fail here until the
problem is fixed. */
if (dr_address_invariant_p (dr) && nest)
return ret;
}
+/* Stores the data references in STMT to DATAREFS. If there is an unanalyzable
+ reference, returns false, otherwise returns true. NEST is the outermost
+ loop of the loop nest in which the references should be analyzed. */
+
+bool
+graphite_find_data_references_in_stmt (struct loop *nest, gimple stmt,
+ VEC (data_reference_p, heap) **datarefs)
+{
+ unsigned i;
+ VEC (data_ref_loc, heap) *references;
+ data_ref_loc *ref;
+ bool ret = true;
+ data_reference_p dr;
+
+ if (get_references_in_stmt (stmt, &references))
+ {
+ VEC_free (data_ref_loc, heap, references);
+ return false;
+ }
+
+ for (i = 0; VEC_iterate (data_ref_loc, references, i, ref); i++)
+ {
+ dr = create_data_ref (nest, *ref->pos, stmt, ref->is_read);
+ gcc_assert (dr != NULL);
+ VEC_safe_push (data_reference_p, heap, *datarefs, dr);
+ }
+
+ VEC_free (data_ref_loc, heap, references);
+ return ret;
+}
+
/* Search the data references in LOOP, and record the information into
DATAREFS. Returns chrec_dont_know when failing to analyze a
difficult case, returns NULL_TREE otherwise. */
TODO: This function should be made smarter so that it can handle address
arithmetic as if they were array accesses, etc. */
-tree
+tree
find_data_references_in_loop (struct loop *loop,
VEC (data_reference_p, heap) **datarefs)
{
/* Returns true when the data dependences have been computed, false otherwise.
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.
- Compute read-read and self relations if
+ DATAREFS is initialized to all the array elements contained in this loop,
+ DEPENDENCE_RELATIONS contains the relations between the data references.
+ Compute read-read and self relations if
COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE. */
bool
-compute_data_dependences_for_loop (struct loop *loop,
+compute_data_dependences_for_loop (struct loop *loop,
bool compute_self_and_read_read_dependences,
VEC (data_reference_p, heap) **datarefs,
VEC (ddr_p, heap) **dependence_relations)
memset (&dependence_stats, 0, sizeof (dependence_stats));
- /* If the loop nest is not well formed, or one of the data references
+ /* If the loop nest is not well formed, or one of the data references
is not computable, give up without spending time to compute other
dependences. */
if (!loop
{
fprintf (dump_file, "Dependence tester statistics:\n");
- fprintf (dump_file, "Number of dependence tests: %d\n",
+ fprintf (dump_file, "Number of dependence tests: %d\n",
dependence_stats.num_dependence_tests);
- fprintf (dump_file, "Number of dependence tests classified dependent: %d\n",
+ fprintf (dump_file, "Number of dependence tests classified dependent: %d\n",
dependence_stats.num_dependence_dependent);
- fprintf (dump_file, "Number of dependence tests classified independent: %d\n",
+ fprintf (dump_file, "Number of dependence tests classified independent: %d\n",
dependence_stats.num_dependence_independent);
- fprintf (dump_file, "Number of undetermined dependence tests: %d\n",
+ fprintf (dump_file, "Number of undetermined dependence tests: %d\n",
dependence_stats.num_dependence_undetermined);
- fprintf (dump_file, "Number of subscript tests: %d\n",
+ fprintf (dump_file, "Number of subscript tests: %d\n",
dependence_stats.num_subscript_tests);
- fprintf (dump_file, "Number of undetermined subscript tests: %d\n",
+ fprintf (dump_file, "Number of undetermined subscript tests: %d\n",
dependence_stats.num_subscript_undetermined);
- fprintf (dump_file, "Number of same subscript function: %d\n",
+ fprintf (dump_file, "Number of same subscript function: %d\n",
dependence_stats.num_same_subscript_function);
fprintf (dump_file, "Number of ziv tests: %d\n",
fprintf (dump_file, "Number of ziv tests returning independent: %d\n",
dependence_stats.num_ziv_independent);
fprintf (dump_file, "Number of ziv tests unimplemented: %d\n",
- dependence_stats.num_ziv_unimplemented);
+ dependence_stats.num_ziv_unimplemented);
- fprintf (dump_file, "Number of siv tests: %d\n",
+ fprintf (dump_file, "Number of siv tests: %d\n",
dependence_stats.num_siv);
fprintf (dump_file, "Number of siv tests returning dependent: %d\n",
dependence_stats.num_siv_dependent);
fprintf (dump_file, "Number of siv tests unimplemented: %d\n",
dependence_stats.num_siv_unimplemented);
- fprintf (dump_file, "Number of miv tests: %d\n",
+ fprintf (dump_file, "Number of miv tests: %d\n",
dependence_stats.num_miv);
fprintf (dump_file, "Number of miv tests returning dependent: %d\n",
dependence_stats.num_miv_dependent);
return res;
}
-/* Returns true when the data dependences for the basic block BB have been
+/* Returns true when the data dependences for the basic block BB have been
computed, false otherwise.
- DATAREFS is initialized to all the array elements contained in this basic
+ DATAREFS is initialized to all the array elements contained in this basic
block, DEPENDENCE_RELATIONS contains the relations between the data
references. Compute read-read and self relations if
COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE. */
/* Entry point (for testing only). Analyze all the data references
and the dependence relations in LOOP.
- The data references are computed first.
-
+ The data references are computed first.
+
A relation on these nodes is represented by a complete graph. Some
of the relations could be of no interest, thus the relations can be
computed on demand.
-
+
In the following function we compute all the relations. This is
just a first implementation that is here for:
- - for showing how to ask for the dependence relations,
+ - for showing how to ask for the dependence relations,
- for the debugging the whole dependence graph,
- for the dejagnu testcases and maintenance.
-
+
It is possible to ask only for a part of the graph, avoiding to
compute the whole dependence graph. The computed dependences are
stored in a knowledge base (KB) such that later queries don't
recompute the same information. The implementation of this KB is
transparent to the optimizer, and thus the KB can be changed with a
more efficient implementation, or the KB could be disabled. */
-static void
+static void
analyze_all_data_dependences (struct loop *loop)
{
unsigned int i;
int nb_data_refs = 10;
- VEC (data_reference_p, heap) *datarefs =
+ VEC (data_reference_p, heap) *datarefs =
VEC_alloc (data_reference_p, heap, nb_data_refs);
- VEC (ddr_p, heap) *dependence_relations =
+ VEC (ddr_p, heap) *dependence_relations =
VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs);
/* Compute DDs on the whole function. */
{
if (chrec_contains_undetermined (DDR_ARE_DEPENDENT (ddr)))
nb_top_relations++;
-
+
else if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
nb_bot_relations++;
-
- else
+
+ else
nb_chrec_relations++;
}
-
+
gather_stats_on_scev_database ();
}
}
/* Free the memory used by the data dependence relations from
DEPENDENCE_RELATIONS. */
-void
+void
free_dependence_relations (VEC (ddr_p, heap) *dependence_relations)
{
unsigned int i;
struct vertex *v = &(rdg->vertices[i]);
struct graph_edge *e;
- fprintf (file, "(vertex %d: (%s%s) (in:", i,
+ fprintf (file, "(vertex %d: (%s%s) (in:", i,
RDG_MEM_WRITE_STMT (rdg, i) ? "w" : "",
RDG_MEM_READS_STMT (rdg, i) ? "r" : "");
{
use_operand_p imm_use_p;
imm_use_iterator iterator;
-
+
FOR_EACH_IMM_USE_FAST (imm_use_p, iterator, def)
{
struct graph_edge *e;
for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++)
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
return false;
-
+
return true;
}
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,
+ compute_data_dependences_for_loop (loop,
false,
&datarefs,
&dependence_relations);
/* Returns the index of PARAMETER in the parameters vector of the
ACCESS_MATRIX. If PARAMETER does not exist return -1. */
-int
-access_matrix_get_index_for_parameter (tree parameter,
+int
+access_matrix_get_index_for_parameter (tree parameter,
struct access_matrix *access_matrix)
{
int i;