patch to fix constant math - 4th patch - the wide-int class - patch ping for the next stage 1
Kenneth Zadeck
zadeck@naturalbridge.com
Mon Apr 22 07:15:00 GMT 2013
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 i hear, it sounds like a chain saw ....").
The api that i have is independent of the rep that i happen to use
inside of wide-ints. The fact that it might be work is really just an
accident. Gimple was designed (and rtl just happened) so that the
operators carry the information that is needed. The fact that those
operators are generally redundant with the types is a byproduct of the
strong typing of the middle ends. With this respect, i think i have
the right interface.
Kenny
More information about the Gcc-patches
mailing list