Commit eb69361d by Richard Sandiford Committed by Richard Sandiford

Allow gimple_build with internal functions

This patch makes the function versions of gimple_build and
gimple_simplify take combined_fns rather than built_in_codes,
so that they work with internal functions too.  The old
gimple_builds were unused, so no existing callers need
to be updated.

2018-05-17  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* 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.

From-SVN: r260315
parent 40659769
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> 2018-05-17 Martin Liska <mliska@suse.cz>
* gimple-ssa-sprintf.c (format_directive): Do not use * gimple-ssa-sprintf.c (format_directive): Do not use
......
...@@ -7204,14 +7204,20 @@ gimple_build (gimple_seq *seq, location_t loc, ...@@ -7204,14 +7204,20 @@ gimple_build (gimple_seq *seq, location_t loc,
statements possibly defining it to SEQ. */ statements possibly defining it to SEQ. */
tree tree
gimple_build (gimple_seq *seq, location_t loc, gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
enum built_in_function fn, tree type, tree arg0) tree type, tree arg0)
{ {
tree res = gimple_simplify (fn, type, arg0, seq, gimple_build_valueize); tree res = gimple_simplify (fn, type, arg0, seq, gimple_build_valueize);
if (!res) if (!res)
{ {
tree decl = builtin_decl_implicit (fn); gcall *stmt;
gimple *stmt = gimple_build_call (decl, 1, arg0); 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)) if (!VOID_TYPE_P (type))
{ {
res = create_tmp_reg_or_ssa_name (type); res = create_tmp_reg_or_ssa_name (type);
...@@ -7230,14 +7236,20 @@ gimple_build (gimple_seq *seq, location_t loc, ...@@ -7230,14 +7236,20 @@ gimple_build (gimple_seq *seq, location_t loc,
statements possibly defining it to SEQ. */ statements possibly defining it to SEQ. */
tree tree
gimple_build (gimple_seq *seq, location_t loc, gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
enum built_in_function fn, tree type, tree arg0, tree arg1) tree type, tree arg0, tree arg1)
{ {
tree res = gimple_simplify (fn, type, arg0, arg1, seq, gimple_build_valueize); tree res = gimple_simplify (fn, type, arg0, arg1, seq, gimple_build_valueize);
if (!res) if (!res)
{ {
tree decl = builtin_decl_implicit (fn); gcall *stmt;
gimple *stmt = gimple_build_call (decl, 2, arg0, arg1); 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)) if (!VOID_TYPE_P (type))
{ {
res = create_tmp_reg_or_ssa_name (type); res = create_tmp_reg_or_ssa_name (type);
...@@ -7256,16 +7268,22 @@ gimple_build (gimple_seq *seq, location_t loc, ...@@ -7256,16 +7268,22 @@ gimple_build (gimple_seq *seq, location_t loc,
statements possibly defining it to SEQ. */ statements possibly defining it to SEQ. */
tree tree
gimple_build (gimple_seq *seq, location_t loc, gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
enum built_in_function fn, tree type, tree type, tree arg0, tree arg1, tree arg2)
tree arg0, tree arg1, tree arg2)
{ {
tree res = gimple_simplify (fn, type, arg0, arg1, arg2, tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
seq, gimple_build_valueize); seq, gimple_build_valueize);
if (!res) if (!res)
{ {
tree decl = builtin_decl_implicit (fn); gcall *stmt;
gimple *stmt = gimple_build_call (decl, 3, arg0, arg1, arg2); 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)) if (!VOID_TYPE_P (type))
{ {
res = create_tmp_reg_or_ssa_name (type); res = create_tmp_reg_or_ssa_name (type);
......
...@@ -86,28 +86,25 @@ gimple_build (gimple_seq *seq, ...@@ -86,28 +86,25 @@ gimple_build (gimple_seq *seq,
{ {
return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2); return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2);
} }
extern tree gimple_build (gimple_seq *, location_t, extern tree gimple_build (gimple_seq *, location_t, combined_fn, tree, tree);
enum built_in_function, tree, tree);
inline tree inline tree
gimple_build (gimple_seq *seq, gimple_build (gimple_seq *seq, combined_fn fn, tree type, tree arg0)
enum built_in_function fn, tree type, tree arg0)
{ {
return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0); return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0);
} }
extern tree gimple_build (gimple_seq *, location_t, extern tree gimple_build (gimple_seq *, location_t, combined_fn,
enum built_in_function, tree, tree, tree); tree, tree, tree);
inline tree inline tree
gimple_build (gimple_seq *seq, gimple_build (gimple_seq *seq, combined_fn fn,
enum built_in_function fn, tree type, tree arg0, tree arg1) tree type, tree arg0, tree arg1)
{ {
return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1); return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1);
} }
extern tree gimple_build (gimple_seq *, location_t, extern tree gimple_build (gimple_seq *, location_t, combined_fn,
enum built_in_function, tree, tree, tree, tree); tree, tree, tree, tree);
inline tree inline tree
gimple_build (gimple_seq *seq, gimple_build (gimple_seq *seq, combined_fn fn,
enum built_in_function fn, tree type, tree type, tree arg0, tree arg1, tree arg2)
tree arg0, tree arg1, tree arg2)
{ {
return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1, arg2); return gimple_build (seq, UNKNOWN_LOCATION, fn, type, arg0, arg1, arg2);
} }
...@@ -153,11 +150,11 @@ extern tree gimple_simplify (enum tree_code, tree, tree, tree, ...@@ -153,11 +150,11 @@ extern tree gimple_simplify (enum tree_code, tree, tree, tree,
gimple_seq *, tree (*)(tree)); gimple_seq *, tree (*)(tree));
extern tree gimple_simplify (enum tree_code, tree, tree, tree, tree, extern tree gimple_simplify (enum tree_code, tree, tree, tree, tree,
gimple_seq *, 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)); 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)); 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)); gimple_seq *, tree (*)(tree));
#endif /* GCC_GIMPLE_FOLD_H */ #endif /* GCC_GIMPLE_FOLD_H */
...@@ -478,55 +478,53 @@ gimple_simplify (enum tree_code code, tree type, ...@@ -478,55 +478,53 @@ gimple_simplify (enum tree_code code, tree type,
return maybe_push_res_to_seq (rcode, type, ops, seq); return maybe_push_res_to_seq (rcode, type, ops, seq);
} }
/* Builtin function with one argument. */ /* Builtin or internal function with one argument. */
tree tree
gimple_simplify (enum built_in_function fn, tree type, gimple_simplify (combined_fn fn, tree type,
tree arg0, tree arg0,
gimple_seq *seq, tree (*valueize)(tree)) gimple_seq *seq, tree (*valueize)(tree))
{ {
if (constant_for_folding (arg0)) 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)) if (res && CONSTANT_CLASS_P (res))
return res; return res;
} }
code_helper rcode; code_helper rcode;
tree ops[3] = {}; tree ops[3] = {};
if (!gimple_simplify (&rcode, ops, seq, valueize, if (!gimple_simplify (&rcode, ops, seq, valueize, fn, type, arg0))
as_combined_fn (fn), type, arg0))
return NULL_TREE; return NULL_TREE;
return maybe_push_res_to_seq (rcode, type, ops, seq); return maybe_push_res_to_seq (rcode, type, ops, seq);
} }
/* Builtin function with two arguments. */ /* Builtin or internal function with two arguments. */
tree tree
gimple_simplify (enum built_in_function fn, tree type, gimple_simplify (combined_fn fn, tree type,
tree arg0, tree arg1, tree arg0, tree arg1,
gimple_seq *seq, tree (*valueize)(tree)) gimple_seq *seq, tree (*valueize)(tree))
{ {
if (constant_for_folding (arg0) if (constant_for_folding (arg0)
&& constant_for_folding (arg1)) && 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)) if (res && CONSTANT_CLASS_P (res))
return res; return res;
} }
code_helper rcode; code_helper rcode;
tree ops[3] = {}; tree ops[3] = {};
if (!gimple_simplify (&rcode, ops, seq, valueize, if (!gimple_simplify (&rcode, ops, seq, valueize, fn, type, arg0, arg1))
as_combined_fn (fn), type, arg0, arg1))
return NULL_TREE; return NULL_TREE;
return maybe_push_res_to_seq (rcode, type, ops, seq); return maybe_push_res_to_seq (rcode, type, ops, seq);
} }
/* Builtin function with three arguments. */ /* Builtin or internal function with three arguments. */
tree tree
gimple_simplify (enum built_in_function fn, tree type, gimple_simplify (combined_fn fn, tree type,
tree arg0, tree arg1, tree arg2, tree arg0, tree arg1, tree arg2,
gimple_seq *seq, tree (*valueize)(tree)) gimple_seq *seq, tree (*valueize)(tree))
{ {
...@@ -534,7 +532,7 @@ gimple_simplify (enum built_in_function fn, tree type, ...@@ -534,7 +532,7 @@ gimple_simplify (enum built_in_function fn, tree type,
&& constant_for_folding (arg1) && constant_for_folding (arg1)
&& constant_for_folding (arg2)) && 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)) if (res && CONSTANT_CLASS_P (res))
return res; return res;
} }
...@@ -542,7 +540,7 @@ gimple_simplify (enum built_in_function fn, tree type, ...@@ -542,7 +540,7 @@ gimple_simplify (enum built_in_function fn, tree type,
code_helper rcode; code_helper rcode;
tree ops[3] = {}; tree ops[3] = {};
if (!gimple_simplify (&rcode, ops, seq, valueize, if (!gimple_simplify (&rcode, ops, seq, valueize,
as_combined_fn (fn), type, arg0, arg1, arg2)) fn, type, arg0, arg1, arg2))
return NULL_TREE; return NULL_TREE;
return maybe_push_res_to_seq (rcode, type, ops, seq); return maybe_push_res_to_seq (rcode, type, ops, seq);
} }
......
...@@ -4181,12 +4181,10 @@ get_initial_def_for_reduction (gimple *stmt, tree init_val, ...@@ -4181,12 +4181,10 @@ get_initial_def_for_reduction (gimple *stmt, tree init_val,
else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant ()) else if (!TYPE_VECTOR_SUBPARTS (vectype).is_constant ())
{ {
/* Option2 (variable length): the first element is INIT_VAL. */ /* Option2 (variable length): the first element is INIT_VAL. */
init_def = build_vector_from_val (vectype, def_for_init); init_def = gimple_build_vector_from_val (&stmts, vectype,
gcall *call = gimple_build_call_internal (IFN_VEC_SHL_INSERT, def_for_init);
2, init_def, init_val); init_def = gimple_build (&stmts, CFN_VEC_SHL_INSERT,
init_def = make_ssa_name (vectype); vectype, init_def, init_val);
gimple_call_set_lhs (call, init_def);
gimple_seq_add_stmt (&stmts, call);
} }
else else
{ {
...@@ -4329,11 +4327,8 @@ get_initial_defs_for_reduction (slp_tree slp_node, ...@@ -4329,11 +4327,8 @@ get_initial_defs_for_reduction (slp_tree slp_node,
while (k > 0) while (k > 0)
{ {
k -= 1; k -= 1;
gcall *call = gimple_build_call_internal init = gimple_build (&ctor_seq, CFN_VEC_SHL_INSERT,
(IFN_VEC_SHL_INSERT, 2, init, elts[k]); vector_type, init, elts[k]);
init = make_ssa_name (vector_type);
gimple_call_set_lhs (call, init);
gimple_seq_add_stmt (&ctor_seq, call);
} }
} }
else else
...@@ -5236,10 +5231,8 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple *stmt, ...@@ -5236,10 +5231,8 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs, gimple *stmt,
sel, new_phi_result, vector_identity); sel, new_phi_result, vector_identity);
/* Do the reduction and convert it to the appropriate type. */ /* Do the reduction and convert it to the appropriate type. */
gcall *call = gimple_build_call_internal (reduc_fn, 1, vec); tree scalar = gimple_build (&seq, as_combined_fn (reduc_fn),
tree scalar = make_ssa_name (TREE_TYPE (vectype)); TREE_TYPE (vectype), vec);
gimple_call_set_lhs (call, scalar);
gimple_seq_add_stmt (&seq, call);
scalar = gimple_convert (&seq, scalar_type, scalar); scalar = gimple_convert (&seq, scalar_type, scalar);
scalar_results.safe_push (scalar); scalar_results.safe_push (scalar);
} }
...@@ -8054,13 +8047,10 @@ vectorizable_live_operation (gimple *stmt, ...@@ -8054,13 +8047,10 @@ vectorizable_live_operation (gimple *stmt,
the loop mask for the final iteration. */ the loop mask for the final iteration. */
gcc_assert (ncopies == 1 && !slp_node); gcc_assert (ncopies == 1 && !slp_node);
tree scalar_type = TREE_TYPE (STMT_VINFO_VECTYPE (stmt_info)); 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), tree mask = vect_get_loop_mask (gsi, &LOOP_VINFO_MASKS (loop_vinfo),
1, vectype, 0); 1, vectype, 0);
gcall *new_stmt = gimple_build_call_internal (IFN_EXTRACT_LAST, tree scalar_res = gimple_build (&stmts, CFN_EXTRACT_LAST,
2, mask, vec_lhs); scalar_type, mask, vec_lhs);
gimple_call_set_lhs (new_stmt, scalar_res);
gimple_seq_add_stmt (&stmts, new_stmt);
/* Convert the extracted vector element to the required scalar type. */ /* Convert the extracted vector element to the required scalar type. */
new_tree = gimple_convert (&stmts, lhs_type, scalar_res); new_tree = gimple_convert (&stmts, lhs_type, scalar_res);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment