2012/1/25 Andrey Belevantsev <a...@ispras.ru>: > 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?
You limit the number of data references we find - but that isn't really the scalability issue (it's linear in the number of stmts). It's really compute_all_dependences that hits the quadraticness, thus _that_ function should fail instead (I realize it doesn't return any success/failure state yet, but the number of callers is limited). Btw, new params need documentation in doc/invoke.texi. The tree-predcom.c and tree-parloops.c changes are ok for trunk anyway. Thanks, Richard. > 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); > >