public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Auto vectorize cond expr (remaining patches)
@ 2005-04-01  0:30 Devang Patel
  2005-04-07 17:03 ` Ping: " Devang Patel
  2005-04-09  7:02 ` Richard Henderson
  0 siblings, 2 replies; 10+ messages in thread
From: Devang Patel @ 2005-04-01  0:30 UTC (permalink / raw)
  To: GCC Patches

This is remaining bits of vectorizing cond expr bits I posted in
last sept. This patch adds support to 1) vectorize conditional
expressions (using vec_cond_optab). 2) It also adds support to check
dependence distance wrt vectorization factor. This work was
presented in two different patches in sept. (along with 4 other
patches but these two missed GCC 4.0 train.). This patches are
used in autovect-branch and apple-ppc-branch since last 6 months.

2005-03-31  Devang Patel  <dpatel@apple.com>

         * tree-data-ref.c (build_classic_dist_vector,
         compute_subscript_distance): Make externally visible.
         * tree-data-ref.h (build_classic_dist_vector,
         compute_subscript_distance): Same.
         * tree-vect-analyze.c (vect_analyze_operations): Check
         vectorizable codition.
         (vect_analyze_data_ref_dependence): Check distance vector
         against vectorization factor.
         (vect_analyze_loop): Determine vectorizaion factor before
         analyzing data dependences.
         * tree-vect-transform.c (vect_is_simple_cond): New function.
         (vectorizable_condition): New function.
         (vect_transform_stmt): Handle condition_vec_info_type.
         * tree-vectorizer.c (loops_num): Make it global and externally
         visible.
         * tree-vectorizer.h (enum stmt_vec_info_type): Add
         condition_vec_info_type.
         (vectorizable_condition, loops_num): New.
         * config/rs6000.c (rs6000_emit_vector_select): Fix vector  
select
         operand ordering.

         * lib/target-supports.exp  
(check_effective_target_vect_condition): New.
         * gcc.dg/vect/vect-dv-1.c: New test.
         * gcc.dg/vect/vect-dv-2.c: New test.
         * gcc.dg/vect/vect-ifcvt-1.c: New test.
         * gcc.dg/vect/vect-ifcvt-2.c: New test.
         * gcc.dg/vect/vect-ifcvt-3.c: New test.
         * gcc.dg/vect/vect-ifcvt-4.c: New test.
         * gcc.dg/vect/vect-ifcvt-5.c: New test.
         * gcc.dg/vect/vect-ifcvt-6.c: New test.
         * gcc.dg/vect/vect-ifcvt-7.c: New test.
         * gcc.dg/vect/vect-none.c: Now one loop is vectorized.

Bootstrapped and tested on powerpc-darwin, tested on SPEC.

-
Devang

Index: tree-data-ref.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
retrieving revision 2.24
diff -Idpatel.pbxuser -c -3 -p -r2.24 tree-data-ref.c
*** tree-data-ref.c     9 Mar 2005 11:30:36 -0000       2.24
--- tree-data-ref.c     31 Mar 2005 23:56:06 -0000
*************** all_chrecs_equal_p (tree chrec)
*** 646,652 ****
   /* Determine for each subscript in the data dependence relation DDR
      the distance.  */

! static void
   compute_subscript_distance (struct data_dependence_relation *ddr)
   {
     if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
--- 646,652 ----
   /* Determine for each subscript in the data dependence relation DDR
      the distance.  */

! void
   compute_subscript_distance (struct data_dependence_relation *ddr)
   {
     if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
*************** subscript_dependence_tester (struct data
*** 1769,1775 ****
      starting at FIRST_LOOP_DEPTH.
      Return TRUE otherwise.  */

! static bool
   build_classic_dist_vector (struct data_dependence_relation *ddr,
                            int nb_loops, int first_loop_depth)
   {
--- 1769,1775 ----
      starting at FIRST_LOOP_DEPTH.
      Return TRUE otherwise.  */

! bool
   build_classic_dist_vector (struct data_dependence_relation *ddr,
                            int nb_loops, int first_loop_depth)
   {
Index: tree-data-ref.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.h,v
retrieving revision 2.5
diff -Idpatel.pbxuser -c -3 -p -r2.5 tree-data-ref.h
*** tree-data-ref.h     13 Oct 2004 03:48:03 -0000      2.5
--- tree-data-ref.h     31 Mar 2005 23:56:06 -0000
*************** extern bool array_base_name_differ_p (st
*** 176,181 ****
--- 176,183 ----
   extern void free_dependence_relation (struct  
data_dependence_relation *);
   extern void free_dependence_relations (varray_type);
   extern void free_data_refs (varray_type);
+ extern void compute_subscript_distance (struct  
data_dependence_relation *);
+ extern bool build_classic_dist_vector (struct  
data_dependence_relation *, int, int);




Index: tree-vect-analyze.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
retrieving revision 2.14
diff -Idpatel.pbxuser -c -3 -p -r2.14 tree-vect-analyze.c
*** tree-vect-analyze.c 23 Mar 2005 15:52:59 -0000      2.14
--- tree-vect-analyze.c 31 Mar 2005 23:56:07 -0000
*************** vect_analyze_operations (loop_vec_info l
*** 493,499 ****
           ok = (vectorizable_operation (stmt, NULL, NULL)
                 || vectorizable_assignment (stmt, NULL, NULL)
                 || vectorizable_load (stmt, NULL, NULL)
!               || vectorizable_store (stmt, NULL, NULL));

           if (!ok)
             {
--- 493,500 ----
           ok = (vectorizable_operation (stmt, NULL, NULL)
                 || vectorizable_assignment (stmt, NULL, NULL)
                 || vectorizable_load (stmt, NULL, NULL)
!               || vectorizable_store (stmt, NULL, NULL)
!               || vectorizable_condition (stmt, NULL, NULL));

           if (!ok)
             {
*************** vect_analyze_data_ref_dependence (struct
*** 773,778 ****
--- 774,785 ----
   {
     bool differ_p;
     struct data_dependence_relation *ddr;
+   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;
+

     if (!vect_base_addr_differ_p (dra, drb, &differ_p))
       {
*************** vect_analyze_data_ref_dependence (struct
*** 796,802 ****

     if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
       return false;
!
     if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
                             LOOP_LOC (loop_vinfo)))
       {
--- 803,867 ----

     if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
       return false;
!
!   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
!     {
!       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
!                                 LOOP_LOC (loop_vinfo)))
!         {
!           fprintf (vect_dump,
!                    "not vectorized: can't determine dependence  
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 true;
!     }
!
!   /* Find loop depth.  */
!   while (loop_nest)
!     {
!       if (loop_nest->outer && loop_nest->outer->outer)
!       {
!         loop_nest = loop_nest->outer;
!         loop_depth++;
!       }
!       else
!       break;
!     }
!
!   /* Compute distance vector.  */
!   compute_subscript_distance (ddr);
!   build_classic_dist_vector (ddr, loops_num, loop_nest->depth);
!
!   if (!DDR_DIST_VECT (ddr))
!     {
!       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
!                               LOOP_LOC (loop_vinfo)))
!       {
!         fprintf (vect_dump, "not vectorized: bad dist vector for ");
!         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;
!     }
!
!   dist = DDR_DIST_VECT (ddr)[loop_depth];
!
!   /* Same loop iteration.  */
!   if (dist == 0)
!     {
!       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, LOOP_LOC  
(loop_vinfo)))
!       fprintf (vect_dump, "dependence distance 0.");
!       return false;
!     }
!
!   if (dist >= vectorization_factor)
!     /* Dependence distance does not create dependence, as far as  
vectorization
!        is concerned, in this case.  */
!     return false;
!
     if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
                             LOOP_LOC (loop_vinfo)))
       {
*************** vect_analyze_data_ref_dependence (struct
*** 814,823 ****
   /* Function vect_analyze_data_ref_dependences.

      Examine all the data references in the loop, and make sure  
there do not
!    exist any data dependences between them.
!
!    TODO: dependences which distance is greater than the  
vectorization factor
!          can be ignored.  */

   static bool
   vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
--- 879,885 ----
   /* Function vect_analyze_data_ref_dependences.

      Examine all the data references in the loop, and make sure  
there do not
!    exist any data dependences between them.  */

   static bool
   vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
*************** vect_analyze_loop (struct loop *loop)
*** 2554,2559 ****
--- 2616,2630 ----
         return NULL;
       }

+   ok = vect_determine_vectorization_factor (loop_vinfo);
+   if (!ok)
+     {
+       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC  
(loop_vinfo)))
+         fprintf (vect_dump, "can't determine vectorization factor.");
+       destroy_loop_vec_info (loop_vinfo);
+       return NULL;
+     }
+
     /* Analyze data dependences between the data-refs in the loop.
        FORNOW: fail at the first data dependence that we encounter.  */

*************** vect_analyze_loop (struct loop *loop)
*** 2578,2592 ****
         return NULL;
       }

-   ok = vect_determine_vectorization_factor (loop_vinfo);
-   if (!ok)
-     {
-       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC  
(loop_vinfo)))
-         fprintf (vect_dump, "can't determine vectorization factor.");
-       destroy_loop_vec_info (loop_vinfo);
-       return NULL;
-     }
-
     /* Analyze the alignment of the data-refs in the loop.
        FORNOW: Only aligned accesses are handled.  */

--- 2649,2654 ----
Index: tree-vect-transform.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-transform.c,v
retrieving revision 2.7
diff -Idpatel.pbxuser -c -3 -p -r2.7 tree-vect-transform.c
*** tree-vect-transform.c       15 Mar 2005 18:32:58 -0000      2.7
--- tree-vect-transform.c       31 Mar 2005 23:56:07 -0000
*************** static tree vect_get_vec_def_for_operand
*** 57,62 ****
--- 57,63 ----
   static tree vect_init_vector (tree, tree);
   static void vect_finish_stmt_generation
     (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
+ static bool vect_is_simple_cond (tree, loop_vec_info);

   /* Utility function dealing with loop peeling (not peeling  
itself).  */
   static void vect_generate_tmps_on_preheader
*************** vectorizable_load (tree stmt, block_stmt
*** 1128,1133 ****
--- 1129,1273 ----
     return true;
   }

+ /* Function vect_is_simple_cond.
+
+    Input:
+    LOOP - the loop that is being vectorized.
+    COND - Condition that is checked for simple use.
+
+    Returns whether a COND can be vectorized. Checkes whether
+    condition operands are supportable using vec_is_simple_use.  */
+
+ static bool
+ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
+ {
+   tree lhs, rhs;
+
+   if (TREE_CODE_CLASS (TREE_CODE (cond)) != tcc_comparison)
+     return false;
+
+   lhs = TREE_OPERAND (cond, 0);
+   rhs = TREE_OPERAND (cond, 1);
+
+   if (TREE_CODE (lhs) == SSA_NAME)
+     {
+       tree lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
+       if (!vect_is_simple_use (lhs, loop_vinfo, &lhs_def_stmt))
+       return false;
+     }
+   else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) !=  
REAL_CST)
+     return false;
+
+   if (TREE_CODE (rhs) == SSA_NAME)
+     {
+       tree rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
+       if (!vect_is_simple_use (rhs, loop_vinfo, &rhs_def_stmt))
+       return false;
+     }
+   else if (TREE_CODE (rhs) != INTEGER_CST  && TREE_CODE (rhs) !=  
REAL_CST)
+     return false;
+
+   return true;
+ }
+
+ /* vectorizable_condition.
+
+    Check if STMT is conditional modify expression that can be  
vectorized.
+    If VEC_STMT is also passed, vectorize the STMT: create a vectorized
+    stmt using VEC_COND_EXPR  to replace it, put it in VEC_STMT, and  
insert it
+    at BSI.
+
+    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
+
+ bool
+ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree  
*vec_stmt)
+ {
+   tree scalar_dest = NULL_TREE;
+   tree vec_dest = NULL_TREE;
+   tree op = NULL_TREE;
+   tree cond_expr, then_clause, else_clause;
+   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+   tree vec_cond_lhs, vec_cond_rhs, vec_then_clause, vec_else_clause;
+   tree vec_compare, vec_cond_expr;
+   tree new_temp;
+   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+   enum machine_mode vec_mode;
+
+   if (!STMT_VINFO_RELEVANT_P (stmt_info))
+     return false;
+
+   if (TREE_CODE (stmt) != MODIFY_EXPR)
+     return false;
+
+   op = TREE_OPERAND (stmt, 1);
+
+   if (TREE_CODE (op) != COND_EXPR)
+     return false;
+
+   cond_expr = TREE_OPERAND (op, 0);
+   then_clause = TREE_OPERAND (op, 1);
+   else_clause = TREE_OPERAND (op, 2);
+
+   if (!vect_is_simple_cond (cond_expr, loop_vinfo))
+     return false;
+
+   if (TREE_CODE (then_clause) == SSA_NAME)
+     {
+       tree then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
+       if (!vect_is_simple_use (then_clause, loop_vinfo,  
&then_def_stmt))
+       return false;
+     }
+   else if (TREE_CODE (then_clause) != INTEGER_CST
+          && TREE_CODE (then_clause) != REAL_CST)
+     return false;
+
+   if (TREE_CODE (else_clause) == SSA_NAME)
+     {
+       tree else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
+       if (!vect_is_simple_use (else_clause, loop_vinfo,  
&else_def_stmt))
+       return false;
+     }
+   else if (TREE_CODE (else_clause) != INTEGER_CST
+          && TREE_CODE (else_clause) != REAL_CST)
+     return false;
+
+
+   vec_mode = TYPE_MODE (vectype);
+
+   if (!vec_stmt)
+     {
+       STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
+       return expand_vec_cond_expr_p (op, vec_mode);
+     }
+
+   /* Transform */
+
+   /* Handle def.  */
+   scalar_dest = TREE_OPERAND (stmt, 0);
+   vec_dest = vect_create_destination_var (scalar_dest, vectype);
+
+   /* Handle cond expr.  */
+   vec_cond_lhs =
+     vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt);
+   vec_cond_rhs =
+     vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt);
+   vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt);
+   vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt);
+
+   /* Arguments are ready. create the new vector stmt.  */
+   vec_compare = build2 (TREE_CODE (cond_expr), vectype,
+                       vec_cond_lhs, vec_cond_rhs);
+   vec_cond_expr = build (VEC_COND_EXPR, vectype,
+                        vec_compare, vec_then_clause, vec_else_clause);
+
+   *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, vec_cond_expr);
+   new_temp = make_ssa_name (vec_dest, *vec_stmt);
+   TREE_OPERAND (*vec_stmt, 0) = new_temp;
+   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+
+   return true;
+ }

   /* Function vect_transform_stmt.

*************** vect_transform_stmt (tree stmt, block_st
*** 1163,1168 ****
--- 1303,1314 ----
         gcc_assert (done);
         is_store = true;
         break;
+
+     case condition_vec_info_type:
+       done = vectorizable_condition (stmt, bsi, &vec_stmt);
+       gcc_assert (done);
+       break;
+
       default:
         if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
           fprintf (vect_dump, "stmt not supported.");
Index: tree-vectorizer.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.c,v
retrieving revision 2.80
diff -Idpatel.pbxuser -c -3 -p -r2.80 tree-vectorizer.c
*** tree-vectorizer.c   16 Mar 2005 21:42:55 -0000      2.80
--- tree-vectorizer.c   31 Mar 2005 23:56:07 -0000
*************** FILE *vect_dump;
*** 176,182 ****
      to mark that it's uninitialized.  */
   enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;

