diff options
-rwxr-xr-x | emcc | 13 | ||||
-rw-r--r-- | tests/test_other.py | 2 | ||||
-rw-r--r-- | tools/js-optimizer.js | 18 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-last-output.js | 2 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre-f32.js | 11 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre-output-f32.js | 11 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre-output.js | 19 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre.js | 22 |
8 files changed, 88 insertions, 10 deletions
@@ -1967,16 +1967,23 @@ try: if len(js_optimizer_extra_info) == 0: js_optimizer_extra_info = None if len(js_optimizer_queue) > 0 and not(not shared.Settings.ASM_JS and len(js_optimizer_queue) == 1 and js_optimizer_queue[0] == 'last'): - if DEBUG != '2': + + def add_opt_args(args): if shared.Settings.ASM_JS: - js_optimizer_queue = ['asm'] + js_optimizer_queue + args = ['asm'] + args + if shared.Settings.PRECISE_F32: + args = ['asmPreciseF32'] + args + return args + + if DEBUG != '2': + js_optimizer_queue = add_opt_args(js_optimizer_queue) logging.debug('applying js optimization passes: %s', js_optimizer_queue) final = shared.Building.js_optimizer(final, js_optimizer_queue, jcache, debug_level >= 4, js_optimizer_extra_info) js_transform_tempfiles.append(final) if DEBUG: save_intermediate('js_opts') else: for name in js_optimizer_queue: - passes = [name] + passes = add_opt_args([name]) if shared.Settings.ASM_JS: passes = ['asm'] + passes logging.debug('applying js optimization pass: %s', passes) diff --git a/tests/test_other.py b/tests/test_other.py index bc05826e..47d26416 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -1779,6 +1779,8 @@ f.close() ['asm', 'registerize', 'minifyLocals']), (path_from_root('tools', 'test-js-optimizer-asm-pre.js'), open(path_from_root('tools', 'test-js-optimizer-asm-pre-output.js')).read(), ['asm', 'simplifyExpressions']), + (path_from_root('tools', 'test-js-optimizer-asm-pre-f32.js'), open(path_from_root('tools', 'test-js-optimizer-asm-pre-output-f32.js')).read(), + ['asm', 'asmPreciseF32', 'simplifyExpressions']), (path_from_root('tools', 'test-js-optimizer-asm-last.js'), open(path_from_root('tools', 'test-js-optimizer-asm-last-output.js')).read(), ['asm', 'last']), (path_from_root('tools', 'test-js-optimizer-asm-relocate.js'), open(path_from_root('tools', 'test-js-optimizer-asm-relocate-output.js')).read(), diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 21d521fd..6724e77f 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -722,14 +722,19 @@ function simplifyExpressions(ast) { if (correct === 'HEAP32') { define[3] = ['binary', '|', define[3], ['num', 0]]; } else { - define[3] = ['unary-prefix', '+', define[3]]; + define[3] = makeAsmCoercion(define[3], asmPreciseF32 ? ASM_FLOAT : ASM_DOUBLE); } // do we want a simplifybitops on the new values here? }); info.uses.forEach(function(use) { use[2][1][1] = correct; }); - asmData.vars[v] = 1 - asmData.vars[v]; + var correctType; + switch(asmData.vars[v]) { + case ASM_INT: correctType = asmPreciseF32 ? ASM_FLOAT : ASM_DOUBLE; break; + case ASM_FLOAT: case ASM_DOUBLE: correctType = ASM_INT; break; + } + asmData.vars[v] = correctType; } } denormalizeAsm(ast, asmData); @@ -1138,7 +1143,9 @@ function optimizeShiftsAggressive(ast) { // or such. Simplifying these saves space and time. function simplifyNotCompsDirect(node) { if (node[0] === 'unary-prefix' && node[1] === '!') { - if (node[2][0] === 'binary') { + // de-morgan's laws do not work on floats, due to nans >:( + if (node[2][0] === 'binary' && (!asm || (((node[2][2][0] === 'binary' && node[2][2][1] === '|') || node[2][2][0] === 'num') && + ((node[2][3][0] === 'binary' && node[2][3][1] === '|') || node[2][3][0] === 'num')))) { switch(node[2][1]) { case '<': return ['binary', '>=', node[2][2], node[2][3]]; case '>': return ['binary', '<=', node[2][2], node[2][3]]; @@ -1577,7 +1584,7 @@ function makeAsmVarDef(v, type) { case ASM_INT: return [v, ['num', 0]]; case ASM_DOUBLE: return [v, ['unary-prefix', '+', ['num', 0]]]; case ASM_FLOAT: return [v, ['call', ['name', 'Math_fround'], [['num', 0]]]]; - default: throw 'wha?'; + default: throw 'wha? ' + JSON.stringify([node, type]) + new Error().stack; } } @@ -5153,7 +5160,7 @@ function asmLastOpts(ast) { // Passes table -var minifyWhitespace = false, printMetadata = true, asm = false, last = false; +var minifyWhitespace = false, printMetadata = true, asm = false, asmPreciseF32 = false, last = false; var passes = { // passes @@ -5182,6 +5189,7 @@ var passes = { minifyWhitespace: function() { minifyWhitespace = true }, noPrintMetadata: function() { printMetadata = false }, asm: function() { asm = true }, + asmPreciseF32: function() { asmPreciseF32 = true }, last: function() { last = true }, }; diff --git a/tools/test-js-optimizer-asm-last-output.js b/tools/test-js-optimizer-asm-last-output.js index f850b18f..1b9ac585 100644 --- a/tools/test-js-optimizer-asm-last-output.js +++ b/tools/test-js-optimizer-asm-last-output.js @@ -39,7 +39,7 @@ function looop() { } while (!condition()); do { do_it(); - } while (a <= b); + } while (!(a > b)); do { do_it(); } while (x()); diff --git a/tools/test-js-optimizer-asm-pre-f32.js b/tools/test-js-optimizer-asm-pre-f32.js new file mode 100644 index 00000000..a5604ef9 --- /dev/null +++ b/tools/test-js-optimizer-asm-pre-f32.js @@ -0,0 +1,11 @@ +function badf() { + var $9 = Math_fround(0); + $9 = (HEAP32[tempDoublePtr>>2]=$8,Math_fround(HEAPF32[tempDoublePtr>>2])); + HEAPF32[$gep23_asptr>>2] = $9; +} +function badf2() { + var $9 = 0; + $9 = (HEAPF32[tempDoublePtr>>2]=$8,HEAP32[tempDoublePtr>>2]|0); + HEAP32[$gep23_asptr>>2] = $9; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8", "tempDoublePtr", "boxx", "_main", "badf", "badf2"] diff --git a/tools/test-js-optimizer-asm-pre-output-f32.js b/tools/test-js-optimizer-asm-pre-output-f32.js new file mode 100644 index 00000000..42343f55 --- /dev/null +++ b/tools/test-js-optimizer-asm-pre-output-f32.js @@ -0,0 +1,11 @@ +function badf() { + var $9 = 0; + $9 = $8 | 0; + HEAP32[$gep23_asptr >> 2] = $9; +} +function badf2() { + var $9 = Math_fround(0); + $9 = Math_fround($8); + HEAPF32[$gep23_asptr >> 2] = $9; +} + diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js index 0fa81050..c9746e78 100644 --- a/tools/test-js-optimizer-asm-pre-output.js +++ b/tools/test-js-optimizer-asm-pre-output.js @@ -519,4 +519,23 @@ function _main($argc, $argv) { STACKTOP = __stackBase__; return $_0 | 0; } +function badf() { + var $9 = 0; + $9 = $8 | 0; + HEAP32[$gep23_asptr >> 2] = $9; +} +function badf2() { + var $9 = +0; + $9 = +$8; + HEAPF32[$gep23_asptr >> 2] = $9; +} +function fcomp() { + if (!($y < $x)) return 5; + if (!(5 < $x)) return 5; + if (!($y < 5)) return 5; + if (($a | 0) >= ($b | 0)) return 5; + if (($a | 0) >= 5) return 5; + if (5 >= ($b | 0)) return 5; + if (5 >= 5) return 5; +} diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js index dadeef53..00ebd7d7 100644 --- a/tools/test-js-optimizer-asm-pre.js +++ b/tools/test-js-optimizer-asm-pre.js @@ -530,4 +530,24 @@ function _main($argc, $argv) { STACKTOP = __stackBase__; return $_0 | 0; } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8", "tempDoublePtr", "boxx", "_main"] +function badf() { + var $9 = Math_fround(0); + $9 = (HEAP32[tempDoublePtr>>2]=$8,Math_fround(HEAPF32[tempDoublePtr>>2])); + HEAPF32[$gep23_asptr>>2] = $9; +} +function badf2() { + var $9 = 0; + $9 = (HEAPF32[tempDoublePtr>>2]=$8,HEAP32[tempDoublePtr>>2]|0); + HEAP32[$gep23_asptr>>2] = $9; +} +function fcomp() { + // de-morgan's laws are not valid on floats, due to NaNs >:( + if (!($y < $x)) return 5; + if (!(5 < $x)) return 5; + if (!($y < 5)) return 5; + if (!(($a|0) < ($b|0))) return 5; + if (!(($a|0) < 5)) return 5; + if (!(5 < ($b|0))) return 5; + if (!(5 < 5)) return 5; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8", "tempDoublePtr", "boxx", "_main", "badf", "badf2", "fcomp"] |