diff options
-rw-r--r-- | settings.py | 2 | ||||
-rw-r--r-- | src/analyzer.js | 36 | ||||
-rw-r--r-- | src/compiler.js | 3 | ||||
-rw-r--r-- | src/intertyper.js | 7 | ||||
-rw-r--r-- | src/jsifier.js | 4 | ||||
-rw-r--r-- | src/library.js | 12 | ||||
-rw-r--r-- | src/parseTools.js | 16 | ||||
-rw-r--r-- | src/preamble.js | 8 | ||||
-rw-r--r-- | src/settings.js | 10 | ||||
-rw-r--r-- | tests/runner.py | 19 |
10 files changed, 76 insertions, 41 deletions
diff --git a/settings.py b/settings.py index cf4fd28c..c6d63341 100644 --- a/settings.py +++ b/settings.py @@ -13,7 +13,7 @@ COMPILER_OPTS = ['-m32'] # Need to build as 32bit arch, for now - # various errors on 64bit compilation # WARNING: '-g' here will generate llvm bitcode that lli will crash on! -SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/mozilla-central/js/src/js'), '-m', '-j', '-p'] +SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/mozilla-central/js/src/js'), '-m', '-n'] V8_ENGINE = [os.path.expanduser('~/Dev/v8/d8')] #COMPILER_ENGINE=SPIDERMONKEY_ENGINE # XXX Warning: currently appears to be broken on trunk, some file reading issue diff --git a/src/analyzer.js b/src/analyzer.js index 96e6297b..824e7903 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -275,25 +275,27 @@ function analyzer(data) { } }); - // Second pass over variables - notice when types are crossed by bitcast - - func.lines.forEach(function(item) { - if (item.intertype === 'assign' && item.value.intertype === 'bitcast') { - // bitcasts are unique in that they convert one pointer to another. We - // sometimes need to know the original type of a pointer, so we save that. - // - // originalType is the type this variable is created from - // derivedTypes are the types that this variable is cast into - func.variables[item.ident].originalType = item.value.type2; - - if (!isNumber(item.value.ident)) { - if (!func.variables[item.value.ident].derivedTypes) { - func.variables[item.value.ident].derivedTypes = []; + if (QUANTUM_SIZE === 1) { + // Second pass over variables - notice when types are crossed by bitcast + + func.lines.forEach(function(item) { + if (item.intertype === 'assign' && item.value.intertype === 'bitcast') { + // bitcasts are unique in that they convert one pointer to another. We + // sometimes need to know the original type of a pointer, so we save that. + // + // originalType is the type this variable is created from + // derivedTypes are the types that this variable is cast into + func.variables[item.ident].originalType = item.value.type2; + + if (!isNumber(item.value.ident)) { + if (!func.variables[item.value.ident].derivedTypes) { + func.variables[item.value.ident].derivedTypes = []; + } + func.variables[item.value.ident].derivedTypes.push(item.value.type); } - func.variables[item.value.ident].derivedTypes.push(item.value.type); } - } - }); + }); + } for (vname in func.variables) { var variable = func.variables[vname]; diff --git a/src/compiler.js b/src/compiler.js index 8980da93..9bf81ba4 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -71,6 +71,9 @@ eval(processMacros(preprocess(read('runtime.js')))); // Read llvm var raw = read(ll_file); +if (FAKE_X86_FP80) { + raw = raw.replace(/x86_fp80/g, 'double'); +} var lines = raw.split('\n'); raw = null; diff --git a/src/intertyper.js b/src/intertyper.js index ed8d5099..83a49645 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -543,7 +543,9 @@ function intertyper(data, parseFunctions, baseLineNum) { item.intertype = 'bitcast'; item.type = item.tokens[4].text; // The final type Types.needAnalysis[item.type] = 0; - item.ident = toNiceIdent(item.tokens[2].text); + var to = getTokenIndexByText(item.tokens, 'to'); + item.params = [parseLLVMSegment(item.tokens.slice(2, to))]; + item.ident = item.params[0].ident; item.type2 = item.tokens[1].text; // The original type Types.needAnalysis[item.type2] = 0; this.forwardItem(item, 'Reintegrator'); @@ -791,10 +793,9 @@ function intertyper(data, parseFunctions, baseLineNum) { // external function stub substrate.addActor('External', { processItem: function(item) { - if (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR) { + if (item.tokens[1].text in LLVM.LINKAGES || item.tokens[1].text in LLVM.PARAM_ATTR || item.tokens[1].text in LLVM.VISIBILITIES) { item.tokens.splice(1, 1); } - var params = parseParamTokens(item.tokens[3].item.tokens); return [{ intertype: 'functionStub', diff --git a/src/jsifier.js b/src/jsifier.js index ab381a03..330597bf 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -585,7 +585,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { makeFuncLineActor('store', function(item) { var value = finalizeLLVMParameter(item.value); if (pointingLevels(item.pointerType) == 1) { - value = parseNumerical(value, removePointing(item.pointerType)); + value = parseNumerical(value, item.valueType); } var impl = VAR_EMULATED; if (item.pointer.intertype == 'value') { @@ -758,7 +758,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { makeFuncLineActor('mathop', processMathop); makeFuncLineActor('bitcast', function(item) { - return item.ident; + return finalizeLLVMParameter(item.params[0]); }); function makeFunctionCall(ident, params, funcData) { diff --git a/src/library.js b/src/library.js index 9cb1967a..62e4de55 100644 --- a/src/library.js +++ b/src/library.js @@ -3743,7 +3743,8 @@ LibraryManager.library = { strdup: function(ptr) { var len = String_len(ptr); var newStr = _malloc(len + 1); - {{{ makeCopyValues('newStr', 'ptr', 'len + 1', 'null', ' || 0') }}}; + {{{ makeCopyValues('newStr', 'ptr', 'len', 'null') }}}; + {{{ makeSetValue('newStr', 'len', '0', 'i8') }}}; return newStr; }, @@ -4037,6 +4038,14 @@ LibraryManager.library = { return -1; // 'indeterminable' for FLT_ROUNDS }, + llvm_memory_barrier: function(){}, + + llvm_atomic_load_add_i32_p0i32: function(ptr, delta) { + var ret = {{{ makeGetValue('ptr', '0', 'i32') }}}; + {{{ makeSetValue('ptr', '0', 'ret+delta', 'i32') }}}; + return ret; + }, + // ========================================================================== // iostream.h // ========================================================================== @@ -5145,6 +5154,7 @@ LibraryManager.library = { pthread_mutex_destroy: function() {}, pthread_mutex_lock: function() {}, pthread_mutex_unlock: function() {}, + pthread_cond_broadcast: function() {}, // ========================================================================== // malloc.h diff --git a/src/parseTools.js b/src/parseTools.js index edf8384d..a3347139 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -74,7 +74,7 @@ function toNiceIdent(ident) { assert(ident); if (parseFloat(ident) == ident) return ident; if (ident == 'null') return '0'; // see parseNumerical - return ident.replace('%', '$').replace(/["&\\ \.@:<>,\*\[\]-]/g, '_'); + return ident.replace('%', '$').replace(/["&\\ \.@:<>,\*\[\]\(\)-]/g, '_'); } // Kind of a hack. In some cases we have strings that we do not want @@ -143,6 +143,7 @@ function isFunctionDef(token) { } function isFunctionType(type) { + type = type.replace(/"[^"]+"/g, '".."'); var parts = type.split(' '); if (pointingLevels(type) !== 1) return false; var text = removeAllPointing(parts.slice(1).join(' ')); @@ -430,6 +431,9 @@ function parseLLVMFunctionCall(segment) { if (type === '?') { if (intertype === 'getelementptr') { type = '*'; // a pointer, we can easily say, this is + } else if (intertype === 'bitcast') { + assert(segment[2].item.tokens.slice(-2)[0].text === 'to'); + type = segment[2].item.tokens.slice(-1)[0].text; } } var ret = { @@ -486,7 +490,15 @@ function IEEEUnHex(stringy) { stringy = stringy.substr(2); // leading '0x'; if (stringy.replace(/0/g, '') === '') return 0; while (stringy.length < 16) stringy = '0' + stringy; - assert(stringy.length === 16, 'Can only unhex 16-digit double numbers, nothing platform-specific'); + if (FAKE_X86_FP80 && stringy.length > 16) { + stringy = stringy.substr(stringy.length-16, 16); + if (!Debugging.shownIEEEUnHexWarning) { + dprint('WARNING: .ll contains floating-point values with more than 64 bits. Faking values for them.'); + dprint(' If they are used, this will almost certainly fail!'); + Debugging.shownIEEEUnHexWarning = true; + } + } + assert(stringy.length === 16, 'Can only unhex 16-digit double numbers, nothing platform-specific'); // |long double| can cause x86_fp80 which causes this var top = eval('0x' + stringy[0]); var neg = !!(top & 8); // sign if (neg) { diff --git a/src/preamble.js b/src/preamble.js index 9e0f5ce3..8ab9bce8 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -428,7 +428,8 @@ var STACK_ROOT, STACKTOP, STACK_MAX; var STATICTOP; var HAS_TYPED_ARRAYS = false; -var TOTAL_MEMORY = 50*1024*1024; +var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || {{{ TOTAL_MEMORY }}}; +var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}}; // Initialize the runtime's memory #if USE_TYPED_ARRAYS @@ -459,9 +460,8 @@ if (HAS_TYPED_ARRAYS) { } else #endif { - // Without this optimization, Chrome is slow. Sadly, the constant here needs to be tweaked depending on the code being run... - var FAST_MEMORY = TOTAL_MEMORY/32; - HEAP = new Array(FAST_MEMORY); + // Make sure that our HEAP is implemented as a flat array. + HEAP = new Array(TOTAL_MEMORY); for (var i = 0; i < FAST_MEMORY; i++) { HEAP[i] = 0; // XXX We do *not* use {{| makeSetValue(0, 'i', 0, 'null') |}} here, since this is done just to optimize runtime speed } diff --git a/src/settings.js b/src/settings.js index ed3437b1..ab532e67 100644 --- a/src/settings.js +++ b/src/settings.js @@ -34,6 +34,12 @@ INVOKE_RUN = 1; // Whether we will call run(). Disable if you embed the generate // code in your own, and will call run() yourself at the right time INIT_STACK = 1; // Whether to initialize memory on the stack to 0. INIT_HEAP = 0; // Whether to initialize memory anywhere other than the stack to 0. +FAST_MEMORY = 2*1024*1024; // The amount of memory to initialize to 0. This ensures it will be + // in a flat array. This only matters in non-typed array builds. +TOTAL_MEMORY = 50*1024*1024; // The total amount of memory to use. This mainly matters in + // typed array builds - accessing memory about this value will + // return undefined values and lead to serious problems, and there + // is currently no warning about that! // Code embetterments OPTIMIZE = 0; // Optimize llvm operations into js commands @@ -129,6 +135,10 @@ RUNTIME_TYPE_INFO = 0; // Whether to expose type info to the script at run time. // to more easily perform operations from handwritten JS on // objects with structures etc. +FAKE_X86_FP80 = 0; // Replaces x86_fp80 with double. This loses precision. It is better, + // if you can, to get the original source code to build without x86_fp80 + // (which is nonportable anyhow). + // Compiler debugging options DEBUG_TAGS_SHOWING = []; // Some useful items: diff --git a/tests/runner.py b/tests/runner.py index 09ea6745..54898ac0 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -178,7 +178,7 @@ class RunnerCore(unittest.TestCase): def do_emscripten(self, filename, output_processor=None, append_ext=True, extra_args=[]): # Run Emscripten exported_settings = {} - for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'AUTO_OPTIMIZE', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTIONS']: + for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'AUTO_OPTIMIZE', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTIONS', 'FAST_MEMORY']: try: value = eval(setting) exported_settings[setting] = value @@ -233,7 +233,7 @@ class RunnerCore(unittest.TestCase): ################################################################################################### -if 'benchmark' not in sys.argv: +if 'benchmark' not in str(sys.argv): # Tests print "Running Emscripten tests..." @@ -2980,7 +2980,6 @@ if 'benchmark' not in sys.argv: self.do_ll_test(path_from_root('tests', 'lua', 'lua.ll'), 'hello lua world!\n17\n1\n2\n3\n4\n7', - js_engines=[V8_ENGINE], # XXX Moz bug 675269 args=['-e', '''print("hello lua world!");print(17);for x = 1,4 do print(x) end;print(10-3)'''], output_nicerizer=lambda string: string.replace('\n\n', '\n').replace('\n\n', '\n')) @@ -3161,15 +3160,13 @@ if 'benchmark' not in sys.argv: self.do_ll_test(combined, lambda: map(ord, open(path_from_root('tests', 'poppler', 'ref.ppm'), 'r').read()).__str__().replace(' ', ''), args='-scale-to 512 paper.pdf filename'.split(' '), - post_build=post, - js_engines=[V8_ENGINE]) # XXX Moz bug 675269 + post_build=post) #, build_ll_hook=self.do_autodebug) def test_openjpeg(self): global USE_TYPED_ARRAYS global CORRECT_SIGNS if USE_TYPED_ARRAYS == 2: - return self.skip() # XXX Moz bug 675269 CORRECT_SIGNS = 1 else: CORRECT_SIGNS = 2 @@ -3250,7 +3247,6 @@ if 'benchmark' not in sys.argv: os.path.join(self.get_building_dir(), 'openjpeg')], force_c=True, post_build=post, - js_engines=[V8_ENGINE], # XXX Moz bug 675269 output_nicerizer=image_compare)# build_ll_hook=self.do_autodebug) def test_python(self): @@ -3264,7 +3260,6 @@ if 'benchmark' not in sys.argv: self.do_ll_test(path_from_root('tests', 'python', 'python.ll'), 'hello python world!\n[0, 2, 4, 6]\n5\n22\n5.470000', - js_engines=[V8_ENGINE], # XXX Moz bug 675269 args=['-S', '-c' '''print "hello python world!"; print [x*2 for x in range(4)]; t=2; print 10-3-t; print (lambda x: x*2)(11); print '%f' % 5.47'''], extra_emscripten_args=['-m']) @@ -3968,7 +3963,8 @@ TT = %s self.assertEquals(output, expected) else: - # Benchmarks + # Benchmarks. Run them with argument |benchmark|. To run a specific test, do + # |benchmark.test_X|. print "Running Emscripten benchmarks..." @@ -4001,6 +3997,7 @@ else: CORRECT_OVERFLOWS_LINES = CORRECT_SIGNS_LINES = CORRECT_ROUNDINGS_LINES = SAFE_HEAP_LINES = [] LLVM_OPTS = 1 DISABLE_EXCEPTIONS = 1 + FAST_MEMORY = 10*1024*1024 TEST_REPS = 4 TOTAL_TESTS = 6 @@ -4009,7 +4006,7 @@ else: total_times = map(lambda x: 0., range(TEST_REPS)) total_native_times = map(lambda x: 0., range(TEST_REPS)) - class Benchmark(RunnerCore): + class benchmark(RunnerCore): def print_stats(self, times, native_times): mean = sum(times)/len(times) squared_times = map(lambda x: x*x, times) @@ -4149,7 +4146,7 @@ else: old_quantum = QUANTUM_SIZE old_use_typed_arrays = USE_TYPED_ARRAYS QUANTUM_SIZE = 1 - USE_TYPED_ARRAYS = 0 # Rounding errors with TA2 are too big in this very rounding-sensitive code + USE_TYPED_ARRAYS = 0 # Rounding errors with TA2 are too big in this very rounding-sensitive code. However, TA2 is much faster (2X) src = open(path_from_root('tests', 'raytrace.cpp'), 'r').read().replace('double', 'float') # benchmark with floats self.do_benchmark(src, ['7', '256'], '256 256') |