Richard Biener <richard.guent...@gmail.com> writes:
> On Fri, Oct 11, 2019 at 4:39 PM Richard Sandiford
> <richard.sandif...@arm.com> wrote:
>>
>> This turned out to be useful for the SVE PCS support, and is a natural
>> tree-level analogue of insn_callee_abi.
>>
>> Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK to install?
>>
>> Richard
>>
>>
>> 2019-10-11  Richard Sandiford  <richard.sandif...@arm.com>
>>
>> gcc/
>>         * function-abi.h (expr_callee_abi): Declare.
>>         * function-abi.cc (expr_callee_abi): New function.
>>
>> Index: gcc/function-abi.h
>> ===================================================================
>> --- gcc/function-abi.h  2019-09-30 17:39:33.514597856 +0100
>> +++ gcc/function-abi.h  2019-10-11 15:38:54.141605718 +0100
>> @@ -315,5 +315,6 @@ call_clobbered_in_region_p (unsigned int
>>  extern const predefined_function_abi &fntype_abi (const_tree);
>>  extern function_abi fndecl_abi (const_tree);
>>  extern function_abi insn_callee_abi (const rtx_insn *);
>> +extern function_abi expr_callee_abi (const_tree);
>>
>>  #endif
>> Index: gcc/function-abi.cc
>> ===================================================================
>> --- gcc/function-abi.cc 2019-09-30 17:39:33.514597856 +0100
>> +++ gcc/function-abi.cc 2019-10-11 15:38:54.141605718 +0100
>> @@ -229,3 +229,32 @@ insn_callee_abi (const rtx_insn *insn)
>>
>>    return default_function_abi;
>>  }
>> +
>> +/* Return the ABI of the function called by CALL_EXPR EXP.  Return the
>> +   default ABI for erroneous calls.  */
>> +
>> +function_abi
>> +expr_callee_abi (const_tree exp)
>> +{
>> +  gcc_assert (TREE_CODE (exp) == CALL_EXPR);
>> +
>> +  if (tree fndecl = get_callee_fndecl (exp))
>> +    return fndecl_abi (fndecl);
>
> Please not.  The ABI in effect on the call is that of
> the type of CALL_EXPR_FN, what GIMPLE optimizers
> propagated as fndecl here doesn't matter.

expr_callee_abi is returning the ABI of the callee function, ignoring
any additional effects involved in actually calling it.  It's supposed
to take advantage of local IPA information where possible, e.g. by
ignoring call-clobbered registers that the target doesn't actually
clobber.

So if get_callee_fndecl returns either the correct FUNCTION_DECL or null,
using it gives better information than just using the type.  Failing to
propagate the decl (or not having a decl to propagate) just means that
we don't take advantage of the IPA information.

>> +
>> +  tree callee = CALL_EXPR_FN (exp);
>> +  if (callee == error_mark_node)
>> +    return default_function_abi;
>> +
>> +  tree type = TREE_TYPE (callee);
>> +  if (type == error_mark_node)
>> +    return default_function_abi;
>> +
>> +  if (POINTER_TYPE_P (type))
>> +    {
>> +      type = TREE_TYPE (type);
>> +      if (type == error_mark_node)
>> +       return default_function_abi;
>> +    }
>
> so when it's not a POINTER_TYPE (it always shold be!)
> then you're handing arbitrary types to fntype_abi.

fntype_abi asserts that TYPE is an appropriate type.  There's no safe
value we can return if it isn't.  (Well, apart from the error_mark_node
cases above, where the assumption is that compilation is going to fail
anyway.)

I can change it to assert for POINTER_TYPE_P if that's guaranteed everywhere.

Thanks,
Richard

>
>> +  return fntype_abi (type);
>> +}

Reply via email to