Title: [160295] trunk/Source/_javascript_Core
Revision
160295
Author
[email protected]
Date
2013-12-08 17:08:53 -0800 (Sun, 08 Dec 2013)

Log Message

Add the notion of ConstantStoragePointer to DFG IR
https://bugs.webkit.org/show_bug.cgi?id=125395

Reviewed by Oliver Hunt.
        
This pushes more typed array folding into StrengthReductionPhase, and enables CSE on
storage pointers. Previously, you might have separate nodes for the same storage
pointer and this would cause some bad register pressure in the DFG. Note that this
was really a theoretical problem and not, to my knowledge a practical one - so this
patch is basically just a clean-up.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::::executeEffects):
* dfg/DFGCSEPhase.cpp:
(JSC::DFG::CSEPhase::constantStoragePointerCSE):
(JSC::DFG::CSEPhase::performNodeCSE):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToConstantStoragePointer):
(JSC::DFG::Node::hasStoragePointer):
(JSC::DFG::Node::storagePointer):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileConstantStoragePointer):
(JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
(JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant):
(JSC::DFG::StrengthReductionPhase::prepareToFoldTypedArray):
* dfg/DFGWatchpointCollectionPhase.cpp:
(JSC::DFG::WatchpointCollectionPhase::handle):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileConstantStoragePointer):
(JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (160294 => 160295)


--- trunk/Source/_javascript_Core/ChangeLog	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-12-09 01:08:53 UTC (rev 160295)
@@ -1,5 +1,57 @@
 2013-12-08  Filip Pizlo  <[email protected]>
 
+        Add the notion of ConstantStoragePointer to DFG IR
+        https://bugs.webkit.org/show_bug.cgi?id=125395
+
+        Reviewed by Oliver Hunt.
+        
+        This pushes more typed array folding into StrengthReductionPhase, and enables CSE on
+        storage pointers. Previously, you might have separate nodes for the same storage
+        pointer and this would cause some bad register pressure in the DFG. Note that this
+        was really a theoretical problem and not, to my knowledge a practical one - so this
+        patch is basically just a clean-up.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::::executeEffects):
+        * dfg/DFGCSEPhase.cpp:
+        (JSC::DFG::CSEPhase::constantStoragePointerCSE):
+        (JSC::DFG::CSEPhase::performNodeCSE):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::convertToConstantStoragePointer):
+        (JSC::DFG::Node::hasStoragePointer):
+        (JSC::DFG::Node::storagePointer):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileConstantStoragePointer):
+        (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        (JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant):
+        (JSC::DFG::StrengthReductionPhase::prepareToFoldTypedArray):
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileConstantStoragePointer):
+        (JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):
+
+2013-12-08  Filip Pizlo  <[email protected]>
+
         FTL should support UntypedUse versions of Compare nodes
         https://bugs.webkit.org/show_bug.cgi?id=125426
 

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2013-12-09 01:08:53 UTC (rev 160295)
@@ -1440,7 +1440,8 @@
         m_state.setHaveStructures(true);
         break;
     }
