aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-08-20 18:45:51 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-08-21 17:09:48 -0700
commit02c42064795765b746c1800b0ce99ab1c89c189f (patch)
treeea7683e94153d718c74ad95b2068d23db9856289
parentd705c37e34ad11b01ad33e7c985818a14623dff7 (diff)
do not emit switches for very sparse/large switch values
-rw-r--r--src/jsifier.js12
-rw-r--r--src/relooper/Relooper.cpp2
2 files changed, 9 insertions, 5 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 31e066ab..385adffc 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -796,10 +796,10 @@ function JSify(data, functionsOnly, givenFunctions) {
var content = getLabelLines(label, '', true);
//printErr(func.ident + ' : ' + label.ident + ' : ' + content + '\n');
var last = label.lines[label.lines.length-1];
- if (last.intertype != 'switch') {
+ if (!last.signedIdent) {
blockMap[label.ident] = Relooper.addBlock(content);
} else {
- assert(last.signedIdent);
+ assert(last.intertype == 'switch');
blockMap[label.ident] = Relooper.addBlock(content, last.signedIdent);
}
}
@@ -1131,7 +1131,13 @@ function JSify(data, functionsOnly, givenFunctions) {
}
});
makeFuncLineActor('switch', function(item) {
- var useIfs = false;
+ // use a switch if the range is not too big or sparse
+ var maxx = 0;
+ item.switchLabels.forEach(function(switchLabel) {
+ maxx = Math.max(maxx, Math.abs(parseInt(switchLabel.value)));
+ });
+ var useIfs = !(maxx <= 2*1024*1024 && (maxx/item.switchLabels.length) < 10*1024);
+
var phiSets = calcPhiSets(item);
// Consolidate checks that go to the same label. This is important because it makes the relooper simpler and faster.
var targetLabels = {}; // for each target label, the list of values going to it
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp
index aefcad93..afb6ecc8 100644
--- a/src/relooper/Relooper.cpp
+++ b/src/relooper/Relooper.cpp
@@ -191,8 +191,6 @@ void Block::Render(bool InLoop) {
}
assert(DefaultTarget); // Since each block *must* branch somewhere, this must be set
- if (ProcessedBranchesOut.size() > 2) assert(BranchVar); // must have a branch variable if multiple conditions
-
bool useSwitch = BranchVar != NULL;
if (useSwitch) {