Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Wed, Apr 24, 2013 at 5:29 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 4:35 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:
 On 04/24/2013 09:36 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

 I'm not sure what you mean here.  CONST_INT HWIs are already
 sign-extended
 from mode precision to HWI precision.  The 8-bit value 0xb1000 must
 be
 represented as (const_int -128); nothing else is allowed.  E.g.
 (const_int 128)
 is not a valid QImode value on BITS_PER_UNIT==8 targets.

 Yes, that's what I understand.  But consider you get a CONST_INT that is
 _not_ a valid QImode value.  Current code simply trusts that it is, given
 the context from ...

 And the fact that it we have to trust but cannot verify is a severe problem
 at the rtl level that is not going to go away.what i have been strongly
 objecting to is your idea that just because we cannot verify it, we can thus
 go change it in some completely different way (i.e. the infinite precision
 nonsense that you keep hitting us with) and it will all be ok.

 Appearantly it is all ok because that's exactly what we have today (and
 had for the last 25 years).  CONST_INT encodes infinite precision signed
 values (with the complication that a QImode 0x80 isn't valid, thus all
 modes are signed as well it seems).

 I think this is the fundamental disagreement.  Your last step doesn't
 follow.  RTL integer modes are neither signed nor unsigned.  They are
 just a collection of N bits.  The fact that CONST_INTs represent
 smaller-than-HWI integers in sign-extended form is purely a represential
 detail.  There are no semantics attached to it.  We could just as easily
 have decided to extend with zeros or ones instead of sign bits.

 Although the decision was made before my time, I'm pretty sure the
 point of having a canonical representation (which happened to be sign
 extension) was to make sure that any given rtl constant has only a
 single representation.  It would be too confusing if a QImode 0x80 could
 be represented as either (const_int 128) or (const_int -128) (would
 (const_int 384) then also be OK?).

No, not as value for a QImode as it doesn't fit there.

 And that's the problem with using an infinite-precision wide_int.
 If you directly convert a CONST_INT representation of 0x80 into a
 wide_int, you will always get infinite-precision -128, thanks to the
 CONST_INT canonicalisation rule.  But if you arrive at 0x80 though
 arithmetic, you might get infinite-precision 128 instead.  These two
 values would not compare equal.

That's true.  Note that I am not objecting to the canonicalization choice
for the RTL object.  On trees we do have -128 and 128 QImode integers
as tree constants have a sign.

So we clearly cannot have wide_int make that choice, but those that
create either a tree object or a RTL object have to do additional
canonicalization (or truncation to not allow a QImode 384).

Yes, I'm again arguing that making choices for wide_int shouldn't be
done because it seems right for RTL or right for how a CPU operates.
But we are mixing two things in this series of patches - introduction
of an additional RTX object kind CONST_WIDE_INT together with
deciding on its encoding of constant values, and introduction of
a wide_int class as a vehicle to do arithmetic on the host for larger
than HOST_WIDE_INT values.

The latter could be separated by dropping CONST_DOUBLE in favor
of CONST_WIDE_INT everywhere and simply providing a
CONST_WIDE_INT - double-int interface (both ways, so you'd
actually never generate a CONST_WIDE_INT that doesn't fit a double-int).

 CONST_DOUBLE encodes infinite precision signed values as well.  Just
 the infinite is limited by the size of the encoding, one and two
 HOST_WIDE_INTs.

 It encodes an N-bit integer.  It's just that (assuming non-power-of-2
 modes) several N-bit integers (with varying N) can be encoded using the
 same CONST_DOUBLE representation.  That might be what you meant, sorry,
 and so might seem pedantic, but I wasn't sure.

Yes, that's what I meant.  Being able to share the same RTX object for
constants with the same representation but a different mode is nice
and looks appealing (of course works only when the actual mode stored
in the RTX object is then sth like VOIDmode ...).  That we have gazillions
of NULL pointer constants on trees (for each pointer type) isn't.

Richard.

 Richard


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Wed, Apr 24, 2013 at 5:55 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2 widths).

 Note that the argument should be about CONST_WIDE_INT here,
 not wide-int.  Indeed CONST_WIDE_INT has the desired feature
 and can be properly truncated/extended according to mode at the time
 we build it
 via immed_wide_int_cst (w, mode).  I don't see the requirement that
 wide-int itself is automagically providing that truncation/extension
 (though it is a possibility, one that does not match existing behavior of
 HWI for CONST_INT or double-int for CONST_DOUBLE).

 I agree it doesn't match the existing behaviour of HWI for CONST_INT or
 double-int for CONST_DOUBLE, but I think that's very much a good thing.
 The model for HWIs at the moment is that you have to truncate results
 to the canonical form after every operation where it matters.  As you
 proved in your earlier message about the plus_constant bug, that's easily
 forgotten.  I don't think the rtl code is doing all CONST_INT arithmetic
 on full HWIs because it wants to: it's doing it because that's the way
 C/C++ arithmetic on primitive types works.  In other words, the current
 CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N)
 using a single primitive integer type.  wide_int gives us N-bit arithmetic
 directly; no emulation is needed.

 Ok, so what wide-int provides is integer values encoded in 'len' HWI
 words that fit in 'precision' or more bits (and often in less).  wide-int
 also provides N-bit arithmetic operations.  IMHO both are tied
 too closely together.  A give constant doesn't really have a precision.

 I disagree.  All rtl objects have a precision.  REGs, MEMs, SYMBOL_REFs,
 LABEL_REFs and CONSTs all have precisions, and the last three are
 run-time constants.  Why should CONST_INT and CONST_DOUBLE be different?

Well - they _are_ different.  They don't even have a mode at the moment.
If you want to change that be my guest (or well, it's unfortunate to lose
the sharing then) - but Kenny always repeats that this is impossible to fix.
Having CONST_INT and CONST_DOUBLE without a precision but
CONST_WIDE_INT with a precision would be at least odd.

 See e.g. the hoops that cselib has to jump through:

 /* We need to pass down the mode of constants through the hash table
functions.  For that purpose, wrap them in a CONST of the appropriate
mode.  */
 static rtx
 wrap_constant (enum machine_mode mode, rtx x)
 {
   if ((!CONST_SCALAR_INT_P (x))  GET_CODE (x) != CONST_FIXED)
 return x;
   gcc_assert (mode != VOIDmode);
   return gen_rtx_CONST (mode, x);
 }

 That is, cselib locally converts (const_int X) into (const:M (const_int X)),
 purely so that it doesn't lose track of the CONST_INT's mode.
 (const:M (const_int ...)) is invalid rtl elsewhere, but a necessary
 hack here all the same.

Indeed ugly.  But I wonder why cselib needs to store constants in
hashtables at all ... they should be VALUEs themselves.  So the fix
for the above might not necessarily be to assign the CONST_INT
a mode (not that CONST_WIDE_INT would fix the above).

 What RTL currently has looks better to me - operations have
 explicitely specified precisions.

 But that isn't enough to determine the precision of all operands.
 A classic case is ZERO_EXTEND.  Something like:

(zero_extend:DI (reg:SI X))

 is unambiguous.  But if you substitute (reg:SI X) with a CONST_INT,
 the result becomes ambiguous.  E.g. we could end up with:

(zero_extend:DI (const_int -1))

 The ZERO_EXTEND operand still has SImode, but that fact is not explicit
 in the rtl, and is certainly not explicit in the ZERO_EXTEND operation.
 So if we just see the result above, we no longer know whether the result
 should be (const_int 0xff), (const_int 0x), or what.  The same goes for:

That situation only occurs when you have unfolded RTX.  You should
have never generated the above (and hopefully the RTL verifier doesn't
allow it), but instead called sth like

  simplify_gen_zero_extend (DImode, SImode, x);

with x being the constant substituted for X.  It's probably unfortunate
that parts of the RTL machinery work like (if I remember correctly)
for_each_rtx (x, replace-interesting-stuff); simplify (x);

(zero_extend:DI (const_int 256))

 where (const_int 0) and (const_int 256) are both potential results.

 It's not just ZERO_EXTEND.  E.g.:

   (zero_extract:SI ...)

 tells you that an SImode value is being extracted, but it doesn't tell
 you what precision you're extracting from.  So for:

   

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Thu, Apr 25, 2013 at 1:18 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 On 04/24/2013 11:13 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
 rdsandif...@googlemail.com  wrote:

 Richard Bienerrichard.guent...@gmail.com  writes:

 On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
 rdsandif...@googlemail.com  wrote:

 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2 widths).

 Note that the argument should be about CONST_WIDE_INT here,
 not wide-int.  Indeed CONST_WIDE_INT has the desired feature
 and can be properly truncated/extended according to mode at the time we
 build it
 via immed_wide_int_cst (w, mode).  I don't see the requirement that
 wide-int itself is automagically providing that truncation/extension
 (though it is a possibility, one that does not match existing behavior
 of
 HWI for CONST_INT or double-int for CONST_DOUBLE).

 I agree it doesn't match the existing behaviour of HWI for CONST_INT or
 double-int for CONST_DOUBLE, but I think that's very much a good thing.
 The model for HWIs at the moment is that you have to truncate results
 to the canonical form after every operation where it matters.  As you
 proved in your earlier message about the plus_constant bug, that's easily
 forgotten.  I don't think the rtl code is doing all CONST_INT arithmetic
 on full HWIs because it wants to: it's doing it because that's the way
 C/C++ arithmetic on primitive types works.  In other words, the current
 CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N)
 using a single primitive integer type.  wide_int gives us N-bit
 arithmetic
 directly; no emulation is needed.

 Ok, so what wide-int provides is integer values encoded in 'len' HWI
 words that fit in 'precision' or more bits (and often in less).  wide-int
 also provides N-bit arithmetic operations.  IMHO both are tied
 too closely together.  A give constant doesn't really have a precision.
 Associating one with it to give a precision to an arithmetic operation
 looks wrong to me and are a source of mismatches.

 What RTL currently has looks better to me - operations have
 explicitely specified precisions.

 I have tried very hard to make wide-int work very efficiently with both tree
 and rtl without biasing the rep towards either representation.  Both rtl and
 trees constants have a precision.   In tree, constants are done better than
 in rtl because the tree really does have a field that is filled in that
 points to a type. However, that does not mean that rtl constants do not have
 a precision: currently you have to look around at the context to find the
 mode of a constant that is in your hand, but it is in fact always there.
 At the rtl level, you can see the entire patch - we always find an
 appropriate mode.

Appearantly you cannot.  See Richard S. examples.

As of better, the tree has the issue that we have so many unshared
constants because they only differ in type but not in their representation.
That's the nice part of RTL constants all having VOIDmode ...

Richard.


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Kenneth Zadeck

On 05/03/2013 07:34 AM, Richard Biener wrote:

On Thu, Apr 25, 2013 at 1:18 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 04/24/2013 11:13 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

Richard Bienerrichard.guent...@gmail.com  writes:

On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

In other words, one of the reasons wide_int can't be exactly 1:1
in practice is because it is clearing out these mistakes (GEN_INT
rather than gen_int_mode) and missing features (non-power-of-2 widths).

Note that the argument should be about CONST_WIDE_INT here,
not wide-int.  Indeed CONST_WIDE_INT has the desired feature
and can be properly truncated/extended according to mode at the time we
build it
via immed_wide_int_cst (w, mode).  I don't see the requirement that
wide-int itself is automagically providing that truncation/extension
(though it is a possibility, one that does not match existing behavior
of
HWI for CONST_INT or double-int for CONST_DOUBLE).

I agree it doesn't match the existing behaviour of HWI for CONST_INT or
double-int for CONST_DOUBLE, but I think that's very much a good thing.
The model for HWIs at the moment is that you have to truncate results
to the canonical form after every operation where it matters.  As you
proved in your earlier message about the plus_constant bug, that's easily
forgotten.  I don't think the rtl code is doing all CONST_INT arithmetic
on full HWIs because it wants to: it's doing it because that's the way
C/C++ arithmetic on primitive types works.  In other words, the current
CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N)
using a single primitive integer type.  wide_int gives us N-bit
arithmetic
directly; no emulation is needed.

Ok, so what wide-int provides is integer values encoded in 'len' HWI
words that fit in 'precision' or more bits (and often in less).  wide-int
also provides N-bit arithmetic operations.  IMHO both are tied
too closely together.  A give constant doesn't really have a precision.
Associating one with it to give a precision to an arithmetic operation
looks wrong to me and are a source of mismatches.

What RTL currently has looks better to me - operations have
explicitely specified precisions.

I have tried very hard to make wide-int work very efficiently with both tree
and rtl without biasing the rep towards either representation.  Both rtl and
trees constants have a precision.   In tree, constants are done better than
in rtl because the tree really does have a field that is filled in that
points to a type. However, that does not mean that rtl constants do not have
a precision: currently you have to look around at the context to find the
mode of a constant that is in your hand, but it is in fact always there.
At the rtl level, you can see the entire patch - we always find an
appropriate mode.

Appearantly you cannot.  See Richard S. examples.

As of better, the tree has the issue that we have so many unshared
constants because they only differ in type but not in their representation.
That's the nice part of RTL constants all having VOIDmode ...

Richard.
I said we could always find a mode, i did not say that in order to find 
the mode we did not have to stand on our head, juggle chainsaws and say 
mother may i.   The decision to leave the mode as void in rtl integer 
constants was made to save space, but comes with an otherwise very high 
cost and in today's world of cheap memory seems fairly dated.   It is a 
decision that i and others would love to change and the truth is wide 
int is one step in that direction (in that it gets rid of the pun of 
using double-int for both integers and floats where the discriminator is 
voidmode for ints.) But for now we have to live with that poor decision.


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Fri, May 3, 2013 at 1:49 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 On 05/03/2013 07:34 AM, Richard Biener wrote:

 On Thu, Apr 25, 2013 at 1:18 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 04/24/2013 11:13 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
 rdsandif...@googlemail.com  wrote:

 Richard Bienerrichard.guent...@gmail.com  writes:

 On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
 rdsandif...@googlemail.com  wrote:

 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2
 widths).

 Note that the argument should be about CONST_WIDE_INT here,
 not wide-int.  Indeed CONST_WIDE_INT has the desired feature
 and can be properly truncated/extended according to mode at the time
 we
 build it
 via immed_wide_int_cst (w, mode).  I don't see the requirement that
 wide-int itself is automagically providing that truncation/extension
 (though it is a possibility, one that does not match existing behavior
 of
 HWI for CONST_INT or double-int for CONST_DOUBLE).

 I agree it doesn't match the existing behaviour of HWI for CONST_INT or
 double-int for CONST_DOUBLE, but I think that's very much a good thing.
 The model for HWIs at the moment is that you have to truncate results
 to the canonical form after every operation where it matters.  As you
 proved in your earlier message about the plus_constant bug, that's
 easily
 forgotten.  I don't think the rtl code is doing all CONST_INT
 arithmetic
 on full HWIs because it wants to: it's doing it because that's the way
 C/C++ arithmetic on primitive types works.  In other words, the current
 CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime
 N)
 using a single primitive integer type.  wide_int gives us N-bit
 arithmetic
 directly; no emulation is needed.

 Ok, so what wide-int provides is integer values encoded in 'len' HWI
 words that fit in 'precision' or more bits (and often in less).
 wide-int
 also provides N-bit arithmetic operations.  IMHO both are tied
 too closely together.  A give constant doesn't really have a precision.
 Associating one with it to give a precision to an arithmetic operation
 looks wrong to me and are a source of mismatches.

 What RTL currently has looks better to me - operations have
 explicitely specified precisions.

 I have tried very hard to make wide-int work very efficiently with both
 tree
 and rtl without biasing the rep towards either representation.  Both rtl
 and
 trees constants have a precision.   In tree, constants are done better
 than
 in rtl because the tree really does have a field that is filled in that
 points to a type. However, that does not mean that rtl constants do not
 have
 a precision: currently you have to look around at the context to find the
 mode of a constant that is in your hand, but it is in fact always there.
 At the rtl level, you can see the entire patch - we always find an
 appropriate mode.

 Appearantly you cannot.  See Richard S. examples.

 As of better, the tree has the issue that we have so many unshared
 constants because they only differ in type but not in their
 representation.
 That's the nice part of RTL constants all having VOIDmode ...

 Richard.

 I said we could always find a mode, i did not say that in order to find the
 mode we did not have to stand on our head, juggle chainsaws and say mother
 may i.   The decision to leave the mode as void in rtl integer constants
 was made to save space, but comes with an otherwise very high cost and in
 today's world of cheap memory seems fairly dated.   It is a decision that i
 and others would love to change and the truth is wide int is one step in
 that direction (in that it gets rid of the pun of using double-int for both
 integers and floats where the discriminator is voidmode for ints.) But for
 now we have to live with that poor decision.

As far as I have read your wide-int patches the CONST_WIDE_INT RTX
object does not include a mode.  So I don't see it as a step forward in
any way (other than that it makes it explicit that you _do_ need a mode
to do any operation on a constant).

Richard.


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Kenneth Zadeck

On 05/03/2013 08:12 AM, Richard Biener wrote:

On Fri, May 3, 2013 at 1:49 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:

On 05/03/2013 07:34 AM, Richard Biener wrote:

On Thu, Apr 25, 2013 at 1:18 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 04/24/2013 11:13 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

Richard Bienerrichard.guent...@gmail.com  writes:

On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

In other words, one of the reasons wide_int can't be exactly 1:1
in practice is because it is clearing out these mistakes (GEN_INT
rather than gen_int_mode) and missing features (non-power-of-2
widths).

Note that the argument should be about CONST_WIDE_INT here,
not wide-int.  Indeed CONST_WIDE_INT has the desired feature
and can be properly truncated/extended according to mode at the time
we
build it
via immed_wide_int_cst (w, mode).  I don't see the requirement that
wide-int itself is automagically providing that truncation/extension
(though it is a possibility, one that does not match existing behavior
of
HWI for CONST_INT or double-int for CONST_DOUBLE).

I agree it doesn't match the existing behaviour of HWI for CONST_INT or
double-int for CONST_DOUBLE, but I think that's very much a good thing.
The model for HWIs at the moment is that you have to truncate results
to the canonical form after every operation where it matters.  As you
proved in your earlier message about the plus_constant bug, that's
easily
forgotten.  I don't think the rtl code is doing all CONST_INT
arithmetic
on full HWIs because it wants to: it's doing it because that's the way
C/C++ arithmetic on primitive types works.  In other words, the current
CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime
N)
using a single primitive integer type.  wide_int gives us N-bit
arithmetic
directly; no emulation is needed.

Ok, so what wide-int provides is integer values encoded in 'len' HWI
words that fit in 'precision' or more bits (and often in less).
wide-int
also provides N-bit arithmetic operations.  IMHO both are tied
too closely together.  A give constant doesn't really have a precision.
Associating one with it to give a precision to an arithmetic operation
looks wrong to me and are a source of mismatches.

What RTL currently has looks better to me - operations have
explicitely specified precisions.

I have tried very hard to make wide-int work very efficiently with both
tree
and rtl without biasing the rep towards either representation.  Both rtl
and
trees constants have a precision.   In tree, constants are done better
than
in rtl because the tree really does have a field that is filled in that
points to a type. However, that does not mean that rtl constants do not
have
a precision: currently you have to look around at the context to find the
mode of a constant that is in your hand, but it is in fact always there.
At the rtl level, you can see the entire patch - we always find an
appropriate mode.

Appearantly you cannot.  See Richard S. examples.

As of better, the tree has the issue that we have so many unshared
constants because they only differ in type but not in their
representation.
That's the nice part of RTL constants all having VOIDmode ...

Richard.

I said we could always find a mode, i did not say that in order to find the
mode we did not have to stand on our head, juggle chainsaws and say mother
may i.   The decision to leave the mode as void in rtl integer constants
was made to save space, but comes with an otherwise very high cost and in
today's world of cheap memory seems fairly dated.   It is a decision that i
and others would love to change and the truth is wide int is one step in
that direction (in that it gets rid of the pun of using double-int for both
integers and floats where the discriminator is voidmode for ints.) But for
now we have to live with that poor decision.

As far as I have read your wide-int patches the CONST_WIDE_INT RTX
object does not include a mode.  So I don't see it as a step forward in
any way (other than that it makes it explicit that you _do_ need a mode
to do any operation on a constant).

Richard.
There are several problems with just dropping a mode into the already 
existing mode field of an rtx constant.
1) There may be places where the a back end is testing equality to see 
if constants of different modes are in fact the same value.
2) Most of the places what build int constants use GEN_INT which does 
not take a mode, even though about 95% of those places have a mode right 
there and the rest just take a little work.There are constructor 
that do take a mode, but in the end they just throw the mode on the floor.
3) The canonical test to see if a CONST_DOUBLE contains an int or float 
is to test if the mode is VOIDmode.


Any port that is converted to have TARGET_SUPPORTS_WIDE_INT has no more 
of problem (3).   I admit that rooting out (1) is 

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 See e.g. the hoops that cselib has to jump through:

 /* We need to pass down the mode of constants through the hash table
functions.  For that purpose, wrap them in a CONST of the appropriate
mode.  */
 static rtx
 wrap_constant (enum machine_mode mode, rtx x)
 {
   if ((!CONST_SCALAR_INT_P (x))  GET_CODE (x) != CONST_FIXED)
 return x;
   gcc_assert (mode != VOIDmode);
   return gen_rtx_CONST (mode, x);
 }

 That is, cselib locally converts (const_int X) into (const:M (const_int X)),
 purely so that it doesn't lose track of the CONST_INT's mode.
 (const:M (const_int ...)) is invalid rtl elsewhere, but a necessary
 hack here all the same.

 Indeed ugly.  But I wonder why cselib needs to store constants in
 hashtables at all ... they should be VALUEs themselves.  So the fix
 for the above might not necessarily be to assign the CONST_INT
 a mode (not that CONST_WIDE_INT would fix the above).

I don't understand.  Do you mean that cselib values ought to have
a field to say whether the value is constant or not, and if so, what
constant that is?  That feels like just the same kind of hack as the above.
The current idea of chaining all known equivalent rtxes in a list seems
more natural than having a list of all known equivalent rtxes except
CONST_INT and CONST_DOUBLE, which have to be stored separately instead.
(Again, we have runtime constants like SYMBOL_REF, which store modes,
and which would presumably still be in the normal rtx list.)

CONST_WIDE_INT was never supposed to solve this problem.  I'm just giving
it as an example to back up the argument that rtx constants do in fact
have modes (although those modes are not stored in the rtx).  The code
above is there to make sure that equivalence stays transitive.
Without it we could have bogus equivalences like:

  (A) (reg:DI X) == (const_int Y) == (reg:SI Z)

even though it cannot be the case that:

  (B) (reg:DI X) == (reg:SI Z)

My point is that, semantically, (A) did not come from X and Z being
equivalent to the same constant.  X was equivalent to (const_int:DI Y)
and Z was equivalent to (const_int:SI Y).  (A) only came about because
we happen to use the same rtx object to represent those two semantically-
distinct constants.

The idea isn't to make CONST_WIDE_INT get rid of the code above.
The idea is to make sure that wide_int has a precision and so doesn't
require code like the above to be written when dealing with wide_ints.

In other words, I got the impression your argument was the fact
that CONST_INT and CONST_DOUBLE don't store a mode shows that
wide_int shouldn't store a precision.  But the fact that CONST_INT
and CONST_DOUBLE don't store a mode doesn't mean they don't _have_
a mode.  You just have to keep track of that mode separately.
And the same would apply to wide_int if we did the same thing there.

What I was trying to argue was that storing the mode/precision
separately is not always easy.  It's also much less robust,
because getting the wrong mode or precision will only show up
for certain values.  If the precision is stored in the wide_int,
mismatches can be asserted for based on precision alone, regardless
of the value.

 Ok, so please then make all CONST_INTs and CONST_DOUBLEs have
 a mode!

I'm saying that CONST_INT and CONST_DOUBLE already have a mode, but that
mode is not stored in the rtx.  So if you're saying make all CONST_INTs
and CONST_DOUBLEs _store_ a mode, then yeah, I'd like to :-)  But I see
Kenny's patch as a prerequisite for that, because it consolidates the
CONST_INT and CONST_DOUBLE code so that the choice of rtx code is
less special.  Lots more work is needed after that.

Although TBH, the huge pushback that Kenny has got from this patch
puts me off ever trying that change.

But storing the mode in the rtx is orthogonal to what Kenny is doing.
The mode of each rtx constant is already available in the places
that Kenny is changing, because we already do the work to keep track
of the mode separately.  Being able to get the mode directly from the
rtx would be simpler and IMO better, but the semantics are the same
either way.

Kenny's patch is not designed to fix the CONST_INT representation
(although the patch does make it easier to fix the representation
in future).  Kenny's patch is about representing and handling constants
that we can't at the moment.

The argument isn't whether CONST_WIDE_INT repeats mistakes made for
CONST_INT and CONST_DOUBLE; I hope we agree that CONST_WIDE_INT should
behave like the other two, whatever that is.  The argument is about
whether we copy the mistake into the wide_int class.

Storing a precision in wide_int in no way requires CONST_WIDE_INT
to store a mode.  They are separate choices.

 The solution is not to have a CONST_WIDE_INT (again with VOIDmode
 and no precision in the RTX object(!)) and only have wide_int have a
 precision.

Why is having a VOIDmode CONST_WIDE_INT any worse than having
a VOIDmode CONST_INT or 

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Fri, May 3, 2013 at 2:31 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 On 05/03/2013 08:12 AM, Richard Biener wrote:

 On Fri, May 3, 2013 at 1:49 PM, Kenneth Zadeck zad...@naturalbridge.com
 wrote:

 On 05/03/2013 07:34 AM, Richard Biener wrote:

 On Thu, Apr 25, 2013 at 1:18 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 04/24/2013 11:13 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
 rdsandif...@googlemail.com  wrote:

 Richard Bienerrichard.guent...@gmail.com  writes:

 On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
 rdsandif...@googlemail.com  wrote:

 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2
 widths).

 Note that the argument should be about CONST_WIDE_INT here,
 not wide-int.  Indeed CONST_WIDE_INT has the desired feature
 and can be properly truncated/extended according to mode at the time
 we
 build it
 via immed_wide_int_cst (w, mode).  I don't see the requirement that
 wide-int itself is automagically providing that truncation/extension
 (though it is a possibility, one that does not match existing
 behavior
 of
 HWI for CONST_INT or double-int for CONST_DOUBLE).

 I agree it doesn't match the existing behaviour of HWI for CONST_INT
 or
 double-int for CONST_DOUBLE, but I think that's very much a good
 thing.
 The model for HWIs at the moment is that you have to truncate results
 to the canonical form after every operation where it matters.  As you
 proved in your earlier message about the plus_constant bug, that's
 easily
 forgotten.  I don't think the rtl code is doing all CONST_INT
 arithmetic
 on full HWIs because it wants to: it's doing it because that's the
 way
 C/C++ arithmetic on primitive types works.  In other words, the
 current
 CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime
 N)
 using a single primitive integer type.  wide_int gives us N-bit
 arithmetic
 directly; no emulation is needed.

 Ok, so what wide-int provides is integer values encoded in 'len' HWI
 words that fit in 'precision' or more bits (and often in less).
 wide-int
 also provides N-bit arithmetic operations.  IMHO both are tied
 too closely together.  A give constant doesn't really have a
 precision.
 Associating one with it to give a precision to an arithmetic operation
 looks wrong to me and are a source of mismatches.

 What RTL currently has looks better to me - operations have
 explicitely specified precisions.

 I have tried very hard to make wide-int work very efficiently with both
 tree
 and rtl without biasing the rep towards either representation.  Both
 rtl
 and
 trees constants have a precision.   In tree, constants are done better
 than
 in rtl because the tree really does have a field that is filled in that
 points to a type. However, that does not mean that rtl constants do not
 have
 a precision: currently you have to look around at the context to find
 the
 mode of a constant that is in your hand, but it is in fact always
 there.
 At the rtl level, you can see the entire patch - we always find an
 appropriate mode.

 Appearantly you cannot.  See Richard S. examples.

 As of better, the tree has the issue that we have so many unshared
 constants because they only differ in type but not in their
 representation.
 That's the nice part of RTL constants all having VOIDmode ...

 Richard.

 I said we could always find a mode, i did not say that in order to find
 the
 mode we did not have to stand on our head, juggle chainsaws and say
 mother
 may i.   The decision to leave the mode as void in rtl integer constants
 was made to save space, but comes with an otherwise very high cost and in
 today's world of cheap memory seems fairly dated.   It is a decision that
 i
 and others would love to change and the truth is wide int is one step in
 that direction (in that it gets rid of the pun of using double-int for
 both
 integers and floats where the discriminator is voidmode for ints.) But
 for
 now we have to live with that poor decision.

 As far as I have read your wide-int patches the CONST_WIDE_INT RTX
 object does not include a mode.  So I don't see it as a step forward in
 any way (other than that it makes it explicit that you _do_ need a mode
 to do any operation on a constant).

 Richard.

 There are several problems with just dropping a mode into the already
 existing mode field of an rtx constant.
 1) There may be places where the a back end is testing equality to see if
 constants of different modes are in fact the same value.

That supposedly only happens in places where both RTX objects are
know to be constants.  Which makes me guess that it's in 99% of the
cases a comparison against one of the static RTX objects like
const0_rtx - thus easily greppable for (and easily converted similar
to the tree case where we have predicates for such tests like integer_zerop ()).

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Kenneth Zadeck

On 05/03/2013 07:19 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 5:29 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Wed, Apr 24, 2013 at 4:35 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 04/24/2013 09:36 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

Can we in such cases please to a preparatory patch and change the
CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
mode precision first?

I'm not sure what you mean here.  CONST_INT HWIs are already
sign-extended
from mode precision to HWI precision.  The 8-bit value 0xb1000 must
be
represented as (const_int -128); nothing else is allowed.  E.g.
(const_int 128)
is not a valid QImode value on BITS_PER_UNIT==8 targets.

Yes, that's what I understand.  But consider you get a CONST_INT that is
_not_ a valid QImode value.  Current code simply trusts that it is, given
the context from ...

And the fact that it we have to trust but cannot verify is a severe problem
at the rtl level that is not going to go away.what i have been strongly
objecting to is your idea that just because we cannot verify it, we can thus
go change it in some completely different way (i.e. the infinite precision
nonsense that you keep hitting us with) and it will all be ok.

Appearantly it is all ok because that's exactly what we have today (and
had for the last 25 years).  CONST_INT encodes infinite precision signed
values (with the complication that a QImode 0x80 isn't valid, thus all
modes are signed as well it seems).

I think this is the fundamental disagreement.  Your last step doesn't
follow.  RTL integer modes are neither signed nor unsigned.  They are
just a collection of N bits.  The fact that CONST_INTs represent
smaller-than-HWI integers in sign-extended form is purely a represential
detail.  There are no semantics attached to it.  We could just as easily
have decided to extend with zeros or ones instead of sign bits.

Although the decision was made before my time, I'm pretty sure the
point of having a canonical representation (which happened to be sign
extension) was to make sure that any given rtl constant has only a
single representation.  It would be too confusing if a QImode 0x80 could
be represented as either (const_int 128) or (const_int -128) (would
(const_int 384) then also be OK?).

No, not as value for a QImode as it doesn't fit there.


And that's the problem with using an infinite-precision wide_int.
If you directly convert a CONST_INT representation of 0x80 into a
wide_int, you will always get infinite-precision -128, thanks to the
CONST_INT canonicalisation rule.  But if you arrive at 0x80 though
arithmetic, you might get infinite-precision 128 instead.  These two
values would not compare equal.

That's true.  Note that I am not objecting to the canonicalization choice
for the RTL object.  On trees we do have -128 and 128 QImode integers
as tree constants have a sign.

So we clearly cannot have wide_int make that choice, but those that
create either a tree object or a RTL object have to do additional
canonicalization (or truncation to not allow a QImode 384).

Yes, I'm again arguing that making choices for wide_int shouldn't be
done because it seems right for RTL or right for how a CPU operates.
But we are mixing two things in this series of patches - introduction
of an additional RTX object kind CONST_WIDE_INT together with
deciding on its encoding of constant values, and introduction of
a wide_int class as a vehicle to do arithmetic on the host for larger
than HOST_WIDE_INT values.

The latter could be separated by dropping CONST_DOUBLE in favor
of CONST_WIDE_INT everywhere and simply providing a
CONST_WIDE_INT - double-int interface (both ways, so you'd
actually never generate a CONST_WIDE_INT that doesn't fit a double-int).
Given the tree world, i am surprised that you would push in this 
direction.   While i do see some benefit for having two reps for ints at 
the rtl level, I understand the argument that is one too many.


The target_supports_wide_int is a transitional trick.   The idea is to 
move the ports away from using CONST_DOUBLE at all for ints. Not only is 
this a step towards putting a mode in an rtl int const, but it also 
would allow the floating point world to move beyond the limits that 
sharing the rep with integers imposes.


One of the big goals of this cleanup is to get rid of the three path 
implementation for integer math:

constant fits in HWI - good implementation.
constant fits in 2 HWIs - spotty implementation.
constant needs more than 2 HWIs - ice or get wrong answer.

Doing a trick like this just makes it harder to unify everything into 
the good implementation category.





CONST_DOUBLE encodes infinite precision signed values as well.  Just
the infinite is limited by the size of the encoding, one and two
HOST_WIDE_INTs.


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Sandiford
Kenneth Zadeck zad...@naturalbridge.com writes:
 There are several problems with just dropping a mode into the already 
 existing mode field of an rtx constant.
 1) There may be places where the a back end is testing equality to see 
 if constants of different modes are in fact the same value.
 2) Most of the places what build int constants use GEN_INT which does 
 not take a mode, even though about 95% of those places have a mode right 
 there and the rest just take a little work.There are constructor 
 that do take a mode, but in the end they just throw the mode on the floor.
 3) The canonical test to see if a CONST_DOUBLE contains an int or float 
 is to test if the mode is VOIDmode.

 Any port that is converted to have TARGET_SUPPORTS_WIDE_INT has no more 
 of problem (3).   I admit that rooting out (1) is likely to be the worst 
 of the problems.   But we were careful to at least make this work move 
 us in the correct direction.

I agree with that, and FWIW, there are others.  Two off the top of my head:

4) Many places use const0_rtx instead of CONST0_RTX (mode) (correctly,
   according to current representation)
5) All const_ints in the .md files would need to be given a mode
   (except for those places where const_int actually represents
   a C++ constant, such as in attributes).

I realise your list wasn't supposed to be exhaustive, and neither's mine :-)

Richard


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Fri, May 3, 2013 at 2:37 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 See e.g. the hoops that cselib has to jump through:

 /* We need to pass down the mode of constants through the hash table
functions.  For that purpose, wrap them in a CONST of the appropriate
mode.  */
 static rtx
 wrap_constant (enum machine_mode mode, rtx x)
 {
   if ((!CONST_SCALAR_INT_P (x))  GET_CODE (x) != CONST_FIXED)
 return x;
   gcc_assert (mode != VOIDmode);
   return gen_rtx_CONST (mode, x);
 }

 That is, cselib locally converts (const_int X) into (const:M (const_int X)),
 purely so that it doesn't lose track of the CONST_INT's mode.
 (const:M (const_int ...)) is invalid rtl elsewhere, but a necessary
 hack here all the same.

 Indeed ugly.  But I wonder why cselib needs to store constants in
 hashtables at all ... they should be VALUEs themselves.  So the fix
 for the above might not necessarily be to assign the CONST_INT
 a mode (not that CONST_WIDE_INT would fix the above).

 I don't understand.  Do you mean that cselib values ought to have
 a field to say whether the value is constant or not, and if so, what
 constant that is?  That feels like just the same kind of hack as the above.
 The current idea of chaining all known equivalent rtxes in a list seems
 more natural than having a list of all known equivalent rtxes except
 CONST_INT and CONST_DOUBLE, which have to be stored separately instead.
 (Again, we have runtime constants like SYMBOL_REF, which store modes,
 and which would presumably still be in the normal rtx list.)

 CONST_WIDE_INT was never supposed to solve this problem.  I'm just giving
 it as an example to back up the argument that rtx constants do in fact
 have modes (although those modes are not stored in the rtx).  The code
 above is there to make sure that equivalence stays transitive.
 Without it we could have bogus equivalences like:

   (A) (reg:DI X) == (const_int Y) == (reg:SI Z)

 even though it cannot be the case that:

   (B) (reg:DI X) == (reg:SI Z)

 My point is that, semantically, (A) did not come from X and Z being
 equivalent to the same constant.  X was equivalent to (const_int:DI Y)
 and Z was equivalent to (const_int:SI Y).  (A) only came about because
 we happen to use the same rtx object to represent those two semantically-
 distinct constants.

 The idea isn't to make CONST_WIDE_INT get rid of the code above.
 The idea is to make sure that wide_int has a precision and so doesn't
 require code like the above to be written when dealing with wide_ints.

 In other words, I got the impression your argument was the fact
 that CONST_INT and CONST_DOUBLE don't store a mode shows that
 wide_int shouldn't store a precision.  But the fact that CONST_INT
 and CONST_DOUBLE don't store a mode doesn't mean they don't _have_
 a mode.  You just have to keep track of that mode separately.
 And the same would apply to wide_int if we did the same thing there.

 What I was trying to argue was that storing the mode/precision
 separately is not always easy.  It's also much less robust,
 because getting the wrong mode or precision will only show up
 for certain values.  If the precision is stored in the wide_int,
 mismatches can be asserted for based on precision alone, regardless
 of the value.

I was just arguing that pointing out facts in the RTL land doesn't
necessarily influence wide-int which is purely separate.  So if you
argue that having a mode in RTL constants would be soo nice and
thus that is why you want a precision in wide-int then I don't follow
that argument.  If you want a mode in RTL constants then get a mode
in RTL constants!

