diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-10-16 09:48:32 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-10-16 09:48:32 -0700 |
commit | 85817285da7a17f8cd914486fdd1f8766a271354 (patch) | |
tree | f5598bbfb20ede742a0ae84a3c5432898cff2ce6 | |
parent | 7e6a5e1ed8627f7d9444708d0e36a67263578bbd (diff) |
inline specific library functions for speed
-rw-r--r-- | src/jsifier.js | 30 | ||||
-rw-r--r-- | src/library.js | 34 | ||||
-rw-r--r-- | src/modules.js | 4 | ||||
-rw-r--r-- | src/parseTools.js | 22 |
4 files changed, 67 insertions, 23 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 9c34ddf1..86f62c41 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -42,6 +42,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { substrate = new Substrate('JSifyer'); var GLOBAL_VARIABLES = !mainPass ? givenGlobalVariables : data.globalVariables; + Variables.globals = GLOBAL_VARIABLES; Functions.currFunctions = !mainPass ? givenFunctions.currFunctions : {}; Functions.currExternalFunctions = !mainPass ? givenFunctions.currExternalFunctions : {}; @@ -831,28 +832,13 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { // We cannot compile assembly. See comment in intertyper.js:'Call' assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); - // Special cases - if (ident == '_llvm_va_start') { - // varargs - we received a pointer to the varargs as a final 'extra' parameter - var data = 'arguments[' + Framework.currItem.funcData.ident + '.length]'; - return makeSetValue(params[0].ident, 0, data, 'void*'); - } else if (ident == '_llvm_va_end') { - return ';'; - } else if (ident == '_EMSCRIPTEN_COMMENT') { - var param = finalizeParam(params[0]); - if (param.indexOf('CHECK_OVERFLOW') >= 0) { - param = param.split('(')[1].split(',')[0]; - } - return '// ' + GLOBAL_VARIABLES[param].value.text.replace('\\00', '') + ' '; - } - + var shortident = LibraryManager.getRootIdent(ident.slice(1)) || ident.slice(1); // ident may not be in library, if all there is is ident__inline var func = Functions.currFunctions[ident] || Functions.currExternalFunctions[ident]; - var args = []; var argsTypes = []; var varargs = []; var varargsTypes = []; - var useJSArgs = (ident.slice(1) + '__jsargs') in LibraryManager.library; + var useJSArgs = (shortident + '__jsargs') in LibraryManager.library; params.forEach(function(param, i) { var val = finalizeParam(param); @@ -878,11 +864,19 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { varargs = makePointer('[' + varargs + ']', 0, 'ALLOC_STACK', varargsTypes); } + args = args.concat(varargs); + var argsText = args.join(', '); + + var inline = LibraryManager.library[shortident + '__inline']; + if (inline) { + return inline.apply(null, args); // Warning: inlining does not prevent recalculation of the arguments. They should be simple identifiers + } + if (getVarData(funcData, ident)) { ident = 'FUNCTION_TABLE[' + ident + ']'; } - return ident + '(' + args.concat(varargs).join(', ') + ')'; + return ident + '(' + args.join(', ') + ')'; } makeFuncLineActor('getelementptr', function(item) { return finalizeLLVMFunctionCall(item) }); makeFuncLineActor('call', function(item) { diff --git a/src/library.js b/src/library.js index a626f729..f8112af9 100644 --- a/src/library.js +++ b/src/library.js @@ -3578,13 +3578,21 @@ LibraryManager.library = { // string.h // ========================================================================== + memcpy__inline: function (dest, src, num, idunno) { + var ret = ''; +#if ASSERTIONS + ret += "assert(" + num + " % 1 === 0, 'memcpy given ' + " + num + " + ' bytes to copy. Problem with QUANTUM_SIZE=1 corrections perhaps?');"; +#endif + ret += makeCopyValues(dest, src, num, 'null'); + return ret; + }, memcpy: function (dest, src, num, idunno) { #if ASSERTIONS assert(num % 1 === 0, 'memcpy given ' + num + ' bytes to copy. Problem with QUANTUM_SIZE=1 corrections perhaps?'); #endif - // || 0, since memcpy sometimes copies uninitialized areas XXX: Investigate why initializing alloc'ed memory does not fix that too - {{{ makeCopyValues('dest', 'src', 'num', 'null', ' || 0') }}}; + {{{ makeCopyValues('dest', 'src', 'num', 'null') }}}; }, + llvm_memcpy_i32: 'memcpy', llvm_memcpy_i64: 'memcpy', llvm_memcpy_p0i8_p0i8_i32: 'memcpy', @@ -3604,6 +3612,9 @@ LibraryManager.library = { llvm_memmove_p0i8_p0i8_i32: 'memmove', llvm_memmove_p0i8_p0i8_i64: 'memmove', + memset__inline: function(ptr, value, num) { + return makeSetValues(ptr, 0, value, 'null', num); + }, memset: function(ptr, value, num) { {{{ makeSetValues('ptr', '0', 'value', 'null', 'num') }}} }, @@ -3984,6 +3995,14 @@ LibraryManager.library = { // LLVM specifics // ========================================================================== + llvm_va_start__inline: function(ptr) { + // varargs - we received a pointer to the varargs as a final 'extra' parameter + var data = 'arguments[' + Framework.currItem.funcData.ident + '.length]'; + return makeSetValue(ptr, 0, data, 'void*'); + }, + + llvm_va_end: function() {}, + llvm_va_copy: function(ppdest, ppsrc) { {{{ makeCopyValues('ppdest', 'ppsrc', QUANTUM_SIZE, 'null') }}} /* Alternate implementation that copies the actual DATA; it assumes the va_list is prefixed by its size @@ -4173,8 +4192,8 @@ LibraryManager.library = { return ret; }, - llvm_expect_i32: function(x, y) { - return x == y; // TODO: inline this + llvm_expect_i32__inline: function(x, y) { + return '((' + x + ')==(' + y + '))'; }, llvm_lifetime_start: function() {}, @@ -5389,6 +5408,13 @@ LibraryManager.library = { _Z21emscripten_run_scriptPKc: function(ptr) { eval(Pointer_stringify(ptr)); + }, + + EMSCRIPTEN_COMMENT__inline: function(param) { + if (param.indexOf('CHECK_OVERFLOW') >= 0) { + param = param.split('(')[1].split(',')[0]; + } + return '// ' + Variables.globals[param].value.text.replace('\\00', '') + ' '; } }; diff --git a/src/modules.js b/src/modules.js index 2341b575..b18fd13c 100644 --- a/src/modules.js +++ b/src/modules.js @@ -186,6 +186,10 @@ var Debugging = { } }; +var Variables = { + globals: null +}; + var Types = { types: {}, fatTypes: {}, // With QUANTUM_SIZE=1, we store the full-size type data here diff --git a/src/parseTools.js b/src/parseTools.js index f9ef419a..f50092c7 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -793,14 +793,23 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore) { } } +var UNROLL_LOOP_LIMIT = 5; + function makeSetValues(ptr, pos, value, type, num) { function safety(where) { where = where || getFastValue(ptr, '+', pos) + '+$mspi$'; return ';' + (SAFE_HEAP ? 'SAFE_HEAP_ACCESS(' + where + ', ' + type + ', 1)' : ''); } if (USE_TYPED_ARRAYS in set(0, 1)) { + if (isNumber(num)) { + if (num < UNROLL_LOOP_LIMIT) { + return range(num).map(function(i) { + return makeSetValue(ptr, getFastValue(pos, '+', i), value, type); + }).join('; '); + } + } return 'for (var $mspi$ = 0; $mspi$ < ' + num + '; $mspi$++) {\n' + - makeSetValue(ptr, getFastValue(pos, '+', '$mspi$'), value, type) + ';\n}'; + makeSetValue(ptr, getFastValue(pos, '+', '$mspi$'), value, type) + '\n}'; } else { // USE_TYPED_ARRAYS == 2 /* return 'for (var $mspi$ = 0; $mspi$ < ' + num + '; $mspi$++) {\n' + @@ -837,6 +846,17 @@ function makeCopyValues(dest, src, num, type, modifier) { return (SAFE_HEAP ? 'SAFE_HEAP_COPY_HISTORY(' + to + ', ' + from + ')' : ''); } if (USE_TYPED_ARRAYS in set(0, 1)) { + if (isNumber(num)) { + if (num < UNROLL_LOOP_LIMIT) { + return range(num).map(function(i) { + return type !== 'null' ? makeSetValue(dest, i, makeGetValue(src, i, type) + (modifier || ''), type) + : // Null is special-cased: We copy over all heaps + makeGetSlabs(dest, 'null', true).map(function(slab) { + return slab + '[' + dest + '+' + i + ']=' + slab + '[' + src + '+' + i + ']'; + }).join('; ') + '; ' + safety(dest + '+' + i, src + '+' + i) + }).join('; '); + } + } return 'for (var $mcpi$ = 0; $mcpi$ < ' + num + '; $mcpi$++) {\n' + (type !== 'null' ? makeSetValue(dest, '$mcpi$', makeGetValue(src, '$mcpi$', type) + (modifier || ''), type) : // Null is special-cased: We copy over all heaps |