tree-loop-linear.c (gather_interchange_stats): Look in the access matrix...
authorJan Sjodin <jan.sjodin@amd.com>
Tue, 20 May 2008 19:11:56 +0000 (19:11 +0000)
committerSebastian Pop <spop@gcc.gnu.org>
Tue, 20 May 2008 19:11:56 +0000 (19:11 +0000)
2008-05-20  Jan Sjodin  <jan.sjodin@amd.com>
    Sebastian Pop  <sebastian.pop@amd.com>

* tree-loop-linear.c (gather_interchange_stats): Look in the access matrix,
and never look at the tree representation of the memory accesses.
(linear_transform_loops): Computes parameters and access matrices.
* tree-data-ref.c (compute_data_dependences_for_loop): Returns false when fails.
(access_matrix_get_index_for_parameter): New.
* tree-data-ref.h (struct access_matrix): New.
(AM_LOOP_NEST_NUM, AM_NB_INDUCTION_VARS, AM_PARAMETERS, AM_MATRIX,
AM_NB_PARAMETERS, AM_CONST_COLUMN_INDEX, AM_NB_COLUMNS,
AM_GET_SUBSCRIPT_ACCESS_VECTOR, AM_GET_ACCESS_MATRIX_ELEMENT,
am_vector_index_for_loop): New.
(struct data_reference): Add field access_matrix.
(DR_ACCESS_MATRIX): New.
(compute_data_dependences_for_loop): Update declaration.
(lambda_collect_parameters, lambda_compute_access_matrices): Declared.
* lambda.h (lambda_vector_vec_p): Declared.
* lambda-code.c: Depend on pointer-set.h.
(lambda_collect_parameters_from_af, lambda_collect_parameters,
av_for_af_base, av_for_af, build_access_matrix,
lambda_compute_access_matrices): New.
* Makefile.in (lambda-code.o): Depend on pointer-set.h.

Co-Authored-By: Sebastian Pop <sebastian.pop@amd.com>
From-SVN: r135672

gcc/ChangeLog
gcc/Makefile.in
gcc/lambda-code.c
gcc/lambda.h
gcc/tree-chrec.h
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-loop-linear.c

index 9a3e9bb5dddad24a3f88b06a38f1873306ea0b4f..ba15ab570147298a97e70e5d1b5f5bb3d8b5de6f 100644 (file)
@@ -1,3 +1,27 @@
+2008-05-20  Jan Sjodin  <jan.sjodin@amd.com>
+           Sebastian Pop  <sebastian.pop@amd.com>
+
+       * tree-loop-linear.c (gather_interchange_stats): Look in the access matrix,
+       and never look at the tree representation of the memory accesses.
+       (linear_transform_loops): Computes parameters and access matrices.
+       * tree-data-ref.c (compute_data_dependences_for_loop): Returns false when fails.
+       (access_matrix_get_index_for_parameter): New.
+       * tree-data-ref.h (struct access_matrix): New.
+       (AM_LOOP_NEST_NUM, AM_NB_INDUCTION_VARS, AM_PARAMETERS, AM_MATRIX,
+       AM_NB_PARAMETERS, AM_CONST_COLUMN_INDEX, AM_NB_COLUMNS,
+       AM_GET_SUBSCRIPT_ACCESS_VECTOR, AM_GET_ACCESS_MATRIX_ELEMENT,
+       am_vector_index_for_loop): New.
+       (struct data_reference): Add field access_matrix.
+       (DR_ACCESS_MATRIX): New.
+       (compute_data_dependences_for_loop): Update declaration.
+       (lambda_collect_parameters, lambda_compute_access_matrices): Declared.
+       * lambda.h (lambda_vector_vec_p): Declared.
+       * lambda-code.c: Depend on pointer-set.h.
+       (lambda_collect_parameters_from_af, lambda_collect_parameters,
+       av_for_af_base, av_for_af, build_access_matrix,
+       lambda_compute_access_matrices): New.
+       * Makefile.in (lambda-code.o): Depend on pointer-set.h.
+
 2008-05-20  Joseph Myers  <joseph@codesourcery.com>
 
        * doc/install.texi2html: Generate gcc-vers.texi in $DESTDIR not
