Skip to content

Commit d1ad7c7

Browse files
committed
[GR-52654] [GR-52655] GraalWasm SIMD: less array allocations in interpreter and Buffer interop support.
PullRequest: graal/17553
2 parents 270e498 + ae09b5f commit d1ad7c7

File tree

9 files changed

+870
-656
lines changed

9 files changed

+870
-656
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
;;
2+
;; Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
3+
;; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
;;
5+
;; The Universal Permissive License (UPL), Version 1.0
6+
;;
7+
;; Subject to the condition set forth below, permission is hereby granted to any
8+
;; person obtaining a copy of this software, associated documentation and/or
9+
;; data (collectively the "Software"), free of charge and under any and all
10+
;; copyright rights in the Software, and any and all patent rights owned or
11+
;; freely licensable by each licensor hereunder covering either (i) the
12+
;; unmodified Software as contributed to or provided by such licensor, or (ii)
13+
;; the Larger Works (as defined below), to deal in both
14+
;;
15+
;; (a) the Software, and
16+
;;
17+
;; (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
;; one is included with the Software each a "Larger Work" to which the Software
19+
;; is contributed by such licensors),
20+
;;
21+
;; without restriction, including without limitation the rights to copy, create
22+
;; derivative works of, display, perform, and distribute the Software and make,
23+
;; use, sell, offer for sale, import, export, have made, and have sold the
24+
;; Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
;; either these or other terms.
26+
;;
27+
;; This license is subject to the following condition:
28+
;;
29+
;; The above copyright notice and either this complete permission notice or at a
30+
;; minimum a reference to the UPL must be included in all copies or substantial
31+
;; portions of the Software.
32+
;;
33+
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
;; SOFTWARE.
40+
;;
41+
(module
42+
(type $int_func (func (result i32)))
43+
(type $proc (func))
44+
45+
(global $iterations i32 (i32.const 2000000))
46+
47+
(memory $memory (export "memory") 0)
48+
49+
(func $run (export "run") (type $int_func)
50+
(local $i i32)
51+
;; Accumulator vector
52+
(local $acc v128)
53+
;; Increment vector
54+
(local $inc v128)
55+
(local.set $inc (v128.const i32x4 3 5 7 11))
56+
57+
(loop $bench_loop
58+
;; Perform int vector multiplication on the increment vector
59+
(local.set $inc (i32x4.mul (local.get $inc) (local.get $inc)))
60+
;; Perform int vector addition on the accumulator vector
61+
(local.set $acc (i32x4.add (local.get $acc) (local.get $inc)))
62+
63+
;; Increment loop counter and exit loop
64+
(local.set $i (i32.add (local.get $i) (i32.const 1)))
65+
(br_if $bench_loop (i32.lt_s (local.get $i) (global.get $iterations)))
66+
)
67+
68+
(i32x4.all_true (local.get $acc))
69+
)
70+
)

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/BinaryParser.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
18501850
state.popChecked(V128_TYPE);
18511851
load(state, V128_TYPE, 8, longMultiResult);
18521852
final byte laneIndex = read1();
1853-
if (Byte.toUnsignedInt(laneIndex) >= 16) {
1853+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.BYTE_LENGTH) {
18541854
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.load8_lane", Byte.toUnsignedInt(laneIndex));
18551855
}
18561856
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_LOAD8_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1861,7 +1861,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
18611861
state.popChecked(V128_TYPE);
18621862
load(state, V128_TYPE, 16, longMultiResult);
18631863
final byte laneIndex = read1();
1864-
if (Byte.toUnsignedInt(laneIndex) >= 8) {
1864+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.SHORT_LENGTH) {
18651865
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.load16_lane", Byte.toUnsignedInt(laneIndex));
18661866
}
18671867
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_LOAD16_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1872,7 +1872,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
18721872
state.popChecked(V128_TYPE);
18731873
load(state, V128_TYPE, 32, longMultiResult);
18741874
final byte laneIndex = read1();
1875-
if (Byte.toUnsignedInt(laneIndex) >= 4) {
1875+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.INT_LENGTH) {
18761876
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.load32_lane", Byte.toUnsignedInt(laneIndex));
18771877
}
18781878
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_LOAD32_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1883,7 +1883,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
18831883
state.popChecked(V128_TYPE);
18841884
load(state, V128_TYPE, 64, longMultiResult);
18851885
final byte laneIndex = read1();
1886-
if (Byte.toUnsignedInt(laneIndex) >= 2) {
1886+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.DOUBLE_LENGTH) {
18871887
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.load64_lane", Byte.toUnsignedInt(laneIndex));
18881888
}
18891889
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_LOAD64_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1893,7 +1893,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
18931893
case Instructions.VECTOR_V128_STORE8_LANE: {
18941894
store(state, V128_TYPE, 8, longMultiResult);
18951895
final byte laneIndex = read1();
1896-
if (Byte.toUnsignedInt(laneIndex) >= 16) {
1896+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.BYTE_LENGTH) {
18971897
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.store8_lane", Byte.toUnsignedInt(laneIndex));
18981898
}
18991899
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_STORE8_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1903,7 +1903,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
19031903
case Instructions.VECTOR_V128_STORE16_LANE: {
19041904
store(state, V128_TYPE, 16, longMultiResult);
19051905
final byte laneIndex = read1();
1906-
if (Byte.toUnsignedInt(laneIndex) >= 8) {
1906+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.SHORT_LENGTH) {
19071907
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.store16_lane", Byte.toUnsignedInt(laneIndex));
19081908
}
19091909
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_STORE16_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1913,7 +1913,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
19131913
case Instructions.VECTOR_V128_STORE32_LANE: {
19141914
store(state, V128_TYPE, 32, longMultiResult);
19151915
final byte laneIndex = read1();
1916-
if (Byte.toUnsignedInt(laneIndex) >= 4) {
1916+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.INT_LENGTH) {
19171917
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.store32_lane", Byte.toUnsignedInt(laneIndex));
19181918
}
19191919
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_STORE32_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1923,7 +1923,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
19231923
case Instructions.VECTOR_V128_STORE64_LANE: {
19241924
store(state, V128_TYPE, 64, longMultiResult);
19251925
final byte laneIndex = read1();
1926-
if (Byte.toUnsignedInt(laneIndex) >= 2) {
1926+
if (Byte.toUnsignedInt(laneIndex) >= Vector128.LONG_LENGTH) {
19271927
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for v128.store64_lane", Byte.toUnsignedInt(laneIndex));
19281928
}
19291929
state.addVectorMemoryLaneInstruction(Bytecode.VECTOR_V128_STORE64_LANE, (int) longMultiResult[0], longMultiResult[1], module.memoryHasIndexType64((int) longMultiResult[0]),
@@ -1939,7 +1939,7 @@ private void readNumericInstructions(ParserState state, int opcode) {
19391939
case Instructions.VECTOR_I8X16_SHUFFLE: {
19401940
final Vector128 indices = readUnsignedInt128();
19411941
for (byte index : indices.getBytes()) {
1942-
if (Byte.toUnsignedInt(index) >= 32) {
1942+
if (Byte.toUnsignedInt(index) >= 2 * Vector128.BYTE_LENGTH) {
19431943
fail(Failure.INVALID_LANE_INDEX, "Lane index %d out of bounds for i8x16.shuffle", Byte.toUnsignedInt(index));
19441944
}
19451945
}
@@ -3185,8 +3185,8 @@ private long readSignedInt64() {
31853185
}
31863186

31873187
private Vector128 readUnsignedInt128() {
3188-
byte[] bytes = new byte[16];
3189-
for (int i = 0; i < 16; i++) {
3188+
byte[] bytes = new byte[Vector128.BYTES];
3189+
for (int i = 0; i < Vector128.BYTES; i++) {
31903190
bytes[i] = read1();
31913191
}
31923192
return new Vector128(bytes);

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/BinaryStreamParser.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242

4343
import static com.oracle.truffle.api.nodes.ExplodeLoop.LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN;
4444

45-
import org.graalvm.wasm.api.Vector128;
4645
import org.graalvm.wasm.constants.GlobalModifier;
4746
import org.graalvm.wasm.exception.Failure;
4847
import org.graalvm.wasm.exception.WasmException;
@@ -464,11 +463,11 @@ public static void writeI64(byte[] bytecode, int offset, long value) {
464463
}
465464

466465
/**
467-
* Reads the {@link Vector128} value at the given bytecode offset.
466+
* Reads the 16 bytes of an {@code i128}/{@code v128} value at the given bytecode offset.
468467
*
469468
* @param bytecode The bytecode
470469
* @param offset The offset in the bytecode.
471-
* @return The {@link Vector128} value at the given bytecode offset.
470+
* @return The 16-byte {@code byte[]} read at the given bytecode offset.
472471
*/
473472
public static byte[] rawPeekI128(byte[] bytecode, int offset) {
474473
return Arrays.copyOfRange(bytecode, offset, offset + 16);

0 commit comments

Comments
 (0)