summaryrefslogtreecommitdiff
path: root/gcc/graphite-isl-ast-to-gimple.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/graphite-isl-ast-to-gimple.c')
-rw-r--r--gcc/graphite-isl-ast-to-gimple.c101
1 files changed, 53 insertions, 48 deletions
diff --git a/gcc/graphite-isl-ast-to-gimple.c b/gcc/graphite-isl-ast-to-gimple.c
index 4939b2140cb..e7d95e22110 100644
--- a/gcc/graphite-isl-ast-to-gimple.c
+++ b/gcc/graphite-isl-ast-to-gimple.c
@@ -177,6 +177,7 @@ class translate_isl_ast_to_gimple
tree gcc_expression_from_isl_ast_expr_id (tree type,
__isl_keep isl_ast_expr *expr_id,
ivs_params &ip);
+ widest_int widest_int_from_isl_expr_int (__isl_keep isl_ast_expr *expr);
tree gcc_expression_from_isl_expr_int (tree type,
__isl_take isl_ast_expr *expr);
tree gcc_expression_from_isl_expr_op (tree type,
@@ -266,29 +267,46 @@ gcc_expression_from_isl_ast_expr_id (tree type,
return fold_convert (type, *val);
}
-/* Converts an isl_ast_expr_int expression E to a GCC expression tree of
- type TYPE. */
+/* Converts an isl_ast_expr_int expression E to a widest_int.
+ Raises a code generation error when the constant doesn't fit. */
-tree translate_isl_ast_to_gimple::
-gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
+widest_int translate_isl_ast_to_gimple::
+widest_int_from_isl_expr_int (__isl_keep isl_ast_expr *expr)
{
gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_int);
isl_val *val = isl_ast_expr_get_val (expr);
size_t n = isl_val_n_abs_num_chunks (val, sizeof (HOST_WIDE_INT));
HOST_WIDE_INT *chunks = XALLOCAVEC (HOST_WIDE_INT, n);
- tree res;
- if (isl_val_get_abs_num_chunks (val, sizeof (HOST_WIDE_INT), chunks) == -1)
- res = NULL_TREE;
- else
+ if (n > WIDE_INT_MAX_ELTS
+ || isl_val_get_abs_num_chunks (val, sizeof (HOST_WIDE_INT), chunks) == -1)
{
- widest_int wi = widest_int::from_array (chunks, n, true);
- if (isl_val_is_neg (val))
- wi = -wi;
- res = wide_int_to_tree (type, wi);
+ isl_val_free (val);
+ set_codegen_error ();
+ return 0;
}
+ widest_int wi = widest_int::from_array (chunks, n, true);
+ if (isl_val_is_neg (val))
+ wi = -wi;
isl_val_free (val);
+ return wi;
+}
+
+/* Converts an isl_ast_expr_int expression E to a GCC expression tree of
+ type TYPE. Raises a code generation error when the constant doesn't fit. */
+
+tree translate_isl_ast_to_gimple::
+gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
+{
+ widest_int wi = widest_int_from_isl_expr_int (expr);
isl_ast_expr_free (expr);
- return res;
+ if (codegen_error_p ())
+ return NULL_TREE;
+ if (wi::min_precision (wi, TYPE_SIGN (type)) > TYPE_PRECISION (type))
+ {
+ set_codegen_error ();
+ return NULL_TREE;
+ }
+ return wide_int_to_tree (type, wi);
}
/* Converts a binary isl_ast_expr_op expression E to a GCC expression tree of
@@ -297,14 +315,25 @@ gcc_expression_from_isl_expr_int (tree type, __isl_take isl_ast_expr *expr)
tree translate_isl_ast_to_gimple::
binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
{
+ enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
tree tree_lhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
arg_expr = isl_ast_expr_get_op_arg (expr, 1);
- tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
-
- enum isl_ast_op_type expr_type = isl_ast_expr_get_op_type (expr);
isl_ast_expr_free (expr);
+ /* From our constraint generation we may get modulo operations that
+ we cannot represent explicitely but that are no-ops for TYPE.
+ Elide those. */
+ if (expr_type == isl_ast_op_pdiv_r
+ && isl_ast_expr_get_type (arg_expr) == isl_ast_expr_int
+ && (wi::exact_log2 (widest_int_from_isl_expr_int (arg_expr))
+ >= TYPE_PRECISION (type)))
+ {
+ isl_ast_expr_free (arg_expr);
+ return tree_lhs_expr;
+ }
+
+ tree tree_rhs_expr = gcc_expression_from_isl_expression (type, arg_expr, ip);
if (codegen_error_p ())
return NULL_TREE;
@@ -320,44 +349,16 @@ binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
return fold_build2 (MULT_EXPR, type, tree_lhs_expr, tree_rhs_expr);
case isl_ast_op_div:
- /* As isl operates on arbitrary precision numbers, we may end up with
- division by 2^64 that is folded to 0. */
- if (integer_zerop (tree_rhs_expr))
- {
- set_codegen_error ();
- return NULL_TREE;
- }
return fold_build2 (EXACT_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
case isl_ast_op_pdiv_q:
- /* As isl operates on arbitrary precision numbers, we may end up with
- division by 2^64 that is folded to 0. */
- if (integer_zerop (tree_rhs_expr))
- {
- set_codegen_error ();
- return NULL_TREE;
- }
return fold_build2 (TRUNC_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
case isl_ast_op_zdiv_r:
case isl_ast_op_pdiv_r:
- /* As isl operates on arbitrary precision numbers, we may end up with
- division by 2^64 that is folded to 0. */
- if (integer_zerop (tree_rhs_expr))
- {
- set_codegen_error ();
- return NULL_TREE;
- }
return fold_build2 (TRUNC_MOD_EXPR, type, tree_lhs_expr, tree_rhs_expr);
case isl_ast_op_fdiv_q:
- /* As isl operates on arbitrary precision numbers, we may end up with
- division by 2^64 that is folded to 0. */
- if (integer_zerop (tree_rhs_expr))
- {
- set_codegen_error ();
- return NULL_TREE;
- }
return fold_build2 (FLOOR_DIV_EXPR, type, tree_lhs_expr, tree_rhs_expr);
case isl_ast_op_and:
@@ -750,10 +751,8 @@ build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
if (codegen_error_p ())
t = integer_zero_node;
- loop_p old_loop = gbb_loop_at_index (gbb, region, i - 2);
- /* Record sth only for real loops. */
- if (loop_in_sese_p (old_loop, region))
- iv_map[old_loop->num] = t;
+ loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
+ iv_map[old_loop->num] = t;
}
}
@@ -1571,6 +1570,12 @@ graphite_regenerate_ast_isl (scop_p scop)
update_ssa (TODO_update_ssa);
checking_verify_ssa (true, true);
rewrite_into_loop_closed_ssa (NULL, 0);
+ /* We analyzed evolutions of all SCOPs during SCOP detection
+ which cached evolutions. Now we've introduced PHIs for
+ liveouts which causes those cached solutions to be invalid
+ for code-generation purposes given we'd insert references
+ to SSA names not dominating their new use. */
+ scev_reset ();
}
if (t.codegen_error_p ())