aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-11-01 11:49:34 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-11-01 11:49:34 +0000
commitef1d3b57d2d00795c6eb01fe6b8ef6f413163c67 (patch)
treeaf7a96746cc35a998026456f2e51bdbaea611a6a /gcc
parentef339d6e2e846ba7ff544def1d79f10762da223d (diff)
downloadgcc-ef1d3b57d2d00795c6eb01fe6b8ef6f413163c67.zip
gcc-ef1d3b57d2d00795c6eb01fe6b8ef6f413163c67.tar.gz
gcc-ef1d3b57d2d00795c6eb01fe6b8ef6f413163c67.tar.bz2
Add a fixed_size_mode class
This patch adds a fixed_size_mode machine_mode wrapper for modes that are known to have a fixed size. That applies to all current modes, but future patches will add support for variable-sized modes. The use of this class should be pretty restricted. One important use case is to hold the mode of static data, which can never be variable-sized with current file formats. Another is to hold the modes of registers involved in __builtin_apply and __builtin_result, since those interfaces don't cope well with variable-sized data. The class can also be useful when reinterpreting the contents of a fixed-length bit string as a different kind of value. 2017-11-01 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * machmode.h (fixed_size_mode): New class. * rtl.h (get_pool_mode): Return fixed_size_mode. * gengtype.c (main): Add fixed_size_mode. * target.def (get_raw_result_mode): Return a fixed_size_mode. (get_raw_arg_mode): Likewise. * doc/tm.texi: Regenerate. * targhooks.h (default_get_reg_raw_mode): Return a fixed_size_mode. * targhooks.c (default_get_reg_raw_mode): Likewise. * config/ia64/ia64.c (ia64_get_reg_raw_mode): Likewise. * config/mips/mips.c (mips_get_reg_raw_mode): Likewise. * config/msp430/msp430.c (msp430_get_raw_arg_mode): Likewise. (msp430_get_raw_result_mode): Likewise. * config/avr/avr-protos.h (regmask): Use as_a <fixed_side_mode> * dbxout.c (dbxout_parms): Require fixed-size modes. * expr.c (copy_blkmode_from_reg, copy_blkmode_to_reg): Likewise. * gimple-ssa-store-merging.c (encode_tree_to_bitpos): Likewise. * omp-low.c (lower_oacc_reductions): Likewise. * simplify-rtx.c (simplify_immed_subreg): Take fixed_size_modes. (simplify_subreg): Update accordingly. * varasm.c (constant_descriptor_rtx::mode): Change to fixed_size_mode. (force_const_mem): Update accordingly. Return NULL_RTX for modes that aren't fixed-size. (get_pool_mode): Return a fixed_size_mode. (output_constant_pool_2): Take a fixed_size_mode. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r254300
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/config/avr/avr-protos.h2
-rw-r--r--gcc/config/ia64/ia64.c4
-rw-r--r--gcc/config/mips/mips.c3
-rw-r--r--gcc/config/msp430/msp430.c7
-rw-r--r--gcc/dbxout.c13
-rw-r--r--gcc/doc/tm.texi4
-rw-r--r--gcc/expr.c15
-rw-r--r--gcc/gengtype.c1
-rw-r--r--gcc/gimple-ssa-store-merging.c5
-rw-r--r--gcc/machmode.h33
-rw-r--r--gcc/omp-low.c6
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/simplify-rtx.c19
-rw-r--r--gcc/target.def4
-rw-r--r--gcc/targhooks.c6
-rw-r--r--gcc/targhooks.h2
-rw-r--r--gcc/varasm.c16
18 files changed, 131 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 19ed953..f35b9541 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,6 +2,35 @@
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
+ * machmode.h (fixed_size_mode): New class.
+ * rtl.h (get_pool_mode): Return fixed_size_mode.
+ * gengtype.c (main): Add fixed_size_mode.
+ * target.def (get_raw_result_mode): Return a fixed_size_mode.
+ (get_raw_arg_mode): Likewise.
+ * doc/tm.texi: Regenerate.
+ * targhooks.h (default_get_reg_raw_mode): Return a fixed_size_mode.
+ * targhooks.c (default_get_reg_raw_mode): Likewise.
+ * config/ia64/ia64.c (ia64_get_reg_raw_mode): Likewise.
+ * config/mips/mips.c (mips_get_reg_raw_mode): Likewise.
+ * config/msp430/msp430.c (msp430_get_raw_arg_mode): Likewise.
+ (msp430_get_raw_result_mode): Likewise.
+ * config/avr/avr-protos.h (regmask): Use as_a <fixed_side_mode>
+ * dbxout.c (dbxout_parms): Require fixed-size modes.
+ * expr.c (copy_blkmode_from_reg, copy_blkmode_to_reg): Likewise.
+ * gimple-ssa-store-merging.c (encode_tree_to_bitpos): Likewise.
+ * omp-low.c (lower_oacc_reductions): Likewise.
+ * simplify-rtx.c (simplify_immed_subreg): Take fixed_size_modes.
+ (simplify_subreg): Update accordingly.
+ * varasm.c (constant_descriptor_rtx::mode): Change to fixed_size_mode.
+ (force_const_mem): Update accordingly. Return NULL_RTX for modes
+ that aren't fixed-size.
+ (get_pool_mode): Return a fixed_size_mode.
+ (output_constant_pool_2): Take a fixed_size_mode.
+
+2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
* doc/rtl.texi (vec_series): Document.
(const): Say that the operand can be a vec_series.
* rtl.def (VEC_SERIES): New rtx code.
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 9ed9480..089e209 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -131,7 +131,7 @@ extern bool avr_casei_sequence_check_operands (rtx *xop);
static inline unsigned
regmask (machine_mode mode, unsigned regno)
{
- return ((1u << GET_MODE_SIZE (mode)) - 1) << regno;
+ return ((1u << GET_MODE_SIZE (as_a <fixed_size_mode> (mode))) - 1) << regno;
}
extern void avr_fix_inputs (rtx*, unsigned, unsigned);
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 3d38365..84a5b56 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -329,7 +329,7 @@ static tree ia64_fold_builtin (tree, int, tree *, bool);
static tree ia64_builtin_decl (unsigned, bool);
static reg_class_t ia64_preferred_reload_class (rtx, reg_class_t);
-static machine_mode ia64_get_reg_raw_mode (int regno);
+static fixed_size_mode ia64_get_reg_raw_mode (int regno);
static section * ia64_hpux_function_section (tree, enum node_frequency,
bool, bool);
@@ -11328,7 +11328,7 @@ ia64_dconst_0_375 (void)
return ia64_dconst_0_375_rtx;
}
-static machine_mode
+static fixed_size_mode
ia64_get_reg_raw_mode (int regno)
{
if (FR_REGNO_P (regno))
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index c836748..7dde705 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -1132,7 +1132,6 @@ static rtx mips_find_pic_call_symbol (rtx_insn *, rtx, bool);
static int mips_register_move_cost (machine_mode, reg_class_t,
reg_class_t);
static unsigned int mips_function_arg_boundary (machine_mode, const_tree);
-static machine_mode mips_get_reg_raw_mode (int regno);
static rtx mips_gen_const_int_vector_shuffle (machine_mode, int);
/* This hash table keeps track of implicit "mips16" and "nomips16" attributes
@@ -6111,7 +6110,7 @@ mips_function_arg_boundary (machine_mode mode, const_tree type)
/* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */
-static machine_mode
+static fixed_size_mode
mips_get_reg_raw_mode (int regno)
{
if (TARGET_FLOATXX && FP_REG_P (regno))
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 9466d09..0ee0b6c 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -1402,16 +1402,17 @@ msp430_return_in_memory (const_tree ret_type, const_tree fntype ATTRIBUTE_UNUSED
#undef TARGET_GET_RAW_ARG_MODE
#define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
-static machine_mode
+static fixed_size_mode
msp430_get_raw_arg_mode (int regno)
{
- return (regno == ARG_POINTER_REGNUM) ? VOIDmode : Pmode;
+ return as_a <fixed_size_mode> (regno == ARG_POINTER_REGNUM
+ ? VOIDmode : Pmode);
}
#undef TARGET_GET_RAW_RESULT_MODE
#define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
-static machine_mode
+static fixed_size_mode
msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
{
return Pmode;
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 0615e84..49a8583 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -3393,12 +3393,16 @@ dbxout_parms (tree parms)
{
++debug_nesting;
emit_pending_bincls_if_required ();
+ fixed_size_mode rtl_mode, type_mode;
for (; parms; parms = DECL_CHAIN (parms))
if (DECL_NAME (parms)
&& TREE_TYPE (parms) != error_mark_node
&& DECL_RTL_SET_P (parms)
- && DECL_INCOMING_RTL (parms))
+ && DECL_INCOMING_RTL (parms)
+ /* We can't represent variable-sized types in this format. */
+ && is_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (parms)), &type_mode)
+ && is_a <fixed_size_mode> (GET_MODE (DECL_RTL (parms)), &rtl_mode))
{
tree eff_type;
char letter;
@@ -3555,10 +3559,9 @@ dbxout_parms (tree parms)
/* Make a big endian correction if the mode of the type of the
parameter is not the same as the mode of the rtl. */
if (BYTES_BIG_ENDIAN
- && TYPE_MODE (TREE_TYPE (parms)) != GET_MODE (DECL_RTL (parms))
- && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))) < UNITS_PER_WORD)
- number += (GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))
- - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parms))));
+ && type_mode != rtl_mode
+ && GET_MODE_SIZE (type_mode) < UNITS_PER_WORD)
+ number += GET_MODE_SIZE (rtl_mode) - GET_MODE_SIZE (type_mode);
}
else
/* ??? We don't know how to represent this argument. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cba3fa6..72606f5 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4551,11 +4551,11 @@ This macro has effect in @option{-fpcc-struct-return} mode, but it does
nothing when you use @option{-freg-struct-return} mode.
@end defmac
-@deftypefn {Target Hook} machine_mode TARGET_GET_RAW_RESULT_MODE (int @var{regno})
+@deftypefn {Target Hook} fixed_size_mode TARGET_GET_RAW_RESULT_MODE (int @var{regno})
This target hook returns the mode to be used when accessing raw return registers in @code{__builtin_return}. Define this macro if the value in @var{reg_raw_mode} is not correct.
@end deftypefn
-@deftypefn {Target Hook} machine_mode TARGET_GET_RAW_ARG_MODE (int @var{regno})
+@deftypefn {Target Hook} fixed_size_mode TARGET_GET_RAW_ARG_MODE (int @var{regno})
This target hook returns the mode to be used when accessing raw argument registers in @code{__builtin_apply_args}. Define this macro if the value in @var{reg_raw_mode} is not correct.
@end deftypefn
diff --git a/gcc/expr.c b/gcc/expr.c
index cb294bb..edcd7e8 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2628,9 +2628,10 @@ copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
rtx src = NULL, dst = NULL;
unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
- machine_mode mode = GET_MODE (srcreg);
- machine_mode tmode = GET_MODE (target);
- machine_mode copy_mode;
+ /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
+ fixed_size_mode mode = as_a <fixed_size_mode> (GET_MODE (srcreg));
+ fixed_size_mode tmode = as_a <fixed_size_mode> (GET_MODE (target));
+ fixed_size_mode copy_mode;
/* BLKmode registers created in the back-end shouldn't have survived. */
gcc_assert (mode != BLKmode);
@@ -2728,19 +2729,21 @@ copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
}
}
-/* Copy BLKmode value SRC into a register of mode MODE. Return the
+/* Copy BLKmode value SRC into a register of mode MODE_IN. Return the
register if it contains any data, otherwise return null.
This is used on targets that return BLKmode values in registers. */
rtx
-copy_blkmode_to_reg (machine_mode mode, tree src)
+copy_blkmode_to_reg (machine_mode mode_in, tree src)
{
int i, n_regs;
unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
unsigned int bitsize;
rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
- machine_mode dst_mode;
+ /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
+ fixed_size_mode mode = as_a <fixed_size_mode> (mode_in);
+ fixed_size_mode dst_mode;
gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index ec949a1..ad2be72 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -5197,6 +5197,7 @@ main (int argc, char **argv)
POS_HERE (do_scalar_typedef ("JCF_u2", &pos));
POS_HERE (do_scalar_typedef ("void", &pos));
POS_HERE (do_scalar_typedef ("machine_mode", &pos));
+ POS_HERE (do_scalar_typedef ("fixed_size_mode", &pos));
POS_HERE (do_typedef ("PTR",
create_pointer (resolve_typedef ("void", &pos)),
&pos));
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index 5a5b776..0bc4813 100644
--- a/gcc/gimple-ssa-store-merging.c
+++ b/gcc/gimple-ssa-store-merging.c
@@ -415,8 +415,11 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
The awkwardness comes from the fact that bitpos is counted from the
most significant bit of a byte. */
+ /* We must be dealing with fixed-size data at this point, since the
+ total size is also fixed. */
+ fixed_size_mode mode = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (expr)));
/* Allocate an extra byte so that we have space to shift into. */
- unsigned int byte_size = GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))) + 1;
+ unsigned int byte_size = GET_MODE_SIZE (mode) + 1;
unsigned char *tmpbuf = XALLOCAVEC (unsigned char, byte_size);
memset (tmpbuf, '\0', byte_size);
/* The store detection code should only have allowed constants that are
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 6667458..f5e5baa 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -652,6 +652,39 @@ GET_MODE_2XWIDER_MODE (const T &m)
extern const unsigned char mode_complex[NUM_MACHINE_MODES];
#define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE])
+/* Represents a machine mode that must have a fixed size. The main
+ use of this class is to represent the modes of objects that always
+ have static storage duration, such as constant pool entries.
+ (No current target supports the concept of variable-size static data.) */
+class fixed_size_mode
+{
+public:
+ typedef mode_traits<fixed_size_mode>::from_int from_int;
+
+ ALWAYS_INLINE fixed_size_mode () {}
+ ALWAYS_INLINE fixed_size_mode (from_int m) : m_mode (machine_mode (m)) {}
+ ALWAYS_INLINE fixed_size_mode (const scalar_mode &m) : m_mode (m) {}
+ ALWAYS_INLINE fixed_size_mode (const scalar_int_mode &m) : m_mode (m) {}
+ ALWAYS_INLINE fixed_size_mode (const scalar_float_mode &m) : m_mode (m) {}
+ ALWAYS_INLINE fixed_size_mode (const scalar_mode_pod &m) : m_mode (m) {}
+ ALWAYS_INLINE fixed_size_mode (const scalar_int_mode_pod &m) : m_mode (m) {}
+ ALWAYS_INLINE fixed_size_mode (const complex_mode &m) : m_mode (m) {}
+ ALWAYS_INLINE operator machine_mode () const { return m_mode; }
+
+ static bool includes_p (machine_mode);
+
+protected:
+ machine_mode m_mode;
+};
+
+/* Return true if MODE has a fixed size. */
+
+inline bool
+fixed_size_mode::includes_p (machine_mode)
+{
+ return true;
+}
+
extern opt_machine_mode mode_for_size (unsigned int, enum mode_class, int);
/* Return the machine mode to use for a MODE_INT of SIZE bits, if one
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index afa758b..33e633c 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -5067,8 +5067,10 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
v1 = v2 = v3 = var;
/* Determine position in reduction buffer, which may be used
- by target. */
- machine_mode mode = TYPE_MODE (TREE_TYPE (var));
+ by target. The parser has ensured that this is not a
+ variable-sized type. */
+ fixed_size_mode mode
+ = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (var)));
unsigned align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
offset = (offset + align - 1) & ~(align - 1);
tree off = build_int_cst (sizetype, offset);
diff --git a/gcc/rtl.h b/gcc/rtl.h
index a0f6965..53635a2 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3021,7 +3021,7 @@ extern rtx force_const_mem (machine_mode, rtx);
struct function;
extern rtx get_pool_constant (const_rtx);
extern rtx get_pool_constant_mark (rtx, bool *);
-extern machine_mode get_pool_mode (const_rtx);
+extern fixed_size_mode get_pool_mode (const_rtx);
extern rtx simplify_subtraction (rtx);
extern void decide_function_section (tree);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 8bee8ed..a6963ce 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -48,8 +48,6 @@ along with GCC; see the file COPYING3. If not see
static rtx neg_const_int (machine_mode, const_rtx);
static bool plus_minus_operand_p (const_rtx);
static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx);
-static rtx simplify_immed_subreg (machine_mode, rtx, machine_mode,
- unsigned int);
static rtx simplify_associative_operation (enum rtx_code, machine_mode,
rtx, rtx);
static rtx simplify_relational_operation_1 (enum rtx_code, machine_mode,
@@ -5806,8 +5804,8 @@ simplify_ternary_operation (enum rtx_code code, machine_mode mode,
and then repacking them again for OUTERMODE. */
static rtx
-simplify_immed_subreg (machine_mode outermode, rtx op,
- machine_mode innermode, unsigned int byte)
+simplify_immed_subreg (fixed_size_mode outermode, rtx op,
+ fixed_size_mode innermode, unsigned int byte)
{
enum {
value_bit = 8,
@@ -6175,7 +6173,18 @@ simplify_subreg (machine_mode outermode, rtx op,
|| CONST_DOUBLE_AS_FLOAT_P (op)
|| GET_CODE (op) == CONST_FIXED
|| GET_CODE (op) == CONST_VECTOR)
- return simplify_immed_subreg (outermode, op, innermode, byte);
+ {
+ /* simplify_immed_subreg deconstructs OP into bytes and constructs
+ the result from bytes, so it only works if the sizes of the modes
+ are known at compile time. Cases that apply to general modes
+ should be handled here before calling simplify_immed_subreg. */
+ fixed_size_mode fs_outermode, fs_innermode;
+ if (is_a <fixed_size_mode> (outermode, &fs_outermode)
+ && is_a <fixed_size_mode> (innermode, &fs_innermode))
+ return simplify_immed_subreg (fs_outermode, op, fs_innermode, byte);
+
+ return NULL_RTX;
+ }
/* Changing mode twice with SUBREG => just change it once,
or not at all if changing back op starting mode. */
diff --git a/gcc/target.def b/gcc/target.def
index 65a415e..577dad8 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5042,7 +5042,7 @@ DEFHOOK
"This target hook returns the mode to be used when accessing raw return\
registers in @code{__builtin_return}. Define this macro if the value\
in @var{reg_raw_mode} is not correct.",
- machine_mode, (int regno),
+ fixed_size_mode, (int regno),
default_get_reg_raw_mode)
/* Return a mode wide enough to copy any argument value that might be
@@ -5052,7 +5052,7 @@ DEFHOOK
"This target hook returns the mode to be used when accessing raw argument\
registers in @code{__builtin_apply_args}. Define this macro if the value\
in @var{reg_raw_mode} is not correct.",
- machine_mode, (int regno),
+ fixed_size_mode, (int regno),
default_get_reg_raw_mode)
HOOK_VECTOR_END (calls)
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index b545bbb..dad1e109 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1872,10 +1872,12 @@ default_dwarf_frame_reg_mode (int regno)
/* To be used by targets where reg_raw_mode doesn't return the right
mode for registers used in apply_builtin_return and apply_builtin_arg. */
-machine_mode
+fixed_size_mode
default_get_reg_raw_mode (int regno)
{
- return reg_raw_mode[regno];
+ /* Targets must override this hook if the underlying register is
+ variable-sized. */
+ return as_a <fixed_size_mode> (reg_raw_mode[regno]);
}
/* Return true if a leaf function should stay leaf even with profiling
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 8686204..15bbf5c 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -236,7 +236,7 @@ extern int default_jump_align_max_skip (rtx_insn *);
extern section * default_function_section(tree decl, enum node_frequency freq,
bool startup, bool exit);
extern machine_mode default_dwarf_frame_reg_mode (int);
-extern machine_mode default_get_reg_raw_mode (int);
+extern fixed_size_mode default_get_reg_raw_mode (int);
extern bool default_keep_leaf_when_profiled ();
extern void *default_get_pch_validity (size_t *);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a139151..655324e 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -3566,7 +3566,7 @@ struct GTY((chain_next ("%h.next"), for_user)) constant_descriptor_rtx {
rtx constant;
HOST_WIDE_INT offset;
hashval_t hash;
- machine_mode mode;
+ fixed_size_mode mode;
unsigned int align;
int labelno;
int mark;
@@ -3742,10 +3742,11 @@ simplify_subtraction (rtx x)
}
/* Given a constant rtx X, make (or find) a memory constant for its value
- and return a MEM rtx to refer to it in memory. */
+ and return a MEM rtx to refer to it in memory. IN_MODE is the mode
+ of X. */
rtx
-force_const_mem (machine_mode mode, rtx x)
+force_const_mem (machine_mode in_mode, rtx x)
{
struct constant_descriptor_rtx *desc, tmp;
struct rtx_constant_pool *pool;
@@ -3754,6 +3755,11 @@ force_const_mem (machine_mode mode, rtx x)
hashval_t hash;
unsigned int align;
constant_descriptor_rtx **slot;
+ fixed_size_mode mode;
+
+ /* We can't force variable-sized objects to memory. */
+ if (!is_a <fixed_size_mode> (in_mode, &mode))
+ return NULL_RTX;
/* If we're not allowed to drop X into the constant pool, don't. */
if (targetm.cannot_force_const_mem (mode, x))
@@ -3859,7 +3865,7 @@ get_pool_constant_mark (rtx addr, bool *pmarked)
/* Similar, return the mode. */
-machine_mode
+fixed_size_mode
get_pool_mode (const_rtx addr)
{
return SYMBOL_REF_CONSTANT (addr)->mode;
@@ -3879,7 +3885,7 @@ constant_pool_empty_p (void)
in MODE with known alignment ALIGN. */
static void
-output_constant_pool_2 (machine_mode mode, rtx x, unsigned int align)
+output_constant_pool_2 (fixed_size_mode mode, rtx x, unsigned int align)
{
switch (GET_MODE_CLASS (mode))
{