Ignore:
Timestamp:
May 7, 2015, 5:23:32 PM (10 years ago)
Author:
[email protected]
Message:

[JSC] Add basic DFG/FTL support for Math.round
https://bugs.webkit.org/show_bug.cgi?id=144725

Patch by Benjamin Poulain <[email protected]> on 2015-05-07
Reviewed by Filip Pizlo.

This patch adds two optimizations targeting Math.round():
-Add a DFGNode ArithRound corresponding to the intrinsic RoundIntrinsic.
-Change the MacroAssembler to be stricter on how we fail to convert a double

to ingeter. Previously, any number valued zero would fail, now we only
fail for -0.

Since ArithRound speculate it produces int32, the MacroAssembler assembler
part became necessary because zero is a pretty common output of Math.round()
and we would OSR exit a lot (and eventually recompile for doubles).

The implementation itself of the inline Math.round() is exactly the same
as the C function that exists for Math.round(). We can very likely do better
but it is a good start known to be valid and inlining alone alread provides
significant speedups.

  • assembler/X86Assembler.h:

(JSC::X86Assembler::movmskpd_rr):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):
When we have a zero, get the sign bit out of the double and check if is one.

I'll look into doing the same improvement for ARM.

  • bytecode/SpeculatedType.cpp:

(JSC::typeOfDoubleRounding):
(JSC::typeOfDoubleFRound): Deleted.

  • bytecode/SpeculatedType.h:
  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsic):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::roundShouldSpeculateInt32):
(JSC::DFG::Graph::negateShouldSpeculateMachineInt): Deleted.

  • dfg/DFGNode.h:

(JSC::DFG::Node::arithNodeFlags):
(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::hasArithMode):

  • dfg/DFGNodeType.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithRound):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLIntrinsicRepository.h:
  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::convertDoubleToInt32):
(JSC::FTL::LowerDFGToLLVM::compileDoubleAsInt32):
(JSC::FTL::LowerDFGToLLVM::compileArithRound):

  • ftl/FTLOutput.h:

(JSC::FTL::Output::ceil64):

  • jit/ThunkGenerators.cpp:
  • runtime/MathCommon.cpp:
  • runtime/MathCommon.h:
  • runtime/MathObject.cpp:

(JSC::mathProtoFuncRound):

  • tests/stress/math-round-basics.js: Added.

(mathRoundOnIntegers):
(mathRoundOnDoubles):
(mathRoundOnBooleans):
(uselessMathRound):
(mathRoundWithOverflow):
(mathRoundConsumedAsDouble):
(mathRoundDoesNotCareAboutMinusZero):
(mathRoundNoArguments):
(mathRoundTooManyArguments):
(testMathRoundOnConstants):
(mathRoundStructTransition):
(Math.round):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r183358 r183963  
    922922
    923923        // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
     924#if CPU(X86_64)
     925        if (negZeroCheck) {
     926            Jump valueIsNonZero = branchTest32(NonZero, dest);
     927            m_assembler.movmskpd_rr(src, scratchRegister);
     928            failureCases.append(branchTest32(NonZero, scratchRegister, TrustedImm32(1)));
     929            valueIsNonZero.link(this);
     930        }
     931#else
    924932        if (negZeroCheck)
    925933            failureCases.append(branchTest32(Zero, dest));
     934#endif
    926935
    927936        // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
Note: See TracChangeset for help on using the changeset viewer.