[JSC] Math unary functions should be handled by DFG
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 May 2017 11:40:46 +0000 (11:40 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 May 2017 11:40:46 +0000 (11:40 +0000)
commit2a8c35e9b22b2ebce949371e5673a862ac691c83
tree43039d1b96373ae735a7c0a2c047119bf55f9475
parent676b97b5cebd4c29d505e5e875ed770c7bbbe078
[JSC] Math unary functions should be handled by DFG
https://bugs.webkit.org/show_bug.cgi?id=171269

Reviewed by Saam Barati.

JSTests:

* stress/arith-acos-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueACosNoArgument):
(testNoArgument):
(opaqueAllTypesACos):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueACosForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueACosForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueACosForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueACosWithException):
(testException):
* stress/arith-acosh-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueACoshNoArgument):
(testNoArgument):
(opaqueAllTypesACosh):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueACoshForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueACoshForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueACoshForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueACoshWithException):
(testException):
* stress/arith-asin-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueASinNoArgument):
(testNoArgument):
(opaqueAllTypesASin):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueASinForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueASinForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueASinForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueASinWithException):
(testException):
* stress/arith-asinh-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueASinhNoArgument):
(testNoArgument):
(opaqueAllTypesASinh):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueASinhForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueASinhForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueASinhForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueASinhWithException):
(testException):
* stress/arith-atan-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueATanNoArgument):
(testNoArgument):
(opaqueAllTypesATan):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueATanForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueATanForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueATanForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueATanWithException):
(testException):
* stress/arith-atanh-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueATanhNoArgument):
(testNoArgument):
(opaqueAllTypesATanh):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueATanhForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueATanhForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueATanhForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueATanhWithException):
(testException):
* stress/arith-cbrt-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueCbrtNoArgument):
(testNoArgument):
(opaqueAllTypesCbrt):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueCbrtForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueCbrtForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueCbrtForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueCbrtWithException):
(testException):
* stress/arith-cosh-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueCoshNoArgument):
(testNoArgument):
(opaqueAllTypesCosh):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueCoshForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueCoshForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueCoshForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueCoshWithException):
(testException):
* stress/arith-expm1-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueExpm1NoArgument):
(testNoArgument):
(opaqueAllTypesExpm1):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueExpm1ForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueExpm1ForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueExpm1ForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueExpm1WithException):
(testException):
* stress/arith-log10-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueLog10NoArgument):
(testNoArgument):
(opaqueAllTypesLog10):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueLog10ForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueLog10ForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueLog10ForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueLog10WithException):
(testException):
* stress/arith-log2-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueLog2NoArgument):
(testNoArgument):
(opaqueAllTypesLog2):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueLog2ForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueLog2ForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueLog2ForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueLog2WithException):
(testException):
* stress/arith-sinh-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueSinhNoArgument):
(testNoArgument):
(opaqueAllTypesSinh):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueSinhForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueSinhForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueSinhForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueSinhWithException):
(testException):
* stress/arith-tan-on-various-types.js:
(isIdentical):
* stress/arith-tanh-on-various-types.js: Added.
(let.validInputTypedTestCases.validInputTestCases.map):
(isIdentical):
(opaqueTanhNoArgument):
(testNoArgument):
(opaqueAllTypesTanh):
(testAllTypesCall):
(testSingleTypeCall):
(testConstant):
(opaqueTanhForSideEffects):
(testSideEffect.let.testObject.valueOf):
(testSideEffect):
(opaqueTanhForCSE):
(testCSE.let.testObject.valueOf):
(testCSE):
(opaqueTanhForDCE):
(testDCE.let.testObject.valueOf):
(testDCE):
(testException.opaqueTanhWithException):
(testException):

Source/JavaScriptCore:

ArithSin, ArithCos, and ArithLog are just calling a C runtime function.
While handling them in DFG is not very effective for performance, they
can drop some type checks & value conversions and mark them as pure
operations. It is effective if they are involved in some complex
optimization phase. Actually, ArithLog is effective in kraken.

