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
+