Title: [160348] trunk/Source/_javascript_Core
Revision
160348
Author
fpi...@apple.com
Date
2013-12-09 21:52:24 -0800 (Mon, 09 Dec 2013)

Log Message

Impose and enforce some basic rules of sanity for where Phi functions are allowed to occur and where their (optional) corresponding MovHints can be
https://bugs.webkit.org/show_bug.cgi?id=125480

Reviewed by Geoffrey Garen.
        
Previously, if you wanted to insert some speculation right after where a value was
produced, you'd get super confused if that value was produced by a Phi node.  You can't
necessarily insert speculations after a Phi node because Phi nodes appear in this
special sequence of Phis and MovHints that establish the OSR exit state for a block.
So, you'd probably want to search for the next place where it's safe to insert things.
We already do this "search for beginning of next bytecode instruction" search by
looking at the next node that has a different CodeOrigin.  But this would be hard for a
Phi because those Phis and MovHints have basically random CodeOrigins and they can all
have different CodeOrigins.

This change imposes some sanity for this situation:

- Phis must have unset CodeOrigins.

- In each basic block, all nodes that have unset CodeOrigins must come before all nodes
  that have set CodeOrigins.

This all ends up working out just great because prior to this change we didn't have a 
use for unset CodeOrigins.  I think it's appropriate to make "unset CodeOrigin" mean
that we're in the prologue of a basic block.

It's interesting what this means for block merging, which we don't yet do in SSA.
Consider merging the edge A->B.  One possibility is that the block merger is now
required to clean up Phi/Upsilons, and reascribe the MovHints to have the CodeOrigin of
the A's block terminal.  But an answer that might be better is that the originless
nodes at the top of the B are just given the origin of the terminal and we keep the
Phis.  That would require changing the above rules.  We'll see how it goes, and what we
end up picking...

Overall, this special-things-at-the-top rule is analogous to what other SSA-based
compilers do.  For example, LLVM has rules mandating that Phis appear at the top of a
block.

* bytecode/CodeOrigin.cpp:
(JSC::CodeOrigin::dump):
* dfg/DFGOSRExitBase.h:
(JSC::DFG::OSRExitBase::OSRExitBase):
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
(JSC::DFG::Validate::validateSSA):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (160347 => 160348)


--- trunk/Source/_javascript_Core/ChangeLog	2013-12-10 03:24:31 UTC (rev 160347)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-12-10 05:52:24 UTC (rev 160348)
@@ -1,3 +1,53 @@
+2013-12-09  Filip Pizlo  <fpi...@apple.com>
+
+        Impose and enforce some basic rules of sanity for where Phi functions are allowed to occur and where their (optional) corresponding MovHints can be
+        https://bugs.webkit.org/show_bug.cgi?id=125480
+
+        Reviewed by Geoffrey Garen.
+        
+        Previously, if you wanted to insert some speculation right after where a value was
+        produced, you'd get super confused if that value was produced by a Phi node.  You can't
+        necessarily insert speculations after a Phi node because Phi nodes appear in this
+        special sequence of Phis and MovHints that establish the OSR exit state for a block.
+        So, you'd probably want to search for the next place where it's safe to insert things.
+        We already do this "search for beginning of next bytecode instruction" search by
+        looking at the next node that has a different CodeOrigin.  But this would be hard for a
+        Phi because those Phis and MovHints have basically random CodeOrigins and they can all
+        have different CodeOrigins.
+
+        This change imposes some sanity for this situation:
+
+        - Phis must have unset CodeOrigins.
+
+        - In each basic block, all nodes that have unset CodeOrigins must come before all nodes
+          that have set CodeOrigins.
+
+        This all ends up working out just great because prior to this change we didn't have a 
+        use for unset CodeOrigins.  I think it's appropriate to make "unset CodeOrigin" mean
+        that we're in the prologue of a basic block.
+
+        It's interesting what this means for block merging, which we don't yet do in SSA.
+        Consider merging the edge A->B.  One possibility is that the block merger is now
+        required to clean up Phi/Upsilons, and reascribe the MovHints to have the CodeOrigin of
+        the A's block terminal.  But an answer that might be better is that the originless
+        nodes at the top of the B are just given the origin of the terminal and we keep the
+        Phis.  That would require changing the above rules.  We'll see how it goes, and what we
+        end up picking...
+
+        Overall, this special-things-at-the-top rule is analogous to what other SSA-based
+        compilers do.  For example, LLVM has rules mandating that Phis appear at the top of a
+        block.
+
+        * bytecode/CodeOrigin.cpp:
+        (JSC::CodeOrigin::dump):
+        * dfg/DFGOSRExitBase.h:
+        (JSC::DFG::OSRExitBase::OSRExitBase):
+        * dfg/DFGSSAConversionPhase.cpp:
+        (JSC::DFG::SSAConversionPhase::run):
+        * dfg/DFGValidate.cpp:
+        (JSC::DFG::Validate::validate):
+        (JSC::DFG::Validate::validateSSA):
+
 2013-12-08  Filip Pizlo  <fpi...@apple.com>
 
         Reveal array bounds checks in DFG IR

