aboutsummaryrefslogtreecommitdiff
path: root/src/analyzer.js
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-11-11 18:40:38 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-11-11 18:40:38 -0800
commite63a5571ac6f213c42202358798ebd6c82ab46b6 (patch)
treee85968effe341e5c329210dd2df9b5f4e2783014 /src/analyzer.js
parenta712f0dbf34060af8ec376483bc9a446233de113 (diff)
fix phi semantics with multiple dependent phis
Diffstat (limited to 'src/analyzer.js')
-rw-r--r--src/analyzer.js23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 366e2e02..efba03e8 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -613,6 +613,7 @@ function analyzer(data) {
func.hasIndirectBr = false;
func.remarkableLabels = [];
func.labels.forEach(function(label) {
+ var phis = [];
label.lines.forEach(function(line) {
if (line.value && line.value.intertype == 'phi') {
for (var i = 0; i < line.value.params.length; i++) {
@@ -627,12 +628,34 @@ function analyzer(data) {
lastLine.currLabelId = remarkableLabelId;
}
}
+ phis.push(line);
func.hasPhi = true;
}
if (line.intertype == 'indirectbr') {
func.hasIndirectBr = true;
}
});
+ if (phis.length >= 2) {
+ // Multiple phis have the semantics that they all occur 'in parallel', i.e., changes to
+ // a variable that is the result of a phi should *not* affect the other results. We must
+ // therefore be careful!
+ // TODO: optimize this for cases where they are not dependent
+ phis[phis.length-1].value.postSet = '; /* post-phi: */';
+ for (var i = 0; i < phis.length-1; i++) {
+ var ident = phis[i].ident;
+ var phid = ident+'$phi'
+ phis[phis.length-1].value.postSet += ident + '=' + phid + ';';
+ phis[i].ident = phid;
+ func.variables[phid] = {
+ ident: phid,
+ type: func.variables[ident].type,
+ origin: func.variables[ident].origin,
+ lineNum: func.variables[ident].lineNum,
+ uses: 1,
+ impl: VAR_EMULATED
+ };
+ }
+ }
});
});
this.forwardItem(item, 'StackAnalyzer');