зеркало из https://github.com/mozilla/gecko-dev.git
Bug 918613 - Specialize some Maths function calls for Float32 in Ion. r=sstangl
This commit is contained in:
Родитель
f9d757d29f
Коммит
3cc09d4c0a
|
@ -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,13 +1214,20 @@ 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Try to mark an add or sub instruction as able to recover its input when
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче