Title: [152139] branches/dfgFourthTier/Source/_javascript_Core
Revision
152139
Author
fpi...@apple.com
Date
2013-06-27 17:02:12 -0700 (Thu, 27 Jun 2013)

Log Message

fourthTier: DFG should know how to find natural loops
https://bugs.webkit.org/show_bug.cgi?id=118152

Reviewed by Mark Hahnenberg.
        
There are a bunch of things we can do when we know where the loops are.
Previously we didn't. With this patch, we do.
        
This patch adds the classic dominator based natural loop finder.
        
The only client of this right now is the DFG::Disassembler. It prints out
a summary of the analysis for each block.
        
This will become more important when I do
https://bugs.webkit.org/show_bug.cgi?id=118151, which definitely requires
this kind of analysis, at least if we want to do the optimization over
DFG IR (and I'm pretty sure we do).

* _javascript_Core.xcodeproj/project.pbxproj:
* dfg/DFGAnalysis.h: Added.
(DFG):
(Analysis):
(JSC::DFG::Analysis::Analysis):
(JSC::DFG::Analysis::invalidate):
(JSC::DFG::Analysis::computeIfNecessary):
(JSC::DFG::Analysis::isValid):
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::createDumpList):
* dfg/DFGDominators.cpp:
(JSC::DFG::Dominators::Dominators):
(JSC::DFG::Dominators::compute):
* dfg/DFGDominators.h:
(Dominators):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dumpBlockHeader):
(JSC::DFG::Graph::invalidateCFG):
(DFG):
* dfg/DFGGraph.h:
(Graph):
* dfg/DFGNaturalLoops.cpp: Added.
(DFG):
(JSC::DFG::NaturalLoop::dump):
(JSC::DFG::NaturalLoops::NaturalLoops):
(JSC::DFG::NaturalLoops::~NaturalLoops):
(JSC::DFG::NaturalLoops::compute):
(JSC::DFG::NaturalLoops::loopsOf):
(JSC::DFG::NaturalLoops::dump):
* dfg/DFGNaturalLoops.h: Added.
(DFG):
(NaturalLoop):
(JSC::DFG::NaturalLoop::NaturalLoop):
(JSC::DFG::NaturalLoop::addBlock):
(JSC::DFG::NaturalLoop::header):
(JSC::DFG::NaturalLoop::size):
(JSC::DFG::NaturalLoop::at):
(JSC::DFG::NaturalLoop::operator[]):
(JSC::DFG::NaturalLoop::contains):
(NaturalLoops):
(JSC::DFG::NaturalLoops::numLoops):
(JSC::DFG::NaturalLoops::loop):
(JSC::DFG::NaturalLoops::headerOf):

Modified Paths

Added Paths

Diff

