/* Conversion of SESE regions to Polyhedra.
- Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Contributed by Sebastian Pop <sebastian.pop@amd.com>.
This file is part of GCC.
#include "system.h"
#include "coretypes.h"
-#include "tree-flow.h"
+#include "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimplify.h"
+#include "gimplify-me.h"
+#include "gimple-ssa.h"
+#include "tree-cfg.h"
+#include "tree-phinodes.h"
+#include "ssa-iterators.h"
+#include "stringpool.h"
+#include "tree-ssanames.h"
+#include "tree-ssa-loop-manip.h"
+#include "tree-ssa-loop-niter.h"
+#include "tree-ssa-loop.h"
+#include "tree-into-ssa.h"
#include "tree-pass.h"
#include "cfgloop.h"
#include "tree-chrec.h"
#include "tree-scalar-evolution.h"
#include "domwalk.h"
#include "sese.h"
+#include "tree-ssa-propagate.h"
#ifdef HAVE_cloog
+#include "expr.h"
#include "graphite-poly.h"
#include "graphite-sese-to-poly.h"
remove_phi_node (psi, false);
gsi_insert_on_edge_immediate (e, stmt);
- SSA_NAME_DEF_STMT (res) = stmt;
}
/* Removes an invariant phi node at position PSI by inserting on the
/* Store the GRAPHITE representation of BB. */
static gimple_bb_p
-new_gimple_bb (basic_block bb, VEC (data_reference_p, heap) *drs)
+new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
{
struct gimple_bb *gbb;
bb->aux = gbb;
GBB_BB (gbb) = bb;
GBB_DATA_REFS (gbb) = drs;
- GBB_CONDITIONS (gbb) = NULL;
- GBB_CONDITION_CASES (gbb) = NULL;
+ GBB_CONDITIONS (gbb).create (0);
+ GBB_CONDITION_CASES (gbb).create (0);
return gbb;
}
static void
-free_data_refs_aux (VEC (data_reference_p, heap) *datarefs)
+free_data_refs_aux (vec<data_reference_p> datarefs)
{
unsigned int i;
struct data_reference *dr;
- FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, dr)
+ FOR_EACH_VEC_ELT (datarefs, i, dr)
if (dr->aux)
{
base_alias_pair *bap = (base_alias_pair *)(dr->aux);
free_data_refs_aux (GBB_DATA_REFS (gbb));
free_data_refs (GBB_DATA_REFS (gbb));
- VEC_free (gimple, heap, GBB_CONDITIONS (gbb));
- VEC_free (gimple, heap, GBB_CONDITION_CASES (gbb));
+ GBB_CONDITIONS (gbb).release ();
+ GBB_CONDITION_CASES (gbb).release ();
GBB_BB (gbb)->aux = 0;
XDELETE (gbb);
}
int i;
poly_bb_p pbb;
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
free_gimple_bb (PBB_BLACK_BOX (pbb));
}
/* Deletes all scops in SCOPS. */
void
-free_scops (VEC (scop_p, heap) *scops)
+free_scops (vec<scop_p> scops)
{
int i;
scop_p scop;
- FOR_EACH_VEC_ELT (scop_p, scops, i, scop)
+ FOR_EACH_VEC_ELT (scops, i, scop)
{
remove_gbbs_in_scop (scop);
free_sese (SCOP_REGION (scop));
free_scop (scop);
}
- VEC_free (scop_p, heap, scops);
+ scops.release ();
}
/* Same as outermost_loop_in_sese, returns the outermost loop
static gimple_bb_p
try_generate_gimple_bb (scop_p scop, basic_block bb)
{
- VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
+ vec<data_reference_p> drs;
+ drs.create (5);
sese region = SCOP_REGION (scop);
loop_p nest = outermost_loop_in_sese_1 (region, bb);
gimple_stmt_iterator gsi;
a deepest loop level. */
static void
-graphite_sort_dominated_info (VEC (basic_block, heap) *dom)
+graphite_sort_dominated_info (vec<basic_block> dom)
{
- VEC_qsort (basic_block, dom, compare_bb_depths);
+ dom.qsort (compare_bb_depths);
}
/* Recursive helper function for build_scops_bbs. */
build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
{
sese region = SCOP_REGION (scop);
- VEC (basic_block, heap) *dom;
+ vec<basic_block> dom;
poly_bb_p pbb;
if (bitmap_bit_p (visited, bb->index)
return;
pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
- VEC_safe_push (poly_bb_p, heap, SCOP_BBS (scop), pbb);
+ SCOP_BBS (scop).safe_push (pbb);
bitmap_set_bit (visited, bb->index);
dom = get_dominated_by (CDI_DOMINATORS, bb);
- if (dom == NULL)
+ if (!dom.exists ())
return;
graphite_sort_dominated_info (dom);
- while (!VEC_empty (basic_block, dom))
+ while (!dom.is_empty ())
{
int i;
basic_block dom_bb;
- FOR_EACH_VEC_ELT (basic_block, dom, i, dom_bb)
+ FOR_EACH_VEC_ELT (dom, i, dom_bb)
if (all_non_dominated_preds_marked_p (dom_bb, visited))
{
build_scop_bbs_1 (scop, visited, dom_bb);
- VEC_unordered_remove (basic_block, dom, i);
+ dom.unordered_remove (i);
break;
}
}
- VEC_free (basic_block, heap, dom);
+ dom.release ();
}
/* Gather the basic blocks belonging to the SCOP. */
static void
build_scop_bbs (scop_p scop)
{
- sbitmap visited = sbitmap_alloc (last_basic_block);
+ sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
sese region = SCOP_REGION (scop);
bitmap_clear (visited);
isl_space *dc = isl_set_get_space (scop->context);
isl_aff *static_sched;
- dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops());
+ dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
/* We have to start schedules at 0 on the first component and
incremented before copying. */
static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
{
gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
int prefix;
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 ((sese) s->region,
- get_loop (CHREC_VARIABLE (e))) - 1;
+ unsigned pos = sese_loop_depth ((sese) s->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);
id = isl_id_for_ssa_name (s, e);
dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
- isl_id_free(id);
+ isl_id_free (id);
dom = isl_set_universe (isl_space_copy (space));
aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
gcc_assert (TREE_CODE (name) == SSA_NAME);
- FOR_EACH_VEC_ELT (tree, SESE_PARAMS (region), i, p)
+ FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
if (p == name)
return i;
gcc_assert (SESE_ADD_PARAMS (region));
- i = VEC_length (tree, SESE_PARAMS (region));
- VEC_safe_push (tree, heap, SESE_PARAMS (region), name);
+ i = SESE_PARAMS (region).length ();
+ SESE_PARAMS (region).safe_push (name);
return i;
}
loop_p loop = GBB_BB (gbb)->loop_father;
/* Find parameters in the access functions of data references. */
- FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
+ FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
/* Find parameters in conditional statements. */
- FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
+ FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
{
tree lhs = scalar_evolution_in_region (region, loop,
gimple_cond_lhs (stmt));
int nbp;
/* Find the parameters used in the loop bounds. */
- FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
+ FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
{
tree nb_iters = number_of_latch_executions (loop);
}
/* Find the parameters used in data accesses. */
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
find_params_in_bb (region, PBB_BLACK_BOX (pbb));
nbp = sese_nb_params (region);
tree e;
isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
- FOR_EACH_VEC_ELT (tree, SESE_PARAMS (region), i, e)
+ FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
space = isl_space_set_dim_id (space, isl_dim_param, i,
isl_id_for_ssa_name (scop, e));
if (TREE_CODE (nb_iters) == INTEGER_CST)
{
c = isl_inequality_alloc
- (isl_local_space_from_space(isl_space_copy (space)));
+ (isl_local_space_from_space (isl_space_copy (space)));
c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
tree_int_to_gmp (nb_iters, g);
isl_int_set_gmp (v, g);
c = isl_constraint_set_constant (c, v);
inner = isl_set_add_constraint (inner, c);
}
+ else
+ isl_pw_aff_free (aff);
}
else
gcc_unreachable ();
break;
default:
- isl_pw_aff_free(lhs);
- isl_pw_aff_free(rhs);
+ isl_pw_aff_free (lhs);
+ isl_pw_aff_free (rhs);
return;
}
gimple stmt;
gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
- if (VEC_empty (gimple, GBB_CONDITIONS (gbb)))
+ if (GBB_CONDITIONS (gbb).is_empty ())
return;
- FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
+ FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
switch (gimple_code (stmt))
{
case GIMPLE_COND:
enum tree_code code = gimple_cond_code (stmt);
/* The conditions for ELSE-branches are inverted. */
- if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
+ if (!GBB_CONDITION_CASES (gbb)[i])
code = invert_tree_comparison (code, false);
add_condition_to_pbb (pbb, stmt, code);
int i;
poly_bb_p pbb;
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
add_conditions_to_domain (pbb);
}
-/* Structure used to pass data to dom_walk. */
-
-struct bsc
-{
- VEC (gimple, heap) **conditions, **cases;
- sese region;
-};
-
/* Returns a COND_EXPR statement when BB has a single predecessor, the
edge between BB and its predecessor is not a loop exit edge, and
the last statement of the single predecessor is a COND_EXPR. */
return NULL;
}
+class sese_dom_walker : public dom_walker
+{
+public:
+ sese_dom_walker (cdi_direction, sese);
+
+ 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_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
+ : dom_walker (direction), m_region (region)
+{
+}
+
/* Call-back for dom_walk executed before visiting the dominated
blocks. */
-static void
-build_sese_conditions_before (struct dom_walk_data *dw_data,
- basic_block bb)
+void
+sese_dom_walker::before_dom_children (basic_block bb)
{
- struct bsc *data = (struct bsc *) dw_data->global_data;
- VEC (gimple, heap) **conditions = data->conditions;
- VEC (gimple, heap) **cases = data->cases;
gimple_bb_p gbb;
gimple stmt;
- if (!bb_in_sese_p (bb, data->region))
+ if (!bb_in_sese_p (bb, m_region))
return;
stmt = single_pred_cond_non_loop_exit (bb);
{
edge e = single_pred_edge (bb);
- VEC_safe_push (gimple, heap, *conditions, stmt);
+ m_conditions.safe_push (stmt);
if (e->flags & EDGE_TRUE_VALUE)
- VEC_safe_push (gimple, heap, *cases, stmt);
+ m_cases.safe_push (stmt);
else
- VEC_safe_push (gimple, heap, *cases, NULL);
+ m_cases.safe_push (NULL);
}
gbb = gbb_from_bb (bb);
if (gbb)
{
- GBB_CONDITIONS (gbb) = VEC_copy (gimple, heap, *conditions);
- GBB_CONDITION_CASES (gbb) = VEC_copy (gimple, heap, *cases);
+ GBB_CONDITIONS (gbb) = m_conditions.copy ();
+ GBB_CONDITION_CASES (gbb) = m_cases.copy ();
}
}
/* Call-back for dom_walk executed after visiting the dominated
blocks. */
-static void
-build_sese_conditions_after (struct dom_walk_data *dw_data,
- basic_block bb)
+void
+sese_dom_walker::after_dom_children (basic_block bb)
{
- struct bsc *data = (struct bsc *) dw_data->global_data;
- VEC (gimple, heap) **conditions = data->conditions;
- VEC (gimple, heap) **cases = data->cases;
-
- if (!bb_in_sese_p (bb, data->region))
+ if (!bb_in_sese_p (bb, m_region))
return;
if (single_pred_cond_non_loop_exit (bb))
{
- VEC_pop (gimple, *conditions);
- VEC_pop (gimple, *cases);
+ m_conditions.pop ();
+ m_cases.pop ();
}
}
-/* Record all conditions in REGION. */
-
-static void
-build_sese_conditions (sese region)
-{
- struct dom_walk_data walk_data;
- VEC (gimple, heap) *conditions = VEC_alloc (gimple, heap, 3);
- VEC (gimple, heap) *cases = VEC_alloc (gimple, heap, 3);
- struct bsc data;
-
- data.conditions = &conditions;
- data.cases = &cases;
- data.region = region;
-
- walk_data.dom_direction = CDI_DOMINATORS;
- walk_data.initialize_block_local_data = NULL;
- walk_data.before_dom_children = build_sese_conditions_before;
- walk_data.after_dom_children = build_sese_conditions_after;
- walk_data.global_data = &data;
- walk_data.block_local_data_size = 0;
-
- init_walk_dominator_tree (&walk_data);
- walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
- fini_walk_dominator_tree (&walk_data);
-
- VEC_free (gimple, heap, conditions);
- VEC_free (gimple, heap, cases);
-}
-
/* Add constraints on the possible values of parameter P from the type
of P. */
static void
add_param_constraints (scop_p scop, graphite_dim_t p)
{
- tree parameter = VEC_index (tree, SESE_PARAMS (SCOP_REGION (scop)), p);
+ tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
tree type = TREE_TYPE (parameter);
tree lb = NULL_TREE;
tree ub = NULL_TREE;
sese region = SCOP_REGION (scop);
int i;
poly_bb_p pbb;
- int nb_loops = number_of_loops ();
+ int nb_loops = number_of_loops (cfun);
isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
- FOR_EACH_VEC_ELT (loop_p, SESE_LOOP_NEST (region), i, loop)
+ FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
if (!loop_in_sese_p (loop_outer (loop), region))
build_loop_iteration_domains (scop, loop, 0,
isl_set_copy (scop->context), doms);
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
{
loop = pbb_loop (pbb);
subscript - low >= 0 and high - subscript >= 0 in case one of
the two bounds isn't known. Do the same here? */
- if (host_integerp (low, 0)
+ if (tree_fits_shwi_p (low)
&& high
- && host_integerp (high, 0)
+ && tree_fits_shwi_p (high)
/* 1-element arrays at end of structures may extend over
their declared size. */
&& !(array_at_struct_end_p (ref)
static inline bool
write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
- VEC (data_reference_p, heap) *drs)
+ vec<data_reference_p> drs)
{
- int num_vertex = VEC_length (data_reference_p, drs);
+ int num_vertex = drs.length ();
int edge_num = 0;
data_reference_p dr1, dr2;
int i, j;
if (num_vertex == 0)
return true;
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
- for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
+ FOR_EACH_VEC_ELT (drs, i, dr1)
+ for (j = i + 1; drs.iterate (j, &dr2); j++)
if (dr_may_alias_p (dr1, dr2, true))
edge_num++;
fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
- for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
+ FOR_EACH_VEC_ELT (drs, i, dr1)
+ for (j = i + 1; drs.iterate (j, &dr2); j++)
if (dr_may_alias_p (dr1, dr2, true))
fprintf (file, "e %d %d\n", i + 1, j + 1);
static inline bool
write_alias_graph_to_ascii_dot (FILE *file, char *comment,
- VEC (data_reference_p, heap) *drs)
+ vec<data_reference_p> drs)
{
- int num_vertex = VEC_length (data_reference_p, drs);
+ int num_vertex = drs.length ();
data_reference_p dr1, dr2;
int i, j;
fprintf (file, "c %s\n", comment);
/* First print all the vertices. */
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
+ FOR_EACH_VEC_ELT (drs, i, dr1)
fprintf (file, "n%d;\n", i);
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
- for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
+ FOR_EACH_VEC_ELT (drs, i, dr1)
+ for (j = i + 1; drs.iterate (j, &dr2); j++)
if (dr_may_alias_p (dr1, dr2, true))
fprintf (file, "n%d n%d\n", i, j);
static inline bool
write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
- VEC (data_reference_p, heap) *drs)
+ vec<data_reference_p> drs)
{
- int num_vertex = VEC_length (data_reference_p, drs);
+ int num_vertex = drs.length ();
data_reference_p dr1, dr2;
int i, j;
if (comment)
fprintf (file, "c %s\n", comment);
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
- for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
+ FOR_EACH_VEC_ELT (drs, i, dr1)
+ for (j = i + 1; drs.iterate (j, &dr2); j++)
if (dr_may_alias_p (dr1, dr2, true))
fprintf (file, "%d %d\n", i, j);
true (1) if the above test is true, and false (0) otherwise. */
static int
-build_alias_set_optimal_p (VEC (data_reference_p, heap) *drs)
+build_alias_set_optimal_p (vec<data_reference_p> drs)
{
- int num_vertices = VEC_length (data_reference_p, drs);
+ int num_vertices = drs.length ();
struct graph *g = new_graph (num_vertices);
data_reference_p dr1, dr2;
int i, j;
int this_component_is_clique;
int all_components_are_cliques = 1;
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
- for (j = i+1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
+ FOR_EACH_VEC_ELT (drs, i, dr1)
+ for (j = i+1; drs.iterate (j, &dr2); j++)
if (dr_may_alias_p (dr1, dr2, true))
{
add_edge (g, i, j);
NULL, true, NULL);
for (i = 0; i < g->n_vertices; i++)
{
- data_reference_p dr = VEC_index (data_reference_p, drs, i);
+ data_reference_p dr = drs[i];
base_alias_pair *bap;
gcc_assert (dr->aux);
/* Group each data reference in DRS with its base object set num. */
static void
-build_base_obj_set_for_drs (VEC (data_reference_p, heap) *drs)
+build_base_obj_set_for_drs (vec<data_reference_p> drs)
{
- int num_vertex = VEC_length (data_reference_p, drs);
+ int num_vertex = drs.length ();
struct graph *g = new_graph (num_vertex);
data_reference_p dr1, dr2;
int i, j;
int *queue;
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
- for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++)
+ FOR_EACH_VEC_ELT (drs, i, dr1)
+ for (j = i + 1; drs.iterate (j, &dr2); j++)
if (dr_same_base_object_p (dr1, dr2))
{
add_edge (g, i, j);
for (i = 0; i < g->n_vertices; i++)
{
- data_reference_p dr = VEC_index (data_reference_p, drs, i);
+ data_reference_p dr = drs[i];
base_alias_pair *bap;
gcc_assert (dr->aux);
{
int j;
data_reference_p dr;
- VEC (data_reference_p, heap) *gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
+ vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
- FOR_EACH_VEC_ELT (data_reference_p, gbb_drs, j, dr)
+ FOR_EACH_VEC_ELT (gbb_drs, j, dr)
build_poly_dr (dr, pbb);
}
/* Dump to file the alias graphs for the data references in DRS. */
static void
-dump_alias_graphs (VEC (data_reference_p, heap) *drs)
+dump_alias_graphs (vec<data_reference_p> drs)
{
char comment[100];
FILE *file_dimacs, *file_ecc, *file_dot;
int i, j;
poly_bb_p pbb;
data_reference_p dr;
- VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
+ auto_vec<data_reference_p, 3> drs;
/* Remove all the PBBs that do not have data references: these basic
blocks are not handled in the polyhedral representation. */
- for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
- if (VEC_empty (data_reference_p, GBB_DATA_REFS (PBB_BLACK_BOX (pbb))))
+ for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
+ if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
{
free_gimple_bb (PBB_BLACK_BOX (pbb));
free_poly_bb (pbb);
- VEC_ordered_remove (poly_bb_p, SCOP_BBS (scop), i);
+ SCOP_BBS (scop).ordered_remove (i);
i--;
}
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
- for (j = 0; VEC_iterate (data_reference_p,
- GBB_DATA_REFS (PBB_BLACK_BOX (pbb)), j, dr); j++)
- VEC_safe_push (data_reference_p, heap, drs, dr);
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
+ for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
+ drs.safe_push (dr);
- FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr)
+ FOR_EACH_VEC_ELT (drs, i, dr)
dr->aux = XNEW (base_alias_pair);
if (!build_alias_set_optimal_p (drs))
if (0)
dump_alias_graphs (drs);
- VEC_free (data_reference_p, heap, drs);
+ drs.release ();
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
build_pbb_drs (pbb);
}
GBB_DATA_REFS vector of BB. */
static void
-analyze_drs_in_stmts (scop_p scop, basic_block bb, VEC (gimple, heap) *stmts)
+analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
{
loop_p nest;
gimple_bb_p gbb;
nest = outermost_loop_in_sese_1 (region, bb);
gbb = gbb_from_bb (bb);
- FOR_EACH_VEC_ELT (gimple, stmts, i, stmt)
+ FOR_EACH_VEC_ELT (stmts, i, stmt)
{
loop_p loop;
gimple_stmt_iterator insert_gsi)
{
gimple_stmt_iterator gsi;
- VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
+ auto_vec<gimple, 3> x;
gimple_seq_add_stmt (&stmts, stmt);
for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
- VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
+ x.safe_push (gsi_stmt (gsi));
gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
- VEC_free (gimple, heap, x);
}
/* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
gimple_seq stmts;
gimple_stmt_iterator gsi;
tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
- gimple stmt = gimple_build_assign (res, var);
- VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
+ gimple stmt = gimple_build_assign (unshare_expr (res), var);
+ auto_vec<gimple, 3> x;
gimple_seq_add_stmt (&stmts, stmt);
for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
- VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
+ x.safe_push (gsi_stmt (gsi));
if (gimple_code (after_stmt) == GIMPLE_PHI)
{
}
analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
- VEC_free (gimple, heap, x);
}
/* Creates a poly_bb_p for basic_block BB from the existing PBB. */
static void
new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
{
- VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 3);
+ vec<data_reference_p> drs;
+ drs.create (3);
gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
- int index, n = VEC_length (poly_bb_p, SCOP_BBS (scop));
+ int index, n = SCOP_BBS (scop).length ();
/* The INDEX of PBB in SCOP_BBS. */
for (index = 0; index < n; index++)
- if (VEC_index (poly_bb_p, SCOP_BBS (scop), index) == pbb)
+ if (SCOP_BBS (scop)[index] == pbb)
break;
pbb1->domain = isl_set_copy (pbb->domain);
GBB_PBB (gbb1) = pbb1;
- GBB_CONDITIONS (gbb1) = VEC_copy (gimple, heap, GBB_CONDITIONS (gbb));
- GBB_CONDITION_CASES (gbb1) = VEC_copy (gimple, heap, GBB_CONDITION_CASES (gbb));
- VEC_safe_insert (poly_bb_p, heap, SCOP_BBS (scop), index + 1, pbb1);
+ GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
+ GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
+ SCOP_BBS (scop).safe_insert (index + 1, pbb1);
}
/* Insert on edge E the assignment "RES := EXPR". */
gimple_stmt_iterator gsi;
gimple_seq stmts = NULL;
tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
- gimple stmt = gimple_build_assign (res, var);
+ gimple stmt = gimple_build_assign (unshare_expr (res), var);
basic_block bb;
- VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
+ auto_vec<gimple, 3> x;
gimple_seq_add_stmt (&stmts, stmt);
for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
- VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
+ x.safe_push (gsi_stmt (gsi));
gsi_insert_seq_on_edge (e, stmts);
gsi_commit_edge_inserts ();
new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
analyze_drs_in_stmts (scop, bb, x);
- VEC_free (gimple, heap, x);
}
/* Creates a zero dimension array of the same type as VAR. */
stmt = gimple_build_assign (res, arg);
remove_phi_node (psi, false);
gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
- SSA_NAME_DEF_STMT (res) = stmt;
return;
}
{
tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
- stmt = gimple_build_assign (res, zero_dim_array);
+ stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
if (TREE_CODE (arg) == SSA_NAME)
insert_out_of_ssa_copy (scop, zero_dim_array, arg,
gimple phi = gsi_stmt (*psi);
basic_block bb = gimple_bb (phi);
tree res = gimple_phi_result (phi);
- tree var;
tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
gimple stmt;
- gimple_seq stmts;
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
}
- var = force_gimple_operand (zero_dim_array, &stmts, true, NULL_TREE);
-
- stmt = gimple_build_assign (res, var);
+ stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
remove_phi_node (psi, false);
- SSA_NAME_DEF_STMT (res) = stmt;
-
- insert_stmts (scop, stmt, stmts, gsi_after_labels (bb));
+ insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
}
/* Rewrite the degenerate phi node at position PSI from the degenerate
stmt = gimple_build_assign (res, rhs);
remove_phi_node (psi, false);
- SSA_NAME_DEF_STMT (res) = stmt;
gsi = gsi_after_labels (bb);
gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
gimple_stmt_iterator psi;
sese region = SCOP_REGION (scop);
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
if (bb_in_sese_p (bb, region))
for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
{
gimple assign = gimple_build_assign (new_name, def);
gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
- SSA_NAME_DEF_STMT (new_name) = assign;
update_stmt (assign);
gsi_insert_before (&psi, assign, GSI_SAME_STMT);
}
/* Create an extra empty BB after the scop. */
split_edge (SESE_EXIT (region));
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
if (bb_in_sese_p (bb, region))
for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
poly_bb_p pbb;
int res = 0;
- FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
+ FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
res++;
/* A part of the data references will end in a different basic block
after the split: move the DRs from the original GBB to the newly
created GBB1. */
- FOR_EACH_VEC_ELT (data_reference_p, GBB_DATA_REFS (gbb), i, dr)
+ FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
{
basic_block bb1 = gimple_bb (DR_STMT (dr));
if (bb1 != bb)
{
gimple_bb_p gbb1 = gbb_from_bb (bb1);
- VEC_safe_push (data_reference_p, heap, GBB_DATA_REFS (gbb1), dr);
- VEC_ordered_remove (data_reference_p, GBB_DATA_REFS (gbb), i);
+ GBB_DATA_REFS (gbb1).safe_push (dr);
+ GBB_DATA_REFS (gbb).ordered_remove (i);
i--;
}
}
static gimple
detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
- VEC (gimple, heap) **in,
- VEC (gimple, heap) **out)
+ vec<gimple> *in,
+ vec<gimple> *out)
{
gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
if (!phi)
return NULL;
- VEC_safe_push (gimple, heap, *in, stmt);
- VEC_safe_push (gimple, heap, *out, stmt);
+ in->safe_push (stmt);
+ out->safe_push (stmt);
return phi;
}
STMT. Return the phi node of the reduction cycle, or NULL. */
static gimple
-detect_commutative_reduction_assign (gimple stmt, VEC (gimple, heap) **in,
- VEC (gimple, heap) **out)
+detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
+ vec<gimple> *out)
{
tree lhs = gimple_assign_lhs (stmt);
node of the reduction cycle, or NULL. */
static gimple
-detect_commutative_reduction (scop_p scop, gimple stmt, VEC (gimple, heap) **in,
- VEC (gimple, heap) **out)
+detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
+ vec<gimple> *out)
{
if (scalar_close_phi_node_p (stmt))
{
|| !has_single_use (gimple_phi_result (phi))))
return NULL;
- VEC_safe_push (gimple, heap, *in, loop_phi);
- VEC_safe_push (gimple, heap, *out, close_phi);
+ in->safe_push (loop_phi);
+ out->safe_push (close_phi);
return phi;
}
tree def;
use_operand_p use_p;
gimple_stmt_iterator gsi;
- VEC (gimple, heap) *update = VEC_alloc (gimple, heap, 3);
+ auto_vec<gimple, 3> update;
unsigned int i;
gimple stmt;
if (is_gimple_debug (stmt))
{
gimple_debug_bind_reset_value (stmt);
- VEC_safe_push (gimple, heap, update, stmt);
+ update.safe_push (stmt);
}
}
- FOR_EACH_VEC_ELT (gimple, update, i, stmt)
+ FOR_EACH_VEC_ELT (update, i, stmt)
update_stmt (stmt);
- VEC_free (gimple, heap, update);
-
gsi = gsi_for_phi_node (phi);
remove_phi_node (&gsi, false);
}
static void
translate_scalar_reduction_to_array (scop_p scop,
- VEC (gimple, heap) *in,
- VEC (gimple, heap) *out)
+ vec<gimple> in,
+ vec<gimple> out)
{
gimple loop_phi;
- unsigned int i = VEC_length (gimple, out) - 1;
- tree red = close_phi_written_to_memory (VEC_index (gimple, out, i));
+ unsigned int i = out.length () - 1;
+ tree red = close_phi_written_to_memory (out[i]);
- FOR_EACH_VEC_ELT (gimple, in, i, loop_phi)
+ FOR_EACH_VEC_ELT (in, i, loop_phi)
{
- gimple close_phi = VEC_index (gimple, out, i);
+ gimple close_phi = out[i];
if (i == 0)
{
red = create_zero_dim_array
(gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
- translate_scalar_reduction_to_array_for_stmt
- (scop, red, stmt, VEC_index (gimple, in, 1));
+ translate_scalar_reduction_to_array_for_stmt (scop, red, stmt, in[1]);
continue;
}
- if (i == VEC_length (gimple, in) - 1)
+ if (i == in.length () - 1)
{
insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
unshare_expr (red), close_phi);
gimple close_phi)
{
bool res;
- VEC (gimple, heap) *in = VEC_alloc (gimple, heap, 10);
- VEC (gimple, heap) *out = VEC_alloc (gimple, heap, 10);
+ auto_vec<gimple, 10> in;
+ auto_vec<gimple, 10> out;
detect_commutative_reduction (scop, close_phi, &in, &out);
- res = VEC_length (gimple, in) > 1;
+ res = in.length () > 1;
if (res)
translate_scalar_reduction_to_array (scop, in, out);
- VEC_free (gimple, heap, in);
- VEC_free (gimple, heap, out);
return res;
}
static void
rewrite_commutative_reductions_out_of_ssa (scop_p scop)
{
- loop_iterator li;
loop_p loop;
bool changed = false;
sese region = SCOP_REGION (scop);
- FOR_EACH_LOOP (li, loop, 0)
+ FOR_EACH_LOOP (loop, 0)
if (loop_in_sese_p (loop, region))
changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
static bool
scop_ivs_can_be_represented (scop_p scop)
{
- loop_iterator li;
loop_p loop;
gimple_stmt_iterator psi;
bool result = true;
- FOR_EACH_LOOP (li, loop, 0)
+ FOR_EACH_LOOP (loop, 0)
{
if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
continue;
}
}
if (!result)
- FOR_EACH_LOOP_BREAK (li);
+ break;
}
return result;
rewrite_commutative_reductions_out_of_ssa (scop);
build_sese_loop_nests (region);
- build_sese_conditions (region);
+ /* Record all conditions in REGION. */
+ sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
find_scop_parameters (scop);
max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);