aboutsummaryrefslogtreecommitdiff
path: root/gcc/wide-int.h
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-20 12:51:36 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-20 12:51:36 +0000
commit0c12fc9b2d605cf323cfdab28a972d86398e71a1 (patch)
treeca58581589b8fa244d77652a9a9c06f5293a8bea /gcc/wide-int.h
parentabd3c800109b95f09af3b3f1a7a43d9b7631f21c (diff)
downloadgcc-0c12fc9b2d605cf323cfdab28a972d86398e71a1.zip
gcc-0c12fc9b2d605cf323cfdab28a972d86398e71a1.tar.gz
gcc-0c12fc9b2d605cf323cfdab28a972d86398e71a1.tar.bz2
poly_int: rtx constants
This patch adds an rtl representation of poly_int values. There were three possible ways of doing this: (1) Add a new rtl code for the poly_ints themselves and store the coefficients as trailing wide_ints. This would give constants like: (const_poly_int [c0 c1 ... cn]) The runtime value would be: c0 + c1 * x1 + ... + cn * xn (2) Like (1), but use rtxes for the coefficients. This would give constants like: (const_poly_int [(const_int c0) (const_int c1) ... (const_int cn)]) although the coefficients could be const_wide_ints instead of const_ints where appropriate. (3) Add a new rtl code for the polynomial indeterminates, then use them in const wrappers. A constant like c0 + c1 * x1 would then look like: (const:M (plus:M (mult:M (const_param:M x1) (const_int c1)) (const_int c0))) There didn't seem to be that much to choose between them. The main advantage of (1) is that it's a more efficient representation and that we can refer to the cofficients directly as wide_int_storage. 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 (const_poly_int): Document. Also document the rtl sharing behavior. * gengenrtl.c (excluded_rtx): Return true for CONST_POLY_INT. * rtl.h (const_poly_int_def): New struct. (rtx_def::u): Add a cpi field. (CASE_CONST_UNIQUE, CASE_CONST_ANY): Add CONST_POLY_INT. (CONST_POLY_INT_P, CONST_POLY_INT_COEFFS): New macros. (wi::rtx_to_poly_wide_ref): New typedef (const_poly_int_value, wi::to_poly_wide, rtx_to_poly_int64) (poly_int_rtx_p): New functions. (trunc_int_for_mode): Declare a poly_int64 version. (plus_constant): Take a poly_int64 instead of a HOST_WIDE_INT. (immed_wide_int_const): Take a poly_wide_int_ref rather than a wide_int_ref. (strip_offset): Declare. (strip_offset_and_add): New function. * rtl.def (CONST_POLY_INT): New rtx code. * rtl.c (rtx_size): Handle CONST_POLY_INT. (shared_const_p): Use poly_int_rtx_p. * emit-rtl.h (gen_int_mode): Take a poly_int64 instead of a HOST_WIDE_INT. (gen_int_shift_amount): Likewise. * emit-rtl.c (const_poly_int_hasher): New class. (const_poly_int_htab): New variable. (init_emit_once): Initialize it when NUM_POLY_INT_COEFFS > 1. (const_poly_int_hasher::hash): New function. (const_poly_int_hasher::equal): Likewise. (gen_int_mode): Take a poly_int64 instead of a HOST_WIDE_INT. (immed_wide_int_const): Rename to... (immed_wide_int_const_1): ...this and make static. (immed_wide_int_const): New function, taking a poly_wide_int_ref instead of a wide_int_ref. (gen_int_shift_amount): Take a poly_int64 instead of a HOST_WIDE_INT. (gen_lowpart_common): Handle CONST_POLY_INT. * cse.c (hash_rtx_cb, equiv_constant): Likewise. * cselib.c (cselib_hash_rtx): Likewise. * dwarf2out.c (const_ok_for_output_1): Likewise. * expr.c (convert_modes): Likewise. * print-rtl.c (rtx_writer::print_rtx, print_value): Likewise. * rtlhash.c (add_rtx): Likewise. * explow.c (trunc_int_for_mode): Add a poly_int64 version. (plus_constant): Take a poly_int64 instead of a HOST_WIDE_INT. Handle existing CONST_POLY_INT rtxes. * expmed.h (expand_shift): Take a poly_int64 instead of a HOST_WIDE_INT. * expmed.c (expand_shift): Likewise. * rtlanal.c (strip_offset): New function. (commutative_operand_precedence): Give CONST_POLY_INT the same precedence as CONST_DOUBLE and put CONST_WIDE_INT between that and CONST_INT. * rtl-tests.c (const_poly_int_tests): New struct. (rtl_tests_c_tests): Use it. * simplify-rtx.c (simplify_const_unary_operation): Handle CONST_POLY_INT. (simplify_const_binary_operation): Likewise. (simplify_binary_operation_1): Fold additions of symbolic constants and CONST_POLY_INTs. (simplify_subreg): Handle extensions and truncations of CONST_POLY_INTs. (simplify_const_poly_int_tests): New struct. (simplify_rtx_c_tests): Use it. * wide-int.h (storage_ref): Add default constructor. (wide_int_ref_storage): Likewise. (trailing_wide_ints): Use GTY((user)). (trailing_wide_ints::operator[]): Add a const version. (trailing_wide_ints::get_precision): New function. (trailing_wide_ints::extra_size): Likewise. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r255862
Diffstat (limited to 'gcc/wide-int.h')
-rw-r--r--gcc/wide-int.h18
1 files changed, 17 insertions, 1 deletions
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index bbfde90..30173a4 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -613,6 +613,7 @@ namespace wi
access. */
struct storage_ref
{
+ storage_ref () {}
storage_ref (const HOST_WIDE_INT *, unsigned int, unsigned int);
const HOST_WIDE_INT *val;
@@ -944,6 +945,8 @@ private:
HOST_WIDE_INT scratch[2];
public:
+ wide_int_ref_storage () {}
+
wide_int_ref_storage (const wi::storage_ref &);
template <typename T>
@@ -1323,7 +1326,7 @@ namespace wi
bytes beyond the sizeof need to be allocated. Use set_precision
to initialize the structure. */
template <int N>
-class GTY(()) trailing_wide_ints
+class GTY((user)) trailing_wide_ints
{
private:
/* The shared precision of each number. */
@@ -1340,9 +1343,14 @@ private:
HOST_WIDE_INT m_val[1];
public:
+ typedef WIDE_INT_REF_FOR (trailing_wide_int_storage) const_reference;
+
void set_precision (unsigned int);
+ unsigned int get_precision () const { return m_precision; }
trailing_wide_int operator [] (unsigned int);
+ const_reference operator [] (unsigned int) const;
static size_t extra_size (unsigned int);
+ size_t extra_size () const { return extra_size (m_precision); }
};
inline trailing_wide_int_storage::
@@ -1414,6 +1422,14 @@ trailing_wide_ints <N>::operator [] (unsigned int index)
&m_val[index * m_max_len]);
}
+template <int N>
+inline typename trailing_wide_ints <N>::const_reference
+trailing_wide_ints <N>::operator [] (unsigned int index) const
+{
+ return wi::storage_ref (&m_val[index * m_max_len],
+ m_len[index], m_precision);
+}
+
/* Return how many extra bytes need to be added to the end of the structure
in order to handle N wide_ints of precision PRECISION. */
template <int N>