author | Noemi Erli <nerli@mozilla.com> |
Tue, 09 Jun 2020 22:39:08 +0300 | |
changeset 598836 | b2df79a80c0303df9d710800ae37dce56847eef5 |
parent 598835 | e8d01bb9df0e3ccdb1c881aae5529ef86c6a230c |
child 598837 | 5a00363d2a4aac7cf407225adcdb8268839b7885 |
push id | 13310 |
push user | ffxbld-merge |
push date | Mon, 29 Jun 2020 14:50:06 +0000 |
treeherder | mozilla-beta@15a59a0afa5c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1564942 |
milestone | 79.0a1 |
backs out | ed869f61d92437944115e25abe6deecd2d4ce07a cee3bb0132911d6944471973719c9eb2af52c397 91d3f5dc57c9b174d75be3a2ceab99ee1567fbb5 0017d61a5a0f1299d4c1f421f73ab7315650f93e |
first release with | nightly linux32
b2df79a80c03
/
79.0a1
/
20200610043607
/
files
nightly linux64
b2df79a80c03
/
79.0a1
/
20200610043607
/
files
nightly mac
b2df79a80c03
/
79.0a1
/
20200610043607
/
files
nightly win32
b2df79a80c03
/
79.0a1
/
20200610043607
/
files
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
79.0a1
/
20200610043607
/
pushlog to previous
nightly linux64
79.0a1
/
20200610043607
/
pushlog to previous
nightly mac
79.0a1
/
20200610043607
/
pushlog to previous
nightly win32
79.0a1
/
20200610043607
/
pushlog to previous
|
deleted file mode 100644 --- a/js/src/jit-test/tests/ion/pow-base-power-of-two-bailouts.js +++ /dev/null @@ -1,85 +0,0 @@ -// Lowering provides a specialisation when the base operand is a constant which -// is a power of two. -// -// Test bailout conditions for this optimisation. - -function test(x) { - function pow(x, y) { return `Math.pow(${x}, ${y})` }; - function exp(x, y) { return `((${x}) ** ${y})` }; - - function make(fn) { - return Function("y, z", ` - // Load from array to prevent constant-folding. - // (Ion is currently not smart enough to realise that both array - // values are the same.) - var ys = [y, y]; - var zs = [z, z]; - for (var i = 0; i < 1000; ++i) { - assertEq(${fn(x, "ys[i & 1]")}, zs[i & 1]); - } - `); - } - - function double(v) { - // NB: Math.cbrt() always returns a double value. - return Math.cbrt(v * v * v) - } - - // Find the first power which will exceed the Int32 range by computing ⌈log_x(2 ^ 31)⌉. - var limit = Math.ceil(Math.log2(2 ** 31) / Math.log2(x)); - assertEq(Math.pow(x, limit - 1) < 2 ** 31, true); - assertEq(Math.pow(x, limit) >= 2 ** 31, true); - - function* args(first, last) { - // Run the test function a few times without a bailout. - for (var i = 0; i < 3; ++i) { - yield first; - } - - // |last| should trigger a bailout. - yield last; - } - - // Test precision loss when the result exceeds 2**31. - for (var fn of [make(pow), make(exp)]) { - for (var y of args(limit - 1, limit)) { - // Ensure the callee always sees a double to avoid an early Bailout_ArgumentCheck. - var z = double(Math.pow(x, y)); - fn(y, z); - } - } - - // Test precision loss when the result is a fractional number. - for (var fn of [make(pow), make(exp)]) { - for (var y of args(0, -1)) { - // Ensure the callee always sees a double to avoid an early Bailout_ArgumentCheck. - var z = double(Math.pow(x, y)); - fn(y, z); - } - } - - // Find the first negative power which can be represented as a double - var negLimit = -Math.floor(1074 / Math.log2(x)); - - // Test precision loss when the result is a non-zero, fractional number. - for (var fn of [make(pow), make(exp)]) { - for (var y of args(limit - 1, limit)) { - // Ensure the callee always sees a double to avoid an early Bailout_ArgumentCheck. - var z = double(Math.pow(x, y)); - fn(y, z); - } - } -} - -function* range(a, b, fn) { - for (var i = a; i <= b; ++i) { - yield fn(i); - } -} - -// Only 2^i with |i| ∈ {1..8} currently triggers the optimisation, but also test -// the next power-of-two values. - -for (var x of range(1, 10, i => 2 ** i)) { - test(x); -}
deleted file mode 100644 --- a/js/src/jit-test/tests/ion/pow-base-power-of-two.js +++ /dev/null @@ -1,73 +0,0 @@ -// Lowering provides a specialisation when the base operand is a constant which -// is a power of two. - -function test(x, y, z) { - function pow(x, y) { return `Math.pow(${x}, ${y})` }; - function exp(x, y) { return `((${x}) ** ${y})` }; - - function make(fn, x, y, z) { - return Function(` - // Load from array to prevent constant-folding. - // (Ion is currently not smart enough to realise that both array - // values are the same.) - var ys = [${y}, ${y}]; - var zs = [${z}, ${z}]; - for (var i = 0; i < 1000; ++i) { - assertEq(${fn(x, "ys[i & 1]")}, zs[i & 1]); - } - `); - } - - function double(v) { - // NB: Math.cbrt() always returns a double value. - return `Math.cbrt(${v * v * v})`; - } - - function addTests(fn) { - tests.push(make(fn, x, y, z)); - tests.push(make(fn, x, double(y), z)); - tests.push(make(fn, double(x), y, z)); - tests.push(make(fn, double(x), double(y), z)); - } - - var tests = []; - addTests(pow); - addTests(exp); - - for (var i = 0; i < tests.length; ++i) { - for (var j = 0; j < 2; ++j) { - tests[i](); - } - } -} - -function* range(a, b, fn) { - for (var i = a; i <= b; ++i) { - yield fn(i); - } -} - -// Only 2^i with |i| ∈ {1..8} currently triggers the optimisation, but also test -// the next power-of-two values, 1 and 0, and negative base-of-two values. -var values = [ - ...range(1, 10, i => 2 ** i), - 1, - 0, - ...range(1, 4, i => -(2 ** i)), -]; - -for (var x of values) { - test(x, 0, 1); - test(x, 1, x); - test(x, 2, x * x); - - // 0**(negative) is Infinity, 1**(negative) is 1. - if (Math.abs(x) > 1) { - test(x, -1076, 0); - } - - // (negative)**(odd-negative) is -0. - if (x > 1) { - test(x, -1075, 0); - } -}
deleted file mode 100644 --- a/js/src/jit-test/tests/ion/pow-constant-power.js +++ /dev/null @@ -1,68 +0,0 @@ -// Ion provides specialisations when Math.pow() resp. the **-operator is used -// with a constant power of one of [-0.5, 0.5, 1, 2, 3, 4]. - -function test(x, y, z) { - function pow(x, y) { return `Math.pow(${x}, ${y})` }; - function exp(x, y) { return `((${x}) ** ${y})` }; - - function make(fn, x, y, z) { - return Function(` - // Load from array to prevent constant-folding. - // (Ion is currently not smart enough to realise that both array - // values are the same.) - var xs = [${x}, ${x}]; - var zs = [${z}, ${z}]; - for (var i = 0; i < 1000; ++i) { - assertEq(${fn("xs[i & 1]", y)}, zs[i & 1]); - } - `); - } - - function double(v) { - // NB: Math.cbrt() always returns a double value. - return `Math.cbrt(${v * v * v})`; - } - - function addTests(fn) { - tests.push(make(fn, x, y, z)); - tests.push(make(fn, x, double(y), z)); - tests.push(make(fn, double(x), y, z)); - tests.push(make(fn, double(x), double(y), z)); - } - - var tests = []; - addTests(pow); - addTests(exp); - - for (var i = 0; i < tests.length; ++i) { - for (var j = 0; j < 2; ++j) { - tests[i](); - } - } -} - -// Make sure the tests below test int32 and double return values. - -// Math.pow(x, -0.5) -test( 1, -0.5, 1); -test(16, -0.5, 0.25); - -// Math.pow(x, 0.5) -test(16, 0.5, 4); -test( 2, 0.5, Math.SQRT2); - -// Math.pow(x, 1) -test(5, 1, 5); -test(0.5, 1, 0.5); - -// Math.pow(x, 2) -test(5, 2, 25); -test(0.5, 2, 0.25); - -// Math.pow(x, 3) -test(5, 3, 125); -test(0.5, 3, 0.125); - -// Math.pow(x, 3) -test(5, 4, 625); -test(0.5, 4, 0.0625);
--- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8260,49 +8260,16 @@ void CodeGenerator::visitPowD(LPowD* ins masm.setupUnalignedABICall(temp); masm.passABIArg(value, MoveOp::DOUBLE); masm.passABIArg(power, MoveOp::DOUBLE); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ecmaPow), MoveOp::DOUBLE); MOZ_ASSERT(ToFloatRegister(ins->output()) == ReturnDoubleReg); } -void CodeGenerator::visitPowOfTwoI(LPowOfTwoI* ins) { - Register power = ToRegister(ins->power()); - Register output = ToRegister(ins->output()); - - uint32_t base = ins->base(); - MOZ_ASSERT(mozilla::IsPowerOfTwo(base)); - - uint32_t n = mozilla::FloorLog2(base); - MOZ_ASSERT(n != 0); - - // Hacker's Delight, 2nd edition, theorem D2. - auto ceilingDiv = [](uint32_t x, uint32_t y) { return (x + y - 1) / y; }; - - // Take bailout if |power| is greater-or-equals |log_y(2^31)| or is negative. - // |2^(n*y) < 2^31| must hold, hence |n*y < 31| resp. |y < 31/n|. - // - // Note: it's important for this condition to match the code in CacheIR.cpp - // (CanAttachInt32Pow) to prevent failure loops. - bailoutCmp32(Assembler::AboveOrEqual, power, Imm32(ceilingDiv(31, n)), - ins->snapshot()); - - // Compute (2^n)^y as 2^(n*y) using repeated shifts. We could directly scale - // |power| and perform a single shift, but due to the lack of necessary - // MacroAssembler functionality, like multiplying a register with an - // immediate, we restrict the number of generated shift instructions when - // lowering this operation. - masm.move32(Imm32(1), output); - do { - masm.lshift32(power, output); - n--; - } while (n > 0); -} - void CodeGenerator::visitSqrtD(LSqrtD* ins) { FloatRegister input = ToFloatRegister(ins->input()); FloatRegister output = ToFloatRegister(ins->output()); masm.sqrtDouble(input, output); } void CodeGenerator::visitSqrtF(LSqrtF* ins) { FloatRegister input = ToFloatRegister(ins->input());
--- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -3607,17 +3607,16 @@ AbortReasonOr<Ok> IonBuilder::powTrySpec MPow* pow = MPow::New(alloc(), base, power, MIRType::Double); current->add(pow); output = pow; // Cast to the right type if (outputType == MIRType::Int32 && output->type() != MIRType::Int32) { auto* toInt = MToNumberInt32::New(alloc(), output); - toInt->setCanBeNegativeZero(pow->canBeNegativeZero()); current->add(toInt); output = toInt; } if (outputType == MIRType::Double && output->type() != MIRType::Double) { MToDouble* toDouble = MToDouble::New(alloc(), output); current->add(toDouble); output = toDouble; }
--- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3,17 +3,16 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "jit/Lowering.h" #include "mozilla/DebugOnly.h" #include "mozilla/EndianUtils.h" -#include "mozilla/MathAlgorithms.h" #include <type_traits> #include "jit/JitSpewer.h" #include "jit/LIR.h" #include "jit/MIR.h" #include "jit/MIRGraph.h" #include "util/Memory.h" @@ -1528,26 +1527,16 @@ void LIRGenerator::visitHypot(MHypot* in void LIRGenerator::visitPow(MPow* ins) { MDefinition* input = ins->input(); MDefinition* power = ins->power(); if (ins->type() == MIRType::Int32) { MOZ_ASSERT(input->type() == MIRType::Int32); MOZ_ASSERT(power->type() == MIRType::Int32); - if (input->isConstant()) { - // Restrict this optimization to |base <= 256| to avoid generating too - // many consecutive shift instructions. - int32_t base = input->toConstant()->toInt32(); - if (2 <= base && base <= 256 && mozilla::IsPowerOfTwo(uint32_t(base))) { - lowerPowOfTwoI(ins); - return; - } - } - auto* lir = new (alloc()) LPowII(useRegister(input), useRegister(power), temp(), temp()); assignSnapshot(lir, Bailout_PrecisionLoss); define(lir, ins); return; } MOZ_ASSERT(ins->type() == MIRType::Double);
--- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2989,16 +2989,17 @@ MDefinition* MPow::foldsConstantPower(Te } if (!power()->toConstant()->isTypeRepresentableAsDouble()) { return nullptr; } MOZ_ASSERT(type() == MIRType::Double || type() == MIRType::Int32); double pow = power()->toConstant()->numberToDouble(); + MIRType outputType = type(); // Math.pow(x, 0.5) is a sqrt with edge-case detection. if (pow == 0.5) { MOZ_ASSERT(type() == MIRType::Double); return MPowHalf::New(alloc, input()); } // Math.pow(x, -0.5) == 1 / Math.pow(x, 0.5), even for edge cases. @@ -3011,54 +3012,42 @@ MDefinition* MPow::foldsConstantPower(Te return MDiv::New(alloc, one, half, MIRType::Double); } // Math.pow(x, 1) == x. if (pow == 1.0) { return input(); } - auto multiply = [this, &alloc](MDefinition* lhs, MDefinition* rhs) { - MMul* mul = MMul::New(alloc, lhs, rhs, type()); - - // Multiplying the same number can't yield negative zero. - mul->setCanBeNegativeZero(lhs != rhs && canBeNegativeZero()); - return mul; - }; - // Math.pow(x, 2) == x*x. if (pow == 2.0) { - return multiply(input(), input()); + return MMul::New(alloc, input(), input(), outputType); } // Math.pow(x, 3) == x*x*x. if (pow == 3.0) { - MMul* mul1 = multiply(input(), input()); + MMul* mul1 = MMul::New(alloc, input(), input(), outputType); block()->insertBefore(this, mul1); - return multiply(input(), mul1); + return MMul::New(alloc, input(), mul1, outputType); } // Math.pow(x, 4) == y*y, where y = x*x. if (pow == 4.0) { - MMul* y = multiply(input(), input()); + MMul* y = MMul::New(alloc, input(), input(), outputType); block()->insertBefore(this, y); - return multiply(y, y); + return MMul::New(alloc, y, y, outputType); } // No optimization return nullptr; } MDefinition* MPow::foldsTo(TempAllocator& alloc) { - if (MDefinition* def = foldsConstant(alloc)) { - return def; - } - if (MDefinition* def = foldsConstantPower(alloc)) { - return def; - } + if (MDefinition* def = foldsConstant(alloc)) return def; + if (MDefinition* def = foldsConstantPower(alloc)) return def; return this; } bool MAbs::fallible() const { return !implicitTruncate_ && (!range() || !range()->hasInt32Bounds()); } void MAbs::trySpecializeFloat32(TempAllocator& alloc) {
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -5169,47 +5169,29 @@ class MHypot : public MVariadicInstructi MInstruction* clone(TempAllocator& alloc, const MDefinitionVector& inputs) const override { return MHypot::New(alloc, inputs); } }; // Inline implementation of Math.pow(). -// -// Supports the following three specializations: -// -// 1. MPow(FloatingPoint, FloatingPoint) -> Double -// - The most general mode, calls js::ecmaPow. -// - Never performs a bailout. -// 2. MPow(FloatingPoint, Int32) -> Double -// - Optimization to call js::powi instead of js::ecmaPow. -// - Never performs a bailout. -// 3. MPow(Int32, Int32) -> Int32 -// - Performs the complete exponentiation operation in assembly code. -// - Bails out if the result doesn't fit in Int32. class MPow : public MBinaryInstruction, public PowPolicy::Data { // If true, convert the power operand to int32 instead of double (this only // affects the Double specialization). This exists because we can sometimes // get more precise types during MIR building than in type analysis. - bool powerIsInt32_ : 1; - - // If true, the result is guaranteed to never be negative zero. - bool canBeNegativeZero_ : 1; + bool powerIsInt32_; MPow(MDefinition* input, MDefinition* power, MIRType specialization) : MBinaryInstruction(classOpcode, input, power), powerIsInt32_(power->type() == MIRType::Int32) { MOZ_ASSERT(specialization == MIRType::Int32 || specialization == MIRType::Double); setResultType(specialization); setMovable(); - - // The result can't be negative zero if the base is an Int32 value. - canBeNegativeZero_ = input->type() != MIRType::Int32; } // Helpers for `foldsTo` MDefinition* foldsConstant(TempAllocator& alloc); MDefinition* foldsConstantPower(TempAllocator& alloc); public: INSTRUCTION_HEADER(Pow) @@ -5225,17 +5207,16 @@ class MPow : public MBinaryInstruction, } return congruentIfOperandsEqual(ins); } AliasSet getAliasSet() const override { return AliasSet::None(); } bool possiblyCalls() const override { return type() != MIRType::Int32; } MOZ_MUST_USE bool writeRecoverData( CompactBufferWriter& writer) const override; bool canRecoverOnBailout() const override { return true; } - bool canBeNegativeZero() const { return canBeNegativeZero_; } MDefinition* foldsTo(TempAllocator& alloc) override; ALLOW_CLONE(MPow) }; // Inline implementation of Math.pow(x, 0.5), which subtly differs from // Math.sqrt(x).
--- a/js/src/jit/arm/Lowering-arm.cpp +++ b/js/src/jit/arm/Lowering-arm.cpp @@ -466,25 +466,16 @@ void LIRGeneratorARM::lowerUrshD(MUrsh* MOZ_ASSERT(lhs->type() == MIRType::Int32); MOZ_ASSERT(rhs->type() == MIRType::Int32); LUrshD* lir = new (alloc()) LUrshD(useRegister(lhs), useRegisterOrConstant(rhs), temp()); define(lir, mir); } -void LIRGeneratorARM::lowerPowOfTwoI(MPow* mir) { - int32_t base = mir->input()->toConstant()->toInt32(); - MDefinition* power = mir->power(); - - auto* lir = new (alloc()) LPowOfTwoI(base, useRegister(power)); - assignSnapshot(lir, Bailout_PrecisionLoss); - define(lir, mir); -} - void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { if (ins->type() == MIRType::Int32) { define(new (alloc()) LNegI(useRegisterAtStart(ins->input())), ins); } else if (ins->type() == MIRType::Float32) { define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); } else { MOZ_ASSERT(ins->type() == MIRType::Double); define(new (alloc()) LNegD(useRegisterAtStart(ins->input())), ins);
--- a/js/src/jit/arm/Lowering-arm.h +++ b/js/src/jit/arm/Lowering-arm.h @@ -37,18 +37,16 @@ class LIRGeneratorARM : public LIRGenera void lowerInt64PhiInput(MPhi* phi, uint32_t inputPosition, LBlock* block, size_t lirIndex); void defineInt64Phi(MPhi* phi, size_t lirIndex); void lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); void lowerUrshD(MUrsh* mir); - void lowerPowOfTwoI(MPow* mir); - void lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input); void lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); void lowerForALUInt64( LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs);
--- a/js/src/jit/arm64/Lowering-arm64.cpp +++ b/js/src/jit/arm64/Lowering-arm64.cpp @@ -309,25 +309,16 @@ void LIRGeneratorARM64::lowerUrshD(MUrsh MOZ_ASSERT(lhs->type() == MIRType::Int32); MOZ_ASSERT(rhs->type() == MIRType::Int32); LUrshD* lir = new (alloc()) LUrshD(useRegister(lhs), useRegisterOrConstant(rhs), temp()); define(lir, mir); } -void LIRGeneratorARM64::lowerPowOfTwoI(MPow* mir) { - int32_t base = mir->input()->toConstant()->toInt32(); - MDefinition* power = mir->power(); - - auto* lir = new (alloc()) LPowOfTwoI(base, useRegister(power)); - assignSnapshot(lir, Bailout_PrecisionLoss); - define(lir, mir); -} - void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { switch (ins->type()) { case MIRType::Int32: define(new (alloc()) LNegI(useRegisterAtStart(ins->input())), ins); break; case MIRType::Float32: define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); break;
--- a/js/src/jit/arm64/Lowering-arm64.h +++ b/js/src/jit/arm64/Lowering-arm64.h @@ -39,18 +39,16 @@ class LIRGeneratorARM64 : public LIRGene void lowerInt64PhiInput(MPhi*, uint32_t, LBlock*, size_t) { MOZ_CRASH("NYI"); } void defineInt64Phi(MPhi*, size_t) { MOZ_CRASH("NYI"); } void lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); void lowerUrshD(MUrsh* mir); - void lowerPowOfTwoI(MPow* mir); - void lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input); void lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); void lowerForALUInt64( LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs);
--- a/js/src/jit/mips-shared/Lowering-mips-shared.cpp +++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp @@ -297,25 +297,16 @@ void LIRGeneratorMIPSShared::lowerUrshD( MOZ_ASSERT(lhs->type() == MIRType::Int32); MOZ_ASSERT(rhs->type() == MIRType::Int32); LUrshD* lir = new (alloc()) LUrshD(useRegister(lhs), useRegisterOrConstant(rhs), temp()); define(lir, mir); } -void LIRGeneratorMIPSShared::lowerPowOfTwoI(MPow* mir) { - int32_t base = mir->input()->toConstant()->toInt32(); - MDefinition* power = mir->power(); - - auto* lir = new (alloc()) LPowOfTwoI(base, useRegister(power)); - assignSnapshot(lir, Bailout_PrecisionLoss); - define(lir, mir); -} - void LIRGenerator::visitWasmNeg(MWasmNeg* ins) { if (ins->type() == MIRType::Int32) { define(new (alloc()) LNegI(useRegisterAtStart(ins->input())), ins); } else if (ins->type() == MIRType::Float32) { define(new (alloc()) LNegF(useRegisterAtStart(ins->input())), ins); } else { MOZ_ASSERT(ins->type() == MIRType::Double); define(new (alloc()) LNegD(useRegisterAtStart(ins->input())), ins);
--- a/js/src/jit/mips-shared/Lowering-mips-shared.h +++ b/js/src/jit/mips-shared/Lowering-mips-shared.h @@ -25,18 +25,16 @@ class LIRGeneratorMIPSShared : public LI LDefinition tempByteOpRegister(); bool needTempForPostBarrier() { return false; } void lowerForShift(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); void lowerUrshD(MUrsh* mir); - void lowerPowOfTwoI(MPow* mir); - void lowerForALU(LInstructionHelper<1, 1, 0>* ins, MDefinition* mir, MDefinition* input); void lowerForALU(LInstructionHelper<1, 2, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs); void lowerForALUInt64( LInstructionHelper<INT64_PIECES, 2 * INT64_PIECES, 0>* ins, MDefinition* mir, MDefinition* lhs, MDefinition* rhs);
--- a/js/src/jit/none/Lowering-none.h +++ b/js/src/jit/none/Lowering-none.h @@ -35,17 +35,16 @@ class LIRGeneratorNone : public LIRGener void lowerUntypedPhiInput(MPhi*, uint32_t, LBlock*, size_t) { MOZ_CRASH(); } void lowerInt64PhiInput(MPhi*, uint32_t, LBlock*, size_t) { MOZ_CRASH(); } void defineInt64Phi(MPhi*, size_t) { MOZ_CRASH(); } void lowerForShift(LInstructionHelper<1, 2, 0>*, MDefinition*, MDefinition*, MDefinition*) { MOZ_CRASH(); } void lowerUrshD(MUrsh*) { MOZ_CRASH(); } - void lowerPowOfTwoI(MPow*) { MOZ_CRASH(); } template <typename T> void lowerForALU(T, MDefinition*, MDefinition*, MDefinition* v = nullptr) { MOZ_CRASH(); } template <typename T> void lowerForFPU(T, MDefinition*, MDefinition*, MDefinition* v = nullptr) { MOZ_CRASH(); }
--- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -2516,31 +2516,16 @@ class LPowD : public LCallInstructionHel setTemp(0, temp); } const LAllocation* value() { return getOperand(0); } const LAllocation* power() { return getOperand(1); } const LDefinition* temp() { return getTemp(0); } }; -// Constant of a power of two raised to an integer power. -class LPowOfTwoI : public LInstructionHelper<1, 1, 0> { - uint32_t base_; - - public: - LIR_HEADER(PowOfTwoI) - LPowOfTwoI(uint32_t base, const LAllocation& power) - : LInstructionHelper(classOpcode), base_(base) { - setOperand(0, power); - } - - uint32_t base() const { return base_; } - const LAllocation* power() { return getOperand(0); } -}; - // Sign value of an integer. class LSignI : public LInstructionHelper<1, 1, 0> { public: LIR_HEADER(SignI) explicit LSignI(const LAllocation& input) : LInstructionHelper(classOpcode) { setOperand(0, input); } };
--- a/js/src/jit/x86-shared/Lowering-x86-shared.cpp +++ b/js/src/jit/x86-shared/Lowering-x86-shared.cpp @@ -145,19 +145,18 @@ void LIRGeneratorX86Shared::lowerForBitA baab->setOperand(1, useRegisterOrConstantAtStart(rhs)); add(baab, mir); } void LIRGeneratorX86Shared::lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs) { // Note: If we need a negative zero check, lhs is used twice. LAllocation lhsCopy = mul->canBeNegativeZero() ? use(lhs) : LAllocation(); - LMulI* lir = new (alloc()) LMulI( - useRegisterAtStart(lhs), - lhs != rhs ? useOrConstant(rhs) : useOrConstantAtStart(rhs), lhsCopy); + LMulI* lir = + new (alloc()) LMulI(useRegisterAtStart(lhs), useOrConstant(rhs), lhsCopy); if (mul->fallible()) { assignSnapshot(lir, Bailout_DoubleOutput); } defineReuseInput(lir, mul, 0); } void LIRGeneratorX86Shared::lowerDivI(MDiv* div) { if (div->isUnsigned()) { @@ -434,27 +433,16 @@ void LIRGeneratorX86Shared::lowerUrshD(M LUse lhsUse = useRegisterAtStart(lhs); LAllocation rhsAlloc = rhs->isConstant() ? useOrConstant(rhs) : useFixed(rhs, ecx); LUrshD* lir = new (alloc()) LUrshD(lhsUse, rhsAlloc, tempCopy(lhs, 0)); define(lir, mir); } -void LIRGeneratorX86Shared::lowerPowOfTwoI(MPow* mir) { - int32_t base = mir->input()->toConstant()->toInt32(); - MDefinition* power = mir->power(); - - // shift operator should be in register ecx; - // x86 can't shift a non-ecx register. - auto* lir = new (alloc()) LPowOfTwoI(base, useFixed(power, ecx)); - assignSnapshot(lir, Bailout_PrecisionLoss); - define(lir, mir); -} - void LIRGeneratorX86Shared::lowerTruncateDToInt32(MTruncateToInt32* ins) { MDefinition* opd = ins->input(); MOZ_ASSERT(opd->type() == MIRType::Double); LDefinition maybeTemp = Assembler::HasSSE3() ? LDefinition::BogusTemp() : tempDouble(); define(new (alloc()) LTruncateDToInt32(useRegister(opd), maybeTemp), ins); }
--- a/js/src/jit/x86-shared/Lowering-x86-shared.h +++ b/js/src/jit/x86-shared/Lowering-x86-shared.h @@ -40,17 +40,16 @@ class LIRGeneratorX86Shared : public LIR void lowerForBitAndAndBranch(LBitAndAndBranch* baab, MInstruction* mir, MDefinition* lhs, MDefinition* rhs); void lowerMulI(MMul* mul, MDefinition* lhs, MDefinition* rhs); void lowerDivI(MDiv* div); void lowerModI(MMod* mod); void lowerUDiv(MDiv* div); void lowerUMod(MMod* mod); void lowerUrshD(MUrsh* mir); - void lowerPowOfTwoI(MPow* mir); void lowerTruncateDToInt32(MTruncateToInt32* ins); void lowerTruncateFToInt32(MTruncateToInt32* ins); void lowerCompareExchangeTypedArrayElement( MCompareExchangeTypedArrayElement* ins, bool useI386ByteRegisters); void lowerAtomicExchangeTypedArrayElement( MAtomicExchangeTypedArrayElement* ins, bool useI386ByteRegisters); void lowerAtomicTypedArrayElementBinop(MAtomicTypedArrayElementBinop* ins, bool useI386ByteRegisters);