8271366: [REDO] JDK-8266054 VectorAPI rotate operation optimization

Reviewed-by: sviswanathan, psandoz
This commit is contained in:
Jatin Bhateja 2021-08-13 04:33:53 +00:00
parent 4d4ba5c5b4
commit 020aec5318
57 changed files with 4376 additions and 219 deletions

View file

@ -380,6 +380,18 @@ public abstract class ByteVector extends AbstractVector<Byte> {
return maskFactory(bits);
}
/*package-private*/
@ForceInline
static byte rotateLeft(byte a, int n) {
return (byte)(((((byte)a) & Byte.toUnsignedInt((byte)-1)) << (n & Byte.SIZE-1)) | ((((byte)a) & Byte.toUnsignedInt((byte)-1)) >>> (Byte.SIZE - (n & Byte.SIZE-1))));
}
/*package-private*/
@ForceInline
static byte rotateRight(byte a, int n) {
return (byte)(((((byte)a) & Byte.toUnsignedInt((byte)-1)) >>> (n & Byte.SIZE-1)) | ((((byte)a) & Byte.toUnsignedInt((byte)-1)) << (Byte.SIZE - (n & Byte.SIZE-1))));
}
/*package-private*/
@Override
abstract ByteSpecies vspecies();
@ -600,12 +612,7 @@ public abstract class ByteVector extends AbstractVector<Byte> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == ROR || op == ROL) { // FIXME: JIT should do this
ByteVector neg = that.lanewise(NEG);
ByteVector hi = this.lanewise(LSHL, (op == ROR) ? neg : that);
ByteVector lo = this.lanewise(LSHR, (op == ROR) ? that : neg);
return hi.lanewise(OR, lo);
} else if (op == AND_NOT) {
if (op == AND_NOT) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -646,6 +653,10 @@ public abstract class ByteVector extends AbstractVector<Byte> {
v0.bOp(v1, (i, a, n) -> (byte)(a >> n));
case VECTOR_OP_URSHIFT: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> (byte)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateRight(a, (int)n));
default: return null;
}}));
}
@ -792,11 +803,6 @@ public abstract class ByteVector extends AbstractVector<Byte> {
assert(opKind(op, VO_SHIFT));
// As per shift specification for Java, mask the shift count.
e &= SHIFT_MASK;
if (op == ROR || op == ROL) { // FIXME: JIT should do this
ByteVector hi = this.lanewise(LSHL, (op == ROR) ? -e : e);
ByteVector lo = this.lanewise(LSHR, (op == ROR) ? e : -e);
return hi.lanewise(OR, lo);
}
int opc = opCode(op);
return VectorSupport.broadcastInt(
opc, getClass(), byte.class, length(),
@ -809,6 +815,10 @@ public abstract class ByteVector extends AbstractVector<Byte> {
v.uOp((i, a) -> (byte)(a >> n));
case VECTOR_OP_URSHIFT: return (v, n) ->
v.uOp((i, a) -> (byte)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v, n) ->
v.uOp((i, a) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v, n) ->
v.uOp((i, a) -> rotateRight(a, (int)n));
default: return null;
}}));
}

View file

@ -380,6 +380,7 @@ public abstract class DoubleVector extends AbstractVector<Double> {
return maskFactory(bits);
}
/*package-private*/
@Override
abstract DoubleSpecies vspecies();

View file

@ -380,6 +380,7 @@ public abstract class FloatVector extends AbstractVector<Float> {
return maskFactory(bits);
}
/*package-private*/
@Override
abstract FloatSpecies vspecies();

View file

