aboutsummaryrefslogtreecommitdiff
path: root/gcc/final.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-09-30 16:19:49 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-09-30 16:19:49 +0000
commit5a5a3bc5fa14664be26748c11325021b6b6f8e74 (patch)
tree049b62e2f4fbaa496017f9703a2f5375610da646 /gcc/final.c
parent002ffd3caa684c3eb30f8f53206439b7aa34b370 (diff)
downloadgcc-5a5a3bc5fa14664be26748c11325021b6b6f8e74.zip
gcc-5a5a3bc5fa14664be26748c11325021b6b6f8e74.tar.gz
gcc-5a5a3bc5fa14664be26748c11325021b6b6f8e74.tar.bz2
Add a function for getting the ABI of a call insn target
This patch replaces get_call_reg_set_usage with insn_callee_abi, which returns the ABI of the target of a call insn. The ABI's full_reg_clobbers corresponds to regs_invalidated_by_call, whereas many callers instead passed call_used_or_fixed_regs, i.e.: (regs_invalidated_by_call | fixed_reg_set) The patch slavishly preserves the "| fixed_reg_set" for these callers; later patches will clean this up. 2019-09-30 Richard Sandiford <richard.sandiford@arm.com> gcc/ * target.def (insn_callee_abi): New hook. (remove_extra_call_preserved_regs): Delete. * doc/tm.texi.in (TARGET_INSN_CALLEE_ABI): New macro. (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): Delete. * doc/tm.texi: Regenerate. * targhooks.h (default_remove_extra_call_preserved_regs): Delete. * targhooks.c (default_remove_extra_call_preserved_regs): Delete. * config/aarch64/aarch64.c (aarch64_simd_call_p): Constify the insn argument. (aarch64_remove_extra_call_preserved_regs): Delete. (aarch64_insn_callee_abi): New function. (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): Delete. (TARGET_INSN_CALLEE_ABI): New macro. * rtl.h (get_call_fndecl): Declare. (cgraph_rtl_info): Fix formatting. Tweak comment for function_used_regs. Remove function_used_regs_valid. * rtlanal.c (get_call_fndecl): Moved from final.c * function-abi.h (insn_callee_abi): Declare. (target_function_abi_info): Mention insn_callee_abi. * function-abi.cc (fndecl_abi): Handle flag_ipa_ra in a similar way to get_call_reg_set_usage did. (insn_callee_abi): New function. * regs.h (get_call_reg_set_usage): Delete. * final.c: Include function-abi.h. (collect_fn_hard_reg_usage): Add fixed and stack registers to function_used_regs before the main loop rather than afterwards. Use insn_callee_abi instead of get_call_reg_set_usage. Exit early if function_used_regs ends up not being useful. (get_call_fndecl): Move to rtlanal.c (get_call_cgraph_rtl_info, get_call_reg_set_usage): Delete. * caller-save.c: Include function-abi.h. (setup_save_areas, save_call_clobbered_regs): Use insn_callee_abi instead of get_call_reg_set_usage. * cfgcleanup.c: Include function-abi.h. (old_insns_match_p): Use insn_callee_abi instead of get_call_reg_set_usage. * cgraph.h (cgraph_node::rtl_info): Take a const_tree instead of a tree. * cgraph.c (cgraph_node::rtl_info): Likewise. Initialize function_used_regs. * df-scan.c: Include function-abi.h. (df_get_call_refs): Use insn_callee_abi instead of get_call_reg_set_usage. * ira-lives.c: Include function-abi.h. (process_bb_node_lives): Use insn_callee_abi instead of get_call_reg_set_usage. * lra-lives.c: Include function-abi.h. (process_bb_lives): Use insn_callee_abi instead of get_call_reg_set_usage. * postreload.c: Include function-abi.h. (reload_combine): Use insn_callee_abi instead of get_call_reg_set_usage. * regcprop.c: Include function-abi.h. (copyprop_hardreg_forward_1): Use insn_callee_abi instead of get_call_reg_set_usage. * resource.c: Include function-abi.h. (mark_set_resources, mark_target_live_regs): Use insn_callee_abi instead of get_call_reg_set_usage. * var-tracking.c: Include function-abi.h. (dataflow_set_clear_at_call): Use insn_callee_abi instead of get_call_reg_set_usage. From-SVN: r276309
Diffstat (limited to 'gcc/final.c')
-rw-r--r--gcc/final.c104
1 files changed, 20 insertions, 84 deletions
diff --git a/gcc/final.c b/gcc/final.c
index ae8ff22..7cf9ef1 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see
#include "asan.h"
#include "rtl-iter.h"
#include "print-rtl.h"
+#include "function-abi.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data declarations. */
@@ -230,7 +231,6 @@ static int alter_cond (rtx);
#endif
static int align_fuzz (rtx, rtx, int, unsigned);
static void collect_fn_hard_reg_usage (void);
-static tree get_call_fndecl (rtx_insn *);
/* Initialize data in final at the beginning of a compilation. */
@@ -4994,7 +4994,16 @@ collect_fn_hard_reg_usage (void)
if (!targetm.call_fusage_contains_non_callee_clobbers)
return;
- CLEAR_HARD_REG_SET (function_used_regs);
+ /* Be conservative - mark fixed and global registers as used. */
+ function_used_regs = fixed_reg_set;
+
+#ifdef STACK_REGS
+ /* Handle STACK_REGS conservatively, since the df-framework does not
+ provide accurate information for them. */
+
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ SET_HARD_REG_BIT (function_used_regs, i);
+#endif
for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn))
{
@@ -5005,96 +5014,23 @@ collect_fn_hard_reg_usage (void)
if (CALL_P (insn)
&& !self_recursive_call_p (insn))
- {
- if (!get_call_reg_set_usage (insn, &insn_used_regs,
- call_used_or_fixed_regs))
- return;
-
- function_used_regs |= insn_used_regs;
- }
+ function_used_regs
+ |= insn_callee_abi (insn).full_and_partial_reg_clobbers ();
find_all_hard_reg_sets (insn, &insn_used_regs, false);
function_used_regs |= insn_used_regs;
- }
- /* Be conservative - mark fixed and global registers as used. */
- function_used_regs |= fixed_reg_set;
-
-#ifdef STACK_REGS
- /* Handle STACK_REGS conservatively, since the df-framework does not
- provide accurate information for them. */
-
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- SET_HARD_REG_BIT (function_used_regs, i);
-#endif
+ if (hard_reg_set_subset_p (crtl->abi->full_and_partial_reg_clobbers (),
+ function_used_regs))
+ return;
+ }
- /* The information we have gathered is only interesting if it exposes a
- register from the call_used_regs that is not used in this function. */
- if (hard_reg_set_subset_p (call_used_or_fixed_regs, function_used_regs))
- return;
+ /* Mask out fully-saved registers, so that they don't affect equality
+ comparisons between function_abis. */
+ function_used_regs &= crtl->abi->full_and_partial_reg_clobbers ();
node = cgraph_node::rtl_info (current_function_decl);
gcc_assert (node != NULL);
node->function_used_regs = function_used_regs;
- node->function_used_regs_valid = 1;
-}
-
-/* Get the declaration of the function called by INSN. */
-
-static tree
-get_call_fndecl (rtx_insn *insn)
-{
- rtx note, datum;
-
- note = find_reg_note (insn, REG_CALL_DECL, NULL_RTX);
- if (note == NULL_RTX)
- return NULL_TREE;
-
- datum = XEXP (note, 0);
- if (datum != NULL_RTX)
- return SYMBOL_REF_DECL (datum);
-
- return NULL_TREE;
-}
-
-/* Return the cgraph_rtl_info of the function called by INSN. Returns NULL for
- call targets that can be overwritten. */
-
-static struct cgraph_rtl_info *
-get_call_cgraph_rtl_info (rtx_insn *insn)
-{
- tree fndecl;
-
- if (insn == NULL_RTX)
- return NULL;
-
- fndecl = get_call_fndecl (insn);
- if (fndecl == NULL_TREE
- || !decl_binds_to_current_def_p (fndecl))
- return NULL;
-
- return cgraph_node::rtl_info (fndecl);
-}
-
-/* Find hard registers used by function call instruction INSN, and return them
- in REG_SET. Return DEFAULT_SET in REG_SET if not found. */
-
-bool
-get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set,
- HARD_REG_SET default_set)
-{
- if (flag_ipa_ra)
- {
- struct cgraph_rtl_info *node = get_call_cgraph_rtl_info (insn);
- if (node != NULL
- && node->function_used_regs_valid)
- {
- *reg_set = node->function_used_regs & default_set;
- return true;
- }
- }
- *reg_set = default_set;
- targetm.remove_extra_call_preserved_regs (insn, reg_set);
- return false;
}