diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-23 12:40:57 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-23 12:40:57 +0000 |
commit | 5fc88ffdd79e9915d97afa901f1e5c24ffcedef9 (patch) | |
tree | ef30b2e656f6d882ebaac0ac1bf93bba51c441f9 | |
parent | 39e126b34175e66f8e55e2d2863e49029673ff40 (diff) | |
download | gcc-5fc88ffdd79e9915d97afa901f1e5c24ffcedef9.tar.gz |
2011-08-23 Richard Guenther <rguenther@suse.de>
* Makefile.in (tree-data-ref.o): Add tree-affine.h dependency.
* tree-affine.h (aff_comb_cannot_overlap_p): Declare.
* tree-affine.c (aff_comb_cannot_overlap_p): New function, moved
from ...
* tree-ssa-loop-im.c (cannot_overlap_p): ... here.
(mem_refs_may_alias_p): Adjust.
* tree-data-ref.h (dr_may_alias_p): Adjust.
* tree-data-ref.c: Include tree-affine.h.
(dr_analyze_indices): Do nothing for the non-loop case.
(dr_may_alias_p): Distinguish loop and non-loop case. Disambiguate
more cases in the non-loop case.
* graphite-sese-to-poly.c (write_alias_graph_to_ascii_dimacs): Adjust
calls to dr_may_alias_p.
(write_alias_graph_to_ascii_ecc): Likewise.
(write_alias_graph_to_ascii_dot): Likewise.
(build_alias_set_optimal_p): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177986 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/graphite-sese-to-poly.c | 10 | ||||
-rw-r--r-- | gcc/tree-affine.c | 27 | ||||
-rw-r--r-- | gcc/tree-affine.h | 1 | ||||
-rw-r--r-- | gcc/tree-data-ref.c | 48 | ||||
-rw-r--r-- | gcc/tree-data-ref.h | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 29 |
8 files changed, 90 insertions, 48 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c07b82295f..5ab9d0c3af3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,24 @@ 2011-08-23 Richard Guenther <rguenther@suse.de> + * Makefile.in (tree-data-ref.o): Add tree-affine.h dependency. + * tree-affine.h (aff_comb_cannot_overlap_p): Declare. + * tree-affine.c (aff_comb_cannot_overlap_p): New function, moved + from ... + * tree-ssa-loop-im.c (cannot_overlap_p): ... here. + (mem_refs_may_alias_p): Adjust. + * tree-data-ref.h (dr_may_alias_p): Adjust. + * tree-data-ref.c: Include tree-affine.h. + (dr_analyze_indices): Do nothing for the non-loop case. + (dr_may_alias_p): Distinguish loop and non-loop case. Disambiguate + more cases in the non-loop case. + * graphite-sese-to-poly.c (write_alias_graph_to_ascii_dimacs): Adjust + calls to dr_may_alias_p. + (write_alias_graph_to_ascii_ecc): Likewise. + (write_alias_graph_to_ascii_dot): Likewise. + (build_alias_set_optimal_p): Likewise. + +2011-08-23 Richard Guenther <rguenther@suse.de> + PR tree-optimization/50162 * tree-vect-stmts.c (vectorizable_call): Fix argument lookup. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index e0b209845f0..15c73c63381 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2690,7 +2690,7 @@ tree-scalar-evolution.o : tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \ $(TREE_PASS_H) $(PARAMS_H) gt-tree-scalar-evolution.h tree-data-ref.o : tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ gimple-pretty-print.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) \ - $(TREE_PASS_H) langhooks.h + $(TREE_PASS_H) langhooks.h tree-affine.h sese.o : sese.c sese.h $(CONFIG_H) $(SYSTEM_H) coretypes.h tree-pretty-print.h \ $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) tree-pass.h value-prof.h graphite.o : graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) \ diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c index 206df46bd19..d9bcf278307 100644 --- a/gcc/graphite-sese-to-poly.c +++ b/gcc/graphite-sese-to-poly.c @@ -1720,7 +1720,7 @@ write_alias_graph_to_ascii_dimacs (FILE *file, char *comment, FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1) for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) - if (dr_may_alias_p (dr1, dr2)) + if (dr_may_alias_p (dr1, dr2, true)) edge_num++; fprintf (file, "$\n"); @@ -1732,7 +1732,7 @@ write_alias_graph_to_ascii_dimacs (FILE *file, char *comment, FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1) for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) - if (dr_may_alias_p (dr1, dr2)) + if (dr_may_alias_p (dr1, dr2, true)) fprintf (file, "e %d %d\n", i + 1, j + 1); return true; @@ -1762,7 +1762,7 @@ write_alias_graph_to_ascii_dot (FILE *file, char *comment, FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1) for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) - if (dr_may_alias_p (dr1, dr2)) + if (dr_may_alias_p (dr1, dr2, true)) fprintf (file, "n%d n%d\n", i, j); return true; @@ -1788,7 +1788,7 @@ write_alias_graph_to_ascii_ecc (FILE *file, char *comment, FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1) for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) - if (dr_may_alias_p (dr1, dr2)) + if (dr_may_alias_p (dr1, dr2, true)) fprintf (file, "%d %d\n", i, j); return true; @@ -1824,7 +1824,7 @@ build_alias_set_optimal_p (VEC (data_reference_p, heap) *drs) FOR_EACH_VEC_ELT (data_reference_p, drs, i, dr1) for (j = i+1; VEC_iterate (data_reference_p, drs, j, dr2); j++) - if (dr_may_alias_p (dr1, dr2)) + if (dr_may_alias_p (dr1, dr2, true)) { add_edge (g, i, j); add_edge (g, j, i); diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c index 06b7f2659da..69cce2e7e61 100644 --- a/gcc/tree-affine.c +++ b/gcc/tree-affine.c @@ -887,3 +887,30 @@ get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size) *size = shwi_to_double_int ((bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT); } +/* Returns true if a region of size SIZE1 at position 0 and a region of + size SIZE2 at position DIFF cannot overlap. */ + +bool +aff_comb_cannot_overlap_p (aff_tree *diff, double_int size1, double_int size2) +{ + double_int d, bound; + + /* Unless the difference is a constant, we fail. */ + if (diff->n != 0) + return false; + + d = diff->offset; + if (double_int_negative_p (d)) + { + /* The second object is before the first one, we succeed if the last + element of the second object is before the start of the first one. */ + bound = double_int_add (d, double_int_add (size2, double_int_minus_one)); + return double_int_negative_p (bound); + } + else + { + /* We succeed if the second object starts after the first one ends. */ + return double_int_scmp (size1, d) <= 0; + } +} + diff --git a/gcc/tree-affine.h b/gcc/tree-affine.h index 0abda96a9da..8cfbd691d9e 100644 --- a/gcc/tree-affine.h +++ b/gcc/tree-affine.h @@ -76,6 +76,7 @@ void tree_to_aff_combination_expand (tree, tree, aff_tree *, struct pointer_map_t **); void get_inner_reference_aff (tree, aff_tree *, double_int *); void free_affine_expand_cache (struct pointer_map_t **); +bool aff_comb_cannot_overlap_p (aff_tree *, double_int, double_int); /* Debugging functions. */ void print_aff (FILE *, aff_tree *); diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index e57489e11d6..2c488ab400d 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-scalar-evolution.h" #include "tree-pass.h" #include "langhooks.h" +#include "tree-affine.h" static struct datadep_stats { @@ -841,8 +842,14 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) tree base, off, access_fn = NULL_TREE; basic_block before_loop = NULL; - if (nest) - before_loop = block_before_loop (nest); + if (!nest) + { + DR_BASE_OBJECT (dr) = ref; + DR_ACCESS_FNS (dr) = NULL; + return; + } + + before_loop = block_before_loop (nest); /* Analyze access functions of dimensions we know to be independent. */ while (handled_component_p (aref)) @@ -852,12 +859,9 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) if (TREE_CODE (aref) == ARRAY_REF) { op = TREE_OPERAND (aref, 1); - if (nest) - { - access_fn = analyze_scalar_evolution (loop, op); - access_fn = instantiate_scev (before_loop, loop, access_fn); - VEC_safe_push (tree, heap, access_fns, access_fn); - } + access_fn = analyze_scalar_evolution (loop, op); + access_fn = instantiate_scev (before_loop, loop, access_fn); + VEC_safe_push (tree, heap, access_fns, access_fn); TREE_OPERAND (aref, 1) = build_int_cst (TREE_TYPE (op), 0); } /* REALPART_EXPR and IMAGPART_EXPR can be handled like accesses @@ -877,8 +881,7 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) aref = TREE_OPERAND (aref, 0); } - if (nest - && TREE_CODE (aref) == MEM_REF) + if (TREE_CODE (aref) == MEM_REF) { op = TREE_OPERAND (aref, 0); access_fn = analyze_scalar_evolution (loop, op); @@ -1286,14 +1289,33 @@ object_address_invariant_in_loop_p (const struct loop *loop, const_tree obj) } /* Returns false if we can prove that data references A and B do not alias, - true otherwise. */ + true otherwise. If LOOP_NEST is false no cross-iteration aliases are + considered. */ bool -dr_may_alias_p (const struct data_reference *a, const struct data_reference *b) +dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, + bool loop_nest) { tree addr_a = DR_BASE_OBJECT (a); tree addr_b = DR_BASE_OBJECT (b); + /* If we are not processing a loop nest but scalar code we + do not need to care about possible cross-iteration dependences + and thus can process the full original reference. Do so, + similar to how loop invariant motion applies extra offset-based + disambiguation. */ + if (!loop_nest) + { + aff_tree off1, off2; + double_int size1, size2; + get_inner_reference_aff (DR_REF (a), &off1, &size1); + get_inner_reference_aff (DR_REF (b), &off2, &size2); + aff_combination_scale (&off1, double_int_minus_one); + aff_combination_add (&off2, &off1); + if (aff_comb_cannot_overlap_p (&off2, size1, size2)) + return false; + } + if (DR_IS_WRITE (a) && DR_IS_WRITE (b)) return refs_output_dependent_p (addr_a, addr_b); else if (DR_IS_READ (a) && DR_IS_WRITE (b)) @@ -1331,7 +1353,7 @@ initialize_data_dependence_relation (struct data_reference *a, } /* If the data references do not alias, then they are independent. */ - if (!dr_may_alias_p (a, b)) + if (!dr_may_alias_p (a, b, loop_nest != NULL)) { DDR_ARE_DEPENDENT (res) = chrec_known; return res; diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index 0588136cb8d..86f056884ea 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -431,7 +431,7 @@ extern tree find_data_references_in_bb (struct loop *, basic_block, extern void create_rdg_vertices (struct graph *, VEC (gimple, heap) *); extern bool dr_may_alias_p (const struct data_reference *, - const struct data_reference *); + const struct data_reference *, bool); extern bool dr_equal_offsets_p (struct data_reference *, struct data_reference *); diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 3a5608e484e..7828c5b343b 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -1835,33 +1835,6 @@ analyze_memory_references (void) create_vop_ref_mapping (); } -/* Returns true if a region of size SIZE1 at position 0 and a region of - size SIZE2 at position DIFF cannot overlap. */ - -static bool -cannot_overlap_p (aff_tree *diff, double_int size1, double_int size2) -{ - double_int d, bound; - - /* Unless the difference is a constant, we fail. */ - if (diff->n != 0) - return false; - - d = diff->offset; - if (double_int_negative_p (d)) - { - /* The second object is before the first one, we succeed if the last - element of the second object is before the start of the first one. */ - bound = double_int_add (d, double_int_add (size2, double_int_minus_one)); - return double_int_negative_p (bound); - } - else - { - /* We succeed if the second object starts after the first one ends. */ - return double_int_scmp (size1, d) <= 0; - } -} - /* Returns true if MEM1 and MEM2 may alias. TTAE_CACHE is used as a cache in tree_to_aff_combination_expand. */ @@ -1890,7 +1863,7 @@ mem_refs_may_alias_p (tree mem1, tree mem2, struct pointer_map_t **ttae_cache) aff_combination_scale (&off1, double_int_minus_one); aff_combination_add (&off2, &off1); - if (cannot_overlap_p (&off2, size1, size2)) + if (aff_comb_cannot_overlap_p (&off2, size1, size2)) return false; return true; |