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); + + 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; + } + + return fntype_abi (type); +}