Skip to content
Merged
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
1 change: 1 addition & 0 deletions scripts/test/fuzzing.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
'cont_export_throw.wast',
'type-merging-cont.wast',
'remove-unused-module-elements-cont.wast',
'abstract-type-refining-cont.wast',
# TODO: fix split_wast() on tricky escaping situations like a string ending
# in \\" (the " is not escaped - there is an escaped \ before it)
'string-lifting-section.wast',
Expand Down
12 changes: 10 additions & 2 deletions src/ir/type-updating.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,10 @@ Type GlobalTypeRewriter::getTempType(Type type) {
}
if (type.isRef()) {
auto heapType = type.getHeapType();
if (auto it = typeIndices.find(heapType); it != typeIndices.end()) {
auto tempHeapType = getTempHeapType(heapType);
if (tempHeapType != heapType) {
return typeBuilder.getTempRefType(
typeBuilder[it->second], type.getNullability(), type.getExactness());
tempHeapType, type.getNullability(), type.getExactness());
}
// This type is not one that is eligible for optimizing. That is fine; just
// use it unmodified.
Expand All @@ -377,6 +378,13 @@ Type GlobalTypeRewriter::getTempType(Type type) {
WASM_UNREACHABLE("bad type");
}

HeapType GlobalTypeRewriter::getTempHeapType(HeapType type) {
if (auto it = typeIndices.find(type); it != typeIndices.end()) {
return typeBuilder[it->second];
}
return type;
}

Type GlobalTypeRewriter::getTempTupleType(Tuple tuple) {
return typeBuilder.getTempTupleType(tuple);
}
Expand Down
3 changes: 2 additions & 1 deletion src/ir/type-updating.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ class GlobalTypeRewriter {
// so that they can use a proper temp type of the TypeBuilder while modifying
// things.
Type getTempType(Type type);
HeapType getTempHeapType(HeapType type);
Type getTempTupleType(Tuple tuple);

using SignatureUpdates = std::unordered_map<HeapType, Signature>;
Expand Down Expand Up @@ -496,7 +497,7 @@ class TypeMapper : public GlobalTypeRewriter {
if (iter != mapping.end()) {
return iter->second;
}
return type;
return getTempHeapType(type);
}

Type getNewType(Type type) {
Expand Down
7 changes: 5 additions & 2 deletions src/wasm-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -805,9 +805,12 @@ struct TypeBuilder {
setHeapType(i, wasm::Array(elem));
return;
}
case HeapTypeKind::Cont:
setHeapType(i, Continuation(map(type.getContinuation().type)));
case HeapTypeKind::Cont: {
auto cont = type.getContinuation();
cont.type = map(cont.type);
setHeapType(i, cont);
return;
}
case HeapTypeKind::Basic:
WASM_UNREACHABLE("unexpected kind");
}
Expand Down
3 changes: 3 additions & 0 deletions src/wasm/wasm-type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1324,6 +1324,9 @@ FeatureSet HeapType::getFeatures() const {

// In addition, scan their non-ref children, to add dependencies on
// things like SIMD.
// XXX This will not scan HeapType children that are not also children of
// Type children, which happens with Continuation (has a HeapType
// child that is not a Type).
Comment on lines +1327 to +1329
Copy link
Member

Choose a reason for hiding this comment

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

It's unclear to me whether this is a problem that needs to be fixed or just a helpful note to inform any future changes.

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 think this will be a problem if we have features that depend on it. Atm I think we don't.

I was just auditing this code and realized that this was a potential future bug. And, regardless, the right thing here is to scan heap types, not types.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, sounds good.

for (auto child : heapType.getTypeChildren()) {
if (!child.isRef()) {
feats |= child.getFeatures();
Expand Down
43 changes: 43 additions & 0 deletions test/lit/passes/abstract-type-refining-cont.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.

;; RUN: foreach %s %t wasm-opt --abstract-type-refining -all --closed-world -S -o - | filecheck %s

;; $uncreated is never created, so we optimize and rebuild types. While doing
;; so we should not get confused as we copy the continuation type, which
;; should end up referring properly to the corresponding func type.

(module
(rec
;; CHECK: (rec
;; CHECK-NEXT: (type $cont (cont $func))

;; CHECK: (type $func (func))
(type $func (func))
(type $cont (cont $func))

(type $uncreated (struct))
)

;; CHECK: (elem declare func $func)

;; CHECK: (func $func (type $func)
;; CHECK-NEXT: )
(func $func (type $func)
)

;; CHECK: (func $test (type $func)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (cont.new $cont
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $test (type $func)
(drop
(cont.new $cont
(ref.func $func)
)
)
)
)

9 changes: 3 additions & 6 deletions test/lit/passes/type-merging-cont.wast
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,12 @@
;; CHECK: (rec
;; CHECK-NEXT: (type $f (func))
(type $f (func))
;; CHECK: (type $f_0 (func))

;; CHECK: (type $k (cont $f_0))
;; CHECK: (type $k (cont $f))
(type $k (cont $f))

;; CHECK: (type $f-i32 (func (result i32)))
(type $f-i32 (func (result i32)))
;; CHECK: (type $f-i32_0 (func (result i32)))

;; CHECK: (type $k-i32 (cont $f-i32_0))
;; CHECK: (type $k-i32 (cont $f-i32))
(type $k-i32 (cont $f-i32))

(rec
Expand Down
Loading