Changeset 43363 in webkit for trunk/JavaScriptCore/jit


Ignore:
Timestamp:
May 7, 2009, 1:42:59 PM (16 years ago)
Author:
[email protected]
Message:

2009-05-07 Maciej Stachowiak <[email protected]>

Reviewed by Sam Weinig.


  • optimize various cases of branch-fused less


1% speedup on SunSpider overall
13% speedup on math-cordic

  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): op_loop_if_less: Optimize case of constant as first operand, just as case of constant as second operand. op_jnless: Factored out into compileFastArith_op_jnless. (JSC::JIT::privateCompileSlowCases): op_jnless: Factored out into compileFastArithSlow_op_jnless.
  • jit/JIT.h:
  • jit/JITArithmetic.cpp: (JSC::JIT::compileFastArith_op_jnless): Factored out from main compile loop.
  • Generate inline code for comparison of constant immediate int as first operand to another immediate int, as for loop_if_less

(JSC::JIT::compileFastArithSlow_op_jnless):

  • Generate inline code for comparing two floating point numbers.
  • Generate code for both cases of comparing a floating point number to a constant immediate int.
  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): Fix dumping of op_jnless (tangentially related bugfix).
Location:
trunk/JavaScriptCore/jit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JIT.cpp

    r43362 r43363  
     1
    12/*
    23 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
     
    229230#endif
    230231                addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3);
     232            } else if (isOperandConstantImmediateInt(op1)) {
     233                emitGetVirtualRegister(op2, regT1);
     234                emitJumpSlowCaseIfNotImmediateInteger(regT1);
     235#if USE(ALTERNATE_JSIMMEDIATE)
     236                int32_t op1imm = getConstantOperandImmediateInt(op1);
     237#else
     238                int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
     239#endif
     240                addJump(branch32(GreaterThan, regT1, Imm32(op1imm)), target + 3);
    231241            } else {
    232242                emitGetVirtualRegisters(op1, regT0, op2, regT1);
     
    614624        }
    615625        case op_jnless: {
    616             unsigned op1 = currentInstruction[1].u.operand;
    617             unsigned op2 = currentInstruction[2].u.operand;
    618626            unsigned target = currentInstruction[3].u.operand;
    619             if (isOperandConstantImmediateInt(op2)) {
    620                 emitGetVirtualRegister(op1, regT0);
    621                 emitJumpSlowCaseIfNotImmediateInteger(regT0);
    622 #if USE(ALTERNATE_JSIMMEDIATE)
    623                 int32_t op2imm = getConstantOperandImmediateInt(op2);
    624 #else
    625                 int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
    626 #endif
    627                 addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3);
    628             } else {
    629                 emitGetVirtualRegisters(op1, regT0, op2, regT1);
    630                 emitJumpSlowCaseIfNotImmediateInteger(regT0);
    631                 emitJumpSlowCaseIfNotImmediateInteger(regT1);
    632                 addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3);
    633             }
     627            compileFastArith_op_jnless(currentInstruction[1].u.operand, currentInstruction[2].u.operand, target);
    634628            RECORD_JUMP_TARGET(target + 3);
    635629            NEXT_OPCODE(op_jnless);
     
    12361230        }
    12371231        case op_loop_if_less: {
     1232            unsigned op1 = currentInstruction[1].u.operand;
    12381233            unsigned op2 = currentInstruction[2].u.operand;
    12391234            unsigned target = currentInstruction[3].u.operand;
     
    12421237                emitPutJITStubArg(regT0, 1);
    12431238                emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
     1239                emitCTICall(JITStubs::cti_op_loop_if_less);
     1240                emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
     1241            } else if (isOperandConstantImmediateInt(op1)) {
     1242                linkSlowCase(iter);
     1243                emitPutJITStubArgFromVirtualRegister(op1, 1, regT1);
     1244                emitPutJITStubArg(regT0, 2);
    12441245                emitCTICall(JITStubs::cti_op_loop_if_less);
    12451246                emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
     
    13231324        }
    13241325        case op_jnless: {
    1325             unsigned op2 = currentInstruction[2].u.operand;
    1326             unsigned target = currentInstruction[3].u.operand;
    1327             if (isOperandConstantImmediateInt(op2)) {
    1328                 linkSlowCase(iter);
    1329                 emitPutJITStubArg(regT0, 1);
    1330                 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, regT2);
    1331                 emitCTICall(JITStubs::cti_op_jless);
    1332                 emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
    1333             } else {
    1334                 linkSlowCase(iter);
    1335                 linkSlowCase(iter);
    1336                 emitPutJITStubArg(regT0, 1);
    1337                 emitPutJITStubArg(regT1, 2);
    1338                 emitCTICall(JITStubs::cti_op_jless);
    1339                 emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
    1340             }
     1326            compileFastArithSlow_op_jnless(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
    13411327            NEXT_OPCODE(op_jnless);
    13421328        }
  • trunk/JavaScriptCore/jit/JIT.h

    r43362 r43363  
    380380        void compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2);
    381381        void compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2);
     382        void compileFastArith_op_jnless(unsigned op1, unsigned op2, unsigned target);
    382383        void compileFastArith_op_pre_inc(unsigned srcDst);
    383384        void compileFastArith_op_pre_dec(unsigned srcDst);
     
    391392        void compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
    392393        void compileFastArithSlow_op_rshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
     394        void compileFastArithSlow_op_jnless(unsigned op1, unsigned op2, unsigned target, Vector<SlowCaseEntry>::iterator&);
    393395        void compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
    394396        void compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
  • trunk/JavaScriptCore/jit/JITArithmetic.cpp

    r43122 r43363  
    217217    emitCTICall(JITStubs::cti_op_rshift);
    218218    emitPutVirtualRegister(result);
     219}
     220
     221void JIT::compileFastArith_op_jnless(unsigned op1, unsigned op2, unsigned target)
     222{
     223    // We generate inline code for the following cases in the fast path:
     224    // - int immediate to constant int immediate
     225    // - constant int immediate to int immediate
     226    // - int immediate to int immediate
     227
     228    if (isOperandConstantImmediateInt(op2)) {
     229        emitGetVirtualRegister(op1, regT0);
     230        emitJumpSlowCaseIfNotImmediateInteger(regT0);
     231#if USE(ALTERNATE_JSIMMEDIATE)
     232        int32_t op2imm = getConstantOperandImmediateInt(op2);
     233#else
     234        int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
     235#endif
     236        addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3);
     237    } else if (isOperandConstantImmediateInt(op1)) {
     238        emitGetVirtualRegister(op2, regT1);
     239        emitJumpSlowCaseIfNotImmediateInteger(regT1);
     240#if USE(ALTERNATE_JSIMMEDIATE)
     241        int32_t op1imm = getConstantOperandImmediateInt(op1);
     242#else
     243        int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
     244#endif
     245        addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target + 3);
     246    } else {
     247        emitGetVirtualRegisters(op1, regT0, op2, regT1);
     248        emitJumpSlowCaseIfNotImmediateInteger(regT0);
     249        emitJumpSlowCaseIfNotImmediateInteger(regT1);
     250
     251        addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3);
     252    }
     253}
     254void JIT::compileFastArithSlow_op_jnless(unsigned op1, unsigned op2, unsigned target, Vector<SlowCaseEntry>::iterator& iter)
     255{
     256    // We generate inline code for the following cases in the slow path:
     257    // - floating-point number to constant int immediate
     258    // - constant int immediate to floating-point number
     259    // - floating-point number to floating-point number.
     260
     261    if (isOperandConstantImmediateInt(op2)) {
     262        linkSlowCase(iter);
     263
     264        if (isSSE2Present()) {
     265#if USE(ALTERNATE_JSIMMEDIATE)
     266            Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
     267            addPtr(tagTypeNumberRegister, regT0);
     268            m_assembler.movq_rr(regT0, X86::xmm0);
     269#else
     270            Jump fail1;
     271            if (!m_codeBlock->isKnownNotImmediate(op1))
     272                fail1 = emitJumpIfNotJSCell(regT0);
     273
     274            Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
     275            m_assembler.movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), regT0, X86::xmm0);
     276#endif
     277           
     278            int32_t op2imm = getConstantOperand(op2).getInt32Fast();;
     279                   
     280            m_assembler.movl_i32r(op2imm, regT1);
     281            m_assembler.cvtsi2sd_rr(regT1, X86::xmm1);
     282
     283            m_assembler.ucomisd_rr(X86::xmm0, X86::xmm1);
     284            emitJumpSlowToHot(Jump(m_assembler.jbe()), target + 3);
     285
     286            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
     287
     288#if USE(ALTERNATE_JSIMMEDIATE)
     289            fail1.link(this);
     290#else
     291            if (!m_codeBlock->isKnownNotImmediate(op1))
     292                fail1.link(this);
     293            fail2.link(this);
     294#endif
     295        }
     296
     297        emitPutJITStubArg(regT0, 1);
     298        emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
     299        emitCTICall(JITStubs::cti_op_jless);
     300        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
     301    } else if (isOperandConstantImmediateInt(op1)) {
     302        linkSlowCase(iter);
     303
     304        if (0 && isSSE2Present()) {
     305#if USE(ALTERNATE_JSIMMEDIATE)
     306            Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
     307            addPtr(tagTypeNumberRegister, regT1);
     308            m_assembler.movq_rr(regT1, X86::xmm1);
     309#else
     310            Jump fail1;
     311            if (!m_codeBlock->isKnownNotImmediate(op2))
     312                fail1 = emitJumpIfNotJSCell(regT1);
     313           
     314            Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
     315            m_assembler.movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), regT1, X86::xmm1);
     316#endif
     317           
     318            int32_t op1imm = getConstantOperand(op1).getInt32Fast();;
     319                   
     320            m_assembler.movl_i32r(op1imm, regT0);
     321            m_assembler.cvtsi2sd_rr(regT0, X86::xmm0);
     322
     323            m_assembler.ucomisd_rr(X86::xmm0, X86::xmm1);
     324            emitJumpSlowToHot(Jump(m_assembler.jbe()), target + 3);
     325
     326            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
     327
     328#if USE(ALTERNATE_JSIMMEDIATE)
     329            fail1.link(this);
     330#else
     331            if (!m_codeBlock->isKnownNotImmediate(op2))
     332                fail1.link(this);
     333            fail2.link(this);
     334#endif
     335        }
     336
     337        emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);
     338        emitPutJITStubArg(regT1, 2);
     339        emitCTICall(JITStubs::cti_op_jless);
     340        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
     341    } else {
     342        linkSlowCase(iter);
     343
     344        if (isSSE2Present()) {
     345#if USE(ALTERNATE_JSIMMEDIATE)
     346            Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
     347            Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
     348            addPtr(tagTypeNumberRegister, regT0);
     349            addPtr(tagTypeNumberRegister, regT1);
     350            m_assembler.movq_rr(regT0, X86::xmm0);
     351            m_assembler.movq_rr(regT1, X86::xmm1);
     352#else
     353            Jump fail1;
     354            if (!m_codeBlock->isKnownNotImmediate(op1))
     355                fail1 = emitJumpIfNotJSCell(regT0);
     356
     357            Jump fail2;
     358            if (!m_codeBlock->isKnownNotImmediate(op2))
     359                fail2 = emitJumpIfNotJSCell(regT1);
     360
     361            Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
     362            Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
     363            m_assembler.movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), regT0, X86::xmm0);
     364            m_assembler.movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), regT1, X86::xmm1);
     365#endif
     366
     367            m_assembler.ucomisd_rr(X86::xmm0, X86::xmm1);
     368            emitJumpSlowToHot(Jump(m_assembler.jbe()), target + 3);
     369
     370            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
     371
     372#if USE(ALTERNATE_JSIMMEDIATE)
     373            fail1.link(this);
     374            fail2.link(this);
     375#else
     376            if (!m_codeBlock->isKnownNotImmediate(op1))
     377                fail1.link(this);
     378            if (!m_codeBlock->isKnownNotImmediate(op2))
     379                fail2.link(this);
     380            fail3.link(this);
     381            fail4.link(this);
     382#endif
     383        }
     384
     385        linkSlowCase(iter);
     386        emitPutJITStubArg(regT0, 1);
     387        emitPutJITStubArg(regT1, 2);
     388        emitCTICall(JITStubs::cti_op_jless);
     389        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
     390    }
    219391}
    220392
Note: See TracChangeset for help on using the changeset viewer.