[vector] Vector API -- alignment with value types
Brian Goetz
brian.goetz at oracle.com
Wed Jan 30 20:58:52 UTC 2019
> Part I
> ------
>
> Here's an idea for simplifying Species, which is: let's drive Species
> down to be a simple class that is really just a constant holder for
> (element type, shape), and move all the behavior to static methods on
> XxxVector.
I've started prototyping this, in a rather slash-and-burn manner. I am
about halfway through. So far, its working, the set of changes I had to
make to client code is very small (almost all transforming
species.doSomething(args) to XxxVector.doSomething(species, args)).
The question, of course, is whether the intrinsification will all
survive the transformation. The most common case is that I have
transformed vector intrinsic calls from
VectorIntrinsic.blah(Int128Vector.class, ...)
to
VectorIntrinsics.blah(species.boxType(), ...)
The basic assumption is that, under the same conditions that we get
inlining now, we'll know the species is a constant, and boxType() will
just inline to a concrete box type anyway. (The goal is to get species
to be values, but in the meantime, they can be enum constants.) This
should work, but we'll likely have to do some JIT work to get back to
where we see all the inlining and intrinsification. (Much of this would
come free in Valhalla.)
There are a few cases where we can't just do the above, and have to do a
switch in the lifted method, such as:
public static Shuffle<Byte> shuffle(ByteSpecies species, IntUnaryOperator f) {
if (species.boxType() == ByteMaxVector.class)
return new ByteMaxVector.ByteMaxShuffle(f);
switch (species.bitSize()) {
case 64:return new Byte64Vector.Byte64Shuffle(f);
case 128:return new Byte128Vector.Byte128Shuffle(f);
case 256:return new Byte256Vector.Byte256Shuffle(f);
case 512:return new Byte512Vector.Byte512Shuffle(f);
default:throw new IllegalArgumentException(Integer.toString(species.bitSize()));
}
}
Because again, species is a constant, this should also just inline down
to the right thing. So far, other than reshape/rebracket, I haven't
seen anything requiring more complicated transformations.
The only code I found so far that tries to be agnostic to shape and size
both is VectorResizeTest; there are strategies for making this work
without the combinatorial automated specialization, so I don't see this
as a big impediment.
Where this leads to is:
- Vector.Species becomes an interface with a handful of methods
(bitSize, etc), and quite possibly one that no one uses directly;
- IntSpecies and friends become enums, with enum constants for I64,
I128, etc (or, values, with static constants for the values);
- The specialized classes for XxxNnVector.XxxNnSpecies _go away_;
- Users need not learn about species at all, but if they do care, they
are just simple data constants that get fed through the API.
I'm not done (and am traveling the next two weeks), but I think I've
made progress validating the API transformation. The real question,
then, is when do we do this. I think it would be best to do before
previewing, simply because it is such an intrusive refactoring. But,
we'd have to evaluate whether we can mitigate the impact in time.
More information about the panama-dev
mailing list