@ -380,6 +380,18 @@ public abstract class IntVector extends AbstractVector<Integer> {
return maskFactory(bits);
}
/*package-private*/
@ForceInline
static int rotateLeft(int a, int n) {
return Integer.rotateLeft(a, n);
}
/*package-private*/
@ForceInline
static int rotateRight(int a, int n) {
return Integer.rotateRight(a, n);
}
/*package-private*/
@Override
abstract IntSpecies vspecies();
@ -600,12 +612,7 @@ public abstract class IntVector extends AbstractVector<Integer> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == ROR || op == ROL) { // FIXME: JIT should do this
IntVector neg = that.lanewise(NEG);
IntVector hi = this.lanewise(LSHL, (op == ROR) ? neg : that);
IntVector lo = this.lanewise(LSHR, (op == ROR) ? that : neg);
return hi.lanewise(OR, lo);
} else if (op == AND_NOT) {
if (op == AND_NOT) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -646,6 +653,10 @@ public abstract class IntVector extends AbstractVector<Integer> {
v0.bOp(v1, (i, a, n) -> (int)(a >> n));
case VECTOR_OP_URSHIFT: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> (int)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateRight(a, (int)n));
default: return null;
}}));
}
@ -792,11 +803,6 @@ public abstract class IntVector extends AbstractVector<Integer> {
assert(opKind(op, VO_SHIFT));
// As per shift specification for Java, mask the shift count.
e &= SHIFT_MASK;
if (op == ROR || op == ROL) { // FIXME: JIT should do this
IntVector hi = this.lanewise(LSHL, (op == ROR) ? -e : e);
IntVector lo = this.lanewise(LSHR, (op == ROR) ? e : -e);
return hi.lanewise(OR, lo);
}
int opc = opCode(op);
return VectorSupport.broadcastInt(
opc, getClass(), int.class, length(),
@ -809,6 +815,10 @@ public abstract class IntVector extends AbstractVector<Integer> {
v.uOp((i, a) -> (int)(a >> n));
case VECTOR_OP_URSHIFT: return (v, n) ->
v.uOp((i, a) -> (int)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v, n) ->
v.uOp((i, a) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v, n) ->
v.uOp((i, a) -> rotateRight(a, (int)n));
default: return null;
}}));
}

View file

@ -380,6 +380,18 @@ public abstract class LongVector extends AbstractVector<Long> {
return maskFactory(bits);
}
/*package-private*/
@ForceInline
static long rotateLeft(long a, int n) {
return Long.rotateLeft(a, n);
}
/*package-private*/
@ForceInline
static long rotateRight(long a, int n) {
return Long.rotateRight(a, n);
}
/*package-private*/
@Override
abstract LongSpecies vspecies();
@ -558,12 +570,7 @@ public abstract class LongVector extends AbstractVector<Long> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == ROR || op == ROL) { // FIXME: JIT should do this
LongVector neg = that.lanewise(NEG);
LongVector hi = this.lanewise(LSHL, (op == ROR) ? neg : that);
LongVector lo = this.lanewise(LSHR, (op == ROR) ? that : neg);
return hi.lanewise(OR, lo);
} else if (op == AND_NOT) {
if (op == AND_NOT) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -604,6 +611,10 @@ public abstract class LongVector extends AbstractVector<Long> {
v0.bOp(v1, (i, a, n) -> (long)(a >> n));
case VECTOR_OP_URSHIFT: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> (long)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateRight(a, (int)n));
default: return null;
}}));
}
@ -710,11 +721,6 @@ public abstract class LongVector extends AbstractVector<Long> {
assert(opKind(op, VO_SHIFT));
// As per shift specification for Java, mask the shift count.
e &= SHIFT_MASK;
if (op == ROR || op == ROL) { // FIXME: JIT should do this
LongVector hi = this.lanewise(LSHL, (op == ROR) ? -e : e);
LongVector lo = this.lanewise(LSHR, (op == ROR) ? e : -e);
return hi.lanewise(OR, lo);
}
int opc = opCode(op);
return VectorSupport.broadcastInt(
opc, getClass(), long.class, length(),
@ -727,6 +733,10 @@ public abstract class LongVector extends AbstractVector<Long> {
v.uOp((i, a) -> (long)(a >> n));
case VECTOR_OP_URSHIFT: return (v, n) ->
v.uOp((i, a) -> (long)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v, n) ->
v.uOp((i, a) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v, n) ->
v.uOp((i, a) -> rotateRight(a, (int)n));
default: return null;
}}));
}

