On Thu, 17 Oct 2013, Kenneth Zadeck wrote: > On 10/17/2013 08:29 AM, Richard Biener wrote: > > On Thu, 17 Oct 2013, Richard Sandiford wrote: > > > > > Richard Biener <rguent...@suse.de> writes: > > > > > The new tree representation can have a length greater than max_len > > > > > for an unsigned tree constant that occupies a whole number of HWIs. > > > > > The tree representation of an unsigned 0x8000 is 0x00 0x80 0x00. > > > > > When extended to max_wide_int the representation is the same. > > > > > But a 2-HWI addr_wide_int would be 0x80 0x00, without the leading > > > > > zero. > > > > > The MIN trims the length from 3 to 2 in the last case. > > > > Oh, so it was the tree rep that changed? _Why_ was it changed? > > > > We still cannot use it directly from wide-int and the extra > > > > word is redundant because we have access to TYPE_UNSIGNED (TREE_TYPE > > > > ()). > > > It means that we can now use the tree's HWI array directly, without any > > > copying, for addr_wide_int and max_wide_int. The only part of decompose > > > () > > > that does a copy is the small_prec case, which is trivially compiled out > > > for addr_wide_int and max_wide_int. > > " 2) addr_wide_int. This is a fixed size representation that is > > guaranteed to be large enough to compute any bit or byte sized > > address calculation on the target. Currently the value is 64 + 4 > > bits rounded up to the next number even multiple of > > HOST_BITS_PER_WIDE_INT (but this can be changed when the first > > port needs more than 64 bits for the size of a pointer). > > > > This flavor can be used for all address math on the target. In > > this representation, the values are sign or zero extended based > > on their input types to the internal precision. All math is done > > in this precision and then the values are truncated to fit in the > > result type. Unlike most gimple or rtl intermediate code, it is > > not useful to perform the address arithmetic at the same > > precision in which the operands are represented because there has > > been no effort by the front ends to convert most addressing > > arithmetic to canonical types. > > > > In the addr_wide_int, all numbers are represented as signed > > numbers. There are enough bits in the internal representation so > > that no infomation is lost by representing them this way." > > > > so I guess from that that addr_wide_int.get_precision is always > > that "64 + 4 rounded up". Thus decompose gets that constant precision > > input and the extra zeros make the necessary extension always a no-op. > > Aha. > it is until someone comes up with a port that this will not work for, then > they will have to add some machinery to sniff the port and make this bigger. > I am hoping to be retired by the time this happens. > > For max_wide_int the same rules apply, just its size is larger. > > > > Ok. So the reps are only canonical wide-int because we only > > ever use them with precision > xprecision (maybe we should assert > > that). > It is now asserted for (as of a few days ago). > > > > > Btw, we are not using them directly, but every time we actually > > build a addr_wide_int / max_wide_int we copy them anyway: > > > > /* Initialize the storage from integer X, in precision N. */ > > template <int N> > > template <typename T> > > inline fixed_wide_int_storage <N>::fixed_wide_int_storage (const T &x) > > { > > /* Check for type compatibility. We don't want to initialize a > > fixed-width integer from something like a wide_int. */ > > WI_BINARY_RESULT (T, FIXED_WIDE_INT (N)) *assertion ATTRIBUTE_UNUSED; > > wide_int_ref xi (x, N); > > len = xi.len; > > for (unsigned int i = 0; i < len; ++i) > > val[i] = xi.val[i]; > > } > > > > it avoids a 2nd copy though, which shows nicely what was rummaging in > > my head for the last two days - that the int_trais <> abstraction > > was somehow at the wrong level - it should have been traits that > > are specific to the storage model? or the above should use > > int_traits<>::decompose manually with it always doing the > > copy (that would also optimize away one copy and eventually > > would make the extra zeros not necessary). > this came in with richard's storage manager patch. In my older code, we > tried and succeeded many times to just borrow the underlying rep. I think > that richard needs to work this out. > > I originally thought that extra zeros get rid of all copying from trees > > to all wide-int kinds. > > > > What's the reason again to not use my original proposed encoding > > of the MSB being the sign bit? RTL constants simply are all signed > > then. Just you have to also sign-extend in functions like lts_p > > as not all constants are sign-extended. But we can use both tree > > (with the now appended zero) and RTL constants representation > > unchanged. > I am not following you here. In trees, the msb is effectively a sign bit, > even for unsigned numbers because we add that extra block. > > but inside of wide int, we do not add extra blocks beyond the precision. > That would be messy for a lot of other reasons.
Can you elaborate? It would make tree and RTX reps directly usable, only wide-int-to-tree and wide-int-to-rtx need special handling. Richard.