Title: [164459] trunk/Source/_javascript_Core
Revision
164459
Author
[email protected]
Date
2014-02-20 17:20:48 -0800 (Thu, 20 Feb 2014)

Log Message

DFG should do its own static estimates of execution frequency before it starts creating OSR entrypoints
https://bugs.webkit.org/show_bug.cgi?id=129129

Reviewed by Geoffrey Garen.
        
We estimate execution counts based on loop depth, and then use those to estimate branch
weights. These weights then get carried all the way down to LLVM prof branch_weights
meta-data.
        
This is better than letting LLVM do its own static estimates, since by the time we
generate LLVM IR, we may have messed up the CFG due to OSR entrypoint creation. Of
course, it would be even better if we just slurped in some kind of execution counts
from profiling, but we don't do that, yet.

* CMakeLists.txt:
* GNUmakefile.list.am:
* _javascript_Core.vcxproj/_javascript_Core.vcxproj:
* _javascript_Core.xcodeproj/project.pbxproj:
* dfg/DFGBasicBlock.cpp:
(JSC::DFG::BasicBlock::BasicBlock):
* dfg/DFGBasicBlock.h:
* dfg/DFGBlockInsertionSet.cpp:
(JSC::DFG::BlockInsertionSet::insert):
(JSC::DFG::BlockInsertionSet::insertBefore):
* dfg/DFGBlockInsertionSet.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseCodeBlock):
* dfg/DFGCriticalEdgeBreakingPhase.cpp:
(JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
* dfg/DFGLoopPreHeaderCreationPhase.cpp:
(JSC::DFG::createPreHeader):
* dfg/DFGNaturalLoops.h:
(JSC::DFG::NaturalLoops::loopDepth):
* dfg/DFGOSREntrypointCreationPhase.cpp:
(JSC::DFG::OSREntrypointCreationPhase::run):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGStaticExecutionCountEstimationPhase.cpp: Added.
(JSC::DFG::StaticExecutionCountEstimationPhase::StaticExecutionCountEstimationPhase):
(JSC::DFG::StaticExecutionCountEstimationPhase::run):
(JSC::DFG::StaticExecutionCountEstimationPhase::applyCounts):
(JSC::DFG::performStaticExecutionCountEstimation):
* dfg/DFGStaticExecutionCountEstimationPhase.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (164458 => 164459)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2014-02-21 01:20:48 UTC (rev 164459)
@@ -184,6 +184,7 @@
     dfg/DFGSpeculativeJIT32_64.cpp
     dfg/DFGSpeculativeJIT64.cpp
     dfg/DFGStackLayoutPhase.cpp
+    dfg/DFGStaticExecutionCountEstimationPhase.cpp
     dfg/DFGStoreBarrierElisionPhase.cpp
     dfg/DFGStrengthReductionPhase.cpp
     dfg/DFGThreadData.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (164458 => 164459)


--- trunk/Source/_javascript_Core/ChangeLog	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-02-21 01:20:48 UTC (rev 164459)
@@ -1,5 +1,52 @@
 2014-02-20  Filip Pizlo  <[email protected]>
 
+        DFG should do its own static estimates of execution frequency before it starts creating OSR entrypoints
+        https://bugs.webkit.org/show_bug.cgi?id=129129
+
+        Reviewed by Geoffrey Garen.
+        
+        We estimate execution counts based on loop depth, and then use those to estimate branch
+        weights. These weights then get carried all the way down to LLVM prof branch_weights
+        meta-data.
+        
+        This is better than letting LLVM do its own static estimates, since by the time we
+        generate LLVM IR, we may have messed up the CFG due to OSR entrypoint creation. Of
+        course, it would be even better if we just slurped in some kind of execution counts
+        from profiling, but we don't do that, yet.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * dfg/DFGBasicBlock.cpp:
+        (JSC::DFG::BasicBlock::BasicBlock):
+        * dfg/DFGBasicBlock.h:
+        * dfg/DFGBlockInsertionSet.cpp:
+        (JSC::DFG::BlockInsertionSet::insert):
+        (JSC::DFG::BlockInsertionSet::insertBefore):
+        * dfg/DFGBlockInsertionSet.h:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::parseCodeBlock):
+        * dfg/DFGCriticalEdgeBreakingPhase.cpp:
+        (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
+        * dfg/DFGLoopPreHeaderCreationPhase.cpp:
+        (JSC::DFG::createPreHeader):
+        * dfg/DFGNaturalLoops.h:
+        (JSC::DFG::NaturalLoops::loopDepth):
+        * dfg/DFGOSREntrypointCreationPhase.cpp:
+        (JSC::DFG::OSREntrypointCreationPhase::run):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGStaticExecutionCountEstimationPhase.cpp: Added.
+        (JSC::DFG::StaticExecutionCountEstimationPhase::StaticExecutionCountEstimationPhase):
+        (JSC::DFG::StaticExecutionCountEstimationPhase::run):
+        (JSC::DFG::StaticExecutionCountEstimationPhase::applyCounts):
+        (JSC::DFG::performStaticExecutionCountEstimation):
+        * dfg/DFGStaticExecutionCountEstimationPhase.h: Added.
+
+2014-02-20  Filip Pizlo  <[email protected]>
+
         FTL may not see a compact_unwind section if there weren't any stackmaps
         https://bugs.webkit.org/show_bug.cgi?id=129125
 

Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (164458 => 164459)


--- trunk/Source/_javascript_Core/GNUmakefile.list.am	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am	2014-02-21 01:20:48 UTC (rev 164459)
@@ -410,6 +410,8 @@
 	Source/_javascript_Core/dfg/DFGSSALoweringPhase.h \
 	Source/_javascript_Core/dfg/DFGStackLayoutPhase.cpp \
 	Source/_javascript_Core/dfg/DFGStackLayoutPhase.h \
+	Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.cpp \
+	Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.h \
 	Source/_javascript_Core/dfg/DFGStoreBarrierElisionPhase.cpp \
 	Source/_javascript_Core/dfg/DFGStoreBarrierElisionPhase.h \
 	Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp \

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (164458 => 164459)


--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj	2014-02-21 01:20:48 UTC (rev 164459)
@@ -436,6 +436,7 @@
     <ClCompile Include="..\dfg\DFGSSAConversionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGSSALoweringPhase.cpp" />
     <ClCompile Include="..\dfg\DFGStackLayoutPhase.cpp" />
+    <ClCompile Include="..\dfg\DFGStaticExecutionCountEstimationPhase.cpp" />
     <ClCompile Include="..\dfg\DFGStoreBarrierElisionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGStrengthReductionPhase.cpp" />
     <ClCompile Include="..\dfg\DFGThreadData.cpp" />
@@ -997,6 +998,7 @@
     <ClInclude Include="..\dfg\DFGSSAConversionPhase.h" />
     <ClInclude Include="..\dfg\DFGSSALoweringPhase.h" />
     <ClInclude Include="..\dfg\DFGStackLayoutPhase.h" />
+    <ClInclude Include="..\dfg\DFGStaticExecutionCountEstimationPhase.h" />
     <ClInclude Include="..\dfg\DFGStoreBarrierElisionPhase.h" />
     <ClInclude Include="..\dfg\DFGStrengthReductionPhase.h" />
     <ClInclude Include="..\dfg\DFGStructureAbstractValue.h" />

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (164458 => 164459)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2014-02-21 01:20:48 UTC (rev 164459)
@@ -261,6 +261,8 @@
 		0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; };
 		0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
