Title: [125823] trunk/Source/_javascript_Core
Revision
125823
Author
[email protected]
Date
2012-08-16 16:17:24 -0700 (Thu, 16 Aug 2012)

Log Message

Structure check hoisting should be less expensive
https://bugs.webkit.org/show_bug.cgi?id=94201

Reviewed by Mark Hahnenberg.

This appears like a broad win on short-running programs.

* dfg/DFGArgumentsSimplificationPhase.cpp:
(JSC::DFG::ArgumentsSimplificationPhase::run):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::performNodeCSE):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::compareAndSwap):
(Graph):
(JSC::DFG::Graph::substitute):
(JSC::DFG::Graph::substituteGetLocal):
* dfg/DFGStructureCheckHoistingPhase.cpp:
(JSC::DFG::StructureCheckHoistingPhase::run):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (125822 => 125823)


--- trunk/Source/_javascript_Core/ChangeLog	2012-08-16 23:11:00 UTC (rev 125822)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-08-16 23:17:24 UTC (rev 125823)
@@ -1,5 +1,28 @@
 2012-08-16  Filip Pizlo  <[email protected]>
 
+        Structure check hoisting should be less expensive
+        https://bugs.webkit.org/show_bug.cgi?id=94201
+
+        Reviewed by Mark Hahnenberg.
+
+        This appears like a broad win on short-running programs.
+
+        * dfg/DFGArgumentsSimplificationPhase.cpp:
+        (JSC::DFG::ArgumentsSimplificationPhase::run):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        * dfg/DFGDriver.cpp:
+        (JSC::DFG::compile):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::compareAndSwap):
+        (Graph):
+        (JSC::DFG::Graph::substitute):
+        (JSC::DFG::Graph::substituteGetLocal):
+        * dfg/DFGStructureCheckHoistingPhase.cpp:
+        (JSC::DFG::StructureCheckHoistingPhase::run):
+
+2012-08-16  Filip Pizlo  <[email protected]>
+
         All op_resolve_global instructions should end up in the list of global resolve instructions
         https://bugs.webkit.org/show_bug.cgi?id=94247
         <rdar://problem/12103500>

Modified: trunk/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp (125822 => 125823)


--- trunk/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp	2012-08-16 23:11:00 UTC (rev 125822)
+++ trunk/Source/_javascript_Core/dfg/DFGArgumentsSimplificationPhase.cpp	2012-08-16 23:17:24 UTC (rev 125823)
@@ -318,6 +318,7 @@
                     break;
                     
                 case CheckStructure:
+                case ForwardCheckStructure:
                 case StructureTransitionWatchpoint:
                     // We don't care about these because if we get uses of the relevant
                     // variable then we can safely get rid of these, too. This of course
@@ -481,6 +482,7 @@
                 }
                     
                 case CheckStructure:
+                case ForwardCheckStructure:
                 case StructureTransitionWatchpoint: {
                     // We can just get rid of this node, if it references a phantom argument.
                     if (!isOKToOptimize(m_graph[node.child1()]))

Modified: trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (125822 => 125823)


--- trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2012-08-16 23:11:00 UTC (rev 125822)
+++ trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2012-08-16 23:17:24 UTC (rev 125823)
@@ -944,7 +944,7 @@
             
         case GetLocal: {
             VariableAccessData* variableAccessData = node.variableAccessData();
-            if (m_fixpointState == FixpointNotConverged && !variableAccessData->isCaptured())
+            if (!variableAccessData->isCaptured())
                 break;
             NodeIndex relevantLocalOp;
             NodeIndex possibleReplacement = getLocalLoadElimination(variableAccessData->local(), relevantLocalOp, variableAccessData->isCaptured());

Modified: trunk/Source/_javascript_Core/dfg/DFGDriver.cpp (125822 => 125823)


--- trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2012-08-16 23:11:00 UTC (rev 125822)
+++ trunk/Source/_javascript_Core/dfg/DFGDriver.cpp	2012-08-16 23:17:24 UTC (rev 125823)
@@ -90,6 +90,7 @@
     validate(dfg);
     performPredictionPropagation(dfg);
     performFixup(dfg);
+    performStructureCheckHoisting(dfg);
     unsigned cnt = 1;
     for (;; ++cnt) {
 #if DFG_ENABLE(DEBUG_VERBOSE)
@@ -106,10 +107,7 @@
         dfg.resetExitStates();
         performFixup(dfg);
     }
-    bool shouldRedoCFA = performStructureCheckHoisting(dfg);
     performCSE(dfg, FixpointConverged);
-    if (shouldRedoCFA)
-        performCFA(dfg);
 #if DFG_ENABLE(DEBUG_VERBOSE)
     dataLog("DFG optimization fixpoint converged in %u iterations.\n", cnt);
 #endif

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (125822 => 125823)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2012-08-16 23:11:00 UTC (rev 125822)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2012-08-16 23:17:24 UTC (rev 125823)
@@ -137,6 +137,20 @@
         edge = newEdge;
     }
     
+    void compareAndSwap(Edge& edge, NodeIndex oldIndex, NodeIndex newIndex, bool changeRef)
+    {
+        if (edge.index() != oldIndex)
+            return;
+        changeIndex(edge, newIndex, changeRef);
+    }
+    
+    void compareAndSwap(Edge& edge, Edge oldEdge, Edge newEdge, bool changeRef)
+    {
+        if (edge != oldEdge)
+            return;
+        changeEdge(edge, newEdge, changeRef);
+    }
+    
     void clearAndDerefChild1(Node& node)
     {
         if (!node.child1())
@@ -614,6 +628,69 @@
         vote(node.child3(), ballot);
     }
     
+    template<typename T> // T = NodeIndex or Edge
+    void substitute(BasicBlock& block, unsigned startIndexInBlock, T oldThing, T newThing)
+    {
+        for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
+            NodeIndex nodeIndex = block[indexInBlock];
+            Node& node = at(nodeIndex);
+            if (node.flags() & NodeHasVarArgs) {
+                for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); ++childIdx)
+                    compareAndSwap(m_varArgChildren[childIdx], oldThing, newThing, node.shouldGenerate());
+                continue;
+            }
+            if (!node.child1())
+                continue;
+            compareAndSwap(node.children.child1(), oldThing, newThing, node.shouldGenerate());
+            if (!node.child2())
+                continue;
+            compareAndSwap(node.children.child2(), oldThing, newThing, node.shouldGenerate());
+            if (!node.child3())
+                continue;
+            compareAndSwap(node.children.child3(), oldThing, newThing, node.shouldGenerate());
+        }
+    }
+    
+    // Use this if you introduce a new GetLocal and you know that you introduced it *before*
+    // any GetLocals in the basic block.
+    // FIXME: it may be appropriate, in the future, to generalize this to handle GetLocals
+    // introduced anywhere in the basic block.
+    void substituteGetLocal(BasicBlock& block, unsigned startIndexInBlock, VariableAccessData* variableAccessData, NodeIndex newGetLocal)
+    {
+        if (variableAccessData->isCaptured()) {
+            // Let CSE worry about this one.
+            return;
+        }
+        for (unsigned indexInBlock = startIndexInBlock; indexInBlock < block.size(); ++indexInBlock) {
+            NodeIndex nodeIndex = block[indexInBlock];
+            Node& node = at(nodeIndex);
+            bool shouldContinue = true;
+            switch (node.op()) {
+            case SetLocal: {
+                if (node.local() == variableAccessData->local())
+                    shouldContinue = false;
+                break;
+            }
+                
+            case GetLocal: {
+                if (node.variableAccessData() != variableAccessData)
+                    continue;
+                substitute(block, indexInBlock, nodeIndex, newGetLocal);
+                NodeIndex oldTailIndex = block.variablesAtTail.operand(variableAccessData->local());
+                if (oldTailIndex == nodeIndex)
+                    block.variablesAtTail.operand(variableAccessData->local()) = newGetLocal;
+                shouldContinue = false;
+                break;
+            }
+                
+            default:
+                break;
+            }
+            if (!shouldContinue)
+                break;
+        }
+    }
+    
     JSGlobalData& m_globalData;
     CodeBlock* m_codeBlock;
     CodeBlock* m_profiledBlock;

Modified: trunk/Source/_javascript_Core/dfg/DFGStructureCheckHoistingPhase.cpp (125822 => 125823)


--- trunk/Source/_javascript_Core/dfg/DFGStructureCheckHoistingPhase.cpp	2012-08-16 23:11:00 UTC (rev 125822)
+++ trunk/Source/_javascript_Core/dfg/DFGStructureCheckHoistingPhase.cpp	2012-08-16 23:17:24 UTC (rev 125823)
@@ -353,6 +353,8 @@
                     if (block->variablesAtTail.operand(variable->local()) == nodeIndex)
                         block->variablesAtTail.operand(variable->local()) = getLocalIndex;
                     
+                    m_graph.substituteGetLocal(*block, indexInBlock, variable, getLocalIndex);
+                    
                     changed = true;
                     break;
                 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to