mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 994016: IonMonkey: More agressively improve types at branches, r=jandem
This commit is contained in:
parent
b8daacb05c
commit
7e064e57d6
@ -3308,7 +3308,7 @@ IonBuilder::replaceTypeSet(MDefinition *subject, TemporaryTypeSet *type, MTest *
|
|||||||
if (type->unknown())
|
if (type->unknown())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (type->equals(subject->resultTypeSet()))
|
if (subject->resultTypeSet() && type->equals(subject->resultTypeSet()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
MInstruction *replace = nullptr;
|
MInstruction *replace = nullptr;
|
||||||
@ -3463,7 +3463,18 @@ IonBuilder::improveTypesAtTypeOfCompare(MCompare *ins, bool trueBranch, MTest *t
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
MDefinition *subject = typeOf->input();
|
MDefinition *subject = typeOf->input();
|
||||||
if (!subject->resultTypeSet() || subject->resultTypeSet()->unknown())
|
TemporaryTypeSet *inputTypes = subject->resultTypeSet();
|
||||||
|
|
||||||
|
// Create temporary typeset equal to the type if there is no resultTypeSet.
|
||||||
|
TemporaryTypeSet tmp;
|
||||||
|
if (!inputTypes) {
|
||||||
|
if (subject->type() == MIRType_Value)
|
||||||
|
return true;
|
||||||
|
inputTypes = &tmp;
|
||||||
|
tmp.addType(TypeSet::PrimitiveType(ValueTypeFromMIRType(subject->type())), alloc_->lifoAlloc());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputTypes->unknown())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Note: we cannot remove the AnyObject type in the false branch,
|
// Note: we cannot remove the AnyObject type in the false branch,
|
||||||
@ -3493,9 +3504,9 @@ IonBuilder::improveTypesAtTypeOfCompare(MCompare *ins, bool trueBranch, MTest *t
|
|||||||
|
|
||||||
TemporaryTypeSet *type;
|
TemporaryTypeSet *type;
|
||||||
if (trueBranch)
|
if (trueBranch)
|
||||||
type = TypeSet::intersectSets(&filter, subject->resultTypeSet(), alloc_->lifoAlloc());
|
type = TypeSet::intersectSets(&filter, inputTypes, alloc_->lifoAlloc());
|
||||||
else
|
else
|
||||||
type = TypeSet::removeSet(subject->resultTypeSet(), &filter, alloc_->lifoAlloc());
|
type = TypeSet::removeSet(inputTypes, &filter, alloc_->lifoAlloc());
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
return false;
|
return false;
|
||||||
@ -3528,13 +3539,20 @@ IonBuilder::improveTypesAtNullOrUndefinedCompare(MCompare *ins, bool trueBranch,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MDefinition *subject = ins->lhs();
|
MDefinition *subject = ins->lhs();
|
||||||
|
TemporaryTypeSet *inputTypes = subject->resultTypeSet();
|
||||||
|
|
||||||
MOZ_ASSERT(IsNullOrUndefined(ins->rhs()->type()));
|
MOZ_ASSERT(IsNullOrUndefined(ins->rhs()->type()));
|
||||||
|
|
||||||
if (!subject->resultTypeSet() || subject->resultTypeSet()->unknown())
|
// Create temporary typeset equal to the type if there is no resultTypeSet.
|
||||||
return true;
|
TemporaryTypeSet tmp;
|
||||||
|
if (!inputTypes) {
|
||||||
|
if (subject->type() == MIRType_Value)
|
||||||
|
return true;
|
||||||
|
inputTypes = &tmp;
|
||||||
|
tmp.addType(TypeSet::PrimitiveType(ValueTypeFromMIRType(subject->type())), alloc_->lifoAlloc());
|
||||||
|
}
|
||||||
|
|
||||||
if (!altersUndefined && !altersNull)
|
if (inputTypes->unknown())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
TemporaryTypeSet *type;
|
TemporaryTypeSet *type;
|
||||||
@ -3548,21 +3566,21 @@ IonBuilder::improveTypesAtNullOrUndefinedCompare(MCompare *ins, bool trueBranch,
|
|||||||
if (altersNull)
|
if (altersNull)
|
||||||
remove.addType(TypeSet::NullType(), alloc_->lifoAlloc());
|
remove.addType(TypeSet::NullType(), alloc_->lifoAlloc());
|
||||||
|
|
||||||
type = TypeSet::removeSet(subject->resultTypeSet(), &remove, alloc_->lifoAlloc());
|
type = TypeSet::removeSet(inputTypes, &remove, alloc_->lifoAlloc());
|
||||||
} else {
|
} else {
|
||||||
// Set undefined/null.
|
// Set undefined/null.
|
||||||
TemporaryTypeSet base;
|
TemporaryTypeSet base;
|
||||||
if (altersUndefined) {
|
if (altersUndefined) {
|
||||||
base.addType(TypeSet::UndefinedType(), alloc_->lifoAlloc());
|
base.addType(TypeSet::UndefinedType(), alloc_->lifoAlloc());
|
||||||
// If TypeSet emulates undefined, then we cannot filter the objects.
|
// If TypeSet emulates undefined, then we cannot filter the objects.
|
||||||
if (subject->resultTypeSet()->maybeEmulatesUndefined(constraints()))
|
if (inputTypes->maybeEmulatesUndefined(constraints()))
|
||||||
base.addType(TypeSet::AnyObjectType(), alloc_->lifoAlloc());
|
base.addType(TypeSet::AnyObjectType(), alloc_->lifoAlloc());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (altersNull)
|
if (altersNull)
|
||||||
base.addType(TypeSet::NullType(), alloc_->lifoAlloc());
|
base.addType(TypeSet::NullType(), alloc_->lifoAlloc());
|
||||||
|
|
||||||
type = TypeSet::intersectSets(&base, subject->resultTypeSet(), alloc_->lifoAlloc());
|
type = TypeSet::intersectSets(&base, inputTypes, alloc_->lifoAlloc());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
@ -3587,9 +3605,17 @@ IonBuilder::improveTypesAtTest(MDefinition *ins, bool trueBranch, MTest *test)
|
|||||||
return improveTypesAtTest(ins->toNot()->getOperand(0), !trueBranch, test);
|
return improveTypesAtTest(ins->toNot()->getOperand(0), !trueBranch, test);
|
||||||
case MDefinition::Op_IsObject: {
|
case MDefinition::Op_IsObject: {
|
||||||
TemporaryTypeSet *oldType = ins->getOperand(0)->resultTypeSet();
|
TemporaryTypeSet *oldType = ins->getOperand(0)->resultTypeSet();
|
||||||
if (!oldType)
|
|
||||||
return true;
|
// Create temporary typeset equal to the type if there is no resultTypeSet.
|
||||||
if (oldType->unknown() || !oldType->mightBeMIRType(MIRType_Object))
|
TemporaryTypeSet tmp;
|
||||||
|
if (!oldType) {
|
||||||
|
if (ins->type() == MIRType_Value)
|
||||||
|
return true;
|
||||||
|
oldType = &tmp;
|
||||||
|
tmp.addType(TypeSet::PrimitiveType(ValueTypeFromMIRType(ins->type())), alloc_->lifoAlloc());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldType->unknown())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
TemporaryTypeSet *type = nullptr;
|
TemporaryTypeSet *type = nullptr;
|
||||||
@ -3656,13 +3682,22 @@ IonBuilder::improveTypesAtTest(MDefinition *ins, bool trueBranch, MTest *test)
|
|||||||
// undefined and null. In false branch we can only encounter undefined, null, false, 0, ""
|
// undefined and null. In false branch we can only encounter undefined, null, false, 0, ""
|
||||||
// and objects that emulate undefined.
|
// and objects that emulate undefined.
|
||||||
|
|
||||||
// If ins does not have a typeset we return as we cannot optimize.
|
|
||||||
if (!ins->resultTypeSet() || ins->resultTypeSet()->unknown())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
TemporaryTypeSet *oldType = ins->resultTypeSet();
|
TemporaryTypeSet *oldType = ins->resultTypeSet();
|
||||||
TemporaryTypeSet *type;
|
TemporaryTypeSet *type;
|
||||||
|
|
||||||
|
// Create temporary typeset equal to the type if there is no resultTypeSet.
|
||||||
|
TemporaryTypeSet tmp;
|
||||||
|
if (!oldType) {
|
||||||
|
if (ins->type() == MIRType_Value)
|
||||||
|
return true;
|
||||||
|
oldType = &tmp;
|
||||||
|
tmp.addType(TypeSet::PrimitiveType(ValueTypeFromMIRType(ins->type())), alloc_->lifoAlloc());
|
||||||
|
}
|
||||||
|
|
||||||
|
// If ins does not have a typeset we return as we cannot optimize.
|
||||||
|
if (oldType->unknown())
|
||||||
|
return true;
|
||||||
|
|
||||||
// Decide either to set or remove.
|
// Decide either to set or remove.
|
||||||
if (trueBranch) {
|
if (trueBranch) {
|
||||||
TemporaryTypeSet remove;
|
TemporaryTypeSet remove;
|
||||||
|
Loading…
Reference in New Issue
Block a user