Title: [280849] branches/safari-611.3.10.0-branch
Revision
280849
Author
[email protected]
Date
2021-08-10 10:08:20 -0700 (Tue, 10 Aug 2021)

Log Message

Cherry-pick r280507. rdar://problem/79730568

    Improve OSR entry into Wasm loops with arguments
    https://bugs.webkit.org/show_bug.cgi?id=228595

    Reviewed by Yusuke Suzuki.

    JSTests:

    Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
    100k iterations was not enough to reliably complete an OSR entry.

    * wasm/stress/osr-entry-with-loop-arguments.js: Added.
    (async test):

    Source/_javascript_Core:

    This patch has two parts:
    - improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
    - improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks.
      Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).

    * b3/B3Validate.cpp:
    * wasm/WasmAirIRGenerator.cpp:
    (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
    (JSC::Wasm::AirIRGenerator::addLoop):
    * wasm/WasmB3IRGenerator.cpp:
    (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
    (JSC::Wasm::B3IRGenerator::addLoop):
    * wasm/WasmLLIntGenerator.cpp:
    (JSC::Wasm::LLIntGenerator::addLoop):

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-611.3.10.0-branch/JSTests/ChangeLog (280848 => 280849)


--- branches/safari-611.3.10.0-branch/JSTests/ChangeLog	2021-08-10 17:08:15 UTC (rev 280848)
+++ branches/safari-611.3.10.0-branch/JSTests/ChangeLog	2021-08-10 17:08:20 UTC (rev 280849)
@@ -1,5 +1,55 @@
 2021-08-10  Russell Epstein  <[email protected]>
 
+        Cherry-pick r280507. rdar://problem/79730568
+
+    Improve OSR entry into Wasm loops with arguments
+    https://bugs.webkit.org/show_bug.cgi?id=228595
+    
+    Reviewed by Yusuke Suzuki.
+    
+    JSTests:
+    
+    Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
+    100k iterations was not enough to reliably complete an OSR entry.
+    
+    * wasm/stress/osr-entry-with-loop-arguments.js: Added.
+    (async test):
+    
+    Source/_javascript_Core:
+    
+    This patch has two parts:
+    - improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
+    - improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks.
+      Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).
+    
+    * b3/B3Validate.cpp:
+    * wasm/WasmAirIRGenerator.cpp:
+    (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
+    (JSC::Wasm::AirIRGenerator::addLoop):
+    * wasm/WasmB3IRGenerator.cpp:
+    (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
+    (JSC::Wasm::B3IRGenerator::addLoop):
+    * wasm/WasmLLIntGenerator.cpp:
+    (JSC::Wasm::LLIntGenerator::addLoop):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-07-30  Robin Morisset  <[email protected]>
+
+            Improve OSR entry into Wasm loops with arguments
+            https://bugs.webkit.org/show_bug.cgi?id=228595
+
+            Reviewed by Yusuke Suzuki.
+
+            Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
+            100k iterations was not enough to reliably complete an OSR entry.
+
+            * wasm/stress/osr-entry-with-loop-arguments.js: Added.
+            (async test):
+
+2021-08-10  Russell Epstein  <[email protected]>
+
         Cherry-pick r275472. rdar://problem/81710596
 
     DFG arity fixup nodes should exit to the caller's call opcode

Added: branches/safari-611.3.10.0-branch/JSTests/wasm/stress/osr-entry-with-loop-arguments.js (0 => 280849)


--- branches/safari-611.3.10.0-branch/JSTests/wasm/stress/osr-entry-with-loop-arguments.js	                        (rev 0)
+++ branches/safari-611.3.10.0-branch/JSTests/wasm/stress/osr-entry-with-loop-arguments.js	2021-08-10 17:08:20 UTC (rev 280849)
@@ -0,0 +1,29 @@
+import * as assert from '../assert.js';
+import { instantiate } from "../wabt-wrapper.js";
+
+let wat = `
+(module
+  (func (export "test") (param $countArg i32) (result i32) (local $result i32)
+    i32.const 0
+    (loop (param i32) (result i32)
+      i32.const 1
+      i32.add
+      local.tee $result
+      local.get $result
+      local.get $countArg
+      i32.lt_u
+      br_if 0
+    )
+  )
+)
+`;
+
+async function test() {
+    let instance = await instantiate(wat);
+
+    let result = instance.exports.test(1000000);
+    if (result !== 1000000)
+        throw new Error("Expected 100000, but got: " + result);
+}
+
+assert.asyncTest(test());

Modified: branches/safari-611.3.10.0-branch/Source/_javascript_Core/ChangeLog (280848 => 280849)


--- branches/safari-611.3.10.0-branch/Source/_javascript_Core/ChangeLog	2021-08-10 17:08:15 UTC (rev 280848)
+++ branches/safari-611.3.10.0-branch/Source/_javascript_Core/ChangeLog	2021-08-10 17:08:20 UTC (rev 280849)
@@ -1,5 +1,64 @@
 2021-08-10  Russell Epstein  <[email protected]>
 
+        Cherry-pick r280507. rdar://problem/79730568
+
+    Improve OSR entry into Wasm loops with arguments
+    https://bugs.webkit.org/show_bug.cgi?id=228595
+    
+    Reviewed by Yusuke Suzuki.
+    
+    JSTests:
+    
+    Just a straightforward test that counts to 1M in a loop, to exercise both OSR entry and a loop with an argument at the same time.
+    100k iterations was not enough to reliably complete an OSR entry.
+    
+    * wasm/stress/osr-entry-with-loop-arguments.js: Added.
+    (async test):
+    
+    Source/_javascript_Core:
+    
+    This patch has two parts:
+    - improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
+    - improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks.
+      Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).
+    
+    * b3/B3Validate.cpp:
+    * wasm/WasmAirIRGenerator.cpp:
+    (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
+    (JSC::Wasm::AirIRGenerator::addLoop):
+    * wasm/WasmB3IRGenerator.cpp:
+    (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
+    (JSC::Wasm::B3IRGenerator::addLoop):
+    * wasm/WasmLLIntGenerator.cpp:
+    (JSC::Wasm::LLIntGenerator::addLoop):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280507 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2021-07-30  Robin Morisset  <[email protected]>
+
+            Improve OSR entry into Wasm loops with arguments
+            https://bugs.webkit.org/show_bug.cgi?id=228595
+
+            Reviewed by Yusuke Suzuki.
+
+            This patch has two parts:
+            - improve the Wasm OSR code to fully support loop arguments (just some plumbing to make sure that the right values are propagated)
+            - improve the B3 validator to fix a hole I noticed while writing the first part: we were not detecting code that introduce Upsilons in the wrong blocks.
+              Naturally, this caused hard to debug issues, as B3 has no well-defined semantics for a Phi that is reached before the corresponding Upsilon(s).
+
+            * b3/B3Validate.cpp:
+            * wasm/WasmAirIRGenerator.cpp:
+            (JSC::Wasm::AirIRGenerator::emitLoopTierUpCheck):
+            (JSC::Wasm::AirIRGenerator::addLoop):
+            * wasm/WasmB3IRGenerator.cpp:
+            (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck):
+            (JSC::Wasm::B3IRGenerator::addLoop):
+            * wasm/WasmLLIntGenerator.cpp:
+            (JSC::Wasm::LLIntGenerator::addLoop):
+
+2021-08-10  Russell Epstein  <[email protected]>
+
         Cherry-pick r275472. rdar://problem/81710596
 
     DFG arity fixup nodes should exit to the caller's call opcode

Modified: branches/safari-611.3.10.0-branch/Source/_javascript_Core/b3/B3Validate.cpp (280848 => 280849)


--- branches/safari-611.3.10.0-branch/Source/_javascript_Core/b3/B3Validate.cpp	2021-08-10 17:08:15 UTC (rev 280848)
+++ branches/safari-611.3.10.0-branch/Source/_javascript_Core/b3/B3Validate.cpp	2021-08-10 17:08:20 UTC (rev 280849)
@@ -572,6 +572,8 @@
                 predecessors.add(predecessor);
             VALIDATE(block->numPredecessors() == predecessors.size(), ("At ", *block));
         }
+
+        validatePhisAreDominatedByUpsilons();
     }
 
 private:
@@ -652,7 +654,51 @@
 
         VALIDATE(memory->offset() >= 0, ("At ", *value));
     }
-    
+
+    // A simple backwards analysis to check that we cannot reach a Phi without going through a corresponding Upsilon
+    // We cannot use the dominator tree, since we are checking that each Phi is dominated by a the set of all of its upsilons, and not by a single node.
+    void validatePhisAreDominatedByUpsilons()
+    {
+        bool changed = true;
+        BitVector blocksToVisit;
+        IndexMap<BasicBlock*, HashSet<Value*>> undominatedPhisAtTail(m_procedure.size());
+        for (BasicBlock* block : m_procedure)
+            blocksToVisit.set(block->index());
+        while (changed) {
+            changed = false;
+            for (BasicBlock* block : m_procedure.blocksInPostOrder()) {
+                if (!blocksToVisit.quickClear(block->index()))
+                    continue;
+                HashSet<Value*> undominatedPhis = undominatedPhisAtTail[block];
+                for (unsigned index = block->size()-1; index--;) {
+                    Value* value = block->at(index);
+                    switch (value->opcode()) {
+                    case Upsilon:
+                        undominatedPhis.remove(value->as<UpsilonValue>()->phi());
+                        break;
+                    case Phi:
+                        VALIDATE(!undominatedPhis.contains(value), ("At ", *value));
+                        undominatedPhis.add(value);
+                        break;
+                    default:
+                        break;
+                    }
+                }
+                for (BasicBlock* predecessor : block->predecessors()) {
+                    bool changedSet = false;
+                    for (Value* phi : undominatedPhis)
+                        changedSet |= undominatedPhisAtTail[predecessor].add(phi).isNewEntry;
+                    if (changedSet) {
+                        blocksToVisit.quickSet(predecessor->index());
+                        changed = true;
+                    }
+                }
+                if (!block->index())
+                    VALIDATE(undominatedPhis.isEmpty(), ("Undominated phi at top of entry block: ", **undominatedPhis.begin()));
+            }
+        }
+    }
+
     NO_RETURN_DUE_TO_CRASH void fail(
         const char* filename, int lineNumber, const char* function, const char* condition,
         CString message)

Modified: branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp (280848 => 280849)


--- branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2021-08-10 17:08:15 UTC (rev 280848)
+++ branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2021-08-10 17:08:20 UTC (rev 280849)
@@ -656,7 +656,7 @@
     void emitThrowException(CCallHelpers&, ExceptionType);
 
     void emitEntryTierUpCheck();
-    void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack);
+    void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack);
 
     void emitWriteBarrierForJSWrapper();
     ExpressionType emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOp);