!


   / 
************************************************************************ 
*
     Simple Loop Peeling Utilities
--- 176,182 ----
      to mark that it's uninitialized.  */
   enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;

! unsigned int loops_num;


   / 
************************************************************************ 
*
     Simple Loop Peeling Utilities
*************** need_imm_uses_for (tree var)
*** 1554,1560 ****
   void
   vectorize_loops (struct loops *loops)
   {
!   unsigned int i, loops_num;
     unsigned int num_vectorized_loops = 0;

     /* Fix the verbosity level if not defined explicitly by the  
user.  */
--- 1554,1560 ----
   void
   vectorize_loops (struct loops *loops)
   {
!   unsigned int i;
     unsigned int num_vectorized_loops = 0;

     /* Fix the verbosity level if not defined explicitly by the  
user.  */
Index: tree-vectorizer.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.h,v
retrieving revision 2.16
diff -Idpatel.pbxuser -c -3 -p -r2.16 tree-vectorizer.h
*** tree-vectorizer.h   15 Mar 2005 18:33:00 -0000      2.16
--- tree-vectorizer.h   31 Mar 2005 23:56:07 -0000
*************** enum stmt_vec_info_type {
*** 144,150 ****
     load_vec_info_type,
     store_vec_info_type,
     op_vec_info_type,
!   assignment_vec_info_type
   };

   typedef struct _stmt_vec_info {
--- 144,151 ----
     load_vec_info_type,
     store_vec_info_type,
     op_vec_info_type,
!   assignment_vec_info_type,
!   condition_vec_info_type
   };

   typedef struct _stmt_vec_info {
*************** known_alignment_for_access_p (struct dat
*** 270,276 ****
   /* vect_dump will be set to stderr or dump_file if exist.  */
   extern FILE *vect_dump;
   extern enum verbosity_levels vect_verbosity_level;
!
   /*-----------------------------------------------------------------*/
   /* Function prototypes.                                            */
   /*-----------------------------------------------------------------*/
--- 271,277 ----
   /* vect_dump will be set to stderr or dump_file if exist.  */
   extern FILE *vect_dump;
   extern enum verbosity_levels vect_verbosity_level;
! extern unsigned int loops_num;
   /*-----------------------------------------------------------------*/
   /* Function prototypes.                                            */
   /*-----------------------------------------------------------------*/
*************** extern bool vectorizable_load (tree, blo
*** 321,326 ****
--- 322,328 ----
   extern bool vectorizable_store (tree, block_stmt_iterator *, tree *);
   extern bool vectorizable_operation (tree, block_stmt_iterator *,  
tree *);
   extern bool vectorizable_assignment (tree, block_stmt_iterator *,  
tree *);
+ extern bool vectorizable_condition (tree, block_stmt_iterator *,  
tree *);
   /* Driver for transformation stage.  */
   extern void vect_transform_loop (loop_vec_info, struct loops *);

Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.796
diff -Idpatel.pbxuser -c -3 -p -r1.796 rs6000.c
*** config/rs6000/rs6000.c      20 Mar 2005 23:25:14 -0000      1.796
--- config/rs6000/rs6000.c      31 Mar 2005 23:56:08 -0000
*************** rs6000_emit_vector_select (rtx dest, rtx
*** 10667,10673 ****

     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
!                                     gen_rtvec (3, op1, op2, mask),
                                       vsel_insn_index));
     emit_insn (t);
     emit_move_insn (dest, temp);
--- 10667,10673 ----

     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
!                                     gen_rtvec (3, op2, op1, mask),
                                       vsel_insn_index));
     emit_insn (t);
     emit_move_insn (dest, temp);
Index: testsuite/gcc.dg/vect/vect-dv-1.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-dv-1.c
diff -N testsuite/gcc.dg/vect/vect-dv-1.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-dv-1.c   31 Mar 2005 23:56:09 -0000
***************
*** 0 ****
--- 1,22 ----
+ /* Test compiler crash when dependence analyzer can not represent
+    dependence relation by distance vector.  */
+ /* { dg-do compile } */
+ /* { dg-require-effective-target vect_int } */
+
+ int x[199];
+
+ void foo()
+
+ {
+   int t,j;
+
+   for (j=99;j>0;j--)
+     x [j+j]=x[j];
+
+   for (j=198;j>=100;j--)
+     if(x[j])
+       {
+       x[j-63]=x[j-3]-x[j];
+       }
+ }
+
Index: testsuite/gcc.dg/vect/vect-dv-2.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-dv-2.c
diff -N testsuite/gcc.dg/vect/vect-dv-2.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-dv-2.c   31 Mar 2005 23:56:09 -0000
***************
*** 0 ****
--- 1,73 ----
+ /* { dg-do run } */
+ /* { dg-require-effective-target vect_int } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 64
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N];
+   int B[N];
+   int C[N];
+   int D[N];
+
+   int i, j;
+
+   for (i = 0; i < N; i++)
+     {
+       A[i] = i;
+       B[i] = i;
+       C[i] = i;
+       D[i] = i;
+     }
+
+   /* Vectorizable */
+   for (i = 0; i < 16; i++)
+     {
+       A[i] = A[i+20];
+     }
+
+   /* check results:  */
+   for (i = 0; i < 16; i++)
+     {
+       if (A[i] != A[i+20])
+       abort ();
+     }
+
+   /* Vectorizable */
+   for (i = 0; i < 16; i++)
+     {
+       B[i] = B[i] + 5;
+     }
+
+   /* check results:  */
+   for (i = 0; i < 16; i++)
+     {
+       if (B[i] != C[i] + 5)
+       abort ();
+     }
+
+   /* Not vectorizable */
+   for (i = 0; i < 4; i++)
+     {
+       C[i] = C[i+3];
+     }
+
+   /* check results:  */
+   for (i = 0; i < 4; i++)
+     {
+       if (C[i] != D[i+3])
+       abort ();
+     }
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1  
"vect" { xfail vect_no_align } } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-1.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-1.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-1.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-1.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,75 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats - 
maltivec" { target powerpc*-*-* } } */
+ /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats - 
msse2" { target i?86-*-* x86_64-*-* } } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 64
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N];
+   int B[N];
+   int C[N];
+   int D[N];
+
+   int i, j;
+
+   for (i = 0; i < N; i++)
+     {
+       A[i] = i;
+       B[i] = i;
+       C[i] = i;
+       D[i] = i;
+     }
+
+   /* Vectorizable */
+   for (i = 0; i < 16; i++)
+     {
+       A[i] = A[i+20];
+     }
+
+   /* check results:  */
+   for (i = 0; i < 16; i++)
+     {
+       if (A[i] != A[i+20])
+       abort ();
+     }
+
+   /* Vectorizable */
+   for (i = 0; i < 16; i++)
+     {
+       B[i] = B[i] + 5;
+     }
+
+   /* check results:  */
+   for (i = 0; i < 16; i++)
+     {
+       if (B[i] != C[i] + 5)
+       abort ();
+     }
+
+   /* Not vectorizable */
+   for (i = 0; i < 4; i++)
+     {
+       C[i] = C[i+3];
+     }
+
+   /* check results:  */
+   for (i = 0; i < 4; i++)
+     {
+       if (C[i] != D[i+3])
+       abort ();
+     }
+
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1  
"vect" { xfail vect_no_align } } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-2.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-2.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-2.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-2.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+   int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0};
+   int i, j;
+
+   for (i = 0; i < 16; i++)
+     A[i] = ( A[i] >= MAX ? MAX : 0);
+
+   /* check results:  */
+   for (i = 0; i < N; i++)
+     if (A[i] != B[i])
+       abort ();
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-3.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-3.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-3.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-3.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+   int B[N] = {0,0,0,42,42,0,0,0,0,0,42,42,42,42,42,0};
+   int i, j;
+
+   for (i = 0; i < 16; i++)
+     A[i] = ( A[i] > MAX ? MAX : 0);
+
+   /* check results:  */
+   for (i = 0; i < N; i++)
+     if (A[i] != B[i])
+       abort ();
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-4.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-4.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-4.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-4.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+   int B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42};
+   int i, j;
+
+   for (i = 0; i < 16; i++)
+     A[i] = ( A[i] <= MAX ? MAX : 0);
+
+   /* check results:  */
+   for (i = 0; i < N; i++)
+     if (A[i] != B[i])
+       abort ();
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-5.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-5.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-5.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-5.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+   int B[N] = {42,42,0,0,0,42,42,42,42,42,0,0,0,0,0,42};
+   int i, j;
+
+   for (i = 0; i < 16; i++)
+     A[i] = ( A[i] < MAX ? MAX : 0);
+
+   /* check results:  */
+   for (i = 0; i < N; i++)
+     if (A[i] != B[i])
+       abort ();
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-6.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-6.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-6.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-6.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N] = {36,39,42,45,43,32,21,42,23,34,45,56,67,42,89,11};
+   int B[N] = {42,42,0,42,42,42,42,0,42,42,42,42,42,0,42,42};
+   int i, j;
+
+   for (i = 0; i < 16; i++)
+     A[i] = ( A[i] != MAX ? MAX : 0);
+
+   /* check results:  */
+   for (i = 0; i < N; i++)
+     if (A[i] != B[i])
+       abort ();
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-7.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-7.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-7.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-7.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int main ()
+ {
+   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,42,78,89,11};
+   int B[N] = {42,42,0,42,42,42,42,42,42,42,42,42,0,42,42,42};
+   int i, j;
+
+   for (i = 0; i < 16; i++)
+     A[i] = ( A[i] == MAX ? 0 : MAX);
+
+   /* check results:  */
+   for (i = 0; i < N; i++)
+     if (A[i] != B[i])
+       abort ();
+
+   return 0;
+ }
+
+
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-ifcvt-9.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-ifcvt-9.c
diff -N testsuite/gcc.dg/vect/vect-ifcvt-9.c
*** /dev/null   1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-ifcvt-9.c        31 Mar 2005 23:56:09  
-0000
***************
*** 0 ****
--- 1,36 ----
+ /* { dg-require-effective-target vect_condition } */
+ /* { dg-do run } */
+
+ #include <stdarg.h>
+ #include <signal.h>
+
+ #define N 16
+ #define MAX 42
+
+ extern void abort(void);
+
+ int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
+ int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0};
+ void foo ()  __attribute__((always_inline));
+ void foo ()
+ {
+   int i, j;
+
+   for (i = 0; i < 16; i++)
+     A[i] = ( A[i] >= MAX ? MAX : 0);
+ }
+
+ int main ()
+ {
+
+   int i, j;
+   foo ();
+   /* check results:  */
+   for (i = 0; i < N; i++)
+     if (A[i] != B[i])
+       abort ();
+
+   return 0;
+ }
+
+ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2  
"vect" } } */
Index: testsuite/gcc.dg/vect/vect-none.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-none.c,v
retrieving revision 1.4
diff -Idpatel.pbxuser -c -3 -p -r1.4 vect-none.c
*** testsuite/gcc.dg/vect/vect-none.c   9 Jan 2005 17:30:24  
-0000       1.4
--- testsuite/gcc.dg/vect/vect-none.c   31 Mar 2005 23:56:09 -0000
*************** foo (int n)
*** 181,184 ****
   }

   /* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */
