@@ -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) \
@@ -9115,6 +9115,13 @@ with more basic blocks than this parameter won't have loop invariant
motion optimization performed on them. The default value of the
parameter is 1000 for -O1 and 10000 for -O2 and above.
+@item loop-max-datarefs-for-datadeps
+Building data dapendencies is expensive for very large loops. This
+parameter limits the number of data references in loops that are
+considered for data dependence analysis. These large loops will not
+be handled then by the optimizations using loop data dependencies.
+The default value is 1000.
+
@item max-vartrack-size
Sets a maximum number of hash table slots to use during variable
tracking dataflow analysis of any function. If this limit is exceeded
@@ -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_LOOP_MAX_DATAREFS_FOR_DATADEPS,
+ "loop-max-datarefs-for-datadeps",
+ "Maximum number of datarefs in loop for building loop data dependencies",
+ 1000, 0, 0)
+
/* Avoid doing loop invariant motion on very large loops. */
DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
@@ -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
{
@@ -4134,9 +4135,10 @@ compute_affine_dependence (struct data_dependence_relation *ddr,
/* Compute in DEPENDENCE_RELATIONS the data dependence graph for all
the data references in DATAREFS, in the LOOP_NEST. When
COMPUTE_SELF_AND_RR is FALSE, don't compute read-read and self
- relations. */
+ relations. Return true when successful, i.e. data references number
+ is small enough to be handled. */
-void
+bool
compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
VEC (ddr_p, heap) **dependence_relations,
VEC (loop_p, heap) *loop_nest,
@@ -4146,6 +4148,18 @@ compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
struct data_reference *a, *b;
unsigned int i, j;
+ if ((int) VEC_length (data_reference_p, datarefs)
+ > PARAM_VALUE (PARAM_LOOP_MAX_DATAREFS_FOR_DATADEPS))
+ {
+ struct data_dependence_relation *ddr;
+
+ /* Insert a single relation into dependence_relations:
+ chrec_dont_know. */
+ ddr = initialize_data_dependence_relation (NULL, NULL, loop_nest);
+ VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
+ return false;
+ }
+
FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, a)
for (j = i + 1; VEC_iterate (data_reference_p, datarefs, j, b); j++)
if (DR_IS_WRITE (a) || DR_IS_WRITE (b) || compute_self_and_rr)
@@ -4164,6 +4178,8 @@ compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
if (loop_nest)
compute_affine_dependence (ddr, VEC_index (loop_p, loop_nest, 0));
}
+
+ return true;
}
/* Stores the locations of memory references in STMT to REFERENCES. Returns
@@ -4338,7 +4354,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)
{
@@ -4427,19 +4443,10 @@ compute_data_dependences_for_loop (struct loop *loop,
dependences. */
if (!loop
|| !find_loop_nest (loop, loop_nest)
- || find_data_references_in_loop (loop, datarefs) == chrec_dont_know)
- {
- struct data_dependence_relation *ddr;
-
- /* Insert a single relation into dependence_relations:
- chrec_dont_know. */
- ddr = initialize_data_dependence_relation (NULL, NULL, *loop_nest);
- VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
- res = false;
- }
- else
- compute_all_dependences (*datarefs, dependence_relations, *loop_nest,
- compute_self_and_read_read_dependences);
+ || find_data_references_in_loop (loop, datarefs) == chrec_dont_know
+ || !compute_all_dependences (*datarefs, dependence_relations, *loop_nest,
+ compute_self_and_read_read_dependences))
+ res = false;
if (dump_file && (dump_flags & TDF_STATS))
{
@@ -4507,9 +4514,8 @@ compute_data_dependences_for_bb (basic_block bb,
if (find_data_references_in_bb (NULL, bb, datarefs) == chrec_dont_know)
return false;
- compute_all_dependences (*datarefs, dependence_relations, NULL,
- compute_self_and_read_read_dependences);
- return true;
+ return compute_all_dependences (*datarefs, dependence_relations, NULL,
+ compute_self_and_read_read_dependences);
}
/* Entry point (for testing only). Analyze all the data references
@@ -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);
@@ -426,7 +424,7 @@ extern bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
extern struct data_dependence_relation *initialize_data_dependence_relation
(struct data_reference *, struct data_reference *, VEC (loop_p, heap) *);
extern void compute_self_dependence (struct data_dependence_relation *);
-extern void compute_all_dependences (VEC (data_reference_p, heap) *,
+extern bool compute_all_dependences (VEC (data_reference_p, heap) *,
VEC (ddr_p, heap) **, VEC (loop_p, heap) *,
bool);
extern tree find_data_references_in_bb (struct loop *, basic_block,