Modified: branches/dfgFourthTier/Source/_javascript_Core/ChangeLog (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/ChangeLog	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/ChangeLog	2013-06-28 00:02:12 UTC (rev 152139)
@@ -1,5 +1,71 @@
 2013-06-27  Filip Pizlo  <fpi...@apple.com>
 
+        fourthTier: DFG should know how to find natural loops
+        https://bugs.webkit.org/show_bug.cgi?id=118152
+
+        Reviewed by Mark Hahnenberg.
+        
+        There are a bunch of things we can do when we know where the loops are.
+        Previously we didn't. With this patch, we do.
+        
+        This patch adds the classic dominator based natural loop finder.
+        
+        The only client of this right now is the DFG::Disassembler. It prints out
+        a summary of the analysis for each block.
+        
+        This will become more important when I do
+        https://bugs.webkit.org/show_bug.cgi?id=118151, which definitely requires
+        this kind of analysis, at least if we want to do the optimization over
+        DFG IR (and I'm pretty sure we do).
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * dfg/DFGAnalysis.h: Added.
+        (DFG):
+        (Analysis):
+        (JSC::DFG::Analysis::Analysis):
+        (JSC::DFG::Analysis::invalidate):
+        (JSC::DFG::Analysis::computeIfNecessary):
+        (JSC::DFG::Analysis::isValid):
+        * dfg/DFGCFGSimplificationPhase.cpp:
+        (JSC::DFG::CFGSimplificationPhase::run):
+        * dfg/DFGDisassembler.cpp:
+        (JSC::DFG::Disassembler::createDumpList):
+        * dfg/DFGDominators.cpp:
+        (JSC::DFG::Dominators::Dominators):
+        (JSC::DFG::Dominators::compute):
+        * dfg/DFGDominators.h:
+        (Dominators):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dumpBlockHeader):
+        (JSC::DFG::Graph::invalidateCFG):
+        (DFG):
+        * dfg/DFGGraph.h:
+        (Graph):
+        * dfg/DFGNaturalLoops.cpp: Added.
+        (DFG):
+        (JSC::DFG::NaturalLoop::dump):
+        (JSC::DFG::NaturalLoops::NaturalLoops):
+        (JSC::DFG::NaturalLoops::~NaturalLoops):
+        (JSC::DFG::NaturalLoops::compute):
+        (JSC::DFG::NaturalLoops::loopsOf):
+        (JSC::DFG::NaturalLoops::dump):
+        * dfg/DFGNaturalLoops.h: Added.
+        (DFG):
+        (NaturalLoop):
+        (JSC::DFG::NaturalLoop::NaturalLoop):
+        (JSC::DFG::NaturalLoop::addBlock):
+        (JSC::DFG::NaturalLoop::header):
+        (JSC::DFG::NaturalLoop::size):
+        (JSC::DFG::NaturalLoop::at):
+        (JSC::DFG::NaturalLoop::operator[]):
+        (JSC::DFG::NaturalLoop::contains):
+        (NaturalLoops):
+        (JSC::DFG::NaturalLoops::numLoops):
+        (JSC::DFG::NaturalLoops::loop):
+        (JSC::DFG::NaturalLoops::headerOf):
+
+2013-06-27  Filip Pizlo  <fpi...@apple.com>
+
         fourthTier: JSC's disassembly infrastructure should be able to disassemble the code that LLVM generates
         https://bugs.webkit.org/show_bug.cgi?id=118148
 

Modified: branches/dfgFourthTier/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-06-28 00:02:12 UTC (rev 152139)
@@ -170,6 +170,9 @@
 		0F46E6B9176F89DB00E1F755 /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6B7176F89D900E1F755 /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F46E6C5176F8A5E00E1F755 /* DFGLazyJSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6C2176F8A5B00E1F755 /* DFGLazyJSValue.cpp */; };
 		0F46E6C6176F8A6000E1F755 /* DFGLazyJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6C3176F8A5B00E1F755 /* DFGLazyJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F46E6EF177CE95A00E1F755 /* DFGAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6EE177CE95A00E1F755 /* DFGAnalysis.h */; };
+		0F46E6F3177CF0D200E1F755 /* DFGNaturalLoops.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6F1177CF0D200E1F755 /* DFGNaturalLoops.cpp */; };
+		0F46E6F4177CF0D200E1F755 /* DFGNaturalLoops.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6F2177CF0D200E1F755 /* DFGNaturalLoops.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F46E6D9177CB90000E1F755 /* LLVMDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F46E6D7177CB8FC00E1F755 /* LLVMDisassembler.cpp */; };
 		0F46E6E3177CC36600E1F755 /* LLVMDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6E0177CC36600E1F755 /* LLVMDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F46E6E4177CC36600E1F755 /* UDis86Disassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F46E6E1177CC36600E1F755 /* UDis86Disassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1183,6 +1186,9 @@
 		0F46E6B7176F89D900E1F755 /* FTLSwitchCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLSwitchCase.h; path = ftl/FTLSwitchCase.h; sourceTree = "<group>"; };
 		0F46E6C2176F8A5B00E1F755 /* DFGLazyJSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLazyJSValue.cpp; path = dfg/DFGLazyJSValue.cpp; sourceTree = "<group>"; };
 		0F46E6C3176F8A5B00E1F755 /* DFGLazyJSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyJSValue.h; path = dfg/DFGLazyJSValue.h; sourceTree = "<group>"; };
+		0F46E6EE177CE95A00E1F755 /* DFGAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAnalysis.h; path = dfg/DFGAnalysis.h; sourceTree = "<group>"; };
+		0F46E6F1177CF0D200E1F755 /* DFGNaturalLoops.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGNaturalLoops.cpp; path = dfg/DFGNaturalLoops.cpp; sourceTree = "<group>"; };
+		0F46E6F2177CF0D200E1F755 /* DFGNaturalLoops.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGNaturalLoops.h; path = dfg/DFGNaturalLoops.h; sourceTree = "<group>"; };
 		0F46E6D7177CB8FC00E1F755 /* LLVMDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLVMDisassembler.cpp; path = disassembler/LLVMDisassembler.cpp; sourceTree = "<group>"; };
 		0F46E6E0177CC36600E1F755 /* LLVMDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLVMDisassembler.h; path = disassembler/LLVMDisassembler.h; sourceTree = "<group>"; };
 		0F46E6E1177CC36600E1F755 /* UDis86Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UDis86Disassembler.h; path = disassembler/UDis86Disassembler.h; sourceTree = "<group>"; };
@@ -2945,6 +2951,7 @@
 				0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */,
 				0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */,
 				0FB4B51916B62772003F696B /* DFGAllocator.h */,
