/* Returns true iff A divides B. */
static inline bool
-tree_fold_divides_p (tree type,
- tree a,
+tree_fold_divides_p (tree a,
tree b)
{
/* Determines whether (A == gcd (A, B)). */
- return integer_zerop
- (fold_build2 (MINUS_EXPR, type, a, tree_fold_gcd (a, b)));
+ return tree_int_cst_equal (a, tree_fold_gcd (a, b));
}
/* Compute the greatest common denominator of two numbers using
else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
{
unsigned int i;
+
for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
{
fprintf (outf, " access_fn_A: ");
print_generic_stmt (outf, DR_ACCESS_FN (drb, i), 0);
dump_subscript (outf, DDR_SUBSCRIPT (ddr, i));
}
- if (DDR_DIST_VECT (ddr))
+
+ for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
{
- fprintf (outf, " distance_vect: ");
- print_lambda_vector (outf, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
+ fprintf (outf, " distance_vector: ");
+ print_lambda_vector (outf, DDR_DIST_VECT (ddr, i),
+ DDR_SIZE_VECT (ddr));
}
- if (DDR_DIR_VECT (ddr))
+
+ for (i = 0; i < DDR_NUM_DIR_VECTS (ddr); i++)
{
- fprintf (outf, " direction_vect: ");
- print_lambda_vector (outf, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
+ fprintf (outf, " direction_vector: ");
+ print_lambda_vector (outf, DDR_DIR_VECT (ddr, i),
+ DDR_SIZE_VECT (ddr));
}
}
void
dump_dist_dir_vectors (FILE *file, varray_type ddrs)
{
- unsigned int i;
+ unsigned int i, j;
for (i = 0; i < VARRAY_ACTIVE_SIZE (ddrs); i++)
{
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE
&& DDR_AFFINE_P (ddr))
{
- fprintf (file, "DISTANCE_V (");
- print_lambda_vector (file, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
- fprintf (file, ")\n");
- fprintf (file, "DIRECTION_V (");
- print_lambda_vector (file, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
- fprintf (file, ")\n");
+ for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
+ {
+ fprintf (file, "DISTANCE_V (");
+ print_lambda_vector (file, DDR_DIST_VECT (ddr, j),
+ DDR_SIZE_VECT (ddr));
+ fprintf (file, ")\n");
+ }
+
+ for (j = 0; j < DDR_NUM_DIR_VECTS (ddr); j++)
+ {
+ fprintf (file, "DIRECTION_V (");
+ print_lambda_vector (file, DDR_DIR_VECT (ddr, j),
+ DDR_SIZE_VECT (ddr));
+ fprintf (file, ")\n");
+ }
}
}
fprintf (file, "\n\n");
/* Given an ARRAY_REF node REF, records its access functions.
Example: given A[i][3], record in ACCESS_FNS the opnd1 function,
i.e. the constant "3", then recursively call the function on opnd0,
- i.e. the ARRAY_REF "A[i]". The function returns the base name:
- "A". */
+ i.e. the ARRAY_REF "A[i]".
+ If ESTIMATE_ONLY is true, we just set the estimated number of loop
+ iterations, we don't store the access function.
+ The function returns the base name: "A". */
static tree
analyze_array_indexes (struct loop *loop,
VEC(tree,heap) **access_fns,
- tree ref, tree stmt)
+ tree ref, tree stmt,
+ bool estimate_only)
{
tree opnd0, opnd1;
tree access_fn;
access_fn = instantiate_parameters
(loop, analyze_scalar_evolution (loop, opnd1));
- if (chrec_contains_undetermined (loop->estimated_nb_iterations))
+ if (estimate_only
+ && chrec_contains_undetermined (loop->estimated_nb_iterations))
estimate_niter_from_size_of_data (loop, opnd0, access_fn, stmt);
-
- VEC_safe_push (tree, heap, *access_fns, access_fn);
+
+ if (!estimate_only)
+ VEC_safe_push (tree, heap, *access_fns, access_fn);
/* Recursively record other array access functions. */
if (TREE_CODE (opnd0) == ARRAY_REF)
- return analyze_array_indexes (loop, access_fns, opnd0, stmt);
+ return analyze_array_indexes (loop, access_fns, opnd0, stmt, estimate_only);
/* Return the base name of the data access. */
else
return opnd0;
}
+/* For an array reference REF contained in STMT, attempt to bound the
+ number of iterations in the loop containing STMT */
+
+void
+estimate_iters_using_array (tree stmt, tree ref)
+{
+ analyze_array_indexes (loop_containing_stmt (stmt), NULL, ref, stmt,
+ true);
+}
+
/* For a data reference REF contained in the statement STMT, initialize
a DATA_REFERENCE structure, and return it. IS_READ flag has to be
set to true when REF is in the right hand side of an
DR_REF (res) = ref;
acc_fns = VEC_alloc (tree, heap, 3);
DR_BASE_OBJECT (res) = analyze_array_indexes
- (loop_containing_stmt (stmt), &acc_fns, ref, stmt);
+ (loop_containing_stmt (stmt), &acc_fns, ref, stmt, false);
DR_TYPE (res) = ARRAY_REF_TYPE;
DR_SET_ACCESS_FNS (res, acc_fns);
DR_IS_READ (res) = is_read;
return false;
init = initial_condition_in_loop_num (access_fn, loop->num);
- if (init == expr && !expr_invariant_in_loop_p (loop, init))
+ if (!expr_invariant_in_loop_p (loop, init))
/* Not enough information: may be not loop invariant.
E.g., for a[b[i]], we get a[D], where D=b[i]. EXPR is D, its
initial_condition is D, but it depends on i - loop's induction
*constant = constant_0 ? constant_0 : constant_1;
if (invariant_0 && invariant_1)
*invariant =
- fold (build (code, TREE_TYPE (invariant_0), invariant_0, invariant_1));
+ fold_build2 (code, TREE_TYPE (invariant_0), invariant_0, invariant_1);
else
*invariant = invariant_0 ? invariant_0 : invariant_1;
}
if (constant)
{
DR_INIT (dr) = fold_convert (ssizetype, constant);
- init_cond = fold (build (TRUNC_DIV_EXPR, TREE_TYPE (constant),
- constant, type_size));
+ init_cond = fold_build2 (TRUNC_DIV_EXPR, TREE_TYPE (constant),
+ constant, type_size);
}
else
DR_INIT (dr) = init_cond = ssize_int (0);;
DDR_ARE_DEPENDENT (res) = NULL_TREE;
DDR_SUBSCRIPTS_VECTOR_INIT (res, DR_NUM_DIMENSIONS (a));
DDR_SIZE_VECT (res) = 0;
- DDR_DIST_VECT (res) = NULL;
- DDR_DIR_VECT (res) = NULL;
-
+ DDR_DIR_VECTS (res) = NULL;
+ DDR_DIST_VECTS (res) = NULL;
+
for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
{
struct subscript *subscript;
fprintf (dump_file, ")\n");
}
+/* Get the real or estimated number of iterations for LOOPNUM, whichever is
+ available. Return the number of iterations as a tree, or NULL_TREE if
+ we don't know. */
+
+static tree
+get_number_of_iters_for_loop (int loopnum)
+{
+ tree numiter = number_of_iterations_in_loop (current_loops->parray[loopnum]);
+
+ if (TREE_CODE (numiter) != INTEGER_CST)
+ numiter = current_loops->parray[loopnum]->estimated_nb_iterations;
+ if (chrec_contains_undetermined (numiter))
+ return NULL_TREE;
+ return numiter;
+}
+
/* Analyze a SIV (Single Index Variable) subscript where CHREC_A is a
constant, and CHREC_B is an affine function. *OVERLAPS_A and
*OVERLAPS_B are initialized to the functions that describe the
chrec_b = {10, +, 1}
*/
- if (tree_fold_divides_p
- (integer_type_node, CHREC_RIGHT (chrec_b), difference))
+ if (tree_fold_divides_p (CHREC_RIGHT (chrec_b), difference))
{
+ tree numiter;
+ int loopnum = CHREC_VARIABLE (chrec_b);
+
*overlaps_a = integer_zero_node;
*overlaps_b = fold_build2 (EXACT_DIV_EXPR, integer_type_node,
fold_build1 (ABS_EXPR,
difference),
CHREC_RIGHT (chrec_b));
*last_conflicts = integer_one_node;
+
+
+ /* Perform weak-zero siv test to see if overlap is
+ outside the loop bounds. */
+ numiter = get_number_of_iters_for_loop (loopnum);
+
+ if (numiter != NULL_TREE
+ && TREE_CODE (*overlaps_b) == INTEGER_CST
+ && tree_int_cst_lt (numiter, *overlaps_b))
+ {
+ *overlaps_a = chrec_known;
+ *overlaps_b = chrec_known;
+ *last_conflicts = integer_zero_node;
+ return;
+ }
return;
}
- /* When the step does not divides the difference, there are
+ /* When the step does not divide the difference, there are
no overlaps. */
else
{
chrec_a = 3
chrec_b = {10, +, -1}
*/
- if (tree_fold_divides_p
- (integer_type_node, CHREC_RIGHT (chrec_b), difference))
+ if (tree_fold_divides_p (CHREC_RIGHT (chrec_b), difference))
{
+ tree numiter;
+ int loopnum = CHREC_VARIABLE (chrec_b);
+
*overlaps_a = integer_zero_node;
- *overlaps_b = fold
- (build (EXACT_DIV_EXPR, integer_type_node, difference,
- CHREC_RIGHT (chrec_b)));
+ *overlaps_b = fold_build2 (EXACT_DIV_EXPR,
+ integer_type_node, difference,
+ CHREC_RIGHT (chrec_b));
*last_conflicts = integer_one_node;
+
+ /* Perform weak-zero siv test to see if overlap is
+ outside the loop bounds. */
+ numiter = get_number_of_iters_for_loop (loopnum);
+
+ if (numiter != NULL_TREE
+ && TREE_CODE (*overlaps_b) == INTEGER_CST
+ && tree_int_cst_lt (numiter, *overlaps_b))
+ {
+ *overlaps_a = chrec_known;
+ *overlaps_b = chrec_known;
+ *last_conflicts = integer_zero_node;
+ return;
+ }
return;
}
- /* When the step does not divides the difference, there
+ /* When the step does not divide the difference, there
are no overlaps. */
else
{
step_y = int_cst_value (CHREC_RIGHT (chrec_a));
step_z = int_cst_value (CHREC_RIGHT (chrec_b));
- numiter_x = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (CHREC_LEFT (chrec_a))]);
- numiter_y = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
- numiter_z = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (chrec_b)]);
-
- if (TREE_CODE (numiter_x) != INTEGER_CST)
- numiter_x = current_loops->parray[CHREC_VARIABLE (CHREC_LEFT (chrec_a))]
- ->estimated_nb_iterations;
- if (TREE_CODE (numiter_y) != INTEGER_CST)
- numiter_y = current_loops->parray[CHREC_VARIABLE (chrec_a)]
- ->estimated_nb_iterations;
- if (TREE_CODE (numiter_z) != INTEGER_CST)
- numiter_z = current_loops->parray[CHREC_VARIABLE (chrec_b)]
- ->estimated_nb_iterations;
-
- if (chrec_contains_undetermined (numiter_x)
- || chrec_contains_undetermined (numiter_y)
- || chrec_contains_undetermined (numiter_z)
- || TREE_CODE (numiter_x) != INTEGER_CST
- || TREE_CODE (numiter_y) != INTEGER_CST
- || TREE_CODE (numiter_z) != INTEGER_CST)
+ numiter_x = get_number_of_iters_for_loop (CHREC_VARIABLE (CHREC_LEFT (chrec_a)));
+ numiter_y = get_number_of_iters_for_loop (CHREC_VARIABLE (chrec_a));
+ numiter_z = get_number_of_iters_for_loop (CHREC_VARIABLE (chrec_b));
+
+ if (numiter_x == NULL_TREE || numiter_y == NULL_TREE
+ || numiter_z == NULL_TREE)
{
*overlaps_a = chrec_dont_know;
*overlaps_b = chrec_dont_know;
int init_a, init_b, gamma, gcd_alpha_beta;
int tau1, tau2;
lambda_matrix A, U, S;
+ tree difference = chrec_fold_minus (integer_type_node, chrec_a, chrec_b);
+ if (integer_zerop (difference))
+ {
+ /* The difference is equal to zero: the accessed index
+ overlaps for each iteration in the loop. */
+ *overlaps_a = integer_zero_node;
+ *overlaps_b = integer_zero_node;
+ *last_conflicts = chrec_dont_know;
+ return;
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "(analyze_subscript_affine_affine \n");
int niter, niter_a, niter_b;
tree numiter_a, numiter_b;
- numiter_a = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
- numiter_b = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (chrec_b)]);
-
- if (TREE_CODE (numiter_a) != INTEGER_CST)
- numiter_a = current_loops->parray[CHREC_VARIABLE (chrec_a)]
- ->estimated_nb_iterations;
- if (TREE_CODE (numiter_b) != INTEGER_CST)
- numiter_b = current_loops->parray[CHREC_VARIABLE (chrec_b)]
- ->estimated_nb_iterations;
- if (chrec_contains_undetermined (numiter_a)
- || chrec_contains_undetermined (numiter_b)
- || TREE_CODE (numiter_a) != INTEGER_CST
- || TREE_CODE (numiter_b) != INTEGER_CST)
+ numiter_a = get_number_of_iters_for_loop (CHREC_VARIABLE (chrec_a));
+ numiter_b = get_number_of_iters_for_loop (CHREC_VARIABLE (chrec_b));
+ if (numiter_a == NULL_TREE || numiter_b == NULL_TREE)
{
*overlaps_a = chrec_dont_know;
*overlaps_b = chrec_dont_know;
int niter, niter_a, niter_b;
tree numiter_a, numiter_b;
- numiter_a = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
- numiter_b = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (chrec_b)]);
-
- if (TREE_CODE (numiter_a) != INTEGER_CST)
- numiter_a = current_loops->parray[CHREC_VARIABLE (chrec_a)]
- ->estimated_nb_iterations;
- if (TREE_CODE (numiter_b) != INTEGER_CST)
- numiter_b = current_loops->parray[CHREC_VARIABLE (chrec_b)]
- ->estimated_nb_iterations;
- if (chrec_contains_undetermined (numiter_a)
- || chrec_contains_undetermined (numiter_b)
- || TREE_CODE (numiter_a) != INTEGER_CST
- || TREE_CODE (numiter_b) != INTEGER_CST)
+ numiter_a = get_number_of_iters_for_loop (CHREC_VARIABLE (chrec_a));
+ numiter_b = get_number_of_iters_for_loop (CHREC_VARIABLE (chrec_b));
+
+ if (numiter_a == NULL_TREE || numiter_b == NULL_TREE)
{
*overlaps_a = chrec_dont_know;
*overlaps_b = chrec_dont_know;
tau1 = (x0 - i0)/i1;
last_conflict = tau2 - tau1;
- *overlaps_a = build_polynomial_chrec
- (1,
- build_int_cst (NULL_TREE, x0),
- build_int_cst (NULL_TREE, i1));
- *overlaps_b = build_polynomial_chrec
- (1,
- build_int_cst (NULL_TREE, y0),
- build_int_cst (NULL_TREE, j1));
- *last_conflicts = build_int_cst (NULL_TREE, last_conflict);
+ /* If the overlap occurs outside of the bounds of the
+ loop, there is no dependence. */
+ if (x0 > niter || y0 > niter)
+
+ {
+ *overlaps_a = chrec_known;
+ *overlaps_b = chrec_known;
+ *last_conflicts = integer_zero_node;
+ }
+ else
+ {
+ *overlaps_a = build_polynomial_chrec
+ (1,
+ build_int_cst (NULL_TREE, x0),
+ build_int_cst (NULL_TREE, i1));
+ *overlaps_b = build_polynomial_chrec
+ (1,
+ build_int_cst (NULL_TREE, y0),
+ build_int_cst (NULL_TREE, j1));
+ *last_conflicts = build_int_cst (NULL_TREE, last_conflict);
+ }
}
else
{
switch (TREE_CODE (chrec))
{
case POLYNOMIAL_CHREC:
- return (tree_fold_divides_p (integer_type_node, CHREC_RIGHT (chrec), cst)
+ return (tree_fold_divides_p (CHREC_RIGHT (chrec), cst)
&& chrec_steps_divide_constant_p (CHREC_LEFT (chrec), cst));
default:
in the same order. */
*overlaps_a = integer_zero_node;
*overlaps_b = integer_zero_node;
- *last_conflicts = number_of_iterations_in_loop
- (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
+ *last_conflicts = get_number_of_iters_for_loop (CHREC_VARIABLE (chrec_a));
+
}
else if (evolution_function_is_constant_p (difference)
NB_LOOPS is the total number of loops we are considering.
FIRST_LOOP_DEPTH is the loop->depth of the first loop in the analyzed
loop nest.
- Return FALSE if the dependence relation is outside of the loop nest
- starting at FIRST_LOOP_DEPTH.
+ Return FALSE when fail to represent the data dependence as a distance
+ vector.
Return TRUE otherwise. */
static bool
{
unsigned i;
lambda_vector dist_v, init_v;
+ bool init_b = false;
+ DDR_SIZE_VECT (ddr) = nb_loops;
dist_v = lambda_vector_new (nb_loops);
init_v = lambda_vector_new (nb_loops);
lambda_vector_clear (dist_v, nb_loops);
dist_v[loop_depth] = dist;
init_v[loop_depth] = 1;
+ init_b = true;
}
}
-
+
+ /* Save the distance vector if we initialized one. */
+ if (init_b)
+ {
+ lambda_vector save_v;
+
+ /* Verify a basic constraint: classic distance vectors should always
+ be lexicographically positive. */
+ if (!lambda_vector_lexico_pos (dist_v, DDR_SIZE_VECT (ddr)))
+ {
+ if (DDR_SIZE_VECT (ddr) == 1)
+ /* This one is simple to fix, and can be fixed.
+ Multidimensional arrays cannot be fixed that simply. */
+ lambda_vector_negate (dist_v, dist_v, DDR_SIZE_VECT (ddr));
+ else
+ /* This is not valid: we need the delta test for properly
+ fixing all this. */
+ return false;
+ }
+
+ save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+ lambda_vector_copy (dist_v, save_v, DDR_SIZE_VECT (ddr));
+ VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), save_v);
+
+ /* There is nothing more to do when there are no outer loops. */
+ if (DDR_SIZE_VECT (ddr) == 1)
+ goto classic_dist_done;
+ }
+
/* There is a distance of 1 on all the outer loops:
Example: there is a dependence of distance 1 on loop_1 for the array A.
/* Get the common ancestor loop. */
lca = find_common_loop (loop_a, loop_b);
-
- lca_depth = lca->depth;
- lca_depth -= first_loop_depth;
+ lca_depth = lca->depth - first_loop_depth;
+
gcc_assert (lca_depth >= 0);
gcc_assert (lca_depth < nb_loops);
-
+
/* For each outer loop where init_v is not set, the accesses are
in dependence of distance 1 in the loop. */
- if (lca != loop_a
- && lca != loop_b
- && init_v[lca_depth] == 0)
- dist_v[lca_depth] = 1;
-
- lca = lca->outer;
-
- if (lca)
+ while (lca->depth != 0)
{
- lca_depth = lca->depth - first_loop_depth;
- while (lca->depth != 0)
- {
- /* If we're considering just a sub-nest, then don't record
- any information on the outer loops. */
- if (lca_depth < 0)
- break;
+ /* If we're considering just a sub-nest, then don't record
+ any information on the outer loops. */
+ if (lca_depth < 0)
+ break;
- gcc_assert (lca_depth < nb_loops);
+ gcc_assert (lca_depth < nb_loops);
- if (init_v[lca_depth] == 0)
- dist_v[lca_depth] = 1;
- lca = lca->outer;
- lca_depth = lca->depth - first_loop_depth;
-
+ /* If we haven't yet determined a distance for this outer
+ loop, push a new distance vector composed of the previous
+ distance, and a distance of 1 for this outer loop.
+ Example:
+
+ | loop_1
+ | loop_2
+ | A[10]
+ | endloop_2
+ | endloop_1
+
+ Saved vectors are of the form (dist_in_1, dist_in_2).
+ First, we save (0, 1), then we have to save (1, 0). */
+ if (init_v[lca_depth] == 0)
+ {
+ lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+
+ lambda_vector_copy (dist_v, save_v, DDR_SIZE_VECT (ddr));
+ save_v[lca_depth] = 1;
+ VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), save_v);
}
+
+ lca = lca->outer;
+ lca_depth = lca->depth - first_loop_depth;
}
}
-
- DDR_DIST_VECT (ddr) = dist_v;
- DDR_SIZE_VECT (ddr) = nb_loops;
+
+ classic_dist_done:;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "(build_classic_dist_vector\n");
+
+ for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
+ {
+ fprintf (dump_file, " dist_vector = (");
+ print_lambda_vector (dump_file, DDR_DIST_VECT (ddr, i),
+ DDR_SIZE_VECT (ddr));
+ fprintf (dump_file, " )\n");
+ }
+ fprintf (dump_file, ")\n");
+ }
+
return true;
}
{
unsigned i;
lambda_vector dir_v, init_v;
+ bool init_b = false;
dir_v = lambda_vector_new (nb_loops);
init_v = lambda_vector_new (nb_loops);
lambda_vector_clear (dir_v, nb_loops);
lambda_vector_clear (init_v, nb_loops);
+
+ DDR_SIZE_VECT (ddr) = nb_loops;
if (DDR_ARE_DEPENDENT (ddr) != NULL_TREE)
return true;
dir_v[loop_depth] = dir;
init_v[loop_depth] = 1;
+ init_b = true;
}
}
-
+
+ /* Save the direction vector if we initialized one. */
+ if (init_b)
+ {
+ lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+
+ lambda_vector_copy (dir_v, save_v, DDR_SIZE_VECT (ddr));
+ VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), save_v);
+ }
+
/* There is a distance of 1 on all the outer loops:
Example: there is a dependence of distance 1 on loop_1 for the array A.
gcc_assert (lca_depth >= 0);
gcc_assert (lca_depth < nb_loops);
- /* For each outer loop where init_v is not set, the accesses are
- in dependence of distance 1 in the loop. */
- if (lca != loop_a
- && lca != loop_b
- && init_v[lca_depth] == 0)
- dir_v[lca_depth] = dir_positive;
-
- lca = lca->outer;
- if (lca)
+ while (lca->depth != 0)
{
- lca_depth = lca->depth - first_loop_depth;
- while (lca->depth != 0)
+ /* If we're considering just a sub-nest, then don't record
+ any information on the outer loops. */
+ if (lca_depth < 0)
+ break;
+
+ gcc_assert (lca_depth < nb_loops);
+
+ if (init_v[lca_depth] == 0)
{
- /* If we're considering just a sub-nest, then don't record
- any information on the outer loops. */
- if (lca_depth < 0)
- break;
+ lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
- gcc_assert (lca_depth < nb_loops);
+ lambda_vector_copy (dir_v, save_v, DDR_SIZE_VECT (ddr));
+ save_v[lca_depth] = dir_positive;
+ VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), save_v);
+ }
- if (init_v[lca_depth] == 0)
- dir_v[lca_depth] = dir_positive;
- lca = lca->outer;
- lca_depth = lca->depth - first_loop_depth;
+ lca = lca->outer;
+ lca_depth = lca->depth - first_loop_depth;
- }
}
}
-
- DDR_DIR_VECT (ddr) = dir_v;
- DDR_SIZE_VECT (ddr) = nb_loops;
+
return true;
}