summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp12
-rw-r--r--test/lit/extern-conversions.wast36
-rw-r--r--test/lit/passes/optimize-instructions-gc-extern.wast26
3 files changed, 62 insertions, 12 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 64d59ca1d..e1478b54f 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -2266,9 +2266,19 @@ struct OptimizeInstructions
refAsChild->value = curr;
refAsChild->finalize();
replaceCurrent(refAsChild);
+ return;
+ }
+
+ // We can optimize away externalizations of internalizations and vice
+ // versa.
+ if ((curr->op == ExternConvertAny &&
+ refAsChild->op == AnyConvertExtern) ||
+ (curr->op == AnyConvertExtern &&
+ refAsChild->op == ExternConvertAny)) {
+ replaceCurrent(refAsChild->value);
+ return;
}
}
- // TODO: optimize away ExternConvertAny of AnyConvertExtern, etc.
return;
}
diff --git a/test/lit/extern-conversions.wast b/test/lit/extern-conversions.wast
index f84097557..6702ba17d 100644
--- a/test/lit/extern-conversions.wast
+++ b/test/lit/extern-conversions.wast
@@ -7,19 +7,21 @@
(module
- ;; CHECK: (type $0 (func (param (ref any)) (result (ref extern))))
+ ;; CHECK: (type $0 (func (param externref) (result anyref)))
- ;; CHECK: (type $1 (func (param externref) (result anyref)))
+ ;; CHECK: (type $1 (func (param (ref any)) (result (ref extern))))
- ;; CHECK: (type $2 (func (param externref) (result externref)))
+ ;; CHECK: (type $2 (func (param anyref) (result externref)))
;; CHECK: (export "ext" (func $extern.convert_any))
;; CHECK: (export "int" (func $any.convert_extern))
- ;; CHECK: (export "legacy" (func $legacy_notation))
+ ;; CHECK: (export "legacy.1" (func $legacy_notation.1))
- ;; CHECK: (func $extern.convert_any (type $0) (param $0 (ref any)) (result (ref extern))
+ ;; CHECK: (export "legacy.2" (func $legacy_notation.2))
+
+ ;; CHECK: (func $extern.convert_any (type $1) (param $0 (ref any)) (result (ref extern))
;; CHECK-NEXT: (extern.convert_any
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
@@ -30,7 +32,7 @@
)
)
- ;; CHECK: (func $any.convert_extern (type $1) (param $0 externref) (result anyref)
+ ;; CHECK: (func $any.convert_extern (type $0) (param $0 externref) (result anyref)
;; CHECK-NEXT: (any.convert_extern
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
@@ -41,18 +43,30 @@
)
)
- ;; CHECK: (func $legacy_notation (type $2) (param $0 externref) (result externref)
- ;; CHECK-NEXT: (extern.convert_any
+ ;; CHECK: (func $legacy_notation.1 (type $0) (param $0 externref) (result anyref)
+ ;; CHECK-NEXT: (ref.as_non_null
;; CHECK-NEXT: (any.convert_extern
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $legacy_notation (export "legacy") (param $x (ref null extern)) (result (ref null extern))
- (extern.externalize
- (extern.internalize
+ (func $legacy_notation.1 (export "legacy.1") (param $x (ref null extern)) (result (ref null any))
+ (extern.internalize
+ (ref.as_non_null ;; Add this to avoid the entire function being merged with
+ ;; another.
(local.get $x)
)
)
)
+
+ ;; CHECK: (func $legacy_notation.2 (type $2) (param $0 anyref) (result externref)
+ ;; CHECK-NEXT: (extern.convert_any
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $legacy_notation.2 (export "legacy.2") (param $x (ref null any)) (result (ref null extern))
+ (extern.externalize
+ (local.get $x)
+ )
+ )
)
diff --git a/test/lit/passes/optimize-instructions-gc-extern.wast b/test/lit/passes/optimize-instructions-gc-extern.wast
index 067efb0ec..633a18a33 100644
--- a/test/lit/passes/optimize-instructions-gc-extern.wast
+++ b/test/lit/passes/optimize-instructions-gc-extern.wast
@@ -85,4 +85,30 @@
)
)
)
+
+ ;; CHECK: (func $extern.intern (type $3) (param $ext externref) (param $any anyref)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $any)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $ext)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $extern.intern (param $ext externref) (param $any anyref)
+ ;; Internalize/externalize operations cancel out.
+ (drop
+ (any.convert_extern
+ (extern.convert_any
+ (local.get $any)
+ )
+ )
+ )
+ (drop
+ (extern.convert_any
+ (any.convert_extern
+ (local.get $ext)
+ )
+ )
+ )
+ )
)