This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [vec-cmp, patch 4/6] Support vector mask invariants


On Thu, Oct 8, 2015 at 5:11 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote:
> Hi,
>
> This patch adds a special handling of boolean vector invariants.  We need additional code to determine type of generated invariant.  For VEC_COND_EXPR case we even provide this type directly because statement vectype doesn't allow us to compute it.  Separate code is used to generate and expand such vectors.
>
> Thanks,
> Ilya
> --
> gcc/
>
> 2015-10-08  Ilya Enkovich  <enkovich.gnu@gmail.com>
>
>         * expr.c (const_vector_mask_from_tree): New.
>         (const_vector_from_tree): Use const_vector_mask_from_tree
>         for boolean vectors.
>         * tree-vect-stmts.c (vect_init_vector): Support boolean vector
>         invariants.
>         (vect_get_vec_def_for_operand): Add VECTYPE arg.
>         (vectorizable_condition): Directly provide vectype for invariants
>         used in comparison.
>         * tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE
>         arg.
>
>
> diff --git a/gcc/expr.c b/gcc/expr.c
> index 88da8cb..a624a34 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -11320,6 +11320,40 @@ try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
>    return 1;
>  }
>
> +/* Return a CONST_VECTOR rtx representing vector mask for
> +   a VECTOR_CST of booleans.  */
> +static rtx
> +const_vector_mask_from_tree (tree exp)
> +{
> +  rtvec v;
> +  unsigned i;
> +  int units;
> +  tree elt;
> +  machine_mode inner, mode;
> +
> +  mode = TYPE_MODE (TREE_TYPE (exp));
> +  units = GET_MODE_NUNITS (mode);
> +  inner = GET_MODE_INNER (mode);
> +
> +  v = rtvec_alloc (units);
> +
> +  for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
> +    {
> +      elt = VECTOR_CST_ELT (exp, i);
> +
> +      gcc_assert (TREE_CODE (elt) == INTEGER_CST);
> +      if (integer_zerop (elt))
> +       RTVEC_ELT (v, i) = CONST0_RTX (inner);
> +      else if (integer_onep (elt)
> +              || integer_minus_onep (elt))
> +       RTVEC_ELT (v, i) = CONSTM1_RTX (inner);
> +      else
> +       gcc_unreachable ();
> +    }
> +
> +  return gen_rtx_CONST_VECTOR (mode, v);
> +}
> +
>  /* Return a CONST_VECTOR rtx for a VECTOR_CST tree.  */
>  static rtx
>  const_vector_from_tree (tree exp)
> @@ -11335,6 +11369,9 @@ const_vector_from_tree (tree exp)
>    if (initializer_zerop (exp))
>      return CONST0_RTX (mode);
>
> +  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
> +      return const_vector_mask_from_tree (exp);
> +
>    units = GET_MODE_NUNITS (mode);
>    inner = GET_MODE_INNER (mode);
>
> diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
> index 6949c71..337ea7b 100644
> --- a/gcc/tree-vect-stmts.c
> +++ b/gcc/tree-vect-stmts.c
> @@ -1308,27 +1308,61 @@ vect_init_vector_1 (gimple *stmt, gimple *new_stmt, gimple_stmt_iterator *gsi)
>  tree
>  vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator *gsi)
>  {
> +  tree val_type = TREE_TYPE (val);
> +  machine_mode mode = TYPE_MODE (type);
> +  machine_mode val_mode = TYPE_MODE(val_type);
>    tree new_var;
>    gimple *init_stmt;
>    tree vec_oprnd;
>    tree new_temp;
>
>    if (TREE_CODE (type) == VECTOR_TYPE
> -      && TREE_CODE (TREE_TYPE (val)) != VECTOR_TYPE)
> -    {
> -      if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val)))
> +      && TREE_CODE (val_type) != VECTOR_TYPE)
> +    {
> +      /* Handle vector of bool represented as a vector of
> +        integers here rather than on expand because it is
> +        a default mask type for targets.  Vector mask is
> +        built in a following way:
> +
> +        tmp = (int)val
> +        vec_tmp = {tmp, ..., tmp}
> +        vec_cst = VIEW_CONVERT_EXPR<vector(N) _Bool>(vec_tmp);  */
> +      if (TREE_CODE (val_type) == BOOLEAN_TYPE
> +         && VECTOR_MODE_P (mode)
> +         && SCALAR_INT_MODE_P (GET_MODE_INNER (mode))
> +         && GET_MODE_INNER (mode) != val_mode)
>         {
> -         if (CONSTANT_CLASS_P (val))
> -           val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
> -         else
> +         unsigned size = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
> +         tree stype = build_nonstandard_integer_type (size, 1);
> +         tree vectype = get_vectype_for_scalar_type (stype);
> +
> +         new_temp = make_ssa_name (stype);
> +         init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
> +         vect_init_vector_1 (stmt, init_stmt, gsi);
> +
> +         val = make_ssa_name (vectype);
> +         new_temp = build_vector_from_val (vectype, new_temp);
> +         init_stmt = gimple_build_assign (val, new_temp);
> +         vect_init_vector_1 (stmt, init_stmt, gsi);
> +
> +         val = build1 (VIEW_CONVERT_EXPR, type, val);

So I don't quite understand - why don't we want to build

   tmp = (bool-element-type)val;
   vec_cst = {tmp, tmp, tmp ... };

?

> +       }
> +      else
> +       {
> +         if (!types_compatible_p (TREE_TYPE (type), val_type))
>             {
> -             new_temp = make_ssa_name (TREE_TYPE (type));
> -             init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
> -             vect_init_vector_1 (stmt, init_stmt, gsi);
> -             val = new_temp;
> +             if (CONSTANT_CLASS_P (val))
> +               val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val);
> +             else
> +               {
> +                 new_temp = make_ssa_name (TREE_TYPE (type));
> +                 init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val);
> +                 vect_init_vector_1 (stmt, init_stmt, gsi);
> +                 val = new_temp;
> +               }
>             }
> +         val = build_vector_from_val (type, val);
>         }
> -      val = build_vector_from_val (type, val);
>      }
>
>    new_var = vect_get_new_vect_var (type, vect_simple_var, "cst_");
> @@ -1350,16 +1384,19 @@ vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator *gsi)
>     STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
>
>     In case OP is an invariant or constant, a new stmt that creates a vector def
> -   needs to be introduced.  */
> +   needs to be introduced.  VECTYPE may be used to specify a required type for
> +   vector invariant.  */
>
>  tree
> -vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def)
> +vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def,
> +                             tree vectype)
>  {
>    tree vec_oprnd;
>    gimple *vec_stmt;
>    gimple *def_stmt;
>    stmt_vec_info def_stmt_info = NULL;
>    stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
> +  tree stmt_vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
>    unsigned int nunits;
>    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
>    tree def;
> @@ -1403,7 +1440,14 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def)
>      /* Case 1: operand is a constant.  */
>      case vect_constant_def:
>        {
> -       vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
> +       if (vectype)
> +         vector_type = vectype;
> +       else if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
> +                && VECTOR_BOOLEAN_TYPE_P (stmt_vectype))
> +         vector_type = build_same_sized_truth_vector_type (stmt_vectype);
> +       else
> +         vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));

