return true;
}
+/* Records the status of a data reference. This struct is attached to
+ each DR->aux field. */
+
+struct ifc_dr {
+ /* -1 when not initialized, 0 when false, 1 when true. */
+ int written_at_least_once;
+
+ /* -1 when not initialized, 0 when false, 1 when true. */
+ int rw_unconditionally;
+};
+
+#define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
+#define DR_WRITTEN_AT_LEAST_ONCE(DR) (IFC_DR (DR)->written_at_least_once)
+#define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
+
/* Returns true when the memory references of STMT are read or written
unconditionally. In other words, this function returns true when
for every data reference A in STMT there exist other accesses to
if (DR_STMT (a) == stmt)
{
bool found = false;
+ int x = DR_RW_UNCONDITIONALLY (a);
+
+ if (x == 0)
+ return false;
+
+ if (x == 1)
+ continue;
for (j = 0; VEC_iterate (data_reference_p, drs, j, b); j++)
if (DR_STMT (b) != stmt
{
tree cb = bb_predicate (gimple_bb (DR_STMT (b)));
- if (is_true_predicate (cb)
+ if (DR_RW_UNCONDITIONALLY (b) == 1
+ || is_true_predicate (cb)
|| is_true_predicate (ca = fold_or_predicates (EXPR_LOCATION (cb),
ca, cb)))
{
+ DR_RW_UNCONDITIONALLY (a) = 1;
+ DR_RW_UNCONDITIONALLY (b) = 1;
found = true;
break;
}
}
if (!found)
- return false;
+ {
+ DR_RW_UNCONDITIONALLY (a) = 0;
+ return false;
+ }
}
return true;
for (i = 0; VEC_iterate (data_reference_p, drs, i, a); i++)
if (DR_STMT (a) == stmt
- && !DR_IS_READ (a))
+ && DR_IS_WRITE (a))
{
bool found = false;
+ int x = DR_WRITTEN_AT_LEAST_ONCE (a);
+
+ if (x == 0)
+ return false;
+
+ if (x == 1)
+ continue;
for (j = 0; VEC_iterate (data_reference_p, drs, j, b); j++)
if (DR_STMT (b) != stmt
- && !DR_IS_READ (b)
+ && DR_IS_WRITE (b)
&& same_data_refs_base_objects (a, b))
{
tree cb = bb_predicate (gimple_bb (DR_STMT (b)));
- if (is_true_predicate (cb)
+ if (DR_WRITTEN_AT_LEAST_ONCE (b) == 1
+ || is_true_predicate (cb)
|| is_true_predicate (ca = fold_or_predicates (EXPR_LOCATION (cb),
ca, cb)))
{
+ DR_WRITTEN_AT_LEAST_ONCE (a) = 1;
+ DR_WRITTEN_AT_LEAST_ONCE (b) = 1;
found = true;
break;
}
}
if (!found)
- return false;
+ {
+ DR_WRITTEN_AT_LEAST_ONCE (a) = 0;
+ return false;
+ }
}
return true;
case GIMPLE_COND:
{
- tree c2;
+ tree c2, tem;
edge true_edge, false_edge;
location_t loc = gimple_location (stmt);
tree c = fold_build2_loc (loc, gimple_cond_code (stmt),
/* If C is false, then FALSE_EDGE is taken. */
c2 = invert_truthvalue_loc (loc, unshare_expr (c));
+ tem = canonicalize_cond_expr_cond (c2);
+ if (tem)
+ c2 = tem;
add_to_dst_predicate_list (loop, false_edge, cond, c2);
cond = NULL_TREE;
if (!res)
return false;
+ if (flag_tree_loop_if_convert_stores)
+ {
+ data_reference_p dr;
+
+ for (i = 0; VEC_iterate (data_reference_p, *refs, i, dr); i++)
+ {
+ dr->aux = XNEW (struct ifc_dr);
+ DR_WRITTEN_AT_LEAST_ONCE (dr) = -1;
+ DR_RW_UNCONDITIONALLY (dr) = -1;
+ }
+ }
+
for (i = 0; i < loop->num_nodes; i++)
{
basic_block bb = ifc_bbs[i];
ddrs = VEC_alloc (ddr_p, heap, 25);
res = if_convertible_loop_p_1 (loop, &refs, &ddrs);
+ if (flag_tree_loop_if_convert_stores)
+ {
+ data_reference_p dr;
+ unsigned int i;
+
+ for (i = 0; VEC_iterate (data_reference_p, refs, i, dr); i++)
+ free (dr->aux);
+ }
+
free_data_refs (refs);
free_dependence_relations (ddrs);
return res;