Changeset 181035 in webkit


Ignore:
Timestamp:
Mar 4, 2015 2:39:28 PM (9 years ago)
Author:
benjamin@webkit.org
Message:

[JSC] Add a node for Math.log()
https://bugs.webkit.org/show_bug.cgi?id=142126

Patch by Benjamin Poulain <bpoulain@apple.com> on 2015-03-04
Reviewed by Geoffrey Garen.

This patch adds the DFG node ArithLog for LogIntrinsic.

Having a direct call to log has very little value by itself, the implementation
in DFG and FTL is a simple function call.

What is useful in ArithLog is that we know the operation is pure.
This allow us to hoist it out of loops when the argument is independent
is an invariant of the loop.

Perf wise, this patch gives:
-Kraken's imaging-darkroom: definitely 1.2372x faster.
-AsmBench's Towers.c: definitely 1.0261x faster.

  • 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/DFGNodeType.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

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

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithLog):

  • 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::compileArithLog):

  • ftl/FTLOutput.h:

(JSC::FTL::Output::doubleLog):

  • tests/stress/math-log-basics.js: Added.
  • tests/stress/math-log-with-constants.js: Added.
Location:
trunk/Source/JavaScriptCore
Files:
2 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r181019 r181035  
     12015-03-04  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] Add a node for Math.log()
     4        https://bugs.webkit.org/show_bug.cgi?id=142126
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        This patch adds the DFG node ArithLog for LogIntrinsic.
     9
     10        Having a direct call to log has very little value by itself, the implementation
     11        in DFG and FTL is a simple function call.
     12
     13        What is useful in ArithLog is that we know the operation is pure.
     14        This allow us to hoist it out of loops when the argument is independent
     15        is an invariant of the loop.
     16
     17        Perf wise, this patch gives:
     18        -Kraken's imaging-darkroom: definitely 1.2372x faster.
     19        -AsmBench's Towers.c: definitely 1.0261x faster.
     20
     21        * dfg/DFGAbstractInterpreterInlines.h:
     22        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     23        * dfg/DFGByteCodeParser.cpp:
     24        (JSC::DFG::ByteCodeParser::handleIntrinsic):
     25        * dfg/DFGClobberize.h:
     26        (JSC::DFG::clobberize):
     27        * dfg/DFGDoesGC.cpp:
     28        (JSC::DFG::doesGC):
     29        * dfg/DFGFixupPhase.cpp:
     30        (JSC::DFG::FixupPhase::fixupNode):
     31        * dfg/DFGNodeType.h:
     32        * dfg/DFGPredictionPropagationPhase.cpp:
     33        (JSC::DFG::PredictionPropagationPhase::propagate):
     34        (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
     35        * dfg/DFGSafeToExecute.h:
     36        (JSC::DFG::safeToExecute):
     37        * dfg/DFGSpeculativeJIT.cpp:
     38        (JSC::DFG::SpeculativeJIT::compileArithLog):
     39        * dfg/DFGSpeculativeJIT.h:
     40        * dfg/DFGSpeculativeJIT32_64.cpp:
     41        (JSC::DFG::SpeculativeJIT::compile):
     42        * dfg/DFGSpeculativeJIT64.cpp:
     43        (JSC::DFG::SpeculativeJIT::compile):
     44        * ftl/FTLCapabilities.cpp:
     45        (JSC::FTL::canCompile):
     46        * ftl/FTLIntrinsicRepository.h:
     47        * ftl/FTLLowerDFGToLLVM.cpp:
     48        (JSC::FTL::LowerDFGToLLVM::compileNode):
     49        (JSC::FTL::LowerDFGToLLVM::compileArithLog):
     50        * ftl/FTLOutput.h:
     51        (JSC::FTL::Output::doubleLog):
     52        * tests/stress/math-log-basics.js: Added.
     53        * tests/stress/math-log-with-constants.js: Added.
     54
    1552015-03-04  Filip Pizlo  <fpizlo@apple.com>
    256
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r180989 r181035  
    790790        if (false && child && child.isNumber()) {
    791791            setConstant(node, jsDoubleNumber(cos(child.asNumber())));
     792            break;
     793        }
     794        forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
     795        break;
     796    }
     797
     798    case ArithLog: {
     799        JSValue child = forNode(node->child1()).value();
     800        if (child && child.isNumber()) {
     801            setConstant(node, jsDoubleNumber(log(child.asNumber())));
    792802            break;
    793803        }
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r180993 r181035  
    18351835    case MaxIntrinsic:
    18361836        return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis, insertChecks);
    1837        
     1837
    18381838    case SqrtIntrinsic:
    18391839    case CosIntrinsic:
    1840     case SinIntrinsic: {
     1840    case SinIntrinsic:
     1841    case LogIntrinsic: {
    18411842        if (argumentCountIncludingThis == 1) {
    18421843            insertChecks();
     
    18591860            insertChecks();
    18601861            set(VirtualRegister(resultOperand), addToGraph(ArithSin, get(virtualRegisterForArgument(1, registerOffset))));
     1862            return true;
     1863
     1864        case LogIntrinsic:
     1865            insertChecks();
     1866            set(VirtualRegister(resultOperand), addToGraph(ArithLog, get(virtualRegisterForArgument(1, registerOffset))));
    18611867            return true;
    18621868           
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r180989 r181035  
    134134    case ArithSin:
    135135    case ArithCos:
     136    case ArithLog:
    136137    case GetScope:
    137138    case SkipScope:
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r180989 r181035  
    8686    case ArithSin:
    8787    case ArithCos:
     88    case ArithLog:
    8889    case ValueAdd:
    8990    case GetById:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r180989 r181035  
    357357        case ArithFRound:
    358358        case ArithSin:
    359         case ArithCos: {
     359        case ArithCos:
     360        case ArithLog: {
    360361            fixDoubleOrBooleanEdge(node->child1());
    361362            node->setResult(NodeResultDouble);
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r180989 r181035  
    141141    macro(ArithSin, NodeResultNumber) \
    142142    macro(ArithCos, NodeResultNumber) \
     143    macro(ArithLog, NodeResultNumber) \
    143144    \
    144145    /* Add of values may either be arithmetic, or result in string concatenation. */\
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r180989 r181035  
    335335        case ArithFRound:
    336336        case ArithSin:
    337         case ArithCos: {
     337        case ArithCos:
     338        case ArithLog: {
    338339            changed |= setPrediction(SpecBytecodeDouble);
    339340            break;
     
    784785        case ArithCos:
    785786        case ArithSin:
     787        case ArithLog:
    786788            if (node->child1()->shouldSpeculateNumber())
    787789                m_graph.voteNode(node->child1(), VoteDouble, weight);
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r180989 r181035  
    156156    case ArithSin:
    157157    case ArithCos:
     158    case ArithLog:
    158159    case ValueAdd:
    159160    case GetById:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r180993 r181035  
    36273627}
    36283628
     3629void SpeculativeJIT::compileArithLog(Node* node)
     3630{
     3631    SpeculateDoubleOperand op1(this, node->child1());
     3632    FPRReg op1FPR = op1.fpr();
     3633    flushRegisters();
     3634    FPRResult result(this);
     3635    callOperation(log, result.fpr(), op1FPR);
     3636    doubleResult(result.fpr(), node);
     3637}
     3638
    36293639// Returns true if the compare is fused with a subsequent branch.
    36303640bool SpeculativeJIT::compare(Node* node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_JITOperation_EJJ operation)
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r181019 r181035  
    21752175    void compileArithPow(Node*);
    21762176    void compileArithSqrt(Node*);
     2177    void compileArithLog(Node*);
    21772178    void compileConstantStoragePointer(Node*);
    21782179    void compileGetIndexedPropertyStorage(Node*);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r180993 r181035  
    22202220        break;
    22212221    }
     2222
     2223    case ArithLog:
     2224        compileArithLog(node);
     2225        break;
    22222226
    22232227    case LogicalNot:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r180993 r181035  
    23532353        break;
    23542354    }
     2355
     2356    case ArithLog:
     2357        compileArithLog(node);
     2358        break;
    23552359
    23562360    case LogicalNot:
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r180989 r181035  
    9292    case ArithPow:
    9393    case ArithSqrt:
     94    case ArithLog:
    9495    case ArithFRound:
    9596    case ArithNegate:
  • trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h

    r180279 r181035  
    4444    macro(doublePowi, "llvm.powi.f64", functionType(doubleType, doubleType, int32)) \
    4545    macro(doubleSqrt, "llvm.sqrt.f64", functionType(doubleType, doubleType)) \
     46    macro(doubleLog, "llvm.log.f64", functionType(doubleType, doubleType)) \
    4647    macro(frameAddress, "llvm.frameaddress", functionType(pointerType(int8), int32)) \
    4748    macro(mulWithOverflow32, "llvm.smul.with.overflow.i32", functionType(structType(m_context, int32, boolean), int32, int32)) \
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r181019 r181035  
    511511            compileArithSqrt();
    512512            break;
     513        case ArithLog:
     514            compileArithLog();
     515            break;
    513516        case ArithFRound:
    514517            compileArithFRound();
     
    17191722
    17201723    void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node->child1()))); }
     1724
     1725    void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node->child1()))); }
    17211726   
    17221727    void compileArithFRound()
  • trunk/Source/JavaScriptCore/ftl/FTLOutput.h

    r180279 r181035  
    193193    }
    194194
     195    LValue doubleLog(LValue value)
     196    {
     197        return call(doubleLogIntrinsic(), value);
     198    }
     199
    195200    static bool hasSensibleDoubleToInt() { return isX86(); }
    196201    LValue sensibleDoubleToInt(LValue);
Note: See TracChangeset for help on using the changeset viewer.