Changeset 93375 in webkit


Ignore:
Timestamp:
Aug 18, 2011 5:18:49 PM (13 years ago)
Author:
fpizlo@apple.com
Message:

DFG non-speculative JIT does not inline the double case of ValueAdd
https://bugs.webkit.org/show_bug.cgi?id=66025

Reviewed by Gavin Barraclough.

This is a 1.3% win on Kraken overall, with >=8% speed-ups on a few
benchmarks (imaging-darkroom, stanford-crypto-pbkdf2,
stanford-crypto-sha256-iterative). It looks like it might have
a speed-up in SunSpider (though not statistically significant or
particularly reproducible) and a slight slow-down in V8 (0.14%,
not statistically significant). It does slow down v8-crypto by
1.5%.

  • dfg/DFGJITCodeGenerator.cpp:

(JSC::DFG::JITCodeGenerator::isKnownInteger):
(JSC::DFG::JITCodeGenerator::isKnownNumeric):

  • dfg/DFGNonSpeculativeJIT.cpp:

(JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
(JSC::DFG::NonSpeculativeJIT::basicArithOp):

  • dfg/DFGOperations.cpp:
Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r93298 r93375  
     12011-08-10  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG non-speculative JIT does not inline the double case of ValueAdd
     4        https://bugs.webkit.org/show_bug.cgi?id=66025
     5
     6        Reviewed by Gavin Barraclough.
     7       
     8        This is a 1.3% win on Kraken overall, with >=8% speed-ups on a few
     9        benchmarks (imaging-darkroom, stanford-crypto-pbkdf2,
     10        stanford-crypto-sha256-iterative).  It looks like it might have
     11        a speed-up in SunSpider (though not statistically significant or
     12        particularly reproducible) and a slight slow-down in V8 (0.14%,
     13        not statistically significant).  It does slow down v8-crypto by
     14        1.5%.
     15
     16        * dfg/DFGJITCodeGenerator.cpp:
     17        (JSC::DFG::JITCodeGenerator::isKnownInteger):
     18        (JSC::DFG::JITCodeGenerator::isKnownNumeric):
     19        * dfg/DFGNonSpeculativeJIT.cpp:
     20        (JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
     21        (JSC::DFG::NonSpeculativeJIT::basicArithOp):
     22        * dfg/DFGOperations.cpp:
     23
    1242011-08-18  Filip Pizlo  <fpizlo@apple.com>
    225
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp

    r93010 r93375  
    331331        return true;
    332332
    333     GenerationInfo& info = m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()];
     333    Node& node = m_jit.graph()[nodeIndex];
     334   
     335    if (node.hasInt32Result())
     336        return true;
     337   
     338    GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    334339
    335340    DataFormat registerFormat = info.registerFormat();
     
    350355        return true;
    351356
    352     GenerationInfo& info = m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()];
     357    Node& node = m_jit.graph()[nodeIndex];
     358   
     359    if (node.hasNumericResult())
     360        return true;
     361   
     362    GenerationInfo& info = m_generationInfo[node.virtualRegister()];
    353363
    354364    DataFormat registerFormat = info.registerFormat();
  • trunk/Source/JavaScriptCore/dfg/DFGNonSpeculativeJIT.cpp

    r93010 r93375  
    170170    overflow.link(&m_jit);
    171171   
     172    JITCompiler::Jump notNumber;
     173   
     174    // first deal with overflow case
     175    m_jit.convertInt32ToDouble(regArgGPR, tmp2FPR);
     176   
     177    // now deal with not-int case, if applicable
     178    if (!isKnownInteger(regChild)) {
     179        JITCompiler::Jump haveValue = m_jit.jump();
     180       
     181        notInt.link(&m_jit);
     182       
     183        if (!isKnownNumeric(regChild)) {
     184            ASSERT(op == ValueAdd);
     185            notNumber = m_jit.branchTestPtr(MacroAssembler::Zero, regArgGPR, GPRInfo::tagTypeNumberRegister);
     186        }
     187       
     188        m_jit.move(regArgGPR, resultGPR);
     189        m_jit.addPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
     190        m_jit.movePtrToDouble(resultGPR, tmp2FPR);
     191       
     192        haveValue.link(&m_jit);
     193    }
     194   
     195    m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(immChild)))), resultGPR);
     196    m_jit.movePtrToDouble(resultGPR, tmp1FPR);
    172197    switch (op) {
    173198    case ValueAdd:
    174         // overflow and not-int are the same
    175         if (!isKnownInteger(regChild))
    176             notInt.link(&m_jit);
    177        
     199    case ArithAdd:
     200        m_jit.addDouble(tmp1FPR, tmp2FPR);
     201        break;
     202       
     203    case ArithSub:
     204        m_jit.subDouble(tmp1FPR, tmp2FPR);
     205        break;
     206           
     207    default:
     208        ASSERT_NOT_REACHED();
     209    }
     210   
     211    JITCompiler::Jump doneCaseConvertedToInt;
     212   
     213    if (op == ValueAdd) {
     214        JITCompiler::JumpList failureCases;
     215        m_jit.branchConvertDoubleToInt32(tmp2FPR, resultGPR, failureCases, tmp1FPR);
     216        m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
     217       
     218        doneCaseConvertedToInt = m_jit.jump();
     219       
     220        failureCases.link(&m_jit);
     221    }
     222   
     223    m_jit.moveDoubleToPtr(tmp2FPR, resultGPR);
     224    m_jit.subPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
     225       
     226    if (!isKnownNumeric(regChild)) {
     227        ASSERT(notNumber.isSet());
     228        ASSERT(op == ValueAdd);
     229           
     230        JITCompiler::Jump doneCaseWasNumber = m_jit.jump();
     231           
     232        notNumber.link(&m_jit);
     233           
    178234        silentSpillAllRegisters(resultGPR);
    179235        if (commute) {
     
    188244        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    189245        silentFillAllRegisters(resultGPR);
    190         break;
    191 
    192     case ArithAdd:
    193     case ArithSub:
    194         // first deal with overflow case
    195         m_jit.convertInt32ToDouble(regArgGPR, tmp2FPR);
    196        
    197         // now deal with not-int case, if applicable
    198         if (!isKnownInteger(regChild)) {
    199             JITCompiler::Jump haveValue = m_jit.jump();
    200            
    201             notInt.link(&m_jit);
    202            
    203             m_jit.move(regArgGPR, resultGPR);
    204             unboxDouble(resultGPR, tmp2FPR);
    205            
    206             haveValue.link(&m_jit);
    207         }
    208        
    209         m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(immChild)))), resultGPR);
    210         m_jit.movePtrToDouble(resultGPR, tmp1FPR);
    211         if (op == ArithAdd)
    212             m_jit.addDouble(tmp1FPR, tmp2FPR);
    213         else
    214             m_jit.subDouble(tmp1FPR, tmp2FPR);
    215         boxDouble(tmp2FPR, resultGPR);
    216         break;
    217        
    218     default:
    219         ASSERT_NOT_REACHED();
     246           
     247        doneCaseWasNumber.link(&m_jit);
    220248    }
    221249   
    222250    done.link(&m_jit);
     251    if (doneCaseConvertedToInt.isSet())
     252        doneCaseConvertedToInt.link(&m_jit);
    223253       
    224254    jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
     
    280310    JITCompiler::Jump done = m_jit.jump();
    281311   
     312    JITCompiler::JumpList haveFPRArguments;
     313
     314    overflow.link(&m_jit);
     315       
     316    // both arguments are integers
     317    m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
     318    m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
     319       
     320    haveFPRArguments.append(m_jit.jump());
     321       
     322    JITCompiler::JumpList notNumbers;
     323       
     324    JITCompiler::Jump child2NotInt2;
     325       
     326    if (!isKnownInteger(node.child1())) {
     327        child1NotInt.link(&m_jit);
     328           
     329        if (!isKnownNumeric(node.child1())) {
     330            ASSERT(op == ValueAdd);
     331            notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg1GPR, GPRInfo::tagTypeNumberRegister));
     332        }
     333           
     334        m_jit.move(arg1GPR, resultGPR);
     335        unboxDouble(resultGPR, tmp1FPR);
     336           
     337        // child1 is converted to a double; child2 may either be an int or
     338        // a boxed double
     339           
     340        if (!isKnownInteger(node.child2())) {
     341            if (isKnownNumeric(node.child2()))
     342                child2NotInt2 = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
     343            else {
     344                ASSERT(op == ValueAdd);
     345                JITCompiler::Jump child2IsInt = m_jit.branchPtr(MacroAssembler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
     346                notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg2GPR, GPRInfo::tagTypeNumberRegister));
     347                child2NotInt2 = m_jit.jump();
     348                child2IsInt.link(&m_jit);
     349            }
     350        }
     351           
     352        // child 2 is definitely an integer
     353        m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
     354           
     355        haveFPRArguments.append(m_jit.jump());
     356    }
     357       
     358    if (!isKnownInteger(node.child2())) {
     359        child2NotInt.link(&m_jit);
     360           
     361        if (!isKnownNumeric(node.child2())) {
     362            ASSERT(op == ValueAdd);
     363            notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg2GPR, GPRInfo::tagTypeNumberRegister));
     364        }
     365           
     366        // child1 is definitely an integer, and child 2 is definitely not
     367           
     368        m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
     369           
     370        if (child2NotInt2.isSet())
     371            child2NotInt2.link(&m_jit);
     372           
     373        m_jit.move(arg2GPR, resultGPR);
     374        unboxDouble(resultGPR, tmp2FPR);
     375    }
     376       
     377    haveFPRArguments.link(&m_jit);
     378       
     379    switch (op) {
     380    case ValueAdd:
     381    case ArithAdd:
     382        m_jit.addDouble(tmp2FPR, tmp1FPR);
     383        break;
     384           
     385    case ArithSub:
     386        m_jit.subDouble(tmp2FPR, tmp1FPR);
     387        break;
     388           
     389    case ArithMul:
     390        m_jit.mulDouble(tmp2FPR, tmp1FPR);
     391        break;
     392           
     393    default:
     394        ASSERT_NOT_REACHED();
     395    }
     396   
     397    JITCompiler::Jump doneCaseConvertedToInt;
     398   
    282399    if (op == ValueAdd) {
    283         if (child1NotInt.isSet())
    284             child1NotInt.link(&m_jit);
    285         if (child2NotInt.isSet())
    286             child2NotInt.link(&m_jit);
    287         overflow.link(&m_jit);
    288        
     400        JITCompiler::JumpList failureCases;
     401        m_jit.branchConvertDoubleToInt32(tmp1FPR, resultGPR, failureCases, tmp2FPR);
     402        m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
     403       
     404        doneCaseConvertedToInt = m_jit.jump();
     405       
     406        failureCases.link(&m_jit);
     407    }
     408       
     409    boxDouble(tmp1FPR, resultGPR);
     410       
     411    if (!notNumbers.empty()) {
     412        ASSERT(op == ValueAdd);
     413           
     414        JITCompiler::Jump doneCaseWasNumber = m_jit.jump();
     415           
     416        notNumbers.link(&m_jit);
     417           
    289418        silentSpillAllRegisters(resultGPR);
    290419        setupStubArguments(arg1GPR, arg2GPR);
     
    293422        m_jit.move(GPRInfo::returnValueGPR, resultGPR);
    294423        silentFillAllRegisters(resultGPR);
    295     } else {
    296         JITCompiler::JumpList haveFPRArguments;
    297 
    298         overflow.link(&m_jit);
    299        
    300         // both arguments are integers
    301         m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
    302         m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
    303        
    304         haveFPRArguments.append(m_jit.jump());
    305        
    306         JITCompiler::Jump child2NotInt2;
    307        
    308         if (!isKnownInteger(node.child1())) {
    309             child1NotInt.link(&m_jit);
    310            
    311             m_jit.move(arg1GPR, resultGPR);
    312             unboxDouble(resultGPR, tmp1FPR);
    313            
    314             // child1 is converted to a double; child2 may either be an int or
    315             // a boxed double
    316            
    317             if (!isKnownInteger(node.child2()))
    318                 child2NotInt2 = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
    319            
    320             // child 2 is definitely an integer
    321             m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
    322            
    323             haveFPRArguments.append(m_jit.jump());
    324         }
    325        
    326         if (!isKnownInteger(node.child2())) {
    327             child2NotInt.link(&m_jit);
    328             // child1 is definitely an integer, and child 2 is definitely not
    329            
    330             m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
    331            
    332             if (child2NotInt2.isSet())
    333                 child2NotInt2.link(&m_jit);
    334            
    335             m_jit.move(arg2GPR, resultGPR);
    336             unboxDouble(resultGPR, tmp2FPR);
    337         }
    338        
    339         haveFPRArguments.link(&m_jit);
    340        
    341         switch (op) {
    342         case ArithAdd:
    343             m_jit.addDouble(tmp2FPR, tmp1FPR);
    344             break;
    345            
    346         case ArithSub:
    347             m_jit.subDouble(tmp2FPR, tmp1FPR);
    348             break;
    349            
    350         case ArithMul:
    351             m_jit.mulDouble(tmp2FPR, tmp1FPR);
    352             break;
    353            
    354         default:
    355             ASSERT_NOT_REACHED();
    356         }
    357        
    358         boxDouble(tmp1FPR, resultGPR);
     424
     425        doneCaseWasNumber.link(&m_jit);
    359426    }
    360427   
    361428    done.link(&m_jit);
     429    if (doneCaseConvertedToInt.isSet())
     430        doneCaseConvertedToInt.link(&m_jit);
    362431       
    363432    jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r93070 r93375  
    124124    JSValue op1 = JSValue::decode(encodedOp1);
    125125    JSValue op2 = JSValue::decode(encodedOp2);
    126 
    127     if (op1.isInt32() && op2.isInt32()) {
    128         int64_t result64 = static_cast<int64_t>(op1.asInt32()) + static_cast<int64_t>(op2.asInt32());
    129         int32_t result32 = static_cast<int32_t>(result64);
    130         if (LIKELY(result32 == result64))
    131             return JSValue::encode(jsNumber(result32));
    132         return JSValue::encode(jsNumber((double)result64));
    133     }
    134    
    135     double number1;
    136     double number2;
    137     if (op1.getNumber(number1) && op2.getNumber(number2))
    138         return JSValue::encode(jsNumber(number1 + number2));
     126   
     127    ASSERT(!op1.isNumber() || !op2.isNumber());
    139128
    140129    return JSValue::encode(jsAddSlowCase(exec, op1, op2));
Note: See TracChangeset for help on using the changeset viewer.