View file

@ -380,6 +380,18 @@ public abstract class ShortVector extends AbstractVector<Short> {
return maskFactory(bits);
}
/*package-private*/
@ForceInline
static short rotateLeft(short a, int n) {
return (short)(((((short)a) & Short.toUnsignedInt((short)-1)) << (n & Short.SIZE-1)) | ((((short)a) & Short.toUnsignedInt((short)-1)) >>> (Short.SIZE - (n & Short.SIZE-1))));
}
/*package-private*/
@ForceInline
static short rotateRight(short a, int n) {
return (short)(((((short)a) & Short.toUnsignedInt((short)-1)) >>> (n & Short.SIZE-1)) | ((((short)a) & Short.toUnsignedInt((short)-1)) << (Short.SIZE - (n & Short.SIZE-1))));
}
/*package-private*/
@Override
abstract ShortSpecies vspecies();
@ -600,12 +612,7 @@ public abstract class ShortVector extends AbstractVector<Short> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == ROR || op == ROL) { // FIXME: JIT should do this
ShortVector neg = that.lanewise(NEG);
ShortVector hi = this.lanewise(LSHL, (op == ROR) ? neg : that);
ShortVector lo = this.lanewise(LSHR, (op == ROR) ? that : neg);
return hi.lanewise(OR, lo);
} else if (op == AND_NOT) {
if (op == AND_NOT) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -646,6 +653,10 @@ public abstract class ShortVector extends AbstractVector<Short> {
v0.bOp(v1, (i, a, n) -> (short)(a >> n));
case VECTOR_OP_URSHIFT: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> (short)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateRight(a, (int)n));
default: return null;
}}));
}
@ -792,11 +803,6 @@ public abstract class ShortVector extends AbstractVector<Short> {
assert(opKind(op, VO_SHIFT));
// As per shift specification for Java, mask the shift count.
e &= SHIFT_MASK;
if (op == ROR || op == ROL) { // FIXME: JIT should do this
ShortVector hi = this.lanewise(LSHL, (op == ROR) ? -e : e);
ShortVector lo = this.lanewise(LSHR, (op == ROR) ? e : -e);
return hi.lanewise(OR, lo);
}
int opc = opCode(op);
return VectorSupport.broadcastInt(
opc, getClass(), short.class, length(),
@ -809,6 +815,10 @@ public abstract class ShortVector extends AbstractVector<Short> {
v.uOp((i, a) -> (short)(a >> n));
case VECTOR_OP_URSHIFT: return (v, n) ->
v.uOp((i, a) -> (short)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v, n) ->
v.uOp((i, a) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v, n) ->
v.uOp((i, a) -> rotateRight(a, (int)n));
default: return null;
}}));
}

View file

