Skip to content

Run multiple iterations of JSDCE, as more may be removable #5855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 6, 2017
Merged
21 changes: 11 additions & 10 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2363,20 +2363,21 @@ def do_binaryen(final, target, asm_target, options, memfile, wasm_binary_target,
if options.opt_level >= 2:
# minify the JS
optimizer.do_minify() # calculate how to minify
if optimizer.cleanup_shell or optimizer.minify_whitespace or options.use_closure_compiler:
misc_temp_files.note(final)
if optimizer.cleanup_shell or options.use_closure_compiler:
if DEBUG: save_intermediate('preclean', 'js')
# in -Os and -Oz, run AJSDCE (aggressive JS DCE, performs multiple iterations)
passes = ['noPrintMetadata', 'JSDCE' if options.shrink_level == 0 else 'AJSDCE', 'last']
if optimizer.minify_whitespace:
passes.append('minifyWhitespace')
misc_temp_files.note(final)
logging.debug('running cleanup on shell code: ' + ' '.join(passes))
final = shared.Building.js_optimizer_no_asmjs(final, passes)
if DEBUG: save_intermediate('postclean', 'js')
if options.use_closure_compiler:
logging.debug('running closure on shell code')
misc_temp_files.note(final)
final = shared.Building.closure_compiler(final, pretty=not optimizer.minify_whitespace)
else:
assert optimizer.cleanup_shell
logging.debug('running cleanup on shell code')
passes = ['noPrintMetadata', 'JSDCE', 'last']
if optimizer.minify_whitespace:
passes.append('minifyWhitespace')
final = shared.Building.js_optimizer_no_asmjs(final, passes)
if DEBUG: save_intermediate('postclean', 'js')
if DEBUG: save_intermediate('postclosure', 'js')
# replace placeholder strings with correct subresource locations
if shared.Settings.SINGLE_FILE:
f = open(final, 'r')
Expand Down
27 changes: 27 additions & 0 deletions tests/optimizer/AJSDCE-output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

var z = fleefl();
var zz = fleefl();
function g(a) {
return a + 1;
}
Module["g"] = g;
function h(a) {
return a + 1;
}
print(h(123));
((function() {
var z = fleefl();
var zz = fleefl();
function g(a) {
return a + 1;
}
Module["g"] = g;
function hh(a) {
return a + 1;
}
print(hh(123));
}))();
function glue() {
}
glue();

61 changes: 61 additions & 0 deletions tests/optimizer/AJSDCE.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

// all unused
var x;
var y = 1;
var z = fleefl();
var xx, yy = 1, zz = fleefl(); // but zz must remain due to the side effects in the value
function f(x, y, z) {
// shadow the x,y,z
x = y;
y = z;
}

// exported
function g(a) {
return a+1;
}
Module['g'] = g;

// used
function h(a) {
var t; // unused
return a+1;
}
print(h(123));

// inner workings
(function() {
var x;
var y = 1;
var z = fleefl();
var xx, yy = 1, zz = fleefl();
function f(x, y, z) {
// shadow the x,y,z
x = y;
y = z;
}

// exported
function g(a) {
return a+1;
}
Module['g'] = g;

// used
function hh(a) {
var t; // unused
return a+1;
}
print(hh(123));
})();

function glue() {
function lookup() { // 2 passes needed for this one
throw 1;
}
function removable() { // first remove this
lookup();
}
}
glue();

6 changes: 6 additions & 0 deletions tests/optimizer/JSDCE-output.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ print(h(123));
}
print(hh(123));
}))();
function glue() {
function lookup() {
throw 1;
}
}
glue();

10 changes: 10 additions & 0 deletions tests/optimizer/JSDCE.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,13 @@ print(h(123));
print(hh(123));
})();

function glue() {
function lookup() { // 2 passes needed for this one
throw 1;
}
function removable() { // first remove this
lookup();
}
}
glue();

25 changes: 13 additions & 12 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ def is_split_memory(self):
def is_wasm(self):
return 'BINARYEN' in str(self.emcc_args) or self.is_wasm_backend()

