}
}
-/* Determine whether the given tree is an affine evolution function or not. */
+/* Determine whether CHREC is an affine evolution function in LOOPNUM. */
static inline bool
-evolution_function_is_affine_p (const_tree chrec)
+evolution_function_is_affine_in_loop (const_tree chrec, int loopnum)
{
if (chrec == NULL_TREE)
return false;
switch (TREE_CODE (chrec))
{
case POLYNOMIAL_CHREC:
- if (evolution_function_is_invariant_p (CHREC_LEFT (chrec),
- CHREC_VARIABLE (chrec))
- && evolution_function_is_invariant_p (CHREC_RIGHT (chrec),
- CHREC_VARIABLE (chrec)))
+ if (evolution_function_is_invariant_p (CHREC_LEFT (chrec), loopnum)
+ && evolution_function_is_invariant_p (CHREC_RIGHT (chrec), loopnum))
return true;
else
return false;
}
}
-/* Determine whether the given tree is an affine or constant evolution
- function. */
+/* Determine whether CHREC is an affine evolution function or not. */
static inline bool
-evolution_function_is_affine_or_constant_p (const_tree chrec)
+evolution_function_is_affine_p (const_tree chrec)
{
- return evolution_function_is_affine_p (chrec)
- || evolution_function_is_constant_p (chrec);
+ if (chrec == NULL_TREE)
+ return false;
+
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ if (evolution_function_is_invariant_p (CHREC_LEFT (chrec), CHREC_VARIABLE (chrec))
+ && evolution_function_is_invariant_p (CHREC_RIGHT (chrec), CHREC_VARIABLE (chrec)))
+ return true;
+ else
+ return false;
+
+ default:
+ return false;
+ }
}
/* Determines whether EXPR does not contains chrec expressions. */
return TREE_TYPE (chrec);
}
+static inline tree
+chrec_fold_op (enum tree_code code, tree type, tree op0, tree op1)
+{
+ switch (code)
+ {
+ case PLUS_EXPR:
+ return chrec_fold_plus (type, op0, op1);
+
+ case MINUS_EXPR:
+ return chrec_fold_minus (type, op0, op1);
+
+ case MULT_EXPR:
+ return chrec_fold_multiply (type, op0, op1);
+
+ default:
+ gcc_unreachable ();
+ }
+
+}
#endif /* GCC_TREE_CHREC_H */
{
op = TREE_OPERAND (aref, 0);
access_fn = analyze_scalar_evolution (loop, op);
- access_fn = resolve_mixers (nest, access_fn);
+ access_fn = instantiate_scev (nest, loop, access_fn);
base = initial_condition (access_fn);
split_constant_offset (base, &base, &off);
access_fn = chrec_replace_initial_condition (access_fn,
/* Helper recursive function for initializing the matrix A. Returns
the initial value of CHREC. */
-static HOST_WIDE_INT
+static tree
initialize_matrix_A (lambda_matrix A, tree chrec, unsigned index, int mult)
{
gcc_assert (chrec);
- if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
- return int_cst_value (chrec);
+ switch (TREE_CODE (chrec))
+ {
+ case POLYNOMIAL_CHREC:
+ gcc_assert (TREE_CODE (CHREC_RIGHT (chrec)) == INTEGER_CST);
+
+ A[index][0] = mult * int_cst_value (CHREC_RIGHT (chrec));
+ return initialize_matrix_A (A, CHREC_LEFT (chrec), index + 1, mult);
+
+ case PLUS_EXPR:
+ case MULT_EXPR:
+ case MINUS_EXPR:
+ {
+ tree op0 = initialize_matrix_A (A, TREE_OPERAND (chrec, 0), index, mult);
+ tree op1 = initialize_matrix_A (A, TREE_OPERAND (chrec, 1), index, mult);
+
+ return chrec_fold_op (TREE_CODE (chrec), chrec_type (chrec), op0, op1);
+ }
- A[index][0] = mult * int_cst_value (CHREC_RIGHT (chrec));
- return initialize_matrix_A (A, CHREC_LEFT (chrec), index + 1, mult);
+ case NOP_EXPR:
+ {
+ tree op = initialize_matrix_A (A, TREE_OPERAND (chrec, 0), index, mult);
+ return chrec_convert (chrec_type (chrec), op, NULL_TREE);
+ }
+
+ case INTEGER_CST:
+ return chrec;
+
+ default:
+ gcc_unreachable ();
+ return NULL_TREE;
+ }
}
#define FLOOR_DIV(x,y) ((x) / (y))
A = lambda_matrix_new (dim, 1);
S = lambda_matrix_new (dim, 1);
- init_a = initialize_matrix_A (A, chrec_a, 0, 1);
- init_b = initialize_matrix_A (A, chrec_b, nb_vars_a, -1);
+ init_a = int_cst_value (initialize_matrix_A (A, chrec_a, 0, 1));
+ init_b = int_cst_value (initialize_matrix_A (A, chrec_b, nb_vars_a, -1));
gamma = init_b - init_a;
/* Don't do all the hard work of solving the Diophantine equation
tree chrec_b,
conflict_function **overlaps_a,
conflict_function **overlaps_b,
- tree *last_conflicts)
+ tree *last_conflicts,
+ int loop_nest_num)
{
dependence_stats.num_siv++;
fprintf (dump_file, "(analyze_siv_subscript \n");
if (evolution_function_is_constant_p (chrec_a)
- && evolution_function_is_affine_p (chrec_b))
+ && evolution_function_is_affine_in_loop (chrec_b, loop_nest_num))
analyze_siv_subscript_cst_affine (chrec_a, chrec_b,
overlaps_a, overlaps_b, last_conflicts);
- else if (evolution_function_is_affine_p (chrec_a)
+ 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,
overlaps_b, overlaps_a, last_conflicts);
- else if (evolution_function_is_affine_p (chrec_a)
- && evolution_function_is_affine_p (chrec_b))
+ 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))
else if (siv_subscript_p (chrec_a, chrec_b))
analyze_siv_subscript (chrec_a, chrec_b,
overlap_iterations_a, overlap_iterations_b,
- last_conflicts);
+ last_conflicts, lnn);
else
analyze_miv_subscript (chrec_a, chrec_b,
}
/* Analyze all the parameters of the chrec, between INSTANTIATION_LOOP
- and EVOLUTION_LOOP, that were left under a symbolic form. CHREC is
- the scalar evolution to instantiate. CACHE is the cache of already
- instantiated values. FLAGS modify the way chrecs are instantiated.
+ and EVOLUTION_LOOP, that were left under a symbolic form.
+
+ CHREC is the scalar evolution to instantiate.
+
+ CACHE is the cache of already instantiated values.
+
+ FOLD_CONVERSIONS should be set to true when the conversions that
+ may wrap in signed/pointer type are folded, as long as the value of
+ the chrec is preserved.
+
SIZE_EXPR is used for computing the size of the expression to be
instantiated, and to stop if it exceeds some limit. */
-
-/* Values for FLAGS. */
-enum
-{
- INSERT_SUPERLOOP_CHRECS = 1, /* Loop invariants are replaced with chrecs
- in outer loops. */
- FOLD_CONVERSIONS = 2 /* The conversions that may wrap in
- signed/pointer type are folded, as long as the
- value of the chrec is preserved. */
-};
static tree
instantiate_scev_1 (struct loop *instantiation_loop,
struct loop *evolution_loop, tree chrec,
- int flags, htab_t cache, int size_expr)
+ bool fold_conversions, htab_t cache, int size_expr)
{
tree res, op0, op1, op2;
basic_block def_bb;
evolutions in outer loops), nothing to do. */
if (!def_bb
|| loop_depth (def_bb->loop_father) == 0
- || (!(flags & INSERT_SUPERLOOP_CHRECS)
- && !flow_bb_inside_loop_p (instantiation_loop, def_bb)))
+ || !flow_bb_inside_loop_p (instantiation_loop, def_bb))
return chrec;
/* We cache the value of instantiated variable to avoid exponential
else if (res != chrec_dont_know)
res = instantiate_scev_1 (instantiation_loop, evolution_loop, res,
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec));
case POLYNOMIAL_CHREC:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
- CHREC_LEFT (chrec), flags, cache, size_expr);
+ CHREC_LEFT (chrec), fold_conversions, cache,
+ size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
- CHREC_RIGHT (chrec), flags, cache, size_expr);
+ CHREC_RIGHT (chrec), fold_conversions, cache,
+ size_expr);
if (op1 == chrec_dont_know)
return chrec_dont_know;
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
- TREE_OPERAND (chrec, 0), flags, cache,
+ TREE_OPERAND (chrec, 0), fold_conversions, cache,
size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
- TREE_OPERAND (chrec, 1), flags, cache,
+ TREE_OPERAND (chrec, 1), fold_conversions, cache,
size_expr);
if (op1 == chrec_dont_know)
return chrec_dont_know;
case MINUS_EXPR:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
- TREE_OPERAND (chrec, 0), flags, cache,
+ TREE_OPERAND (chrec, 0), fold_conversions, cache,
size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 1),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
return chrec_dont_know;
case MULT_EXPR:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 0),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 1),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
return chrec_dont_know;
CASE_CONVERT:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 0),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
- if (flags & FOLD_CONVERSIONS)
+ if (fold_conversions)
{
tree tmp = chrec_convert_aggressive (TREE_TYPE (chrec), op0);
if (tmp)
/* If we used chrec_convert_aggressive, we can no longer assume that
signed chrecs do not overflow, as chrec_convert does, so avoid
calling it in that case. */
- if (flags & FOLD_CONVERSIONS)
+ if (fold_conversions)
return fold_convert (TREE_TYPE (chrec), op0);
return chrec_convert (TREE_TYPE (chrec), op0, NULL_TREE);
case 3:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 0),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 1),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
return chrec_dont_know;
op2 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 2),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op2 == chrec_dont_know)
return chrec_dont_know;
case 2:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 0),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
op1 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 1),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op1 == chrec_dont_know)
return chrec_dont_know;
case 1:
op0 = instantiate_scev_1 (instantiation_loop, evolution_loop,
TREE_OPERAND (chrec, 0),
- flags, cache, size_expr);
+ fold_conversions, cache, size_expr);
if (op0 == chrec_dont_know)
return chrec_dont_know;
if (op0 == TREE_OPERAND (chrec, 0))
fprintf (dump_file, ")\n");
}
- res = instantiate_scev_1 (instantiation_loop, evolution_loop, chrec,
- INSERT_SUPERLOOP_CHRECS, cache, 0);
+ res = instantiate_scev_1 (instantiation_loop, evolution_loop, chrec, false,
+ cache, 0);
if (dump_file && (dump_flags & TDF_DETAILS))
{
resolve_mixers (struct loop *loop, tree chrec)
{
htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
- tree ret = instantiate_scev_1 (loop, loop, chrec, FOLD_CONVERSIONS, cache, 0);
+ tree ret = instantiate_scev_1 (loop, loop, chrec, true, cache, 0);
htab_delete (cache);
return ret;
}