@@ -2640,7 +2640,7 @@
     emitPatchpoint(patch, Tmp(), countdownPtr);
 }
 
-void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack)
+void AirIRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack)
 {
     uint32_t outerLoopIndex = this->outerLoopIndex();
     m_outerLoops.append(loopIndex);
@@ -2680,6 +2680,8 @@
     }
     for (TypedExpression value : enclosingStack)
         patchArgs.append(ConstrainedTmp(value.value(), B3::ValueRep::ColdAny));
+    for (TypedExpression value : newStack)
+        patchArgs.append(ConstrainedTmp(value.value(), B3::ValueRep::ColdAny));
 
     TierUpCount::TriggerReason* forceEntryTrigger = &(m_tierUp->osrEntryTriggers().last());
     static_assert(!static_cast<uint8_t>(TierUpCount::TriggerReason::DontTrigger), "the JIT code assumes non-zero means 'enter'");
@@ -2731,7 +2733,7 @@
     m_currentBlock->setSuccessors(body);
 
     m_currentBlock = body;
-    emitLoopTierUpCheck(loopIndex, enclosingStack);
+    emitLoopTierUpCheck(loopIndex, enclosingStack, newStack);
 
     return { };
 }

Modified: branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (280848 => 280849)


--- branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2021-08-10 17:08:15 UTC (rev 280848)
+++ branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2021-08-10 17:08:20 UTC (rev 280849)
@@ -295,7 +295,7 @@
     void emitExceptionCheck(CCallHelpers&, ExceptionType);
 
     void emitEntryTierUpCheck();
