8271368: [BACKOUT] JDK-8266054 VectorAPI rotate operation optimization

Reviewed-by: dholmes, iklam
This commit is contained in:
Vladimir Kozlov 2021-07-28 06:58:36 +00:00
parent ecd445562f
commit d7b5cb6889
57 changed files with 219 additions and 4380 deletions

View file

@ -380,18 +380,6 @@ 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();
@ -612,7 +600,12 @@ public abstract class ByteVector extends AbstractVector<Byte> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == AND_NOT) {
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) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -653,10 +646,6 @@ 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;
}}));
}
@ -803,6 +792,11 @@ 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(),
@ -815,10 +809,6 @@ 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,7 +380,6 @@ public abstract class DoubleVector extends AbstractVector<Double> {
return maskFactory(bits);
}
/*package-private*/
@Override
abstract DoubleSpecies vspecies();

View file

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

View file

@ -380,18 +380,6 @@ 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();
@ -612,7 +600,12 @@ public abstract class IntVector extends AbstractVector<Integer> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == AND_NOT) {
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) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -653,10 +646,6 @@ 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;
}}));
}
@ -803,6 +792,11 @@ 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(),
@ -815,10 +809,6 @@ 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,18 +380,6 @@ 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();
@ -570,7 +558,12 @@ public abstract class LongVector extends AbstractVector<Long> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == AND_NOT) {
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) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -611,10 +604,6 @@ 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;
}}));
}
@ -721,6 +710,11 @@ 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(),
@ -733,10 +727,6 @@ 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,18 +380,6 @@ 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();
@ -612,7 +600,12 @@ public abstract class ShortVector extends AbstractVector<Short> {
// This allows the JIT to ignore some ISA details.
that = that.lanewise(AND, SHIFT_MASK);
}
if (op == AND_NOT) {
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) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -653,10 +646,6 @@ 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;
}}));
}
@ -803,6 +792,11 @@ 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(),
@ -815,10 +809,6 @@ 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", VectorSupport.VECTOR_OP_LROTATE, VO_SHIFT);
public static final /*bitwise*/ Binary ROL = binary("ROL", "rotateLeft", -1 /*VectorSupport.VECTOR_OP_LROTATE*/, VO_SHIFT | VO_SPECIAL);
/** Produce {@code rotateRight(a,n)}. Integral only. */
public static final /*bitwise*/ Binary ROR = binary("ROR", "rotateRight", VectorSupport.VECTOR_OP_RROTATE, VO_SHIFT);
public static final /*bitwise*/ Binary ROR = binary("ROR", "rotateRight", -1 /*VectorSupport.VECTOR_OP_RROTATE*/, VO_SHIFT | VO_SPECIAL);
/** 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,28 +384,6 @@ 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();
@ -679,7 +657,12 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
that = that.lanewise(AND, SHIFT_MASK);
}
#end[!FP]
if (op == AND_NOT) {
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) {
// FIXME: Support this in the JIT.
that = that.lanewise(NOT);
op = AND;
@ -722,10 +705,6 @@ 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) ->
@ -890,6 +869,11 @@ 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(),
@ -902,10 +886,6 @@ 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;
}}));
}