Modified: trunk/Source/_javascript_Core/bytecode/CodeOrigin.cpp (160347 => 160348)


--- trunk/Source/_javascript_Core/bytecode/CodeOrigin.cpp	2013-12-10 03:24:31 UTC (rev 160347)
+++ trunk/Source/_javascript_Core/bytecode/CodeOrigin.cpp	2013-12-10 05:52:24 UTC (rev 160348)
@@ -59,6 +59,11 @@
 
 void CodeOrigin::dump(PrintStream& out) const
 {
+    if (!isSet()) {
+        out.print("<none>");
+        return;
+    }
+    
     Vector<CodeOrigin> stack = inlineStack();
     for (unsigned i = 0; i < stack.size(); ++i) {
         if (i)

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitBase.h (160347 => 160348)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitBase.h	2013-12-10 03:24:31 UTC (rev 160347)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitBase.h	2013-12-10 05:52:24 UTC (rev 160348)
@@ -48,6 +48,8 @@
         , m_codeOrigin(origin)
         , m_codeOriginForExitProfile(originForProfile)
     {
+        ASSERT(m_codeOrigin.isSet());
+        ASSERT(m_codeOriginForExitProfile.isSet());
     }
     
     ExitKind m_kind;

Modified: trunk/Source/_javascript_Core/dfg/DFGSSAConversionPhase.cpp (160347 => 160348)


--- trunk/Source/_javascript_Core/dfg/DFGSSAConversionPhase.cpp	2013-12-10 03:24:31 UTC (rev 160347)
+++ trunk/Source/_javascript_Core/dfg/DFGSSAConversionPhase.cpp	2013-12-10 05:52:24 UTC (rev 160348)
@@ -151,7 +151,7 @@
                         NodeFlags result = resultFor(format);
                         UseKind useKind = useKindFor(format);
                         
-                        node = m_insertionSet.insertNode(0, SpecNone, Phi, node->codeOrigin);
+                        node = m_insertionSet.insertNode(0, SpecNone, Phi, CodeOrigin());
                         node->mergeFlags(result);
                         RELEASE_ASSERT((node->flags() & NodeResultMask) == result);
                         
@@ -184,7 +184,7 @@
                             // the value was already on the stack.
                         } else {
                             m_insertionSet.insertNode(
-                                0, SpecNone, MovHint, node->codeOrigin, OpInfo(variable),
+                                0, SpecNone, MovHint, CodeOrigin(), OpInfo(variable),
                                 Edge(node));
                         }
                     }

Modified: trunk/Source/_javascript_Core/dfg/DFGValidate.cpp (160347 => 160348)


--- trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2013-12-10 03:24:31 UTC (rev 160347)
+++ trunk/Source/_javascript_Core/dfg/DFGValidate.cpp	2013-12-10 05:52:24 UTC (rev 160348)
@@ -191,7 +191,7 @@
             break;
             
         case SSA:
-            // FIXME: Implement SSA verification.
+            validateSSA();
             break;
         }
     }
@@ -398,6 +398,40 @@
         }
     }
     
+    void validateSSA()
+    {
+        // FIXME: Add more things here.
+        // https://bugs.webkit.org/show_bug.cgi?id=123471
+        
+        for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            
+            unsigned nodeIndex = 0;
+            for (; nodeIndex < block->size() && !block->at(nodeIndex)->codeOrigin.isSet(); nodeIndex++) { }
+            
+            VALIDATE((block), nodeIndex < block->size());
+            
+            for (; nodeIndex < block->size(); nodeIndex++)
+                VALIDATE((block->at(nodeIndex)), block->at(nodeIndex)->codeOrigin.isSet());
+            
+            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
+                Node* node = block->at(nodeIndex);
+                switch (node->op()) {
+                case Phi:
+                    VALIDATE((node), !node->codeOrigin.isSet());
+                    break;
+                    
+                default:
+                    // FIXME: Add more things here.
+                    // https://bugs.webkit.org/show_bug.cgi?id=123471
+                    break;
+                }
+            }
+        }
+    }
+    
     void checkOperand(
         BasicBlock* block, Operands<size_t>& getLocalPositions,
         Operands<size_t>& setLocalPositions, VirtualRegister operand)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to