diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-11-18 10:47:52 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-11-18 10:47:52 -0800 |
commit | 1c2bf360597108c5a26f05acd1f806bbca55e224 (patch) | |
tree | d97798e9457f2527dc71196af7e9242dbe617cf7 | |
parent | 846c77ae557699372c7c372ea50135f1f0cb6458 (diff) |
further refactoring of phi, and work towards optimized phi
-rw-r--r-- | src/analyzer.js | 52 | ||||
-rw-r--r-- | src/jsifier.js | 22 |
2 files changed, 51 insertions, 23 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 1195c68b..6cfb2b6d 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -621,19 +621,15 @@ function analyzer(data) { // we need __lastLabel__. func.needsLastLabel = false; func.labels.forEach(function(label) { - var phis = []; + var phis = [], phi; label.lines.forEach(function(line) { - if (line.value && line.value.intertype == 'phi') { - for (var i = 0; i < line.value.params.length; i++) { - var remarkableLabelId = line.value.params[i].label; - var remarkableLabel = func.labelsDict[remarkableLabelId]; - assert(remarkableLabel); - var lastLine = remarkableLabel.lines.slice(-1)[0]; - if (lastLine.intertype === 'assign') { - lastLine.value.currLabelId = remarkableLabelId; - } else { - lastLine.currLabelId = remarkableLabelId; - } + if ((phi = line.value) && phi.intertype == 'phi') { + for (var i = 0; i < phi.params.length; i++) { + var sourceLabelId = phi.params[i].label; + var sourceLabel = func.labelsDict[sourceLabelId]; + var lastLine = sourceLabel.lines.slice(-1)[0]; + assert(lastLine.intertype == 'branch', 'Only branches can lead to labels with phis'); + lastLine.currLabelId = sourceLabelId; } phis.push(line); func.needsLastLabel = true; @@ -661,8 +657,36 @@ function analyzer(data) { } } }); - } else { // MICRO_OPTS - assert(0, 'TODO'); + } else { + // MICRO_OPTS == 1: Properly implement phis, by pushing them back into the branch + // that leads to here. We will only have the |var| definition in this location. + + // First, push phis back + func.labels.forEach(function(label) { + label.lines.forEach(function(line) { + var phi; + if ((phi = line.value) && phi.intertype == 'phi') { + for (var i = 0; i < phi.params.length; i++) { + var param = phi.params[i]; + var sourceLabelId = param.label; + var sourceLabel = func.labelsDict[sourceLabelId]; + var lastLine = sourceLabel.lines.slice(-1)[0]; + assert(lastLine.intertype == 'branch', 'Only branches can lead to labels with phis'); + if (!lastLine.phi) { + // We store the phi assignments in the branch's params (which are otherwise unused) + lastLine.phi = true; + assert(!lastLine.params); + lastLine.params = []; + }; + lastLine.params.push({ + intertype: 'phiassign', + ident: line.ident, + value: param.value + }); + } + } + }); + }); } }); this.forwardItem(item, 'StackAnalyzer'); diff --git a/src/jsifier.js b/src/jsifier.js index 604e8b8c..d158a9b9 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -671,7 +671,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { function makeBranch(label, lastLabel, labelIsVariable) { var pre = ''; - if (lastLabel) { + if (!MICRO_OPTS && lastLabel) { pre = '__lastLabel__ = ' + getLabelId(lastLabel) + '; '; } if (label[0] == 'B') { @@ -819,16 +819,20 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { }); makeFuncLineActor('phi', function(item) { var params = item.params; - function makeOne(i) { - if (i === params.length-1) { - return finalizeLLVMParameter(params[i].value); + if (!MICRO_OPTS) { + function makeOne(i) { + if (i === params.length-1) { + return finalizeLLVMParameter(params[i].value); + } + return '__lastLabel__ == ' + getLabelId(params[i].label) + ' ? ' + + finalizeLLVMParameter(params[i].value) + ' : (' + makeOne(i+1) + ')'; } - return '__lastLabel__ == ' + getLabelId(params[i].label) + ' ? ' + - finalizeLLVMParameter(params[i].value) + ' : (' + makeOne(i+1) + ')'; + var ret = makeOne(0); + if (item.postSet) ret += item.postSet; + return ret; + } else { // MICRO_OPTS == 1 + assert(0, 'TODO'); } - var ret = makeOne(0); - if (item.postSet) ret += item.postSet; - return ret; }); makeFuncLineActor('mathop', processMathop); |