! /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 3  
"vect"} } */
--- 181,185 ----
   }

   /* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */
! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
"vect"} } */
! /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2  
"vect"} } */
Index: testsuite/lib/target-supports.exp
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/lib/target-supports.exp,v
retrieving revision 1.46
diff -Idpatel.pbxuser -c -3 -p -r1.46 target-supports.exp
*** testsuite/lib/target-supports.exp   25 Mar 2005 02:21:01  
-0000      1.46
--- testsuite/lib/target-supports.exp   31 Mar 2005 23:56:09 -0000
*************** proc check_effective_target_vect_no_alig
*** 765,770 ****
--- 765,789 ----
       return $et_vect_no_align_saved
   }

+ # Return 1 if the target supports vector conditional operations, 0  
otherwise.
+
+ proc check_effective_target_vect_condition { } {
+     global et_vect_cond_saved
+
+     if [info exists et_vect_int_cond] {
+       verbose "check_effective_target_vect_cond: using cached  
result" 2
+     } else {
+       set et_vect_cond_saved 0
+       if { [istarget powerpc*-*-*] } {
+          set et_vect_cond_saved 1
+       }
+     }
+
+     verbose "check_effective_target_vect_cond: returning  
$et_vect_cond_saved" 2
+     return $et_vect_cond_saved
+ }
+
+
   # Return 1 if the target matches the effective target 'arg', 0  
otherwise.
   # This can be used with any check_* proc that takes no argument and
   # returns only 1 or 0.  It could be used with check_* procs that take

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Ping: Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-01  0:30 [PATCH] Auto vectorize cond expr (remaining patches) Devang Patel
@ 2005-04-07 17:03 ` Devang Patel
  2005-04-09  7:02 ` Richard Henderson
  1 sibling, 0 replies; 10+ messages in thread
From: Devang Patel @ 2005-04-07 17:03 UTC (permalink / raw)
  To: GCC Patches


On Mar 31, 2005, at 4:29 PM, Devang Patel wrote:

> This is remaining bits of vectorizing cond expr bits I posted in
> last sept. This patch adds support to 1) vectorize conditional
> expressions (using vec_cond_optab). 2) It also adds support to check
> dependence distance wrt vectorization factor. This work was
> presented in two different patches in sept. (along with 4 other
> patches but these two missed GCC 4.0 train.). This patches are
> used in autovect-branch and apple-ppc-branch since last 6 months.
>
> 2005-03-31  Devang Patel  <dpatel@apple.com>
>
>         * tree-data-ref.c (build_classic_dist_vector,
>         compute_subscript_distance): Make externally visible.
>         * tree-data-ref.h (build_classic_dist_vector,
>         compute_subscript_distance): Same.
>         * tree-vect-analyze.c (vect_analyze_operations): Check
>         vectorizable codition.
>         (vect_analyze_data_ref_dependence): Check distance vector
>         against vectorization factor.
>         (vect_analyze_loop): Determine vectorizaion factor before
>         analyzing data dependences.
>         * tree-vect-transform.c (vect_is_simple_cond): New function.
>         (vectorizable_condition): New function.
>         (vect_transform_stmt): Handle condition_vec_info_type.
>         * tree-vectorizer.c (loops_num): Make it global and externally
>         visible.
>         * tree-vectorizer.h (enum stmt_vec_info_type): Add
>         condition_vec_info_type.
>         (vectorizable_condition, loops_num): New.
>         * config/rs6000.c (rs6000_emit_vector_select): Fix vector  
> select
>         operand ordering.
>
>         * lib/target-supports.exp  
> (check_effective_target_vect_condition): New.
>         * gcc.dg/vect/vect-dv-1.c: New test.
>         * gcc.dg/vect/vect-dv-2.c: New test.
>         * gcc.dg/vect/vect-ifcvt-1.c: New test.
>         * gcc.dg/vect/vect-ifcvt-2.c: New test.
>         * gcc.dg/vect/vect-ifcvt-3.c: New test.
>         * gcc.dg/vect/vect-ifcvt-4.c: New test.
>         * gcc.dg/vect/vect-ifcvt-5.c: New test.
>         * gcc.dg/vect/vect-ifcvt-6.c: New test.
>         * gcc.dg/vect/vect-ifcvt-7.c: New test.
>         * gcc.dg/vect/vect-none.c: Now one loop is vectorized.
>
> Bootstrapped and tested on powerpc-darwin, tested on SPEC.
>
> -
> Devang
>
> Index: tree-data-ref.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
> retrieving revision 2.24
> diff -Idpatel.pbxuser -c -3 -p -r2.24 tree-data-ref.c
> *** tree-data-ref.c     9 Mar 2005 11:30:36 -0000       2.24
> --- tree-data-ref.c     31 Mar 2005 23:56:06 -0000
> *************** all_chrecs_equal_p (tree chrec)
> *** 646,652 ****
>   /* Determine for each subscript in the data dependence relation DDR
>      the distance.  */
>
> ! static void
>   compute_subscript_distance (struct data_dependence_relation *ddr)
>   {
>     if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
> --- 646,652 ----
>   /* Determine for each subscript in the data dependence relation DDR
>      the distance.  */
>
> ! void
>   compute_subscript_distance (struct data_dependence_relation *ddr)
>   {
>     if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
> *************** subscript_dependence_tester (struct data
> *** 1769,1775 ****
>      starting at FIRST_LOOP_DEPTH.
>      Return TRUE otherwise.  */
>
> ! static bool
>   build_classic_dist_vector (struct data_dependence_relation *ddr,
>                            int nb_loops, int first_loop_depth)
>   {
> --- 1769,1775 ----
>      starting at FIRST_LOOP_DEPTH.
>      Return TRUE otherwise.  */
>
> ! bool
>   build_classic_dist_vector (struct data_dependence_relation *ddr,
>                            int nb_loops, int first_loop_depth)
>   {
> Index: tree-data-ref.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.h,v
> retrieving revision 2.5
> diff -Idpatel.pbxuser -c -3 -p -r2.5 tree-data-ref.h
> *** tree-data-ref.h     13 Oct 2004 03:48:03 -0000      2.5
> --- tree-data-ref.h     31 Mar 2005 23:56:06 -0000
> *************** extern bool array_base_name_differ_p (st
> *** 176,181 ****
> --- 176,183 ----
>   extern void free_dependence_relation (struct  
> data_dependence_relation *);
>   extern void free_dependence_relations (varray_type);
>   extern void free_data_refs (varray_type);
> + extern void compute_subscript_distance (struct  
> data_dependence_relation *);
> + extern bool build_classic_dist_vector (struct  
> data_dependence_relation *, int, int);
>
>
>
>
> Index: tree-vect-analyze.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
> retrieving revision 2.14
> diff -Idpatel.pbxuser -c -3 -p -r2.14 tree-vect-analyze.c
> *** tree-vect-analyze.c 23 Mar 2005 15:52:59 -0000      2.14
> --- tree-vect-analyze.c 31 Mar 2005 23:56:07 -0000
> *************** vect_analyze_operations (loop_vec_info l
> *** 493,499 ****
>           ok = (vectorizable_operation (stmt, NULL, NULL)
>                 || vectorizable_assignment (stmt, NULL, NULL)
>                 || vectorizable_load (stmt, NULL, NULL)
> !               || vectorizable_store (stmt, NULL, NULL));
>
>           if (!ok)
>             {
> --- 493,500 ----
>           ok = (vectorizable_operation (stmt, NULL, NULL)
>                 || vectorizable_assignment (stmt, NULL, NULL)
>                 || vectorizable_load (stmt, NULL, NULL)
> !               || vectorizable_store (stmt, NULL, NULL)
> !               || vectorizable_condition (stmt, NULL, NULL));
>
>           if (!ok)
>             {
> *************** vect_analyze_data_ref_dependence (struct
> *** 773,778 ****
> --- 774,785 ----
>   {
>     bool differ_p;
>     struct data_dependence_relation *ddr;
> +   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;
> +
>
>     if (!vect_base_addr_differ_p (dra, drb, &differ_p))
>       {
> *************** vect_analyze_data_ref_dependence (struct
> *** 796,802 ****
>
>     if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
>       return false;
> !
>     if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
>                             LOOP_LOC (loop_vinfo)))
>       {
> --- 803,867 ----
>
>     if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
>       return false;
> !
> !   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
> !     {
> !       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
> !                                 LOOP_LOC (loop_vinfo)))
> !         {
> !           fprintf (vect_dump,
> !                    "not vectorized: can't determine dependence  
> 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 true;
> !     }
> !
> !   /* Find loop depth.  */
> !   while (loop_nest)
> !     {
> !       if (loop_nest->outer && loop_nest->outer->outer)
> !       {
> !         loop_nest = loop_nest->outer;
> !         loop_depth++;
> !       }
> !       else
> !       break;
> !     }
> !
> !   /* Compute distance vector.  */
> !   compute_subscript_distance (ddr);
> !   build_classic_dist_vector (ddr, loops_num, loop_nest->depth);
> !
> !   if (!DDR_DIST_VECT (ddr))
> !     {
> !       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
> !                               LOOP_LOC (loop_vinfo)))
> !       {
> !         fprintf (vect_dump, "not vectorized: bad dist vector for ");
> !         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;
> !     }
> !
> !   dist = DDR_DIST_VECT (ddr)[loop_depth];
> !
> !   /* Same loop iteration.  */
> !   if (dist == 0)
> !     {
> !       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,  
> LOOP_LOC (loop_vinfo)))
> !       fprintf (vect_dump, "dependence distance 0.");
> !       return false;
> !     }
> !
> !   if (dist >= vectorization_factor)
> !     /* Dependence distance does not create dependence, as far as  
> vectorization
> !        is concerned, in this case.  */
> !     return false;
> !
>     if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
>                             LOOP_LOC (loop_vinfo)))
>       {
> *************** vect_analyze_data_ref_dependence (struct
> *** 814,823 ****
>   /* Function vect_analyze_data_ref_dependences.
>
>      Examine all the data references in the loop, and make sure  
> there do not
> !    exist any data dependences between them.
> !
> !    TODO: dependences which distance is greater than the  
> vectorization factor
> !          can be ignored.  */
>
>   static bool
>   vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
> --- 879,885 ----
>   /* Function vect_analyze_data_ref_dependences.
>
>      Examine all the data references in the loop, and make sure  
> there do not
> !    exist any data dependences between them.  */
>
>   static bool
>   vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
> *************** vect_analyze_loop (struct loop *loop)
> *** 2554,2559 ****
> --- 2616,2630 ----
>         return NULL;
>       }
>
> +   ok = vect_determine_vectorization_factor (loop_vinfo);
> +   if (!ok)
> +     {
> +       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC  
> (loop_vinfo)))
> +         fprintf (vect_dump, "can't determine vectorization  
> factor.");
> +       destroy_loop_vec_info (loop_vinfo);
> +       return NULL;
> +     }
> +
>     /* Analyze data dependences between the data-refs in the loop.
>        FORNOW: fail at the first data dependence that we  
> encounter.  */
>
> *************** vect_analyze_loop (struct loop *loop)
> *** 2578,2592 ****
>         return NULL;
>       }
>
> -   ok = vect_determine_vectorization_factor (loop_vinfo);
> -   if (!ok)
> -     {
> -       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC  
> (loop_vinfo)))
> -         fprintf (vect_dump, "can't determine vectorization  
> factor.");
> -       destroy_loop_vec_info (loop_vinfo);
> -       return NULL;
> -     }
> -
>     /* Analyze the alignment of the data-refs in the loop.
>        FORNOW: Only aligned accesses are handled.  */
>
> --- 2649,2654 ----
> Index: tree-vect-transform.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/tree-vect-transform.c,v
> retrieving revision 2.7
> diff -Idpatel.pbxuser -c -3 -p -r2.7 tree-vect-transform.c
> *** tree-vect-transform.c       15 Mar 2005 18:32:58 -0000      2.7
> --- tree-vect-transform.c       31 Mar 2005 23:56:07 -0000
> *************** static tree vect_get_vec_def_for_operand
> *** 57,62 ****
> --- 57,63 ----
>   static tree vect_init_vector (tree, tree);
>   static void vect_finish_stmt_generation
>     (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
> + static bool vect_is_simple_cond (tree, loop_vec_info);
>
>   /* Utility function dealing with loop peeling (not peeling  
> itself).  */
>   static void vect_generate_tmps_on_preheader
> *************** vectorizable_load (tree stmt, block_stmt
> *** 1128,1133 ****
> --- 1129,1273 ----
>     return true;
>   }
>
> + /* Function vect_is_simple_cond.
> +
> +    Input:
> +    LOOP - the loop that is being vectorized.
> +    COND - Condition that is checked for simple use.
> +
> +    Returns whether a COND can be vectorized. Checkes whether
> +    condition operands are supportable using vec_is_simple_use.  */
> +
> + static bool
> + vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
> + {
> +   tree lhs, rhs;
> +
> +   if (TREE_CODE_CLASS (TREE_CODE (cond)) != tcc_comparison)
> +     return false;
> +
> +   lhs = TREE_OPERAND (cond, 0);
> +   rhs = TREE_OPERAND (cond, 1);
> +
> +   if (TREE_CODE (lhs) == SSA_NAME)
> +     {
> +       tree lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
> +       if (!vect_is_simple_use (lhs, loop_vinfo, &lhs_def_stmt))
> +       return false;
> +     }
> +   else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) !=  
> REAL_CST)
> +     return false;
> +
> +   if (TREE_CODE (rhs) == SSA_NAME)
> +     {
> +       tree rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
> +       if (!vect_is_simple_use (rhs, loop_vinfo, &rhs_def_stmt))
> +       return false;
> +     }
> +   else if (TREE_CODE (rhs) != INTEGER_CST  && TREE_CODE (rhs) !=  
> REAL_CST)
> +     return false;
> +
> +   return true;
> + }
> +
> + /* vectorizable_condition.
> +
> +    Check if STMT is conditional modify expression that can be  
> vectorized.
> +    If VEC_STMT is also passed, vectorize the STMT: create a  
> vectorized
> +    stmt using VEC_COND_EXPR  to replace it, put it in VEC_STMT,  
> and insert it
> +    at BSI.
> +
> +    Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
> +
> + bool
> + vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree  
> *vec_stmt)
> + {
> +   tree scalar_dest = NULL_TREE;
> +   tree vec_dest = NULL_TREE;
> +   tree op = NULL_TREE;
> +   tree cond_expr, then_clause, else_clause;
> +   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
> +   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
> +   tree vec_cond_lhs, vec_cond_rhs, vec_then_clause, vec_else_clause;
> +   tree vec_compare, vec_cond_expr;
> +   tree new_temp;
> +   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
> +   enum machine_mode vec_mode;
> +
> +   if (!STMT_VINFO_RELEVANT_P (stmt_info))
> +     return false;
> +
> +   if (TREE_CODE (stmt) != MODIFY_EXPR)
> +     return false;
> +
> +   op = TREE_OPERAND (stmt, 1);
> +
> +   if (TREE_CODE (op) != COND_EXPR)
> +     return false;
> +
> +   cond_expr = TREE_OPERAND (op, 0);
> +   then_clause = TREE_OPERAND (op, 1);
> +   else_clause = TREE_OPERAND (op, 2);
> +
> +   if (!vect_is_simple_cond (cond_expr, loop_vinfo))
> +     return false;
> +
> +   if (TREE_CODE (then_clause) == SSA_NAME)
> +     {
> +       tree then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
> +       if (!vect_is_simple_use (then_clause, loop_vinfo,  
> &then_def_stmt))
> +       return false;
> +     }
> +   else if (TREE_CODE (then_clause) != INTEGER_CST
> +          && TREE_CODE (then_clause) != REAL_CST)
> +     return false;
> +
> +   if (TREE_CODE (else_clause) == SSA_NAME)
> +     {
> +       tree else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
> +       if (!vect_is_simple_use (else_clause, loop_vinfo,  
> &else_def_stmt))
> +       return false;
> +     }
> +   else if (TREE_CODE (else_clause) != INTEGER_CST
> +          && TREE_CODE (else_clause) != REAL_CST)
> +     return false;
> +
> +
> +   vec_mode = TYPE_MODE (vectype);
> +
> +   if (!vec_stmt)
> +     {
> +       STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
> +       return expand_vec_cond_expr_p (op, vec_mode);
> +     }
> +
> +   /* Transform */
> +
> +   /* Handle def.  */
> +   scalar_dest = TREE_OPERAND (stmt, 0);
> +   vec_dest = vect_create_destination_var (scalar_dest, vectype);
> +
> +   /* Handle cond expr.  */
> +   vec_cond_lhs =
> +     vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),  
> stmt);
> +   vec_cond_rhs =
> +     vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),  
> stmt);
> +   vec_then_clause = vect_get_vec_def_for_operand (then_clause,  
> stmt);
> +   vec_else_clause = vect_get_vec_def_for_operand (else_clause,  
> stmt);
> +
> +   /* Arguments are ready. create the new vector stmt.  */
> +   vec_compare = build2 (TREE_CODE (cond_expr), vectype,
> +                       vec_cond_lhs, vec_cond_rhs);
> +   vec_cond_expr = build (VEC_COND_EXPR, vectype,
> +                        vec_compare, vec_then_clause,  
> vec_else_clause);
> +
> +   *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,  
> vec_cond_expr);
> +   new_temp = make_ssa_name (vec_dest, *vec_stmt);
> +   TREE_OPERAND (*vec_stmt, 0) = new_temp;
> +   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
> +
> +   return true;
> + }
>
>   /* Function vect_transform_stmt.
>
> *************** vect_transform_stmt (tree stmt, block_st
> *** 1163,1168 ****
> --- 1303,1314 ----
>         gcc_assert (done);
>         is_store = true;
>         break;
> +
> +     case condition_vec_info_type:
> +       done = vectorizable_condition (stmt, bsi, &vec_stmt);
> +       gcc_assert (done);
> +       break;
> +
>       default:
>         if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
>           fprintf (vect_dump, "stmt not supported.");
> Index: tree-vectorizer.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.c,v
> retrieving revision 2.80
> diff -Idpatel.pbxuser -c -3 -p -r2.80 tree-vectorizer.c
> *** tree-vectorizer.c   16 Mar 2005 21:42:55 -0000      2.80
> --- tree-vectorizer.c   31 Mar 2005 23:56:07 -0000
> *************** FILE *vect_dump;
> *** 176,182 ****
>      to mark that it's uninitialized.  */
>   enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
>
> !
>
>
>   / 
> ********************************************************************** 
> ***
>     Simple Loop Peeling Utilities
> --- 176,182 ----
>      to mark that it's uninitialized.  */
>   enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
>
> ! unsigned int loops_num;
>
>
>   / 
> ********************************************************************** 
> ***
>     Simple Loop Peeling Utilities
> *************** need_imm_uses_for (tree var)
> *** 1554,1560 ****
>   void
>   vectorize_loops (struct loops *loops)
>   {
> !   unsigned int i, loops_num;
>     unsigned int num_vectorized_loops = 0;
>
>     /* Fix the verbosity level if not defined explicitly by the  
> user.  */
> --- 1554,1560 ----
>   void
>   vectorize_loops (struct loops *loops)
>   {
> !   unsigned int i;
>     unsigned int num_vectorized_loops = 0;
>
>     /* Fix the verbosity level if not defined explicitly by the  
> user.  */
> Index: tree-vectorizer.h
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.h,v
> retrieving revision 2.16
> diff -Idpatel.pbxuser -c -3 -p -r2.16 tree-vectorizer.h
> *** tree-vectorizer.h   15 Mar 2005 18:33:00 -0000      2.16
> --- tree-vectorizer.h   31 Mar 2005 23:56:07 -0000
> *************** enum stmt_vec_info_type {
> *** 144,150 ****
>     load_vec_info_type,
>     store_vec_info_type,
>     op_vec_info_type,
> !   assignment_vec_info_type
>   };
>
>   typedef struct _stmt_vec_info {
> --- 144,151 ----
>     load_vec_info_type,
>     store_vec_info_type,
>     op_vec_info_type,
> !   assignment_vec_info_type,
> !   condition_vec_info_type
>   };
>
>   typedef struct _stmt_vec_info {
> *************** known_alignment_for_access_p (struct dat
> *** 270,276 ****
>   /* vect_dump will be set to stderr or dump_file if exist.  */
>   extern FILE *vect_dump;
>   extern enum verbosity_levels vect_verbosity_level;
> !
>   / 
> *-----------------------------------------------------------------*/
>   /* Function  
> prototypes.                                            */
>   / 
> *-----------------------------------------------------------------*/
> --- 271,277 ----
>   /* vect_dump will be set to stderr or dump_file if exist.  */
>   extern FILE *vect_dump;
>   extern enum verbosity_levels vect_verbosity_level;
> ! extern unsigned int loops_num;
>   / 
> *-----------------------------------------------------------------*/
>   /* Function  
> prototypes.                                            */
>   / 
> *-----------------------------------------------------------------*/
> *************** extern bool vectorizable_load (tree, blo
> *** 321,326 ****
> --- 322,328 ----
>   extern bool vectorizable_store (tree, block_stmt_iterator *, tree  
> *);
>   extern bool vectorizable_operation (tree, block_stmt_iterator *,  
> tree *);
>   extern bool vectorizable_assignment (tree, block_stmt_iterator *,  
> tree *);
> + extern bool vectorizable_condition (tree, block_stmt_iterator *,  
> tree *);
>   /* Driver for transformation stage.  */
>   extern void vect_transform_loop (loop_vec_info, struct loops *);
>
> Index: config/rs6000/rs6000.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
> retrieving revision 1.796
> diff -Idpatel.pbxuser -c -3 -p -r1.796 rs6000.c
> *** config/rs6000/rs6000.c      20 Mar 2005 23:25:14 -0000      1.796
> --- config/rs6000/rs6000.c      31 Mar 2005 23:56:08 -0000
> *************** rs6000_emit_vector_select (rtx dest, rtx
> *** 10667,10673 ****
>
>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
> !                                     gen_rtvec (3, op1, op2, mask),
>                                       vsel_insn_index));
>     emit_insn (t);
>     emit_move_insn (dest, temp);
> --- 10667,10673 ----
>
>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
> !                                     gen_rtvec (3, op2, op1, mask),
>                                       vsel_insn_index));
>     emit_insn (t);
>     emit_move_insn (dest, temp);
> Index: testsuite/gcc.dg/vect/vect-dv-1.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-dv-1.c
> diff -N testsuite/gcc.dg/vect/vect-dv-1.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-dv-1.c   31 Mar 2005 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,22 ----
> + /* Test compiler crash when dependence analyzer can not represent
> +    dependence relation by distance vector.  */
> + /* { dg-do compile } */
> + /* { dg-require-effective-target vect_int } */
> +
> + int x[199];
> +
> + void foo()
> +
> + {
> +   int t,j;
> +
> +   for (j=99;j>0;j--)
> +     x [j+j]=x[j];
> +
> +   for (j=198;j>=100;j--)
> +     if(x[j])
> +       {
> +       x[j-63]=x[j-3]-x[j];
> +       }
> + }
> +
> Index: testsuite/gcc.dg/vect/vect-dv-2.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-dv-2.c
> diff -N testsuite/gcc.dg/vect/vect-dv-2.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-dv-2.c   31 Mar 2005 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,73 ----
> + /* { dg-do run } */
> + /* { dg-require-effective-target vect_int } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 64
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N];
> +   int B[N];
> +   int C[N];
> +   int D[N];
> +
> +   int i, j;
> +
> +   for (i = 0; i < N; i++)
> +     {
> +       A[i] = i;
> +       B[i] = i;
> +       C[i] = i;
> +       D[i] = i;
> +     }
> +
> +   /* Vectorizable */
> +   for (i = 0; i < 16; i++)
> +     {
> +       A[i] = A[i+20];
> +     }
> +
> +   /* check results:  */
> +   for (i = 0; i < 16; i++)
> +     {
> +       if (A[i] != A[i+20])
> +       abort ();
> +     }
> +
> +   /* Vectorizable */
> +   for (i = 0; i < 16; i++)
> +     {
> +       B[i] = B[i] + 5;
> +     }
> +
> +   /* check results:  */
> +   for (i = 0; i < 16; i++)
> +     {
> +       if (B[i] != C[i] + 5)
> +       abort ();
> +     }
> +
> +   /* Not vectorizable */
> +   for (i = 0; i < 4; i++)
> +     {
> +       C[i] = C[i+3];
> +     }
> +
> +   /* check results:  */
> +   for (i = 0; i < 4; i++)
> +     {
> +       if (C[i] != D[i+3])
> +       abort ();
> +     }
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1  
> "vect" { xfail vect_no_align } } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-1.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-1.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-1.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-1.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,75 ----
> + /* { dg-do run } */
> + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats - 
> maltivec" { target powerpc*-*-* } } */
> + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats - 
> msse2" { target i?86-*-* x86_64-*-* } } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 64
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N];
> +   int B[N];
> +   int C[N];
> +   int D[N];
> +
> +   int i, j;
> +
> +   for (i = 0; i < N; i++)
> +     {
> +       A[i] = i;
> +       B[i] = i;
> +       C[i] = i;
> +       D[i] = i;
> +     }
> +
> +   /* Vectorizable */
> +   for (i = 0; i < 16; i++)
> +     {
> +       A[i] = A[i+20];
> +     }
> +
> +   /* check results:  */
> +   for (i = 0; i < 16; i++)
> +     {
> +       if (A[i] != A[i+20])
> +       abort ();
> +     }
> +
> +   /* Vectorizable */
> +   for (i = 0; i < 16; i++)
> +     {
> +       B[i] = B[i] + 5;
> +     }
> +
> +   /* check results:  */
> +   for (i = 0; i < 16; i++)
> +     {
> +       if (B[i] != C[i] + 5)
> +       abort ();
> +     }
> +
> +   /* Not vectorizable */
> +   for (i = 0; i < 4; i++)
> +     {
> +       C[i] = C[i+3];
> +     }
> +
> +   /* check results:  */
> +   for (i = 0; i < 4; i++)
> +     {
> +       if (C[i] != D[i+3])
> +       abort ();
> +     }
> +
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1  
> "vect" { xfail vect_no_align } } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-2.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-2.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-2.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-2.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,31 ----
> + /* { dg-require-effective-target vect_condition } */
> + /* { dg-do run } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 16
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
> +   int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0};
> +   int i, j;
> +
> +   for (i = 0; i < 16; i++)
> +     A[i] = ( A[i] >= MAX ? MAX : 0);
> +
> +   /* check results:  */
> +   for (i = 0; i < N; i++)
> +     if (A[i] != B[i])
> +       abort ();
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
> "vect" } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-3.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-3.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-3.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-3.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,31 ----
> + /* { dg-require-effective-target vect_condition } */
> + /* { dg-do run } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 16
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
> +   int B[N] = {0,0,0,42,42,0,0,0,0,0,42,42,42,42,42,0};
> +   int i, j;
> +
> +   for (i = 0; i < 16; i++)
> +     A[i] = ( A[i] > MAX ? MAX : 0);
> +
> +   /* check results:  */
> +   for (i = 0; i < N; i++)
> +     if (A[i] != B[i])
> +       abort ();
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
> "vect" } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-4.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-4.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-4.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-4.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,31 ----
> + /* { dg-require-effective-target vect_condition } */
> + /* { dg-do run } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 16
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
> +   int B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42};
> +   int i, j;
> +
> +   for (i = 0; i < 16; i++)
> +     A[i] = ( A[i] <= MAX ? MAX : 0);
> +
> +   /* check results:  */
> +   for (i = 0; i < N; i++)
> +     if (A[i] != B[i])
> +       abort ();
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
> "vect" } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-5.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-5.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-5.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-5.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,31 ----
> + /* { dg-require-effective-target vect_condition } */
> + /* { dg-do run } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 16
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
> +   int B[N] = {42,42,0,0,0,42,42,42,42,42,0,0,0,0,0,42};
> +   int i, j;
> +
> +   for (i = 0; i < 16; i++)
> +     A[i] = ( A[i] < MAX ? MAX : 0);
> +
> +   /* check results:  */
> +   for (i = 0; i < N; i++)
> +     if (A[i] != B[i])
> +       abort ();
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
> "vect" } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-6.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-6.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-6.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-6.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,31 ----
> + /* { dg-require-effective-target vect_condition } */
> + /* { dg-do run } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 16
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N] = {36,39,42,45,43,32,21,42,23,34,45,56,67,42,89,11};
> +   int B[N] = {42,42,0,42,42,42,42,0,42,42,42,42,42,0,42,42};
> +   int i, j;
> +
> +   for (i = 0; i < 16; i++)
> +     A[i] = ( A[i] != MAX ? MAX : 0);
> +
> +   /* check results:  */
> +   for (i = 0; i < N; i++)
> +     if (A[i] != B[i])
> +       abort ();
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
> "vect" } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-7.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-7.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-7.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-7.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,31 ----
> + /* { dg-require-effective-target vect_condition } */
> + /* { dg-do run } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 16
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int main ()
> + {
> +   int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,42,78,89,11};
> +   int B[N] = {42,42,0,42,42,42,42,42,42,42,42,42,0,42,42,42};
> +   int i, j;
> +
> +   for (i = 0; i < 16; i++)
> +     A[i] = ( A[i] == MAX ? 0 : MAX);
> +
> +   /* check results:  */
> +   for (i = 0; i < N; i++)
> +     if (A[i] != B[i])
> +       abort ();
> +
> +   return 0;
> + }
> +
> +
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
> "vect" } } */
> Index: testsuite/gcc.dg/vect/vect-ifcvt-9.c
> ===================================================================
> RCS file: testsuite/gcc.dg/vect/vect-ifcvt-9.c
> diff -N testsuite/gcc.dg/vect/vect-ifcvt-9.c
> *** /dev/null   1 Jan 1970 00:00:00 -0000
> --- testsuite/gcc.dg/vect/vect-ifcvt-9.c        31 Mar 2005  
> 23:56:09 -0000
> ***************
> *** 0 ****
> --- 1,36 ----
> + /* { dg-require-effective-target vect_condition } */
> + /* { dg-do run } */
> +
> + #include <stdarg.h>
> + #include <signal.h>
> +
> + #define N 16
> + #define MAX 42
> +
> + extern void abort(void);
> +
> + int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11};
> + int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0};
> + void foo ()  __attribute__((always_inline));
> + void foo ()
> + {
> +   int i, j;
> +
> +   for (i = 0; i < 16; i++)
> +     A[i] = ( A[i] >= MAX ? MAX : 0);
> + }
> +
> + int main ()
> + {
> +
> +   int i, j;
> +   foo ();
> +   /* check results:  */
> +   for (i = 0; i < N; i++)
> +     if (A[i] != B[i])
> +       abort ();
> +
> +   return 0;
> + }
> +
> + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2  
> "vect" } } */
> Index: testsuite/gcc.dg/vect/vect-none.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/vect/vect-none.c,v
> retrieving revision 1.4
> diff -Idpatel.pbxuser -c -3 -p -r1.4 vect-none.c
> *** testsuite/gcc.dg/vect/vect-none.c   9 Jan 2005 17:30:24  
> -0000       1.4
> --- testsuite/gcc.dg/vect/vect-none.c   31 Mar 2005 23:56:09 -0000
> *************** foo (int n)
> *** 181,184 ****
>   }
>
>   /* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */
> ! /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 3  
> "vect"} } */
> --- 181,185 ----
>   }
>
>   /* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */
> ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1  
> "vect"} } */
> ! /* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2  
> "vect"} } */
> Index: testsuite/lib/target-supports.exp
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/testsuite/lib/target-supports.exp,v
> retrieving revision 1.46
> diff -Idpatel.pbxuser -c -3 -p -r1.46 target-supports.exp
> *** testsuite/lib/target-supports.exp   25 Mar 2005 02:21:01  
> -0000      1.46
> --- testsuite/lib/target-supports.exp   31 Mar 2005 23:56:09 -0000
> *************** proc check_effective_target_vect_no_alig
> *** 765,770 ****
> --- 765,789 ----
>       return $et_vect_no_align_saved
>   }
>
> + # Return 1 if the target supports vector conditional operations,  
> 0 otherwise.
> +
> + proc check_effective_target_vect_condition { } {
> +     global et_vect_cond_saved
> +
> +     if [info exists et_vect_int_cond] {
> +       verbose "check_effective_target_vect_cond: using cached  
> result" 2
> +     } else {
> +       set et_vect_cond_saved 0
> +       if { [istarget powerpc*-*-*] } {
> +          set et_vect_cond_saved 1
> +       }
> +     }
> +
> +     verbose "check_effective_target_vect_cond: returning  
> $et_vect_cond_saved" 2
> +     return $et_vect_cond_saved
> + }
> +
> +
>   # Return 1 if the target matches the effective target 'arg', 0  
> otherwise.
>   # This can be used with any check_* proc that takes no argument and
>   # returns only 1 or 0.  It could be used with check_* procs that  
> take
>

