Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions scripts/test/fuzzing.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
'waitqueue.wast',
'gufa-waitqueue.wast',
'publish.wast',
'optimize-instructions-publish.wast',
# TODO: fix handling of the non-utf8 names here
'name-high-bytes.wast',
# JS interop testcases have complex js-wasm interactions
Expand Down
2 changes: 2 additions & 0 deletions src/ir/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ inline Expression** getImmediateFallthroughPtr(
passOptions, module, br->ref, br->desc))) {
return &br->ref;
}
} else if (auto* pub = curr->dynCast<Publish>()) {
return &pub->ref;
}
return currp;
}
Expand Down
46 changes: 46 additions & 0 deletions src/passes/OptimizeInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

#include "call-utils.h"
#include "support/utilities.h"
#include "wasm-type.h"

// TODO: Use the new sign-extension opcodes where appropriate. This needs to be
// conditionalized on the availability of atomics.
Expand Down Expand Up @@ -2829,6 +2830,51 @@ struct OptimizeInstructions
trapOnNull(curr, curr->ref);
}

void visitPublish(Publish* curr) {
if (curr->type == Type::unreachable) {
return;
}

// Publish of a reference that cannot be a shared array or struct can be
// removed.
auto canBeSharedArrayOrStruct = [](Type type) {
if (!type.isRef()) {
return false;
}
auto ht = type.getHeapType();
if (ht.isBottom() || ht.isMaybeShared(HeapType::i31)) {
return false;
}
return HeapType::isSubType(ht, HeapTypes::any.getBasic(Shared));
};

if (!canBeSharedArrayOrStruct(getFallthroughType(curr->ref))) {
replaceCurrent(curr->ref);
return;
}

auto isAllocation = [](Expression* expr) {
return expr->is<StructNew>() || expr->is<ArrayNew>() ||
expr->is<ArrayNewData>() || expr->is<ArrayNewElem>() ||
expr->is<ArrayNewFixed>();
};

// Publish of publish or of a struct/array allocation can be removed.
Expression* fallthrough = curr->ref;
while (true) {
if (fallthrough->is<Publish>() || isAllocation(fallthrough)) {
replaceCurrent(curr->ref);
return;
}
auto* next = Properties::getImmediateFallthrough(
fallthrough, getPassOptions(), *getModule());
if (next == fallthrough) {
break;
}
fallthrough = next;
}
}

void visitTupleExtract(TupleExtract* curr) {
if (curr->type == Type::unreachable) {
return;
Expand Down
Loading
Loading