index 56d2aed78406da7379e1b76d4d593757cf9872b2..0d88228f99c995e8fd0c381672f47daf740a97e1 100644 (file)
@@ -2885,7 +2885,7 @@ lambda-code.o: lambda-code.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
    $(TM_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
    $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
    $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) coretypes.h $(TARGET_H) \
-   tree-chrec.h tree-pass.h vec.h vecprim.h $(OBSTACK_H)
+   tree-chrec.h tree-pass.h vec.h vecprim.h $(OBSTACK_H) pointer-set.h
 params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(PARAMS_H) toplev.h
 pointer-set.o: pointer-set.c pointer-set.h $(CONFIG_H) $(SYSTEM_H)
 hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H)
index dc656d3ef4e08b75c264e0f7b1b9e6886d7f2711..707591154e168a18447e2cec46ba29ea2aee8280 100644 (file)
@@ -42,6 +42,7 @@
 #include "vec.h"
 #include "lambda.h"
 #include "vecprim.h"
+#include "pointer-set.h"
 
 /* This loop nest code generation is based on non-singular matrix
    math.
@@ -2641,3 +2642,198 @@ lambda_transform_legal_p (lambda_trans_matrix trans,
     }
   return true;
 }
+
+
+/* Collects parameters from affine function ACCESS_FUNCTION, and push
+   them in PARAMETERS.  */
+
+static void
+lambda_collect_parameters_from_af (tree access_function,
+                                  struct pointer_set_t *param_set,
+                                  VEC (tree, heap) **parameters)
+{
+  if (access_function == NULL)
+    return;
+
+  if (TREE_CODE (access_function) == SSA_NAME
+      && pointer_set_contains (param_set, access_function) == 0)
+    {
+      pointer_set_insert (param_set, access_function);
+      VEC_safe_push (tree, heap, *parameters, access_function);
+    }
+  else
+    {
+      int i, num_operands = tree_operand_length (access_function);
+
+      for (i = 0; i < num_operands; i++)
+       lambda_collect_parameters_from_af (TREE_OPERAND (access_function, i),
+                                          param_set, parameters);
+    }
+}
+
+/* Collects parameters from DATAREFS, and push them in PARAMETERS.  */
+
+void
+lambda_collect_parameters (VEC (data_reference_p, heap) *datarefs,
+                          VEC (tree, heap) **parameters)
+{
+  unsigned i, j;
+  struct pointer_set_t *parameter_set = pointer_set_create ();
+  data_reference_p data_reference;
+
+  for (i = 0; VEC_iterate (data_reference_p, datarefs, i, data_reference); i++)
+    for (j = 0; j < DR_NUM_DIMENSIONS (data_reference); j++)
+      lambda_collect_parameters_from_af (DR_ACCESS_FN (data_reference, j),
+                                        parameter_set, parameters);
+}
+
+/* Translates BASE_EXPR to vector CY.  AM is needed for inferring
+   indexing positions in the data access vector.  CST is the analyzed
+   integer constant.  */
+
+static bool
+av_for_af_base (tree base_expr, lambda_vector cy, struct access_matrix *am,
+               int cst)
+{
+  bool result = true;
+
+  switch (TREE_CODE (base_expr))
+    {
+    case INTEGER_CST:
+      /* Constant part.  */
+      cy[AM_CONST_COLUMN_INDEX (am)] += int_cst_value (base_expr) * cst;
+      return true;
+
+    case SSA_NAME:
+      {
+       int param_index =
+         access_matrix_get_index_for_parameter (base_expr, am);
+
+       if (param_index >= 0)
+         {
+           cy[param_index] = cst + cy[param_index];
+           return true;
+         }
+
+       return false;
+      }
+
+    case PLUS_EXPR:
+      return av_for_af_base (TREE_OPERAND (base_expr, 0), cy, am, cst)
+       && av_for_af_base (TREE_OPERAND (base_expr, 1), cy, am, cst);
+
+    case MINUS_EXPR:
+      return av_for_af_base (TREE_OPERAND (base_expr, 0), cy, am, cst)
+       && av_for_af_base (TREE_OPERAND (base_expr, 1), cy, am, -1 * cst);
+
+    case MULT_EXPR:
+      if (TREE_CODE (TREE_OPERAND (base_expr, 0)) == INTEGER_CST)
+       result = av_for_af_base (TREE_OPERAND (base_expr, 1), 
+                                cy, am, cst *
+                                int_cst_value (TREE_OPERAND (base_expr, 0)));
+      else if (TREE_CODE (TREE_OPERAND (base_expr, 1)) == INTEGER_CST)
+       result = av_for_af_base (TREE_OPERAND (base_expr, 0),
+                                cy, am, cst *
+                                int_cst_value (TREE_OPERAND (base_expr, 1)));
+      else
+       result = false;
+
+      return result;
+
+    case NEGATE_EXPR:
+      return av_for_af_base (TREE_OPERAND (base_expr, 0), cy, am, -1 * cst);
+
+    default:
+      return false;
+    }
+
+  return result;
+}
+
+/* Translates ACCESS_FUN to vector CY.  AM is needed for inferring
+   indexing positions in the data access vector.  */
+
+static bool
+av_for_af (tree access_fun, lambda_vector cy, struct access_matrix *am)
+{
+  switch (TREE_CODE (access_fun))
+    {
+    case POLYNOMIAL_CHREC:
+      {
+       tree left = CHREC_LEFT (access_fun);
+       tree right = CHREC_RIGHT (access_fun);
+       unsigned var;
+
+       if (TREE_CODE (right) != INTEGER_CST)
+         return false;
+
+       var = am_vector_index_for_loop (am, CHREC_VARIABLE (access_fun));
+       cy[var] = int_cst_value (right);
+
+       if (TREE_CODE (left) == POLYNOMIAL_CHREC)
+         return av_for_af (left, cy, am);
+       else
+         return av_for_af_base (left, cy, am, 1);
+      }
+
+    case INTEGER_CST:
+      /* Constant part.  */
+      return av_for_af_base (access_fun, cy, am, 1);
+
+    default:
+      return false;
+    }
+}
+
+/* Initializes the access matrix for DATA_REFERENCE.  */
+
+static bool
+build_access_matrix (data_reference_p data_reference,
+                    VEC (tree, heap) *parameters, int loop_nest_num)
+{
+  struct access_matrix *am = GGC_NEW (struct access_matrix);
+  unsigned i, ndim = DR_NUM_DIMENSIONS (data_reference);
+  struct loop *loop = bb_for_stmt (DR_STMT (data_reference))->loop_father;
+  unsigned nb_induction_vars = loop_depth (loop) - loop_nest_num + 1;
+  unsigned lambda_nb_columns;
+  lambda_vector_vec_p matrix;
+
+  AM_LOOP_NEST_NUM (am) = loop_nest_num;
+  AM_NB_INDUCTION_VARS (am) = nb_induction_vars;
+  AM_PARAMETERS (am) = parameters;
+
+  lambda_nb_columns = AM_NB_COLUMNS (am);
+  matrix = VEC_alloc (lambda_vector, heap, lambda_nb_columns);
+  AM_MATRIX (am) = matrix;
+
+  for (i = 0; i < ndim; i++)
+    {
+      lambda_vector access_vector = lambda_vector_new (lambda_nb_columns);
+      tree access_function = DR_ACCESS_FN (data_reference, i);
+
+      if (!av_for_af (access_function, access_vector, am))
+       return false;
+
+      VEC_safe_push (lambda_vector, heap, matrix, access_vector);
+    }
+
+  DR_ACCESS_MATRIX (data_reference) = am;
+  return true;
+}
+
+/* Returns false when one of the access matrices cannot be built.  */
+
+bool
+lambda_compute_access_matrices (VEC (data_reference_p, heap) *datarefs,
+                               VEC (tree, heap) *parameters,
+                               int loop_nest_num)
+{
+  data_reference_p dataref;
+  unsigned ix;
+
+  for (ix = 0; VEC_iterate (data_reference_p, datarefs, ix, dataref); ix++)
+    if (!build_access_matrix (dataref, parameters, loop_nest_num))
+      return false;
+
+  return true;
+}
index 641b3bcaa051c2d1a2b47a414436582b5067c1cb..40e8502973cbd018777525ee93aa6dfe56ec64e5 100644 (file)
@@ -28,10 +28,13 @@ along with GCC; see the file COPYING3.  If not see
    and scalar multiplication.  In this vector space, an element is a list of
    integers.  */
 typedef int *lambda_vector;