-
Devang

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-01  0:30 [PATCH] Auto vectorize cond expr (remaining patches) Devang Patel
  2005-04-07 17:03 ` Ping: " Devang Patel
@ 2005-04-09  7:02 ` Richard Henderson
  2005-04-09 22:15   ` Devang Patel
  1 sibling, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2005-04-09  7:02 UTC (permalink / raw)
  To: Devang Patel; +Cc: GCC Patches

On Thu, Mar 31, 2005 at 04:29:41PM -0800, Devang Patel wrote:
> This is remaining bits of vectorizing cond expr bits I posted in
> last sept.

Please recall that apple's mailer is broken and mangles patches.

> This patch adds support to 1) vectorize conditional
> expressions (using vec_cond_optab). 2) It also adds support to check
> dependence distance wrt vectorization factor. This work was
> presented in two different patches in sept. (along with 4 other
> patches but these two missed GCC 4.0 train.). This patches are
> used in autovect-branch and apple-ppc-branch since last 6 months.

I found one of these, I think,

  http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02889.html

but not the other, and even the one basically has no commentary
on what you're trying to do.

I definitely want them split back into separate patches.

> !   /* Same loop iteration.  */
> !   if (dist == 0)
> !     {
> !       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, LOOP_LOC  
> (loop_vinfo)))
> !       fprintf (vect_dump, "dependence distance 0.");
> !       return false;
> !     }

return true?

> ! unsigned int loops_num;

What is this?

> *************** rs6000_emit_vector_select (rtx dest, rtx
> *** 10667,10673 ****
> 
>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
> !                                     gen_rtvec (3, op1, op2, mask),
>                                       vsel_insn_index));
>     emit_insn (t);
>     emit_move_insn (dest, temp);
> --- 10667,10673 ----
> 
>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
> !                                     gen_rtvec (3, op2, op1, mask),
>                                       vsel_insn_index));

I don't have enough context to know whether this is correct,
but you should pass this separately though an rs6000 maintainer.

> + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats - 
> maltivec" { target powerpc*-*-* } } */
> + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats - 
> msse2" { target i?86-*-* x86_64-*-* } } */

Surely you're looking for another effective-target hook?



r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-09  7:02 ` Richard Henderson
@ 2005-04-09 22:15   ` Devang Patel
  2005-04-09 23:33     ` Richard Henderson
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Devang Patel @ 2005-04-09 22:15 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches


On Apr 9, 2005, at 12:02 AM, Richard Henderson wrote:

> On Thu, Mar 31, 2005 at 04:29:41PM -0800, Devang Patel wrote:
>> This is remaining bits of vectorizing cond expr bits I posted in
>> last sept.
>
> Please recall that apple's mailer is broken and mangles patches.

Usually I attach my patches, but this time I did cut-n-paste.

>> This patch adds support to 1) vectorize conditional
>> expressions (using vec_cond_optab). 2) It also adds support to check
>> dependence distance wrt vectorization factor. This work was
>> presented in two different patches in sept. (along with 4 other
>> patches but these two missed GCC 4.0 train.). This patches are
>> used in autovect-branch and apple-ppc-branch since last 6 months.
>
> I found one of these, I think,
>
>   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02889.html
>
> but not the other, and even the one basically has no commentary
> on what you're trying to do.

Yes, this message is the last in this thread. The basic idea is simple.
If dependence distance is more than vectorization factor then it
does not prevent vectorization. If dependence distance is zero then
also it does not hurt vectorization.

Another is at

     http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01768.html

and it has some info and pointers to other messages. I included
dependence vector patch together because now it is very small
thanks to other changes in vectorizer.

> I definitely want them split back into separate patches.
>
>> !   /* Same loop iteration.  */
>> !   if (dist == 0)
>> !     {
>> !       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, LOOP_LOC
>> (loop_vinfo)))
>> !       fprintf (vect_dump, "dependence distance 0.");
>> !       return false;
>> !     }
>
> return true?

zero distance is ok for vectorization. This function returns true
iff dependence exist such that it prohibits vectorization.

>
>> ! unsigned int loops_num;
>
> What is this?

I am just moving this from tree-vectorizer.c to tree-vectorizer.h
It holds number of loops in this function at the beginning of  
vectorization.
I'll add comments here.

>
>> *************** rs6000_emit_vector_select (rtx dest, rtx
>> *** 10667,10673 ****
>>
>>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
>> !                                     gen_rtvec (3, op1, op2, mask),
>>                                       vsel_insn_index));
>>     emit_insn (t);
>>     emit_move_insn (dest, temp);
>> --- 10667,10673 ----
>>
>>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
>> !                                     gen_rtvec (3, op2, op1, mask),
>>                                       vsel_insn_index));
>
> I don't have enough context to know whether this is correct,
> but you should pass this separately though an rs6000 maintainer.

OK. It was supplying operands in wrong order to vector select
instruction. When I posted patch for rs6000_emit_vector_select (),
test case only checked compilation. Obviously it did not catch the  
change
of behavior in vectorized loop because of this bug.

>> + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -
>> maltivec" { target powerpc*-*-* } } */
>> + /* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -
>> msse2" { target i?86-*-* x86_64-*-* } } */
>
> Surely you're looking for another effective-target hook?

I just need to use same new check_effective_target_vect_condition hook.
Somehow, I missed it in this example.


Thanks,
-
Devang

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-09 22:15   ` Devang Patel
@ 2005-04-09 23:33     ` Richard Henderson
  2005-04-10  1:15       ` Devang Patel
  2005-04-11 18:10     ` Devang Patel
  2005-04-11 18:24     ` Devang Patel
  2 siblings, 1 reply; 10+ messages in thread
From: Richard Henderson @ 2005-04-09 23:33 UTC (permalink / raw)
  To: Devang Patel; +Cc: GCC Patches

On Sat, Apr 09, 2005 at 03:15:25PM -0700, Devang Patel wrote:
> >>!       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS, LOOP_LOC
> >>(loop_vinfo)))
> >>!       fprintf (vect_dump, "dependence distance 0.");
> >>!       return false;
> >>!     }
> >
> >return true?
> 
> zero distance is ok for vectorization. This function returns true
> iff dependence exist such that it prohibits vectorization.

Then why are you reporting it under "unvectorized loops"?


r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-09 23:33     ` Richard Henderson
@ 2005-04-10  1:15       ` Devang Patel
  0 siblings, 0 replies; 10+ messages in thread
From: Devang Patel @ 2005-04-10  1:15 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches


On Apr 9, 2005, at 4:33 PM, Richard Henderson wrote:

> On Sat, Apr 09, 2005 at 03:15:25PM -0700, Devang Patel wrote:
>>>> !       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,  
>>>> LOOP_LOC
>>>> (loop_vinfo)))
>>>> !       fprintf (vect_dump, "dependence distance 0.");
>>>> !       return false;
>>>> !     }
>>>
>>> return true?
>>
>> zero distance is ok for vectorization. This function returns true
>> iff dependence exist such that it prohibits vectorization.
>
> Then why are you reporting it under "unvectorized loops"?

Aha... that's wrong. I'll fix it.

-
Devang

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-09 22:15   ` Devang Patel
  2005-04-09 23:33     ` Richard Henderson
@ 2005-04-11 18:10     ` Devang Patel
  2005-04-11 19:24       ` Richard Henderson
  2005-04-11 18:24     ` Devang Patel
  2 siblings, 1 reply; 10+ messages in thread
From: Devang Patel @ 2005-04-11 18:10 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 2141 bytes --]


On Apr 9, 2005, at 3:15 PM, Devang Patel wrote:

>>> This patch adds support to 1) vectorize conditional
>>> expressions (using vec_cond_optab). 2) It also adds support to check
>>> dependence distance wrt vectorization factor. This work was
>>> presented in two different patches in sept. (along with 4 other
>>> patches but these two missed GCC 4.0 train.). This patches are
>>> used in autovect-branch and apple-ppc-branch since last 6 months.
>>
>> I found one of these, I think,
>>
>>   http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02889.html
>>
>> but not the other, and even the one basically has no commentary
>> on what you're trying to do.
>
> Yes, this message is the last in this thread. The basic idea is  
> simple.
> If dependence distance is more than vectorization factor then it
> does not prevent vectorization. If dependence distance is zero then
> also it does not hurt vectorization.
>
> Another is at
>
>     http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01768.html
>
> and it has some info and pointers to other messages. I included
> dependence vector patch together because now it is very small
> thanks to other changes in vectorizer.
>
>> I definitely want them split back into separate patches.

Here is the patch for distance vector only. I will CC you when
I send separate patch for vector conditions.


2005-04-11  Devang Patel  <dpatel@apple.com>

         * tree-data-ref.c (build_classic_dist_vector,
         compute_subscript_distance): Make externally visible.
         * tree-data-ref.h (build_classic_dist_vector,
         compute_subscript_distance): Same.
         * tree-vect-analyze.c (vect_analyze_data_ref_dependence):
         Check distance vector against vectorization factor.
         (vect_analyze_loop): Determine vectorizaion factor before
         analyzing data dependences.
         * tree-vectorizer.c (loops_num): Make it externally visible and
         rename ...
         * tree-vectorizer.c (vect_loops_num): ... new name.
         * tree-vectorizer.h  (vect_loops_num): New.

         * gcc.dg/vect/vect-dv-1.c: New test.
         * gcc.dg/vect/vect-dv-2.c: New test.

-
Devang


