Richard Biener <[email protected]> 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 *,