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);


Reply via email to