diff options
-rwxr-xr-x | emscripten.py | 2 | ||||
-rw-r--r-- | src/analyzer.js | 10 | ||||
-rw-r--r-- | src/parseTools.js | 17 | ||||
-rw-r--r-- | src/preamble.js | 7 | ||||
-rw-r--r-- | src/settings.js | 1 | ||||
-rw-r--r-- | tests/cases/phi24_ta2.ll | 3 | ||||
-rw-r--r-- | tools/find_bigvars.py | 24 |
7 files changed, 57 insertions, 7 deletions
diff --git a/emscripten.py b/emscripten.py index 217fd6d5..1b1284c7 100755 --- a/emscripten.py +++ b/emscripten.py @@ -423,6 +423,8 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, math_envs = ['Math.min'] # TODO: move min to maths asm_setup += '\n'.join(['var %s = %s;' % (f.replace('.', '_'), f) for f in math_envs]) + if settings['TO_FLOAT32']: maths += ['Math.toFloat32'] + basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs] if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall') if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_HEAP_CLEAR'] diff --git a/src/analyzer.js b/src/analyzer.js index 1a752305..931ce421 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -765,7 +765,15 @@ function analyzer(data, sidePass) { } break; } - case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem': + case 'add': case 'sub': case 'sdiv': case 'udiv': case 'mul': case 'urem': case 'srem': { + if (sourceBits < 32) { + // when we add illegal types like i24, we must work on the singleton chunks + item.assignTo += '$0'; + item.params[0].ident += '$0'; + item.params[1].ident += '$0'; + } + // fall through + } case 'uitofp': case 'sitofp': case 'fptosi': case 'fptoui': { // We cannot do these in parallel chunks of 32-bit operations. We will handle these in processMathop i++; diff --git a/src/parseTools.js b/src/parseTools.js index b655d13e..f11c867a 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -2020,6 +2020,13 @@ function makeIsNaN(value) { return 'isNaN(' + value + ')'; } +function makeFloat(value, type) { + if (TO_FLOAT32 && type == 'float') { + return 'Math.toFloat32(' + value + ')'; + } + return value; +} + // fptoui and fptosi are not in these, because we need to be careful about what we do there. We can't // just sign/unsign the input first. var UNSIGNED_OP = set('udiv', 'urem', 'uitofp', 'zext', 'lshr'); @@ -2275,11 +2282,11 @@ function processMathop(item) { return idents[0] + ' >>> ' + idents[1]; } // basic float ops - case 'fadd': return getFastValue(idents[0], '+', idents[1], item.type); - case 'fsub': return getFastValue(idents[0], '-', idents[1], item.type); - case 'fdiv': return getFastValue(idents[0], '/', idents[1], item.type); - case 'fmul': return getFastValue(idents[0], '*', idents[1], item.type); - case 'frem': return getFastValue(idents[0], '%', idents[1], item.type); + case 'fadd': return makeFloat(getFastValue(idents[0], '+', idents[1], item.type), item.type); + case 'fsub': return makeFloat(getFastValue(idents[0], '-', idents[1], item.type), item.type); + case 'fdiv': return makeFloat(getFastValue(idents[0], '/', idents[1], item.type), item.type); + case 'fmul': return makeFloat(getFastValue(idents[0], '*', idents[1], item.type), item.type); + case 'frem': return makeFloat(getFastValue(idents[0], '%', idents[1], item.type), item.type); case 'uitofp': case 'sitofp': return asmCoercion(idents[0], 'double', op[0]); case 'fptoui': case 'fptosi': return makeRounding(idents[0], bitsLeft, op === 'fptosi', true); diff --git a/src/preamble.js b/src/preamble.js index 95bf2dc2..0f3f52c9 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -853,6 +853,13 @@ Math['imul'] = function(a, b) { #endif Math.imul = Math['imul']; +#if TO_FLOAT32 +if (!Math['toFloat32']) Math['toFloat32'] = function(x) { + return x; +}; +Math.toFloat32 = Math['toFloat32']; +#endif + // A counter of dependencies for calling run(). If we need to // do asynchronous work before running, increment this and // decrement it. Incrementing must happen in a place like diff --git a/src/settings.js b/src/settings.js index 3515091d..3ecac040 100644 --- a/src/settings.js +++ b/src/settings.js @@ -108,6 +108,7 @@ var PRECISE_I64_MATH = 1; // If enabled, i64 addition etc. is emulated - which i var PRECISE_I32_MUL = 1; // If enabled, i32 multiplication is done with full precision, which means it is // correct even if the value exceeds the JS double-integer limit of ~52 bits (otherwise, // rounding will occur above that range). +var TO_FLOAT32 = 0; // Use Math.toFloat32 var CLOSURE_ANNOTATIONS = 0; // If set, the generated code will be annotated for the closure // compiler. This potentially lets closure optimize the code better. diff --git a/tests/cases/phi24_ta2.ll b/tests/cases/phi24_ta2.ll index b5b0664b..4894d5e6 100644 --- a/tests/cases/phi24_ta2.ll +++ b/tests/cases/phi24_ta2.ll @@ -549,7 +549,8 @@ safe_mod_func_uint32_t_u_u.exit.i.i: ; preds = %189, %.preheader..p %p_5.sroa.0.0.extract.trunc2674116.i.i = phi i8 [ %p_5.sroa.0.0.extract.trunc2670.i.i, %189 ], [ -1, %.preheader..preheader.split_crit_edge.i.i ] %p_5.sroa.1.sroa.0.0.load6982115.i.i = phi i24 [ %p_5.sroa.1.sroa.0.0.load6978.i.i, %189 ], [ -1, %.preheader..preheader.split_crit_edge.i.i ] store i16 0, i16* @g_84, align 2 - %p_5.sroa.1.1.insert.ext36.i.i = trunc i24 %p_5.sroa.1.sroa.0.0.load6982115.i.i to i16 + %adddd = add i24 %p_5.sroa.1.sroa.0.0.load6982115.i.i, 1 ; test i24 add + %p_5.sroa.1.1.insert.ext36.i.i = trunc i24 %adddd to i16 %p_5.sroa.1.1.insert.shift37.i.i = shl i16 %p_5.sroa.1.1.insert.ext36.i.i, 8 %p_5.sroa.0.0.insert.ext10.i.i = zext i8 %p_5.sroa.0.0.extract.trunc2674116.i.i to i16 %p_5.sroa.0.0.insert.insert12.i.i = or i16 %p_5.sroa.1.1.insert.shift37.i.i, %p_5.sroa.0.0.insert.ext10.i.i diff --git a/tools/find_bigvars.py b/tools/find_bigvars.py new file mode 100644 index 00000000..6bee5dd4 --- /dev/null +++ b/tools/find_bigvars.py @@ -0,0 +1,24 @@ +''' +Simple tool to find functions with lots of vars. +''' + +import os, sys, re + +filename = sys.argv[1] +i = 0 +curr = None +data = [] +size = 0 +for line in open(filename): + i += 1 + if line.startswith('function '): + size = len(line.split(',')) # params + curr = line + elif line.strip().startswith('var '): + size += len(line.split(',')) + 1 # vars + elif line.startswith('}') and curr: + data.append([curr, size]) + curr = None +data.sort(lambda x, y: x[1] - y[1]) +print ''.join(['%6d : %s' % (x[1], x[0]) for x in data]) + |