/* Print to stderr all the elements of MAP. */
-void
+DEBUG_FUNCTION void
debug_clast_name_indexes (htab_t map)
{
htab_traverse (map, debug_clast_name_indexes_1, NULL);
{
int p1 = TYPE_PRECISION (type1);
int p2 = TYPE_PRECISION (type2);
- int precision = p1 > p2 ? p1 : p2;
- tree type = lang_hooks.types.type_for_size (precision, false);
+ int precision;
+ tree type;
+
+ if (p1 > p2)
+ precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
+ else
+ precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
+
+ type = lang_hooks.types.type_for_size (precision, false);
if (!type)
{
static tree
max_precision_type (tree type1, tree type2)
{
-
if (POINTER_TYPE_P (type1))
return type1;
if (t->var)
{
- if (value_one_p (t->val))
+ if (mpz_cmp_si (t->val, 1) == 0)
{
tree name = clast_name_to_gcc (t->var, region, newivs,
newivs_index, params_index);
return name;
}
- else if (value_mone_p (t->val))
+ else if (mpz_cmp_si (t->val, -1) == 0)
{
tree name = clast_name_to_gcc (t->var, region, newivs,
newivs_index, params_index);
/* Return the precision needed to represent the value VAL. */
static int
-precision_for_value (Value val)
+precision_for_value (mpz_t val)
{
- Value x, y, two;
+ mpz_t x, y, two;
int precision;
value_init (x);
UP. */
static int
-precision_for_interval (Value low, Value up)
+precision_for_interval (mpz_t low, mpz_t up)
{
- Value diff;
+ mpz_t diff;
int precision;
gcc_assert (value_le (low, up));
return precision;
}
-/* Return a type that could represent the integer value VAL, or
- otherwise return NULL_TREE. */
+/* Return a type that could represent the integer value VAL. */
static tree
-gcc_type_for_interval (Value low, Value up, tree old_type)
+gcc_type_for_interval (mpz_t low, mpz_t up)
{
bool unsigned_p = true;
int precision, prec_up, prec_int;
tree type;
+ enum machine_mode mode;
gcc_assert (value_le (low, up));
- /* Preserve the signedness of the old IV. */
- if ((old_type && !TYPE_UNSIGNED (old_type))
- || value_neg_p (low))
+ if (value_neg_p (low))
unsigned_p = false;
prec_up = precision_for_value (up);
prec_int = precision_for_interval (low, up);
- precision = prec_up > prec_int ? prec_up : prec_int;
+ precision = MAX (prec_up, prec_int);
+
+ if (precision > BITS_PER_WORD)
+ {
+ gloog_error = true;
+ return integer_type_node;
+ }
+
+ mode = smallest_mode_for_size (precision, MODE_INT);
+ precision = GET_MODE_PRECISION (mode);
+ type = build_nonstandard_integer_type (precision, unsigned_p);
- type = lang_hooks.types.type_for_size (precision, unsigned_p);
if (!type)
{
gloog_error = true;
otherwise return NULL_TREE. */
static tree
-gcc_type_for_value (Value val)
+gcc_type_for_value (mpz_t val)
{
- return gcc_type_for_interval (val, val, NULL_TREE);
+ return gcc_type_for_interval (val, val);
}
/* Return the type for the clast_term T used in STMT. */
the iteration domain, and G the context parameters. */
static void
-compute_bounds_for_level (poly_bb_p pbb, int level, Value low, Value up)
+compute_bounds_for_level (poly_bb_p pbb, int level, mpz_t low, mpz_t up)
{
ppl_Pointset_Powerset_C_Polyhedron_t ps;
ppl_Linear_Expression_t le;
}
/* Compute the type for the induction variable at LEVEL for the
- statement PBB, based on the transformed schedule of PBB. OLD_TYPE
- is the type of the old induction variable for that loop. */
+ statement PBB, based on the transformed schedule of PBB. */
static tree
-compute_type_for_level_1 (poly_bb_p pbb, int level, tree old_type)
+compute_type_for_level (poly_bb_p pbb, int level)
{
- Value low, up;
+ mpz_t low, up;
tree type;
value_init (low);
value_init (up);
compute_bounds_for_level (pbb, level, low, up);
- type = gcc_type_for_interval (low, up, old_type);
+ type = gcc_type_for_interval (low, up);
value_clear (low);
value_clear (up);
return type;
}
-/* Compute the type for the induction variable at LEVEL for the
- statement PBB, based on the transformed schedule of PBB. */
-
-static tree
-compute_type_for_level (poly_bb_p pbb, int level)
-{
- tree oldiv = pbb_to_depth_to_oldiv (pbb, level);
- tree type = TREE_TYPE (oldiv);
-
- if (type && POINTER_TYPE_P (type))
- {
-#ifdef ENABLE_CHECKING
- tree ctype = compute_type_for_level_1 (pbb, level, type);
-
- /* In the case of a pointer type, check that after the loop
- transform, the lower and the upper bounds of the type fit the
- oldiv pointer type. */
- gcc_assert (TYPE_PRECISION (type) >= TYPE_PRECISION (ctype)
- && integer_zerop (lower_bound_in_type (ctype, ctype)));
-#endif
- return type;
- }
-
- return compute_type_for_level_1 (pbb, level, type);
-}
-
/* Walks a CLAST and returns the first statement in the body of a
loop. */
CloogStatement *cs = body->statement;
poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
- return max_precision_type (lb_type, max_precision_type
- (ub_type, compute_type_for_level (pbb,
- level - 1)));
+ return max_signed_precision_type (lb_type, max_precision_type
+ (ub_type, compute_type_for_level
+ (pbb, level - 1)));
}
/* Creates a new LOOP corresponding to Cloog's STMT. Inserts an
/* Creates a new if region protecting the loop to be executed, if the execution
count is zero (lb > ub). */
+
static edge
graphite_create_new_loop_guard (sese region, edge entry_edge,
struct clast_for *stmt,
newivs_index, params_index);
tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs,
newivs_index, params_index);
-
- /* XXX: Adding +1 and using LT_EXPR helps with loop latches that have a
+ tree one = POINTER_TYPE_P (type) ? size_one_node
+ : fold_convert (type, integer_one_node);
+ /* Adding +1 and using LT_EXPR helps with loop latches that have a
loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
2^{32|64}, and the condition lb <= ub is true, even if we do not want this.
- However lb < ub + 1 is false, as expected.
- There might be a problem with cases where ub is 2^32. */
- tree one;
- Value gmp_one;
- value_init (gmp_one);
- value_set_si (gmp_one, 1);
- one = gmp_cst_to_tree (type, gmp_one);
- value_clear (gmp_one);
-
- ub = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
- type, ub, one);
- cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub);
+ However lb < ub + 1 is false, as expected. */
+ tree ub_one = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR
+ : PLUS_EXPR, type, ub, one);
+
+ /* When ub + 1 wraps around, use lb <= ub. */
+ if (integer_zerop (ub_one))
+ cond_expr = fold_build2 (LE_EXPR, boolean_type_node, lb, ub);
+ else
+ cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub_one);
exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
/* Prints STMT to STDERR. */
-void
+DEBUG_FUNCTION void
debug_clast_stmt (struct clast_stmt *stmt)
{
print_clast_stmt (stderr, stmt);
/* Prints to STDERR the code generated by CLooG for SCOP. */
-void
+DEBUG_FUNCTION void
debug_generated_program (scop_p scop)
{
print_generated_program (stderr, scop);