[killloop] Loop reversal

Sebastian Pop sebastian.pop@cri.ensmp.fr
Mon Oct 24 09:31:00 GMT 2005


Sebastian Pop wrote:
> Zdenek Dvorak wrote:
> > The pass is currently disabled by default, since it exposes a bug in
> > data dependence analysis, thus causing misscompilations (in the test
> > loop-12:foo9, the loop gets reversed, even though this is not
> > correct).
> 
> Sorry, I didn't get to fix it yet.  I will propose a patch later.
> 

Here is a fix for this one.  The patch also fixes the computation of
distance vectors as described in http://gcc.gnu.org/PR23411

For example, in the following case,

loop_1
  loop_2
    A[5] = ...
  end_loop_2
end_loop_1

the answer is the set of distance vectors: (0, 1) and (1, 0).

I would like to see this patch also included in mainline after some
more testing on SPEC, etc.  I will post a patch for mainline later.
For now, I'm bootntesting this patch on killloop branch, amd64-linux.

Sebastian

	* lambda-code.c (lambda_transform_legal_p): Use DDR_NUM_DIST_VECTS
	for testing whether the data_dependence_relation contains distance
	vectors.  Iterate over all distance vectors of the ddr.
	* lambda.h: Define a vec of lambda_vector pointers.
	* tree-data-ref.c (dump_data_dependence_relation,
	dump_data_dependence_direction): Iterate over all distance and
	direction vectors of the ddr.
	(initialize_data_dependence_relation): Initialize DDR_DIR_VECTS and
	DDR_DIST_VECTS.
	(build_classic_dist_vector, build_classic_dir_vector): Push a set
	of distance/direction vectors instead of a single one.
	* tree-data-ref.h (dir_vects, dist_vects): Replace dir/dist 
	lambda_vectors with a vec of lambda_vectors.
	(DDR_DIR_VECT, DDR_DIST_VECT): Redefined as operations on vec.
	(DDR_DIR_VECTS, DDR_DIST_VECTS, DDR_NUM_DIR_VECTS,
	DDR_NUM_DIST_VECTS): New.
	* tree-loop-linear.c (gather_interchange_stats): Test for the
	existence of distance vectors only after having checked that there
	is a dependence.  Iterate over all distance vectors of the ddr.
	(linear_transform_loops): Use dump_data_dependence_relation.
	* tree-vect-analyze.c (vect_analyze_data_ref_dependence): Test for
	distance vectors using DDR_NUM_DIST_VECTS.  Iterate over all the
	distance vectors of the ddr.

Index: lambda-code.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lambda-code.c,v
retrieving revision 2.47.2.1
diff -d -u -p -r2.47.2.1 lambda-code.c
--- lambda-code.c	2 Sep 2005 16:42:18 -0000	2.47.2.1
+++ lambda-code.c	24 Oct 2005 08:44:57 -0000
@@ -2591,7 +2591,7 @@ lambda_transform_legal_p (lambda_trans_m
 			  int nb_loops,
 			  varray_type dependence_relations)
 {
-  unsigned int i;
+  unsigned int i, j;
   lambda_vector distres;
   struct data_dependence_relation *ddr;
 
@@ -2628,15 +2628,18 @@ lambda_transform_legal_p (lambda_trans_m
 	  
       /* If the dependence could not be captured by a distance vector,
 	 conservatively answer that the transform is not valid.  */
-      if (DDR_DIST_VECT (ddr) == NULL)
+      if (DDR_NUM_DIST_VECTS (ddr) == 0)
 	return false;
 
       /* Compute trans.dist_vect */
-      lambda_matrix_vector_mult (LTM_MATRIX (trans), nb_loops, nb_loops, 
-				 DDR_DIST_VECT (ddr), distres);
+      for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
+	{
+	  lambda_matrix_vector_mult (LTM_MATRIX (trans), nb_loops, nb_loops, 
+				     DDR_DIST_VECT (ddr, j), distres);
 
-      if (!lambda_vector_lexico_pos (distres, nb_loops))
-	return false;
+	  if (!lambda_vector_lexico_pos (distres, nb_loops))
+	    return false;
+	}
     }
   return true;
 }
Index: lambda.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lambda.h,v
retrieving revision 2.13.2.1
diff -d -u -p -r2.13.2.1 lambda.h
--- lambda.h	2 Sep 2005 16:42:18 -0000	2.13.2.1
+++ lambda.h	24 Oct 2005 08:44:57 -0000
@@ -30,6 +30,9 @@ Software Foundation, 51 Franklin Street,
    integers.  */
 typedef int *lambda_vector;
 
