From b2f3b2845ab9863641b2571523731340cfcddba7 Mon Sep 17 00:00:00 2001 From: dcode Date: Sat, 19 Oct 2019 15:30:16 +0200 Subject: [PATCH 1/4] Fix loop RC issues --- src/compiler.ts | 42 ++- tests/compiler/rc/global-init.untouched.wat | 28 +- tests/compiler/rc/local-init.untouched.wat | 28 +- .../rc/logical-and-mismatch.untouched.wat | 28 +- .../rc/logical-or-mismatch.untouched.wat | 28 +- tests/compiler/rc/rereturn.untouched.wat | 28 +- .../rc/ternary-mismatch.untouched.wat | 28 +- tests/compiler/resolve-ternary.untouched.wat | 28 +- .../retain-release-sanity.optimized.wat | 4 +- .../retain-release-sanity.untouched.wat | 100 +++--- tests/compiler/retain-release.optimized.wat | 41 ++- tests/compiler/retain-release.ts | 54 +++ tests/compiler/retain-release.untouched.wat | 154 +++++++- tests/compiler/runtime-full.untouched.wat | 28 +- .../compiler/std/array-literal.untouched.wat | 28 +- tests/compiler/std/array.optimized.wat | 150 ++++---- tests/compiler/std/array.untouched.wat | 332 +++++++++--------- tests/compiler/std/arraybuffer.untouched.wat | 28 +- tests/compiler/std/dataview.untouched.wat | 28 +- tests/compiler/std/map.optimized.wat | 84 ----- tests/compiler/std/map.untouched.wat | 112 +----- tests/compiler/std/set.untouched.wat | 28 +- .../std/string-encoding.untouched.wat | 28 +- tests/compiler/std/string.untouched.wat | 32 +- tests/compiler/std/typedarray.optimized.wat | 32 +- tests/compiler/std/typedarray.untouched.wat | 156 ++++---- 26 files changed, 854 insertions(+), 803 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index d3d5f835fb..b90961cba8 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1946,8 +1946,11 @@ export class Compiler extends DiagnosticEmitter { // ) var fallsThrough = !terminates && !innerFlow.is(FlowFlags.BREAKS); - if (fallsThrough && !alwaysFalse) { // (4) - stmts.push(module.br(continueLabel, condExpr)); + if (fallsThrough) { + this.performAutoreleases(innerFlow, stmts); + if (!alwaysFalse) { // (4) + stmts.push(module.br(continueLabel, condExpr)); + } } var expr = flatten(module, stmts, NativeType.None); if (fallsThrough && !alwaysFalse || continues) { // (2) @@ -1958,7 +1961,6 @@ export class Compiler extends DiagnosticEmitter { } // Switch back to the parent flow - if (!terminates) this.performAutoreleases(innerFlow, stmts); innerFlow.freeScopedLocals(); outerFlow.popBreakLabel(); innerFlow.unset( @@ -2030,16 +2032,13 @@ export class Compiler extends DiagnosticEmitter { } innerFlow.inheritNonnullIfTrue(condExpr); - // Compile incrementor - var incrementor = statement.incrementor; - var incrExpr: ExpressionRef = 0; - if (incrementor) incrExpr = this.compileExpression(incrementor, Type.void, Constraints.CONV_IMPLICIT | Constraints.WILL_DROP); - // Compile body (break: drop out, continue: fall through to incrementor, + loop) - var breakLabel = innerFlow.breakLabel = "break|" + label; innerFlow.breakLabel = breakLabel; - innerFlow.breakLabel = breakLabel; + var bodyFlow = innerFlow.fork(); + this.currentFlow = bodyFlow; + var breakLabel = innerFlow.breakLabel = "break|" + label; bodyFlow.breakLabel = breakLabel; + bodyFlow.breakLabel = breakLabel; var continueLabel = "continue|" + label; - innerFlow.continueLabel = continueLabel; + bodyFlow.continueLabel = continueLabel; var loopLabel = "loop|" + label; var bodyStatement = statement.statement; var stmts = new Array(); @@ -2048,9 +2047,16 @@ export class Compiler extends DiagnosticEmitter { } else { stmts.push(this.compileStatement(bodyStatement)); } - var terminates = innerFlow.is(FlowFlags.TERMINATES); - var continues = innerFlow.isAny(FlowFlags.CONTINUES | FlowFlags.CONDITIONALLY_CONTINUES); - var breaks = innerFlow.isAny(FlowFlags.BREAKS | FlowFlags.CONDITIONALLY_BREAKS); + var terminates = bodyFlow.is(FlowFlags.TERMINATES); + var continues = bodyFlow.isAny(FlowFlags.CONTINUES | FlowFlags.CONDITIONALLY_CONTINUES); + var breaks = bodyFlow.isAny(FlowFlags.BREAKS | FlowFlags.CONDITIONALLY_BREAKS); + var fallsThrough = !terminates && !innerFlow.is(FlowFlags.BREAKS); + + // Finalize body flow + if (fallsThrough) this.performAutoreleases(bodyFlow, stmts); + bodyFlow.freeScopedLocals(); + innerFlow.inherit(bodyFlow); + this.currentFlow = innerFlow; // (block $break ;; (1) skip label (needed anyway) if skipping (4) + no breaks // (initializer) ;; (2) [may be empty] @@ -2063,7 +2069,6 @@ export class Compiler extends DiagnosticEmitter { // (br $loop) ;; (8) skip if skipping (3) // ) // ) - var fallsThrough = !terminates && !innerFlow.is(FlowFlags.BREAKS); var needsLabel = !alwaysTrue || breaks; var loop = new Array(); @@ -2079,7 +2084,12 @@ export class Compiler extends DiagnosticEmitter { } var expr: ExpressionRef; if (fallsThrough || continues) { // (3) - if (incrExpr) loop.push(incrExpr); // (7) + let incrementor = statement.incrementor; + if (incrementor) { // (7) + loop.push( + this.compileExpression(incrementor, Type.void, Constraints.CONV_IMPLICIT | Constraints.WILL_DROP) + ); + } this.performAutoreleases(innerFlow, loop); loop.push(module.br(loopLabel)); // (8) if (initExpr) { // (2) diff --git a/tests/compiler/rc/global-init.untouched.wat b/tests/compiler/rc/global-init.untouched.wat index 7c7b8830b8..5a4adb3e0d 100644 --- a/tests/compiler/rc/global-init.untouched.wat +++ b/tests/compiler/rc/global-init.untouched.wat @@ -1427,50 +1427,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/rc/local-init.untouched.wat b/tests/compiler/rc/local-init.untouched.wat index 9157c0e601..fbd090dfe0 100644 --- a/tests/compiler/rc/local-init.untouched.wat +++ b/tests/compiler/rc/local-init.untouched.wat @@ -1421,50 +1421,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/rc/logical-and-mismatch.untouched.wat b/tests/compiler/rc/logical-and-mismatch.untouched.wat index b3ca3f728d..c77e57f058 100644 --- a/tests/compiler/rc/logical-and-mismatch.untouched.wat +++ b/tests/compiler/rc/logical-and-mismatch.untouched.wat @@ -1339,50 +1339,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/rc/logical-or-mismatch.untouched.wat b/tests/compiler/rc/logical-or-mismatch.untouched.wat index c28a4e768a..7ae7e65123 100644 --- a/tests/compiler/rc/logical-or-mismatch.untouched.wat +++ b/tests/compiler/rc/logical-or-mismatch.untouched.wat @@ -1339,50 +1339,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/rc/rereturn.untouched.wat b/tests/compiler/rc/rereturn.untouched.wat index e0b5fa9f29..9fbacb5e3b 100644 --- a/tests/compiler/rc/rereturn.untouched.wat +++ b/tests/compiler/rc/rereturn.untouched.wat @@ -1337,50 +1337,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/rc/ternary-mismatch.untouched.wat b/tests/compiler/rc/ternary-mismatch.untouched.wat index 7f526cb5af..d164fcc758 100644 --- a/tests/compiler/rc/ternary-mismatch.untouched.wat +++ b/tests/compiler/rc/ternary-mismatch.untouched.wat @@ -1341,50 +1341,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/resolve-ternary.untouched.wat b/tests/compiler/resolve-ternary.untouched.wat index 835bcaf82f..56f40cccc8 100644 --- a/tests/compiler/resolve-ternary.untouched.wat +++ b/tests/compiler/resolve-ternary.untouched.wat @@ -1369,50 +1369,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/retain-release-sanity.optimized.wat b/tests/compiler/retain-release-sanity.optimized.wat index 6dbbd81bf0..cb08bb3c5f 100644 --- a/tests/compiler/retain-release-sanity.optimized.wat +++ b/tests/compiler/retain-release-sanity.optimized.wat @@ -2507,12 +2507,12 @@ br $loop|1 end end + local.get $0 + call $~lib/rt/pure/__release local.get $3 i32.const 1 i32.add local.set $3 - local.get $0 - call $~lib/rt/pure/__release br $loop|0 end end diff --git a/tests/compiler/retain-release-sanity.untouched.wat b/tests/compiler/retain-release-sanity.untouched.wat index 6ee9cd3996..d1f914aed7 100644 --- a/tests/compiler/retain-release-sanity.untouched.wat +++ b/tests/compiler/retain-release-sanity.untouched.wat @@ -1346,50 +1346,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable @@ -4207,12 +4207,12 @@ end unreachable end + local.get $2 + call $~lib/rt/pure/__release local.get $1 i32.const 1 i32.add local.set $1 - local.get $2 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -4225,20 +4225,20 @@ local.get $0 i32.const 512 call $~lib/string/String.__concat - local.tee $2 + local.tee $1 call $~lib/rt/pure/__retain - local.set $1 - local.get $1 + local.set $2 + local.get $2 i32.const 560 call $~lib/string/String.__concat local.tee $3 drop local.get $0 call $~lib/rt/pure/__release - local.get $2 - call $~lib/rt/pure/__release local.get $1 call $~lib/rt/pure/__release + local.get $2 + call $~lib/rt/pure/__release local.get $3 call $~lib/rt/pure/__release i32.const 0 @@ -4246,112 +4246,112 @@ local.set $3 i32.const 0 call $retain-release-sanity/B#constructor - local.set $1 + local.set $2 local.get $3 - local.tee $2 - local.get $1 - local.tee $0 + local.tee $1 local.get $2 + local.tee $0 + local.get $1 i32.load - local.tee $2 + local.tee $1 i32.ne if local.get $0 call $~lib/rt/pure/__retain drop - local.get $2 + local.get $1 call $~lib/rt/pure/__release end local.get $0 i32.store local.get $3 local.tee $0 - local.get $1 - local.tee $2 + local.get $2 + local.tee $1 local.get $0 i32.load local.tee $0 i32.ne if - local.get $2 + local.get $1 call $~lib/rt/pure/__retain drop local.get $0 call $~lib/rt/pure/__release end - local.get $2 - i32.store local.get $1 - local.tee $2 + i32.store + local.get $2 + local.tee $1 local.get $3 local.tee $0 - local.get $2 + local.get $1 i32.load - local.tee $2 + local.tee $1 i32.ne if local.get $0 call $~lib/rt/pure/__retain drop - local.get $2 + local.get $1 call $~lib/rt/pure/__release end local.get $0 i32.store - local.get $1 + local.get $2 local.tee $0 local.get $3 - local.tee $2 + local.tee $1 local.get $0 i32.load local.tee $0 i32.ne if - local.get $2 + local.get $1 call $~lib/rt/pure/__retain drop local.get $0 call $~lib/rt/pure/__release end - local.get $2 + local.get $1 i32.store local.get $3 - local.tee $2 - local.get $1 - local.tee $0 + local.tee $1 local.get $2 + local.tee $0 + local.get $1 i32.load - local.tee $2 + local.tee $1 i32.ne if local.get $0 call $~lib/rt/pure/__retain drop - local.get $2 + local.get $1 call $~lib/rt/pure/__release end local.get $0 i32.store - local.get $1 + local.get $2 local.tee $0 local.get $3 - local.tee $2 + local.tee $1 local.get $0 i32.load local.tee $0 i32.ne if - local.get $2 + local.get $1 call $~lib/rt/pure/__retain drop local.get $0 call $~lib/rt/pure/__release end - local.get $2 + local.get $1 i32.store local.get $3 call $~lib/rt/pure/__release - local.get $1 + local.get $2 call $~lib/rt/pure/__release call $~lib/rt/pure/__collect ) diff --git a/tests/compiler/retain-release.optimized.wat b/tests/compiler/retain-release.optimized.wat index 6a8666c5c9..0e495740e7 100644 --- a/tests/compiler/retain-release.optimized.wat +++ b/tests/compiler/retain-release.optimized.wat @@ -43,8 +43,11 @@ (export "scopeWhile" (func $retain-release/takeRef)) (export "scopeDo" (func $retain-release/takeRef)) (export "scopeFor" (func $retain-release/takeRef)) + (export "scopeForComplex" (func $retain-release/scopeForComplex)) (export "scopeBreak" (func $retain-release/takeRef)) + (export "scopeBreakNested" (func $retain-release/takeRef)) (export "scopeContinue" (func $retain-release/takeRef)) + (export "scopeContinueNested" (func $retain-release/takeRef)) (export "scopeThrow" (func $retain-release/scopeThrow)) (export "scopeUnreachable" (func $retain-release/scopeUnreachable)) (export "callInline" (func $retain-release/receiveRef)) @@ -185,38 +188,64 @@ (local $1 i32) nop ) - (func $retain-release/scopeThrow (; 12 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/scopeForComplex (; 12 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + (local $2 i32) + loop $loop|0 + local.get $0 + if + i32.const 0 + local.set $1 + loop $loop|1 + local.get $0 + if + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $loop|1 + end + end + local.get $2 + i32.const 1 + i32.add + local.set $2 + br $loop|0 + end + end + ) + (func $retain-release/scopeThrow (; 13 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 if i32.const 24 i32.const 56 - i32.const 313 + i32.const 367 i32.const 4 call $~lib/builtins/abort unreachable end ) - (func $retain-release/scopeUnreachable (; 13 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/scopeUnreachable (; 14 ;) (type $FUNCSIG$vi) (param $0 i32) local.get $0 if unreachable end ) - (func $retain-release/provideRefIndirect (; 14 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/provideRefIndirect (; 15 ;) (type $FUNCSIG$vi) (param $0 i32) i32.const 1 global.set $~lib/argc global.get $retain-release/REF local.get $0 call_indirect (type $FUNCSIG$vi) ) - (func $retain-release/receiveRefIndirect (; 15 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/receiveRefIndirect (; 16 ;) (type $FUNCSIG$vi) (param $0 i32) i32.const 0 global.set $~lib/argc local.get $0 call_indirect (type $FUNCSIG$i) drop ) - (func $start (; 16 ;) (type $FUNCSIG$v) + (func $start (; 17 ;) (type $FUNCSIG$v) (local $0 i32) global.get $~lib/started if diff --git a/tests/compiler/retain-release.ts b/tests/compiler/retain-release.ts index c5ad2e5bc2..bc4177571c 100644 --- a/tests/compiler/retain-release.ts +++ b/tests/compiler/retain-release.ts @@ -278,6 +278,26 @@ export function scopeFor(cond: bool): void { } } +export function scopeForComplex(cond: bool): void { + + // Validates that complex `for` scopes behave properly + + for (let i = 0; cond; ++i) { + let $0: Ref = /* __retain( */ REF /* ) */; + for (let j = 0; cond; ++j) { + let $1: Ref = /* __retain( */ REF /* ) */; + if (cond) { + let $2: Ref = /* __retain( */ REF /* ) */; + // __release($2) + // __release($1) + continue; + } + // __release($1) + } + // __release($0) + } +} + export function scopeBreak(cond: bool): void { // Validates that `break` statements terminate flows so that no further @@ -290,6 +310,23 @@ export function scopeBreak(cond: bool): void { } } +export function scopeBreakNested(cond: bool): void { + + // Validates that nested `break` statements terminate flows so that no + // further releases are performed afterwards. + + while (cond) { + let $0: Ref = /* __retain( */ REF /* ) */; + while (cond) { + let $1: Ref = /* __retain( */ REF /* ) */; + // __release($1) + // __release($0) + break; + } + // __release($0) + } +} + export function scopeContinue(cond: bool): void { // Validates that `continue` statements terminate flows so that no further @@ -302,6 +339,23 @@ export function scopeContinue(cond: bool): void { } } +export function scopeContinueNested(cond: bool): void { + + // Validates that nested `continue` statements terminate flows so that no + // further releases are performed afterwards. + + while (cond) { + let $0: Ref = /* __retain( */ REF /* ) */; + while (cond) { + let $1: Ref = /* __retain( */ REF /* ) */; + // __release($1) + // __release($0) + continue; + } + // __release($0) + } +} + export function scopeThrow(cond: bool): void { // Validates that `throw` statements terminate flows so that no further diff --git a/tests/compiler/retain-release.untouched.wat b/tests/compiler/retain-release.untouched.wat index c571504fc4..69975fa594 100644 --- a/tests/compiler/retain-release.untouched.wat +++ b/tests/compiler/retain-release.untouched.wat @@ -44,8 +44,11 @@ (export "scopeWhile" (func $retain-release/scopeWhile)) (export "scopeDo" (func $retain-release/scopeDo)) (export "scopeFor" (func $retain-release/scopeFor)) + (export "scopeForComplex" (func $retain-release/scopeForComplex)) (export "scopeBreak" (func $retain-release/scopeBreak)) + (export "scopeBreakNested" (func $retain-release/scopeBreakNested)) (export "scopeContinue" (func $retain-release/scopeContinue)) + (export "scopeContinueNested" (func $retain-release/scopeContinueNested)) (export "scopeThrow" (func $retain-release/scopeThrow)) (export "scopeUnreachable" (func $retain-release/scopeUnreachable)) (export "callInline" (func $retain-release/callInline)) @@ -513,6 +516,8 @@ global.get $retain-release/REF call $~lib/rt/stub/__retain local.set $1 + local.get $1 + call $~lib/rt/stub/__release local.get $0 br_if $continue|0 end @@ -534,7 +539,67 @@ unreachable end ) - (func $retain-release/scopeBreak (; 31 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/scopeForComplex (; 31 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + block $break|0 + i32.const 0 + local.set $1 + loop $loop|0 + local.get $0 + i32.eqz + br_if $break|0 + global.get $retain-release/REF + call $~lib/rt/stub/__retain + local.set $2 + block $break|1 + i32.const 0 + local.set $3 + loop $loop|1 + local.get $0 + i32.eqz + br_if $break|1 + block $continue|1 + global.get $retain-release/REF + call $~lib/rt/stub/__retain + local.set $4 + local.get $0 + if + global.get $retain-release/REF + call $~lib/rt/stub/__retain + local.set $5 + local.get $5 + call $~lib/rt/stub/__release + local.get $4 + call $~lib/rt/stub/__release + br $continue|1 + end + local.get $4 + call $~lib/rt/stub/__release + end + local.get $3 + i32.const 1 + i32.add + local.set $3 + br $loop|1 + end + unreachable + end + local.get $2 + call $~lib/rt/stub/__release + local.get $1 + i32.const 1 + i32.add + local.set $1 + br $loop|0 + end + unreachable + end + ) + (func $retain-release/scopeBreak (; 32 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) block $break|0 local.get $0 @@ -548,8 +613,55 @@ br $break|0 end ) - (func $retain-release/scopeContinue (; 32 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/scopeBreakNested (; 33 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + (local $2 i32) + block $break|0 + loop $continue|0 + local.get $0 + i32.eqz + br_if $break|0 + global.get $retain-release/REF + call $~lib/rt/stub/__retain + local.set $1 + block $break|1 + local.get $0 + i32.eqz + br_if $break|1 + global.get $retain-release/REF + call $~lib/rt/stub/__retain + local.set $2 + local.get $2 + call $~lib/rt/stub/__release + br $break|1 + end + local.get $1 + call $~lib/rt/stub/__release + br $continue|0 + end + unreachable + end + ) + (func $retain-release/scopeContinue (; 34 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + block $break|0 + loop $continue|0 + local.get $0 + i32.eqz + br_if $break|0 + global.get $retain-release/REF + call $~lib/rt/stub/__retain + local.set $1 + local.get $1 + call $~lib/rt/stub/__release + br $continue|0 + end + unreachable + end + ) + (func $retain-release/scopeContinueNested (; 35 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) + (local $2 i32) block $break|0 loop $continue|0 local.get $0 @@ -558,6 +670,20 @@ global.get $retain-release/REF call $~lib/rt/stub/__retain local.set $1 + block $break|1 + loop $continue|1 + local.get $0 + i32.eqz + br_if $break|1 + global.get $retain-release/REF + call $~lib/rt/stub/__retain + local.set $2 + local.get $2 + call $~lib/rt/stub/__release + br $continue|1 + end + unreachable + end local.get $1 call $~lib/rt/stub/__release br $continue|0 @@ -565,7 +691,7 @@ unreachable end ) - (func $retain-release/scopeThrow (; 33 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/scopeThrow (; 36 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) block $break|0 local.get $0 @@ -578,13 +704,13 @@ call $~lib/rt/stub/__release i32.const 24 i32.const 56 - i32.const 313 + i32.const 367 i32.const 4 call $~lib/builtins/abort unreachable end ) - (func $retain-release/scopeUnreachable (; 34 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/scopeUnreachable (; 37 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) block $break|0 loop $continue|0 @@ -599,7 +725,7 @@ unreachable end ) - (func $retain-release/callInline (; 35 ;) (type $FUNCSIG$v) + (func $retain-release/callInline (; 38 ;) (type $FUNCSIG$v) (local $0 i32) global.get $retain-release/REF call $~lib/rt/stub/__retain @@ -607,7 +733,7 @@ local.get $0 call $~lib/rt/stub/__release ) - (func $retain-release/provideRefInline (; 36 ;) (type $FUNCSIG$v) + (func $retain-release/provideRefInline (; 39 ;) (type $FUNCSIG$v) (local $0 i32) global.get $retain-release/REF call $~lib/rt/stub/__retain @@ -615,7 +741,7 @@ local.get $0 call $~lib/rt/stub/__release ) - (func $retain-release/receiveRefInline (; 37 ;) (type $FUNCSIG$v) + (func $retain-release/receiveRefInline (; 40 ;) (type $FUNCSIG$v) (local $0 i32) global.get $retain-release/REF call $~lib/rt/stub/__retain @@ -625,19 +751,19 @@ local.get $0 call $~lib/rt/stub/__release ) - (func $retain-release/receiveRefInlineDrop (; 38 ;) (type $FUNCSIG$v) + (func $retain-release/receiveRefInlineDrop (; 41 ;) (type $FUNCSIG$v) global.get $retain-release/REF call $~lib/rt/stub/__retain call $~lib/rt/stub/__release ) - (func $retain-release/provideRefIndirect (; 39 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/provideRefIndirect (; 42 ;) (type $FUNCSIG$vi) (param $0 i32) i32.const 1 global.set $~lib/argc global.get $retain-release/REF local.get $0 call_indirect (type $FUNCSIG$vi) ) - (func $retain-release/receiveRefIndirect (; 40 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/receiveRefIndirect (; 43 ;) (type $FUNCSIG$vi) (param $0 i32) (local $1 i32) i32.const 0 global.set $~lib/argc @@ -649,14 +775,14 @@ local.get $1 call $~lib/rt/stub/__release ) - (func $retain-release/receiveRefIndirectDrop (; 41 ;) (type $FUNCSIG$vi) (param $0 i32) + (func $retain-release/receiveRefIndirectDrop (; 44 ;) (type $FUNCSIG$vi) (param $0 i32) i32.const 0 global.set $~lib/argc local.get $0 call_indirect (type $FUNCSIG$i) call $~lib/rt/stub/__release ) - (func $start (; 42 ;) (type $FUNCSIG$v) + (func $start (; 45 ;) (type $FUNCSIG$v) global.get $~lib/started if return @@ -666,6 +792,6 @@ end call $start:retain-release ) - (func $null (; 43 ;) (type $FUNCSIG$v) + (func $null (; 46 ;) (type $FUNCSIG$v) ) ) diff --git a/tests/compiler/runtime-full.untouched.wat b/tests/compiler/runtime-full.untouched.wat index 56944d4a18..b53d53a26d 100644 --- a/tests/compiler/runtime-full.untouched.wat +++ b/tests/compiler/runtime-full.untouched.wat @@ -1335,50 +1335,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/std/array-literal.untouched.wat b/tests/compiler/std/array-literal.untouched.wat index ce577611f0..1b1313e59f 100644 --- a/tests/compiler/std/array-literal.untouched.wat +++ b/tests/compiler/std/array-literal.untouched.wat @@ -1420,50 +1420,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/std/array.optimized.wat b/tests/compiler/std/array.optimized.wat index f40924b724..43d9041d69 100644 --- a/tests/compiler/std/array.optimized.wat +++ b/tests/compiler/std/array.optimized.wat @@ -4913,9 +4913,9 @@ local.get $5 f32.store i32.const 1 - local.set $3 + local.set $1 loop $continue|3 - local.get $3 + local.get $1 i32.const 5 i32.shr_s i32.const 2 @@ -4923,35 +4923,35 @@ local.get $6 i32.add i32.load - local.get $3 + local.get $1 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and - local.get $3 + local.get $1 i32.const 1 i32.shl i32.add - local.tee $1 + local.tee $3 local.get $4 i32.ge_s i32.eqz if - local.get $1 - local.set $3 + local.get $3 + local.set $1 br $continue|3 end end loop $continue|4 - local.get $3 + local.get $1 i32.const 0 i32.gt_s if local.get $0 f32.load local.set $5 - local.get $3 + local.get $1 i32.const 2 i32.shl local.get $0 @@ -4967,24 +4967,24 @@ i32.const 0 i32.lt_s if - local.get $3 + local.get $1 i32.const 5 i32.shr_s i32.const 2 i32.shl local.get $6 i32.add - local.tee $1 - local.get $1 + local.tee $3 + local.get $3 i32.load i32.const 1 - local.get $3 + local.get $1 i32.const 31 i32.and i32.shl i32.xor i32.store - local.get $3 + local.get $1 i32.const 2 i32.shl local.get $0 @@ -4995,10 +4995,10 @@ local.get $7 f32.store end - local.get $3 + local.get $1 i32.const 1 i32.shr_s - local.set $3 + local.set $1 br $continue|4 end end @@ -5427,9 +5427,9 @@ local.get $5 f64.store i32.const 1 - local.set $3 + local.set $1 loop $continue|3 - local.get $3 + local.get $1 i32.const 5 i32.shr_s i32.const 2 @@ -5437,35 +5437,35 @@ local.get $6 i32.add i32.load - local.get $3 + local.get $1 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and - local.get $3 + local.get $1 i32.const 1 i32.shl i32.add - local.tee $1 + local.tee $3 local.get $4 i32.ge_s i32.eqz if - local.get $1 - local.set $3 + local.get $3 + local.set $1 br $continue|3 end end loop $continue|4 - local.get $3 + local.get $1 i32.const 0 i32.gt_s if local.get $0 f64.load local.set $5 - local.get $3 + local.get $1 i32.const 3 i32.shl local.get $0 @@ -5481,24 +5481,24 @@ i32.const 0 i32.lt_s if - local.get $3 + local.get $1 i32.const 5 i32.shr_s i32.const 2 i32.shl local.get $6 i32.add - local.tee $1 - local.get $1 + local.tee $3 + local.get $3 i32.load i32.const 1 - local.get $3 + local.get $1 i32.const 31 i32.and i32.shl i32.xor i32.store - local.get $3 + local.get $1 i32.const 3 i32.shl local.get $0 @@ -5509,10 +5509,10 @@ local.get $7 f64.store end - local.get $3 + local.get $1 i32.const 1 i32.shr_s - local.set $3 + local.set $1 br $continue|4 end end @@ -5832,20 +5832,20 @@ local.get $1 i32.const 1 i32.sub - local.set $3 + local.set $4 loop $loop|0 block $break|0 - local.get $3 + local.get $4 i32.const 0 i32.le_s br_if $break|0 - local.get $3 - local.set $4 + local.get $4 + local.set $3 loop $continue|1 - local.get $4 + local.get $3 i32.const 1 i32.and - local.get $4 + local.get $3 i32.const 6 i32.shr_s i32.const 2 @@ -5853,7 +5853,7 @@ local.get $5 i32.add i32.load - local.get $4 + local.get $3 i32.const 1 i32.shr_s i32.const 31 @@ -5864,14 +5864,14 @@ i32.ne i32.eqz if - local.get $4 + local.get $3 i32.const 1 i32.shr_s - local.set $4 + local.set $3 br $continue|1 end end - local.get $4 + local.get $3 i32.const 1 i32.shr_s local.tee $7 @@ -5880,8 +5880,8 @@ local.get $0 i32.add i32.load - local.set $4 - local.get $3 + local.set $3 + local.get $4 i32.const 2 i32.shl local.get $0 @@ -5890,14 +5890,14 @@ local.set $6 i32.const 2 global.set $~lib/argc - local.get $4 + local.get $3 local.get $6 local.get $2 call_indirect (type $FUNCSIG$iii) i32.const 0 i32.lt_s if - local.get $3 + local.get $4 i32.const 5 i32.shr_s i32.const 2 @@ -5908,18 +5908,18 @@ local.get $8 i32.load i32.const 1 - local.get $3 + local.get $4 i32.const 31 i32.and i32.shl i32.xor i32.store - local.get $3 + local.get $4 i32.const 2 i32.shl local.get $0 i32.add - local.get $4 + local.get $3 i32.store local.get $7 i32.const 2 @@ -5929,10 +5929,10 @@ local.get $6 i32.store end - local.get $3 + local.get $4 i32.const 1 i32.sub - local.set $3 + local.set $4 br $loop|0 end end @@ -6427,12 +6427,12 @@ local.get $0 local.get $2 call $~lib/array/Array<~lib/array/Array>#__set + local.get $2 + call $~lib/rt/pure/__release local.get $0 i32.const 1 i32.add local.set $0 - local.get $2 - call $~lib/rt/pure/__release br $loop|0 end end @@ -6536,12 +6536,12 @@ i32.add local.get $6 i32.store + local.get $6 + call $~lib/rt/pure/__release local.get $3 i32.const 1 i32.add local.set $3 - local.get $6 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -6651,14 +6651,14 @@ i32.const 0 return else - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $3 call $~lib/rt/pure/__release local.get $4 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable @@ -6728,12 +6728,12 @@ local.get $0 local.get $2 call $~lib/array/Array<~lib/array/Array>#__set + local.get $2 + call $~lib/rt/pure/__release local.get $0 i32.const 1 i32.add local.set $0 - local.get $2 - call $~lib/rt/pure/__release br $loop|0 end end @@ -6801,14 +6801,14 @@ i32.const 0 return else - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $3 call $~lib/rt/pure/__release local.get $4 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable @@ -7161,14 +7161,14 @@ i32.const 0 return else - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $3 call $~lib/rt/pure/__release local.get $4 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable @@ -7323,14 +7323,14 @@ local.get $3 call $~lib/rt/pure/__release end - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $4 call $~lib/rt/pure/__release local.get $5 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end end @@ -7367,12 +7367,12 @@ call $std/array/createRandomString local.tee $2 call $~lib/array/Array<~lib/array/Array>#__set + local.get $2 + call $~lib/rt/pure/__release local.get $1 i32.const 1 i32.add local.set $1 - local.get $2 - call $~lib/rt/pure/__release br $loop|0 end end diff --git a/tests/compiler/std/array.untouched.wat b/tests/compiler/std/array.untouched.wat index 1e7046a659..3a6e80ed65 100644 --- a/tests/compiler/std/array.untouched.wat +++ b/tests/compiler/std/array.untouched.wat @@ -1550,50 +1550,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable @@ -7428,9 +7428,9 @@ local.get $1 i32.const 1 i32.sub - local.set $7 + local.set $5 loop $loop|2 - local.get $7 + local.get $5 i32.const 2 i32.ge_s i32.eqz @@ -7440,55 +7440,55 @@ local.set $9 local.get $0 local.get $0 - local.get $7 + local.get $5 i32.const 2 i32.shl i32.add f32.load f32.store local.get $0 - local.get $7 + local.get $5 i32.const 2 i32.shl i32.add local.get $9 f32.store i32.const 1 - local.set $6 + local.set $7 block $break|3 loop $continue|3 - local.get $6 + local.get $7 i32.const 1 i32.shl local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add i32.load - local.get $6 + local.get $7 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and i32.add - local.tee $5 - local.get $7 + local.tee $6 + local.get $5 i32.lt_s i32.eqz br_if $break|3 - local.get $5 - local.set $6 + local.get $6 + local.set $7 br $continue|3 end unreachable end block $break|4 loop $continue|4 - local.get $6 + local.get $7 i32.const 0 i32.gt_s i32.eqz @@ -7497,7 +7497,7 @@ f32.load local.set $9 local.get $0 - local.get $6 + local.get $7 i32.const 2 i32.shl i32.add @@ -7513,14 +7513,14 @@ i32.lt_s if local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 @@ -7528,14 +7528,14 @@ i32.add i32.load i32.const 1 - local.get $6 + local.get $7 i32.const 31 i32.and i32.shl i32.xor i32.store local.get $0 - local.get $6 + local.get $7 i32.const 2 i32.shl i32.add @@ -7545,18 +7545,18 @@ local.get $8 f32.store end - local.get $6 + local.get $7 i32.const 1 i32.shr_s - local.set $6 + local.set $7 br $continue|4 end unreachable end - local.get $7 + local.get $5 i32.const 1 i32.sub - local.set $7 + local.set $5 br $loop|2 end unreachable @@ -8042,9 +8042,9 @@ local.get $1 i32.const 1 i32.sub - local.set $7 + local.set $5 loop $loop|2 - local.get $7 + local.get $5 i32.const 2 i32.ge_s i32.eqz @@ -8054,55 +8054,55 @@ local.set $9 local.get $0 local.get $0 - local.get $7 + local.get $5 i32.const 3 i32.shl i32.add f64.load f64.store local.get $0 - local.get $7 + local.get $5 i32.const 3 i32.shl i32.add local.get $9 f64.store i32.const 1 - local.set $6 + local.set $7 block $break|3 loop $continue|3 - local.get $6 + local.get $7 i32.const 1 i32.shl local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add i32.load - local.get $6 + local.get $7 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and i32.add - local.tee $5 - local.get $7 + local.tee $6 + local.get $5 i32.lt_s i32.eqz br_if $break|3 - local.get $5 - local.set $6 + local.get $6 + local.set $7 br $continue|3 end unreachable end block $break|4 loop $continue|4 - local.get $6 + local.get $7 i32.const 0 i32.gt_s i32.eqz @@ -8111,7 +8111,7 @@ f64.load local.set $9 local.get $0 - local.get $6 + local.get $7 i32.const 3 i32.shl i32.add @@ -8127,14 +8127,14 @@ i32.lt_s if local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 @@ -8142,14 +8142,14 @@ i32.add i32.load i32.const 1 - local.get $6 + local.get $7 i32.const 31 i32.and i32.shl i32.xor i32.store local.get $0 - local.get $6 + local.get $7 i32.const 3 i32.shl i32.add @@ -8159,18 +8159,18 @@ local.get $8 f64.store end - local.get $6 + local.get $7 i32.const 1 i32.shr_s - local.set $6 + local.set $7 br $continue|4 end unreachable end - local.get $7 + local.get $5 i32.const 1 i32.sub - local.set $7 + local.set $5 br $loop|2 end unreachable @@ -8689,99 +8689,99 @@ local.get $1 i32.const 1 i32.sub - local.set $9 + local.set $5 loop $loop|2 - local.get $9 + local.get $5 i32.const 2 i32.ge_s i32.eqz br_if $break|2 local.get $0 i32.load - local.set $8 + local.set $9 local.get $0 local.get $0 - local.get $9 + local.get $5 i32.const 2 i32.shl i32.add i32.load i32.store local.get $0 - local.get $9 + local.get $5 i32.const 2 i32.shl i32.add - local.get $8 + local.get $9 i32.store i32.const 1 - local.set $7 + local.set $8 block $break|3 loop $continue|3 - local.get $7 + local.get $8 i32.const 1 i32.shl local.get $4 - local.get $7 + local.get $8 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add i32.load - local.get $7 + local.get $8 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and i32.add - local.tee $6 - local.get $9 + local.tee $7 + local.get $5 i32.lt_s i32.eqz br_if $break|3 - local.get $6 - local.set $7 + local.get $7 + local.set $8 br $continue|3 end unreachable end block $break|4 loop $continue|4 - local.get $7 + local.get $8 i32.const 0 i32.gt_s i32.eqz br_if $break|4 local.get $0 i32.load - local.set $8 + local.set $9 local.get $0 - local.get $7 + local.get $8 i32.const 2 i32.shl i32.add i32.load - local.set $5 + local.set $6 i32.const 2 global.set $~lib/argc - local.get $8 - local.get $5 + local.get $9 + local.get $6 local.get $2 call_indirect (type $FUNCSIG$iii) i32.const 0 i32.lt_s if local.get $4 - local.get $7 + local.get $8 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add local.get $4 - local.get $7 + local.get $8 i32.const 5 i32.shr_s i32.const 2 @@ -8789,35 +8789,35 @@ i32.add i32.load i32.const 1 - local.get $7 + local.get $8 i32.const 31 i32.and i32.shl i32.xor i32.store local.get $0 - local.get $7 + local.get $8 i32.const 2 i32.shl i32.add - local.get $8 + local.get $9 i32.store local.get $0 - local.get $5 + local.get $6 i32.store end - local.get $7 + local.get $8 i32.const 1 i32.shr_s - local.set $7 + local.set $8 br $continue|4 end unreachable end - local.get $9 + local.get $5 i32.const 1 i32.sub - local.set $9 + local.set $5 br $loop|2 end unreachable @@ -9166,99 +9166,99 @@ local.get $1 i32.const 1 i32.sub - local.set $9 + local.set $5 loop $loop|2 - local.get $9 + local.get $5 i32.const 2 i32.ge_s i32.eqz br_if $break|2 local.get $0 i32.load - local.set $8 + local.set $9 local.get $0 local.get $0 - local.get $9 + local.get $5 i32.const 2 i32.shl i32.add i32.load i32.store local.get $0 - local.get $9 + local.get $5 i32.const 2 i32.shl i32.add - local.get $8 + local.get $9 i32.store i32.const 1 - local.set $7 + local.set $8 block $break|3 loop $continue|3 - local.get $7 + local.get $8 i32.const 1 i32.shl local.get $4 - local.get $7 + local.get $8 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add i32.load - local.get $7 + local.get $8 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and i32.add - local.tee $6 - local.get $9 + local.tee $7 + local.get $5 i32.lt_s i32.eqz br_if $break|3 - local.get $6 - local.set $7 + local.get $7 + local.set $8 br $continue|3 end unreachable end block $break|4 loop $continue|4 - local.get $7 + local.get $8 i32.const 0 i32.gt_s i32.eqz br_if $break|4 local.get $0 i32.load - local.set $8 + local.set $9 local.get $0 - local.get $7 + local.get $8 i32.const 2 i32.shl i32.add i32.load - local.set $5 + local.set $6 i32.const 2 global.set $~lib/argc - local.get $8 - local.get $5 + local.get $9 + local.get $6 local.get $2 call_indirect (type $FUNCSIG$iii) i32.const 0 i32.lt_s if local.get $4 - local.get $7 + local.get $8 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add local.get $4 - local.get $7 + local.get $8 i32.const 5 i32.shr_s i32.const 2 @@ -9266,35 +9266,35 @@ i32.add i32.load i32.const 1 - local.get $7 + local.get $8 i32.const 31 i32.and i32.shl i32.xor i32.store local.get $0 - local.get $7 + local.get $8 i32.const 2 i32.shl i32.add - local.get $8 + local.get $9 i32.store local.get $0 - local.get $5 + local.get $6 i32.store end - local.get $7 + local.get $8 i32.const 1 i32.shr_s - local.set $7 + local.set $8 br $continue|4 end unreachable end - local.get $9 + local.get $5 i32.const 1 i32.sub - local.set $9 + local.set $5 br $loop|2 end unreachable @@ -9767,12 +9767,12 @@ local.get $2 local.get $3 call $~lib/array/Array<~lib/array/Array>#__set + local.get $3 + call $~lib/rt/pure/__release local.get $2 i32.const 1 i32.add local.set $2 - local.get $3 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -9886,12 +9886,12 @@ i32.add local.get $4 i32.store + local.get $4 + call $~lib/rt/pure/__release local.get $3 i32.const 1 i32.add local.set $3 - local.get $4 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -10063,23 +10063,23 @@ local.get $6 return end - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $4 call $~lib/rt/pure/__release local.get $5 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable end i32.const 1 - local.set $5 + local.set $3 local.get $0 call $~lib/rt/pure/__release - local.get $5 + local.get $3 ) (func $std/array/assertSorted<~lib/array/Array> (; 192 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) @@ -10229,12 +10229,12 @@ call $std/array/Proxy#constructor local.tee $3 call $~lib/array/Array>#__set + local.get $3 + call $~lib/rt/pure/__release local.get $2 i32.const 1 i32.add local.set $2 - local.get $3 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -10346,12 +10346,12 @@ i32.add local.get $4 i32.store + local.get $4 + call $~lib/rt/pure/__release local.get $3 i32.const 1 i32.add local.set $3 - local.get $4 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -10523,23 +10523,23 @@ local.get $6 return end - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $4 call $~lib/rt/pure/__release local.get $5 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable end i32.const 1 - local.set $5 + local.set $3 local.get $0 call $~lib/rt/pure/__release - local.get $5 + local.get $3 ) (func $std/array/assertSorted> (; 205 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) @@ -10651,12 +10651,12 @@ i32.add local.get $4 i32.store + local.get $4 + call $~lib/rt/pure/__release local.get $3 i32.const 1 i32.add local.set $3 - local.get $4 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -10816,23 +10816,23 @@ local.get $6 return end - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $4 call $~lib/rt/pure/__release local.get $5 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable end i32.const 1 - local.set $5 + local.set $3 local.get $0 call $~lib/rt/pure/__release - local.get $5 + local.get $3 ) (func $std/array/assertSorted<~lib/string/String | null> (; 212 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) @@ -11283,25 +11283,25 @@ local.get $6 return end - local.get $3 - i32.const 1 - i32.add - local.set $3 local.get $4 call $~lib/rt/pure/__release local.get $5 call $~lib/rt/pure/__release + local.get $3 + i32.const 1 + i32.add + local.set $3 br $loop|0 end unreachable end i32.const 1 - local.set $5 + local.set $3 local.get $0 call $~lib/rt/pure/__release local.get $1 call $~lib/rt/pure/__release - local.get $5 + local.get $3 ) (func $~lib/array/Array<~lib/string/String>#constructor (; 220 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) local.get $0 @@ -11498,14 +11498,14 @@ end local.get $6 local.set $1 - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $4 call $~lib/rt/pure/__release local.get $5 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable @@ -11596,12 +11596,12 @@ call $std/array/createRandomString local.tee $3 call $~lib/array/Array<~lib/string/String>#__set + local.get $3 + call $~lib/rt/pure/__release local.get $2 i32.const 1 i32.add local.set $2 - local.get $3 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -11693,12 +11693,12 @@ i32.add local.get $4 i32.store + local.get $4 + call $~lib/rt/pure/__release local.get $3 i32.const 1 i32.add local.set $3 - local.get $4 - call $~lib/rt/pure/__release br $loop|0 end unreachable @@ -11870,23 +11870,23 @@ local.get $6 return end - local.get $2 - i32.const 1 - i32.add - local.set $2 local.get $4 call $~lib/rt/pure/__release local.get $5 call $~lib/rt/pure/__release + local.get $2 + i32.const 1 + i32.add + local.set $2 br $loop|0 end unreachable end i32.const 1 - local.set $5 + local.set $3 local.get $0 call $~lib/rt/pure/__release - local.get $5 + local.get $3 ) (func $std/array/assertSorted<~lib/string/String> (; 234 ;) (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) (local $2 i32) diff --git a/tests/compiler/std/arraybuffer.untouched.wat b/tests/compiler/std/arraybuffer.untouched.wat index b6146ac6e0..04ceec562e 100644 --- a/tests/compiler/std/arraybuffer.untouched.wat +++ b/tests/compiler/std/arraybuffer.untouched.wat @@ -1344,50 +1344,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/std/dataview.untouched.wat b/tests/compiler/std/dataview.untouched.wat index 4342b53b52..a622a9ea55 100644 --- a/tests/compiler/std/dataview.untouched.wat +++ b/tests/compiler/std/dataview.untouched.wat @@ -1351,50 +1351,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/std/map.optimized.wat b/tests/compiler/std/map.optimized.wat index a95428d740..e8bb20d68e 100644 --- a/tests/compiler/std/map.optimized.wat +++ b/tests/compiler/std/map.optimized.wat @@ -2483,10 +2483,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -2506,10 +2502,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 10 i32.add i32.ne @@ -2565,10 +2557,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 10 i32.add i32.ne @@ -2583,10 +2571,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 20 i32.add call $~lib/map/Map#set @@ -2606,10 +2590,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 20 i32.add i32.ne @@ -2665,10 +2645,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 20 i32.add i32.ne @@ -2736,10 +2712,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -3175,8 +3147,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 255 - i32.and i32.const 10 i32.add call $~lib/map/Map#set @@ -3196,8 +3166,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 255 - i32.and i32.const 10 i32.add i32.ne @@ -3253,8 +3221,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 255 - i32.and i32.const 10 i32.add i32.ne @@ -3269,8 +3235,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 255 - i32.and i32.const 20 i32.add call $~lib/map/Map#set @@ -3290,8 +3254,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 255 - i32.and i32.const 20 i32.add i32.ne @@ -3347,8 +3309,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 255 - i32.and i32.const 20 i32.add i32.ne @@ -3416,8 +3376,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 255 - i32.and i32.const 10 i32.add call $~lib/map/Map#set @@ -3921,10 +3879,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -3944,10 +3898,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.const 10 i32.add i32.ne @@ -4003,10 +3953,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.const 10 i32.add i32.ne @@ -4021,10 +3967,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.const 20 i32.add call $~lib/map/Map#set @@ -4044,10 +3986,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.const 20 i32.add i32.ne @@ -4103,10 +4041,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.const 20 i32.add i32.ne @@ -4174,10 +4108,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -4613,8 +4543,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 65535 - i32.and i32.const 10 i32.add call $~lib/map/Map#set @@ -4634,8 +4562,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 65535 - i32.and i32.const 10 i32.add i32.ne @@ -4691,8 +4617,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 65535 - i32.and i32.const 10 i32.add i32.ne @@ -4707,8 +4631,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 65535 - i32.and i32.const 20 i32.add call $~lib/map/Map#set @@ -4728,8 +4650,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 65535 - i32.and i32.const 20 i32.add i32.ne @@ -4785,8 +4705,6 @@ local.get $0 call $~lib/map/Map#get local.get $0 - i32.const 65535 - i32.and i32.const 20 i32.add i32.ne @@ -4854,8 +4772,6 @@ local.get $1 local.get $0 local.get $0 - i32.const 65535 - i32.and i32.const 10 i32.add call $~lib/map/Map#set diff --git a/tests/compiler/std/map.untouched.wat b/tests/compiler/std/map.untouched.wat index 6a6ff321d6..a7b176ba6a 100644 --- a/tests/compiler/std/map.untouched.wat +++ b/tests/compiler/std/map.untouched.wat @@ -1352,50 +1352,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable @@ -4123,10 +4123,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -4146,10 +4142,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.add i32.eq i32.eqz @@ -4208,10 +4200,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.add i32.eq i32.eqz @@ -4227,10 +4215,6 @@ local.get $1 i32.const 20 local.get $1 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -4250,10 +4234,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.add i32.eq i32.eqz @@ -4312,10 +4292,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.add i32.eq i32.eqz @@ -4391,10 +4367,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 24 - i32.shl - i32.const 24 - i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -5005,8 +4977,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 255 - i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -5026,8 +4996,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 255 - i32.and i32.add i32.eq i32.eqz @@ -5086,8 +5054,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 255 - i32.and i32.add i32.eq i32.eqz @@ -5103,8 +5069,6 @@ local.get $1 i32.const 20 local.get $1 - i32.const 255 - i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -5124,8 +5088,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 255 - i32.and i32.add i32.eq i32.eqz @@ -5184,8 +5146,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 255 - i32.and i32.add i32.eq i32.eqz @@ -5261,8 +5221,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 255 - i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -5905,10 +5863,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -5928,10 +5882,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.add i32.eq i32.eqz @@ -5990,10 +5940,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.add i32.eq i32.eqz @@ -6009,10 +5955,6 @@ local.get $1 i32.const 20 local.get $1 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -6032,10 +5974,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.add i32.eq i32.eqz @@ -6094,10 +6032,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.add i32.eq i32.eqz @@ -6173,10 +6107,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 16 - i32.shl - i32.const 16 - i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -6787,8 +6717,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 65535 - i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -6808,8 +6736,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 65535 - i32.and i32.add i32.eq i32.eqz @@ -6868,8 +6794,6 @@ call $~lib/map/Map#get i32.const 10 local.get $1 - i32.const 65535 - i32.and i32.add i32.eq i32.eqz @@ -6885,8 +6809,6 @@ local.get $1 i32.const 20 local.get $1 - i32.const 65535 - i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -6906,8 +6828,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 65535 - i32.and i32.add i32.eq i32.eqz @@ -6966,8 +6886,6 @@ call $~lib/map/Map#get i32.const 20 local.get $1 - i32.const 65535 - i32.and i32.add i32.eq i32.eqz @@ -7043,8 +6961,6 @@ local.get $1 i32.const 10 local.get $1 - i32.const 65535 - i32.and i32.add call $~lib/map/Map#set local.get $0 diff --git a/tests/compiler/std/set.untouched.wat b/tests/compiler/std/set.untouched.wat index 5a06f6b538..572742ec0f 100644 --- a/tests/compiler/std/set.untouched.wat +++ b/tests/compiler/std/set.untouched.wat @@ -1350,50 +1350,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/std/string-encoding.untouched.wat b/tests/compiler/std/string-encoding.untouched.wat index 14de432e7c..e34a9f852e 100644 --- a/tests/compiler/std/string-encoding.untouched.wat +++ b/tests/compiler/std/string-encoding.untouched.wat @@ -1434,50 +1434,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable diff --git a/tests/compiler/std/string.untouched.wat b/tests/compiler/std/string.untouched.wat index 73a45fd527..7235c13fc0 100644 --- a/tests/compiler/std/string.untouched.wat +++ b/tests/compiler/std/string.untouched.wat @@ -1815,50 +1815,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable @@ -8783,10 +8783,10 @@ end local.get $4 call $~lib/rt/pure/__retain - local.set $8 + local.set $7 local.get $1 call $~lib/rt/pure/__release - local.get $8 + local.get $7 return else local.get $5 diff --git a/tests/compiler/std/typedarray.optimized.wat b/tests/compiler/std/typedarray.optimized.wat index 76bf43537f..69541da103 100644 --- a/tests/compiler/std/typedarray.optimized.wat +++ b/tests/compiler/std/typedarray.optimized.wat @@ -3209,9 +3209,9 @@ local.get $5 f64.store i32.const 1 - local.set $3 + local.set $1 loop $continue|3 - local.get $3 + local.get $1 i32.const 5 i32.shr_s i32.const 2 @@ -3219,35 +3219,35 @@ local.get $6 i32.add i32.load - local.get $3 + local.get $1 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and - local.get $3 + local.get $1 i32.const 1 i32.shl i32.add - local.tee $1 + local.tee $3 local.get $4 i32.ge_s i32.eqz if - local.get $1 - local.set $3 + local.get $3 + local.set $1 br $continue|3 end end loop $continue|4 - local.get $3 + local.get $1 i32.const 0 i32.gt_s if local.get $0 f64.load local.set $5 - local.get $3 + local.get $1 i32.const 3 i32.shl local.get $0 @@ -3263,24 +3263,24 @@ i32.const 0 i32.lt_s if - local.get $3 + local.get $1 i32.const 5 i32.shr_s i32.const 2 i32.shl local.get $6 i32.add - local.tee $1 - local.get $1 + local.tee $3 + local.get $3 i32.load i32.const 1 - local.get $3 + local.get $1 i32.const 31 i32.and i32.shl i32.xor i32.store - local.get $3 + local.get $1 i32.const 3 i32.shl local.get $0 @@ -3291,10 +3291,10 @@ local.get $7 f64.store end - local.get $3 + local.get $1 i32.const 1 i32.shr_s - local.set $3 + local.set $1 br $continue|4 end end diff --git a/tests/compiler/std/typedarray.untouched.wat b/tests/compiler/std/typedarray.untouched.wat index 02c0d3e4f8..7b949a74d9 100644 --- a/tests/compiler/std/typedarray.untouched.wat +++ b/tests/compiler/std/typedarray.untouched.wat @@ -1457,50 +1457,50 @@ global.set $~lib/rt/pure/CUR block $break|1 local.get $0 - local.set $5 + local.set $3 loop $loop|1 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|1 - local.get $5 + local.get $3 i32.load call $~lib/rt/pure/scan - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|1 end unreachable end block $break|2 local.get $0 - local.set $5 + local.set $3 loop $loop|2 - local.get $5 + local.get $3 local.get $1 i32.lt_u i32.eqz br_if $break|2 - local.get $5 + local.get $3 i32.load - local.set $4 - local.get $4 - local.get $4 + local.set $2 + local.get $2 + local.get $2 i32.load offset=4 i32.const -2147483648 i32.const -1 i32.xor i32.and i32.store offset=4 - local.get $4 + local.get $2 call $~lib/rt/pure/collectWhite - local.get $5 + local.get $3 i32.const 4 i32.add - local.set $5 + local.set $3 br $loop|2 end unreachable @@ -5010,9 +5010,9 @@ local.get $1 i32.const 1 i32.sub - local.set $7 + local.set $5 loop $loop|2 - local.get $7 + local.get $5 i32.const 2 i32.ge_s i32.eqz @@ -5022,55 +5022,55 @@ local.set $9 local.get $0 local.get $0 - local.get $7 + local.get $5 i32.const 3 i32.shl i32.add f64.load f64.store local.get $0 - local.get $7 + local.get $5 i32.const 3 i32.shl i32.add local.get $9 f64.store i32.const 1 - local.set $6 + local.set $7 block $break|3 loop $continue|3 - local.get $6 + local.get $7 i32.const 1 i32.shl local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add i32.load - local.get $6 + local.get $7 i32.const 31 i32.and i32.shr_u i32.const 1 i32.and i32.add - local.tee $5 - local.get $7 + local.tee $6 + local.get $5 i32.lt_s i32.eqz br_if $break|3 - local.get $5 - local.set $6 + local.get $6 + local.set $7 br $continue|3 end unreachable end block $break|4 loop $continue|4 - local.get $6 + local.get $7 i32.const 0 i32.gt_s i32.eqz @@ -5079,7 +5079,7 @@ f64.load local.set $9 local.get $0 - local.get $6 + local.get $7 i32.const 3 i32.shl i32.add @@ -5095,14 +5095,14 @@ i32.lt_s if local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 i32.shl i32.add local.get $4 - local.get $6 + local.get $7 i32.const 5 i32.shr_s i32.const 2 @@ -5110,14 +5110,14 @@ i32.add i32.load i32.const 1 - local.get $6 + local.get $7 i32.const 31 i32.and i32.shl i32.xor i32.store local.get $0 - local.get $6 + local.get $7 i32.const 3 i32.shl i32.add @@ -5127,18 +5127,18 @@ local.get $8 f64.store end - local.get $6 + local.get $7 i32.const 1 i32.shr_s - local.set $6 + local.set $7 br $continue|4 end unreachable end - local.get $7 + local.get $5 i32.const 1 i32.sub - local.set $7 + local.set $5 br $loop|2 end unreachable @@ -11216,20 +11216,20 @@ local.get $8 i32.const 0 i32.shl - local.set $10 + local.set $9 local.get $6 - local.get $10 + local.get $9 call $~lib/rt/tlsf/__realloc - local.set $9 + local.set $10 local.get $5 - local.get $9 + local.get $10 call $~lib/rt/pure/__retain i32.store local.get $5 - local.get $10 + local.get $9 i32.store offset=8 local.get $5 - local.get $9 + local.get $10 i32.store offset=4 local.get $5 call $~lib/rt/pure/__retain @@ -11444,20 +11444,20 @@ local.get $8 i32.const 0 i32.shl - local.set $10 + local.set $9 local.get $6 - local.get $10 + local.get $9 call $~lib/rt/tlsf/__realloc - local.set $9 + local.set $10 local.get $5 - local.get $9 + local.get $10 call $~lib/rt/pure/__retain i32.store local.get $5 - local.get $10 + local.get $9 i32.store offset=8 local.get $5 - local.get $9 + local.get $10 i32.store offset=4 local.get $5 call $~lib/rt/pure/__retain @@ -11672,20 +11672,20 @@ local.get $8 i32.const 0 i32.shl - local.set $10 + local.set $9 local.get $6 - local.get $10 + local.get $9 call $~lib/rt/tlsf/__realloc - local.set $9 + local.set $10 local.get $5 - local.get $9 + local.get $10 call $~lib/rt/pure/__retain i32.store local.get $5 - local.get $10 + local.get $9 i32.store offset=8 local.get $5 - local.get $9 + local.get $10 i32.store offset=4 local.get $5 call $~lib/rt/pure/__retain @@ -11902,20 +11902,20 @@ local.get $8 i32.const 1 i32.shl - local.set $10 + local.set $9 local.get $6 - local.get $10 + local.get $9 call $~lib/rt/tlsf/__realloc - local.set $9 + local.set $10 local.get $5 - local.get $9 + local.get $10 call $~lib/rt/pure/__retain i32.store local.get $5 - local.get $10 + local.get $9 i32.store offset=8 local.get $5 - local.get $9 + local.get $10 i32.store offset=4 local.get $5 call $~lib/rt/pure/__retain @@ -12130,20 +12130,20 @@ local.get $8 i32.const 1 i32.shl - local.set $10 + local.set $9 local.get $6 - local.get $10 + local.get $9 call $~lib/rt/tlsf/__realloc - local.set $9 + local.set $10 local.get $5 - local.get $9 + local.get $10 call $~lib/rt/pure/__retain i32.store local.get $5 - local.get $10 + local.get $9 i32.store offset=8 local.get $5 - local.get $9 + local.get $10 i32.store offset=4 local.get $5 call $~lib/rt/pure/__retain @@ -12356,20 +12356,20 @@ local.get $8 i32.const 2 i32.shl - local.set $10 + local.set $9 local.get $6 - local.get $10 + local.get $9 call $~lib/rt/tlsf/__realloc - local.set $9 + local.set $10 local.get $5 - local.get $9 + local.get $10 call $~lib/rt/pure/__retain i32.store local.get $5 - local.get $10 + local.get $9 i32.store offset=8 local.get $5 - local.get $9 + local.get $10 i32.store offset=4 local.get $5 call $~lib/rt/pure/__retain @@ -12582,20 +12582,20 @@ local.get $8 i32.const 2 i32.shl - local.set $10 + local.set $9 local.get $6 - local.get $10 + local.get $9 call $~lib/rt/tlsf/__realloc - local.set $9 + local.set $10 local.get $5 - local.get $9 + local.get $10 call $~lib/rt/pure/__retain i32.store local.get $5 - local.get $10 + local.get $9 i32.store offset=8 local.get $5 - local.get $9 + local.get $10 i32.store offset=4 local.get $5 call $~lib/rt/pure/__retain From 14501b8c66cfc96182854628f4263615c188adec Mon Sep 17 00:00:00 2001 From: dcode Date: Sat, 19 Oct 2019 23:46:25 +0200 Subject: [PATCH 2/4] revert compile order, unify local flags instead --- src/compiler.ts | 19 +++++-- src/flow.ts | 14 +++++ tests/compiler/std/map.optimized.wat | 84 ++++++++++++++++++++++++++++ tests/compiler/std/map.untouched.wat | 84 ++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 6 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index b90961cba8..1678984700 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -2032,6 +2032,18 @@ export class Compiler extends DiagnosticEmitter { } innerFlow.inheritNonnullIfTrue(condExpr); + // Compile the incrementor before the body in order to... + var incrementor = statement.incrementor; + var incrExpr: ExpressionRef = 0; + if (incrementor) { + let incrFlow = innerFlow.fork(); + this.currentFlow = incrFlow; + incrExpr = this.compileExpression(incrementor, Type.void, Constraints.CONV_IMPLICIT | Constraints.WILL_DROP); + this.currentFlow = innerFlow; + // ...unify local states before and after the incrementor has been executed the first time + innerFlow.unifyLocalFlags(incrFlow); + } + // Compile body (break: drop out, continue: fall through to incrementor, + loop) var bodyFlow = innerFlow.fork(); this.currentFlow = bodyFlow; @@ -2084,12 +2096,7 @@ export class Compiler extends DiagnosticEmitter { } var expr: ExpressionRef; if (fallsThrough || continues) { // (3) - let incrementor = statement.incrementor; - if (incrementor) { // (7) - loop.push( - this.compileExpression(incrementor, Type.void, Constraints.CONV_IMPLICIT | Constraints.WILL_DROP) - ); - } + if (incrExpr) loop.push(incrExpr); // (7) this.performAutoreleases(innerFlow, loop); loop.push(module.br(loopLabel)); // (8) if (initExpr) { // (2) diff --git a/src/flow.ts b/src/flow.ts index b3e532418c..62c4153d16 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -592,6 +592,20 @@ export class Flow { this.localFlags = combinedFlags; } + /** Unifies local flags between this and the other flow. */ + unifyLocalFlags(other: Flow): void { + var numThisLocalFlags = this.localFlags.length; + var numOtherLocalFlags = other.localFlags.length; + for (let i = 0, k = min(numThisLocalFlags, numOtherLocalFlags); i < k; ++i) { + if (this.isLocalFlag(i, LocalFlags.WRAPPED) != other.isLocalFlag(i, LocalFlags.WRAPPED)) { + this.unsetLocalFlag(i, LocalFlags.WRAPPED); + } + if (this.isLocalFlag(i, LocalFlags.NONNULL) != other.isLocalFlag(i, LocalFlags.NONNULL)) { + this.unsetLocalFlag(i, LocalFlags.NONNULL); + } + } + } + /** Checks if an expression of the specified type is known to be non-null, even if the type might be nullable. */ isNonnull(expr: ExpressionRef, type: Type): bool { if (!type.is(TypeFlags.NULLABLE)) return true; diff --git a/tests/compiler/std/map.optimized.wat b/tests/compiler/std/map.optimized.wat index e8bb20d68e..a95428d740 100644 --- a/tests/compiler/std/map.optimized.wat +++ b/tests/compiler/std/map.optimized.wat @@ -2483,6 +2483,10 @@ local.get $1 local.get $0 local.get $0 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -2502,6 +2506,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 10 i32.add i32.ne @@ -2557,6 +2565,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 10 i32.add i32.ne @@ -2571,6 +2583,10 @@ local.get $1 local.get $0 local.get $0 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 20 i32.add call $~lib/map/Map#set @@ -2590,6 +2606,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 20 i32.add i32.ne @@ -2645,6 +2665,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 20 i32.add i32.ne @@ -2712,6 +2736,10 @@ local.get $1 local.get $0 local.get $0 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -3147,6 +3175,8 @@ local.get $1 local.get $0 local.get $0 + i32.const 255 + i32.and i32.const 10 i32.add call $~lib/map/Map#set @@ -3166,6 +3196,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 255 + i32.and i32.const 10 i32.add i32.ne @@ -3221,6 +3253,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 255 + i32.and i32.const 10 i32.add i32.ne @@ -3235,6 +3269,8 @@ local.get $1 local.get $0 local.get $0 + i32.const 255 + i32.and i32.const 20 i32.add call $~lib/map/Map#set @@ -3254,6 +3290,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 255 + i32.and i32.const 20 i32.add i32.ne @@ -3309,6 +3347,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 255 + i32.and i32.const 20 i32.add i32.ne @@ -3376,6 +3416,8 @@ local.get $1 local.get $0 local.get $0 + i32.const 255 + i32.and i32.const 10 i32.add call $~lib/map/Map#set @@ -3879,6 +3921,10 @@ local.get $1 local.get $0 local.get $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -3898,6 +3944,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.const 10 i32.add i32.ne @@ -3953,6 +4003,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.const 10 i32.add i32.ne @@ -3967,6 +4021,10 @@ local.get $1 local.get $0 local.get $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.const 20 i32.add call $~lib/map/Map#set @@ -3986,6 +4044,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.const 20 i32.add i32.ne @@ -4041,6 +4103,10 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.const 20 i32.add i32.ne @@ -4108,6 +4174,10 @@ local.get $1 local.get $0 local.get $0 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.const 10 i32.add call $~lib/map/Map#set @@ -4543,6 +4613,8 @@ local.get $1 local.get $0 local.get $0 + i32.const 65535 + i32.and i32.const 10 i32.add call $~lib/map/Map#set @@ -4562,6 +4634,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 65535 + i32.and i32.const 10 i32.add i32.ne @@ -4617,6 +4691,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 65535 + i32.and i32.const 10 i32.add i32.ne @@ -4631,6 +4707,8 @@ local.get $1 local.get $0 local.get $0 + i32.const 65535 + i32.and i32.const 20 i32.add call $~lib/map/Map#set @@ -4650,6 +4728,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 65535 + i32.and i32.const 20 i32.add i32.ne @@ -4705,6 +4785,8 @@ local.get $0 call $~lib/map/Map#get local.get $0 + i32.const 65535 + i32.and i32.const 20 i32.add i32.ne @@ -4772,6 +4854,8 @@ local.get $1 local.get $0 local.get $0 + i32.const 65535 + i32.and i32.const 10 i32.add call $~lib/map/Map#set diff --git a/tests/compiler/std/map.untouched.wat b/tests/compiler/std/map.untouched.wat index a7b176ba6a..b05bb7c219 100644 --- a/tests/compiler/std/map.untouched.wat +++ b/tests/compiler/std/map.untouched.wat @@ -4123,6 +4123,10 @@ local.get $1 i32.const 10 local.get $1 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -4142,6 +4146,10 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.add i32.eq i32.eqz @@ -4200,6 +4208,10 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.add i32.eq i32.eqz @@ -4215,6 +4227,10 @@ local.get $1 i32.const 20 local.get $1 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -4234,6 +4250,10 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.add i32.eq i32.eqz @@ -4292,6 +4312,10 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.add i32.eq i32.eqz @@ -4367,6 +4391,10 @@ local.get $1 i32.const 10 local.get $1 + i32.const 24 + i32.shl + i32.const 24 + i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -4977,6 +5005,8 @@ local.get $1 i32.const 10 local.get $1 + i32.const 255 + i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -4996,6 +5026,8 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 255 + i32.and i32.add i32.eq i32.eqz @@ -5054,6 +5086,8 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 255 + i32.and i32.add i32.eq i32.eqz @@ -5069,6 +5103,8 @@ local.get $1 i32.const 20 local.get $1 + i32.const 255 + i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -5088,6 +5124,8 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 255 + i32.and i32.add i32.eq i32.eqz @@ -5146,6 +5184,8 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 255 + i32.and i32.add i32.eq i32.eqz @@ -5221,6 +5261,8 @@ local.get $1 i32.const 10 local.get $1 + i32.const 255 + i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -5863,6 +5905,10 @@ local.get $1 i32.const 10 local.get $1 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -5882,6 +5928,10 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.add i32.eq i32.eqz @@ -5940,6 +5990,10 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.add i32.eq i32.eqz @@ -5955,6 +6009,10 @@ local.get $1 i32.const 20 local.get $1 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -5974,6 +6032,10 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.add i32.eq i32.eqz @@ -6032,6 +6094,10 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.add i32.eq i32.eqz @@ -6107,6 +6173,10 @@ local.get $1 i32.const 10 local.get $1 + i32.const 16 + i32.shl + i32.const 16 + i32.shr_s i32.add call $~lib/map/Map#set local.get $0 @@ -6717,6 +6787,8 @@ local.get $1 i32.const 10 local.get $1 + i32.const 65535 + i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -6736,6 +6808,8 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 65535 + i32.and i32.add i32.eq i32.eqz @@ -6794,6 +6868,8 @@ call $~lib/map/Map#get i32.const 10 local.get $1 + i32.const 65535 + i32.and i32.add i32.eq i32.eqz @@ -6809,6 +6885,8 @@ local.get $1 i32.const 20 local.get $1 + i32.const 65535 + i32.and i32.add call $~lib/map/Map#set local.get $0 @@ -6828,6 +6906,8 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 65535 + i32.and i32.add i32.eq i32.eqz @@ -6886,6 +6966,8 @@ call $~lib/map/Map#get i32.const 20 local.get $1 + i32.const 65535 + i32.and i32.add i32.eq i32.eqz @@ -6961,6 +7043,8 @@ local.get $1 i32.const 10 local.get $1 + i32.const 65535 + i32.and i32.add call $~lib/map/Map#set local.get $0 From 7ec3fe19ae1ff1e1a5647f6ecc50522bac9a0e00 Mon Sep 17 00:00:00 2001 From: dcode Date: Sun, 20 Oct 2019 09:47:16 +0200 Subject: [PATCH 3/4] update do statements, add asserts --- src/compiler.ts | 22 +++++++++++++++------- src/flow.ts | 21 +++++++++++++++++++-- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/compiler.ts b/src/compiler.ts index 1678984700..0dbdccf3ae 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1909,12 +1909,25 @@ export class Compiler extends DiagnosticEmitter { var outerFlow = this.currentFlow; var label = outerFlow.pushBreakLabel(); var innerFlow = outerFlow.fork(); - this.currentFlow = innerFlow; var breakLabel = "break|" + label; innerFlow.breakLabel = breakLabel; var continueLabel = "continue|" + label; innerFlow.continueLabel = continueLabel; + // Compile the condition before the body in order to... + var condFlow = outerFlow.fork(); + this.currentFlow = condFlow; + var condExpr = module.precomputeExpression( + this.makeIsTrueish( + this.compileExpression(statement.condition, Type.i32), + this.currentType + ) + ); + assert(!condFlow.hasScopedLocals); + // ...unify local states before and after the condition has been executed the first time + innerFlow.unifyLocalFlags(condFlow); + this.currentFlow = innerFlow; + var stmts = new Array(); if (statement.statement.kind == NodeKind.BLOCK) { this.compileStatements((statement.statement).statements, false, stmts); @@ -1923,12 +1936,6 @@ export class Compiler extends DiagnosticEmitter { this.compileStatement(statement.statement) ); } - var condExpr = module.precomputeExpression( - this.makeIsTrueish( - this.compileExpression(statement.condition, Type.i32), - this.currentType - ) - ); var alwaysFalse = false; if (getExpressionId(condExpr) == ExpressionId.Const) { assert(getExpressionType(condExpr) == NativeType.I32); @@ -2039,6 +2046,7 @@ export class Compiler extends DiagnosticEmitter { let incrFlow = innerFlow.fork(); this.currentFlow = incrFlow; incrExpr = this.compileExpression(incrementor, Type.void, Constraints.CONV_IMPLICIT | Constraints.WILL_DROP); + assert(!incrFlow.hasScopedLocals); this.currentFlow = innerFlow; // ...unify local states before and after the incrementor has been executed the first time innerFlow.unifyLocalFlags(incrFlow); diff --git a/src/flow.ts b/src/flow.ts index 62c4153d16..30db86e122 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -440,6 +440,18 @@ export class Flow { return scopedAlias; } + /** Tests if this flow has any scoped locals that must be free'd. */ + get hasScopedLocals(): bool { + if (this.scopedLocals) { + for (let scopedLocal of this.scopedLocals.values()) { + if (scopedLocal.is(CommonFlags.SCOPED)) { // otherwise an alias + return true; + } + } + } + return false; + } + /** Frees this flow's scoped variables and returns its parent flow. */ freeScopedLocals(): void { if (this.scopedLocals) { @@ -598,11 +610,16 @@ export class Flow { var numOtherLocalFlags = other.localFlags.length; for (let i = 0, k = min(numThisLocalFlags, numOtherLocalFlags); i < k; ++i) { if (this.isLocalFlag(i, LocalFlags.WRAPPED) != other.isLocalFlag(i, LocalFlags.WRAPPED)) { - this.unsetLocalFlag(i, LocalFlags.WRAPPED); + this.unsetLocalFlag(i, LocalFlags.WRAPPED); // assume not wrapped } if (this.isLocalFlag(i, LocalFlags.NONNULL) != other.isLocalFlag(i, LocalFlags.NONNULL)) { - this.unsetLocalFlag(i, LocalFlags.NONNULL); + this.unsetLocalFlag(i, LocalFlags.NONNULL); // assume possibly null } + assert( + // having different retain states would be a problem because the compiler + // either can't release a retained local or would release a non-retained local + this.isAnyLocalFlag(i, LocalFlags.ANY_RETAINED) == other.isAnyLocalFlag(i, LocalFlags.ANY_RETAINED) + ); } } From 5083e21f0b27e499d62e5d65a6e7a73077c2d78c Mon Sep 17 00:00:00 2001 From: dcode Date: Sun, 20 Oct 2019 10:07:57 +0200 Subject: [PATCH 4/4] add test --- tests/compiler/loop-wrap.json | 5 ++ tests/compiler/loop-wrap.optimized.wat | 66 ++++++++++++++++++++ tests/compiler/loop-wrap.ts | 20 +++++++ tests/compiler/loop-wrap.untouched.wat | 83 ++++++++++++++++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 tests/compiler/loop-wrap.json create mode 100644 tests/compiler/loop-wrap.optimized.wat create mode 100644 tests/compiler/loop-wrap.ts create mode 100644 tests/compiler/loop-wrap.untouched.wat diff --git a/tests/compiler/loop-wrap.json b/tests/compiler/loop-wrap.json new file mode 100644 index 0000000000..b1da366ff4 --- /dev/null +++ b/tests/compiler/loop-wrap.json @@ -0,0 +1,5 @@ +{ + "asc_flags": [ + "--runtime none" + ] +} \ No newline at end of file diff --git a/tests/compiler/loop-wrap.optimized.wat b/tests/compiler/loop-wrap.optimized.wat new file mode 100644 index 0000000000..16f3053b10 --- /dev/null +++ b/tests/compiler/loop-wrap.optimized.wat @@ -0,0 +1,66 @@ +(module + (type $FUNCSIG$v (func)) + (type $FUNCSIG$vi (func (param i32))) + (memory $0 0) + (export "memory" (memory $0)) + (export "testAlwaysWrapped" (func $loop-wrap/testAlwaysWrapped)) + (export "testFirstWrapped" (func $loop-wrap/testFirstWrapped)) + (export "testSubsequentWrapped" (func $loop-wrap/testSubsequentWrapped)) + (func $loop-wrap/testAlwaysWrapped (; 0 ;) (type $FUNCSIG$v) + (local $0 i32) + loop $continue|0 + local.get $0 + i32.const 10 + i32.ne + if + local.get $0 + i32.const 1 + i32.add + i32.const 255 + i32.and + local.tee $0 + br_if $continue|0 + end + end + ) + (func $loop-wrap/testFirstWrapped (; 1 ;) (type $FUNCSIG$v) + (local $0 i32) + loop $continue|0 + local.get $0 + i32.const 255 + i32.and + i32.const 10 + i32.ne + if + local.get $0 + i32.const 1 + i32.add + local.tee $0 + i32.const 255 + i32.and + br_if $continue|0 + end + end + ) + (func $loop-wrap/testSubsequentWrapped (; 2 ;) (type $FUNCSIG$vi) (param $0 i32) + loop $continue|0 + local.get $0 + i32.const 255 + i32.and + i32.const 10 + i32.ne + if + local.get $0 + i32.const 1 + i32.add + i32.const 255 + i32.and + local.tee $0 + br_if $continue|0 + end + end + ) + (func $null (; 3 ;) (type $FUNCSIG$v) + nop + ) +) diff --git a/tests/compiler/loop-wrap.ts b/tests/compiler/loop-wrap.ts new file mode 100644 index 0000000000..c447044412 --- /dev/null +++ b/tests/compiler/loop-wrap.ts @@ -0,0 +1,20 @@ +export function testAlwaysWrapped(): void { + var i: u8 = 0; // <-- + do { + if (i == 10) break; // no need to wrap + } while (i = (i + 1) & 0xff); // <-- +} + +export function testFirstWrapped(): void { + var i: u8 = 0; + do { + if (i == 10) break; // must wrap + } while (++i); // <-- +} + +export function testSubsequentWrapped(a: i32): void { + var i = a; // <-- + do { + if (i == 10) break; // must wrap + } while (i = (i + 1) & 0xff); +} diff --git a/tests/compiler/loop-wrap.untouched.wat b/tests/compiler/loop-wrap.untouched.wat new file mode 100644 index 0000000000..db3a161eee --- /dev/null +++ b/tests/compiler/loop-wrap.untouched.wat @@ -0,0 +1,83 @@ +(module + (type $FUNCSIG$v (func)) + (type $FUNCSIG$vi (func (param i32))) + (memory $0 0) + (table $0 1 funcref) + (elem (i32.const 0) $null) + (export "memory" (memory $0)) + (export "testAlwaysWrapped" (func $loop-wrap/testAlwaysWrapped)) + (export "testFirstWrapped" (func $loop-wrap/testFirstWrapped)) + (export "testSubsequentWrapped" (func $loop-wrap/testSubsequentWrapped)) + (func $loop-wrap/testAlwaysWrapped (; 0 ;) (type $FUNCSIG$v) + (local $0 i32) + i32.const 0 + local.set $0 + block $break|0 + loop $continue|0 + local.get $0 + i32.const 10 + i32.eq + if + br $break|0 + end + local.get $0 + i32.const 1 + i32.add + i32.const 255 + i32.and + local.tee $0 + br_if $continue|0 + end + end + ) + (func $loop-wrap/testFirstWrapped (; 1 ;) (type $FUNCSIG$v) + (local $0 i32) + i32.const 0 + local.set $0 + block $break|0 + loop $continue|0 + local.get $0 + i32.const 255 + i32.and + i32.const 10 + i32.eq + if + br $break|0 + end + local.get $0 + i32.const 1 + i32.add + local.tee $0 + i32.const 255 + i32.and + br_if $continue|0 + end + end + ) + (func $loop-wrap/testSubsequentWrapped (; 2 ;) (type $FUNCSIG$vi) (param $0 i32) + (local $1 i32) + local.get $0 + local.set $1 + block $break|0 + loop $continue|0 + local.get $1 + i32.const 255 + i32.and + i32.const 10 + i32.eq + if + br $break|0 + end + local.get $1 + i32.const 1 + i32.add + i32.const 255 + i32.and + local.tee $1 + br_if $continue|0 + end + end + ) + (func $null (; 3 ;) (type $FUNCSIG$v) + ) +)