Hello,
In this PR data dependence analysis goes wild by trying to process >20k
datarefs, so the patch limits the number of datarefs per loop we handle to
1000 via a param. On the way find_data_references_in_loop is made static
and predcom/parloops are fixed for compute_data_dependences_for_loop
returning false.
Bootstrapped and tested on x86_64-linux, no testcase as it is really a
memory hog. Strictly speaking, this could be a regression only from the
time when -O3 didn't have predcom/vectorization turned on by default, so --
ok for trunk or 4.8? Branches?
Andrey
2012-01-25 Andrey Belevantsev <a...@ispras.ru>
PR middle-end/51389
* Makefile.in (tree-data-ref.o): Depend on $(PARAMS_H).
* tree-data-ref.c (find_data_references_in_loop): Make static.
Bail out for too many datarefs in a loop.
* tree-data-ref.h (find_data_references_in_loop): Remove declaration.
* tree-predcom.c (tree_predictive_commoning_loop): Bail out when
compute_data_dependences_for_loop returns false.
* tree-parloops.c (loop_parallel_p): Likewise.
* params.def (PARAM_DATADEPS_MAX_DATAREFS_IN_LOOP): New param.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f450d3e..43295aa 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2598,7 +2598,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-affine.h
+ $(TREE_PASS_H) langhooks.h tree-affine.h $(PARAMS_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/params.def b/gcc/params.def
index 239b684..e50fa26 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -820,6 +820,12 @@ DEFPARAM (PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION,
"maximum number of basic blocks per function to be analyzed by
Graphite",
100, 0, 0)
+/* Avoid data dependence analysis on very large loops. */
+DEFPARAM (PARAM_DATADEPS_MAX_DATAREFS_IN_LOOP,
+ "datadeps-max-datarefs-in-loop",
+ "Maximum number of datarefs in loop for loop data dependence
analysis",
+ 1000, 0, 0)
+
/* Avoid doing loop invariant motion on very large loops. */
DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index a0d86ec..5a7659a 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -85,6 +85,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "langhooks.h"
#include "tree-affine.h"
+#include "params.h"
static struct datadep_stats
{
@@ -4338,7 +4339,7 @@ find_data_references_in_bb (struct loop *loop,
basic_block bb,
TODO: This function should be made smarter so that it can handle address
arithmetic as if they were array accesses, etc. */
-tree
+static tree
find_data_references_in_loop (struct loop *loop,
VEC (data_reference_p, heap) **datarefs)
{
@@ -4351,7 +4352,9 @@ find_data_references_in_loop (struct loop *loop,
{
bb = bbs[i];
- if (find_data_references_in_bb (loop, bb, datarefs) == chrec_dont_know)
+ if (find_data_references_in_bb (loop, bb, datarefs) == chrec_dont_know
+ || ((int) VEC_length (data_reference_p, *datarefs)
+ > PARAM_VALUE (PARAM_DATADEPS_MAX_DATAREFS_IN_LOOP)))
{
free (bbs);
return chrec_dont_know;
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index 0f12962..66258ab 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -394,8 +394,6 @@ extern bool compute_data_dependences_for_loop (struct
loop *, bool,
extern bool compute_data_dependences_for_bb (basic_block, bool,
VEC (data_reference_p, heap) **,
VEC (ddr_p, heap) **);
-extern tree find_data_references_in_loop (struct loop *,
- VEC (data_reference_p, heap) **);
extern void print_direction_vector (FILE *, lambda_vector, int);
extern void print_dir_vectors (FILE *, VEC (lambda_vector, heap) *, int);
extern void print_dist_vectors (FILE *, VEC (lambda_vector, heap) *, int);
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 339ddcc..c5b7655 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -387,8 +387,14 @@ loop_parallel_p (struct loop *loop, struct obstack *
parloop_obstack)
datarefs = VEC_alloc (data_reference_p, heap, 10);
dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
loop_nest = VEC_alloc (loop_p, heap, 3);
- compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
- &dependence_relations);
+ if (! compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
+ &dependence_relations))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " FAILED: cannot analyze data dependencies\n");
+ ret = false;
+ goto end;
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
dump_data_dependence_relations (dump_file, dependence_relations);
@@ -405,6 +411,7 @@ loop_parallel_p (struct loop *loop, struct obstack *
parloop_obstack)
fprintf (dump_file,
" FAILED: data dependencies exist across iterations\n");
+ end:
VEC_free (loop_p, heap, loop_nest);
free_dependence_relations (dependence_relations);
free_data_refs (datarefs);
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 751bdeb..6419878 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -2476,8 +2476,17 @@ tree_predictive_commoning_loop (struct loop *loop)
datarefs = VEC_alloc (data_reference_p, heap, 10);
dependences = VEC_alloc (ddr_p, heap, 10);
loop_nest = VEC_alloc (loop_p, heap, 3);
- compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
- &dependences);
+ if (! compute_data_dependences_for_loop (loop, true, &loop_nest, &datarefs,
+ &dependences))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Cannot analyze data dependencies\n");
+ VEC_free (loop_p, heap, loop_nest);
+ free_data_refs (datarefs);
+ free_dependence_relations (dependences);
+ return false;
+ }
+
if (dump_file && (dump_flags & TDF_DETAILS))
dump_data_dependence_relations (dump_file, dependences);