Skip to content

Commit efa325c

Browse files
authored
Metadce fixes (emscripten-core#6444)
* we cannot metadce linkable code, like shared modules. Fixes emscripten-core#6362 * improve the error message for when the metadce passes cannot find necessary things due to improper use of --pre/--post-js emscripten-core#6442 * we also cannot jsdce linkable code
1 parent 5868b17 commit efa325c

4 files changed

Lines changed: 40 additions & 28 deletions

File tree

site/source/docs/tools_reference/emcc.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ Options that are modified or new in *emcc* are listed below:
255255
.. _emcc-pre-js:
256256

257257
``--pre-js <file>``
258-
Specify a file whose contents are added before the emitted code and optimized together with it. Note that this might not literally be the very first thing in the JS output, for example if ``MODULARIZE`` is used (see ``src/settings.js``). If you want that, you can just prepend to the output from emscripten; the benefit of ``--pre-js`` is that it optimizes the code with the rest of the emscripten output, which allows better dead code elimination and minification.
258+
Specify a file whose contents are added before the emitted code and optimized together with it. Note that this might not literally be the very first thing in the JS output, for example if ``MODULARIZE`` is used (see ``src/settings.js``). If you want that, you can just prepend to the output from emscripten; the benefit of ``--pre-js`` is that it optimizes the code with the rest of the emscripten output, which allows better dead code elimination and minification, and it should only be used for that purpose. In particular, ``--pre-js`` code should not alter the main output from emscripten in ways that could confuse the optimizer, such as using ``--pre-js`` + ``--post-js`` to put all the output in an inner function scope (see ``MODULARIZE`` for that).
259259

260260
.. _emcc-post-js:
261261

tests/test_other.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7854,15 +7854,18 @@ def test(filename, expectations):
78547854

78557855
print('test on hello world')
78567856
test(path_from_root('tests', 'hello_world.cpp'), [
7857-
([], 24, ['abort', 'tempDoublePtr'], ['waka'], 46505, 25, 19),
7858-
(['-O1'], 19, ['abort', 'tempDoublePtr'], ['waka'], 12630, 16, 17),
7859-
(['-O2'], 19, ['abort', 'tempDoublePtr'], ['waka'], 12616, 16, 17),
7860-
(['-O3'], 7, ['abort'], ['tempDoublePtr', 'waka'], 2818, 10, 2), # in -O3, -Os and -Oz we metadce
7861-
(['-Os'], 7, ['abort'], ['tempDoublePtr', 'waka'], 2771, 10, 2),
7862-
(['-Oz'], 7, ['abort'], ['tempDoublePtr', 'waka'], 2765, 10, 2),
7857+
([], 24, ['abort', 'tempDoublePtr'], ['waka'], 46505, 25, 19),
7858+
(['-O1'], 19, ['abort', 'tempDoublePtr'], ['waka'], 12630, 16, 17),
7859+
(['-O2'], 19, ['abort', 'tempDoublePtr'], ['waka'], 12616, 16, 17),
7860+
(['-O3'], 7, ['abort'], ['tempDoublePtr', 'waka'], 2818, 10, 2), # in -O3, -Os and -Oz we metadce
7861+
(['-Os'], 7, ['abort'], ['tempDoublePtr', 'waka'], 2771, 10, 2),
7862+
(['-Oz'], 7, ['abort'], ['tempDoublePtr', 'waka'], 2765, 10, 2),
78637863
# finally, check what happens when we export nothing. wasm should be almost empty
78647864
(['-Os', '-s', 'EXPORTED_FUNCTIONS=[]'],
7865-
0, [], ['tempDoublePtr', 'waka'], 8, 0, 0), # totally empty!
7865+
0, [], ['tempDoublePtr', 'waka'], 8, 0, 0), # totally empty!
7866+
# but we don't metadce with linkable code! other modules may want it
7867+
(['-O3', '-s', 'MAIN_MODULE=1'],
7868+
1542, ['invoke_i'], ['waka'], 496958, 168, 2558),
78667869
])
78677870

78687871
print('test on a minimal pure computational thing')

