Changeset 196799 in webkit


Ignore:
Timestamp:
Feb 18, 2016 10:42:06 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[JSC] Improve the instruction selection of Select
https://bugs.webkit.org/show_bug.cgi?id=154432

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-02-18
Reviewed by Filip Pizlo.

Plenty of code but this patch is pretty dumb:
-On ARM64: use the 3 operand form of CSEL instead of forcing a source

to be alised to the destination. This gives more freedom to the register
allocator and it is one less Move to process per Select.

-On x86, introduce a fake 3 operands form and use aggressive aliasing

to try to alias both sources to the destination.

If aliasing succeed on the "elseCase", the condition of the Select
is reverted in the MacroAssembler.

If no aliasing is possible and we end up with 3 registers, the missing
move instruction is generated by the MacroAssembler.

The missing move is generated after testing the values because the destination
can use the same register as one of the test operand.
Experimental testing seems to indicate there is no macro-fusion on CMOV,
there is no measurable cost to having the move there.

  • assembler/MacroAssembler.h:

(JSC::MacroAssembler::isInvertible):
(JSC::MacroAssembler::invert):

  • assembler/MacroAssemblerARM64.h:

(JSC::MacroAssemblerARM64::moveConditionallyDouble):
(JSC::MacroAssemblerARM64::moveConditionallyFloat):
(JSC::MacroAssemblerARM64::moveConditionallyAfterFloatingPointCompare):
(JSC::MacroAssemblerARM64::moveConditionally32):
(JSC::MacroAssemblerARM64::moveConditionally64):
(JSC::MacroAssemblerARM64::moveConditionallyTest32):
(JSC::MacroAssemblerARM64::moveConditionallyTest64):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::moveConditionallyDouble):
(JSC::MacroAssemblerX86Common::moveConditionallyFloat):
(JSC::MacroAssemblerX86Common::moveConditionally32):
(JSC::MacroAssemblerX86Common::moveConditionallyTest32):
(JSC::MacroAssemblerX86Common::invert):
(JSC::MacroAssemblerX86Common::isInvertible):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::moveConditionally64):
(JSC::MacroAssemblerX86_64::moveConditionallyTest64):

  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::createSelect):
(JSC::B3::Air::LowerToAir::lower):

  • b3/air/AirInstInlines.h:

(JSC::B3::Air::Inst::shouldTryAliasingDef):

  • b3/air/AirOpcode.opcodes:
Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r196796 r196799  
     12016-02-18  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] Improve the instruction selection of Select
     4        https://bugs.webkit.org/show_bug.cgi?id=154432
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Plenty of code but this patch is pretty dumb:
     9        -On ARM64: use the 3 operand form of CSEL instead of forcing a source
     10         to be alised to the destination. This gives more freedom to the register
     11         allocator and it is one less Move to process per Select.
     12        -On x86, introduce a fake 3 operands form and use aggressive aliasing
     13         to try to alias both sources to the destination.
     14
     15         If aliasing succeed on the "elseCase", the condition of the Select
     16         is reverted in the MacroAssembler.
     17
     18         If no aliasing is possible and we end up with 3 registers, the missing
     19         move instruction is generated by the MacroAssembler.
     20
     21         The missing move is generated after testing the values because the destination
     22         can use the same register as one of the test operand.
     23         Experimental testing seems to indicate there is no macro-fusion on CMOV,
     24         there is no measurable cost to having the move there.
     25
     26        * assembler/MacroAssembler.h:
     27        (JSC::MacroAssembler::isInvertible):
     28        (JSC::MacroAssembler::invert):
     29        * assembler/MacroAssemblerARM64.h:
     30        (JSC::MacroAssemblerARM64::moveConditionallyDouble):
     31        (JSC::MacroAssemblerARM64::moveConditionallyFloat):
     32        (JSC::MacroAssemblerARM64::moveConditionallyAfterFloatingPointCompare):
     33        (JSC::MacroAssemblerARM64::moveConditionally32):
     34        (JSC::MacroAssemblerARM64::moveConditionally64):
     35        (JSC::MacroAssemblerARM64::moveConditionallyTest32):
     36        (JSC::MacroAssemblerARM64::moveConditionallyTest64):
     37        * assembler/MacroAssemblerX86Common.h:
     38        (JSC::MacroAssemblerX86Common::moveConditionallyDouble):
     39        (JSC::MacroAssemblerX86Common::moveConditionallyFloat):
     40        (JSC::MacroAssemblerX86Common::moveConditionally32):
     41        (JSC::MacroAssemblerX86Common::moveConditionallyTest32):
     42        (JSC::MacroAssemblerX86Common::invert):
     43        (JSC::MacroAssemblerX86Common::isInvertible):
     44        * assembler/MacroAssemblerX86_64.h:
     45        (JSC::MacroAssemblerX86_64::moveConditionally64):
     46        (JSC::MacroAssemblerX86_64::moveConditionallyTest64):
     47        * b3/B3LowerToAir.cpp:
     48        (JSC::B3::Air::LowerToAir::createSelect):
     49        (JSC::B3::Air::LowerToAir::lower):
     50        * b3/air/AirInstInlines.h:
     51        (JSC::B3::Air::Inst::shouldTryAliasingDef):
     52        * b3/air/AirOpcode.opcodes:
     53
    1542016-02-18  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
    255
  • trunk/Source/JavaScriptCore/assembler/MacroAssembler.h

    r194628 r196799  
    178178        case Zero:
    179179        case NonZero:
     180        case Signed:
     181        case PositiveOrZero:
    180182            return true;
    181183        default:
     
    191193        case NonZero:
    192194            return Zero;
     195        case Signed:
     196            return PositiveOrZero;
     197        case PositiveOrZero:
     198            return Signed;
    193199        default:
    194200            RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h

    r196736 r196799  
    16021602    }
    16031603
     1604    void moveConditionallyDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1605    {
     1606        m_assembler.fcmp<64>(left, right);
     1607        moveConditionallyAfterFloatingPointCompare<64>(cond, thenCase, elseCase, dest);
     1608    }
     1609
    16041610    void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID src, RegisterID dest)
    16051611    {
    16061612        m_assembler.fcmp<32>(left, right);
    16071613        moveConditionallyAfterFloatingPointCompare<64>(cond, src, dest);
     1614    }
     1615
     1616    void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1617    {
     1618        m_assembler.fcmp<32>(left, right);
     1619        moveConditionallyAfterFloatingPointCompare<64>(cond, thenCase, elseCase, dest);
    16081620    }
    16091621
     
    16271639        }
    16281640        m_assembler.csel<datasize>(dest, src, dest, ARM64Condition(cond));
     1641    }
     1642
     1643    template<int datasize>
     1644    void moveConditionallyAfterFloatingPointCompare(DoubleCondition cond, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1645    {
     1646        if (cond == DoubleNotEqual) {
     1647            Jump unordered = makeBranch(ARM64Assembler::ConditionVS);
     1648            m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionNE);
     1649            unordered.link(this);
     1650            return;
     1651        }
     1652        if (cond == DoubleEqualOrUnordered) {
     1653            // If the compare is unordered, thenCase is copied to dest and the
     1654            // next csel has all arguments equal to thenCase.
     1655            // If the compare is ordered, dest is unchanged and EQ decides
     1656            // what value to set.
     1657            m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Assembler::ConditionVS);
     1658            m_assembler.csel<datasize>(dest, thenCase, dest, ARM64Assembler::ConditionEQ);
     1659            return;
     1660        }
     1661        m_assembler.csel<datasize>(dest, thenCase, elseCase, ARM64Condition(cond));
    16291662    }
    16301663
     
    18951928    }
    18961929
     1930    void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1931    {
     1932        m_assembler.cmp<32>(left, right);
     1933        m_assembler.csel<32>(dest, thenCase, elseCase, ARM64Condition(cond));
     1934    }
     1935
    18971936    void moveConditionally64(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID src, RegisterID dest)
    18981937    {
     
    19011940    }
    19021941
     1942    void moveConditionally64(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1943    {
     1944        m_assembler.cmp<64>(left, right);
     1945        m_assembler.csel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
     1946    }
     1947
    19031948    void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest)
    19041949    {
     
    19071952    }
    19081953
     1954    void moveConditionallyTest32(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1955    {
     1956        m_assembler.tst<32>(left, right);
     1957        m_assembler.csel<32>(dest, thenCase, elseCase, ARM64Condition(cond));
     1958    }
     1959
    19091960    void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest)
    19101961    {
    19111962        m_assembler.tst<64>(testReg, mask);
    19121963        m_assembler.csel<64>(dest, src, dest, ARM64Condition(cond));
     1964    }
     1965
     1966    void moveConditionallyTest64(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1967    {
     1968        m_assembler.tst<64>(left, right);
     1969        m_assembler.csel<64>(dest, thenCase, elseCase, ARM64Condition(cond));
    19131970    }
    19141971
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r196513 r196799  
    15781578    }
    15791579
     1580    void moveConditionallyDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1581    {
     1582        ASSERT(isSSE2Present());
     1583
     1584        if (thenCase != dest && elseCase != dest) {
     1585            move(elseCase, dest);
     1586            elseCase = dest;
     1587        }
     1588
     1589        RegisterID src;
     1590        if (elseCase == dest)
     1591            src = thenCase;
     1592        else {
     1593            cond = invert(cond);
     1594            src = elseCase;
     1595        }
     1596
     1597        if (cond & DoubleConditionBitInvert)
     1598            m_assembler.ucomisd_rr(left, right);
     1599        else
     1600            m_assembler.ucomisd_rr(right, left);
     1601        moveConditionallyAfterFloatingPointCompare(cond, left, right, src, dest);
     1602    }
     1603
    15801604    void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID src, RegisterID dest)
    15811605    {
     
    15881612        moveConditionallyAfterFloatingPointCompare(cond, left, right, src, dest);
    15891613    }
     1614
     1615    void moveConditionallyFloat(DoubleCondition cond, FPRegisterID left, FPRegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1616    {
     1617        ASSERT(isSSE2Present());
     1618
     1619        if (thenCase != dest && elseCase != dest) {
     1620            move(elseCase, dest);
     1621            elseCase = dest;
     1622        }
     1623
     1624        RegisterID src;
     1625        if (elseCase == dest)
     1626            src = thenCase;
     1627        else {
     1628            cond = invert(cond);
     1629            src = elseCase;
     1630        }
     1631
     1632        if (cond & DoubleConditionBitInvert)
     1633            m_assembler.ucomiss_rr(left, right);
     1634        else
     1635            m_assembler.ucomiss_rr(right, left);
     1636        moveConditionallyAfterFloatingPointCompare(cond, left, right, src, dest);
     1637    }
    15901638   
    15911639    void swap(RegisterID reg1, RegisterID reg2)
     
    17011749    }
    17021750
     1751    void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1752    {
     1753        m_assembler.cmpl_rr(right, left);
     1754
     1755        if (thenCase != dest && elseCase != dest) {
     1756            move(elseCase, dest);
     1757            elseCase = dest;
     1758        }
     1759
     1760        if (elseCase == dest)
     1761            cmov(x86Condition(cond), thenCase, dest);
     1762        else
     1763            cmov(x86Condition(invert(cond)), elseCase, dest);
     1764    }
     1765
    17031766    void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest)
    17041767    {
     
    17061769        cmov(x86Condition(cond), src, dest);
    17071770    }
    1708    
     1771
     1772    void moveConditionallyTest32(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1773    {
     1774        ASSERT(isInvertible(cond));
     1775        ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag.");
     1776
     1777        m_assembler.testl_rr(right, left);
     1778
     1779        if (thenCase != dest && elseCase != dest) {
     1780            move(elseCase, dest);
     1781            elseCase = dest;
     1782        }
     1783
     1784        if (elseCase == dest)
     1785            cmov(x86Condition(cond), thenCase, dest);
     1786        else
     1787            cmov(x86Condition(invert(cond)), elseCase, dest);
     1788    }
     1789
    17091790    void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, TrustedImm32 mask, RegisterID src, RegisterID dest)
    17101791    {
     
    17121793        cmov(x86Condition(cond), src, dest);
    17131794    }
    1714    
     1795
     1796    void moveConditionallyTest32(ResultCondition cond, RegisterID testReg, TrustedImm32 mask, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1797    {
     1798        ASSERT(isInvertible(cond));
     1799        ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag.");
     1800
     1801        test32(cond, testReg, mask);
     1802
     1803        if (thenCase != dest && elseCase != dest) {
     1804            move(elseCase, dest);
     1805            elseCase = dest;
     1806        }
     1807
     1808        if (elseCase == dest)
     1809            cmov(x86Condition(cond), thenCase, dest);
     1810        else
     1811            cmov(x86Condition(invert(cond)), elseCase, dest);
     1812    }
    17151813
    17161814    // Forwards / external control flow operations:
     
    21192217    {
    21202218        return static_cast<RelationalCondition>(cond ^ 1);
     2219    }
     2220
     2221    static DoubleCondition invert(DoubleCondition cond)
     2222    {
     2223        switch (cond) {
     2224        case DoubleEqual:
     2225            return DoubleNotEqualOrUnordered;
     2226        case DoubleNotEqual:
     2227            return DoubleEqualOrUnordered;
     2228        case DoubleGreaterThan:
     2229            return DoubleLessThanOrEqualOrUnordered;
     2230        case DoubleGreaterThanOrEqual:
     2231            return DoubleLessThanOrUnordered;
     2232        case DoubleLessThan:
     2233            return DoubleGreaterThanOrEqualOrUnordered;
     2234        case DoubleLessThanOrEqual:
     2235            return DoubleGreaterThanOrUnordered;
     2236        case DoubleEqualOrUnordered:
     2237            return DoubleNotEqual;
     2238        case DoubleNotEqualOrUnordered:
     2239            return DoubleEqual;
     2240        case DoubleGreaterThanOrUnordered:
     2241            return DoubleLessThanOrEqual;
     2242        case DoubleGreaterThanOrEqualOrUnordered:
     2243            return DoubleLessThan;
     2244        case DoubleLessThanOrUnordered:
     2245            return DoubleGreaterThanOrEqual;
     2246        case DoubleLessThanOrEqualOrUnordered:
     2247            return DoubleGreaterThan;
     2248        }
     2249        RELEASE_ASSERT_NOT_REACHED();
     2250        return DoubleEqual; // make compiler happy
     2251    }
     2252
     2253    static bool isInvertible(ResultCondition cond)
     2254    {
     2255        switch (cond) {
     2256        case Zero:
     2257        case NonZero:
     2258        case Signed:
     2259        case PositiveOrZero:
     2260            return true;
     2261        default:
     2262            return false;
     2263        }
     2264    }
     2265
     2266    static ResultCondition invert(ResultCondition cond)
     2267    {
     2268        switch (cond) {
     2269        case Zero:
     2270            return NonZero;
     2271        case NonZero:
     2272            return Zero;
     2273        case Signed:
     2274            return PositiveOrZero;
     2275        case PositiveOrZero:
     2276            return Signed;
     2277        default:
     2278            RELEASE_ASSERT_NOT_REACHED();
     2279            return Zero; // Make compiler happy for release builds.
     2280        }
    21212281    }
    21222282
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r196513 r196799  
    980980    }
    981981
     982    void moveConditionally64(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     983    {
     984        m_assembler.cmpq_rr(right, left);
     985
     986        if (thenCase != dest && elseCase != dest) {
     987            move(elseCase, dest);
     988            elseCase = dest;
     989        }
     990
     991        if (elseCase == dest)
     992            cmov(x86Condition(cond), thenCase, dest);
     993        else
     994            cmov(x86Condition(invert(cond)), elseCase, dest);
     995    }
     996
    982997    void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, RegisterID mask, RegisterID src, RegisterID dest)
    983998    {
    984999        m_assembler.testq_rr(testReg, mask);
    9851000        cmov(x86Condition(cond), src, dest);
     1001    }
     1002
     1003    void moveConditionallyTest64(ResultCondition cond, RegisterID left, RegisterID right, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1004    {
     1005        ASSERT(isInvertible(cond));
     1006        ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag.");
     1007
     1008        m_assembler.testq_rr(right, left);
     1009
     1010        if (thenCase != dest && elseCase != dest) {
     1011            move(elseCase, dest);
     1012            elseCase = dest;
     1013        }
     1014
     1015        if (elseCase == dest)
     1016            cmov(x86Condition(cond), thenCase, dest);
     1017        else
     1018            cmov(x86Condition(invert(cond)), elseCase, dest);
    9861019    }
    9871020   
     
    9961029            m_assembler.testq_i32r(mask.m_value, testReg);
    9971030        cmov(x86Condition(cond), src, dest);
     1031    }
     1032
     1033    void moveConditionallyTest64(ResultCondition cond, RegisterID testReg, TrustedImm32 mask, RegisterID thenCase, RegisterID elseCase, RegisterID dest)
     1034    {
     1035        ASSERT(isInvertible(cond));
     1036        ASSERT_WITH_MESSAGE(cond != Overflow, "TEST does not set the Overflow Flag.");
     1037
     1038        if (mask.m_value == -1)
     1039            m_assembler.testq_rr(testReg, testReg);
     1040        else if (!(mask.m_value & ~0x7f))
     1041            m_assembler.testb_i8r(mask.m_value, testReg);
     1042        else
     1043            m_assembler.testq_i32r(mask.m_value, testReg);
     1044
     1045        if (thenCase != dest && elseCase != dest) {
     1046            move(elseCase, dest);
     1047            elseCase = dest;
     1048        }
     1049
     1050        if (elseCase == dest)
     1051            cmov(x86Condition(cond), thenCase, dest);
     1052        else
     1053            cmov(x86Condition(invert(cond)), elseCase, dest);
    9981054    }
    9991055   
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r196736 r196799  
    16001600        Air::Opcode moveConditionallyDouble;
    16011601        Air::Opcode moveConditionallyFloat;
    1602         Tmp source;
    1603         Tmp destination;
    16041602    };
    1605     Inst createSelect(Value* value, const MoveConditionallyConfig& config, bool inverted = false)
    1606     {
     1603    Inst createSelect(const MoveConditionallyConfig& config)
     1604    {
     1605        auto createSelectInstruction = [&] (Air::Opcode opcode, const Arg& condition, const ArgPromise& left, const ArgPromise& right) -> Inst {
     1606            if (isValidForm(opcode, condition.kind(), left.kind(), right.kind(), Arg::Tmp, Arg::Tmp, Arg::Tmp)) {
     1607                Tmp result = tmp(m_value);
     1608                Tmp thenCase = tmp(m_value->child(1));
     1609                Tmp elseCase = tmp(m_value->child(2));
     1610                append(relaxedMoveForType(m_value->type()), tmp(m_value->child(2)), result);
     1611                return Inst(
     1612                    opcode, m_value, condition,
     1613                    left.consume(*this), right.consume(*this), thenCase, elseCase, result);
     1614            }
     1615            if (isValidForm(opcode, condition.kind(), left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) {
     1616                Tmp result = tmp(m_value);
     1617                Tmp source = tmp(m_value->child(1));
     1618                append(relaxedMoveForType(m_value->type()), tmp(m_value->child(2)), result);
     1619                return Inst(
     1620                    opcode, m_value, condition,
     1621                    left.consume(*this), right.consume(*this), source, result);
     1622            }
     1623            return Inst();
     1624        };
     1625
    16071626        return createGenericCompare(
    1608             value,
     1627            m_value->child(0),
    16091628            [&] (
    16101629                Arg::Width width, const Arg& relCond,
     
    16181637                    return Inst();
    16191638                case Arg::Width32:
    1620                     if (isValidForm(config.moveConditionally32, Arg::RelCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) {
    1621                         return Inst(
    1622                             config.moveConditionally32, m_value, relCond,
    1623                             left.consume(*this), right.consume(*this), config.source, config.destination);
    1624                     }
    1625                     return Inst();
     1639                    return createSelectInstruction(config.moveConditionally32, relCond, left, right);
    16261640                case Arg::Width64:
    1627                     if (isValidForm(config.moveConditionally64, Arg::RelCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) {
    1628                         return Inst(
    1629                             config.moveConditionally64, m_value, relCond,
    1630                             left.consume(*this), right.consume(*this), config.source, config.destination);
    1631                     }
    1632                     return Inst();
     1641                    return createSelectInstruction(config.moveConditionally64, relCond, left, right);
    16331642                }
    16341643                ASSERT_NOT_REACHED();
     
    16451654                    return Inst();
    16461655                case Arg::Width32:
    1647                     if (isValidForm(config.moveConditionallyTest32, Arg::ResCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) {
    1648                         return Inst(
    1649                             config.moveConditionallyTest32, m_value, resCond,
    1650                             left.consume(*this), right.consume(*this), config.source, config.destination);
    1651                     }
    1652                     return Inst();
     1656                    return createSelectInstruction(config.moveConditionallyTest32, resCond, left, right);
    16531657                case Arg::Width64:
    1654                     if (isValidForm(config.moveConditionallyTest64, Arg::ResCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) {
    1655                         return Inst(
    1656                             config.moveConditionallyTest64, m_value, resCond,
    1657                             left.consume(*this), right.consume(*this), config.source, config.destination);
    1658                     }
    1659                     return Inst();
     1658                    return createSelectInstruction(config.moveConditionallyTest64, resCond, left, right);
    16601659                }
    16611660                ASSERT_NOT_REACHED();
    16621661            },
    16631662            [&] (Arg doubleCond, const ArgPromise& left, const ArgPromise& right) -> Inst {
    1664                 if (isValidForm(config.moveConditionallyDouble, Arg::DoubleCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) {
    1665                     return Inst(
    1666                         config.moveConditionallyDouble, m_value, doubleCond,
    1667                         left.consume(*this), right.consume(*this), config.source, config.destination);
    1668                 }
    1669                 return Inst();
     1663                return createSelectInstruction(config.moveConditionallyDouble, doubleCond, left, right);
    16701664            },
    16711665            [&] (Arg doubleCond, const ArgPromise& left, const ArgPromise& right) -> Inst {
    1672                 if (isValidForm(config.moveConditionallyFloat, Arg::DoubleCond, left.kind(), right.kind(), Arg::Tmp, Arg::Tmp)) {
    1673                     return Inst(
    1674                         config.moveConditionallyFloat, m_value, doubleCond,
    1675                         left.consume(*this), right.consume(*this), config.source, config.destination);
    1676                 }
    1677                 return Inst();
     1666                return createSelectInstruction(config.moveConditionallyFloat, doubleCond, left, right);
    16781667            },
    1679             inverted);
     1668            false);
    16801669    }
    16811670
     
    20282017
    20292018        case Select: {
    2030             Tmp result = tmp(m_value);
    2031             append(relaxedMoveForType(m_value->type()), tmp(m_value->child(2)), result);
    2032 
    20332019            MoveConditionallyConfig config;
    2034             config.source = tmp(m_value->child(1));
    2035             config.destination = result;
    2036 
    20372020            if (isInt(m_value->type())) {
    20382021                config.moveConditionally32 = MoveConditionally32;
     
    20522035            }
    20532036           
    2054             m_insts.last().append(createSelect(m_value->child(0), config));
     2037            m_insts.last().append(createSelect(config));
    20552038            return;
    20562039        }
  • trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h

    r196573 r196799  
    197197            return 3;
    198198        break;
     199    case MoveConditionally32:
     200    case MoveConditionally64:
     201    case MoveConditionallyTest32:
     202    case MoveConditionallyTest64:
     203    case MoveConditionallyDouble:
     204    case MoveConditionallyFloat:
     205        if (args.size() == 6)
     206            return 5;
     207        break;
     208        break;
    199209    case Patch:
    200210        return PatchCustom::shouldTryAliasingDef(*this);
  • trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes

    r196736 r196799  
    714714    RelCond, Tmp, Tmp, Tmp, Tmp
    715715
     716MoveConditionally32 U:G:32, U:G:32, U:G:32, U:G:Ptr, U:G:Ptr, D:G:Ptr
     717    RelCond, Tmp, Tmp, Tmp, Tmp, Tmp
     718
    71671964: MoveConditionally64 U:G:32, U:G:64, U:G:64, U:G:Ptr, UD:G:Ptr
    717720    RelCond, Tmp, Tmp, Tmp, Tmp
     721
     72264: MoveConditionally64 U:G:32, U:G:64, U:G:64, U:G:Ptr, U:G:Ptr, D:G:Ptr
     723    RelCond, Tmp, Tmp, Tmp, Tmp, Tmp
    718724
    719725MoveConditionallyTest32 U:G:32, U:G:32, U:G:32, U:G:Ptr, UD:G:Ptr
     
    721727    x86: ResCond, Tmp, Imm, Tmp, Tmp
    722728
     729MoveConditionallyTest32 U:G:32, U:G:32, U:G:32, U:G:Ptr, U:G:Ptr, D:G:Ptr
     730    ResCond, Tmp, Tmp, Tmp, Tmp, Tmp
     731    x86: ResCond, Tmp, Imm, Tmp, Tmp, Tmp
     732
    72373364: MoveConditionallyTest64 U:G:32, U:G:64, U:G:64, U:G:Ptr, UD:G:Ptr
    724734    ResCond, Tmp, Tmp, Tmp, Tmp
    725735    x86: ResCond, Tmp, Imm, Tmp, Tmp
    726736
     73764: MoveConditionallyTest64 U:G:32, U:G:32, U:G:32, U:G:Ptr, U:G:Ptr, D:G:Ptr
     738    ResCond, Tmp, Tmp, Tmp, Tmp, Tmp
     739    x86_64: ResCond, Tmp, Imm, Tmp, Tmp, Tmp
     740
     741MoveConditionallyDouble U:G:32, U:F:64, U:F:64, U:G:Ptr, U:G:Ptr, D:G:Ptr
     742    DoubleCond, Tmp, Tmp, Tmp, Tmp, Tmp
     743
    727744MoveConditionallyDouble U:G:32, U:F:64, U:F:64, U:G:Ptr, UD:G:Ptr
    728745    DoubleCond, Tmp, Tmp, Tmp, Tmp
     746
     747MoveConditionallyFloat U:G:32, U:F:32, U:F:32, U:G:Ptr, U:G:Ptr, D:G:Ptr
     748    DoubleCond, Tmp, Tmp, Tmp, Tmp, Tmp
    729749
    730750MoveConditionallyFloat U:G:32, U:F:32, U:F:32, U:G:Ptr, UD:G:Ptr
Note: See TracChangeset for help on using the changeset viewer.