diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-07-18 16:20:40 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-07-18 16:20:40 -0700 |
commit | 698b0c53ebe4b06e3a7b848811cde9272c7c26d1 (patch) | |
tree | 8a831d7a47e1232ef753d5646b1a647311c070f6 /tools | |
parent | a1a7cb6031f7120f229593e00879860ad01d09f5 (diff) |
emit only necessary return proxying code when outlining
Diffstat (limited to 'tools')
-rw-r--r-- | tools/js-optimizer.js | 19 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-outline1-output.js | 8 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-outline2-output.js | 12 |
3 files changed, 15 insertions, 24 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 14d26a89..5c80abb6 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -3031,7 +3031,7 @@ function outline(ast) { var writes = {}; var appearances = {}; - var hasReturn = false, hasBreak = false, hasContinue = false; + var hasReturn = false, hasReturnInt = false, hasReturnDouble = false, hasBreak = false, hasContinue = false; var breaks = {}; // set of labels we break or continue var continues = {}; // to (name -> id, just like labels) var breakCapturers = 0; @@ -3050,7 +3050,13 @@ function outline(ast) { appearances[name] = (appearances[name] || 0) + 1; } } else if (type == 'return') { - hasReturn = true; + if (!node[1]) { + hasReturn = true; + } else if (detectAsmCoercion(node[1]) == ASM_INT) { + hasReturnInt = true; + } else { + hasReturnDouble = true; + } } else if (type == 'break') { var label = node[1] || 0; if (!label && breakCapturers > 0) return; // no label, and captured @@ -3079,13 +3085,14 @@ function outline(ast) { continueCapturers--; } }); + assert(hasReturn + hasReturnInt + hasReturnDouble <= 1); var reads = {}; for (var name in appearances) { if (appearances[name] > 0) reads[name] = 0; } - return { writes: writes, reads: reads, hasReturn: hasReturn, hasBreak: hasBreak, hasContinue: hasContinue, breaks: breaks, continues: continues, labels: labels }; + return { writes: writes, reads: reads, hasReturn: hasReturn, hasReturnInt: hasReturnInt, hasReturnDouble: hasReturnDouble, hasBreak: hasBreak, hasContinue: hasContinue, breaks: breaks, continues: continues, labels: labels }; } function makeAssign(dst, src) { @@ -3128,7 +3135,7 @@ function outline(ast) { reps.push(['stat', ['assign', true, ['name', v], makeAsmCoercion(['sub', ['name', getAsmType(v, asmData) == ASM_INT ? 'HEAP32' : 'HEAPF32'], ['binary', '>>', ['binary', '+', ['name', 'sp'], ['num', asmData.stackPos[v]]], ['num', '2']]], getAsmType(v, asmData))]]); } // Generate new function - if (codeInfo.hasReturn || codeInfo.hasBreak || codeInfo.hasContinue) { + if (codeInfo.hasReturn || codeInfo.hasReturnInt || codeInfo.hasReturnDouble || codeInfo.hasBreak || codeInfo.hasContinue) { // we need to capture all control flow using a top-level labeled one-time loop in the outlined function var breakCapturers = 0; var continueCapturers = 0; @@ -3199,10 +3206,14 @@ function outline(ast) { makeComparison(makeAsmCoercion(makeStackAccess(ASM_INT, asmData.controlStackPos), ASM_INT), '==', ['num', CONTROL_RETURN_VOID]), [['stat', ['return']]] )); + } + if (codeInfo.hasReturnInt) { reps.push(makeIf( makeComparison(makeAsmCoercion(makeStackAccess(ASM_INT, asmData.controlStackPos), ASM_INT), '==', ['num', CONTROL_RETURN_INT]), [['stat', ['return', makeStackAccess(ASM_INT, asmData.controlDataStackPos)]]] )); + } + if (codeInfo.hasReturnDouble) { reps.push(makeIf( makeComparison(makeAsmCoercion(makeStackAccess(ASM_INT, asmData.controlStackPos), ASM_INT), '==', ['num', CONTROL_RETURN_DOUBLE]), [['stat', ['return', makeStackAccess(ASM_DOUBLE, asmData.controlDataStackPos)]]] diff --git a/tools/test-js-optimizer-asm-outline1-output.js b/tools/test-js-optimizer-asm-outline1-output.js index 03d90cb7..78bfcb88 100644 --- a/tools/test-js-optimizer-asm-outline1-output.js +++ b/tools/test-js-optimizer-asm-outline1-output.js @@ -36,18 +36,10 @@ function lin3() { c(5); lin3$1(sp); lin3$0(sp); - if ((HEAP32[sp + 0 >> 2] | 0) == 5) { - STACKTOP = sp; - return; - } if ((HEAP32[sp + 0 >> 2] | 0) == 6) { STACKTOP = sp; return HEAP32[sp + 8 >> 2]; } - if ((HEAP32[sp + 0 >> 2] | 0) == 7) { - STACKTOP = sp; - return HEAPF32[sp + 8 >> 2]; - } } STACKTOP = sp; return 20; diff --git a/tools/test-js-optimizer-asm-outline2-output.js b/tools/test-js-optimizer-asm-outline2-output.js index d9c292a0..c70b0030 100644 --- a/tools/test-js-optimizer-asm-outline2-output.js +++ b/tools/test-js-optimizer-asm-outline2-output.js @@ -95,12 +95,6 @@ function _free($mem) { if ((HEAP32[sp + 632 >> 2] | 0) == 5) { return; } - if ((HEAP32[sp + 632 >> 2] | 0) == 6) { - return HEAP32[sp + 640 >> 2]; - } - if ((HEAP32[sp + 632 >> 2] | 0) == 7) { - return HEAPF32[sp + 640 >> 2]; - } if ((HEAP32[sp + 632 >> 2] | 0) == 1) { break; } @@ -195,12 +189,6 @@ function _free($mem) { if ((HEAP32[sp + 632 >> 2] | 0) == 5) { return; } - if ((HEAP32[sp + 632 >> 2] | 0) == 6) { - return HEAP32[sp + 640 >> 2]; - } - if ((HEAP32[sp + 632 >> 2] | 0) == 7) { - return HEAPF32[sp + 640 >> 2]; - } if ((HEAP32[sp + 632 >> 2] | 0) == 1) { break; } |