From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 0575B3858D33 for ; Tue, 29 Aug 2023 10:42:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0575B3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DA4702F4; Tue, 29 Aug 2023 03:43:29 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.110.72]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CE3243F738; Tue, 29 Aug 2023 03:42:49 -0700 (PDT) From: Richard Sandiford To: Richard Biener Mail-Followup-To: Richard Biener ,Jakub Jelinek , gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Cc: Jakub Jelinek , gcc-patches@gcc.gnu.org Subject: Re: [RFC] > WIDE_INT_MAX_PREC support in wide-int References: Date: Tue, 29 Aug 2023 11:42:48 +0100 In-Reply-To: (Richard Biener's message of "Tue, 29 Aug 2023 09:49:59 +0000 (UTC)") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-19.4 required=5.0 tests=BAYES_00,KAM_DMARC_NONE,KAM_DMARC_STATUS,KAM_LAZY_DOMAIN_SECURITY,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Just some off-the-cuff thoughts. Might think differently when I've had more time... Richard Biener writes: > On Mon, 28 Aug 2023, Jakub Jelinek wrote: > >> Hi! >> >> While the _BitInt series isn't committed yet, I had a quick look at >> lifting the current lowest limitation on maximum _BitInt precision, >> that wide_int can only support wide_int until WIDE_INT_MAX_PRECISION - 1. >> >> Note, other limits if that is lifted are INTEGER_CST currently using 3 >> unsigned char members and so being able to only hold up to 255 * 64 = 16320 >> bit numbers and then TYPE_PRECISION being 16-bit, so limiting us to 65535 >> bits. The INTEGER_CST limit could be dealt with by dropping the >> int_length.offset "cache" and making int_length.extended and >> int_length.unextended members unsinged short rather than unsigned char. >> >> The following so far just compile tested patch changes wide_int_storage >> to be a union, for precisions up to WIDE_INT_MAX_PRECISION inclusive it >> will work as before (just being no longer trivially copyable type and >> having an inline destructor), while larger precision instead use a pointer >> to heap allocated array. >> For wide_int this is fairly easy (of course, I'd need to see what the >> patch does to gcc code size and compile time performance, some >> growth/slowdown is certain), but I'd like to brainstorm on >> widest_int/widest2_int. >> >> Currently it is a constant precision storage with WIDE_INT_MAX_PRECISION >> precision (widest2_int twice that), so memory layout-wide on at least 64-bit >> hosts identical to wide_int, just it doesn't have precision member and so >> 32 bits smaller on 32-bit hosts. It is used in lots of places. >> >> I think the most common is what is done e.g. in tree_int_cst* comparisons >> and similarly, using wi::to_widest () to just compare INTEGER_CSTs. >> That case actually doesn't even use wide_int but widest_extended_tree >> as storage, unless stored into widest_int in between (that happens in >> various spots as well). For comparisons, it would be fine if >> widest_int_storage/widest_extended_tree storages had a dynamic precision, >> WIDE_INT_MAX_PRECISION for most of the cases (if only >> precision < WIDE_INT_MAX_PRECISION is involved), otherwise the needed >> precision (e.g. for binary ops) which would be what we say have in >> INTEGER_CST or some type, rounded up to whole multiples of HOST_WIDE_INTs >> and if unsigned with multiple of HOST_WIDE_INT precision, have another >> HWI to make it always sign-extended. >> >> Another common case is how e.g. tree-ssa-ccp.cc uses them, that is mostly >> for bitwise ops and so I think the above would be just fine for that case. >> >> Another case is how tree-ssa-loop-niter.cc uses it, I think for such a usage >> it really wants something widest, perhaps we could just try to punt for >> _BitInt(N) for N >= WIDE_INT_MAX_PRECISION in there, so that we never care >> about bits beyond that limit? > > I'll note tree-ssa-loop-niter.cc also uses GMP in some cases, widest_int > is really trying to be poor-mans GMP by limiting the maximum precision. I'd characterise widest_int as "a wide_int that is big enough to hold all supported integer types, without losing sign information". It's not big enough to do arbitrary arithmetic without losing precision (in the way that GMP is). If the new limit on integer sizes is 65535 bits for all targets, then I think that means that widest_int needs to become a 65536-bit type. (But not with all bits represented all the time, of course.) [ And at that point I think widest_int should ideally become a GMP wrapper. The wide_int stuff isn't optimised for such large sizes, even accepting that large sizes will be a worst case. That might not be easy to do with the current infrastructure though. Especially not if widest_ints are stored in GC-ed structures. ] That seems like it would stand the biggest chance of preserving existing semantics. But we might want to define new typedefs for narrower limits. E.g. the current widest_int limit probably still makes sense for operations on scalar_int_modes. (But then most RTL arithmetic should use wide_int rather than widest_int.) Perhaps some widest_int uses are really restricted to address-like things and could instead use offset_int. Until now there hasn't been much incentive to make the distinction. And perhaps we could identify other similar cases where the limit is known (statically) to be the current limit, rather than 65536. I think one of the worst things we could do is push the requirement up to users of the API to have one path for _BitInts and one for "normal" integers. That's bound to lead to a whack-a-mole effect. Thanks, Richard