-
 DEF_VEC_P(lambda_vector);
 DEF_VEC_ALLOC_P(lambda_vector,heap);
 
+typedef VEC(lambda_vector, heap) *lambda_vector_vec_p;
+DEF_VEC_P (lambda_vector_vec_p);
+DEF_VEC_ALLOC_P (lambda_vector_vec_p, heap);
+
 /* An integer matrix.  A matrix consists of m vectors of length n (IE
    all vectors are the same length).  */
 typedef lambda_vector *lambda_matrix;
@@ -487,4 +490,3 @@ dependence_level (lambda_vector dist_vect, int length)
 }
 
 #endif /* LAMBDA_H  */
-
index a92469298161c074d5dcb7ef79583a13f5180d59..7f240c6c739e62b6feebdcb9b8603dd0def1ab70 100644 (file)
@@ -201,8 +201,10 @@ evolution_function_is_affine_p (const_tree chrec)
   switch (TREE_CODE (chrec))
     {
     case POLYNOMIAL_CHREC:
-      if (evolution_function_is_invariant_p (CHREC_LEFT (chrec), CHREC_VARIABLE (chrec))
-         && evolution_function_is_invariant_p (CHREC_RIGHT (chrec), CHREC_VARIABLE (chrec)))
+      if (evolution_function_is_invariant_p (CHREC_LEFT (chrec),
+                                            CHREC_VARIABLE (chrec))
+         && evolution_function_is_invariant_p (CHREC_RIGHT (chrec),
+                                               CHREC_VARIABLE (chrec)))
        return true;
       else
        return false;
index 75545496a1773ec3151ac6b18efe9a4cf9d9b833..bf9516cd6724a0a2000a63ea566c04019ba4aaca 100644 (file)
@@ -4180,18 +4180,20 @@ find_loop_nest (struct loop *loop, VEC (loop_p, heap) **loop_nest)
   return true;
 }
 