This would make it immediately obvious where to get the precision
for wide-ints - something you do not address at all (and as you don't
I sort of cannot believe the 'it would be so nice to have a mode on RTL
constants').

That said, if modes on RTL constants were so useful then why not
have them on CONST_WIDE_INT at least?  Please.  Only sticking
them to wide-int in form of a precision is completely backward to me
(and I still think the core wide-int shouldn't have a precision, and if
you really want a wide-int-with-precision simply derive from wide-int).

 Ok, so please then make all CONST_INTs and CONST_DOUBLEs have
 a mode!

 I'm saying that CONST_INT and CONST_DOUBLE already have a mode, but that
 mode is not stored in the rtx.  So if you're saying make all CONST_INTs
 and CONST_DOUBLEs _store_ a mode, then yeah, I'd like to :-)  But I see
 Kenny's patch as a prerequisite for that, because it consolidates the
 CONST_INT and CONST_DOUBLE code so that the choice of rtx code is
 less special.  Lots more work is needed after that.

If there were a separate patch consolidating the paths I'd be all for
doing that.
I don't see a reason that this cannot be done even with the current
code using double-ints.

 Although TBH, the huge pushback that Kenny has got from this patch
 puts me off ever 

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Fri, May 3, 2013 at 2:45 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 On 05/03/2013 07:19 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 5:29 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 On Wed, Apr 24, 2013 at 4:35 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 04/24/2013 09:36 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

 I'm not sure what you mean here.  CONST_INT HWIs are already
 sign-extended
 from mode precision to HWI precision.  The 8-bit value 0xb1000
 must
 be
 represented as (const_int -128); nothing else is allowed.  E.g.
 (const_int 128)
 is not a valid QImode value on BITS_PER_UNIT==8 targets.

 Yes, that's what I understand.  But consider you get a CONST_INT that
 is
 _not_ a valid QImode value.  Current code simply trusts that it is,
 given
 the context from ...

 And the fact that it we have to trust but cannot verify is a severe
 problem
 at the rtl level that is not going to go away.what i have been
 strongly
 objecting to is your idea that just because we cannot verify it, we can
 thus
 go change it in some completely different way (i.e. the infinite
 precision
 nonsense that you keep hitting us with) and it will all be ok.

 Appearantly it is all ok because that's exactly what we have today (and
 had for the last 25 years).  CONST_INT encodes infinite precision signed
 values (with the complication that a QImode 0x80 isn't valid, thus all
 modes are signed as well it seems).

 I think this is the fundamental disagreement.  Your last step doesn't
 follow.  RTL integer modes are neither signed nor unsigned.  They are
 just a collection of N bits.  The fact that CONST_INTs represent
 smaller-than-HWI integers in sign-extended form is purely a represential
 detail.  There are no semantics attached to it.  We could just as easily
 have decided to extend with zeros or ones instead of sign bits.

 Although the decision was made before my time, I'm pretty sure the
 point of having a canonical representation (which happened to be sign
 extension) was to make sure that any given rtl constant has only a
 single representation.  It would be too confusing if a QImode 0x80 could
 be represented as either (const_int 128) or (const_int -128) (would
 (const_int 384) then also be OK?).

 No, not as value for a QImode as it doesn't fit there.

 And that's the problem with using an infinite-precision wide_int.
 If you directly convert a CONST_INT representation of 0x80 into a
 wide_int, you will always get infinite-precision -128, thanks to the
 CONST_INT canonicalisation rule.  But if you arrive at 0x80 though
 arithmetic, you might get infinite-precision 128 instead.  These two
 values would not compare equal.

 That's true.  Note that I am not objecting to the canonicalization choice
 for the RTL object.  On trees we do have -128 and 128 QImode integers
 as tree constants have a sign.

 So we clearly cannot have wide_int make that choice, but those that
 create either a tree object or a RTL object have to do additional
 canonicalization (or truncation to not allow a QImode 384).

 Yes, I'm again arguing that making choices for wide_int shouldn't be
 done because it seems right for RTL or right for how a CPU operates.
 But we are mixing two things in this series of patches - introduction
 of an additional RTX object kind CONST_WIDE_INT together with
 deciding on its encoding of constant values, and introduction of
 a wide_int class as a vehicle to do arithmetic on the host for larger
 than HOST_WIDE_INT values.

 The latter could be separated by dropping CONST_DOUBLE in favor
 of CONST_WIDE_INT everywhere and simply providing a
 CONST_WIDE_INT - double-int interface (both ways, so you'd
 actually never generate a CONST_WIDE_INT that doesn't fit a double-int).

 Given the tree world, i am surprised that you would push in this direction.
 While i do see some benefit for having two reps for ints at the rtl level, I
 understand the argument that is one too many.

 The target_supports_wide_int is a transitional trick.   The idea is to move
 the ports away from using CONST_DOUBLE at all for ints. Not only is this a
 step towards putting a mode in an rtl int const, but it also would allow the
 floating point world to move beyond the limits that sharing the rep with
 integers imposes.

 One of the big goals of this cleanup is to get rid of the three path
 implementation for integer math:
 constant fits in HWI - good implementation.
 constant fits in 2 HWIs - spotty implementation.
 constant needs more than 2 HWIs - ice or get wrong answer.

 Doing a trick like this just makes it harder to unify everything into the
 good implementation category.


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Biener
On Fri, May 3, 2013 at 2:48 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Kenneth Zadeck zad...@naturalbridge.com writes:
 There are several problems with just dropping a mode into the already
 existing mode field of an rtx constant.
 1) There may be places where the a back end is testing equality to see
 if constants of different modes are in fact the same value.
 2) Most of the places what build int constants use GEN_INT which does
 not take a mode, even though about 95% of those places have a mode right
 there and the rest just take a little work.There are constructor
 that do take a mode, but in the end they just throw the mode on the floor.
 3) The canonical test to see if a CONST_DOUBLE contains an int or float
 is to test if the mode is VOIDmode.

 Any port that is converted to have TARGET_SUPPORTS_WIDE_INT has no more
 of problem (3).   I admit that rooting out (1) is likely to be the worst
 of the problems.   But we were careful to at least make this work move
 us in the correct direction.

 I agree with that, and FWIW, there are others.  Two off the top of my head:

 4) Many places use const0_rtx instead of CONST0_RTX (mode) (correctly,
according to current representation)

As it's easy from the context to get at a mode just drop const0_rtx
and fix the fallout? (and complicate the CONST0_RTX macro to
dispatch to const_int_rtx for integer modes)

 5) All const_ints in the .md files would need to be given a mode
(except for those places where const_int actually represents
a C++ constant, such as in attributes).

 I realise your list wasn't supposed to be exhaustive, and neither's mine :-)

Now, do you think it is a good idea to assign integer constants a mode
or not?

Richard.

 Richard


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 5) All const_ints in the .md files would need to be given a mode
(except for those places where const_int actually represents
a C++ constant, such as in attributes).

 I realise your list wasn't supposed to be exhaustive, and neither's mine :-)

 Now, do you think it is a good idea to assign integer constants a mode
 or not?

I think the answer was obvious: good idea.  But it's an aspiration.
The huge amount of work involved means that it's out of scope unless
someone has several spare months on their hands.

The equivalent choice for wide_ints is not an aspiration.  The choice
is in ours hands.  So why force the class to use the old, problematic
model that rtl followed when (a) there are no compatiblity reasons
to do so and (b) Kenny has already written an implementation that
does it the better way?

The main reason we share the same CONST_INT and CONST_DOUBLE representation
for distinct constants is to save memory.  Even that's not an advantage
for wide_int, since wide_ints are supposed to be short-lived stack objects.

Richard


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 But storing the mode in the rtx is orthogonal to what Kenny is doing.
 The mode of each rtx constant is already available in the places
 that Kenny is changing, because we already do the work to keep track
 of the mode separately.  Being able to get the mode directly from the
 rtx would be simpler and IMO better, but the semantics are the same
 either way.

 Well, you showed examples where it is impossible to get at the mode.

No, I showed examples where the mode is not inherent in the rtl.
That's a very different thing.  I wrote that in respnose to:

Richard Biener richard.guent...@gmail.com writes:
 Ok, so what wide-int provides is integer values encoded in 'len' HWI
 words that fit in 'precision' or more bits (and often in less).  wide-int
 also provides N-bit arithmetic operations.  IMHO both are tied
 too closely together.  A give constant doesn't really have a precision.
 Associating one with it to give a precision to an arithmetic operation
 looks wrong to me and are a source of mismatches.

 What RTL currently has looks better to me - operations have
 explicitely specified precisions.

That is, you seemed to be arguing that constants don't need a precision
because, whenever you do anything with them, the operator tells you
what precision the constant has.  And you seemed to be citing rtl
as proof of that.

What I was trying to show is that the operator _doesn't_ tell you the
precision in all cases.  Instead, the operands always have their own
precision, and there are rules about which combinations of operand and
operator precision are allowed.  For most binary operations the three
precisions have to be the same.  For things like popcount there's no
real restriction: the precision of the thing being counted and the
precision of the result can be arbitrarily different.  For things like
zero_extend the operator precision must be greater than the operand
precision.  Etc.

The onus is then on the rtl code to keep track of both the operator
and operand precisions where necessary.  _And the current rtl code
already tries to do that_[*].  The cselib example I gave is one place
where we take special measures.  See also things like:

  /* Now recursively process each operand of this operation.  We need to
 handle ZERO_EXTEND specially so that we don't lose track of the
 inner mode.  */
  if (GET_CODE (x) == ZERO_EXTEND)
{
  new_rtx = make_compound_operation (XEXP (x, 0), next_code);
  tem = simplify_const_unary_operation (ZERO_EXTEND, GET_MODE (x),
new_rtx, GET_MODE (XEXP (x, 0)));
  if (tem)
return tem;
  SUBST (XEXP (x, 0), new_rtx);
  return x;
}

in combine.c, which is there specifically because this code still knows
the mode of both the operand and operator.

So all this was trying to dispel the idea that:

(a) rtl constants don't have a mode
(b) the mode of an operator tells you the mode of the operands

Neither is really true.  Instead, every rtl constant has a precision/mode.
Every tree constant likewise has a precision.  The main purpose of wide_int
is to handle compile-time arithmetic on rtl constants and tree constants,
and if both of those have a precision, it seems strange that wide_int
shouldn't.  It just pushes the onus of tracking the precision onto the
callers, like the current rtl representation does.  And the examples
I've been giving were supposed to show what a hassle that can be.

  [*] Highlighted because that's why storing a mode in a CONST_INT or
  CONST_DOUBLE isn't a prerequisite for Kenny's patch.  The mode
  is already to hand where it needs to be.

Thanks,
Richard


Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Kenneth Zadeck

On 05/03/2013 08:40 AM, Richard Biener wrote:

On Fri, May 3, 2013 at 2:31 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:

On 05/03/2013 08:12 AM, Richard Biener wrote:

On Fri, May 3, 2013 at 1:49 PM, Kenneth Zadeck zad...@naturalbridge.com
wrote:

On 05/03/2013 07:34 AM, Richard Biener wrote:

On Thu, Apr 25, 2013 at 1:18 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 04/24/2013 11:13 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

Richard Bienerrichard.guent...@gmail.com  writes:

On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

In other words, one of the reasons wide_int can't be exactly 1:1
in practice is because it is clearing out these mistakes (GEN_INT
rather than gen_int_mode) and missing features (non-power-of-2
widths).

Note that the argument should be about CONST_WIDE_INT here,
not wide-int.  Indeed CONST_WIDE_INT has the desired feature
and can be properly truncated/extended according to mode at the time
we
build it
via immed_wide_int_cst (w, mode).  I don't see the requirement that
wide-int itself is automagically providing that truncation/extension
(though it is a possibility, one that does not match existing
behavior
of
HWI for CONST_INT or double-int for CONST_DOUBLE).

I agree it doesn't match the existing behaviour of HWI for CONST_INT
or
double-int for CONST_DOUBLE, but I think that's very much a good
thing.
The model for HWIs at the moment is that you have to truncate results
to the canonical form after every operation where it matters.  As you
proved in your earlier message about the plus_constant bug, that's
easily
forgotten.  I don't think the rtl code is doing all CONST_INT
arithmetic
on full HWIs because it wants to: it's doing it because that's the
way
C/C++ arithmetic on primitive types works.  In other words, the
current
CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime
N)
using a single primitive integer type.  wide_int gives us N-bit
arithmetic
directly; no emulation is needed.

Ok, so what wide-int provides is integer values encoded in 'len' HWI
words that fit in 'precision' or more bits (and often in less).
wide-int
also provides N-bit arithmetic operations.  IMHO both are tied
too closely together.  A give constant doesn't really have a
precision.
Associating one with it to give a precision to an arithmetic operation
looks wrong to me and are a source of mismatches.

What RTL currently has looks better to me - operations have
explicitely specified precisions.

I have tried very hard to make wide-int work very efficiently with both
tree
and rtl without biasing the rep towards either representation.  Both
rtl
and
trees constants have a precision.   In tree, constants are done better
than
in rtl because the tree really does have a field that is filled in that
points to a type. However, that does not mean that rtl constants do not
have
a precision: currently you have to look around at the context to find
the
mode of a constant that is in your hand, but it is in fact always
there.
At the rtl level, you can see the entire patch - we always find an
appropriate mode.

Appearantly you cannot.  See Richard S. examples.

As of better, the tree has the issue that we have so many unshared
constants because they only differ in type but not in their
representation.
That's the nice part of RTL constants all having VOIDmode ...

Richard.

I said we could always find a mode, i did not say that in order to find
the
mode we did not have to stand on our head, juggle chainsaws and say
mother
may i.   The decision to leave the mode as void in rtl integer constants
was made to save space, but comes with an otherwise very high cost and in
today's world of cheap memory seems fairly dated.   It is a decision that
i
and others would love to change and the truth is wide int is one step in
that direction (in that it gets rid of the pun of using double-int for
both
integers and floats where the discriminator is voidmode for ints.) But
for
now we have to live with that poor decision.

As far as I have read your wide-int patches the CONST_WIDE_INT RTX
object does not include a mode.  So I don't see it as a step forward in
any way (other than that it makes it explicit that you _do_ need a mode
to do any operation on a constant).

Richard.

There are several problems with just dropping a mode into the already
existing mode field of an rtx constant.
1) There may be places where the a back end is testing equality to see if
constants of different modes are in fact the same value.

That supposedly only happens in places where both RTX objects are
know to be constants.  Which makes me guess that it's in 99% of the
cases a comparison against one of the static RTX objects like
const0_rtx - thus easily greppable for (and easily converted similar
to the tree case where we have predicates for such tests like integer_zerop ()).
The remaining cases would be missed optimizations at 

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Kenneth Zadeck

On 05/03/2013 08:53 AM, Richard Biener wrote:

On Fri, May 3, 2013 at 2:37 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

See e.g. the hoops that cselib has to jump through:

/* We need to pass down the mode of constants through the hash table
functions.  For that purpose, wrap them in a CONST of the appropriate
mode.  */
static rtx
wrap_constant (enum machine_mode mode, rtx x)
{
   if ((!CONST_SCALAR_INT_P (x))  GET_CODE (x) != CONST_FIXED)
 return x;
   gcc_assert (mode != VOIDmode);
   return gen_rtx_CONST (mode, x);
}

That is, cselib locally converts (const_int X) into (const:M (const_int X)),
purely so that it doesn't lose track of the CONST_INT's mode.
(const:M (const_int ...)) is invalid rtl elsewhere, but a necessary
hack here all the same.

Indeed ugly.  But I wonder why cselib needs to store constants in
hashtables at all ... they should be VALUEs themselves.  So the fix
for the above might not necessarily be to assign the CONST_INT
a mode (not that CONST_WIDE_INT would fix the above).

I don't understand.  Do you mean that cselib values ought to have
a field to say whether the value is constant or not, and if so, what
constant that is?  That feels like just the same kind of hack as the above.
The current idea of chaining all known equivalent rtxes in a list seems
more natural than having a list of all known equivalent rtxes except
CONST_INT and CONST_DOUBLE, which have to be stored separately instead.
(Again, we have runtime constants like SYMBOL_REF, which store modes,
and which would presumably still be in the normal rtx list.)

CONST_WIDE_INT was never supposed to solve this problem.  I'm just giving
it as an example to back up the argument that rtx constants do in fact
have modes (although those modes are not stored in the rtx).  The code
above is there to make sure that equivalence stays transitive.
Without it we could have bogus equivalences like:

   (A) (reg:DI X) == (const_int Y) == (reg:SI Z)

even though it cannot be the case that:

   (B) (reg:DI X) == (reg:SI Z)

My point is that, semantically, (A) did not come from X and Z being
equivalent to the same constant.  X was equivalent to (const_int:DI Y)
and Z was equivalent to (const_int:SI Y).  (A) only came about because
we happen to use the same rtx object to represent those two semantically-
distinct constants.

The idea isn't to make CONST_WIDE_INT get rid of the code above.
The idea is to make sure that wide_int has a precision and so doesn't
require code like the above to be written when dealing with wide_ints.

In other words, I got the impression your argument was the fact
that CONST_INT and CONST_DOUBLE don't store a mode shows that
wide_int shouldn't store a precision.  But the fact that CONST_INT
and CONST_DOUBLE don't store a mode doesn't mean they don't _have_
a mode.  You just have to keep track of that mode separately.
And the same would apply to wide_int if we did the same thing there.

What I was trying to argue was that storing the mode/precision
separately is not always easy.  It's also much less robust,
because getting the wrong mode or precision will only show up
for certain values.  If the precision is stored in the wide_int,
mismatches can be asserted for based on precision alone, regardless
of the value.

I was just arguing that pointing out facts in the RTL land doesn't
necessarily influence wide-int which is purely separate.  So if you
argue that having a mode in RTL constants would be soo nice and
thus that is why you want a precision in wide-int then I don't follow
that argument.  If you want a mode in RTL constants then get a mode
in RTL constants!

This would make it immediately obvious where to get the precision
for wide-ints - something you do not address at all (and as you don't
I sort of cannot believe the 'it would be so nice to have a mode on RTL
constants').

That said, if modes on RTL constants were so useful then why not
have them on CONST_WIDE_INT at least?  Please.  Only sticking
them to wide-int in form of a precision is completely backward to me
(and I still think the core wide-int shouldn't have a precision, and if
you really want a wide-int-with-precision simply derive from wide-int).


Ok, so please then make all CONST_INTs and CONST_DOUBLEs have
a mode!

I'm saying that CONST_INT and CONST_DOUBLE already have a mode, but that
mode is not stored in the rtx.  So if you're saying make all CONST_INTs
and CONST_DOUBLEs _store_ a mode, then yeah, I'd like to :-)  But I see
Kenny's patch as a prerequisite for that, because it consolidates the
CONST_INT and CONST_DOUBLE code so that the choice of rtx code is
less special.  Lots more work is needed after that.

If there were a separate patch consolidating the paths I'd be all for
doing that.
I don't see a reason that this cannot be done even with the current
code using double-ints.


Although TBH, the huge pushback that Kenny has got from this patch
puts me off ever trying 

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Kenneth Zadeck

On 05/03/2013 09:02 AM, Richard Biener wrote:

On Fri, May 3, 2013 at 2:45 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:

On 05/03/2013 07:19 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 5:29 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Wed, Apr 24, 2013 at 4:35 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 04/24/2013 09:36 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

Can we in such cases please to a preparatory patch and change the
CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
mode precision first?

I'm not sure what you mean here.  CONST_INT HWIs are already
sign-extended
from mode precision to HWI precision.  The 8-bit value 0xb1000
must
be
represented as (const_int -128); nothing else is allowed.  E.g.
(const_int 128)
is not a valid QImode value on BITS_PER_UNIT==8 targets.

Yes, that's what I understand.  But consider you get a CONST_INT that
is
_not_ a valid QImode value.  Current code simply trusts that it is,
given
the context from ...

And the fact that it we have to trust but cannot verify is a severe
problem
at the rtl level that is not going to go away.what i have been
strongly
objecting to is your idea that just because we cannot verify it, we can
thus
go change it in some completely different way (i.e. the infinite
precision
nonsense that you keep hitting us with) and it will all be ok.

Appearantly it is all ok because that's exactly what we have today (and
had for the last 25 years).  CONST_INT encodes infinite precision signed
values (with the complication that a QImode 0x80 isn't valid, thus all
modes are signed as well it seems).

I think this is the fundamental disagreement.  Your last step doesn't
follow.  RTL integer modes are neither signed nor unsigned.  They are
just a collection of N bits.  The fact that CONST_INTs represent
smaller-than-HWI integers in sign-extended form is purely a represential
detail.  There are no semantics attached to it.  We could just as easily
have decided to extend with zeros or ones instead of sign bits.

Although the decision was made before my time, I'm pretty sure the
point of having a canonical representation (which happened to be sign
extension) was to make sure that any given rtl constant has only a
single representation.  It would be too confusing if a QImode 0x80 could
be represented as either (const_int 128) or (const_int -128) (would
(const_int 384) then also be OK?).

No, not as value for a QImode as it doesn't fit there.


And that's the problem with using an infinite-precision wide_int.
If you directly convert a CONST_INT representation of 0x80 into a
wide_int, you will always get infinite-precision -128, thanks to the
CONST_INT canonicalisation rule.  But if you arrive at 0x80 though
arithmetic, you might get infinite-precision 128 instead.  These two
values would not compare equal.

That's true.  Note that I am not objecting to the canonicalization choice
for the RTL object.  On trees we do have -128 and 128 QImode integers
as tree constants have a sign.

So we clearly cannot have wide_int make that choice, but those that
create either a tree object or a RTL object have to do additional
canonicalization (or truncation to not allow a QImode 384).

Yes, I'm again arguing that making choices for wide_int shouldn't be
done because it seems right for RTL or right for how a CPU operates.
But we are mixing two things in this series of patches - introduction
of an additional RTX object kind CONST_WIDE_INT together with
deciding on its encoding of constant values, and introduction of
a wide_int class as a vehicle to do arithmetic on the host for larger
than HOST_WIDE_INT values.

The latter could be separated by dropping CONST_DOUBLE in favor
of CONST_WIDE_INT everywhere and simply providing a
CONST_WIDE_INT - double-int interface (both ways, so you'd
actually never generate a CONST_WIDE_INT that doesn't fit a double-int).

Given the tree world, i am surprised that you would push in this direction.
While i do see some benefit for having two reps for ints at the rtl level, I
understand the argument that is one too many.

The target_supports_wide_int is a transitional trick.   The idea is to move
the ports away from using CONST_DOUBLE at all for ints. Not only is this a
step towards putting a mode in an rtl int const, but it also would allow the
floating point world to move beyond the limits that sharing the rep with
integers imposes.

One of the big goals of this cleanup is to get rid of the three path
implementation for integer math:
constant fits in HWI - good implementation.
constant fits in 2 HWIs - spotty implementation.
constant needs more than 2 HWIs - ice or get wrong answer.

Doing a trick like this just makes it harder to unify everything into the
good implementation category.



CONST_DOUBLE encodes infinite 

Re: patch to fix constant math -5th patch, rtl

2013-05-03 Thread Kenneth Zadeck

Richi,

I also think that it is a digression to have this discussion about 
rtl.The root problem is really that Mike, Richard, and myself do not 
believe that infinite precision math is the proper way to do math for 
the majority of the compiler.   Most of the compiler, at both the rtl 
and tree level just does the math inline.   There are 314 places at the 
tree level where we ask if the value fits in a hwi and then we do the 
hwi inline math.   The rtl level is even more skewed towards this style 
of programming.  While you view replacing double-int as my primary goal, 
it accounts for the minority of the places in the code where wide-int 
needs to be used.


Furthermore to call what is done in double-int infinite precision is 
really pushing it.   Because it certainly is not infinite if you happen 
to have a TImode variable.


What i did when i designed wide-int was to come up with a mechanism 
where i could preserve the performance of that inline math while 
generalizing it so that it worked correctly for any width. That is why 
the precision is there.   It allows me to avoid the hard work 99% of the 
time, with an inline test of the precision and then a branch free 
calculation of the answer.   For instance there is no loop checking for 
carries and propagating them.


I also feel strongly that it is our responsibility to preserve, to the 
extent possible, the notion that optimization never changes the output 
of a program, except of course for timing.   We, in the optimization 
community, do not always so do so well here, but at the very least, we 
should always try.   Having said that, there are optimizations like VRP 
that really do need to do math larger than precision defined in the 
type.   I get this, and always have.   I understand that if you truncate 
multiplies, add or subtracts, in VRP then the resulting range is not 
simple and becomes too difficult to reasonably represent.I have no 
intention of giving up anything in VRP.   My plan for that is to look at 
the types used in function being compiled and take the largest type, 
double the precision, and do all of the math within VRP at that expanded 
fixed precision.   We can always guarantee that we can do this in 
wide-int since the size of the buffer is computed by looking at the 
target's modes and taking the largest one those times a comfortable 
multipler.   Since you cannot have a type without a corresponding mode, 
this will always work.   This scheme preserves the behavior of VRP while 
making it work with any sized integer.
The alternative is to use a true infinite precision package for VRP but 
i think that is overkill.


Kenny



Re: patch to fix constant math - builtins.c - the first of the tree level patches for wide-int

2013-05-02 Thread Kenneth Zadeck

The only changes here were account for the changes to the wide-int api.

On 04/16/2013 04:24 PM, Kenneth Zadeck wrote:
Richard, this is the first of the tree level patches so that you can 
see how the wide-int changes will effect the tree level.   This patch 
converts builtins.c so that it does not in any way assume that 
tree-cst holds two HWIs.   The patch divides all math into two 
categories:   Things that are always so small that we can easily 
assume that the math can be done using a single HWI and everything 
else.   The things that it assumes can easily be done with a HWI are 
guarded with assertions.   The everything else is done with wide-int.  
Everything else in this patch is additional abi to support this.


The idea is that each pass will be converted, 1 pass per patch in this 
way.Once everything does not depend on the internals of tree-cst 
as they do now, then tree-cst will be converted to have an array 
inside of it rather than just two hwis.


Kenny


diff --git a/gcc/builtins.c b/gcc/builtins.c
index 0c587d1..181784b 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -339,8 +339,8 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
   if (TREE_CODE (addr) == BIT_AND_EXPR
 	   TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
 	{
-	  align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
-		 -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
+	  align = (tree_to_hwi (TREE_OPERAND (addr, 1))
+		-tree_to_hwi (TREE_OPERAND (addr, 1)));
 	  align *= BITS_PER_UNIT;
 	  addr = TREE_OPERAND (addr, 0);
 	}
@@ -357,7 +357,7 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
 	{
 	  unsigned HOST_WIDE_INT step = 1;
 	  if (TMR_STEP (exp))
-		step = TREE_INT_CST_LOW (TMR_STEP (exp));
+		step = tree_to_hwi (TMR_STEP (exp));
 	  align = MIN (align, (step  -step) * BITS_PER_UNIT);
 	}
 	  if (TMR_INDEX2 (exp))
@@ -379,7 +379,8 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
 	  bitpos += ptr_bitpos;
 	  if (TREE_CODE (exp) == MEM_REF
 	  || TREE_CODE (exp) == TARGET_MEM_REF)
-	bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
+	bitpos += wide_int::from_tree (TREE_OPERAND (exp, 1))
+	  .to_shwi () * BITS_PER_UNIT;
 	}
 }
   else if (TREE_CODE (exp) == STRING_CST)
@@ -408,23 +409,23 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
 	}
   else
 	next_offset = NULL;
-  if (host_integerp (offset, 1))
+  if (tree_fits_uhwi_p (offset))
 	{
 	  /* Any overflow in calculating offset_bits won't change
 	 the alignment.  */
 	  unsigned offset_bits
-	= ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
+	= ((unsigned) tree_to_hwi (offset) * BITS_PER_UNIT);
 
 	  if (offset_bits)
 	inner = MIN (inner, (offset_bits  -offset_bits));
 	}
   else if (TREE_CODE (offset) == MULT_EXPR
-	host_integerp (TREE_OPERAND (offset, 1), 1))
+	tree_fits_uhwi_p (TREE_OPERAND (offset, 1)))
 	{
 	  /* Any overflow in calculating offset_factor won't change
 	 the alignment.  */
 	  unsigned offset_factor
-	= ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
+	= ((unsigned) tree_to_hwi (TREE_OPERAND (offset, 1))
 	   * BITS_PER_UNIT);
 
 	  if (offset_factor)
@@ -515,7 +516,7 @@ get_pointer_alignment_1 (tree exp, unsigned int *alignp,
   else if (TREE_CODE (exp) == INTEGER_CST)
 {
   *alignp = BIGGEST_ALIGNMENT;
-  *bitposp = ((TREE_INT_CST_LOW (exp) * BITS_PER_UNIT)
+  *bitposp = ((tree_to_hwi (exp) * BITS_PER_UNIT)
 		   (BIGGEST_ALIGNMENT - 1));
   return true;
 }
@@ -624,10 +625,10 @@ c_strlen (tree src, int only_value)
  a null character if we can represent it as a single HOST_WIDE_INT.  */
   if (offset_node == 0)
 offset = 0;
-  else if (! host_integerp (offset_node, 0))
+  else if (!tree_fits_shwi_p (offset_node))
 offset = -1;
   else
-offset = tree_low_cst (offset_node, 0);
+offset = tree_to_hwi (offset_node);
 
   /* If the offset is known to be out of bounds, warn, and call strlen at
  runtime.  */
@@ -665,11 +666,11 @@ c_getstr (tree src)
 
   if (offset_node == 0)
 return TREE_STRING_POINTER (src);
-  else if (!host_integerp (offset_node, 1)
+  else if (!tree_fits_uhwi_p (offset_node)
 	   || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1)  0)
 return 0;
 
-  return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
+  return TREE_STRING_POINTER (src) + tree_to_uhwi (offset_node);
 }
 
 /* Return a constant integer corresponding to target reading
@@ -723,7 +724,9 @@ target_char_cast (tree cst, char *p)
   || CHAR_TYPE_SIZE  HOST_BITS_PER_WIDE_INT)
 return 1;
 
-  val = TREE_INT_CST_LOW (cst);
+  /* Do not care if it fits or not right here.  */
+  val = tree_to_hwi (cst);
+
   if (CHAR_TYPE_SIZE  HOST_BITS_PER_WIDE_INT)
 val = (((unsigned HOST_WIDE_INT) 1)  CHAR_TYPE_SIZE) - 1;
 
@@ -3168,7 +3171,7 @@ expand_builtin_mempcpy_args (tree dest, tree src, tree len,
 	return 

Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 I suppose the above should use immed_double_int_const (v, mode), too,

In practice it doesn't matter, because...

 which oddly only ever truncates to mode for modes = HOST_BITS_PER_WIDE_INT
 via gen_int_mode.

...right.  That's because there's not really any proper support for
non-power-of-2 modes.  Partial modes like PDI are specified by things like:

PARTIAL_INT_MODE (DI);

which is glaringly absent of any bit width.  So if the constant is big
enough to need 2 HWIs, it in practice must be exactly 2 HWIs wide.
One of the advantages of wide_int is that it allows us to relax this
restriction: we can have both (a) mode widths greater than
HOST_BITS_PER_WIDE_INT*2 and (b) mode widths that are greater than
HOST_BITS_PER_WIDE_INT while not being a multiple of it.

In other words, one of the reasons wide_int can't be exactly 1:1
in practice is because it is clearing out these mistakes (GEN_INT
rather than gen_int_mode) and missing features (non-power-of-2 widths).

Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Kenneth Zadeck

On 04/24/2013 09:36 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

Can we in such cases please to a preparatory patch and change the
CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
mode precision first?

I'm not sure what you mean here.  CONST_INT HWIs are already sign-extended
from mode precision to HWI precision.  The 8-bit value 0xb1000 must be
represented as (const_int -128); nothing else is allowed.  E.g. (const_int 128)
is not a valid QImode value on BITS_PER_UNIT==8 targets.

Yes, that's what I understand.  But consider you get a CONST_INT that is
_not_ a valid QImode value.  Current code simply trusts that it is, given
the context from ...
And the fact that it we have to trust but cannot verify is a severe 
problem at the rtl level that is not going to go away.what i have 
been strongly objecting to is your idea that just because we cannot 
verify it, we can thus go change it in some completely different way 
(i.e. the infinite precision nonsense that you keep hitting us with) and 
it will all be ok.


I have three problems with this.

1) Even if we could do this, it gives us answers that are not what the 
programmer expects!!
Understand this!!!  Programmers expect the code to behave the same way 
if they optimize it or not.   If you do infinite precision arithmetic 
you get different answers than the machine may give you. While the C and 
C++ standards allow this, it is NOT desirable. While there are some 
optimizations that must make visible changes to be effective, this is 
certainly not the case with infinite precision mathMaking the change 
to infinite precision math only because you think is pretty is NOT best 
practices and will only give GCC a bad reputation in the community.


Each programming language defines what it means to do constant 
arithmetic and by and large, our front ends do this the way they say.  
But once you go beyond that, you are squarely in the realm where an 
optimizer is expected to try to make the program run fast without 
changing the results.  Infinite precision math in the optimizations is 
visible in that A * B / C may get different answers between an infinite 
precision evaluation and one that is finite precision as specified by 
the types.  And all of this without any possible upside to the 
programmer.   Why would we want to drive people to use llvm?   This 
is my primary objection.If you ever gave any reason for infinite 
precision aside from that you consider it pretty, then i would consider 
it.BUT THIS IS NOT WHAT PROGRAMMERS WANT


2) The rtl level of GCC does not follow best practices by today's 
standards.It is quite fragile. At this point, the best that can 
be said is that it generally seems to work.   What you are asking is for 
us to make the assumption that the code is in fact in better shape than 
it is.I understand that in your mind, you are objecting to letting 
the back ends hold back something that you believe the middle ends 
should do, but the truth is that this is a bad idea for the middle ends.


3) If i am on a 32 bit machine and i say GEN_INT (0x), i get a 
32 bit word with 32 1s in it.   There is no other information. In 
particular there is no information that tells me was that a -1 or was 
that the largest positive integer.   We do not have GEN_INTS and a 
GEN_INTU, we just have GEN_INT.  Your desire is that we can take those 
32 bits and apply the lt_p function, not the ltu_p or lts_p function, 
but an lu_p function and use that to compare those 32 bits to 
something.   At the rtl level  there is simply not enough information 
there to sign extend this value.   This will never work without a major 
rewrite of the back ends.




Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Biener
On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 I suppose the above should use immed_double_int_const (v, mode), too,

 In practice it doesn't matter, because...

 which oddly only ever truncates to mode for modes = HOST_BITS_PER_WIDE_INT
 via gen_int_mode.

 ...right.  That's because there's not really any proper support for
 non-power-of-2 modes.  Partial modes like PDI are specified by things like:

 PARTIAL_INT_MODE (DI);

 which is glaringly absent of any bit width.  So if the constant is big
 enough to need 2 HWIs, it in practice must be exactly 2 HWIs wide.

Ah, of course.

 One of the advantages of wide_int is that it allows us to relax this
 restriction: we can have both (a) mode widths greater than
 HOST_BITS_PER_WIDE_INT*2 and (b) mode widths that are greater than
 HOST_BITS_PER_WIDE_INT while not being a multiple of it.

 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2 widths).

Note that the argument should be about CONST_WIDE_INT here,
not wide-int.  Indeed CONST_WIDE_INT has the desired feature
and can be properly truncated/extended according to mode at the time we build it
via immed_wide_int_cst (w, mode).  I don't see the requirement that
wide-int itself is automagically providing that truncation/extension
(though it is a possibility, one that does not match existing behavior of
HWI for CONST_INT or double-int for CONST_DOUBLE).

Richard.

 Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Kenneth Zadeck

On 04/24/2013 10:42 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

I suppose the above should use immed_double_int_const (v, mode), too,

In practice it doesn't matter, because...


which oddly only ever truncates to mode for modes = HOST_BITS_PER_WIDE_INT
via gen_int_mode.

...right.  That's because there's not really any proper support for
non-power-of-2 modes.  Partial modes like PDI are specified by things like:

PARTIAL_INT_MODE (DI);

which is glaringly absent of any bit width.  So if the constant is big
enough to need 2 HWIs, it in practice must be exactly 2 HWIs wide.

Ah, of course.


One of the advantages of wide_int is that it allows us to relax this
restriction: we can have both (a) mode widths greater than
HOST_BITS_PER_WIDE_INT*2 and (b) mode widths that are greater than
HOST_BITS_PER_WIDE_INT while not being a multiple of it.

In other words, one of the reasons wide_int can't be exactly 1:1
in practice is because it is clearing out these mistakes (GEN_INT
rather than gen_int_mode) and missing features (non-power-of-2 widths).

Note that the argument should be about CONST_WIDE_INT here,
not wide-int.  Indeed CONST_WIDE_INT has the desired feature
and can be properly truncated/extended according to mode at the time we build it
via immed_wide_int_cst (w, mode).  I don't see the requirement that
wide-int itself is automagically providing that truncation/extension
(though it is a possibility, one that does not match existing behavior of
HWI for CONST_INT or double-int for CONST_DOUBLE).

Richard.

yes but you still have the problem with partial ints having no 
length.Our plan was to be very careful and make sure that at no 
point were we doing anything that makes it harder to put modes in 
const_ints, but that is different from going thru everything and doing it.


Partially because of this discussion and some issues that you brought up 
with patch 4, i am removing the trick of being able to say 'wi + rtl' 
because there is no mode for the rtl.
i am leaving the 'wi + tree' because there is enough to info in the 
treecst to make this work.

but you are going to have to say something wi::add (mode, rtl)

see, i am willing to do things that work better in the tree world than 
in the rtl world.


kenny


Richard




Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2 widths).

 Note that the argument should be about CONST_WIDE_INT here,
 not wide-int.  Indeed CONST_WIDE_INT has the desired feature
 and can be properly truncated/extended according to mode at the time we build 
 it
 via immed_wide_int_cst (w, mode).  I don't see the requirement that
 wide-int itself is automagically providing that truncation/extension
 (though it is a possibility, one that does not match existing behavior of
 HWI for CONST_INT or double-int for CONST_DOUBLE).

