зеркало из https://github.com/mozilla/gecko-dev.git
Bug 946425 - Make phi specialization more accurate when one of the inputs has an empty typeset. r=bhackett
This commit is contained in:
Родитель
75164d8012
Коммит
4ca63cacde
|
@ -436,13 +436,17 @@ class TypeAnalyzer
|
|||
|
||||
// Try to specialize this phi based on its non-cyclic inputs.
|
||||
static MIRType
|
||||
GuessPhiType(MPhi *phi)
|
||||
GuessPhiType(MPhi *phi, bool *hasInputsWithEmptyTypes)
|
||||
{
|
||||
*hasInputsWithEmptyTypes = false;
|
||||
|
||||
MIRType type = MIRType_None;
|
||||
bool convertibleToFloat32 = false;
|
||||
bool hasPhiInputs = false;
|
||||
for (size_t i = 0, e = phi->numOperands(); i < e; i++) {
|
||||
MDefinition *in = phi->getOperand(i);
|
||||
if (in->isPhi()) {
|
||||
hasPhiInputs = true;
|
||||
if (!in->toPhi()->triedToSpecialize())
|
||||
continue;
|
||||
if (in->type() == MIRType_None) {
|
||||
|
@ -452,6 +456,13 @@ GuessPhiType(MPhi *phi)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore operands which we've never observed.
|
||||
if (in->resultTypeSet() && in->resultTypeSet()->empty()) {
|
||||
*hasInputsWithEmptyTypes = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type == MIRType_None) {
|
||||
type = in->type();
|
||||
if (in->canProduceFloat32())
|
||||
|
@ -459,10 +470,6 @@ GuessPhiType(MPhi *phi)
|
|||
continue;
|
||||
}
|
||||
if (type != in->type()) {
|
||||
// Ignore operands which we've never observed.
|
||||
if (in->resultTypeSet() && in->resultTypeSet()->empty())
|
||||
continue;
|
||||
|
||||
if (convertibleToFloat32 && in->type() == MIRType_Float32) {
|
||||
// If we only saw definitions that can be converted into Float32 before and
|
||||
// encounter a Float32 value, promote previous values to Float32
|
||||
|
@ -476,6 +483,14 @@ GuessPhiType(MPhi *phi)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == MIRType_None && !hasPhiInputs) {
|
||||
// All inputs are non-phis with empty typesets. Use MIRType_Value
|
||||
// in this case, as it's impossible to get better type information.
|
||||
JS_ASSERT(*hasInputsWithEmptyTypes);
|
||||
type = MIRType_Value;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -537,18 +552,28 @@ TypeAnalyzer::propagateSpecialization(MPhi *phi)
|
|||
bool
|
||||
TypeAnalyzer::specializePhis()
|
||||
{
|
||||
Vector<MPhi *, 0, SystemAllocPolicy> phisWithEmptyInputTypes;
|
||||
|
||||
for (PostorderIterator block(graph.poBegin()); block != graph.poEnd(); block++) {
|
||||
if (mir->shouldCancel("Specialize Phis (main loop)"))
|
||||
return false;
|
||||
|
||||
for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++) {
|
||||
MIRType type = GuessPhiType(*phi);
|
||||
bool hasInputsWithEmptyTypes;
|
||||
MIRType type = GuessPhiType(*phi, &hasInputsWithEmptyTypes);
|
||||
phi->specialize(type);
|
||||
if (type == MIRType_None) {
|
||||
// We tried to guess the type but failed because all operands are
|
||||
// phis we still have to visit. Set the triedToSpecialize flag but
|
||||
// don't propagate the type to other phis, propagateSpecialization
|
||||
// will do that once we know the type of one of the operands.
|
||||
|
||||
// Edge case: when this phi has a non-phi input with an empty
|
||||
// typeset, it's possible for two phis to have a cyclic
|
||||
// dependency and they will both have MIRType_None. Specialize
|
||||
// such phis to MIRType_Value later on.
|
||||
if (hasInputsWithEmptyTypes && !phisWithEmptyInputTypes.append(*phi))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if (!propagateSpecialization(*phi))
|
||||
|
@ -556,14 +581,31 @@ TypeAnalyzer::specializePhis()
|
|||
}
|
||||
}
|
||||
|
||||
while (!phiWorklist_.empty()) {
|
||||
if (mir->shouldCancel("Specialize Phis (worklist)"))
|
||||
return false;
|
||||
do {
|
||||
while (!phiWorklist_.empty()) {
|
||||
if (mir->shouldCancel("Specialize Phis (worklist)"))
|
||||
return false;
|
||||
|
||||
MPhi *phi = popPhi();
|
||||
if (!propagateSpecialization(phi))
|
||||
return false;
|
||||
}
|
||||
MPhi *phi = popPhi();
|
||||
if (!propagateSpecialization(phi))
|
||||
return false;
|
||||
}
|
||||
|
||||
// When two phis have a cyclic dependency and inputs that have an empty
|
||||
// typeset (which are ignored by GuessPhiType), we may still have to
|
||||
// specialize these to MIRType_Value.
|
||||
while (!phisWithEmptyInputTypes.empty()) {
|
||||
if (mir->shouldCancel("Specialize Phis (phisWithEmptyInputTypes)"))
|
||||
return false;
|
||||
|
||||
MPhi *phi = phisWithEmptyInputTypes.popCopy();
|
||||
if (phi->type() == MIRType_None) {
|
||||
phi->specialize(MIRType_Value);
|
||||
if (!propagateSpecialization(phi))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} while (!phiWorklist_.empty());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -572,6 +614,7 @@ void
|
|||
TypeAnalyzer::adjustPhiInputs(MPhi *phi)
|
||||
{
|
||||
MIRType phiType = phi->type();
|
||||
JS_ASSERT(phiType != MIRType_None);
|
||||
|
||||
// If we specialized a type that's not Value, there are 3 cases:
|
||||
// 1. Every input is of that type.
|
||||
|
|
Загрузка…
Ссылка в новой задаче