[-- Attachment #2: av-distance-vect.diff --]
[-- Type: application/octet-stream, Size: 13020 bytes --]

Index: tree-data-ref.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.c,v
retrieving revision 2.24
diff -Idpatel.pbxuser -c -3 -p -r2.24 tree-data-ref.c
*** tree-data-ref.c	9 Mar 2005 11:30:36 -0000	2.24
--- tree-data-ref.c	11 Apr 2005 16:33:56 -0000
*************** all_chrecs_equal_p (tree chrec)
*** 646,652 ****
  /* Determine for each subscript in the data dependence relation DDR
     the distance.  */
  
! static void
  compute_subscript_distance (struct data_dependence_relation *ddr)
  {
    if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
--- 646,652 ----
  /* Determine for each subscript in the data dependence relation DDR
     the distance.  */
  
! void
  compute_subscript_distance (struct data_dependence_relation *ddr)
  {
    if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
*************** subscript_dependence_tester (struct data
*** 1769,1775 ****
     starting at FIRST_LOOP_DEPTH. 
     Return TRUE otherwise.  */
  
! static bool
  build_classic_dist_vector (struct data_dependence_relation *ddr, 
  			   int nb_loops, int first_loop_depth)
  {
--- 1769,1775 ----
     starting at FIRST_LOOP_DEPTH. 
     Return TRUE otherwise.  */
  
! bool
  build_classic_dist_vector (struct data_dependence_relation *ddr, 
  			   int nb_loops, int first_loop_depth)
  {
Index: tree-data-ref.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-data-ref.h,v
retrieving revision 2.5
diff -Idpatel.pbxuser -c -3 -p -r2.5 tree-data-ref.h
*** tree-data-ref.h	13 Oct 2004 03:48:03 -0000	2.5
--- tree-data-ref.h	11 Apr 2005 16:33:56 -0000
*************** extern bool array_base_name_differ_p (st
*** 176,181 ****
--- 176,183 ----
  extern void free_dependence_relation (struct data_dependence_relation *);
  extern void free_dependence_relations (varray_type);
  extern void free_data_refs (varray_type);
+ extern void compute_subscript_distance (struct data_dependence_relation *);
+ extern bool build_classic_dist_vector (struct data_dependence_relation *, int, int);
  
  
  \f
Index: tree-vect-analyze.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
retrieving revision 2.14
diff -Idpatel.pbxuser -c -3 -p -r2.14 tree-vect-analyze.c
*** tree-vect-analyze.c	23 Mar 2005 15:52:59 -0000	2.14
--- tree-vect-analyze.c	11 Apr 2005 16:33:56 -0000
*************** vect_analyze_data_ref_dependence (struct
*** 773,778 ****
--- 774,785 ----
  {
    bool differ_p; 
    struct data_dependence_relation *ddr;
+   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;  
+ 
    
    if (!vect_base_addr_differ_p (dra, drb, &differ_p))
      {
*************** vect_analyze_data_ref_dependence (struct
*** 796,802 ****
  
    if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
      return false;
!   
    if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
  			    LOOP_LOC (loop_vinfo)))
      {
--- 803,867 ----
  
    if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
      return false;
! 
!   if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
!     {
!       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
!                                 LOOP_LOC (loop_vinfo)))
!         {
!           fprintf (vect_dump, 
!                    "not vectorized: can't determine dependence 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 true;
!     }
! 
!   /* Find loop depth.  */
!   while (loop_nest)
!     {
!       if (loop_nest->outer && loop_nest->outer->outer)
! 	{
! 	  loop_nest = loop_nest->outer;
! 	  loop_depth++;
! 	}
!       else
! 	break;
!     }
! 
!   /* Compute distance vector.  */
!   compute_subscript_distance (ddr);
!   build_classic_dist_vector (ddr, vect_loops_num, loop_nest->depth);
! 
!   if (!DDR_DIST_VECT (ddr))
!     {
!       if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
! 				LOOP_LOC (loop_vinfo)))
! 	{
! 	  fprintf (vect_dump, "not vectorized: bad dist vector for ");
! 	  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;
!     }
! 
!   dist = DDR_DIST_VECT (ddr)[loop_depth];
! 
!   /* Same loop iteration.  */
!   if (dist == 0)
!     {
!       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
! 	fprintf (vect_dump, "dependence distance 0.");
!       return false;
!     }
! 
!   if (dist >= vectorization_factor)
!     /* Dependence distance does not create dependence, as far as vectorization
!        is concerned, in this case.  */
!     return false;
!     
    if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
  			    LOOP_LOC (loop_vinfo)))
      {
*************** vect_analyze_data_ref_dependence (struct
*** 814,823 ****
  /* Function vect_analyze_data_ref_dependences.
  
     Examine all the data references in the loop, and make sure there do not
!    exist any data dependences between them.
! 
!    TODO: dependences which distance is greater than the vectorization factor
!          can be ignored.  */
  
  static bool
  vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
--- 879,885 ----
  /* Function vect_analyze_data_ref_dependences.
  
     Examine all the data references in the loop, and make sure there do not
!    exist any data dependences between them.  */
  
  static bool
  vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
*************** vect_analyze_loop (struct loop *loop)
*** 2554,2559 ****
--- 2616,2630 ----
        return NULL;
      }
  
+   ok = vect_determine_vectorization_factor (loop_vinfo);
+   if (!ok)
+     {
+       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
+         fprintf (vect_dump, "can't determine vectorization factor.");
+       destroy_loop_vec_info (loop_vinfo);
+       return NULL;
+     }
+ 
    /* Analyze data dependences between the data-refs in the loop. 
       FORNOW: fail at the first data dependence that we encounter.  */
  
*************** vect_analyze_loop (struct loop *loop)
*** 2578,2592 ****
        return NULL;
      }
  
-   ok = vect_determine_vectorization_factor (loop_vinfo);
-   if (!ok)
-     {
-       if (vect_print_dump_info (REPORT_DETAILS, LOOP_LOC (loop_vinfo)))
-         fprintf (vect_dump, "can't determine vectorization factor.");
-       destroy_loop_vec_info (loop_vinfo);
-       return NULL;
-     }
- 
    /* Analyze the alignment of the data-refs in the loop.
       FORNOW: Only aligned accesses are handled.  */
  
--- 2649,2654 ----
Index: tree-vectorizer.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.c,v
retrieving revision 2.80
diff -Idpatel.pbxuser -c -3 -p -r2.80 tree-vectorizer.c
*** tree-vectorizer.c	16 Mar 2005 21:42:55 -0000	2.80
--- tree-vectorizer.c	11 Apr 2005 16:33:56 -0000
*************** FILE *vect_dump;
*** 176,182 ****
     to mark that it's uninitialized.  */
  enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
  
! 
  \f
  /*************************************************************************
    Simple Loop Peeling Utilities
--- 176,183 ----
     to mark that it's uninitialized.  */
  enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
  
! /* Number of loops, at the beginning of vectorization.  */
! unsigned int vect_loops_num;
  \f
  /*************************************************************************
    Simple Loop Peeling Utilities
*************** need_imm_uses_for (tree var)
*** 1554,1560 ****
  void
  vectorize_loops (struct loops *loops)
  {
!   unsigned int i, loops_num;
    unsigned int num_vectorized_loops = 0;
  
    /* Fix the verbosity level if not defined explicitly by the user.  */
--- 1555,1561 ----
  void
  vectorize_loops (struct loops *loops)
  {
!   unsigned int i;
    unsigned int num_vectorized_loops = 0;
  
    /* Fix the verbosity level if not defined explicitly by the user.  */
*************** vectorize_loops (struct loops *loops)
*** 1580,1587 ****
    /* If some loop was duplicated, it gets bigger number 
       than all previously defined loops. This fact allows us to run 
       only over initial loops skipping newly generated ones.  */
!   loops_num = loops->num;
!   for (i = 1; i < loops_num; i++)
      {
        loop_vec_info loop_vinfo;
        struct loop *loop = loops->parray[i];
--- 1581,1588 ----
    /* If some loop was duplicated, it gets bigger number 
       than all previously defined loops. This fact allows us to run 
       only over initial loops skipping newly generated ones.  */
!   vect_loops_num = loops->num;
!   for (i = 1; i < vect_loops_num; i++)
      {
        loop_vec_info loop_vinfo;
        struct loop *loop = loops->parray[i];
*************** vectorize_loops (struct loops *loops)
*** 1606,1612 ****
    /*  ----------- Finalize. -----------  */
  
    free_df ();
!   for (i = 1; i < loops_num; i++)
      {
        struct loop *loop = loops->parray[i];
        loop_vec_info loop_vinfo;
--- 1607,1613 ----
    /*  ----------- Finalize. -----------  */
  
    free_df ();
!   for (i = 1; i < vect_loops_num; i++)
      {
        struct loop *loop = loops->parray[i];
        loop_vec_info loop_vinfo;
Index: tree-vectorizer.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.h,v
retrieving revision 2.16
diff -Idpatel.pbxuser -c -3 -p -r2.16 tree-vectorizer.h
*** tree-vectorizer.h	15 Mar 2005 18:33:00 -0000	2.16
--- tree-vectorizer.h	11 Apr 2005 16:33:56 -0000
*************** known_alignment_for_access_p (struct dat
*** 271,276 ****
--- 272,279 ----
  extern FILE *vect_dump;
  extern enum verbosity_levels vect_verbosity_level;
  
+ /* Number of loops, at the beginning of vectorization.  */
+ extern unsigned int vect_loops_num;
  /*-----------------------------------------------------------------*/
  /* Function prototypes.                                            */
  /*-----------------------------------------------------------------*/
Index: testsuite/gcc.dg/vect/vect-dv-1.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-dv-1.c
diff -N testsuite/gcc.dg/vect/vect-dv-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-dv-1.c	11 Apr 2005 16:33:59 -0000
***************
*** 0 ****
--- 1,22 ----
+ /* Test compiler crash when dependence analyzer can not represent
+    dependence relation by distance vector.  */
+ /* { dg-do compile } */
+ /* { dg-require-effective-target vect_int } */
+ 
+ int x[199];
+ 
+ void foo()
+   
+ {
+   int t,j;
+ 
+   for (j=99;j>0;j--) 
+     x [j+j]=x[j];
+ 
+   for (j=198;j>=100;j--) 
+     if(x[j]) 
+       {
+ 	x[j-63]=x[j-3]-x[j];
+       }
+ }
+ 
Index: testsuite/gcc.dg/vect/vect-dv-2.c
===================================================================
RCS file: testsuite/gcc.dg/vect/vect-dv-2.c
diff -N testsuite/gcc.dg/vect/vect-dv-2.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/vect/vect-dv-2.c	11 Apr 2005 16:33:59 -0000
***************
*** 0 ****
--- 1,73 ----
+ /* { dg-do run } */
+ /* { dg-require-effective-target vect_int } */
+ 
+ #include <stdarg.h>
+ #include <signal.h>
+ 
+ #define N 64
+ #define MAX 42
+ 
+ extern void abort(void); 
+ 
+ int main ()
+ {  
+   int A[N];
+   int B[N];
+   int C[N];
+   int D[N];
+ 
+   int i, j;
+ 
+   for (i = 0; i < N; i++)
+     {
+       A[i] = i;
+       B[i] = i;
+       C[i] = i;
+       D[i] = i;
+     }
+ 
+   /* Vectorizable */
+   for (i = 0; i < 16; i++)
+     {
+       A[i] = A[i+20];
+     }
+ 
+   /* check results:  */
+   for (i = 0; i < 16; i++)
+     {
+       if (A[i] != A[i+20])
+ 	abort ();
+     }
+ 
+   /* Vectorizable */
+   for (i = 0; i < 16; i++)
+     {
+       B[i] = B[i] + 5;
+     }
+ 
+   /* check results:  */
+   for (i = 0; i < 16; i++)
+     {
+       if (B[i] != C[i] + 5)
+ 	abort ();
+     }
+ 
+   /* Not vectorizable */
+   for (i = 0; i < 4; i++)
+     {
+       C[i] = C[i+3];
+     }
+ 
+   /* check results:  */
+   for (i = 0; i < 4; i++)
+     {
+       if (C[i] != D[i+3])
+ 	abort ();
+     }
+ 
+   return 0;
+ }
+ 
+ 
+ 
+ /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */

[-- Attachment #3: Type: text/plain, Size: 1 bytes --]



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-09 22:15   ` Devang Patel
  2005-04-09 23:33     ` Richard Henderson
  2005-04-11 18:10     ` Devang Patel
@ 2005-04-11 18:24     ` Devang Patel
  2005-04-11 19:05       ` Geoffrey Keating
  2 siblings, 1 reply; 10+ messages in thread
From: Devang Patel @ 2005-04-11 18:24 UTC (permalink / raw)
  To: GCC Patches; +Cc: Richard Henderson, Geoff Keating


         * config/rs6000.c (rs6000_emit_vector_select): Fix vector  
select
         operand ordering.


>>
>>> *************** rs6000_emit_vector_select (rtx dest, rtx
>>> *** 10667,10673 ****
>>>
>>>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>>>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
>>> !                                     gen_rtvec (3, op1, op2, mask),
>>>                                       vsel_insn_index));
>>>     emit_insn (t);
>>>     emit_move_insn (dest, temp);
>>> --- 10667,10673 ----
>>>
>>>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>>>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
>>> !                                     gen_rtvec (3, op2, op1, mask),
>>>                                       vsel_insn_index));
>>
>> I don't have enough context to know whether this is correct,
>> but you should pass this separately though an rs6000 maintainer.
>
> OK. It was supplying operands in wrong order to vector select
> instruction. When I posted patch for rs6000_emit_vector_select (),
> test case only checked compilation. Obviously it did not catch the  
> change
> of behavior in vectorized loop because of this bug.

rs6000 maintainers, what do you think?

Thanks,
-
Devang

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-11 18:24     ` Devang Patel
@ 2005-04-11 19:05       ` Geoffrey Keating
  0 siblings, 0 replies; 10+ messages in thread
From: Geoffrey Keating @ 2005-04-11 19:05 UTC (permalink / raw)
  To: Devang Patel; +Cc: GCC Patches, Richard Henderson

[-- Attachment #1: Type: text/plain, Size: 1647 bytes --]


On 11/04/2005, at 11:23 AM, Devang Patel wrote:

>
>         * config/rs6000.c (rs6000_emit_vector_select): Fix vector 
> select
>         operand ordering.
>
>
>>>
>>>> *************** rs6000_emit_vector_select (rtx dest, rtx
>>>> *** 10667,10673 ****
>>>>
>>>>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>>>>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
>>>> !                                     gen_rtvec (3, op1, op2, mask),
>>>>                                       vsel_insn_index));
>>>>     emit_insn (t);
>>>>     emit_move_insn (dest, temp);
>>>> --- 10667,10673 ----
>>>>
>>>>     t = gen_rtx_fmt_ee (SET, VOIDmode, temp,
>>>>                       gen_rtx_fmt_Ei (UNSPEC, dest_mode,
>>>> !                                     gen_rtvec (3, op2, op1, mask),
>>>>                                       vsel_insn_index));
>>>
>>> I don't have enough context to know whether this is correct,
>>> but you should pass this separately though an rs6000 maintainer.
>>
>> OK. It was supplying operands in wrong order to vector select
>> instruction. When I posted patch for rs6000_emit_vector_select (),
>> test case only checked compilation. Obviously it did not catch the 
>> change
>> of behavior in vectorized loop because of this bug.
>
> rs6000 maintainers, what do you think?

I think this code would be much clearer if it was using gen_rtx_SET and 
gen_rtx_UNSPEC, instead of the gen_rtx_fmt_* functions, and if the 
functions involved mentioned in their comments what the actual 
operation to be generated was, rather than just "emit a vector select 
insn... using op1, op2, and mask".

I think the change is correct.

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2408 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] Auto vectorize cond expr (remaining patches)
  2005-04-11 18:10     ` Devang Patel
@ 2005-04-11 19:24       ` Richard Henderson
  0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2005-04-11 19:24 UTC (permalink / raw)
  To: Devang Patel; +Cc: GCC Patches

On Mon, Apr 11, 2005 at 11:10:34AM -0700, Devang Patel wrote:
>         * tree-data-ref.c (build_classic_dist_vector,
>         compute_subscript_distance): Make externally visible.
>         * tree-data-ref.h (build_classic_dist_vector,
>         compute_subscript_distance): Same.
>         * tree-vect-analyze.c (vect_analyze_data_ref_dependence):
>         Check distance vector against vectorization factor.
>         (vect_analyze_loop): Determine vectorizaion factor before
>         analyzing data dependences.
>         * tree-vectorizer.c (loops_num): Make it externally visible and
>         rename ...
>         * tree-vectorizer.c (vect_loops_num): ... new name.
>         * tree-vectorizer.h  (vect_loops_num): New.

Ok.


r~

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2005-04-11 19:24 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-01  0:30 [PATCH] Auto vectorize cond expr (remaining patches) Devang Patel
2005-04-07 17:03 ` Ping: " Devang Patel
2005-04-09  7:02 ` Richard Henderson
2005-04-09 22:15   ` Devang Patel
2005-04-09 23:33     ` Richard Henderson
2005-04-10  1:15       ` Devang Patel
2005-04-11 18:10     ` Devang Patel
2005-04-11 19:24       ` Richard Henderson
2005-04-11 18:24     ` Devang Patel
2005-04-11 19:05       ` Geoffrey Keating

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).