⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 242866 in webkit


Ignore:
Timestamp:
Mar 13, 2019, 2:24:56 AM (7 years ago)
Author:
Carlos Garcia Campos
Message:

Merge r242569 - Air::reportUsedRegisters must padInterference
https://bugs.webkit.org/show_bug.cgi?id=195303
<rdar://problem/48270343>

Reviewed by Keith Miller.

JSTests:

  • stress/optional-def-arg-width-should-be-both-early-and-late-use.js: Added.

Source/JavaScriptCore:

reportUsedRegisters uses reg liveness to eliminate loads/moves into dead
registers. However, liveness can report incorrect results in certain
scenarios when considering liveness at instruction boundaries. For example,
it can go wrong when an Inst has a LateUse of a register and the following
Inst has an EarlyDef of that same register. Such a scenario could lead us
to incorrectly say the register is not live-in to the first Inst. Pad
interference inserts Nops between such instruction boundaries that cause
this issue.

The test with this patch fixes the issue in reportUsedRegisters. This patch
also conservatively makes it so that lowerAfterRegAlloc calls padInterference
since it also reasons about liveness.

  • b3/air/AirLowerAfterRegAlloc.cpp:

(JSC::B3::Air::lowerAfterRegAlloc):

  • b3/air/AirPadInterference.h:
  • b3/air/AirReportUsedRegisters.cpp:

(JSC::B3::Air::reportUsedRegisters):

  • b3/testb3.cpp:

(JSC::B3::testReportUsedRegistersLateUseNotDead):
(JSC::B3::run):

Location:
releases/WebKitGTK/webkit-2.24
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • releases/WebKitGTK/webkit-2.24/JSTests/ChangeLog

    r242865 r242866  
     12019-03-06  Saam Barati  <sbarati@apple.com>
     2
     3        Air::reportUsedRegisters must padInterference
     4        https://bugs.webkit.org/show_bug.cgi?id=195303
     5        <rdar://problem/48270343>
     6
     7        Reviewed by Keith Miller.
     8
     9        * stress/optional-def-arg-width-should-be-both-early-and-late-use.js: Added.
     10
    1112019-02-28  Yusuke Suzuki  <ysuzuki@apple.com>
    212
  • releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/ChangeLog

    r242865 r242866  
     12019-03-06  Saam Barati  <sbarati@apple.com>
     2
     3        Air::reportUsedRegisters must padInterference
     4        https://bugs.webkit.org/show_bug.cgi?id=195303
     5        <rdar://problem/48270343>
     6
     7        Reviewed by Keith Miller.
     8
     9        reportUsedRegisters uses reg liveness to eliminate loads/moves into dead
     10        registers. However, liveness can report incorrect results in certain
     11        scenarios when considering liveness at instruction boundaries. For example,
     12        it can go wrong when an Inst has a LateUse of a register and the following
     13        Inst has an EarlyDef of that same register. Such a scenario could lead us
     14        to incorrectly say the register is not live-in to the first Inst. Pad
     15        interference inserts Nops between such instruction boundaries that cause
     16        this issue.
     17       
     18        The test with this patch fixes the issue in reportUsedRegisters. This patch
     19        also conservatively makes it so that lowerAfterRegAlloc calls padInterference
     20        since it also reasons about liveness.
     21
     22        * b3/air/AirLowerAfterRegAlloc.cpp:
     23        (JSC::B3::Air::lowerAfterRegAlloc):
     24        * b3/air/AirPadInterference.h:
     25        * b3/air/AirReportUsedRegisters.cpp:
     26        (JSC::B3::Air::reportUsedRegisters):
     27        * b3/testb3.cpp:
     28        (JSC::B3::testReportUsedRegistersLateUseNotDead):
     29        (JSC::B3::run):
     30
    1312019-03-04  Carlos Garcia Campos  <cgarcia@igalia.com>
    232
  • releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp

    r221954 r242866  
    3535#include "AirInsertionSet.h"
    3636#include "AirInstInlines.h"
     37#include "AirPadInterference.h"
    3738#include "AirRegLiveness.h"
    3839#include "AirPhaseScope.h"
     
    7778    if (!haveAnyRelevant)
    7879        return;
     80
     81    padInterference(code);
    7982
    8083    HashMap<Inst*, RegisterSet> usedRegisters;
  • releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/b3/air/AirPadInterference.h

    r207434 r242866  
    3333
    3434// This isn't a phase - it's meant to be a utility that other phases use. Air reasons about liveness by
    35 // reasoning about interference at boundaries between instructions. This can go wrong - for example, a
     35// reasoning about interference at boundaries between instructions. This is convenient because it works
     36// great in the most common case: early uses and late defs. However, this can go wrong - for example, a
    3637// late use in one instruction doesn't actually interfere with an early def of the next instruction, but
    37 // Air thinks that it does. This is convenient because it works great in the most common case: early uses
    38 // and late defs. In practice, only the register allocators need to use this, since only they need to be
    39 // able to color the interference graph using a bounded number of colors.
     38// Air thinks that it does. It can also go wrong by having liveness incorrectly report that something is
     39// dead when it isn't.
    4040//
    4141// See https://bugs.webkit.org/show_bug.cgi?id=163548#c2 for more info.
  • releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp

    r225893 r242866  
    3232#include "AirCode.h"
    3333#include "AirInstInlines.h"
     34#include "AirPadInterference.h"
    3435#include "AirRegLiveness.h"
    3536#include "AirPhaseScope.h"
     
    4243   
    4344    static constexpr bool verbose = false;
     45
     46    padInterference(code);
    4447   
    4548    if (verbose)
  • releases/WebKitGTK/webkit-2.24/Source/JavaScriptCore/b3/testb3.cpp

    r242472 r242866  
    1656116561    demoteValues(proc, valuesToDemote);
    1656216562    validate(proc);
     16563}
     16564
     16565void testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead()
     16566{
     16567    Procedure proc;
     16568    if (proc.optLevel() < 2)
     16569        return;
     16570    BasicBlock* root = proc.addBlock();
     16571
     16572    RegisterSet allRegs = RegisterSet::allGPRs();
     16573    allRegs.exclude(RegisterSet::stackRegisters());
     16574    allRegs.exclude(RegisterSet::reservedHardwareRegisters());
     16575
     16576    {
     16577        // Make every reg 42 (just needs to be a value other than 10).
     16578        PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
     16579        Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
     16580        for (Reg reg : allRegs)
     16581            patchpoint->append(const42, ValueRep::reg(reg));
     16582        patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
     16583    }
     16584
     16585    {
     16586        PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
     16587        Value* const10 = root->appendNew<Const32Value>(proc, Origin(), 10);
     16588        for (Reg reg : allRegs)
     16589            patchpoint->append(const10, ValueRep::lateReg(reg));
     16590        patchpoint->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) {
     16591            for (Reg reg : allRegs) {
     16592                auto done = jit.branch32(CCallHelpers::Equal, reg.gpr(), CCallHelpers::TrustedImm32(10));
     16593                jit.breakpoint();
     16594                done.link(&jit);
     16595            }
     16596        });
     16597    }
     16598
     16599    {
     16600        PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
     16601        patchpoint->resultConstraint = ValueRep::SomeEarlyRegister;
     16602        patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams& params) {
     16603            RELEASE_ASSERT(allRegs.contains(params[0].gpr()));
     16604        });
     16605    }
     16606
     16607    root->appendNewControlValue(proc, Return, Origin());
     16608
     16609    compileAndRun<void>(proc);
    1656316610}
    1656416611
     
    1818918236    }
    1819018237
     18238    RUN(testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead());
     18239
    1819118240    if (tasks.isEmpty())
    1819218241        usage();
Note: See TracChangeset for help on using the changeset viewer.