Pass an ABI to choose_hard_reg_mode

choose_hard_reg_mode previously took a boolean saying whether the
mode needed to be call-preserved.  This patch replaces it with an
optional ABI pointer instead, so that the function can use that
to test whether a value is call-saved.

default_dwarf_frame_reg_mode uses eh_edge_abi because that's the
ABI that matters for unwinding.  Targets need to override the hook
if they want something different.

2019-09-30  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* rtl.h (predefined_function_abi): Declare.
	(choose_hard_reg_mode): Take a pointer to a predefined_function_abi
	instead of a boolean call_save flag.
	* config/gcn/gcn.c (gcn_hard_regno_caller_save_mode): Update call
	accordingly.
	* config/i386/i386.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
	* config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
	* config/mips/mips.c (mips_hard_regno_caller_save_mode): Likewise.
	* config/msp430/msp430.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
	* config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
	* config/sh/sh.c (sh_hard_regno_caller_save_mode): Likewise.
	* reginfo.c (init_reg_modes_target): Likewise.
	(choose_hard_reg_mode): Take a pointer to a predefined_function_abi
	instead of a boolean call_save flag.
	* targhooks.c: Include function-abi.h.
	(default_dwarf_frame_reg_mode): Update call to choose_hard_reg_mode,
	using eh_edge_abi to choose the mode.

From-SVN: r276312
This commit is contained in:
Richard Sandiford 2019-09-30 16:20:04 +00:00 committed by Richard Sandiford
parent 6ee2cc7002
commit 737d6a1a17
11 changed files with 44 additions and 23 deletions

View File

@ -1,3 +1,23 @@
2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
* rtl.h (predefined_function_abi): Declare.
(choose_hard_reg_mode): Take a pointer to a predefined_function_abi
instead of a boolean call_save flag.
* config/gcn/gcn.c (gcn_hard_regno_caller_save_mode): Update call
accordingly.
* config/i386/i386.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/mips/mips.c (mips_hard_regno_caller_save_mode): Likewise.
* config/msp430/msp430.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
* config/sh/sh.c (sh_hard_regno_caller_save_mode): Likewise.
* reginfo.c (init_reg_modes_target): Likewise.
(choose_hard_reg_mode): Take a pointer to a predefined_function_abi
instead of a boolean call_save flag.
* targhooks.c: Include function-abi.h.
(default_dwarf_frame_reg_mode): Update call to choose_hard_reg_mode,
using eh_edge_abi to choose the mode.
2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
* target.def (hard_regno_call_part_clobbered): Take an ABI

View File

@ -3017,7 +3017,7 @@ machine_mode
gcn_hard_regno_caller_save_mode (unsigned int regno, unsigned int nregs,
machine_mode regmode)
{
machine_mode result = choose_hard_reg_mode (regno, nregs, false);
machine_mode result = choose_hard_reg_mode (regno, nregs, NULL);
if (VECTOR_MODE_P (result) && !VECTOR_MODE_P (regmode))
result = (nregs == 1 ? SImode : DImode);

View File

@ -1258,7 +1258,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
(CC_REGNO_P (REGNO) ? VOIDmode \
: (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \
: (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false) \
: (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), NULL) \
: (MODE) == HImode && !((GENERAL_REGNO_P (REGNO) \
&& TARGET_PARTIAL_REG_STALL) \
|| MASK_REGNO_P (REGNO)) ? SImode \

View File

@ -562,7 +562,7 @@ while (0)
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
((FR_REGNO_P (REGNO) && (NREGS) == 1) ? RFmode \
: choose_hard_reg_mode ((REGNO), (NREGS), false))
: choose_hard_reg_mode ((REGNO), (NREGS), NULL))
/* Handling Leaf Functions */

View File

@ -22174,7 +22174,7 @@ mips_hard_regno_caller_save_mode (unsigned int regno,
/* For performance, avoid saving/restoring upper parts of a register
by returning MODE as save mode when the mode is known. */
if (mode == VOIDmode)
return choose_hard_reg_mode (regno, nregs, false);
return choose_hard_reg_mode (regno, nregs, NULL);
else
return mode;
}

View File

@ -467,7 +467,7 @@ typedef struct
when spilling hard registers when they may contain PSImode values. */
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \
((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode \
: choose_hard_reg_mode ((REGNO), (NREGS), false))
: choose_hard_reg_mode ((REGNO), (NREGS), NULL))
#define ACCUMULATE_OUTGOING_ARGS 1

View File

@ -1038,7 +1038,7 @@ enum data_align { align_abi, align_opt, align_both };
? DFmode \
: (MODE) == TDmode && FP_REGNO_P (REGNO) \
? DImode \
: choose_hard_reg_mode ((REGNO), (NREGS), false))
: choose_hard_reg_mode ((REGNO), (NREGS), NULL))
#define VSX_VECTOR_MODE(MODE) \
((MODE) == V4SFmode \

View File

@ -10637,7 +10637,7 @@ sh_hard_regno_caller_save_mode (unsigned int regno, unsigned int nregs,
&& ((regno - FIRST_FP_REG) & 1) == 0)))
return mode;
return choose_hard_reg_mode (regno, nregs, false);
return choose_hard_reg_mode (regno, nregs, NULL);
}
/* Implement TARGET_CAN_CHANGE_MODE_CLASS. */

