mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 843023: IonMonkey: Inline Math.pow when result is expected to be intger, r=sstangl
This commit is contained in:
parent
f489fdedf7
commit
851ff52806
@ -581,12 +581,12 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
|
|||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
|
|
||||||
// Typechecking.
|
// Typechecking.
|
||||||
if (getInlineReturnType() != MIRType_Double)
|
|
||||||
return InliningStatus_NotInlined;
|
|
||||||
|
|
||||||
MIRType baseType = getInlineArgType(callInfo, 0);
|
MIRType baseType = getInlineArgType(callInfo, 0);
|
||||||
MIRType powerType = getInlineArgType(callInfo, 1);
|
MIRType powerType = getInlineArgType(callInfo, 1);
|
||||||
|
MIRType outputType = getInlineReturnType();
|
||||||
|
|
||||||
|
if (outputType != MIRType_Int32 && outputType != MIRType_Double)
|
||||||
|
return InliningStatus_NotInlined;
|
||||||
if (baseType != MIRType_Int32 && baseType != MIRType_Double)
|
if (baseType != MIRType_Int32 && baseType != MIRType_Double)
|
||||||
return InliningStatus_NotInlined;
|
return InliningStatus_NotInlined;
|
||||||
if (powerType != MIRType_Int32 && powerType != MIRType_Double)
|
if (powerType != MIRType_Int32 && powerType != MIRType_Double)
|
||||||
@ -596,14 +596,7 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
|
|||||||
|
|
||||||
MDefinition *base = callInfo.getArg(0);
|
MDefinition *base = callInfo.getArg(0);
|
||||||
MDefinition *power = callInfo.getArg(1);
|
MDefinition *power = callInfo.getArg(1);
|
||||||
|
MDefinition *output = NULL;
|
||||||
// If the base is integer, convert it to a Double.
|
|
||||||
// Safe since the output must be a Double.
|
|
||||||
if (baseType == MIRType_Int32) {
|
|
||||||
MToDouble *conv = MToDouble::New(base);
|
|
||||||
current->add(conv);
|
|
||||||
base = conv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimize some constant powers.
|
// Optimize some constant powers.
|
||||||
if (callInfo.getArg(1)->isConstant()) {
|
if (callInfo.getArg(1)->isConstant()) {
|
||||||
@ -615,8 +608,7 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
|
|||||||
if (pow == 0.5) {
|
if (pow == 0.5) {
|
||||||
MPowHalf *half = MPowHalf::New(base);
|
MPowHalf *half = MPowHalf::New(base);
|
||||||
current->add(half);
|
current->add(half);
|
||||||
current->push(half);
|
output = half;
|
||||||
return InliningStatus_Inlined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Math.pow(x, -0.5) == 1 / Math.pow(x, 0.5), even for edge cases.
|
// Math.pow(x, -0.5) == 1 / Math.pow(x, 0.5), even for edge cases.
|
||||||
@ -627,48 +619,59 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
|
|||||||
current->add(one);
|
current->add(one);
|
||||||
MDiv *div = MDiv::New(one, half, MIRType_Double);
|
MDiv *div = MDiv::New(one, half, MIRType_Double);
|
||||||
current->add(div);
|
current->add(div);
|
||||||
current->push(div);
|
output = div;
|
||||||
return InliningStatus_Inlined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Math.pow(x, 1) == x.
|
// Math.pow(x, 1) == x.
|
||||||
if (pow == 1.0) {
|
if (pow == 1.0)
|
||||||
current->push(base);
|
output = base;
|
||||||
return InliningStatus_Inlined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Math.pow(x, 2) == x*x.
|
// Math.pow(x, 2) == x*x.
|
||||||
if (pow == 2.0) {
|
if (pow == 2.0) {
|
||||||
MMul *mul = MMul::New(base, base, MIRType_Double);
|
MMul *mul = MMul::New(base, base, outputType);
|
||||||
current->add(mul);
|
current->add(mul);
|
||||||
current->push(mul);
|
output = mul;
|
||||||
return InliningStatus_Inlined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Math.pow(x, 3) == x*x*x.
|
// Math.pow(x, 3) == x*x*x.
|
||||||
if (pow == 3.0) {
|
if (pow == 3.0) {
|
||||||
MMul *mul1 = MMul::New(base, base, MIRType_Double);
|
MMul *mul1 = MMul::New(base, base, outputType);
|
||||||
current->add(mul1);
|
current->add(mul1);
|
||||||
MMul *mul2 = MMul::New(base, mul1, MIRType_Double);
|
MMul *mul2 = MMul::New(base, mul1, outputType);
|
||||||
current->add(mul2);
|
current->add(mul2);
|
||||||
current->push(mul2);
|
output = mul2;
|
||||||
return InliningStatus_Inlined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Math.pow(x, 4) == y*y, where y = x*x.
|
// Math.pow(x, 4) == y*y, where y = x*x.
|
||||||
if (pow == 4.0) {
|
if (pow == 4.0) {
|
||||||
MMul *y = MMul::New(base, base, MIRType_Double);
|
MMul *y = MMul::New(base, base, outputType);
|
||||||
current->add(y);
|
current->add(y);
|
||||||
MMul *mul = MMul::New(y, y, MIRType_Double);
|
MMul *mul = MMul::New(y, y, outputType);
|
||||||
current->add(mul);
|
current->add(mul);
|
||||||
current->push(mul);
|
output = mul;
|
||||||
return InliningStatus_Inlined;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MPow *ins = MPow::New(base, power, powerType);
|
// Use MPow for other powers
|
||||||
current->add(ins);
|
if (!output) {
|
||||||
current->push(ins);
|
MPow *pow = MPow::New(base, power, powerType);
|
||||||
|
current->add(pow);
|
||||||
|
output = pow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast to the right type
|
||||||
|
if (outputType == MIRType_Int32 && output->type() != MIRType_Int32) {
|
||||||
|
MToInt32 *toInt = MToInt32::New(output);
|
||||||
|
current->add(toInt);
|
||||||
|
output = toInt;
|
||||||
|
}
|
||||||
|
if (outputType == MIRType_Double && output->type() != MIRType_Double) {
|
||||||
|
MToDouble *toDouble = MToDouble::New(output);
|
||||||
|
current->add(toDouble);
|
||||||
|
output = toDouble;
|
||||||
|
}
|
||||||
|
|
||||||
|
current->push(output);
|
||||||
return InliningStatus_Inlined;
|
return InliningStatus_Inlined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user