+DEF_VEC_P(lambda_vector);
+DEF_VEC_ALLOC_P(lambda_vector,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;
Index: tree-data-ref.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
retrieving revision 2.35.2.4
diff -d -u -p -r2.35.2.4 tree-data-ref.c
--- tree-data-ref.c	5 Oct 2005 23:18:29 -0000	2.35.2.4
+++ tree-data-ref.c	24 Oct 2005 08:45:01 -0000
@@ -626,6 +626,7 @@ dump_data_dependence_relation (FILE *out
   else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
     {
       unsigned int i;
+
       for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
 	{
 	  fprintf (outf, "  access_fn_A: ");
@@ -634,15 +635,19 @@ dump_data_dependence_relation (FILE *out
 	  print_generic_stmt (outf, DR_ACCESS_FN (drb, i), 0);
 	  dump_subscript (outf, DDR_SUBSCRIPT (ddr, i));
 	}
-      if (DDR_DIST_VECT (ddr))
+
+      for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
 	{
-	  fprintf (outf, "  distance_vect: ");
-	  print_lambda_vector (outf, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
+	  fprintf (outf, "  distance_vector: ");
+	  print_lambda_vector (outf, DDR_DIST_VECT (ddr, i),
+			       DDR_SIZE_VECT (ddr));
 	}
-      if (DDR_DIR_VECT (ddr))
+
+      for (i = 0; i < DDR_NUM_DIR_VECTS (ddr); i++)
 	{
-	  fprintf (outf, "  direction_vect: ");
-	  print_lambda_vector (outf, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
+	  fprintf (outf, "  direction_vector: ");
+	  print_lambda_vector (outf, DDR_DIR_VECT (ddr, i),
+			       DDR_SIZE_VECT (ddr));
 	}
     }
 
@@ -700,7 +705,7 @@ dump_data_dependence_direction (FILE *fi
 void 
 dump_dist_dir_vectors (FILE *file, varray_type ddrs)
 {
-  unsigned int i;
+  unsigned int i, j;
 
   for (i = 0; i < VARRAY_ACTIVE_SIZE (ddrs); i++)
     {
@@ -710,12 +715,21 @@ dump_dist_dir_vectors (FILE *file, varra
       if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE
 	  && DDR_AFFINE_P (ddr))
 	{
-	  fprintf (file, "DISTANCE_V (");
-	  print_lambda_vector (file, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
-	  fprintf (file, ")\n");
-	  fprintf (file, "DIRECTION_V (");
-	  print_lambda_vector (file, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
-	  fprintf (file, ")\n");
+	  for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
+	    {
+	      fprintf (file, "DISTANCE_V (");
+	      print_lambda_vector (file, DDR_DIST_VECT (ddr, j),
+				   DDR_SIZE_VECT (ddr));
+	      fprintf (file, ")\n");
+	    }
+
+	  for (j = 0; j < DDR_NUM_DIR_VECTS (ddr); j++)
+	    {
+	      fprintf (file, "DIRECTION_V (");
+	      print_lambda_vector (file, DDR_DIR_VECT (ddr, j),
+				   DDR_SIZE_VECT (ddr));
+	      fprintf (file, ")\n");
+	    }
 	}
     }
   fprintf (file, "\n\n");
@@ -2002,9 +2016,9 @@ initialize_data_dependence_relation (str
   DDR_ARE_DEPENDENT (res) = NULL_TREE;
   DDR_SUBSCRIPTS_VECTOR_INIT (res, DR_NUM_DIMENSIONS (a));
   DDR_SIZE_VECT (res) = 0;
-  DDR_DIST_VECT (res) = NULL;
-  DDR_DIR_VECT (res) = NULL;
-      
+  DDR_DIR_VECTS (res) = NULL;
+  DDR_DIST_VECTS (res) = NULL;
+
   for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
     {
       struct subscript *subscript;
@@ -3070,7 +3084,9 @@ build_classic_dist_vector (struct data_d
 {
   unsigned i;
   lambda_vector dist_v, init_v;
+  bool init_b = false;
   
+  DDR_SIZE_VECT (ddr) = nb_loops;
   dist_v = lambda_vector_new (nb_loops);
   init_v = lambda_vector_new (nb_loops);
   lambda_vector_clear (dist_v, nb_loops);
@@ -3168,9 +3184,38 @@ build_classic_dist_vector (struct data_d
 
 	  dist_v[loop_depth] = dist;
 	  init_v[loop_depth] = 1;
+	  init_b = true;
 	}
     }
-  
+
+  /* Save the distance vector if we initialized one.  */
+  if (init_b)
+    {
+      lambda_vector save_v;
+
+      /* Verify a basic constraint: classic distance vectors should always
+	 be lexicographically positive.  */
+      if (!lambda_vector_lexico_pos (dist_v, DDR_SIZE_VECT (ddr)))
+	{
+	  if (DDR_SIZE_VECT (ddr) == 1)
+	    /* This one is simple to fix, and can be fixed.
+	       Multidimensional arrays cannot be fixed that simply.  */
+	    lambda_vector_negate (dist_v, dist_v, DDR_SIZE_VECT (ddr));
+	  else
+	    /* This is not valid: we need the delta test for properly
+	       fixing all this.  */
+	    return false;
+	}
+
+      save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+      lambda_vector_copy (dist_v, save_v, DDR_SIZE_VECT (ddr));
+      VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), save_v);
+
+      /* There is nothing more to do when there are no outer loops.  */
+      if (DDR_SIZE_VECT (ddr) == 1)
+	goto classic_dist_done;
+    }
+
   /* There is a distance of 1 on all the outer loops: 
      
      Example: there is a dependence of distance 1 on loop_1 for the array A.
@@ -3188,59 +3233,63 @@ build_classic_dist_vector (struct data_d
     
     /* Get the common ancestor loop.  */
     lca = find_common_loop (loop_a, loop_b); 
-    
-    lca_depth = lca->depth;
-    lca_depth -= first_loop_depth;
+    lca_depth = lca->depth - first_loop_depth;
+
     gcc_assert (lca_depth >= 0);
     gcc_assert (lca_depth < nb_loops);
-
+    
     /* For each outer loop where init_v is not set, the accesses are
        in dependence of distance 1 in the loop.  */
-    if (lca != loop_a
-	&& lca != loop_b
-	&& init_v[lca_depth] == 0)
-      dist_v[lca_depth] = 1;
-    
-    lca = lca->outer;
-    
-    if (lca)
+    while (lca->depth != 0)
       {
-	lca_depth = lca->depth - first_loop_depth;
-	while (lca->depth != 0)
-	  {
-	    /* If we're considering just a sub-nest, then don't record
-	       any information on the outer loops.  */
-	    if (lca_depth < 0)
-	      break;
+	/* If we're considering just a sub-nest, then don't record
+	   any information on the outer loops.  */
+	if (lca_depth < 0)
+	  break;
 
-	    gcc_assert (lca_depth < nb_loops);
+	gcc_assert (lca_depth < nb_loops);
 
-	    if (init_v[lca_depth] == 0)
-	      dist_v[lca_depth] = 1;
-	    lca = lca->outer;
-	    lca_depth = lca->depth - first_loop_depth;
-	  
+	/* If we haven't yet determined a distance for this outer
+	   loop, push a new distance vector composed of the previous
+	   distance, and a distance of 1 for this outer loop.
+	   Example:
+
+	   | loop_1
+	   |   loop_2
+	   |     A[10]
+	   |   endloop_2
+	   | endloop_1
+
+	   Saved vectors are of the form (dist_in_1, dist_in_2).
+	   First, we save (0, 1), then we have to save (1, 0).  */
+	if (init_v[lca_depth] == 0)
+	  {
+	    lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+
+	    lambda_vector_copy (dist_v, save_v, DDR_SIZE_VECT (ddr));
+	    save_v[lca_depth] = 1;
+	    VEC_safe_push (lambda_vector, heap, DDR_DIST_VECTS (ddr), save_v);
 	  }
+
+	lca = lca->outer;
+	lca_depth = lca->depth - first_loop_depth;
       }
   }
-  
-  DDR_DIST_VECT (ddr) = dist_v;
-  DDR_SIZE_VECT (ddr) = nb_loops;
 
-  /* Verify a basic constraint: classic distance vectors should always
-     be lexicographically positive.  */
-  if (!lambda_vector_lexico_pos (DDR_DIST_VECT (ddr),
-				 DDR_SIZE_VECT (ddr)))
+ classic_dist_done:;
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
     {
-      if (DDR_SIZE_VECT (ddr) == 1)
-	/* This one is simple to fix, and can be fixed.
-	   Multidimensional arrays cannot be fixed that simply.  */
-	lambda_vector_negate (DDR_DIST_VECT (ddr), DDR_DIST_VECT (ddr),
-			      DDR_SIZE_VECT (ddr));
-      else
-	/* This is not valid: we need the delta test for properly
-	   fixing all this.  */
-	return false;
+      fprintf (dump_file, "(build_classic_dist_vector\n");
+
+      for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
+	{
+	  fprintf (dump_file, "  dist_vector = (");
+	  print_lambda_vector (dump_file, DDR_DIST_VECT (ddr, i),
+			       DDR_SIZE_VECT (ddr));
+	  fprintf (dump_file, "  )\n");
+	}
+      fprintf (dump_file, ")\n");
     }
 
   return true;
@@ -3262,11 +3311,14 @@ build_classic_dir_vector (struct data_de
 {
   unsigned i;
   lambda_vector dir_v, init_v;
+  bool init_b = false;
   
   dir_v = lambda_vector_new (nb_loops);
   init_v = lambda_vector_new (nb_loops);
   lambda_vector_clear (dir_v, nb_loops);
   lambda_vector_clear (init_v, nb_loops);
+
+  DDR_SIZE_VECT (ddr) = nb_loops;
   
   if (DDR_ARE_DEPENDENT (ddr) != NULL_TREE)
     return true;
@@ -3370,9 +3422,19 @@ build_classic_dir_vector (struct data_de
 	  
 	  dir_v[loop_depth] = dir;
 	  init_v[loop_depth] = 1;
+	  init_b = true;
 	}
     }
-  
+
+  /* Save the direction vector if we initialized one.  */
+  if (init_b)
+    {
+      lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
+
+      lambda_vector_copy (dir_v, save_v, DDR_SIZE_VECT (ddr));
+      VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), save_v);
+    }
+
   /* There is a distance of 1 on all the outer loops: 
      
      Example: there is a dependence of distance 1 on loop_1 for the array A.
@@ -3395,37 +3457,30 @@ build_classic_dir_vector (struct data_de
     gcc_assert (lca_depth >= 0);
     gcc_assert (lca_depth < nb_loops);
 
-    /* For each outer loop where init_v is not set, the accesses are
-       in dependence of distance 1 in the loop.  */
-    if (lca != loop_a
-	&& lca != loop_b
-	&& init_v[lca_depth] == 0)
-      dir_v[lca_depth] = dir_positive;
-    
-    lca = lca->outer;
-    if (lca)
+    while (lca->depth != 0)
       {
-	lca_depth = lca->depth - first_loop_depth;
-	while (lca->depth != 0)
+	/* If we're considering just a sub-nest, then don't record
+	   any information on the outer loops.  */
+	if (lca_depth < 0)
+	  break;
+
+	gcc_assert (lca_depth < nb_loops);
+
+	if (init_v[lca_depth] == 0)
 	  {
-	    /* If we're considering just a sub-nest, then don't record
-	       any information on the outer loops.  */
-	    if (lca_depth < 0)
-	      break;
+	    lambda_vector save_v = lambda_vector_new (DDR_SIZE_VECT (ddr));
 
-	    gcc_assert (lca_depth < nb_loops);
+	    lambda_vector_copy (dir_v, save_v, DDR_SIZE_VECT (ddr));
+	    save_v[lca_depth] = dir_positive;
+	    VEC_safe_push (lambda_vector, heap, DDR_DIR_VECTS (ddr), save_v);
+	  }
 
-	    if (init_v[lca_depth] == 0)
-	      dir_v[lca_depth] = dir_positive;
-	    lca = lca->outer;
-	    lca_depth = lca->depth - first_loop_depth;
+	lca = lca->outer;
+	lca_depth = lca->depth - first_loop_depth;
 	   
-	  }
       }
   }
-  
-  DDR_DIR_VECT (ddr) = dir_v;
-  DDR_SIZE_VECT (ddr) = nb_loops;
+
   return true;
 }
 
Index: tree-data-ref.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.h,v
retrieving revision 2.10.2.2
diff -d -u -p -r2.10.2.2 tree-data-ref.h
--- tree-data-ref.h	5 Oct 2005 23:18:29 -0000	2.10.2.2
+++ tree-data-ref.h	24 Oct 2005 08:45:01 -0000
@@ -217,14 +217,15 @@ struct data_dependence_relation
      the data_dependence_relation.  */
   varray_type subscripts;
 
-  /* The size of the direction/distance vectors.  */
+  /* The size of the direction/distance vectors: the depth of the
+     analyzed loop nest.  */
   int size_vect;
 
   /* The classic direction vector.  */
-  lambda_vector dir_vect;
+  VEC(lambda_vector,heap) *dir_vects;
 
   /* The classic distance vector.  */
-  lambda_vector dist_vect;
+  VEC(lambda_vector,heap) *dist_vects;
 };
 
 #define DDR_A(DDR) DDR->a
@@ -237,8 +238,17 @@ struct data_dependence_relation
 #define DDR_SUBSCRIPT(DDR, I) VARRAY_GENERIC_PTR (DDR_SUBSCRIPTS (DDR), I)
 #define DDR_NUM_SUBSCRIPTS(DDR) VARRAY_ACTIVE_SIZE (DDR_SUBSCRIPTS (DDR))
 #define DDR_SIZE_VECT(DDR) DDR->size_vect
-#define DDR_DIR_VECT(DDR) DDR->dir_vect
-#define DDR_DIST_VECT(DDR) DDR->dist_vect
+
+#define DDR_DIST_VECTS(DDR) ((DDR)->dist_vects)
+#define DDR_DIR_VECTS(DDR) ((DDR)->dir_vects)
+#define DDR_NUM_DIST_VECTS(DDR) \
+  (VEC_length (lambda_vector, DDR_DIST_VECTS (DDR)))
+#define DDR_NUM_DIR_VECTS(DDR) \
+  (VEC_length (lambda_vector, DDR_DIR_VECTS (DDR)))
+#define DDR_DIR_VECT(DDR, I) \
+  VEC_index (lambda_vector, DDR_DIR_VECTS (DDR), I)
+#define DDR_DIST_VECT(DDR, I) \
+  VEC_index (lambda_vector, DDR_DIST_VECTS (DDR), I)
 
 
 
Index: tree-loop-linear.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-loop-linear.c,v
retrieving revision 2.17
diff -d -u -p -r2.17 tree-loop-linear.c
--- tree-loop-linear.c	25 Jul 2005 12:04:50 -0000	2.17
+++ tree-loop-linear.c	24 Oct 2005 08:45:01 -0000
@@ -98,7 +98,7 @@ gather_interchange_stats (varray_type de
 			  unsigned int *nb_deps_not_carried_by_loop, 
 			  unsigned int *access_strides)
 {
-  unsigned int i;
+  unsigned int i, j;
 
   *dependence_steps = 0;
   *nb_deps_not_carried_by_loop = 0;
@@ -106,7 +106,6 @@ gather_interchange_stats (varray_type de
 
   for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
     {
-      int dist;
       struct data_dependence_relation *ddr = 
 	(struct data_dependence_relation *) 
 	VARRAY_GENERIC_PTR (dependence_relations, i);
@@ -114,21 +113,24 @@ gather_interchange_stats (varray_type de
       /* If we don't know anything about this dependence, or the distance
 	 vector is NULL, or there is no dependence, then there is no reuse of
 	 data.  */
-
-      if (DDR_DIST_VECT (ddr) == NULL
-	  || DDR_ARE_DEPENDENT (ddr) == chrec_dont_know
-	  || DDR_ARE_DEPENDENT (ddr) == chrec_known)
+      if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know
+	  || DDR_ARE_DEPENDENT (ddr) == chrec_known
+	  || DDR_NUM_DIST_VECTS (ddr) == 0)
 	continue;
-      
 
-      
-      dist = DDR_DIST_VECT (ddr)[loop->depth - first_loop->depth];
-      if (dist == 0)
-	(*nb_deps_not_carried_by_loop) += 1;
-      else if (dist < 0)
-	(*dependence_steps) += -dist;
-      else
-	(*dependence_steps) += dist;
+      for (j = 0; j < DDR_NUM_DIST_VECTS (ddr); j++)
+	{
+	  int dist = DDR_DIST_VECT (ddr, j)[loop->depth - first_loop->depth];
+
+	  if (dist == 0)
+	    (*nb_deps_not_carried_by_loop) += 1;
+
+	  else if (dist < 0)
+	    (*dependence_steps) += -dist;
+
+	  else
+	    (*dependence_steps) += dist;
+	}
     }
 
   /* Compute the access strides.  */
@@ -307,16 +309,7 @@ linear_transform_loops (struct loops *lo
 		VARRAY_GENERIC_PTR (dependence_relations, j);
 
 	      if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
-		{
-		  fprintf (dump_file, "DISTANCE_V (");
-		  print_lambda_vector (dump_file, DDR_DIST_VECT (ddr), 
-				       DDR_SIZE_VECT (ddr));
-		  fprintf (dump_file, ")\n");
-		  fprintf (dump_file, "DIRECTION_V (");
-		  print_lambda_vector (dump_file, DDR_DIR_VECT (ddr), 
-				       DDR_SIZE_VECT (ddr));
-		  fprintf (dump_file, ")\n");
-		}
+		dump_data_dependence_relation (dump_file, ddr);
 	    }
 	  fprintf (dump_file, "\n\n");
 	}
Index: tree-vect-analyze.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
retrieving revision 2.33.2.2
diff -d -u -p -r2.33.2.2 tree-vect-analyze.c
--- tree-vect-analyze.c	5 Oct 2005 23:18:30 -0000	2.33.2.2
+++ tree-vect-analyze.c	24 Oct 2005 08:45:01 -0000
@@ -570,9 +570,9 @@ static bool
 vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
                                   loop_vec_info loop_vinfo)
 {
+  unsigned int i;
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
-  int dist = 0;
   unsigned int loop_depth = 0;
   struct loop *loop_nest = loop;
   struct data_reference *dra = DDR_A (ddr);
@@ -596,7 +596,7 @@ vect_analyze_data_ref_dependence (struct
       return true;
     }
 
-  if (!DDR_DIST_VECT (ddr))
+  if (DDR_NUM_DIST_VECTS (ddr) == 0)
     {
       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
         {
@@ -614,48 +614,54 @@ vect_analyze_data_ref_dependence (struct
       loop_nest = loop_nest->outer;
       loop_depth++;
     }
-         
-  dist = DDR_DIST_VECT (ddr)[loop_depth];
-  if (vect_print_dump_info (REPORT_DR_DETAILS))
-    fprintf (vect_dump, "dependence distance  = %d.",dist);
 
-  /* Same loop iteration.  */
-  if (dist % vectorization_factor == 0)
+  for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
     {
-      /* Two references with distance zero have the same alignment.  */
-      VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
-      VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
-      if (vect_print_dump_info (REPORT_ALIGNMENT))
-        fprintf (vect_dump, "accesses have the same alignment.");
-      if (vect_print_dump_info (REPORT_DR_DETAILS))
-        {
-          fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
-          print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
-          fprintf (vect_dump, " and ");
-          print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
-        }
-      return false;
-    }    
+      int dist = DDR_DIST_VECT (ddr, i)[loop_depth];
 
-  if (abs (dist) >= vectorization_factor)
-    {
-      /* Dependence distance does not create dependence, as far as vectorization
-         is concerned, in this case.  */
       if (vect_print_dump_info (REPORT_DR_DETAILS))
-        fprintf (vect_dump, "dependence distance >= VF.");
-       return false;
-    }
-  
-  if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
-    {
-      fprintf (vect_dump,
-        "not vectorized: possible dependence between data-refs ");
-      print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
-      fprintf (vect_dump, " and ");
-      print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+	fprintf (vect_dump, "dependence distance  = %d.", dist);
+
+      /* Same loop iteration.  */
+      if (dist % vectorization_factor == 0)
+	{
+	  /* Two references with distance zero have the same alignment.  */
+	  VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
+	  VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
+	  if (vect_print_dump_info (REPORT_ALIGNMENT))
+	    fprintf (vect_dump, "accesses have the same alignment.");
+	  if (vect_print_dump_info (REPORT_DR_DETAILS))
+	    {
+	      fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
+	      print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
+	      fprintf (vect_dump, " and ");
+	      print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+	    }
+	  continue;
+	}
+
+      if (abs (dist) >= vectorization_factor)
+	{
+	  /* Dependence distance does not create dependence, as far as vectorization
+	     is concerned, in this case.  */
+	  if (vect_print_dump_info (REPORT_DR_DETAILS))
+	    fprintf (vect_dump, "dependence distance >= VF.");
+	  continue;
+	}
+
+      if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
+	{
+	  fprintf (vect_dump,
+		   "not vectorized: possible dependence between data-refs ");
+	  print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
+	  fprintf (vect_dump, " and ");
+	  print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+	}
+
+      return true;
     }
-        
-  return true;
+
+  return false;
 }
 
 



More information about the Gcc-patches mailing list