diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/js-optimizer.js | 29 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-outline1-output.js | 60 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-outline1.js | 32 |
3 files changed, 107 insertions, 14 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 9aba3fda..95212fbc 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -2993,11 +2993,11 @@ function outline(ast) { // Analyze uses - reads and writes - of variables in part of the AST of a function function analyzeCode(func, asmData, ast) { - var labels = {}; + var labels = {}; // labels defined in this code var labelCounter = 1; // 0 means no label traverse(ast, function(node, type) { - if ((type == 'label' || type in LOOP_FLOW) && node[1] && !(node[1] in labels)) { + if (type == 'label' && !(node[1] in labels)) { labels[node[1]] = labelCounter++; } }); @@ -3006,7 +3006,7 @@ function outline(ast) { var appearances = {}; var hasReturn = false, hasBreak = false, hasContinue = false; var breaks = {}; // set of labels we break or continue - var continues = {}; // to. '0' is an unlabeled one + var continues = {}; // to (name -> id, just like labels) var breakCapturers = 0; var continueCapturers = 0; @@ -3028,13 +3028,13 @@ function outline(ast) { var label = node[1] || 0; if (!label && breakCapturers > 0) return; // no label, and captured if (label && (label in labels)) return; // label, and defined in this code, so captured - breaks[label || 0] = 0; + if (label) breaks[label] = labelCounter++; hasBreak = true; } else if (type == 'continue') { var label = node[1] || 0; if (!label && continueCapturers > 0) return; // no label, and captured if (label && (label in labels)) return; // label, and defined in this code, so captured - continues[label || 0] = 0; + if (label) continues[label] = labelCounter++; hasContinue = true; } else { if (type in BREAK_CAPTURERS) { @@ -3127,8 +3127,8 @@ function outline(ast) { var ret = ['break', 'OL']; ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos), ['num', label ? CONTROL_BREAK_LABEL : CONTROL_BREAK]), ret]; if (label) { - assert(label in codeInfo.labels, label + ' in ' + keys(codeInfo.labels)); - ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlDataStackPos), ['num', codeInfo.labels[label]]), ret]; + assert(label in codeInfo.breaks); + ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlDataStackPos), ['num', codeInfo.breaks[label]]), ret]; } return ret; } else if (type == 'continue') { @@ -3138,7 +3138,8 @@ function outline(ast) { var ret = ['break', 'OL']; ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlStackPos), ['num', label ? CONTROL_CONTINUE_LABEL : CONTROL_CONTINUE]), ret]; if (label) { - ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlDataStackPos), ['num', codeInfo.labels[label]]), ret]; + assert(label in codeInfo.continues); + ret = ['seq', makeAssign(makeStackAccess(ASM_INT, asmData.controlDataStackPos), ['num', codeInfo.continues[label]]), ret]; } return ret; } else { @@ -3178,11 +3179,11 @@ function outline(ast) { makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_BREAK]), [['stat', ['break']]] )); - if (keys(codeInfo.labels).length > 0) { + if (keys(codeInfo.breaks).length > 0) { reps.push(makeIf( makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_BREAK_LABEL]), - [makeSwitch(makeStackAccess(ASM_INT, asmData.controlDataStackPos), keys(codeInfo.labels).map(function(key) { - var id = codeInfo.labels[key]; + [makeSwitch(makeStackAccess(ASM_INT, asmData.controlDataStackPos), keys(codeInfo.breaks).map(function(key) { + var id = codeInfo.breaks[key]; return [['num', id], [['stat', ['break', key]]]]; }))] )); @@ -3193,11 +3194,11 @@ function outline(ast) { makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_CONTINUE]), [['stat', ['continue']]] )); - if (keys(codeInfo.labels).length > 0) { + if (keys(codeInfo.continues).length > 0) { reps.push(makeIf( makeComparison(makeStackAccess(ASM_INT, asmData.controlStackPos), '==', ['num', CONTROL_CONTINUE_LABEL]), - [makeSwitch(makeStackAccess(ASM_INT, asmData.controlDataStackPos), keys(codeInfo.labels).map(function(key) { - var id = codeInfo.labels[key]; + [makeSwitch(makeStackAccess(ASM_INT, asmData.controlDataStackPos), keys(codeInfo.continues).map(function(key) { + var id = codeInfo.continues[key]; return [['num', id], [['stat', ['continue', key]]]]; }))] )); diff --git a/tools/test-js-optimizer-asm-outline1-output.js b/tools/test-js-optimizer-asm-outline1-output.js index cbf6d8e6..0780484a 100644 --- a/tools/test-js-optimizer-asm-outline1-output.js +++ b/tools/test-js-optimizer-asm-outline1-output.js @@ -65,6 +65,37 @@ function lin5() { } return 20; } +function mix() { + main : while (1) { + c(1); + c(2); + c(3); + c(4); + c(5); + c(6); + mix$1(sp); + mix$0(sp); + if (HEAP32[sp + 0 >> 2] == 1) { + break; + } + if (HEAP32[sp + 0 >> 2] == 2) { + switch (HEAP32[sp + 8 >> 2]) { + case 1: + break main; + } + } + if (HEAP32[sp + 0 >> 2] == 3) { + continue; + } + if (HEAP32[sp + 0 >> 2] == 4) { + switch (HEAP32[sp + 8 >> 2]) { + case 2: + continue main; + } + } + } + return 20; +} function lin$0(sp) { sp = sp | 0; c(13); @@ -183,4 +214,33 @@ function lin5$1(sp) { c(11); c(12); } +function mix$0(sp) { + sp = sp | 0; + OL : do { + c(15); + c(16); + c(17); + HEAP32[sp + 8 >> 2] = 1, HEAP32[sp + 0 >> 2] = 2, break OL; + c(18); + HEAP32[sp + 0 >> 2] = 1, break OL; + while (1) { + break; + } + c(19); + HEAP32[sp + 0 >> 2] = 3, break OL; + c(20); + HEAP32[sp + 8 >> 2] = 2, HEAP32[sp + 0 >> 2] = 4, break OL; + } while (0); +} +function mix$1(sp) { + sp = sp | 0; + c(7); + c(8); + c(9); + c(10); + c(11); + c(12); + c(13); + c(14); +} diff --git a/tools/test-js-optimizer-asm-outline1.js b/tools/test-js-optimizer-asm-outline1.js index 5f9a79f3..035e32e7 100644 --- a/tools/test-js-optimizer-asm-outline1.js +++ b/tools/test-js-optimizer-asm-outline1.js @@ -122,5 +122,37 @@ function lin5() { } return 20; } +function mix() { + main: while (1) { + c(1); + c(2); + c(3); + c(4); + c(5); + c(6); + c(7); + c(8); + c(9); + c(10); + c(11); + c(12); + c(13); + c(14); + c(15); + c(16); + c(17); + break main; + c(18); + break; + while (1) { + break; // no need to forward + } + c(19); + continue; + c(20); + continue main; + } + return 20; +} // EMSCRIPTEN_GENERATED_FUNCTIONS // EXTRA_INFO: { "sizeToOutline": 30 } |