mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8271366: [REDO] JDK-8266054 VectorAPI rotate operation optimization
Reviewed-by: sviswanathan, psandoz
This commit is contained in:
parent
4d4ba5c5b4
commit
020aec5318
57 changed files with 4376 additions and 219 deletions
|
@ -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;
|
||||
}}));
|
||||
}
|
||||
|
|
|
@ -380,6 +380,7 @@ public abstract class DoubleVector extends AbstractVector<Double> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract DoubleSpecies vspecies();
|
||||
|
|
|
@ -380,6 +380,7 @@ public abstract class FloatVector extends AbstractVector<Float> {
|
|||
return maskFactory(bits);
|
||||
}
|
||||
|
||||
|
||||
/*package-private*/
|
||||
@Override
|
||||
abstract FloatSpecies vspecies();
|
||||
|
|
|
@ -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;
|
||||
}}));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}}));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}}));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}}));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue