Commit 4cfe7a6c by Richard Sandiford Committed by Richard Sandiford

Short-cut generation of simple built-in functions

This patch short-circuits the builtins.c expansion code for a particular
gimple call if:

- the function has an associated internal function
- the target implements that internal function
- the call has no side effects

This allows a later patch to remove the builtins.c code, once calls with
side effects have been handled.

Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.

gcc/
	* builtins.h (called_as_built_in): Declare.
	* builtins.c (called_as_built_in): Make external.
	* internal-fn.h (expand_internal_call): Define a variant that
	specifies the internal function explicitly.
	* internal-fn.c (expand_load_lanes_optab_fn)
	(expand_store_lanes_optab_fn, expand_ANNOTATE, expand_GOMP_SIMD_LANE)
	(expand_GOMP_SIMD_VF, expand_GOMP_SIMD_LAST_LANE)
	(expand_GOMP_SIMD_ORDERED_START, expand_GOMP_SIMD_ORDERED_END)
	(expand_UBSAN_NULL, expand_UBSAN_BOUNDS, expand_UBSAN_VPTR)
	(expand_UBSAN_OBJECT_SIZE, expand_ASAN_CHECK, expand_TSAN_FUNC_EXIT)
	(expand_UBSAN_CHECK_ADD, expand_UBSAN_CHECK_SUB)
	(expand_UBSAN_CHECK_MUL, expand_ADD_OVERFLOW, expand_SUB_OVERFLOW)
	(expand_MUL_OVERFLOW, expand_LOOP_VECTORIZED)
	(expand_mask_load_optab_fn, expand_mask_store_optab_fn)
	(expand_ABNORMAL_DISPATCHER, expand_BUILTIN_EXPECT, expand_VA_ARG)
	(expand_UNIQUE, expand_GOACC_DIM_SIZE, expand_GOACC_DIM_POS)
	(expand_GOACC_LOOP, expand_GOACC_REDUCTION, expand_direct_optab_fn)
	(expand_unary_optab_fn, expand_binary_optab_fn): Add an internal_fn
	argument.
	(internal_fn_expanders): Update prototype.
	(expand_internal_call): Define a variant that specifies the
	internal function explicitly. Use it to implement the previous
	interface.
	* cfgexpand.c (expand_call_stmt): Try to expand calls to built-in
	functions as calls to internal functions.

From-SVN: r230487
parent b1dc4a20
2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
* builtins.h (called_as_built_in): Declare.
* builtins.c (called_as_built_in): Make external.
* internal-fn.h (expand_internal_call): Define a variant that
specifies the internal function explicitly.
* internal-fn.c (expand_load_lanes_optab_fn)
(expand_store_lanes_optab_fn, expand_ANNOTATE, expand_GOMP_SIMD_LANE)
(expand_GOMP_SIMD_VF, expand_GOMP_SIMD_LAST_LANE)
(expand_GOMP_SIMD_ORDERED_START, expand_GOMP_SIMD_ORDERED_END)
(expand_UBSAN_NULL, expand_UBSAN_BOUNDS, expand_UBSAN_VPTR)
(expand_UBSAN_OBJECT_SIZE, expand_ASAN_CHECK, expand_TSAN_FUNC_EXIT)
(expand_UBSAN_CHECK_ADD, expand_UBSAN_CHECK_SUB)
(expand_UBSAN_CHECK_MUL, expand_ADD_OVERFLOW, expand_SUB_OVERFLOW)
(expand_MUL_OVERFLOW, expand_LOOP_VECTORIZED)
(expand_mask_load_optab_fn, expand_mask_store_optab_fn)
(expand_ABNORMAL_DISPATCHER, expand_BUILTIN_EXPECT, expand_VA_ARG)
(expand_UNIQUE, expand_GOACC_DIM_SIZE, expand_GOACC_DIM_POS)
(expand_GOACC_LOOP, expand_GOACC_REDUCTION, expand_direct_optab_fn)
(expand_unary_optab_fn, expand_binary_optab_fn): Add an internal_fn
argument.
(internal_fn_expanders): Update prototype.
(expand_internal_call): Define a variant that specifies the
internal function explicitly. Use it to implement the previous
interface.
* cfgexpand.c (expand_call_stmt): Try to expand calls to built-in
functions as calls to internal functions.
2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
* Makefile.in (MOSTLYCLEANFILES): Add cfn-operators.pd.
(generated_files): Likewise.
(s-cfn-operators, cfn-operators.pd): New rules.
......@@ -222,7 +222,7 @@ is_builtin_fn (tree decl)
of the optimization level. This means whenever a function is invoked with
its "internal" name, which normally contains the prefix "__builtin". */
static bool
bool
called_as_built_in (tree node)
{
/* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
......
......@@ -50,6 +50,7 @@ extern struct target_builtins *this_target_builtins;
extern bool force_folding_builtin_constant_p;
extern bool is_builtin_fn (tree);
extern bool called_as_built_in (tree);
extern bool get_object_alignment_1 (tree, unsigned int *,
unsigned HOST_WIDE_INT *);
extern unsigned int get_object_alignment (tree);
......
......@@ -2551,10 +2551,25 @@ expand_call_stmt (gcall *stmt)
return;
}
/* If this is a call to a built-in function and it has no effect other
than setting the lhs, try to implement it using an internal function
instead. */
decl = gimple_call_fndecl (stmt);
if (gimple_call_lhs (stmt)
&& !gimple_has_side_effects (stmt)
&& (optimize || (decl && called_as_built_in (decl))))
{
internal_fn ifn = replacement_internal_fn (stmt);
if (ifn != IFN_LAST)
{
expand_internal_call (ifn, stmt);
return;
}
}
exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3);
CALL_EXPR_FN (exp) = gimple_call_fn (stmt);
decl = gimple_call_fndecl (stmt);
builtin_p = decl && DECL_BUILT_IN (decl);
/* If this is not a builtin function, the function type through which the
......
......@@ -162,5 +162,6 @@ extern bool direct_internal_fn_supported_p (internal_fn, tree_pair);
extern bool direct_internal_fn_supported_p (internal_fn, tree);
extern void expand_internal_call (gcall *);
extern void expand_internal_call (internal_fn, gcall *);
#endif
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