Bug 918613 - Specialize some Maths function calls for Float32 in Ion. r=sstangl

This commit is contained in:
Benjamin Bouvier 2013-10-17 08:50:56 +02:00
Родитель f9d757d29f
Коммит 3cc09d4c0a
9 изменённых файлов: 166 добавлений и 6 удалений

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

@ -136,6 +136,88 @@ function refuseAddFunctionCall() {
}
test(refuseAddFunctionCall);
function acceptTrigo() {
var res = Math.cos(f32[0]);
f32[0] = res;
assertFloat32(res, true);
var res = Math.sin(f32[0]);
f32[0] = res;
assertFloat32(res, true);
var res = Math.tan(f32[0]);
f32[0] = res;
assertFloat32(res, true);
var res = Math.acos(f32[0]);
f32[0] = res;
assertFloat32(res, true);
var res = Math.asin(f32[0]);
f32[0] = res;
assertFloat32(res, true);
res = Math.atan(f32[0]);
f32[0] = res;
assertFloat32(res, true);
}
test(acceptTrigo);
function refuseMath() {
var res = Math.log10(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.log2(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.log1p(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.expm1(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.cosh(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.sinh(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.tanh(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.acosh(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.asinh(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.atanh(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.cbrt(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.sign(f32[0]);
f32[0] = res;
assertFloat32(res, false);
res = Math.trunc(f32[0]);
f32[0] = res;
assertFloat32(res, false);
}
test(refuseMath);
function refuseLoop() {
var res = f32[0],
n = 10;

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

@ -3841,6 +3841,34 @@ CodeGenerator::visitMathFunctionD(LMathFunctionD *ins)
return true;
}
bool
CodeGenerator::visitMathFunctionF(LMathFunctionF *ins)
{
Register temp = ToRegister(ins->temp());
FloatRegister input = ToFloatRegister(ins->input());
JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg);
masm.setupUnalignedABICall(1, temp);
masm.passABIArg(input);
void *funptr = NULL;
switch (ins->mir()->function()) {
case MMathFunction::Log: funptr = JS_FUNC_TO_DATA_PTR(void *, logf); break;
case MMathFunction::Sin: funptr = JS_FUNC_TO_DATA_PTR(void *, sinf); break;
case MMathFunction::Cos: funptr = JS_FUNC_TO_DATA_PTR(void *, cosf); break;
case MMathFunction::Exp: funptr = JS_FUNC_TO_DATA_PTR(void *, expf); break;
case MMathFunction::Tan: funptr = JS_FUNC_TO_DATA_PTR(void *, tanf); break;
case MMathFunction::ATan: funptr = JS_FUNC_TO_DATA_PTR(void *, atanf); break;
case MMathFunction::ASin: funptr = JS_FUNC_TO_DATA_PTR(void *, sinf); break;
case MMathFunction::ACos: funptr = JS_FUNC_TO_DATA_PTR(void *, acosf); break;
default:
MOZ_ASSUME_UNREACHABLE("Unknown or unsupported float32 math function");
}
masm.callWithABI(funptr, MacroAssembler::DOUBLE);
return true;
}
bool
CodeGenerator::visitModD(LModD *ins)
{

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

@ -181,6 +181,7 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitPowD(LPowD *lir);
bool visitRandom(LRandom *lir);
bool visitMathFunctionD(LMathFunctionD *ins);
bool visitMathFunctionF(LMathFunctionF *ins);
bool visitModD(LModD *ins);
bool visitMinMaxI(LMinMaxI *lir);
bool visitBinaryV(LBinaryV *lir);

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

@ -2340,6 +2340,26 @@ class LMathFunctionD : public LCallInstructionHelper<1, 1, 1>
}
};
class LMathFunctionF : public LCallInstructionHelper<1, 1, 1>
{
public:
LIR_HEADER(MathFunctionF)
LMathFunctionF(const LAllocation &input, const LDefinition &temp) {
setOperand(0, input);
setTemp(0, temp);
}
const LDefinition *temp() {
return getTemp(0);
}
MMathFunction *mir() const {
return mir_->toMathFunction();
}
const char *extraName() const {
return MMathFunction::FunctionName(mir()->function());
}
};
// Adds two integers, returning an integer value.
class LAddI : public LBinaryMath<0>
{

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

@ -104,6 +104,7 @@
_(PowD) \
_(Random) \
_(MathFunctionD) \
_(MathFunctionF) \
_(NotI) \
_(NotD) \
_(NotO) \

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

@ -1214,11 +1214,18 @@ LIRGenerator::visitRandom(MRandom *ins)
bool
LIRGenerator::visitMathFunction(MMathFunction *ins)
{
JS_ASSERT(ins->type() == MIRType_Double);
JS_ASSERT(ins->input()->type() == MIRType_Double);
JS_ASSERT(IsFloatingPointType(ins->type()));
JS_ASSERT_IF(ins->type() == MIRType_Double, ins->input()->type() == MIRType_Double);
JS_ASSERT_IF(ins->type() == MIRType_Float32, ins->input()->type() == MIRType_Float32);
// Note: useRegisterAtStart is safe here, the temp is not a FP register.
LMathFunctionD *lir = new LMathFunctionD(useRegisterAtStart(ins->input()),
if (ins->type() == MIRType_Double) {
// Note: useRegisterAtStart is safe here, the temp is not a FP register.
LMathFunctionD *lir = new LMathFunctionD(useRegisterAtStart(ins->input()),
tempFixed(CallTempReg0));
return defineReturn(lir, ins);
}
LMathFunctionF *lir = new LMathFunctionF(useRegisterAtStart(ins->input()),
tempFixed(CallTempReg0));
return defineReturn(lir, ins);
}

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

@ -1376,6 +1376,19 @@ MMod::fallible()
return !isTruncated();
}
void
MMathFunction::trySpecializeFloat32()
{
if (!input()->canProduceFloat32() || !CheckUsesAreFloat32Consumers(this)) {
if (input()->type() == MIRType_Float32)
ConvertDefinitionToDouble<0>(input(), this);
return;
}
setResultType(MIRType_Float32);
setPolicyType(MIRType_Float32);
}
bool
MAdd::fallible()
{

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

@ -3597,7 +3597,7 @@ class MRandom : public MNullaryInstruction
class MMathFunction
: public MUnaryInstruction,
public DoublePolicy<0>
public FloatingPointPolicy<0>
{
public:
enum Function {
@ -3634,6 +3634,7 @@ class MMathFunction
: MUnaryInstruction(input), function_(function), cache_(cache)
{
setResultType(MIRType_Double);
setPolicyType(MIRType_Double);
setMovable();
}
@ -3672,6 +3673,13 @@ class MMathFunction
void printOpcode(FILE *fp) const;
static const char *FunctionName(Function function);
bool isFloat32Commutative() const {
return function_ == Log || function_ == Sin || function_ == Cos
|| function_ == Exp || function_ == Tan || function_ == ATan
|| function_ == ASin || function_ == ACos;
}
void trySpecializeFloat32();
};
class MAdd : public MBinaryArithInstruction

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

@ -159,7 +159,7 @@ class Float32Policy : public BoxInputsPolicy
// Expect a float32 OR a double for operand Op, but will prioritize Float32
// if the result type is set as such. If the input is a Value, it is unboxed.
template <unsigned Op>
class RuntimePolicy : public TypePolicy
class FloatingPointPolicy : public TypePolicy
{
MIRType policyType_;