-    void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack);
+    void emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack);
 
     void emitWriteBarrierForJSWrapper();
     ExpressionType emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOp);
@@ -1808,7 +1808,7 @@
     });
 }
 
-void B3IRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack)
+void B3IRGenerator::emitLoopTierUpCheck(uint32_t loopIndex, const Stack& enclosingStack, const Stack& newStack)
 {
     uint32_t outerLoopIndex = this->outerLoopIndex();
     m_outerLoops.append(loopIndex);
@@ -1835,6 +1835,8 @@
     }
     for (TypedExpression value : enclosingStack)
         stackmap.append(value);
+    for (TypedExpression value : newStack)
+        stackmap.append(value);
 
     PatchpointValue* patch = m_currentBlock->appendNew<PatchpointValue>(m_proc, B3::Void, origin);
     Effects effects = Effects::none();
@@ -1885,19 +1887,14 @@
     BasicBlock* continuation = m_proc.addBlock();
 
     block = ControlData(m_proc, origin(), signature, BlockType::Loop, continuation, body);
-
-    ExpressionList args;
-    {
-        unsigned offset = enclosingStack.size() - signature->argumentCount();
-        for (unsigned i = 0; i < signature->argumentCount(); ++i) {
-            TypedExpression value = enclosingStack.at(offset + i);
-            auto* upsilon = m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), value);
-            Value* phi = block.phis[i];
-            body->append(phi);
-            upsilon->setPhi(phi);
-            newStack.constructAndAppend(value.type(), phi);
-        }
-        enclosingStack.shrink(offset);
+    unsigned offset = enclosingStack.size() - signature->argumentCount();
+    for (unsigned i = 0; i < signature->argumentCount(); ++i) {
+        TypedExpression value = enclosingStack.at(offset + i);
+        auto* upsilon = m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), value);
+        Value* phi = block.phis[i];
+        body->append(phi);
+        upsilon->setPhi(phi);
+        newStack.constructAndAppend(value.type(), phi);
     }
 
     m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body);
