Skip to content

Commit 633885b

Browse files
authored
Remove fastcomp-only PRECISE_F32 setting (#11863)
Removing this also means we can remove the "client mods" stuff that used to do various things but recently has only done PRECISE_F32. Also the optimizeFrounds optimizer pass was only for this option, and the asm2f test mode.
1 parent c8903ba commit 633885b

26 files changed

+36
-2262
lines changed

emcc.py

Lines changed: 4 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
from subprocess import PIPE
4141

4242
import emscripten
43-
from tools import shared, system_libs, client_mods, js_optimizer
43+
from tools import shared, system_libs, js_optimizer
4444
from tools import colored_logger, diagnostics, building
4545
from tools.shared import unsuffixed, unsuffixed_basename, WINDOWS, safe_move, run_process, asbytes, read_and_preprocess, exit_with_error, DEBUG
4646
from tools.response_file import substitute_response_files
@@ -369,8 +369,6 @@ def flush(self, title='js_opts'):
369369
def run_passes(self, passes, title, just_split, just_concat):
370370
global final
371371
passes = ['asm'] + passes
372-
if shared.Settings.PRECISE_F32:
373-
passes = ['asmPreciseF32'] + passes
374372
if (self.emit_symbol_map or shared.Settings.CYBERDWARF) and 'minifyNames' in passes:
375373
passes += ['symbolMap=' + shared.replace_or_append_suffix(self.target, '.symbols')]
376374
if self.profiling_funcs and 'minifyNames' in passes:
@@ -1258,9 +1256,6 @@ def get_last_setting_change(setting):
12581256
wasm_binary_target = asm_target.replace('.asm.js', '.wasm') # ditto, might not be used
12591257
wasm_source_map_target = shared.replace_or_append_suffix(wasm_binary_target, '.map')
12601258

1261-
if final_suffix == '.html' and not options.separate_asm and 'PRECISE_F32=2' in settings_changes:
1262-
options.separate_asm = True
1263-
diagnostics.warning('emcc', 'forcing separate asm output (--separate-asm), because -s PRECISE_F32=2 was passed.')
12641259
if options.separate_asm:
12651260
shared.Settings.SEPARATE_ASM = shared.JS.get_subresource_location(asm_target)
12661261

@@ -1879,8 +1874,6 @@ def include_and_export(name):
18791874
if shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS:
18801875
diagnostics.warning('emcc', 'for wasm there is no need to set ELIMINATE_DUPLICATE_FUNCTIONS, the binaryen optimizer does it automatically')
18811876
shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS = 0
1882-
# default precise-f32 to on, since it works well in wasm
1883-
shared.Settings.PRECISE_F32 = 1
18841877
if options.js_opts and not options.force_js_opts:
18851878
options.js_opts = None
18861879
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')
@@ -2001,10 +1994,6 @@ def include_and_export(name):
20011994
if (shared.Settings.MAIN_MODULE or shared.Settings.SIDE_MODULE) and shared.Settings.ALLOW_MEMORY_GROWTH and not shared.Settings.WASM:
20021995
exit_with_error('memory growth is not supported with shared asm.js modules')
20031996

2004-
if shared.Settings.MINIMAL_RUNTIME:
2005-
if shared.Settings.PRECISE_F32 == 2:
2006-
exit_with_error('-s PRECISE_F32=2 is not supported with -s MINIMAL_RUNTIME=1')
2007-
20081997
if shared.Settings.ALLOW_MEMORY_GROWTH and shared.Settings.ASM_JS == 1:
20091998
# this is an issue in asm.js, but not wasm
20101999
if not shared.Settings.WASM:
@@ -2705,9 +2694,6 @@ def get_eliminate():
27052694
if shared.Settings.SIMPLIFY_IFS and debugging and not shared.Settings.WASM:
27062695
optimizer.queue += ['simplifyIfs']
27072696

2708-
if shared.Settings.PRECISE_F32:
2709-
optimizer.queue += ['optimizeFrounds']
2710-
27112697
if options.js_opts:
27122698
if shared.Settings.SAFE_HEAP and not building.is_wasm_only():
27132699
optimizer.queue += ['safeHeap']
@@ -3523,8 +3509,6 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
35233509
assert '{{{ SCRIPT }}}' in shell, 'HTML shell must contain {{{ SCRIPT }}} , see src/shell.html for an example'
35243510
base_js_target = os.path.basename(js_target)
35253511

3526-
asm_mods = []
3527-
35283512
if options.proxy_to_worker:
35293513
proxy_worker_filename = (shared.Settings.PROXY_TO_WORKER_FILENAME or target_basename) + '.js'
35303514
worker_js = worker_js_script(proxy_worker_filename)
@@ -3534,7 +3518,6 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
35343518
console.log('running code in a web worker');
35353519
''' % shared.JS.get_subresource_location(proxy_worker_filename)) + worker_js + '''
35363520
} else {
3537-
// note: no support for code mods (PRECISE_F32==2)
35383521
console.log('running code on the main thread');
35393522
var fileBytes = tryParseAsDataURI(filename);
35403523
var script = document.createElement('script');
@@ -3550,10 +3533,6 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
35503533
# Normal code generation path
35513534
script.src = base_js_target
35523535

3553-
asm_mods = client_mods.get_mods(shared.Settings,
3554-
minified='minifyNames' in optimizer.queue_history,
3555-
separate_asm=options.separate_asm)
3556-
35573536
if not shared.Settings.SINGLE_FILE:
35583537
if options.memory_init_file and not shared.Settings.MEM_INIT_IN_WASM:
35593538
# start to load the memory init file in the HTML, in parallel with the JS
@@ -3571,13 +3550,11 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
35713550
# Download .asm.js if --separate-asm was passed in an asm.js build, or if 'asmjs' is one
35723551
# of the wasm run methods.
35733552
if not options.separate_asm or shared.Settings.WASM:
3574-
if len(asm_mods):
3575-
exit_with_error('no --separate-asm means no client code mods are possible')
3553+
pass
35763554
else:
35773555
script.un_src()
3578-
if len(asm_mods) == 0:
3579-
# just load the asm, then load the rest
3580-
script.inline = '''
3556+
# just load the asm, then load the rest
3557+
script.inline = '''
35813558
var filename = '%s';
35823559
var fileBytes = tryParseAsDataURI(filename);
35833560
var script = document.createElement('script');
@@ -3593,38 +3570,6 @@ def generate_traditional_runtime_html(target, options, js_target, target_basenam
35933570
};
35943571
document.body.appendChild(script);
35953572
''' % (shared.JS.get_subresource_location(asm_target), script.inline)
3596-
else:
3597-
# may need to modify the asm code, load it as text, modify, and load asynchronously
3598-
script.inline = '''
3599-
var codeURL = '%s';
3600-
var codeXHR = new XMLHttpRequest();
3601-
codeXHR.open('GET', codeURL, true);
3602-
codeXHR.onload = function() {
3603-
var code;
3604-
if (codeXHR.status === 200 || codeXHR.status === 0) {
3605-
code = codeXHR.responseText;
3606-
} else {
3607-
var codeURLBytes = tryParseAsDataURI(codeURL);
3608-
if (codeURLBytes) {
3609-
code = intArrayToString(codeURLBytes);
3610-
}
3611-
}
3612-
%s
3613-
var blob = new Blob([code], { type: 'text/javascript' });
3614-
codeXHR = null;
3615-
var src = URL.createObjectURL(blob);
3616-
var script = document.createElement('script');
3617-
script.src = src;
3618-
script.onload = function() {
3619-
setTimeout(function() {
3620-
%s
3621-
}, 1); // delaying even 1ms is enough to allow compilation memory to be reclaimed
3622-
URL.revokeObjectURL(script.src);
3623-
};
3624-
document.body.appendChild(script);
3625-
};
3626-
codeXHR.send(null);
3627-
''' % (shared.JS.get_subresource_location(asm_target), '\n'.join(asm_mods), script.inline)
36283573

36293574
if shared.Settings.WASM and not shared.Settings.WASM_ASYNC_COMPILATION:
36303575
# We need to load the wasm file before anything else, it has to be synchronously ready TODO: optimize

emscripten.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,6 @@ def parse_fastcomp_output(backend_output, DEBUG):
154154
if 'Float64Array' in metadata['externUses']:
155155
metadata['externUses'] += ['Float32Array']
156156

157-
# If we are generating references to Math.fround() from here in emscripten.py, declare it used as well.
158-
if provide_fround():
159-
metadata['externUses'] += ['Math.fround']
160-
161157
# functions marked llvm.used in the code are exports requested by the user
162158
building.user_requested_exports += metadata['exports']
163159

@@ -514,10 +510,10 @@ def create_module_asmjs(function_table_sigs, metadata,
514510
stack += apply_memory(' var STACK_MAX = {{{ STACK_MAX }}};\n')
515511

516512
if 'tempFloat' in shared.Settings.ASM_PRIMITIVE_VARS:
517-
temp_float = ' var tempFloat = %s;\n' % ('Math_fround(0)' if provide_fround() else '0.0')
513+
temp_float = ' var tempFloat = %s;\n' % 'Math_fround(0)'
518514
else:
519515
temp_float = ''
520-
f0_fround = ' const f0 = Math_fround(0);\n' if provide_fround() else ''
516+
f0_fround = ' const f0 = Math_fround(0);\n'
521517

522518
replace_memory = create_replace_memory(metadata)
523519

@@ -574,8 +570,6 @@ def create_backend_cmd(infile, temp_js):
574570
'-emscripten-stack-size=%d' % shared.Settings.TOTAL_STACK,
575571
'-O%s' % shared.Settings.OPT_LEVEL,
576572
]
577-
if shared.Settings.PRECISE_F32:
578-
args += ['-emscripten-precise-f32']
579573
if shared.Settings.USE_PTHREADS:
580574
args += ['-emscripten-enable-pthreads']
581575
if shared.Settings.WARN_UNALIGNED:
@@ -1346,9 +1340,7 @@ def asm_backend_uses(metadata, symbol):
13461340

13471341

13481342
def create_asm_global_funcs(bg_funcs, metadata):
1349-
maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul', 'min', 'max', 'clz32']]
1350-
if provide_fround():
1351-
maths += ['Math.fround']
1343+
maths = ['Math.' + func for func in ['floor', 'abs', 'sqrt', 'pow', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'atan2', 'exp', 'log', 'ceil', 'imul', 'min', 'max', 'clz32', 'fround']]
13521344

13531345
asm_global_funcs = ''
13541346
for math in maths:
@@ -1375,10 +1367,6 @@ def asm_safe_heap():
13751367
return shared.Settings.SAFE_HEAP and not shared.Settings.SAFE_HEAP_LOG and not shared.Settings.RELOCATABLE
13761368

13771369

1378-
def provide_fround():
1379-
return shared.Settings.PRECISE_F32
1380-
1381-
13821370
def create_asm_setup(debug_tables, function_table_data, invoke_function_names, metadata):
13831371
function_table_sigs = function_table_data.keys()
13841372

site/source/docs/api_reference/emscripten.h.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,9 +1031,9 @@ Functions
10311031
10321032
Returns the value of a compiler setting.
10331033
1034-
For example, to return the integer representing the value of ``PRECISE_F32`` during compilation: ::
1034+
For example, to return the integer representing the value of ``INITIAL_MEMORY`` during compilation: ::
10351035
1036-
emscripten_get_compiler_setting("PRECISE_F32")
1036+
emscripten_get_compiler_setting("INITIAL_MEMORY")
10371037
10381038
For values containing anything other than an integer, a string is returned (you will need to cast the ``int`` return value to a ``char*``).
10391039

site/source/docs/compiling/Building-Projects.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ Emscripten compiler output often consists of several files and not just one. The
8585
- `emcc ... -o output.a` generates a single archive file `output.a`.
8686
- `emcc ... -o output.{html,js} -s WASM=0` causes the compiler to target asm.js, and therefore a `.wasm` file is not produced.
8787
- `emcc ... -o output.{html,js} -s WASM=0 --separate-asm` likewise targets asm.js, but splits up the generated code to two files, `output.js` and `output.asm.js`.
88-
- `emcc ... -o output.html -s WASM=0 -s PRECISE_F32=2` (combination of targeting .html, asm.js and PRECISE_F32=2) implies as if `--separate-asm` was passed, so also produces `output.asm.js`.
8988
- `emcc ... -o output.{html,js} --emit-symbol-map` produces a file `output.{html,js}.symbols` if WebAssembly is being targeted (`-s WASM=0` not specified), or if asm.js is being targeted and `-Os`, `-Oz` or `-O2` or higher is specified, but debug level setting is `-g1` or lower (i.e. if symbols minification did occur).
9089
- `emcc ... -o output.{html,js} -s WASM=0 --memory-init-file 1` causes the generation of `output.{html,js}.mem` memory initializer file. Pasing `-O2`, `-Os` or `-Oz` also implies `--memory-init-file 1`.
9190
- `emcc ... -o output.{html,js} -g4` generates a source map file `output.wasm.map`. If targeting asm.js with `-s WASM=0`, the filename is `output.{html,js}.map`.

site/source/docs/compiling/WebAssembly.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ asm.js support is considered very stable now, and you can change between it and
145145
- Timing issues - wasm might run faster or slower. To some extent you can mitigate that by building with ``-s DETERMINISTIC=1``.
146146
- Trap mode. As mentioned above, we can generate wasm that traps or that avoids traps. Make sure the trap mode is ``"js"`` when comparing builds. The ``"js"`` trap mode is also useful in a single build, as otherwise operations like division or float-to-int may trap, and the optimizer may happen to change whether a trap occurs or not, which can be confusing (for example, enabling ``SAFE_HEAP`` may prevent some optimizations, and a trap may start to occur). Instead, in the ``"js"`` trap mode there are no traps and all operations are deterministically defined as identical to JavaScript.
147147
- Minor libc and runtime differences exist between wasm and asm.js. We used to have a way to emit more compatable builds (``-s "BINARYEN_METHOD='asmjs,native-wasm'"`` etc.) but due to its complexity and low value it was removed.
148-
- Floating-point behavior: WebAssembly uses 32-bit floats in a standard way, while asm.js by default implements floats using doubles. That can lead to differences in the precision of results. You can force 32-bit float behavior in asm.js with ``-s PRECISE_F32=1``, in which case it should be identical to wasm.
149148
- Browser instability: It's worth testing multiple browsers, as one might have a wasm bug that another doesn't. You can also test the Binaryen interpreter (e.g. using the ``interpret-binary`` method, as discussed above).
150149

151150
If you find that an asm.js build has the same behavior as a wasm one, then it is currently easier to debug the asm.js build: you can edit the source easily (add debug printouts, etc.), there is debug info and source maps support, etc.

site/source/docs/getting_started/FAQ.rst

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -502,16 +502,6 @@ Building :ref:`Fastcomp from source <building-fastcomp-from-source>` (and hence
502502
The solution is to ensure the system has sufficient memory. On Ubuntu 14.04.1 LTS 64bit, you should use at least 6Gb.
503503

504504

505-
Why do I get odd rounding errors when using float variables?
506-
============================================================
507-
508-
In asm.js, by default Emscripten uses doubles for all floating-point variables, that is, 64-bit floats even when C/C++ code contains 32-bit floats. This is simplest and most efficient to implement in JS as doubles are the only native numeric type. As a result, you may see rounding errors compared to native code using 32-bit floats, just because of the difference in precision between 32-bit and 64-bit floating-point values.
509-
510-
To check if this is the issue you are seeing, build with ``-s PRECISE_F32=1``. This uses proper 32-bit floating-point values, at the cost of some extra code size overhead. This may be faster in some browsers, if they optimize ``Math.fround``, but can be slower in others. See ``src/settings.js`` for more details on this option.
511-
512-
(This is not an issue for wasm, which has native float types.)
513-
514-
515505
How do I pass int64_t and uint64_t values from js into wasm functions?
516506
======================================================================
517507

src/parseTools.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ function ensureDot(value) {
757757

758758
function asmEnsureFloat(value, type) { // ensures that a float type has either 5.5 (clearly a float) or +5 (float due to asm coercion)
759759
if (!isNumber(value)) return value;
760-
if (PRECISE_F32 && type === 'float') {
760+
if (type === 'float') {
761761
// normally ok to just emit Math_fround(0), but if the constant is large we may need a .0 (if it can't fit in an int)
762762
if (value == 0) return 'Math_fround(0)';
763763
value = ensureDot(value);
@@ -772,7 +772,7 @@ function asmEnsureFloat(value, type) { // ensures that a float type has either 5
772772

773773
function asmInitializer(type) {
774774
if (type in Compiletime.FLOAT_TYPES) {
775-
if (PRECISE_F32 && type === 'float') return 'Math_fround(0)';
775+
if (type === 'float') return 'Math_fround(0)';
776776
return RUNNING_JS_OPTS ? '+0' : '.0';
777777
} else {
778778
return '0';
@@ -793,7 +793,7 @@ function asmCoercion(value, type, signedness) {
793793
value = '(' + value + ')|0';
794794
}
795795
}
796-
if (PRECISE_F32 && type === 'float') {
796+
if (type === 'float') {
797797
return 'Math_fround(' + value + ')';
798798
} else {
799799
return '(+(' + value + '))';
@@ -1461,7 +1461,7 @@ function ensureValidFFIType(type) {
14611461
// FFI return values must arrive as doubles, and we can force them to floats afterwards
14621462
function asmFFICoercion(value, type) {
14631463
value = asmCoercion(value, ensureValidFFIType(type));
1464-
if (PRECISE_F32 && type === 'float') value = asmCoercion(value, 'float');
1464+
if (type === 'float') value = asmCoercion(value, 'float');
14651465
return value;
14661466
}
14671467

src/runtime_math.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,10 @@ if (!Math.imul || Math.imul(0xffffffff, 5) !== -5) Math.imul = function imul(a,
1919

2020
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround
2121
#if POLYFILL_OLD_MATH_FUNCTIONS || MIN_CHROME_VERSION < 38 || MIN_EDGE_VERSION < 12 || MIN_FIREFOX_VERSION < 26 || MIN_IE_VERSION != TARGET_NOT_SUPPORTED || MIN_SAFARI_VERSION < 80000 // || MIN_NODE_VERSION < 0.12
22-
#if PRECISE_F32
23-
#if PRECISE_F32 == 1
2422
if (!Math.fround) {
2523
var froundBuffer = new Float32Array(1);
2624
Math.fround = function(x) { froundBuffer[0] = x; return froundBuffer[0] };
2725
}
28-
#else // 2
29-
if (!Math.fround) Math.fround = function(x) { return x };
30-
#endif
31-
#endif
3226
#endif
3327

3428
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32

src/settings.js

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -265,29 +265,6 @@ var DOUBLE_MODE = 1;
265265
// wasm.
266266
var WARN_UNALIGNED = 0;
267267

268-
// 0: Use JS numbers for floating-point values. These are 64-bit and do not model C++
269-
// floats exactly, which are 32-bit.
270-
// 1: Model C++ floats precisely, using Math.fround, polyfilling when necessary. This
271-
// can be slow if the polyfill is used on heavy float32 computation. See note on
272-
// browser support below.
273-
// 2: Model C++ floats precisely using Math.fround if available in the JS engine, otherwise
274-
// use an empty polyfill. This will have much less of a speed penalty than using the full
275-
// polyfill in cases where engine support is not present. In addition, we can
276-
// remove the empty polyfill calls themselves on the client when generating html,
277-
// which should mean that this gives you the best of both worlds of 0 and 1, and is
278-
// therefore recommended, *unless* you need a guarantee of proper float32 precision
279-
// (in that case, use option 1).
280-
// XXX Note: To optimize float32-using code, we use the 'const' keyword in the emitted
281-
// code. This allows us to avoid unnecessary calls to Math.fround, which would
282-
// slow down engines not yet supporting that function. 'const' is present in
283-
// all modern browsers, including Firefox, Chrome and Safari, but in IE is only
284-
// present in IE11 and above. Therefore if you need to support legacy versions of
285-
// IE, you should not enable PRECISE_F32 1 or 2.
286-
// [fastcomp-only]
287-
// With upstream backend and WASM=0, JS output always uses Math.fround for consistent
288-
// behavior with WebAssembly.
289-
var PRECISE_F32 = 0;
290-
291268
// Whether closure compiling is being run on this output
292269
var USE_CLOSURE_COMPILER = 0;
293270

tests/fuzz/test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ rm *.out *.bc *.js
77
gcc $@ -m32 -I/home/alon/Dev/csmith/runtime -o n1.out &> /dev/null
88
/home/alon/Dev/fastcomp/build/Release+Asserts/bin/clang -m32 -I/home/alon/Dev/csmith/runtime -o n2.out $@ &> /dev/null
99
/home/alon/Dev/fastcomp/build/Release+Asserts/bin/clang -m32 -I/home/alon/Dev/csmith/runtime -emit-llvm -c -o bc.bc $@ &> o
10-
~/Dev/emscripten/emcc $@ -I/home/alon/Dev/csmith/runtime -s PRECISE_F32=1 -o fc.out.js --memory-init-file 0 -profiling &> /dev/null
11-
~/Dev/emscripten/emcc $@ -s SAFE_HEAP=1 -I/home/alon/Dev/csmith/runtime -s PRECISE_F32=1 -o fc-sh.out.js &> /dev/null
10+
~/Dev/emscripten/emcc $@ -I/home/alon/Dev/csmith/runtime -o fc.out.js --memory-init-file 0 -profiling &> /dev/null
11+
~/Dev/emscripten/emcc $@ -s SAFE_HEAP=1 -I/home/alon/Dev/csmith/runtime -o fc-sh.out.js &> /dev/null
1212
echo "run n1"
1313
./n1.out &> n1
1414
echo "run n2"

0 commit comments

Comments
 (0)