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); >> +}