support reaching phi from invoke, and a workaround with vars in phi sets for closure compiler

This commit is contained in:
Alon Zakai 2011-11-18 18:52:56 -08:00
Родитель 6fe6d4c2e4
Коммит cc86495ebd
3 изменённых файлов: 11 добавлений и 10 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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
};