View File

@ -442,7 +442,7 @@ init_reg_modes_target (void)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
reg_raw_mode[i] = choose_hard_reg_mode (i, 1, NULL);
/* If we couldn't find a valid mode, just use the previous mode
if it is suitable, otherwise fall back on word_mode. */
@ -550,10 +550,11 @@ memory_move_secondary_cost (machine_mode mode, reg_class_t rclass,
/* Return a machine mode that is legitimate for hard reg REGNO and large
enough to save nregs. If we can't find one, return VOIDmode.
If CALL_SAVED is true, only consider modes that are call saved. */
If ABI is nonnull, only consider modes that are preserved across
calls that use ABI. */
machine_mode
choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
unsigned int nregs, bool call_saved)
unsigned int nregs, const predefined_function_abi *abi)
{
unsigned int /* machine_mode */ m;
machine_mode found_mode = VOIDmode, mode;
@ -567,32 +568,28 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
|| !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& (!abi || !abi->clobbers_reg_p (mode, regno))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
|| !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& (!abi || !abi->clobbers_reg_p (mode, regno))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
|| !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& (!abi || !abi->clobbers_reg_p (mode, regno))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
|| !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& (!abi || !abi->clobbers_reg_p (mode, regno))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
@ -605,8 +602,7 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
mode = (machine_mode) m;
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
|| !targetm.hard_regno_call_part_clobbered (0, regno, mode)))
&& (!abi || !abi->clobbers_reg_p (mode, regno)))
return mode;
}

View File

@ -36,6 +36,8 @@ along with GCC; see the file COPYING3. If not see
#include "hard-reg-set.h"
class predefined_function_abi;
/* Value used by some passes to "recognize" noop moves as valid
instructions. */
#define NOOP_MOVE_INSN_CODE INT_MAX
@ -3410,7 +3412,8 @@ extern bool val_signbit_known_clear_p (machine_mode,
unsigned HOST_WIDE_INT);
/* In reginfo.c */
extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int, bool);
extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
const predefined_function_abi *);
extern const HARD_REG_SET &simplifiable_subregs (const subreg_shape &);
/* In emit-rtl.c */

View File

@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see
#include "real.h"
#include "langhooks.h"
#include "sbitmap.h"
#include "function-abi.h"
bool
default_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
@ -1928,8 +1929,9 @@ default_dwarf_frame_reg_mode (int regno)
{
machine_mode save_mode = reg_raw_mode[regno];
if (targetm.hard_regno_call_part_clobbered (0, regno, save_mode))
save_mode = choose_hard_reg_mode (regno, 1, true);
if (targetm.hard_regno_call_part_clobbered (eh_edge_abi.id (),
regno, save_mode))
save_mode = choose_hard_reg_mode (regno, 1, &eh_edge_abi);
return save_mode;
}