I agree it doesn't match the existing behaviour of HWI for CONST_INT or
double-int for CONST_DOUBLE, but I think that's very much a good thing.
The model for HWIs at the moment is that you have to truncate results
to the canonical form after every operation where it matters.  As you
proved in your earlier message about the plus_constant bug, that's easily
forgotten.  I don't think the rtl code is doing all CONST_INT arithmetic
on full HWIs because it wants to: it's doing it because that's the way
C/C++ arithmetic on primitive types works.  In other words, the current
CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N)
using a single primitive integer type.  wide_int gives us N-bit arithmetic
directly; no emulation is needed.

If your point is that an arbitrary-precision wide_int could be used by
other (non-rtl, and probably non-tree) clients, then I don't really
see the need.  We already have mpz_t for that.  What we don't have,
and what we IMO need, is something that performs N-bit arithmetic
for runtime N.  It seems better to have a single class that does
that for us (wide_int), rather than scatter N-bit emulation throughout
the codebase, which is what we do now.

Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Biener
On Wed, Apr 24, 2013 at 4:35 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 On 04/24/2013 09:36 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

 I'm not sure what you mean here.  CONST_INT HWIs are already
 sign-extended
 from mode precision to HWI precision.  The 8-bit value 0xb1000 must
 be
 represented as (const_int -128); nothing else is allowed.  E.g.
 (const_int 128)
 is not a valid QImode value on BITS_PER_UNIT==8 targets.

 Yes, that's what I understand.  But consider you get a CONST_INT that is
 _not_ a valid QImode value.  Current code simply trusts that it is, given
 the context from ...

 And the fact that it we have to trust but cannot verify is a severe problem
 at the rtl level that is not going to go away.what i have been strongly
 objecting to is your idea that just because we cannot verify it, we can thus
 go change it in some completely different way (i.e. the infinite precision
 nonsense that you keep hitting us with) and it will all be ok.

Appearantly it is all ok because that's exactly what we have today (and
had for the last 25 years).  CONST_INT encodes infinite precision signed
values (with the complication that a QImode 0x80 isn't valid, thus all
modes are signed as well it seems).  CONST_DOUBLE encodes infinite
precision signed values as well.  Just the infinite is limited by the size
of the encoding, one and two HOST_WIDE_INTs.

The interpretation of those infinite precision constants is based on
the context (the operation mode of the operation we apply to a CONST_INT
or CONST_DOUBLE).  Thus CONST_INT and CONST_DOUBLE do
not have a mode or precision but VOIDmode so different mode 1
can be shared (which is probably the original reason of that design
decision).

 I have three problems with this.

 1) Even if we could do this, it gives us answers that are not what the
 programmer expects!!
 Understand this!!!  Programmers expect the code to behave the same way if
 they optimize it or not.   If you do infinite precision arithmetic you get
 different answers than the machine may give you. While the C and C++
 standards allow this, it is NOT desirable. While there are some
 optimizations that must make visible changes to be effective, this is
 certainly not the case with infinite precision mathMaking the change to
 infinite precision math only because you think is pretty is NOT best
 practices and will only give GCC a bad reputation in the community.

Note that as I tried to explain above this isn't a change.  _You_ are
proposing a change here!  Namely to associate a precision with a _constant_.
What precision does a '1' have?  What precision does a '12374' have?
It doesn't have any.  With this proposed change we will have the possibility
to explicitely program mismatches like

  simplify_binary_operation (PLUS_EXPR, HImode,
 wide_int_rtx (SImode, 27),
wide_int_rtx (QImode, 1))

even if _only_ the desired mode of the result matters!  Because given the
invariant that a wide-int is valid (it doesn't have bits outside of
its precision)
it's precision does no longer matter!

 Each programming language defines what it means to do constant arithmetic
 and by and large, our front ends do this the way they say.  But once you go
 beyond that, you are squarely in the realm where an optimizer is expected to
 try to make the program run fast without changing the results.  Infinite
 precision math in the optimizations is visible in that A * B / C may get
 different answers between an infinite precision evaluation and one that is
 finite precision as specified by the types.  And all of this without any
 possible upside to the programmer.   Why would we want to drive people to
 use llvm?   This is my primary objection.If you ever gave any reason
 for infinite precision aside from that you consider it pretty, then i would
 consider it.BUT THIS IS NOT WHAT PROGRAMMERS WANT

Programming languages or prettiness is not in any way a reason to do
infinite precision math.  All-caps or pretty punctuation does not change that.

Infinite precision math is what we do now.  What I ask for is to make
separate changes separately.  You want larger and host independent
integer constants.  Fine - do that.  You want to change how we do
arithmetic?  Fine - do that.  But please separate the two.  (well, I'm
likely still going to object to the latter)

 2) The rtl level of GCC does not follow best practices by today's standards.
 It is quite fragile.

It works quite well.

 At this point, the best that can be said is that it
 generally seems to work.   What you are asking is for us to make the
 assumption that the code is in fact in better shape than it is.I
 understand 

Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Biener
On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2 widths).

 Note that the argument should be about CONST_WIDE_INT here,
 not wide-int.  Indeed CONST_WIDE_INT has the desired feature
 and can be properly truncated/extended according to mode at the time we 
 build it
 via immed_wide_int_cst (w, mode).  I don't see the requirement that
 wide-int itself is automagically providing that truncation/extension
 (though it is a possibility, one that does not match existing behavior of
 HWI for CONST_INT or double-int for CONST_DOUBLE).

 I agree it doesn't match the existing behaviour of HWI for CONST_INT or
 double-int for CONST_DOUBLE, but I think that's very much a good thing.
 The model for HWIs at the moment is that you have to truncate results
 to the canonical form after every operation where it matters.  As you
 proved in your earlier message about the plus_constant bug, that's easily
 forgotten.  I don't think the rtl code is doing all CONST_INT arithmetic
 on full HWIs because it wants to: it's doing it because that's the way
 C/C++ arithmetic on primitive types works.  In other words, the current
 CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N)
 using a single primitive integer type.  wide_int gives us N-bit arithmetic
 directly; no emulation is needed.

Ok, so what wide-int provides is integer values encoded in 'len' HWI
words that fit in 'precision' or more bits (and often in less).  wide-int
also provides N-bit arithmetic operations.  IMHO both are tied
too closely together.  A give constant doesn't really have a precision.
Associating one with it to give a precision to an arithmetic operation
looks wrong to me and are a source of mismatches.

What RTL currently has looks better to me - operations have
explicitely specified precisions.

 If your point is that an arbitrary-precision wide_int could be used by
 other (non-rtl, and probably non-tree) clients, then I don't really
 see the need.  We already have mpz_t for that.  What we don't have,
 and what we IMO need, is something that performs N-bit arithmetic
 for runtime N.  It seems better to have a single class that does
 that for us (wide_int), rather than scatter N-bit emulation throughout
 the codebase, which is what we do now.

mpz_t is not suitable here - it's way too expensive.  double-int
was the suitable bit for now, but given it's host dependency and
inability to handle larger ints (VRP ...) the ability to use wide-ints
for this looks appealing.

Richard.

 Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 4:35 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:
 On 04/24/2013 09:36 AM, Richard Biener wrote:

 On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

 I'm not sure what you mean here.  CONST_INT HWIs are already
 sign-extended
 from mode precision to HWI precision.  The 8-bit value 0xb1000 must
 be
 represented as (const_int -128); nothing else is allowed.  E.g.
 (const_int 128)
 is not a valid QImode value on BITS_PER_UNIT==8 targets.

 Yes, that's what I understand.  But consider you get a CONST_INT that is
 _not_ a valid QImode value.  Current code simply trusts that it is, given
 the context from ...

 And the fact that it we have to trust but cannot verify is a severe problem
 at the rtl level that is not going to go away.what i have been strongly
 objecting to is your idea that just because we cannot verify it, we can thus
 go change it in some completely different way (i.e. the infinite precision
 nonsense that you keep hitting us with) and it will all be ok.

 Appearantly it is all ok because that's exactly what we have today (and
 had for the last 25 years).  CONST_INT encodes infinite precision signed
 values (with the complication that a QImode 0x80 isn't valid, thus all
 modes are signed as well it seems).

I think this is the fundamental disagreement.  Your last step doesn't
follow.  RTL integer modes are neither signed nor unsigned.  They are
just a collection of N bits.  The fact that CONST_INTs represent
smaller-than-HWI integers in sign-extended form is purely a represential
detail.  There are no semantics attached to it.  We could just as easily
have decided to extend with zeros or ones instead of sign bits.

Although the decision was made before my time, I'm pretty sure the
point of having a canonical representation (which happened to be sign
extension) was to make sure that any given rtl constant has only a
single representation.  It would be too confusing if a QImode 0x80 could
be represented as either (const_int 128) or (const_int -128) (would
(const_int 384) then also be OK?).

And that's the problem with using an infinite-precision wide_int.
If you directly convert a CONST_INT representation of 0x80 into a
wide_int, you will always get infinite-precision -128, thanks to the
CONST_INT canonicalisation rule.  But if you arrive at 0x80 though
arithmetic, you might get infinite-precision 128 instead.  These two
values would not compare equal.

 CONST_DOUBLE encodes infinite precision signed values as well.  Just
 the infinite is limited by the size of the encoding, one and two
 HOST_WIDE_INTs.

It encodes an N-bit integer.  It's just that (assuming non-power-of-2
modes) several N-bit integers (with varying N) can be encoded using the
same CONST_DOUBLE representation.  That might be what you meant, sorry,
and so might seem pedantic, but I wasn't sure.

Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 In other words, one of the reasons wide_int can't be exactly 1:1
 in practice is because it is clearing out these mistakes (GEN_INT
 rather than gen_int_mode) and missing features (non-power-of-2 widths).

 Note that the argument should be about CONST_WIDE_INT here,
 not wide-int.  Indeed CONST_WIDE_INT has the desired feature
 and can be properly truncated/extended according to mode at the time
 we build it
 via immed_wide_int_cst (w, mode).  I don't see the requirement that
 wide-int itself is automagically providing that truncation/extension
 (though it is a possibility, one that does not match existing behavior of
 HWI for CONST_INT or double-int for CONST_DOUBLE).

 I agree it doesn't match the existing behaviour of HWI for CONST_INT or
 double-int for CONST_DOUBLE, but I think that's very much a good thing.
 The model for HWIs at the moment is that you have to truncate results
 to the canonical form after every operation where it matters.  As you
 proved in your earlier message about the plus_constant bug, that's easily
 forgotten.  I don't think the rtl code is doing all CONST_INT arithmetic
 on full HWIs because it wants to: it's doing it because that's the way
 C/C++ arithmetic on primitive types works.  In other words, the current
 CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N)
 using a single primitive integer type.  wide_int gives us N-bit arithmetic
 directly; no emulation is needed.

 Ok, so what wide-int provides is integer values encoded in 'len' HWI
 words that fit in 'precision' or more bits (and often in less).  wide-int
 also provides N-bit arithmetic operations.  IMHO both are tied
 too closely together.  A give constant doesn't really have a precision.

I disagree.  All rtl objects have a precision.  REGs, MEMs, SYMBOL_REFs,
LABEL_REFs and CONSTs all have precisions, and the last three are
run-time constants.  Why should CONST_INT and CONST_DOUBLE be different?

See e.g. the hoops that cselib has to jump through:

/* We need to pass down the mode of constants through the hash table
   functions.  For that purpose, wrap them in a CONST of the appropriate
   mode.  */
static rtx
wrap_constant (enum machine_mode mode, rtx x)
{
  if ((!CONST_SCALAR_INT_P (x))  GET_CODE (x) != CONST_FIXED)
return x;
  gcc_assert (mode != VOIDmode);
  return gen_rtx_CONST (mode, x);
}

That is, cselib locally converts (const_int X) into (const:M (const_int X)),
purely so that it doesn't lose track of the CONST_INT's mode.
(const:M (const_int ...)) is invalid rtl elsewhere, but a necessary
hack here all the same.

 What RTL currently has looks better to me - operations have
 explicitely specified precisions.

But that isn't enough to determine the precision of all operands.
A classic case is ZERO_EXTEND.  Something like:

   (zero_extend:DI (reg:SI X))

is unambiguous.  But if you substitute (reg:SI X) with a CONST_INT,
the result becomes ambiguous.  E.g. we could end up with:

   (zero_extend:DI (const_int -1))

The ZERO_EXTEND operand still has SImode, but that fact is not explicit
in the rtl, and is certainly not explicit in the ZERO_EXTEND operation.
So if we just see the result above, we no longer know whether the result
should be (const_int 0xff), (const_int 0x), or what.  The same goes for:

   (zero_extend:DI (const_int 256))

where (const_int 0) and (const_int 256) are both potential results.

It's not just ZERO_EXTEND.  E.g.:

  (zero_extract:SI ...)

tells you that an SImode value is being extracted, but it doesn't tell
you what precision you're extracting from.  So for:

  (zero_extract:SI (const_int -1) (const_int X) (const_int 3))

how many 1 bits should be the result have?  Because of the sign-extension
canonicalisation, the answer depends on the precision of the (const_int -1),
which has now been lost.  If instead CONST_INTs were stored in zero-extended
form, the same ambiguity would apply to SIGN_EXTRACT.

This sort of thing has been a constant headache in rtl.  I can't stress
how much I feel it is _not_ better than recording the precision of
the constant :-)

Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Kenneth Zadeck

On 04/24/2013 11:13 AM, Richard Biener wrote:

On Wed, Apr 24, 2013 at 5:00 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

Richard Bienerrichard.guent...@gmail.com  writes:

On Wed, Apr 24, 2013 at 4:29 PM, Richard Sandiford
rdsandif...@googlemail.com  wrote:

In other words, one of the reasons wide_int can't be exactly 1:1
in practice is because it is clearing out these mistakes (GEN_INT
rather than gen_int_mode) and missing features (non-power-of-2 widths).

Note that the argument should be about CONST_WIDE_INT here,
not wide-int.  Indeed CONST_WIDE_INT has the desired feature
and can be properly truncated/extended according to mode at the time we build it
via immed_wide_int_cst (w, mode).  I don't see the requirement that
wide-int itself is automagically providing that truncation/extension
(though it is a possibility, one that does not match existing behavior of
HWI for CONST_INT or double-int for CONST_DOUBLE).

I agree it doesn't match the existing behaviour of HWI for CONST_INT or
double-int for CONST_DOUBLE, but I think that's very much a good thing.
The model for HWIs at the moment is that you have to truncate results
to the canonical form after every operation where it matters.  As you
proved in your earlier message about the plus_constant bug, that's easily
forgotten.  I don't think the rtl code is doing all CONST_INT arithmetic
on full HWIs because it wants to: it's doing it because that's the way
C/C++ arithmetic on primitive types works.  In other words, the current
CONST_INT code is trying to emulate N-bit arithmetic (for gcc runtime N)
using a single primitive integer type.  wide_int gives us N-bit arithmetic
directly; no emulation is needed.

Ok, so what wide-int provides is integer values encoded in 'len' HWI
words that fit in 'precision' or more bits (and often in less).  wide-int
also provides N-bit arithmetic operations.  IMHO both are tied
too closely together.  A give constant doesn't really have a precision.
Associating one with it to give a precision to an arithmetic operation
looks wrong to me and are a source of mismatches.

What RTL currently has looks better to me - operations have
explicitely specified precisions.
I have tried very hard to make wide-int work very efficiently with both 
tree and rtl without biasing the rep towards either representation.  
Both rtl and trees constants have a precision.   In tree, constants are 
done better than in rtl because the tree really does have a field that 
is filled in that points to a type. However, that does not mean that rtl 
constants do not have a precision: currently you have to look around at 
the context to find the mode of a constant that is in your hand, but it 
is in fact always there.   At the rtl level, you can see the entire 
patch - we always find an appropriate mode.


In the future, this may change.   Wide-int moves one step closer in that 
ports that support it will not expect that double-ints never have a 
mode.   But that is a long way from having the mode attached.


What is not stored with the constant is a indication of the signedness. 
Unlike a desire to add modes to rtl constants, there is no one even 
thinking about the sign.   The sign is implicit in the operator, just as 
it is at the tree level.


So when i designed wide-int, i assumed that i could get precisions from 
the variables or at least close to them.


As far as the question of infinite precision, 99% of the uses of 
double-int today are get in, do a single operation and get out. If 
this is all that we plan to do, then it does not really matter if it is 
infinite precision or not, because at both the rtl and tree level, we 
truncate on the way out. However, the use of double-int accounts for 
only a small percentage of the math done in the compiler.   My wide-int 
port converts a substantial portion of the math from inline code that is 
guarded by checks to the precision against HOST_WIDE_BITS_PER_INT or 
calls to host_integerp.   The conversion of this code has substantial 
potential to expose the differences between the fixed precision and 
infinite precision representations.


The only justification that you have ever given for wanting to use 
infinite precision is that it is cleaner.   You have never directly 
addressed my point that it gives surprising answers except to say that 
the user would have to put in explicit intermediate truncations.It 
is hard for me to imaging buggering up something as bad as having to put 
in explicit intermediate truncations.   When i write a * b / c, it 
should really look something like the expression.





If your point is that an arbitrary-precision wide_int could be used by
other (non-rtl, and probably non-tree) clients, then I don't really
see the need.  We already have mpz_t for that.  What we don't have,
and what we IMO need, is something that performs N-bit arithmetic
for runtime N.  It seems better to have a single class that does
that for us (wide_int), rather than scatter N-bit 

Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Biener
On Tue, Apr 16, 2013 at 10:17 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 Here is a refreshed version of the rtl changes for wide-int.   the only
 change from the previous versions is that the wide-int binary operations
 have been simplified to use the new wide-int binary templates.

Looking for from_rtx calls (to see where we get the mode/precision from) I
see for example

- o = rtx_to_double_int (outer);
- i = rtx_to_double_int (inner);
-
- m = double_int::mask (width);
- i = m;
- m = m.llshift (offset, HOST_BITS_PER_DOUBLE_INT);
- i = i.llshift (offset, HOST_BITS_PER_DOUBLE_INT);
- o = o.and_not (m) | i;
-
+
+ o = (wide_int::from_rtx (outer, GET_MODE (SET_DEST (temp)))
+  .insert (wide_int::from_rtx (inner, GET_MODE (dest)),
+   offset, width));

where I'd rather have the original code preserved as much as possible
and not introduce a new primitive wide_int::insert for this.  The conversion
and review process will be much more error-prone if we do multiple
things at once (and it might keep the wide_int initial interface leaner).

Btw, the wide_int::insert implementation doesn't assert anything about
the inputs precision.  Instead it reads

+  if (start + width = precision)
+width = precision - start;
+
+  mask = shifted_mask (start, width, false, precision);
+  tmp = op0.lshift (start, 0, precision, NONE);
+  result = tmp  mask;
+
+  tmp = and_not (mask);
+  result = result | tmp;

which eventually ends up performing everything in target precision.  So
we don't really care about the mode or precision of inner.

Then I see

diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index ad03a34..531a7c1 100644
@@ -180,6 +182,7 @@ typedef struct GTY(()) dw_val_struct {
   HOST_WIDE_INT GTY ((default)) val_int;
   unsigned HOST_WIDE_INT GTY ((tag
(dw_val_class_unsigned_const))) val_unsigned;
   double_int GTY ((tag (dw_val_class_const_double))) val_double;
+  wide_int GTY ((tag (dw_val_class_wide_int))) val_wide;
   dw_vec_const GTY ((tag (dw_val_class_vec))) val_vec;
   struct dw_val_die_union
{

ick.  That makes dw_val_struct really large ... (and thus dw_attr_struct).
You need to make this a pointer to a wide_int at least.

-/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
+/* Return a constant integer corresponding to target reading
GET_MODE_BITSIZE (MODE) bits from string constant STR.  */

 static rtx
 c_readstr (const char *str, enum machine_mode mode)
 {
-  HOST_WIDE_INT c[2];
+  wide_int c;
...
-  return immed_double_const (c[0], c[1], mode);
+
+  c = wide_int::from_array (tmp, len, mode);
+  return immed_wide_int_const (c, mode);
 }

err - what's this good for?  It doesn't look necessary as part of the initial
wide-int conversion at least.  (please audit your patches for such cases)

@@ -4994,12 +4999,12 @@ expand_builtin_signbit (tree exp, rtx target)

   if (bitpos  GET_MODE_BITSIZE (rmode))
 {
-  double_int mask = double_int_zero.set_bit (bitpos);
+  wide_int mask = wide_int::set_bit_in_zero (bitpos, rmode);

   if (GET_MODE_SIZE (imode)  GET_MODE_SIZE (rmode))
temp = gen_lowpart (rmode, temp);
   temp = expand_binop (rmode, and_optab, temp,
-  immed_double_int_const (mask, rmode),
+  immed_wide_int_const (mask, rmode),
   NULL_RTX, 1, OPTAB_LIB_WIDEN);
 }
   else

Likewise.  I suppose you remove immed_double_int_const but I see no
reason to do that.  It just makes your patch larger than necessary.

[what was the reason again to have TARGET_SUPPORTS_WIDE_INT at all?
It's supposed to be a no-op conversion, right?]

@@ -95,38 +95,9 @@ plus_constant (enum machine_mode mode, rtx x,
HOST_WIDE_INT c)

   switch (code)
 {
-case CONST_INT:
-  if (GET_MODE_BITSIZE (mode)  HOST_BITS_PER_WIDE_INT)
-   {
- double_int di_x = double_int::from_shwi (INTVAL (x));
- double_int di_c = double_int::from_shwi (c);
-
- bool overflow;
- double_int v = di_x.add_with_sign (di_c, false, overflow);
- if (overflow)
-   gcc_unreachable ();
-
- return immed_double_int_const (v, VOIDmode);
-   }
-
-  return GEN_INT (INTVAL (x) + c);
-
-case CONST_DOUBLE:
-  {
-   double_int di_x = double_int::from_pair (CONST_DOUBLE_HIGH (x),
-CONST_DOUBLE_LOW (x));
-   double_int di_c = double_int::from_shwi (c);
-
-   bool overflow;
-   double_int v = di_x.add_with_sign (di_c, false, overflow);
-   if (overflow)
- /* Sorry, we have no way to represent overflows this wide.
-To fix, add constant support wider than CONST_DOUBLE.  */
- gcc_assert (GET_MODE_BITSIZE (mode) = HOST_BITS_PER_DOUBLE_INT);
-
-   return immed_double_int_const (v, VOIDmode);
-  }
-
+CASE_CONST_SCALAR_INT:
+  return 

Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

I'm not sure what you mean here.  CONST_INT HWIs are already sign-extended
from mode precision to HWI precision.  The 8-bit value 0xb1000 must be
represented as (const_int -128); nothing else is allowed.  E.g. (const_int 128)
is not a valid QImode value on BITS_PER_UNIT==8 targets.

 What does wide-int do with VOIDmode mode inputs?
 It seems to ICE on them for from_rtx and use garbage (0) for from_shwi.  Ugh.

ICEing is right.  As mentioned before, every rtx constant has a mode,
whether it's stored in the rtx or not.  Callers must keep track of
what that mode is.

 Btw, plus_constant asserts that mode is either VOIDmode (I suppose
 semantically do arbitrary precision)

No, not arbitrary precision.  It's always the precision specified
by the mode parameter.  The assert is:

  gcc_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);

This is because GET_MODE always returns VOIDmode for CONST_INT and
CONST_DOUBLE integers.  The mode parameter is needed to tell us what
precision those CONST_INTs and CONST_DOUBLEs actually have, because
the rtx itself doesn't tell us.  The mode parameter serves no purpose
beyond that.

So if the rtx does specify a mode (everything except CONST_INT and
CONST_DOUBLE), the assert is making sure that the caller has correctly
tracked the rtx's mode and provided the right mode parameter.  The caller
must do that for all rtxes, it's just that we can't assert for it in the
CONST_INT and CONST_DOUBLE case, because the rtx has no mode to check
against.  If CONST_INT and CONST_DOUBLE did have a mode to check against,
there would be no need for the mode parameter at all.  Likewise there
would be no need for wide_int::from_rtx to have a mode parameter.

Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Biener
On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

 I'm not sure what you mean here.  CONST_INT HWIs are already sign-extended
 from mode precision to HWI precision.  The 8-bit value 0xb1000 must be
 represented as (const_int -128); nothing else is allowed.  E.g. (const_int 
 128)
 is not a valid QImode value on BITS_PER_UNIT==8 targets.

Yes, that's what I understand.  But consider you get a CONST_INT that is
_not_ a valid QImode value.  Current code simply trusts that it is, given
the context from ...

 What does wide-int do with VOIDmode mode inputs?
 It seems to ICE on them for from_rtx and use garbage (0) for from_shwi.  Ugh.

 ICEing is right.  As mentioned before, every rtx constant has a mode,
 whether it's stored in the rtx or not.  Callers must keep track of
 what that mode is.

... here.  So I see that both CONST_INT and CONST_DOUBLE get their
mode (or in wide-int speak precision) from the context.

Effectively a CONST_INT and CONST_DOUBLE is valid in multiple
modes and thus arbitrary precision with a limit set by the limit
of the encoding.

 Btw, plus_constant asserts that mode is either VOIDmode (I suppose
 semantically do arbitrary precision)

 No, not arbitrary precision.  It's always the precision specified
 by the mode parameter.  The assert is:

   gcc_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);

 This is because GET_MODE always returns VOIDmode for CONST_INT and
 CONST_DOUBLE integers.  The mode parameter is needed to tell us what
 precision those CONST_INTs and CONST_DOUBLEs actually have, because
 the rtx itself doesn't tell us.  The mode parameter serves no purpose
 beyond that.

That doesn't make sense.  The only thing we could then do with the mode
is assert that the CONST_INT/CONST_DOUBLE is valid for mode.

mode does not constrain the result in any way, thus it happily produces
a CONST_INT (128) from QImode CONST_INT (127) + 1.  So, does the
caller of plus_constant have to verify the result is actually valid in the
mode it expects?  And what should it do if the result is not valid?

Given that we do not verify the input values and do not care for mode for
producing the output value the current behavior of plus_constant is to
compute in arbitrary precision.

wide-int changes the above to produce a different result (CONST_INT (-128)).
I'd rather not have this patch-set introduce such subtle differences.

I'd like to see the following:

1) strip away 'precision' from wide-int, make the sign/zero-extend operations
that are now implicitely done explicit in the same way as done currently,
thus, ...
2) do a more-or-less 1:1 conversion of existing double-int code.  double-int
code already has all sign/zero-extensions that are required for correctness.

and after merging in wide-int

3) see what common code can be factored out (wide_int::insert and friends)
4) if seems fit, introduce a wide_int_with_precision class that provides
a wrapper around wide_int and carries out operations in a fixed precision,
doing sign-/zero-extends after each operation (I suppose not much code
will be simplified by that)

before merging converting all targets is necessary - this isn't a part of
the infrastructure that can stand a partial conversion.  I suspect that
conversion of all targets is much easier after 2), especially if most
of the double-int interfaces are not removed but their implementation
changed to work on wide-ints (just as I mentioned for the immed_double_int_const
case, but likely not restricted to that - CONST_DOUBLE_LOW/HIGH
can be converted to code that asserts the encoding is sufficiently small
for example).  Thus,

5) piecewise remove legacy code dealing with CONST_DOUBLE

Btw, on 64bit hosts the rtx_def struct has 32bits padding before
the rtunion.  I think 32bit hosts are legacy now, so using that 32bits
padding by storing 'len' there will make space-efficient conversion
of CONST_INT possible.  Well, and avoids wasting another 32bits
of padding for CONST_WIDE on 64bit hosts.

 So if the rtx does specify a mode (everything except CONST_INT and
 CONST_DOUBLE), the assert is making sure that the caller has correctly
 tracked the rtx's mode and provided the right mode parameter.  The caller
 must do that for all rtxes, it's just that we can't assert for it in the
 CONST_INT and CONST_DOUBLE case, because the rtx has no mode to check
 against.  If CONST_INT and CONST_DOUBLE did have a mode to check against,
 there would be no need for the mode parameter at all.  Likewise there
 would be no need for wide_int::from_rtx to have a mode parameter.

constants do not have an intrinsic mode or precision.  They either do or
do not fit into a specific mode or precision.  If an operation is to be carried
out in a specific mode 

Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

 I'm not sure what you mean here.  CONST_INT HWIs are already sign-extended
 from mode precision to HWI precision.  The 8-bit value 0xb1000 must be
 represented as (const_int -128); nothing else is allowed.
 E.g. (const_int 128)
 is not a valid QImode value on BITS_PER_UNIT==8 targets.

 Yes, that's what I understand.  But consider you get a CONST_INT that is
 _not_ a valid QImode value.

But that's invalid :-)  It is not valid to call:

  plus_constant (QImode, GEN_INT (128), 1)

The point is that, even though it's invalid, we can't assert for it.

plus_constant is not for arbitrary precision arithmetic.  It's for
arithmetic in a given non-VOIDmode mode.

 Effectively a CONST_INT and CONST_DOUBLE is valid in multiple
 modes and thus arbitrary precision with a limit set by the limit
 of the encoding.

The same CONST_INT and CONST_DOUBLE can be shared for several constants
in different modes, yes, which is presumably what motivated making them
VOIDmode in the first place.  E.g. zero is const0_rtx for every integer
mode.  But in any given context, including plus_constant, the CONST_INT
or CONST_DOUBLE has a specific mode.

 Btw, plus_constant asserts that mode is either VOIDmode (I suppose
 semantically do arbitrary precision)

 No, not arbitrary precision.  It's always the precision specified
 by the mode parameter.  The assert is:

   gcc_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);

 This is because GET_MODE always returns VOIDmode for CONST_INT and
 CONST_DOUBLE integers.  The mode parameter is needed to tell us what
 precision those CONST_INTs and CONST_DOUBLEs actually have, because
 the rtx itself doesn't tell us.  The mode parameter serves no purpose
 beyond that.

 That doesn't make sense.  The only thing we could then do with the mode
 is assert that the CONST_INT/CONST_DOUBLE is valid for mode.

No, we have to generate a correct CONST_INT or CONST_DOUBLE result.
If we are adding 1 to a QImode (const_int 127), we must return
(const_int -128).  If we are adding 1 to HImode (const_int 127),
we must return (const_int 128).  However...

 mode does not constrain the result in any way, thus it happily produces
 a CONST_INT (128) from QImode CONST_INT (127) + 1.  So, does the
 caller of plus_constant have to verify the result is actually valid in the
 mode it expects?  And what should it do if the result is not valid?

...good spot.  That's a bug.  It should be:

  return gen_int_mode (INTVAL (x) + c, mode);

rather than:

  return GEN_INT (INTVAL (x) + c);

It's a long-standing bug, because in the old days we didn't have
the mode to hand.  It was missed when the mode was added.

But the mode is also used in:

  if (GET_MODE_BITSIZE (mode)  HOST_BITS_PER_WIDE_INT)
{
  double_int di_x = double_int::from_shwi (INTVAL (x));
  double_int di_c = double_int::from_shwi (c);

  bool overflow;
  double_int v = di_x.add_with_sign (di_c, false, overflow);
  if (overflow)
gcc_unreachable ();

  return immed_double_int_const (v, VOIDmode);
}

which is deciding whether the result should be kept as a HWI even
in cases where the addition overflows.  It isn't arbitrary precision.

Richard


Re: patch to fix constant math -5th patch, rtl

2013-04-24 Thread Richard Biener
On Wed, Apr 24, 2013 at 4:03 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Apr 24, 2013 at 2:44 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 Can we in such cases please to a preparatory patch and change the
 CONST_INT/CONST_DOUBLE paths to do an explicit [sz]ext to
 mode precision first?

 I'm not sure what you mean here.  CONST_INT HWIs are already sign-extended
 from mode precision to HWI precision.  The 8-bit value 0xb1000 must be
 represented as (const_int -128); nothing else is allowed.
 E.g. (const_int 128)
 is not a valid QImode value on BITS_PER_UNIT==8 targets.

 Yes, that's what I understand.  But consider you get a CONST_INT that is
 _not_ a valid QImode value.

 But that's invalid :-)  It is not valid to call:

   plus_constant (QImode, GEN_INT (128), 1)

 The point is that, even though it's invalid, we can't assert for it.

Why can't we assert for it?

 plus_constant is not for arbitrary precision arithmetic.  It's for
 arithmetic in a given non-VOIDmode mode.

 Effectively a CONST_INT and CONST_DOUBLE is valid in multiple
 modes and thus arbitrary precision with a limit set by the limit
 of the encoding.

 The same CONST_INT and CONST_DOUBLE can be shared for several constants
 in different modes, yes, which is presumably what motivated making them
 VOIDmode in the first place.  E.g. zero is const0_rtx for every integer
 mode.  But in any given context, including plus_constant, the CONST_INT
 or CONST_DOUBLE has a specific mode.

 Btw, plus_constant asserts that mode is either VOIDmode (I suppose
 semantically do arbitrary precision)

 No, not arbitrary precision.  It's always the precision specified
 by the mode parameter.  The assert is:

   gcc_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);

 This is because GET_MODE always returns VOIDmode for CONST_INT and
 CONST_DOUBLE integers.  The mode parameter is needed to tell us what
 precision those CONST_INTs and CONST_DOUBLEs actually have, because
 the rtx itself doesn't tell us.  The mode parameter serves no purpose
 beyond that.

 That doesn't make sense.  The only thing we could then do with the mode
 is assert that the CONST_INT/CONST_DOUBLE is valid for mode.

 No, we have to generate a correct CONST_INT or CONST_DOUBLE result.
 If we are adding 1 to a QImode (const_int 127), we must return
 (const_int -128).  If we are adding 1 to HImode (const_int 127),
 we must return (const_int 128).  However...

 mode does not constrain the result in any way, thus it happily produces
 a CONST_INT (128) from QImode CONST_INT (127) + 1.  So, does the
 caller of plus_constant have to verify the result is actually valid in the
 mode it expects?  And what should it do if the result is not valid?

 ...good spot.  That's a bug.  It should be:

   return gen_int_mode (INTVAL (x) + c, mode);

 rather than:

   return GEN_INT (INTVAL (x) + c);

 It's a long-standing bug, because in the old days we didn't have
 the mode to hand.  It was missed when the mode was added.

 But the mode is also used in:

   if (GET_MODE_BITSIZE (mode)  HOST_BITS_PER_WIDE_INT)
 {
   double_int di_x = double_int::from_shwi (INTVAL (x));
   double_int di_c = double_int::from_shwi (c);

   bool overflow;
   double_int v = di_x.add_with_sign (di_c, false, overflow);
   if (overflow)
 gcc_unreachable ();

   return immed_double_int_const (v, VOIDmode);
 }

 which is deciding whether the result should be kept as a HWI even
 in cases where the addition overflows.  It isn't arbitrary precision.

The above is wrong for SImode HOST_WIDE_INT and 0x7fff + 1
in the same way as the QImode case above.  It will produce
0x8000.  The ICEing on overflow is odd as well as I'd have
expected twos-complement behavior which double-int, when
overflowing its 2 * HWI precision, provides.

I suppose the above should use immed_double_int_const (v, mode), too,
which oddly only ever truncates to mode for modes = HOST_BITS_PER_WIDE_INT
via gen_int_mode.

Same of course for the code for CONST_DOUBLE.

Richard.

 Richard


Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-22 Thread Richard Biener
On Sun, Apr 21, 2013 at 10:54 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 Richard,

 i pulled these two frags out of your comments because i wanted to get some
 input from you on it while i addressed the other issues you raised.


 +  enum SignOp {
 +/* Many of the math functions produce different results depending
 +   on if they are SIGNED or UNSIGNED.  In general, there are two
 +   different functions, whose names are prefixed with an 'S and
 +   or an 'U'.  However, for some math functions there is also a
 +   routine that does not have the prefix and takes an SignOp
 +   parameter of SIGNED or UNSIGNED.  */
 +SIGNED,
 +UNSIGNED
 +  };

 You seem to insist on that.  It should propagate to the various parts
 of the compiler that have settled for the 'uns' integer argument.
 Having one piece behave different is just weird.  I suppose I will
 find code like

  wi.ext (prec, uns ? UNSIGNED : SIGNED)


 there is a lot more flexibility on my part than you perceive with respect to
 this point.   My primary issue is that i do not want to have is an interface
 that has 0 and 1 as a programmer visible part.   Beyond that i am open to
 suggestion.

 The poster child of my hate are the host_integer_p and the tree_low_cst
 interfaces. I did not want the wide int stuff to look like these.  I see
 several problems with these:

 1) of the 314 places where tree_low_cst is called in the gcc directory (not
 the subdirectories where the front ends live), NONE of the calls have a
 variable second parameter.   There are a handful of places, as one expects,
 in the front ends that do, but NONE in the middle end.
 2) there are a small number of the places where host_integer_p is called
 with one parameter and then it is followed by a call to tree_low_cst that
 has the value with the other sex.   I am sure these are mistakes, but having
 the 0s and 1s flying around does not make it easy to spot them.
 3) tree_low_cst implies that the tree cst has only two hwis in it.

 While i do not want to propagate an interface with 0 and 1 into wide-int, i
 can understand your dislike of having a wide-int only solution for this.

 I will point out that for your particular example, uns is almost always set
 by a call to TYPE_UNSIGNED.  There could easily be a different type accessor
 that converts this part of the type to the right thing to pass in here.   I
 think that there is certainly some place for there to be a unified SYMBOLIC
 api that controls the signedness everywhere in the compiler.

 I would like to move toward this direction, but you have been so negative to
 the places where i have made it convenient to directly convert from tree or
 rtl into or out of wide-int that i have hesitated to do something that
 directly links trees and wide-int. So i would like to ask you what would
 like?

Ideally I'd like the wide-int introduction to _not_ be the introduction of
a unified symbolic way that controls signedness.  We do have two
kinds of interfaces currently - one that uses different API entries,
like build_int_cstu vs. build_int_cst or double_int::from_shwi vs. from_uhwi,
and one that uses the aforementioned integer flag 'uns' with 0 being
signed and 1 being unsigned.

