optabs.h (OTI_movmisalign, [...]): New.
authorRichard Henderson <rth@redhat.com>
Thu, 23 Dec 2004 07:58:41 +0000 (23:58 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 23 Dec 2004 07:58:41 +0000 (23:58 -0800)
        * optabs.h (OTI_movmisalign, movmisalign_optab): New.
        * optabs.c (init_optabs): Create it.
        * genopinit.c (optabs): Initialize it.
        * expr.c (expand_expr_real_1) <MISALIGNED_INDIRECT_REF>: Use it.
        * tree-vectorizer.c (vect_supportable_dr_alignment): Likewise.
        * target-def.h (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.
        * target.h (vectorize.misaligned_mem_ok): Remove.
        * targhooks.c (default_vect_misaligned_mem_ok): Remove.
        * doc/md.texi (movmisalign): New.
        * doc/tm.texi (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.

From-SVN: r92537

gcc/ChangeLog
gcc/doc/md.texi
gcc/doc/tm.texi
gcc/expr.c
gcc/genopinit.c
gcc/optabs.c
gcc/optabs.h
gcc/target-def.h
gcc/target.h
gcc/targhooks.c
gcc/tree-vectorizer.c

index fe3acf1ae49a4babc0597b72303325417f08130a..0d959dccedbde2b7efd29a65364af7317a5fa8d3 100644 (file)
@@ -1,3 +1,16 @@
+2004-12-22  Richard Henderson  <rth@redhat.com>
+
+       * optabs.h (OTI_movmisalign, movmisalign_optab): New.
+       * optabs.c (init_optabs): Create it.
+       * genopinit.c (optabs): Initialize it.
+       * expr.c (expand_expr_real_1) <MISALIGNED_INDIRECT_REF>: Use it.
+       * tree-vectorizer.c (vect_supportable_dr_alignment): Likewise.
+       * target-def.h (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.
+       * target.h (vectorize.misaligned_mem_ok): Remove.
+       * targhooks.c (default_vect_misaligned_mem_ok): Remove.
+       * doc/md.texi (movmisalign): New.
+       * doc/tm.texi (TARGET_VECTORIZE_MISALIGNED_MEM_OK): Remove.
+
 2004-12-22  Richard Henderson  <rth@redhat.com>
 
        * config/i386/emmintrin.h (_mm_loadh_pd): Don't cast pointer arg
index 36c73a193923049f317a8ad80eb8a12cb73932f8..2c41bc41c598d101e4bc3633f5ab4224e6fed1f3 100644 (file)
@@ -2758,6 +2758,17 @@ with mode @var{m} of a register whose natural mode is wider,
 the @samp{movstrict@var{m}} instruction is guaranteed not to alter
 any of the register except the part which belongs to mode @var{m}.
 
+@cindex @code{movmisalign@var{m}} instruction pattern
+@item @samp{movmisalign@var{m}}
+This variant of a move pattern is designed to load or store a value
+from a memory address that is not naturally aligned for its mode.
+For a store, the memory will be in operand 0; for a load, the memory
+will be in operand 1.  The other operand is guaranteed not to be a
+memory, so that it's easy to tell whether this is a load or store.
+
+This pattern is used by the autovectorizer, and when expanding a
+@code{MISALIGNED_INDIRECT_REF} expression.
+
 @cindex @code{load_multiple} instruction pattern
 @item @samp{load_multiple}
 Load several consecutive memory locations into consecutive registers.
index e33844237b4535c9e1f6b7dc36082e49ecb83061..fb45a6c8ea3d6b8d29094222a2fedfb72869c039 100644 (file)
@@ -5184,16 +5184,6 @@ holding the constant.  This restriction is often true of addresses
 of TLS symbols for various targets.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_VECTORIZE_MISALIGNED_MEM_OK (@var{mode})
-This hook should return true if a move* pattern to/from memory
-can be generated for machine_mode @var{mode} even if the memory location 
-is unaligned.
-If a move* of data to/from unaligned memory locations is not supported for
-machine_mode @var{mode}, the hook should return false.  
-This hook is used by the autovectorizer, and when expanding a 
-@code{MISALIGNED_INDIRECT_REF} expression.
-@end deftypefn
-
 @deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD (void)
 This hook should return the DECL of a function @var{f} that given an
 address @var{addr} as an argument returns a mask @var{m} that can be
index 3a09222943e6246b7c9c1c83319ddb3d9792ded4..d69a8dff07e7f51ef2b3509055ee5dad440fac24 100644 (file)
@@ -6697,10 +6697,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        tree exp1 = TREE_OPERAND (exp, 0);
        tree orig;
 
-       if (code == MISALIGNED_INDIRECT_REF
-           && !targetm.vectorize.misaligned_mem_ok (mode))
-         abort ();
-
        if (modifier != EXPAND_WRITE)
          {
            tree t;
@@ -6727,6 +6723,33 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
          orig = exp;
        set_mem_attributes (temp, orig, 0);
 
+       /* Resolve the misalignment now, so that we don't have to remember
+          to resolve it later.  Of course, this only works for reads.  */
+       /* ??? When we get around to supporting writes, we'll have to handle
+          this in store_expr directly.  The vectorizer isn't generating
+          those yet, however.  */
+       if (code == MISALIGNED_INDIRECT_REF)
+         {
+           int icode;
+           rtx reg, insn;
+
+           gcc_assert (modifier == EXPAND_NORMAL);
+
+           /* The vectorizer should have already checked the mode.  */
+           icode = movmisalign_optab->handlers[mode].insn_code;
+           gcc_assert (icode != CODE_FOR_nothing);
+
+           /* We've already validated the memory, and we're creating a
+              new pseudo destination.  The predicates really can't fail.  */
+           reg = gen_reg_rtx (mode);
+
+           /* Nor can the insn generator.  */
+           insn = GEN_FCN (icode) (reg, temp);
+           emit_insn (insn);
+
+           return reg;
+         }
+
        return temp;
       }
 
index 494a4821cc0d9efce23c6934c5c1755fcbc9d7e6..72593a62ede94992ba9daa95c0cf8d6055945008 100644 (file)
@@ -151,6 +151,7 @@ static const char * const optabs[] =
   "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
   "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
   "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
+  "movmisalign_optab->handlers[$A].insn_code = CODE_FOR_$(movmisalign$a$)",
   "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
   "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
   "addcc_optab->handlers[$A].insn_code = CODE_FOR_$(add$acc$)",
index 7c5c6aa71dd6f47f0e3f3aa4e0c9313158f5fa11..e18b42bf75fe14c89750ac9ec947b4c533211b15 100644 (file)
@@ -4786,6 +4786,7 @@ init_optabs (void)
   vec_set_optab = init_optab (UNKNOWN);
   vec_init_optab = init_optab (UNKNOWN);
   vec_realign_load_optab = init_optab (UNKNOWN);
+  movmisalign_optab = init_optab (UNKNOWN);
 
   /* Conversions.  */
   sext_optab = init_convert_optab (SIGN_EXTEND);
index 241abfdb5a56f29d8020bd3d8f20e73f4af384a4..a5942da7cd679c89c1f100d7f021b252bce5aaa6 100644 (file)
@@ -133,6 +133,8 @@ enum optab_index
   OTI_mov,
   /* Move, preserving high part of register.  */
   OTI_movstrict,
+  /* Move, with a misaligned memory.  */
+  OTI_movmisalign,
 
   /* Unary operations */
   /* Negation */
@@ -273,6 +275,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 
 #define mov_optab (optab_table[OTI_mov])
 #define movstrict_optab (optab_table[OTI_movstrict])
+#define movmisalign_optab (optab_table[OTI_movmisalign])
 
 #define neg_optab (optab_table[OTI_neg])
 #define negv_optab (optab_table[OTI_negv])
index ac00556397881afb55ad23314aecac12666eb10c..75c949e9e2973bd81c7d193ed5a913ae2b46ade4 100644 (file)
@@ -273,14 +273,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    TARGET_SCHED_DFA_NEW_CYCLE,                                 \
    TARGET_SCHED_IS_COSTLY_DEPENDENCE}
 
-#ifndef TARGET_VECTORIZE_MISALIGNED_MEM_OK
-#define TARGET_VECTORIZE_MISALIGNED_MEM_OK default_vect_misaligned_mem_ok
-#endif
 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD 0
 
 #define TARGET_VECTORIZE                                                \
-  {TARGET_VECTORIZE_MISALIGNED_MEM_OK,                                  \
-   TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD}
+  {TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD}
 
 /* In except.c */
 #define TARGET_EH_RETURN_FILTER_MODE  default_eh_return_filter_mode
index aa3542c476d60f34b8c7212cadbf4d12e0bed433..4f4b49ebb51265bb9c48ce1c9eea81192880e978 100644 (file)
@@ -285,13 +285,6 @@ struct gcc_target
   /* Functions relating to vectorization.  */
   struct vectorize
   {
-    /* The following member value is a pointer to a function called
-       by te vectorizer, and when expanding a MISALIGNED_INDIRECT_REF
-       expression.  If the hook returns true (false) then a move* pattern
-       to/from memory can (cannot) be generated for this mode even if the
-       memory location is unaligned.  */
-    bool (* misaligned_mem_ok) (enum machine_mode);
-
     /* The following member value is a pointer to a function called
        by the vectorizer, and return the decl of the target builtin
        function.  */
index 852421cb9e33996ab482731812b8fe448bafa3e8..dbb59cf9b46dcfb89e7bb62e09a6b767d763f9d0 100644 (file)
@@ -262,12 +262,6 @@ default_scalar_mode_supported_p (enum machine_mode mode)
     }
 }
 
-bool
-default_vect_misaligned_mem_ok (enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return !STRICT_ALIGNMENT;
-}
-
 bool
 hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
        CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
index c591d48825c3ca37d2e33c06fd973624f0f53b37..9a7ee12d3fc822e515a88e02613c4b77b46d8e24 100644 (file)
@@ -2704,8 +2704,8 @@ vect_supportable_dr_alignment (struct data_reference *dr)
              || targetm.vectorize.builtin_mask_for_load ()))
        return dr_unaligned_software_pipeline;
 
-      if (targetm.vectorize.misaligned_mem_ok (mode))
-       /* Can't software pipeline the loads.  */
+      if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
+       /* Can't software pipeline the loads, but can at least do them.  */
        return dr_unaligned_supported;
     }