Re: Short-cut generation of simple built-in functions

2015-11-22 Thread H.J. Lu
On Sat, Nov 7, 2015 at 5:31 AM, Richard Sandiford
 wrote:
> 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.
> OK to install?
>
> Thanks,
> Richard
>
>
> 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.
>

This caused:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68488


H.J.


Re: Short-cut generation of simple built-in functions

2015-11-17 Thread Richard Biener
On Tue, Nov 17, 2015 at 10:55 AM, Richard Sandiford
 wrote:
> Richard Sandiford  writes:
>> Richard Biener  writes:
>>> On Tue, Nov 10, 2015 at 10:24 PM, Richard Sandiford
>>>  wrote:
 Richard Biener  writes:
> On Sat, Nov 7, 2015 at 2:31 PM, Richard Sandiford
>  wrote:
>> 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.
>> OK to install?
>>
>> Thanks,
>> Richard
>>
>>
>> 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.
>>
>> diff --git a/gcc/builtins.c b/gcc/builtins.c
>> index f65011e..bbcc7dc3 100644
>> --- a/gcc/builtins.c
>> +++ b/gcc/builtins.c
>> @@ -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
>> diff --git a/gcc/builtins.h b/gcc/builtins.h
>> index 917eb90..1d00068 100644
>> --- a/gcc/builtins.h
>> +++ b/gcc/builtins.h
>> @@ -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);
>> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
>> index bfbc958..dc7d4f5 100644
>> --- a/gcc/cfgexpand.c
>> +++ b/gcc/cfgexpand.c
>> @@ -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_vdef (stmt)
>
> I think you want && ! gimple_has_side_effects (stmt)
> instead of checking !gimple_vdef (stmt).

 OK, I can do that, but what would the difference be in practice for
 these types of call?  I.e. are there cases for built-ins where:

   (A) gimple_vdef (stmt) && !gimple_side_effects (stmt)

 or:

   (B) !gimple_vdef (stmt) && gimple_side_effects (stmt)

 ?
>>>
>>> There was talk to make calls use volatile to prevent CSE and friends.
>>>
>>> Using gimple_has_side_effects 

Re: Short-cut generation of simple built-in functions

2015-11-17 Thread Richard Sandiford
Richard Sandiford  writes:
> Richard Biener  writes:
>> On Tue, Nov 10, 2015 at 10:24 PM, Richard Sandiford
>>  wrote:
>>> Richard Biener  writes:
 On Sat, Nov 7, 2015 at 2:31 PM, Richard Sandiford
  wrote:
> 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.
> OK to install?
>
> Thanks,
> Richard
>
>
> 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.
>
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index f65011e..bbcc7dc3 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -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
> diff --git a/gcc/builtins.h b/gcc/builtins.h
> index 917eb90..1d00068 100644
> --- a/gcc/builtins.h
> +++ b/gcc/builtins.h
> @@ -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);
> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
> index bfbc958..dc7d4f5 100644
> --- a/gcc/cfgexpand.c
> +++ b/gcc/cfgexpand.c
> @@ -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_vdef (stmt)

 I think you want && ! gimple_has_side_effects (stmt)
 instead of checking !gimple_vdef (stmt).
>>>
>>> OK, I can do that, but what would the difference be in practice for
>>> these types of call?  I.e. are there cases for built-ins where:
>>>
>>>   (A) gimple_vdef (stmt) && !gimple_side_effects (stmt)
>>>
>>> or:
>>>
>>>   (B) !gimple_vdef (stmt) && gimple_side_effects (stmt)
>>>
>>> ?
>>
>> There was talk to make calls use volatile to prevent CSE and friends.
>>
>> Using gimple_has_side_effects is just the better check.
>>
>>> It just seems like this check should be the opposite of the one used
>>> in the call-cdce patch (when deciding whether to optimise a call
>>> with an lhs).  In order to keep them in sync I'd need to use

Re: Short-cut generation of simple built-in functions