@@ -1958,15 +1955,22 @@
             auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack;
             connectControlEntry(data, expressionStack);
         }
+        for (unsigned i = 0; i < signature->argumentCount(); ++i) {
+            TypedExpression value = enclosingStack.at(offset + i);
+            Value* phi = block.phis[i];
+            m_currentBlock->appendNew<UpsilonValue>(m_proc, value->origin(), loadFromScratchBuffer(value->type()), phi);
+        }
+        enclosingStack.shrink(offset);
         connectControlEntry(block, enclosingStack);
 
         m_osrEntryScratchBufferSize = indexInBuffer;
         m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body);
         body->addPredecessor(m_currentBlock);
-    }
+    } else
+        enclosingStack.shrink(offset);
 
     m_currentBlock = body;
-    emitLoopTierUpCheck(loopIndex, enclosingStack);
+    emitLoopTierUpCheck(loopIndex, enclosingStack, newStack);
     return { };
 }
 

Modified: branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmLLIntGenerator.cpp (280848 => 280849)


--- branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmLLIntGenerator.cpp	2021-08-10 17:08:15 UTC (rev 280848)
+++ branches/safari-611.3.10.0-branch/Source/_javascript_Core/wasm/WasmLLIntGenerator.cpp	2021-08-10 17:08:20 UTC (rev 280849)
@@ -885,6 +885,8 @@
     }
     for (TypedExpression _expression_ : enclosingStack)
         osrEntryData.append(_expression_);
+    for (TypedExpression _expression_ : newStack)
+        osrEntryData.append(_expression_);
 
     WasmLoopHint::emit(this);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to