+				0F46E6EE177CE95A00E1F755 /* DFGAnalysis.h */,
 				0F1E3A431534CBAD000F9456 /* DFGArgumentPosition.h */,
 				0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */,
 				0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */,
@@ -3024,6 +3031,8 @@
 				0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
 				0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */,
 				0F2BDC3E1522801700CD8910 /* DFGMinifiedNode.h */,
+				0F46E6F1177CF0D200E1F755 /* DFGNaturalLoops.cpp */,
+				0F46E6F2177CF0D200E1F755 /* DFGNaturalLoops.h */,
 				0FB4B51E16B62772003F696B /* DFGNode.cpp */,
 				86ECA3E9132DEF1C002B2AD7 /* DFGNode.h */,
 				0FB4B51F16B62772003F696B /* DFGNodeAllocator.h */,
@@ -3818,6 +3827,8 @@
 				0F5EE4E9175424AF009AE42D /* JSCTestRunnerUtils.h in Headers */,
 				0F46E6C6176F8A6000E1F755 /* DFGLazyJSValue.h in Headers */,
 				0F46E6B9176F89DB00E1F755 /* FTLSwitchCase.h in Headers */,
+				0F46E6EF177CE95A00E1F755 /* DFGAnalysis.h in Headers */,
+				0F46E6F4177CF0D200E1F755 /* DFGNaturalLoops.h in Headers */,
 				0F46E6E3177CC36600E1F755 /* LLVMDisassembler.h in Headers */,
 				0F46E6E4177CC36600E1F755 /* UDis86Disassembler.h in Headers */,
 			);
@@ -4511,6 +4522,7 @@
 				0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
 				0F5EE4E8175424AF009AE42D /* JSCTestRunnerUtils.cpp in Sources */,
 				0F46E6C5176F8A5E00E1F755 /* DFGLazyJSValue.cpp in Sources */,
+				0F46E6F3177CF0D200E1F755 /* DFGNaturalLoops.cpp in Sources */,
 				0F46E6D9177CB90000E1F755 /* LLVMDisassembler.cpp in Sources */,
 				0F46E6E5177CC36600E1F755 /* X86Disassembler.cpp in Sources */,
 			);