# Use closure in some tests for some additional coverage
def maybe_closure(self):
if '-O2' in self.emcc_args or '-Os' in self.emcc_args:
self.emcc_args += ['--closure', '1']
return True
return False

def do_run_in_out_file_test(self, *path, **kwargs):
test_path = path_from_root(*path)

Expand Down Expand Up @@ -882,8 +889,7 @@ def test_exceptions(self):
Settings.EXCEPTION_DEBUG = 1

Settings.DISABLE_EXCEPTION_CATCHING = 0
if '-O2' in self.emcc_args:
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
self.maybe_closure()

src = '''
#include <stdio.h>
Expand Down Expand Up @@ -4089,8 +4095,7 @@ def test_langinfo(self):

def test_files(self):
self.banned_js_engines = [SPIDERMONKEY_ENGINE] # closure can generate variables called 'gc', which pick up js shell stuff
if '-O2' in self.emcc_args:
self.emcc_args += ['--closure', '1'] # Use closure here, to test we don't break FS stuff
if self.maybe_closure(): # Use closure here, to test we don't break FS stuff
self.emcc_args = [x for x in self.emcc_args if x != '-g'] # ensure we test --closure 1 --memory-init-file 1 (-g would disable closure)
elif '-O3' in self.emcc_args and not self.is_wasm():
print('closure 2')
Expand Down Expand Up @@ -5095,8 +5100,7 @@ def test_sse1(self):
orig_args = self.emcc_args
for mode in [[], ['-s', 'SIMD=1']]:
self.emcc_args = orig_args + mode + ['-msse']
if '-O2' in self.emcc_args:
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
self.maybe_closure()

self.do_run(open(path_from_root('tests', 'test_sse1.cpp'), 'r').read(), 'Success!')

Expand All @@ -5118,8 +5122,7 @@ def test_sse1_full(self):
orig_args = self.emcc_args
for mode in [[], ['-s', 'SIMD=1']]:
self.emcc_args = orig_args + mode + ['-I' + path_from_root('tests'), '-msse']
if '-O2' in self.emcc_args:
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
self.maybe_closure()

self.do_run(open(path_from_root('tests', 'test_sse1_full.cpp'), 'r').read(), self.ignore_nans(native_result), output_nicerizer=self.ignore_nans)

Expand All @@ -5141,8 +5144,7 @@ def test_sse2_full(self):
orig_args = self.emcc_args
for mode in [[], ['-s', 'SIMD=1']]:
self.emcc_args = orig_args + mode + ['-I' + path_from_root('tests'), '-msse2'] + args
if '-O2' in self.emcc_args:
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
self.maybe_closure()

self.do_run(open(path_from_root('tests', 'test_sse2_full.cpp'), 'r').read(), self.ignore_nans(native_result), output_nicerizer=self.ignore_nans)

Expand Down Expand Up @@ -5451,8 +5453,7 @@ def test_sqlite(self):
force_c=True)

def test_zlib(self):
if '-O2' in self.emcc_args and 'ASM_JS=0' not in self.emcc_args: # without asm, closure minifies Math.imul badly
self.emcc_args += ['--closure', '1'] # Use closure here for some additional coverage
self.maybe_closure()

assert 'asm2g' in test_modes
if self.run_name == 'asm2g':
Expand Down
2 changes: 2 additions & 0 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -1973,6 +1973,8 @@ def test_js_optimizer(self):
['JSDCE']),
(path_from_root('tests', 'optimizer', 'JSDCE-hasOwnProperty.js'), open(path_from_root('tests', 'optimizer', 'JSDCE-hasOwnProperty-output.js')).read(),
['JSDCE']),
(path_from_root('tests', 'optimizer', 'AJSDCE.js'), open(path_from_root('tests', 'optimizer', 'AJSDCE-output.js')).read(),
['AJSDCE']),
]:
print(input, passes)

Expand Down
Loading