Title: [152829] branches/dfgFourthTier/Source/_javascript_Core
Revision
152829
Author
[email protected]
Date
2013-07-17 22:16:12 -0700 (Wed, 17 Jul 2013)

Log Message

fourthTier: Add a phase to create loop pre-headers
https://bugs.webkit.org/show_bug.cgi?id=118778

Reviewed by Oliver Hunt.
        
Add a loop pre-header creation phase. Any loop that doesn't already have
just one predecessor that isn't part of the loop has a pre-header
prepended. All non-loop predecessors then jump to that pre-header.
        
Also fix a handful of bugs:
        
- DFG::Analysis should set m_valid before running the analysis, since that
  makes it easier to use ASSERT(m_valid) in the analysis' methods, which
  may be called by the analysis before the analysis completes. NaturalLoops
  does this with loopsOf().
        
- NaturalLoops::headerOf() was missing a check for innerMostLoopOf()
  returning 0, since that'll happen if the block isn't in any loop.
        
- Change BlockInsertionSet to dethread the graph, since anyone using it
  will want to do so.
        
- Change dethreading to ignore SSA form graphs.
        
This also adds NaturalLoops::belongsTo(), which I always used in the
pre-header creation phase. I didn't end up using it but I'll probably use
it in the near future.
        
* _javascript_Core.xcodeproj/project.pbxproj:
* dfg/DFGAnalysis.h:
(JSC::DFG::Analysis::computeIfNecessary):
* dfg/DFGBlockInsertionSet.cpp:
(JSC::DFG::BlockInsertionSet::execute):
* dfg/DFGCriticalEdgeBreakingPhase.cpp:
(JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dethread):
* dfg/DFGLoopPreHeaderCreationPhase.cpp: Added.
(DFG):
(LoopPreHeaderCreationPhase):
(JSC::DFG::LoopPreHeaderCreationPhase::LoopPreHeaderCreationPhase):
(JSC::DFG::LoopPreHeaderCreationPhase::run):
(JSC::DFG::performLoopPreHeaderCreation):
* dfg/DFGLoopPreHeaderCreationPhase.h: Added.
(DFG):
* dfg/DFGNaturalLoops.h:
(NaturalLoop):
(JSC::DFG::NaturalLoops::headerOf):
(JSC::DFG::NaturalLoops::innerMostLoopOf):
(JSC::DFG::NaturalLoops::innerMostOuterLoop):
(JSC::DFG::NaturalLoops::belongsTo):
(NaturalLoops):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):

Modified Paths

Added Paths

Diff

Modified: branches/dfgFourthTier/Source/_javascript_Core/ChangeLog (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/ChangeLog	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/ChangeLog	2013-07-18 05:16:12 UTC (rev 152829)
@@ -1,5 +1,62 @@
 2013-07-16  Filip Pizlo  <[email protected]>
 
+        fourthTier: Add a phase to create loop pre-headers
+        https://bugs.webkit.org/show_bug.cgi?id=118778
+
+        Reviewed by Oliver Hunt.
+        
+        Add a loop pre-header creation phase. Any loop that doesn't already have
+        just one predecessor that isn't part of the loop has a pre-header
+        prepended. All non-loop predecessors then jump to that pre-header.
+        
+        Also fix a handful of bugs:
+        
+        - DFG::Analysis should set m_valid before running the analysis, since that
+          makes it easier to use ASSERT(m_valid) in the analysis' methods, which
+          may be called by the analysis before the analysis completes. NaturalLoops
+          does this with loopsOf().
+        
+        - NaturalLoops::headerOf() was missing a check for innerMostLoopOf()
+          returning 0, since that'll happen if the block isn't in any loop.
+        
+        - Change BlockInsertionSet to dethread the graph, since anyone using it
+          will want to do so.
+        
+        - Change dethreading to ignore SSA form graphs.
+        
+        This also adds NaturalLoops::belongsTo(), which I always used in the
+        pre-header creation phase. I didn't end up using it but I'll probably use
+        it in the near future.
+        
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * dfg/DFGAnalysis.h:
+        (JSC::DFG::Analysis::computeIfNecessary):
+        * dfg/DFGBlockInsertionSet.cpp:
+        (JSC::DFG::BlockInsertionSet::execute):
+        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
+        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dethread):
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp: Added.
+        (DFG):
+        (LoopPreHeaderCreationPhase):
+        (JSC::DFG::LoopPreHeaderCreationPhase::LoopPreHeaderCreationPhase):
+        (JSC::DFG::LoopPreHeaderCreationPhase::run):
+        (JSC::DFG::performLoopPreHeaderCreation):
+        * dfg/DFGLoopPreHeaderCreationPhase.h: Added.
+        (DFG):
+        * dfg/DFGNaturalLoops.h:
+        (NaturalLoop):
+        (JSC::DFG::NaturalLoops::headerOf):
+        (JSC::DFG::NaturalLoops::innerMostLoopOf):
+        (JSC::DFG::NaturalLoops::innerMostOuterLoop):
+        (JSC::DFG::NaturalLoops::belongsTo):
+        (NaturalLoops):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+
+2013-07-16  Filip Pizlo  <[email protected]>
+
         fourthTier: Rationalize Node::replacement
         https://bugs.webkit.org/show_bug.cgi?id=118774
 

Modified: branches/dfgFourthTier/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-07-18 05:16:12 UTC (rev 152829)
@@ -368,6 +368,8 @@
 		0FE5057B178F5B5300B35F8C /* DFGOSRAvailabilityAnalysisPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5056E178F5B5300B35F8C /* DFGOSRAvailabilityAnalysisPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FE5057C178F5B5300B35F8C /* DFGSSAConversionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5056F178F5B5300B35F8C /* DFGSSAConversionPhase.cpp */; };
 		0FE5057D178F5B5300B35F8C /* DFGSSAConversionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE50570178F5B5300B35F8C /* DFGSSAConversionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FE5058217965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5058017965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.cpp */; };
+		0FE5058317965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5058117965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FE8534B1723CDA500B618F5 /* DFGDesiredWatchpoints.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */; };
 		0FE8534C1723CDA500B618F5 /* DFGDesiredWatchpoints.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1414,6 +1416,8 @@
 		0FE5056E178F5B5300B35F8C /* DFGOSRAvailabilityAnalysisPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRAvailabilityAnalysisPhase.h; path = dfg/DFGOSRAvailabilityAnalysisPhase.h; sourceTree = "<group>"; };
 		0FE5056F178F5B5300B35F8C /* DFGSSAConversionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSSAConversionPhase.cpp; path = dfg/DFGSSAConversionPhase.cpp; sourceTree = "<group>"; };
 		0FE50570178F5B5300B35F8C /* DFGSSAConversionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSSAConversionPhase.h; path = dfg/DFGSSAConversionPhase.h; sourceTree = "<group>"; };
+		0FE5058017965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLoopPreHeaderCreationPhase.cpp; path = dfg/DFGLoopPreHeaderCreationPhase.cpp; sourceTree = "<group>"; };
+		0FE5058117965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLoopPreHeaderCreationPhase.h; path = dfg/DFGLoopPreHeaderCreationPhase.h; sourceTree = "<group>"; };
 		0FE853491723CDA500B618F5 /* DFGDesiredWatchpoints.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredWatchpoints.cpp; path = dfg/DFGDesiredWatchpoints.cpp; sourceTree = "<group>"; };
 		0FE8534A1723CDA500B618F5 /* DFGDesiredWatchpoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredWatchpoints.h; path = dfg/DFGDesiredWatchpoints.h; sourceTree = "<group>"; };
 		0FEA09FD170513DB00BB722C /* FTLAbbreviations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLAbbreviations.h; path = ftl/FTLAbbreviations.h; sourceTree = "<group>"; };
@@ -3068,6 +3072,8 @@
 				0FE5056C178F5B5300B35F8C /* DFGLivenessAnalysisPhase.h */,
 				0FB4B51C16B62772003F696B /* DFGLongLivedState.cpp */,
 				0FB4B51D16B62772003F696B /* DFGLongLivedState.h */,
+				0FE5058017965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.cpp */,
+				0FE5058117965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.h */,
 				0F2BDC3D1522801700CD8910 /* DFGMinifiedGraph.h */,
 				0FB4B51016B3A964003F696B /* DFGMinifiedID.h */,
 				0F2BDC4C1522818300CD8910 /* DFGMinifiedNode.cpp */,
@@ -3866,6 +3872,7 @@
 				0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */,
 				0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */,
 				0FFB921A16D02EC50055A5DB /* DFGBasicBlockInlines.h in Headers */,
+				0FE5058317965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.h in Headers */,
 				0FFB921B16D02F010055A5DB /* DFGNodeAllocator.h in Headers */,
 				0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
 				0F235BEE17178E7300690C7F /* DFGOSRExitPreparation.h in Headers */,
