From aab75ed890a3e491d00e652bbfbe19edd17d38cb Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Wed, 5 Feb 2020 15:40:04 -0800 Subject: Fix LocalCSE's usable local selection (#2638) Now that we have subtypes, we cannot reuse any local that contains the same expression, because that local's type can be a supertype. For example: ``` (local $0 anyref) (local $1 nullref) ... (local.set $0 (ref.null)) (local.set $1 (ref.null)) ;; cannot be replaced with (local.get $0) ``` This extends `usables` map's key to contain both `HashedExpression` and the local's type, so we can get the right usable local in presence of subtypes. --- test/passes/flatten_local-cse_all-features.txt | 20 ++++++++++++++++++++ test/passes/flatten_local-cse_all-features.wast | 21 ++++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/passes/flatten_local-cse_all-features.txt b/test/passes/flatten_local-cse_all-features.txt index 0697e27a5..fc2dff3aa 100644 --- a/test/passes/flatten_local-cse_all-features.txt +++ b/test/passes/flatten_local-cse_all-features.txt @@ -762,6 +762,7 @@ ) ) (module + (type $none_=>_none (func)) (type $none_=>_funcref (func (result funcref))) (func $subtype-test (; 0 ;) (result funcref) (local $0 nullref) @@ -789,4 +790,23 @@ (local.get $2) ) ) + (func $test (; 1 ;) + (local $0 anyref) + (local $1 nullref) + (local $2 nullref) + (block $label$1 + (local.set $0 + (ref.null) + ) + (local.set $1 + (ref.null) + ) + ) + (local.set $2 + (local.get $1) + ) + (drop + (local.get $1) + ) + ) ) diff --git a/test/passes/flatten_local-cse_all-features.wast b/test/passes/flatten_local-cse_all-features.wast index 6ca154278..112dfe647 100644 --- a/test/passes/flatten_local-cse_all-features.wast +++ b/test/passes/flatten_local-cse_all-features.wast @@ -288,14 +288,29 @@ ) ) -;; After --flatten, there will be a series of chain copies between multiple -;; locals, but some of the locals will be nullref type and others funcref type. -;; We cannot make locals of different types a common subexpression. (module + ;; After --flatten, there will be a series of chain copies between multiple + ;; locals, but some of the locals will be nullref type and others funcref type. + ;; We cannot make locals of different types a common subexpression. (func $subtype-test (result funcref) (nop) (loop $label$1 (result nullref) (ref.null) ) ) + + (func $test + (local $0 anyref) + (drop + (block $label$1 (result nullref) + (local.set $0 + (ref.null) + ) + ;; After --flatten, this will be assigned to a local of nullref type. After + ;; --local-cse, even if we set (ref.null) to local $0 above, this should not + ;; be replaced with $0, because it is of type anyref. + (ref.null) + ) + ) + ) ) -- cgit v1.2.3