===================================================================
@@ -51,11 +51,14 @@
#include "sese.h"
#include "tree-ssa-loop-manip.h"
#include "tree-scalar-evolution.h"
+#include "gimple-ssa.h"
+#include "tree-into-ssa.h"
#include <map>
#ifdef HAVE_cloog
#include "graphite-poly.h"
#include "graphite-isl-ast-to-gimple.h"
+#include "graphite-htab.h"
/* This flag is set when an error occurred during the translation of
ISL AST to Gimple. */
@@ -94,18 +97,21 @@
#endif
}
-/* IVS_PARAMS maps ISL's scattering and parameter identifiers
+/* TREE_FROM_ISL_ID maps ISL's scattering and parameter identifiers
to corresponding trees. */
-typedef std::map<isl_id *, tree> ivs_params;
+typedef struct ivs_params {
+ std::map<isl_id *, tree> tree_from_isl_id;
+ sese region;
+} *ivs_params_p;
/* Free all memory allocated for ISL's identifiers. */
-void ivs_params_clear (ivs_params &ip)
+void ivs_params_clear (ivs_params_p ip)
{
std::map<isl_id *, tree>::iterator it;
- for (it = ip.begin ();
- it != ip.end (); it++)
+ for (it = ip->tree_from_isl_id.begin ();
+ it != ip->tree_from_isl_id.end (); it++)
{
isl_id_free (it->first);
}
@@ -113,21 +119,21 @@
static tree
gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *,
- ivs_params &ip);
+ ivs_params_p ip);
/* Return the tree variable that corresponds to the given isl ast identifier
expression (an isl_ast_expr of type isl_ast_expr_id). */
static tree
gcc_expression_from_isl_ast_expr_id (__isl_keep isl_ast_expr *expr_id,
- ivs_params &ip)
+ ivs_params_p ip)
{
gcc_assert (isl_ast_expr_get_type (expr_id) == isl_ast_expr_id);
isl_id *tmp_isl_id = isl_ast_expr_get_id (expr_id);
std::map<isl_id *, tree>::iterator res;
- res = ip.find (tmp_isl_id);
+ res = ip->tree_from_isl_id.find (tmp_isl_id);
isl_id_free (tmp_isl_id);
- gcc_assert (res != ip.end () &&
+ gcc_assert (res != ip->tree_from_isl_id.end () &&
"Could not map isl_id to tree expression");
isl_ast_expr_free (expr_id);
return res->second;
@@ -158,7 +164,7 @@
type TYPE. */
static tree
-binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
+binary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params_p ip)
{
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);
@@ -214,7 +220,7 @@
type TYPE. */
static tree
-ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
+ternary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params_p ip)
{
gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
@@ -235,7 +241,7 @@
type TYPE. */
static tree
-unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
+unary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params_p ip)
{
gcc_assert (isl_ast_expr_get_op_type (expr) == isl_ast_op_minus);
isl_ast_expr *arg_expr = isl_ast_expr_get_op_arg (expr, 0);
@@ -248,7 +254,7 @@
to a GCC expression tree of type TYPE. */
static tree
-nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params &ip)
+nary_op_to_tree (tree type, __isl_take isl_ast_expr *expr, ivs_params_p ip)
{
enum tree_code op_code;
switch (isl_ast_expr_get_op_type (expr))
@@ -283,7 +289,7 @@
static tree
gcc_expression_from_isl_expr_op (tree type, __isl_take isl_ast_expr *expr,
- ivs_params &ip)
+ ivs_params_p ip)
{
gcc_assert (isl_ast_expr_get_type (expr) == isl_ast_expr_op);
switch (isl_ast_expr_get_op_type (expr))
@@ -334,7 +340,7 @@
static tree
gcc_expression_from_isl_expression (tree type, __isl_take isl_ast_expr *expr,
- ivs_params &ip)
+ ivs_params_p ip)
{
switch (isl_ast_expr_get_type (expr))
{
@@ -365,7 +371,7 @@
static struct loop *
graphite_create_new_loop (edge entry_edge, __isl_keep isl_ast_node *node_for,
loop_p outer, tree type, tree lb, tree ub,
- ivs_params &ip)
+ ivs_params_p ip)
{
isl_ast_expr *for_inc = isl_ast_node_for_get_inc (node_for);
tree stride = gcc_expression_from_isl_expression (type, for_inc, ip);
@@ -377,14 +383,15 @@
isl_ast_expr *for_iterator = isl_ast_node_for_get_iterator (node_for);
isl_id *id = isl_ast_expr_get_id (for_iterator);
- ip[id] = iv;
+ ip->tree_from_isl_id[id] = iv;
isl_ast_expr_free (for_iterator);
return loop;
}
static edge
translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
- edge next_e, ivs_params &ip);
+ edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
+ ivs_params_p ip);
/* Create the loop for a isl_ast_node_for.
@@ -393,8 +400,8 @@
static edge
translate_isl_ast_for_loop (loop_p context_loop,
__isl_keep isl_ast_node *node_for, edge next_e,
- tree type, tree lb, tree ub,
- ivs_params &ip)
+ bb_pbb_htab_type *bb_pbb_mapping, tree type,
+ tree lb, tree ub, ivs_params_p ip)
{
gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
struct loop *loop = graphite_create_new_loop (next_e, node_for, context_loop,
@@ -408,7 +415,7 @@
/* Translate the body of the loop. */
isl_ast_node *for_body = isl_ast_node_for_get_body (node_for);
- next_e = translate_isl_ast (loop, for_body, to_body, ip);
+ next_e = translate_isl_ast (loop, for_body, to_body, bb_pbb_mapping, ip);
isl_ast_node_free (for_body);
redirect_edge_succ_nodup (next_e, after);
set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
@@ -460,7 +467,8 @@
case isl_ast_op_lt:
{
// (iterator < ub) => (iterator <= ub - 1)
- isl_val *one = isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
+ isl_val *one =
+ isl_val_int_from_si (isl_ast_expr_get_ctx (for_cond), 1);
isl_ast_expr *ub = isl_ast_expr_get_op_arg (for_cond, 1);
res = isl_ast_expr_sub (ub, isl_ast_expr_from_val (one));
break;
@@ -488,7 +496,7 @@
static edge
graphite_create_new_loop_guard (edge entry_edge,
__isl_keep isl_ast_node *node_for, tree *type,
- tree *lb, tree *ub, ivs_params &ip)
+ tree *lb, tree *ub, ivs_params_p ip)
{
gcc_assert (isl_ast_node_get_type (node_for) == isl_ast_node_for);
tree cond_expr;
@@ -528,7 +536,8 @@
static edge
translate_isl_ast_node_for (loop_p context_loop, __isl_keep isl_ast_node *node,
- edge next_e, ivs_params &ip)
+ edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
+ ivs_params_p ip)
{
gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_for);
tree type, lb, ub;
@@ -537,16 +546,96 @@
edge true_e = get_true_edge_from_guard_bb (next_e->dest);
translate_isl_ast_for_loop (context_loop, node, true_e,
- type, lb, ub, ip);
+ bb_pbb_mapping, type, lb, ub, ip);
return last_e;
}
+/* Inserts in iv_map a tuple (OLD_LOOP->num, NEW_NAME) for the
+ induction variables of the loops around GBB in SESE. */
+
+static void
+build_iv_mapping (vec<tree> iv_map, gimple_bb_p gbb,
+ __isl_keep isl_ast_expr *user_expr, ivs_params_p ip)
+{
+ gcc_assert (isl_ast_expr_get_type (user_expr) == isl_ast_expr_op &&
+ isl_ast_expr_get_op_type (user_expr) == isl_ast_op_call);
+ int i;
+ isl_ast_expr *arg_expr;
+ for (i = 1; i < isl_ast_expr_get_op_n_arg (user_expr); i++)
+ {
+ arg_expr = isl_ast_expr_get_op_arg (user_expr, i);
+ tree type = *graphite_expression_size_type;
+ tree t = gcc_expression_from_isl_expression (type, arg_expr, ip);
+ loop_p old_loop = gbb_loop_at_index (gbb, ip->region, i - 1);
+ iv_map[old_loop->num] = t;
+ }
+
+}
+
+/* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING. */
+
+static void
+mark_bb_with_pbb (poly_bb_p pbb, basic_block bb,
+ bb_pbb_htab_type *bb_pbb_mapping)
+{
+ bool existed;
+ poly_bb_p &e = bb_pbb_mapping->get_or_insert (bb, &existed);
+ if (!existed)
+ e = pbb;
+}
+
+/* Translates an isl_ast_node_user to Gimple. */
+
+static edge
+translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
+ edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
+ ivs_params_p ip)
+{
+ gcc_assert (isl_ast_node_get_type (node) == isl_ast_node_user);
+ int i, nb_loops;
+ basic_block new_bb;
+ isl_ast_expr *user_expr = isl_ast_node_user_get_expr (node);
+ isl_ast_expr *name_expr = isl_ast_expr_get_op_arg (user_expr, 0);
+ gcc_assert (isl_ast_expr_get_type (name_expr) == isl_ast_expr_id);
+ isl_id *name_id = isl_ast_expr_get_id (name_expr);
+ poly_bb_p pbb = (poly_bb_p) isl_id_get_user (name_id);
+ gcc_assert (pbb);
+ gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
+ vec<tree> iv_map;
+ isl_ast_expr_free (name_expr);
+ isl_id_free (name_id);
+
+ if (GBB_BB (gbb) == ENTRY_BLOCK_PTR_FOR_FN (cfun))
+ {
+ isl_ast_expr_free (user_expr);
+ return next_e;
+ }
+
+ nb_loops = number_of_loops (cfun);
+ iv_map.create (nb_loops);
+ for (i = 0; i < nb_loops; i++)
+ iv_map.quick_push (NULL_TREE);
+
+ build_iv_mapping (iv_map, gbb, user_expr, ip);
+ isl_ast_expr_free (user_expr);
+ next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), ip->region,
+ next_e, iv_map,
+ &graphite_regenerate_error);
+ iv_map.release ();
+ new_bb = next_e->src;
+ mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
+ mark_virtual_operands_for_renaming (cfun);
+ update_ssa (TODO_update_ssa);
+ return next_e;
+}
+
/* Translates an ISL AST node NODE to GCC representation in the
context of a SESE. */
static edge
translate_isl_ast (loop_p context_loop, __isl_keep isl_ast_node *node,
- edge next_e, ivs_params &ip)
+ edge next_e, bb_pbb_htab_type *bb_pbb_mapping,
+ ivs_params_p ip)
{
switch (isl_ast_node_get_type (node))
{
@@ -555,13 +644,13 @@
case isl_ast_node_for:
return translate_isl_ast_node_for (context_loop, node,
- next_e, ip);
+ next_e, bb_pbb_mapping, ip);
case isl_ast_node_if:
return next_e;
case isl_ast_node_user:
- return next_e;
+ return translate_isl_ast_node_user (node, next_e, bb_pbb_mapping, ip);
case isl_ast_node_block:
return next_e;
@@ -587,7 +676,7 @@
/* Add ISL's parameter identifiers and corresponding.trees to ivs_params */
static void
-add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
+add_parameters_to_ivs_params (scop_p scop, ivs_params_p ip)
{
sese region = SCOP_REGION (scop);
unsigned nb_parameters = isl_set_dim (scop->context, isl_dim_param);
@@ -596,7 +685,7 @@
for (i = 0; i < nb_parameters; i++)
{
isl_id *tmp_id = isl_set_get_dim_id (scop->context, isl_dim_param, i);
- ip[tmp_id] = SESE_PARAMS (region)[i];
+ ip->tree_from_isl_id[tmp_id] = SESE_PARAMS (region)[i];
}
}
@@ -639,7 +728,7 @@
}
static __isl_give isl_ast_node *
-scop_to_isl_ast (scop_p scop, ivs_params &ip)
+scop_to_isl_ast (scop_p scop, ivs_params_p ip)
{
/* Generate loop upper bounds that consist of the current loop iterator,
an operator (< or <=) and an expression not involving the iterator.
@@ -663,17 +752,18 @@
with ISL ASTs. Generation of GIMPLE code has to be completed. */
bool
-graphite_regenerate_ast_isl (scop_p scop)
+graphite_regenerate_ast_isl (scop_p scop, bb_pbb_htab_type *bb_pbb_mapping)
{
loop_p context_loop;
sese region = SCOP_REGION (scop);
ifsese if_region = NULL;
isl_ast_node *root_node;
- ivs_params ip;
+ struct ivs_params ip;
+ ip.region = region;
timevar_push (TV_GRAPHITE_CODE_GEN);
graphite_regenerate_error = false;
- root_node = scop_to_isl_ast (scop, ip);
+ root_node = scop_to_isl_ast (scop, &ip);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -696,7 +786,7 @@
context_loop = SESE_ENTRY (region)->src->loop_father;
translate_isl_ast (context_loop, root_node, if_region->true_region->entry,
- ip);
+ bb_pbb_mapping, &ip);
graphite_verify ();
scev_reset ();
recompute_all_dominators ();
@@ -709,7 +799,7 @@
free (if_region->region);
free (if_region);
- ivs_params_clear (ip);
+ ivs_params_clear (&ip);
isl_ast_node_free (root_node);
timevar_pop (TV_GRAPHITE_CODE_GEN);
/* TODO: Add dump */
===================================================================
@@ -21,6 +21,8 @@
#ifndef GCC_GRAPHITE_ISL_AST_TO_GIMPLE_H
#define GCC_GRAPHITE_ISL_AST_TO_GIMPLE_H
-extern bool graphite_regenerate_ast_isl (scop_p);
+#include "graphite-htab.h"
+extern bool graphite_regenerate_ast_isl (scop_p, bb_pbb_htab_type *);
+
#endif
===================================================================
@@ -301,7 +301,7 @@
if (POLY_SCOP_P (scop)
&& apply_poly_transforms (scop)
&& (((flag_graphite_code_gen == FGRAPHITE_CODE_GEN_ISL)
- && graphite_regenerate_ast_isl (scop))
+ && graphite_regenerate_ast_isl (scop, &bb_pbb_mapping))
|| ((flag_graphite_code_gen == FGRAPHITE_CODE_GEN_CLOOG)
&& graphite_regenerate_ast_cloog (scop, &bb_pbb_mapping))))
need_cfg_cleanup_p = true;