-    case GetIndexedPropertyStorage: {
+    case GetIndexedPropertyStorage:
+    case ConstantStoragePointer: {
         forNode(node).clear();
         break; 
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -162,6 +162,21 @@
         return 0;
     }
     
+    Node* constantStoragePointerCSE(Node* node)
+    {
+        for (unsigned i = endIndexForPureCSE(); i--;) {
+            Node* otherNode = m_currentBlock->at(i);
+            if (otherNode->op() != ConstantStoragePointer)
+                continue;
+            
+            if (otherNode->storagePointer() != node->storagePointer())
+                continue;
+            
+            return otherNode;
+        }
+        return 0;
+    }
+    
     Node* getCalleeLoadElimination()
     {
         for (unsigned i = m_indexInBlock; i--;) {
@@ -1154,6 +1169,12 @@
             setReplacement(weakConstantCSE(node));
             break;
             
+        case ConstantStoragePointer:
+            if (cseMode == StoreElimination)
+                break;
+            setReplacement(constantStoragePointerCSE(node));
+            break;
+            
         case GetArrayLength:
             if (cseMode == StoreElimination)
                 break;

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2013-12-09 01:08:53 UTC (rev 160295)
@@ -116,6 +116,7 @@
     case ExtractOSREntryLocal:
     case Int52ToDouble:
     case Int52ToValue:
+    case ConstantStoragePointer:
         return;
         
     case MovHintAndCheck:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -877,6 +877,10 @@
         case Int52ToValue:
         case InvalidationPoint:
         case CheckArray:
+        case ConstantStoragePointer:
+            // These are just nodes that we don't currently expect to see during fixup.
+            // If we ever wanted to insert them prior to fixup, then we just have to create
+            // fixup rules for them.
             RELEASE_ASSERT_NOT_REACHED();
             break;
 

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -290,6 +290,12 @@
         out.print(comma, "^", node->phi()->index());
     if (node->hasExecutionCounter())
         out.print(comma, RawPointer(node->executionCounter()));
+    if (node->hasVariableWatchpointSet())
+        out.print(comma, RawPointer(node->variableWatchpointSet()));
+    if (node->hasTypedArray())
+        out.print(comma, inContext(JSValue(node->typedArray()), context));
+    if (node->hasStoragePointer())
+        out.print(comma, RawPointer(node->storagePointer()));
     if (op == JSConstant) {
         out.print(comma, "$", node->constantNumber());
         JSValue value = valueOfJSConstant(node);

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2013-12-09 01:08:53 UTC (rev 160295)
@@ -407,6 +407,13 @@
         children.reset();
     }
     
+    void convertToConstantStoragePointer(void* pointer)
+    {
+        ASSERT(op() == GetIndexedPropertyStorage);
+        m_op = ConstantStoragePointer;
+        m_opInfo = bitwise_cast<uintptr_t>(pointer);
+    }
+    
     void convertToGetLocalUnlinked(VirtualRegister local)
     {
         m_op = GetLocalUnlinked;
@@ -982,6 +989,16 @@
     {
         return reinterpret_cast<JSArrayBufferView*>(m_opInfo);
     }
+    
+    bool hasStoragePointer()
+    {
+        return op() == ConstantStoragePointer;
+    }
+    
+    void* storagePointer()
+    {
+        return reinterpret_cast<void*>(m_opInfo);
+    }
 
     bool hasStructureTransitionData()
     {

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2013-12-09 01:08:53 UTC (rev 160295)
@@ -171,6 +171,7 @@
     macro(Arrayify, NodeMustGenerate) \
     macro(ArrayifyToStructure, NodeMustGenerate) \
     macro(GetIndexedPropertyStorage, NodeResultStorage) \
+    macro(ConstantStoragePointer, NodeResultStorage) \
     macro(TypedArrayWatchpoint, NodeMustGenerate) \
     macro(GetByOffset, NodeResultJS) \
     macro(PutByOffset, NodeMustGenerate) \

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -578,6 +578,7 @@
         case NotifyWrite:
         case FunctionReentryWatchpoint:
         case TypedArrayWatchpoint:
+        case ConstantStoragePointer:
             break;
             
         // This gets ignored because it already has a prediction.

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2013-12-09 01:08:53 UTC (rev 160295)
@@ -245,6 +245,7 @@
     case NotifyWrite:
     case FunctionReentryWatchpoint:
     case TypedArrayWatchpoint:
+    case ConstantStoragePointer:
         return true;
         
     case GetByVal:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -4042,26 +4042,16 @@
 #endif
 }
 
-bool SpeculativeJIT::compileConstantIndexedPropertyStorage(Node* node)
+void SpeculativeJIT::compileConstantStoragePointer(Node* node)
 {
-    JSArrayBufferView* view = m_jit.graph().tryGetFoldableViewForChild1(node);
-    if (!view)
-        return false;
-    if (view->mode() == FastTypedArray)
-        return false;
-    
     GPRTemporary storage(this);
     GPRReg storageGPR = storage.gpr();
-    m_jit.move(TrustedImmPtr(view->vector()), storageGPR);
+    m_jit.move(TrustedImmPtr(node->storagePointer()), storageGPR);
     storageResult(storageGPR, node);
-    return true;
 }
 
 void SpeculativeJIT::compileGetIndexedPropertyStorage(Node* node)
 {
-    if (compileConstantIndexedPropertyStorage(node))
-        return;
-    
     SpeculateCellOperand base(this, node->child1());
     GPRReg baseReg = base.gpr();
     

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2013-12-09 01:08:53 UTC (rev 160295)
@@ -2027,7 +2027,7 @@
     void compileArithIMul(Node*);
     void compileArithDiv(Node*);
     void compileArithMod(Node*);
-    bool compileConstantIndexedPropertyStorage(Node*);
+    void compileConstantStoragePointer(Node*);
     void compileGetIndexedPropertyStorage(Node*);
     JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
     void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -3946,6 +3946,11 @@
         break;
     }
 
+    case ConstantStoragePointer: {
+        compileConstantStoragePointer(node);
+        break;
+    }
+        
     case GetTypedArrayByteOffset: {
         compileGetTypedArrayByteOffset(node);
         break;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -4243,6 +4243,11 @@
         break;
     }
         
+    case ConstantStoragePointer: {
+        compileConstantStoragePointer(node);
+        break;
+    }
+        
     case GetTypedArrayByteOffset: {
         compileGetTypedArrayByteOffset(node);
         break;

Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -95,9 +95,22 @@
                 foldTypedArrayPropertyToConstant(view, jsNumber(view->byteOffset()));
             break;
             
-        // FIXME: The constant-folding of GetIndexedPropertyStorage should be expressed
-        // as an IR transformation in this phase.
-        // https://bugs.webkit.org/show_bug.cgi?id=125395
+        case GetIndexedPropertyStorage:
+            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {
+                if (view->mode() != FastTypedArray) {
+                    prepareToFoldTypedArray(view);
+                    m_node->convertToConstantStoragePointer(view->vector());
+                    m_changed = true;
+                    break;
+                } else {
+                    // FIXME: It would be awesome to be able to fold the property storage for
+                    // these GC-allocated typed arrays. For now it doesn't matter because the
+                    // most common use-cases for constant typed arrays involve large arrays with
+                    // aliased buffer views.
+                    // https://bugs.webkit.org/show_bug.cgi?id=125425
+                }
+            }
+            break;
             
         default:
             break;
@@ -106,11 +119,18 @@
     
     void foldTypedArrayPropertyToConstant(JSArrayBufferView* view, JSValue constant)
     {
+        prepareToFoldTypedArray(view);
+        m_graph.convertToConstant(m_node, constant);
+        m_changed = true;
+    }
+    
+    void prepareToFoldTypedArray(JSArrayBufferView* view)
+    {
         m_insertionSet.insertNode(
             m_nodeIndex, SpecNone, TypedArrayWatchpoint, m_node->codeOrigin,
             OpInfo(view));
-        m_graph.convertToConstant(m_node, constant);
-        m_changed = true;
+        m_insertionSet.insertNode(
+            m_nodeIndex, SpecNone, Phantom, m_node->codeOrigin, m_node->children);
     }
     
     InsertionSet m_insertionSet;

Modified: trunk/Source/_javascript_Core/dfg/DFGWatchpointCollectionPhase.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/dfg/DFGWatchpointCollectionPhase.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGWatchpointCollectionPhase.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -138,18 +138,6 @@
             addLazily(m_node->symbolTable()->m_functionEnteredOnce);
             break;
             
-        case GetIndexedPropertyStorage:
-            if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {
-                // FIXME: It would be awesome to be able to fold the property storage for
-                // these GC-allocated typed arrays. For now it doesn't matter because the
-                // most common use-cases for constant typed arrays involve large arrays with
-                // aliased buffer views.
-                if (view->mode() == FastTypedArray)
-                    break;
-                addLazily(view);
-            }
-            break;
-            
         case TypedArrayWatchpoint:
             addLazily(m_node->typedArray());
             break;

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (160294 => 160295)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2013-12-09 01:08:53 UTC (rev 160295)
@@ -343,6 +343,9 @@
         case GetButterfly:
             compileGetButterfly();
             break;
+        case ConstantStoragePointer:
+            compileConstantStoragePointer();
+            break;
         case GetIndexedPropertyStorage:
             compileGetIndexedPropertyStorage();
             break;
@@ -1397,6 +1400,11 @@
         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
     }
     
+    void compileConstantStoragePointer()
+    {
+        setStorage(m_out.constIntPtr(m_node->storagePointer()));
+    }
+    
     void compileGetIndexedPropertyStorage()
     {
         LValue cell = lowCell(m_node->child1());
@@ -1423,13 +1431,6 @@
             return;
         }
         
-        if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node)) {
-            if (view->mode() != FastTypedArray) {
-                setStorage(m_out.constIntPtr(view->vector()));
-                return;
-            }
-        }
-        
         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
     }
     
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to