Bug 931489 - IonMonkey: Use range analysis to avoid testing for special cases in PowHalf. r=nbp

This commit is contained in:
Dan Gohman 2013-11-12 05:46:43 -08:00
Родитель 4ede47ab1e
Коммит 806aee4308
4 изменённых файлов: 52 добавлений и 12 удалений

Просмотреть файл

@ -3673,8 +3673,15 @@ class MPowHalf
: public MUnaryInstruction,
public DoublePolicy<0>
{
bool operandIsNeverNegativeInfinity_;
bool operandIsNeverNegativeZero_;
bool operandIsNeverNaN_;
MPowHalf(MDefinition *input)
: MUnaryInstruction(input)
: MUnaryInstruction(input),
operandIsNeverNegativeInfinity_(false),
operandIsNeverNegativeZero_(false),
operandIsNeverNaN_(false)
{
setResultType(MIRType_Double);
setMovable();
@ -3688,12 +3695,22 @@ class MPowHalf
bool congruentTo(MDefinition *ins) const {
return congruentIfOperandsEqual(ins);
}
bool operandIsNeverNegativeInfinity() const {
return operandIsNeverNegativeInfinity_;
}
bool operandIsNeverNegativeZero() const {
return operandIsNeverNegativeZero_;
}
bool operandIsNeverNaN() const {
return operandIsNeverNaN_;
}
TypePolicy *typePolicy() {
return this;
}
AliasSet getAliasSet() const {
return AliasSet::None();
}
void collectRangeInfo();
};
// Inline implementation of Math.random().

Просмотреть файл

@ -2424,3 +2424,13 @@ MNot::collectRangeInfo()
{
operandIsNeverNaN_ = !Range(operand()).canBeNaN();
}
void
MPowHalf::collectRangeInfo()
{
Range inputRange(input());
operandIsNeverNegativeInfinity_ = !inputRange.canBeInfiniteOrNaN() ||
inputRange.hasInt32LowerBound();
operandIsNeverNegativeZero_ = !inputRange.canBeZero();
operandIsNeverNaN_ = !inputRange.canBeNaN();
}

Просмотреть файл

@ -551,19 +551,29 @@ CodeGeneratorX86Shared::visitPowHalfD(LPowHalfD *ins)
Label done, sqrt;
// Branch if not -Infinity.
masm.loadConstantDouble(NegativeInfinity(), ScratchFloatReg);
masm.branchDouble(Assembler::DoubleNotEqualOrUnordered, input, ScratchFloatReg, &sqrt);
if (!ins->mir()->operandIsNeverNegativeInfinity()) {
// Branch if not -Infinity.
masm.loadConstantDouble(NegativeInfinity(), ScratchFloatReg);
// Math.pow(-Infinity, 0.5) == Infinity.
masm.xorpd(input, input);
masm.subsd(ScratchFloatReg, input);
masm.jump(&done);
Assembler::DoubleCondition cond = Assembler::DoubleNotEqualOrUnordered;
if (ins->mir()->operandIsNeverNaN())
cond = Assembler::DoubleNotEqual;
masm.branchDouble(cond, input, ScratchFloatReg, &sqrt);
// Math.pow(-Infinity, 0.5) == Infinity.
masm.xorpd(input, input);
masm.subsd(ScratchFloatReg, input);
masm.jump(&done);
masm.bind(&sqrt);
}
if (!ins->mir()->operandIsNeverNegativeZero()) {
// Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5). Adding 0 converts any -0 to 0.
masm.xorpd(ScratchFloatReg, ScratchFloatReg);
masm.addsd(ScratchFloatReg, input);
}
// Math.pow(-0, 0.5) == 0 == Math.pow(0, 0.5). Adding 0 converts any -0 to 0.
masm.bind(&sqrt);
masm.xorpd(ScratchFloatReg, ScratchFloatReg);
masm.addsd(ScratchFloatReg, input);
masm.sqrtsd(input, input);
masm.bind(&done);

Просмотреть файл

@ -171,6 +171,9 @@ class LPowHalfD : public LInstructionHelper<1, 1, 0>
const LDefinition *output() {
return getDef(0);
}
MPowHalf *mir() const {
return mir_->toPowHalf();
}
};
// Takes a tableswitch with an integer to decide