Skip to content

Update TypeUpdating for exact heap types #7452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
1 change: 1 addition & 0 deletions scripts/test/fuzzing.py
Original file line number Diff line number Diff line change
@@ -115,6 +115,7 @@
'custom-descriptors.wast',
# TODO: fuzzer support for exact heap types
'exact.wast',
'remove-unused-types-exact.wast',
]


8 changes: 7 additions & 1 deletion src/ir/type-updating.cpp
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ GlobalTypeRewriter::TypeMap GlobalTypeRewriter::rebuildTypes(

// Create the temporary heap types.
i = 0;
auto map = [&](HeapType type) -> HeapType {
auto map = [&](HeapTypeDef type) -> HeapType {
if (auto it = typeIndices.find(type); it != typeIndices.end()) {
return typeBuilder[it->second];
}
@@ -226,6 +226,12 @@ void GlobalTypeRewriter::mapTypes(const TypeMap& oldToNewTypes) {
if (iter != oldToNewTypes.end()) {
return iter->second;
}
if (type.isExact()) {
iter = oldToNewTypes.find(type.with(Inexact));
if (iter != oldToNewTypes.end()) {
return iter->second.with(Exact);
}
}
Copy link
Member

Choose a reason for hiding this comment

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

It might be a little more efficient and perhaps clear if we put the normal path and the exact path in separate if arms? That is, there is no need to try the normal path first before the exact one, if we are exact, IIANM

Copy link
Member Author

Choose a reason for hiding this comment

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

I was thinking that it would be nice to have the flexibility to map exact types to inexact types, but I think YAGNI is the correct response here. Will fix.

return type;
}

14 changes: 8 additions & 6 deletions src/wasm-type.h
Original file line number Diff line number Diff line change
@@ -729,9 +729,9 @@ struct TypeBuilder {
void setHeapType(size_t i, Array array);

// Sets the heap type at index `i` to be a copy of the given heap type with
// its referenced HeapTypes to be replaced according to the provided mapping
// its referenced HeapTypeDef to be replaced according to the provided mapping
// function.
template<typename F> void copyHeapType(size_t i, HeapType type, F map) {
template<typename F> void copyHeapType(size_t i, HeapTypeDef type, F map) {
assert(!type.isBasic());
if (auto super = type.getDeclaredSuperType()) {
setSubType(i, map(*super));
@@ -750,7 +750,9 @@ struct TypeBuilder {
return t;
}
assert(t.isRef());
return getTempRefType(map(t.getHeapType()), t.getNullability());
auto ht = t.getHeapType();
return getTempRefType(map(ht).with(ht.getExactness()),
t.getNullability());
};
auto copyType = [&](Type t) -> Type {
if (t.isTuple()) {
@@ -797,7 +799,7 @@ struct TypeBuilder {

// Gets the temporary HeapType at index `i`. This HeapType should only be used
// to construct temporary Types using the methods below.
HeapType getTempHeapType(size_t i);
HeapTypeDef getTempHeapType(size_t i);

// Gets a temporary type or heap type for use in initializing the
// TypeBuilder's HeapTypes. For Ref types, the HeapType may be a temporary
@@ -878,7 +880,7 @@ struct TypeBuilder {
struct Entry {
TypeBuilder& builder;
size_t index;
operator HeapType() const { return builder.getTempHeapType(index); }
operator HeapTypeDef() const { return builder.getTempHeapType(index); }
Entry& operator=(Signature signature) {
builder.setHeapType(index, signature);
return *this;
@@ -919,7 +921,7 @@ struct TypeBuilder {
builder.setShared(index, share);
return *this;
}
template<typename F> Entry& copy(HeapType type, F map) {
template<typename F> Entry& copy(HeapTypeDef type, F map) {
builder.copyHeapType(index, type, map);
return *this;
}
2 changes: 1 addition & 1 deletion src/wasm/wasm-type.cpp
Original file line number Diff line number Diff line change
@@ -2278,7 +2278,7 @@ void TypeBuilder::setHeapType(size_t i, Array array) {
impl->entries[i].set(array);
}

HeapType TypeBuilder::getTempHeapType(size_t i) {
HeapTypeDef TypeBuilder::getTempHeapType(size_t i) {
assert(i < size() && "index out of bounds");
return impl->entries[i].get();
}
16 changes: 16 additions & 0 deletions test/lit/passes/remove-unused-types-exact.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.

;; RUN: wasm-opt -all %s --closed-world --remove-unused-types -S -o - | filecheck %s

;; Check that exactness is preserved through type updating and that the
;; underlying heap types are actually updated.

(module
(rec
(type $unused (struct))
;; CHECK: (type $used (struct (field (ref null $used)) (field (ref (exact $used)))))
(type $used (struct (field (ref null $used) (ref (exact $used)))))
)
;; CHECK: (global $g (ref null (exact $used)) (ref.null none))
(global $g (ref null (exact $used)) (ref.null none))
)