2015-11-13 Thread Richard Sandiford
Richard Biener  writes:
> On Tue, Nov 10, 2015 at 10:24 PM, Richard Sandiford
>  wrote:
>> Richard Biener  writes:
>>> On Sat, Nov 7, 2015 at 2:31 PM, Richard Sandiford
>>>  wrote:
 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.
 OK to install?

 Thanks,
 Richard


 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.

 diff --git a/gcc/builtins.c b/gcc/builtins.c
 index f65011e..bbcc7dc3 100644
 --- a/gcc/builtins.c
 +++ b/gcc/builtins.c
 @@ -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
 diff --git a/gcc/builtins.h b/gcc/builtins.h
 index 917eb90..1d00068 100644
 --- a/gcc/builtins.h
 +++ b/gcc/builtins.h
 @@ -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);
 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
 index bfbc958..dc7d4f5 100644
 --- a/gcc/cfgexpand.c
 +++ b/gcc/cfgexpand.c
 @@ -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_vdef (stmt)
>>>
>>> I think you want && ! gimple_has_side_effects (stmt)
>>> instead of checking !gimple_vdef (stmt).
>>
>> OK, I can do that, but what would the difference be in practice for
>> these types of call?  I.e. are there cases for built-ins where:
>>
>>   (A) gimple_vdef (stmt) && !gimple_side_effects (stmt)
>>
>> or:
>>
>>   (B) !gimple_vdef (stmt) && gimple_side_effects (stmt)
>>
>> ?
>
> There was talk to make calls use volatile to prevent CSE and friends.
>
> Using gimple_has_side_effects is just the better check.
>
>> It just seems like this check should be the opposite of the one used
>> in the call-cdce patch (when deciding whether to optimise a call
>> with an lhs).  In order to keep them in sync I'd need to use
>> gimple_side_effects rather than gimple_vdef there too, but is
>> (B) a possibility there?
>
> Not sure if the tests should be in-sync.

Well, with the series, we have two 

Re: Short-cut generation of simple built-in functions

2015-11-11 Thread Richard Biener
On Tue, Nov 10, 2015 at 10:24 PM, Richard Sandiford
 wrote:
> Richard Biener  writes:
>> On Sat, Nov 7, 2015 at 2:31 PM, Richard Sandiford
>>  wrote:
>>> 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.
>>> OK to install?
>>>
>>> Thanks,
>>> Richard
>>>
>>>
>>> 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.
>>>
>>> diff --git a/gcc/builtins.c b/gcc/builtins.c
>>> index f65011e..bbcc7dc3 100644
>>> --- a/gcc/builtins.c
>>> +++ b/gcc/builtins.c
>>> @@ -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
>>> diff --git a/gcc/builtins.h b/gcc/builtins.h
>>> index 917eb90..1d00068 100644
>>> --- a/gcc/builtins.h
>>> +++ b/gcc/builtins.h
>>> @@ -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);
>>> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
>>> index bfbc958..dc7d4f5 100644
>>> --- a/gcc/cfgexpand.c
>>> +++ b/gcc/cfgexpand.c
>>> @@ -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_vdef (stmt)
>>
>> I think you want && ! gimple_has_side_effects (stmt)
>> instead of checking !gimple_vdef (stmt).
>
> OK, I can do that, but what would the difference be in practice for
> these types of call?  I.e. are there cases for built-ins where:
>
>   (A) gimple_vdef (stmt) && !gimple_side_effects (stmt)
>
> or:
>
>   (B) !gimple_vdef (stmt) && gimple_side_effects (stmt)
>
> ?

There was talk to make calls use volatile to prevent CSE and friends.

Using gimple_has_side_effects is just the better check.

> It just seems like this check should be the opposite of the one used
> in the call-cdce patch (when deciding whether to optimise a call
> with an lhs).  In order to keep them in sync I'd need to use
> gimple_side_effects rather than gimple_vdef there too, but is
> (B) a possibility there?

Not sure if the tests should be in-sync.

I'm also not sure what you really want to check with

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

Re: Short-cut generation of simple built-in functions

2015-11-10 Thread Richard Sandiford
Richard Biener  writes:
> On Sat, Nov 7, 2015 at 2:31 PM, Richard Sandiford
>  wrote:
>> 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.
>> OK to install?
>>
>> Thanks,
>> Richard
>>
>>
>> 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.
>>
>> diff --git a/gcc/builtins.c b/gcc/builtins.c
>> index f65011e..bbcc7dc3 100644
>> --- a/gcc/builtins.c
>> +++ b/gcc/builtins.c
>> @@ -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
>> diff --git a/gcc/builtins.h b/gcc/builtins.h
>> index 917eb90..1d00068 100644
>> --- a/gcc/builtins.h
>> +++ b/gcc/builtins.h
>> @@ -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);
>> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
>> index bfbc958..dc7d4f5 100644
>> --- a/gcc/cfgexpand.c
>> +++ b/gcc/cfgexpand.c
>> @@ -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_vdef (stmt)
>
> I think you want && ! gimple_has_side_effects (stmt)
> instead of checking !gimple_vdef (stmt).

