{
tree base_a = DR_BASE_NAME (a);
tree base_b = DR_BASE_NAME (b);
- tree ta, tb;
if (!base_a || !base_b)
return false;
- ta = TREE_TYPE (base_a);
- tb = TREE_TYPE (base_b);
-
- gcc_assert (!POINTER_TYPE_P (ta) && !POINTER_TYPE_P (tb));
-
/* Determine if same base. Example: for the array accesses
a[i], b[i] or pointer accesses *a, *b, bases are a, b. */
if (base_a == base_b)
static tree
analyze_array_indexes (struct loop *loop,
- varray_type *access_fns,
+ VEC(tree,heap) **access_fns,
tree ref, tree stmt)
{
tree opnd0, opnd1;
if (loop->estimated_nb_iterations == NULL_TREE)
estimate_niter_from_size_of_data (loop, opnd0, access_fn, stmt);
- VARRAY_PUSH_TREE (*access_fns, access_fn);
+ VEC_safe_push (tree, heap, *access_fns, access_fn);
/* Recursively record other array access functions. */
if (TREE_CODE (opnd0) == ARRAY_REF)
DR_STMT (res) = stmt;
DR_REF (res) = ref;
- VARRAY_TREE_INIT (DR_ACCESS_FNS (res), 3, "access_fns");
+ DR_ACCESS_FNS (res) = VEC_alloc (tree, heap, 3);
DR_BASE_NAME (res) = analyze_array_indexes
(loop_containing_stmt (stmt), &(DR_ACCESS_FNS (res)), ref, stmt);
DR_IS_READ (res) = is_read;
DR_STMT (res) = stmt;
DR_REF (res) = ref;
- VARRAY_TREE_INIT (DR_ACCESS_FNS (res), 5, "access_fns");
+ DR_ACCESS_FNS (res) = VEC_alloc (tree, heap, 5);
DR_BASE_NAME (res) = base;
- VARRAY_PUSH_TREE (DR_ACCESS_FNS (res), access_fn);
+ VEC_quick_push (tree, DR_ACCESS_FNS (res), access_fn);
DR_IS_READ (res) = is_read;
if (dump_file && (dump_flags & TDF_DETAILS))
/* Determine for each subscript in the data dependence relation DDR
the distance. */
-static void
+void
compute_subscript_distance (struct data_dependence_relation *ddr)
{
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
starting at FIRST_LOOP_DEPTH.
Return TRUE otherwise. */
-static bool
+bool
build_classic_dist_vector (struct data_dependence_relation *ddr,
int nb_loops, int first_loop_depth)
{
access_functions_are_affine_or_constant_p (struct data_reference *a)
{
unsigned int i;
- varray_type fns = DR_ACCESS_FNS (a);
+ VEC(tree,heap) **fns = &DR_ACCESS_FNS (a);
+ tree t;
- for (i = 0; i < VARRAY_ACTIVE_SIZE (fns); i++)
- if (!evolution_function_is_constant_p (VARRAY_TREE (fns, i))
- && !evolution_function_is_affine_multivariate_p (VARRAY_TREE (fns, i)))
+ for (i = 0; VEC_iterate (tree, *fns, i, t); i++)
+ if (!evolution_function_is_constant_p (t)
+ && !evolution_function_is_affine_multivariate_p (t))
return false;
return true;
fprintf (dump_file, ")\n");
}
+
+typedef struct data_dependence_relation *ddr_p;
+DEF_VEC_P(ddr_p);
+DEF_VEC_ALLOC_P(ddr_p,heap);
+
/* Compute a subset of the data dependence relation graph. Don't
compute read-read relations, and avoid the computation of the
opposite relation, i.e. when AB has been computed, don't compute BA.
static void
compute_all_dependences (varray_type datarefs,
- varray_type *dependence_relations)
+ VEC(ddr_p,heap) **dependence_relations)
{
unsigned int i, j, N;
b = VARRAY_GENERIC_PTR (datarefs, j);
ddr = initialize_data_dependence_relation (a, b);
- VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
+ VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
compute_affine_dependence (ddr);
compute_subscript_distance (ddr);
}
tree
find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
{
- bool dont_know_node_not_inserted = true;
basic_block bb, *bbs;
unsigned int i;
block_stmt_iterator bsi;
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
tree stmt = bsi_stmt (bsi);
- stmt_ann_t ann = stmt_ann (stmt);
- if (TREE_CODE (stmt) != MODIFY_EXPR)
- continue;
+ /* ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
+ Calls have side-effects, except those to const or pure
+ functions. */
+ if ((TREE_CODE (stmt) == CALL_EXPR
+ && !(call_expr_flags (stmt) & (ECF_CONST | ECF_PURE)))
+ || (TREE_CODE (stmt) == ASM_EXPR
+ && ASM_VOLATILE_P (stmt)))
+ goto insert_dont_know_node;
- if (!VUSE_OPS (ann)
- && !V_MUST_DEF_OPS (ann)
- && !V_MAY_DEF_OPS (ann))
+ if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
continue;
-
- /* In the GIMPLE representation, a modify expression
- contains a single load or store to memory. */
- if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF)
- VARRAY_PUSH_GENERIC_PTR
- (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 0),
- false));
-
- else if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ARRAY_REF)
- VARRAY_PUSH_GENERIC_PTR
- (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 1),
- true));
- else
+
+ switch (TREE_CODE (stmt))
{
- if (dont_know_node_not_inserted)
+ case MODIFY_EXPR:
+ if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF)
+ VARRAY_PUSH_GENERIC_PTR
+ (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 0),
+ false));
+
+ if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ARRAY_REF)
+ VARRAY_PUSH_GENERIC_PTR
+ (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 1),
+ true));
+
+ if (TREE_CODE (TREE_OPERAND (stmt, 0)) != ARRAY_REF
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) != ARRAY_REF)
+ goto insert_dont_know_node;
+
+ break;
+
+ case CALL_EXPR:
+ {
+ tree args;
+ bool one_inserted = false;
+
+ for (args = TREE_OPERAND (stmt, 1); args; args = TREE_CHAIN (args))
+ if (TREE_CODE (TREE_VALUE (args)) == ARRAY_REF)
+ {
+ VARRAY_PUSH_GENERIC_PTR
+ (*datarefs, analyze_array (stmt, TREE_VALUE (args), true));
+ one_inserted = true;
+ }
+
+ if (!one_inserted)
+ goto insert_dont_know_node;
+
+ break;
+ }
+
+ default:
{
struct data_reference *res;
+
+ insert_dont_know_node:;
res = xmalloc (sizeof (struct data_reference));
DR_STMT (res) = NULL_TREE;
DR_REF (res) = NULL_TREE;
DR_BASE_NAME (res) = NULL;
DR_IS_READ (res) = false;
VARRAY_PUSH_GENERIC_PTR (*datarefs, res);
- dont_know_node_not_inserted = false;
+
+ free (bbs);
+ return chrec_dont_know;
}
}
/* When there are no defs in the loop, the loop is parallel. */
- if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0
- || NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
+ if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
bb->loop_father->parallel_p = false;
}
free (bbs);
- return dont_know_node_not_inserted ? NULL_TREE : chrec_dont_know;
+ return NULL_TREE;
}
\f
varray_type *dependence_relations)
{
unsigned int i;
- varray_type allrelations;
+ VEC(ddr_p,heap) *allrelations;
+ struct data_dependence_relation *ddr;
/* If one of the data references is not computable, give up without
spending time to compute other dependences. */
return;
}
- VARRAY_GENERIC_PTR_INIT (allrelations, 1, "Data dependence relations");
+ allrelations = NULL;
compute_all_dependences (*datarefs, &allrelations);
- for (i = 0; i < VARRAY_ACTIVE_SIZE (allrelations); i++)
+ for (i = 0; VEC_iterate (ddr_p, allrelations, i, ddr); i++)
{
- struct data_dependence_relation *ddr;
- ddr = VARRAY_GENERIC_PTR (allrelations, i);
if (build_classic_dist_vector (ddr, nb_loops, loop->depth))
{
VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
VARRAY_GENERIC_PTR (datarefs, i);
if (dr)
{
- if (DR_ACCESS_FNS (dr))
- varray_clear (DR_ACCESS_FNS (dr));
+ VEC_free (tree, heap, DR_ACCESS_FNS (dr));
free (dr);
}
}