aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-09-30 16:20:04 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-09-30 16:20:04 +0000
commit737d6a1a1745bdd4041e73800a842a1086967d5d (patch)
tree1347aa114cf2ffddae7f64d2e90f4d8389e1aba9
parent6ee2cc70024253d2670a4a317158b2a65251a1d1 (diff)
downloadgcc-737d6a1a1745bdd4041e73800a842a1086967d5d.zip
gcc-737d6a1a1745bdd4041e73800a842a1086967d5d.tar.gz
gcc-737d6a1a1745bdd4041e73800a842a1086967d5d.tar.bz2
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
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/gcn/gcn.c2
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/ia64/ia64.h2
-rw-r--r--gcc/config/mips/mips.c2
-rw-r--r--gcc/config/msp430/msp430.h2
-rw-r--r--gcc/config/rs6000/rs6000.h2
-rw-r--r--gcc/config/sh/sh.c2
-rw-r--r--gcc/reginfo.c22
-rw-r--r--gcc/rtl.h5
-rw-r--r--gcc/targhooks.c6
11 files changed, 44 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59bfeb2..86caf6e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,25 @@
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
identifier instead of an rtx_insn.
* doc/tm.texi: Regenerate.
diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
index 50ae8e1..b5f09da 100644
--- a/gcc/config/gcn/gcn.c
+++ b/gcc/config/gcn/gcn.c
@@ -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);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 885846e..9fe1f45 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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 \
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index d9d78fd..fc985b4 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -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 */
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 91dd94b..648d95f 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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;
}
diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h
index 36b715d..3449bd4 100644
--- a/gcc/config/msp430/msp430.h
+++ b/gcc/config/msp430/msp430.h
@@ -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
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 0156448..27373c5 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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 \
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 34c4c8f..9917f2b 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -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. */
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index f084c0e..265157f 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -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;
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index d798562..554608c 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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 */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 6105137..5445038 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -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;
}