Title: [242857] branches/safari-607-branch
Revision
242857
Author
[email protected]
Date
2019-03-13 01:24:38 -0700 (Wed, 13 Mar 2019)

Log Message

Cherry-pick r242569. rdar://problem/48839273

    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/_javascript_Core:

    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):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242569 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-607-branch/JSTests/ChangeLog (242856 => 242857)


--- branches/safari-607-branch/JSTests/ChangeLog	2019-03-13 08:24:34 UTC (rev 242856)
+++ branches/safari-607-branch/JSTests/ChangeLog	2019-03-13 08:24:38 UTC (rev 242857)
@@ -1,5 +1,56 @@
 2019-03-13  Babak Shafiei  <[email protected]>
 
+        Cherry-pick r242569. rdar://problem/48839273
+
+    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/_javascript_Core:
+    
+    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):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-03-06  Saam Barati  <[email protected]>
+
+            Air::reportUsedRegisters must padInterference
+            https://bugs.webkit.org/show_bug.cgi?id=195303
+            <rdar://problem/48270343>
+
+            Reviewed by Keith Miller.
+
+            * stress/optional-def-arg-width-should-be-both-early-and-late-use.js: Added.
+
+2019-03-13  Babak Shafiei  <[email protected]>
+
         Cherry-pick r242276. rdar://problem/48839389
 
     DFG: Loop-invariant code motion (LICM) should not hoist dead code

Added: branches/safari-607-branch/JSTests/stress/optional-def-arg-width-should-be-both-early-and-late-use.js (0 => 242857)


--- branches/safari-607-branch/JSTests/stress/optional-def-arg-width-should-be-both-early-and-late-use.js	                        (rev 0)
+++ branches/safari-607-branch/JSTests/stress/optional-def-arg-width-should-be-both-early-and-late-use.js	2019-03-13 08:24:38 UTC (rev 242857)
@@ -0,0 +1,19 @@
+//@ runDefault("--useConcurrentJIT=false", "--thresholdForJITAfterWarmUp=10", "--thresholdForFTLOptimizeAfterWarmUp=1000")
+
+function v0(v1) {
+    function v7(v8) {
+        function v12(v13, v14) {
+            const v16 = v14 - -0x80000000;
+            const v19 = [13.37, 13.37, 13.37];
+            function v20() {
+                return v16;
+            }
+            return v19;
+        }
+        return v8(v12, v1);
+    }
+    const v27 = v7(v7);
+}
+for (let i = 0; i < 100; i++) {
+    v0(i);
+}

Modified: branches/safari-607-branch/Source/_javascript_Core/ChangeLog (242856 => 242857)


--- branches/safari-607-branch/Source/_javascript_Core/ChangeLog	2019-03-13 08:24:34 UTC (rev 242856)
+++ branches/safari-607-branch/Source/_javascript_Core/ChangeLog	2019-03-13 08:24:38 UTC (rev 242857)
@@ -1,5 +1,76 @@
 2019-03-13  Babak Shafiei  <[email protected]>
 
+        Cherry-pick r242569. rdar://problem/48839273
+
+    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/_javascript_Core:
+    
+    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):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242569 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-03-06  Saam Barati  <[email protected]>
+
+            Air::reportUsedRegisters must padInterference
+            https://bugs.webkit.org/show_bug.cgi?id=195303
+            <rdar://problem/48270343>
+
+            Reviewed by Keith Miller.
+
+            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):
+
+2019-03-13  Babak Shafiei  <[email protected]>
+
         Cherry-pick r242276. rdar://problem/48839389
 
     DFG: Loop-invariant code motion (LICM) should not hoist dead code

Modified: branches/safari-607-branch/Source/_javascript_Core/b3/air/AirLowerAfterRegAlloc.cpp (242856 => 242857)


--- branches/safari-607-branch/Source/_javascript_Core/b3/air/AirLowerAfterRegAlloc.cpp	2019-03-13 08:24:34 UTC (rev 242856)
+++ branches/safari-607-branch/Source/_javascript_Core/b3/air/AirLowerAfterRegAlloc.cpp	2019-03-13 08:24:38 UTC (rev 242857)
@@ -34,6 +34,7 @@
 #include "AirEmitShuffle.h"
 #include "AirInsertionSet.h"
 #include "AirInstInlines.h"
+#include "AirPadInterference.h"
 #include "AirRegLiveness.h"
 #include "AirPhaseScope.h"
 #include "B3CCallValue.h"
@@ -77,6 +78,8 @@
     if (!haveAnyRelevant)
         return;
 
+    padInterference(code);
+
     HashMap<Inst*, RegisterSet> usedRegisters;
     
     RegLiveness liveness(code);

