MVT-based vectors: experiments with JVM support

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Wed Nov 22 14:43:27 UTC 2017


Hi,

Based on the initial experience (very pleasant!) with MVT-based vectors 
[1], I decided to proceed and tried to port JVM part of vector support 
from Panama. I'd like to update you where we stand right now.

Vector support in Panama mostly resides in C2. Vectors are represented 
in Java either as super-longs (e.g, Long4 [2]) or typed classes (e.g., 
jdk.incubator.vector.Int256Vector [3]) and C2 tries hard to avoid boxing 
by wrapping vector values in VectorBoxNode [4] or VBoxNode [5] nodes and 
dragging values through vector store/load chains between vector IR 
nodes. Since Panama doesn't support any notion of value types yet in 
bytecode (Q-types), it works in adhoc manner.

In Valhalla/MVT there's much more powerful alternative - ValueTypeNode. 
Moving from VectorBoxNode/VBoxNode to ValueTypeNode looks very 
promising. Some nice synergies between vectors & value types become 
possible, like extending VT-specific calling conventions in C2 to vector 
calling conventions, e.g:

     QLong4(QLong4,QLong4) => ymm0(ymm0,ymm1)

But, unfortunately, simply replacing VectorBoxNode/VBoxNode with 
ValueTypeNode doesn't work.

ValueTypeNode represents a value instance as a pack of elements 
comprising it. Elements are either primitive/reference values or other 
composite values. But for vectors it's desirable to keep them 
indivisible on JVM level. And that requires drastic changes across the 
JVM, like adding new case into JVM's BasicType structure [6].

    ValueTypeNode vbuf v # vector[4]{int}

where
   buf is value buffer (optional)
   v is vector[4]{int}

The alternative is to pretend that vectors are just a dense homogeneous 
packs of primitive elements (e.g., vector of 8 ints):

   ValueTypeNode vbuf i0 i1 i2 i3 # vector[4]{int}

But (even leaving endianness aspect aside) that still requires some 
special logic (though much more focused compared to new basic type) to 
produce efficient vectorized code.

Some examples:

   (0) On IR level, every vector value has to be unpacked before used in 
ValueTypeNode:

   ValueTypeNode _ (Unpack #0 v) (Unpack #1 v)
                   (Unpack #2 v) (Unpack #3 v) # vector[4]{int}

where: v is vector[4]{int}

Compiler has to thread the vector and connect users directly to it in 
order to avoid repacks leaking into generated code.


   (1) Vector values are represented as single values in C2 IR and 
indivisible w/o special operations.

Extracting/updating element in a vector residing in a register requires 
special instructions ([v]pinsr*/[v]pextr*). Simply changing an edge 
doesn't (it'll lead to vector repackaging):

   #vwithfield
   UpdateElement #2 new_i2
      (ValueTypeNode (vbuf?) i0 i1 i2 i3 # vector[4]{int})
=\=>
   ValueTypeNode _ i0 i1 new_i2 i3 # vector[4]{int}


   (2) (Packed) vector values should be loaded & stored in one step 
(represented as LoadVectorNode/StoreVectorNode in C2).

If a vector memory operation is represented as per-element operation & 
an explicit pack, then C2 has to convert that shape into vectorized 
load/store:

   Pack (LoadI arr +16) (LoadI arr +20)...(LoadI arr +28) # vector{int,4}
   # 4 instructions: pinsrd, pinsrd, pinsrd, pinsrd
===>
   LoadVector arr +16 # vector {int,4}
   # 1 instruction: vmov


   (3) Rematerialization (on deoptimization) has to support vector values.

On rematerialization there are no individual entries for vector 
elements, but a single one for the raw vector value. Rematerialization 
logic has to know how to properly move it into the buffer.


Current status is:

   (1) I played with former approach (full support for vector values 
across the JVM) for some time and gave up :-)

   (2) Latter approach (vectors as explicit packs of elements) is still 
an idea, but looks promising enough to give it a try.

Best regards,
Vladimir Ivanov

[1] 
http://mail.openjdk.java.net/pipermail/valhalla-dev/2017-June/002731.html

[2] 
http://hg.openjdk.java.net/panama/panama/jdk/file/300a5ac72db8/src/java.base/share/classes/java/lang/Long4.java

[3] 
http://hg.openjdk.java.net/panama/panama/jdk/file/300a5ac72db8/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Int256Vector.java

[4] 
http://hg.openjdk.java.net/panama/panama/hotspot/file/69c75a8e7c74/src/share/vm/opto/vectornode.hpp#l822

[5] 
http://hg.openjdk.java.net/panama/panama/hotspot/file/69c75a8e7c74/src/share/vm/opto/callnode.hpp#l1172

[6] 
http://hg.openjdk.java.net/panama/panama/hotspot/file/69c75a8e7c74/src/share/vm/utilities/globalDefinitions.hpp#l645



More information about the valhalla-dev mailing list