Bug 1648820 - Part 2: Optimize Math.hypot in CacheIR. r=iain

Differential Revision: https://phabricator.services.mozilla.com/D83022
This commit is contained in:
caroline 2020-07-10 21:49:04 +00:00
Родитель 45fed54608
Коммит 1335a54165
4 изменённых файлов: 190 добавлений и 0 удалений

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

@ -5996,6 +5996,64 @@ AttachDecision CallIRGenerator::tryAttachMathPow(HandleFunction callee) {
return AttachDecision::Attach;
}
AttachDecision CallIRGenerator::tryAttachMathHypot(HandleFunction callee) {
// Only optimize if there are 2-4 arguments.
if (argc_ < 2 || argc_ > 4) {
return AttachDecision::NoAction;
}
for (size_t i = 0; i < argc_; i++) {
if (!args_[i].isNumber()) {
return AttachDecision::NoAction;
}
}
// Initialize the input operand.
Int32OperandId argcId(writer.setInputOperandId(0));
// Guard callee is the 'hypot' native function.
emitNativeCalleeGuard(callee);
ValOperandId firstId = writer.loadStandardCallArgument(0, argc_);
ValOperandId secondId = writer.loadStandardCallArgument(1, argc_);
NumberOperandId firstNumId = writer.guardIsNumber(firstId);
NumberOperandId secondNumId = writer.guardIsNumber(secondId);
ValOperandId thirdId;
ValOperandId fourthId;
NumberOperandId thirdNumId;
NumberOperandId fourthNumId;
switch (argc_) {
case 2:
writer.mathHypot2NumberResult(firstNumId, secondNumId);
break;
case 3:
thirdId = writer.loadStandardCallArgument(2, argc_);
thirdNumId = writer.guardIsNumber(thirdId);
writer.mathHypot3NumberResult(firstNumId, secondNumId, thirdNumId);
break;
case 4:
thirdId = writer.loadStandardCallArgument(2, argc_);
fourthId = writer.loadStandardCallArgument(3, argc_);
thirdNumId = writer.guardIsNumber(thirdId);
fourthNumId = writer.guardIsNumber(fourthId);
writer.mathHypot4NumberResult(firstNumId, secondNumId, thirdNumId,
fourthNumId);
break;
default:
MOZ_CRASH("Unexpected number of arguments to hypot function.");
}
// Math.hypot always returns a double so we don't need type monitoring.
writer.returnFromIC();
cacheIRStubKind_ = BaselineCacheIRStubKind::Regular;
trackAttached("MathHypot");
return AttachDecision::Attach;
}
AttachDecision CallIRGenerator::tryAttachMathATan2(HandleFunction callee) {
// Requires two numbers as arguments.
if (argc_ != 2 || !args_[0].isNumber() || !args_[1].isNumber()) {
@ -6363,6 +6421,8 @@ AttachDecision CallIRGenerator::tryAttachInlinableNative(
return tryAttachMathSqrt(callee);
case InlinableNative::MathFRound:
return tryAttachMathFRound(callee);
case InlinableNative::MathHypot:
return tryAttachMathHypot(callee);
case InlinableNative::MathATan2:
return tryAttachMathATan2(callee);
case InlinableNative::MathSin:

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

@ -1602,6 +1602,7 @@ class MOZ_RAII CallIRGenerator : public IRGenerator {
AttachDecision tryAttachMathRound(HandleFunction callee);
AttachDecision tryAttachMathSqrt(HandleFunction callee);
AttachDecision tryAttachMathFRound(HandleFunction callee);
AttachDecision tryAttachMathHypot(HandleFunction callee);
AttachDecision tryAttachMathATan2(HandleFunction callee);
AttachDecision tryAttachMathFunction(HandleFunction callee,
UnaryMathFunction fun);

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

@ -3884,6 +3884,108 @@ bool CacheIRCompiler::emitMathFRoundNumberResult(NumberOperandId inputId) {
return true;
}
bool CacheIRCompiler::emitMathHypot2NumberResult(NumberOperandId first,
NumberOperandId second) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
AutoAvailableFloatRegister floatScratch0(*this, FloatReg0);
AutoAvailableFloatRegister floatScratch1(*this, FloatReg1);
allocator.ensureDoubleRegister(masm, first, floatScratch0);
allocator.ensureDoubleRegister(masm, second, floatScratch1);
LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
masm.PushRegsInMask(save);
masm.setupUnalignedABICall(scratch);
masm.passABIArg(floatScratch0, MoveOp::DOUBLE);
masm.passABIArg(floatScratch1, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ecmaHypot), MoveOp::DOUBLE);
masm.storeCallFloatResult(floatScratch0);
LiveRegisterSet ignore;
ignore.add(floatScratch0);
masm.PopRegsInMaskIgnore(save, ignore);
masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0);
return true;
}
bool CacheIRCompiler::emitMathHypot3NumberResult(NumberOperandId first,
NumberOperandId second,
NumberOperandId third) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
AutoAvailableFloatRegister floatScratch0(*this, FloatReg0);
AutoAvailableFloatRegister floatScratch1(*this, FloatReg1);
AutoAvailableFloatRegister floatScratch2(*this, FloatReg2);
allocator.ensureDoubleRegister(masm, first, floatScratch0);
allocator.ensureDoubleRegister(masm, second, floatScratch1);
allocator.ensureDoubleRegister(masm, third, floatScratch2);
LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
masm.PushRegsInMask(save);
masm.setupUnalignedABICall(scratch);
masm.passABIArg(floatScratch0, MoveOp::DOUBLE);
masm.passABIArg(floatScratch1, MoveOp::DOUBLE);
masm.passABIArg(floatScratch2, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, hypot3), MoveOp::DOUBLE);
masm.storeCallFloatResult(floatScratch0);
LiveRegisterSet ignore;
ignore.add(floatScratch0);
masm.PopRegsInMaskIgnore(save, ignore);
masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0);
return true;
}
bool CacheIRCompiler::emitMathHypot4NumberResult(NumberOperandId first,
NumberOperandId second,
NumberOperandId third,
NumberOperandId fourth) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);
AutoOutputRegister output(*this);
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
AutoAvailableFloatRegister floatScratch0(*this, FloatReg0);
AutoAvailableFloatRegister floatScratch1(*this, FloatReg1);
AutoAvailableFloatRegister floatScratch2(*this, FloatReg2);
AutoAvailableFloatRegister floatScratch3(*this, FloatReg3);
allocator.ensureDoubleRegister(masm, first, floatScratch0);
allocator.ensureDoubleRegister(masm, second, floatScratch1);
allocator.ensureDoubleRegister(masm, third, floatScratch2);
allocator.ensureDoubleRegister(masm, fourth, floatScratch3);
LiveRegisterSet save(GeneralRegisterSet::Volatile(), liveVolatileFloatRegs());
masm.PushRegsInMask(save);
masm.setupUnalignedABICall(scratch);
masm.passABIArg(floatScratch0, MoveOp::DOUBLE);
masm.passABIArg(floatScratch1, MoveOp::DOUBLE);
masm.passABIArg(floatScratch2, MoveOp::DOUBLE);
masm.passABIArg(floatScratch3, MoveOp::DOUBLE);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, hypot4), MoveOp::DOUBLE);
masm.storeCallFloatResult(floatScratch0);
LiveRegisterSet ignore;
ignore.add(floatScratch0);
masm.PopRegsInMaskIgnore(save, ignore);
masm.boxDouble(floatScratch0, output.valueReg(), floatScratch0);
return true;
}
bool CacheIRCompiler::emitMathAtan2NumberResult(NumberOperandId yId,
NumberOperandId xId) {
JitSpew(JitSpew_Codegen, "%s", __FUNCTION__);

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

@ -920,6 +920,33 @@
args:
rng: RawPointerField
- name: MathHypot2NumberResult
shared: true
transpile: false
cost_estimate: 4
args:
first: NumberId
second: NumberId
- name: MathHypot3NumberResult
shared: true
transpile: false
cost_estimate: 4
args:
first: NumberId
second: NumberId
third: NumberId
- name: MathHypot4NumberResult
shared: true
transpile: false
cost_estimate: 4
args:
first: NumberId
second: NumberId
third: NumberId
fourth: NumberId
- name: MathAtan2NumberResult
shared: true
transpile: true