diff options
author | Alon Zakai <alonzakai@gmail.com> | 2019-03-01 10:28:07 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-01 10:28:07 -0800 |
commit | 689fe405a3417fbfd59456035add6f6f53149f35 (patch) | |
tree | d6f1dcaf0cbb85eb3ae830f68a46c9a6627d1562 /src/pass.h | |
parent | f59c3033e678ced61bc8c78e8ac9fbee31ef0210 (diff) | |
download | binaryen-689fe405a3417fbfd59456035add6f6f53149f35.tar.gz binaryen-689fe405a3417fbfd59456035add6f6f53149f35.tar.bz2 binaryen-689fe405a3417fbfd59456035add6f6f53149f35.zip |
Consistently optimize small added constants into load/store offsets (#1924)
See #1919 - we did not do this consistently before.
This adds a lowMemoryUnused option to PassOptions. It can be passed on the commandline with --low-memory-unused. If enabled, we run the new optimize-added-constants pass, which does the real work here, replacing older code in post-emscripten.
Aside from running at the proper time (unlike the old pass, see #1919), this also has a -propagate mode, which can do stuff like this:
y = x + 10
[..]
load(y)
[..]
load(y)
=>
y = x + 10
[..]
load(x, offset=10)
[..]
load(x, offset=10)
That is, it can propagate such offsets to the loads/stores. This pattern is common in big interpreter loops, where the pointers are offsets into a big struct of state.
The pass does this propagation by using a new feature of LocalGraph, which can verify which locals are in SSA mode. Binaryen IR is not SSA (intentionally, since it's a later IR), but if a local only has a single set for all gets, that means that local is in such a state, and can be optimized. The tricky thing is that all locals are initialized to zero, so there are at minimum two sets. But if we verify that the real set dominates all the gets, then the zero initialization cannot reach them, and we are safe.
This PR also makes safe-heap aware of lowMemoryUnused. If so, we check for not just an access of 0, but the range 0-1023.
This makes zlib 5% faster, with either the wasm backend or asm2wasm. It also makes it 0.5% smaller. Also helps sqlite (1.5% faster) and lua (1% faster)
Diffstat (limited to 'src/pass.h')
-rw-r--r-- | src/pass.h | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/src/pass.h b/src/pass.h index 78d1f594e..9ef159d7d 100644 --- a/src/pass.h +++ b/src/pass.h @@ -56,14 +56,26 @@ private: }; struct PassOptions { - bool debug = false; // run passes in debug mode, doing extra validation and timing checks - bool validate = true; // whether to run the validator to check for errors - bool validateGlobally = false; // when validating validate globally and not just locally - int optimizeLevel = 0; // 0, 1, 2 correspond to -O0, -O1, -O2, etc. - int shrinkLevel = 0; // 0, 1, 2 correspond to -O0, -Os, -Oz - bool ignoreImplicitTraps = false; // optimize assuming things like div by 0, bad load/store, will not trap - bool debugInfo = false; // whether to try to preserve debug info through, which are special calls - FeatureSet features = FeatureSet::All; // Which wasm features to accept, and be allowed to use + // Run passes in debug mode, doing extra validation and timing checks. + bool debug = false; + // Whether to run the validator to check for errors. + bool validate = true; + // When validating validate globally and not just locally + bool validateGlobally = false; + // 0, 1, 2 correspond to -O0, -O1, -O2, etc. + int optimizeLevel = 0; + // 0, 1, 2 correspond to -O0, -Os, -Oz + int shrinkLevel = 0; + // Optimize assuming things like div by 0, bad load/store, will not trap. + bool ignoreImplicitTraps = false; + // Optimize assuming that the low 1K of memory is not valid memory for the application + // to use. In that case, we can optimize load/store offsets in many cases. + bool lowMemoryUnused = false; + enum { LowMemoryBound = 1024 }; + // Whether to try to preserve debug info through, which are special calls. + bool debugInfo = false; + // Which wasm features to accept, and be allowed to use. + FeatureSet features = FeatureSet::All; void setDefaultOptimizationOptions() { // -Os is our default |