Rather than this...

> +
>         gcc_assert (vector_type);
>         nunits = TYPE_VECTOR_SUBPARTS (vector_type);
>
> @@ -1421,7 +1465,13 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def)
>      /* Case 2: operand is defined outside the loop - loop invariant.  */
>      case vect_external_def:
>        {
> -       vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
> +       if (vectype)
> +         vector_type = vectype;
> +       else if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE
> +                && VECTOR_BOOLEAN_TYPE_P (stmt_vectype))
> +         vector_type = build_same_sized_truth_vector_type (stmt_vectype);
> +       else
> +         vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
>         gcc_assert (vector_type);

and this ...

>         if (scalar_def)
> @@ -7437,13 +7487,13 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi,
>               gimple *gtemp;
>               vec_cond_lhs =
>               vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0),
> -                                           stmt, NULL);
> +                                           stmt, NULL, comp_vectype);
>               vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt,
>                                   loop_vinfo, NULL, &gtemp, &def, &dts[0]);
>
>               vec_cond_rhs =
>                 vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1),
> -                                               stmt, NULL);
> +                                             stmt, NULL, comp_vectype);
>               vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt,
>                                   loop_vinfo, NULL, &gtemp, &def, &dts[1]);

I'd simply open-code this here?

>               if (reduc_index == 1)
> diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
> index 23a82ee..1a1e509 100644
> --- a/gcc/tree-vectorizer.h
> +++ b/gcc/tree-vectorizer.h
> @@ -1032,7 +1032,7 @@ extern unsigned record_stmt_cost (stmt_vector_for_cost *, int,
>  extern void vect_finish_stmt_generation (gimple *, gimple *,
>                                           gimple_stmt_iterator *);
>  extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
> -extern tree vect_get_vec_def_for_operand (tree, gimple *, tree *);
> +extern tree vect_get_vec_def_for_operand (tree, gimple *, tree *, tree = NULL);
>  extern tree vect_init_vector (gimple *, tree, tree,
>                                gimple_stmt_iterator *);
>  extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]