tools/js-optimizer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8139,7 +8139,8 @@ function emitDCEGraph(ast) {
81398139
return null; // don't look inside
81408140
}
81418141
});
8142-
assert(foundAsmLibraryArgAssign); // must find the info we need
8142+
// must find the info we need
8143+
assert(foundAsmLibraryArgAssign, 'could not find the assigment to "asmLibraryArg". perhaps --pre-js or --post-js code moved it out of the global scope? (things like that should be done after emcc runs, as they do not need to be run through the optimizer which is the special thing about --pre-js/--post-js code)');
81438144
// Second pass: everything used in the toplevel scope is rooted;
81448145
// things used in defun scopes create links
81458146
function getGraphName(name, what) {

tools/shared.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,7 @@ def emscripten(filename, append_ext=True, extra_args=[]):
20192019

20202020
return filename + '.o.js'
20212021

2022+
# TODO: deprecate this method, we should just need Settings.LINKABLE anyhow
20222023
@staticmethod
20232024
def can_build_standalone():
20242025
return not Settings.BUILD_AS_SHARED_LIB and not Settings.LINKABLE
@@ -2217,27 +2218,34 @@ def closure_compiler(filename, pretty=True):
22172218
@staticmethod
22182219
def minify_wasm_js(js_file, wasm_file, expensive_optimizations, minify_whitespace, use_closure_compiler, debug_info, emit_symbol_map):
22192220
# start with JSDCE, to clean up obvious JS garbage. When optimizing for size,
2220-
# use AJSDCE (aggressive JS DCE, performs multiple iterations)
2221-
passes = ['noPrintMetadata', 'JSDCE' if not expensive_optimizations else 'AJSDCE']
2221+
# use AJSDCE (aggressive JS DCE, performs multiple iterations). Clean up
2222+
# whitespace if necessary too.
2223+
passes = []
2224+
if not Settings.LINKABLE:
2225+
passes.append('JSDCE' if not expensive_optimizations else 'AJSDCE')
22222226
if minify_whitespace:
22232227
passes.append('minifyWhitespace')
2224-
logging.debug('running cleanup on shell code: ' + ' '.join(passes))
2225-
js_file = Building.js_optimizer_no_asmjs(js_file, passes)
2226-
# if we are optimizing for size, shrink the combined wasm+JS
2227-
# TODO: support this when a symbol map is used
2228-
if expensive_optimizations and not emit_symbol_map:
2229-
js_file = Building.metadce(js_file, wasm_file, minify_whitespace=minify_whitespace, debug_info=debug_info)
2230-
# now that we removed unneeded communication between js and wasm, we can clean up
2231-
# the js some more.
2232-
passes = ['noPrintMetadata', 'AJSDCE']
2233-
if minify_whitespace:
2234-
passes.append('minifyWhitespace')
2235-
logging.debug('running post-meta-DCE cleanup on shell code: ' + ' '.join(passes))
2236-
js_file = Building.js_optimizer_no_asmjs(js_file, passes)
2237-
# finally, optionally use closure compiler to finish cleaning up the JS
2238-
if use_closure_compiler:
2239-
logging.debug('running closure on shell code')
2240-
js_file = Building.closure_compiler(js_file, pretty=not minify_whitespace)
2228+
if passes:
2229+
logging.debug('running cleanup on shell code: ' + ' '.join(passes))
2230+
js_file = Building.js_optimizer_no_asmjs(js_file, ['noPrintMetadata'] + passes)
2231+
# if we can optimize this js+wasm combination under the assumption no one else
2232+
# will see the internals, do so
2233+
if not Settings.LINKABLE:
2234+
# if we are optimizing for size, shrink the combined wasm+JS
2235+
# TODO: support this when a symbol map is used
2236+
if expensive_optimizations and not emit_symbol_map:
2237+
js_file = Building.metadce(js_file, wasm_file, minify_whitespace=minify_whitespace, debug_info=debug_info)
2238+
# now that we removed unneeded communication between js and wasm, we can clean up
2239+
# the js some more.
2240+
passes = ['noPrintMetadata', 'AJSDCE']
2241+
if minify_whitespace:
2242+
passes.append('minifyWhitespace')
2243+
logging.debug('running post-meta-DCE cleanup on shell code: ' + ' '.join(passes))
2244+
js_file = Building.js_optimizer_no_asmjs(js_file, passes)
2245+
# finally, optionally use closure compiler to finish cleaning up the JS
2246+
if use_closure_compiler:
2247+
logging.debug('running closure on shell code')
2248+
js_file = Building.closure_compiler(js_file, pretty=not minify_whitespace)
22412249
return js_file
22422250

22432251
# run binaryen's wasm-metadce to dce both js and wasm

0 commit comments

Comments
 (0)