Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
59 changes: 59 additions & 0 deletions src/passes/OptimizeInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2829,6 +2829,65 @@ 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.isShared() || ht.isBottom()) {
return false;
}
if (ht.isStruct() || ht.isArray()) {
return true;
}
if (ht.isBasic()) {
switch (ht.getBasic(Unshared)) {
case HeapType::any:
case HeapType::eq:
case HeapType::struct_:
case HeapType::array:
return true;
default:
return false;
}
}
return false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this work?

Suggested change
if (!ht.isShared() || ht.isBottom()) {
return false;
}
if (ht.isStruct() || ht.isArray()) {
return true;
}
if (ht.isBasic()) {
switch (ht.getBasic(Unshared)) {
case HeapType::any:
case HeapType::eq:
case HeapType::struct_:
case HeapType::array:
return true;
default:
return false;
}
}
return false;
if (!ht.isShared()) {
return false;
}
return HeapType::isSubType(ht, HeapType::any.getShared(true));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, almost. Just have to exclude bottom types as well.

};

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