From 0fcc85cd9e285522f9896a88e1374e0cc2454b4f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 29 Jun 2012 09:18:15 -0700 Subject: [PATCH] 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. From-SVN: r189081 --- gcc/ChangeLog | 6 ++++ gcc/Makefile.in | 2 +- gcc/tree-vect-generic.c | 94 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 76 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a1c4cc..32e8ce2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-06-29 Richard Henderson + + * 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 * configure.ac: Remove special gtfiles case for C. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index afea4f3..9955fd7 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 c83db5e..89d8bae 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, -- 2.7.4