-/* Given a loop nest LOOP, the following vectors are returned:
+/* Returns true when the data dependences have been computed, false otherwise.
+   Given a loop nest LOOP, the following vectors are returned:
    DATAREFS is initialized to all the array elements contained in this loop, 
    DEPENDENCE_RELATIONS contains the relations between the data references.  
    Compute read-read and self relations if 
    COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE.  */
 
-void
+bool
 compute_data_dependences_for_loop (struct loop *loop, 
                                   bool compute_self_and_read_read_dependences,
                                   VEC (data_reference_p, heap) **datarefs,
                                   VEC (ddr_p, heap) **dependence_relations)
 {
+  bool res = true;
   VEC (loop_p, heap) *vloops = VEC_alloc (loop_p, heap, 3);
 
   memset (&dependence_stats, 0, sizeof (dependence_stats));
@@ -4209,6 +4211,7 @@ compute_data_dependences_for_loop (struct loop *loop,
         chrec_dont_know.  */
       ddr = initialize_data_dependence_relation (NULL, NULL, vloops);
       VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
+      res = false;
     }
   else
     compute_all_dependences (*datarefs, dependence_relations, vloops,
@@ -4260,7 +4263,9 @@ compute_data_dependences_for_loop (struct loop *loop,
               dependence_stats.num_miv_independent);
       fprintf (dump_file, "Number of miv tests unimplemented: %d\n",
               dependence_stats.num_miv_unimplemented);
-    }    
+    }
+
+  return res;
 }
 
 /* Entry point (for testing only).  Analyze all the data references
@@ -5032,3 +5037,20 @@ remove_similar_memory_refs (VEC (tree, heap) **stmts)
   htab_delete (seen);
 }
 
+/* Returns the index of PARAMETER in the parameters vector of the
+   ACCESS_MATRIX.  If PARAMETER does not exist return -1.  */
+
+int 
+access_matrix_get_index_for_parameter (tree parameter, 
+                                      struct access_matrix *access_matrix)
+{
+  int i;
+  VEC (tree,heap) *lambda_parameters = AM_PARAMETERS (access_matrix);
+  tree lambda_parameter;
+
+  for (i = 0; VEC_iterate (tree, lambda_parameters, i, lambda_parameter); i++)
+    if (lambda_parameter == parameter)
+      return i + AM_NB_INDUCTION_VARS (access_matrix);
+
+  return -1;
+}
index 5e668cbaf4322fe5129ba8599a1db68b1c5be7ad..c1672eb3d53f53d655a1d9f24d629a5f76092546 100644 (file)
@@ -96,6 +96,63 @@ struct dr_alias
   bitmap vops;
 };
 
