diff options
author | alon@honor <none@none> | 2010-10-09 19:21:35 -0700 |
---|---|---|
committer | alon@honor <none@none> | 2010-10-09 19:21:35 -0700 |
commit | 9f7d7f67ed96a9a5972f68df1767deaf802db683 (patch) | |
tree | 0e0248cdbf88e2b462bb6d2cea9da4bfc4ec54eb | |
parent | 1f86652596288066bb27b83fb9b8e70a871ff16d (diff) |
optimize away 1's and 0's in getelementptr; 1% speedup
-rw-r--r-- | src/jsifier.js | 52 | ||||
-rw-r--r-- | src/utility.js | 4 |
2 files changed, 49 insertions, 7 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index d21e44d4..9baf247d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -40,15 +40,21 @@ function JSify(data) { return ptr; } + function calcFastOffset(ptr, pos, noNeedFirst) { + var offset = noNeedFirst ? '0' : makeGetPos(ptr); + return getFastValue(offset, '+', pos); + } + function makeGetValue(ptr, pos, noNeedFirst) { - return makeGetSlab(ptr) + '[' + (noNeedFirst ? '0' : makeGetPos(ptr)) + (pos ? ' + ' + pos : '') + ']'; + return makeGetSlab(ptr) + '[' + calcFastOffset(ptr, pos, noNeedFirst) + ']'; } function makeSetValue(ptr, pos, value, noNeedFirst) { + var offset = calcFastOffset(ptr, pos, noNeedFirst); if (SAFE_HEAP) { - return 'SAFE_HEAP_STORE(' + (noNeedFirst ? '0' : makeGetPos(ptr)) + (pos ? ' + ' + pos : '') + ', ' + value + ')'; + return 'SAFE_HEAP_STORE(' + offset + ', ' + value + ')'; } else { - return makeGetSlab(ptr) + '[' + (noNeedFirst ? '0' : makeGetPos(ptr)) + (pos ? ' + ' + pos : '') + '] = ' + value; + return makeGetSlab(ptr) + '[' + offset + '] = ' + value; } } @@ -647,6 +653,34 @@ function JSify(data) { }]; */ + // Given two values and an operation, returns the result of that operation. + // Tries to do as much as possible at compile time. + function getFastValue(a, op, b) { + if (isNumber(a) && isNumber(b)) { + return eval(a + op + b); + } + if (op == '*') { + if (!a) a = 1; + if (!b) b = 1; + if (a == 0 || b == 0) { + return 0; + } else if (a == 1) { + return b; + } else if (b == 1) { + return a; + } + } else if (op == '+') { + if (!a) a = 0; + if (!b) b = 0; + if (a == 0) { + return b; + } else if (b == 0) { + return a; + } + } + return a + op + b; + } + function getGetElementPtrIndexes(item) { var ident = item.ident; var type = item.params[0].type.text; // param 0 == type @@ -658,9 +692,9 @@ function JSify(data) { var offset = toNiceIdent(item.params[1].ident); if (offset != 0) { if (isStructType(type)) { - indexes.push((TYPES[type].flatSize != 1 ? TYPES[type].flatSize + '*' : '') + offset); + indexes.push(getFastValue(TYPES[type].flatSize, '*', offset)); } else { - indexes.push(getNativeFieldSize(type, true) + '*' + offset); + indexes.push(getFastValue(getNativeFieldSize(type, true), '*', offset)); } } item.params.slice(2, item.params.length).forEach(function(arg) { @@ -669,7 +703,7 @@ function JSify(data) { var typeData = TYPES[type]; if (isStructType(type) && typeData.needsFlattening) { if (typeData.flatFactor) { - indexes.push(curr + '*' + typeData.flatFactor); + indexes.push(getFastValue(curr, '*', typeData.flatFactor)); } else { indexes.push(toNiceIdent(type) + '___FLATTENER[' + curr + ']'); } @@ -680,7 +714,11 @@ function JSify(data) { } type = TYPES[type] ? TYPES[type].fields[curr] : ''; }); - return indexes.join('+'); + var ret = indexes[0]; + for (var i = 1; i < indexes.length; i++) { + ret = getFastValue(ret, '+', indexes[i]); + } + return ret; } function finalizeLLVMFunctionCall(item) { diff --git a/src/utility.js b/src/utility.js index d5583ffb..2cc2408c 100644 --- a/src/utility.js +++ b/src/utility.js @@ -213,3 +213,7 @@ function setIntersect(x, y) { return ret; } +function isNumber(x) { + return x == parseInt(x); +} + |