summaryrefslogtreecommitdiff
path: root/gcc/sel-sched.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-09-30 16:21:39 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-09-30 16:21:39 +0000
commit497b699b93759c7f84527f49a9644c3ea692405d (patch)
treeb2a1867421a87e4da2ffeeecd6244839917cf052 /gcc/sel-sched.c
parent2e2c6df346ab70eda7378a750cb96a1792de5b3b (diff)
Remove global call sets: sel-sched.c
The main change here is to replace a crosses_call boolean with a bitmask of the ABIs used by the crossed calls. For space reasons, I didn't also add a HARD_REG_SET that tracks the set of registers that are actually clobbered, which means that this is the one part of the series that doesn't benefit from -fipa-ra. The existing FIXME suggests that the current structures aren't the preferred way of representing this anyhow, and the pass already makes conservative assumptions about call-crossing registers. 2019-09-30 Richard Sandiford <richard.sandiford@arm.com> gcc/ * sel-sched-ir.h (_def::crosses_call): Replace with... (_def::crossed_call_abis): ..this new field. (def_list_add): Take a mask of ABIs instead of a crosses_call boolean. * sel-sched-ir.c (def_list_add): Likewise. Update initialization of _def accordingly. * sel-sched.c: Include function-abi.h. (hard_regs_data::regs_for_call_clobbered): Delete. (reg_rename::crosses_call): Replace with... (reg_rename::crossed_call_abis): ...this new field. (fur_static_params::crosses_call): Replace with... (fur_static_params::crossed_call_abis): ...this new field. (init_regs_for_mode): Don't initialize sel_hrd.regs_for_call_clobbered. (init_hard_regs_data): Use crtl->abi to test which registers the current function would need to save before it uses them. (mark_unavailable_hard_regs): Update handling of call-clobbered registers, using call_clobbers_in_region to find out which registers might be call-clobbered (but without taking -fipa-ra into account for now). Remove separate handling of partially call-clobbered registers. (verify_target_availability): Use crossed_call_abis instead of crosses_call. (get_spec_check_type_for_insn, find_used_regs): Likewise. (fur_orig_expr_found, fur_on_enter, fur_orig_expr_not_found): Likewise. From-SVN: r276336
Diffstat (limited to 'gcc/sel-sched.c')
-rw-r--r--gcc/sel-sched.c78
1 files changed, 36 insertions, 42 deletions
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index bf370b5a5d8..652784e79ed 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "sel-sched-dump.h"
#include "sel-sched.h"
#include "dbgcnt.h"
+#include "function-abi.h"
/* Implementation of selective scheduling approach.
The below implementation follows the original approach with the following
@@ -302,10 +303,6 @@ struct hard_regs_data
that the whole set is not computed yet. */
HARD_REG_SET regs_for_rename[FIRST_PSEUDO_REGISTER];
- /* For every mode, this stores registers not available due to
- call clobbering. */
- HARD_REG_SET regs_for_call_clobbered[NUM_MACHINE_MODES];
-
/* All registers that are used or call used. */
HARD_REG_SET regs_ever_used;
@@ -325,8 +322,8 @@ struct reg_rename
/* These are *available* for renaming. */
HARD_REG_SET available_for_renaming;
- /* Whether this code motion path crosses a call. */
- bool crosses_call;
+ /* The set of ABIs used by calls that the code motion path crosses. */
+ unsigned int crossed_call_abis : NUM_ABI_IDS;
};
/* A global structure that contains the needed information about harg
@@ -390,8 +387,8 @@ struct fur_static_params
/* Pointer to the list of original insns definitions. */
def_list_t *original_insns;
- /* True if a code motion path contains a CALL insn. */
- bool crosses_call;
+ /* The set of ABIs used by calls that the code motion path crosses. */
+ unsigned int crossed_call_abis : NUM_ABI_IDS;
};
typedef struct fur_static_params *fur_static_params_p;
@@ -1067,7 +1064,6 @@ init_regs_for_mode (machine_mode mode)
int cur_reg;
CLEAR_HARD_REG_SET (sel_hrd.regs_for_mode[mode]);
- CLEAR_HARD_REG_SET (sel_hrd.regs_for_call_clobbered[mode]);
for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
{
@@ -1102,10 +1098,6 @@ init_regs_for_mode (machine_mode mode)
if (i >= 0)
continue;
- if (targetm.hard_regno_call_part_clobbered (0, cur_reg, mode))
- SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode],
- cur_reg);
-
/* If the CUR_REG passed all the checks above,
then it's ok. */
SET_HARD_REG_BIT (sel_hrd.regs_for_mode[mode], cur_reg);
@@ -1123,7 +1115,8 @@ init_hard_regs_data (void)
CLEAR_HARD_REG_SET (sel_hrd.regs_ever_used);
for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
- if (df_regs_ever_live_p (cur_reg) || call_used_or_fixed_reg_p (cur_reg))
+ if (df_regs_ever_live_p (cur_reg)
+ || crtl->abi->clobbers_full_reg_p (cur_reg))
SET_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg);
/* Initialize registers that are valid based on mode when this is
@@ -1193,7 +1186,7 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs);
/* Give a chance for original register, if it isn't in used_regs. */
- if (!def->crosses_call)
+ if (!def->crossed_call_abis)
CLEAR_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, regno);
return;
@@ -1224,13 +1217,20 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
reg_rename_p->unavailable_hard_regs |= sel_hrd.stack_regs;
#endif
- /* If there's a call on this path, make regs from call_used_or_fixed_regs
- unavailable. */
- if (def->crosses_call)
- reg_rename_p->unavailable_hard_regs |= call_used_or_fixed_regs;
+ mode = GET_MODE (orig_dest);
+
+ /* If there's a call on this path, make regs from full_reg_clobbers
+ unavailable.
- /* Stop here before reload: we need FRAME_REGS, STACK_REGS, and crosses_call,
- but not register classes. */
+ ??? It would be better to track the set of clobbered registers
+ directly, but that would be quite expensive in a def_t. */
+ if (def->crossed_call_abis)
+ reg_rename_p->unavailable_hard_regs
+ |= call_clobbers_in_region (def->crossed_call_abis,
+ reg_class_contents[ALL_REGS], mode);
+
+ /* Stop here before reload: we need FRAME_REGS, STACK_REGS, and
+ crossed_call_abis, but not register classes. */
if (!reload_completed)
return;
@@ -1238,19 +1238,11 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
register class. */
reg_rename_p->available_for_renaming = reg_class_contents[cl];
- mode = GET_MODE (orig_dest);
-
/* Leave only registers available for this mode. */
if (!sel_hrd.regs_for_mode_ok[mode])
init_regs_for_mode (mode);
reg_rename_p->available_for_renaming &= sel_hrd.regs_for_mode[mode];
- /* Exclude registers that are partially call clobbered. */
- if (def->crosses_call
- && !targetm.hard_regno_call_part_clobbered (0, regno, mode))
- reg_rename_p->available_for_renaming
- &= ~sel_hrd.regs_for_call_clobbered[mode];
-
/* Leave only those that are ok to rename. */
EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming,
0, cur_reg, hrsi)
@@ -1481,7 +1473,7 @@ choose_best_pseudo_reg (regset used_regs,
/* Don't let register cross a call if it doesn't already
cross one. This condition is written in accordance with
that in sched-deps.c sched_analyze_reg(). */
- if (!reg_rename_p->crosses_call
+ if (!reg_rename_p->crossed_call_abis
|| REG_N_CALLS_CROSSED (orig_regno) > 0)
return gen_rtx_REG (mode, orig_regno);
}
@@ -1508,7 +1500,8 @@ choose_best_pseudo_reg (regset used_regs,
max_regno = max_reg_num ();
maybe_extend_reg_info_p ();
- REG_N_CALLS_CROSSED (REGNO (new_reg)) = reg_rename_p->crosses_call ? 1 : 0;
+ REG_N_CALLS_CROSSED (REGNO (new_reg))
+ = reg_rename_p->crossed_call_abis ? 1 : 0;
return new_reg;
}
@@ -1560,7 +1553,8 @@ verify_target_availability (expr_t expr, regset used_regs,
as well. */
gcc_assert (scheduled_something_on_previous_fence || !live_available
|| !hard_available
- || (!reload_completed && reg_rename_p->crosses_call
+ || (!reload_completed
+ && reg_rename_p->crossed_call_abis
&& REG_N_CALLS_CROSSED (regno) == 0));
}
@@ -3248,7 +3242,7 @@ get_spec_check_type_for_insn (insn_t insn, expr_t expr)
All the original operations found during the traversal are saved in the
ORIGINAL_INSNS list.
- REG_RENAME_P->CROSSES_CALL is true, if there is a call insn on the path
+ REG_RENAME_P->CROSSED_CALL_ABIS is true, if there is a call insn on the path
from INSN to original insn. In this case CALL_USED_REG_SET will be added
to unavailable hard regs at the point original operation is found. */
@@ -3269,7 +3263,7 @@ find_used_regs (insn_t insn, av_set_t orig_ops, regset used_regs,
bitmap_clear (code_motion_visited_blocks);
/* Init parameters for code_motion_path_driver. */
- sparams.crosses_call = false;
+ sparams.crossed_call_abis = 0;
sparams.original_insns = original_insns;
sparams.used_regs = used_regs;
@@ -3278,7 +3272,7 @@ find_used_regs (insn_t insn, av_set_t orig_ops, regset used_regs,
res = code_motion_path_driver (insn, orig_ops, NULL, &lparams, &sparams);
- reg_rename_p->crosses_call |= sparams.crosses_call;
+ reg_rename_p->crossed_call_abis |= sparams.crossed_call_abis;
gcc_assert (res == 1);
gcc_assert (original_insns && *original_insns);
@@ -6006,7 +6000,7 @@ move_op_orig_expr_found (insn_t insn, expr_t expr,
/* The function is called when original expr is found.
INSN - current insn traversed, EXPR - the corresponding expr found,
- crosses_call and original_insns in STATIC_PARAMS are updated. */
+ crossed_call_abis and original_insns in STATIC_PARAMS are updated. */
static void
fur_orig_expr_found (insn_t insn, expr_t expr ATTRIBUTE_UNUSED,
cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
@@ -6016,9 +6010,9 @@ fur_orig_expr_found (insn_t insn, expr_t expr ATTRIBUTE_UNUSED,
regset tmp;
if (CALL_P (insn))
- params->crosses_call = true;
+ params->crossed_call_abis |= 1 << insn_callee_abi (insn).id ();
- def_list_add (params->original_insns, insn, params->crosses_call);
+ def_list_add (params->original_insns, insn, params->crossed_call_abis);
/* Mark the registers that do not meet the following condition:
(2) not among the live registers of the point
@@ -6176,10 +6170,10 @@ fur_on_enter (insn_t insn ATTRIBUTE_UNUSED, cmpd_local_params_p local_params,
least one insn in ORIGINAL_INSNS. */
gcc_assert (*sparams->original_insns);
- /* Adjust CROSSES_CALL, since we may have come to this block along
+ /* Adjust CROSSED_CALL_ABIS, since we may have come to this block along
different path. */
- DEF_LIST_DEF (*sparams->original_insns)->crosses_call
- |= sparams->crosses_call;
+ DEF_LIST_DEF (*sparams->original_insns)->crossed_call_abis
+ |= sparams->crossed_call_abis;
}
else
local_params->old_original_insns = *sparams->original_insns;
@@ -6233,7 +6227,7 @@ fur_orig_expr_not_found (insn_t insn, av_set_t orig_ops, void *static_params)
fur_static_params_p sparams = (fur_static_params_p) static_params;
if (CALL_P (insn))
- sparams->crosses_call = true;
+ sparams->crossed_call_abis |= 1 << insn_callee_abi (insn).id ();
else if (DEBUG_INSN_P (insn))
return true;