I think the _uhwi vs. _shwi and _cstu variants are perfectly fine
(but only for compile-time constant uses as you say), and the wide-int
interface makes use of this kind, too.

Proposing a better API for the 'uns' flag separately from wide-int would
be a better way to get anybody else than me chime in (I have the feeling
that the wide-int series seems to scare off every other reviewer besides me...).
I can live with the SIGNED/UNSIGNED enum, but existing APIs should
be changed to use that.

For wide-int I suggest to go the route you don't want to go.  Stick to
existing practice and use the integer 'uns' flag.  It's as good as
SIGNED/UNSIGNED for _variable_ cases (and yes, a lot less descriptive
for constant cases).  For wide-int, always add a static interface
if there is a variable one and convert variable uses to the proper static
interface.

That said, a lot of my pushback is because I feel a little lonesome in this
wide-int review and don't want to lone-some decide about that (generic)
interface part as well.

 +  template typename T
 +inline bool gt_p (T c, SignOp sgn) const;
 +  template typename T
 +inline bool gts_p (T c) const;
 +  template typename T
 +inline bool gtu_p (T c) const;

 it's bad that we can't use the sign information we have available in
 almost
 all cases ... (where precision is not an exact multiple of
 HOST_BITS_PER_WIDE_INT
 and len == precision / HOST_BITS_PER_WIDE_INT).  It isn't hard to encode
 a sign - you just have to possibly waste a word of zeroes for positive
 values where at the moment precision is an exact multiple of
 HOST_BIST_PER_WIDE_INT and len == precision / HOST_BITS_PER_WIDE_INT.
 Which of course means that the encoding can be one word larger than
 maximally 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-22 Thread Kenneth Zadeck

On 04/19/2013 09:31 AM, Richard Biener wrote:

+   number of elements of the vector that are in use.  When LEN *
+   HOST_BITS_PER_WIDE_INT  the precision, the value has been
+   compressed.  The values of the elements of the vector greater than
+   LEN - 1. are all equal to the highest order bit of LEN.

equal to the highest order bit of element LEN - 1. ?

Fixed, you are correct.

I have gone thru the entire wide-int patch to clean this up.   The 
bottom line is that if the precision is not a multiple of the size of a 
HWI then everything above that precision is assumed to be identical to 
the sign bit.



Especially _not_ equal to the precision - 1 bit of the value, correct?
I do not understand your question here, because in the case talked about 
above, the bit at precision - 1 would not have been explicitly represented.


Anyway,  i went thru this top part carefully and made many things clearer.

+   The representation does not contain any information inherant about
+   signedness of the represented value, so it can be used to represent
+   both signed and unsigned numbers.   For operations where the results
+   depend on signedness (division, comparisons), the signedness must
+   be specified separately.  For operations where the signness
+   matters, one of the operands to the operation specifies either
+   wide_int::SIGNED or wide_int::UNSIGNED.

The last sentence is somehow duplicated.

fixed


+   The numbers are stored as sign entended numbers as a means of
+   compression.  Leading HOST_WIDE_INTS that contain strings of either
+   -1 or 0 are removed as long as they can be reconstructed from the
+   top bit that is being represented.

I'd put this paragraph before the one that talks about signedness, next
to the one that already talks about encoding.

done

+   All constructors for wide_int take either a precision, an enum
+   machine_mode or tree_type.  */

That's probably no longer true (I'll now check).

yes you are correct


+class wide_int {
+  /* Internal representation.  */
+
+  /* VAL is set to a size that is capable of computing a full
+ multiplication on the largest mode that is represented on the
+ target.  The full multiplication is use by tree-vrp.  tree-vpn
+ currently does a 2x largest mode by 2x largest mode yielding a 4x
+ largest mode result.  If operations are added that require larger
+ buffers, then VAL needs to be changed.  */
+  HOST_WIDE_INT val[WIDE_INT_MAX_ELTS];
+  unsigned short len;
+  unsigned int precision;

I wonder if there is a technical reason to stick to HOST_WIDE_INTs?
I'd say for efficiency HOST_WIDEST_FAST_INT would be more appropriate
(to get a 32bit value on 32bit x86 for example).  I of course see that
conversion to/from HOST_WIDE_INT is an important operation
that would get slightly more complicated.

Maybe just quickly checking the code generated on 32bit x86 for
HOST_WIDE_INT vs. HOST_WIDEST_FAST_INT tells us whether
it's worth considering (it would be bad if each add/multiply would
end up calling to libgcc for example - I know that doesn't happen
for x86, but maybe it would happen for an arm hosted gcc
targeting x86_64?)
This is an interesting point.   my guess is that it is unlikely to be 
worth the work.
consider add:most machines have add with carry and well written 32 
bit ports would have used an add with carry sequence rather than making 
the libcall.   If i rewrite wide-int in terms of host_fastest_int, then 
i have to do some messy code to compute the carry which is unlikely to 
translate into the proper carry instructions.   Not to mention the cost 
overhead of converting to and from HFI given that gcc is written almost 
entirely using HWIs.


I thought about the possible idea of just converting the mul and div 
functions.   This would be easy because i already reblock them into 
HOST_WIDE_HALF_INTs to do the math.I could just do a different 
reblocking.   However, i think that it is unlikely that doing this would 
ever show up on anyone's performance counts.   Either way you do the 
same number of multiply instructions, it is just the subroutine wrapper 
that could possibly go away.



+  enum ShiftOp {
+NONE,
+/* There are two uses for the wide-int shifting functions.  The
+   first use is as an emulation of the target hardware.  The
+   second use is as service routines for other optimizations.  The
+   first case needs to be identified by passing TRUNC as the value
+   of ShiftOp so that shift amount is properly handled according to the
+   SHIFT_COUNT_TRUNCATED flag.  For the second case, the shift
+   amount is always truncated by the bytesize of the mode of
+   THIS.  */
+TRUNC
+  };

double-int simply honors SHIFT_COUNT_TRUNCATED.  Why differ
from that (and thus change behavior in existing code - not sure if you
do that with introducing wide-int)?
I believe that GCC is supposed to be a little schizophrenic here, at 
least according to the doc.when it is doing 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-22 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 At the rtl level your idea does not work.   rtl constants do not have a mode
 or type.

 Which is not true and does not matter.  I tell you why.  Quote:

It _is_ true, as long as you read rtl constants as rtl integer constants :-)

 +#if TARGET_SUPPORTS_WIDE_INT
 +
 +/* Match CONST_*s that can represent compile-time constant integers.  */
 +#define CASE_CONST_SCALAR_INT \
 +   case CONST_INT: \
 +   case CONST_WIDE_INT

 which means you are only replacing CONST_DOUBLE with wide-int.
 And _all_ CONST_DOUBLE have a mode.  Otherwise you'd have no
 way of creating the wide-int in the first place.

No, integer CONST_DOUBLEs have VOIDmode, just like CONST_INT.
Only floating-point CONST_DOUBLEs have a real mode.

 I understand that this makes me vulnerable to the argument that we should
 not let the rtl level ever dictate anything about the tree level, but the
 truth is that a variable len rep is almost always used for big integers.
 In our code, most constants of large types are small numbers.   (Remember i
 got into this because the tree constant prop thinks that left shifting any
 number by anything greater than 128 is always 0 and discovered that that was
 just the tip of the iceberg.) But mostly i support the decision to canonize
 numbers to the smallest number of HWIs because most of the algorithms to do
 the math can be short circuited.I admit that if i had to effectively
 unpack most numbers to do the math, that the canonization would be a waste.
 However, this is not really relevant to this conversation.   Yes, you could
 get rid of the len, but this such a small part of picture.

 Getting rid of 'len' in the RTX storage was only a question of whether it
 is an efficient way to go forward.  And with considering to unify
 CONST_INTs and CONST_WIDE_INTs it is not.  And even for CONST_WIDE_INTs
 (which most of the time would be 2 HWI storage, as otherwise you'd use
 a CONST_INT) it would be an improvement.

FWIW, I don't really see any advantage in unifying CONST_INT and
CONST_WIDE_INT, for the reasons Kenny has already given.  CONST_INT
can represent a large majority of the integers and it is already a
fairly efficient representation.

It's more important that we don't pick a design that forces one
choice or the other.  And I think Kenny's patch achieves that goal,
because the choice is hidden behind macros and behind the wide_int
interface.

Thanks,
Richard


Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-22 Thread Richard Biener
Richard Sandiford rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:
 At the rtl level your idea does not work.   rtl constants do not
have a mode
 or type.

 Which is not true and does not matter.  I tell you why.  Quote:

It _is_ true, as long as you read rtl constants as rtl integer
constants :-)

 +#if TARGET_SUPPORTS_WIDE_INT
 +
 +/* Match CONST_*s that can represent compile-time constant integers.
 */
 +#define CASE_CONST_SCALAR_INT \
 +   case CONST_INT: \
 +   case CONST_WIDE_INT

 which means you are only replacing CONST_DOUBLE with wide-int.
 And _all_ CONST_DOUBLE have a mode.  Otherwise you'd have no
 way of creating the wide-int in the first place.

No, integer CONST_DOUBLEs have VOIDmode, just like CONST_INT.
Only floating-point CONST_DOUBLEs have a real mode.

I stand corrected. Now that's one more argument for infinite precision 
constants, as the mode is then certainly provided by the operations similar to 
the sign. That is, the mode (or size, or precision) of 1 certainly does not 
matter.

 I understand that this makes me vulnerable to the argument that we
should
 not let the rtl level ever dictate anything about the tree level,
but the
 truth is that a variable len rep is almost always used for big
integers.
 In our code, most constants of large types are small numbers.  
(Remember i
 got into this because the tree constant prop thinks that left
shifting any
 number by anything greater than 128 is always 0 and discovered that
that was
 just the tip of the iceberg.) But mostly i support the decision to
canonize
 numbers to the smallest number of HWIs because most of the
algorithms to do
 the math can be short circuited.I admit that if i had to
effectively
 unpack most numbers to do the math, that the canonization would be a
waste.
 However, this is not really relevant to this conversation.   Yes,
you could
 get rid of the len, but this such a small part of picture.

 Getting rid of 'len' in the RTX storage was only a question of
whether it
 is an efficient way to go forward.  And with considering to unify
 CONST_INTs and CONST_WIDE_INTs it is not.  And even for
CONST_WIDE_INTs
 (which most of the time would be 2 HWI storage, as otherwise you'd
use
 a CONST_INT) it would be an improvement.

FWIW, I don't really see any advantage in unifying CONST_INT and
CONST_WIDE_INT, for the reasons Kenny has already given.  CONST_INT
can represent a large majority of the integers and it is already a
fairly efficient representation.

It's more important that we don't pick a design that forces one
choice or the other.  And I think Kenny's patch achieves that goal,
because the choice is hidden behind macros and behind the wide_int
interface.

Not unifying const-int and double-int in the end would be odd.

Richard.

Thanks,
Richard




Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-22 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 Richard Sandiford rdsandif...@googlemail.com wrote:
Richard Biener richard.guent...@gmail.com writes:
 At the rtl level your idea does not work.   rtl constants do not
have a mode
 or type.

 Which is not true and does not matter.  I tell you why.  Quote:

It _is_ true, as long as you read rtl constants as rtl integer
constants :-)

 +#if TARGET_SUPPORTS_WIDE_INT
 +
 +/* Match CONST_*s that can represent compile-time constant integers.
 */
 +#define CASE_CONST_SCALAR_INT \
 +   case CONST_INT: \
 +   case CONST_WIDE_INT

 which means you are only replacing CONST_DOUBLE with wide-int.
 And _all_ CONST_DOUBLE have a mode.  Otherwise you'd have no
 way of creating the wide-int in the first place.

No, integer CONST_DOUBLEs have VOIDmode, just like CONST_INT.
Only floating-point CONST_DOUBLEs have a real mode.

 I stand corrected. Now that's one more argument for infinite precision
 constants, as the mode is then certainly provided by the operations
 similar to the sign. That is, the mode (or size, or precision) of 1
 certainly does not matter.

I disagree.  Although CONST_INT and CONST_DOUBLE don't _store_ a mode,
they are always interpreted according to a particular mode.  It's just
that that mode has to be specified separately.  That's why so many
rtl functions have (enum machine_mode, rtx) pairs.

Infinite precision seems very alien to rtl, where everything is
interpreted according to a particular mode (whether that mode is
stored in the rtx or not).

For one thing, I don't see how infinite precision could work in an
environment where signedness often isn't defined.  E.g. if you optimise
an addition of two rtl constants, you don't know (and aren't supposed
to know) whether the values involved are signed or unsigned.  With
fixed-precision arithmetic it doesn't matter, because both operands must
have the same precision, and because bits outside the precision are not
significant.  With infinite precision arithmetic, the choice carries
over to the next operation.  E.g., to take a 4-bit example, you don't
know when constructing a wide_int from an rtx whether 0b1000 represents
8 or -8.  But if you have no precision to say how many bits are significant,
you have to pick one.  Which do you choose?  And why should we have to
make a choice at all?  (Note that this is a different question to
whether the internal wide_int representation is sign-extending or not,
which is purely an implementation detail.  The same implementation
principle applies to CONST_INTs: the HWI in a CONST_INT is always
sign-extended from the msb of the represented value, although of course
the CONST_INT itself doesn't tell you which bit the msb is; that has to
be determined separately.)

A particular wide_int isn't, and IMO shouldn't be, inherently signed
or unsigned.  The rtl model is that signedness is a question of
interpretation rather than representation.  I realise trees are
different, because signedness is a property of the type rather
than operations on the type, but I still think fixed precision
works with both tree and rtl whereas infinite precision doesn't
work with rtl.

I also fear there are going to be lots of bugs where we forget to
truncate the result of an N-bit operation from infinite precision
to N bits before using it in the next operation (as per Kenny's ring
explanation).  With finite precision, and with all-important asserts
that the operands have consistent precisions, we shouldn't have any
hidden bugs like that.

If there are parts of gcc that really want to do infinite-precision
arithmetic, mpz_t ought to be as good as anything.

Thanks,
Richard


Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-22 Thread Kenneth Zadeck

On 04/22/2013 08:20 AM, Richard Biener wrote:



That said, a lot of my pushback is because I feel a little lonesome in this
wide-int review and don't want to lone-some decide about that (generic)
interface part as well.
yeh,  now sandiford is back from vacation so there are two of us to beat 
on you about your

how bad it would be to do infinite precision!!!

be careful what you wish for.

kenny


Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-21 Thread Kenneth Zadeck

Richard,

i pulled these two frags out of your comments because i wanted to get 
some input from you on it while i addressed the other issues you raised.



+  enum SignOp {
+/* Many of the math functions produce different results depending
+   on if they are SIGNED or UNSIGNED.  In general, there are two
+   different functions, whose names are prefixed with an 'S and
+   or an 'U'.  However, for some math functions there is also a
+   routine that does not have the prefix and takes an SignOp
+   parameter of SIGNED or UNSIGNED.  */
+SIGNED,
+UNSIGNED
+  };

You seem to insist on that.  It should propagate to the various parts
of the compiler that have settled for the 'uns' integer argument.
Having one piece behave different is just weird.  I suppose I will
find code like

 wi.ext (prec, uns ? UNSIGNED : SIGNED)


there is a lot more flexibility on my part than you perceive with 
respect to this point.   My primary issue is that i do not want to have 
is an interface that has 0 and 1 as a programmer visible part.   Beyond 
that i am open to suggestion.


The poster child of my hate are the host_integer_p and the tree_low_cst 
interfaces. I did not want the wide int stuff to look like these.  I see 
several problems with these:


1) of the 314 places where tree_low_cst is called in the gcc directory 
(not the subdirectories where the front ends live), NONE of the calls 
have a variable second parameter.   There are a handful of places, as 
one expects, in the front ends that do, but NONE in the middle end.
2) there are a small number of the places where host_integer_p is called 
with one parameter and then it is followed by a call to tree_low_cst 
that has the value with the other sex.   I am sure these are mistakes, 
but having the 0s and 1s flying around does not make it easy to spot them.

3) tree_low_cst implies that the tree cst has only two hwis in it.

While i do not want to propagate an interface with 0 and 1 into 
wide-int, i can understand your dislike of having a wide-int only 
solution for this.


I will point out that for your particular example, uns is almost always 
set by a call to TYPE_UNSIGNED.  There could easily be a different type 
accessor that converts this part of the type to the right thing to pass 
in here.   I think that there is certainly some place for there to be a 
unified SYMBOLIC api that controls the signedness everywhere in the 
compiler.


I would like to move toward this direction, but you have been so 
negative to the places where i have made it convenient to directly 
convert from tree or rtl into or out of wide-int that i have hesitated 
to do something that directly links trees and wide-int. So i would like 
to ask you what would like?





+  template typename T
+inline bool gt_p (T c, SignOp sgn) const;
+  template typename T
+inline bool gts_p (T c) const;
+  template typename T
+inline bool gtu_p (T c) const;

it's bad that we can't use the sign information we have available in almost
all cases ... (where precision is not an exact multiple of
HOST_BITS_PER_WIDE_INT
and len == precision / HOST_BITS_PER_WIDE_INT).  It isn't hard to encode
a sign - you just have to possibly waste a word of zeroes for positive
values where at the moment precision is an exact multiple of
HOST_BIST_PER_WIDE_INT and len == precision / HOST_BITS_PER_WIDE_INT.
Which of course means that the encoding can be one word larger than
maximally required by 'precision'.

Going back to point 1 above,   the front ends structure the middle end 
code where (generally) the sign that is used is encoded in the operator 
that one is looking at.So the majority of uses in the middle end 
this fall into the second or third templates and the first template is 
there as a convenience routine for the middle ends.

The front ends certainly use the first template.

This is how the rtl level has survived so long without a sign bit in the 
modes, the operators tell the whole story.   The truth is that in the 
middle end, the story is the same - it is the operators (most of the 
time) that drive the calls being made.


There is an assumption that you are making that i certainly do not 
believe is true in the backends and i kind of doubt is true in the 
middle ends.   That is that the sign of the compare ALWAYS matches the 
sign of the operands.   Given that i have never seen any code that 
verifies this in the middle end, i am going to assume that it is not 
true, because it is always true in gcc that anything that we do not 
explicitly verify generally turns out to only be generally true and you 
can spend your life tracking down the end cases.  This is a needless 
complication.
At the rtl level, this is completely doomed by the GEN_INT which neither 
takes a mode or an indication of sign.   To assume that there is any 
meaningful sign information there is a horror story waiting to be 
written (sure what could go wrong if we go into the old house?  whats 
that 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-19 Thread Richard Biener
On Tue, Apr 16, 2013 at 10:07 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 Richard,

 I made major changes to wide-int along the lines you suggested. Each of the
 binary operations is now a template.
 There are 5 possible implementations of those operations, one for each of
 HWI, unsigned HWI, wide-int, rtl, and tree.   Note that this is not exactly
 as you suggested, but it is along the same lines.

 The HWI template sign extends the value to the precision of the first
 operand, the unsigned HWI is the same except that it is an unsigned
 extension.   The wide-int version is used as before, but is in truth rarely
 used.  The rtl and tree logically convert the value to a wide-int but in
 practice do something more efficient than converting to the wide-int.   What
 they do is look inside the rtl or the tree and pass a pointer to the data
 and a length to the binary operation.  This is perfectly safe in the
 position of a second operand to the binary operation because the lifetime is
 guaranteed to be very short.  The wide-int implementation was also modified
 to do the same pointer trick allowing all 5 templates to share the same use
 of the data.

 Note that currently the tree code is more crufty than one would like.   This
 will clean up nicely when the tree-cst is changed to represent the value
 with an array and a length field.

 So now, at least for the second operand of binary operations, the storage is
 never copied.I do not believe that there is a good similar trick for the
 first operand.  i did not consider something like wide_int::add (a, b) to be
 a viable option; it seems to mis the point of using an object oriented
 language.   So I think that you really have to copy the data into an
 instance of a wide int.

 However, while all of this avoids ever having to pass a precision into the
 second operand, this patch does preserve the finite math implementation of
 wide-int.Finite math is really what people expect an optimizer to do,
 because it seamlessly matches what the machine is going to do.

 I hope at this point, i can get a comprehensive review on these patches.   I
 believe that I have done what is required.

 There are two other patches that will be submitted in the next few minutes.
 The first one is an updated version of the rtl level patch.   The only
 changes from what you have seen before are that the binary operations now
 use the templated binary operations.  The second one is the first of the
 tree level patches.   It converts builtins.c to use both use wide-int and it
 removes all assumptions that tree-csts are built with two HWIs.

 Once builtins.c is accepted, i will convert the rest of the middle end
 patches.   They will all be converted in a similar way.

+   number of elements of the vector that are in use.  When LEN *
+   HOST_BITS_PER_WIDE_INT  the precision, the value has been
+   compressed.  The values of the elements of the vector greater than
+   LEN - 1. are all equal to the highest order bit of LEN.

equal to the highest order bit of element LEN - 1. ?

Especially _not_ equal to the precision - 1 bit of the value, correct?

+   The representation does not contain any information inherant about
+   signedness of the represented value, so it can be used to represent
+   both signed and unsigned numbers.   For operations where the results
+   depend on signedness (division, comparisons), the signedness must
+   be specified separately.  For operations where the signness
+   matters, one of the operands to the operation specifies either
+   wide_int::SIGNED or wide_int::UNSIGNED.

The last sentence is somehow duplicated.

+   The numbers are stored as sign entended numbers as a means of
+   compression.  Leading HOST_WIDE_INTS that contain strings of either
+   -1 or 0 are removed as long as they can be reconstructed from the
+   top bit that is being represented.

I'd put this paragraph before the one that talks about signedness, next
to the one that already talks about encoding.

+   All constructors for wide_int take either a precision, an enum
+   machine_mode or tree_type.  */

That's probably no longer true (I'll now check).

+class wide_int {
+  /* Internal representation.  */
+
+  /* VAL is set to a size that is capable of computing a full
+ multiplication on the largest mode that is represented on the
+ target.  The full multiplication is use by tree-vrp.  tree-vpn
+ currently does a 2x largest mode by 2x largest mode yielding a 4x
+ largest mode result.  If operations are added that require larger
+ buffers, then VAL needs to be changed.  */
+  HOST_WIDE_INT val[WIDE_INT_MAX_ELTS];
+  unsigned short len;
+  unsigned int precision;

I wonder if there is a technical reason to stick to HOST_WIDE_INTs?
I'd say for efficiency HOST_WIDEST_FAST_INT would be more appropriate
(to get a 32bit value on 32bit x86 for example).  I of course see that
conversion to/from HOST_WIDE_INT is an important operation
that would get slightly more 

Re: patch to fix constant math - builtins.c - the first of the tree level patches for wide-int

2013-04-16 Thread Kenneth Zadeck
Richard, this is the first of the tree level patches so that you can see 
how the wide-int changes will effect the tree level.   This patch 
converts builtins.c so that it does not in any way assume that tree-cst 
holds two HWIs.   The patch divides all math into two categories:   
Things that are always so small that we can easily assume that the math 
can be done using a single HWI and everything else.   The things that it 
assumes can easily be done with a HWI are guarded with assertions.   The 
everything else is done with wide-int.  Everything else in this patch is 
additional abi to support this.


The idea is that each pass will be converted, 1 pass per patch in this 
way.Once everything does not depend on the internals of tree-cst as 
they do now, then tree-cst will be converted to have an array inside of 
it rather than just two hwis.


Kenny
2012-04-16  Kenneth Zadeck zad...@naturalbridge.com

* builtins.c (get_object_alignment_2, get_pointer_alignment_1,
c_strlen, c_getstr, target_char_cast,
expand_builtin_mempcpy_args, expand_builtin_strncpy,
expand_builtin_memset_args, expand_builtin_strncpy,
expand_builtin_memset_args, expand_builtin_frame_address,
expand_builtin_alloca, expand_builtin_atomic_compare_exchange,
fold_builtin_powi, fold_builtin_memset,
fold_builtin_memory_op, fold_builtin_memchr,
fold_builtin_memcmp, fold_builtin_strncmp,
fold_builtin_load_exponent, fold_builtin_snprintf,
expand_builtin_object_size, expand_builtin_memory_chk,
maybe_emit_chk_warning, maybe_emit_sprintf_chk_warning,
fold_builtin_object_size, fold_builtin_memory_chk,
fold_builtin_stxcpy_chk, fold_builtin_strcat_chk,
fold_builtin_sprintf_chk_1, fold_builtin_snprintf_chk_1,
do_mpfr_bessel_n): Convert to api that does not assume that
tree_cst is two HWIs.
(fold_builtin_int_roundingfn, fold_builtin_bitop,
fold_builtin_bswap, fold_builtin_memory_op,
expand_builtin_object_size): Use wide-int rather than double-int api.

* dfp.c (decimal_real_to_integer): Add wide-int version. 
* real.c (real_to_integer): Ditto.
* tree.h (tree_fits_uhwi_p, tree_fits_shwi_p, tree_fits_hwi_p, 
tree_to_shwi, tree_to_hwi, tree_to_uhwi): New functions.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index ed5a6b3..5ba2297 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -339,8 +339,8 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
   if (TREE_CODE (addr) == BIT_AND_EXPR
 	   TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
 	{
-	  align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
-		 -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
+	  align = (tree_to_hwi (TREE_OPERAND (addr, 1))
+		-tree_to_hwi (TREE_OPERAND (addr, 1)));
 	  align *= BITS_PER_UNIT;
 	  addr = TREE_OPERAND (addr, 0);
 	}
@@ -357,7 +357,7 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
 	{
 	  unsigned HOST_WIDE_INT step = 1;
 	  if (TMR_STEP (exp))
-		step = TREE_INT_CST_LOW (TMR_STEP (exp));
+		step = tree_to_hwi (TMR_STEP (exp));
 	  align = MIN (align, (step  -step) * BITS_PER_UNIT);
 	}
 	  if (TMR_INDEX2 (exp))
@@ -379,7 +379,8 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
 	  bitpos += ptr_bitpos;
 	  if (TREE_CODE (exp) == MEM_REF
 	  || TREE_CODE (exp) == TARGET_MEM_REF)
-	bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
+	bitpos += wide_int::from_tree (TREE_OPERAND (exp, 1))
+	  .to_shwi () * BITS_PER_UNIT;
 	}
 }
   else if (TREE_CODE (exp) == STRING_CST)
@@ -408,23 +409,23 @@ get_object_alignment_2 (tree exp, unsigned int *alignp,
 	}
   else
 	next_offset = NULL;
-  if (host_integerp (offset, 1))
+  if (tree_fits_uhwi_p (offset))
 	{
 	  /* Any overflow in calculating offset_bits won't change
 	 the alignment.  */
 	  unsigned offset_bits
-	= ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
+	= ((unsigned) tree_to_hwi (offset) * BITS_PER_UNIT);
 
 	  if (offset_bits)
 	inner = MIN (inner, (offset_bits  -offset_bits));
 	}
   else if (TREE_CODE (offset) == MULT_EXPR
-	host_integerp (TREE_OPERAND (offset, 1), 1))
+	tree_fits_uhwi_p (TREE_OPERAND (offset, 1)))
 	{
 	  /* Any overflow in calculating offset_factor won't change
 	 the alignment.  */
 	  unsigned offset_factor
-	= ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
+	= ((unsigned) tree_to_hwi (TREE_OPERAND (offset, 1))
 	   * BITS_PER_UNIT);
 
 	  if (offset_factor)
@@ -515,7 +516,7 @@ get_pointer_alignment_1 (tree exp, unsigned int *alignp,
   else if (TREE_CODE (exp) == INTEGER_CST)
 {
   *alignp = BIGGEST_ALIGNMENT;
-  *bitposp = ((TREE_INT_CST_LOW (exp) * BITS_PER_UNIT)
+  *bitposp = ((tree_to_hwi (exp) * BITS_PER_UNIT)
 		   (BIGGEST_ALIGNMENT - 1));
   return true;
 }
@@ -624,10 +625,10 @@ c_strlen (tree src, int 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-08 Thread Richard Biener
On Fri, Apr 5, 2013 at 2:34 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 Richard,

 There has been something that has bothered me about you proposal for the
 storage manager and i think i can now characterize that problem.  Say i want
 to compute the expression

 (a + b) / c

 converting from tree values, using wide-int as the engine and then storing
 the result in a tree.   (A very common operation for the various simplifiers
 in gcc.)

 in my version of wide-int where there is only the stack allocated fix size
 allocation for the data, the compiler arranges for 6 instances of wide-int
 that are statically allocated on the stack when the function is entered.
 There would be 3 copies of the precision and data to get things started and
 one allocation variable sized object at the end when the INT_CST is built
 and one copy to put it back.   As i have argued, these copies are of
 negligible size.

 In your world, to get things started, you would do 3 pointer copies to get
 the values out of the tree to set the expression leaves but then you will
 call the allocator 3 times to get space to hold the intermediate nodes
 before you get to pointer copy the result back into the result cst which
 still needs an allocation to build it. I am assuming that we can play the
 same game at the tree level that we do at the rtl level where we do 1
 variable sized allocation to get the entire INT_CST rather than doing 1
 fixed sized allocation and 1 variable sized one.

 even if we take the simpler example of a + b, you still loose.   The cost of
 the extra allocation and it's subsequent recovery is more than my copies.
 In fact, even in the simplest case of someone going from a HWI thru wide_int
 into tree, you have 2 allocations vs my 1.

Just to clarify, my code wouldn't handle

  tree a, b, c;
  tree res = (a + b) / c;

transparently.  The most complex form of the above that I think would
be reasonable to handle would be

  tree a, b, c;
  wide_int wires = (wi (a) + b) / c;
  tree res = build_int_cst (TREE_TYPE (a), wires);

and the code as posted would even require you to specify the
return type of operator+ and operator/ explicitely like

 wide_int wires = (wi (a).operator+wi_embed_var
(b)).operator/wi_embed_var (c);

but as I said I just didn't bother to decide that the return type is
always of wide_int variable-len-storage kind.

Now, the only real allocation that happens is done by build_int_cst.
There is one wide_int on the stack to hold the a + b result and one
separate wide_int to hold wires (it's literally written in the code).
There are no pointer copies involved in the end - the result from
converting a tree to a wide_inttree-storage is the original 'tree'
pointer itself, thus a register.

 I just do not see the cost savings and if there are no cost savings, you
 certainly cannot say that having these templates is simpler than not having
 the templates.

I think you are missing the point - by abstracting away the storage
you don't necessarily need to add the templates.  But you open up
a very easy route for doing so and you make the operations _trivially_
work on the tree / RTL storage with no overhead in generated code
and minimal overhead in the amount of code in GCC itself.  In my
prototype the overhead of adding 'tree' support is to place

class wi_tree_int_cst
{
  tree cst;
public:
  void construct (tree c) { cst = c; }
  const HOST_WIDE_INT *storage() const { return reinterpret_cast
HOST_WIDE_INT *(TREE_INT_CST (cst)); }
  unsigned len() const { return 2; }
};

template 
class wi_traits tree
{
public:
typedef wide_int wi_tree_int_cst wi_t;
wi_traits(tree t)
  {
wi_tree_int_cst ws;
ws.construct (t);
w.construct (ws);
  }
wi_t* operator-() { return w; }
private:
wi_t w;
};

into tree.h.

Richard.

 Kenny


 On 04/02/2013 11:04 AM, Richard Biener wrote:

 On Wed, Feb 27, 2013 at 2:59 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 This patch contains a large number of the changes requested by Richi.
 It
 does not contain any of the changes that he requested to abstract the
 storage layer.   That suggestion appears to be quite unworkable.

 I of course took this claim as a challenge ... with the following result.
 It is
 of course quite workable ;)

 The attached patch implements the core wide-int class and three storage
 models (fixed size for things like plain HWI and double-int, variable size
 similar to how your wide-int works and an adaptor for the double-int as
 contained in trees).  With that you can now do

 HOST_WIDE_INT
 wi_test (tree x)
 {
// template argument deduction doesn't do the magic we want it to do
// to make this kind of implicit conversions work
// overload resolution considers this kind of conversions so we
// need some magic that combines both ... but seeding the overload
// set with some instantiations doesn't seem to be possible :/
// wide_int w = x + 1;
wide_int w;
w += x;
w += 1;
// template argument 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-05 Thread Kenneth Zadeck

Richard,

There has been something that has bothered me about you proposal for the 
storage manager and i think i can now characterize that problem.  Say i 
want to compute the expression


(a + b) / c

converting from tree values, using wide-int as the engine and then 
storing the result in a tree.   (A very common operation for the various 
simplifiers in gcc.)


in my version of wide-int where there is only the stack allocated fix 
size allocation for the data, the compiler arranges for 6 instances of 
wide-int that are statically allocated on the stack when the function 
is entered.There would be 3 copies of the precision and data to get 
things started and one allocation variable sized object at the end when 
the INT_CST is built and one copy to put it back.   As i have argued, 
these copies are of negligible size.


In your world, to get things started, you would do 3 pointer copies to 
get the values out of the tree to set the expression leaves but then you 
will call the allocator 3 times to get space to hold the intermediate 
nodes before you get to pointer copy the result back into the result cst 
which still needs an allocation to build it. I am assuming that we can 
play the same game at the tree level that we do at the rtl level where 
we do 1 variable sized allocation to get the entire INT_CST rather than 
doing 1 fixed sized allocation and 1 variable sized one.


even if we take the simpler example of a + b, you still loose.   The 
cost of the extra allocation and it's subsequent recovery is more than 
my copies.   In fact, even in the simplest case of someone going from a 
HWI thru wide_int into tree, you have 2 allocations vs my 1.


I just do not see the cost savings and if there are no cost savings, you 
certainly cannot say that having these templates is simpler than not 
having the templates.


Kenny

On 04/02/2013 11:04 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 2:59 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

This patch contains a large number of the changes requested by Richi.   It
does not contain any of the changes that he requested to abstract the
storage layer.   That suggestion appears to be quite unworkable.

I of course took this claim as a challenge ... with the following result.  It is
of course quite workable ;)

The attached patch implements the core wide-int class and three storage
models (fixed size for things like plain HWI and double-int, variable size
similar to how your wide-int works and an adaptor for the double-int as
contained in trees).  With that you can now do

HOST_WIDE_INT
wi_test (tree x)
{
   // template argument deduction doesn't do the magic we want it to do
   // to make this kind of implicit conversions work
   // overload resolution considers this kind of conversions so we
   // need some magic that combines both ... but seeding the overload
   // set with some instantiations doesn't seem to be possible :/
   // wide_int w = x + 1;
   wide_int w;
   w += x;
   w += 1;
   // template argument deduction doesn't deduce the return value type,
   // not considering the template default argument either ...
   // w = wi (x) + 1;
   // we could support this by providing rvalue-to-lvalue promotion
   // via a traits class?
   // otoh it would lead to sub-optimal code anyway so we should
   // make the result available as reference parameter and only support
   // wide_int  res; add (res, x, 1); ?
   w = wi (x).operator+wide_int (1);
   wide_int::add(w, x, 1);
   return w.to_hwi ();
}

we are somewhat limited with C++ unless we want to get really fancy.
Eventually providing operator+ just doesn't make much sense for
generic wide-int combinations (though then the issue is its operands
are no longer commutative which I think is the case with your wide-int
or double-int as well - they don't suport 1 + wide_int for obvious reasons).

So there are implementation design choices left undecided.

Oh, and the operation implementations are crap (they compute nonsense).

But you should get the idea.

Richard.




Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-04 Thread Richard Biener
On Wed, Apr 3, 2013 at 6:16 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 On 04/03/2013 09:53 AM, Richard Biener wrote:

 On Wed, Apr 3, 2013 at 2:05 PM, Kenneth Zadeck zad...@naturalbridge.com
 wrote:

 On 04/03/2013 05:17 AM, Richard Biener wrote:

 In the end you will have a variable-size storage in TREE_INT_CST thus
 you will have at least to emit _code_ copying over meta-data and data
 from the tree representation to the wide-int (similar for RTX
 CONST_DOUBLE/INT).
 I'm objecting to the amount of code you emit and agree that the runtime
 cost is copying the meta-data (hopefully optimizable via CSE / SRA)
 and in most cases one (or two) iterations of the loop copying the data
 (not optimizable).

 i did get rid of the bitsize in the wide-int patch so at this point the
 meta
 data is the precision and the len.
 not really a lot here.   As usual we pay a high price in gcc for not
 pushing
 the tree rep down into the rtl level, then it would have been acceptable
 to
 have the tree type bleed into the wide-int code.



 2)  You present this as if the implementor actually should care about
 the
 implementation and you give 3 alternatives:  the double_int, the
 current
 one, and HWI. We have tried to make it so that the client should
 not
 care.   Certainly in my experience here, I have not found a place to
 care.

 Well, similar as for the copying overhead for tree your approach
 requires
 overloading operations for HOST_WIDE_INT operands to be able to
 say wi + 1 (which is certainly desirable), or the overhead of using
 wide_int_one ().

 In my opinion double_int needs to go away.  That is the main thrust of
 my
 patches.   There is no place in a compiler for an abi that depends on
 constants fitting into 2 two words whose size is defined by the host.

 That's true.  I'm not arguing to preserve double-int - I'm arguing to
 preserve a way to ask for an integer type on the host with (at least)
 N bits.  Almost all double-int users really ask for an integer type on
 the
 host that has at least as many bits as the pointer representation (or
 word_mode) on
 the target (we do have HOST_WIDEST_INT == 32bits for 64bit pointer
 targets).  No double-int user specifically wants 2 * HOST_WIDE_INT
 precision - that is just what happens to be there.  Thus I am providing
 a way to say get me a host integer with at least N bits (VRP asks for
 this, for example).

 What I was asking for is that whatever can provide the above should
 share
 the functional interface with wide-int (or the othert way around).  And
 I
 was claiming that wide-int is too fat, because current users of
 double-int
 eventually store double-ints permanently.

 The problem is that, in truth, double int is too fat. 99.something% of
 all
 constants fit in 1 hwi and that is likely to be true forever (i
 understand
 that tree vpn may need some thought here).  The rtl level, which has, for
 as
 long as i have known it, had 2 reps for integer constants. So it was
 relatively easy to slide the CONST_WIDE_INT in.  It seems like the right
 trickery here rather than adding a storage model for wide-ints might be a
 way to use the c++ to invisibly support several (and by several i
 really
 mean 2) classes of TREE_CSTs.

 The truth is that _now_ TREE_INT_CSTs use double-ints and we have
 CONST_INT and CONST_DOUBLE.  What I (and you) propose would
 get us to use variable-size storage for both, allowing to just use a
 single
 HOST_WIDE_INT in the majority of cases.  In my view the constant
 length of the variable-size storage for TREE_INT_CSTs is determined
 by its type (thus, it doesn't have optimized variable-size storage
 but unoptimized fixed-size storage based on the maximum storage
 requirement for the type).  Similar for RTX CONST_INT which would
 have fixed-size storage based on the mode-size of the constant.
 Using optimized space (thus using the encoding properties) requires you
 to fit the 'short len' somewhere which possibly will not pay off in the
 end
 (for tree we do have that storage available, so we could go with optimized
 storage for it, not sure with RTL, I don't see available space there).

 There are two questions here:   one is the fact that you object to the fact
 that we represent small constants efficiently

Huh?  Where do I object to that?  I question that for the storage in tree
and RTX the encoding trick pays off if you need another HWI-aligned
word to store the len.  But see below.

 and the second is that we take
 advantage of the fact that fixed size stack allocation is effectively free
 for short lived objects like wide-ints (as i use them).

I don't question that and I am not asking you to change that.  As part of
what I ask for a more optimal (smaller) stack allocation would be _possible_
(but not required).

 At the rtl level your idea does not work.   rtl constants do not have a mode
 or type.So if you do not compress, how are you going to determine how
 many words you need for the constant 1.   I would love to 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-03 Thread Richard Biener
On Tue, Apr 2, 2013 at 7:35 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 Yes, I agree that you win the challenge that it can be done.What you
 have always failed to address is why anyone would want to do this.  Or how
 this would at all be desirable.But I completely agree that from a purely
 abstract point of view you can add a storage model.

 Now here is why we REALLY do not want to go down this road:

 1)  The following comment from your earlier mail is completely wrong


 +#ifdef NEW_REP_FOR_INT_CST
 +  /* This is the code once the tree level is converted.  */
 +  wide_int result;
 +  int i;
 +
 +  tree type = TREE_TYPE (tcst);
 +
 +  result.bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
 +  result.precision = TYPE_PRECISION (type);
 +  result.len = TREE_INT_CST_LEN (tcst);
 +  for (i = 0; i  result.len; i++)
 +result.val[i] = TREE_INT_CST_ELT (tcst, i);
 +
 +  return result;
 +#else


 this also shows the main reason I was asking for storage abstraction.
 The initialization from tree is way too expensive.


 In almost all cases, constants will fit in a single HWI.  Thus, the only
 thing that you are copying is the length and a single HWI. So you are
 dragging in a lot of machinery just to save these two copies?   Certainly
 there has to be more to it than that.

In the end you will have a variable-size storage in TREE_INT_CST thus
you will have at least to emit _code_ copying over meta-data and data
from the tree representation to the wide-int (similar for RTX CONST_DOUBLE/INT).
I'm objecting to the amount of code you emit and agree that the runtime
cost is copying the meta-data (hopefully optimizable via CSE / SRA)
and in most cases one (or two) iterations of the loop copying the data
(not optimizable).

 2)  You present this as if the implementor actually should care about the
 implementation and you give 3 alternatives:  the double_int, the current
 one, and HWI. We have tried to make it so that the client should not
 care.   Certainly in my experience here, I have not found a place to care.

Well, similar as for the copying overhead for tree your approach requires
overloading operations for HOST_WIDE_INT operands to be able to
say wi + 1 (which is certainly desirable), or the overhead of using
wide_int_one ().

 In my opinion double_int needs to go away.  That is the main thrust of my
 patches.   There is no place in a compiler for an abi that depends on
 constants fitting into 2 two words whose size is defined by the host.

That's true.  I'm not arguing to preserve double-int - I'm arguing to
preserve a way to ask for an integer type on the host with (at least)
N bits.  Almost all double-int users really ask for an integer type on the
host that has at least as many bits as the pointer representation (or
word_mode) on
the target (we do have HOST_WIDEST_INT == 32bits for 64bit pointer
targets).  No double-int user specifically wants 2 * HOST_WIDE_INT
precision - that is just what happens to be there.  Thus I am providing
a way to say get me a host integer with at least N bits (VRP asks for
this, for example).

What I was asking for is that whatever can provide the above should share
the functional interface with wide-int (or the othert way around).  And I
was claiming that wide-int is too fat, because current users of double-int
eventually store double-ints permanently.

 This is not a beauty contest argument, we have public ports are beginning to
 use modes that are larger than two x86-64 HWIs and i have a private port
 that has such modes and it is my experience that any pass that uses this
 interface has one of three behaviors: it silently gets the wrong answer, it
 ices, or it fails to do the transformation.  If we leave double_int as an
 available option, then any use of it potentially will have one of these
 three behaviors.  And so one of my strong objections to this direction is
 that i do not want to fight this kind of bug for the rest of my life.
 Having a single storage model that just always works is in my opinion a
 highly desirable option.  What you have never answered in a concrete manner
 is, if we decide to provide this generality, what it would be used for.
 There is no place in a portable compiler where the right answer for every
 target is two HOST wide integers.

 However, i will admit that the HWI option has some merits.   We try to
 address this in our implementation by dividing what is done inline in
 wide-int.h to the cases that fit in an HWI and then only drop into the heavy
 code in wide-int.c if mode is larger (which it rarely will be).   However, a
 case could be made that for certain kinds of things like string lengths and
 such, we could use another interface or as you argue, a different storage
 model with the same interface.   I just do not see that the cost of the
 conversion code is really going to show up on anyone's radar.

What's the issue with abstracting away the model so a fixed-size 'len'
is possible?  (let away the argument that 

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-03 Thread Richard Biener
On Tue, Apr 2, 2013 at 9:08 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 this time for sure.

Almost ...

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..92d54a3 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,35 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
 {
   return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
 }
+
+#ifndef ENABLE_CHECKING

#ifdef ENABLE_CHECKING

+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);
+

Ok with that change.  (maybe catch one random use of the pattern
in code and use the helpers - that would have catched this issue)

Thanks,
Richard.



 kenny

 On 04/02/2013 10:54 AM, Richard Biener wrote:

 On Tue, Apr 2, 2013 at 3:49 PM, Kenneth Zadeck zad...@naturalbridge.com
 wrote:

 Richard,

 did everything that you asked here.  bootstrapped and regtested on
 x86-64.
 ok to commit?

 diff --git a/gcc/hwint.c b/gcc/hwint.c
 index 330b42c..7e5b85c 100644
 --- a/gcc/hwint.c
 +++ b/gcc/hwint.c
 @@ -204,3 +204,33 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT
 b)
   {
 return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
   }
 +
 +#ifndef ENABLE_CHECKING
 +/* Sign extend SRC starting from PREC.  */
 +
 +HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)

 this should go to hwint.h, and without the masking of prec.
 while ...

 diff --git a/gcc/hwint.h b/gcc/hwint.h
 index da62fad..9dddf05 100644
 --- a/gcc/hwint.h
 +++ b/gcc/hwint.h
 @@ -276,4 +316,42 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT,
 HOST_WIDE_INT);
   extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
   extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT,
 HOST_WIDE_INT);

 +/* Sign extend SRC starting from PREC.  */
 +
 +#ifdef ENABLE_CHECKING
 +extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
 +#else
 +static inline HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)
 +{
 +  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);

 this should go to hwint.c (also without masking prec).

 Richard.




 kenny


 On 04/02/2013 05:38 AM, Richard Biener wrote:

 On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 richard,

 I was able to add everything except for the checking asserts.While
 I
 think that this is a reasonable idea, it is difficult to add that to a
 function that is defined in hwint.h because of circular includes.   I
 could
 move this another file (though this appears to be the logical correct
 place
 for it), or we can do without the asserts.

 The context is that [sz]ext_hwi is that are used are over the compiler
 but
 are generally written out long.   The wide-int class uses them also,
 but
 wide-int did not see like the right place for them to live and i
 believe
 that you suggested that i move them.

 ok to commit, or do you have a suggested resolution to the assert
 issue?

 Yes, do

 #ifdef ENABLE_CHECKING
 extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
 #else
 +/* Sign extend SRC starting from PREC.  */
 +
 +static inline HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)
 +{
 +  if (prec == HOST_BITS_PER_WIDE_INT)
 +return src;
 +  else
 +{
   int shift = HOST_BITS_PER_WIDE_INT - prec;
 +  return (src  shift)  shift;
 +}
 +}
 #endif

 and for ENABLE_CHECKING only provide an out-of-line implementation
 in hwint.c.  That's how we did it with abs_hwi (well, we just do not
 provide
 an inline variant there - that's another possibility).

 Note that hwint.h is always included after config.h so the
 ENABLE_CHECKING
 definition should be available.

 Richard.

 kenny


 On 03/27/2013 10:13 AM, Richard Biener wrote:

 On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 Here is the first of my wide int patches with joseph's comments and
 the
 patch rot removed.

 I would like to get these pre approved for the next stage 1.

 +  int shift = HOST_BITS_PER_WIDE_INT - (prec 
 (HOST_BITS_PER_WIDE_INT - 1));

 I think this should gcc_checking_assert that prec is not out of range
 (any reason why prec is signed int and not unsigned int?) rather than
 ignore bits in prec.

 +static inline HOST_WIDE_INT
 +zext_hwi (HOST_WIDE_INT src, int prec)
 +{
 +  if (prec == HOST_BITS_PER_WIDE_INT)
 +return src;
 +  else
 +return src  (((HOST_WIDE_INT)1
 +   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
 +}

 likewise.  Also I'm not sure I agree about the signedness of the
 result
 /
 src.
 zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

 The patch misses context of uses, so I'm not sure what the above
 functions
 are intended to do.

 Richard.

 On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

 On Fri, 5 Oct 2012, Kenneth Zadeck wrote:

 +# define HOST_HALF_WIDE_INT_PRINT h

 This may cause problems on hosts not supporting %hd (MinGW?), and
 

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-03 Thread Kenneth Zadeck
yes, i had caught that when i merged it in with the patches that used 
it, is it ok aside from that?

kenny
On 04/03/2013 05:32 AM, Richard Biener wrote:

On Tue, Apr 2, 2013 at 9:08 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:

this time for sure.

Almost ...

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..92d54a3 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,35 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
  {
return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
  }
+
+#ifndef ENABLE_CHECKING

#ifdef ENABLE_CHECKING

+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);
+

Ok with that change.  (maybe catch one random use of the pattern
in code and use the helpers - that would have catched this issue)

Thanks,
Richard.




kenny

On 04/02/2013 10:54 AM, Richard Biener wrote:

On Tue, Apr 2, 2013 at 3:49 PM, Kenneth Zadeck zad...@naturalbridge.com
wrote:

Richard,

did everything that you asked here.  bootstrapped and regtested on
x86-64.
ok to commit?

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..7e5b85c 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,33 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT
b)
   {
 return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
   }
+
+#ifndef ENABLE_CHECKING
+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)

this should go to hwint.h, and without the masking of prec.
while ...

diff --git a/gcc/hwint.h b/gcc/hwint.h
index da62fad..9dddf05 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -276,4 +316,42 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT,
HOST_WIDE_INT);
   extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
   extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT,
HOST_WIDE_INT);

+/* Sign extend SRC starting from PREC.  */
+
+#ifdef ENABLE_CHECKING
+extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
+#else
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);

this should go to hwint.c (also without masking prec).

Richard.





kenny


On 04/02/2013 05:38 AM, Richard Biener wrote:

On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

richard,

I was able to add everything except for the checking asserts.While
I
think that this is a reasonable idea, it is difficult to add that to a
function that is defined in hwint.h because of circular includes.   I
could
move this another file (though this appears to be the logical correct
place
for it), or we can do without the asserts.

The context is that [sz]ext_hwi is that are used are over the compiler
but
are generally written out long.   The wide-int class uses them also,
but
wide-int did not see like the right place for them to live and i
believe
that you suggested that i move them.

ok to commit, or do you have a suggested resolution to the assert
issue?

Yes, do

#ifdef ENABLE_CHECKING
extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
#else
+/* Sign extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
   int shift = HOST_BITS_PER_WIDE_INT - prec;
+  return (src  shift)  shift;
+}
+}
#endif

and for ENABLE_CHECKING only provide an out-of-line implementation
in hwint.c.  That's how we did it with abs_hwi (well, we just do not
provide
an inline variant there - that's another possibility).

Note that hwint.h is always included after config.h so the
ENABLE_CHECKING
definition should be available.

Richard.


kenny


On 03/27/2013 10:13 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the first of my wide int patches with joseph's comments and
the
patch rot removed.

I would like to get these pre approved for the next stage 1.

+  int shift = HOST_BITS_PER_WIDE_INT - (prec 
(HOST_BITS_PER_WIDE_INT - 1));

I think this should gcc_checking_assert that prec is not out of range
(any reason why prec is signed int and not unsigned int?) rather than
ignore bits in prec.

+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}

likewise.  Also I'm not sure I agree about the signedness of the
result
/
src.
zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

The patch misses context of uses, so I'm not sure what the above
functions
are intended to do.

Richard.


On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

On Fri, 5 Oct 2012, Kenneth Zadeck wrote:


+# define HOST_HALF_WIDE_INT_PRINT h

This may cause problems on 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-03 Thread Kenneth Zadeck


On 04/03/2013 05:17 AM, Richard Biener wrote:


In the end you will have a variable-size storage in TREE_INT_CST thus
you will have at least to emit _code_ copying over meta-data and data
from the tree representation to the wide-int (similar for RTX CONST_DOUBLE/INT).
I'm objecting to the amount of code you emit and agree that the runtime
cost is copying the meta-data (hopefully optimizable via CSE / SRA)
and in most cases one (or two) iterations of the loop copying the data
(not optimizable).
i did get rid of the bitsize in the wide-int patch so at this point the 
meta data is the precision and the len.
not really a lot here.   As usual we pay a high price in gcc for not 
pushing the tree rep down into the rtl level, then it would have been 
acceptable to have the tree type bleed into the wide-int code.




2)  You present this as if the implementor actually should care about the
implementation and you give 3 alternatives:  the double_int, the current
one, and HWI. We have tried to make it so that the client should not
care.   Certainly in my experience here, I have not found a place to care.

Well, similar as for the copying overhead for tree your approach requires
overloading operations for HOST_WIDE_INT operands to be able to
say wi + 1 (which is certainly desirable), or the overhead of using
wide_int_one ().


In my opinion double_int needs to go away.  That is the main thrust of my
patches.   There is no place in a compiler for an abi that depends on
constants fitting into 2 two words whose size is defined by the host.

That's true.  I'm not arguing to preserve double-int - I'm arguing to
preserve a way to ask for an integer type on the host with (at least)
N bits.  Almost all double-int users really ask for an integer type on the
host that has at least as many bits as the pointer representation (or
word_mode) on
the target (we do have HOST_WIDEST_INT == 32bits for 64bit pointer
targets).  No double-int user specifically wants 2 * HOST_WIDE_INT
precision - that is just what happens to be there.  Thus I am providing
a way to say get me a host integer with at least N bits (VRP asks for
this, for example).

What I was asking for is that whatever can provide the above should share
the functional interface with wide-int (or the othert way around).  And I
was claiming that wide-int is too fat, because current users of double-int
eventually store double-ints permanently.
The problem is that, in truth, double int is too fat. 99.something% of 
all constants fit in 1 hwi and that is likely to be true forever (i 
understand that tree vpn may need some thought here).  The rtl level, 
which has, for as long as i have known it, had 2 reps for integer 
constants. So it was relatively easy to slide the CONST_WIDE_INT in.  It 
seems like the right trickery here rather than adding a storage model 
for wide-ints might be a way to use the c++ to invisibly support several 
(and by several i really mean 2) classes of TREE_CSTs.





This is not a beauty contest argument, we have public ports are beginning to
use modes that are larger than two x86-64 HWIs and i have a private port
that has such modes and it is my experience that any pass that uses this
interface has one of three behaviors: it silently gets the wrong answer, it
ices, or it fails to do the transformation.  If we leave double_int as an
available option, then any use of it potentially will have one of these
three behaviors.  And so one of my strong objections to this direction is
that i do not want to fight this kind of bug for the rest of my life.
Having a single storage model that just always works is in my opinion a
highly desirable option.  What you have never answered in a concrete manner
is, if we decide to provide this generality, what it would be used for.
There is no place in a portable compiler where the right answer for every
target is two HOST wide integers.

However, i will admit that the HWI option has some merits.   We try to
address this in our implementation by dividing what is done inline in
wide-int.h to the cases that fit in an HWI and then only drop into the heavy
code in wide-int.c if mode is larger (which it rarely will be).   However, a
case could be made that for certain kinds of things like string lengths and
such, we could use another interface or as you argue, a different storage
model with the same interface.   I just do not see that the cost of the
conversion code is really going to show up on anyone's radar.

What's the issue with abstracting away the model so a fixed-size 'len'
is possible?  (let away the argument that this would easily allow an
adaptor to tree)
I have a particularly pessimistic perspective because i have already 
written most of this patch.   It is not that i do not want to change 
that code, it is that i have seen a certain set of mistakes that were 
made and i do not want to fix them more than once.   At the rtl level 
you can see the transition from only supporting 32 bit ints to 
supporting 64 bit 

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-03 Thread Richard Biener
On Wed, Apr 3, 2013 at 12:47 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 yes, i had caught that when i merged it in with the patches that used it, is
 it ok aside from that?

Yes.

Thanks,
Richard.

 kenny

 On 04/03/2013 05:32 AM, Richard Biener wrote:

 On Tue, Apr 2, 2013 at 9:08 PM, Kenneth Zadeck zad...@naturalbridge.com
 wrote:

 this time for sure.

 Almost ...

 diff --git a/gcc/hwint.c b/gcc/hwint.c
 index 330b42c..92d54a3 100644
 --- a/gcc/hwint.c
 +++ b/gcc/hwint.c
 @@ -204,3 +204,35 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT
 b)
   {
 return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
   }
 +
 +#ifndef ENABLE_CHECKING

 #ifdef ENABLE_CHECKING

 +/* Sign extend SRC starting from PREC.  */
 +
 +HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)
 +{
 +  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);
 +

 Ok with that change.  (maybe catch one random use of the pattern
 in code and use the helpers - that would have catched this issue)

 Thanks,
 Richard.



 kenny

 On 04/02/2013 10:54 AM, Richard Biener wrote:

 On Tue, Apr 2, 2013 at 3:49 PM, Kenneth Zadeck
 zad...@naturalbridge.com
 wrote:

 Richard,

 did everything that you asked here.  bootstrapped and regtested on
 x86-64.
 ok to commit?

 diff --git a/gcc/hwint.c b/gcc/hwint.c
 index 330b42c..7e5b85c 100644
 --- a/gcc/hwint.c
 +++ b/gcc/hwint.c
 @@ -204,3 +204,33 @@ least_common_multiple (HOST_WIDE_INT a,
 HOST_WIDE_INT
 b)
{
  return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
}
 +
 +#ifndef ENABLE_CHECKING
 +/* Sign extend SRC starting from PREC.  */
 +
 +HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)

 this should go to hwint.h, and without the masking of prec.
 while ...

 diff --git a/gcc/hwint.h b/gcc/hwint.h
 index da62fad..9dddf05 100644
 --- a/gcc/hwint.h
 +++ b/gcc/hwint.h
 @@ -276,4 +316,42 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT,
 HOST_WIDE_INT);
extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT,
 HOST_WIDE_INT);

 +/* Sign extend SRC starting from PREC.  */
 +
 +#ifdef ENABLE_CHECKING
 +extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
 +#else
 +static inline HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)
 +{
 +  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);

 this should go to hwint.c (also without masking prec).

 Richard.




 kenny


 On 04/02/2013 05:38 AM, Richard Biener wrote:

 On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 richard,

 I was able to add everything except for the checking asserts.
 While
 I
 think that this is a reasonable idea, it is difficult to add that to
 a
 function that is defined in hwint.h because of circular includes.   I
 could
 move this another file (though this appears to be the logical correct
 place
 for it), or we can do without the asserts.

 The context is that [sz]ext_hwi is that are used are over the
 compiler
 but
 are generally written out long.   The wide-int class uses them also,
 but
 wide-int did not see like the right place for them to live and i
 believe
 that you suggested that i move them.

 ok to commit, or do you have a suggested resolution to the assert
 issue?

 Yes, do

 #ifdef ENABLE_CHECKING
 extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
 #else
 +/* Sign extend SRC starting from PREC.  */
 +
 +static inline HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)
 +{
 +  if (prec == HOST_BITS_PER_WIDE_INT)
 +return src;
 +  else
 +{
int shift = HOST_BITS_PER_WIDE_INT - prec;
 +  return (src  shift)  shift;
 +}
 +}
 #endif

 and for ENABLE_CHECKING only provide an out-of-line implementation
 in hwint.c.  That's how we did it with abs_hwi (well, we just do not
 provide
 an inline variant there - that's another possibility).

 Note that hwint.h is always included after config.h so the
 ENABLE_CHECKING
 definition should be available.

 Richard.

 kenny


 On 03/27/2013 10:13 AM, Richard Biener wrote:

 On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 Here is the first of my wide int patches with joseph's comments and
 the
 patch rot removed.

 I would like to get these pre approved for the next stage 1.

 +  int shift = HOST_BITS_PER_WIDE_INT - (prec 
 (HOST_BITS_PER_WIDE_INT - 1));

 I think this should gcc_checking_assert that prec is not out of
 range
 (any reason why prec is signed int and not unsigned int?) rather
 than
 ignore bits in prec.

 +static inline HOST_WIDE_INT
 +zext_hwi (HOST_WIDE_INT src, int prec)
 +{
 +  if (prec == HOST_BITS_PER_WIDE_INT)
 +return src;
 +  else
 +return src  (((HOST_WIDE_INT)1
 +   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
 +}

 likewise.  Also I'm not sure I agree about the signedness of the
 result
 /
 src.
 zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

 The 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-03 Thread Richard Biener
On Wed, Apr 3, 2013 at 2:05 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:

 On 04/03/2013 05:17 AM, Richard Biener wrote:

 In the end you will have a variable-size storage in TREE_INT_CST thus
 you will have at least to emit _code_ copying over meta-data and data
 from the tree representation to the wide-int (similar for RTX
 CONST_DOUBLE/INT).
 I'm objecting to the amount of code you emit and agree that the runtime
 cost is copying the meta-data (hopefully optimizable via CSE / SRA)
 and in most cases one (or two) iterations of the loop copying the data
 (not optimizable).

 i did get rid of the bitsize in the wide-int patch so at this point the meta
 data is the precision and the len.
 not really a lot here.   As usual we pay a high price in gcc for not pushing
 the tree rep down into the rtl level, then it would have been acceptable to
 have the tree type bleed into the wide-int code.



 2)  You present this as if the implementor actually should care about the
 implementation and you give 3 alternatives:  the double_int, the current
 one, and HWI. We have tried to make it so that the client should not
 care.   Certainly in my experience here, I have not found a place to
 care.

 Well, similar as for the copying overhead for tree your approach requires
 overloading operations for HOST_WIDE_INT operands to be able to
 say wi + 1 (which is certainly desirable), or the overhead of using
 wide_int_one ().

 In my opinion double_int needs to go away.  That is the main thrust of my
 patches.   There is no place in a compiler for an abi that depends on
 constants fitting into 2 two words whose size is defined by the host.

 That's true.  I'm not arguing to preserve double-int - I'm arguing to
 preserve a way to ask for an integer type on the host with (at least)
 N bits.  Almost all double-int users really ask for an integer type on the
 host that has at least as many bits as the pointer representation (or
 word_mode) on
 the target (we do have HOST_WIDEST_INT == 32bits for 64bit pointer
 targets).  No double-int user specifically wants 2 * HOST_WIDE_INT
 precision - that is just what happens to be there.  Thus I am providing
 a way to say get me a host integer with at least N bits (VRP asks for
 this, for example).

 What I was asking for is that whatever can provide the above should share
 the functional interface with wide-int (or the othert way around).  And I
 was claiming that wide-int is too fat, because current users of double-int
 eventually store double-ints permanently.

 The problem is that, in truth, double int is too fat. 99.something% of all
 constants fit in 1 hwi and that is likely to be true forever (i understand
 that tree vpn may need some thought here).  The rtl level, which has, for as
 long as i have known it, had 2 reps for integer constants. So it was
 relatively easy to slide the CONST_WIDE_INT in.  It seems like the right
 trickery here rather than adding a storage model for wide-ints might be a
 way to use the c++ to invisibly support several (and by several i really
 mean 2) classes of TREE_CSTs.

The truth is that _now_ TREE_INT_CSTs use double-ints and we have
CONST_INT and CONST_DOUBLE.  What I (and you) propose would
get us to use variable-size storage for both, allowing to just use a single
HOST_WIDE_INT in the majority of cases.  In my view the constant
length of the variable-size storage for TREE_INT_CSTs is determined
by its type (thus, it doesn't have optimized variable-size storage
but unoptimized fixed-size storage based on the maximum storage
requirement for the type).  Similar for RTX CONST_INT which would
have fixed-size storage based on the mode-size of the constant.
Using optimized space (thus using the encoding properties) requires you
to fit the 'short len' somewhere which possibly will not pay off in the end
(for tree we do have that storage available, so we could go with optimized
storage for it, not sure with RTL, I don't see available space there).

 This is not a beauty contest argument, we have public ports are beginning
 to
 use modes that are larger than two x86-64 HWIs and i have a private port
 that has such modes and it is my experience that any pass that uses this
 interface has one of three behaviors: it silently gets the wrong answer,
 it
 ices, or it fails to do the transformation.  If we leave double_int as an
 available option, then any use of it potentially will have one of these
 three behaviors.  And so one of my strong objections to this direction is
 that i do not want to fight this kind of bug for the rest of my life.
 Having a single storage model that just always works is in my opinion a
 highly desirable option.  What you have never answered in a concrete
 manner
 is, if we decide to provide this generality, what it would be used for.
 There is no place in a portable compiler where the right answer for every
 target is two HOST wide integers.

 However, i will admit that the HWI option has some merits.   We try to
 address this 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-03 Thread Kenneth Zadeck

On 04/03/2013 09:53 AM, Richard Biener wrote:

On Wed, Apr 3, 2013 at 2:05 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:

On 04/03/2013 05:17 AM, Richard Biener wrote:


In the end you will have a variable-size storage in TREE_INT_CST thus
you will have at least to emit _code_ copying over meta-data and data
from the tree representation to the wide-int (similar for RTX
CONST_DOUBLE/INT).
I'm objecting to the amount of code you emit and agree that the runtime
cost is copying the meta-data (hopefully optimizable via CSE / SRA)
and in most cases one (or two) iterations of the loop copying the data
(not optimizable).

i did get rid of the bitsize in the wide-int patch so at this point the meta
data is the precision and the len.
not really a lot here.   As usual we pay a high price in gcc for not pushing
the tree rep down into the rtl level, then it would have been acceptable to
have the tree type bleed into the wide-int code.




2)  You present this as if the implementor actually should care about the
implementation and you give 3 alternatives:  the double_int, the current
one, and HWI. We have tried to make it so that the client should not
care.   Certainly in my experience here, I have not found a place to
care.

Well, similar as for the copying overhead for tree your approach requires
overloading operations for HOST_WIDE_INT operands to be able to
say wi + 1 (which is certainly desirable), or the overhead of using
wide_int_one ().


In my opinion double_int needs to go away.  That is the main thrust of my
patches.   There is no place in a compiler for an abi that depends on
constants fitting into 2 two words whose size is defined by the host.

That's true.  I'm not arguing to preserve double-int - I'm arguing to
preserve a way to ask for an integer type on the host with (at least)
N bits.  Almost all double-int users really ask for an integer type on the
host that has at least as many bits as the pointer representation (or
word_mode) on
the target (we do have HOST_WIDEST_INT == 32bits for 64bit pointer
targets).  No double-int user specifically wants 2 * HOST_WIDE_INT
precision - that is just what happens to be there.  Thus I am providing
a way to say get me a host integer with at least N bits (VRP asks for
this, for example).

What I was asking for is that whatever can provide the above should share
the functional interface with wide-int (or the othert way around).  And I
was claiming that wide-int is too fat, because current users of double-int
eventually store double-ints permanently.

The problem is that, in truth, double int is too fat. 99.something% of all
constants fit in 1 hwi and that is likely to be true forever (i understand
that tree vpn may need some thought here).  The rtl level, which has, for as
long as i have known it, had 2 reps for integer constants. So it was
relatively easy to slide the CONST_WIDE_INT in.  It seems like the right
trickery here rather than adding a storage model for wide-ints might be a
way to use the c++ to invisibly support several (and by several i really
mean 2) classes of TREE_CSTs.

The truth is that _now_ TREE_INT_CSTs use double-ints and we have
CONST_INT and CONST_DOUBLE.  What I (and you) propose would
get us to use variable-size storage for both, allowing to just use a single
HOST_WIDE_INT in the majority of cases.  In my view the constant
length of the variable-size storage for TREE_INT_CSTs is determined
by its type (thus, it doesn't have optimized variable-size storage
but unoptimized fixed-size storage based on the maximum storage
requirement for the type).  Similar for RTX CONST_INT which would
have fixed-size storage based on the mode-size of the constant.
Using optimized space (thus using the encoding properties) requires you
to fit the 'short len' somewhere which possibly will not pay off in the end
(for tree we do have that storage available, so we could go with optimized
storage for it, not sure with RTL, I don't see available space there).
There are two questions here:   one is the fact that you object to the 
fact that we represent small constants efficiently and the second is 
that we take advantage of the fact that fixed size stack allocation is 
effectively free for short lived objects like wide-ints (as i use them).


At the rtl level your idea does not work.   rtl constants do not have a 
mode or type.So if you do not compress, how are you going to 
determine how many words you need for the constant 1.   I would love to 
have a rep that had the mode in it.But it is a huge change that 
requires a lot of hacking to every port.


I understand that this makes me vulnerable to the argument that we 
should not let the rtl level ever dictate anything about the tree level, 
but the truth is that a variable len rep is almost always used for big 
integers.   In our code, most constants of large types are small 
numbers.   (Remember i got into this because the tree constant prop 
thinks that left shifting any number by anything 

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-03 Thread Kenneth Zadeck

committed as revision 197456

kenny
On 04/03/2013 08:05 AM, Richard Biener wrote:

On Wed, Apr 3, 2013 at 12:47 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

yes, i had caught that when i merged it in with the patches that used it, is
it ok aside from that?

Yes.

Thanks,
Richard.


kenny

On 04/03/2013 05:32 AM, Richard Biener wrote:

On Tue, Apr 2, 2013 at 9:08 PM, Kenneth Zadeck zad...@naturalbridge.com
wrote:

this time for sure.

Almost ...

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..92d54a3 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,35 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT
b)
   {
 return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
   }
+
+#ifndef ENABLE_CHECKING

#ifdef ENABLE_CHECKING

+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);
+

Ok with that change.  (maybe catch one random use of the pattern
in code and use the helpers - that would have catched this issue)

Thanks,
Richard.




kenny

On 04/02/2013 10:54 AM, Richard Biener wrote:

On Tue, Apr 2, 2013 at 3:49 PM, Kenneth Zadeck
zad...@naturalbridge.com
wrote:

Richard,

did everything that you asked here.  bootstrapped and regtested on
x86-64.
ok to commit?

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..7e5b85c 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,33 @@ least_common_multiple (HOST_WIDE_INT a,
HOST_WIDE_INT
b)
{
  return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
}
+
+#ifndef ENABLE_CHECKING
+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)

this should go to hwint.h, and without the masking of prec.
while ...

diff --git a/gcc/hwint.h b/gcc/hwint.h
index da62fad..9dddf05 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -276,4 +316,42 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT,
HOST_WIDE_INT);
extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT,
HOST_WIDE_INT);

+/* Sign extend SRC starting from PREC.  */
+
+#ifdef ENABLE_CHECKING
+extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
+#else
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);

this should go to hwint.c (also without masking prec).

Richard.





kenny


On 04/02/2013 05:38 AM, Richard Biener wrote:

On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

richard,

I was able to add everything except for the checking asserts.
While
I
think that this is a reasonable idea, it is difficult to add that to
a
function that is defined in hwint.h because of circular includes.   I
could
move this another file (though this appears to be the logical correct
place
for it), or we can do without the asserts.

The context is that [sz]ext_hwi is that are used are over the
compiler
but
are generally written out long.   The wide-int class uses them also,
but
wide-int did not see like the right place for them to live and i
believe
that you suggested that i move them.

ok to commit, or do you have a suggested resolution to the assert
issue?

Yes, do

#ifdef ENABLE_CHECKING
extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
#else
+/* Sign extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
int shift = HOST_BITS_PER_WIDE_INT - prec;
+  return (src  shift)  shift;
+}
+}
#endif

and for ENABLE_CHECKING only provide an out-of-line implementation
in hwint.c.  That's how we did it with abs_hwi (well, we just do not
provide
an inline variant there - that's another possibility).

Note that hwint.h is always included after config.h so the
ENABLE_CHECKING
definition should be available.

Richard.


kenny


On 03/27/2013 10:13 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the first of my wide int patches with joseph's comments and
the
patch rot removed.

I would like to get these pre approved for the next stage 1.

+  int shift = HOST_BITS_PER_WIDE_INT - (prec 
(HOST_BITS_PER_WIDE_INT - 1));

I think this should gcc_checking_assert that prec is not out of
range
(any reason why prec is signed int and not unsigned int?) rather
than
ignore bits in prec.

+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}

likewise.  Also I'm not sure I agree about the signedness of the
result
/
src.
zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

The patch misses context of uses, so I'm not sure what the above

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-02 Thread Richard Biener
On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 richard,

 I was able to add everything except for the checking asserts.While I
 think that this is a reasonable idea, it is difficult to add that to a
 function that is defined in hwint.h because of circular includes.   I could
 move this another file (though this appears to be the logical correct place
 for it), or we can do without the asserts.

 The context is that [sz]ext_hwi is that are used are over the compiler but
 are generally written out long.   The wide-int class uses them also, but
 wide-int did not see like the right place for them to live and i believe
 that you suggested that i move them.

 ok to commit, or do you have a suggested resolution to the assert issue?

Yes, do

#ifdef ENABLE_CHECKING
extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
#else
+/* Sign extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
int shift = HOST_BITS_PER_WIDE_INT - prec;
+  return (src  shift)  shift;
+}
+}
#endif

and for ENABLE_CHECKING only provide an out-of-line implementation
in hwint.c.  That's how we did it with abs_hwi (well, we just do not provide
an inline variant there - that's another possibility).

Note that hwint.h is always included after config.h so the ENABLE_CHECKING
definition should be available.

Richard.


 kenny


 On 03/27/2013 10:13 AM, Richard Biener wrote:

 On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 Here is the first of my wide int patches with joseph's comments and the
 patch rot removed.

 I would like to get these pre approved for the next stage 1.

 +  int shift = HOST_BITS_PER_WIDE_INT - (prec 
 (HOST_BITS_PER_WIDE_INT - 1));

 I think this should gcc_checking_assert that prec is not out of range
 (any reason why prec is signed int and not unsigned int?) rather than
 ignore bits in prec.

 +static inline HOST_WIDE_INT
 +zext_hwi (HOST_WIDE_INT src, int prec)
 +{
 +  if (prec == HOST_BITS_PER_WIDE_INT)
 +return src;
 +  else
 +return src  (((HOST_WIDE_INT)1
 +   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
 +}

 likewise.  Also I'm not sure I agree about the signedness of the result /
 src.
 zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

 The patch misses context of uses, so I'm not sure what the above functions
 are intended to do.

 Richard.

 On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

 On Fri, 5 Oct 2012, Kenneth Zadeck wrote:

 +# define HOST_HALF_WIDE_INT_PRINT h

 This may cause problems on hosts not supporting %hd (MinGW?), and
 there's
 no real need for using h here given the promotion of short to int; you
 can just use  (rather than e.g. needing special handling in
 xm-mingw32.h
 like is done for HOST_LONG_LONG_FORMAT).




Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-02 Thread Kenneth Zadeck

Richard,

did everything that you asked here.  bootstrapped and regtested on 
x86-64.  ok to commit?


kenny

On 04/02/2013 05:38 AM, Richard Biener wrote:

On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

richard,

I was able to add everything except for the checking asserts.While I
think that this is a reasonable idea, it is difficult to add that to a
function that is defined in hwint.h because of circular includes.   I could
move this another file (though this appears to be the logical correct place
for it), or we can do without the asserts.

The context is that [sz]ext_hwi is that are used are over the compiler but
are generally written out long.   The wide-int class uses them also, but
wide-int did not see like the right place for them to live and i believe
that you suggested that i move them.

ok to commit, or do you have a suggested resolution to the assert issue?

Yes, do

#ifdef ENABLE_CHECKING
extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
#else
+/* Sign extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
 int shift = HOST_BITS_PER_WIDE_INT - prec;
+  return (src  shift)  shift;
+}
+}
#endif

and for ENABLE_CHECKING only provide an out-of-line implementation
in hwint.c.  That's how we did it with abs_hwi (well, we just do not provide
an inline variant there - that's another possibility).

Note that hwint.h is always included after config.h so the ENABLE_CHECKING
definition should be available.

Richard.


kenny


On 03/27/2013 10:13 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the first of my wide int patches with joseph's comments and the
patch rot removed.

I would like to get these pre approved for the next stage 1.

+  int shift = HOST_BITS_PER_WIDE_INT - (prec 
(HOST_BITS_PER_WIDE_INT - 1));

I think this should gcc_checking_assert that prec is not out of range
(any reason why prec is signed int and not unsigned int?) rather than
ignore bits in prec.

+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}

likewise.  Also I'm not sure I agree about the signedness of the result /
src.
zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

The patch misses context of uses, so I'm not sure what the above functions
are intended to do.

Richard.


On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

On Fri, 5 Oct 2012, Kenneth Zadeck wrote:


+# define HOST_HALF_WIDE_INT_PRINT h

This may cause problems on hosts not supporting %hd (MinGW?), and
there's
no real need for using h here given the promotion of short to int; you
can just use  (rather than e.g. needing special handling in
xm-mingw32.h
like is done for HOST_LONG_LONG_FORMAT).



2013-4-02  Kenneth Zadeck zad...@naturalbridge.com

* hwint.c (sext_hwi, zext_hwi): New functions.
* hwint.h (HOST_BITS_PER_HALF_WIDE_INT, HOST_HALF_WIDE_INT,
HOST_HALF_WIDE_INT_PRINT, HOST_HALF_WIDE_INT_PRINT_C,
HOST_HALF_WIDE_INT_PRINT_DEC, HOST_HALF_WIDE_INT_PRINT_DEC_C,
HOST_HALF_WIDE_INT_PRINT_UNSIGNED, HOST_HALF_WIDE_INT_PRINT_HEX,
HOST_HALF_WIDE_INT_PRINT_HEX_PURE): New symbols.
(sext_hwi, zext_hwi): New functions.

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..7e5b85c 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,33 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
 {
   return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
 }
+
+#ifndef ENABLE_CHECKING
+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
+  int shift = HOST_BITS_PER_WIDE_INT - 
+	(prec  (HOST_BITS_PER_WIDE_INT - 1));
+  return (src  shift)  shift;
+}
+}
+
+/* Zero extend SRC starting from PREC.  */
+
+unsigned HOST_WIDE_INT
+zext_hwi (unsigned HOST_WIDE_INT src, unsigned int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+		(prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}
+
+#endif
diff --git a/gcc/hwint.h b/gcc/hwint.h
index da62fad..9dddf05 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -76,6 +76,40 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
 # endif
 #endif
 
+/* Print support for half a host wide int.  */
+#define HOST_BITS_PER_HALF_WIDE_INT (HOST_BITS_PER_WIDE_INT / 2)
+#if HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_HALF_WIDE_INT long
+# define HOST_HALF_WIDE_INT_PRINT HOST_LONG_FORMAT
+# define HOST_HALF_WIDE_INT_PRINT_C L
+# define HOST_HALF_WIDE_INT_PRINT_DEC % 

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-02 Thread Richard Biener
On Tue, Apr 2, 2013 at 3:49 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 Richard,

 did everything that you asked here.  bootstrapped and regtested on x86-64.
 ok to commit?

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..7e5b85c 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,33 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
 {
   return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
 }
+
+#ifndef ENABLE_CHECKING
+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)

this should go to hwint.h, and without the masking of prec.
while ...

diff --git a/gcc/hwint.h b/gcc/hwint.h
index da62fad..9dddf05 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -276,4 +316,42 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT,
HOST_WIDE_INT);
 extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);

+/* Sign extend SRC starting from PREC.  */
+
+#ifdef ENABLE_CHECKING
+extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
+#else
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);

this should go to hwint.c (also without masking prec).

Richard.




 kenny


 On 04/02/2013 05:38 AM, Richard Biener wrote:

 On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 richard,

 I was able to add everything except for the checking asserts.While I
 think that this is a reasonable idea, it is difficult to add that to a
 function that is defined in hwint.h because of circular includes.   I
 could
 move this another file (though this appears to be the logical correct
 place
 for it), or we can do without the asserts.

 The context is that [sz]ext_hwi is that are used are over the compiler
 but
 are generally written out long.   The wide-int class uses them also, but
 wide-int did not see like the right place for them to live and i believe
 that you suggested that i move them.

 ok to commit, or do you have a suggested resolution to the assert issue?

 Yes, do

 #ifdef ENABLE_CHECKING
 extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
 #else
 +/* Sign extend SRC starting from PREC.  */
 +
 +static inline HOST_WIDE_INT
 +sext_hwi (HOST_WIDE_INT src, unsigned int prec)
 +{
 +  if (prec == HOST_BITS_PER_WIDE_INT)
 +return src;
 +  else
 +{
  int shift = HOST_BITS_PER_WIDE_INT - prec;
 +  return (src  shift)  shift;
 +}
 +}
 #endif

 and for ENABLE_CHECKING only provide an out-of-line implementation
 in hwint.c.  That's how we did it with abs_hwi (well, we just do not
 provide
 an inline variant there - that's another possibility).

 Note that hwint.h is always included after config.h so the ENABLE_CHECKING
 definition should be available.

 Richard.

 kenny


 On 03/27/2013 10:13 AM, Richard Biener wrote:

 On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 Here is the first of my wide int patches with joseph's comments and the
 patch rot removed.

 I would like to get these pre approved for the next stage 1.

 +  int shift = HOST_BITS_PER_WIDE_INT - (prec 
 (HOST_BITS_PER_WIDE_INT - 1));

 I think this should gcc_checking_assert that prec is not out of range
 (any reason why prec is signed int and not unsigned int?) rather than
 ignore bits in prec.

 +static inline HOST_WIDE_INT
 +zext_hwi (HOST_WIDE_INT src, int prec)
 +{
 +  if (prec == HOST_BITS_PER_WIDE_INT)
 +return src;
 +  else
 +return src  (((HOST_WIDE_INT)1
 +   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
 +}

 likewise.  Also I'm not sure I agree about the signedness of the result
 /
 src.
 zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

 The patch misses context of uses, so I'm not sure what the above
 functions
 are intended to do.

 Richard.

 On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

 On Fri, 5 Oct 2012, Kenneth Zadeck wrote:

 +# define HOST_HALF_WIDE_INT_PRINT h

 This may cause problems on hosts not supporting %hd (MinGW?), and
 there's
 no real need for using h here given the promotion of short to int;
 you
 can just use  (rather than e.g. needing special handling in
 xm-mingw32.h
 like is done for HOST_LONG_LONG_FORMAT).




Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-02 Thread Richard Biener
On Wed, Feb 27, 2013 at 2:59 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 This patch contains a large number of the changes requested by Richi.   It
 does not contain any of the changes that he requested to abstract the
 storage layer.   That suggestion appears to be quite unworkable.

I of course took this claim as a challenge ... with the following result.  It is
of course quite workable ;)

The attached patch implements the core wide-int class and three storage
models (fixed size for things like plain HWI and double-int, variable size
similar to how your wide-int works and an adaptor for the double-int as
contained in trees).  With that you can now do

HOST_WIDE_INT
wi_test (tree x)
{
  // template argument deduction doesn't do the magic we want it to do
  // to make this kind of implicit conversions work
  // overload resolution considers this kind of conversions so we
  // need some magic that combines both ... but seeding the overload
  // set with some instantiations doesn't seem to be possible :/
  // wide_int w = x + 1;
  wide_int w;
  w += x;
  w += 1;
  // template argument deduction doesn't deduce the return value type,
  // not considering the template default argument either ...
  // w = wi (x) + 1;
  // we could support this by providing rvalue-to-lvalue promotion
  // via a traits class?
  // otoh it would lead to sub-optimal code anyway so we should
  // make the result available as reference parameter and only support
  // wide_int  res; add (res, x, 1); ?
  w = wi (x).operator+wide_int (1);
  wide_int::add(w, x, 1);
  return w.to_hwi ();
}

we are somewhat limited with C++ unless we want to get really fancy.
Eventually providing operator+ just doesn't make much sense for
generic wide-int combinations (though then the issue is its operands
are no longer commutative which I think is the case with your wide-int
or double-int as well - they don't suport 1 + wide_int for obvious reasons).

So there are implementation design choices left undecided.

Oh, and the operation implementations are crap (they compute nonsense).

But you should get the idea.

Richard.
#include config.h
#include system.h

#include coretypes.h
#include hwint.h
#include tree.h


/* ???  wide-int should probably use HOST_WIDEST_FAST_INT as storage,
   not HOST_WIDE_INT.  Yeah, we could even template on that ...  */

/* Fixed-length embedded storage.  wi_embed2 is double-int,
   wi_embed1 is a plain HOST_WIDE_INT.  Can be used for
   small fixed-(minimum)-size calculations on hosts that have
   no suitable integer type.  */

template unsigned sz
class wi_embed
{
private:
  HOST_WIDE_INT s[sz];

public:
  void construct () {}
  HOST_WIDE_INT* storage() { return s; }
  const HOST_WIDE_INT* storage() const { return s; }
  unsigned len() const { return sz; }
  void set_len(unsigned l) { gcc_checking_assert (l = sz); }
};


/* Fixed maximum-length embedded storage but variable dynamic size.  */

//#define MAXSZ (4 * (MAX_MODE_INT_SIZE / HOST_BITS_PER_WIDE_INT))
#define MAXSZ 8

template unsigned max_sz
class wi_embed_var
{
private:
  unsigned len_;
  HOST_WIDE_INT s[max_sz];

public:
  void construct () { len_ = 0; }
  HOST_WIDE_INT* storage() { return s; }
  const HOST_WIDE_INT* storage() const { return s; }
  unsigned len() const { return len_; }
  void set_len(unsigned l) { len_ =  l; }
};


/* The wide-int class.  Defaults to variable-length storage
   (alternatively use a typedef to avoid the need to use wide_int ).  */

template class S = wi_embed_varMAXSZ 
class wide_int;


/* Avoid constructors / destructors to make sure this is a C++04 POD.  */

/* Basic wide_int class.  The storage model allows for rvalue
   storage abstraction avoiding copying from for example tree
   or RTX and to avoid the need of explicit construction for
   integral arguments of up to HWI size.

   A storage model needs to provide the following methods:
- construct (), default-initialize the storage
- unsigned len () const, the size of the storage in HWI quantities
- const HOST_WIDE_INT *storage () const, return a pointer
  to read-only HOST_WIDE_INT storage of size len ().
- HOST_WIDE_INT *storage (), return a pointer to writable
  HOST_WIDE_INT storage of size len ().  This method is optional.
- void set_len (unsigned l), adjust the size of the storage
  to at least l HWI words.

   Conversions of wide_int _to_ tree or RTX or HWI are explicit.

   Conversions to wide_int happen with overloads to the global
   function template wi () or via wide_int_traits specializations.  */

/* ???  With mixed length operations there are encoding issues
   for signed vs. unsigned numbers.  The easiest encoding is to
   say wide-ints are always signed which means that -1U needs
   the MSB of the wide-int storage as zero which means an extra
   word with zeros.  The sign-bit of a wide-int is then always
   storage()[len()  (1  (HOST_BITS_PER_WIDE_INT - 1))].  */

template class S
class wide_int : private S
{
  /* Allow 

Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-04-02 Thread Kenneth Zadeck
Yes, I agree that you win the challenge that it can be done.What you 
have always failed to address is why anyone would want to do this.  Or 
how this would at all be desirable.But I completely agree that from 
a purely abstract point of view you can add a storage model.


Now here is why we REALLY do not want to go down this road:

1)  The following comment from your earlier mail is completely wrong


+#ifdef NEW_REP_FOR_INT_CST
+  /* This is the code once the tree level is converted.  */
+  wide_int result;
+  int i;
+
+  tree type = TREE_TYPE (tcst);
+
+  result.bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
+  result.precision = TYPE_PRECISION (type);
+  result.len = TREE_INT_CST_LEN (tcst);
+  for (i = 0; i  result.len; i++)
+result.val[i] = TREE_INT_CST_ELT (tcst, i);
+
+  return result;
+#else



this also shows the main reason I was asking for storage abstraction.
The initialization from tree is way too expensive.


In almost all cases, constants will fit in a single HWI.  Thus, the only 
thing that you are copying is the length and a single HWI. So you are 
dragging in a lot of machinery just to save these two copies?   
Certainly there has to be more to it than that.


2)  You present this as if the implementor actually should care about 
the implementation and you give 3 alternatives:  the double_int, the 
current one, and HWI. We have tried to make it so that the client 
should not care.   Certainly in my experience here, I have not found a 
place to care.


In my opinion double_int needs to go away.  That is the main thrust of 
my patches.   There is no place in a compiler for an abi that depends on 
constants fitting into 2 two words whose size is defined by the host.
This is not a beauty contest argument, we have public ports are 
beginning to use modes that are larger than two x86-64 HWIs and i have a 
private port that has such modes and it is my experience that any pass 
that uses this interface has one of three behaviors: it silently gets 
the wrong answer, it ices, or it fails to do the transformation.  If we 
leave double_int as an available option, then any use of it potentially 
will have one of these three behaviors.  And so one of my strong 
objections to this direction is that i do not want to fight this kind of 
bug for the rest of my life.Having a single storage model that just 
always works is in my opinion a highly desirable option.  What you have 
never answered in a concrete manner is, if we decide to provide this 
generality, what it would be used for.There is no place in a 
portable compiler where the right answer for every target is two HOST 
wide integers.


However, i will admit that the HWI option has some merits.   We try to 
address this in our implementation by dividing what is done inline in 
wide-int.h to the cases that fit in an HWI and then only drop into the 
heavy code in wide-int.c if mode is larger (which it rarely will be).   
However, a case could be made that for certain kinds of things like 
string lengths and such, we could use another interface or as you argue, 
a different storage model with the same interface.   I just do not see 
that the cost of the conversion code is really going to show up on 
anyone's radar.


3) your trick will work at the tree level, but not at the rtl level.   
The wide-int code cannot share storage with the CONST_INTs.We tried 
this, and there are a million bugs that would have to be fixed to make 
it work.It could have worked if CONST_INTs had carried a mode 
around, but since they do not, you end up with the same CONST_INT 
sharing the rep for several different types and that just did not work 
unless you are willing to do substantial cleanups.


On 04/02/2013 11:04 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 2:59 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

This patch contains a large number of the changes requested by Richi.   It
does not contain any of the changes that he requested to abstract the
storage layer.   That suggestion appears to be quite unworkable.

I of course took this claim as a challenge ... with the following result.  It is
of course quite workable ;)

The attached patch implements the core wide-int class and three storage
models (fixed size for things like plain HWI and double-int, variable size
similar to how your wide-int works and an adaptor for the double-int as
contained in trees).  With that you can now do

HOST_WIDE_INT
wi_test (tree x)
{
   // template argument deduction doesn't do the magic we want it to do
   // to make this kind of implicit conversions work
   // overload resolution considers this kind of conversions so we
   // need some magic that combines both ... but seeding the overload
   // set with some instantiations doesn't seem to be possible :/
   // wide_int w = x + 1;
   wide_int w;
   w += x;
   w += 1;
   // template argument deduction doesn't deduce the return value type,
   // not considering the template default argument 

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-04-02 Thread Kenneth Zadeck

this time for sure.

kenny
On 04/02/2013 10:54 AM, Richard Biener wrote:

On Tue, Apr 2, 2013 at 3:49 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:

Richard,

did everything that you asked here.  bootstrapped and regtested on x86-64.
ok to commit?

diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..7e5b85c 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,33 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
  {
return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
  }
+
+#ifndef ENABLE_CHECKING
+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)

this should go to hwint.h, and without the masking of prec.
while ...

diff --git a/gcc/hwint.h b/gcc/hwint.h
index da62fad..9dddf05 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -276,4 +316,42 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT,
HOST_WIDE_INT);
  extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
  extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);

+/* Sign extend SRC starting from PREC.  */
+
+#ifdef ENABLE_CHECKING
+extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
+#else
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);

this should go to hwint.c (also without masking prec).

Richard.





kenny


On 04/02/2013 05:38 AM, Richard Biener wrote:

On Sun, Mar 31, 2013 at 7:51 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

richard,

I was able to add everything except for the checking asserts.While I
think that this is a reasonable idea, it is difficult to add that to a
function that is defined in hwint.h because of circular includes.   I
could
move this another file (though this appears to be the logical correct
place
for it), or we can do without the asserts.

The context is that [sz]ext_hwi is that are used are over the compiler
but
are generally written out long.   The wide-int class uses them also, but
wide-int did not see like the right place for them to live and i believe
that you suggested that i move them.

ok to commit, or do you have a suggested resolution to the assert issue?

Yes, do

#ifdef ENABLE_CHECKING
extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
#else
+/* Sign extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
  int shift = HOST_BITS_PER_WIDE_INT - prec;
+  return (src  shift)  shift;
+}
+}
#endif

and for ENABLE_CHECKING only provide an out-of-line implementation
in hwint.c.  That's how we did it with abs_hwi (well, we just do not
provide
an inline variant there - that's another possibility).

Note that hwint.h is always included after config.h so the ENABLE_CHECKING
definition should be available.

Richard.


kenny


On 03/27/2013 10:13 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the first of my wide int patches with joseph's comments and the
patch rot removed.

I would like to get these pre approved for the next stage 1.

+  int shift = HOST_BITS_PER_WIDE_INT - (prec 
(HOST_BITS_PER_WIDE_INT - 1));

I think this should gcc_checking_assert that prec is not out of range
(any reason why prec is signed int and not unsigned int?) rather than
ignore bits in prec.

+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}

likewise.  Also I'm not sure I agree about the signedness of the result
/
src.
zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

The patch misses context of uses, so I'm not sure what the above
functions
are intended to do.

Richard.


On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

On Fri, 5 Oct 2012, Kenneth Zadeck wrote:


+# define HOST_HALF_WIDE_INT_PRINT h

This may cause problems on hosts not supporting %hd (MinGW?), and
there's
no real need for using h here given the promotion of short to int;
you
can just use  (rather than e.g. needing special handling in
xm-mingw32.h
like is done for HOST_LONG_LONG_FORMAT).



diff --git a/gcc/hwint.c b/gcc/hwint.c
index 330b42c..92d54a3 100644
--- a/gcc/hwint.c
+++ b/gcc/hwint.c
@@ -204,3 +204,35 @@ least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b)
 {
   return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b));
 }
+
+#ifndef ENABLE_CHECKING
+/* Sign extend SRC starting from PREC.  */
+
+HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, unsigned int prec)
+{
+  gcc_checking_assert (prec = HOST_BITS_PER_WIDE_INT);
+
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
+  int shift = HOST_BITS_PER_WIDE_INT - prec;
+  return (src  shift)  shift;
+}
+}
+
+/* Zero extend SRC starting 

Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-03-31 Thread Kenneth Zadeck

richard,

I was able to add everything except for the checking asserts.While I 
think that this is a reasonable idea, it is difficult to add that to a 
function that is defined in hwint.h because of circular includes.   I 
could move this another file (though this appears to be the logical 
correct place for it), or we can do without the asserts.


The context is that [sz]ext_hwi is that are used are over the compiler 
but are generally written out long.   The wide-int class uses them also, 
but wide-int did not see like the right place for them to live and i 
believe that you suggested that i move them.


ok to commit, or do you have a suggested resolution to the assert issue?

kenny


On 03/27/2013 10:13 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the first of my wide int patches with joseph's comments and the
patch rot removed.

I would like to get these pre approved for the next stage 1.

+  int shift = HOST_BITS_PER_WIDE_INT - (prec 
(HOST_BITS_PER_WIDE_INT - 1));

I think this should gcc_checking_assert that prec is not out of range
(any reason why prec is signed int and not unsigned int?) rather than
ignore bits in prec.

+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}

likewise.  Also I'm not sure I agree about the signedness of the result / src.
zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

The patch misses context of uses, so I'm not sure what the above functions
are intended to do.

Richard.


On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

On Fri, 5 Oct 2012, Kenneth Zadeck wrote:


+# define HOST_HALF_WIDE_INT_PRINT h

This may cause problems on hosts not supporting %hd (MinGW?), and there's
no real need for using h here given the promotion of short to int; you
can just use  (rather than e.g. needing special handling in xm-mingw32.h
like is done for HOST_LONG_LONG_FORMAT).



diff --git a/gcc/hwint.h b/gcc/hwint.h
index da62fad..b086af0 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -76,6 +76,40 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
 # endif
 #endif
 
+/* Print support for half a host wide int.  */
+#define HOST_BITS_PER_HALF_WIDE_INT (HOST_BITS_PER_WIDE_INT / 2)
+#if HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_HALF_WIDE_INT long
+# define HOST_HALF_WIDE_INT_PRINT HOST_LONG_FORMAT
+# define HOST_HALF_WIDE_INT_PRINT_C L
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_HALF_WIDE_INT int
+# define HOST_HALF_WIDE_INT_PRINT 
+# define HOST_HALF_WIDE_INT_PRINT_C 
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_SHORT
+# define HOST_HALF_WIDE_INT short
+# define HOST_HALF_WIDE_INT_PRINT 
+# define HOST_HALF_WIDE_INT_PRINT_C 
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#else
+#error Please add support for HOST_HALF_WIDE_INT
+#endif
+
+
 #define HOST_WIDE_INT_1 HOST_WIDE_INT_C(1)
 
 /* This is a magic identifier which allows GCC to figure out the type
@@ -93,9 +127,13 @@ typedef HOST_WIDE_INT __gcc_host_wide_int__;
 # if HOST_BITS_PER_WIDE_INT == 64
 #  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
  0x% HOST_LONG_FORMAT x%016 HOST_LONG_FORMAT x
+#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
+ %016 HOST_LONG_FORMAT x
 # else
 #  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
  0x% HOST_LONG_FORMAT x%08 HOST_LONG_FORMAT x
+#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
+ %08 HOST_LONG_FORMAT x
 # endif
 #else
 # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
@@ -103,6 +141,8 @@ typedef HOST_WIDE_INT __gcc_host_wide_int__;
   /* We can assume that 'long long' is at least 64 bits.  */
 # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
 0x% HOST_LONG_LONG_FORMAT x%016 

Re: patch to fix constant math - third patch - what is left for next stage 1

2013-03-28 Thread Kenneth Zadeck

committed as revision 197198

kenny
On 03/27/2013 10:19 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:37 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

the original patch 3 was accepted and committed.   These were subsequent
comments.   This could likely be just checked in the next stage 1 without
approval.

Ok.

Thanks,
Richard.







Re: patch to fix constant math - second small patch -patch ping for next stage 1

2013-03-28 Thread Kenneth Zadeck

committed as revision 197200.

kenny


On 03/27/2013 11:07 AM, Richard Biener wrote:

On Wed, Mar 27, 2013 at 3:23 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 03/27/2013 10:18 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:27 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the second of my wide int patches with the patch rot removed.

I would like to get these pre approved for the next stage 1.
On 10/05/2012 06:48 PM, Kenneth Zadeck wrote:

This patch adds machinery to genmodes.c so that largest possible sizes
of
various data structures can be determined at gcc build time. These
functions
create 3 symbols that are available in insn-modes.h:
MAX_BITSIZE_MODE_INT - the bitsize of the largest int.
MAX_BITSIZE_MODE_PARTIAL_INT - the bitsize of the largest partial int.
MAX_BITSIZE_MODE_ANY_INT - the largest bitsize of any kind of int.

I remember we have discussed about the need to special-case/handle partial
integer modes.  Do further patches use the _INT and _PARTIAL_INT sizes
at all?  I'm fine with providing MAX_BITSIZE_MODE_ANY_INT.

i do not believe that in the end, those two ended up getting used.i can
remove them if you want.

Yes please.  Ok with that change.

Richard.


kenny


Richard.






Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-03-28 Thread Kenneth Zadeck

richard,

adding the gcc_checking_assert is going to require that i include 
system.h in hwint.h which seems to cause a loop.  while in principle, i 
agree with the assert, this is going to be a mess.


kenny


On 03/27/2013 10:13 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the first of my wide int patches with joseph's comments and the
patch rot removed.

I would like to get these pre approved for the next stage 1.

+  int shift = HOST_BITS_PER_WIDE_INT - (prec 
(HOST_BITS_PER_WIDE_INT - 1));

I think this should gcc_checking_assert that prec is not out of range
(any reason why prec is signed int and not unsigned int?) rather than
ignore bits in prec.

+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}

likewise.  Also I'm not sure I agree about the signedness of the result / src.
zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

The patch misses context of uses, so I'm not sure what the above functions
are intended to do.

Richard.


On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

On Fri, 5 Oct 2012, Kenneth Zadeck wrote:


+# define HOST_HALF_WIDE_INT_PRINT h

This may cause problems on hosts not supporting %hd (MinGW?), and there's
no real need for using h here given the promotion of short to int; you
can just use  (rather than e.g. needing special handling in xm-mingw32.h
like is done for HOST_LONG_LONG_FORMAT).





Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-03-27 Thread Richard Biener
On Wed, Feb 27, 2013 at 1:22 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 Here is the first of my wide int patches with joseph's comments and the
 patch rot removed.

 I would like to get these pre approved for the next stage 1.

+  int shift = HOST_BITS_PER_WIDE_INT - (prec 
(HOST_BITS_PER_WIDE_INT - 1));

I think this should gcc_checking_assert that prec is not out of range
(any reason why prec is signed int and not unsigned int?) rather than
ignore bits in prec.

+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+   (prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}

likewise.  Also I'm not sure I agree about the signedness of the result / src.
zext_hwi (-1, HOST_BITS_PER_WIDE_INT)  0 is true which is odd.

The patch misses context of uses, so I'm not sure what the above functions
are intended to do.

Richard.

 On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

 On Fri, 5 Oct 2012, Kenneth Zadeck wrote:

 +# define HOST_HALF_WIDE_INT_PRINT h

 This may cause problems on hosts not supporting %hd (MinGW?), and there's
 no real need for using h here given the promotion of short to int; you
 can just use  (rather than e.g. needing special handling in xm-mingw32.h
 like is done for HOST_LONG_LONG_FORMAT).




Re: patch to fix constant math - second small patch -patch ping for next stage 1

2013-03-27 Thread Richard Biener
On Wed, Feb 27, 2013 at 1:27 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 Here is the second of my wide int patches with the patch rot removed.

 I would like to get these pre approved for the next stage 1.
 On 10/05/2012 06:48 PM, Kenneth Zadeck wrote:

 This patch adds machinery to genmodes.c so that largest possible sizes of
 various data structures can be determined at gcc build time. These functions
 create 3 symbols that are available in insn-modes.h:
 MAX_BITSIZE_MODE_INT - the bitsize of the largest int.
 MAX_BITSIZE_MODE_PARTIAL_INT - the bitsize of the largest partial int.
 MAX_BITSIZE_MODE_ANY_INT - the largest bitsize of any kind of int.

I remember we have discussed about the need to special-case/handle partial
integer modes.  Do further patches use the _INT and _PARTIAL_INT sizes
at all?  I'm fine with providing MAX_BITSIZE_MODE_ANY_INT.

Richard.


Re: patch to fix constant math - third patch - what is left for next stage 1

2013-03-27 Thread Richard Biener
On Wed, Feb 27, 2013 at 1:37 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 the original patch 3 was accepted and committed.   These were subsequent
 comments.   This could likely be just checked in the next stage 1 without
 approval.

Ok.

Thanks,
Richard.





Re: patch to fix constant math - second small patch -patch ping for next stage 1

2013-03-27 Thread Kenneth Zadeck


On 03/27/2013 10:18 AM, Richard Biener wrote:

On Wed, Feb 27, 2013 at 1:27 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

Here is the second of my wide int patches with the patch rot removed.

I would like to get these pre approved for the next stage 1.
On 10/05/2012 06:48 PM, Kenneth Zadeck wrote:

This patch adds machinery to genmodes.c so that largest possible sizes of
various data structures can be determined at gcc build time. These functions
create 3 symbols that are available in insn-modes.h:
MAX_BITSIZE_MODE_INT - the bitsize of the largest int.
MAX_BITSIZE_MODE_PARTIAL_INT - the bitsize of the largest partial int.
MAX_BITSIZE_MODE_ANY_INT - the largest bitsize of any kind of int.

I remember we have discussed about the need to special-case/handle partial
integer modes.  Do further patches use the _INT and _PARTIAL_INT sizes
at all?  I'm fine with providing MAX_BITSIZE_MODE_ANY_INT.
i do not believe that in the end, those two ended up getting used.i 
can remove them if you want.


kenny


Richard.




Re: patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1

2013-03-27 Thread Richard Biener
On Wed, Feb 27, 2013 at 2:59 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:
 This patch contains a large number of the changes requested by Richi.   It
 does not contain any of the changes that he requested to abstract the
 storage layer.   That suggestion appears to be quite unworkable.

 I believe that the wide-int class addresses the needs of gcc for performing
 math on any size integer irregardless of the platform that hosts the
 compiler.  The interface is admittedly large, but it is large for a reason:
 these are the operations that are commonly performed by the client
 optimizations in the compiler.

 I would like to get this patch preapproved for the next stage 1.

Please clean from dead code like

+// using wide_int::;

and

+#ifdef DEBUG_WIDE_INT
+  if (dump_file)
+debug_wh (wide_int::from_shwi %s  HOST_WIDE_INT_PRINT_HEX )\n,
+ result, op0);
+#endif

and

+#ifdef NEW_REP_FOR_INT_CST
+  /* This is the code once the tree level is converted.  */
+  wide_int result;
+  int i;
+
+  tree type = TREE_TYPE (tcst);
+
+  result.bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
+  result.precision = TYPE_PRECISION (type);
+  result.len = TREE_INT_CST_LEN (tcst);
+  for (i = 0; i  result.len; i++)
+result.val[i] = TREE_INT_CST_ELT (tcst, i);
+
+  return result;
+#else

this also shows the main reason I was asking for storage abstraction.
The initialization from tree is way too expensive.

