Ignore:
Timestamp:
Mar 4, 2022, 5:16:16 AM (3 years ago)
Author:
Angelos Oikonomopoulos
Message:

[JSC] Improve reuse of known register values on ARMv7
https://bugs.webkit.org/show_bug.cgi?id=237424

Reviewed by Žan Doberšek.

Reduce the generated code size by introducing and pervasively using
setupArmAddress(AbsoluteAddress address, ...). This effectively
replaces sequences of e.g.

movw r6, cst1
movt r6, cst2
strd r0, r1, [r6]

with

strd r0, r1, [r6, offset]

when a close enough address is already available in r6.

While here, change short_move to only emit an add/sub if this results in an
actual reduction in code size. When the add/sub would be neutral,
prefer loading an immediate as that doesn't introduce a data dependency
between the instructions.

This results in a measurable but small (< 1%) reduction in the
generated code size on JS2.

Hat tip to Geza Lore for the suggestions.

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::add32):
(JSC::MacroAssemblerARMv7::add64):
(JSC::MacroAssemblerARMv7::or8):
(JSC::MacroAssemblerARMv7::or16):
(JSC::MacroAssemblerARMv7::or32):
(JSC::MacroAssemblerARMv7::sub32):
(JSC::MacroAssemblerARMv7::load32):
(JSC::MacroAssemblerARMv7::load8):
(JSC::MacroAssemblerARMv7::load16):
(JSC::MacroAssemblerARMv7::store32):
(JSC::MacroAssemblerARMv7::store8):
(JSC::MacroAssemblerARMv7::store16):
(JSC::MacroAssemblerARMv7::storePair32):
(JSC::MacroAssemblerARMv7::short_move):
(JSC::MacroAssemblerARMv7::add32Impl):
(JSC::MacroAssemblerARMv7::branch8):
(JSC::MacroAssemblerARMv7::branchTest32):
(JSC::MacroAssemblerARMv7::branchTest8):
(JSC::MacroAssemblerARMv7::branchTest16):
(JSC::MacroAssemblerARMv7::farJump):
(JSC::MacroAssemblerARMv7::absoluteAddressWithinShortOffset):
(JSC::MacroAssemblerARMv7::setupArmAddress):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h

    r290647 r290828  
    5656
    5757public:
     58    template<typename MacroAssemblerType, typename Condition, typename ...Args>
     59        friend void JSC::MacroAssemblerHelpers::load8OnCondition(MacroAssemblerType&, Condition, Args...);
     60    template<typename MacroAssemblerType, typename Condition, typename ...Args>
     61        friend void JSC::MacroAssemblerHelpers::load16OnCondition(MacroAssemblerType&, Condition, Args...);
     62
    5863#define DUMMY_REGISTER_VALUE(id, name, r, cs) 0,
    5964    static constexpr unsigned numGPRs = std::initializer_list<int>({ FOR_EACH_GP_REGISTER(DUMMY_REGISTER_VALUE) }).size();
     
    188193    void add32(AbsoluteAddress src, RegisterID dest)
    189194    {
    190         load32(src.m_ptr, dataTempRegister);
     195        load32(setupArmAddress(src), dataTempRegister);
    191196        add32(dataTempRegister, dest);
    192197    }
     
    254259    {
    255260        RegisterID scratch = getCachedDataTempRegisterIDAndInvalidate();
    256         move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    257 
    258         m_assembler.ldr(scratch, addressTempRegister, ARMThumbImmediate::makeUInt12(0));
     261
     262        load32(setupArmAddress(address), scratch);
    259263        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
    260264        if (armImm.isValid())
     
    380384    {
    381385        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
     386        load8(setupArmAddress(address), dataTempRegister);
    382387        if (armImm.isValid()) {
    383             move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    384             load8(Address(addressTempRegister), dataTempRegister);
    385388            m_assembler.orr(dataTempRegister, dataTempRegister, armImm);
    386389            store8(dataTempRegister, Address(addressTempRegister));
    387390        } else {
    388             move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    389             load8(Address(addressTempRegister), dataTempRegister);
    390391            move(imm, addressTempRegister);
    391392            m_assembler.orr(dataTempRegister, dataTempRegister, addressTempRegister);
     
    398399    {
    399400        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
     401        load16(setupArmAddress(dest), dataTempRegister);
    400402        if (armImm.isValid()) {
    401             move(TrustedImmPtr(dest.m_ptr), addressTempRegister);
    402             load16(Address(addressTempRegister), dataTempRegister);
    403403            m_assembler.orr(dataTempRegister, dataTempRegister, armImm);
    404404            store16(dataTempRegister, Address(addressTempRegister));
    405405        } else {
    406             move(TrustedImmPtr(dest.m_ptr), addressTempRegister);
    407             load16(Address(addressTempRegister), dataTempRegister);
    408406            move(imm, addressTempRegister);
    409407            m_assembler.orr(dataTempRegister, dataTempRegister, addressTempRegister);
     
    420418    void or32(RegisterID src, AbsoluteAddress dest)
    421419    {
    422         move(TrustedImmPtr(dest.m_ptr), addressTempRegister);
    423         load32(Address(addressTempRegister), dataTempRegister);
     420        load32(setupArmAddress(dest), dataTempRegister);
    424421        or32(src, dataTempRegister);
    425422        store32(dataTempRegister, Address(addressTempRegister));
     
    429426    {
    430427        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
     428        load32(setupArmAddress(address), dataTempRegister);
    431429        if (armImm.isValid()) {
    432             move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    433             load32(Address(addressTempRegister), dataTempRegister);
    434430            m_assembler.orr(dataTempRegister, dataTempRegister, armImm);
    435431            store32(dataTempRegister, Address(addressTempRegister));
    436432        } else {
    437             move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    438             load32(Address(addressTempRegister), dataTempRegister);
    439433            move(imm, addressTempRegister);
    440434            m_assembler.orr(dataTempRegister, dataTempRegister, addressTempRegister);
     
    601595    void sub32(TrustedImm32 imm, AbsoluteAddress address)
    602596    {
    603         load32(address.m_ptr, dataTempRegister);
     597        load32(setupArmAddress(address), dataTempRegister);
    604598
    605599        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
     
    815809    void load32(const void* address, RegisterID dest)
    816810    {
    817         move(TrustedImmPtr(address), addressTempRegister);
    818         m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
    819         cachedAddressTempRegister().invalidate();
    820     }
    821    
     811        load32(setupArmAddress(AbsoluteAddress(address)), dest);
     812    }
     813
    822814    void abortWithReason(AbortReason reason)
    823815    {
     
    862854    void load8(const void* address, RegisterID dest)
    863855    {
    864         move(TrustedImmPtr(address), dest);
    865         load8(Address(dest), dest);
     856        load8(setupArmAddress(AbsoluteAddress(address), dest), dest);
    866857    }
    867858
    868859    void load16(const void* address, RegisterID dest)
    869860    {
    870         move(TrustedImmPtr(address), addressTempRegister);
    871         m_assembler.ldrh(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
     861        load16(setupArmAddress(AbsoluteAddress(address), dest), dest);
    872862    }
    873863
     
    973963    void store32(RegisterID src, const void* address)
    974964    {
    975         move(TrustedImmPtr(address), addressTempRegister);
    976         m_assembler.str(src, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
     965        store32(src, setupArmAddress(AbsoluteAddress(address)));
    977966    }
    978967
     
    995984    void store8(RegisterID src, const void *address)
    996985    {
    997         RegisterID scratch = getCachedAddressTempRegisterIDAndInvalidate();
    998         move(TrustedImmPtr(address), scratch);
    999         store8(src, ArmAddress(scratch, 0));
     986        store8(src, setupArmAddress(AbsoluteAddress(address)));
    1000987    }
    1001988   
     
    10311018    void store16(RegisterID src, const void* address)
    10321019    {
    1033         move(TrustedImmPtr(address), addressTempRegister);
    1034         m_assembler.strh(src, addressTempRegister, ARMThumbImmediate::makeUInt12(0));
     1020        store16(src, setupArmAddress(AbsoluteAddress(address)));
    10351021    }
    10361022
     
    10801066    void storePair32(RegisterID src1, RegisterID src2, const void* address)
    10811067    {
    1082         move(TrustedImmPtr(address), addressTempRegister);
    1083         storePair32(src1, src2, addressTempRegister);
     1068        ArmAddress armAddress = setupArmAddress(AbsoluteAddress(address));
     1069        ASSERT(armAddress.type == ArmAddress::HasOffset);
     1070        storePair32(src1, src2, Address(armAddress.base, armAddress.u.offset));
    10841071    }
    10851072
     
    15591546            }
    15601547            ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(valueDelta);
    1561             if (armImm.isValid()) {
     1548            // Only use an add/sub if it results in a shorter instruction,
     1549            // otherwise we introduce a data dependency for no gain.
     1550            if (armImm.isValid() && armImm.isUInt8()) {
    15621551                if (valueDeltaSave > 0)
    15631552                    m_assembler.add(dest, dest, armImm);
     
    17491738    void add32Impl(TrustedImm32 imm, AbsoluteAddress address, bool updateFlags = false)
    17501739    {
    1751         load32(address.m_ptr, dataTempRegister);
     1740        load32(setupArmAddress(address), dataTempRegister);
    17521741
    17531742        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
     
    19011890        // Use addressTempRegister instead of dataTempRegister, since branch32 uses dataTempRegister.
    19021891        TrustedImm32 right8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, right);
    1903         move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    1904         MacroAssemblerHelpers::load8OnCondition(*this, cond, Address(addressTempRegister), addressTempRegister);
     1892        ArmAddress armAddress = setupArmAddress(address);
     1893        MacroAssemblerHelpers::load8OnCondition(*this, cond, armAddress, addressTempRegister);
    19051894        return branch32(cond, addressTempRegister, right8);
    19061895    }
     
    19371926    {
    19381927        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
    1939         move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    1940         load32(Address(addressTempRegister), addressTempRegister);
     1928        load32(setupArmAddress(address), addressTempRegister);
    19411929        return branchTest32(cond, addressTempRegister, mask);
    19421930    }
     
    19641952        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
    19651953        TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask);
    1966         move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    1967         MacroAssemblerHelpers::load8OnCondition(*this, cond, Address(addressTempRegister), addressTempRegister);
     1954        ArmAddress armAddress = setupArmAddress(address);
     1955        MacroAssemblerHelpers::load8OnCondition(*this, cond, armAddress, addressTempRegister);
    19681956        return branchTest32(cond, addressTempRegister, mask8);
    19691957    }
     
    19911979        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
    19921980        TrustedImm32 mask16 = MacroAssemblerHelpers::mask16OnCondition(*this, cond, mask);
    1993         move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    1994         MacroAssemblerHelpers::load16OnCondition(*this, cond, Address(addressTempRegister), addressTempRegister);
     1981        ArmAddress armAddress = setupArmAddress(address);
     1982        MacroAssemblerHelpers::load16OnCondition(*this, cond, armAddress, addressTempRegister);
    19951983        return branchTest32(cond, addressTempRegister, mask16);
    19961984    }
     
    20212009    void farJump(AbsoluteAddress address, PtrTag)
    20222010    {
    2023         move(TrustedImmPtr(address.m_ptr), addressTempRegister);
    2024         load32(Address(addressTempRegister), addressTempRegister);
     2011        load32(setupArmAddress(address), addressTempRegister);
    20252012        cachedDataTempRegister().invalidate();
    20262013        m_assembler.bx(addressTempRegister);
     
    24932480    }
    24942481
     2482    std::optional<int32_t> absoluteAddressWithinShortOffset(AbsoluteAddress address, CachedTempRegister &cachedRegister)
     2483    {
     2484        intptr_t addressAsInt = reinterpret_cast<uintptr_t>(address.m_ptr);
     2485        intptr_t currentRegisterContents;
     2486        if (cachedRegister.value(currentRegisterContents)) {
     2487            intptr_t addressDelta = addressAsInt - currentRegisterContents;
     2488            if ((addressDelta >= -0xff) && (addressDelta <= 0xfff))
     2489                return reinterpret_cast<int32_t>(addressDelta);
     2490        }
     2491        return { };
     2492    }
     2493
     2494    ArmAddress setupArmAddress(AbsoluteAddress address, RegisterID scratch = addressTempRegister)
     2495    {
     2496        if (auto offset = absoluteAddressWithinShortOffset(address, cachedAddressTempRegister()))
     2497            return ArmAddress(addressTempRegister, *offset);
     2498        if (auto offset = absoluteAddressWithinShortOffset(address, cachedDataTempRegister()))
     2499            return ArmAddress(dataTempRegister, *offset);
     2500        move(TrustedImmPtr(address.m_ptr), scratch);
     2501        return ArmAddress(scratch);
     2502    }
     2503
    24952504    RegisterID makeBaseIndexBase(BaseIndex address)
    24962505    {
Note: See TracChangeset for help on using the changeset viewer.