Added: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGAnalysis.h (0 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGAnalysis.h	                        (rev 0)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGAnalysis.h	2013-06-28 00:02:12 UTC (rev 152139)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGAnalysis_h
+#define DFGAnalysis_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Use this as a mixin for DFG analyses. The analysis itself implements a public
+// compute(Graph&) method. Clients call computeIfNecessary() when they want
+// results.
+
+template<typename T>
+class Analysis {
+public:
+    Analysis()
+        : m_valid(false)
+    {
+    }
+    
+    void invalidate()
+    {
+        m_valid = false;
+    }
+    
+    void computeIfNecessary(Graph& graph)
+    {
+        if (m_valid)
+            return;
+        static_cast<T*>(this)->compute(graph);
+        m_valid = true;
+    }
+    
+    bool isValid() const { return m_valid; }
+
+private:
+    bool m_valid;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGAnalysis_h
+

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCFGSimplificationPhase.cpp (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCFGSimplificationPhase.cpp	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCFGSimplificationPhase.cpp	2013-06-28 00:02:12 UTC (rev 152139)
@@ -280,6 +280,7 @@
                 // successors' Phi functions to remove any references from them into the
                 // removed block.
                 
+                m_graph.invalidateCFG();
                 m_graph.resetReachability();
 
                 for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDisassembler.cpp (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDisassembler.cpp	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDisassembler.cpp	2013-06-28 00:02:12 UTC (rev 152139)
@@ -90,6 +90,7 @@
     append(result, out, previousOrigin);
     
     m_graph.m_dominators.computeIfNecessary(m_graph);
+    m_graph.m_naturalLoops.computeIfNecessary(m_graph);
     
     const char* prefix = "    ";
     const char* disassemblyPrefix = "        ";

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDominators.cpp (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDominators.cpp	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDominators.cpp	2013-06-28 00:02:12 UTC (rev 152139)
@@ -33,7 +33,6 @@
 namespace JSC { namespace DFG {
 
 Dominators::Dominators()
-    : m_valid(false)
 {
 }
 
@@ -85,8 +84,6 @@
         for (unsigned i = numBlocks; i-- > 1;)
             changed |= iterateForBlock(graph, i);
     } while (changed);
-    
-    m_valid = true;
 }
 
 bool Dominators::iterateForBlock(Graph& graph, BlockIndex i)

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDominators.h (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDominators.h	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGDominators.h	2013-06-28 00:02:12 UTC (rev 152139)
@@ -30,6 +30,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "DFGAnalysis.h"
 #include "DFGCommon.h"
 #include <wtf/FastBitVector.h>
 
@@ -37,25 +38,13 @@
 
 class Graph;
 
-class Dominators {
+class Dominators : public Analysis<Dominators> {
 public:
     Dominators();
     ~Dominators();
     
     void compute(Graph& graph);
-    void invalidate()
-    {
-        m_valid = false;
-    }
-    void computeIfNecessary(Graph& graph)
-    {
-        if (m_valid)
-            return;
-        compute(graph);
-    }
     
-    bool isValid() const { return m_valid; }
-    
     bool dominates(BlockIndex from, BlockIndex to) const
     {
         ASSERT(isValid());
@@ -67,7 +56,6 @@
     
     Vector<FastBitVector> m_results;
     FastBitVector m_scratch;
-    bool m_valid;
 };
 
 } } // namespace JSC::DFG

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.cpp (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-06-28 00:02:12 UTC (rev 152139)
@@ -294,6 +294,27 @@
         }
         out.print("\n");
     }
+    if (m_naturalLoops.isValid()) {
+        if (const NaturalLoop* loop = m_naturalLoops.headerOf(blockIndex)) {
+            out.print(prefix, "  Loop header, contains:");
+            Vector<BlockIndex> sortedBlockList;
+            for (unsigned i = 0; i < loop->size(); ++i)
+                sortedBlockList.append(loop->at(i));
+            std::sort(sortedBlockList.begin(), sortedBlockList.end());
+            for (unsigned i = 0; i < sortedBlockList.size(); ++i)
+                out.print(" #", sortedBlockList[i]);
+            out.print("\n");
+        }
+        
+        Vector<const NaturalLoop*> containingLoops =
+            m_naturalLoops.loopsOf(blockIndex);
+        if (!containingLoops.isEmpty()) {
+            out.print(prefix, "  Containing loop headers:");
+            for (unsigned i = 0; i < containingLoops.size(); ++i)
+                out.print(" #", containingLoops[i]->header());
+            out.print("\n");
+        }
+    }
     out.print(prefix, "  Phi Nodes:");
     for (size_t i = 0; i < block->phis.size(); ++i) {
         Node* phiNode = block->phis[i];
@@ -423,6 +444,12 @@
     }
 }
 
+void Graph::invalidateCFG()
+{
+    m_dominators.invalidate();
+    m_naturalLoops.invalidate();
+}
+
 } } // namespace JSC::DFG
 
 #endif

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.h (152138 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.h	2013-06-27 23:41:19 UTC (rev 152138)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.h	2013-06-28 00:02:12 UTC (rev 152139)
@@ -36,6 +36,7 @@
 #include "DFGBasicBlock.h"
 #include "DFGDominators.h"
 #include "DFGLongLivedState.h"
+#include "DFGNaturalLoops.h"
 #include "DFGNode.h"
 #include "DFGNodeAllocator.h"
 #include "DFGPlan.h"
@@ -676,6 +677,8 @@
         }
     }
     
+    void invalidateCFG();
+    
     Profiler::Compilation* compilation() { return m_plan.compilation.get(); }
     
     DesiredIdentifiers& identifiers() { return m_plan.identifiers; }
@@ -703,6 +706,7 @@
     HashSet<ExecutableBase*> m_executablesWhoseArgumentsEscaped;
     BitVector m_preservedVars;
     Dominators m_dominators;
+    NaturalLoops m_naturalLoops;
     unsigned m_localVars;
     unsigned m_parameterSlots;
     

Added: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.cpp (0 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.cpp	                        (rev 0)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.cpp	2013-06-28 00:02:12 UTC (rev 152139)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "DFGNaturalLoops.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include <wtf/CommaPrinter.h>
+
+namespace JSC { namespace DFG {
+
+void NaturalLoop::dump(PrintStream& out) const
+{
+    out.print("[Header: #", header(), ", Body:");
+    for (unsigned i = 0; i < m_body.size(); ++i)
+        out.print(" #", m_body[i]);
+    out.print("]");
+}
+
+NaturalLoops::NaturalLoops() { }
+NaturalLoops::~NaturalLoops() { }
+
+void NaturalLoops::compute(Graph& graph)
+{
+    // Implement the classic dominator-based natural loop finder. The first
+    // step is to find all control flow edges A -> B where B dominates A.
+    // Then B is a loop header and A is a backward branching block. We will
+    // then accumulate, for each loop header, multiple backward branching
+    // blocks. Then we backwards graph search from the backward branching
+    // blocks to their loop headers, which gives us all of the blocks in the
+    // loop body.
+    
+    static const bool verbose = false;
+    
+    graph.m_dominators.computeIfNecessary(graph);
+    
+    m_loops.resize(0);
+    
+    for (BlockIndex blockIndex = graph.m_blocks.size(); blockIndex--;) {
+        BasicBlock* block = graph.m_blocks[blockIndex].get();
+        if (!block)
+            continue;
+        
+        for (unsigned i = graph.numSuccessors(block); i--;) {
+            BlockIndex successorIndex = graph.successor(block, i);
+            if (!graph.m_dominators.dominates(successorIndex, blockIndex))
+                continue;
+            bool found = false;
+            for (unsigned j = m_loops.size(); j--;) {
+                if (m_loops[i].header() == successorIndex) {
+                    m_loops[i].addBlock(blockIndex);
+                    found = true;
+                }
+            }
+            if (found)
+                continue;
+            NaturalLoop loop(successorIndex);
+            loop.addBlock(blockIndex);
+            m_loops.append(loop);
+        }
+    }
+    
+    if (verbose)
+        dataLog("After bootstrap: ", *this, "\n");
+    
+    FastBitVector seenBlocks;
+    Vector<BlockIndex, 4> blockWorklist;
+    seenBlocks.resize(graph.m_blocks.size());
+    
+    for (unsigned i = m_loops.size(); i--;) {
+        NaturalLoop& loop = m_loops[i];
+        
+        seenBlocks.clearAll();
+        ASSERT(blockWorklist.isEmpty());
+        
+        if (verbose)
+            dataLog("Dealing with loop ", loop, "\n");
+        
+        for (unsigned j = loop.size(); j--;) {
+            seenBlocks.set(loop[j]);
+            blockWorklist.append(loop[j]);
+        }
+        
+        while (!blockWorklist.isEmpty()) {
+            BlockIndex blockIndex = blockWorklist.takeLast();
+            
+            if (verbose)
+                dataLog("    Dealing with #", blockIndex, "\n");
+            
+            if (blockIndex == loop.header())
+                continue;
+            
+            BasicBlock* block = graph.m_blocks[blockIndex].get();
+            ASSERT(block);
+            
+            for (unsigned j = block->m_predecessors.size(); j--;) {
+                BlockIndex predecessorIndex = block->m_predecessors[j];
+                if (seenBlocks.get(predecessorIndex))
+                    continue;
+                
+                loop.addBlock(predecessorIndex);
+                blockWorklist.append(predecessorIndex);
+                seenBlocks.set(predecessorIndex);
+            }
+        }
+    }
+    
+    if (verbose)
+        dataLog("Results: ", *this, "\n");
+}
+
+Vector<const NaturalLoop*> NaturalLoops::loopsOf(BlockIndex blockIndex) const
+{
+    Vector<const NaturalLoop*> result;
+    
+    for (unsigned i = m_loops.size(); i--;) {
+        if (m_loops[i].contains(blockIndex))
+            result.append(&m_loops[i]);
+    }
+    
+    return result;
+}
+
+void NaturalLoops::dump(PrintStream& out) const
+{
+    out.print("NaturalLoops:{");
+    CommaPrinter comma;
+    for (unsigned i = 0; i < m_loops.size(); ++i)
+        out.print(comma, m_loops[i]);
+    out.print("}");
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+

Added: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.h (0 => 152139)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.h	                        (rev 0)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.h	2013-06-28 00:02:12 UTC (rev 152139)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef DFGNaturalLoops_h
+#define DFGNaturalLoops_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGAnalysis.h"
+#include "DFGCommon.h"
+
+namespace JSC { namespace DFG {
+
+class NaturalLoop {
+public:
+    NaturalLoop()
+        : m_header(NoBlock)
+    {
+    }
+    
+    NaturalLoop(BlockIndex header)
+        : m_header(header)
+    {
+    }
+    
+    void addBlock(BlockIndex block) { m_body.append(block); }
+    
+    BlockIndex header() const { return m_header; }
+    
+    unsigned size() const { return m_body.size(); }
+    BlockIndex at(unsigned i) const { return m_body[i]; }
+    BlockIndex operator[](unsigned i) const { return at(i); }
+    
+    bool contains(BlockIndex block) const
+    {
+        for (unsigned i = m_body.size(); i--;) {
+            if (m_body[i] == block)
+                return true;
+        }
+        ASSERT(block != header()); // Header should be contained.
+        return false;
+    }
+    
+    void dump(PrintStream&) const;
+private:
+    BlockIndex m_header;
+    Vector<BlockIndex, 4> m_body;
+};
+
+class NaturalLoops : public Analysis<NaturalLoops> {
+public:
+    NaturalLoops();
+    ~NaturalLoops();
+    
+    void compute(Graph&);
+    
+    unsigned numLoops() const
+    {
+        ASSERT(isValid());
+        return m_loops.size();
+    }
+    const NaturalLoop& loop(unsigned i) const
+    {
+        ASSERT(isValid());
+        return m_loops[i];
+    }
+    
+    // Return either null if the block isn't a loop header, or the
+    // loop it belongs to.
+    const NaturalLoop* headerOf(BlockIndex blockIndex) const
+    {
+        for (unsigned i = m_loops.size(); i--;) {
+            if (m_loops[i].header() == blockIndex)
+                return &m_loops[i];
+        }
+        return 0;
+    }
+    
+    // Return the indices of all loops this belongs to.
+    Vector<const NaturalLoop*> loopsOf(BlockIndex blockIndex) const;
+
+    void dump(PrintStream&) const;
+private:
+    // If we ever had a scalability problem in our natural loop finder, we could
+    // use some HashMap's here. But it just feels a heck of a lot less convenient.
+    Vector<NaturalLoop, 4> m_loops;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGNaturalLoops_h
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to