#include "graphite-poly.h"
#include "graphite-scop-detection.h"
+/* Forward declarations. */
+static void make_close_phi_nodes_unique (basic_block);
+
/* The type of the analyzed basic block. */
typedef enum gbb_type {
bool res = true;
VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
- graphite_find_data_references_in_stmt (outermost_loop, stmt, &drs);
+ graphite_find_data_references_in_stmt (outermost_loop,
+ loop_containing_stmt (stmt),
+ stmt, &drs);
FOR_EACH_VEC_ELT (data_reference_p, drs, j, dr)
for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++)
static bool
graphite_can_represent_loop (basic_block scop_entry, loop_p loop)
{
- tree niter = number_of_latch_executions (loop);
+ tree niter;
+ struct tree_niter_desc niter_desc;
- /* Number of iterations unknown. */
- if (chrec_contains_undetermined (niter))
- return false;
+ /* FIXME: For the moment, graphite cannot be used on loops that
+ iterate using induction variables that wrap. */
- /* Number of iterations not affine. */
- if (!graphite_can_represent_expr (scop_entry, loop, niter))
- return false;
-
- return true;
+ return 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)
+ && graphite_can_represent_expr (scop_entry, loop, niter);
}
/* Store information needed by scopdet_* functions. */
SET_USE (use_p, res);
update_stmt (use_stmt);
+
+ /* It is possible that we just created a duplicate close-phi
+ for an already-processed containing loop. Check for this
+ case and clean it up. */
+ if (gimple_code (use_stmt) == GIMPLE_PHI
+ && gimple_phi_num_args (use_stmt) == 1)
+ make_close_phi_nodes_unique (gimple_bb (use_stmt));
}
remove_phi_node (gsi, true);