+		0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
 		0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F55989817C86C5800A1E543 /* ToNativeFromValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55989717C86C5600A1E543 /* ToNativeFromValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1735,6 +1737,8 @@
 		0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLRecoveryOpcode.h; path = ftl/FTLRecoveryOpcode.h; sourceTree = "<group>"; };
 		0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = "<group>"; };
 		0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; };
+		0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = "<group>"; };
+		0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; };
 		0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = "<group>"; };
 		0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialPointer.h; sourceTree = "<group>"; };
 		0F55989717C86C5600A1E543 /* ToNativeFromValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToNativeFromValue.h; sourceTree = "<group>"; };
@@ -4174,6 +4178,8 @@
 		86EC9DB31328DF44002B2AD7 /* dfg */ = {
 			isa = PBXGroup;
 			children = (
+				0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */,
+				0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */,
 				A77A423617A0BBFD00A8DB81 /* DFGAbstractHeap.cpp */,
 				A77A423717A0BBFD00A8DB81 /* DFGAbstractHeap.h */,
 				A704D8FE17A0BAA8006BA554 /* DFGAbstractInterpreter.h */,
@@ -5158,6 +5164,7 @@
 				0F2B66E017B6B5AB00A7AE3F /* GenericTypedArrayView.h in Headers */,
 				0F2B66E117B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h in Headers */,
 				0F9332A014CA7DCD0085F3C6 /* GetByIdStatus.h in Headers */,
+				0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */,
 				0F24E54417EA9F5900ABB217 /* GPRInfo.h in Headers */,
 				142E3134134FF0A600AFADB5 /* Handle.h in Headers */,
 				C283190016FE4B7D00157BFD /* HandleBlock.h in Headers */,
@@ -6082,6 +6089,7 @@
 				0F55C19417276E4600CEABFD /* DFGAbstractValue.cpp in Sources */,
 				0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */,
 				0F63948415E48118006A597C /* DFGArrayMode.cpp in Sources */,
+				0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */,
 				A7D9A29417A0BC7400EE2618 /* DFGAtTailAbstractState.cpp in Sources */,
 				0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */,
 				FEB58C14187B8B160098EF0B /* ErrorHandlingScope.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/dfg/DFGBasicBlock.cpp (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGBasicBlock.cpp	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGBasicBlock.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +32,8 @@
 
 namespace JSC { namespace DFG {
 
-BasicBlock::BasicBlock(unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals)
+BasicBlock::BasicBlock(
+    unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals, float executionCount)
     : bytecodeBegin(bytecodeBegin)
     , index(NoBlock)
     , isOSRTarget(false)
@@ -49,6 +50,7 @@
     , variablesAtTail(numArguments, numLocals)
     , valuesAtHead(numArguments, numLocals)
     , valuesAtTail(numArguments, numLocals)
+    , executionCount(executionCount)
 {
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGBasicBlock.h (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGBasicBlock.h	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGBasicBlock.h	2014-02-21 01:20:48 UTC (rev 164459)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -48,7 +48,9 @@
 typedef Vector<BasicBlock*, 2> PredecessorList;
 
 struct BasicBlock : RefCounted<BasicBlock> {
-    BasicBlock(unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals);
+    BasicBlock(
+        unsigned bytecodeBegin, unsigned numArguments, unsigned numLocals,
+        float executionCount);
     ~BasicBlock();
     
     void ensureLocals(unsigned newNumLocals);
@@ -134,6 +136,8 @@
     Operands<AbstractValue> valuesAtHead;
     Operands<AbstractValue> valuesAtTail;
     
+    float executionCount;
+    
     // These fields are reserved for NaturalLoops.
     static const unsigned numberOfInnerMostLoopIndices = 2;
     unsigned innerMostLoopIndices[numberOfInnerMostLoopIndices];

Modified: trunk/Source/_javascript_Core/dfg/DFGBlockInsertionSet.cpp (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGBlockInsertionSet.cpp	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGBlockInsertionSet.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -49,20 +49,21 @@
     insert(BlockInsertion(index, block));
 }
 
-BasicBlock* BlockInsertionSet::insert(size_t index)
+BasicBlock* BlockInsertionSet::insert(size_t index, float executionCount)
 {
     RefPtr<BasicBlock> block = adoptRef(new BasicBlock(
         UINT_MAX,
         m_graph.block(0)->variablesAtHead.numberOfArguments(),
-        m_graph.block(0)->variablesAtHead.numberOfLocals()));
+        m_graph.block(0)->variablesAtHead.numberOfLocals(),
+        executionCount));
     block->isReachable = true;
     insert(index, block);
     return block.get();
 }
 
-BasicBlock* BlockInsertionSet::insertBefore(BasicBlock* before)
+BasicBlock* BlockInsertionSet::insertBefore(BasicBlock* before, float executionCount)
 {
-    return insert(before->index);
+    return insert(before->index, executionCount);
 }
 
 bool BlockInsertionSet::execute()

Modified: trunk/Source/_javascript_Core/dfg/DFGBlockInsertionSet.h (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGBlockInsertionSet.h	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGBlockInsertionSet.h	2014-02-21 01:20:48 UTC (rev 164459)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,8 +43,8 @@
     
     void insert(const BlockInsertion& insertion);
     void insert(size_t index, PassRefPtr<BasicBlock> block);
-    BasicBlock* insert(size_t index);
-    BasicBlock* insertBefore(BasicBlock* before);
+    BasicBlock* insert(size_t index, float executionCount);
+    BasicBlock* insertBefore(BasicBlock* before, float executionCount);
     
     bool execute();
 

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -1455,7 +1455,7 @@
     
 
     // Need to create a new basic block for the continuation at the caller.
-    RefPtr<BasicBlock> block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals));
+    RefPtr<BasicBlock> block = adoptRef(new BasicBlock(nextOffset, m_numArguments, m_numLocals, QNaN));
 
     // Link the early returns to the basic block we're about to create.
     for (size_t i = 0; i < inlineStackEntry.m_unlinkedBlocks.size(); ++i) {
@@ -3710,7 +3710,7 @@
                     m_currentBlock = m_graph.lastBlock();
                     m_currentBlock->bytecodeBegin = m_currentIndex;
                 } else {
-                    RefPtr<BasicBlock> block = adoptRef(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals));
+                    RefPtr<BasicBlock> block = adoptRef(new BasicBlock(m_currentIndex, m_numArguments, m_numLocals, QNaN));
                     m_currentBlock = block.get();
                     // This assertion checks two things:
                     // 1) If the bytecodeBegin is greater than currentIndex, then something has gone

Modified: trunk/Source/_javascript_Core/dfg/DFGCriticalEdgeBreakingPhase.cpp (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGCriticalEdgeBreakingPhase.cpp	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGCriticalEdgeBreakingPhase.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -73,7 +73,9 @@
 private:
     void breakCriticalEdge(BasicBlock* predecessor, BasicBlock** successor)
     {
-        BasicBlock* pad = m_insertionSet.insertBefore(*successor);
+        // Note that we pass NaN for the count of the critical edge block, because we honestly
+        // don't know its execution frequency.
+        BasicBlock* pad = m_insertionSet.insertBefore(*successor, QNaN);
         pad->appendNode(
             m_graph, SpecNone, Jump, (*successor)->at(0)->origin, OpInfo(*successor));
         pad->predecessors.append(predecessor);

Modified: trunk/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.cpp (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.cpp	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGLoopPreHeaderCreationPhase.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -39,7 +39,8 @@
 
 BasicBlock* createPreHeader(Graph& graph, BlockInsertionSet& insertionSet, BasicBlock* block)
 {
-    BasicBlock* preHeader = insertionSet.insertBefore(block);
+    // Don't bother to preserve execution frequencies for now.
+    BasicBlock* preHeader = insertionSet.insertBefore(block, QNaN);
     preHeader->appendNode(
         graph, SpecNone, Jump, block->at(0)->origin, OpInfo(block));
     

Modified: trunk/Source/_javascript_Core/dfg/DFGNaturalLoops.h (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGNaturalLoops.h	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGNaturalLoops.h	2014-02-21 01:20:48 UTC (rev 164459)
@@ -154,6 +154,14 @@
         return false;
     }
     
+    unsigned loopDepth(BasicBlock* block) const
+    {
+        unsigned depth = 0;
+        for (const NaturalLoop* loop = innerMostLoopOf(block); loop; loop = innerMostOuterLoop(*loop))
+            depth++;
+        return depth;
+    }
+    
     // Return the indices of all loops this belongs to.
     Vector<const NaturalLoop*> loopsOf(BasicBlock*) const;
 

Modified: trunk/Source/_javascript_Core/dfg/DFGOSREntrypointCreationPhase.cpp (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGOSREntrypointCreationPhase.cpp	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGOSREntrypointCreationPhase.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -83,7 +83,7 @@
         
         BlockInsertionSet insertionSet(m_graph);
         
-        BasicBlock* newRoot = insertionSet.insert(0);
+        BasicBlock* newRoot = insertionSet.insert(0, QNaN);
         NodeOrigin origin = target->at(0)->origin;
         
         Vector<Node*> locals(baseline->m_numCalleeRegisters);

Modified: trunk/Source/_javascript_Core/dfg/DFGPlan.cpp (164458 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2014-02-21 01:14:35 UTC (rev 164458)
+++ trunk/Source/_javascript_Core/dfg/DFGPlan.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -56,6 +56,7 @@
 #include "DFGSSAConversionPhase.h"
 #include "DFGSSALoweringPhase.h"
 #include "DFGStackLayoutPhase.h"
+#include "DFGStaticExecutionCountEstimationPhase.h"
 #include "DFGStoreBarrierElisionPhase.h"
 #include "DFGStrengthReductionPhase.h"
 #include "DFGTierUpCheckInjectionPhase.h"
@@ -208,6 +209,9 @@
     performUnification(dfg);
     performPredictionInjection(dfg);
     
+    if (isFTL(mode))
+        performStaticExecutionCountEstimation(dfg);
+    
     if (mode == FTLForOSREntryMode) {
         bool result = performOSREntrypointCreation(dfg);
         if (!result) {

Added: trunk/Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.cpp (0 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.cpp	2014-02-21 01:20:48 UTC (rev 164459)
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 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 "DFGStaticExecutionCountEstimationPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGBasicBlockInlines.h"
+#include "DFGGraph.h"
+#include "DFGPhase.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+class StaticExecutionCountEstimationPhase : public Phase {
+public:
+    StaticExecutionCountEstimationPhase(Graph& graph)
+        : Phase(graph, "static execution count estimation")
+    {
+    }
+    
+    bool run()
+    {
+        m_graph.m_naturalLoops.computeIfNecessary(m_graph);
+        
+        // Estimate basic block execution counts based on loop depth.
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+
+            block->executionCount = pow(10, m_graph.m_naturalLoops.loopDepth(block));
+        }
+        
+        // Estimate branch weights based on execution counts. This isn't quite correct. It'll
+        // assume that each block's conditional successor only has that block as its
+        // predecessor.
+        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
+            BasicBlock* block = m_graph.block(blockIndex);
+            if (!block)
+                continue;
+            
+            switch (block->last()->op()) {
+            case Branch: {
+                BranchData* data = ""
+                applyCounts(data->taken);
+                applyCounts(data->notTaken);
+                break;
+            }
+                
+            case Switch: {
+                SwitchData* data = ""
+                for (unsigned i = data->cases.size(); i--;)
+                    applyCounts(data->cases[i].target);
+                applyCounts(data->fallThrough);
+                break;
+            }
+                
+            default:
+                break;
+            }
+        }
+        
+        return true;
+    }
+
+private:
+    void applyCounts(BranchTarget& target)
+    {
+        target.count = target.block->executionCount;
+    }
+};
+
+bool performStaticExecutionCountEstimation(Graph& graph)
+{
+    SamplingRegion samplingRegion("DFG Static Execution Count Estimation");
+    return runPhase<StaticExecutionCountEstimationPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+

Added: trunk/Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.h (0 => 164459)


--- trunk/Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGStaticExecutionCountEstimationPhase.h	2014-02-21 01:20:48 UTC (rev 164459)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 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 DFGStaticExecutionCountEstimationPhase_h
+#define DFGStaticExecutionCountEstimationPhase_h
+
+#if ENABLE(DFG_JIT)
+
+namespace JSC { namespace DFG {
+
+class Graph;
+
+// Estimate execution counts (branch execution counts, in particular) based on
+// presently available static information. This phase is important because
+// subsequent CFG transformations, such as OSR entrypoint creation, perturb our
+// ability to do accurate static estimations. Hence we lock in the estimates early.
+// Ideally, we would have dynamic information, but we don't right now, so this is as
+// good as it gets.
+//
+// It's worth noting that if we didn't have this phase, then the static estimation
+// would be perfomed by LLVM instead. It's worth trying to make this phase perform
+// the estimates using the same heuristics that LLVM would use.
+
+bool performStaticExecutionCountEstimation(Graph&);
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGStaticExecutionCountEstimationPhase_h
+
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to