On 10/04/2012 09:17 AM, Marc Glisse wrote:
On Wed, 3 Oct 2012, Mike Stump wrote:
On Oct 3, 2012, at 1:47 PM, Marc Glisse <marc.gli...@inria.fr> wrote:
did you consider making the size of wide_int a template parameter,
now that we are using C++? All with a convenient typedef or macro so
it doesn't show. I am asking because in vrp I do some arithmetic
that requires 2*N+1 bits where N is the size of double_int.
No, not really. I'd maybe answer it this way, we put in a type
(singular) to support all integral constants in all languages on a
port. Since we only needed 1, there was little need to templatize
it. By supporting all integral constants in all languages, there is
little need for more. If Ada say, wanted a 2048 bit integer, then,
we just have it drop off the size it wants someplace and we would mix
that in on a MAX(….) line, net result, the type we use would then
directly support the needs of Ada. If vpr wanted 2x of all existing
modes, we could simply change the MAX equation and essentially double
it; if people need that. This comes as a cost, as the intermediate
wide values are fixed size allocated (not variable); so these all
would be larger.
And this cost could be eliminated by having a template wide_int_ so
only the places that need it actually use the extra size ;-)
The space is not really an issue in most places since wide-ints tend to
be short lived. i guess vrp is slightly different because it creates a
lot at once. but then they go away.
However the real question is what are you going to instantiate the
template on? What we do is look at the target and determine the
largest type that the target supports and build a wide int type that
supports that. how are you going to do better? are you going to
instantiate one for every type you see? are these going to be static
or dynamic? The last line this email seems to imply that you were
planning to "know" that __int128 was the largest integer that any target
or front end could support.
and then what do you do for the parts of the compiler that have
operations that take things of two different types, like shift. The
shift amount can and may times is a shorter type that what is being
shifted. Would these different length integers be represented with
different instances from the same template? I am not a c++ programmer
and so all of this is a little new to me, but given a perspective of the
rest of the compiler, this does not seem like the right way to go.
On Wed, 3 Oct 2012, Kenneth Zadeck wrote:
i have already converted the vrp code, so i have some guess at where
you are talking about. (of course correct me if i am wrong).
in the code that computes the range when two variables are multiplied
together needs to do a multiplication that produces a result that is
twice as wide as the inputs.
Yes, exactly.
my library is able to do that with one catch (and this is a big
catch): the target has to have an integer mode that is twice as big
as the mode of the operands. The issue is that wide-ints actually
carry around the mode of the value in order to get the bitsize and
precision of the operands (it does not have the type, because this
code has to both work on the rtl and tree level and i generally do
not want the signness anyway).
my current code in vrp checks to see if such a mode exists and if it
does, it produces the product. if the mode does not exist, it
returns bottom. What this means is that for most (many or some)
targets that have a TImode, the largest thing that particular vrp
discover ranges for is a DImode value. We could get around this by
defining the next larger mode than what the target really needs but i
wonder how much mileage you are going to get out of that with really
large numbers.
This will be for discussion when you submit that next patch, but
currently VRP handles integers the same size as double_int. In
particular, it handles __int128. I would be unhappy if introducing a
larger bigint type in gcc made us regress there.
You are only happy now because you do not really understand the world
around you. This is not what your code does. What you code does is
that if the host is a 64 bit host you can handle __int128 and if your
host is a 32 bit host you can handle a __int64. If you are building a
cross compiler from a 32 bit host to a 64 bit target, your pass is
either going to get the wrong answer, give up, or ice. There are
currently parts of gcc that do each of these three "solutions" and my
patch gets rid of these because it does the math as the target does the
math, no matter that the target is.
The goal of my patch is to make gcc produce the same correct results no
matter what types the target or host support. The last thing that we
need to have some optimization "knowing" what the limits of either of
these are and hard coding that in a set of templates that have been
statically instantiated.