While a few of Math functions have DFG nodes, basically math functions
are pure. And large part of these functions are just calling a C runtime
function. This patch generalizes these nodes in DFG as ArithUnary. And
we annotate many unary math functions with Intrinsics and convert them
to ArithUnary in DFG. It also cleans up duplicate code in ArithSin,
ArithCos, and ArithLog. If your math function has some good DFG / FTL
optimization rather than calling a C runtime function, you should add
a specialized DFG node, like ArithSqrt.

We also create a new namespace JSC::Math. Inside it, we collect math functions.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGArithMode.cpp:
(JSC::DFG::arithUnaryFunction):
(JSC::DFG::arithUnaryOperation):
(WTF::printInternal):
* dfg/DFGArithMode.h:
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasArithUnaryType):
(JSC::DFG::Node::arithUnaryType):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithUnary):
(JSC::DFG::SpeculativeJIT::compileArithCos): Deleted.
(JSC::DFG::SpeculativeJIT::compileArithTan): Deleted.
(JSC::DFG::SpeculativeJIT::compileArithSin): Deleted.
(JSC::DFG::SpeculativeJIT::compileArithLog): Deleted.
* 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/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileArithUnary):
(JSC::FTL::DFG::LowerDFGToB3::compileArithSin): Deleted.
(JSC::FTL::DFG::LowerDFGToB3::compileArithCos): Deleted.
(JSC::FTL::DFG::LowerDFGToB3::compileArithTan): Deleted.
(JSC::FTL::DFG::LowerDFGToB3::compileArithLog): Deleted.
* ftl/FTLOutput.cpp:
(JSC::FTL::Output::doubleUnary):
(JSC::FTL::Output::doubleSin): Deleted.
(JSC::FTL::Output::doubleCos): Deleted.
(JSC::FTL::Output::doubleTan): Deleted.
(JSC::FTL::Output::doubleLog): Deleted.
* ftl/FTLOutput.h:
* runtime/Intrinsic.h:
* runtime/MathCommon.cpp:
(JSC::Math::log1p):
* runtime/MathCommon.h:
* runtime/MathObject.cpp:
(JSC::MathObject::finishCreation):
(JSC::mathProtoFuncACos):
(JSC::mathProtoFuncASin):
(JSC::mathProtoFuncATan):
(JSC::mathProtoFuncCos):
(JSC::mathProtoFuncExp):
(JSC::mathProtoFuncLog):
(JSC::mathProtoFuncSin):
(JSC::mathProtoFuncTan):
(JSC::mathProtoFuncACosh):
(JSC::mathProtoFuncASinh):
(JSC::mathProtoFuncATanh):
(JSC::mathProtoFuncCbrt):
(JSC::mathProtoFuncCosh):
(JSC::mathProtoFuncExpm1):
(JSC::mathProtoFuncLog1p):
(JSC::mathProtoFuncLog10):
(JSC::mathProtoFuncLog2):
(JSC::mathProtoFuncSinh):
(JSC::mathProtoFuncTanh):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@216178 268f45cc-cd09-0410-ab3c-d52691b4dbfc
44 files changed:
JSTests/ChangeLog
JSTests/stress/arith-acos-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-acosh-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-asin-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-asinh-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-atan-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-atanh-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-cbrt-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-cosh-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-expm1-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-log10-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-log2-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-sinh-on-various-types.js [new file with mode: 0644]
JSTests/stress/arith-tan-on-various-types.js
JSTests/stress/arith-tanh-on-various-types.js [new file with mode: 0644]
JSTests/stress/math-unary-no-arg.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGArithMode.cpp
Source/JavaScriptCore/dfg/DFGArithMode.h
Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGGraph.cpp
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGOperations.h
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/ftl/FTLOutput.cpp
Source/JavaScriptCore/ftl/FTLOutput.h
Source/JavaScriptCore/runtime/Intrinsic.h
Source/JavaScriptCore/runtime/MathCommon.cpp
Source/JavaScriptCore/runtime/MathCommon.h
Source/JavaScriptCore/runtime/MathObject.cpp