OK, I can do that, but what would the difference be in practice for
these types of call?  I.e. are there cases for built-ins where:

  (A) gimple_vdef (stmt) && !gimple_side_effects (stmt)

or:

  (B) !gimple_vdef (stmt) && gimple_side_effects (stmt)

?

It just seems like this check should be the opposite of the one used
in the call-cdce patch (when deciding whether to optimise a call
with an lhs).  In order to keep them in sync I'd need to use
gimple_side_effects rather than gimple_vdef there too, but is
(B) a possibility there?

>> +  && (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
>> diff --git a/gcc/internal-fn.c 

Re: Short-cut generation of simple built-in functions

2015-11-10 Thread Richard Biener
On Sat, Nov 7, 2015 at 2:31 PM, Richard Sandiford
 wrote:
> 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.
> OK to install?
>
> Thanks,
> Richard
>
>
> 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.
>
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index f65011e..bbcc7dc3 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -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
> diff --git a/gcc/builtins.h b/gcc/builtins.h
> index 917eb90..1d00068 100644
> --- a/gcc/builtins.h
> +++ b/gcc/builtins.h
> @@ -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);
> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
> index bfbc958..dc7d4f5 100644
> --- a/gcc/cfgexpand.c
> +++ b/gcc/cfgexpand.c
> @@ -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_vdef (stmt)

I think you want && ! gimple_has_side_effects (stmt)
instead of checking !gimple_vdef (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
> diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
> index 9f9f9cf..c03c0fc 100644
> --- a/gcc/internal-fn.c
> +++ b/gcc/internal-fn.c
> @@ -103,7 +103,7 @@ get_multi_vector_move (tree array_type, convert_optab 
> optab)
>  /* Expand LOAD_LANES call STMT using optab OPTAB.  */
>
>  static void
> -expand_load_lanes_optab_fn (gcall *stmt, convert_optab optab)
> +expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)

I'm somewhat confused by all these unused internal_fn args.  I'm sure
we can avoid them?

>  {
>struct expand_operand ops[2];
>tree type, lhs, rhs;
> @@ -127,7 +127,7 @@ expand_load_lanes_optab_fn (gcall *stmt, convert_optab 
> optab)
>  /* Expand STORE_LANES call STMT using optab OPTAB.  */
>

Short-cut generation of simple built-in functions

2015-11-07 Thread Richard Sandiford
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.
OK to install?

Thanks,
Richard


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.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index f65011e..bbcc7dc3 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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
diff --git a/gcc/builtins.h b/gcc/builtins.h
index 917eb90..1d00068 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -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);
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index bfbc958..dc7d4f5 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -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_vdef (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
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 9f9f9cf..c03c0fc 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -103,7 +103,7 @@ get_multi_vector_move (tree array_type, convert_optab optab)
 /* Expand LOAD_LANES call STMT using optab OPTAB.  */
 
 static void
-expand_load_lanes_optab_fn (gcall *stmt, convert_optab optab)
+expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
 {
   struct expand_operand ops[2];
   tree type, lhs, rhs;
@@ -127,7 +127,7 @@ expand_load_lanes_optab_fn (gcall *stmt, convert_optab 
optab)
 /* Expand STORE_LANES call STMT using optab OPTAB.  */
 
 static void
-expand_store_lanes_optab_fn (gcall *stmt, convert_optab optab)
+expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
 {
   struct expand_operand ops[2];
   tree type, lhs, rhs;
@@ -149,7 +149,7 @@ expand_store_lanes_optab_fn (gcall *stmt, convert_optab 
optab)
 }
 
 static void
-expand_ANNOTATE (gcall *)
+expand_ANNOTATE (internal_fn, gcall *)
 {
   gcc_unreachable ();
 }
@@ -157,7 +157,7 @@ expand_ANNOTATE (gcall *)
 /* This should get expanded