OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-vect-data-refs.c
index 2c92c37..8348287 100644 (file)
@@ -1,5 +1,5 @@
 /* Data References Analysis and Manipulation Utilities for Vectorization.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Dorit Naishlos <dorit@il.ibm.com>
    and Ira Rosen <irar@il.ibm.com>
@@ -1019,7 +1019,7 @@ vect_update_misalignment_for_peel (struct data_reference *dr,
       int misal = DR_MISALIGNMENT (dr);
       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
       misal += negative ? -npeel * dr_size : npeel * dr_size;
-      misal &= GET_MODE_SIZE (TYPE_MODE (vectype)) - 1;
+      misal &= (TYPE_ALIGN (vectype) / BITS_PER_UNIT) - 1;
       SET_DR_MISALIGNMENT (dr, misal);
       return;
     }
@@ -1143,6 +1143,9 @@ vector_alignment_reachable_p (struct data_reference *dr)
       if (ba)
        is_packed = contains_packed_reference (ba);
 
+      if (compare_tree_int (TYPE_SIZE (type), TYPE_ALIGN (type)) > 0)
+       is_packed = true;
+
       if (vect_print_dump_info (REPORT_DETAILS))
        fprintf (vect_dump, "Unknown misalignment, is_packed = %d",is_packed);
       if (targetm.vectorize.vector_alignment_reachable (type, is_packed))
@@ -1490,6 +1493,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
       stmt = DR_STMT (dr);
       stmt_info = vinfo_for_stmt (stmt);
 
+      if (!STMT_VINFO_RELEVANT (stmt_info))
+       continue;
+
       /* For interleaving, only the alignment of the first access
          matters.  */
       if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
@@ -2042,8 +2048,12 @@ vect_analyze_group_access (struct data_reference *dr)
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
   bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
   HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
-  HOST_WIDE_INT stride;
+  HOST_WIDE_INT stride, last_accessed_element = 1;
   bool slp_impossible = false;
+  struct loop *loop = NULL;
+
+  if (loop_vinfo)
+    loop = LOOP_VINFO_LOOP (loop_vinfo);
 
   /* For interleaving, STRIDE is STEP counted in elements, i.e., the size of the
      interleaving group (including gaps).  */
@@ -2071,6 +2081,23 @@ vect_analyze_group_access (struct data_reference *dr)
              fprintf (vect_dump, " step ");
              print_generic_expr (vect_dump, step, TDF_SLIM);
            }
+
+         if (loop_vinfo)
+           {
+             if (vect_print_dump_info (REPORT_DETAILS))
+               fprintf (vect_dump, "Data access with gaps requires scalar "
+                                   "epilogue loop");
+              if (loop->inner)
+                {
+                  if (vect_print_dump_info (REPORT_DETAILS))
+                    fprintf (vect_dump, "Peeling for outer loop is not"
+                                        " supported");
+                  return false;
+                }
+
+              LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true;
+           }
+
          return true;
        }
 
@@ -2136,6 +2163,7 @@ vect_analyze_group_access (struct data_reference *dr)
               next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
               continue;
             }
+
           prev = next;
 
           /* Check that all the accesses have the same STEP.  */
@@ -2166,6 +2194,8 @@ vect_analyze_group_access (struct data_reference *dr)
               gaps += diff - 1;
            }
 
+         last_accessed_element += diff;
+
           /* Store the gap from the previous member of the group. If there is no
              gap in the access, DR_GROUP_GAP is always 1.  */
           DR_GROUP_GAP (vinfo_for_stmt (next)) = diff;
@@ -2257,6 +2287,22 @@ vect_analyze_group_access (struct data_reference *dr)
             VEC_safe_push (gimple, heap, BB_VINFO_STRIDED_STORES (bb_vinfo),
                            stmt);
         }
+
+      /* There is a gap in the end of the group.  */
+      if (stride - last_accessed_element > 0 && loop_vinfo)
+       {
+         if (vect_print_dump_info (REPORT_DETAILS))
+           fprintf (vect_dump, "Data access with gaps requires scalar "
+                               "epilogue loop");
+          if (loop->inner)
+            {
+              if (vect_print_dump_info (REPORT_DETAILS))
+                fprintf (vect_dump, "Peeling for outer loop is not supported");
+              return false;
+            }
+
+          LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) = true;
+       }
     }
 
   return true;
@@ -2487,7 +2533,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
     {
       loop = LOOP_VINFO_LOOP (loop_vinfo);
       res = compute_data_dependences_for_loop
-       (loop, true, &LOOP_VINFO_DATAREFS (loop_vinfo),
+       (loop, true,
+        &LOOP_VINFO_LOOP_NEST (loop_vinfo),
+        &LOOP_VINFO_DATAREFS (loop_vinfo),
         &LOOP_VINFO_DDRS (loop_vinfo));
 
       if (!res)
@@ -2547,14 +2595,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
               print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
             }
 
-          if (bb_vinfo)
-            {
-              /* Mark the statement as not vectorizable.  */
-              STMT_VINFO_VECTORIZABLE (stmt_info) = false;
-              continue;
-            }
-          else
-            return false;
+          return false;
         }
 
       if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST)
@@ -2562,21 +2603,24 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
             fprintf (vect_dump, "not vectorized: base addr of dr is a "
                      "constant");
-          if (bb_vinfo)
+          return false;
+        }
+
+      if (TREE_THIS_VOLATILE (DR_REF (dr)))
+        {
+          if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
             {
-              /* Mark the statement as not vectorizable.  */
-              STMT_VINFO_VECTORIZABLE (stmt_info) = false;
-              continue;
+              fprintf (vect_dump, "not vectorized: volatile type ");
+              print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
             }
-          else
-            return false;
+          return false;
         }
 
       base = unshare_expr (DR_BASE_ADDRESS (dr));
       offset = unshare_expr (DR_OFFSET (dr));
       init = unshare_expr (DR_INIT (dr));
 
-      if (stmt_could_throw_p (stmt))
+      if (stmt_can_throw_internal (stmt))
         {
           if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
             {
@@ -2587,6 +2631,16 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
           return false;
         }
 
+      if (is_gimple_call (stmt))
+       {
+         if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+           {
+             fprintf (vect_dump, "not vectorized: dr in a call ");
+             print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+           }
+         return false;
+       }
+
       /* Update DR field in stmt_vec_info struct.  */
 
       /* If the dataref is in an inner-loop of the loop that is considered for
@@ -2918,7 +2972,14 @@ vect_create_addr_base_for_vector_ref (gimple stmt,
 
   if (DR_PTR_INFO (dr)
       && TREE_CODE (vec_stmt) == SSA_NAME)
-    duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr));
+    {
+      duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr));
+      if (offset)
+       {
+         SSA_NAME_PTR_INFO (vec_stmt)->align = 1;
+         SSA_NAME_PTR_INFO (vec_stmt)->misalign = 0;
+       }
+    }
 
   if (vect_print_dump_info (REPORT_DETAILS))
     {
@@ -3308,7 +3369,11 @@ bump_vector_ptr (tree dataref_ptr, gimple ptr_incr, gimple_stmt_iterator *gsi,
 
   /* Copy the points-to information if it exists. */
   if (DR_PTR_INFO (dr))
-    duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
+    {
+      duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
+      SSA_NAME_PTR_INFO (new_dataref_ptr)->align = 1;
+      SSA_NAME_PTR_INFO (new_dataref_ptr)->misalign = 0;
+    }
 
   if (!ptr_incr)
     return new_dataref_ptr;