/* Detection of Static Control Parts (SCoP) for Graphite.
- Copyright (C) 2009-2018 Free Software Foundation, Inc.
+ Copyright (C) 2009-2021 Free Software Foundation, Inc.
Contributed by Sebastian Pop <sebastian.pop@amd.com> and
Tobias Grosser <grosser@fim.uni-passau.de>.
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
-#define USES_ISL
+#define INCLUDE_ISL
#include "config.h"
#include "backend.h"
#include "cfghooks.h"
#include "domwalk.h"
-#include "params.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
tree niter;
struct tree_niter_desc niter_desc;
- return single_exit (loop)
- && !(loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP)
+ /* We can only handle do {} while () style loops correctly. */
+ edge exit = single_exit (loop);
+ if (!exit
+ || !single_pred_p (loop->latch)
+ || exit->src != single_pred (loop->latch)
+ || !empty_block_p (loop->latch))
+ return false;
+
+ return !(loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP)
&& number_of_iterations_exit (loop, single_exit (loop), &niter_desc, false)
&& niter_desc.control.no_overflow
&& (niter = number_of_latch_executions (loop))
&& !chrec_contains_undetermined (niter)
- && !chrec_contains_undetermined (scalar_evolution_in_region (scop,
- loop, niter))
&& graphite_can_represent_expr (scop, loop, niter);
}
{
gcc_assert (s);
+ /* If the exit edge is fake discard the SCoP for now as we're removing the
+ fake edges again after analysis. */
+ if (s.exit->flags & EDGE_FAKE)
+ {
+ DEBUG_PRINT (dp << "[scop-detection-fail] Discarding infinite loop SCoP: ";
+ print_sese (dump_file, s));
+ return;
+ }
+
/* Include the BB with the loop-closed SSA PHI nodes, we need this
block in the region for code-generating out-of-SSA copies.
canonicalize_loop_closed_ssa makes sure that is in proper shape. */
return false;
return graphite_can_represent_scev (scop, CHREC_LEFT (scev));
+ case ADDR_EXPR:
+ /* We cannot encode addresses for ISL. */
+ return false;
+
default:
break;
}
scop_detection::graphite_can_represent_expr (sese_l scop, loop_p loop,
tree expr)
{
- tree scev = scalar_evolution_in_region (scop, loop, expr);
+ tree scev = cached_scalar_evolution_in_region (scop, loop, expr);
return graphite_can_represent_scev (scop, scev);
}
case GIMPLE_ASSIGN:
case GIMPLE_CALL:
- return true;
+ {
+ tree op, lhs = gimple_get_lhs (stmt);
+ ssa_op_iter i;
+ /* If we are not going to instantiate the stmt do not require
+ its operands to be instantiatable at this point. */
+ if (lhs
+ && TREE_CODE (lhs) == SSA_NAME
+ && scev_analyzable_p (lhs, scop))
+ return true;
+ /* Verify that if we can analyze operands at their def site we
+ also can represent them when analyzed at their uses. */
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
+ if (scev_analyzable_p (op, scop)
+ && chrec_contains_undetermined
+ (cached_scalar_evolution_in_region (scop,
+ bb->loop_father, op)))
+ {
+ DEBUG_PRINT (dp << "[scop-detection-fail] "
+ << "Graphite cannot code-gen stmt:\n";
+ print_gimple_stmt (dump_file, stmt, 0,
+ TDF_VOPS | TDF_MEMSYMS));
+ return false;
+ }
+ return true;
+ }
default:
/* These nodes cut a new scope. */
assign_parameter_index_in_region (tree name, sese_info_p region)
{
gcc_assert (TREE_CODE (name) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (name))
&& ! defined_in_sese_p (name, region->region));
-
int i;
tree p;
FOR_EACH_VEC_ELT (region->params, i, p)
if (p == name)
return;
- i = region->params.length ();
region->params.safe_push (name);
}
/* Find parameters in conditional statements. */
gimple *stmt;
- loop_p loop = GBB_BB (gbb)->loop_father;
FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
{
- tree lhs = scalar_evolution_in_region (region->region, loop,
- gimple_cond_lhs (stmt));
- tree rhs = scalar_evolution_in_region (region->region, loop,
- gimple_cond_rhs (stmt));
+ loop_p loop = gimple_bb (stmt)->loop_father;
+ tree lhs = cached_scalar_evolution_in_region (region->region, loop,
+ gimple_cond_lhs (stmt));
+ tree rhs = cached_scalar_evolution_in_region (region->region, loop,
+ gimple_cond_rhs (stmt));
+ gcc_assert (!chrec_contains_undetermined (lhs)
+ && !chrec_contains_undetermined (rhs));
scan_tree_for_params (region, lhs);
scan_tree_for_params (region, rhs);
&& (def_bb != gimple_bb (use_stmt) && !is_gimple_debug (use_stmt)))
{
add_write (writes, def);
- /* This is required by the FOR_EACH_IMM_USE_STMT when we want to break
- before all the uses have been visited. */
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
}
int i, j;
int *all_vertices;
+ struct loop *nest
+ = find_common_loop (scop->scop_info->region.entry->dest->loop_father,
+ scop->scop_info->region.exit->src->loop_father);
+
FOR_EACH_VEC_ELT (scop->drs, i, dr1)
for (j = i+1; scop->drs.iterate (j, &dr2); j++)
- if (dr_may_alias_p (dr1->dr, dr2->dr, true))
+ if (dr_may_alias_p (dr1->dr, dr2->dr, nest))
{
/* Dependences in the same alias set need to be handled
by just looking at DR_ACCESS_FNs. */
tree nb_iters = number_of_latch_executions (loop);
if (chrec_contains_symbols (nb_iters))
{
- nb_iters = scalar_evolution_in_region (region->region,
- loop, nb_iters);
+ nb_iters = cached_scalar_evolution_in_region (region->region,
+ loop, nb_iters);
scan_tree_for_params (region, nb_iters);
}
}
continue;
}
- unsigned max_arrays = PARAM_VALUE (PARAM_GRAPHITE_MAX_ARRAYS_PER_SCOP);
+ unsigned max_arrays = param_graphite_max_arrays_per_scop;
if (max_arrays > 0
&& scop->drs.length () >= max_arrays)
{
}
find_scop_parameters (scop);
- graphite_dim_t max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
+ graphite_dim_t max_dim = param_graphite_max_nb_scop_params;
if (max_dim > 0
&& scop_nb_params (scop) > max_dim)
{