diff options
author | Daniel Wirtz <dcode@dcode.io> | 2020-02-08 00:52:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-07 15:52:15 -0800 |
commit | 2b77f6ae60cfaf3f3cbdcc4121e82a619b9372c3 (patch) | |
tree | 0992863a82cc06d6cb591e4b2a32867b927f472d | |
parent | 2119f3fcc32c58d581d7c86b7612e3bc89da24e0 (diff) | |
download | binaryen-2b77f6ae60cfaf3f3cbdcc4121e82a619b9372c3.tar.gz binaryen-2b77f6ae60cfaf3f3cbdcc4121e82a619b9372c3.tar.bz2 binaryen-2b77f6ae60cfaf3f3cbdcc4121e82a619b9372c3.zip |
Add C-/JS-APIs for lowMemoryUnused and pass arguments (#2639)
Allows a user to enable/disable the `lowMemoryUnused` option and to get/set/clear arbitrary pass arguments when using the C- or JS-APIs.
* binaryen.**getLowMemoryUnused**(): `boolean`
* binaryen.**setLowMemoryUnused**(on: `boolean`): `void`
* binaryen.**getPassArgument**(key: `string`): `string | null`
* binaryen.**setPassArgument**(key: `string`, value: `string | null`): `void`
* binaryen.**clearPassArguments**(): `void`
-rw-r--r-- | src/binaryen-c.cpp | 58 | ||||
-rw-r--r-- | src/binaryen-c.h | 20 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 38 | ||||
-rw-r--r-- | test/binaryen.js/low-memory-unused.js | 40 | ||||
-rw-r--r-- | test/binaryen.js/low-memory-unused.js.txt | 75 | ||||
-rw-r--r-- | test/binaryen.js/pass-arguments.js | 17 | ||||
-rw-r--r-- | test/binaryen.js/pass-arguments.js.txt | 25 |
7 files changed, 270 insertions, 3 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 1362e0960..17c95c96e 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -3900,6 +3900,64 @@ void BinaryenSetDebugInfo(int on) { globalPassOptions.debugInfo = on != 0; } +int BinaryenGetLowMemoryUnused(void) { + if (tracing) { + std::cout << " BinaryenGetLowMemoryUnused();\n"; + } + + return globalPassOptions.lowMemoryUnused; +} + +void BinaryenSetLowMemoryUnused(int on) { + if (tracing) { + std::cout << " BinaryenSetLowMemoryUnused(" << on << ");\n"; + } + + globalPassOptions.lowMemoryUnused = on != 0; +} + +const char* BinaryenGetPassArgument(const char* key) { + if (tracing) { + std::cout << " BinaryenGetPassArgument("; + traceNameOrNULL(key); + std::cout << ");\n"; + } + + assert(key); + auto& args = globalPassOptions.arguments; + auto it = args.find(key); + if (it == args.end()) { + return nullptr; + } + // internalize the string so it remains valid while the module is + return Name(it->second).c_str(); +} + +void BinaryenSetPassArgument(const char* key, const char* value) { + if (tracing) { + std::cout << " BinaryenSetPassArgument("; + traceNameOrNULL(key); + std::cout << ", "; + traceNameOrNULL(value); + std::cout << ");\n"; + } + + assert(key); + if (value) { + globalPassOptions.arguments[key] = value; + } else { + globalPassOptions.arguments.erase(key); + } +} + +void BinaryenClearPassArguments(void) { + if (tracing) { + std::cout << " BinaryenClearPassArguments();\n"; + } + + globalPassOptions.arguments.clear(); +} + void BinaryenModuleRunPasses(BinaryenModuleRef module, const char** passes, BinaryenIndex numPasses) { diff --git a/src/binaryen-c.h b/src/binaryen-c.h index 0a9a70f4d..66a68e8d2 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -1284,6 +1284,26 @@ BINARYEN_API int BinaryenGetDebugInfo(void); // Applies to all modules, globally. BINARYEN_API void BinaryenSetDebugInfo(int on); +// Gets whether the low 1K of memory can be considered unused when optimizing. +// Applies to all modules, globally. +BINARYEN_API int BinaryenGetLowMemoryUnused(void); + +// Enables or disables whether the low 1K of memory can be considered unused +// when optimizing. Applies to all modules, globally. +BINARYEN_API void BinaryenSetLowMemoryUnused(int on); + +// Gets the value of the specified arbitrary pass argument. +// Applies to all modules, globally. +BINARYEN_API const char* BinaryenGetPassArgument(const char* name); + +// Sets the value of the specified arbitrary pass argument. Removes the +// respective argument if `value` is NULL. Applies to all modules, globally. +BINARYEN_API void BinaryenSetPassArgument(const char* name, const char* value); + +// Clears all arbitrary pass arguments. +// Applies to all modules, globally. +BINARYEN_API void BinaryenClearPassArguments(); + // Runs the specified passes on the module. Uses the currently set global // optimize and shrink level. BINARYEN_API void BinaryenModuleRunPasses(BinaryenModuleRef module, diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index fd2832bf2..d41e9575b 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -2873,7 +2873,7 @@ Module['getOptimizeLevel'] = function() { // Sets the optimization level to use. 0, 1, 2 correspond to -O0, -O1, -O2, etc. Module['setOptimizeLevel'] = function(level) { - return Module['_BinaryenSetOptimizeLevel'](level); + Module['_BinaryenSetOptimizeLevel'](level); }; // Gets the currently set shrink level. 0, 1, 2 correspond to -O0, -Os, -Oz. @@ -2883,7 +2883,7 @@ Module['getShrinkLevel'] = function() { // Sets the shrink level to use. 0, 1, 2 correspond to -O0, -Os, -Oz. Module['setShrinkLevel'] = function(level) { - return Module['_BinaryenSetShrinkLevel'](level); + Module['_BinaryenSetShrinkLevel'](level); }; // Gets whether generating debug information is currently enabled or not. @@ -2893,7 +2893,39 @@ Module['getDebugInfo'] = function() { // Enables or disables debug information in emitted binaries. Module['setDebugInfo'] = function(on) { - return Module['_BinaryenSetDebugInfo'](on); + Module['_BinaryenSetDebugInfo'](on); +}; + +// Gets whether the low 1K of memory can be considered unused when optimizing. +Module['getLowMemoryUnused'] = function() { + return Boolean(Module['_BinaryenGetLowMemoryUnused']()); +}; + +// Enables or disables whether the low 1K of memory can be considered unused +// when optimizing. +Module['setLowMemoryUnused'] = function(on) { + Module['_BinaryenSetLowMemoryUnused'](on); +}; + +// Gets the value of the specified arbitrary pass argument. +Module['getPassArgument'] = function(key) { + return preserveStack(function() { + var ret = Module['_BinaryenGetPassArgument'](strToStack(key)); + return ret !== 0 ? UTF8ToString(ret) : null; + }); +}; + +// Sets the value of the specified arbitrary pass argument. Removes the +// respective argument if `value` is NULL. +Module['setPassArgument'] = function (key, value) { + preserveStack(function () { + Module['_BinaryenSetPassArgument'](strToStack(key), strToStack(value)); + }); +}; + +// Clears all arbitrary pass arguments. +Module['clearPassArguments'] = function() { + Module['_BinaryenClearPassArguments'](); }; // Enables or disables C-API tracing diff --git a/test/binaryen.js/low-memory-unused.js b/test/binaryen.js/low-memory-unused.js new file mode 100644 index 000000000..37bdc2cb0 --- /dev/null +++ b/test/binaryen.js/low-memory-unused.js @@ -0,0 +1,40 @@ +var wast = ` +(module + (memory $0 1) + (export "test" (func $test)) + (func $test (param $0 i32) (result i32) + (i32.load + (i32.add + (local.get $0) + (i32.const 128) + ) + ) + ) +) +`; + +console.log("=== input wast ===" + wast); + +var module = binaryen.parseText(wast); + +console.log("=== unoptimized ==="); +assert(module.validate()); +console.log(module.emitText()); + +console.log("=== optimized, lowMemoryUnused=" + binaryen.getLowMemoryUnused() + " ==="); +module.optimize(); +assert(module.validate()); +console.log(module.emitText()); + +binaryen.setAPITracing(true); +binaryen.setLowMemoryUnused(true); +assert(binaryen.getLowMemoryUnused()); +binaryen.setAPITracing(false); +console.log(); + +console.log("=== optimized, lowMemoryUnused=" + binaryen.getLowMemoryUnused() + " ==="); +module.optimize(); +assert(module.validate()); +console.log(module.emitText()); + +module.dispose(); diff --git a/test/binaryen.js/low-memory-unused.js.txt b/test/binaryen.js/low-memory-unused.js.txt new file mode 100644 index 000000000..13850128c --- /dev/null +++ b/test/binaryen.js/low-memory-unused.js.txt @@ -0,0 +1,75 @@ +=== input wast === +(module + (memory $0 1) + (export "test" (func $test)) + (func $test (param $0 i32) (result i32) + (i32.load + (i32.add + (local.get $0) + (i32.const 128) + ) + ) + ) +) + +=== unoptimized === +(module + (type $i32_=>_i32 (func (param i32) (result i32))) + (memory $0 1) + (export "test" (func $test)) + (func $test (; 0 ;) (param $0 i32) (result i32) + (i32.load + (i32.add + (local.get $0) + (i32.const 128) + ) + ) + ) +) + +=== optimized, lowMemoryUnused=false === +(module + (type $i32_=>_i32 (func (param i32) (result i32))) + (memory $0 1) + (export "test" (func $test)) + (func $test (; 0 ;) (; has Stack IR ;) (param $0 i32) (result i32) + (i32.load + (i32.add + (local.get $0) + (i32.const 128) + ) + ) + ) +) + +// beginning a Binaryen API trace +#include <math.h> +#include <map> +#include "binaryen-c.h" +int main() { + std::map<size_t, BinaryenExpressionRef> expressions; + std::map<size_t, BinaryenFunctionRef> functions; + std::map<size_t, BinaryenGlobalRef> globals; + std::map<size_t, BinaryenEventRef> events; + std::map<size_t, BinaryenExportRef> exports; + std::map<size_t, RelooperBlockRef> relooperBlocks; + BinaryenModuleRef the_module = NULL; + RelooperRef the_relooper = NULL; + BinaryenSetLowMemoryUnused(1); + BinaryenGetLowMemoryUnused(); + return 0; +} +// ending a Binaryen API trace + +=== optimized, lowMemoryUnused=true === +(module + (type $i32_=>_i32 (func (param i32) (result i32))) + (memory $0 1) + (export "test" (func $test)) + (func $test (; 0 ;) (; has Stack IR ;) (param $0 i32) (result i32) + (i32.load offset=128 + (local.get $0) + ) + ) +) + diff --git a/test/binaryen.js/pass-arguments.js b/test/binaryen.js/pass-arguments.js new file mode 100644 index 000000000..7e1f83a2b --- /dev/null +++ b/test/binaryen.js/pass-arguments.js @@ -0,0 +1,17 @@ +binaryen.setAPITracing(true); + +assert(binaryen.getPassArgument("theKey") === null); + +binaryen.setPassArgument("theKey", "theValue"); +assert(binaryen.getPassArgument("theKey") === "theValue"); + +binaryen.setPassArgument("theKey", null); +assert(binaryen.getPassArgument("theKey") === null); + +binaryen.setPassArgument("theKey", "theValue2"); +assert(binaryen.getPassArgument("theKey") === "theValue2"); + +binaryen.clearPassArguments(); +assert(binaryen.getPassArgument("theKey") === null); + +binaryen.setAPITracing(false); diff --git a/test/binaryen.js/pass-arguments.js.txt b/test/binaryen.js/pass-arguments.js.txt new file mode 100644 index 000000000..f877b2248 --- /dev/null +++ b/test/binaryen.js/pass-arguments.js.txt @@ -0,0 +1,25 @@ +// beginning a Binaryen API trace +#include <math.h> +#include <map> +#include "binaryen-c.h" +int main() { + std::map<size_t, BinaryenExpressionRef> expressions; + std::map<size_t, BinaryenFunctionRef> functions; + std::map<size_t, BinaryenGlobalRef> globals; + std::map<size_t, BinaryenEventRef> events; + std::map<size_t, BinaryenExportRef> exports; + std::map<size_t, RelooperBlockRef> relooperBlocks; + BinaryenModuleRef the_module = NULL; + RelooperRef the_relooper = NULL; + BinaryenGetPassArgument("theKey"); + BinaryenSetPassArgument("theKey", "theValue"); + BinaryenGetPassArgument("theKey"); + BinaryenSetPassArgument("theKey", NULL); + BinaryenGetPassArgument("theKey"); + BinaryenSetPassArgument("theKey", "theValue2"); + BinaryenGetPassArgument("theKey"); + BinaryenClearPassArguments(); + BinaryenGetPassArgument("theKey"); + return 0; +} +// ending a Binaryen API trace |