aboutsummaryrefslogtreecommitdiff
path: root/gcc/wide-int.h
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-10-14 09:35:44 +0200
committerJakub Jelinek <jakub@redhat.com>2023-10-14 09:35:44 +0200
commitcb0119242317c2a6f3127b4acff6aadbfd1dfbc4 (patch)
treef84c2a0388630c4f69a56dbcb3995ba2154ea0f7 /gcc/wide-int.h
parent78dd49f387c515a6b28ef3fcb989605a168ff752 (diff)
downloadgcc-cb0119242317c2a6f3127b4acff6aadbfd1dfbc4.zip
gcc-cb0119242317c2a6f3127b4acff6aadbfd1dfbc4.tar.gz
gcc-cb0119242317c2a6f3127b4acff6aadbfd1dfbc4.tar.bz2
middle-end: Allow _BitInt(65535) [PR102989]
The following patch lifts further restrictions which limited _BitInt to at most 16319 bits up to 65535. The problem was mainly in INTEGER_CST representation, which had 3 unsigned char members to describe lengths in number of 64-bit limbs, which it wanted to fit into 32 bits. This patch removes the third one which was just a cache to save a few compile time cycles for wi::to_offset and enlarges the other two members to unsigned short. Furthermore, the same problem has been in some uses of trailing_wide_int* (in value-range-storage*) and value-range-storage* itself, while other uses of trailing_wide_int* have been fine (e.g. CONST_POLY_INT, where no constants will be larger than 3/5/9/11 limbs depending on target, so 255 limit is plenty). The patch turns all those length representations to be unsigned short for consistency, so value-range-storage* can handle even 16320-65535 bits BITINT_TYPE ranges. The cc1plus growth is about 16K, so not really significant for 38M .text section. Note, the reason for the new limit is unsigned int precision : 16; TYPE_PRECISION limit, if we wanted to overcome that, TYPE_PRECISION would need to use some other member for BITINT_TYPE from all the others and we could reach that way 4194239 limit (65535 * 64 - 1, again implied by INTEGER_CST and value-range-storage*). Dunno if that is worth it or if it is something we want to do for GCC 14 though. 2023-10-14 Jakub Jelinek <jakub@redhat.com> PR c/102989 gcc/ * tree-core.h (struct tree_base): Remove int_length.offset member, change type of int_length.unextended and int_length.extended from unsigned char to unsigned short. * tree.h (TREE_INT_CST_OFFSET_NUNITS): Remove. (wi::extended_tree <N>::get_len): Don't use TREE_INT_CST_OFFSET_NUNITS, instead compute it at runtime from TREE_INT_CST_EXT_NUNITS and TREE_INT_CST_NUNITS. * tree.cc (wide_int_to_tree_1): Don't assert TREE_INT_CST_OFFSET_NUNITS value. (make_int_cst): Don't initialize TREE_INT_CST_OFFSET_NUNITS. * wide-int.h (WIDE_INT_MAX_ELTS): Change from 255 to 1024. (WIDEST_INT_MAX_ELTS): Change from 510 to 2048, adjust comment. (trailing_wide_int_storage): Change m_len type from unsigned char * to unsigned short *. (trailing_wide_int_storage::trailing_wide_int_storage): Change second argument from unsigned char * to unsigned short *. (trailing_wide_ints): Change m_max_len type from unsigned char to unsigned short. Change m_len element type from struct{unsigned char len;} to unsigned short. (trailing_wide_ints <N>::operator []): Remove .len from m_len accesses. * value-range-storage.h (irange_storage::lengths_address): Change return type from const unsigned char * to const unsigned short *. (irange_storage::write_lengths_address): Change return type from unsigned char * to unsigned short *. * value-range-storage.cc (irange_storage::write_lengths_address): Likewise. (irange_storage::lengths_address): Change return type from const unsigned char * to const unsigned short *. (write_wide_int): Change len argument type from unsigned char *& to unsigned short *&. (irange_storage::set_irange): Change len variable type from unsigned char * to unsigned short *. (read_wide_int): Change len argument type from unsigned char to unsigned short. Use trailing_wide_int_storage <unsigned short> instead of trailing_wide_int_storage and trailing_wide_int <unsigned short> instead of trailing_wide_int. (irange_storage::get_irange): Change len variable type from unsigned char * to unsigned short *. (irange_storage::size): Multiply n by sizeof (unsigned short) in len_size variable initialization. (irange_storage::dump): Change len variable type from unsigned char * to unsigned short *. gcc/cp/ * module.cc (trees_out::start, trees_in::start): Remove TREE_INT_CST_OFFSET_NUNITS handling. gcc/testsuite/ * gcc.dg/bitint-38.c: Change into dg-do run test, in addition to checking the addition, division and right shift results at compile time check it also at runtime. * gcc.dg/bitint-39.c: New test.
Diffstat (limited to 'gcc/wide-int.h')
-rw-r--r--gcc/wide-int.h25
1 files changed, 11 insertions, 14 deletions
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index 07bacc9..73e431d 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -249,12 +249,11 @@ along with GCC; see the file COPYING3. If not see
/* Precision of wide_int and largest _BitInt precision + 1 we can
support. */
-#define WIDE_INT_MAX_ELTS 255
+#define WIDE_INT_MAX_ELTS 1024
#define WIDE_INT_MAX_PRECISION (WIDE_INT_MAX_ELTS * HOST_BITS_PER_WIDE_INT)
-/* Precision of widest_int and largest _BitInt precision + 1 we can
- support. */
-#define WIDEST_INT_MAX_ELTS 510
+/* Precision of widest_int. */
+#define WIDEST_INT_MAX_ELTS 2048
#define WIDEST_INT_MAX_PRECISION (WIDEST_INT_MAX_ELTS * HOST_BITS_PER_WIDE_INT)
STATIC_ASSERT (WIDE_INT_MAX_INL_ELTS < WIDE_INT_MAX_ELTS);
@@ -1717,14 +1716,14 @@ private:
unsigned int m_precision;
/* A pointer to the length field. */
- unsigned char *m_len;
+ unsigned short *m_len;
/* A pointer to the HWI array. There are enough elements to hold all
values of precision M_PRECISION. */
HOST_WIDE_INT *m_val;
public:
- trailing_wide_int_storage (unsigned int, unsigned char *, HOST_WIDE_INT *);
+ trailing_wide_int_storage (unsigned int, unsigned short *, HOST_WIDE_INT *);
/* The standard generic_wide_int storage methods. */
unsigned int get_len () const;
@@ -1762,15 +1761,13 @@ private:
unsigned short m_precision;
/* The shared maximum length of each number. */
- unsigned char m_max_len;
+ unsigned short m_max_len;
/* The number of elements. */
unsigned char m_num_elements;
- /* The current length of each number.
- Avoid char array so the whole structure is not a typeless storage
- that will, in turn, turn off TBAA on gimple, trees and RTL. */
- struct {unsigned char len;} m_len[N];
+ /* The current length of each number. */
+ unsigned short m_len[N];
/* The variable-length part of the structure, which always contains
at least one HWI. Element I starts at index I * M_MAX_LEN. */
@@ -1791,7 +1788,7 @@ public:
};
inline trailing_wide_int_storage::
-trailing_wide_int_storage (unsigned int precision, unsigned char *len,
+trailing_wide_int_storage (unsigned int precision, unsigned short *len,
HOST_WIDE_INT *val)
: m_precision (precision), m_len (len), m_val (val)
{
@@ -1857,7 +1854,7 @@ template <int N>
inline trailing_wide_int
trailing_wide_ints <N>::operator [] (unsigned int index)
{
- return trailing_wide_int_storage (m_precision, &m_len[index].len,
+ return trailing_wide_int_storage (m_precision, &m_len[index],
&m_val[index * m_max_len]);
}
@@ -1866,7 +1863,7 @@ 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].len, m_precision);
+ m_len[index], m_precision);
}
/* Return how many extra bytes need to be added to the end of the