Modified: branches/safari-607-branch/Source/_javascript_Core/b3/air/AirPadInterference.h (242856 => 242857)


--- branches/safari-607-branch/Source/_javascript_Core/b3/air/AirPadInterference.h	2019-03-13 08:24:34 UTC (rev 242856)
+++ branches/safari-607-branch/Source/_javascript_Core/b3/air/AirPadInterference.h	2019-03-13 08:24:38 UTC (rev 242857)
@@ -32,11 +32,11 @@
 class Code;
 
 // This isn't a phase - it's meant to be a utility that other phases use. Air reasons about liveness by
-// reasoning about interference at boundaries between instructions. This can go wrong - for example, a
+// reasoning about interference at boundaries between instructions. This is convenient because it works
+// great in the most common case: early uses and late defs. However, this can go wrong - for example, a
 // late use in one instruction doesn't actually interfere with an early def of the next instruction, but
-// Air thinks that it does. This is convenient because it works great in the most common case: early uses
-// and late defs. In practice, only the register allocators need to use this, since only they need to be
-// able to color the interference graph using a bounded number of colors.
+// Air thinks that it does. It can also go wrong by having liveness incorrectly report that something is
+// dead when it isn't.
 //
 // See https://bugs.webkit.org/show_bug.cgi?id=163548#c2 for more info.
 

Modified: branches/safari-607-branch/Source/_javascript_Core/b3/air/AirReportUsedRegisters.cpp (242856 => 242857)


--- branches/safari-607-branch/Source/_javascript_Core/b3/air/AirReportUsedRegisters.cpp	2019-03-13 08:24:34 UTC (rev 242856)
+++ branches/safari-607-branch/Source/_javascript_Core/b3/air/AirReportUsedRegisters.cpp	2019-03-13 08:24:38 UTC (rev 242857)
@@ -31,6 +31,7 @@
 #include "AirArgInlines.h"
 #include "AirCode.h"
 #include "AirInstInlines.h"
+#include "AirPadInterference.h"
 #include "AirRegLiveness.h"
 #include "AirPhaseScope.h"
 
@@ -41,6 +42,8 @@
     PhaseScope phaseScope(code, "reportUsedRegisters");
     
     static constexpr bool verbose = false;
+
+    padInterference(code);
     
     if (verbose)
         dataLog("Doing reportUsedRegisters on:\n", code);

Modified: branches/safari-607-branch/Source/_javascript_Core/b3/testb3.cpp (242856 => 242857)


--- branches/safari-607-branch/Source/_javascript_Core/b3/testb3.cpp	2019-03-13 08:24:34 UTC (rev 242856)
+++ branches/safari-607-branch/Source/_javascript_Core/b3/testb3.cpp	2019-03-13 08:24:38 UTC (rev 242857)
@@ -16280,6 +16280,53 @@
     validate(proc);
 }
 
+void testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead()
+{
+    Procedure proc;
+    if (proc.optLevel() < 2)
+        return;
+    BasicBlock* root = proc.addBlock();
+
+    RegisterSet allRegs = RegisterSet::allGPRs();
+    allRegs.exclude(RegisterSet::stackRegisters());
+    allRegs.exclude(RegisterSet::reservedHardwareRegisters());
+
+    {
+        // Make every reg 42 (just needs to be a value other than 10).
+        PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
+        Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
+        for (Reg reg : allRegs)
+            patchpoint->append(const42, ValueRep::reg(reg));
+        patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
+    }
+
+    {
+        PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
+        Value* const10 = root->appendNew<Const32Value>(proc, Origin(), 10);
+        for (Reg reg : allRegs)
+            patchpoint->append(const10, ValueRep::lateReg(reg));
+        patchpoint->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) {
+            for (Reg reg : allRegs) {
+                auto done = jit.branch32(CCallHelpers::Equal, reg.gpr(), CCallHelpers::TrustedImm32(10));
+                jit.breakpoint();
+                done.link(&jit);
+            }
+        });
+    }
+
+    {
+        PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
+        patchpoint->resultConstraint = ValueRep::SomeEarlyRegister;
+        patchpoint->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams& params) {
+            RELEASE_ASSERT(allRegs.contains(params[0].gpr()));
+        });
+    }
+
+    root->appendNewControlValue(proc, Return, Origin());
+
+    compileAndRun<void>(proc);
+}
+
 // Make sure the compiler does not try to optimize anything out.
 NEVER_INLINE double zero()
 {
@@ -17875,6 +17922,8 @@
         RUN(testTernarySubInstructionSelection(Trunc, Int32, Air::Sub32));
     }
 
+    RUN(testReportUsedRegistersLateUseFollowedByEarlyDefDoesNotMarkUseAsDead());
+
     if (tasks.isEmpty())
         usage();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to