Commit 3fa6f5d3 authored by fpizlo@apple.com's avatar fpizlo@apple.com

DFG should allow phases to break Phi's and then have one phase to rebuild them

https://bugs.webkit.org/show_bug.cgi?id=108414

Reviewed by Mark Hahnenberg.
        
Introduces two new DFG forms: LoadStore and ThreadedCPS. These are described in
detail in DFGCommon.h.
        
Consequently, DFG phases no longer have to worry about preserving data flow
links between basic blocks. It is generally always safe to request that the
graph be dethreaded (Graph::dethread), which brings it into LoadStore form, where
the data flow is implicit. In this form, only liveness-at-head needs to be
preserved.
        
All of the machinery for "threading" the graph to introduce data flow between
blocks is now moved out of the bytecode parser and into the CPSRethreadingPhase.
All phases that previously did this maintenance themselves now just rely on
being able to dethread the graph. The one exception is the structure check
hoising phase, which operates over a threaded graph and preserves it, for the
sake of performance.
        
Also moved two other things into their own phases: unification (previously found
in the parser) and prediction injection (previously found in various places).

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/Operands.h:
(Operands):
(JSC::Operands::sizeFor):
(JSC::Operands::atFor):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
(JSC::DFG::AbstractState::mergeStateAtTail):
* dfg/DFGAllocator.h:
(JSC::DFG::::allocateSlow):
* dfg/DFGArgumentsSimplificationPhase.cpp:
(JSC::DFG::ArgumentsSimplificationPhase::run):
* dfg/DFGBasicBlockInlines.h:
(DFG):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::getLocal):
(JSC::DFG::ByteCodeParser::getArgument):
(JSC::DFG::ByteCodeParser::flushDirect):
(JSC::DFG::ByteCodeParser::parseBlock):
(DFG):
(JSC::DFG::ByteCodeParser::parse):
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
(JSC::DFG::CFGSimplificationPhase::killUnreachable):
(JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
(CFGSimplificationPhase):
(JSC::DFG::CFGSimplificationPhase::fixJettisonedPredecessors):
(JSC::DFG::CFGSimplificationPhase::mergeBlocks):
* dfg/DFGCPSRethreadingPhase.cpp: Added.
(DFG):
(CPSRethreadingPhase):
(JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
(JSC::DFG::CPSRethreadingPhase::run):
(JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
(JSC::DFG::CPSRethreadingPhase::clearVariablesAtHeadAndTail):
(JSC::DFG::CPSRethreadingPhase::addPhiSilently):
(JSC::DFG::CPSRethreadingPhase::addPhi):
(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocal):
(JSC::DFG::CPSRethreadingPhase::canonicalizeSetLocal):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocal):
(JSC::DFG::CPSRethreadingPhase::canonicalizeSetArgument):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks):
(JSC::DFG::CPSRethreadingPhase::propagatePhis):
(JSC::DFG::CPSRethreadingPhase::PhiStackEntry::PhiStackEntry):
(PhiStackEntry):
(JSC::DFG::CPSRethreadingPhase::phiStackFor):
(JSC::DFG::performCPSRethreading):
* dfg/DFGCPSRethreadingPhase.h: Added.
(DFG):
* dfg/DFGCSEPhase.cpp:
(CSEPhase):
(JSC::DFG::CSEPhase::performNodeCSE):
* dfg/DFGCommon.cpp:
(WTF):
(WTF::printInternal):
* dfg/DFGCommon.h:
(JSC::DFG::logCompilationChanges):
(DFG):
(WTF):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::dethread):
(JSC::DFG::Graph::collectGarbage):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::performSubstitution):
(Graph):
(JSC::DFG::Graph::performSubstitutionForEdge):
(JSC::DFG::Graph::convertToConstant):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToPhantomLocal):
(Node):
(JSC::DFG::Node::convertToGetLocal):
(JSC::DFG::Node::hasVariableAccessData):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGPhase.cpp:
(JSC::DFG::Phase::beginPhase):
* dfg/DFGPhase.h:
(JSC::DFG::runAndLog):
* dfg/DFGPredictionInjectionPhase.cpp: Added.
(DFG):
(PredictionInjectionPhase):
(JSC::DFG::PredictionInjectionPhase::PredictionInjectionPhase):
(JSC::DFG::PredictionInjectionPhase::run):
(JSC::DFG::performPredictionInjection):
* dfg/DFGPredictionInjectionPhase.h: Added.
(DFG):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::run):
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStructureCheckHoistingPhase.cpp:
(JSC::DFG::StructureCheckHoistingPhase::run):
* dfg/DFGUnificationPhase.cpp: Added.
(DFG):
(UnificationPhase):
(JSC::DFG::UnificationPhase::UnificationPhase):
(JSC::DFG::UnificationPhase::run):
(JSC::DFG::performUnification):
* dfg/DFGUnificationPhase.h: Added.
(DFG):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
(JSC::DFG::Validate::dumpGraphIfAppropriate):
* dfg/DFGVirtualRegisterAllocationPhase.cpp:
(JSC::DFG::VirtualRegisterAllocationPhase::run):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dump):
* runtime/JSString.h:
(JSString):
* runtime/Options.h:
(JSC):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@142377 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 5ca728d9
......@@ -82,6 +82,7 @@ set(JavaScriptCore_SOURCES
dfg/DFGCommon.cpp
dfg/DFGCFAPhase.cpp
dfg/DFGCFGSimplificationPhase.cpp
dfg/DFGCPSRethreadingPhase.cpp
dfg/DFGConstantFoldingPhase.cpp
dfg/DFGCSEPhase.cpp
dfg/DFGDisassembler.cpp
......@@ -104,12 +105,14 @@ set(JavaScriptCore_SOURCES
dfg/DFGOperations.cpp
dfg/DFGPhase.cpp
dfg/DFGPredictionPropagationPhase.cpp
dfg/DFGPredictionInjectionPhase.cpp
dfg/DFGRepatch.cpp
dfg/DFGSpeculativeJIT.cpp
dfg/DFGSpeculativeJIT32_64.cpp
dfg/DFGSpeculativeJIT64.cpp
dfg/DFGStructureCheckHoistingPhase.cpp
dfg/DFGThunks.cpp
dfg/DFGUnificationPhase.cpp
dfg/DFGValueSource.cpp
dfg/DFGVariableAccessDataDump.cpp
dfg/DFGVariableEvent.cpp
......
2013-02-08 Filip Pizlo <fpizlo@apple.com>
DFG should allow phases to break Phi's and then have one phase to rebuild them
https://bugs.webkit.org/show_bug.cgi?id=108414
Reviewed by Mark Hahnenberg.
Introduces two new DFG forms: LoadStore and ThreadedCPS. These are described in
detail in DFGCommon.h.
Consequently, DFG phases no longer have to worry about preserving data flow
links between basic blocks. It is generally always safe to request that the
graph be dethreaded (Graph::dethread), which brings it into LoadStore form, where
the data flow is implicit. In this form, only liveness-at-head needs to be
preserved.
All of the machinery for "threading" the graph to introduce data flow between
blocks is now moved out of the bytecode parser and into the CPSRethreadingPhase.
All phases that previously did this maintenance themselves now just rely on
being able to dethread the graph. The one exception is the structure check
hoising phase, which operates over a threaded graph and preserves it, for the
sake of performance.
Also moved two other things into their own phases: unification (previously found
in the parser) and prediction injection (previously found in various places).
* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* bytecode/Operands.h:
(Operands):
(JSC::Operands::sizeFor):
(JSC::Operands::atFor):
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
(JSC::DFG::AbstractState::mergeStateAtTail):
* dfg/DFGAllocator.h:
(JSC::DFG::::allocateSlow):
* dfg/DFGArgumentsSimplificationPhase.cpp:
(JSC::DFG::ArgumentsSimplificationPhase::run):
* dfg/DFGBasicBlockInlines.h:
(DFG):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::getLocal):
(JSC::DFG::ByteCodeParser::getArgument):
(JSC::DFG::ByteCodeParser::flushDirect):
(JSC::DFG::ByteCodeParser::parseBlock):
(DFG):
(JSC::DFG::ByteCodeParser::parse):
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::run):
(JSC::DFG::CFGSimplificationPhase::killUnreachable):
(JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
(CFGSimplificationPhase):
(JSC::DFG::CFGSimplificationPhase::fixJettisonedPredecessors):
(JSC::DFG::CFGSimplificationPhase::mergeBlocks):
* dfg/DFGCPSRethreadingPhase.cpp: Added.
(DFG):
(CPSRethreadingPhase):
(JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
(JSC::DFG::CPSRethreadingPhase::run):
(JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
(JSC::DFG::CPSRethreadingPhase::clearVariablesAtHeadAndTail):
(JSC::DFG::CPSRethreadingPhase::addPhiSilently):
(JSC::DFG::CPSRethreadingPhase::addPhi):
(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocal):
(JSC::DFG::CPSRethreadingPhase::canonicalizeSetLocal):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocal):
(JSC::DFG::CPSRethreadingPhase::canonicalizeSetArgument):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks):
(JSC::DFG::CPSRethreadingPhase::propagatePhis):
(JSC::DFG::CPSRethreadingPhase::PhiStackEntry::PhiStackEntry):
(PhiStackEntry):
(JSC::DFG::CPSRethreadingPhase::phiStackFor):
(JSC::DFG::performCPSRethreading):
* dfg/DFGCPSRethreadingPhase.h: Added.
(DFG):
* dfg/DFGCSEPhase.cpp:
(CSEPhase):
(JSC::DFG::CSEPhase::performNodeCSE):
* dfg/DFGCommon.cpp:
(WTF):
(WTF::printInternal):
* dfg/DFGCommon.h:
(JSC::DFG::logCompilationChanges):
(DFG):
(WTF):
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* dfg/DFGDriver.cpp:
(JSC::DFG::compile):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::dethread):
(JSC::DFG::Graph::collectGarbage):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::performSubstitution):
(Graph):
(JSC::DFG::Graph::performSubstitutionForEdge):
(JSC::DFG::Graph::convertToConstant):
* dfg/DFGNode.h:
(JSC::DFG::Node::convertToPhantomLocal):
(Node):
(JSC::DFG::Node::convertToGetLocal):
(JSC::DFG::Node::hasVariableAccessData):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGPhase.cpp:
(JSC::DFG::Phase::beginPhase):
* dfg/DFGPhase.h:
(JSC::DFG::runAndLog):
* dfg/DFGPredictionInjectionPhase.cpp: Added.
(DFG):
(PredictionInjectionPhase):
(JSC::DFG::PredictionInjectionPhase::PredictionInjectionPhase):
(JSC::DFG::PredictionInjectionPhase::run):
(JSC::DFG::performPredictionInjection):
* dfg/DFGPredictionInjectionPhase.h: Added.
(DFG):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::run):
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGStructureCheckHoistingPhase.cpp:
(JSC::DFG::StructureCheckHoistingPhase::run):
* dfg/DFGUnificationPhase.cpp: Added.
(DFG):
(UnificationPhase):
(JSC::DFG::UnificationPhase::UnificationPhase):
(JSC::DFG::UnificationPhase::run):
(JSC::DFG::performUnification):
* dfg/DFGUnificationPhase.h: Added.
(DFG):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
(JSC::DFG::Validate::dumpGraphIfAppropriate):
* dfg/DFGVirtualRegisterAllocationPhase.cpp:
(JSC::DFG::VirtualRegisterAllocationPhase::run):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::setUpCall):
* runtime/JSCJSValue.cpp:
(JSC::JSValue::dump):
* runtime/JSString.h:
(JSString):
* runtime/Options.h:
(JSC):
2013-02-08 Jer Noble <jer.noble@apple.com>
Bring WebKit up to speed with latest Encrypted Media spec.
......
......@@ -195,6 +195,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGCapabilities.h \
Source/JavaScriptCore/dfg/DFGCFAPhase.cpp \
Source/JavaScriptCore/dfg/DFGCFAPhase.h \
Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp \
Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.h \
Source/JavaScriptCore/dfg/DFGCommon.cpp \
Source/JavaScriptCore/dfg/DFGCommon.h \
Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp \
......@@ -249,6 +251,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGPhase.h \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp \
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h \
Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.cpp \
Source/JavaScriptCore/dfg/DFGPredictionInjectionPhase.h \
Source/JavaScriptCore/dfg/DFGRegisterBank.h \
Source/JavaScriptCore/dfg/DFGRegisterSet.h \
Source/JavaScriptCore/dfg/DFGRepatch.cpp \
......@@ -266,6 +270,8 @@ javascriptcore_sources += \
Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.h \
Source/JavaScriptCore/dfg/DFGThunks.cpp \
Source/JavaScriptCore/dfg/DFGThunks.h \
Source/JavaScriptCore/dfg/DFGUnificationPhase.cpp \
Source/JavaScriptCore/dfg/DFGUnificationPhase.h \
Source/JavaScriptCore/dfg/DFGValueRecoveryOverride.h \
Source/JavaScriptCore/dfg/DFGValueSource.cpp \
Source/JavaScriptCore/dfg/DFGValueSource.h \
......
......@@ -201,7 +201,7 @@
0F96EBB316676EF6008BADE3 /* CodeBlockWithJITType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F96EBB116676EF4008BADE3 /* CodeBlockWithJITType.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9749711687ADE400A4FF6A /* JSCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F97496F1687ADE200A4FF6A /* JSCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F98205D16BFE37F00240D02 /* PreciseJumpTargets.cpp */; };
0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */; };
0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F98205E16BFE37F00240D02 /* PreciseJumpTargets.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9D3370165DBB90005AD387 /* Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D336E165DBB8D005AD387 /* Disassembler.cpp */; };
0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */; };
0F9FC8C414E1B60000D52AE0 /* PolymorphicPutByIdList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */; settings = {ATTRIBUTES = (Private, ); }; };
......@@ -234,6 +234,12 @@
0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */; };
0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBD7E691447999600481315 /* CodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBD7E671447998F00481315 /* CodeOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */; };
0FBE0F7316C1DB050082C5E8 /* DFGCPSRethreadingPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */; };
0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */; };
0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976D1468AB4E00CF2442 /* DFGAssemblyHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976E1468AB5100CF2442 /* DFGAssemblyHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */; };
......@@ -1119,6 +1125,12 @@
0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGExitProfile.cpp; sourceTree = "<group>"; };
0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGExitProfile.h; sourceTree = "<group>"; };
0FBD7E671447998F00481315 /* CodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeOrigin.h; sourceTree = "<group>"; };
0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCPSRethreadingPhase.cpp; path = dfg/DFGCPSRethreadingPhase.cpp; sourceTree = "<group>"; };
0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCPSRethreadingPhase.h; path = dfg/DFGCPSRethreadingPhase.h; sourceTree = "<group>"; };
0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPredictionInjectionPhase.cpp; path = dfg/DFGPredictionInjectionPhase.cpp; sourceTree = "<group>"; };
0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPredictionInjectionPhase.h; path = dfg/DFGPredictionInjectionPhase.h; sourceTree = "<group>"; };
0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUnificationPhase.cpp; path = dfg/DFGUnificationPhase.cpp; sourceTree = "<group>"; };
0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUnificationPhase.h; path = dfg/DFGUnificationPhase.h; sourceTree = "<group>"; };
0FC097681468A6EF00CF2442 /* DFGOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExit.h; path = dfg/DFGOSRExit.h; sourceTree = "<group>"; };
0FC0976B1468AB4A00CF2442 /* DFGAssemblyHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAssemblyHelpers.cpp; path = dfg/DFGAssemblyHelpers.cpp; sourceTree = "<group>"; };
0FC0976C1468AB4A00CF2442 /* DFGAssemblyHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAssemblyHelpers.h; path = dfg/DFGAssemblyHelpers.h; sourceTree = "<group>"; };
......@@ -2604,6 +2616,8 @@
0FC0977E1469EBC400CF2442 /* DFGCommon.h */,
0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */,
0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */,
0FBE0F6B16C1DB010082C5E8 /* DFGCPSRethreadingPhase.cpp */,
0FBE0F6C16C1DB010082C5E8 /* DFGCPSRethreadingPhase.h */,
0FFFC94D14EF909500C72532 /* DFGCSEPhase.cpp */,
0FFFC94E14EF909500C72532 /* DFGCSEPhase.h */,
0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */,
......@@ -2652,6 +2666,8 @@
0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */,
0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
0FFFC95014EF909500C72532 /* DFGPhase.h */,
0FBE0F6D16C1DB010082C5E8 /* DFGPredictionInjectionPhase.cpp */,
0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */,
0FFFC95114EF909500C72532 /* DFGPredictionPropagationPhase.cpp */,
0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */,
86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
......@@ -2671,6 +2687,8 @@
0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */,
0FC0979F146B28C700CF2442 /* DFGThunks.cpp */,
0FC097A0146B28C700CF2442 /* DFGThunks.h */,
0FBE0F6F16C1DB010082C5E8 /* DFGUnificationPhase.cpp */,
0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */,
0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */,
0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */,
0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */,
......@@ -3330,6 +3348,9 @@
86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
0F98206116BFE38300240D02 /* PreciseJumpTargets.h in Headers */,
0FBE0F7316C1DB050082C5E8 /* DFGCPSRethreadingPhase.h in Headers */,
0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */,
0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -3965,6 +3986,9 @@
86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
0F98206016BFE38100240D02 /* PreciseJumpTargets.cpp in Sources */,
0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */,
0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */,
0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -118,6 +118,7 @@ SOURCES += \
dfg/DFGCommon.cpp \
dfg/DFGCFAPhase.cpp \
dfg/DFGCFGSimplificationPhase.cpp \
dfg/DFGCPSRethreadingPhase.cpp \
dfg/DFGConstantFoldingPhase.cpp \
dfg/DFGCSEPhase.cpp \
dfg/DFGDisassembler.cpp \
......@@ -140,12 +141,14 @@ SOURCES += \
dfg/DFGOSRExitJumpPlaceholder.cpp \
dfg/DFGPhase.cpp \
dfg/DFGPredictionPropagationPhase.cpp \
dfg/DFGPredictionInjectionPhase.cpp \
dfg/DFGRepatch.cpp \
dfg/DFGSpeculativeJIT.cpp \
dfg/DFGSpeculativeJIT32_64.cpp \
dfg/DFGSpeculativeJIT64.cpp \
dfg/DFGStructureCheckHoistingPhase.cpp \
dfg/DFGThunks.cpp \
dfg/DFGUnificationPhase.cpp \
dfg/DFGValueSource.cpp \
dfg/DFGVariableAccessDataDump.cpp \
dfg/DFGVariableEvent.cpp \
......
......@@ -46,6 +46,8 @@ struct OperandValueTraits {
static void dump(const T& value, PrintStream& out) { value.dump(out); }
};
enum OperandKind { ArgumentOperand, LocalOperand };
template<typename T, typename Traits = OperandValueTraits<T> >
class Operands {
public:
......@@ -66,6 +68,28 @@ public:
T& local(size_t idx) { return m_locals[idx]; }
const T& local(size_t idx) const { return m_locals[idx]; }
template<OperandKind operandKind>
size_t sizeFor() const
{
if (operandKind == ArgumentOperand)
return numberOfArguments();
return numberOfLocals();
}
template<OperandKind operandKind>
T& atFor(size_t idx)
{
if (operandKind == ArgumentOperand)
return argument(idx);
return local(idx);
}
template<OperandKind operandKind>
const T& atFor(size_t idx) const
{
if (operandKind == ArgumentOperand)
return argument(idx);
return local(idx);
}
void ensureLocals(size_t size)
{
if (size <= m_locals.size())
......
......@@ -1787,6 +1787,7 @@ bool AbstractState::execute(unsigned indexInBlock)
case Phi:
case Flush:
case PhantomLocal:
node->setCanExit(false);
break;
......@@ -1913,6 +1914,7 @@ inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, Abstract
switch (node->op()) {
case Phi:
case SetArgument:
case PhantomLocal:
case Flush:
// The block transfers the value from head to tail.
source = inVariable;
......
......@@ -30,6 +30,7 @@
#if ENABLE(DFG_JIT)
#include "DFGCommon.h"
#include <wtf/PageAllocationAligned.h>
#include <wtf/StdLibExtras.h>
......@@ -197,6 +198,9 @@ void* Allocator<T>::allocateSlow()
ASSERT(!m_freeListHead);
ASSERT(!m_bumpRemaining);
if (logCompilationChanges())
dataLog("Allocating another allocator region.\n");
PageAllocationAligned allocation = PageAllocationAligned::allocate(Region::size(), Region::size(), OSAllocator::JSGCHeapPages);
if (!static_cast<bool>(allocation))
CRASH();
......
......@@ -239,7 +239,7 @@ public:
}
case GetLocal:
case Phi: {
case Phi: /* FIXME: https://bugs.webkit.org/show_bug.cgi?id=108555 */ {
VariableAccessData* variableAccessData = node->variableAccessData();
if (variableAccessData->isCaptured())
break;
......@@ -507,6 +507,7 @@ public:
m_graph.deref(node->child1());
node->children.child1() = Edge();
node->setOpAndDefaultFlags(GetMyArgumentsLength);
node->ref(); // This is a must-generate node.
changed = true;
--indexInBlock; // Force reconsideration of this op noew that it's a GetMyArgumentsLength.
break;
......@@ -635,8 +636,10 @@ public:
insertionSet.execute(block);
}
if (changed)
m_graph.collectGarbage();
if (changed) {
m_graph.dethread();
m_graph.m_form = LoadStore;
}
return changed;
}
......
......@@ -34,7 +34,7 @@
namespace JSC { namespace DFG {
#define DFG_DEFINE_APPEND_NODE(templatePre, templatePost, typeParams, valueParamsComma, valueParams, valueArgs) \
templatePre typeParams templatePost Node* BasicBlock::appendNode(Graph& graph, RefChildrenMode refChildrenMode, RefNodeMode refNodeMode, SpeculatedType type valueParamsComma valueParams) \
templatePre typeParams templatePost inline Node* BasicBlock::appendNode(Graph& graph, RefChildrenMode refChildrenMode, RefNodeMode refNodeMode, SpeculatedType type valueParamsComma valueParams) \
{ \
Node* result = graph.addNode(refChildrenMode, refNodeMode, type valueParamsComma valueArgs); \
append(result); \
......
This diff is collapsed.
/*
* 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 DFGCPSRethreadingPhase_h
#define DFGCPSRethreadingPhase_h
#include <wtf/Platform.h>
#if ENABLE(DFG_JIT)
namespace JSC { namespace DFG {
class Graph;
// CPS Rethreading:
//
// Takes a graph in which there are arbitrary GetLocals/SetLocals with no connections
// between them. Removes redundant ones in the case of uncaptured variables. Connects
// all of them with Phi functions to represent live ranges.
bool performCPSRethreading(Graph&);
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
#endif // DFGCPSRethreadingPhase_h
......@@ -974,27 +974,6 @@ private:
return result;
}
void performSubstitution(Edge& child, bool addRef = true)
{
// Check if this operand is actually unused.
if (!child)
return;
// Check if there is any replacement.
Node* replacement = child->replacement;
if (!replacement)
return;
child.setNode(replacement);
// There is definitely a replacement. Assert that the replacement does not
// have a replacement.
ASSERT(!child->replacement);
if (addRef)
m_graph.ref(child);
}
void eliminateIrrelevantPhantomChildren(Node* node)
{
ASSERT(node->op() == Phantom);
......@@ -1072,21 +1051,12 @@ private:
void performNodeCSE(Node* node)
{
bool shouldGenerate = node->shouldGenerate();
if (node->flags() & NodeHasVarArgs) {
for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++)
performSubstitution(m_graph.m_varArgChildren[childIdx], shouldGenerate);
} else {
performSubstitution(node->children.child1(), shouldGenerate);
performSubstitution(node->children.child2(), shouldGenerate);
performSubstitution(node->children.child3(), shouldGenerate);
}
m_graph.performSubstitution(node);
if (node->op() == SetLocal)
node->child1()->mergeFlags(NodeRelevantToOSR);
if (!shouldGenerate)
if (!node->shouldGenerate())
return;
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
......@@ -1162,26 +1132,16 @@ private:
Node* phi = node->child1().node();
if (!setReplacement(possibleReplacement))
break;
// If the GetLocal we replaced used to refer to a SetLocal, then it now
// should refer to the child of the SetLocal instead.
if (phi->op() == SetLocal) {
ASSERT(node->child1() == phi);
m_graph.changeEdge(node->children.child1(), phi->child1());
}
Node* oldTail = m_currentBlock->variablesAtTail.operand(
variableAccessData->local());
if (oldTail == node) {
m_currentBlock->variablesAtTail.operand(variableAccessData->local()) =
relevantLocalOp;
// Maintain graph integrity: since we're replacing a GetLocal with a GetLocalUnlinked,
// make sure that the GetLocalUnlinked is now linked.
if (relevantLocalOp->op() == GetLocalUnlinked) {
relevantLocalOp->setOp(GetLocal);
relevantLocalOp->children.child1() = Edge(phi);
m_graph.ref(phi);
}
m_graph.dethread();
// If we replace a GetLocal with a GetLocalUnlinked, then turn the GetLocalUnlinked
// into a GetLocal.
if (relevantLocalOp->op() == GetLocalUnlinked) {
relevantLocalOp->convertToGetLocal(variableAccessData, phi);
m_graph.ref(phi);
}
m_changed = true;
break;
}
......@@ -1235,9 +1195,7 @@ private:
m_graph.clearAndDerefChild1(node);
node->children.child1() = Edge(dataNode);
m_graph.ref(dataNode);
Node* oldTail = m_currentBlock->variablesAtTail.operand(local);
if (oldTail == node)
m_currentBlock->variablesAtTail.operand(local) = replacement;
m_graph.dethread();
m_changed = true;
break;
}
......
......@@ -39,5 +39,57 @@ void NodePointerTraits::dump(Node* value, PrintStream& out)
} } // namespace JSC::DFG
namespace WTF {
void printInternal(PrintStream& out, JSC::DFG::OptimizationFixpointState state)
{
switch (state) {
case JSC::DFG::BeforeFixpoint:
out.print("BeforeFixpoint");
break;
case JSC::DFG::FixpointNotConverged:
out.print("FixpointNotConverged");
break;
case JSC::DFG::FixpointConverged:
out.print("FixpointConverged");
break;
default:
RELEASE_ASSERT_NOT_REACHED();
break;
}
}
void printInternal(PrintStream& out, JSC::DFG::GraphForm form)
{
switch (form) {
case JSC::DFG::LoadStore:
out.print("LoadStore");
break;
case JSC::DFG::ThreadedCPS:
out.print("ThreadedCPS");
break;
default:
RELEASE_ASSERT_NOT_REACHED();
break;
}
}
void printInternal(PrintStream& out, JSC::DFG::UnificationState state)
{
switch (state) {
case JSC::DFG::LocallyUnified:
out.print("LocallyUnified");
break;
case JSC::DFG::GloballyUnified:
out.print("GloballyUnified");
break;
default:
RELEASE_ASSERT_NOT_REACHED();
break;
}
}
} // namespace WTF
#endif // ENABLE(DFG_JIT)
......@@ -146,6 +146,15 @@ inline bool verboseCompilationEnabled()
#endif
}
inline bool logCompilationChanges()
{
#if DFG_ENABLE(DEBUG_VERBOSE)
return true;
#else
return verboseCompilationEnabled() || Options::logCompilationChanges();
#endif
}
inline bool shouldDumpGraphAtEachPhase()
{
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
......@@ -157,7 +166,11 @@ inline bool shouldDumpGraphAtEachPhase()
inline bool validationEnabled()
{
#if !ASSERT_DISABLED
return true;
#else
return Options::validateGraph() || Options::validateGraphAtEachPhase();
#endif
}
enum SpillRegistersMode { NeedToSpill, DontSpill };
......@@ -166,8 +179,73 @@ enum NoResultTag { NoResult };
enum OptimizationFixpointState { BeforeFixpoint, FixpointNotConverged, FixpointConverged };
// Describes the form you can expect the entire graph to be in.
enum GraphForm {
// LoadStore form means that basic blocks may freely use GetLocal, SetLocal,
// GetLocalUnlinked, and Flush for accessing local variables and indicating
// where their live ranges ought to be. Data flow between local accesses is
// implicit. Liveness is only explicit at block heads (variablesAtHead).
// This is only used by the DFG simplifier and is only preserved by same.
//
// For example, LoadStore form gives no easy way to determine which SetLocal's
// flow into a GetLocal. As well, LoadStore form implies no restrictions on
// redundancy: you can freely emit multiple GetLocals, or multiple SetLocals