diff options
author | Heejin Ahn <aheejin@gmail.com> | 2020-06-03 00:12:15 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-03 00:12:15 -0700 |
commit | 501b0a08fafd2b4d2fbb5dd6a4320641bfc823b1 (patch) | |
tree | 9f3ea2e81941baa532818e53a5a8bc1ac19a97d5 /test/binaryen.js | |
parent | 3c4630bbe90752c7c720da4ad3805808852b8566 (diff) | |
download | binaryen-501b0a08fafd2b4d2fbb5dd6a4320641bfc823b1.tar.gz binaryen-501b0a08fafd2b4d2fbb5dd6a4320641bfc823b1.tar.bz2 binaryen-501b0a08fafd2b4d2fbb5dd6a4320641bfc823b1.zip |
Prevent pops from sinking in SimplifyLocals (#2885)
This prevents `exnref.pop`s from being sinked and separated from
`catch`. For example,
```wast
(try
(do)
(catch
(local.set $0 (exnref.pop))
(call $foo
(i32.const 3)
(local.get $0)
)
)
)
```
Here, if we sink `exnref.pop` to remove `local.set $0` and
`local.get $0`, it becomes this:
```wast
(try
(do)
(catch
(nop)
(call $foo
(i32.const 3)
(exnref.pop)
)
)
)
```
This move was possible because `i32.const 3` does not have any side
effects. But this is incorrect because now `exnref.pop` does not follow
right after `catch`.
To prevent this, this patch checks this case in `canSink` in
SimplifyLocals. When we encountered a similar case in CodeFolding, we
prevented every expression that contains `Pop` anywhere in it from being
moved, which was too conservative. This adds `danglingPop` property in
`EffectAnalyzer`, so that only pops that are not enclosed within a
`catch` count as 'dangling pops` and we only prevent those pops from
being moved or sinked.
Diffstat (limited to 'test/binaryen.js')
-rw-r--r-- | test/binaryen.js/sideffects.js | 10 | ||||
-rw-r--r-- | test/binaryen.js/sideffects.js.txt | 3 |
2 files changed, 12 insertions, 1 deletions
diff --git a/test/binaryen.js/sideffects.js b/test/binaryen.js/sideffects.js index 76bc1db68..bfb5404c2 100644 --- a/test/binaryen.js/sideffects.js +++ b/test/binaryen.js/sideffects.js @@ -10,6 +10,7 @@ console.log("SideEffects.WritesMemory=" + binaryen.SideEffects.WritesMemory); console.log("SideEffects.ImplicitTrap=" + binaryen.SideEffects.ImplicitTrap); console.log("SideEffects.IsAtomic=" + binaryen.SideEffects.IsAtomic); console.log("SideEffects.Throws=" + binaryen.SideEffects.Throws); +console.log("SideEffects.DanglingPop=" + binaryen.SideEffects.DanglingPop); console.log("SideEffects.Any=" + binaryen.SideEffects.Any); var module = new binaryen.Module(); @@ -104,3 +105,12 @@ assert( == binaryen.SideEffects.Calls | binaryen.SideEffects.Throws ); + +assert( + binaryen.getSideEffects( + module.drop(module.exnref.pop()), + module.getFeatures() + ) + == + binaryen.SideEffects.DanglingPop +); diff --git a/test/binaryen.js/sideffects.js.txt b/test/binaryen.js/sideffects.js.txt index 4aca0ac46..53ee474e5 100644 --- a/test/binaryen.js/sideffects.js.txt +++ b/test/binaryen.js/sideffects.js.txt @@ -10,4 +10,5 @@ SideEffects.WritesMemory=128 SideEffects.ImplicitTrap=256 SideEffects.IsAtomic=512 SideEffects.Throws=1024 -SideEffects.Any=2047 +SideEffects.DanglingPop=2048 +SideEffects.Any=4095 |