diff options
author | alon@honor <none@none> | 2010-10-16 11:51:33 -0700 |
---|---|---|
committer | alon@honor <none@none> | 2010-10-16 11:51:33 -0700 |
commit | a05a516811dc9fb9e8b9bf9400dbb6c37de57926 (patch) | |
tree | dbbbc2dfea2a4c4a7abc35908bf876de0f442a54 /src/analyzer.js | |
parent | 0be63d3eeba00b0e68d309e4af84f4906b1750aa (diff) |
rewrite BNOPP optimizer
Diffstat (limited to 'src/analyzer.js')
-rw-r--r-- | src/analyzer.js | 57 |
1 files changed, 43 insertions, 14 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 8d77b13d..1eebe2c4 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -667,7 +667,6 @@ function analyzer(data) { actualEntryLabels.forEach(function(actualEntryLabel) { dprint('relooping', ' creating sub-block in multiple for ' + actualEntryLabel.ident + ' : ' + getLabelIds(actualEntryLabel.blockChildren) + ' ::: ' + actualEntryLabel.blockChildren.length); - // TODO: Move this into BJSET keys(postEntryLabels).forEach(function(post) { replaceLabelLabels(actualEntryLabel.blockChildren, set(post), 'BREAK|' + actualEntries[0]); }); @@ -710,31 +709,61 @@ function analyzer(data) { } if (!RELOOP) return finish(); - function walkBlock(block) { + // Find where each block will 'naturally' get to, just by the flow of code + function exploreBlock(block, endOfTheWorld) { // endoftheworld - where we will get, if we have nothing else to get to - 'fall off the face of the earth' if (!block) return; - dprint('relooping', "// loopOptimizing block: " + block.type + ' : ' + block.entries); + + function singular(block) { + if (!block || block.type === 'multiple') return null; + if (block.entries.length == 1) { + return block.entries[0]; + } else { + return null; + } + } + + dprint('relooping', "// exploring block: " + block.type + ' : ' + block.entries); + if (block.type == 'emulated') { - if (block.labels.length == 1 && block.next) { - var label = block.labels[0]; - dprint('relooping', '// simple emulated: ' + label.originalOutLabels + ' || ' + block.next.entries); - if (label.originalOutLabels.length == 1) { - dprint('relooping', '// removing!'); - replaceLabelLabels([label], set('BJSET|' + label.originalOutLabels[0] + '|' + label.originalOutLabels[0]), 'BNOPP'); + if (block.labels.length == 1) { + if (block.next) { + block.willGetTo = singular(block.next); + } else { + block.willGetTo = endOfTheWorld; } } } else if (block.type == 'reloop') { - walkBlock(block.inner); + exploreBlock(block.inner, singular(block.inner)); } else if (block.type == 'multiple') { - block.entryLabels.forEach(function(entryLabel) { walkBlock(entryLabel.block) }); + block.entryLabels.forEach(function(entryLabel) { exploreBlock(entryLabel.block, singular(block.next)) }); } else { - throw "Walked into an invalid block type: " + block.type; + throw "Explored into an invalid block type: " + block.type; + } + + dprint('relooping', "// explored block: " + block.type + ' , willGetTo: ' + block.willGetTo); + + exploreBlock(block.next, endOfTheWorld); + } + + // Remove unneeded label settings, if we set it to where we will get anyhow + function optimizeBlock(block) { + if (!block) return; + + dprint('relooping', "// optimizing block: " + block.type + ' : ' + block.entries); + + if (block.willGetTo) { + dprint('relooping', '// removing (trying)'); + replaceLabelLabels(block.labels, set('BJSET|' + block.willGetTo + '|' + block.willGetTo), 'BNOPP'); } - walkBlock(block.next); + + recurseBlock(block, optimizeBlock); } + // TODO: Parallelize item.functions.forEach(function(func) { dprint('relooping', "// loopOptimizing function: " + func.ident); - walkBlock(func.block); + exploreBlock(func.block); + optimizeBlock(func.block); }); return finish(); }, |