diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-29 16:18:15 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-29 16:18:15 +0000 |
commit | 10dd7335fa297d10c08d7ec9ec8440018e91461b (patch) | |
tree | a60d1f6cd77109afc8f7c41317d57566f8f0922a | |
parent | e53d55e7b556f38b546938e3a16cf2f8ed1e27d8 (diff) | |
download | gcc-10dd7335fa297d10c08d7ec9ec8440018e91461b.tar.gz |
Use builtin_widen_mult_even/odd in tree-vect-generic division expansion
* tree-vect-generic.c: Include target.h.
(expand_vector_divmod): Use builtin_mul_widen_even/odd if supported.
* Makefile.in (tree-vect-generic.o): Update.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189081 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/tree-vect-generic.c | 94 |
3 files changed, 76 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a1c4cc9b84..32e8ce2515b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-06-29 Richard Henderson <rth@redhat.com> + + * tree-vect-generic.c: Include target.h. + (expand_vector_divmod): Use builtin_mul_widen_even/odd if supported. + * Makefile.in (tree-vect-generic.o): Update. + 2012-06-29 Steven Bosscher <steven@gcc.gnu.org> * configure.ac: Remove special gtfiles case for C. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index afea4f38622..9955fd79fef 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -3036,7 +3036,7 @@ tree-vect-generic.o : tree-vect-generic.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ $(TM_H) $(TREE_FLOW_H) $(GIMPLE_H) tree-iterator.h $(TREE_PASS_H) \ $(FLAGS_H) $(OPTABS_H) $(MACHMODE_H) $(EXPR_H) \ langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-vect-generic.h $(GGC_H) \ - coretypes.h insn-codes.h $(DIAGNOSTIC_H) + coretypes.h insn-codes.h $(DIAGNOSTIC_H) $(TARGET_H) df-core.o : df-core.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \ hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \ diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index c83db5e1e30..89d8bae99c7 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "ggc.h" #include "diagnostic.h" +#include "target.h" /* Need to include rtl.h, expr.h, etc. for optabs. */ #include "expr.h" @@ -456,7 +457,7 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0, optab op; tree *vec; unsigned char *sel = NULL; - tree cur_op, mhi, mlo, mulcst, perm_mask, wider_type, tem; + tree cur_op, mhi, mlo, mulcst, perm_mask, wider_type, tem, decl_e, decl_o; if (prec > HOST_BITS_PER_WIDE_INT) return NULL_TREE; @@ -745,32 +746,52 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0, return NULL_TREE; op = optab_for_tree_code (MULT_HIGHPART_EXPR, type, optab_default); - if (op != NULL - && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing) - wider_type = NULL_TREE; + if (op != NULL && optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing) + wider_type = decl_e = decl_o = NULL_TREE; else { - op = optab_for_tree_code (VEC_WIDEN_MULT_LO_EXPR, type, optab_default); - if (op == NULL - || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing) - return NULL_TREE; - op = optab_for_tree_code (VEC_WIDEN_MULT_HI_EXPR, type, optab_default); - if (op == NULL - || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing) - return NULL_TREE; - sel = XALLOCAVEC (unsigned char, nunits); - for (i = 0; i < nunits; i++) - sel[i] = 2 * i + (BYTES_BIG_ENDIAN ? 0 : 1); - if (!can_vec_perm_p (TYPE_MODE (type), false, sel)) - return NULL_TREE; - wider_type - = build_vector_type (build_nonstandard_integer_type (prec * 2, - unsignedp), - nunits / 2); + wider_type = build_nonstandard_integer_type (prec * 2, unsignedp), + wider_type = build_vector_type (wider_type, nunits / 2); if (GET_MODE_CLASS (TYPE_MODE (wider_type)) != MODE_VECTOR_INT || GET_MODE_BITSIZE (TYPE_MODE (wider_type)) != GET_MODE_BITSIZE (TYPE_MODE (type))) return NULL_TREE; + + sel = XALLOCAVEC (unsigned char, nunits); + + if (targetm.vectorize.builtin_mul_widen_even + && targetm.vectorize.builtin_mul_widen_odd + && (decl_e = targetm.vectorize.builtin_mul_widen_even (type)) + && (decl_o = targetm.vectorize.builtin_mul_widen_odd (type)) + && (TYPE_MODE (TREE_TYPE (TREE_TYPE (decl_e))) + == TYPE_MODE (wider_type))) + { + for (i = 0; i < nunits; i++) + sel[i] = !BYTES_BIG_ENDIAN + (i & ~1) + ((i & 1) ? nunits : 0); + if (!can_vec_perm_p (TYPE_MODE (wider_type), false, sel)) + decl_e = decl_o = NULL_TREE; + } + else + decl_e = decl_o = NULL_TREE; + + if (decl_e == NULL_TREE) + { + op = optab_for_tree_code (VEC_WIDEN_MULT_LO_EXPR, + type, optab_default); + if (op == NULL + || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing) + return NULL_TREE; + op = optab_for_tree_code (VEC_WIDEN_MULT_HI_EXPR, + type, optab_default); + if (op == NULL + || optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing) + return NULL_TREE; + + for (i = 0; i < nunits; i++) + sel[i] = 2 * i + (BYTES_BIG_ENDIAN ? 0 : 1); + if (!can_vec_perm_p (TYPE_MODE (type), false, sel)) + return NULL_TREE; + } } cur_op = op0; @@ -816,11 +837,34 @@ expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0, for (i = 0; i < nunits; i++) vec[i] = build_int_cst (TREE_TYPE (type), sel[i]); perm_mask = build_vector (type, vec); - mhi = gimplify_build2 (gsi, VEC_WIDEN_MULT_HI_EXPR, wider_type, - cur_op, mulcst); + + if (decl_e != NULL_TREE) + { + gimple call; + + call = gimple_build_call (decl_e, 2, cur_op, mulcst); + mhi = create_tmp_reg (wider_type, NULL); + add_referenced_var (mhi); + mhi = make_ssa_name (mhi, call); + gimple_call_set_lhs (call, mhi); + gsi_insert_seq_before (gsi, call, GSI_SAME_STMT); + + call = gimple_build_call (decl_o, 2, cur_op, mulcst); + mlo = create_tmp_reg (wider_type, NULL); + add_referenced_var (mlo); + mlo = make_ssa_name (mlo, call); + gimple_call_set_lhs (call, mlo); + gsi_insert_seq_before (gsi, call, GSI_SAME_STMT); + } + else + { + mhi = gimplify_build2 (gsi, VEC_WIDEN_MULT_HI_EXPR, wider_type, + cur_op, mulcst); + mlo = gimplify_build2 (gsi, VEC_WIDEN_MULT_LO_EXPR, wider_type, + cur_op, mulcst); + } + mhi = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, mhi); - mlo = gimplify_build2 (gsi, VEC_WIDEN_MULT_LO_EXPR, wider_type, - cur_op, mulcst); mlo = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, mlo); if (BYTES_BIG_ENDIAN) cur_op = gimplify_build3 (gsi, VEC_PERM_EXPR, type, mhi, mlo, |