Commit 02f5d6c5 by Richard Guenther Committed by Richard Biener

Makefile.in (tree-data-ref.o): Add tree-affine.h dependency.

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.

From-SVN: r177986
parent 0fcbc86b
2011-08-23 Richard Guenther <rguenther@suse.de> 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 PR tree-optimization/50162
* tree-vect-stmts.c (vectorizable_call): Fix argument lookup. * tree-vect-stmts.c (vectorizable_call): Fix argument lookup.
......
...@@ -2690,7 +2690,7 @@ tree-scalar-evolution.o : tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \ ...@@ -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_PASS_H) $(PARAMS_H) gt-tree-scalar-evolution.h
tree-data-ref.o : tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.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) \ 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 \ 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 $(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) \ graphite.o : graphite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DIAGNOSTIC_CORE_H) \
......
...@@ -1720,7 +1720,7 @@ write_alias_graph_to_ascii_dimacs (FILE *file, char *comment, ...@@ -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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) 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++; edge_num++;
fprintf (file, "$\n"); fprintf (file, "$\n");
...@@ -1732,7 +1732,7 @@ write_alias_graph_to_ascii_dimacs (FILE *file, char *comment, ...@@ -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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) 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); fprintf (file, "e %d %d\n", i + 1, j + 1);
return true; return true;
...@@ -1762,7 +1762,7 @@ write_alias_graph_to_ascii_dot (FILE *file, char *comment, ...@@ -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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) 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); fprintf (file, "n%d n%d\n", i, j);
return true; return true;
...@@ -1788,7 +1788,7 @@ write_alias_graph_to_ascii_ecc (FILE *file, char *comment, ...@@ -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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
for (j = i + 1; VEC_iterate (data_reference_p, drs, j, dr2); j++) 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); fprintf (file, "%d %d\n", i, j);
return true; return true;
...@@ -1824,7 +1824,7 @@ build_alias_set_optimal_p (VEC (data_reference_p, heap) *drs) ...@@ -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_EACH_VEC_ELT (data_reference_p, drs, i, dr1)
for (j = i+1; VEC_iterate (data_reference_p, drs, j, dr2); j++) 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, i, j);
add_edge (g, j, i); add_edge (g, j, i);
......
...@@ -887,3 +887,30 @@ get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size) ...@@ -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); *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;
}
}
...@@ -76,6 +76,7 @@ void tree_to_aff_combination_expand (tree, tree, aff_tree *, ...@@ -76,6 +76,7 @@ void tree_to_aff_combination_expand (tree, tree, aff_tree *,
struct pointer_map_t **); struct pointer_map_t **);
void get_inner_reference_aff (tree, aff_tree *, double_int *); void get_inner_reference_aff (tree, aff_tree *, double_int *);
void free_affine_expand_cache (struct pointer_map_t **); void free_affine_expand_cache (struct pointer_map_t **);
bool aff_comb_cannot_overlap_p (aff_tree *, double_int, double_int);
/* Debugging functions. */ /* Debugging functions. */
void print_aff (FILE *, aff_tree *); void print_aff (FILE *, aff_tree *);
......
...@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-scalar-evolution.h" #include "tree-scalar-evolution.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "langhooks.h" #include "langhooks.h"
#include "tree-affine.h"
static struct datadep_stats static struct datadep_stats
{ {
...@@ -841,8 +842,14 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) ...@@ -841,8 +842,14 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
tree base, off, access_fn = NULL_TREE; tree base, off, access_fn = NULL_TREE;
basic_block before_loop = NULL; basic_block before_loop = NULL;
if (nest) if (!nest)
before_loop = block_before_loop (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. */ /* Analyze access functions of dimensions we know to be independent. */
while (handled_component_p (aref)) while (handled_component_p (aref))
...@@ -852,12 +859,9 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) ...@@ -852,12 +859,9 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
if (TREE_CODE (aref) == ARRAY_REF) if (TREE_CODE (aref) == ARRAY_REF)
{ {
op = TREE_OPERAND (aref, 1); op = TREE_OPERAND (aref, 1);
if (nest) access_fn = analyze_scalar_evolution (loop, op);
{ access_fn = instantiate_scev (before_loop, loop, access_fn);
access_fn = analyze_scalar_evolution (loop, op); VEC_safe_push (tree, heap, access_fns, access_fn);
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); TREE_OPERAND (aref, 1) = build_int_cst (TREE_TYPE (op), 0);
} }
/* REALPART_EXPR and IMAGPART_EXPR can be handled like accesses /* 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) ...@@ -877,8 +881,7 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop)
aref = TREE_OPERAND (aref, 0); aref = TREE_OPERAND (aref, 0);
} }
if (nest if (TREE_CODE (aref) == MEM_REF)
&& TREE_CODE (aref) == MEM_REF)
{ {
op = TREE_OPERAND (aref, 0); op = TREE_OPERAND (aref, 0);
access_fn = analyze_scalar_evolution (loop, op); access_fn = analyze_scalar_evolution (loop, op);
...@@ -1286,14 +1289,33 @@ object_address_invariant_in_loop_p (const struct loop *loop, const_tree obj) ...@@ -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, /* 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 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_a = DR_BASE_OBJECT (a);
tree addr_b = DR_BASE_OBJECT (b); 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)) if (DR_IS_WRITE (a) && DR_IS_WRITE (b))
return refs_output_dependent_p (addr_a, addr_b); return refs_output_dependent_p (addr_a, addr_b);
else if (DR_IS_READ (a) && DR_IS_WRITE (b)) else if (DR_IS_READ (a) && DR_IS_WRITE (b))
...@@ -1331,7 +1353,7 @@ initialize_data_dependence_relation (struct data_reference *a, ...@@ -1331,7 +1353,7 @@ initialize_data_dependence_relation (struct data_reference *a,
} }
/* If the data references do not alias, then they are independent. */ /* 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; DDR_ARE_DEPENDENT (res) = chrec_known;
return res; return res;
......
...@@ -431,7 +431,7 @@ extern tree find_data_references_in_bb (struct loop *, basic_block, ...@@ -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 void create_rdg_vertices (struct graph *, VEC (gimple, heap) *);
extern bool dr_may_alias_p (const struct data_reference *, 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 *, extern bool dr_equal_offsets_p (struct data_reference *,
struct data_reference *); struct data_reference *);
......
...@@ -1835,33 +1835,6 @@ analyze_memory_references (void) ...@@ -1835,33 +1835,6 @@ analyze_memory_references (void)
create_vop_ref_mapping (); 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 /* Returns true if MEM1 and MEM2 may alias. TTAE_CACHE is used as a cache in
tree_to_aff_combination_expand. */ tree_to_aff_combination_expand. */
...@@ -1890,7 +1863,7 @@ mem_refs_may_alias_p (tree mem1, tree mem2, struct pointer_map_t **ttae_cache) ...@@ -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_scale (&off1, double_int_minus_one);
aff_combination_add (&off2, &off1); aff_combination_add (&off2, &off1);
if (cannot_overlap_p (&off2, size1, size2)) if (aff_comb_cannot_overlap_p (&off2, size1, size2))
return false; return false;
return true; return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment