aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/js-optimizer.js29
-rw-r--r--tools/test-js-optimizer-asm-outline1-output.js60
-rw-r--r--tools/test-js-optimizer-asm-outline1.js32
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 }