#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 {
Graphite. */
static bool
-stmt_has_simple_data_refs_p (loop_p outermost_loop, gimple stmt)
+stmt_has_simple_data_refs_p (loop_p outermost_loop ATTRIBUTE_UNUSED,
+ gimple stmt)
{
data_reference_p dr;
unsigned i;
int j;
bool res = true;
- VEC (data_reference_p, heap) *drs = VEC_alloc (data_reference_p, heap, 5);
+ VEC (data_reference_p, heap) *drs = NULL;
+ loop_p outer;
- graphite_find_data_references_in_stmt (outermost_loop,
- loop_containing_stmt (stmt),
- stmt, &drs);
+ for (outer = loop_containing_stmt (stmt); outer; outer = loop_outer (outer))
+ {
+ graphite_find_data_references_in_stmt (outer,
+ 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++)
- if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i)))
- {
- res = false;
- goto done;
- }
+ FOR_EACH_VEC_ELT (data_reference_p, drs, j, dr)
+ for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++)
+ if (!graphite_can_represent_scev (DR_ACCESS_FN (dr, i)))
+ {
+ res = false;
+ goto done;
+ }
+
+ free_data_refs (drs);
+ drs = NULL;
+ }
done:
free_data_refs (drs);
static bool
graphite_can_represent_loop (basic_block scop_entry, loop_p loop)
{
- tree niter = number_of_latch_executions (loop);
-
- /* Number of iterations unknown. */
- if (chrec_contains_undetermined (niter))
- return false;
+ tree niter;
+ struct tree_niter_desc niter_desc;
- /* Number of iterations not affine. */
- if (!graphite_can_represent_expr (scop_entry, loop, niter))
- return false;
+ /* FIXME: For the moment, graphite cannot be used on loops that
+ iterate using induction variables that wrap. */
- 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);