aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.cc
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/tree.cc
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/tree.cc')
-rw-r--r--gcc/tree.cc9
1 files changed, 0 insertions, 9 deletions
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 6fa85cc..69369c6 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -1763,7 +1763,6 @@ wide_int_to_tree_1 (tree type, const wide_int_ref &pcst)
/* Make sure no one is clobbering the shared constant. */
gcc_checking_assert (TREE_TYPE (t) == type
&& TREE_INT_CST_NUNITS (t) == 1
- && TREE_INT_CST_OFFSET_NUNITS (t) == 1
&& TREE_INT_CST_EXT_NUNITS (t) == 1
&& TREE_INT_CST_ELT (t, 0) == hwi);
return t;
@@ -2789,14 +2788,6 @@ make_int_cst (int len, int ext_len MEM_STAT_DECL)
TREE_SET_CODE (t, INTEGER_CST);
TREE_INT_CST_NUNITS (t) = len;
TREE_INT_CST_EXT_NUNITS (t) = ext_len;
- /* to_offset can only be applied to trees that are offset_int-sized
- or smaller. EXT_LEN is correct if it fits, otherwise the constant
- must be exactly the precision of offset_int and so LEN is correct. */
- if (ext_len <= OFFSET_INT_ELTS)
- TREE_INT_CST_OFFSET_NUNITS (t) = ext_len;
- else
- TREE_INT_CST_OFFSET_NUNITS (t) = len;
-
TREE_CONSTANT (t) = 1;
return t;