diff options
author | alon@honor <none@none> | 2010-10-02 23:29:02 -0700 |
---|---|---|
committer | alon@honor <none@none> | 2010-10-02 23:29:02 -0700 |
commit | 2f64c269303d4731f511e8b77e1ec8fb5f906763 (patch) | |
tree | c30b4a075239b6739efc41e3a76abada6ab93e8c | |
parent | 981b5832f5c0ae8a732e5e89f313c88efdadd0e3 (diff) |
add missing branch detection of default in switch. all reloop but sauer, dlmalloc/clang
-rw-r--r-- | src/analyzer.js | 20 | ||||
-rw-r--r-- | src/intertyper.js | 2 | ||||
-rw-r--r-- | src/jsifier.js | 5 | ||||
-rw-r--r-- | src/utility.js | 11 | ||||
-rw-r--r-- | tests/runner.py | 4 | ||||
-rw-r--r-- | tests/settings.py | 2 |
6 files changed, 36 insertions, 8 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 54f766cc..b44165b1 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -348,7 +348,7 @@ function analyzer(data) { labels.forEach(function(label) { label.lines.forEach(function(line) { function process(item) { - ['label', 'labelTrue', 'labelFalse', 'toLabel', 'unwindLabel'].forEach(function(id) { + ['label', 'labelTrue', 'labelFalse', 'toLabel', 'unwindLabel', 'defaultLabel'].forEach(function(id) { if (item[id]) { if (item[id][0] == 'B') { // BREAK, BCONT, BNOPP label.hasBreak = true; @@ -460,7 +460,7 @@ function analyzer(data) { if (entries.length > 1) return emulated(); var entry = entries[0]; assert(entry); - dprint('relooping', 'Relooping: ' + entry + ',' + labels.length + ' labels'); + dprint('relooping', 'makeBlock: ' + entry + ',' + labels.length + ' labels'); var entryLabel = labelsDict[entry]; assert(entryLabel); @@ -469,11 +469,12 @@ function analyzer(data) { var canReturn = values(entryLabel.inLabels).length > 0; + labels = labels.filter(function(label) { return label === entryLabel || label.ident in entryLabel.allOutLabels }); // ignore unreachables + // === (simple) 'emulated' === if (!canReturn && values(entryLabel.outLabels).length == 1) { dprint('relooping', ' Creating simple emulated, outlabels: ' + keys(entryLabel.outLabels)); - assertEq(lastLine.intertype, 'branch'); var next = keys(entryLabel.outLabels)[0]; if (next in exitLabels) { exitLabelsHit[next] = true; @@ -506,6 +507,19 @@ function analyzer(data) { var internals = split_.leftIn; var currExitLabels = set(getLabelIds(externals)); + // Verify that no external can reach an internal + var inLabels = set(getLabelIds(internals)); + var fail = false; + externals.forEach(function(external) { + if (fail || values(setIntersect(external.outLabels, inLabels)).length > 0) { + fail = true; + } + }); + if (fail) { + dprint('relooping', 'Found an external that wants to reach an internal, fallback to flow emulation'); + return emulated(); + } + dprint('relooping', function() { return ' Creating reloop: Inner: ' + dump(getLabelIds(internals)) + ', Exxer: ' + dump(currExitLabels) }); replaceLabelLabels(internals, searchable(entry), 'BCONT' + entry); // we will be in a loop, |continue| gets us back to the entry diff --git a/src/intertyper.js b/src/intertyper.js index ed670e65..3092a310 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -559,7 +559,7 @@ function intertyper(data) { intertype: 'switch', type: item.tokens[1].text, ident: item.tokens[2].text, - defaultLabel: item.tokens[5].text, + defaultLabel: toNiceIdent(item.tokens[5].text), switchLabels: parseSwitchLabels(item.tokens[6]), lineNum: item.lineNum, }]; diff --git a/src/jsifier.js b/src/jsifier.js index a4d7b96e..69bc7d1e 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -260,6 +260,7 @@ function JSify(data) { if (!block.entry && block.entries.length == 1) block.entry = block.entries[0]; dprint('relooping', 'walking block: ' + block.type + ',' + block.entry + ',' + block.entries + ' : ' + block.labels.length); function getLabelLines(label, indent) { + if (!label) return ''; var ret = ''; if (LABEL_DEBUG) { ret += indent + "print(INDENT + '" + func.ident + ":" + label.ident + "');\n"; @@ -427,7 +428,7 @@ function JSify(data) { if (label[0] == 'B') { if (label[1] == 'R') { assert(oldLabel); - return '__label__ = ' + getLabelId(oldLabel) + '; ' + // TODO: optimize away + return '__label__ = ' + getLabelId(oldLabel) + '; /* ' + label + ' */' + // TODO: optimize away 'break ' + label.substr(5) + ';'; } else if (label[1] == 'C') { return 'continue ' + label.substr(5) + ';'; @@ -435,7 +436,7 @@ function JSify(data) { return ';'; // Returning no text might confuse this parser } } else { - return '__label__ = ' + getLabelId(label) + '; break;'; + return '__label__ = ' + getLabelId(label) + '; /* ' + label + ' */ break;'; } } diff --git a/src/utility.js b/src/utility.js index 3d8ce86e..d5583ffb 100644 --- a/src/utility.js +++ b/src/utility.js @@ -202,3 +202,14 @@ function setSub(x, y) { return ret; } +// Intersection of 2 sets. Faster if |xx| << |yy| +function setIntersect(x, y) { + var ret = {}; + for (xx in x) { + if (xx in y) { + ret[xx] = true; + } + } + return ret; +} + diff --git a/tests/runner.py b/tests/runner.py index c43125c3..dc3dfba0 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -69,7 +69,8 @@ class T(unittest.TestCase): if DEBUG: print output # Run Emscripten emscripten_settings = ['{ "QUANTUM_SIZE": %d, "RELOOP": %d }' % (QUANTUM_SIZE, RELOOP)] - timeout_run(Popen([EMSCRIPTEN, filename + '.o.llvm', PARSER_ENGINE] + emscripten_settings, stdout=open(filename + '.o.js', 'w'), stderr=STDOUT), 2400, 'Compiling') + out = open(filename + '.o.js', 'w') if not OUTPUT_TO_SCREEN else None + timeout_run(Popen([EMSCRIPTEN, filename + '.o.llvm', PARSER_ENGINE] + emscripten_settings, stdout=out, stderr=STDOUT), 240, 'Compiling') output = open(filename + '.o.js').read() if output_processor is not None: output_processor(output) @@ -825,7 +826,6 @@ class T(unittest.TestCase): # used, see Mozilla bug 593659. assert PARSER_ENGINE != SPIDERMONKEY_ENGINE - # FIXME - hangs the compiler after an assert assert not RELOOP self.do_test(path_from_root(['tests', 'sauer']), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp') diff --git a/tests/settings.py b/tests/settings.py index 0782528d..e07241fc 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -33,3 +33,5 @@ JS_ENGINE=SPIDERMONKEY_ENGINE JS_ENGINE_OPTS=[] +OUTPUT_TO_SCREEN = 0 # useful for debugging specific tests, or for subjectively seeing what parts are slow + |