diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp index 5615a3280ab..8b64795a57c 100644 --- a/src/passes/Heap2Local.cpp +++ b/src/passes/Heap2Local.cpp @@ -248,6 +248,19 @@ struct EscapeAnalyzer { auto* child = flow.first; auto* parent = flow.second; + auto interaction = getParentChildInteraction(allocation, parent, child); + if (interaction == ParentChildInteraction::Escapes || + interaction == ParentChildInteraction::Mixes) { + // If the parent may let us escape, or the parent mixes other values + // up with us, give up. + return true; + } + + // The parent either fully consumes us, or flows us onwards; either way, + // we can proceed here, hopefully. + assert(interaction == ParentChildInteraction::FullyConsumes || + interaction == ParentChildInteraction::Flows); + // If we've already seen an expression, stop since we cannot optimize // things that overlap in any way (see the notes on exclusivity, above). // Note that we use a nonrepeating queue here, so we already do not visit @@ -268,19 +281,6 @@ struct EscapeAnalyzer { return true; } - auto interaction = getParentChildInteraction(allocation, parent, child); - if (interaction == ParentChildInteraction::Escapes || - interaction == ParentChildInteraction::Mixes) { - // If the parent may let us escape, or the parent mixes other values - // up with us, give up. - return true; - } - - // The parent either fully consumes us, or flows us onwards; either way, - // we can proceed here, hopefully. - assert(interaction == ParentChildInteraction::FullyConsumes || - interaction == ParentChildInteraction::Flows); - // We can proceed, as the parent interacts with us properly, and we are // the only allocation to get here. diff --git a/test/lit/passes/heap2local.wast b/test/lit/passes/heap2local.wast index e6d5d4d88df..a037684ec92 100644 --- a/test/lit/passes/heap2local.wast +++ b/test/lit/passes/heap2local.wast @@ -2162,15 +2162,31 @@ ;; CHECK: (func $ref-eq-self (type $4) (result i32) ;; CHECK-NEXT: (local $eq eqref) - ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (local.tee $eq - ;; CHECK-NEXT: (struct.new $struct.A + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 f64) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 f64) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block (result nullref) + ;; CHECK-NEXT: (local.set $3 ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 ;; CHECK-NEXT: (f64.const 0) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (local.get $eq) ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) ;; CHECK-NEXT: ) (func $ref-eq-self (result i32) (local $eq eqref)