aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-10-16 15:33:19 -0700
committeralon@honor <none@none>2010-10-16 15:33:19 -0700
commit373e75c2151229ae4b6caaae77eb9d49da72e2c2 (patch)
tree6297cdad2fa5c916b25768cdef99807e44f3ca72 /src
parent6fa5f7160c816fc982432dc5f990a1da14d09175 (diff)
optimize out unneeded loops in |multiple| blocks
Diffstat (limited to 'src')
-rw-r--r--src/analyzer.js18
-rw-r--r--src/jsifier.js18
2 files changed, 27 insertions, 9 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 6c062b82..30512b45 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -353,6 +353,7 @@ function analyzer(data) {
}
}
+ //! @param toLabelId If false, just a dry run - useful to search for labels
function replaceLabels(line, labelIds, toLabelId) {
var ret = [];
@@ -362,18 +363,22 @@ function analyzer(data) {
var wildcardParts = null;
if (wildcard) {
wildcardParts = value.split('|');
- assert(wildcardParts[1] == '*'); // For now, just handle that case
}
function wildcardCheck(s) {
var parts = s.split('|');
- return wildcardParts[0] == parts[0] && wildcardParts[2] == parts[2];
+ for (var i = 0; i < 3; i++) {
+ if (wildcardParts[i] !== '*' && wildcardParts[i] != parts[i]) return false;
+ }
+ return true;
}
operateOnLabels(line, function process(item, id) {
if (item[id] in labelIds || (wildcard && wildcardCheck(item[id]))) {
ret.push(item[id]);
dprint('relooping', 'zz ' + id + ' replace ' + item[id] + ' with ' + toLabelId);
- item[id] = toLabelId + '|' + item[id];
+ if (toLabelId) {
+ item[id] = toLabelId + '|' + item[id];
+ }
}
});
return ret;
@@ -769,6 +774,13 @@ function analyzer(data) {
}
recurseBlock(block, optimizeBlock);
+
+ if (block.type === 'multiple') {
+ // Check if the one-time loop (that allows breaking out) is actually needed
+ if (replaceLabelLabels(block.labels, set('BREAK|' + block.entries[0] + '|*')).length === 0) {
+ block.loopless = true;
+ }
+ }
}
// TODO: Parallelize
diff --git a/src/jsifier.js b/src/jsifier.js
index b6c36db0..15e66669 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -343,17 +343,23 @@ function JSify(data) {
ret += indent + '}\n';
} else if (block.type == 'multiple') {
var first = true;
- ret += indent + ((block.entry in usedLabels) ? '' : (block.entry+':')) + ' do { \n';
+ var multipleIdent = '';
+ if (!block.loopless) {
+ ret += indent + ((block.entry in usedLabels) ? '' : (block.entry+':')) + ' do { \n';
+ multipleIdent = ' ';
+ }
block.entryLabels.forEach(function(entryLabel) {
- ret += indent + (first ? '' : ' else ') + ' if (__label__ == ' + getLabelId(entryLabel.ident) + ') {\n';
- ret += walkBlock(entryLabel.block, indent + ' ');
- ret += indent + ' }\n';
+ ret += indent + (first ? '' : 'else ') + multipleIdent + 'if (__label__ == ' + getLabelId(entryLabel.ident) + ') {\n';
+ ret += walkBlock(entryLabel.block, indent + ' ' + multipleIdent);
+ ret += indent + multipleIdent + '}\n';
first = false;
});
if (GUARD_LABELS) {
- ret += indent + ' else { throw "Bad multiple branching: " + __label__ + " : " + (new Error().stack); }\n';
+ ret += indent + multipleIdent + 'else { throw "Bad multiple branching: " + __label__ + " : " + (new Error().stack); }\n';
+ }
+ if (!block.loopless) {
+ ret += indent + '} while(0);\n';
}
- ret += indent + '} while(0);\n';
} else {
throw "Walked into an invalid block type: " + block.type;
}