diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-12-12 13:35:51 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-12-12 13:35:51 -0800 |
commit | 063298bda9a66fc55b22c55d4ddf8ca3768efc8a (patch) | |
tree | 67f8e4e59c818698500807d1625dad3aaf58fd99 | |
parent | 30f386472c4d92828f1c15ebd826e62328e66fa6 (diff) |
emcc initial support for -Ox
-rwxr-xr-x | emcc | 40 | ||||
-rw-r--r-- | tests/runner.py | 38 |
2 files changed, 63 insertions, 15 deletions
@@ -128,8 +128,12 @@ Most normal gcc/g++ options will work, for example: --version Display compiler version information Options that are modified or new in %s include: - -O0 [..] default - -OX TODO + -O0 No optimizations (default) + -O1 Simple optimizations and no runtime assertions + -O2 As -O1, plus code flow optimization (relooper) + Warning: Compiling with this takes a long time! + -O3 As -O2, plus dangerous optimizations that may + break things -s OPTION=VALUE JavaScript code generation option passed into the emscripten compiler --typed-arrays <mode> 0: no typed arrays @@ -253,10 +257,20 @@ if use_linker: elif use_compiler: call = CXX if use_cxx else CC + + ## Parse args + newargs = sys.argv[1:] + + opt_level = 0 + for i in range(len(newargs)): if newargs[i].startswith('-O'): - if DEBUG: print >> sys.stderr, 'emcc: WARNING: Optimization flags (-Ox) are ignored in emcc. Tell emscripten.py to do that, or run LLVM opt.' + try: + opt_level = int(newargs[i][2]) + assert 0 <= opt_level <= 3 + except: + raise Exception('Invalid optimization level: ' + newargs[i]) newargs[i] = '' newargs = [ arg for arg in newargs if arg is not '' ] + CC_ADDITIONAL_ARGS @@ -271,6 +285,8 @@ elif use_compiler: final_suffix = target.split('.')[-1] + ## Compile + # First, generate LLVM bitcode TODO: handle |emcc a.cpp b.cpp -c| which generate *two* bitcode files newargs = newargs + ['-emit-llvm', '-c', '-o', target_basename + '.bc'] @@ -283,7 +299,23 @@ elif use_compiler: shutil.move(target_basename + '.bc', target_basename + '.o') exit(0) - # Continue on to create JavaScript + ## Continue on to create JavaScript + + # Apply optimization level settings + if opt_level >= 1: + shared.Settings.ASSERTIONS = 0 + if opt_level >= 2: + shared.Settings.RELOOP = 1 + if opt_level >= 3: + shared.Settings.CORRECT_SIGNS = 0 + shared.Settings.CORRECT_OVERFLOWS = 0 + shared.Settings.CORRECT_ROUNDINGS = 0 + shared.Settings.I64_MODE = 0 + shared.Settings.DOUBLE_MODE = 0 + shared.Settings.DISABLE_EXCEPTION_CATCHING = 1 + + # TODO: apply -s settings in newargs here (after -Ox, so they can override it) + temp_files = shared.TempFiles() temp_files.note(target_basename + '.bc') try: diff --git a/tests/runner.py b/tests/runner.py index 76881a67..0d224c50 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -4894,8 +4894,12 @@ Most normal gcc/g++ options will work, for example: --version Display compiler version information Options that are modified or new in %s include: - -O0 [..] default - -OX TODO + -O0 No optimizations (default) + -O1 Simple optimizations and no runtime assertions + -O2 As -O1, plus code flow optimization (relooper) + Warning: Compiling with this takes a long time! + -O3 As -O2, plus dangerous optimizations that may + break things -s OPTION=VALUE JavaScript code generation option passed into the emscripten compiler --typed-arrays <mode> 0: no typed arrays @@ -4936,15 +4940,26 @@ JavaScript in the final linking stage of building. assert os.path.exists(target), output self.assertContained('hello, world!', self.run_llvm_interpreter([target])) - # emcc src.cpp -o something.js - clear() - output = Popen([compiler, path_from_root('tests', 'hello_world' + suffix), '-o', 'something.js'], stdout=PIPE, stderr=PIPE).communicate(input) - assert len(output[0]) == 0, output[0] - assert os.path.exists('something.js'), output - self.assertContained('hello, world!', run_js('something.js')) - - # emcc -O0 src.cpp ==> same as without -O0: assertions, etc., and greatest chance of code working: i64 1, ta2, etc., micro-opts - # emcc -O1 src.cpp ==> no assertions, plus eliminator, plus js optimizer + # emcc src.cpp -o something.js [-Ox]. -O0 is the same as not specifying any optimization setting + for opt_params, opt_level in [([], 0), (['-O0'], 0), (['-O1'], 1), (['-O2'], 2), (['-O3'], 3)]: + clear() + output = Popen([compiler, path_from_root('tests', 'hello_world_loop.cpp'), '-o', 'something.js'] + opt_params, + stdout=PIPE, stderr=PIPE).communicate(input) + assert len(output[0]) == 0, output[0] + assert os.path.exists('something.js'), '\n'.join(output) + self.assertContained('hello, world!', run_js('something.js')) + + # Verify optimization level in the generated code + # XXX these are quite sensitive, and will need updating when code generation changes + generated = open('something.js').read() # TODO: parse out the _main function itself, not support code, if the tests below need that some day + assert ('while(1) switch(__label__)' in generated) == (opt_level <= 1), 'relooping should be in opt >= 2' + assert ('assert(STACKTOP < STACK_MAX)' in generated) == (opt_level == 0), 'assertions should be in opt == 0' + assert ('|0)/2)|0)' in generated) == (opt_level <= 2), 'corrections should be in opt <= 2' + assert 'var $i;' in generated, 'micro opts should always be on' + assert 'HEAP32[' in generated, 'typed arrays 2 should be used by default' + assert 'SAFE_HEAP' not in generated, 'safe heap should not be used by default' + + # TODO: -O1 plus eliminator, plus js optimizer # emcc -O2 src.cpp ==> plus reloop (warn about speed) # emcc -O3 src.cpp ==> no corrections, relax some other stuff like i64 1 into 0, etc., do closure: dangerous stuff, warn, suggest -O2! # emcc --typed-arrays=x .. ==> should use typed arrays. default should be 2 @@ -4960,6 +4975,7 @@ JavaScript in the final linking stage of building. # TODO: when ready, switch tools/shared building to use emcc over emmaken # TODO: add shebang to generated .js files, using JS_ENGINES[0]? #!/usr/bin/python etc # TODO: when this is done, more test runner to test these (i.e., test all -Ox thoroughly) + # TODO: use -O3 in benchmarks, which will test that -O3 is optimized for max speed # Finally, test HTML generation. (Coincidentally we also test that compiling a .cpp works in EMCC here.) clear() |