mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1331350 - Fuse BitAnd, Compare and Test into BitAndAndBranch r=jandem
MozReview-Commit-ID: 3EqbLbOywc9
This commit is contained in:
parent
8ffcff7389
commit
a9119dcaa8
56
js/src/jit-test/tests/ion/bug1331350.js
Normal file
56
js/src/jit-test/tests/ion/bug1331350.js
Normal file
@ -0,0 +1,56 @@
|
||||
// |jit-test| --ion-eager
|
||||
function optimize(a, b) {
|
||||
a = a | 0;
|
||||
b = b | 0;
|
||||
|
||||
if ((a & 3) === 0) {
|
||||
a = a + 1 | 0
|
||||
}
|
||||
|
||||
if ((a & 7) !== 0) {
|
||||
a = a + 1 | 0
|
||||
}
|
||||
|
||||
return a + b | 0
|
||||
}
|
||||
|
||||
for (var i=0; i<20; i++) {
|
||||
assertEq(optimize(4 | 0, 6 | 0), 12);
|
||||
assertEq(optimize(7 | 0, 11 | 0), 19);
|
||||
}
|
||||
|
||||
function not_optimizable(a, b) {
|
||||
a = a | 0;
|
||||
b = b | 0;
|
||||
|
||||
if ((a & 3) > 0) {
|
||||
a = a + 1 | 0
|
||||
}
|
||||
|
||||
if ((a & 3) >= 0) {
|
||||
a = a + 1 | 0
|
||||
}
|
||||
|
||||
if ((a & 7) < 0) {
|
||||
a = a + 1 | 0
|
||||
}
|
||||
|
||||
if ((a & 7) <= 0) {
|
||||
a = a + 1 | 0
|
||||
}
|
||||
|
||||
if ((b & 3) === 1) {
|
||||
b = b + 1 | 0
|
||||
}
|
||||
|
||||
if ((b & 7) !== 3) {
|
||||
b = b + 1 | 0
|
||||
}
|
||||
|
||||
return a + b | 0
|
||||
}
|
||||
|
||||
for (var i=0; i<20; i++) {
|
||||
assertEq(not_optimizable(4 | 0, 6 | 0), 12);
|
||||
assertEq(not_optimizable(7 | 0, 11 | 0), 20);
|
||||
}
|
@ -779,6 +779,40 @@ LIRGenerator::visitTest(MTest* test)
|
||||
return;
|
||||
}
|
||||
|
||||
if (opd->isCompare() && opd->isEmittedAtUses()) {
|
||||
// Emit LBitAndBranch for cases like |if ((x & y) === 0)|.
|
||||
MCompare* comp = opd->toCompare();
|
||||
if ((comp->isInt32Comparison() ||
|
||||
comp->compareType() == MCompare::Compare_UInt32) &&
|
||||
comp->getOperand(1)->isConstant() &&
|
||||
comp->getOperand(1)->toConstant()->isInt32(0) &&
|
||||
comp->getOperand(0)->isBitAnd() &&
|
||||
comp->getOperand(0)->isEmittedAtUses())
|
||||
{
|
||||
MDefinition* bitAnd = opd->getOperand(0);
|
||||
MDefinition* lhs = bitAnd->getOperand(0);
|
||||
MDefinition* rhs = bitAnd->getOperand(1);
|
||||
|
||||
Assembler::Condition cond = JSOpToCondition(comp->compareType(),
|
||||
comp->jsop());
|
||||
|
||||
if (lhs->type() == MIRType::Int32 && rhs->type() == MIRType::Int32 &&
|
||||
(cond == Assembler::Equal || cond == Assembler::NotEqual))
|
||||
{
|
||||
ReorderCommutative(&lhs, &rhs, test);
|
||||
if (cond == Assembler::Equal)
|
||||
cond = Assembler::Zero;
|
||||
else if(cond == Assembler::NotEqual)
|
||||
cond = Assembler::NonZero;
|
||||
else
|
||||
MOZ_ASSERT_UNREACHABLE("inequality operators cannot be folded");
|
||||
lowerForBitAndAndBranch(new(alloc()) LBitAndAndBranch(ifTrue, ifFalse, cond),
|
||||
test, lhs, rhs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the operand for this test is a compare operation. If it is, we want
|
||||
// to emit an LCompare*AndBranch rather than an LTest*AndBranch, to fuse the
|
||||
// compare and jump instructions.
|
||||
@ -1221,10 +1255,11 @@ CanEmitBitAndAtUses(MInstruction* ins)
|
||||
return false;
|
||||
|
||||
MNode* node = iter->consumer();
|
||||
if (!node->isDefinition())
|
||||
if (!node->isDefinition() || !node->toDefinition()->isInstruction())
|
||||
return false;
|
||||
|
||||
if (!node->toDefinition()->isTest())
|
||||
MInstruction* use = node->toDefinition()->toInstruction();
|
||||
if (!use->isTest() && !(use->isCompare() && CanEmitCompareAtUses(use)))
|
||||
return false;
|
||||
|
||||
iter++;
|
||||
|
@ -1633,7 +1633,7 @@ CodeGeneratorARM::visitBitAndAndBranch(LBitAndAndBranch* baab)
|
||||
masm.ma_tst(ToRegister(baab->left()), Imm32(ToInt32(baab->right())), scratch);
|
||||
else
|
||||
masm.ma_tst(ToRegister(baab->left()), ToRegister(baab->right()));
|
||||
emitBranch(Assembler::NonZero, baab->ifTrue(), baab->ifFalse());
|
||||
emitBranch(baab->cond(), baab->ifTrue(), baab->ifFalse());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1736,7 +1736,7 @@ CodeGeneratorMIPSShared::visitBitAndAndBranch(LBitAndAndBranch* lir)
|
||||
masm.ma_and(ScratchRegister, ToRegister(lir->left()), Imm32(ToInt32(lir->right())));
|
||||
else
|
||||
masm.as_and(ScratchRegister, ToRegister(lir->left()), ToRegister(lir->right()));
|
||||
emitBranch(ScratchRegister, ScratchRegister, Assembler::NonZero, lir->ifTrue(),
|
||||
emitBranch(ScratchRegister, ScratchRegister, lir->cond(), lir->ifTrue(),
|
||||
lir->ifFalse());
|
||||
}
|
||||
|
||||
|
@ -2967,9 +2967,12 @@ class LCompareVM : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
|
||||
|
||||
class LBitAndAndBranch : public LControlInstructionHelper<2, 2, 0>
|
||||
{
|
||||
Assembler::Condition cond_;
|
||||
public:
|
||||
LIR_HEADER(BitAndAndBranch)
|
||||
LBitAndAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse)
|
||||
LBitAndAndBranch(MBasicBlock* ifTrue, MBasicBlock* ifFalse,
|
||||
Assembler::Condition cond = Assembler::NonZero)
|
||||
: cond_(cond)
|
||||
{
|
||||
setSuccessor(0, ifTrue);
|
||||
setSuccessor(1, ifFalse);
|
||||
@ -2987,6 +2990,10 @@ class LBitAndAndBranch : public LControlInstructionHelper<2, 2, 0>
|
||||
const LAllocation* right() {
|
||||
return getOperand(1);
|
||||
}
|
||||
Assembler::Condition cond() const {
|
||||
MOZ_ASSERT(cond_ == Assembler::Zero || cond_ == Assembler::NonZero);
|
||||
return cond_;
|
||||
}
|
||||
};
|
||||
|
||||
// Takes a value and tests whether it is null, undefined, or is an object that
|
||||
|
@ -141,7 +141,7 @@ CodeGeneratorX86Shared::visitBitAndAndBranch(LBitAndAndBranch* baab)
|
||||
masm.test32(ToRegister(baab->left()), Imm32(ToInt32(baab->right())));
|
||||
else
|
||||
masm.test32(ToRegister(baab->left()), ToRegister(baab->right()));
|
||||
emitBranch(Assembler::NonZero, baab->ifTrue(), baab->ifFalse());
|
||||
emitBranch(baab->cond(), baab->ifTrue(), baab->ifFalse());
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user