diff options
-rw-r--r-- | src/passes/GlobalStructInference.cpp | 4 | ||||
-rw-r--r-- | test/lit/passes/gsi.wast | 50 | ||||
-rw-r--r-- | test/lit/passes/gsi_vacuum_precompute.wast | 24 |
3 files changed, 18 insertions, 60 deletions
diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp index 1444f8ad8..901a51a9f 100644 --- a/src/passes/GlobalStructInference.cpp +++ b/src/passes/GlobalStructInference.cpp @@ -75,6 +75,10 @@ struct GlobalStructInference : public Pass { return; } + if (!getPassOptions().closedWorld) { + Fatal() << "GSI requires --closed-world"; + } + // First, find all the information we need. We need to know which struct // types are created in functions, because we will not be able to optimize // those. diff --git a/test/lit/passes/gsi.wast b/test/lit/passes/gsi.wast index 6fe4da95a..8803f66e6 100644 --- a/test/lit/passes/gsi.wast +++ b/test/lit/passes/gsi.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --gsi -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --nominal --gsi -all --closed-world -S -o - | filecheck %s (module ;; CHECK: (type $struct (struct (field i32))) @@ -515,54 +515,6 @@ ) ) -;; We ignore imports, as we assume a closed world, but that might change in the -;; future. For now, we will optimize here. -(module - ;; CHECK: (type $struct (struct (field i32))) - (type $struct (struct i32)) - - ;; CHECK: (type $ref?|$struct|_=>_none (func (param (ref null $struct)))) - - ;; CHECK: (import "a" "b" (global $global-import (ref $struct))) - (import "a" "b" (global $global-import (ref $struct))) - - ;; CHECK: (global $global1 (ref $struct) (struct.new $struct - ;; CHECK-NEXT: (i32.const 42) - ;; CHECK-NEXT: )) - (global $global1 (ref $struct) (struct.new $struct - (i32.const 42) - )) - - ;; CHECK: (global $global2 (ref $struct) (struct.new $struct - ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: )) - (global $global2 (ref $struct) (struct.new $struct - (i32.const 1337) - )) - - ;; CHECK: (func $test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct)) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (select - ;; CHECK-NEXT: (i32.const 42) - ;; CHECK-NEXT: (i32.const 1337) - ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (local.get $struct) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (global.get $global1) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - (func $test (param $struct (ref null $struct)) - (drop - (struct.get $struct 0 - (local.get $struct) - ) - ) - ) -) - ;; A struct.new in a non-toplevel position in a global stops us from ;; optimizing. (module diff --git a/test/lit/passes/gsi_vacuum_precompute.wast b/test/lit/passes/gsi_vacuum_precompute.wast index 9f67c84f5..7f7371b6a 100644 --- a/test/lit/passes/gsi_vacuum_precompute.wast +++ b/test/lit/passes/gsi_vacuum_precompute.wast @@ -1,5 +1,5 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. -;; RUN: foreach %s %t wasm-opt --nominal --gsi --vacuum --precompute -tnh -all -S -o - | filecheck %s +;; RUN: foreach %s %t wasm-opt --nominal --gsi --vacuum --precompute -tnh --closed-world -all -S -o - | filecheck %s ;; Test a common pattern in j2wasm where itables are differentiated by type, but ;; vtables are not. For example, the vtable might be "hashable" and provide a @@ -30,11 +30,9 @@ ;; Two $vtable instances are created, in separate enclosing objects. - ;; CHECK: (type $none_=>_none (func)) - - ;; CHECK: (type $ref|$itable1|_=>_funcref (func (param (ref $itable1)) (result funcref))) + ;; CHECK: (type $ref|any|_=>_funcref (func (param (ref any)) (result funcref))) - ;; CHECK: (type $ref|$itable2|_=>_funcref (func (param (ref $itable2)) (result funcref))) + ;; CHECK: (type $none_=>_none (func)) ;; CHECK: (global $itable1 (ref $itable1) (struct.new $itable1 ;; CHECK-NEXT: (struct.new $vtable @@ -64,24 +62,28 @@ ;; CHECK: (export "test-B" (func $test-B)) - ;; CHECK: (func $test-A (type $ref|$itable1|_=>_funcref) (param $ref (ref $itable1)) (result funcref) + ;; CHECK: (func $test-A (type $ref|any|_=>_funcref) (param $ref (ref any)) (result funcref) ;; CHECK-NEXT: (ref.func $func1) ;; CHECK-NEXT: ) - (func $test-A (export "test-A") (param $ref (ref $itable1)) (result funcref) + (func $test-A (export "test-A") (param $ref (ref any)) (result funcref) (struct.get $vtable 0 ;; this is a reference to $func1 (struct.get $itable1 0 ;; this is the sub-object in the global $itable1 - (local.get $ref) ;; this can be inferred to be the global $itable1 + (ref.cast $itable1 + (local.get $ref) ;; this can be inferred to be the global $itable1 + ) ) ) ) - ;; CHECK: (func $test-B (type $ref|$itable2|_=>_funcref) (param $ref (ref $itable2)) (result funcref) + ;; CHECK: (func $test-B (type $ref|any|_=>_funcref) (param $ref (ref any)) (result funcref) ;; CHECK-NEXT: (ref.func $func2) ;; CHECK-NEXT: ) - (func $test-B (export "test-B") (param $ref (ref $itable2)) (result funcref) + (func $test-B (export "test-B") (param $ref (ref any)) (result funcref) (struct.get $vtable 0 ;; this is a reference to $func2 (struct.get $itable2 0 ;; this is the sub-object in the global $itable2 - (local.get $ref) ;; this can be inferred to be the global $itable2 + (ref.cast $itable2 + (local.get $ref) ;; this can be inferred to be the global $itable2 + ) ) ) ) |