author | Dan Gohman <sunfish@google.com> |
Sat, 02 Nov 2013 14:29:44 -0700 | |
changeset 153267 | 3d175be0fcb0e51946459cdca3abd3917ef3c60e |
parent 153266 | e9ff16009983c0f79efa0f86f65f11f46c857e44 |
child 153268 | 238b3c81f42c11f3f0d9dd9c27d6ed7238523c2b |
push id | 35737 |
push user | sunfish@google.com |
push date | Sat, 02 Nov 2013 21:39:57 +0000 |
treeherder | mozilla-inbound@3d175be0fcb0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nbp |
bugs | 931489 |
milestone | 28.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -2013,27 +2013,35 @@ class LNotI : public LInstructionHelper< class LNotD : public LInstructionHelper<1, 1, 0> { public: LIR_HEADER(NotD) LNotD(const LAllocation &input) { setOperand(0, input); } + + MNot *mir() { + return mir_->toNot(); + } }; // Not operation on a float32. class LNotF : public LInstructionHelper<1, 1, 0> { public: LIR_HEADER(NotF) LNotF(const LAllocation &input) { setOperand(0, input); } + + MNot *mir() { + return mir_->toNot(); + } }; // Boolean complement operation on an object. class LNotO : public LInstructionHelper<1, 1, 0> { public: LIR_HEADER(NotO)
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -5154,21 +5154,23 @@ class MTypedObjectElements }; // Perform !-operation class MNot : public MUnaryInstruction, public TestPolicy { bool operandMightEmulateUndefined_; + bool operandIsNeverNaN_; public: MNot(MDefinition *input) : MUnaryInstruction(input), - operandMightEmulateUndefined_(true) + operandMightEmulateUndefined_(true), + operandIsNeverNaN_(false) { setResultType(MIRType_Boolean); setMovable(); } static MNot *New(MDefinition *elements) { return new MNot(elements); } @@ -5184,27 +5186,31 @@ class MNot MDefinition *foldsTo(bool useValueNumbers); void markOperandCantEmulateUndefined() { operandMightEmulateUndefined_ = false; } bool operandMightEmulateUndefined() const { return operandMightEmulateUndefined_; } + bool operandIsNeverNaN() const { + return operandIsNeverNaN_; + } MDefinition *operand() const { return getOperand(0); } virtual AliasSet getAliasSet() const { return AliasSet::None(); } TypePolicy *typePolicy() { return this; } + void collectRangeInfo(); void trySpecializeFloat32(); bool isFloat32Commutative() const { return true; } #ifdef DEBUG bool isConsistentFloat32Use() const { return true; } #endif
--- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -2408,8 +2408,14 @@ MBoundsCheckLower::collectRangeInfo() fallible_ = !indexRange.hasInt32LowerBound() || indexRange.lower() < minimum_; } void MCompare::collectRangeInfo() { operandsAreNeverNaN_ = !Range(lhs()).canBeNaN() && !Range(rhs()).canBeNaN(); } + +void +MNot::collectRangeInfo() +{ + operandIsNeverNaN_ = !Range(operand()).canBeNaN(); +}
--- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -229,30 +229,42 @@ CodeGeneratorX86Shared::visitNotI(LNotI return true; } bool CodeGeneratorX86Shared::visitNotD(LNotD *ins) { FloatRegister opd = ToFloatRegister(ins->input()); + // Not returns true if the input is a NaN. We don't have to worry about + // it if we know the input is never NaN though. + Assembler::NaNCond nanCond = Assembler::NaN_IsTrue; + if (ins->mir()->operandIsNeverNaN()) + nanCond = Assembler::NaN_HandledByCond; + masm.xorpd(ScratchFloatReg, ScratchFloatReg); masm.compareDouble(Assembler::DoubleEqualOrUnordered, opd, ScratchFloatReg); - masm.emitSet(Assembler::Equal, ToRegister(ins->output()), Assembler::NaN_IsTrue); + masm.emitSet(Assembler::Equal, ToRegister(ins->output()), nanCond); return true; } bool CodeGeneratorX86Shared::visitNotF(LNotF *ins) { FloatRegister opd = ToFloatRegister(ins->input()); + // Not returns true if the input is a NaN. We don't have to worry about + // it if we know the input is never NaN though. + Assembler::NaNCond nanCond = Assembler::NaN_IsTrue; + if (ins->mir()->operandIsNeverNaN()) + nanCond = Assembler::NaN_HandledByCond; + masm.xorps(ScratchFloatReg, ScratchFloatReg); masm.compareFloat(Assembler::DoubleEqualOrUnordered, opd, ScratchFloatReg); - masm.emitSet(Assembler::Equal, ToRegister(ins->output()), Assembler::NaN_IsTrue); + masm.emitSet(Assembler::Equal, ToRegister(ins->output()), nanCond); return true; } bool CodeGeneratorX86Shared::visitCompareDAndBranch(LCompareDAndBranch *comp) { FloatRegister lhs = ToFloatRegister(comp->left()); FloatRegister rhs = ToFloatRegister(comp->right());