diff options
author | alon@honor <none@none> | 2010-10-16 15:33:19 -0700 |
---|---|---|
committer | alon@honor <none@none> | 2010-10-16 15:33:19 -0700 |
commit | 373e75c2151229ae4b6caaae77eb9d49da72e2c2 (patch) | |
tree | 6297cdad2fa5c916b25768cdef99807e44f3ca72 /src | |
parent | 6fa5f7160c816fc982432dc5f990a1da14d09175 (diff) |
optimize out unneeded loops in |multiple| blocks
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 18 | ||||
-rw-r--r-- | src/jsifier.js | 18 |
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; } |