+/* Each vector of the access matrix represents a linear access
+   function for a subscript.  First elements correspond to the
+   leftmost indices, ie. for a[i][j] the first vector corresponds to
+   the subscript in "i".  The elements of a vector are relative to
+   the loop nests in which the data reference is considered,
+   i.e. the vector is relative to the SCoP that provides the context
+   in which this data reference occurs.
+
+   For example, in
+
+   | loop_1
+   |    loop_2
+   |      a[i+3][2*j+n-1]
+
+   if "i" varies in loop_1 and "j" varies in loop_2, the access 
+   matrix with respect to the loop nest {loop_1, loop_2} is:
+
+   | loop_1  loop_2  param_n  cst
+   |   1       0        0      3
+   |   0       2        1     -1
+
+   whereas the access matrix with respect to loop_2 considers "i" as
+   a parameter:
+
+   | loop_2  param_i  param_n  cst
+   |   0       1         0      3
+   |   2       0         1     -1
+*/
+struct access_matrix
+{
+  int loop_nest_num;
+  int nb_induction_vars;
+  VEC (tree, heap) *parameters;
+  VEC (lambda_vector, heap) *matrix;
+};
+
+#define AM_LOOP_NEST_NUM(M) (M)->loop_nest_num
+#define AM_NB_INDUCTION_VARS(M) (M)->nb_induction_vars
+#define AM_PARAMETERS(M) (M)->parameters
+#define AM_MATRIX(M) (M)->matrix
+#define AM_NB_PARAMETERS(M) (VEC_length (tree, AM_PARAMETERS(M)))
+#define AM_CONST_COLUMN_INDEX(M) (AM_NB_INDUCTION_VARS (M) + AM_NB_PARAMETERS (M))
+#define AM_NB_COLUMNS(M) (AM_NB_INDUCTION_VARS (M) + AM_NB_PARAMETERS (M) + 1)
+#define AM_GET_SUBSCRIPT_ACCESS_VECTOR(M, I) VEC_index (lambda_vector, AM_MATRIX (M), I)
+#define AM_GET_ACCESS_MATRIX_ELEMENT(M, I, J) AM_GET_SUBSCRIPT_ACCESS_VECTOR (M, I)[J]
+
+/* Return the column in the access matrix of LOOP_NUM.  */
+
+static inline int
+am_vector_index_for_loop (struct access_matrix *access_matrix, int loop_num)
+{
+  gcc_assert (loop_num >= AM_LOOP_NEST_NUM (access_matrix));
+  return loop_num - AM_LOOP_NEST_NUM (access_matrix);
+}
+
+int access_matrix_get_index_for_parameter (tree, struct access_matrix *);
+
 struct data_reference
 {
   /* A pointer to the statement that contains this DR.  */
@@ -118,11 +175,10 @@ struct data_reference
 
   /* Alias information for the data reference.  */
   struct dr_alias alias;
-};
 
-typedef struct data_reference *data_reference_p;
-DEF_VEC_P(data_reference_p);
-DEF_VEC_ALLOC_P (data_reference_p, heap);
+  /* Matrix representation for the data access functions.  */
+  struct access_matrix *access_matrix;
+};
 
 #define DR_STMT(DR)                (DR)->stmt
 #define DR_REF(DR)                 (DR)->ref
@@ -139,6 +195,11 @@ DEF_VEC_ALLOC_P (data_reference_p, heap);
 #define DR_PTR_INFO(DR)            (DR)->alias.ptr_info
 #define DR_VOPS(DR)               (DR)->alias.vops
 #define DR_ALIGNED_TO(DR)          (DR)->innermost.aligned_to
