summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-stack.h5
-rw-r--r--src/wasm/wasm-stack.cpp43
-rw-r--r--test/exception-handling.wast.fromBinary11
-rw-r--r--test/exception-handling.wast.fromBinary.noDebugInfo11
-rw-r--r--test/lit/multivalue.wast86
5 files changed, 103 insertions, 53 deletions
diff --git a/src/wasm-stack.h b/src/wasm-stack.h
index 1f66212ad..03ec4eef5 100644
--- a/src/wasm-stack.h
+++ b/src/wasm-stack.h
@@ -148,11 +148,6 @@ private:
InsertOrderedMap<Type, Index> scratchLocals;
void countScratchLocals();
void setScratchLocals();
-
- // local.get, local.tee, and glboal.get expressions that will be followed by
- // tuple.extracts. We can optimize these by getting only the local for the
- // extracted index.
- std::unordered_map<Expression*, Index> extractedGets;
};
// Takes binaryen IR and converts it to something else (binary or stack IR)
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index c3d53f126..1ddf69d41 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -87,13 +87,6 @@ void BinaryInstWriter::visitCallIndirect(CallIndirect* curr) {
}
void BinaryInstWriter::visitLocalGet(LocalGet* curr) {
- if (auto it = extractedGets.find(curr); it != extractedGets.end()) {
- // We have a tuple of locals to get, but we will only end up using one of
- // them, so we can just emit that one.
- o << int8_t(BinaryConsts::LocalGet)
- << U32LEB(mappedLocals[std::make_pair(curr->index, it->second)]);
- return;
- }
size_t numValues = func->getLocalType(curr->index).size();
for (Index i = 0; i < numValues; ++i) {
o << int8_t(BinaryConsts::LocalGet)
@@ -103,28 +96,14 @@ void BinaryInstWriter::visitLocalGet(LocalGet* curr) {
void BinaryInstWriter::visitLocalSet(LocalSet* curr) {
size_t numValues = func->getLocalType(curr->index).size();
- // If this is a tuple, set all the elements with nonzero index.
for (Index i = numValues - 1; i >= 1; --i) {
o << int8_t(BinaryConsts::LocalSet)
<< U32LEB(mappedLocals[std::make_pair(curr->index, i)]);
}
if (!curr->isTee()) {
- // This is not a tee, so just finish setting the values.
o << int8_t(BinaryConsts::LocalSet)
<< U32LEB(mappedLocals[std::make_pair(curr->index, 0)]);
- } else if (auto it = extractedGets.find(curr); it != extractedGets.end()) {
- // We only need to get the single extracted value.
- if (it->second == 0) {
- o << int8_t(BinaryConsts::LocalTee)
- << U32LEB(mappedLocals[std::make_pair(curr->index, 0)]);
- } else {
- o << int8_t(BinaryConsts::LocalSet)
- << U32LEB(mappedLocals[std::make_pair(curr->index, 0)]);
- o << int8_t(BinaryConsts::LocalGet)
- << U32LEB(mappedLocals[std::make_pair(curr->index, it->second)]);
- }
} else {
- // We need to get all the values.
o << int8_t(BinaryConsts::LocalTee)
<< U32LEB(mappedLocals[std::make_pair(curr->index, 0)]);
for (Index i = 1; i < numValues; ++i) {
@@ -135,14 +114,8 @@ void BinaryInstWriter::visitLocalSet(LocalSet* curr) {
}
void BinaryInstWriter::visitGlobalGet(GlobalGet* curr) {
- Index index = parent.getGlobalIndex(curr->name);
- if (auto it = extractedGets.find(curr); it != extractedGets.end()) {
- // We have a tuple of globals to get, but we will only end up using one of
- // them, so we can just emit that one.
- o << int8_t(BinaryConsts::GlobalGet) << U32LEB(index + it->second);
- return;
- }
// Emit a global.get for each element if this is a tuple global
+ Index index = parent.getGlobalIndex(curr->name);
size_t numValues = curr->type.size();
for (Index i = 0; i < numValues; ++i) {
o << int8_t(BinaryConsts::GlobalGet) << U32LEB(index + i);
@@ -1997,10 +1970,6 @@ void BinaryInstWriter::visitTupleMake(TupleMake* curr) {
}
void BinaryInstWriter::visitTupleExtract(TupleExtract* curr) {
- if (extractedGets.count(curr->tuple)) {
- // We already have just the extracted value on the stack.
- return;
- }
size_t numVals = curr->tuple->type.size();
// Drop all values after the one we want
for (size_t i = curr->index + 1; i < numVals; ++i) {
@@ -2537,7 +2506,6 @@ void BinaryInstWriter::mapLocalsAndEmitHeader() {
}
}
setScratchLocals();
-
o << U32LEB(numLocalsByType.size());
for (auto& localType : localTypes) {
o << U32LEB(numLocalsByType.at(localType));
@@ -2564,15 +2532,6 @@ void BinaryInstWriter::countScratchLocals() {
for (auto& [type, _] : scratchLocals) {
noteLocalType(type);
}
- // While we have all the tuple.extracts, also find extracts of local.gets,
- // local.tees, and global.gets that we can optimize.
- for (auto* extract : extracts.list) {
- auto* tuple = extract->tuple;
- if (tuple->is<LocalGet>() || tuple->is<LocalSet>() ||
- tuple->is<GlobalGet>()) {
- extractedGets.insert({tuple, extract->index});
- }
- }
}
void BinaryInstWriter::setScratchLocals() {
diff --git a/test/exception-handling.wast.fromBinary b/test/exception-handling.wast.fromBinary
index 44bd2e5c3..d5cc2c179 100644
--- a/test/exception-handling.wast.fromBinary
+++ b/test/exception-handling.wast.fromBinary
@@ -20,6 +20,7 @@
(local $1 i64)
(local $2 (i32 i64))
(local $3 i32)
+ (local $4 i32)
(try $label$3
(do
(throw $e-i32
@@ -59,7 +60,15 @@
)
)
(drop
- (local.get $x)
+ (block (result i32)
+ (local.set $4
+ (local.get $x)
+ )
+ (drop
+ (local.get $1)
+ )
+ (local.get $4)
+ )
)
)
)
diff --git a/test/exception-handling.wast.fromBinary.noDebugInfo b/test/exception-handling.wast.fromBinary.noDebugInfo
index 27202e8a6..5c527119e 100644
--- a/test/exception-handling.wast.fromBinary.noDebugInfo
+++ b/test/exception-handling.wast.fromBinary.noDebugInfo
@@ -20,6 +20,7 @@
(local $1 i64)
(local $2 (i32 i64))
(local $3 i32)
+ (local $4 i32)
(try $label$3
(do
(throw $tag$0
@@ -59,7 +60,15 @@
)
)
(drop
- (local.get $0)
+ (block (result i32)
+ (local.set $4
+ (local.get $0)
+ )
+ (drop
+ (local.get $1)
+ )
+ (local.get $4)
+ )
)
)
)
diff --git a/test/lit/multivalue.wast b/test/lit/multivalue.wast
index 0d52f5382..f75182ca4 100644
--- a/test/lit/multivalue.wast
+++ b/test/lit/multivalue.wast
@@ -155,6 +155,13 @@
;; CHECK-NEXT: (local $5 (i32 i64 f32))
;; CHECK-NEXT: (local $6 i64)
;; CHECK-NEXT: (local $7 i32)
+ ;; CHECK-NEXT: (local $8 i64)
+ ;; CHECK-NEXT: (local $9 i32)
+ ;; CHECK-NEXT: (local $10 i64)
+ ;; CHECK-NEXT: (local $11 i32)
+ ;; CHECK-NEXT: (local $12 i64)
+ ;; CHECK-NEXT: (local $13 i32)
+ ;; CHECK-NEXT: (local $14 f32)
;; CHECK-NEXT: (local.set $5
;; CHECK-NEXT: (call $triple)
;; CHECK-NEXT: )
@@ -183,10 +190,69 @@
;; CHECK-NEXT: (local.get $7)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (local.set $9
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i64)
+ ;; CHECK-NEXT: (local.set $8
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $4
+ ;; CHECK-NEXT: (local.get $3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $8)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $9)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: (tuple.make
- ;; CHECK-NEXT: (local.get $3)
- ;; CHECK-NEXT: (local.get $1)
- ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (block (result f32)
+ ;; CHECK-NEXT: (local.set $14
+ ;; CHECK-NEXT: (local.get $4)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (local.set $11
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $2
+ ;; CHECK-NEXT: (block (result i64)
+ ;; CHECK-NEXT: (local.set $10
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $10)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $11)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $14)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $2)
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (local.set $13
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i64)
+ ;; CHECK-NEXT: (local.set $12
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $12)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $13)
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $reverse (result f32 i64 i32)
@@ -230,6 +296,7 @@
;; CHECK: (func $global (type $0) (result i32 i64)
;; CHECK-NEXT: (local $0 i64)
;; CHECK-NEXT: (local $1 i32)
+ ;; CHECK-NEXT: (local $2 i32)
;; CHECK-NEXT: (global.set $g1
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (local.set $1
@@ -242,7 +309,18 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (global.get $g2)
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (local.set $2
+ ;; CHECK-NEXT: (global.get $g1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (global.get $g2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (tuple.make
;; CHECK-NEXT: (global.get $global$2)