Bug 999764 - Optimize floating-point division into multiplication when safe; r=sunfish

This commit is contained in:
Sankha Narayan Guria 2014-07-09 11:37:14 +02:00
parent e68b639905
commit c570a9da37

View File

@ -7,6 +7,7 @@
#include "jit/MIR.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/MathAlgorithms.h"
#include <ctype.h>
@ -134,6 +135,38 @@ EvaluateConstantOperands(TempAllocator &alloc, MBinaryInstruction *ins, bool *pt
return MConstant::New(alloc, ret);
}
static MMul *
EvaluateExactReciprocal(TempAllocator &alloc, MDiv *ins)
{
// we should fold only when it is a floating point operation
if (!IsFloatingPointType(ins->type()))
return nullptr;
MDefinition *left = ins->getOperand(0);
MDefinition *right = ins->getOperand(1);
if (!right->isConstant())
return nullptr;
Value rhs = right->toConstant()->value();
int32_t num;
if (!mozilla::NumberIsInt32(rhs.toNumber(), &num))
return nullptr;
// check if rhs is a power of two
if (mozilla::Abs(num) & (mozilla::Abs(num) - 1))
return nullptr;
Value ret;
ret.setDouble(1.0 / (double) num);
MConstant *foldedRhs = MConstant::New(alloc, ret);
foldedRhs->setResultType(ins->type());
ins->block()->insertBefore(ins, foldedRhs);
return MMul::New(alloc, left, foldedRhs, ins->type());
}
void
MDefinition::printName(FILE *fp) const
{
@ -1505,6 +1538,9 @@ MDiv::foldsTo(TempAllocator &alloc)
if (MDefinition *folded = EvaluateConstantOperands(alloc, this))
return folded;
if (MDefinition *folded = EvaluateExactReciprocal(alloc, this))
return folded;
return this;
}