+#define DR_ACCESS_MATRIX(DR)       (DR)->access_matrix
+
+typedef struct data_reference *data_reference_p;
+DEF_VEC_P(data_reference_p);
+DEF_VEC_ALLOC_P (data_reference_p, heap);
 
 enum data_dependence_direction {
   dir_positive, 
@@ -309,7 +370,7 @@ DEF_VEC_ALLOC_O (data_ref_loc, heap);
 
 bool get_references_in_stmt (tree, VEC (data_ref_loc, heap) **);
 void dr_analyze_innermost (struct data_reference *);
-extern void compute_data_dependences_for_loop (struct loop *, bool,
+extern bool compute_data_dependences_for_loop (struct loop *, bool,
                                               VEC (data_reference_p, heap) **,
                                               VEC (ddr_p, heap) **);
 extern void print_direction_vector (FILE *, lambda_vector, int);
@@ -493,7 +554,12 @@ rdg_has_similar_memory_accesses (struct graph *rdg, int v1, int v2)
 }
 
 /* In lambda-code.c  */
-bool lambda_transform_legal_p (lambda_trans_matrix, int, VEC (ddr_p, heap) *);
+bool lambda_transform_legal_p (lambda_trans_matrix, int,
+                              VEC (ddr_p, heap) *);
+void lambda_collect_parameters (VEC (data_reference_p, heap) *,
+                               VEC (tree, heap) **);
+bool lambda_compute_access_matrices (VEC (data_reference_p, heap) *,
+                                    VEC (tree, heap) *, int);
 
 /* In tree-data-refs.c  */
 void split_constant_offset (tree , tree *, tree *);
index 806d9e6d1cb7b3886bd042c70c9d9db04586d9cd..f58bd11b7fb1e96c9aaf9895adcbcab920a6046c 100644 (file)
@@ -146,19 +146,17 @@ gather_interchange_stats (VEC (ddr_p, heap) *dependence_relations,
       for (it = 0; it < DR_NUM_DIMENSIONS (dr); 
           it++, ref = TREE_OPERAND (ref, 0))
        {
-         tree chrec = DR_ACCESS_FN (dr, it);
-         tree tstride = evolution_part_in_loop_num (chrec, loop->num);
+         int num = am_vector_index_for_loop (DR_ACCESS_MATRIX (dr), loop->num);
+         int istride = AM_GET_ACCESS_MATRIX_ELEMENT (DR_ACCESS_MATRIX (dr), it, num);
          tree array_size = TYPE_SIZE (TREE_TYPE (ref));
          double_int dstride;
 
-         if (tstride == NULL_TREE
-             || array_size == NULL_TREE 
-             || TREE_CODE (tstride) != INTEGER_CST
+         if (array_size == NULL_TREE 
              || TREE_CODE (array_size) != INTEGER_CST)
            continue;
 
          dstride = double_int_mul (tree_to_double_int (array_size), 
-                                   tree_to_double_int (tstride));
+                                   shwi_to_double_int (istride));
          (*access_strides) = double_int_add (*access_strides, dstride);
        }
     }
@@ -320,6 +318,7 @@ linear_transform_loops (void)
   loop_iterator li;
   VEC(tree,heap) *oldivs = NULL;
   VEC(tree,heap) *invariants = NULL;
+  VEC(tree,heap) *lambda_parameters = NULL;
   VEC(tree,heap) *remove_ivs = VEC_alloc (tree, heap, 3);
   struct loop *loop_nest;
   tree oldiv_stmt;
@@ -330,6 +329,7 @@ linear_transform_loops (void)
       unsigned int depth = 0;
       VEC (ddr_p, heap) *dependence_relations;
       VEC (data_reference_p, heap) *datarefs;
+      
       lambda_loopnest before, after;
       lambda_trans_matrix trans;
       struct obstack lambda_obstack;
@@ -341,11 +341,18 @@ linear_transform_loops (void)
 
       VEC_truncate (tree, oldivs, 0);
       VEC_truncate (tree, invariants, 0);
+      VEC_truncate (tree, lambda_parameters, 0);
 
       datarefs = VEC_alloc (data_reference_p, heap, 10);
       dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
-      compute_data_dependences_for_loop (loop_nest, true, &datarefs,
-                                        &dependence_relations);
+      if (!compute_data_dependences_for_loop (loop_nest, true, &datarefs,
+                                             &dependence_relations))
+       continue;
+      
+      lambda_collect_parameters (datarefs, &lambda_parameters);
+      if (!lambda_compute_access_matrices (datarefs, lambda_parameters,
+                                          loop_nest->num))
+       continue;
 
       if (dump_file && (dump_flags & TDF_DETAILS))
        dump_ddrs (dump_file, dependence_relations);