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;
|
||||
|
||||
// Typechecking.
|
||||
if (getInlineReturnType() != MIRType_Double)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
MIRType baseType = getInlineArgType(callInfo, 0);
|
||||
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)
|
||||
return InliningStatus_NotInlined;
|
||||
if (powerType != MIRType_Int32 && powerType != MIRType_Double)
|
||||
@ -596,14 +596,7 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
|
||||
|
||||
MDefinition *base = callInfo.getArg(0);
|
||||
MDefinition *power = callInfo.getArg(1);
|
||||
|
||||
// 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;
|
||||
}
|
||||
MDefinition *output = NULL;
|
||||
|
||||
// Optimize some constant powers.
|
||||
if (callInfo.getArg(1)->isConstant()) {
|
||||
@ -615,8 +608,7 @@ IonBuilder::inlineMathPow(CallInfo &callInfo)
|
||||
if (pow == 0.5) {
|
||||
MPowHalf *half = MPowHalf::New(base);
|
||||
current->add(half);
|
||||
current->push(half);
|
||||
return InliningStatus_Inlined;
|
||||
output = half;
|
||||
}
|
||||
|
||||
// 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);
|
||||
MDiv *div = MDiv::New(one, half, MIRType_Double);
|
||||
current->add(div);
|
||||
current->push(div);
|
||||
return InliningStatus_Inlined;
|
||||
output = div;
|
||||
}
|
||||
|
||||
// Math.pow(x, 1) == x.
|
||||
if (pow == 1.0) {
|
||||
current->push(base);
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
if (pow == 1.0)
|
||||
output = base;
|
||||
|
||||
// Math.pow(x, 2) == x*x.
|
||||
if (pow == 2.0) {
|
||||
MMul *mul = MMul::New(base, base, MIRType_Double);
|
||||
MMul *mul = MMul::New(base, base, outputType);
|
||||
current->add(mul);
|
||||
current->push(mul);
|
||||
return InliningStatus_Inlined;
|
||||
output = mul;
|
||||
}
|
||||
|
||||
// Math.pow(x, 3) == x*x*x.
|
||||
if (pow == 3.0) {
|
||||
MMul *mul1 = MMul::New(base, base, MIRType_Double);
|
||||
MMul *mul1 = MMul::New(base, base, outputType);
|
||||
current->add(mul1);
|
||||
MMul *mul2 = MMul::New(base, mul1, MIRType_Double);
|
||||
MMul *mul2 = MMul::New(base, mul1, outputType);
|
||||
current->add(mul2);
|
||||
current->push(mul2);
|
||||
return InliningStatus_Inlined;
|
||||
output = mul2;
|
||||
}
|
||||
|
||||
// Math.pow(x, 4) == y*y, where y = x*x.
|
||||
if (pow == 4.0) {
|
||||
MMul *y = MMul::New(base, base, MIRType_Double);
|
||||
MMul *y = MMul::New(base, base, outputType);
|
||||
current->add(y);
|
||||
MMul *mul = MMul::New(y, y, MIRType_Double);
|
||||
MMul *mul = MMul::New(y, y, outputType);
|
||||
current->add(mul);
|
||||
current->push(mul);
|
||||
return InliningStatus_Inlined;
|
||||
output = mul;
|
||||
}
|
||||
}
|
||||
|
||||
MPow *ins = MPow::New(base, power, powerType);
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
// Use MPow for other powers
|
||||
if (!output) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user