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
This commit is contained in:
Richard Sandiford 2017-11-01 11:49:34 +00:00 committed by Richard Sandiford
parent ef339d6e2e
commit ef1d3b57d2
18 changed files with 131 additions and 40 deletions

View File

@ -1,3 +1,32 @@
2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
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>

View File

@ -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);

View File

@ -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))

View File

@ -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))

View File

@ -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;

View File

@ -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. */

View File

@ -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

View File

@ -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);

View File

@ -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));

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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. */

View File

@ -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)

View File

@ -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

View File

@ -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 *);

View File

@ -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))
{