mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 895465 - IonMonkey: Optimize codegen for test(and(x, y)). r=mrosenberg
This commit is contained in:
parent
5d2089d328
commit
c31a6471bc
@ -1666,6 +1666,33 @@ class LCompareVM : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
|
||||
}
|
||||
};
|
||||
|
||||
class LBitAndAndBranch : public LControlInstructionHelper<2, 2, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(BitAndAndBranch)
|
||||
LBitAndAndBranch(MBasicBlock *ifTrue, MBasicBlock *ifFalse)
|
||||
{
|
||||
setSuccessor(0, ifTrue);
|
||||
setSuccessor(1, ifFalse);
|
||||
}
|
||||
|
||||
MBasicBlock *ifTrue() const {
|
||||
return getSuccessor(0);
|
||||
}
|
||||
MBasicBlock *ifFalse() const {
|
||||
return getSuccessor(1);
|
||||
}
|
||||
const LAllocation *left() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LAllocation *right() {
|
||||
return getOperand(1);
|
||||
}
|
||||
MCompare *mir() {
|
||||
return mir_->toCompare();
|
||||
}
|
||||
};
|
||||
|
||||
class LIsNullOrLikeUndefined : public LInstructionHelper<1, BOX_PIECES, 2>
|
||||
{
|
||||
public:
|
||||
|
@ -81,6 +81,7 @@
|
||||
_(CompareV) \
|
||||
_(CompareVAndBranch) \
|
||||
_(CompareVM) \
|
||||
_(BitAndAndBranch) \
|
||||
_(IsNullOrLikeUndefined) \
|
||||
_(IsNullOrLikeUndefinedAndBranch)\
|
||||
_(EmulatesUndefined) \
|
||||
|
@ -518,6 +518,27 @@ ReorderComparison(JSOp op, MDefinition **lhsp, MDefinition **rhsp)
|
||||
return op;
|
||||
}
|
||||
|
||||
static void
|
||||
ReorderCommutative(MDefinition **lhsp, MDefinition **rhsp)
|
||||
{
|
||||
MDefinition *lhs = *lhsp;
|
||||
MDefinition *rhs = *rhsp;
|
||||
|
||||
// Ensure that if there is a constant, then it is in rhs.
|
||||
// In addition, since clobbering binary operations clobber the left
|
||||
// operand, prefer a non-constant lhs operand with no further uses.
|
||||
|
||||
if (rhs->isConstant())
|
||||
return;
|
||||
|
||||
if (lhs->isConstant() ||
|
||||
(rhs->defUseCount() == 1 && lhs->defUseCount() > 1))
|
||||
{
|
||||
*rhsp = lhs;
|
||||
*lhsp = rhs;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitTest(MTest *test)
|
||||
{
|
||||
@ -672,6 +693,17 @@ LIRGenerator::visitTest(MTest *test)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the operand for this test is a bitand operation. If it is, we want
|
||||
// to emit an LBitAndAndBranch rather than an LTest*AndBranch.
|
||||
if (opd->isBitAnd() && opd->isEmittedAtUses()) {
|
||||
MDefinition *lhs = opd->getOperand(0);
|
||||
MDefinition *rhs = opd->getOperand(1);
|
||||
if (lhs->type() == MIRType_Int32 && rhs->type() == MIRType_Int32) {
|
||||
ReorderCommutative(&lhs, &rhs);
|
||||
return lowerForBitAndAndBranch(new LBitAndAndBranch(ifTrue, ifFalse), test, lhs, rhs);
|
||||
}
|
||||
}
|
||||
|
||||
if (opd->type() == MIRType_Double)
|
||||
return add(new LTestDAndBranch(useRegister(opd), ifTrue, ifFalse));
|
||||
|
||||
@ -846,27 +878,6 @@ LIRGenerator::visitCompare(MCompare *comp)
|
||||
MOZ_ASSUME_UNREACHABLE("Unrecognized compare type.");
|
||||
}
|
||||
|
||||
static void
|
||||
ReorderCommutative(MDefinition **lhsp, MDefinition **rhsp)
|
||||
{
|
||||
MDefinition *lhs = *lhsp;
|
||||
MDefinition *rhs = *rhsp;
|
||||
|
||||
// Ensure that if there is a constant, then it is in rhs.
|
||||
// In addition, since clobbering binary operations clobber the left
|
||||
// operand, prefer a non-constant lhs operand with no further uses.
|
||||
|
||||
if (rhs->isConstant())
|
||||
return;
|
||||
|
||||
if (lhs->isConstant() ||
|
||||
(rhs->defUseCount() == 1 && lhs->defUseCount() > 1))
|
||||
{
|
||||
*rhsp = lhs;
|
||||
*lhsp = rhs;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::lowerBitOp(JSOp op, MInstruction *ins)
|
||||
{
|
||||
@ -926,9 +937,36 @@ LIRGenerator::visitBitNot(MBitNot *ins)
|
||||
return assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
static bool
|
||||
CanEmitBitAndAtUses(MInstruction *ins)
|
||||
{
|
||||
if (!ins->canEmitAtUses())
|
||||
return false;
|
||||
|
||||
if (ins->getOperand(0)->type() != MIRType_Int32 || ins->getOperand(1)->type() != MIRType_Int32)
|
||||
return false;
|
||||
|
||||
MUseDefIterator iter(ins);
|
||||
if (!iter)
|
||||
return false;
|
||||
|
||||
if (!iter.def()->isTest())
|
||||
return false;
|
||||
|
||||
iter++;
|
||||
return !iter;
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitBitAnd(MBitAnd *ins)
|
||||
{
|
||||
// Sniff out if the output of this bitand is used only for a branching.
|
||||
// If it is, then we will emit an LBitAndAndBranch instruction in place
|
||||
// of this bitand and any test that uses this bitand. Thus, we can
|
||||
// ignore this BitAnd.
|
||||
if (CanEmitBitAndAtUses(ins))
|
||||
return emitAtUses(ins);
|
||||
|
||||
return lowerBitOp(JSOP_BITAND, ins);
|
||||
}
|
||||
|
||||
|
@ -1449,6 +1449,17 @@ CodeGeneratorARM::visitCompareVAndBranch(LCompareVAndBranch *lir)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM::visitBitAndAndBranch(LBitAndAndBranch *baab)
|
||||
{
|
||||
if (baab->right()->isConstant())
|
||||
masm.ma_tst(ToRegister(baab->left()), Imm32(ToInt32(baab->right())));
|
||||
else
|
||||
masm.ma_tst(ToRegister(baab->left()), ToRegister(baab->right()));
|
||||
emitBranch(Assembler::NonZero, baab->ifTrue(), baab->ifFalse());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM::visitUInt32ToDouble(LUInt32ToDouble *lir)
|
||||
{
|
||||
|
@ -95,6 +95,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
||||
virtual bool visitCompareBAndBranch(LCompareBAndBranch *lir);
|
||||
virtual bool visitCompareV(LCompareV *lir);
|
||||
virtual bool visitCompareVAndBranch(LCompareVAndBranch *lir);
|
||||
virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab);
|
||||
virtual bool visitUInt32ToDouble(LUInt32ToDouble *lir);
|
||||
virtual bool visitNotI(LNotI *ins);
|
||||
virtual bool visitNotD(LNotD *ins);
|
||||
|
@ -185,6 +185,15 @@ LIRGeneratorARM::lowerForFPU(LInstructionHelper<1, 2, 0> *ins, MDefinition *mir,
|
||||
LDefinition(LDefinition::TypeFrom(mir->type()), LDefinition::DEFAULT));
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorARM::lowerForBitAndAndBranch(LBitAndAndBranch *baab, MInstruction *mir,
|
||||
MDefinition *lhs, MDefinition *rhs)
|
||||
{
|
||||
baab->setOperand(0, useRegister(lhs));
|
||||
baab->setOperand(1, useRegisterOrConstant(rhs));
|
||||
return add(baab, mir);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorARM::defineUntypedPhi(MPhi *phi, size_t lirIndex)
|
||||
{
|
||||
|
@ -45,6 +45,8 @@ class LIRGeneratorARM : public LIRGeneratorShared
|
||||
MDefinition *src);
|
||||
bool lowerForFPU(LInstructionHelper<1, 2, 0> *ins, MDefinition *mir,
|
||||
MDefinition *lhs, MDefinition *rhs);
|
||||
bool lowerForBitAndAndBranch(LBitAndAndBranch *baab, MInstruction *mir,
|
||||
MDefinition *lhs, MDefinition *rhs);
|
||||
|
||||
bool lowerTruncateDToInt32(MTruncateToInt32 *ins);
|
||||
|
||||
|
@ -128,6 +128,17 @@ CodeGeneratorX86Shared::visitTestDAndBranch(LTestDAndBranch *test)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitBitAndAndBranch(LBitAndAndBranch *baab)
|
||||
{
|
||||
if (baab->right()->isConstant())
|
||||
masm.testl(ToRegister(baab->left()), Imm32(ToInt32(baab->right())));
|
||||
else
|
||||
masm.testl(ToRegister(baab->left()), ToRegister(baab->right()));
|
||||
emitBranch(Assembler::NonZero, baab->ifTrue(), baab->ifFalse());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CodeGeneratorX86Shared::emitCompare(MCompare::CompareType type, const LAllocation *left, const LAllocation *right)
|
||||
{
|
||||
|
@ -98,6 +98,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
||||
virtual bool visitCompareAndBranch(LCompareAndBranch *comp);
|
||||
virtual bool visitCompareD(LCompareD *comp);
|
||||
virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp);
|
||||
virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab);
|
||||
virtual bool visitNotI(LNotI *comp);
|
||||
virtual bool visitNotD(LNotD *comp);
|
||||
virtual bool visitMathD(LMathD *math);
|
||||
|
@ -116,6 +116,15 @@ LIRGeneratorX86Shared::lowerForFPU(LInstructionHelper<1, 2, 0> *ins, MDefinition
|
||||
return defineReuseInput(ins, mir, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorX86Shared::lowerForBitAndAndBranch(LBitAndAndBranch *baab, MInstruction *mir,
|
||||
MDefinition *lhs, MDefinition *rhs)
|
||||
{
|
||||
baab->setOperand(0, useRegister(lhs));
|
||||
baab->setOperand(1, useRegisterOrConstant(rhs));
|
||||
return add(baab, mir);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGeneratorX86Shared::lowerMulI(MMul *mul, MDefinition *lhs, MDefinition *rhs)
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ class LIRGeneratorX86Shared : public LIRGeneratorShared
|
||||
MDefinition *rhs);
|
||||
bool lowerForFPU(LInstructionHelper<1, 2, 0> *ins, MDefinition *mir, MDefinition *lhs,
|
||||
MDefinition *rhs);
|
||||
bool lowerForBitAndAndBranch(LBitAndAndBranch *baab, MInstruction *mir,
|
||||
MDefinition *lhs, MDefinition *rhs);
|
||||
bool visitConstant(MConstant *ins);
|
||||
bool visitAsmJSNeg(MAsmJSNeg *ins);
|
||||
bool visitAsmJSUDiv(MAsmJSUDiv *ins);
|
||||
|
Loading…
Reference in New Issue
Block a user