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

Reply via email to