X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-if-conv.c;h=642dbda24cb6041c2c85b9e96df281980146ba48;hb=0a5dd1a5aa5e923702f39d0c25212a65455778e0;hp=55e2a11a2b1665bb1fe8b028b2ca50d58cb0d2aa;hpb=e1cc68bd3e4621c0829b59365aeb11fc4c132e5f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 55e2a11a2b1..642dbda24cb 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -446,6 +446,21 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi) 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 @@ -465,6 +480,13 @@ memrefs_read_or_written_unconditionally (gimple stmt, 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 @@ -472,17 +494,23 @@ memrefs_read_or_written_unconditionally (gimple 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; @@ -505,28 +533,41 @@ write_memrefs_written_at_least_once (gimple stmt, 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; @@ -874,7 +915,7 @@ predicate_bbs (loop_p loop) 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), @@ -891,6 +932,9 @@ predicate_bbs (loop_p loop) /* 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; @@ -972,6 +1016,18 @@ if_convertible_loop_p_1 (struct loop *loop, 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]; @@ -1045,6 +1101,15 @@ if_convertible_loop_p (struct loop *loop) 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;