+2015-10-07 Aditya Kumar <aditya.k7@samsung.com>
+ Sebastian Pop <s.pop@samsung.com>
+
+ * graphite-isl-ast-to-gimple.c (translate_isl_ast_to_gimple): Use
+ an sese_info_p.
+ (copy_def): Same.
+ (copy_internal_parameters): Same.
+ (translate_isl_ast_to_gimple): Use an sese_l.
+ (build_iv_mapping): Same.
+ * graphite-poly.c (new_sese): Rename new_sese_info.
+ (free_sese): Rename free_sese_info.
+ * graphite-poly.h (struct scop): Use an sese_info_p.
+ (scop_set_region): Same.
+ * graphite-scop-detection.c (struct sese_l): Moved...
+ (get_entry_bb): Moved...
+ (get_exit_bb): Moved...
+ (parameter_index_in_region_1): Use an sese_info_p.
+ (parameter_index_in_region): Same.
+ (scan_tree_for_params): Same.
+ (find_params_in_bb): Same.
+ (sese_dom_walker): Use an sese_l.
+ * graphite-sese-to-poly.c (remove_invariant_phi): Same.
+ (reduction_phi_p): Same.
+ (parameter_index_in_region_1): Use an sese_info_p.
+ (propagate_expr_outside_region): Use an sese_l.
+ * graphite.c: Replace uses of SCOP_REGION.
+ * sese.c (sese_record_loop): Use an sese_info_p.
+ (build_sese_loop_nests): Same.
+ (sese_build_liveouts_use): Same.
+ (sese_build_liveouts_bb): Same.
+ (sese_build_liveouts_bb): Same.
+ (sese_bad_liveouts_use): Same.
+ (sese_reset_debug_liveouts_bb): Same.
+ (sese_build_liveouts): Same.
+ (new_sese): Renamed new_sese_info.
+ (free_sese): Renamed free_sese_info.
+ (set_rename): Use an sese_info_p.
+ (graphite_copy_stmts_from_block): Same.
+ (copy_bb_and_scalar_dependences): Same.
+ (outermost_loop_in_sese_1): Use an sese_l.
+ (outermost_loop_in_sese): Same.
+ (if_region_set_false_region): Use an sese_info_p.
+ (move_sese_in_condition): Same.
+ (scalar_evolution_in_region): Use an sese_l.
+ * sese.h (struct sese_l): ... here.
+ (SESE_ENTRY): Remove.
+ (SESE_ENTRY_BB): Remove.
+ (SESE_EXIT): Remove.
+ (SESE_EXIT_BB): Remove.
+ (sese_contains_loop): Use an sese_info_p.
+ (sese_nb_params): Same.
+ (bb_in_sese_p): Use an sese_l.
+ (stmt_in_sese_p): Same.
+ (defined_in_sese_p): Same.
+ (loop_in_sese_p): Same.
+ (sese_loop_depth): Same.
+ (struct ifsese_s): Use an sese_info_p.
+ (gbb_loop_at_index): Use an sese_l.
+ (nb_common_loops): Same.
+ (scev_analyzable_p): Same.
+
2015-10-07 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (ix86_conditional_register_usage): Use
class translate_isl_ast_to_gimple
{
public:
- translate_isl_ast_to_gimple (sese r)
+ translate_isl_ast_to_gimple (sese_info_p r)
: region (r)
{ }
corresponding tree expressions. */
void build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
__isl_keep isl_ast_expr *user_expr, ivs_params &ip,
- sese region);
+ sese_l ®ion);
private:
- sese region;
+ sese_info_p region;
};
/* Return the tree variable that corresponds to the given isl ast identifier
translate_isl_ast_to_gimple::
build_iv_mapping (vec<tree> iv_map, gimple_poly_bb_p gbb,
__isl_keep isl_ast_expr *user_expr, ivs_params &ip,
- sese region)
+ sese_l ®ion)
{
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);
loop_p old_loop = gbb_loop_at_index (gbb, region, i - 1);
iv_map[old_loop->num] = t;
}
-
}
/* Translates an isl_ast_node_user to Gimple.
iv_map.create (nb_loops);
iv_map.safe_grow_cleared (nb_loops);
- build_iv_mapping (iv_map, gbb, user_expr, ip, SCOP_REGION (pbb->scop));
+ build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->region->region);
isl_ast_expr_free (user_expr);
next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb),
- SCOP_REGION (pbb->scop), next_e,
+ pbb->scop->region, next_e,
iv_map,
&graphite_regenerate_error);
iv_map.release ();
static void
add_parameters_to_ivs_params (scop_p scop, ivs_params &ip)
{
- sese region = SCOP_REGION (scop);
+ sese_info_p region = scop->region;
unsigned nb_parameters = isl_set_dim (scop->param_context, isl_dim_param);
gcc_assert (nb_parameters == SESE_PARAMS (region).length ());
unsigned i;
DEF_STMT. GSI points to entry basic block of the TO_REGION. */
static void
-copy_def(tree tr, gimple *def_stmt, sese region, sese to_region, gimple_stmt_iterator *gsi)
+copy_def (tree tr, gimple *def_stmt, sese_info_p region, sese_info_p to_region,
+ gimple_stmt_iterator *gsi)
{
- if (!defined_in_sese_p (tr, region))
+ if (!defined_in_sese_p (tr, region->region))
return;
+
ssa_op_iter iter;
use_operand_p use_p;
-
FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
{
tree use_tr = USE_FROM_PTR (use_p);
}
static void
-copy_internal_parameters(sese region, sese to_region)
+copy_internal_parameters (sese_info_p region, sese_info_p to_region)
{
/* For all the parameters which definitino is in the if_region->false_region,
insert code on true_region (if_region->true_region->entry). */
int i;
tree tr;
- gimple_stmt_iterator gsi = gsi_start_bb(to_region->entry->dest);
+ gimple_stmt_iterator gsi = gsi_start_bb(to_region->region.entry->dest);
FOR_EACH_VEC_ELT (region->params, i, tr)
{
graphite_regenerate_ast_isl (scop_p scop)
{
loop_p context_loop;
- sese region = SCOP_REGION (scop);
+ sese_info_p region = scop->region;
ifsese if_region = NULL;
isl_ast_node *root_node;
ivs_params ip;
if_region = move_sese_in_condition (region);
sese_insert_phis_for_liveouts (region,
- if_region->region->exit->src,
- if_region->false_region->exit,
- if_region->true_region->exit);
+ if_region->region->region.exit->src,
+ if_region->false_region->region.exit,
+ if_region->true_region->region.exit);
recompute_all_dominators ();
graphite_verify ();
- context_loop = SESE_ENTRY (region)->src->loop_father;
+ context_loop = region->region.entry->src->loop_father;
/* Copy all the parameters which are defined in the region. */
copy_internal_parameters(if_region->false_region, if_region->true_region);
translate_isl_ast_to_gimple t(region);
- edge e = single_succ_edge (if_region->true_region->entry->dest);
+ edge e = single_succ_edge (if_region->true_region->region.entry->dest);
split_edge (e);
t.translate_isl_ast (context_loop, root_node, e, ip);
scop_p
new_scop (edge entry, edge exit)
{
- sese region = new_sese (entry, exit);
+ sese_info_p region = new_sese_info (entry, exit);
scop_p scop = XNEW (struct scop);
scop->param_context = NULL;
poly_bb_p pbb;
remove_gbbs_in_scop (scop);
- free_sese (SCOP_REGION (scop));
+ free_sese_info (SCOP_REGION (scop));
FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
free_poly_bb (pbb);
struct scop
{
/* A SCOP is defined as a SESE region. */
- sese region;
+ sese_info_p region;
/* Number of parameters in SCoP. */
graphite_dim_t nb_params;
/* Set the region of SCOP to REGION. */
static inline void
-scop_set_region (scop_p scop, sese region)
+scop_set_region (scop_p scop, sese_info_p region)
{
scop->region = region;
}
#include "graphite-scop-detection.h"
#include "gimple-pretty-print.h"
-/* Lightweight representation of sese for scop detection.
- TODO: Make all this as a constant_edge. */
-struct sese_l
-{
- sese_l (edge e, edge x) : entry (e), exit (x) {}
-
- /* This is to push objects of sese_l in a vec. */
- sese_l (int i) : entry (NULL), exit (NULL) { gcc_assert (i == 0); }
-
- operator bool () const { return entry && exit; }
-
- const sese_l &
- operator= (const sese_l &s)
- {
- entry = s.entry;
- exit = s.exit;
- return *this;
- }
-
- edge entry;
- edge exit;
-};
-
-/* APIs for getting entry/exit of an sese. */
-static basic_block
-get_entry_bb (edge e)
-{
- return e->dest;
-}
-
-static basic_block
-get_exit_bb (edge e)
-{
- return e->src;
-}
-
class debug_printer
{
private:
/* Find the common dominators for entry,
and common post-dominators for the exit. */
basic_block dom = nearest_common_dominator (CDI_DOMINATORS,
- get_entry_bb (first.entry),
- get_entry_bb (second.entry));
+ get_entry_bb (first),
+ get_entry_bb (second));
edge entry = get_nearest_dom_with_single_entry (dom);
if (!entry)
return invalid_sese;
basic_block pdom = nearest_common_dominator (CDI_POST_DOMINATORS,
- get_exit_bb (first.exit),
- get_exit_bb (second.exit));
+ get_exit_bb (first),
+ get_exit_bb (second));
pdom = nearest_common_dominator (CDI_POST_DOMINATORS, dom, pdom);
edge exit = get_nearest_pdom_with_single_exit (pdom);
/* For now we just want to bail out when exit does not post-dominate entry.
TODO: We might just add a basic_block at the exit to make exit
post-dominate entry (the entire region). */
- if (!dominated_by_p (CDI_POST_DOMINATORS, get_entry_bb (entry),
- get_exit_bb (exit))
- || !dominated_by_p (CDI_DOMINATORS, get_exit_bb (exit),
- get_entry_bb (entry)))
+ if (!dominated_by_p (CDI_POST_DOMINATORS, get_entry_bb (combined),
+ get_exit_bb (combined))
+ || !dominated_by_p (CDI_DOMINATORS, get_exit_bb (combined),
+ get_entry_bb (combined)))
{
DEBUG_PRINT (dp << "[scop-detection-fail] cannot merge seses.\n");
return invalid_sese;
/* FIXME: We should remove this piece of code once
canonicalize_loop_closed_ssa has been removed, because that function
adds a BB with single exit. */
- if (!trivially_empty_bb_p (get_exit_bb (combined.exit)))
+ if (!trivially_empty_bb_p (get_exit_bb (combined)))
{
/* Find the first empty succ (with single exit) of combined.exit. */
basic_block imm_succ = combined.exit->dest;
return;
}
- if (get_exit_bb (s.exit) == EXIT_BLOCK_PTR_FOR_FN (cfun))
+ if (get_exit_bb (s) == EXIT_BLOCK_PTR_FOR_FN (cfun))
{
DEBUG_PRINT (dp << "\n[scop-detection-fail] "
<< "Discarding SCoP exiting to return";
bool
scop_detection::harmful_stmt_in_region (sese_l scop) const
{
- basic_block exit_bb = get_exit_bb (scop.exit);
- basic_block entry_bb = get_entry_bb (scop.entry);
+ basic_block exit_bb = get_exit_bb (scop);
+ basic_block entry_bb = get_entry_bb (scop);
DEBUG_PRINT (dp << "\n[checking-harmful-bbs] ";
print_sese (dump_file, scop));
bool
scop_detection::subsumes (sese_l s1, sese_l s2)
{
- if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2.entry),
- get_entry_bb (s1.entry))
- && dominated_by_p (CDI_POST_DOMINATORS, get_entry_bb (s2.exit),
- get_entry_bb (s1.exit)))
+ if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
+ get_entry_bb (s1))
+ && dominated_by_p (CDI_POST_DOMINATORS, s2.exit->dest,
+ s1.exit->dest))
return true;
return false;
}
bool
scop_detection::intersects (sese_l s1, sese_l s2)
{
- if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2.entry),
- get_entry_bb (s1.entry))
- && !dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2.entry),
- get_exit_bb (s1.exit)))
+ if (dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
+ get_entry_bb (s1))
+ && !dominated_by_p (CDI_DOMINATORS, get_entry_bb (s2),
+ get_exit_bb (s1)))
return true;
if ((s1.exit == s2.entry) || (s2.exit == s1.entry))
return true;
scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
tree expr)
{
- sese region = new_sese (scop.entry, scop.exit);
- tree scev = scalar_evolution_in_region (region, loop, expr);
- free_sese (region);
+ tree scev = scalar_evolution_in_region (scop, loop, expr);
return graphite_can_represent_scev (scev);
}
bool
scop_detection::stmt_has_simple_data_refs_p (sese_l scop, gimple *stmt)
{
- sese region = new_sese (scop.entry, scop.exit);
- loop_p nest = outermost_loop_in_sese (region, gimple_bb (stmt));
+ loop_p nest = outermost_loop_in_sese (scop, gimple_bb (stmt));
loop_p loop = loop_containing_stmt (stmt);
vec<data_reference_p> drs = vNULL;
/* Select color for SCoP. */
FOR_EACH_VEC_ELT (scops, i, scop)
{
- sese region = SCOP_REGION (scop);
- if (bb_in_sese_p (bb, region) || (SESE_EXIT_BB (region) == bb)
- || (SESE_ENTRY_BB (region) == bb))
+ sese_l region = scop->region->region;
+ if (bb_in_sese_p (bb, region) || (region.exit->dest == bb)
+ || (region.entry->dest == bb))
{
switch (i % 17)
{
if (!bb_in_sese_p (bb, region))
fprintf (file, " (");
- if (bb == SESE_ENTRY_BB (region) && bb == SESE_EXIT_BB (region))
+ if (bb == region.entry->dest && bb == region.exit->dest)
fprintf (file, " %d*# ", bb->index);
- else if (bb == SESE_ENTRY_BB (region))
+ else if (bb == region.entry->dest)
fprintf (file, " %d* ", bb->index);
- else if (bb == SESE_EXIT_BB (region))
+ else if (bb == region.exit->dest)
fprintf (file, " %d# ", bb->index);
else
fprintf (file, " %d ", bb->index);
{
vec<data_reference_p> drs;
drs.create (5);
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
loop_p nest = outermost_loop_in_sese (region, bb);
loop_p loop = bb->loop_father;
void
scop_detection::build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
{
- sese region = SCOP_REGION (scop);
-
- if (bitmap_bit_p (visited, bb->index) || !bb_in_sese_p (bb, region))
+ if (bitmap_bit_p (visited, bb->index)
+ || !bb_in_sese_p (bb, scop->region->region))
return;
poly_bb_p pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
scop_detection::build_scop_bbs (scop_p scop)
{
sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
bitmap_clear (visited);
- build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
+ build_scop_bbs_1 (scop, visited, region.entry->dest);
sbitmap_free (visited);
}
int res = 0;
FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
- if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
+ if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), scop->region->region))
res++;
return res;
Otherwise returns -1. */
static inline int
-parameter_index_in_region_1 (tree name, sese region)
+parameter_index_in_region_1 (tree name, sese_info_p region)
{
int i;
tree p;
and returns the index of NAME. */
static int
-parameter_index_in_region (tree name, sese region)
+parameter_index_in_region (tree name, sese_info_p region)
{
int i;
if (TREE_CODE (TREE_TYPE (name)) != INTEGER_TYPE)
return -1;
- if (!invariant_in_sese_p_rec (name, region))
+ if (!invariant_in_sese_p_rec (name, region->region))
return -1;
i = parameter_index_in_region_1 (name, region);
parameters. */
static void
-scan_tree_for_params (sese s, tree e)
+scan_tree_for_params (sese_info_p s, tree e)
{
if (e == chrec_dont_know)
return;
access functions, conditions and loop bounds. */
static void
-find_params_in_bb (sese region, gimple_poly_bb_p gbb)
+find_params_in_bb (sese_info_p region, gimple_poly_bb_p gbb)
{
/* Find parameters in the access functions of data references. */
int i;
loop_p loop = GBB_BB (gbb)->loop_father;
FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
{
- tree lhs = scalar_evolution_in_region (region, loop,
+ tree lhs = scalar_evolution_in_region (region->region, loop,
gimple_cond_lhs (stmt));
- tree rhs = scalar_evolution_in_region (region, loop,
+ tree rhs = scalar_evolution_in_region (region->region, loop,
gimple_cond_rhs (stmt));
scan_tree_for_params (region, lhs);
find_scop_parameters (scop_p scop)
{
unsigned i;
- sese region = SCOP_REGION (scop);
+ sese_info_p region = scop->region;
struct loop *loop;
/* Find the parameters used in the loop bounds. */
if (!chrec_contains_symbols (nb_iters))
continue;
- nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
+ nb_iters = scalar_evolution_in_region (region->region, loop, nb_iters);
scan_tree_for_params (region, nb_iters);
}
class sese_dom_walker : public dom_walker
{
public:
- sese_dom_walker (cdi_direction, sese);
+ sese_dom_walker (cdi_direction, sese_l);
virtual void before_dom_children (basic_block);
virtual void after_dom_children (basic_block);
private:
auto_vec<gimple *, 3> m_conditions, m_cases;
- sese m_region;
+ sese_l m_region;
};
}
-sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
+sese_dom_walker::sese_dom_walker (cdi_direction direction, sese_l region)
: dom_walker (direction), m_region (region)
{
}
build_sese_loop_nests (scop->region);
/* Record all conditions in REGION. */
- sese_dom_walker (CDI_DOMINATORS, scop->region).walk
+ sese_dom_walker (CDI_DOMINATORS, scop->region->region).walk
(cfun->cfg->x_entry_block_ptr);
find_scop_parameters (scop);
loop ENTRY edge the assignment RES = INIT. */
static void
-remove_invariant_phi (sese region, gphi_iterator *psi)
+remove_invariant_phi (sese_l ®ion, gphi_iterator *psi)
{
gphi *phi = psi->phi ();
loop_p loop = loop_containing_stmt (phi);
be considered. */
static bool
-reduction_phi_p (sese region, gphi_iterator *psi)
+reduction_phi_p (sese_l ®ion, gphi_iterator *psi)
{
loop_p loop;
gphi *phi = psi->phi ();
int prefix = 0;
if (previous_gbb)
- prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
+ prefix = nb_common_loops (scop->region->region, previous_gbb, gbb);
previous_gbb = gbb;
isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
isl_local_space *ls = isl_local_space_from_space (space);
- unsigned pos = sese_loop_depth (SCOP_REGION (s), get_chrec_loop (e)) - 1;
+ unsigned pos = sese_loop_depth (s->region->region, get_chrec_loop (e)) - 1;
isl_aff *loop = isl_aff_set_coefficient_si
(isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
isl_pw_aff *l = isl_pw_aff_from_aff (loop);
Otherwise returns -1. */
static inline int
-parameter_index_in_region_1 (tree name, sese region)
+parameter_index_in_region_1 (tree name, sese_info_p region)
{
int i;
tree p;
case SSA_NAME:
gcc_assert (-1 != parameter_index_in_region_1 (e, s->region)
- || !invariant_in_sese_p_rec (e, s->region));
+ || !invariant_in_sese_p_rec (e, s->region->region));
res = extract_affine_name (s, e, space);
break;
static void
set_scop_parameter_dim (scop_p scop)
{
- sese region = SCOP_REGION (scop);
+ sese_info_p region = scop->region;
unsigned nbp = sese_nb_params (region);
isl_space *space = isl_space_set_alloc (scop->isl_context, nbp, 0);
{
tree nb_iters = number_of_latch_executions (loop);
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
gcc_assert (loop_in_sese_p (loop, region));
isl_set *inner = isl_set_copy (outer);
{
scop_p scop = PBB_SCOP (pbb);
- t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
+ t = scalar_evolution_in_region (scop->region->region, pbb_loop (pbb), t);
gcc_assert (!automatically_generated_chrec_p (t));
return extract_affine (scop, t, isl_set_get_space (pbb->domain));
static void
add_param_constraints (scop_p scop, graphite_dim_t p)
{
- tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
+ tree parameter = SESE_PARAMS (scop->region)[p];
tree type = TREE_TYPE (parameter);
tree lb = NULL_TREE;
tree ub = NULL_TREE;
static void
build_scop_iteration_domain (scop_p scop)
{
- sese region = SCOP_REGION (scop);
+ sese_info_p region = scop->region;
int nb_loops = number_of_loops (cfun);
isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
int i;
struct loop *loop;
FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
- if (!loop_in_sese_p (loop_outer (loop), region))
+ if (!loop_in_sese_p (loop_outer (loop), region->region))
build_loop_iteration_domains (scop, loop, 0,
isl_set_copy (scop->param_context), doms);
static void
analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple *> stmts)
{
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
if (!bb_in_sese_p (bb, region))
return;
gsi_commit_edge_inserts ();
basic_block bb = gimple_bb (stmt);
- if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
+ if (!bb_in_sese_p (bb, scop->region->region))
return;
if (!gbb_from_bb (bb))
all the uses of DEF outside REGION. */
static void
-propagate_expr_outside_region (tree def, tree expr, sese region)
+propagate_expr_outside_region (tree def, tree expr, sese_l ®ion)
{
gimple_seq stmts;
bool replaced_once = false;
if (replaced_once)
{
- gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
+ gsi_insert_seq_on_edge (region.entry, stmts);
gsi_commit_edge_inserts ();
}
}
static void
rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
{
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
gimple *phi = gsi_stmt (*psi);
tree res = gimple_phi_result (phi);
basic_block bb = gimple_bb (phi);
rewrite_reductions_out_of_ssa (scop_p scop)
{
basic_block bb;
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
FOR_EACH_BB_FN (bb, cfun)
if (bb_in_sese_p (bb, region))
tree var = create_tmp_reg (TREE_TYPE (def));
tree new_name = make_ssa_name (var, stmt);
bool needs_copy = false;
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
imm_use_iterator imm_iter;
gimple *use_stmt;
if (needs_copy)
{
gimple *assign = gimple_build_assign (new_name, def);
- gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
+ gimple_stmt_iterator psi = gsi_after_labels (region.exit->dest);
update_stmt (assign);
gsi_insert_before (&psi, assign, GSI_SAME_STMT);
static bool
rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
{
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
gimple *stmt = gsi_stmt (*gsi);
imm_use_iterator imm_iter;
tree def;
{
basic_block bb;
gimple_stmt_iterator psi;
- sese region = SCOP_REGION (scop);
+ sese_l region = scop->region->region;
bool changed = false;
/* Create an extra empty BB after the scop. */
- split_edge (SESE_EXIT (region));
+ split_edge (region.exit);
FOR_EACH_BB_FN (bb, cfun)
if (bb_in_sese_p (bb, region))
gimple_stmt_iterator psi;
loop_p loop = bb->loop_father;
- if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
+ if (!bb_in_sese_p (bb, scop->region->region))
continue;
n_bbs++;
n_p_stmts += bb->count;
}
- if (loop->header == bb && loop_in_sese_p (loop, SCOP_REGION (scop)))
+ if (loop->header == bb && loop_in_sese_p (loop, scop->region->region))
{
n_loops++;
n_p_loops += bb->count;
fprintf (file, "\nFunction Name: %s\n", current_function_name ());
- edge scop_begin = scop->region->entry;
- edge scop_end = scop->region->exit;
+ edge scop_begin = scop->region->region.entry;
+ edge scop_end = scop->region->region.exit;
fprintf (file, "\nSCoP (entry_edge (bb_%d, bb_%d), ",
scop_begin->src->index, scop_begin->dest->index);
/* Record LOOP as occurring in REGION. */
static void
-sese_record_loop (sese region, loop_p loop)
+sese_record_loop (sese_info_p region, loop_p loop)
{
if (sese_contains_loop (region, loop))
return;
operation was successful. */
void
-build_sese_loop_nests (sese region)
+build_sese_loop_nests (sese_info_p region)
{
unsigned i;
basic_block bb;
struct loop *loop0, *loop1;
FOR_EACH_BB_FN (bb, cfun)
- if (bb_in_sese_p (bb, region))
+ if (bb_in_sese_p (bb, region->region))
{
struct loop *loop = bb->loop_father;
/* Only add loops if they are completely contained in the SCoP. */
if (loop->header == bb
- && bb_in_sese_p (loop->latch, region))
+ && bb_in_sese_p (loop->latch, region->region))
sese_record_loop (region, loop);
}
LIVEOUTS set. */
static void
-sese_build_liveouts_use (sese region, bitmap liveouts, basic_block bb,
+sese_build_liveouts_use (sese_info_p region, bitmap liveouts, basic_block bb,
tree use)
{
- gcc_assert (!bb_in_sese_p (bb, region));
+ gcc_assert (!bb_in_sese_p (bb, region->region));
if (TREE_CODE (use) != SSA_NAME)
return;
basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));
- if (!def_bb || !bb_in_sese_p (def_bb, region))
+ if (!def_bb || !bb_in_sese_p (def_bb, region->region))
return;
unsigned ver = SSA_NAME_VERSION (use);
used in BB that is outside of the REGION. */
static void
-sese_build_liveouts_bb (sese region, bitmap liveouts, basic_block bb)
+sese_build_liveouts_bb (sese_info_p region, bitmap liveouts, basic_block bb)
{
edge e;
edge_iterator ei;
in the LIVEOUTS set. */
static bool
-sese_bad_liveouts_use (sese region, bitmap liveouts, basic_block bb,
+sese_bad_liveouts_use (sese_info_p region, bitmap liveouts, basic_block bb,
tree use)
{
- gcc_assert (!bb_in_sese_p (bb, region));
+ gcc_assert (!bb_in_sese_p (bb, region->region));
if (TREE_CODE (use) != SSA_NAME)
return false;
basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));
- if (!def_bb || !bb_in_sese_p (def_bb, region))
+ if (!def_bb || !bb_in_sese_p (def_bb, region->region))
return false;
return true;
are not marked as liveouts. */
static void
-sese_reset_debug_liveouts_bb (sese region, bitmap liveouts, basic_block bb)
+sese_reset_debug_liveouts_bb (sese_info_p region, bitmap liveouts, basic_block bb)
{
gimple_stmt_iterator bsi;
ssa_op_iter iter;
and used outside the REGION. */
static void
-sese_build_liveouts (sese region, bitmap liveouts)
+sese_build_liveouts (sese_info_p region, bitmap liveouts)
{
basic_block bb;
/* FIXME: We could start iterating form the successor of sese. */
FOR_EACH_BB_FN (bb, cfun)
- if (!bb_in_sese_p (bb, region))
+ if (!bb_in_sese_p (bb, region->region))
sese_build_liveouts_bb (region, liveouts, bb);
/* FIXME: We could start iterating form the successor of sese. */
if (MAY_HAVE_DEBUG_STMTS)
FOR_EACH_BB_FN (bb, cfun)
- if (!bb_in_sese_p (bb, region))
+ if (!bb_in_sese_p (bb, region->region))
sese_reset_debug_liveouts_bb (region, liveouts, bb);
}
/* Builds a new SESE region from edges ENTRY and EXIT. */
-sese
-new_sese (edge entry, edge exit)
+sese_info_p
+new_sese_info (edge entry, edge exit)
{
- sese region = XNEW (struct sese_s);
+ sese_info_p region = XNEW (struct sese_info_t);
- SESE_ENTRY (region) = entry;
- SESE_EXIT (region) = exit;
+ region->region.entry = entry;
+ region->region.exit = exit;
SESE_LOOPS (region) = BITMAP_ALLOC (NULL);
SESE_LOOP_NEST (region).create (3);
SESE_ADD_PARAMS (region) = true;
/* Deletes REGION. */
void
-free_sese (sese region)
+free_sese_info (sese_info_p region)
{
if (SESE_LOOPS (region))
SESE_LOOPS (region) = BITMAP_ALLOC (NULL);
*/
void
-sese_insert_phis_for_liveouts (sese region, basic_block bb,
+sese_insert_phis_for_liveouts (sese_info_p region, basic_block bb,
edge false_e, edge true_e)
{
unsigned i;
/* Register in RENAME_MAP the rename tuple (OLD_NAME, EXPR). */
static void
-set_rename (rename_map_type *rename_map, tree old_name, tree expr, sese region)
+set_rename (rename_map_type *rename_map, tree old_name, tree expr,
+ sese_info_p region)
{
if (old_name == expr)
return;
static bool
rename_uses (gimple *copy, rename_map_type *rename_map,
gimple_stmt_iterator *gsi_tgt,
- sese region, loop_p loop, vec<tree> iv_map,
+ sese_info_p region, loop_p loop, vec<tree> iv_map,
bool *gloog_error)
{
use_operand_p use_p;
continue;
}
- scev = scalar_evolution_in_region (region, loop, old_name);
+ scev = scalar_evolution_in_region (region->region, loop, old_name);
/* At this point we should know the exact scev for each
scalar SSA_NAME used in the scop: all the other scalar
static void
graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
rename_map_type *rename_map,
- vec<tree> iv_map, sese region,
+ vec<tree> iv_map, sese_info_p region,
bool *gloog_error)
{
gimple_stmt_iterator gsi, gsi_tgt;
&& (lhs = gimple_assign_lhs (stmt))
&& TREE_CODE (lhs) == SSA_NAME
&& is_gimple_reg (lhs)
- && scev_analyzable_p (lhs, region))
+ && scev_analyzable_p (lhs, region->region))
continue;
/* Do not copy parameters that have been generated in the header of the
set when the code generation cannot continue. */
edge
-copy_bb_and_scalar_dependences (basic_block bb, sese region,
+copy_bb_and_scalar_dependences (basic_block bb, sese_info_p region,
edge next_e, vec<tree> iv_map,
bool *gloog_error)
{
/* Returns the outermost loop in SCOP that contains BB. */
struct loop *
-outermost_loop_in_sese_1 (sese region, basic_block bb)
+outermost_loop_in_sese_1 (sese_l ®ion, basic_block bb)
{
struct loop *nest;
REGION when the loop containing BB does not belong to REGION. */
loop_p
-outermost_loop_in_sese (sese region, basic_block bb)
+outermost_loop_in_sese (sese_l ®ion, basic_block bb)
{
loop_p nest = outermost_loop_in_sese_1 (region, bb);
/* Sets the false region of an IF_REGION to REGION. */
void
-if_region_set_false_region (ifsese if_region, sese region)
+if_region_set_false_region (ifsese if_region, sese_info_p region)
{
basic_block condition = if_region_get_condition_block (if_region);
edge false_edge = get_false_edge_from_guard_bb (condition);
basic_block dummy = false_edge->dest;
- edge entry_region = SESE_ENTRY (region);
- edge exit_region = SESE_EXIT (region);
+ edge entry_region = region->region.entry;
+ edge exit_region = region->region.exit;
basic_block before_region = entry_region->src;
basic_block last_in_region = exit_region->src;
hashval_t hash = htab_hash_pointer (exit_region);
exit_region->flags = EDGE_FALLTHRU;
recompute_all_dominators ();
- SESE_EXIT (region) = false_edge;
+ region->region.exit = false_edge;
free (if_region->false_region);
if_region->false_region = region;
{
edge e;
edge_iterator ei;
- sese sese_region = XNEW (struct sese_s);
- sese true_region = XNEW (struct sese_s);
- sese false_region = XNEW (struct sese_s);
+ sese_info_p sese_region = XNEW (struct sese_info_t);
+ sese_info_p true_region = XNEW (struct sese_info_t);
+ sese_info_p false_region = XNEW (struct sese_info_t);
ifsese if_region = XNEW (struct ifsese_s);
edge exit = create_empty_if_region_on_edge (entry, condition);
if_region->region = sese_region;
- if_region->region->entry = entry;
- if_region->region->exit = exit;
+ if_region->region->region.entry = entry;
+ if_region->region->region.exit = exit;
FOR_EACH_EDGE (e, ei, entry->dest->succs)
{
if (e->flags & EDGE_TRUE_VALUE)
{
- true_region->entry = e;
- true_region->exit = single_succ_edge (e->dest);
+ true_region->region.entry = e;
+ true_region->region.exit = single_succ_edge (e->dest);
if_region->true_region = true_region;
}
else if (e->flags & EDGE_FALSE_VALUE)
{
- false_region->entry = e;
- false_region->exit = single_succ_edge (e->dest);
+ false_region->region.entry = e;
+ false_region->region.exit = single_succ_edge (e->dest);
if_region->false_region = false_region;
}
}
*/
ifsese
-move_sese_in_condition (sese region)
+move_sese_in_condition (sese_info_p region)
{
- basic_block pred_block = split_edge (SESE_ENTRY (region));
+ basic_block pred_block = split_edge (region->region.entry);
ifsese if_region;
- SESE_ENTRY (region) = single_succ_edge (pred_block);
+ region->region.entry = single_succ_edge (pred_block);
if_region = create_if_region_on_edge (single_pred_edge (pred_block),
integer_one_node);
if_region_set_false_region (if_region, region);
void
set_ifsese_condition (ifsese if_region, tree condition)
{
- sese region = if_region->region;
- edge entry = region->entry;
+ sese_info_p region = if_region->region;
+ edge entry = region->region.entry;
basic_block bb = entry->dest;
gimple *last = last_stmt (bb);
gimple_stmt_iterator gsi = gsi_last_bb (bb);
variant in REGION. */
bool
-invariant_in_sese_p_rec (tree t, sese region)
+invariant_in_sese_p_rec (tree t, sese_l ®ion)
{
ssa_op_iter iter;
use_operand_p use_p;
is not defined in the REGION is considered a parameter. */
tree
-scalar_evolution_in_region (sese region, loop_p loop, tree t)
+scalar_evolution_in_region (sese_l ®ion, loop_p loop, tree t)
{
gimple *def;
struct loop *def_loop;
- basic_block before = block_before_sese (region);
+ basic_block before = region.entry->src;
/* SCOP parameters. */
if (TREE_CODE (t) == SSA_NAME
/* A Single Entry, Single Exit region is a part of the CFG delimited
by two edges. */
-typedef struct sese_s
+struct sese_l
{
- /* Single ENTRY and single EXIT from the SESE region. */
- edge entry, exit;
+ sese_l (edge e, edge x) : entry (e), exit (x) {}
+
+ /* This is to push objects of sese_l in a vec. */
+ sese_l (int i) : entry (NULL), exit (NULL) { gcc_assert (i == 0); }
+
+ operator bool () const { return entry && exit; }
+
+ const sese_l &
+ operator= (const sese_l &s)
+ {
+ entry = s.entry;
+ exit = s.exit;
+ return *this;
+ }
+
+ edge entry;
+ edge exit;
+};
+
+/* Get the entry of an sese S. */
+
+static inline basic_block
+get_entry_bb (sese_l &s)
+{
+ return s.entry->dest;
+}
+
+/* Get the exit of an sese S. */
+
+static inline basic_block
+get_exit_bb (sese_l &s)
+{
+ return s.exit->src;
+}
+
+/* A helper structure for bookkeeping information about a scop in graphite. */
+typedef struct sese_info_t
+{
+ /* The SESE region. */
+ sese_l region;
/* Parameters used within the SCOP. */
vec<tree> params;
can only add new params before generating the bb domains, otherwise they
become invalid. */
bool add_params;
-} *sese;
+} *sese_info_p;
-#define SESE_ENTRY(S) (S->entry)
-#define SESE_ENTRY_BB(S) (S->entry->dest)
-#define SESE_EXIT(S) (S->exit)
-#define SESE_EXIT_BB(S) (S->exit->dest)
#define SESE_PARAMS(S) (S->params)
#define SESE_LOOPS(S) (S->loops)
#define SESE_LOOP_NEST(S) (S->loop_nest)
#define SESE_ADD_PARAMS(S) (S->add_params)
-extern sese new_sese (edge, edge);
-extern void free_sese (sese);
-extern void sese_insert_phis_for_liveouts (sese, basic_block, edge, edge);
-extern void build_sese_loop_nests (sese);
-extern edge copy_bb_and_scalar_dependences (basic_block, sese, edge,
+extern sese_info_p new_sese_info (edge, edge);
+extern void free_sese_info (sese_info_p);
+extern void sese_insert_phis_for_liveouts (sese_info_p, basic_block, edge, edge);
+extern void build_sese_loop_nests (sese_info_p);
+extern edge copy_bb_and_scalar_dependences (basic_block, sese_info_p, edge,
vec<tree> , bool *);
-extern struct loop *outermost_loop_in_sese (sese, basic_block);
-extern tree scalar_evolution_in_region (sese, loop_p, tree);
-extern bool invariant_in_sese_p_rec (tree, sese);
+extern struct loop *outermost_loop_in_sese (sese_l &, basic_block);
+extern tree scalar_evolution_in_region (sese_l &, loop_p, tree);
+extern bool invariant_in_sese_p_rec (tree, sese_l &);
/* Check that SESE contains LOOP. */
static inline bool
-sese_contains_loop (sese sese, struct loop *loop)
+sese_contains_loop (sese_info_p sese, struct loop *loop)
{
return bitmap_bit_p (SESE_LOOPS (sese), loop->num);
}
/* The number of parameters in REGION. */
static inline unsigned
-sese_nb_params (sese region)
+sese_nb_params (sese_info_p region)
{
return SESE_PARAMS (region).length ();
}
EXIT blocks. */
static inline bool
-bb_in_sese_p (basic_block bb, sese region)
+bb_in_sese_p (basic_block bb, sese_l &r)
{
- basic_block entry = SESE_ENTRY_BB (region);
- basic_block exit = SESE_EXIT_BB (region);
-
- return bb_in_region (bb, entry, exit);
+ return bb_in_region (bb, r.entry->dest, r.exit->dest);
}
/* Returns true when STMT is defined in REGION. */
static inline bool
-stmt_in_sese_p (gimple *stmt, sese region)
+stmt_in_sese_p (gimple *stmt, sese_l &r)
{
basic_block bb = gimple_bb (stmt);
- return bb && bb_in_sese_p (bb, region);
+ return bb && bb_in_sese_p (bb, r);
}
/* Returns true when NAME is defined in REGION. */
static inline bool
-defined_in_sese_p (tree name, sese region)
+defined_in_sese_p (tree name, sese_l &r)
{
- gimple *stmt = SSA_NAME_DEF_STMT (name);
- return stmt_in_sese_p (stmt, region);
+ return stmt_in_sese_p (SSA_NAME_DEF_STMT (name), r);
}
/* Returns true when LOOP is in REGION. */
static inline bool
-loop_in_sese_p (struct loop *loop, sese region)
+loop_in_sese_p (struct loop *loop, sese_l ®ion)
{
return (bb_in_sese_p (loop->header, region)
&& bb_in_sese_p (loop->latch, region));
loop_2 is completely contained -> depth 1 */
static inline unsigned int
-sese_loop_depth (sese region, loop_p loop)
+sese_loop_depth (sese_l ®ion, loop_p loop)
{
unsigned int depth = 0;
/* Splits BB to make a single entry single exit region. */
-static inline sese
+static inline sese_info_p
split_region_for_bb (basic_block bb)
{
edge entry, exit;
exit = split_block (bb, gsi_stmt (gsi));
}
- return new_sese (entry, exit);
-}
-
-/* Returns the block preceding the entry of a SESE. */
-
-static inline basic_block
-block_before_sese (sese sese)
-{
- return SESE_ENTRY (sese)->src;
+ return new_sese_info (entry, exit);
}
\f
/* A single entry single exit specialized for conditions. */
typedef struct ifsese_s {
- sese region;
- sese true_region;
- sese false_region;
+ sese_info_p region;
+ sese_info_p true_region;
+ sese_info_p false_region;
} *ifsese;
-extern void if_region_set_false_region (ifsese, sese);
-extern ifsese move_sese_in_condition (sese);
+extern void if_region_set_false_region (ifsese, sese_info_p);
+extern ifsese move_sese_in_condition (sese_info_p);
extern edge get_true_edge_from_guard_bb (basic_block);
extern edge get_false_edge_from_guard_bb (basic_block);
extern void set_ifsese_condition (ifsese, tree);
static inline edge
if_region_entry (ifsese if_region)
{
- return SESE_ENTRY (if_region->region);
+ return if_region->region->region.entry;
}
static inline edge
if_region_exit (ifsese if_region)
{
- return SESE_EXIT (if_region->region);
+ return if_region->region->region.exit;
}
static inline basic_block
If there is no corresponding gimple loop, we return NULL. */
static inline loop_p
-gbb_loop_at_index (gimple_poly_bb_p gbb, sese region, int index)
+gbb_loop_at_index (gimple_poly_bb_p gbb, sese_l ®ion, int index)
{
loop_p loop = gbb_loop (gbb);
int depth = sese_loop_depth (region, loop);
while (--depth > index)
loop = loop_outer (loop);
- gcc_assert (sese_contains_loop (region, loop));
+ gcc_assert (loop_in_sese_p (loop, region));
return loop;
}
/* The number of common loops in REGION for GBB1 and GBB2. */
static inline int
-nb_common_loops (sese region, gimple_poly_bb_p gbb1, gimple_poly_bb_p gbb2)
+nb_common_loops (sese_l ®ion, gimple_poly_bb_p gbb1, gimple_poly_bb_p gbb2)
{
loop_p l1 = gbb_loop (gbb1);
loop_p l2 = gbb_loop (gbb2);
evolution analyzer. */
static inline bool
-scev_analyzable_p (tree def, sese region)
+scev_analyzable_p (tree def, sese_l ®ion)
{
loop_p loop;
tree scev;