Richard Biener <rguent...@suse.de> writes:
> So I came up with this, yet another overload of vect_is_simple_use (ick).
> But at least for the two functions I tackled it seems to be straight-forward.
>
> I'll see to enforce a type on all invariants in vect_get_constant_vectors
> and thus try to adjust all other vectorizable_* (but I'm sure I'll miss
> some...).
>
> Comments still welcome.  The patch below passes vect.exp testing on
> x86_64-linux.

LGTM FWIW.  Just wondering...

> @@ -11710,6 +11735,58 @@ vect_is_simple_use (tree operand, vec_info *vinfo, 
> enum vect_def_type *dt,
>    return true;
>  }
>  
> +/* Function vect_is_simple_use.
> +
> +   Same as vect_is_simple_use but determines the operand by operand
> +   position OPERAND from either STMT or SLP_NODE, filling in *OP
> +   and *SLP_DEF (when SLP_NODE is not NULL).  */
> +
> +bool
> +vect_is_simple_use (vec_info *vinfo, stmt_vec_info stmt, slp_tree slp_node,
> +                 unsigned operand, tree *op, slp_tree *slp_def,
> +                 enum vect_def_type *dt,
> +                 tree *vectype, stmt_vec_info *def_stmt_info_out)
> +{
> +  if (slp_node)
> +    {
> +      if (operand >= SLP_TREE_CHILDREN (slp_node).length ())
> +     return false;

...which case needs the return false?  Asserting for out-of-range
indices (like for !slp_node) feels like it would hide fewer bugs.

Thanks,
Richard

> +      slp_tree child = SLP_TREE_CHILDREN (slp_node)[operand];
> +      *slp_def = child;
> +      if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
> +     *op = gimple_get_lhs (SLP_TREE_SCALAR_STMTS (child)[0]->stmt);
> +      else
> +     *op = SLP_TREE_SCALAR_OPS (child)[0];
> +    }
> +  else
> +    {
> +      if (gassign *ass = dyn_cast <gassign *> (stmt->stmt))
> +     *op = gimple_op (ass, operand + 1);
> +      else if (gcall *call = dyn_cast <gcall *> (stmt->stmt))
> +     *op = gimple_call_arg (call, operand);
> +      else
> +     gcc_unreachable ();
> +    }
> +
> +  /* ???  We might want to update *vectype from *slp_def here though
> +     when sharing nodes this would prevent unsharing in the caller.  */
> +  return vect_is_simple_use (*op, vinfo, dt, vectype, def_stmt_info_out);
> +}
> +
> +/* If OP is not NULL and is external or constant update its vector
> +   type with VECTYPE.  Returns true if successful or false if not,
> +   for example when conflicting vector types are present.  */
> +
> +bool
> +vect_maybe_update_slp_op_vectype (slp_tree op, tree vectype)
> +{
> +  if (!op || SLP_TREE_DEF_TYPE (op) == vect_internal_def)
> +    return true;
> +  if (SLP_TREE_VECTYPE (op))
> +    return types_compatible_p (SLP_TREE_VECTYPE (op), vectype);
> +  SLP_TREE_VECTYPE (op) = vectype;
> +  return true;
> +}
>  
>  /* Function supportable_widening_operation
>  
> diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
> index 38a0a1d278b..5b4188d08a3 100644
> --- a/gcc/tree-vectorizer.h
> +++ b/gcc/tree-vectorizer.h
> @@ -1695,6 +1695,11 @@ extern bool vect_is_simple_use (tree, vec_info *, enum 
> vect_def_type *,
>  extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
>                               tree *, stmt_vec_info * = NULL,
>                               gimple ** = NULL);
> +extern bool vect_is_simple_use (vec_info *, stmt_vec_info, slp_tree,
> +                             unsigned, tree *, slp_tree *,
> +                             enum vect_def_type *,
> +                             tree *, stmt_vec_info * = NULL);
> +extern bool vect_maybe_update_slp_op_vectype (slp_tree, tree);
>  extern bool supportable_widening_operation (vec_info *,
>                                           enum tree_code, stmt_vec_info,
>                                           tree, tree, enum tree_code *,

Reply via email to