@@ -4451,6 +4458,7 @@
 				0F0B839C14BCF46300885B4F /* LLIntThunks.cpp in Sources */,
 				0F4E1A13173AF07E007EE2D3 /* DFGDesiredStructureChains.cpp in Sources */,
 				14469DDE107EC7E700650446 /* Lookup.cpp in Sources */,
+				0FE5058217965C3D00B35F8C /* DFGLoopPreHeaderCreationPhase.cpp in Sources */,
 				0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
 				0FDB2CE41746CE9F007B3C1B /* CompilationResult.cpp in Sources */,
 				14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGAnalysis.h (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGAnalysis.h	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGAnalysis.h	2013-07-18 05:16:12 UTC (rev 152829)
@@ -55,8 +55,10 @@
     {
         if (m_valid)
             return;
+        // Set to true early, since the analysis may choose to call its own methods in
+        // compute() and it may want to ASSERT() validity in those methods.
+        m_valid = true;
         static_cast<T*>(this)->compute(graph);
-        m_valid = true;
     }
     
     bool isValid() const { return m_valid; }

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGBlockInsertionSet.cpp (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGBlockInsertionSet.cpp	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGBlockInsertionSet.cpp	2013-07-18 05:16:12 UTC (rev 152829)
@@ -91,6 +91,7 @@
     
     // And finally, invalidate all analyses that rely on the CFG.
     m_graph.invalidateCFG();
+    m_graph.dethread();
     
     return true;
 }

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCriticalEdgeBreakingPhase.cpp (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCriticalEdgeBreakingPhase.cpp	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCriticalEdgeBreakingPhase.cpp	2013-07-18 05:16:12 UTC (rev 152829)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * 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
@@ -73,8 +73,6 @@
 private:
     void breakCriticalEdge(BasicBlock* predecessor, BasicBlock** successor)
     {
-        m_graph.dethread();
-        
         BasicBlock* pad = m_insertionSet.insertBefore(*successor);
         pad->appendNode(
             m_graph, SpecNone, Jump, (*successor)->at(0)->codeOrigin, OpInfo(*successor));

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.cpp (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGGraph.cpp	2013-07-18 05:16:12 UTC (rev 152829)
@@ -404,7 +404,7 @@
 
 void Graph::dethread()
 {
-    if (m_form == LoadStore)
+    if (m_form == LoadStore || m_form == SSA)
         return;
     
     if (logCompilationChanges())

Added: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.cpp (0 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.cpp	                        (rev 0)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.cpp	2013-07-18 05:16:12 UTC (rev 152829)
@@ -0,0 +1,111 @@
+/*
+ * 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 "DFGLoopPreHeaderCreationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGBlockInsertionSet.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "Operations.h"
+#include <wtf/HashMap.h>
+
+namespace JSC { namespace DFG {
+
+class LoopPreHeaderCreationPhase : public Phase {
+public:
+    LoopPreHeaderCreationPhase(Graph& graph)
+        : Phase(graph, "loop pre-header creation")
+        , m_insertionSet(graph)
+    {
+    }
+    
+    bool run()
+    {
+        m_graph.m_dominators.computeIfNecessary(m_graph);
+        m_graph.m_naturalLoops.computeIfNecessary(m_graph);
+        
+        for (unsigned loopIndex = m_graph.m_naturalLoops.numLoops(); loopIndex--;) {
+            const NaturalLoop& loop = m_graph.m_naturalLoops.loop(loopIndex);
+            BasicBlock* existingPreHeader = 0;
+            bool needsNewPreHeader = false;
+            for (unsigned predecessorIndex = loop.header()->predecessors.size(); predecessorIndex--;) {
+                BasicBlock* predecessor = loop.header()->predecessors[predecessorIndex];
+                if (m_graph.m_dominators.dominates(loop.header(), predecessor))
+                    continue;
+                if (!existingPreHeader) {
+                    existingPreHeader = predecessor;
+                    continue;
+                }
+                if (existingPreHeader == predecessor)
+                    continue;
+                needsNewPreHeader = true;
+                break;
+            }
+            if (!needsNewPreHeader)
+                continue;
+            
+            BasicBlock* preHeader = m_insertionSet.insertBefore(loop.header());
+            preHeader->appendNode(
+                m_graph, SpecNone, Jump, loop.header()->at(0)->codeOrigin, OpInfo(loop.header()));
+            
+            for (unsigned predecessorIndex = 0; predecessorIndex < loop.header()->predecessors.size(); predecessorIndex++) {
+                BasicBlock* predecessor = loop.header()->predecessors[predecessorIndex];
+                if (m_graph.m_dominators.dominates(loop.header(), predecessor))
+                    continue;
+                loop.header()->predecessors[predecessorIndex--] = loop.header()->predecessors.last();
+                loop.header()->predecessors.takeLast();
+                for (unsigned successorIndex = predecessor->numSuccessors(); successorIndex--;) {
+                    BasicBlock*& successor = predecessor->successor(successorIndex);
+                    if (successor != loop.header())
+                        continue;
+                    successor = preHeader;
+                    preHeader->predecessors.append(predecessor);
+                }
+            }
+            
+            loop.header()->predecessors.append(preHeader);
+        }
+        
+        return m_insertionSet.execute();
+    }
+
+    BlockInsertionSet m_insertionSet;
+};
+
+bool performLoopPreHeaderCreation(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Loop Pre-Header Creation Phase");
+    return runPhase<LoopPreHeaderCreationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+

Added: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.h (0 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.h	                        (rev 0)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.h	2013-07-18 05:16:12 UTC (rev 152829)
@@ -0,0 +1,47 @@
+/*
+ * 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 DFGLoopPreHeaderCreationPhase_h
+#define DFGLoopPreHeaderCreationPhase_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Inserts dummy basic blocks before any loop headers that don't already have
+// a single non-loop predecessor.
+
+bool performLoopPreHeaderCreation(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGLoopPreHeaderCreationPhase_h
+

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.h (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.h	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGNaturalLoops.h	2013-07-18 05:16:12 UTC (rev 152829)
@@ -58,7 +58,11 @@
     unsigned size() const { return m_body.size(); }
     BasicBlock* at(unsigned i) const { return m_body[i]; }
     BasicBlock* operator[](unsigned i) const { return at(i); }
-    
+
+    // This is the slower, but simpler, way of asking if a block belongs to
+    // a natural loop. It's faster to call NaturalLoops::belongsTo(), which
+    // tries to be O(loop depth) rather than O(loop size). Loop depth is
+    // almost always smaller than loop size. A *lot* smaller.
     bool contains(BasicBlock* block) const
     {
         for (unsigned i = m_body.size(); i--;) {
@@ -108,7 +112,10 @@
     // loop it belongs to.
     const NaturalLoop* headerOf(BasicBlock* block) const
     {
+        ASSERT(isValid());
         const NaturalLoop* loop = innerMostLoopOf(block);
+        if (!loop)
+            return 0;
         if (loop->header() == block)
             return loop;
         if (!ASSERT_DISABLED) {
@@ -120,6 +127,7 @@
     
     const NaturalLoop* innerMostLoopOf(BasicBlock* block) const
     {
+        ASSERT(isValid());
         unsigned index = block->innerMostLoopIndices[0];
         if (index == UINT_MAX)
             return 0;
@@ -128,11 +136,26 @@
     
     const NaturalLoop* innerMostOuterLoop(const NaturalLoop& loop) const
     {
+        ASSERT(isValid());
         if (loop.m_outerLoopIndex == UINT_MAX)
             return 0;
         return &m_loops[loop.m_outerLoopIndex];
     }
     
+    bool belongsTo(BasicBlock* block, const NaturalLoop& candidateLoop) const
+    {
+        ASSERT(isValid());
+        // It's faster to do this test using the loop itself, if it's small.
+        if (candidateLoop.size() < 4)
+            return candidateLoop.contains(block);
+        
+        for (const NaturalLoop* loop = innerMostLoopOf(block); loop; loop = innerMostOuterLoop(*loop)) {
+            if (loop == &candidateLoop)
+                return true;
+        }
+        return false;
+    }
+    
     // Return the indices of all loops this belongs to.
     Vector<const NaturalLoop*> loopsOf(BasicBlock*) const;
 

Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGPlan.cpp (152828 => 152829)


--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGPlan.cpp	2013-07-18 04:38:54 UTC (rev 152828)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGPlan.cpp	2013-07-18 05:16:12 UTC (rev 152829)
@@ -43,6 +43,7 @@
 #include "DFGFixupPhase.h"
 #include "DFGJITCompiler.h"
 #include "DFGLivenessAnalysisPhase.h"
+#include "DFGLoopPreHeaderCreationPhase.h"
 #include "DFGOSRAvailabilityAnalysisPhase.h"
 #include "DFGPredictionInjectionPhase.h"
 #include "DFGPredictionPropagationPhase.h"
@@ -201,6 +202,7 @@
         && FTL::canCompile(dfg)) {
         
         performCriticalEdgeBreaking(dfg);
+        performLoopPreHeaderCreation(dfg);
         performCPSRethreading(dfg);
         performSSAConversion(dfg);
         performLivenessAnalysis(dfg);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to