Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,14 +578,19 @@ struct NullInstrParserCtx {
MemoryOrder) {
return Ok{};
}
template<typename HeapTypeT>
Result<> makeArrayLoad(
Index, const std::vector<Annotation>&, Type, int, bool, HeapTypeT) {
template<typename MemargT, typename HeapTypeT>
Result<> makeArrayLoad(Index,
const std::vector<Annotation>&,
Type,
int,
bool,
MemargT,
HeapTypeT) {
return Ok{};
}
template<typename HeapTypeT>
Result<>
makeArrayStore(Index, const std::vector<Annotation>&, Type, int, HeapTypeT) {
template<typename MemargT, typename HeapTypeT>
Result<> makeArrayStore(
Index, const std::vector<Annotation>&, Type, int, MemargT, HeapTypeT) {
return Ok{};
}
Result<> makeAtomicRMW(Index,
Expand Down Expand Up @@ -2388,17 +2393,23 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx>, AnnotationParserCtx {
Type type,
int bytes,
bool signed_,
Memarg memarg,
HeapTypeT arrayType) {
return withLoc(pos,
irBuilder.makeArrayLoad(arrayType, bytes, signed_, type));
return withLoc(
pos,
irBuilder.makeArrayLoad(
arrayType, bytes, signed_, memarg.offset, memarg.align, type));
}

Result<> makeArrayStore(Index pos,
const std::vector<Annotation>& annotations,
Type type,
int bytes,
Memarg memarg,
HeapTypeT arrayType) {
return withLoc(pos, irBuilder.makeArrayStore(arrayType, bytes, type));
return withLoc(pos,
irBuilder.makeArrayStore(
arrayType, bytes, memarg.offset, memarg.align, type));
}

Result<> makeAtomicRMW(Index pos,
Expand Down
26 changes: 19 additions & 7 deletions src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1807,22 +1807,27 @@ Result<> makeLoad(Ctx& ctx,
bool signed_,
int bytes,
bool isAtomic) {
auto mem = maybeMemidx(ctx);
CHECK_ERR(mem);

if (ctx.in.takeSExprStart("type"sv)) {
if (mem) {
return ctx.in.err("memory index is not allowed for array load");
}
auto arrayType = typeidx(ctx);
CHECK_ERR(arrayType);

if (!ctx.in.takeRParen()) {
return ctx.in.err("expected end of type use");
}

auto arg = memarg(ctx, bytes);
CHECK_ERR(arg);

return ctx.makeArrayLoad(
pos, annotations, type, bytes, signed_, *arrayType);
pos, annotations, type, bytes, signed_, *arg, *arrayType);
}

auto mem = maybeMemidx(ctx);
CHECK_ERR(mem);

// We could only parse this when `isAtomic`, but this way gives a clearer
// error when a memorder is given for non-atomic operations
// since the next token can never be mistaken for a `memOrder`.
Expand Down Expand Up @@ -1855,18 +1860,25 @@ Result<> makeStore(Ctx& ctx,
Type type,
int bytes,
bool isAtomic) {
auto mem = maybeMemidx(ctx);
CHECK_ERR(mem);

if (ctx.in.takeSExprStart("type"sv)) {
if (mem) {
return ctx.in.err("memory index is not allowed for array store");
}
auto arrayType = typeidx(ctx);
CHECK_ERR(arrayType);

if (!ctx.in.takeRParen()) {
return ctx.in.err("expected end of type use");
}

return ctx.makeArrayStore(pos, annotations, type, bytes, *arrayType);
auto arg = memarg(ctx, bytes);
CHECK_ERR(arg);

return ctx.makeArrayStore(pos, annotations, type, bytes, *arg, *arrayType);
}
auto mem = maybeMemidx(ctx);
CHECK_ERR(mem);

auto maybeOrder = maybeMemOrder(ctx);
CHECK_ERR(maybeOrder);
Expand Down
4 changes: 4 additions & 0 deletions src/passes/DeAlign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ struct DeAlign : public WalkerPass<PostWalker<DeAlign>> {
void visitStore(Store* curr) { curr->align = 1; }

void visitSIMDLoad(SIMDLoad* curr) { curr->align = 1; }

void visitArrayLoad(ArrayLoad* curr) { curr->align = 1; }

void visitArrayStore(ArrayStore* curr) { curr->align = 1; }
};

Pass* createDeAlignPass() { return new DeAlign(); }
Expand Down
12 changes: 12 additions & 0 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2479,6 +2479,12 @@ struct PrintExpressionContents
printMinor(o, "type ");
printHeapTypeName(curr->ref->type.getHeapType());
o << ')';
if (curr->offset) {
o << " offset=" << curr->offset;
}
if (curr->align != curr->bytes) {
o << " align=" << curr->align;
}
}

void visitArrayStore(ArrayStore* curr) {
Expand All @@ -2492,6 +2498,12 @@ struct PrintExpressionContents
printMinor(o, "type ");
printHeapTypeName(curr->ref->type.getHeapType());
o << ')';
if (curr->offset) {
o << " offset=" << curr->offset;
}
if (curr->align != curr->bytes) {
o << " align=" << curr->align;
}
}
void visitArrayLen(ArrayLen* curr) { printMedium(o, "array.len"); }
void visitArrayCopy(ArrayCopy* curr) {
Expand Down
8 changes: 8 additions & 0 deletions src/wasm-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1162,12 +1162,16 @@ class Builder {
}
ArrayLoad* makeArrayLoad(unsigned bytes,
bool signed_,
Address offset,
Address align,
Expression* ref,
Expression* index,
Type type) {
auto* ret = wasm.allocator.alloc<ArrayLoad>();
ret->bytes = bytes;
ret->signed_ = signed_;
ret->offset = offset;
ret->align = align ? align : Address(bytes);
ret->ref = ref;
ret->index = index;
ret->type = type;
Expand All @@ -1176,11 +1180,15 @@ class Builder {
}

ArrayStore* makeArrayStore(unsigned bytes,
Address offset,
Address align,
Expression* ref,
Expression* index,
Expression* value) {
auto* ret = wasm.allocator.alloc<ArrayStore>();
ret->bytes = bytes;
ret->offset = offset;
ret->align = align ? align : Address(bytes);
ret->ref = ref;
ret->index = index;
ret->value = value;
Expand Down
4 changes: 4 additions & 0 deletions src/wasm-delegations-fields.def
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,8 @@ DELEGATE_FIELD_CASE_END(ArraySet)
DELEGATE_FIELD_CASE_START(ArrayLoad)
DELEGATE_FIELD_CHILD(ArrayLoad, index)
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayLoad, ref)
DELEGATE_FIELD_ADDRESS(ArrayLoad, offset)
DELEGATE_FIELD_ADDRESS(ArrayLoad, align)
DELEGATE_FIELD_INT(ArrayLoad, bytes)
DELEGATE_FIELD_INT(ArrayLoad, signed_)
DELEGATE_FIELD_TYPE(ArrayLoad, type)
Expand All @@ -771,6 +773,8 @@ DELEGATE_FIELD_CASE_START(ArrayStore)
DELEGATE_FIELD_CHILD(ArrayStore, value)
DELEGATE_FIELD_CHILD(ArrayStore, index)
DELEGATE_FIELD_IMMEDIATE_TYPED_CHILD(ArrayStore, ref)
DELEGATE_FIELD_ADDRESS(ArrayStore, offset)
DELEGATE_FIELD_ADDRESS(ArrayStore, align)
DELEGATE_FIELD_INT(ArrayStore, bytes)
DELEGATE_FIELD_CASE_END(ArrayStore)

Expand Down
14 changes: 11 additions & 3 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,17 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
Result<> makeArrayNewFixed(HeapType type, uint32_t arity);
Result<> makeArrayGet(HeapType type, bool signed_, MemoryOrder order);
Result<> makeArraySet(HeapType type, MemoryOrder order);
Result<>
makeArrayLoad(HeapType arrayType, unsigned bytes, bool signed_, Type type);
Result<> makeArrayStore(HeapType arrayType, unsigned bytes, Type type);
Result<> makeArrayLoad(HeapType arrayType,
unsigned bytes,
bool signed_,
Address offset,
Address align,
Type type);
Result<> makeArrayStore(HeapType arrayType,
unsigned bytes,
Address offset,
Address align,
Type type);
Result<> makeArrayLen();
Result<> makeArrayCopy(HeapType destType, HeapType srcType);
Result<> makeArrayFill(HeapType type);
Expand Down
4 changes: 4 additions & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,8 @@ class ArrayLoad : public SpecificExpression<Expression::ArrayLoadId> {

uint8_t bytes;
bool signed_ = false;
Address offset = 0;
Address align = 0;
Expression* ref;
Expression* index;

Expand All @@ -1930,6 +1932,8 @@ class ArrayStore : public SpecificExpression<Expression::ArrayStoreId> {
ArrayStore(MixedArena& allocator) {}

uint8_t bytes;
Address offset = 0;
Address align = 0;
Expression* ref;
Expression* index;
Expression* value;
Expand Down
18 changes: 8 additions & 10 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3394,7 +3394,8 @@ Result<> WasmBinaryReader::readLoad(unsigned bytes, bool signed_, Type type) {
auto [mem, align, offset, backing] = getMemarg();
if (backing == BackingType::Array) {
HeapType arrayType = getIndexedHeapType();
return builder.makeArrayLoad(arrayType, bytes, signed_, type);
return builder.makeArrayLoad(
arrayType, bytes, signed_, offset, align, type);
}
return builder.makeLoad(bytes, signed_, offset, align, type, mem);
}
Expand All @@ -3403,7 +3404,7 @@ Result<> WasmBinaryReader::readStore(unsigned bytes, Type type) {
auto [mem, align, offset, backing] = getMemarg();
if (backing == BackingType::Array) {
HeapType arrayType = getIndexedHeapType();
return builder.makeArrayStore(arrayType, bytes, type);
return builder.makeArrayStore(arrayType, bytes, offset, align, type);
}
return builder.makeStore(bytes, offset, align, type, mem);
}
Expand Down Expand Up @@ -4111,12 +4112,10 @@ Result<> WasmBinaryReader::readInst() {
return builder.makeElemDrop(elem);
}
case BinaryConsts::F32_F16LoadMem: {
auto [mem, align, offset, backing] = getMemarg();
return builder.makeLoad(2, false, offset, align, Type::f32, mem);
return readLoad(2, false, Type::f32);
}
case BinaryConsts::F32_F16StoreMem: {
auto [mem, align, offset, backing] = getMemarg();
return builder.makeStore(2, offset, align, Type::f32, mem);
return readStore(2, Type::f32);
}
}
return Err{"unknown misc operation: " + std::to_string(op)};
Expand Down Expand Up @@ -4666,12 +4665,10 @@ Result<> WasmBinaryReader::readInst() {
case BinaryConsts::V128Const:
return builder.makeConst(getVec128Literal());
case BinaryConsts::V128Store: {
auto [mem, align, offset, backing] = getMemarg();
return builder.makeStore(16, offset, align, Type::v128, mem);
return readStore(16, Type::v128);
}
case BinaryConsts::V128Load: {
auto [mem, align, offset, backing] = getMemarg();
return builder.makeLoad(16, false, offset, align, Type::v128, mem);
return readLoad(16, false, Type::v128);
}
case BinaryConsts::V128Load8Splat: {
auto [mem, align, offset, backing] = getMemarg();
Expand Down Expand Up @@ -5759,6 +5756,7 @@ WasmBinaryReader::readMemoryAccess(bool isAtomic, bool isRMW) {
throwError(
"Memory index and memory order are not allowed for array backing.");
}
offset = getU32LEB();
} else {
WASM_UNREACHABLE("Invalid backing type");
}
Expand Down
15 changes: 11 additions & 4 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2463,8 +2463,11 @@ Result<> IRBuilder::makeArraySet(HeapType type, MemoryOrder order) {
return Ok{};
}

Result<>
IRBuilder::makeArrayStore(HeapType arrayType, unsigned bytes, Type type) {
Result<> IRBuilder::makeArrayStore(HeapType arrayType,
unsigned bytes,
Address offset,
Address align,
Type type) {
if (!arrayType.isArray()) {
return Err{"expected array type annotation on array store"};
}
Expand All @@ -2473,13 +2476,16 @@ IRBuilder::makeArrayStore(HeapType arrayType, unsigned bytes, Type type) {
CHECK_ERR(ChildPopper{*this}.visitArrayStore(&curr, arrayType, type));

CHECK_ERR(validateTypeAnnotation(arrayType, curr.ref));
push(builder.makeArrayStore(bytes, curr.ref, curr.index, curr.value));
push(builder.makeArrayStore(
bytes, offset, align, curr.ref, curr.index, curr.value));
return Ok{};
}

Result<> IRBuilder::makeArrayLoad(HeapType arrayType,
unsigned bytes,
bool signed_,
Address offset,
Address align,
Type type) {
if (!arrayType.isArray()) {
return Err{"expected array type annotation on array load"};
Expand All @@ -2489,7 +2495,8 @@ Result<> IRBuilder::makeArrayLoad(HeapType arrayType,
CHECK_ERR(ChildPopper{*this}.visitArrayLoad(&curr, arrayType));

CHECK_ERR(validateTypeAnnotation(arrayType, curr.ref));
push(builder.makeArrayLoad(bytes, signed_, curr.ref, curr.index, type));
push(builder.makeArrayLoad(
bytes, signed_, offset, align, curr.ref, curr.index, type));
return Ok{};
}

Expand Down
16 changes: 14 additions & 2 deletions src/wasm/wasm-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2828,24 +2828,36 @@ void BinaryInstWriter::visitArraySet(ArraySet* curr) {
}

void BinaryInstWriter::visitArrayLoad(ArrayLoad* curr) {
if (curr->type == Type::unreachable) {
return;
}
if (curr->ref->type.isNull()) {
emitUnreachable();
return;
}
emitLoadOpcode(curr->bytes, curr->signed_, curr->type);
uint32_t alignmentBits = BinaryConsts::HasBackingArrayMask;
uint32_t alignmentBits =
Bits::log2(curr->align ? curr->align : Address(curr->bytes)) |
BinaryConsts::HasBackingArrayMask;
o << U32LEB(alignmentBits);
o << U32LEB(curr->offset);
parent.writeIndexedHeapType(curr->ref->type.getHeapType());
}

void BinaryInstWriter::visitArrayStore(ArrayStore* curr) {
if (curr->type == Type::unreachable) {
return;
}
if (curr->ref->type.isNull()) {
emitUnreachable();
return;
}
emitStoreOpcode(curr->bytes, curr->value->type);
uint32_t alignmentBits = BinaryConsts::HasBackingArrayMask;
uint32_t alignmentBits =
Bits::log2(curr->align ? curr->align : Address(curr->bytes)) |
BinaryConsts::HasBackingArrayMask;
o << U32LEB(alignmentBits);
o << U32LEB(curr->offset);
parent.writeIndexedHeapType(curr->ref->type.getHeapType());
}

Expand Down
Loading
Loading