optabs.h (OTI_movmisalign, [...]): New.

* 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
This commit is contained in:
Richard Henderson 2004-12-22 23:58:41 -08:00 committed by Richard Henderson
parent 1c47af84a3
commit 1e0598e25c
11 changed files with 59 additions and 34 deletions

View 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

View 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.

View 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

View 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;
}

View 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$)",

View 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);

View 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])

View 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

View 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. */

View 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,

View 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;
}