Skip to content

Commit 574f381

Browse files
authored
Remove fastcomp-only ELIMINATE_DUPLICATE_FUNCTIONS* options (#11876)
This has been a no-op on wasm, and this PR keeps it that way (we do duplicate function elimination in binaryen automatically). See #11860
1 parent 40dbef9 commit 574f381

File tree

9 files changed

+4
-1147
lines changed

9 files changed

+4
-1147
lines changed

emcc.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,9 +1869,6 @@ def include_and_export(name):
18691869
shared.Settings.WASM_BINARY_FILE = shared.JS.escape_for_js_string(os.path.basename(wasm_binary_target))
18701870
shared.Settings.ASMJS_CODE_FILE = shared.JS.escape_for_js_string(os.path.basename(asm_target))
18711871
shared.Settings.ASM_JS = 2 # when targeting wasm, we use a wasm Memory, but that is not compatible with asm.js opts
1872-
if shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS:
1873-
diagnostics.warning('emcc', 'for wasm there is no need to set ELIMINATE_DUPLICATE_FUNCTIONS, the binaryen optimizer does it automatically')
1874-
shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS = 0
18751872
if options.js_opts and not options.force_js_opts:
18761873
options.js_opts = None
18771874
logger.debug('asm.js opts not forced by user or an option that depends them, and we do not intend to run the asm.js, so disabling and leaving opts to the binaryen optimizer')
@@ -2695,12 +2692,6 @@ def get_eliminate():
26952692
else:
26962693
optimizer.queue += ['registerize']
26972694

2698-
# NOTE: Important that this comes after registerize/registerizeHarder
2699-
if shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS and shared.Settings.OPT_LEVEL >= 2:
2700-
optimizer.flush()
2701-
building.eliminate_duplicate_funcs(final)
2702-
save_intermediate('dfe')
2703-
27042695
if shared.Settings.EVAL_CTORS and options.memory_init_file and not use_source_map(options) and not shared.Settings.WASM:
27052696
optimizer.flush()
27062697
building.eval_ctors(final, memfile)

site/source/docs/optimizing/Optimizing-Code.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ The following compiler settings can help (see ``src/settings.js`` for more detai
8686
- Disable inlining when possible, using ``-s INLINING_LIMIT=1``. Compiling with -Os or -Oz generally avoids inlining too. (Inlining can make code faster, though, so use this carefully.)
8787
- You can use the ``-s FILESYSTEM=0`` option to disable bundling of filesystem support code (the compiler should optimize it out if not used, but may not always succeed). This can be useful if you are building a pure computational library, for example.
8888
- The ``ENVIRONMENT`` flag lets you specify that the output will only run on the web, or only run in node.js, etc. This prevents the compiler from emitting code to support all possible runtime environments, saving ~2KB.
89-
- You can use ``ELIMINATE_DUPLICATE_FUNCTIONS`` to remove duplicate functions, which C++ templates often create. (This is already done by default for wasm, in ``-O1`` and above.)
9089

9190
LTO
9291
===

src/settings.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,19 +1412,6 @@ var PTHREADS_DEBUG = 0;
14121412
// If true, building against Emscripten's asm.js/wasm heap memory profiler.
14131413
var MEMORYPROFILER = 0;
14141414

1415-
// Duplicate function elimination. This coalesces function bodies that are
1416-
// identical, which can happen e.g. if two methods have different C/C++ or LLVM
1417-
// types, but end up identical at the asm.js level (all pointers are the same as
1418-
// int32_t in asm.js, for example).
1419-
//
1420-
// This option is quite slow to run, as it processes and hashes all methods in
1421-
// the codebase in multiple passes.
1422-
//
1423-
// [fastcomp-only]
1424-
var ELIMINATE_DUPLICATE_FUNCTIONS = 0; // disabled by default
1425-
var ELIMINATE_DUPLICATE_FUNCTIONS_DUMP_EQUIVALENT_FUNCTIONS = 0;
1426-
var ELIMINATE_DUPLICATE_FUNCTIONS_PASSES = 5;
1427-
14281415
// This tries to evaluate global ctors at compile-time, applying their effects
14291416
// into the mem init file. This saves running code during startup, and also
14301417
// allows removing the global ctor functions and other code that only they used,
@@ -1766,6 +1753,9 @@ var LEGACY_SETTINGS = [
17661753
['SKIP_STACK_IN_SMALL', [0, 1], 'SKIP_STACK_IN_SMALL is no longer needed as the backend can optimize it directly'],
17671754
['SAFE_STACK', [0], 'Replace SAFE_STACK=1 with STACK_OVERFLOW_CHECK=2'],
17681755
['MEMORY_GROWTH_STEP', 'MEMORY_GROWTH_LINEAR_STEP'],
1756+
['ELIMINATE_DUPLICATE_FUNCTIONS', [0, 1], 'Duplicate function elimination for wasm is handled automatically by binaryen'],
1757+
['ELIMINATE_DUPLICATE_FUNCTIONS_DUMP_EQUIVALENT_FUNCTIONS', [0], 'Duplicate function elimination for wasm is handled automatically by binaryen'],
1758+
['ELIMINATE_DUPLICATE_FUNCTIONS_PASSES', [5], 'Duplicate function elimination for wasm is handled automatically by binaryen'],
17691759
// WASM_OBJECT_FILES is handled in emcc.py, supporting both 0 and 1 for now.
17701760
['WASM_OBJECT_FILES', [0, 1], 'For LTO, use -flto or -fto=thin instead; to disable LTO, just do not pass WASM_OBJECT_FILES=1 as 1 is the default anyhow'],
17711761
['TOTAL_MEMORY', 'INITIAL_MEMORY'],

tests/fuzz/25.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,8 +1785,3 @@ XXX max block depth: 5
17851785
XXX percentage a fresh-made variable is used: 17.8
17861786
XXX percentage an existing variable is used: 82.2
17871787
********************* end of statistics **********************/
1788-
1789-
1790-
// /usr/bin/python /Users/achoudhury/Code/emscripten/emscripten/emcc -Oz --llvm-opts 1 /Users/achoudhury/Code/emscripten/emscripten/tests/fuzz/temp_fuzzcode28225_.cpp -o /Users/achoudhury/Code/emscripten/emscripten/tests/fuzz/fuzz.cpp -I /usr/local/Cellar/csmith/2.2.0/include/csmith-2.2.0/runtime -s ELIMINATE_DUPLICATE_FUNCTIONS=1 --emit-symbol-map -w -s MAIN_MODULE=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_WHITELIST=["_main"]
1791-
1792-

tests/test_core.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -264,18 +264,6 @@ class TestCoreBase(RunnerCore):
264264
def is_wasm2js(self):
265265
return self.is_wasm_backend() and not self.get_setting('WASM')
266266

267-
# whether the test mode supports duplicate function elimination in js
268-
def supports_js_dfe(self):
269-
# wasm does this when optimizing anyhow, and the wasm backend always
270-
# optimizes the wasm even if it does wasm2js later
271-
if self.is_wasm() or self.is_wasm_backend():
272-
return False
273-
supported_opt_levels = ['-O2', '-O3', '-Oz', '-Os']
274-
for opt_level in supported_opt_levels:
275-
if opt_level in self.emcc_args:
276-
return True
277-
return False
278-
279267
# Use closure in some tests for some additional coverage
280268
def maybe_closure(self):
281269
if '-g' not in self.emcc_args and ('-O2' in self.emcc_args or '-Os' in self.emcc_args):
@@ -6258,14 +6246,6 @@ def test():
62586246

62596247
test()
62606248

6261-
if self.supports_js_dfe():
6262-
print("Testing poppler with ELIMINATE_DUPLICATE_FUNCTIONS set to 1", file=sys.stderr)
6263-
num_original_funcs = self.count_funcs('src.cpp.o.js')
6264-
self.set_setting('ELIMINATE_DUPLICATE_FUNCTIONS', 1)
6265-
test()
6266-
# Make sure that DFE ends up eliminating more than 200 functions (if we can view source)
6267-
assert (num_original_funcs - self.count_funcs('src.cpp.o.js')) > 200
6268-
62696249
@needs_make('make')
62706250
@is_slow_test
62716251
def test_openjpeg(self):
@@ -8290,14 +8270,6 @@ def test(assert_returncode=0):
82908270
print('ENVIRONMENT =', self.get_setting('ENVIRONMENT'))
82918271
test()
82928272

8293-
def test_dfe(self):
8294-
if not self.supports_js_dfe():
8295-
self.skipTest('dfe-only')
8296-
self.set_setting('ELIMINATE_DUPLICATE_FUNCTIONS', 1)
8297-
self.do_run_in_out_file_test('tests', 'core', 'test_hello_world')
8298-
self.emcc_args += ['-g2'] # test for issue #6331
8299-
self.do_run_in_out_file_test('tests', 'core', 'test_hello_world')
8300-
83018273
def test_postrun_exception(self):
83028274
# verify that an exception thrown in postRun() will not trigger the
83038275
# compilation failed handler, and will be printed to stderr.

tests/test_other.py

Lines changed: 1 addition & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import tools.line_endings
4444
import tools.js_optimizer
4545
import tools.tempfiles
46-
import tools.duplicate_function_eliminator
4746

4847
scons_path = shared.which('scons')
4948
emmake = shared.bat_suffix(path_from_root('emmake'))
@@ -6999,130 +6998,6 @@ def test_warn_unexported_main(self):
69996998
proc = self.run_process([EMCC, path_from_root('tests', 'hello_world.c'), '-s', 'EXPORTED_FUNCTIONS=[]'], stderr=PIPE)
70006999
self.assertContained(WARNING, proc.stderr)
70017000

7002-
############################################################
7003-
# Function eliminator tests
7004-
############################################################
7005-
def normalize_line_endings(self, input):
7006-
return input.replace('\r\n', '\n').replace('\n\n', '\n').replace('\n\n', '\n')
7007-
7008-
def get_file_contents(self, file):
7009-
file_contents = ""
7010-
with open(file) as fout:
7011-
file_contents = "".join(fout.readlines())
7012-
7013-
file_contents = self.normalize_line_endings(file_contents)
7014-
7015-
return file_contents
7016-
7017-
def function_eliminator_test_helper(self, input_file, expected_output_file, use_hash_info=False):
7018-
input_file = path_from_root('tests', 'optimizer', input_file)
7019-
expected_output_file = path_from_root('tests', 'optimizer', expected_output_file)
7020-
command = [path_from_root('tools', 'eliminate-duplicate-functions.js'), input_file, '--no-minimize-whitespace', '--use-asm-ast']
7021-
7022-
if use_hash_info:
7023-
command.append('--use-hash-info')
7024-
7025-
proc = self.run_process(NODE_JS + command, stdin=PIPE, stderr=PIPE, stdout=PIPE)
7026-
assert proc.stderr == '', proc.stderr
7027-
expected_output = self.get_file_contents(expected_output_file)
7028-
output = self.normalize_line_endings(proc.stdout)
7029-
7030-
self.assertIdentical(expected_output, output)
7031-
7032-
def test_function_eliminator_simple(self):
7033-
self.function_eliminator_test_helper('test-function-eliminator-simple.js',
7034-
'test-function-eliminator-simple-output.js')
7035-
7036-
def test_function_eliminator_replace_function_call(self):
7037-
self.function_eliminator_test_helper('test-function-eliminator-replace-function-call.js',
7038-
'test-function-eliminator-replace-function-call-output.js')
7039-
7040-
def test_function_eliminator_replace_function_call_two_passes(self):
7041-
self.function_eliminator_test_helper('test-function-eliminator-replace-function-call-output.js',
7042-
'test-function-eliminator-replace-function-call-two-passes-output.js')
7043-
7044-
def test_function_eliminator_replace_array_value(self):
7045-
output_file = 'output.js'
7046-
7047-
try:
7048-
shared.safe_copy(path_from_root('tests', 'optimizer', 'test-function-eliminator-replace-array-value.js'), output_file)
7049-
7050-
tools.duplicate_function_eliminator.run(output_file)
7051-
7052-
output_file_contents = self.get_file_contents(output_file)
7053-
7054-
expected_file_contents = self.get_file_contents(path_from_root('tests', 'optimizer', 'test-function-eliminator-replace-array-value-output.js'))
7055-
7056-
self.assertIdentical(expected_file_contents, output_file_contents)
7057-
finally:
7058-
tools.tempfiles.try_delete(output_file)
7059-
7060-
def test_function_eliminator_replace_object_value_assignment(self):
7061-
self.function_eliminator_test_helper('test-function-eliminator-replace-object-value-assignment.js',
7062-
'test-function-eliminator-replace-object-value-assignment-output.js')
7063-
7064-
def test_function_eliminator_variable_clash(self):
7065-
self.function_eliminator_test_helper('test-function-eliminator-variable-clash.js',
7066-
'test-function-eliminator-variable-clash-output.js')
7067-
7068-
def test_function_eliminator_replace_variable_value(self):
7069-
self.function_eliminator_test_helper('test-function-eliminator-replace-variable-value.js',
7070-
'test-function-eliminator-replace-variable-value-output.js')
7071-
7072-
@no_wasm_backend('tests native asm.js optimizer, which is never build for wasm backend')
7073-
def test_function_eliminator_double_parsed_correctly(self):
7074-
# This is a test that makes sure that when we perform final optimization on
7075-
# the JS file, doubles are preserved (and not converted to ints).
7076-
output_file = 'output.js'
7077-
7078-
try:
7079-
shared.safe_copy(path_from_root('tests', 'optimizer', 'test-function-eliminator-double-parsed-correctly.js'), output_file)
7080-
7081-
# Run duplicate function elimination
7082-
tools.duplicate_function_eliminator.run(output_file)
7083-
7084-
# Run last opts
7085-
shutil.move(tools.js_optimizer.run(output_file, ['last', 'asm']), output_file)
7086-
output_file_contents = self.get_file_contents(output_file)
7087-
7088-
# Compare
7089-
expected_file_contents = self.get_file_contents(path_from_root('tests', 'optimizer', 'test-function-eliminator-double-parsed-correctly-output.js'))
7090-
self.assertIdentical(expected_file_contents, output_file_contents)
7091-
finally:
7092-
tools.tempfiles.try_delete(output_file)
7093-
7094-
# Now do the same, but using a pre-generated equivalent function hash info that
7095-
# comes in handy for parallel processing
7096-
def test_function_eliminator_simple_with_hash_info(self):
7097-
self.function_eliminator_test_helper('test-function-eliminator-simple-with-hash-info.js',
7098-
'test-function-eliminator-simple-output.js',
7099-
use_hash_info=True)
7100-
7101-
def test_function_eliminator_replace_function_call_with_hash_info(self):
7102-
self.function_eliminator_test_helper('test-function-eliminator-replace-function-call-with-hash-info.js',
7103-
'test-function-eliminator-replace-function-call-output.js',
7104-
use_hash_info=True)
7105-
7106-
def test_function_eliminator_replace_function_call_two_passes_with_hash_info(self):
7107-
self.function_eliminator_test_helper('test-function-eliminator-replace-function-call-output-with-hash-info.js',
7108-
'test-function-eliminator-replace-function-call-two-passes-output.js',
7109-
use_hash_info=True)
7110-
7111-
def test_function_eliminator_replace_object_value_assignment_with_hash_info(self):
7112-
self.function_eliminator_test_helper('test-function-eliminator-replace-object-value-assignment-with-hash-info.js',
7113-
'test-function-eliminator-replace-object-value-assignment-output.js',
7114-
use_hash_info=True)
7115-
7116-
def test_function_eliminator_variable_clash_with_hash_info(self):
7117-
self.function_eliminator_test_helper('test-function-eliminator-variable-clash-with-hash-info.js',
7118-
'test-function-eliminator-variable-clash-output.js',
7119-
use_hash_info=True)
7120-
7121-
def test_function_eliminator_replace_variable_value_with_hash_info(self):
7122-
self.function_eliminator_test_helper('test-function-eliminator-replace-variable-value-with-hash-info.js',
7123-
'test-function-eliminator-replace-variable-value-output.js',
7124-
use_hash_info=True)
7125-
71267001
def test_source_file_with_fixed_language_mode(self):
71277002
create_test_file('src_tmp_fixed_lang', '''
71287003
#include <string>
@@ -9035,7 +8910,7 @@ def test_minimal_runtime_code_size(self):
90358910
'-DNDEBUG',
90368911
'-ffast-math']
90378912

9038-
asmjs = ['-s', 'WASM=0', '--separate-asm', '-s', 'ELIMINATE_DUPLICATE_FUNCTIONS=1', '--memory-init-file', '1']
8913+
asmjs = ['-s', 'WASM=0', '--separate-asm', '-s', '--memory-init-file', '1']
90398914
wasm2js = ['-s', 'WASM=0', '--memory-init-file', '1']
90408915

90418916
hello_world_sources = [path_from_root('tests', 'small_hello_world.c'),

tools/building.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -986,11 +986,6 @@ def eval_ctors(js_file, binary_file, binaryen_bin='', debug_info=False):
986986
check_call(cmd)
987987

988988

989-
def eliminate_duplicate_funcs(filename):
990-
from . import duplicate_function_eliminator
991-
duplicate_function_eliminator.eliminate_duplicate_funcs(filename)
992-
993-
994989
def calculate_reachable_functions(infile, initial_list, can_reach=True):
995990
with ToolchainProfiler.profile_block('calculate_reachable_functions'):
996991
from . import asm_module

0 commit comments

Comments
 (0)