+/* Convert a integer cst into a wide int expanded to BITSIZE and
+   PRECISION.  This call is used by tree passes like vrp that expect
+   that the math is done in an infinite precision style.  BITSIZE and
+   PRECISION are generally determined to be twice the largest type
+   seen in the function.  */
+
+wide_int
+wide_int::from_tree_as_infinite_precision (const_tree tcst,
+  unsigned int bitsize,
+  unsigned int precision)
+{

I know you have converted everything, but to make this patch reviewable
I'd like you to strip the initial wide_int down to a bare minimum.

Only then people will have a reasonable chance to play with interface
changes (such as providing a storage abstraction).

+/* Check the upper HOST_WIDE_INTs of src to see if the length can be
+   shortened.  An upper HOST_WIDE_INT is unnecessary if it is all ones
+   or zeros and the top bit of the next lower word matches.
+
+   This function may change the representation of THIS, but does not
+   change the value that THIS represents.  It does not sign extend in
+   the case that the size of the mode is less than
+   HOST_BITS_PER_WIDE_INT.  */
+
+void
+wide_int::canonize ()

this shouldn't be necessary - it's an optimization - and due to value
semantics (yes - I know you have a weird mix of value semantics
and modify-in-place in wide_int) the new length should be computed
transparently when creating a new value.

Well.  Leaving wide-int.c for now.

+class wide_int {
+  /* Internal representation.  */
+
+  /* VAL is set to a size that is capable of computing a full
+ multiplication on the largest mode that is represented on the
+ target.  The full multiplication is use by tree-vrp.  tree-vpn
+ currently does a 2x largest mode by 2x largest mode yielding a 4x
+ largest mode result.  If operations are added that require larger
+ buffers, then VAL needs to be changed.  */
+  HOST_WIDE_INT val[4 * MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT];

as you conver partial int modes in MAX_BITSIZE_MODE_ANY_INT the
above may come too short.  Please properly round up.

+  unsigned short len;
+  unsigned int bitsize;
+  unsigned int precision;

I see we didn't get away with this mix of bitsize and precision.  I'm probably
going to try revisit the past discussions - but can you point me to a single
place in the RTL conversion where they make a difference?  Bits beyond
precision are either undefined or properly zero-/sign-extended.  Implicit
extension beyond len val members should then provide in valid bits
up to bitsize (if anyone cares).  That's how double-ints work on tree
INTGER_CSTs
which only care for precision, even with partial integer mode types
(ok, I never came along one of these beasts - testcase / target?).

[abstraction possibility - have both wide_ints with actual mode and
wide_ints with arbitrary bitsize/precision]

+  enum ShiftOp {
+NONE,
+/* There are two uses for the wide-int shifting functions.  The
+   first use is as an emulation of the target hardware.  The
+   second use is as service routines for other optimizations.  The
+   first case needs to be identified by passing TRUNC as the value
+   of ShiftOp so that shift amount is properly handled according to the
+   SHIFT_COUNT_TRUNCATED flag.  For the second case, the shift
+   amount is always truncated by the bytesize of the mode of
+   THIS.  */
+TRUNC
+  };

I think I have expressed my opinion on this.  (and SHIFT_COUNT_TRUNCATED

Re: patch to fix constant math - second small patch -patch ping for next stage 1

2013-03-27 Thread Richard Biener
On Wed, Mar 27, 2013 at 3:23 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

 On 03/27/2013 10:18 AM, Richard Biener wrote:

 On Wed, Feb 27, 2013 at 1:27 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 Here is the second of my wide int patches with the patch rot removed.

 I would like to get these pre approved for the next stage 1.
 On 10/05/2012 06:48 PM, Kenneth Zadeck wrote:

 This patch adds machinery to genmodes.c so that largest possible sizes
 of
 various data structures can be determined at gcc build time. These
 functions
 create 3 symbols that are available in insn-modes.h:
 MAX_BITSIZE_MODE_INT - the bitsize of the largest int.
 MAX_BITSIZE_MODE_PARTIAL_INT - the bitsize of the largest partial int.
 MAX_BITSIZE_MODE_ANY_INT - the largest bitsize of any kind of int.

 I remember we have discussed about the need to special-case/handle partial
 integer modes.  Do further patches use the _INT and _PARTIAL_INT sizes
 at all?  I'm fine with providing MAX_BITSIZE_MODE_ANY_INT.

 i do not believe that in the end, those two ended up getting used.i can
 remove them if you want.

Yes please.  Ok with that change.

Richard.

 kenny


 Richard.




Re: patch to fix constant math - first small patch - patch ping for the next stage 1

2013-02-26 Thread Kenneth Zadeck
Here is the first of my wide int patches with joseph's comments and the 
patch rot removed.


I would like to get these pre approved for the next stage 1.
On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

On Fri, 5 Oct 2012, Kenneth Zadeck wrote:


+# define HOST_HALF_WIDE_INT_PRINT h

This may cause problems on hosts not supporting %hd (MinGW?), and there's
no real need for using h here given the promotion of short to int; you
can just use  (rather than e.g. needing special handling in xm-mingw32.h
like is done for HOST_LONG_LONG_FORMAT).



2013-2-26  Kenneth Zadeck zad...@naturalbridge.com

* hwint.h (HOST_BITS_PER_HALF_WIDE_INT, HOST_HALF_WIDE_INT,
HOST_HALF_WIDE_INT_PRINT, HOST_HALF_WIDE_INT_PRINT_C,
HOST_HALF_WIDE_INT_PRINT_DEC, HOST_HALF_WIDE_INT_PRINT_DEC_C,
HOST_HALF_WIDE_INT_PRINT_UNSIGNED, HOST_HALF_WIDE_INT_PRINT_HEX,
HOST_HALF_WIDE_INT_PRINT_HEX_PURE): New symbols.
(sext_hwi, zext_hwi): New functions.

diff --git a/gcc/hwint.h b/gcc/hwint.h
index da62fad..aaa66ed 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -76,6 +76,40 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
 # endif
 #endif
 
+/* Print support for half a host wide int.  */
+#define HOST_BITS_PER_HALF_WIDE_INT (HOST_BITS_PER_WIDE_INT / 2)
+#if HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_HALF_WIDE_INT long
+# define HOST_HALF_WIDE_INT_PRINT HOST_LONG_FORMAT
+# define HOST_HALF_WIDE_INT_PRINT_C L
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_HALF_WIDE_INT int
+# define HOST_HALF_WIDE_INT_PRINT 
+# define HOST_HALF_WIDE_INT_PRINT_C 
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_SHORT
+# define HOST_HALF_WIDE_INT short
+# define HOST_HALF_WIDE_INT_PRINT 
+# define HOST_HALF_WIDE_INT_PRINT_C 
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#else
+#error Please add support for HOST_HALF_WIDE_INT
+#endif
+
+
 #define HOST_WIDE_INT_1 HOST_WIDE_INT_C(1)
 
 /* This is a magic identifier which allows GCC to figure out the type
@@ -93,9 +127,13 @@ typedef HOST_WIDE_INT __gcc_host_wide_int__;
 # if HOST_BITS_PER_WIDE_INT == 64
 #  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
  0x% HOST_LONG_FORMAT x%016 HOST_LONG_FORMAT x
+#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
+ %016 HOST_LONG_FORMAT x
 # else
 #  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
  0x% HOST_LONG_FORMAT x%08 HOST_LONG_FORMAT x
+#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
+ %08 HOST_LONG_FORMAT x
 # endif
 #else
 # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
@@ -103,6 +141,8 @@ typedef HOST_WIDE_INT __gcc_host_wide_int__;
   /* We can assume that 'long long' is at least 64 bits.  */
 # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
 0x% HOST_LONG_LONG_FORMAT x%016 HOST_LONG_LONG_FORMAT x
+# define HOST_WIDE_INT_PRINT_PADDED_HEX \
+%016 HOST_LONG_LONG_FORMAT x
 #endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
 
 #define HOST_WIDE_INT_PRINT_DEC % HOST_WIDE_INT_PRINT d
@@ -276,4 +316,32 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
 
+/* Sign extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
+  int shift = HOST_BITS_PER_WIDE_INT - (prec  (HOST_BITS_PER_WIDE_INT - 1));
+  return (src  shift)  shift;
+}
+}
+
+/* Zero extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+		(prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}
+
+
+
 #endif /* ! GCC_HWINT_H */


Re: patch to fix constant math - second small patch -patch ping for next stage 1

2013-02-26 Thread Kenneth Zadeck

Here is the second of my wide int patches with the patch rot removed.

I would like to get these pre approved for the next stage 1.
On 10/05/2012 06:48 PM, Kenneth Zadeck wrote:
This patch adds machinery to genmodes.c so that largest possible sizes 
of various data structures can be determined at gcc build time. These 
functions create 3 symbols that are available in insn-modes.h:

MAX_BITSIZE_MODE_INT - the bitsize of the largest int.
MAX_BITSIZE_MODE_PARTIAL_INT - the bitsize of the largest partial int.
MAX_BITSIZE_MODE_ANY_INT - the largest bitsize of any kind of int.


2013-2-26  Kenneth Zadeck zad...@naturalbridge.com

* genmodes.c (emit_max_int): New function.
(emit_insn_modes_h): Added call to emit_max_function.
* doc/rtl.texi (MAX_BITSIZE_MODE_INT, MAX_BITSIZE_MODE_PARTIAL_INT,
MAX_BITSIZE_MODE_ANY_INT, MAX_BITSIZE_MODE_ANY_MODE): Added doc.
* machmode.def: Fixed comment.
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index b0b0723..095a642 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1456,6 +1456,28 @@ Returns the number of units contained in a mode, i.e.,
 Returns the narrowest mode in mode class @var{c}.
 @end table
 
+The following 4 variables are defined on every target.   They can be
+used to allocate buffers that are guaranteed to be large enough to
+hold any value that can be represented on the target.   
+
+@table @code
+@findex MAX_BITSIZE_MODE_INT
+@item MAX_BITSIZE_MODE_INT
+The bitsize of the largest integer mode defined on the target.
+
+@findex MAX_BITSIZE_MODE_PARTIAL_INT
+@item MAX_BITSIZE_MODE_PARTIAL_INT
+The bitsize of the largest partial integer mode defined on the target.
+
+@findex MAX_BITSIZE_MODE_ANY_INT
+@item MAX_BITSIZE_MODE_ANY_INT
+The maximum of MAX_BITSIZE_MODE_INT and MAX_BITSIZE_MODE_PARTIAL_INT.
+
+@findex MAX_BITSIZE_MODE_ANY_MODE
+@item MAX_BITSIZE_MODE_ANY_MODE
+The bitsize of the largest mode on the target.   
+@end table
+
 @findex byte_mode
 @findex word_mode
 The global variables @code{byte_mode} and @code{word_mode} contain modes
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index 9907d69..f822dcd 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -848,6 +848,38 @@ calc_wider_mode (void)
 
 #define print_closer() puts (};)
 
+/* Compute the max bitsize of some of the classes of integers.  It may
+   be that there are needs for the other integer classes, and this
+   code is easy to extend.  */
+static void
+emit_max_int (void)
+{
+  unsigned int max, mmax;
+  struct mode_data *i;
+  int j;
+
+  puts ();
+  for (max = 1, i = modes[MODE_INT]; i; i = i-next)
+if (max  i-bytesize)
+	max = i-bytesize;
+  printf (#define MAX_BITSIZE_MODE_INT %d*BITS_PER_UNIT\n, max);
+  mmax = max;
+  for (max = 1, i = modes[MODE_PARTIAL_INT]; i; i = i-next)
+if (max  i-bytesize)
+	max = i-bytesize;
+  printf (#define MAX_BITSIZE_MODE_PARTIAL_INT %d*BITS_PER_UNIT\n, max);
+  if (max  mmax)
+mmax = max;
+  printf (#define MAX_BITSIZE_MODE_ANY_INT %d*BITS_PER_UNIT\n, mmax);
+
+  mmax = 0;
+  for (j = 0; j  MAX_MODE_CLASS; j++)
+for (i = modes[j]; i; i = i-next)
+  if (mmax  i-bytesize)
+	mmax = i-bytesize;
+  printf (#define MAX_BITSIZE_MODE_ANY_MODE %d*BITS_PER_UNIT\n, mmax);
+}
+
 static void
 emit_insn_modes_h (void)
 {
@@ -912,6 +944,7 @@ enum machine_mode\n{);
 #endif
   printf (#define CONST_MODE_IBIT%s\n, adj_ibit ?  :  const);
   printf (#define CONST_MODE_FBIT%s\n, adj_fbit ?  :  const);
+  emit_max_int ();
   puts (\
 \n\
 #endif /* insn-modes.h */);
diff --git a/gcc/machmode.def b/gcc/machmode.def
index 4b58150..1062f18 100644
--- a/gcc/machmode.def
+++ b/gcc/machmode.def
@@ -179,8 +179,11 @@ RANDOM_MODE (BLK);
 FRACTIONAL_INT_MODE (BI, 1, 1);
 
 /* Basic integer modes.  We go up to TI in generic code (128 bits).
-   The name OI is reserved for a 256-bit type (needed by some back ends).
-   FIXME TI shouldn't be generically available either.  */
+   TImode is needed here because the some front ends now genericly
+   support __int128.  If the front ends decide to generically support
+   larger types, then corresponding modes must be added here.  The
+   name OI is reserved for a 256-bit type (needed by some back ends).
+*/
 INT_MODE (QI, 1);
 INT_MODE (HI, 2);
 INT_MODE (SI, 4);


Re: patch to fix constant math - second small patch

2012-11-26 Thread Richard Biener
On Thu, Nov 8, 2012 at 7:13 PM, Kenneth Zadeck zad...@naturalbridge.com wrote:
 I have added the proper doc.  OK to commit?

Ok.

Thanks,
Richard.

 Kenny



 On 10/08/2012 05:06 AM, Richard Guenther wrote:

 On Sat, Oct 6, 2012 at 12:48 AM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 This patch adds machinery to genmodes.c so that largest possible sizes of
 various data structures can be determined at gcc build time.  These
 functions create 3 symbols that are available in insn-modes.h:
 MAX_BITSIZE_MODE_INT - the bitsize of the largest int.
 MAX_BITSIZE_MODE_PARTIAL_INT - the bitsize of the largest partial int.
 MAX_BITSIZE_MODE_ANY_INT - the largest bitsize of any kind of int.

 Ok.  Please document these macros in rtl.texi.

 Richard.




Re: patch to fix constant math - third small patch

2012-11-09 Thread Kenneth Zadeck
This patch is an updated version of my patch 3 with all of richard 
sandiford's comments resolved.


Richi had approved it before he went on vacation.

Committed as revision 193360.

Kenny


On 10/08/2012 03:42 PM, Richard Sandiford wrote:

Kenneth Zadeck zad...@naturalbridge.com writes:

diff --git a/gcc/combine.c b/gcc/combine.c
index 4e0a579..b531305 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2617,16 +2617,19 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int 
*new_direct_jump_p,
   constant.  */
if (i1 == 0
 (temp = single_set (i2)) != 0
-   (CONST_INT_P (SET_SRC (temp))
- || CONST_DOUBLE_AS_INT_P (SET_SRC (temp)))
+   CONST_SCALAR_INT_P (SET_SRC (temp))
 GET_CODE (PATTERN (i3)) == SET
-   (CONST_INT_P (SET_SRC (PATTERN (i3)))
- || CONST_DOUBLE_AS_INT_P (SET_SRC (PATTERN (i3
+   CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3)))
 reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp)))
  {
rtx dest = SET_DEST (PATTERN (i3));
int offset = -1;
int width = 0;
+
+  /* There are not explicit tests to make sure that this is not a
+float, but there is code here that would not be correct if it
+was.  */
+  gcc_assert (GET_MODE_CLASS (GET_MODE (SET_SRC (temp))) != MODE_FLOAT);

No need for this assert: CONST_SCALAR_INT_P (SET_SRC (temp)) should cover it.


@@ -1009,9 +1007,7 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, enum machine_mode 
memmode)
  static rtx
  wrap_constant (enum machine_mode mode, rtx x)
  {
-  if (!CONST_INT_P (x)
-   GET_CODE (x) != CONST_FIXED
-   !CONST_DOUBLE_AS_INT_P (x))
+  if ((!CONST_SCALAR_INT_P (x))  GET_CODE (x) != CONST_FIXED)

Redundant brackets.

Looks good to me otherwise, thanks.

Richard


2012-11-09  Kenneth Zadeck zad...@naturalbridge.com

* rtl.h (CONST_SCALAR_INT_P): New macro.
* cfgexpand.c (expand_debug_locations): Changed to use
CONST_SCALAR_INT_P macro.
* combine.c (try_combine, subst, make_extraction,
gen_lowpart_for_combine): Ditto.
* cselib.c (entry_and_rtx_equal_p, rtx_equal_for_cselib_1): Ditto.
* dwarf2out.c (loc_descriptor): Ditto.
* emit-rtl.c (gen_lowpart_common): Ditto.
* ira-costs.c (record_reg_classes, record_address_regs): Ditto.
* ira-lives.c (single_reg_class): Ditto.
* recog.c (simplify_while_replacing, asm_operand_ok,
constrain_operands): Ditto.
* reload.c (find_reloads): Ditto.
* simplify-rtx.c (simplify_unary_operation_1,
simplify_const_unary_operation, simplify_binary_operation_1,
simplify_const_binary_operation, simplify_relational_operation_1,
simplify_subreg): Ditto.

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index e501b4b..0bd9d1d 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3647,9 +3647,8 @@ expand_debug_locations (void)
 
 	gcc_assert (mode == GET_MODE (val)
 			|| (GET_MODE (val) == VOIDmode
-			 (CONST_INT_P (val)
+			 (CONST_SCALAR_INT_P (val)
 || GET_CODE (val) == CONST_FIXED
-|| CONST_DOUBLE_AS_INT_P (val) 
 || GET_CODE (val) == LABEL_REF)));
 	  }
 
diff --git a/gcc/combine.c b/gcc/combine.c
index 00719a7..5e85f77 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2619,17 +2619,15 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p,
  constant.  */
   if (i1 == 0
(temp = single_set (i2)) != 0
-   (CONST_INT_P (SET_SRC (temp))
-	  || CONST_DOUBLE_AS_INT_P (SET_SRC (temp)))
+   CONST_SCALAR_INT_P (SET_SRC (temp))
GET_CODE (PATTERN (i3)) == SET
-   (CONST_INT_P (SET_SRC (PATTERN (i3)))
-	  || CONST_DOUBLE_AS_INT_P (SET_SRC (PATTERN (i3
+   CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3)))
reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp)))
 {
   rtx dest = SET_DEST (PATTERN (i3));
   int offset = -1;
   int width = 0;
-
+  
   if (GET_CODE (dest) == ZERO_EXTRACT)
 	{
 	  if (CONST_INT_P (XEXP (dest, 1))
@@ -5104,8 +5102,7 @@ subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy)
 	  if (GET_CODE (new_rtx) == CLOBBER  XEXP (new_rtx, 0) == const0_rtx)
 		return new_rtx;
 
-	  if (GET_CODE (x) == SUBREG
-		   (CONST_INT_P (new_rtx) || CONST_DOUBLE_AS_INT_P (new_rtx)))
+	  if (GET_CODE (x) == SUBREG  CONST_SCALAR_INT_P (new_rtx))
 		{
 		  enum machine_mode mode = GET_MODE (x);
 
@@ -7134,7 +7131,7 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
   if (mode == tmode)
 	return new_rtx;
 
-  if (CONST_INT_P (new_rtx) || CONST_DOUBLE_AS_INT_P (new_rtx))
+  if (CONST_SCALAR_INT_P (new_rtx))
 	return simplify_unary_operation (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
 	 mode, new_rtx, tmode);
 
@@ -10658,8 +10655,7 @@ gen_lowpart_for_combine (enum machine_mode omode, rtx x)
   /* We can only support MODE being wider than a word if X is a
  constant integer or has a mode the same size.  

Re: patch to fix constant math - first small patch

2012-11-08 Thread Kenneth Zadeck

Joseph,

Here is a revised patch with the change you asked for.  There have been 
no other comments.   May I commit it?


Kenny


On 10/05/2012 08:14 PM, Joseph S. Myers wrote:

On Fri, 5 Oct 2012, Kenneth Zadeck wrote:


+# define HOST_HALF_WIDE_INT_PRINT h

This may cause problems on hosts not supporting %hd (MinGW?), and there's
no real need for using h here given the promotion of short to int; you
can just use  (rather than e.g. needing special handling in xm-mingw32.h
like is done for HOST_LONG_LONG_FORMAT).



diff --git a/gcc/hwint.h b/gcc/hwint.h
index ca47148..87371b5 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -77,6 +77,40 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
 # endif
 #endif
 
+/* Print support for half a host wide int.  */
+#define HOST_BITS_PER_HALF_WIDE_INT (HOST_BITS_PER_WIDE_INT / 2)
+#if HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_HALF_WIDE_INT long
+# define HOST_HALF_WIDE_INT_PRINT HOST_LONG_FORMAT
+# define HOST_HALF_WIDE_INT_PRINT_C L
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_INT
+# define HOST_HALF_WIDE_INT int
+# define HOST_HALF_WIDE_INT_PRINT 
+# define HOST_HALF_WIDE_INT_PRINT_C 
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_SHORT
+# define HOST_HALF_WIDE_INT short
+# define HOST_HALF_WIDE_INT_PRINT 
+# define HOST_HALF_WIDE_INT_PRINT_C 
+# define HOST_HALF_WIDE_INT_PRINT_DEC % HOST_HALF_WIDE_INT_PRINT d
+# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
+# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED % HOST_HALF_WIDE_INT_PRINT u
+# define HOST_HALF_WIDE_INT_PRINT_HEX %# HOST_HALF_WIDE_INT_PRINT x
+# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE % HOST_HALF_WIDE_INT_PRINT x
+#else
+#error Please add support for HOST_HALF_WIDE_INT
+#endif
+
+
 #define HOST_WIDE_INT_1 HOST_WIDE_INT_C(1)
 
 /* This is a magic identifier which allows GCC to figure out the type
@@ -94,9 +128,13 @@ typedef HOST_WIDE_INT __gcc_host_wide_int__;
 # if HOST_BITS_PER_WIDE_INT == 64
 #  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
  0x% HOST_LONG_FORMAT x%016 HOST_LONG_FORMAT x
+#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
+ %016 HOST_LONG_FORMAT x
 # else
 #  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
  0x% HOST_LONG_FORMAT x%08 HOST_LONG_FORMAT x
+#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
+ %08 HOST_LONG_FORMAT x
 # endif
 #else
 # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
@@ -104,6 +142,8 @@ typedef HOST_WIDE_INT __gcc_host_wide_int__;
   /* We can assume that 'long long' is at least 64 bits.  */
 # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
 0x% HOST_LONG_LONG_FORMAT x%016 HOST_LONG_LONG_FORMAT x
+# define HOST_WIDE_INT_PRINT_PADDED_HEX \
+%016 HOST_LONG_LONG_FORMAT x
 #endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
 
 #define HOST_WIDE_INT_PRINT_DEC % HOST_WIDE_INT_PRINT d
@@ -277,4 +317,32 @@ extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
 extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
 
+/* Sign extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+sext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+{
+  int shift = HOST_BITS_PER_WIDE_INT - (prec  (HOST_BITS_PER_WIDE_INT - 1));
+  return (src  shift)  shift;
+}
+}
+
+/* Zero extend SRC starting from PREC.  */
+
+static inline HOST_WIDE_INT
+zext_hwi (HOST_WIDE_INT src, int prec)
+{
+  if (prec == HOST_BITS_PER_WIDE_INT)
+return src;
+  else
+return src  (((HOST_WIDE_INT)1
+		(prec  (HOST_BITS_PER_WIDE_INT - 1))) - 1);
+}
+
+
+
 #endif /* ! GCC_HWINT_H */
2012-10-5  Kenneth Zadeck zad...@naturalbridge.com

* hwint.h (HOST_BITS_PER_HALF_WIDE_INT, HOST_HALF_WIDE_INT,
HOST_HALF_WIDE_INT_PRINT, HOST_HALF_WIDE_INT_PRINT_C,
HOST_HALF_WIDE_INT_PRINT_DEC, HOST_HALF_WIDE_INT_PRINT_DEC_C,
HOST_HALF_WIDE_INT_PRINT_UNSIGNED, HOST_HALF_WIDE_INT_PRINT_HEX,
HOST_HALF_WIDE_INT_PRINT_HEX_PURE): New symbols.
(sext_hwi, zext_hwi): New functions.



Re: patch to fix constant math - second small patch

2012-11-08 Thread Kenneth Zadeck

I have added the proper doc.  OK to commit?

Kenny


On 10/08/2012 05:06 AM, Richard Guenther wrote:

On Sat, Oct 6, 2012 at 12:48 AM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

This patch adds machinery to genmodes.c so that largest possible sizes of
various data structures can be determined at gcc build time.  These
functions create 3 symbols that are available in insn-modes.h:
MAX_BITSIZE_MODE_INT - the bitsize of the largest int.
MAX_BITSIZE_MODE_PARTIAL_INT - the bitsize of the largest partial int.
MAX_BITSIZE_MODE_ANY_INT - the largest bitsize of any kind of int.

Ok.  Please document these macros in rtl.texi.

Richard.


2012-11-8  Kenneth Zadeck zad...@naturalbridge.com

* genmodes.c (emit_max_int): New function.
(emit_insn_modes_h): Added call to emit_max_function.
* doc/rtl.texi (MAX_BITSIZE_MODE_INT, MAX_BITSIZE_MODE_PARTIAL_INT,
MAX_BITSIZE_MODE_ANY_INT, MAX_BITSIZE_MODE_ANY_MODE): Added doc.
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 07c480d..6842cb8 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1458,6 +1458,28 @@ Returns the number of units contained in a mode, i.e.,
 Returns the narrowest mode in mode class @var{c}.
 @end table
 
+The following 4 variables are defined on every target.   They can be
+used to allocate buffers that are guaranteed to be large enough to
+hold any value that can be represented on the target.   
+
+@table @code
+@findex MAX_BITSIZE_MODE_INT
+@item MAX_BITSIZE_MODE_INT
+The bitsize of the largest integer mode defined on the target.
+
+@findex MAX_BITSIZE_MODE_PARTIAL_INT
+@item MAX_BITSIZE_MODE_PARTIAL_INT
+The bitsize of the largest partial integer mode defined on the target.
+
+@findex MAX_BITSIZE_MODE_ANY_INT
+@item MAX_BITSIZE_MODE_ANY_INT
+The maximum of MAX_BITSIZE_MODE_INT and MAX_BITSIZE_MODE_PARTIAL_INT.
+
+@findex MAX_BITSIZE_MODE_ANY_MODE
+@item MAX_BITSIZE_MODE_ANY_MODE
+The bitsize of the largest mode on the target.   
+@end table
+
 @findex byte_mode
 @findex word_mode
 The global variables @code{byte_mode} and @code{word_mode} contain modes
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index d0095c3..3e63cc7 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -849,6 +849,38 @@ calc_wider_mode (void)
 
 #define print_closer() puts (};)
 
+/* Compute the max bitsize of some of the classes of integers.  It may
+   be that there are needs for the other integer classes, and this
+   code is easy to extend.  */
+static void
+emit_max_int (void)
+{
+  unsigned int max, mmax;
+  struct mode_data *i;
+  int j;
+
+  puts ();
+  for (max = 1, i = modes[MODE_INT]; i; i = i-next)
+if (max  i-bytesize)
+	max = i-bytesize;
+  printf (#define MAX_BITSIZE_MODE_INT %d*BITS_PER_UNIT\n, max);
+  mmax = max;
+  for (max = 1, i = modes[MODE_PARTIAL_INT]; i; i = i-next)
+if (max  i-bytesize)
+	max = i-bytesize;
+  printf (#define MAX_BITSIZE_MODE_PARTIAL_INT %d*BITS_PER_UNIT\n, max);
+  if (max  mmax)
+mmax = max;
+  printf (#define MAX_BITSIZE_MODE_ANY_INT %d*BITS_PER_UNIT\n, mmax);
+
+  mmax = 0;
+  for (j = 0; j  MAX_MODE_CLASS; j++)
+for (i = modes[j]; i; i = i-next)
+  if (mmax  i-bytesize)
+	mmax = i-bytesize;
+  printf (#define MAX_BITSIZE_MODE_ANY_MODE %d*BITS_PER_UNIT\n, mmax);
+}
+
 static void
 emit_insn_modes_h (void)
 {
@@ -913,6 +945,7 @@ enum machine_mode\n{);
 #endif
   printf (#define CONST_MODE_IBIT%s\n, adj_ibit ?  :  const);
   printf (#define CONST_MODE_FBIT%s\n, adj_fbit ?  :  const);
+  emit_max_int ();
   puts (\
 \n\
 #endif /* insn-modes.h */);
diff --git a/gcc/machmode.def b/gcc/machmode.def
index 631015f..7186cb4 100644
--- a/gcc/machmode.def
+++ b/gcc/machmode.def
@@ -180,8 +180,11 @@ RANDOM_MODE (BLK);
 FRACTIONAL_INT_MODE (BI, 1, 1);
 
 /* Basic integer modes.  We go up to TI in generic code (128 bits).
-   The name OI is reserved for a 256-bit type (needed by some back ends).
-   FIXME TI shouldn't be generically available either.  */
+   TImode is needed here because the some front ends now genericly
+   support __int128.  If the front ends decide to generically support
+   larger types, then corresponding modes must be added here.  The
+   name OI is reserved for a 256-bit type (needed by some back ends).
+*/
 INT_MODE (QI, 1);
 INT_MODE (HI, 2);
 INT_MODE (SI, 4);


Re: patch to fix constant math - 8th patch - tree-vrp.c

2012-11-01 Thread Marc Glisse

On Thu, 1 Nov 2012, Kenneth Zadeck wrote:

This patch converts tree-vpn to use wide-int.   In doing so it gets rid of 
all restrictions that this pass currently has on the target or source word 
size.


The pass's reliance on a finite infinite precision representation has been 
preserved.  It first scans the function being compiled to determine the 
largest type that needs to be represented within that function and then it 
uses some multiple of that size as it's definition of infinite.


I am currently using 4 for this value.   However marc glisse claims that this 
may be due to a bug and that the value should be 2. This is something that 
has to be investigated further.   This could easily be my mistake or some 
other issue that has crept into the pass.  The value of 2 or 4 is easily 
changed in largest_initialize.The only truly non mechanical 
transformation is in the code that multiplies two ranges.   This code uses 
the wide-int multiply full functions rather than using pairs of double-ints.


(I didn't look at the patch (yet))

Er, no, I didn't claim that using 4 was wrong, I think it is good because 
it makes things easier. I only claimed that the current implementation 
jumps through enough hoops to make do with 2.


--
Marc Glisse


Re: patch to fix constant math - 4th patch - wide-int.[ch] refresh

2012-11-01 Thread Kenneth Zadeck
This patch refreshes wide-int.[ch].   Most of the changes are bug fixes 
that were fixed for tree-vrp.c in patch 8.


There are two significant differences:

1) There are now constructors to override the precision and bitsize that 
are normally taken from the type.  These are used to perform the finite 
infinite precision that is required by the tree-vrp.c pass.   The 
bitsize and precision passed in are the ones necessary to compile the 
current function.


2) The signed and unsigned extension functions have changed a lot. The 
ones with the name ext do an extension but the result always has the 
bitsize and precision of this.  the functions that are named 
force_to_size, now return results based on the precision and bitsize 
passed in after doing the proper extension.


The second change is in line with comments made by richi and others.

kenny




Re: patch to fix constant math - 8th patch - tree-vrp.c

2012-11-01 Thread Kenneth Zadeck

either way, this needs to be investigated.  it could just be my bad.
On 11/01/2012 06:28 PM, Marc Glisse wrote:

On Thu, 1 Nov 2012, Kenneth Zadeck wrote:

This patch converts tree-vpn to use wide-int.   In doing so it gets 
rid of all restrictions that this pass currently has on the target or 
source word size.


The pass's reliance on a finite infinite precision representation 
has been preserved.  It first scans the function being compiled to 
determine the largest type that needs to be represented within that 
function and then it uses some multiple of that size as it's 
definition of infinite.


I am currently using 4 for this value.   However marc glisse claims 
that this may be due to a bug and that the value should be 2. This is 
something that has to be investigated further. This could easily be 
my mistake or some other issue that has crept into the pass.  The 
value of 2 or 4 is easily changed in largest_initialize.The only 
truly non mechanical transformation is in the code that multiplies 
two ranges.   This code uses the wide-int multiply full functions 
rather than using pairs of double-ints.


(I didn't look at the patch (yet))

Er, no, I didn't claim that using 4 was wrong, I think it is good 
because it makes things easier. I only claimed that the current 
implementation jumps through enough hoops to make do with 2.






Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte mode
 size 4 on a 64bit host.

 I do not believe that this can happen.   The core compiler includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes that
 are not power of two, and, if there isn't an int mode that is bigger, we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template templated
 on the number of HWIs in val.  Interface-wise wide_int2 should be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int. This
 goal of
 this patch is to get the compiler to do the constant math the way that
 the
 target does it.   Any such instantiation is by definition placing some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two implementations
 of functions that perform integer math on two-HWI sized integers.  What
 I also don't like too much is that we have two different interfaces to
 operate
 on them!  Can't you see how I come to not liking this?  Especially the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int is a
 waste of time, as the time is better spent removing double-int from the
 compiler.  All the necessary semantics and code of double-int _has_ been
 refactored into wide-int already.  Changing wide-int in any way to vend
 anything to double-int is wrong, as once double-int is removed, then all 
 the
 api changes to make double-int share from wide-int is wasted and must then
 be removed.  The path forward is the complete removal of double-int; it is
 wrong, has been wrong and always will be wrong, nothing can change that.

 double_int, compared to wide_int, is fast and lean.  I doubt we will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at least_
 templating wide_int on 'len' and providing specializations for 1 and 2.

 It might be a non-issue for math that operates on trees or RTXen due to
 the allocation overhead we pay, but in recent years we transitioned
 important
 paths away from using tree math to using double_ints _for speed reasons_.

 Richard.

 i do not know why you believe this about the speed. double int always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the precision's
 size, it almost never does uses synthetic operations since the sizes for
 almost every instance can be done using the native math on the machine.
 almost every call has a check to see if the operation can be done natively.
 I seriously doubt that you are going to do TI mode math much faster than i
 do it and if you do who cares.

 the number of calls does not effect the performance in any negative way and
 it fact is more efficient since common things that require more than one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
 }

 are always going to be faster than conditionally executing only one operation
 (but inside an offline function).

OK, this is really in reply to the 4.8 thing, but it felt more
appropriate here.

It's interesting that you gave this example, since before you were
complaining about too many fused ops.  Clearly this one could be
removed in favour of separate and() and not() operations, but why
not provide a fused one if there are clients who'll make use of it?
I think Kenny's API is just taking that to its logical conclusion.
There doesn't seem to be anything sacrosanct about the current choice
of what's fused and what isn't.

The speed problem we had using trees 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Biener
On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte mode
 size 4 on a 64bit host.

 I do not believe that this can happen.   The core compiler includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes that
 are not power of two, and, if there isn't an int mode that is bigger, we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template templated
 on the number of HWIs in val.  Interface-wise wide_int2 should be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int. This
 goal of
 this patch is to get the compiler to do the constant math the way that
 the
 target does it.   Any such instantiation is by definition placing some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two implementations
 of functions that perform integer math on two-HWI sized integers.  What
 I also don't like too much is that we have two different interfaces to
 operate
 on them!  Can't you see how I come to not liking this?  Especially the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int is a
 waste of time, as the time is better spent removing double-int from the
 compiler.  All the necessary semantics and code of double-int _has_ been
 refactored into wide-int already.  Changing wide-int in any way to vend
 anything to double-int is wrong, as once double-int is removed, then all 
 the
 api changes to make double-int share from wide-int is wasted and must then
 be removed.  The path forward is the complete removal of double-int; it is
 wrong, has been wrong and always will be wrong, nothing can change that.

 double_int, compared to wide_int, is fast and lean.  I doubt we will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at least_
 templating wide_int on 'len' and providing specializations for 1 and 2.

 It might be a non-issue for math that operates on trees or RTXen due to
 the allocation overhead we pay, but in recent years we transitioned
 important
 paths away from using tree math to using double_ints _for speed reasons_.

 Richard.

 i do not know why you believe this about the speed. double int always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the precision's
 size, it almost never does uses synthetic operations since the sizes for
 almost every instance can be done using the native math on the machine.
 almost every call has a check to see if the operation can be done natively.
 I seriously doubt that you are going to do TI mode math much faster than i
 do it and if you do who cares.

 the number of calls does not effect the performance in any negative way and
 it fact is more efficient since common things that require more than one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
 }

 are always going to be faster than conditionally executing only one operation
 (but inside an offline function).

 OK, this is really in reply to the 4.8 thing, but it felt more
 appropriate here.

 It's interesting that you gave this example, since before you were
 complaining about too many fused ops.  Clearly this one could be
 removed in favour of separate and() and not() operations, but why
 not provide a fused one if there are clients who'll make use of it?

I was more concerned about fused operations that use precision
or bitsize as input.  That is for example

 +  bool 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte mode
 size 4 on a 64bit host.

 I do not believe that this can happen.   The core compiler includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes that
 are not power of two, and, if there isn't an int mode that is bigger, 
 we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template templated
 on the number of HWIs in val.  Interface-wise wide_int2 should be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int. This
 goal of
 this patch is to get the compiler to do the constant math the way that
 the
 target does it.   Any such instantiation is by definition placing some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two implementations
 of functions that perform integer math on two-HWI sized integers.  What
 I also don't like too much is that we have two different interfaces to
 operate
 on them!  Can't you see how I come to not liking this?  Especially the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int is a
 waste of time, as the time is better spent removing double-int from the
 compiler.  All the necessary semantics and code of double-int _has_ been
 refactored into wide-int already.  Changing wide-int in any way to vend
 anything to double-int is wrong, as once double-int is removed,
 then all the
 api changes to make double-int share from wide-int is wasted and must 
 then
 be removed.  The path forward is the complete removal of double-int; it 
 is
 wrong, has been wrong and always will be wrong, nothing can change that.

 double_int, compared to wide_int, is fast and lean.  I doubt we will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at least_
 templating wide_int on 'len' and providing specializations for 1 and 2.

 It might be a non-issue for math that operates on trees or RTXen due to
 the allocation overhead we pay, but in recent years we transitioned
 important
 paths away from using tree math to using double_ints _for speed reasons_.

 Richard.

 i do not know why you believe this about the speed. double int always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the precision's
 size, it almost never does uses synthetic operations since the sizes for
 almost every instance can be done using the native math on the machine.
 almost every call has a check to see if the operation can be done natively.
 I seriously doubt that you are going to do TI mode math much faster than i
 do it and if you do who cares.

 the number of calls does not effect the performance in any negative way and
 it fact is more efficient since common things that require more than one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
 }

 are always going to be faster than conditionally executing only one 
 operation
 (but inside an offline function).

 OK, this is really in reply to the 4.8 thing, but it felt more
 appropriate here.

 It's interesting that you gave this example, since before you were
 complaining about too many fused ops.  Clearly this one could be
 removed in favour of separate and() and not() operations, but why
 not provide a fused one if there are clients who'll make use of it?

 I was more concerned about fused operations that use 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Biener
On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net 
 wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte mode
 size 4 on a 64bit host.

 I do not believe that this can happen.   The core compiler includes 
 all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes that
 are not power of two, and, if there isn't an int mode that is bigger, 
 we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template 
 templated
 on the number of HWIs in val.  Interface-wise wide_int2 should be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int. This
 goal of
 this patch is to get the compiler to do the constant math the way that
 the
 target does it.   Any such instantiation is by definition placing some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two implementations
 of functions that perform integer math on two-HWI sized integers.  What
 I also don't like too much is that we have two different interfaces to
 operate
 on them!  Can't you see how I come to not liking this?  Especially the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int is a
 waste of time, as the time is better spent removing double-int from the
 compiler.  All the necessary semantics and code of double-int _has_ been
 refactored into wide-int already.  Changing wide-int in any way to vend
 anything to double-int is wrong, as once double-int is removed,
 then all the
 api changes to make double-int share from wide-int is wasted and must 
 then
 be removed.  The path forward is the complete removal of double-int; it 
 is
 wrong, has been wrong and always will be wrong, nothing can change that.

 double_int, compared to wide_int, is fast and lean.  I doubt we will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at least_
 templating wide_int on 'len' and providing specializations for 1 and 2.

 It might be a non-issue for math that operates on trees or RTXen due to
 the allocation overhead we pay, but in recent years we transitioned
 important
 paths away from using tree math to using double_ints _for speed reasons_.

 Richard.

 i do not know why you believe this about the speed. double int always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the precision's
 size, it almost never does uses synthetic operations since the sizes for
 almost every instance can be done using the native math on the machine.
 almost every call has a check to see if the operation can be done 
 natively.
 I seriously doubt that you are going to do TI mode math much faster than i
 do it and if you do who cares.

 the number of calls does not effect the performance in any negative way 
 and
 it fact is more efficient since common things that require more than one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
 }

 are always going to be faster than conditionally executing only one 
 operation
 (but inside an offline function).

 OK, this is really in reply to the 4.8 thing, but it felt more
 appropriate here.

 It's interesting that you gave this example, since before you were
 complaining about too many fused ops.  Clearly this one could be
 removed in favour of separate and() and not() operations, but why
 not provide a fused one if 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump
 mikest...@comcast.net wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener 
 richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte 
 mode
 size 4 on a 64bit host.

 I do not believe that this can happen.  The core compiler
 includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes that
 are not power of two, and, if there isn't an int mode that is
 bigger, we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template
 templated
 on the number of HWIs in val.  Interface-wise wide_int2 should be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int. This
 goal of
 this patch is to get the compiler to do the constant math the way 
 that
 the
 target does it.   Any such instantiation is by definition placing 
 some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two implementations
 of functions that perform integer math on two-HWI sized integers.  
 What
 I also don't like too much is that we have two different interfaces to
 operate
 on them!  Can't you see how I come to not liking this?  Especially the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int is a
 waste of time, as the time is better spent removing double-int from the
 compiler.  All the necessary semantics and code of double-int _has_ 
 been
 refactored into wide-int already.  Changing wide-int in any way to vend
 anything to double-int is wrong, as once double-int is removed,
 then all the
 api changes to make double-int share from wide-int is wasted and
 must then
 be removed.  The path forward is the complete removal of
 double-int; it is
 wrong, has been wrong and always will be wrong, nothing can change 
 that.

 double_int, compared to wide_int, is fast and lean.  I doubt we will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at least_
 templating wide_int on 'len' and providing specializations for 1 and 2.

 It might be a non-issue for math that operates on trees or RTXen due to
 the allocation overhead we pay, but in recent years we transitioned
 important
 paths away from using tree math to using double_ints _for speed 
 reasons_.

 Richard.

 i do not know why you believe this about the speed. double int always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the precision's
 size, it almost never does uses synthetic operations since the sizes for
 almost every instance can be done using the native math on the machine.
 almost every call has a check to see if the operation can be done
 natively.
 I seriously doubt that you are going to do TI mode math much faster than 
 i
 do it and if you do who cares.

 the number of calls does not effect the performance in any
 negative way and
 it fact is more efficient since common things that require more than one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
 }

 are always going to be faster than conditionally executing only one
 operation
 (but inside an offline function).

 OK, this is really in reply to the 4.8 thing, but it felt more
 appropriate here.

 It's interesting that you gave this example, since before you were
 complaining about too many fused ops.  Clearly this one could be
 removed in favour of separate and() 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Biener
On Wed, Oct 31, 2012 at 1:22 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump
 mikest...@comcast.net wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener 
 richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte 
 mode
 size 4 on a 64bit host.

 I do not believe that this can happen.  The core compiler
 includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes that
 are not power of two, and, if there isn't an int mode that is
 bigger, we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide specializations 
 of
 wide_int
 for small sizes, thus ideally wide_int would be a template
 templated
 on the number of HWIs in val.  Interface-wise wide_int2 should be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for 
 it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int. This
 goal of
 this patch is to get the compiler to do the constant math the way 
 that
 the
 target does it.   Any such instantiation is by definition placing 
 some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two 
 implementations
 of functions that perform integer math on two-HWI sized integers.  
 What
 I also don't like too much is that we have two different interfaces 
 to
 operate
 on them!  Can't you see how I come to not liking this?  Especially 
 the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int is a
 waste of time, as the time is better spent removing double-int from 
 the
 compiler.  All the necessary semantics and code of double-int _has_ 
 been
 refactored into wide-int already.  Changing wide-int in any way to 
 vend
 anything to double-int is wrong, as once double-int is removed,
 then all the
 api changes to make double-int share from wide-int is wasted and
 must then
 be removed.  The path forward is the complete removal of
 double-int; it is
 wrong, has been wrong and always will be wrong, nothing can change 
 that.

 double_int, compared to wide_int, is fast and lean.  I doubt we will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at 
 least_
 templating wide_int on 'len' and providing specializations for 1 and 2.

 It might be a non-issue for math that operates on trees or RTXen due to
 the allocation overhead we pay, but in recent years we transitioned
 important
 paths away from using tree math to using double_ints _for speed 
 reasons_.

 Richard.

 i do not know why you believe this about the speed. double int 
 always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the precision's
 size, it almost never does uses synthetic operations since the sizes for
 almost every instance can be done using the native math on the machine.
 almost every call has a check to see if the operation can be done
 natively.
 I seriously doubt that you are going to do TI mode math much faster 
 than i
 do it and if you do who cares.

 the number of calls does not effect the performance in any
 negative way and
 it fact is more efficient since common things that require more than one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
 }

 are always going to be faster than conditionally executing only one
 operation
 (but inside an offline function).

 OK, this is really in reply to the 4.8 thing, but it felt more
 appropriate here.

 It's interesting that you gave this example, since before you were

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Sandiford
Richard Biener richard.guent...@gmail.com writes:
 But that means that wide_int has to model a P-bit operation as a
 normal len*HOST_WIDE_INT operation and then fix up the result
 after the fact, which seems unnecessarily convoluted.

 It does that right now.  The operations are carried out in a loop
 over len HOST_WIDE_INT parts, the last HWI is then special-treated
 to account for precision/size.  (yes, 'len' is also used as optimization - the
 fact that len ends up being mutable is another thing I dislike about
 wide-int.  If wide-ints are cheap then all ops should be non-mutating
 (at least to 'len')).

But the point of having a mutating len is that things like zero and -1
are common even for OImode values.  So if you're doing someting potentially
expensive like OImode multiplication, why do it to the number of
HOST_WIDE_INTs needed for an OImode value when the value we're
processing has only one significant HOST_WIDE_INT?

  I still don't
 see why a full-precision 2*HOST_WIDE_INT operation (or a full-precision
 X*HOST_WIDE_INT operation for any X) has any special meaning.

 Well, the same reason as a HOST_WIDE_INT variable has a meaning.
 We use it to constrain what we (efficiently) want to work on.  For example
 CCP might iterate up to 2 * HOST_BITS_PER_WIDE_INT times when
 doing bit-constant-propagation in loops (for TImode integers on a x86_64 
 host).

But what about targets with modes wider than TImode?  Would double_int
still be appropriate then?  If not, why does CCP have to use a templated
type with a fixed number of HWIs (and all arithmetic done to a fixed
number of HWIs) rather than one that can adapt to the runtime values,
like wide_int can?

 Oh, and I don't necessary see a use of double_int in its current form
 but for an integer representation on the host that is efficient to manipulate
 integer constants of a target dependent size.  For example the target
 detail that we have partial integer modes with bitsize  precision and that
 the bits  precision appearantly have a meaning when looking at the
 bit-representation of a constant should not be part of the base class
 of wide-int (I doubt it belongs to wide-int at all, but I guess you know more
 about the reason we track bitsize in addition to precision - I think it's
 abstraction at the wrong level, the tree level does fine without knowing
 about bitsize).

TBH I'm uneasy about the bitsize thing too.  I think bitsize is only
tracked for shift truncation, and if so, I agree it makes sense
to do that separately.

But anyway, this whole discussion seems to have reached a stalemate.
Or I suppose a de-facto rejection, since you're the only person in
a position to approve the thing :-)

Richard


Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Kenneth Zadeck


On 10/31/2012 08:11 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/25/2012 06:42 AM, Richard Biener wrote:

On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net wrote:

On Oct 24, 2012, at 2:43 AM, Richard Biener richard.guent...@gmail.com
wrote:

On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/23/2012 10:12 AM, Richard Biener wrote:

+  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
HOST_BITS_PER_WIDE_INT];

are we sure this rounds properly?  Consider a port with max byte mode
size 4 on a 64bit host.

I do not believe that this can happen.   The core compiler includes all
modes up to TI mode, so by default we already up to 128 bits.

And mode bitsizes are always power-of-two?  I suppose so.

Actually, no, they are not.  Partial int modes can have bit sizes that
are not power of two, and, if there isn't an int mode that is bigger, we'd
want to round up the partial int bit size.  Something like ((2 *
MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
HOST_BITS_PER_WIDE_INT should do it.


I still would like to have the ability to provide specializations of
wide_int
for small sizes, thus ideally wide_int would be a template templated
on the number of HWIs in val.  Interface-wise wide_int2 should be
identical to double_int, thus we should be able to do

typedef wide_int2 double_int;

If you want to go down this path after the patches get in, go for it.
I
see no use at all for this.
This was not meant to be a plug in replacement for double int. This
goal of
this patch is to get the compiler to do the constant math the way that
the
target does it.   Any such instantiation is by definition placing some
predefined limit that some target may not want.

Well, what I don't really like is that we now have two implementations
of functions that perform integer math on two-HWI sized integers.  What
I also don't like too much is that we have two different interfaces to
operate
on them!  Can't you see how I come to not liking this?  Especially the
latter …

double_int is logically dead.  Reactoring wide-int and double-int is a
waste of time, as the time is better spent removing double-int from the
compiler.  All the necessary semantics and code of double-int _has_ been
refactored into wide-int already.  Changing wide-int in any way to vend
anything to double-int is wrong, as once double-int is removed,
then all the
api changes to make double-int share from wide-int is wasted and must then
be removed.  The path forward is the complete removal of double-int; it is
wrong, has been wrong and always will be wrong, nothing can change that.

double_int, compared to wide_int, is fast and lean.  I doubt we will
get rid of it - you
will make compile-time math a _lot_ slower.  Just profile when you for
example
change get_inner_reference to use wide_ints.

To be able to remove double_int in favor of wide_int requires _at least_
templating wide_int on 'len' and providing specializations for 1 and 2.

It might be a non-issue for math that operates on trees or RTXen due to
the allocation overhead we pay, but in recent years we transitioned
important
paths away from using tree math to using double_ints _for speed reasons_.

Richard.

i do not know why you believe this about the speed. double int always
does synthetic math since you do everything at 128 bit precision.

the thing about wide int, is that since it does math to the precision's
size, it almost never does uses synthetic operations since the sizes for
almost every instance can be done using the native math on the machine.
almost every call has a check to see if the operation can be done natively.
I seriously doubt that you are going to do TI mode math much faster than i
do it and if you do who cares.

the number of calls does not effect the performance in any negative way and
it fact is more efficient since common things that require more than one
operation in double in are typically done in a single operation.

Simple double-int operations like

inline double_int
double_int::and_not (double_int b) const
{
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
}

are always going to be faster than conditionally executing only one operation
(but inside an offline function).

OK, this is really in reply to the 4.8 thing, but it felt more
appropriate here.

It's interesting that you gave this example, since before you were
complaining about too many fused ops.  Clearly this one could be
removed in favour of separate and() and not() operations, but why
not provide a fused one if there are clients who'll make use of it?

I was more 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Biener
On Wed, Oct 31, 2012 at 2:30 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 Richard Biener richard.guent...@gmail.com writes:
 But that means that wide_int has to model a P-bit operation as a
 normal len*HOST_WIDE_INT operation and then fix up the result
 after the fact, which seems unnecessarily convoluted.

 It does that right now.  The operations are carried out in a loop
 over len HOST_WIDE_INT parts, the last HWI is then special-treated
 to account for precision/size.  (yes, 'len' is also used as optimization - 
 the
 fact that len ends up being mutable is another thing I dislike about
 wide-int.  If wide-ints are cheap then all ops should be non-mutating
 (at least to 'len')).

 But the point of having a mutating len is that things like zero and -1
 are common even for OImode values.  So if you're doing someting potentially
 expensive like OImode multiplication, why do it to the number of
 HOST_WIDE_INTs needed for an OImode value when the value we're
 processing has only one significant HOST_WIDE_INT?

I don't propose doing that.  I propose that no wide-int member function
may _change_ it's len (to something larger).  Only that way you can
avoid allocating wasted space for zero and -1.  That way also the
artificial limit on 2 * largest-int-mode-hwis goes.

  I still don't
 see why a full-precision 2*HOST_WIDE_INT operation (or a full-precision
 X*HOST_WIDE_INT operation for any X) has any special meaning.

 Well, the same reason as a HOST_WIDE_INT variable has a meaning.
 We use it to constrain what we (efficiently) want to work on.  For example
 CCP might iterate up to 2 * HOST_BITS_PER_WIDE_INT times when
 doing bit-constant-propagation in loops (for TImode integers on a x86_64 
 host).

 But what about targets with modes wider than TImode?  Would double_int
 still be appropriate then?  If not, why does CCP have to use a templated
 type with a fixed number of HWIs (and all arithmetic done to a fixed
 number of HWIs) rather than one that can adapt to the runtime values,
 like wide_int can?

Because nobody cares about accurate bit-tracking for modes larger than
TImode.  And because no convenient abstraction was available ;)

 Oh, and I don't necessary see a use of double_int in its current form
 but for an integer representation on the host that is efficient to manipulate
 integer constants of a target dependent size.  For example the target
 detail that we have partial integer modes with bitsize  precision and that
 the bits  precision appearantly have a meaning when looking at the
 bit-representation of a constant should not be part of the base class
 of wide-int (I doubt it belongs to wide-int at all, but I guess you know more
 about the reason we track bitsize in addition to precision - I think it's
 abstraction at the wrong level, the tree level does fine without knowing
 about bitsize).

 TBH I'm uneasy about the bitsize thing too.  I think bitsize is only
 tracked for shift truncation, and if so, I agree it makes sense
 to do that separately.

So, can we please remove all traces of bitsize from wide-int then?

 But anyway, this whole discussion seems to have reached a stalemate.
 Or I suppose a de-facto rejection, since you're the only person in
 a position to approve the thing :-)

There are many (silent) people that are able to approve the thing.  But the
point is I have too many issues with the current patch that I'm unable
to point at a specific thing I want Kenny to change after which the patch
would be fine.  So I rely on some guesswork from Kenny giving my
advices leaner API, less fused ops, get rid of bitsize, think of
abstracting the core HWI[len] operation, there should be no tree or
RTL dependencies in the wide-int API to produce an updated variant.
Which of course takes time, which of course crosses my vacation, which
in the end means it isn't going to make 4.8 (I _do_ like the idea of not
having a dependence on host properties for integer constant representation).

Btw, a good hint at what a minimal wide-int API would look like is if
you _just_ replace double-int users with it.  Then you obviously have to
implement only the double-int interface and conversion from/to double-int.

Richard.


 Richard


Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Biener
On Wed, Oct 31, 2012 at 2:54 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

 On 10/31/2012 08:11 AM, Richard Biener wrote:

 On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net
 wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener
 richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte
 mode
 size 4 on a 64bit host.

 I do not believe that this can happen.   The core compiler
 includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes
 that
 are not power of two, and, if there isn't an int mode that is
 bigger, we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide
 specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template
 templated
 on the number of HWIs in val.  Interface-wise wide_int2 should
 be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for
 it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int.
 This
 goal of
 this patch is to get the compiler to do the constant math the way
 that
 the
 target does it.   Any such instantiation is by definition placing
 some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two
 implementations
 of functions that perform integer math on two-HWI sized integers.
 What
 I also don't like too much is that we have two different
 interfaces to
 operate
 on them!  Can't you see how I come to not liking this?  Especially
 the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int
 is a
 waste of time, as the time is better spent removing double-int from
 the
 compiler.  All the necessary semantics and code of double-int _has_
 been
 refactored into wide-int already.  Changing wide-int in any way to
 vend
 anything to double-int is wrong, as once double-int is removed,
 then all the
 api changes to make double-int share from wide-int is wasted and
 must then
 be removed.  The path forward is the complete removal of
 double-int; it is
 wrong, has been wrong and always will be wrong, nothing can change
 that.

 double_int, compared to wide_int, is fast and lean.  I doubt we will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you
 for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at
 least_
 templating wide_int on 'len' and providing specializations for 1 and
 2.

 It might be a non-issue for math that operates on trees or RTXen due
 to
 the allocation overhead we pay, but in recent years we transitioned
 important
 paths away from using tree math to using double_ints _for speed
 reasons_.

 Richard.

 i do not know why you believe this about the speed. double int
 always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the
 precision's
 size, it almost never does uses synthetic operations since the sizes
 for
 almost every instance can be done using the native math on the
 machine.
 almost every call has a check to see if the operation can be done
 natively.
 I seriously doubt that you are going to do TI mode math much faster
 than i
 do it and if you do who cares.

 the number of calls does not effect the performance in any negative
 way and
 it fact is more efficient since common things that require more than
 one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
double_int result;
result.low = low  ~b.low;
result.high = high  ~b.high;
return result;
 }

 are always going to be faster than conditionally executing only one
 operation
 (but inside an offline function).

 OK, this is really in reply to the 4.8 thing, but it felt more
 appropriate here.

 It's interesting that you gave this example, since before you were
 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Kenneth Zadeck


On 10/31/2012 10:05 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 2:54 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/31/2012 08:11 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/25/2012 06:42 AM, Richard Biener wrote:

On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net
wrote:

On Oct 24, 2012, at 2:43 AM, Richard Biener
richard.guent...@gmail.com
wrote:

On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/23/2012 10:12 AM, Richard Biener wrote:

+  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
HOST_BITS_PER_WIDE_INT];

are we sure this rounds properly?  Consider a port with max byte
mode
size 4 on a 64bit host.

I do not believe that this can happen.   The core compiler
includes all
modes up to TI mode, so by default we already up to 128 bits.

And mode bitsizes are always power-of-two?  I suppose so.

Actually, no, they are not.  Partial int modes can have bit sizes
that
are not power of two, and, if there isn't an int mode that is
bigger, we'd
want to round up the partial int bit size.  Something like ((2 *
MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
HOST_BITS_PER_WIDE_INT should do it.


I still would like to have the ability to provide
specializations of
wide_int
for small sizes, thus ideally wide_int would be a template
templated
on the number of HWIs in val.  Interface-wise wide_int2 should
be
identical to double_int, thus we should be able to do

typedef wide_int2 double_int;

If you want to go down this path after the patches get in, go for
it.
I
see no use at all for this.
This was not meant to be a plug in replacement for double int.
This
goal of
this patch is to get the compiler to do the constant math the way
that
the
target does it.   Any such instantiation is by definition placing
some
predefined limit that some target may not want.

Well, what I don't really like is that we now have two
implementations
of functions that perform integer math on two-HWI sized integers.
What
I also don't like too much is that we have two different
interfaces to
operate
on them!  Can't you see how I come to not liking this?  Especially
the
latter …

double_int is logically dead.  Reactoring wide-int and double-int
is a
waste of time, as the time is better spent removing double-int from
the
compiler.  All the necessary semantics and code of double-int _has_
been
refactored into wide-int already.  Changing wide-int in any way to
vend
anything to double-int is wrong, as once double-int is removed,
then all the
api changes to make double-int share from wide-int is wasted and
must then
be removed.  The path forward is the complete removal of
double-int; it is
wrong, has been wrong and always will be wrong, nothing can change
that.

double_int, compared to wide_int, is fast and lean.  I doubt we will
get rid of it - you
will make compile-time math a _lot_ slower.  Just profile when you
for
example
change get_inner_reference to use wide_ints.

To be able to remove double_int in favor of wide_int requires _at
least_
templating wide_int on 'len' and providing specializations for 1 and
2.

It might be a non-issue for math that operates on trees or RTXen due
to
the allocation overhead we pay, but in recent years we transitioned
important
paths away from using tree math to using double_ints _for speed
reasons_.

Richard.

i do not know why you believe this about the speed. double int
always
does synthetic math since you do everything at 128 bit precision.

the thing about wide int, is that since it does math to the
precision's
size, it almost never does uses synthetic operations since the sizes
for
almost every instance can be done using the native math on the
machine.
almost every call has a check to see if the operation can be done
natively.
I seriously doubt that you are going to do TI mode math much faster
than i
do it and if you do who cares.

the number of calls does not effect the performance in any negative
way and
it fact is more efficient since common things that require more than
one
operation in double in are typically done in a single operation.

Simple double-int operations like

inline double_int
double_int::and_not (double_int b) const
{
double_int result;
result.low = low  ~b.low;
result.high = high  ~b.high;
return result;
}

are always going to be faster than conditionally executing only one
operation
(but inside an offline function).

OK, this is really in reply to the 4.8 thing, but it felt more
appropriate here.

It's interesting that you gave this example, since before you were
complaining about too many fused ops.  Clearly this one could be
removed in favour 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Richard Biener
On Wed, Oct 31, 2012 at 3:18 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

 On 10/31/2012 10:05 AM, Richard Biener wrote:

 On Wed, Oct 31, 2012 at 2:54 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/31/2012 08:11 AM, Richard Biener wrote:

 On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
 rdsandif...@googlemail.com wrote:

 Richard Biener richard.guent...@gmail.com writes:

 On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/25/2012 06:42 AM, Richard Biener wrote:

 On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump
 mikest...@comcast.net
 wrote:

 On Oct 24, 2012, at 2:43 AM, Richard Biener
 richard.guent...@gmail.com
 wrote:

 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max
 byte
 mode
 size 4 on a 64bit host.

 I do not believe that this can happen.   The core compiler
 includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes
 that
 are not power of two, and, if there isn't an int mode that is
 bigger, we'd
 want to round up the partial int bit size.  Something like ((2 *
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide
 specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template
 templated
 on the number of HWIs in val.  Interface-wise wide_int2
 should
 be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go
 for
 it.
 I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int.
 This
 goal of
 this patch is to get the compiler to do the constant math the
 way
 that
 the
 target does it.   Any such instantiation is by definition
 placing
 some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two
 implementations
 of functions that perform integer math on two-HWI sized
 integers.
 What
 I also don't like too much is that we have two different
 interfaces to
 operate
 on them!  Can't you see how I come to not liking this?
 Especially
 the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int
 is a
 waste of time, as the time is better spent removing double-int
 from
 the
 compiler.  All the necessary semantics and code of double-int
 _has_
 been
 refactored into wide-int already.  Changing wide-int in any way
 to
 vend
 anything to double-int is wrong, as once double-int is removed,
 then all the
 api changes to make double-int share from wide-int is wasted and
 must then
 be removed.  The path forward is the complete removal of
 double-int; it is
 wrong, has been wrong and always will be wrong, nothing can
 change
 that.

 double_int, compared to wide_int, is fast and lean.  I doubt we
 will
 get rid of it - you
 will make compile-time math a _lot_ slower.  Just profile when you
 for
 example
 change get_inner_reference to use wide_ints.

 To be able to remove double_int in favor of wide_int requires _at
 least_
 templating wide_int on 'len' and providing specializations for 1
 and
 2.

 It might be a non-issue for math that operates on trees or RTXen
 due
 to
 the allocation overhead we pay, but in recent years we
 transitioned
 important
 paths away from using tree math to using double_ints _for speed
 reasons_.

 Richard.

 i do not know why you believe this about the speed. double int
 always
 does synthetic math since you do everything at 128 bit precision.

 the thing about wide int, is that since it does math to the
 precision's
 size, it almost never does uses synthetic operations since the
 sizes
 for
 almost every instance can be done using the native math on the
 machine.
 almost every call has a check to see if the operation can be done
 natively.
 I seriously doubt that you are going to do TI mode math much faster
 than i
 do it and if you do who cares.

 the number of calls does not effect the performance in any negative
 way and
 it fact is more efficient since common things that require more
 than
 one
 operation in double in are typically done in a single operation.

 Simple double-int operations like

 inline double_int
 double_int::and_not (double_int b) const
 {
 double_int result;
 result.low = low  ~b.low;
 result.high = high  ~b.high;
 return result;
 }

 are always going to be faster than conditionally executing only one
 operation
 (but inside an offline function).

 OK, 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Kenneth Zadeck


On 10/31/2012 09:54 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 2:30 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

But that means that wide_int has to model a P-bit operation as a
normal len*HOST_WIDE_INT operation and then fix up the result
after the fact, which seems unnecessarily convoluted.

It does that right now.  The operations are carried out in a loop
over len HOST_WIDE_INT parts, the last HWI is then special-treated
to account for precision/size.  (yes, 'len' is also used as optimization - the
fact that len ends up being mutable is another thing I dislike about
wide-int.  If wide-ints are cheap then all ops should be non-mutating
(at least to 'len')).

But the point of having a mutating len is that things like zero and -1
are common even for OImode values.  So if you're doing someting potentially
expensive like OImode multiplication, why do it to the number of
HOST_WIDE_INTs needed for an OImode value when the value we're
processing has only one significant HOST_WIDE_INT?

I don't propose doing that.  I propose that no wide-int member function
may _change_ it's len (to something larger).  Only that way you can
avoid allocating wasted space for zero and -1.  That way also the
artificial limit on 2 * largest-int-mode-hwis goes.

it is now 4x not 2x to accomodate the extra bit in tree-vrp.

remember that the space burden is minimal.wide-ints are not 
persistent and there are never more than a handful at a time.



  I still don't
see why a full-precision 2*HOST_WIDE_INT operation (or a full-precision
X*HOST_WIDE_INT operation for any X) has any special meaning.

Well, the same reason as a HOST_WIDE_INT variable has a meaning.
We use it to constrain what we (efficiently) want to work on.  For example
CCP might iterate up to 2 * HOST_BITS_PER_WIDE_INT times when
doing bit-constant-propagation in loops (for TImode integers on a x86_64 host).

But what about targets with modes wider than TImode?  Would double_int
still be appropriate then?  If not, why does CCP have to use a templated
type with a fixed number of HWIs (and all arithmetic done to a fixed
number of HWIs) rather than one that can adapt to the runtime values,
like wide_int can?

Because nobody cares about accurate bit-tracking for modes larger than
TImode.  And because no convenient abstraction was available ;)
yes, but tree-vrp does not even work for timode.  and there are not 
tests to scale it back when it does see ti-mode.   I understand that 
these can be added, but they so far have not been.


I would also point out that i was corrected on this point by (i believe) 
lawrence.   He points out that tree-vrp is still important for 
converting signed to unsigned for larger modes.




Oh, and I don't necessary see a use of double_int in its current form
but for an integer representation on the host that is efficient to manipulate
integer constants of a target dependent size.  For example the target
detail that we have partial integer modes with bitsize  precision and that
the bits  precision appearantly have a meaning when looking at the
bit-representation of a constant should not be part of the base class
of wide-int (I doubt it belongs to wide-int at all, but I guess you know more
about the reason we track bitsize in addition to precision - I think it's
abstraction at the wrong level, the tree level does fine without knowing
about bitsize).

TBH I'm uneasy about the bitsize thing too.  I think bitsize is only
tracked for shift truncation, and if so, I agree it makes sense
to do that separately.

So, can we please remove all traces of bitsize from wide-int then?


But anyway, this whole discussion seems to have reached a stalemate.
Or I suppose a de-facto rejection, since you're the only person in
a position to approve the thing :-)

There are many (silent) people that are able to approve the thing.  But the
point is I have too many issues with the current patch that I'm unable
to point at a specific thing I want Kenny to change after which the patch
would be fine.  So I rely on some guesswork from Kenny giving my
advices leaner API, less fused ops, get rid of bitsize, think of
abstracting the core HWI[len] operation, there should be no tree or
RTL dependencies in the wide-int API to produce an updated variant.
Which of course takes time, which of course crosses my vacation, which
in the end means it isn't going to make 4.8 (I _do_ like the idea of not
having a dependence on host properties for integer constant representation).

Btw, a good hint at what a minimal wide-int API would look like is if
you _just_ replace double-int users with it.  Then you obviously have to
implement only the double-int interface and conversion from/to double-int.

Richard.



Richard




Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Kenneth Zadeck


On 10/31/2012 10:24 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 3:18 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/31/2012 10:05 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 2:54 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/31/2012 08:11 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/25/2012 06:42 AM, Richard Biener wrote:

On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump
mikest...@comcast.net
wrote:

On Oct 24, 2012, at 2:43 AM, Richard Biener
richard.guent...@gmail.com
wrote:

On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/23/2012 10:12 AM, Richard Biener wrote:

+  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
HOST_BITS_PER_WIDE_INT];

are we sure this rounds properly?  Consider a port with max
byte
mode
size 4 on a 64bit host.

I do not believe that this can happen.   The core compiler
includes all
modes up to TI mode, so by default we already up to 128 bits.

And mode bitsizes are always power-of-two?  I suppose so.

Actually, no, they are not.  Partial int modes can have bit sizes
that
are not power of two, and, if there isn't an int mode that is
bigger, we'd
want to round up the partial int bit size.  Something like ((2 *
MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
HOST_BITS_PER_WIDE_INT should do it.


I still would like to have the ability to provide
specializations of
wide_int
for small sizes, thus ideally wide_int would be a template
templated
on the number of HWIs in val.  Interface-wise wide_int2
should
be
identical to double_int, thus we should be able to do

typedef wide_int2 double_int;

If you want to go down this path after the patches get in, go
for
it.
I
see no use at all for this.
This was not meant to be a plug in replacement for double int.
This
goal of
this patch is to get the compiler to do the constant math the
way
that
the
target does it.   Any such instantiation is by definition
placing
some
predefined limit that some target may not want.

Well, what I don't really like is that we now have two
implementations
of functions that perform integer math on two-HWI sized
integers.
What
I also don't like too much is that we have two different
interfaces to
operate
on them!  Can't you see how I come to not liking this?
Especially
the
latter …

double_int is logically dead.  Reactoring wide-int and double-int
is a
waste of time, as the time is better spent removing double-int
from
the
compiler.  All the necessary semantics and code of double-int
_has_
been
refactored into wide-int already.  Changing wide-int in any way
to
vend
anything to double-int is wrong, as once double-int is removed,
then all the
api changes to make double-int share from wide-int is wasted and
must then
be removed.  The path forward is the complete removal of
double-int; it is
wrong, has been wrong and always will be wrong, nothing can
change
that.

double_int, compared to wide_int, is fast and lean.  I doubt we
will
get rid of it - you
will make compile-time math a _lot_ slower.  Just profile when you
for
example
change get_inner_reference to use wide_ints.

To be able to remove double_int in favor of wide_int requires _at
least_
templating wide_int on 'len' and providing specializations for 1
and
2.

It might be a non-issue for math that operates on trees or RTXen
due
to
the allocation overhead we pay, but in recent years we
transitioned
important
paths away from using tree math to using double_ints _for speed
reasons_.

Richard.

i do not know why you believe this about the speed. double int
always
does synthetic math since you do everything at 128 bit precision.

the thing about wide int, is that since it does math to the
precision's
size, it almost never does uses synthetic operations since the
sizes
for
almost every instance can be done using the native math on the
machine.
almost every call has a check to see if the operation can be done
natively.
I seriously doubt that you are going to do TI mode math much faster
than i
do it and if you do who cares.

the number of calls does not effect the performance in any negative
way and
it fact is more efficient since common things that require more
than
one
operation in double in are typically done in a single operation.

Simple double-int operations like

inline double_int
double_int::and_not (double_int b) const
{
 double_int result;
 result.low = low  ~b.low;
 result.high = high  ~b.high;
 return result;
}

are always going to be faster than conditionally executing only one
operation
(but inside an offline function).

OK, this is really in reply to the 4.8 thing, but it felt more
appropriate here.

It's interesting 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Kenneth Zadeck


On 10/31/2012 08:44 AM, Richard Biener wrote:

On Wed, Oct 31, 2012 at 1:22 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Wed, Oct 31, 2012 at 1:05 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Wed, Oct 31, 2012 at 11:43 AM, Richard Sandiford
rdsandif...@googlemail.com wrote:

Richard Biener richard.guent...@gmail.com writes:

On Thu, Oct 25, 2012 at 12:55 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/25/2012 06:42 AM, Richard Biener wrote:

On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump
mikest...@comcast.net wrote:

On Oct 24, 2012, at 2:43 AM, Richard Biener richard.guent...@gmail.com
wrote:

On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
zad...@naturalbridge.com wrote:

On 10/23/2012 10:12 AM, Richard Biener wrote:

+  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
HOST_BITS_PER_WIDE_INT];

are we sure this rounds properly?  Consider a port with max byte mode
size 4 on a 64bit host.

I do not believe that this can happen.  The core compiler
includes all
modes up to TI mode, so by default we already up to 128 bits.

And mode bitsizes are always power-of-two?  I suppose so.

Actually, no, they are not.  Partial int modes can have bit sizes that
are not power of two, and, if there isn't an int mode that is
bigger, we'd
want to round up the partial int bit size.  Something like ((2 *
MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /
HOST_BITS_PER_WIDE_INT should do it.


I still would like to have the ability to provide specializations of
wide_int
for small sizes, thus ideally wide_int would be a template
templated
on the number of HWIs in val.  Interface-wise wide_int2 should be
identical to double_int, thus we should be able to do

typedef wide_int2 double_int;

If you want to go down this path after the patches get in, go for it.
I
see no use at all for this.
This was not meant to be a plug in replacement for double int. This
goal of
this patch is to get the compiler to do the constant math the way that
the
target does it.   Any such instantiation is by definition placing some
predefined limit that some target may not want.

Well, what I don't really like is that we now have two implementations
of functions that perform integer math on two-HWI sized integers.  What
I also don't like too much is that we have two different interfaces to
operate
on them!  Can't you see how I come to not liking this?  Especially the
latter …

double_int is logically dead.  Reactoring wide-int and double-int is a
waste of time, as the time is better spent removing double-int from the
compiler.  All the necessary semantics and code of double-int _has_ been
refactored into wide-int already.  Changing wide-int in any way to vend
anything to double-int is wrong, as once double-int is removed,
then all the
api changes to make double-int share from wide-int is wasted and
must then
be removed.  The path forward is the complete removal of
double-int; it is
wrong, has been wrong and always will be wrong, nothing can change that.

double_int, compared to wide_int, is fast and lean.  I doubt we will
get rid of it - you
will make compile-time math a _lot_ slower.  Just profile when you for
example
change get_inner_reference to use wide_ints.

To be able to remove double_int in favor of wide_int requires _at least_
templating wide_int on 'len' and providing specializations for 1 and 2.

It might be a non-issue for math that operates on trees or RTXen due to
the allocation overhead we pay, but in recent years we transitioned
important
paths away from using tree math to using double_ints _for speed reasons_.

Richard.

i do not know why you believe this about the speed. double int always
does synthetic math since you do everything at 128 bit precision.

the thing about wide int, is that since it does math to the precision's
size, it almost never does uses synthetic operations since the sizes for
almost every instance can be done using the native math on the machine.
almost every call has a check to see if the operation can be done
natively.
I seriously doubt that you are going to do TI mode math much faster than i
do it and if you do who cares.

the number of calls does not effect the performance in any
negative way and
it fact is more efficient since common things that require more than one
operation in double in are typically done in a single operation.

Simple double-int operations like

inline double_int
double_int::and_not (double_int b) const
{
   double_int result;
   result.low = low  ~b.low;
   result.high = high  ~b.high;
   return result;
}

are always going to be faster than conditionally executing only one
operation
(but inside an offline function).

OK, this is really in reply to the 4.8 thing, but it felt more
appropriate here.

It's interesting that you gave this example, since before you were
complaining about too many fused ops.  Clearly this one could be
removed in 

Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Kenneth Zadeck


On 10/31/2012 09:30 AM, Richard Sandiford wrote:

Richard Biener richard.guent...@gmail.com writes:

But that means that wide_int has to model a P-bit operation as a
normal len*HOST_WIDE_INT operation and then fix up the result
after the fact, which seems unnecessarily convoluted.

It does that right now.  The operations are carried out in a loop
over len HOST_WIDE_INT parts, the last HWI is then special-treated
to account for precision/size.  (yes, 'len' is also used as optimization - the
fact that len ends up being mutable is another thing I dislike about
wide-int.  If wide-ints are cheap then all ops should be non-mutating
(at least to 'len')).

But the point of having a mutating len is that things like zero and -1
are common even for OImode values.  So if you're doing someting potentially
expensive like OImode multiplication, why do it to the number of
HOST_WIDE_INTs needed for an OImode value when the value we're
processing has only one significant HOST_WIDE_INT?
I think with a little thought i can add some special constructors and 
get rid of the mutating aspects of the interface.





  I still don't
see why a full-precision 2*HOST_WIDE_INT operation (or a full-precision
X*HOST_WIDE_INT operation for any X) has any special meaning.

Well, the same reason as a HOST_WIDE_INT variable has a meaning.
We use it to constrain what we (efficiently) want to work on.  For example
CCP might iterate up to 2 * HOST_BITS_PER_WIDE_INT times when
doing bit-constant-propagation in loops (for TImode integers on a x86_64 host).

But what about targets with modes wider than TImode?  Would double_int
still be appropriate then?  If not, why does CCP have to use a templated
type with a fixed number of HWIs (and all arithmetic done to a fixed
number of HWIs) rather than one that can adapt to the runtime values,
like wide_int can?


Oh, and I don't necessary see a use of double_int in its current form
but for an integer representation on the host that is efficient to manipulate
integer constants of a target dependent size.  For example the target
detail that we have partial integer modes with bitsize  precision and that
the bits  precision appearantly have a meaning when looking at the
bit-representation of a constant should not be part of the base class
of wide-int (I doubt it belongs to wide-int at all, but I guess you know more
about the reason we track bitsize in addition to precision - I think it's
abstraction at the wrong level, the tree level does fine without knowing
about bitsize).

TBH I'm uneasy about the bitsize thing too.  I think bitsize is only
tracked for shift truncation, and if so, I agree it makes sense
to do that separately.

But anyway, this whole discussion seems to have reached a stalemate.
Or I suppose a de-facto rejection, since you're the only person in
a position to approve the thing :-)

Richard




Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Mike Stump
On Oct 31, 2012, at 5:44 AM, Richard Biener richard.guent...@gmail.com wrote:
 the
 fact that len ends up being mutable is another thing I dislike about
 wide-int.

We expose len for construction only, it is non-mutating.  During construction, 
there is no previous value.

  If wide-ints are cheap then all ops should be non-mutating
 (at least to 'len')).

It is.  Construction modifies the object as construction must be defined as 
initializing the state of the data.  Before construction, there is no data, so, 
we are constructing the data, not mutating the data.  Surely you don't object 
to construction?


Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Mike Stump
On Oct 31, 2012, at 6:54 AM, Richard Biener richard.guent...@gmail.com wrote:
 I propose that no wide-int member function
 may _change_ it's len (to something larger).

We never do that, so, we already do as you wish.  We construct wide ints, and 
we have member functions to construct values.  We need to construct values as 
some parts of the compiler want to create values.  The construction of values 
can be removed when the rest of the compiler no longer wishes to construct 
values. LTO is an example of a client that wanted to construct a value.  I'll 
let the LTO people chime in if they wish to no loner construct values.


Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-31 Thread Mike Stump
On Oct 31, 2012, at 7:05 AM, Richard Biener richard.guent...@gmail.com wrote:
 You have an artificial limit on what 'len' can be.

No.  There is no limit, and nothing artificial.  We take the maximum of the 
needs of the target, the maximum of the front-ends and the maximum of the 
mid-end and the back-end.  We can drop a category, if that category no longer 
wishes to be our client.  Any client is free to stop using wide-int, any time 
they want.  For example, vrp could use gmp, if they wanted to, and the need to 
serve them drops.  You have imagined the cost is high to do this, the reality 
is all long lived objects are small, and all short lived objects are so 
transitory that we are talking about maybe 5 live at a time.

 And you do not accomodate
 users that do not want to pay the storage penalty for that arbitrary upper 
 limit
 choice.

This is also wrong.  First, there is no arbitrary upper limit.  Second, all 
long lived objects are small.  We accommodated them by having all long lived 
objects be small.  The transitory objects are big, but there are only 5 of them 
alive at a time.

  That's all because 'len' may grow (mutate).

This is also wrong.


Re: patch to fix constant math - 4th patch - the wide-int class.

2012-10-25 Thread Richard Biener
On Wed, Oct 24, 2012 at 7:23 PM, Mike Stump mikest...@comcast.net wrote:
 On Oct 24, 2012, at 2:43 AM, Richard Biener richard.guent...@gmail.com 
 wrote:
 On Tue, Oct 23, 2012 at 6:12 PM, Kenneth Zadeck
 zad...@naturalbridge.com wrote:

 On 10/23/2012 10:12 AM, Richard Biener wrote:

 +  HOST_WIDE_INT val[2 * MAX_BITSIZE_MODE_ANY_INT /
 HOST_BITS_PER_WIDE_INT];

 are we sure this rounds properly?  Consider a port with max byte mode
 size 4 on a 64bit host.

 I do not believe that this can happen.   The core compiler includes all
 modes up to TI mode, so by default we already up to 128 bits.

 And mode bitsizes are always power-of-two?  I suppose so.

 Actually, no, they are not.  Partial int modes can have bit sizes that are 
 not power of two, and, if there isn't an int mode that is bigger, we'd want 
 to round up the partial int bit size.  Something like ((2 * 
 MAX_BITSIZE_MODE_ANY_INT + HOST_BITS_PER_WIDE_INT - 1) /  
 HOST_BITS_PER_WIDE_INT should do it.

 I still would like to have the ability to provide specializations of
 wide_int
 for small sizes, thus ideally wide_int would be a template templated
 on the number of HWIs in val.  Interface-wise wide_int2 should be
 identical to double_int, thus we should be able to do

 typedef wide_int2 double_int;

 If you want to go down this path after the patches get in, go for it.I
 see no use at all for this.
 This was not meant to be a plug in replacement for double int. This goal of
 this patch is to get the compiler to do the constant math the way that the
 target does it.   Any such instantiation is by definition placing some
 predefined limit that some target may not want.

 Well, what I don't really like is that we now have two implementations
 of functions that perform integer math on two-HWI sized integers.  What
 I also don't like too much is that we have two different interfaces to 
 operate
 on them!  Can't you see how I come to not liking this?  Especially the
 latter …

 double_int is logically dead.  Reactoring wide-int and double-int is a waste 
 of time, as the time is better spent removing double-int from the compiler.  
 All the necessary semantics and code of double-int _has_ been refactored into 
 wide-int already.  Changing wide-int in any way to vend anything to 
 double-int is wrong, as once double-int is removed, then all the api changes 
 to make double-int share from wide-int is wasted and must then be removed.  
 The path forward is the complete removal of double-int; it is wrong, has been 
 wrong and always will be wrong, nothing can change that.

double_int, compared to wide_int, is fast and lean.  I doubt we will
get rid of it - you
will make compile-time math a _lot_ slower.  Just profile when you for example
change get_inner_reference to use wide_ints.

To be able to remove double_int in favor of wide_int requires _at least_
templating wide_int on 'len' and providing specializations for 1 and 2.

It might be a non-issue for math that operates on trees or RTXen due to
the allocation overhead we pay, but in recent years we transitioned important
paths away from using tree math to using double_ints _for speed reasons_.

Richard.


  1   2   >