diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-11-18 18:52:56 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-11-18 18:52:56 -0800 |
commit | cc86495ebd83005e1f63bfa12b90d903d7ac7b66 (patch) | |
tree | 8fbc5fce9292e9aab28d1e9048af2248a0b54908 | |
parent | 6fe6d4c2e43a7b2637c9cace06c7ef3f21018f0d (diff) |
support reaching phi from invoke, and a workaround with vars in phi sets for closure compiler
-rw-r--r-- | src/analyzer.js | 4 | ||||
-rw-r--r-- | src/jsifier.js | 15 | ||||
-rw-r--r-- | src/modules.js | 2 |
3 files changed, 11 insertions, 10 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index c8e31dea..0c362eff 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -628,7 +628,7 @@ function analyzer(data) { var sourceLabelId = phi.params[i].label; var sourceLabel = func.labelsDict[sourceLabelId]; var lastLine = sourceLabel.lines.slice(-1)[0]; - assert(lastLine.intertype in LLVM.BRANCHINGS, 'Only branches can lead to labels with phis, line ' + [func.ident, label.ident]); + assert(lastLine.intertype in LLVM.PHI_REACHERS, 'Only some can lead to labels with phis, line ' + [func.ident, label.ident]); lastLine.currLabelId = sourceLabelId; } phis.push(line); @@ -671,7 +671,7 @@ function analyzer(data) { var sourceLabelId = param.label; var sourceLabel = func.labelsDict[sourceLabelId]; var lastLine = sourceLabel.lines.slice(-1)[0]; - assert(lastLine.intertype in LLVM.BRANCHINGS, 'Only branches can lead to labels with phis, line ' + [func.ident, label.ident]); + assert(lastLine.intertype in LLVM.PHI_REACHERS, 'Only some can lead to labels with phis, line ' + [func.ident, label.ident]); if (!lastLine.phi) { // We store the phi assignments in the branch's params (which are otherwise unused) lastLine.phi = true; diff --git a/src/jsifier.js b/src/jsifier.js index 38cdac35..9cf7e1e0 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -716,8 +716,9 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { label = getOldLabel(label); if (!phiSets || !phiSets[label]) return ''; var labelSets = phiSets[label]; + // FIXME: Many of the |var |s here are not needed, but without them we get slowdowns with closure compiler. TODO: remove this workaround. if (labelSets.length == 1) { - return labelSets[0].ident + ' = ' + labelSets[0].valueJS + ';'; + return 'var ' + labelSets[0].ident + ' = ' + labelSets[0].valueJS + ';'; } // TODO: eliminate unneeded sets (to undefined etc.) var deps = {}; // for each ident we will set, which others it depends on @@ -743,14 +744,14 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { } for (var i = 0; i < idents.length; i++) { if (keys(deps[idents[i]]).length == 0) { - pre = idents[i] + ' = ' + valueJSes[idents[i]] + ';' + pre; + pre = 'var ' + idents[i] + ' = ' + valueJSes[idents[i]] + ';' + pre; remove(idents[i]); continue mainLoop; } } // If we got here, we have circular dependencies, and must break at least one. pre = 'var ' + idents[0] + '$phi = ' + valueJSes[idents[i]] + ';' + pre; - post += idents[0] + ' = ' + idents[0] + '$phi;'; + post += 'var ' + idents[0] + ' = ' + idents[0] + '$phi;'; remove(idents[0]); } return pre + post; @@ -806,7 +807,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { ret += '}\n'; }); if (item.switchLabels.length > 0) ret += 'else {\n'; - ret += makeBranch(item.defaultLabel, item.currLabelId) + '\n'; + ret += getPhiSetsForLabel(phiSets, item.defaultLabel) + makeBranch(item.defaultLabel, item.currLabelId) + '\n'; if (item.switchLabels.length > 0) ret += '}\n'; if (item.value) { ret += ' ' + toNiceIdent(item.value); @@ -837,16 +838,16 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) { makeFuncLineActor('invoke', function(item) { // Wrapping in a function lets us easily return values if we are // in an assignment + var phiSets = calcPhiSets(item); var call_ = makeFunctionCall(item.ident, item.params, item.funcData); - var branch = makeBranch(item.toLabel, item.currLabelId); var ret = '(function() { try { __THREW__ = false; return ' + call_ + ' ' + '} catch(e) { ' + 'if (typeof e != "number") throw e; ' + 'if (ABORT) throw e; __THREW__ = true; ' + (EXCEPTION_DEBUG ? 'print("Exception: " + e + ", currently at: " + (new Error().stack)); ' : '') - + 'return null } })(); if (!__THREW__) { ' + branch - + ' } else { ' + makeBranch(item.unwindLabel, item.currLabelId) + ' }'; + + 'return null } })(); if (!__THREW__) { ' + getPhiSetsForLabel(phiSets, item.toLabel) + makeBranch(item.toLabel, item.currLabelId) + + ' } else { ' + getPhiSetsForLabel(phiSets, item.unwindLabel) + makeBranch(item.unwindLabel, item.currLabelId) + ' }'; return ret; }); makeFuncLineActor('landingpad', function(item) { diff --git a/src/modules.js b/src/modules.js index ba4a95bd..fec73f34 100644 --- a/src/modules.js +++ b/src/modules.js @@ -12,7 +12,7 @@ var LLVM = { ACCESS_OPTIONS: set('volatile', 'atomic'), INVOKE_MODIFIERS: set('alignstack', 'alwaysinline', 'inlinehint', 'naked', 'noimplicitfloat', 'noinline', 'alwaysinline attribute.', 'noredzone', 'noreturn', 'nounwind', 'optsize', 'readnone', 'readonly', 'ssp', 'sspreq'), SHIFTS: set('ashr', 'lshr', 'shl'), - BRANCHINGS: set('branch', 'switch'), + PHI_REACHERS: set('branch', 'switch', 'invoke'), EXTENDS: set('sext', 'zext'), INTRINSICS_32: set('_llvm_memcpy_p0i8_p0i8_i64', '_llvm_memmove_p0i8_p0i8_i64', '_llvm_memset_p0i8_i64'), // intrinsics that need args converted to i32 in I64_MODE 1 }; |