+2018-05-17 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * gimple-fold.h (gimple_build): Make the function forms take
+ combined_fn rather than built_in_function.
+ (gimple_simplify): Likewise.
+ * gimple-match-head.c (gimple_simplify): Likewise.
+ * gimple-fold.c (gimple_build): Likewise.
+ * tree-vect-loop.c (get_initial_def_for_reduction): Use gimple_build
+ rather than gimple_build_call_internal.
+ (get_initial_defs_for_reduction): Likewise.
+ (vect_create_epilog_for_reduction): Likewise.
+ (vectorizable_live_operation): Likewise.
+
2018-05-17 Martin Liska <mliska@suse.cz>
* gimple-ssa-sprintf.c (format_directive): Do not use
statements possibly defining it to SEQ. */
tree
-gimple_build (gimple_seq *seq, location_t loc,
- enum built_in_function fn, tree type, tree arg0)
+gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
+ tree type, tree arg0)
{
tree res = gimple_simplify (fn, type, arg0, seq, gimple_build_valueize);
if (!res)
{
- tree decl = builtin_decl_implicit (fn);
- gimple *stmt = gimple_build_call (decl, 1, arg0);
+ gcall *stmt;
+ if (internal_fn_p (fn))
+ stmt = gimple_build_call_internal (as_internal_fn (fn), 1, arg0);
+ else
+ {
+ tree decl = builtin_decl_implicit (as_builtin_fn (fn));
+ stmt = gimple_build_call (decl, 1, arg0);
+ }
if (!VOID_TYPE_P (type))
{
res = create_tmp_reg_or_ssa_name (type);
statements possibly defining it to SEQ. */
tree
-gimple_build (gimple_seq *seq, location_t loc,
- enum built_in_function fn, tree type, tree arg0, tree arg1)
+gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
+ tree type, tree arg0, tree arg1)
{
tree res = gimple_simplify (fn, type, arg0, arg1, seq, gimple_build_valueize);
if (!res)
{
- tree decl = builtin_decl_implicit (fn);
- gimple *stmt = gimple_build_call (decl, 2, arg0, arg1);
+ gcall *stmt;
+ if (internal_fn_p (fn))
+ stmt = gimple_build_call_internal (as_internal_fn (fn), 2, arg0, arg1);
+ else
+ {
+ tree decl = builtin_decl_implicit (as_builtin_fn (fn));
+ stmt = gimple_build_call (decl, 2, arg0, arg1);
+ }
if (!VOID_TYPE_P (type))
{
res = create_tmp_reg_or_ssa_name (type);
statements possibly defining it to SEQ. */
tree
-gimple_build (gimple_seq *seq, location_t loc,
- enum built_in_function fn, tree type,
- tree arg0, tree arg1, tree arg2)
+gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
+ tree type, tree arg0, tree arg1, tree arg2)
{
tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
seq, gimple_build_valueize);
if (!res)
{
- tree decl = builtin_decl_implicit (fn);
- gimple *stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
+ gcall *stmt;
+ if (internal_fn_p (fn))
+ stmt = gimple_build_call_internal (as_internal_fn (fn),
+ 3, arg0, arg1, arg2);
+ else
+ {
+ tree decl = builtin_decl_implicit (as_builtin_fn (fn));
+ stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
+ }
if (!VOID_TYPE_P (type))
{
res = create_tmp_reg_or_ssa_name (type);
{
return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2);
}
-extern tree gimple_build (gimple_seq *, location_t,
- enum built_in_function, tree, tree);
+extern tree gimple_build (gimple_seq *, location_t, combined_fn, tree, tree);
inline tree
-gimple_build (gimple_seq *seq,
- enum built_in_function fn, tree type, tree arg0)
+gimple_build (gimple_seq *seq, combined_fn fn, tree type, tree arg0)
{
return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0);
}
-extern tree gimple_build (gimple_seq *, location_t,
- enum built_in_function, tree, tree, tree);
+extern tree gimple_build (gimple_seq *, location_t, combined_fn,
+ tree, tree, tree);
inline tree
-gimple_build (gimple_seq *seq,
- enum built_in_function fn, tree type, tree arg0, tree arg1)
+gimple_build (gimple_seq *seq, combined_fn fn,
+ tree type, tree arg0, tree arg1)
{
return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1);
}
-extern tree gimple_build (gimple_seq *, location_t,
- enum built_in_function, tree, tree, tree, tree);
+extern tree gimple_build (gimple_seq *, location_t, combined_fn,
+ tree, tree, tree, tree);
inline tree
-gimple_build (gimple_seq *seq,
- enum built_in_function fn, tree type,
- tree arg0, tree arg1, tree arg2)
+gimple_build (gimple_seq *seq, combined_fn fn,
+ tree type, tree arg0, tree arg1, tree arg2)
{
return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1, arg2);
}
gimple_seq *, tree (*)(tree));
extern tree gimple_simplify (enum tree_code, tree, tree, tree, tree,
gimple_seq *, tree (*)(tree));
-extern tree gimple_simplify (enum built_in_function, tree, tree,
+extern tree gimple_simplify (combined_fn, tree, tree,
gimple_seq *, tree (*)(tree));
-extern tree gimple_simplify (enum built_in_function, tree, tree, tree,
+extern tree gimple_simplify (combined_fn, tree, tree, tree,
gimple_seq *, tree (*)(tree));
-extern tree gimple_simplify (enum built_in_function, tree, tree, tree, tree,
+extern tree gimple_simplify (combined_fn, tree, tree, tree, tree,
gimple_seq *, tree (*)(tree));
#endif /* GCC_GIMPLE_FOLD_H */
return maybe_push_res_to_seq (rcode, type, ops, seq);
}
-/* Builtin function with one argument. */
+/* Builtin or internal function with one argument. */
tree
-gimple_simplify (enum built_in_function fn, tree type,
+gimple_simplify (combined_fn fn, tree type,
tree arg0,
gimple_seq *seq, tree (*valueize)(tree))
{
if (constant_for_folding (arg0))
{
- tree res = fold_const_call (as_combined_fn (fn), type, arg0);
+ tree res = fold_const_call (fn, type, arg0);
if (res && CONSTANT_CLASS_P (res))
return res;
}
code_helper rcode;
tree ops[3] = {};
- if (!gimple_simplify (&rcode, ops, seq, valueize,
- as_combined_fn (fn), type, arg0))
+ if (!gimple_simplify (&rcode, ops, seq, valueize, fn, type, arg0))
return NULL_TREE;
return maybe_push_res_to_seq (rcode, type, ops, seq);
}
-/* Builtin function with two arguments. */
+/* Builtin or internal function with two arguments. */
tree
-gimple_simplify (enum built_in_function fn, tree type,
+gimple_simplify (combined_fn fn, tree type,
tree arg0, tree arg1,
gimple_seq *seq, tree (*valueize)(tree))
{
if (constant_for_folding (arg0)
&& constant_for_folding (arg1))
{
- tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1);
+ tree res = fold_const_call (fn, type, arg0, arg1);
if (res && CONSTANT_CLASS_P (res))
return res;
}
code_helper rcode;
tree ops[3] = {};
- if (!gimple_simplify (&rcode, ops, seq, valueize,
- as_combined_fn (fn), type, arg0, arg1))
+ if (!gimple_simplify (&rcode, ops, seq, valueize, fn, type, arg0, arg1))
return NULL_TREE;
return maybe_push_res_to_seq (rcode, type, ops, seq);
}
-/* Builtin function with three arguments. */
+/* Builtin or internal function with three arguments. */
tree
-gimple_simplify (enum built_in_function fn, tree type,
+gimple_simplify (combined_fn fn, tree type,
tree arg0, tree arg1, tree arg2,
gimple_seq *seq, tree (*valueize)(tree))
{
&& constant_for_folding (arg1)
&& constant_for_folding (arg2))
{
- tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1, arg2);
+ tree res = fold_const_call (fn, type, arg0, arg1, arg2);
if (res && CONSTANT_CLASS_P (res))
return res;
}
code_helper rcode;
tree ops[3] = {};
if (!gimple_simplify (&rcode, ops, seq, valueize,
- as_combined_fn (fn), type, arg0, arg1, arg2))
+ fn, type, arg0, arg1, arg2))
return NULL_TREE;
return maybe_push_res_to_seq (rcode, type, ops, seq);
}
else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant ())
{
/* Option2 (variable length): the first element is INIT_VAL. */
- init_def = build_vector_from_val (vectype, def_for_init);
- gcall *call = gimple_build_call_internal (IFN_VEC_SHL_INSERT,
- 2, init_def, init_val);
- init_def = make_ssa_name (vectype);
- gimple_call_set_lhs (call, init_def);
- gimple_seq_add_stmt (&stmts, call);
+ init_def = gimple_build_vector_from_val (&stmts, vectype,
+ def_for_init);
+ init_def = gimple_build (&stmts, CFN_VEC_SHL_INSERT,
+ vectype, init_def, init_val);
}
else
{
while (k > 0)
{
k -= 1;
- gcall *call = gimple_build_call_internal
- (IFN_VEC_SHL_INSERT, 2, init, elts[k]);
- init = make_ssa_name (vector_type);
- gimple_call_set_lhs (call, init);
- gimple_seq_add_stmt (&ctor_seq, call);
+ init = gimple_build (&ctor_seq, CFN_VEC_SHL_INSERT,
+ vector_type, init, elts[k]);
}
}
else
sel, new_phi_result, vector_identity);
/* Do the reduction and convert it to the appropriate type. */
- gcall *call = gimple_build_call_internal (reduc_fn, 1, vec);
- tree scalar = make_ssa_name (TREE_TYPE (vectype));
- gimple_call_set_lhs (call, scalar);
- gimple_seq_add_stmt (&seq, call);
+ tree scalar = gimple_build (&seq, as_combined_fn (reduc_fn),
+ TREE_TYPE (vectype), vec);
scalar = gimple_convert (&seq, scalar_type, scalar);
scalar_results.safe_push (scalar);
}
the loop mask for the final iteration. */
gcc_assert (ncopies == 1 && !slp_node);
tree scalar_type = TREE_TYPE (STMT_VINFO_VECTYPE (stmt_info));
- tree scalar_res = make_ssa_name (scalar_type);
tree mask = vect_get_loop_mask (gsi, &LOOP_VINFO_MASKS (loop_vinfo),
1, vectype, 0);
- gcall *new_stmt = gimple_build_call_internal (IFN_EXTRACT_LAST,
- 2, mask, vec_lhs);
- gimple_call_set_lhs (new_stmt, scalar_res);
- gimple_seq_add_stmt (&stmts, new_stmt);
+ tree scalar_res = gimple_build (&stmts, CFN_EXTRACT_LAST,
+ scalar_type, mask, vec_lhs);
/* Convert the extracted vector element to the required scalar type. */
new_tree = gimple_convert (&stmts, lhs_type, scalar_res);