aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtl.h
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-20 12:54:28 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-20 12:54:28 +0000
commit91914e56a5e952cc87468bdd6d006e51eaa54294 (patch)
treebd8f6dfd41592b49da05616444cddb8a72b5109f /gcc/rtl.h
parent9dcf1f868c048e20c72df7ee5d378625d1e77bc8 (diff)
downloadgcc-91914e56a5e952cc87468bdd6d006e51eaa54294.zip
gcc-91914e56a5e952cc87468bdd6d006e51eaa54294.tar.gz
gcc-91914e56a5e952cc87468bdd6d006e51eaa54294.tar.bz2
poly_int: SUBREG_BYTE
This patch changes SUBREG_BYTE from an int to a poly_int. Since valid SUBREG_BYTEs must be contained within the mode of the SUBREG_REG, the required range is the same as for GET_MODE_SIZE, i.e. unsigned short. The patch therefore uses poly_uint16(_pod) for the SUBREG_BYTE. Using poly_uint16_pod rtx fields requires a new field code ('p'). Since there are no other uses of 'p' besides SUBREG_BYTE, the patch doesn't add an XPOLY or whatever; all uses should go via SUBREG_BYTE instead. The patch doesn't bother implementing 'p' support for legacy define_peepholes, since none of the remaining ones have subregs in their patterns. As it happened, the rtl documentation used SUBREG as an example of a code with mixed field types, accessed via XEXP (x, 0) and XINT (x, 1). Since there's no direct replacement for XINT, and since people should never use it even if there were, the patch changes the example to use INT_LIST instead. The patch also changes subreg-related helper functions so that they too take and return polynomial offsets. This makes the patch quite big, but it's mostly mechanical. The patch generally sticks to existing choices wrt signedness. 2017-12-20 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * doc/rtl.texi: Update documentation of SUBREG_BYTE. Document the 'p' format code. Use INT_LIST rather than SUBREG as the example of a code with an XINT and an XEXP. Remove the implication that accessing an rtx field using XINT is expected to work. * rtl.def (SUBREG): Change format from "ei" to "ep". * rtl.h (rtunion::rt_subreg): New field. (XCSUBREG): New macro. (SUBREG_BYTE): Use it. (subreg_shape): Change offset from an unsigned int to a poly_uint16. Update constructor accordingly. (subreg_shape::operator ==): Update accordingly. (subreg_shape::unique_id): Return an unsigned HOST_WIDE_INT rather than an unsigned int. (subreg_lsb, subreg_lowpart_offset, subreg_highpart_offset): Return a poly_uint64 rather than an unsigned int. (subreg_lsb_1): Likewise. Take the offset as a poly_uint64 rather than an unsigned int. (subreg_size_offset_from_lsb, subreg_size_lowpart_offset) (subreg_size_highpart_offset): Return a poly_uint64 rather than an unsigned int. Take the sizes as poly_uint64s. (subreg_offset_from_lsb): Return a poly_uint64 rather than an unsigned int. Take the shift as a poly_uint64 rather than an unsigned int. (subreg_regno_offset, subreg_offset_representable_p): Take the offset as a poly_uint64 rather than an unsigned int. (simplify_subreg_regno): Likewise. (byte_lowpart_offset): Return the memory offset as a poly_int64 rather than an int. (subreg_memory_offset): Likewise. Take the subreg offset as a poly_uint64 rather than an unsigned int. (simplify_subreg, simplify_gen_subreg, subreg_get_info) (gen_rtx_SUBREG, validate_subreg): Take the subreg offset as a poly_uint64 rather than an unsigned int. * rtl.c (rtx_format): Describe 'p' in comment. (copy_rtx, rtx_equal_p_cb, rtx_equal_p): Handle 'p'. * emit-rtl.c (validate_subreg, gen_rtx_SUBREG): Take the subreg offset as a poly_uint64 rather than an unsigned int. (byte_lowpart_offset): Return the memory offset as a poly_int64 rather than an int. (subreg_memory_offset): Likewise. Take the subreg offset as a poly_uint64 rather than an unsigned int. (subreg_size_lowpart_offset, subreg_size_highpart_offset): Take the mode sizes as poly_uint64s rather than unsigned ints. Return a poly_uint64 rather than an unsigned int. (subreg_lowpart_p): Treat subreg offsets as poly_ints. (copy_insn_1): Handle 'p'. * rtlanal.c (set_noop_p): Treat subregs offsets as poly_uint64s. (subreg_lsb_1): Take the subreg offset as a poly_uint64 rather than an unsigned int. Return the shift in the same way. (subreg_lsb): Return the shift as a poly_uint64 rather than an unsigned int. (subreg_size_offset_from_lsb): Take the sizes and shift as poly_uint64s rather than unsigned ints. Return the offset as a poly_uint64. (subreg_get_info, subreg_regno_offset, subreg_offset_representable_p) (simplify_subreg_regno): Take the offset as a poly_uint64 rather than an unsigned int. * rtlhash.c (add_rtx): Handle 'p'. * genemit.c (gen_exp): Likewise. * gengenrtl.c (type_from_format, gendef): Likewise. * gensupport.c (subst_pattern_match, get_alternatives_number) (collect_insn_data, alter_predicate_for_insn, alter_constraints) (subst_dup): Likewise. * gengtype.c (adjust_field_rtx_def): Likewise. * genrecog.c (find_operand, find_matching_operand, validate_pattern) (match_pattern_2): Likewise. (rtx_test::SUBREG_FIELD): New rtx_test::kind_enum. (rtx_test::subreg_field): New function. (operator ==, safe_to_hoist_p, transition_parameter_type) (print_nonbool_test, print_test): Handle SUBREG_FIELD. * genattrtab.c (attr_rtx_1): Say that 'p' is deliberately not handled. * genpeep.c (match_rtx): Likewise. * print-rtl.c (print_poly_int): Include if GENERATOR_FILE too. (rtx_writer::print_rtx_operand): Handle 'p'. (print_value): Handle SUBREG. * read-rtl.c (apply_int_iterator): Likewise. (rtx_reader::read_rtx_operand): Handle 'p'. * alias.c (rtx_equal_for_memref_p): Likewise. * cselib.c (rtx_equal_for_cselib_1, cselib_hash_rtx): Likewise. * caller-save.c (replace_reg_with_saved_mem): Treat subreg offsets as poly_ints. * calls.c (expand_call): Likewise. * combine.c (combine_simplify_rtx, expand_field_assignment): Likewise. (make_extraction, gen_lowpart_for_combine): Likewise. * loop-invariant.c (hash_invariant_expr_1, invariant_expr_equal_p): Likewise. * cse.c (remove_invalid_subreg_refs): Take the offset as a poly_uint64 rather than an unsigned int. Treat subreg offsets as poly_ints. (exp_equiv_p): Handle 'p'. (hash_rtx_cb): Likewise. Treat subreg offsets as poly_ints. (equiv_constant, cse_insn): Treat subreg offsets as poly_ints. * dse.c (find_shift_sequence): Likewise. * dwarf2out.c (rtl_for_decl_location): Likewise. * expmed.c (extract_low_bits): Likewise. * expr.c (emit_group_store, undefined_operand_subword_p): Likewise. (expand_expr_real_2): Likewise. * final.c (alter_subreg): Likewise. (leaf_renumber_regs_insn): Handle 'p'. * function.c (assign_parm_find_stack_rtl, assign_parm_setup_stack): Treat subreg offsets as poly_ints. * fwprop.c (forward_propagate_and_simplify): Likewise. * ifcvt.c (noce_emit_move_insn, noce_emit_cmove): Likewise. * ira.c (get_subreg_tracking_sizes): Likewise. * ira-conflicts.c (go_through_subreg): Likewise. * ira-lives.c (process_single_reg_class_operands): Likewise. * jump.c (rtx_renumbered_equal_p): Likewise. Handle 'p'. * lower-subreg.c (simplify_subreg_concatn): Take the subreg offset as a poly_uint64 rather than an unsigned int. (simplify_gen_subreg_concatn, resolve_simple_move): Treat subreg offsets as poly_ints. * lra-constraints.c (operands_match_p): Handle 'p'. (match_reload, curr_insn_transform): Treat subreg offsets as poly_ints. * lra-spills.c (assign_mem_slot): Likewise. * postreload.c (move2add_valid_value_p): Likewise. * recog.c (general_operand, indirect_operand): Likewise. * regcprop.c (copy_value, maybe_mode_change): Likewise. (copyprop_hardreg_forward_1): Likewise. * reginfo.c (simplifiable_subregs_hasher::hash, simplifiable_subregs) (record_subregs_of_mode): Likewise. * rtlhooks.c (gen_lowpart_general, gen_lowpart_if_possible): Likewise. * reload.c (operands_match_p): Handle 'p'. (find_reloads_subreg_address): Treat subreg offsets as poly_ints. * reload1.c (alter_reg, choose_reload_regs): Likewise. (compute_reload_subreg_offset): Likewise, and return an poly_int64. * simplify-rtx.c (simplify_truncation, simplify_binary_operation_1): (test_vector_ops_duplicate): Treat subreg offsets as poly_ints. (simplify_const_poly_int_tests<N>::run): Likewise. (simplify_subreg, simplify_gen_subreg): Take the subreg offset as a poly_uint64 rather than an unsigned int. * valtrack.c (debug_lowpart_subreg): Likewise. * var-tracking.c (var_lowpart): Likewise. (loc_cmp): Handle 'p'. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r255882
Diffstat (limited to 'gcc/rtl.h')
-rw-r--r--gcc/rtl.h79
1 files changed, 39 insertions, 40 deletions
diff --git a/gcc/rtl.h b/gcc/rtl.h
index f09a9f4..df41078 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -198,6 +198,7 @@ union rtunion
{
int rt_int;
unsigned int rt_uint;
+ poly_uint16_pod rt_subreg;
const char *rt_str;
rtx rt_rtx;
rtvec rt_rtvec;
@@ -1335,6 +1336,7 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
#define XCINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_int)
#define XCUINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_uint)
+#define XCSUBREG(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_subreg)
#define XCSTR(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_str)
#define XCEXP(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_rtx)
#define XCVEC(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rt_rtvec)
@@ -1963,7 +1965,7 @@ set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
SUBREG_BYTE extracts the byte-number. */
#define SUBREG_REG(RTX) XCEXP (RTX, 0, SUBREG)
-#define SUBREG_BYTE(RTX) XCUINT (RTX, 1, SUBREG)
+#define SUBREG_BYTE(RTX) XCSUBREG (RTX, 1, SUBREG)
/* in rtlanal.c */
/* Return the right cost to give to an operation
@@ -2036,19 +2038,19 @@ costs_add_n_insns (struct full_rtx_costs *c, int n)
offset == the SUBREG_BYTE
outer_mode == the mode of the SUBREG itself. */
struct subreg_shape {
- subreg_shape (machine_mode, unsigned int, machine_mode);
+ subreg_shape (machine_mode, poly_uint16, machine_mode);
bool operator == (const subreg_shape &) const;
bool operator != (const subreg_shape &) const;
- unsigned int unique_id () const;
+ unsigned HOST_WIDE_INT unique_id () const;
machine_mode inner_mode;
- unsigned int offset;
+ poly_uint16 offset;
machine_mode outer_mode;
};
inline
subreg_shape::subreg_shape (machine_mode inner_mode_in,
- unsigned int offset_in,
+ poly_uint16 offset_in,
machine_mode outer_mode_in)
: inner_mode (inner_mode_in), offset (offset_in), outer_mode (outer_mode_in)
{}
@@ -2057,7 +2059,7 @@ inline bool
subreg_shape::operator == (const subreg_shape &other) const
{
return (inner_mode == other.inner_mode
- && offset == other.offset
+ && known_eq (offset, other.offset)
&& outer_mode == other.outer_mode);
}
@@ -2072,11 +2074,16 @@ subreg_shape::operator != (const subreg_shape &other) const
current mode is anywhere near being 65536 bytes in size, so the
id comfortably fits in an int. */
-inline unsigned int
+inline unsigned HOST_WIDE_INT
subreg_shape::unique_id () const
{
- STATIC_ASSERT (MAX_MACHINE_MODE <= 256);
- return (int) inner_mode + ((int) outer_mode << 8) + (offset << 16);
+ { STATIC_ASSERT (MAX_MACHINE_MODE <= 256); }
+ { STATIC_ASSERT (NUM_POLY_INT_COEFFS <= 3); }
+ { STATIC_ASSERT (sizeof (offset.coeffs[0]) <= 2); }
+ int res = (int) inner_mode + ((int) outer_mode << 8);
+ for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+ res += (HOST_WIDE_INT) offset.coeffs[i] << ((1 + i) * 16);
+ return res;
}
/* Return the shape of a SUBREG rtx. */
@@ -2330,11 +2337,10 @@ extern int rtx_cost (rtx, machine_mode, enum rtx_code, int, bool);
extern int address_cost (rtx, machine_mode, addr_space_t, bool);
extern void get_full_rtx_cost (rtx, machine_mode, enum rtx_code, int,
struct full_rtx_costs *);
-extern unsigned int subreg_lsb (const_rtx);
-extern unsigned int subreg_lsb_1 (machine_mode, machine_mode,
- unsigned int);
-extern unsigned int subreg_size_offset_from_lsb (unsigned int, unsigned int,
- unsigned int);
+extern poly_uint64 subreg_lsb (const_rtx);
+extern poly_uint64 subreg_lsb_1 (machine_mode, machine_mode, poly_uint64);
+extern poly_uint64 subreg_size_offset_from_lsb (poly_uint64, poly_uint64,
+ poly_uint64);
extern bool read_modify_subreg_p (const_rtx);
/* Return the subreg byte offset for a subreg whose outer mode is
@@ -2343,22 +2349,22 @@ extern bool read_modify_subreg_p (const_rtx);
the inner value. This is the inverse of subreg_lsb_1 (which converts
byte offsets to bit shifts). */
-inline unsigned int
+inline poly_uint64
subreg_offset_from_lsb (machine_mode outer_mode,
machine_mode inner_mode,
- unsigned int lsb_shift)
+ poly_uint64 lsb_shift)
{
return subreg_size_offset_from_lsb (GET_MODE_SIZE (outer_mode),
GET_MODE_SIZE (inner_mode), lsb_shift);
}
-extern unsigned int subreg_regno_offset (unsigned int, machine_mode,
- unsigned int, machine_mode);
+extern unsigned int subreg_regno_offset (unsigned int, machine_mode,
+ poly_uint64, machine_mode);
extern bool subreg_offset_representable_p (unsigned int, machine_mode,
- unsigned int, machine_mode);
+ poly_uint64, machine_mode);
extern unsigned int subreg_regno (const_rtx);
extern int simplify_subreg_regno (unsigned int, machine_mode,
- unsigned int, machine_mode);
+ poly_uint64, machine_mode);
extern unsigned int subreg_nregs (const_rtx);
extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, machine_mode);
@@ -3042,7 +3048,7 @@ extern rtx operand_subword (rtx, unsigned int, int, machine_mode);
/* In emit-rtl.c */
extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
extern int subreg_lowpart_p (const_rtx);
-extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int);
+extern poly_uint64 subreg_size_lowpart_offset (poly_uint64, poly_uint64);
/* Return true if a subreg of mode OUTERMODE would only access part of
an inner register with mode INNERMODE. The other bits of the inner
@@ -3089,7 +3095,7 @@ paradoxical_subreg_p (const_rtx x)
/* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value. */
-inline unsigned int
+inline poly_uint64
subreg_lowpart_offset (machine_mode outermode, machine_mode innermode)
{
return subreg_size_lowpart_offset (GET_MODE_SIZE (outermode),
@@ -3124,20 +3130,21 @@ wider_subreg_mode (const_rtx x)
return wider_subreg_mode (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
}
-extern unsigned int subreg_size_highpart_offset (unsigned int, unsigned int);
+extern poly_uint64 subreg_size_highpart_offset (poly_uint64, poly_uint64);
/* Return the SUBREG_BYTE for an OUTERMODE highpart of an INNERMODE value. */
-inline unsigned int
+inline poly_uint64
subreg_highpart_offset (machine_mode outermode, machine_mode innermode)
{
return subreg_size_highpart_offset (GET_MODE_SIZE (outermode),
GET_MODE_SIZE (innermode));
}
-extern int byte_lowpart_offset (machine_mode, machine_mode);
-extern int subreg_memory_offset (machine_mode, machine_mode, unsigned int);
-extern int subreg_memory_offset (const_rtx);
+extern poly_int64 byte_lowpart_offset (machine_mode, machine_mode);
+extern poly_int64 subreg_memory_offset (machine_mode, machine_mode,
+ poly_uint64);
+extern poly_int64 subreg_memory_offset (const_rtx);
extern rtx make_safe_from (rtx, rtx);
extern rtx convert_memory_address_addr_space_1 (scalar_int_mode, rtx,
addr_space_t, bool, bool);
@@ -3289,16 +3296,8 @@ extern rtx simplify_gen_ternary (enum rtx_code, machine_mode,
machine_mode, rtx, rtx, rtx);
extern rtx simplify_gen_relational (enum rtx_code, machine_mode,
machine_mode, rtx, rtx);
-extern rtx simplify_subreg (machine_mode, rtx, machine_mode,
- unsigned int);
-extern rtx simplify_gen_subreg (machine_mode, rtx, machine_mode,
- unsigned int);
-inline rtx
-simplify_gen_subreg (machine_mode omode, rtx x, machine_mode imode,
- poly_uint64 offset)
-{
- return simplify_gen_subreg (omode, x, imode, offset.to_constant ());
-}
+extern rtx simplify_subreg (machine_mode, rtx, machine_mode, poly_uint64);
+extern rtx simplify_gen_subreg (machine_mode, rtx, machine_mode, poly_uint64);
extern rtx lowpart_subreg (machine_mode, rtx, machine_mode);
extern rtx simplify_replace_fn_rtx (rtx, const_rtx,
rtx (*fn) (rtx, const_rtx, void *), void *);
@@ -3484,7 +3483,7 @@ struct subreg_info
};
extern void subreg_get_info (unsigned int, machine_mode,
- unsigned int, machine_mode,
+ poly_uint64, machine_mode,
struct subreg_info *);
/* lists.c */
@@ -3722,7 +3721,7 @@ extern rtx gen_rtx_CONST_VECTOR (machine_mode, rtvec);
extern void set_mode_and_regno (rtx, machine_mode, unsigned int);
extern rtx gen_raw_REG (machine_mode, unsigned int);
extern rtx gen_rtx_REG (machine_mode, unsigned int);
-extern rtx gen_rtx_SUBREG (machine_mode, rtx, int);
+extern rtx gen_rtx_SUBREG (machine_mode, rtx, poly_uint64);
extern rtx gen_rtx_MEM (machine_mode, rtx);
extern rtx gen_rtx_VAR_LOCATION (machine_mode, tree, rtx,
enum var_init_status);
@@ -3939,7 +3938,7 @@ extern rtx gen_const_mem (machine_mode, rtx);
extern rtx gen_frame_mem (machine_mode, rtx);
extern rtx gen_tmp_stack_mem (machine_mode, rtx);
extern bool validate_subreg (machine_mode, machine_mode,
- const_rtx, unsigned int);
+ const_rtx, poly_uint64);
/* In combine.c */
extern unsigned int extended_count (const_rtx, machine_mode, int);