@ -551,9 +551,9 @@ public abstract class VectorOperators {
/** Produce {@code a>>>(n&(ESIZE*8-1))}. Integral only. */
public static final /*bitwise*/ Binary LSHR = binary("LSHR", ">>>", VectorSupport.VECTOR_OP_URSHIFT, VO_SHIFT);
/** Produce {@code rotateLeft(a,n)}. Integral only. */
public static final /*bitwise*/ Binary ROL = binary("ROL", "rotateLeft", -1 /*VectorSupport.VECTOR_OP_LROTATE*/, VO_SHIFT | VO_SPECIAL);
public static final /*bitwise*/ Binary ROL = binary("ROL", "rotateLeft", VectorSupport.VECTOR_OP_LROTATE, VO_SHIFT);
/** Produce {@code rotateRight(a,n)}. Integral only. */
public static final /*bitwise*/ Binary ROR = binary("ROR", "rotateRight", -1 /*VectorSupport.VECTOR_OP_RROTATE*/, VO_SHIFT | VO_SPECIAL);
public static final /*bitwise*/ Binary ROR = binary("ROR", "rotateRight", VectorSupport.VECTOR_OP_RROTATE, VO_SHIFT);
/** Produce {@code atan2(a,b)}. See Floating only.
* Not guaranteed to be semi-monotonic. See section "Operations on floating point vectors" above

View file

@ -384,6 +384,28 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
return maskFactory(bits);
}
#if[BITWISE]
/*package-private*/
@ForceInline
static $type$ rotateLeft($type$ a, int n) {
#if[intOrLong]
return $Boxtype$.rotateLeft(a, n);
#else[intOrLong]
return ($type$)((((($type$)a) & $Boxtype$.toUnsignedInt(($type$)-1)) << (n & $Boxtype$.SIZE-1)) | (((($type$)a) & $Boxtype$.toUnsignedInt(($type$)-1)) >>> ($Boxtype$.SIZE - (n & $Boxtype$.SIZE-1))));
#end[intOrLong]
}
/*package-private*/
@ForceInline
static $type$ rotateRight($type$ a, int n) {
#if[intOrLong]
return $Boxtype$.rotateRight(a, n);
#else[intOrLong]
return ($type$)((((($type$)a) & $Boxtype$.toUnsignedInt(($type$)-1)) >>> (n & $Boxtype$.SIZE-1)) | (((($type$)a) & $Boxtype$.toUnsignedInt(($type$)-1)) << ($Boxtype$.SIZE - (n & $Boxtype$.SIZE-1))));
#end[intOrLong]
}
#end[BITWISE]
/*package-private*/
@Override
abstract $Type$Species vspecies();
@ -657,12 +679,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
that = that.lanewise(AND, SHIFT_MASK);
}
#end[!FP]
if (op == ROR || op == ROL) { // FIXME: JIT should do this
$abstractvectortype$ neg = that.lanewise(NEG);
$abstractvectortype$ hi = this.lanewise(LSHL, (op == ROR) ? neg : that);
$abstractvectortype$ lo = this.lanewise(LSHR, (op == ROR) ? that : neg);
return hi.lanewise(OR, lo);
} else if (op == AND_NOT) {
if (op == AND_NOT) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -705,6 +722,10 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
v0.bOp(v1, (i, a, n) -> ($type$)(a >> n));
case VECTOR_OP_URSHIFT: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> ($type$)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v0, v1) ->
v0.bOp(v1, (i, a, n) -> rotateRight(a, (int)n));
#end[BITWISE]
#if[FP]
case VECTOR_OP_ATAN2: return (v0, v1) ->
@ -869,11 +890,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
assert(opKind(op, VO_SHIFT));
// As per shift specification for Java, mask the shift count.
e &= SHIFT_MASK;
if (op == ROR || op == ROL) { // FIXME: JIT should do this
$abstractvectortype$ hi = this.lanewise(LSHL, (op == ROR) ? -e : e);
$abstractvectortype$ lo = this.lanewise(LSHR, (op == ROR) ? e : -e);
return hi.lanewise(OR, lo);
}
int opc = opCode(op);
return VectorSupport.broadcastInt(
opc, getClass(), $type$.class, length(),
@ -886,6 +902,10 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
v.uOp((i, a) -> ($type$)(a >> n));
case VECTOR_OP_URSHIFT: return (v, n) ->
v.uOp((i, a) -> ($type$)((a & LSHR_SETUP_MASK) >>> n));
case VECTOR_OP_LROTATE: return (v, n) ->
v.uOp((i, a) -> rotateLeft(a, (int)n));
case VECTOR_OP_RROTATE: return (v, n) ->
v.uOp((i, a) -> rotateRight(a, (int)n));
default: return null;
}}));
}