New function for checking misalignment
authorrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 15 Sep 2009 10:39:13 +0000 (10:39 +0000)
committerrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 15 Sep 2009 10:39:13 +0000 (10:39 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151715 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/doc/tm.texi
gcc/target-def.h
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h
gcc/tree-vect-data-refs.c

index 1b36f26..e64ec0f 100644 (file)
@@ -1,3 +1,20 @@
+2009-09-15  Revital Eres  <eres@il.ibm.com>
+
+       * doc/tm.texi (TARGET_SUPPORT_VECTOR_MISALIGNMENT): Document.
+       * targhooks.c (default_builtin_support_vector_misalignment):
+       New builtin function.
+       * targhooks.h (default_builtin_support_vector_misalignment):
+       Declare.
+       * target.h (builtin_support_vector_misalignment):
+       New field in struct gcc_target.
+       * tree-vect-data-refs.c (vect_supportable_dr_alignment): Call
+       new builtin function.
+       * target-def.h (TARGET_SUPPORT_VECTOR_MISALIGNMENT):
+       Define.
+       * config/rs6000/rs6000.c
+       (rs6000_builtin_support_vector_misalignment): New function.
+       (TARGET_SUPPORT_VECTOR_MISALIGNMENT): Define.
+
 2009-09-15  Jie Zhang  <jie.zhang@analog.com>
 
        * config/bfin/bfin.c (length_for_loop): Use NONDEBUG_INSN_P
index f796c08..932a7e3 100644 (file)
@@ -919,6 +919,10 @@ static tree rs6000_builtin_mul_widen_even (tree);
 static tree rs6000_builtin_mul_widen_odd (tree);
 static tree rs6000_builtin_conversion (unsigned int, tree);
 static tree rs6000_builtin_vec_perm (tree, tree *);
+static bool rs6000_builtin_support_vector_misalignment (enum
+                                                       machine_mode,
+                                                       const_tree,
+                                                       int, bool);
 
 static void def_builtin (int, const char *, tree, int);
 static bool rs6000_vector_alignment_reachable (const_tree, bool);
@@ -1300,7 +1304,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
-
+#undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
+#define TARGET_SUPPORT_VECTOR_MISALIGNMENT             \
+  rs6000_builtin_support_vector_misalignment
 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
 
@@ -2895,6 +2901,36 @@ rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_pac
     }
 }
 
+/* Return true if the vector misalignment factor is supported by the
+   target.  */ 
+bool
+rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
+                                           const_tree type,
+                                           int misalignment,
+                                           bool is_packed)
+{
+  if (TARGET_VSX)
+    {
+      /* Return if movmisalign pattern is not supported for this mode.  */
+      if (optab_handler (movmisalign_optab, mode)->insn_code ==
+          CODE_FOR_nothing)
+        return false;
+
+      if (misalignment == -1)
+       {
+         /* misalignment factor is unknown at compile time but we know
+            it's word aligned.  */
+         if (rs6000_vector_alignment_reachable (type, is_packed))
+           return true;
+         return false;
+       }
+      /* VSX supports word-aligned vector.  */
+      if (misalignment % 4 == 0)
+       return true;
+    }
+  return false;
+}
+
 /* Implement targetm.vectorize.builtin_vec_perm.  */
 tree
 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
index f236a7d..0139a8b 100644 (file)
@@ -5679,6 +5679,14 @@ the vectorized function shall be of vector type @var{vec_type_out} and the
 argument types should be @var{vec_type_in}.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_SUPPORT_VECTOR_MISALIGNMENT (enum machine_mode @var{mode}, tree @var{type}, int @var{misalignment}, bool @var{is_packed})
+This hook should return true if the target supports misaligned vector
+store/load of a specific factor denoted in the @var{misalignment}
+parameter.  The vector store/load should be of machine mode @var{mode} and
+the elements in the vectors should be of type @var{type}.  @var{is_packed}
+parameter is true if the memory access is defined in a packed struct.
+@end deftypefn
+
 @node Anchored Addresses
 @section Anchored Addresses
 @cindex anchored addresses
index 286e1e6..728e018 100644 (file)
 #define TARGET_VECTOR_ALIGNMENT_REACHABLE \
   default_builtin_vector_alignment_reachable
 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM 0
+#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
+  default_builtin_support_vector_misalignment 
+   
 
 #define TARGET_VECTORIZE                                                \
   {                                                                    \
     TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD,                            \
     TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST,                       \
     TARGET_VECTOR_ALIGNMENT_REACHABLE,                                  \
-    TARGET_VECTORIZE_BUILTIN_VEC_PERM                                   \
+    TARGET_VECTORIZE_BUILTIN_VEC_PERM,                                 \
+    TARGET_SUPPORT_VECTOR_MISALIGNMENT                         \
   }
 
 #define TARGET_DEFAULT_TARGET_FLAGS 0
index 7f7f177..c57b683 100644 (file)
@@ -481,6 +481,11 @@ struct gcc_target
 
     /* Target builtin that implements vector permute.  */
     tree (* builtin_vec_perm) (tree, tree*);
+    /* Return true if the target supports misaligned store/load of a
+       specific factor denoted in the third parameter.  The last parameter
+       is true if the access is defined in a packed struct.  */
+    bool (* builtin_support_vector_misalignment) (enum machine_mode, 
+                                                  const_tree, int, bool);
   } vectorize;
 
   /* The initial value of target_flags.  */
index 7535bc1..8480c0b 100644 (file)
@@ -771,6 +771,23 @@ default_builtin_vector_alignment_reachable (const_tree type, bool is_packed)
   return true;
 }
 
+/* By default, assume that a target supports any factor of misalignment
+   memory access if it supports movmisalign patten. 
+   is_packed is true if the memory access is defined in a packed struct.  */
+bool
+default_builtin_support_vector_misalignment (enum machine_mode mode,
+                                            const_tree type
+                                            ATTRIBUTE_UNUSED,
+                                            int misalignment
+                                            ATTRIBUTE_UNUSED,
+                                            bool is_packed
+                                            ATTRIBUTE_UNUSED)
+{
+  if (optab_handler (movmisalign_optab, mode)->insn_code != CODE_FOR_nothing)
+    return true;
+  return false;
+}
+
 bool
 default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
 {
index 4e5f631..7a93552 100644 (file)
@@ -77,6 +77,10 @@ extern tree default_builtin_vectorized_conversion (unsigned int, tree);
 extern tree default_builtin_reciprocal (unsigned int, bool, bool);
 
 extern bool default_builtin_vector_alignment_reachable (const_tree, bool);
+extern bool
+default_builtin_support_vector_misalignment (enum machine_mode mode,
+                                            const_tree,
+                                            int, bool); 
 
 /* These are here, and not in hooks.[ch], because not all users of
    hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS.  */
index facde06..bc18f02 100644 (file)
@@ -3455,6 +3455,9 @@ vect_supportable_dr_alignment (struct data_reference *dr)
 
   if (DR_IS_READ (dr))
     {
+      bool is_packed = false;
+      tree type = (TREE_TYPE (DR_REF (dr)));
+
       if (optab_handler (vec_realign_load_optab, mode)->insn_code != 
                                                             CODE_FOR_nothing
          && (!targetm.vectorize.builtin_mask_for_load
@@ -3468,18 +3471,39 @@ vect_supportable_dr_alignment (struct data_reference *dr)
          else
            return dr_explicit_realign_optimized;
        }
-
-      if (optab_handler (movmisalign_optab, mode)->insn_code != 
-                                                            CODE_FOR_nothing)
+      if (!known_alignment_for_access_p (dr))
+       {
+         tree ba = DR_BASE_OBJECT (dr);
+         
+         if (ba)
+           is_packed = contains_packed_reference (ba);
+       }
+     
+      if (targetm.vectorize.
+         builtin_support_vector_misalignment (mode, type,
+                                              DR_MISALIGNMENT (dr), is_packed))
        /* Can't software pipeline the loads, but can at least do them.  */
        return dr_unaligned_supported;
     }
-   else
-     {
-       if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
-         return dr_unaligned_supported;
-     }
+  else
+    {
+      bool is_packed = false;
+      tree type = (TREE_TYPE (DR_REF (dr)));
 
+      if (!known_alignment_for_access_p (dr))
+       {
+         tree ba = DR_BASE_OBJECT (dr);
+         
+         if (ba)
+           is_packed = contains_packed_reference (ba);
+       }
+     
+     if (targetm.vectorize.
+         builtin_support_vector_misalignment (mode, type, 
+                                             DR_MISALIGNMENT (dr), is_packed))
+       return dr_unaligned_supported;
+    }
+  
   /* Unsupported.  */
   return dr_unaligned_unsupported;
 }