DFG should not use or preserve Phantoms during transformations
https://bugs.webkit.org/show_bug.cgi?id=143736
Reviewed by Geoffrey Garen.
Since http://trac.webkit.org/changeset/183207 and http://trac.webkit.org/changeset/183406, it is
no longer necessary to preserve Phantoms during transformations. They are still useful just
before FixupPhase to support backwards propagation analyses. They are still inserted late in the
game in the DFG backend. But transformations don't need to worry about them. Inside a basic
block, we can be sure that so long as the IR pinpoints the place where the value becomes
available in a bytecode register (using MovHint) and so long as there is a SetLocal anytime some
other block would need the value (either for OSR or for DFG execution), then we don't need any
liveness markers.
So, this removes any places where we inserted Phantoms just for liveness during transformation
and it replaces convertToPhantom() with remove(), which just converts the node to a Check. A
Check node only keeps its children so long as those children have checks.
The fact that we no longer convertToPhantom() means that we have to be more careful when
constant-folding GetLocal. Previously we would convertToPhantom() and use the fact that
Phantom(Phi) was a valid construct. It's not valid anymore. So, when constant folding encounters
a GetLocal it needs to insert a PhantomLocal directly. This allows us to simplify
Graph::convertToConstant() a bit. Luckily, none of the other users of this method would see
GetLocals.
The only Phantom-like cruft left over after this patch is:
- Phantoms before FixupPhase. I kind of like these. It means that before FixupPhase, we can do
backwards analyses and rely on the fact that the users of a node in DFG IR are a superset of
the users of the original local's live range in bytecode. This is essential for supporting our
BackwardsPropagationPhase, which is an important optimization for things like asm.js.
- PhantomLocals and GetLocals being NodeMustGenerate. See discussion in
https://bugs.webkit.org/show_bug.cgi?id=144086. It appears that this is not as evil as the
alternatives. The best long-term plan is to simply ditch the ThreadedCPS IR entirely and have
the DFG use SSA. For now, so long as any new DFG optimizations we add are block-local and
treat GetLocal/SetLocal conservatively, this should all be sound.
This change should be perf-neutral although it does reduce the total work that the compiler
does.
* CMakeLists.txt:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGAdjacencyList.h:
(JSC::DFG::AdjacencyList::justChecks):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGBasicBlock.cpp:
(JSC::DFG::BasicBlock::replaceTerminal):
* dfg/DFGBasicBlock.h:
(JSC::DFG::BasicBlock::findTerminal):
* dfg/DFGCFGSimplificationPhase.cpp:
(JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
(JSC::DFG::CFGSimplificationPhase::mergeBlocks):
* dfg/DFGCPSRethreadingPhase.cpp:
(JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
(JSC::DFG::CPSRethreadingPhase::clearVariables):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
* dfg/DFGCSEPhase.cpp:
* dfg/DFGCleanUpPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp.
(JSC::DFG::CleanUpPhase::CleanUpPhase):
(JSC::DFG::CleanUpPhase::run):
(JSC::DFG::performCleanUp):
(JSC::DFG::PhantomRemovalPhase::PhantomRemovalPhase): Deleted.
(JSC::DFG::PhantomRemovalPhase::run): Deleted.
(JSC::DFG::performPhantomRemoval): Deleted.
* dfg/DFGCleanUpPhase.h: Copied from Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h.
* dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
(JSC::DFG::ConstantFoldingPhase::addBaseCheck):
(JSC::DFG::ConstantFoldingPhase::fixUpsilons):
* dfg/DFGDCEPhase.cpp:
(JSC::DFG::DCEPhase::run):
(JSC::DFG::DCEPhase::fixupBlock):
(JSC::DFG::DCEPhase::cleanVariables):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupBlock):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::convertStringAddUse):
(JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
(JSC::DFG::FixupPhase::checkArray):
(JSC::DFG::FixupPhase::fixIntConvertingEdge):
(JSC::DFG::FixupPhase::fixIntOrBooleanEdge):
(JSC::DFG::FixupPhase::fixDoubleOrBooleanEdge):
(JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
(JSC::DFG::FixupPhase::tryToRelaxRepresentation):
(JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
(JSC::DFG::FixupPhase::addRequiredPhantom): Deleted.
(JSC::DFG::FixupPhase::addPhantomsIfNecessary): Deleted.
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::convertToConstant):
(JSC::DFG::Graph::mergeRelevantToOSR): Deleted.
* dfg/DFGGraph.h:
* dfg/DFGInsertionSet.h:
(JSC::DFG::InsertionSet::insertCheck):
* dfg/DFGIntegerCheckCombiningPhase.cpp:
(JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
* dfg/DFGLICMPhase.cpp:
(JSC::DFG::LICMPhase::attemptHoist):
* dfg/DFGNode.cpp:
(JSC::DFG::Node::remove):
* dfg/DFGNode.h:
(JSC::DFG::Node::replaceWith):
(JSC::DFG::Node::convertToPhantom): Deleted.
(JSC::DFG::Node::convertToCheck): Deleted.
(JSC::DFG::Node::willHaveCodeGenOrOSR): Deleted.
* dfg/DFGNodeFlags.h:
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
(JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
(JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
* dfg/DFGPhantomCanonicalizationPhase.cpp: Removed.
* dfg/DFGPhantomCanonicalizationPhase.h: Removed.
* dfg/DFGPhantomRemovalPhase.cpp: Removed.
* dfg/DFGPhantomRemovalPhase.h: Removed.
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPutStackSinkingPhase.cpp:
* dfg/DFGResurrectionForValidationPhase.cpp: Removed.
* dfg/DFGResurrectionForValidationPhase.h: Removed.
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
* dfg/DFGStoreBarrierElisionPhase.cpp:
(JSC::DFG::StoreBarrierElisionPhase::elideBarrier):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
(JSC::DFG::StrengthReductionPhase::convertToIdentityOverChild):
* dfg/DFGValidate.cpp:
(JSC::DFG::Validate::validate):
(JSC::DFG::Validate::validateCPS):
(JSC::DFG::Validate::validateSSA):
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileNoOp):
(JSC::FTL::LowerDFGToLLVM::compilePhantom): Deleted.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@183497 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index 58f1eb0..65d83a4 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -138,6 +138,7 @@
dfg/DFGCPSRethreadingPhase.cpp
dfg/DFGCSEPhase.cpp
dfg/DFGCapabilities.cpp
+ dfg/DFGCleanUpPhase.cpp
dfg/DFGClobberSet.cpp
dfg/DFGClobberize.cpp
dfg/DFGCommon.cpp
@@ -202,9 +203,7 @@
dfg/DFGObjectAllocationSinkingPhase.cpp
dfg/DFGObjectMaterializationData.cpp
dfg/DFGOperations.cpp
- dfg/DFGPhantomCanonicalizationPhase.cpp
dfg/DFGPhantomInsertionPhase.cpp
- dfg/DFGPhantomRemovalPhase.cpp
dfg/DFGPhase.cpp
dfg/DFGPhiChildren.cpp
dfg/DFGPlan.cpp
@@ -214,7 +213,6 @@
dfg/DFGPromotedHeapLocation.cpp
dfg/DFGPureValue.cpp
dfg/DFGPutStackSinkingPhase.cpp
- dfg/DFGResurrectionForValidationPhase.cpp
dfg/DFGSSACalculator.cpp
dfg/DFGSSAConversionPhase.cpp
dfg/DFGSSALoweringPhase.cpp
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 2adeaf6..f0e203b 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,147 @@
+2015-04-28 Filip Pizlo <fpizlo@apple.com>
+
+ DFG should not use or preserve Phantoms during transformations
+ https://bugs.webkit.org/show_bug.cgi?id=143736
+
+ Reviewed by Geoffrey Garen.
+
+ Since http://trac.webkit.org/changeset/183207 and http://trac.webkit.org/changeset/183406, it is
+ no longer necessary to preserve Phantoms during transformations. They are still useful just
+ before FixupPhase to support backwards propagation analyses. They are still inserted late in the
+ game in the DFG backend. But transformations don't need to worry about them. Inside a basic
+ block, we can be sure that so long as the IR pinpoints the place where the value becomes
+ available in a bytecode register (using MovHint) and so long as there is a SetLocal anytime some
+ other block would need the value (either for OSR or for DFG execution), then we don't need any
+ liveness markers.
+
+ So, this removes any places where we inserted Phantoms just for liveness during transformation
+ and it replaces convertToPhantom() with remove(), which just converts the node to a Check. A
+ Check node only keeps its children so long as those children have checks.
+
+ The fact that we no longer convertToPhantom() means that we have to be more careful when
+ constant-folding GetLocal. Previously we would convertToPhantom() and use the fact that
+ Phantom(Phi) was a valid construct. It's not valid anymore. So, when constant folding encounters
+ a GetLocal it needs to insert a PhantomLocal directly. This allows us to simplify
+ Graph::convertToConstant() a bit. Luckily, none of the other users of this method would see
+ GetLocals.
+
+ The only Phantom-like cruft left over after this patch is:
+
+ - Phantoms before FixupPhase. I kind of like these. It means that before FixupPhase, we can do
+ backwards analyses and rely on the fact that the users of a node in DFG IR are a superset of
+ the users of the original local's live range in bytecode. This is essential for supporting our
+ BackwardsPropagationPhase, which is an important optimization for things like asm.js.
+
+ - PhantomLocals and GetLocals being NodeMustGenerate. See discussion in
+ https://bugs.webkit.org/show_bug.cgi?id=144086. It appears that this is not as evil as the
+ alternatives. The best long-term plan is to simply ditch the ThreadedCPS IR entirely and have
+ the DFG use SSA. For now, so long as any new DFG optimizations we add are block-local and
+ treat GetLocal/SetLocal conservatively, this should all be sound.
+
+ This change should be perf-neutral although it does reduce the total work that the compiler
+ does.
+
+ * CMakeLists.txt:
+ * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGAdjacencyList.h:
+ (JSC::DFG::AdjacencyList::justChecks):
+ * dfg/DFGArgumentsEliminationPhase.cpp:
+ * dfg/DFGBasicBlock.cpp:
+ (JSC::DFG::BasicBlock::replaceTerminal):
+ * dfg/DFGBasicBlock.h:
+ (JSC::DFG::BasicBlock::findTerminal):
+ * dfg/DFGCFGSimplificationPhase.cpp:
+ (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
+ (JSC::DFG::CFGSimplificationPhase::mergeBlocks):
+ * dfg/DFGCPSRethreadingPhase.cpp:
+ (JSC::DFG::CPSRethreadingPhase::CPSRethreadingPhase):
+ (JSC::DFG::CPSRethreadingPhase::clearVariables):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):
+ (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
+ * dfg/DFGCSEPhase.cpp:
+ * dfg/DFGCleanUpPhase.cpp: Copied from Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp.
+ (JSC::DFG::CleanUpPhase::CleanUpPhase):
+ (JSC::DFG::CleanUpPhase::run):
+ (JSC::DFG::performCleanUp):
+ (JSC::DFG::PhantomRemovalPhase::PhantomRemovalPhase): Deleted.
+ (JSC::DFG::PhantomRemovalPhase::run): Deleted.
+ (JSC::DFG::performPhantomRemoval): Deleted.
+ * dfg/DFGCleanUpPhase.h: Copied from Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h.
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (JSC::DFG::ConstantFoldingPhase::addBaseCheck):
+ (JSC::DFG::ConstantFoldingPhase::fixUpsilons):
+ * dfg/DFGDCEPhase.cpp:
+ (JSC::DFG::DCEPhase::run):
+ (JSC::DFG::DCEPhase::fixupBlock):
+ (JSC::DFG::DCEPhase::cleanVariables):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupBlock):
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::convertStringAddUse):
+ (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
+ (JSC::DFG::FixupPhase::checkArray):
+ (JSC::DFG::FixupPhase::fixIntConvertingEdge):
+ (JSC::DFG::FixupPhase::fixIntOrBooleanEdge):
+ (JSC::DFG::FixupPhase::fixDoubleOrBooleanEdge):
+ (JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
+ (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
+ (JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
+ (JSC::DFG::FixupPhase::addRequiredPhantom): Deleted.
+ (JSC::DFG::FixupPhase::addPhantomsIfNecessary): Deleted.
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::convertToConstant):
+ (JSC::DFG::Graph::mergeRelevantToOSR): Deleted.
+ * dfg/DFGGraph.h:
+ * dfg/DFGInsertionSet.h:
+ (JSC::DFG::InsertionSet::insertCheck):
+ * dfg/DFGIntegerCheckCombiningPhase.cpp:
+ (JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
+ * dfg/DFGLICMPhase.cpp:
+ (JSC::DFG::LICMPhase::attemptHoist):
+ * dfg/DFGNode.cpp:
+ (JSC::DFG::Node::remove):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::replaceWith):
+ (JSC::DFG::Node::convertToPhantom): Deleted.
+ (JSC::DFG::Node::convertToCheck): Deleted.
+ (JSC::DFG::Node::willHaveCodeGenOrOSR): Deleted.
+ * dfg/DFGNodeFlags.h:
+ * dfg/DFGNodeType.h:
+ * dfg/DFGObjectAllocationSinkingPhase.cpp:
+ (JSC::DFG::ObjectAllocationSinkingPhase::lowerNonReadingOperationsOnPhantomAllocations):
+ (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+ * dfg/DFGPhantomCanonicalizationPhase.cpp: Removed.
+ * dfg/DFGPhantomCanonicalizationPhase.h: Removed.
+ * dfg/DFGPhantomRemovalPhase.cpp: Removed.
+ * dfg/DFGPhantomRemovalPhase.h: Removed.
+ * dfg/DFGPlan.cpp:
+ (JSC::DFG::Plan::compileInThreadImpl):
+ * dfg/DFGPutStackSinkingPhase.cpp:
+ * dfg/DFGResurrectionForValidationPhase.cpp: Removed.
+ * dfg/DFGResurrectionForValidationPhase.h: Removed.
+ * dfg/DFGSSAConversionPhase.cpp:
+ (JSC::DFG::SSAConversionPhase::run):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+ * dfg/DFGStoreBarrierElisionPhase.cpp:
+ (JSC::DFG::StoreBarrierElisionPhase::elideBarrier):
+ * dfg/DFGStrengthReductionPhase.cpp:
+ (JSC::DFG::StrengthReductionPhase::handleNode):
+ (JSC::DFG::StrengthReductionPhase::convertToIdentityOverChild):
+ * dfg/DFGValidate.cpp:
+ (JSC::DFG::Validate::validate):
+ (JSC::DFG::Validate::validateCPS):
+ (JSC::DFG::Validate::validateSSA):
+ * dfg/DFGVarargsForwardingPhase.cpp:
+ * ftl/FTLLink.cpp:
+ (JSC::FTL::link):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compileNode):
+ (JSC::FTL::LowerDFGToLLVM::compileNoOp):
+ (JSC::FTL::LowerDFGToLLVM::compilePhantom): Deleted.
+
2015-04-28 Andreas Kling <akling@apple.com>
DFG+FTL should generate efficient code for branching on a string's boolean value.
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
index 02e379c..febde27 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
@@ -380,6 +380,7 @@
<ClCompile Include="..\dfg\DFGCapabilities.cpp" />
<ClCompile Include="..\dfg\DFGCFAPhase.cpp" />
<ClCompile Include="..\dfg\DFGCFGSimplificationPhase.cpp" />
+ <ClCompile Include="..\dfg\DFGCleanUpPhase.cpp" />
<ClCompile Include="..\dfg\DFGClobberize.cpp" />
<ClCompile Include="..\dfg\DFGClobberSet.cpp" />
<ClCompile Include="..\dfg\DFGCommon.cpp" />
@@ -446,9 +447,7 @@
<ClCompile Include="..\dfg\DFGOSRExitPreparation.cpp" />
<ClCompile Include="..\dfg\DFGObjectAllocationSinkingPhase.cpp" />
<ClCompile Include="..\dfg\DFGObjectMaterializationData.cpp" />
- <ClCompile Include="..\dfg\DFGPhantomCanonicalizationPhase.cpp" />
<ClCompile Include="..\dfg\DFGPhantomInsertionPhase.cpp" />
- <ClCompile Include="..\dfg\DFGPhantomRemovalPhase.cpp" />
<ClCompile Include="..\dfg\DFGPhase.cpp" />
<ClCompile Include="..\dfg\DFGPhiChildren.cpp" />
<ClCompile Include="..\dfg\DFGPlan.cpp" />
@@ -458,7 +457,6 @@
<ClCompile Include="..\dfg\DFGPromotedHeapLocation.cpp" />
<ClCompile Include="..\dfg\DFGPureValue.cpp" />
<ClCompile Include="..\dfg\DFGPutStackSinkingPhase.cpp" />
- <ClCompile Include="..\dfg\DFGResurrectionForValidationPhase.cpp" />
<ClCompile Include="..\dfg\DFGSafepoint.cpp" />
<ClCompile Include="..\dfg\DFGSpeculativeJIT.cpp" />
<ClCompile Include="..\dfg\DFGSpeculativeJIT32_64.cpp" />
@@ -1062,6 +1060,7 @@
<ClInclude Include="..\dfg\DFGCCallHelpers.h" />
<ClInclude Include="..\dfg\DFGCFAPhase.h" />
<ClInclude Include="..\dfg\DFGCFGSimplificationPhase.h" />
+ <ClInclude Include="..\dfg\DFGCleanUpPhase.h" />
<ClInclude Include="..\dfg\DFGClobberize.h" />
<ClInclude Include="..\dfg\DFGClobberSet.h" />
<ClInclude Include="..\dfg\DFGCommon.h" />
@@ -1142,9 +1141,7 @@
<ClInclude Include="..\dfg\DFGOSRExitCompilerCommon.h" />
<ClInclude Include="..\dfg\DFGOSRExitJumpPlaceholder.h" />
<ClInclude Include="..\dfg\DFGOSRExitPreparation.h" />
- <ClInclude Include="..\dfg\DFGPhantomCanonicalizationPhase.h" />
<ClInclude Include="..\dfg\DFGPhantomInsertionPhase.h" />
- <ClInclude Include="..\dfg\DFGPhantomRemovalPhase.h" />
<ClInclude Include="..\dfg\DFGPhase.h" />
<ClInclude Include="..\dfg\DFGPhiChildren.h" />
<ClInclude Include="..\dfg\DFGPlan.h" />
@@ -1158,7 +1155,6 @@
<ClInclude Include="..\dfg\DFGPutStackSinkingPhase.h" />
<ClInclude Include="..\dfg\DFGRegisterBank.h" />
<ClInclude Include="..\dfg\DFGRegisterSet.h" />
- <ClInclude Include="..\dfg\DFGResurrectionForValidationPhase.h" />
<ClInclude Include="..\dfg\DFGSafeToExecute.h" />
<ClInclude Include="..\dfg\DFGSafepoint.h" />
<ClInclude Include="..\dfg\DFGSaneStringGetByValSlowPathGenerator.h" />
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index c790580..1a2b460 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -365,8 +365,6 @@
0F666EC1183566F900D017F1 /* FullBytecodeLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F666EC61835672B00D017F1 /* DFGAvailability.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666EC21835672B00D017F1 /* DFGAvailability.cpp */; };
0F666EC71835672B00D017F1 /* DFGAvailability.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666EC31835672B00D017F1 /* DFGAvailability.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0F666ECC1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */; };
- 0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F66E16C14DF3F1600B7B2E4 /* DFGEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F682FB219BCB36400FA3BAD /* DFGSSACalculator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F682FB019BCB36400FA3BAD /* DFGSSACalculator.cpp */; };
@@ -410,8 +408,6 @@
0F79085619A290B200F6310C /* DFGStructureRegistrationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0977E1469EBC400CF2442 /* DFGCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0F7B3661197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7B365F197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp */; };
- 0F7B3662197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7B3660197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8023E91613832300A0BA45 /* ByValInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F8335B71639C1E6001443B5 /* ArrayAllocationProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */; };
0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -462,6 +458,8 @@
0F9D339717FFC4E60073C2BC /* DFGFlushedAt.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9D339A1803ADB70073C2BC /* FTLStackMaps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D33981803ADB70073C2BC /* FTLStackMaps.cpp */; };
0F9D339B1803ADB70073C2BC /* FTLStackMaps.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D33991803ADB70073C2BC /* FTLStackMaps.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F9D36941AE9CC33000D4DFB /* DFGCleanUpPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D36921AE9CC33000D4DFB /* DFGCleanUpPhase.cpp */; };
+ 0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D36931AE9CC33000D4DFB /* DFGCleanUpPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FB4F217FCB91700CB67F8 /* DFGStackLayoutPhase.cpp */; };
0F9FB4F517FCB91700CB67F8 /* DFGStackLayoutPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F9FC8C314E1B5FE00D52AE0 /* PolymorphicPutByIdList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */; };
@@ -519,8 +517,6 @@
0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBF158C19B7A53100695DD0 /* DFGBlockSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */; };
0FBF158D19B7A53100695DD0 /* DFGBlockSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0FBFDD04196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */; };
- 0FBFDD05196C92BF007A5BFA /* DFGPhantomRemovalPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0977114693AF500CF2442 /* DFGOSRExitCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */; };
@@ -2102,8 +2098,6 @@
0F666EBF183566F900D017F1 /* FullBytecodeLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FullBytecodeLiveness.h; sourceTree = "<group>"; };
0F666EC21835672B00D017F1 /* DFGAvailability.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAvailability.cpp; path = dfg/DFGAvailability.cpp; sourceTree = "<group>"; };
0F666EC31835672B00D017F1 /* DFGAvailability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAvailability.h; path = dfg/DFGAvailability.h; sourceTree = "<group>"; };
- 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGResurrectionForValidationPhase.cpp; path = dfg/DFGResurrectionForValidationPhase.cpp; sourceTree = "<group>"; };
- 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGResurrectionForValidationPhase.h; path = dfg/DFGResurrectionForValidationPhase.h; sourceTree = "<group>"; };
0F66E16814DF3F1300B7B2E4 /* DFGAdjacencyList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAdjacencyList.h; path = dfg/DFGAdjacencyList.h; sourceTree = "<group>"; };
0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGEdge.h; path = dfg/DFGEdge.h; sourceTree = "<group>"; };
0F682FB019BCB36400FA3BAD /* DFGSSACalculator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSSACalculator.cpp; path = dfg/DFGSSACalculator.cpp; sourceTree = "<group>"; };
@@ -2145,8 +2139,6 @@
0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
0F79085319A290B200F6310C /* DFGStructureRegistrationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStructureRegistrationPhase.cpp; path = dfg/DFGStructureRegistrationPhase.cpp; sourceTree = "<group>"; };
0F79085419A290B200F6310C /* DFGStructureRegistrationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureRegistrationPhase.h; path = dfg/DFGStructureRegistrationPhase.h; sourceTree = "<group>"; };
- 0F7B365F197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhantomCanonicalizationPhase.cpp; path = dfg/DFGPhantomCanonicalizationPhase.cpp; sourceTree = "<group>"; };
- 0F7B3660197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhantomCanonicalizationPhase.h; path = dfg/DFGPhantomCanonicalizationPhase.h; sourceTree = "<group>"; };
0F8023E91613832300A0BA45 /* ByValInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByValInfo.h; sourceTree = "<group>"; };
0F8335B41639C1E3001443B5 /* ArrayAllocationProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayAllocationProfile.cpp; sourceTree = "<group>"; };
0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; };
@@ -2197,6 +2189,8 @@
0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFlushedAt.h; path = dfg/DFGFlushedAt.h; sourceTree = "<group>"; };
0F9D33981803ADB70073C2BC /* FTLStackMaps.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLStackMaps.cpp; path = ftl/FTLStackMaps.cpp; sourceTree = "<group>"; };
0F9D33991803ADB70073C2BC /* FTLStackMaps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLStackMaps.h; path = ftl/FTLStackMaps.h; sourceTree = "<group>"; };
+ 0F9D36921AE9CC33000D4DFB /* DFGCleanUpPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCleanUpPhase.cpp; path = dfg/DFGCleanUpPhase.cpp; sourceTree = "<group>"; };
+ 0F9D36931AE9CC33000D4DFB /* DFGCleanUpPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCleanUpPhase.h; path = dfg/DFGCleanUpPhase.h; sourceTree = "<group>"; };
0F9FB4F217FCB91700CB67F8 /* DFGStackLayoutPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStackLayoutPhase.cpp; path = dfg/DFGStackLayoutPhase.cpp; sourceTree = "<group>"; };
0F9FB4F317FCB91700CB67F8 /* DFGStackLayoutPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStackLayoutPhase.h; path = dfg/DFGStackLayoutPhase.h; sourceTree = "<group>"; };
0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicPutByIdList.cpp; sourceTree = "<group>"; };
@@ -2264,8 +2258,6 @@
0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUnificationPhase.h; path = dfg/DFGUnificationPhase.h; sourceTree = "<group>"; };
0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockSet.cpp; path = dfg/DFGBlockSet.cpp; sourceTree = "<group>"; };
0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockSetInlines.h; path = dfg/DFGBlockSetInlines.h; sourceTree = "<group>"; };
- 0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGPhantomRemovalPhase.cpp; path = dfg/DFGPhantomRemovalPhase.cpp; sourceTree = "<group>"; };
- 0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPhantomRemovalPhase.h; path = dfg/DFGPhantomRemovalPhase.h; sourceTree = "<group>"; };
0FC097681468A6EF00CF2442 /* DFGOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExit.h; path = dfg/DFGOSRExit.h; sourceTree = "<group>"; };
0FC0976F14693AEF00CF2442 /* DFGOSRExitCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompiler.h; path = dfg/DFGOSRExitCompiler.h; sourceTree = "<group>"; };
0FC0977014693AEF00CF2442 /* DFGOSRExitCompiler64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitCompiler64.cpp; path = dfg/DFGOSRExitCompiler64.cpp; sourceTree = "<group>"; };
@@ -4880,6 +4872,8 @@
0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */,
0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */,
0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */,
+ 0F9D36921AE9CC33000D4DFB /* DFGCleanUpPhase.cpp */,
+ 0F9D36931AE9CC33000D4DFB /* DFGCleanUpPhase.h */,
A77A423817A0BBFD00A8DB81 /* DFGClobberize.cpp */,
A77A423917A0BBFD00A8DB81 /* DFGClobberize.h */,
A77A423A17A0BBFD00A8DB81 /* DFGClobberSet.cpp */,
@@ -5026,12 +5020,8 @@
0FEFC9A81681A3B000567F53 /* DFGOSRExitJumpPlaceholder.h */,
0F235BE917178E7300690C7F /* DFGOSRExitPreparation.cpp */,
0F235BEA17178E7300690C7F /* DFGOSRExitPreparation.h */,
- 0F7B365F197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp */,
- 0F7B3660197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.h */,
0F6237951AE45CA700D402EA /* DFGPhantomInsertionPhase.cpp */,
0F6237961AE45CA700D402EA /* DFGPhantomInsertionPhase.h */,
- 0FBFDD02196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp */,
- 0FBFDD03196C92BF007A5BFA /* DFGPhantomRemovalPhase.h */,
0FFFC94F14EF909500C72532 /* DFGPhase.cpp */,
0FFFC95014EF909500C72532 /* DFGPhase.h */,
0F2B9CDE19D0BA7D00B1D1B5 /* DFGPhiChildren.cpp */,
@@ -5053,8 +5043,6 @@
0F3A1BF71A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp */,
0F3A1BF81A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h */,
86EC9DC11328DF82002B2AD7 /* DFGRegisterBank.h */,
- 0F666ECA1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp */,
- 0F666ECB1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h */,
0F2FCCF418A60070001A27F8 /* DFGSafepoint.cpp */,
0F2FCCF518A60070001A27F8 /* DFGSafepoint.h */,
A77A423C17A0BBFD00A8DB81 /* DFGSafeToExecute.h */,
@@ -5868,7 +5856,6 @@
0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */,
0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */,
86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */,
- 0F666ECD1836B37E00D017F1 /* DFGResurrectionForValidationPhase.h in Headers */,
0F2FCCFC18A60070001A27F8 /* DFGSafepoint.h in Headers */,
A77A424317A0BBFD00A8DB81 /* DFGSafeToExecute.h in Headers */,
A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */,
@@ -5943,6 +5930,7 @@
0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */,
0F235BD717178E1C00690C7F /* FTLExitArgumentList.h in Headers */,
0F235BD917178E1C00690C7F /* FTLExitThunkGenerator.h in Headers */,
+ 0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */,
0F235BDB17178E1C00690C7F /* FTLExitValue.h in Headers */,
A53CE08618BC1A5600BEDF76 /* ConsolePrototype.h in Headers */,
A7F2996C17A0BB670010417A /* FTLFail.h in Headers */,
@@ -6053,7 +6041,6 @@
8606DDEA18DA44AB00A383D0 /* IdentifierInlines.h in Headers */,
A532438C18568335002ED692 /* InspectorProtocolObjects.h in Headers */,
A50E4B6218809DD50068A46D /* InspectorRuntimeAgent.h in Headers */,
- 0FBFDD05196C92BF007A5BFA /* DFGPhantomRemovalPhase.h in Headers */,
A55D93AC18514F7900400DED /* InspectorProtocolTypes.h in Headers */,
A593CF831840377100BFCE27 /* InspectorValues.h in Headers */,
969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */,
@@ -6142,7 +6129,6 @@
0F2B66F217B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructor.h in Headers */,
0F2B66F317B6B5AB00A7AE3F /* JSGenericTypedArrayViewConstructorInlines.h in Headers */,
0F2B66F417B6B5AB00A7AE3F /* JSGenericTypedArrayViewInlines.h in Headers */,
- 0F7B3662197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.h in Headers */,
0F5A1274192D9FDF008764A3 /* DFGDoesGC.h in Headers */,
0F2B66F517B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototype.h in Headers */,
0F2B66F617B6B5AB00A7AE3F /* JSGenericTypedArrayViewPrototypeInlines.h in Headers */,
@@ -7110,6 +7096,7 @@
0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
0FD120331A8C85BD000F5280 /* FTLJSCallVarargs.cpp in Sources */,
0F9D339617FFC4E60073C2BC /* DFGFlushedAt.cpp in Sources */,
+ 0F9D36941AE9CC33000D4DFB /* DFGCleanUpPhase.cpp in Sources */,
A7D89CF717A0B8CC00773AD8 /* DFGFlushFormat.cpp in Sources */,
0F3A1BF91A9ECB7D000DE01A /* DFGPutStackSinkingPhase.cpp in Sources */,
86EC9DC71328DF82002B2AD7 /* DFGGraph.cpp in Sources */,
@@ -7152,7 +7139,6 @@
A78A977A179738B8009DF744 /* DFGPlan.cpp in Sources */,
0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */,
0FFFC95D14EF90B300C72532 /* DFGPredictionPropagationPhase.cpp in Sources */,
- 0F666ECC1836B37E00D017F1 /* DFGResurrectionForValidationPhase.cpp in Sources */,
0F2FCCFB18A60070001A27F8 /* DFGSafepoint.cpp in Sources */,
86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */,
86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
@@ -7367,7 +7353,6 @@
A503FA1D188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp in Sources */,
14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */,
0F3D0BBC194A414300FC9CF9 /* ConstantStructureCheck.cpp in Sources */,
- 0F7B3661197C525C00ED1DDC /* DFGPhantomCanonicalizationPhase.cpp in Sources */,
C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */,
A700874117CBE8EB00C3E643 /* JSMap.cpp in Sources */,
A74DEF95182D991400522C22 /* JSMapIterator.cpp in Sources */,
@@ -7540,7 +7525,6 @@
C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */,
9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
0F8F2B9E17306C8D007DBDA5 /* SourceCode.cpp in Sources */,
- 0FBFDD04196C92BF007A5BFA /* DFGPhantomRemovalPhase.cpp in Sources */,
0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */,
0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */,
diff --git a/Source/JavaScriptCore/dfg/DFGAdjacencyList.h b/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
index 358ac79..63ebef5 100644
--- a/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
+++ b/Source/JavaScriptCore/dfg/DFGAdjacencyList.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -156,6 +156,21 @@
return AdjacencyList(Fixed, child1().sanitized(), child2().sanitized(), child3().sanitized());
}
+ AdjacencyList justChecks() const
+ {
+ AdjacencyList result(Fixed);
+ unsigned sourceIndex = 0;
+ unsigned targetIndex = 0;
+ while (sourceIndex < AdjacencyList::Size) {
+ Edge edge = child(sourceIndex++);
+ if (!edge)
+ break;
+ if (edge.willHaveCheck())
+ result.child(targetIndex++) = edge;
+ }
+ return result;
+ }
+
unsigned hash() const
{
unsigned result = 0;
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp
index a974f13..77ab193 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp
@@ -159,7 +159,6 @@
escape(node->child3());
break;
- case Phantom:
case Check:
case MovHint:
case PutHint:
@@ -353,7 +352,6 @@
break;
node->setOpAndDefaultFlags(PhantomDirectArguments);
- insertionSet.insertNode(nodeIndex + 1, SpecNone, Phantom, node->origin, Edge(node));
break;
case CreateClonedArguments:
@@ -361,7 +359,6 @@
break;
node->setOpAndDefaultFlags(PhantomClonedArguments);
- insertionSet.insertNode(nodeIndex + 1, SpecNone, Phantom, node->origin, Edge(node));
break;
case GetFromArguments: {
@@ -485,7 +482,7 @@
nodeIndex, SpecNone, PutStack, node->origin, OpInfo(data), Edge(value));
}
- node->convertToPhantom();
+ node->remove();
break;
}
@@ -536,7 +533,7 @@
case GetButterfly: {
if (!m_candidates.contains(node->child1().node()))
break;
- node->convertToPhantom();
+ node->remove();
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp b/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp
index 7949e13..f83f50c 100644
--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.cpp
@@ -78,7 +78,7 @@
append(node);
else {
m_nodes.insert(result.index + 1, node);
- result.node->convertToPhantom();
+ result.node->remove();
}
ASSERT(terminal());
diff --git a/Source/JavaScriptCore/dfg/DFGBasicBlock.h b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
index f0d21e6..420ff51 100644
--- a/Source/JavaScriptCore/dfg/DFGBasicBlock.h
+++ b/Source/JavaScriptCore/dfg/DFGBasicBlock.h
@@ -94,7 +94,8 @@
case Return:
case Unreachable:
return NodeAndIndex(node, i);
- // The bitter end can contain Phantoms and the like. There will probably only be one or two nodes after the terminal.
+ // The bitter end can contain Phantoms and the like. There will probably only be one or two nodes after the terminal. They are all no-ops and will not have any checked children.
+ case Check: // This is here because it's our universal no-op.
case Phantom:
case PhantomLocal:
case Flush:
diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
index 4d37c7a..34a1336 100644
--- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
@@ -272,8 +272,13 @@
NodeType nodeType;
if (livenessNode->flags() & NodeIsFlushed)
nodeType = Flush;
- else
+ else {
+ // This seems like it shouldn't be necessary because we could just rematerialize
+ // PhantomLocals or something similar using bytecode liveness. However, in ThreadedCPS, it's
+ // worth the sanity to maintain this eagerly. See
+ // https://bugs.webkit.org/show_bug.cgi?id=144086
nodeType = PhantomLocal;
+ }
block->appendNode(
m_graph, SpecNone, nodeType, nodeOrigin,
OpInfo(livenessNode->variableAccessData()));
@@ -317,11 +322,11 @@
// kept alive.
// Remove the terminal of firstBlock since we don't need it anymore. Well, we don't
- // really remove it; we actually turn it into a Phantom.
+ // really remove it; we actually turn it into a check.
Node* terminal = firstBlock->terminal();
ASSERT(terminal->isTerminal());
NodeOrigin boundaryNodeOrigin = terminal->origin;
- terminal->convertToPhantom();
+ terminal->remove();
ASSERT(terminal->refCount() == 1);
for (unsigned i = jettisonedBlocks.size(); i--;) {
diff --git a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
index 3489424..91a1ec6 100644
--- a/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCPSRethreadingPhase.cpp
@@ -39,7 +39,6 @@
public:
CPSRethreadingPhase(Graph& graph)
: Phase(graph, "CPS rethreading")
- , m_availableForOSR(OperandsLike, graph.block(0)->variablesAtHead)
{
}
@@ -126,14 +125,10 @@
ASSERT(
m_block->variablesAtHead.sizeFor<operandKind>()
== m_block->variablesAtTail.sizeFor<operandKind>());
- ASSERT(
- m_block->variablesAtHead.sizeFor<operandKind>()
- == m_availableForOSR.sizeFor<operandKind>());
for (unsigned i = m_block->variablesAtHead.sizeFor<operandKind>(); i--;) {
m_block->variablesAtHead.atFor<operandKind>(i) = nullptr;
m_block->variablesAtTail.atFor<operandKind>(i) = nullptr;
- m_availableForOSR.atFor<operandKind>(i) = Edge();
}
}
@@ -247,8 +242,7 @@
// redundant and inefficient, since really it just means that we want to
// keep the last MovHinted value of that local alive.
- node->children.setChild1(m_availableForOSR.atFor<operandKind>(idx));
- node->convertToPhantom();
+ node->remove();
return;
}
@@ -359,14 +353,6 @@
canonicalizeSet(node);
break;
- case MovHint:
- m_availableForOSR.operand(node->unlinkedLocal()) = node->child1();
- break;
-
- case ZombieHint:
- m_availableForOSR.operand(node->unlinkedLocal()) = Edge();
- break;
-
default:
break;
}
@@ -517,7 +503,6 @@
Vector<PhiStackEntry, 128> m_argumentPhiStack;
Vector<PhiStackEntry, 128> m_localPhiStack;
Vector<Node*, 128> m_flushedLocalOpWorklist;
- Operands<Edge> m_availableForOSR;
};
bool performCPSRethreading(Graph& graph)
diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
index 0ceaa25..1413843 100644
--- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp
@@ -234,8 +234,7 @@
m_graph.performSubstitution(m_node);
if (m_node->op() == Identity) {
- m_node->convertToCheck();
- m_node->setReplacement(m_node->child1().node());
+ m_node->replaceWith(m_node->child1().node());
m_changed = true;
} else {
// This rule only makes sense for local CSE, since in SSA form we have already
@@ -437,8 +436,7 @@
m_graph.performSubstitution(m_node);
if (m_node->op() == Identity) {
- m_node->convertToCheck();
- m_node->setReplacement(m_node->child1().node());
+ m_node->replaceWith(m_node->child1().node());
m_changed = true;
} else
clobberize(m_graph, m_node, *this);
diff --git a/Source/JavaScriptCore/dfg/DFGCleanUpPhase.cpp b/Source/JavaScriptCore/dfg/DFGCleanUpPhase.cpp
new file mode 100644
index 0000000..313094c
--- /dev/null
+++ b/Source/JavaScriptCore/dfg/DFGCleanUpPhase.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014, 2015 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 "DFGCleanUpPhase.h"
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+#include "DFGInsertionSet.h"
+#include "DFGPhase.h"
+#include "DFGPredictionPropagationPhase.h"
+#include "DFGVariableAccessDataDump.h"
+#include "JSCInlines.h"
+
+namespace JSC { namespace DFG {
+
+class CleanUpPhase : public Phase {
+public:
+ CleanUpPhase(Graph& graph)
+ : Phase(graph, "clean up")
+ {
+ }
+
+ bool run()
+ {
+ bool changed = false;
+
+ for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
+ unsigned sourceIndex = 0;
+ unsigned targetIndex = 0;
+ while (sourceIndex < block->size()) {
+ Node* node = block->at(sourceIndex++);
+ bool kill = false;
+
+ if (node->op() == Check)
+ node->children = node->children.justChecks();
+
+ switch (node->op()) {
+ case Phantom:
+ case Check:
+ if (node->children.isEmpty())
+ kill = true;
+ break;
+ default:
+ break;
+ }
+
+ if (kill)
+ m_graph.m_allocator.free(node);
+ else
+ block->at(targetIndex++) = node;
+ }
+ block->resize(targetIndex);
+ }
+
+ return changed;
+ }
+};
+
+bool performCleanUp(Graph& graph)
+{
+ SamplingRegion samplingRegion("DFG Clean Up Phase");
+ return runPhase<CleanUpPhase>(graph);
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
diff --git a/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h b/Source/JavaScriptCore/dfg/DFGCleanUpPhase.h
similarity index 73%
rename from Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h
rename to Source/JavaScriptCore/dfg/DFGCleanUpPhase.h
index c02afd2..3a1bc69 100644
--- a/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.h
+++ b/Source/JavaScriptCore/dfg/DFGCleanUpPhase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,8 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DFGPhantomRemovalPhase_h
-#define DFGPhantomRemovalPhase_h
+#ifndef DFGCleanUpPhase_h
+#define DFGCleanUpPhase_h
#if ENABLE(DFG_JIT)
@@ -32,16 +32,12 @@
class Graph;
-// Cleans up unnecessary Phantoms and Phanton children. This reduces live ranges, but also, it
-// eliminates many Phantoms entirely. This invalidates liveness analysis.
-//
-// This should work over all IR forms; however, in SSA form it's better to run
-// PhantomCanonicalizationPhase since it's more powerful.
+// Cleans up unneeded nodes, like empty Checks and Phantoms.
-bool performPhantomRemoval(Graph&);
+bool performCleanUp(Graph&);
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
-#endif // DFGPhantomRemovalPhase_h
+#endif // DFGCleanUpPhase_h
diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
index 9589b5e..0e57a07 100644
--- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
@@ -108,7 +108,7 @@
set = node->structureSet();
if (value.m_structure.isSubsetOf(set)) {
m_interpreter.execute(indexInBlock); // Catch the fact that we may filter on cell.
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -133,8 +133,7 @@
m_interpreter.execute(indexInBlock);
eliminated = true;
- m_insertionSet.insertNode(
- indexInBlock, SpecNone, Phantom, node->origin, node->children);
+ m_insertionSet.insertCheck(indexInBlock, node->origin, node->children);
node->convertToConstantStoragePointer(view->vector());
break;
}
@@ -147,7 +146,7 @@
if (Structure* structure = jsDynamicCast<Structure*>(value.value())) {
if (set.contains(structure)) {
m_interpreter.execute(indexInBlock);
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -167,7 +166,7 @@
});
if (allGood) {
m_interpreter.execute(indexInBlock);
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -179,7 +178,7 @@
case Arrayify: {
if (!node->arrayMode().alreadyChecked(m_graph, node, m_state.forNode(node->child1())))
break;
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -188,7 +187,7 @@
if (m_state.forNode(node->child1()).m_structure.onlyStructure() != node->transition()->next)
break;
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -196,7 +195,7 @@
case CheckCell: {
if (m_state.forNode(node->child1()).value() != node->cellOperand()->value())
break;
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -204,7 +203,7 @@
case CheckNotEmpty: {
if (m_state.forNode(node->child1()).m_type & SpecEmpty)
break;
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -214,7 +213,7 @@
JSValue right = m_state.forNode(node->child2()).value();
if (left && right && left.isInt32() && right.isInt32()
&& static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
- node->convertToPhantom();
+ node->remove();
eliminated = true;
break;
}
@@ -512,14 +511,16 @@
if (!*value)
continue;
- NodeOrigin origin = node->origin;
- AdjacencyList children = node->children;
-
- m_graph.convertToConstant(node, value);
- if (!children.isEmpty()) {
+ if (node->op() == GetLocal) {
+ // Need to preserve bytecode liveness in ThreadedCPS form. This wouldn't be necessary
+ // if it wasn't for https://bugs.webkit.org/show_bug.cgi?id=144086.
m_insertionSet.insertNode(
- indexInBlock, SpecNone, Phantom, origin, children);
- }
+ indexInBlock, SpecNone, PhantomLocal, node->origin,
+ OpInfo(node->variableAccessData()));
+ m_graph.dethread();
+ } else
+ m_insertionSet.insertCheck(indexInBlock, node->origin, node->children);
+ m_graph.convertToConstant(node, value);
changed = true;
}
@@ -640,10 +641,8 @@
return;
}
- if (baseValue.m_type & ~SpecCell) {
- m_insertionSet.insertNode(
- indexInBlock, SpecNone, Phantom, node->origin, node->child1());
- }
+ if (baseValue.m_type & ~SpecCell)
+ m_insertionSet.insertCheck(indexInBlock, node->origin, node->child1());
}
void addChecks(
@@ -683,7 +682,7 @@
case JSConstant:
case DoubleConstant:
case Int52Constant:
- node->convertToPhantom();
+ node->remove();
break;
default:
DFG_CRASH(m_graph, node, "Bad Upsilon phi() pointer");
diff --git a/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
index 7fe8868..5290f24 100644
--- a/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp
@@ -50,27 +50,11 @@
m_graph.computeRefCounts();
- if (m_graph.m_form == SSA) {
- for (BasicBlock* block : m_graph.blocksInPreOrder())
- fixupBlock(block);
-
- // This is like cleanVariables, but has a much simpler approach to GetLocal.
- for (unsigned i = m_graph.m_arguments.size(); i--;) {
- Node* node = m_graph.m_arguments[i];
- if (!node)
- continue;
- if (node->op() != Phantom && node->op() != Check && node->shouldGenerate())
- continue;
- m_graph.m_arguments[i] = nullptr;
- }
- } else {
- RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
-
- for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
- fixupBlock(m_graph.block(blockIndex));
- cleanVariables(m_graph.m_arguments);
- }
+ for (BasicBlock* block : m_graph.blocksInPreOrder())
+ fixupBlock(block);
+ cleanVariables(m_graph.m_arguments);
+
// Just do a basic Phantom/Check clean-up.
for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
@@ -104,22 +88,12 @@
{
if (!block)
return;
-
- switch (m_graph.m_form) {
- case SSA:
- break;
-
- case ThreadedCPS: {
- // Clean up variable links for the block. We need to do this before the actual DCE
- // because we need to see GetLocals, so we can bypass them in situations where the
- // vars-at-tail point to a GetLocal, the GetLocal is dead, but the Phi it points
- // to is alive.
-
+
+ if (m_graph.m_form == ThreadedCPS) {
for (unsigned phiIndex = 0; phiIndex < block->phis.size(); ++phiIndex) {
- if (!block->phis[phiIndex]->shouldGenerate()) {
- // FIXME: We could actually free nodes here. Except that it probably
- // doesn't matter, since we don't add any nodes after this phase.
- // https://bugs.webkit.org/show_bug.cgi?id=126239
+ Node* phi = block->phis[phiIndex];
+ if (!phi->shouldGenerate()) {
+ m_graph.m_allocator.free(phi);
block->phis[phiIndex--] = block->phis.last();
block->phis.removeLast();
}
@@ -127,12 +101,6 @@
cleanVariables(block->variablesAtHead);
cleanVariables(block->variablesAtTail);
- break;
- }
-
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return;
}
// This has to be a forward loop because we are using the insertion set.
@@ -141,40 +109,24 @@
if (node->shouldGenerate())
continue;
- switch (node->op()) {
- case MovHint:
- case ZombieHint:
- // These are not killable. (They once were.)
- RELEASE_ASSERT_NOT_REACHED();
-
- default: {
- if (node->flags() & NodeHasVarArgs) {
- for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
- Edge edge = m_graph.m_varArgChildren[childIdx];
-
- if (!edge || edge.isProved() || edge.willNotHaveCheck())
- continue;
-
- m_insertionSet.insertNode(indexInBlock, SpecNone, Check, node->origin, edge);
- }
-
- node->convertToPhantom();
- node->children.reset();
- node->setRefCount(1);
- break;
- }
-
- node->convertToCheck();
- for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
- Edge edge = node->children.child(i);
- if (!edge)
+ if (node->flags() & NodeHasVarArgs) {
+ for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
+ Edge edge = m_graph.m_varArgChildren[childIdx];
+
+ if (!edge || edge.willNotHaveCheck())
continue;
- if (edge.isProved() || edge.willNotHaveCheck())
- node->children.removeEdge(i--);
+
+ m_insertionSet.insertNode(indexInBlock, SpecNone, Check, node->origin, edge);
}
+
+ node->setOpAndDefaultFlags(Check);
+ node->children.reset();
node->setRefCount(1);
- break;
- } }
+ continue;
+ }
+
+ node->remove();
+ node->setRefCount(1);
}
m_insertionSet.execute(block);
@@ -187,19 +139,9 @@
Node* node = variables[i];
if (!node)
continue;
- if (node->op() != Phantom && node->op() != Check && node->shouldGenerate())
+ if (node->op() != Check && node->shouldGenerate())
continue;
- if (node->op() == GetLocal) {
- node = node->child1().node();
-
- ASSERT(node->op() == Phi || node->op() == SetArgument);
-
- if (node->shouldGenerate()) {
- variables[i] = node;
- continue;
- }
- }
- variables[i] = 0;
+ variables[i] = nullptr;
}
}
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index cbac371..77662c6 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -82,10 +82,8 @@
m_block = block;
for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
m_currentNode = block->at(m_indexInBlock);
- addPhantomsIfNecessary();
fixupNode(m_currentNode);
}
- addPhantomsIfNecessary();
m_insertionSet.execute(block);
}
@@ -142,14 +140,12 @@
case ValueAdd: {
if (attemptToMakeIntegerAdd(node)) {
node->setOp(ArithAdd);
- node->clearFlags(NodeMustGenerate);
break;
}
if (Node::shouldSpeculateNumberOrBooleanExpectingDefined(node->child1().node(), node->child2().node())) {
fixDoubleOrBooleanEdge(node->child1());
fixDoubleOrBooleanEdge(node->child2());
node->setOp(ArithAdd);
- node->clearFlags(NodeMustGenerate);
node->setResult(NodeResultDouble);
break;
}
@@ -268,12 +264,6 @@
fixDoubleOrBooleanEdge(node->child1());
fixDoubleOrBooleanEdge(node->child2());
- // But we have to make sure that everything is phantom'd until after the
- // DoubleAsInt32 node, which occurs after the Div/Mod node that the conversions
- // will be insered on.
- addRequiredPhantom(node->child1().node());
- addRequiredPhantom(node->child2().node());
-
// We don't need to do ref'ing on the children because we're stealing them from
// the original division.
Node* newDivision = m_insertionSet.insertNode(
@@ -847,7 +837,7 @@
}
m_insertionSet.insertNode(
- m_indexInBlock, SpecNone, Phantom, node->origin,
+ m_indexInBlock, SpecNone, Check, node->origin,
Edge(node->child1().node(), OtherUse));
observeUseKindOnNode<OtherUse>(node->child1().node());
m_graph.convertToConstant(
@@ -998,7 +988,6 @@
break;
}
- case Phantom:
case Check: {
switch (node->child1().useKind()) {
case NumberUse:
@@ -1012,6 +1001,11 @@
break;
}
+ case Phantom:
+ // Phantoms are meaningless past Fixup. We recreate them on-demand in the backend.
+ node->remove();
+ break;
+
case FiatInt52: {
RELEASE_ASSERT(enableInt52());
node->convertToIdentity();
@@ -1075,7 +1069,7 @@
case IsString:
if (node->child1()->shouldSpeculateString()) {
m_insertionSet.insertNode(
- m_indexInBlock, SpecNone, Phantom, node->origin,
+ m_indexInBlock, SpecNone, Check, node->origin,
Edge(node->child1().node(), StringUse));
m_graph.convertToConstant(node, jsBoolean(true));
observeUseKindOnNode<StringUse>(node);
@@ -1085,7 +1079,7 @@
case IsObject:
if (node->child1()->shouldSpeculateObject()) {
m_insertionSet.insertNode(
- m_indexInBlock, SpecNone, Phantom, node->origin,
+ m_indexInBlock, SpecNone, Check, node->origin,
Edge(node->child1().node(), ObjectUse));
m_graph.convertToConstant(node, jsBoolean(true));
observeUseKindOnNode<ObjectUse>(node);
@@ -1158,28 +1152,28 @@
RefPtr<TypeSet> typeSet = node->typeLocation()->m_instructionTypeSet;
RuntimeTypeMask seenTypes = typeSet->seenTypes();
if (typeSet->doesTypeConformTo(TypeMachineInt)) {
- node->convertToCheck();
if (node->child1()->shouldSpeculateInt32())
fixEdge<Int32Use>(node->child1());
else
fixEdge<MachineIntUse>(node->child1());
+ node->remove();
} else if (typeSet->doesTypeConformTo(TypeNumber | TypeMachineInt)) {
- node->convertToCheck();
fixEdge<NumberUse>(node->child1());
+ node->remove();
} else if (typeSet->doesTypeConformTo(TypeString)) {
- node->convertToCheck();
fixEdge<StringUse>(node->child1());
+ node->remove();
} else if (typeSet->doesTypeConformTo(TypeBoolean)) {
- node->convertToCheck();
fixEdge<BooleanUse>(node->child1());
+ node->remove();
} else if (typeSet->doesTypeConformTo(TypeUndefined | TypeNull) && (seenTypes & TypeUndefined) && (seenTypes & TypeNull)) {
- node->convertToCheck();
fixEdge<OtherUse>(node->child1());
+ node->remove();
} else if (typeSet->doesTypeConformTo(TypeObject)) {
StructureSet set = typeSet->structureSet();
if (!set.isEmpty()) {
- node->convertToCheckStructure(m_graph.addStructureSet(set));
fixEdge<CellUse>(node->child1());
+ node->convertToCheckStructure(m_graph.addStructureSet(set));
}
}
@@ -1296,7 +1290,7 @@
// decision process much easier.
observeUseKindOnNode<StringUse>(edge.node());
m_insertionSet.insertNode(
- m_indexInBlock, SpecNone, Phantom, node->origin,
+ m_indexInBlock, SpecNone, Check, node->origin,
Edge(edge.node(), StringUse));
edge.setUseKind(KnownStringUse);
return;
@@ -1398,9 +1392,6 @@
template<UseKind leftUseKind>
bool attemptToMakeFastStringAdd(Node* node, Edge& left, Edge& right)
{
- Node* originalLeft = left.node();
- Node* originalRight = right.node();
-
ASSERT(leftUseKind == StringUse || leftUseKind == StringObjectUse || leftUseKind == StringOrStringObjectUse);
if (isStringObjectUse<leftUseKind>() && !canOptimizeStringObjectAccess(node->origin.semantic))
@@ -1435,12 +1426,6 @@
right.setNode(toString);
}
- // We're doing checks up there, so we need to make sure that the
- // *original* inputs to the addition are live up to here.
- m_insertionSet.insertNode(
- m_indexInBlock, SpecNone, Phantom, node->origin,
- Edge(originalLeft), Edge(originalRight));
-
convertToMakeRope(node);
return true;
}
@@ -1564,7 +1549,7 @@
if (arrayMode.type() == Array::String) {
m_insertionSet.insertNode(
- m_indexInBlock, SpecNone, Phantom, origin, Edge(array, StringUse));
+ m_indexInBlock, SpecNone, Check, origin, Edge(array, StringUse));
} else {
Structure* structure = arrayMode.originalArrayStructure(m_graph, origin.semantic);
@@ -1775,7 +1760,6 @@
observeUseKindOnNode(node, useKind);
edge = Edge(newNode, KnownInt32Use);
- addRequiredPhantom(node);
}
void fixIntOrBooleanEdge(Edge& edge)
@@ -1797,7 +1781,6 @@
observeUseKindOnNode(node, useKind);
edge = Edge(newNode, Int32Use);
- addRequiredPhantom(node);
}
void fixDoubleOrBooleanEdge(Edge& edge)
@@ -1819,7 +1802,6 @@
observeUseKindOnNode(node, useKind);
edge = Edge(newNode, DoubleRepUse);
- addRequiredPhantom(node);
}
void truncateConstantToInt32(Edge& edge)
@@ -1999,11 +1981,9 @@
m_block = block;
for (m_indexInBlock = 0; m_indexInBlock < block->size(); ++m_indexInBlock) {
m_currentNode = block->at(m_indexInBlock);
- addPhantomsIfNecessary();
tryToRelaxRepresentation(m_currentNode);
DFG_NODE_DO_TO_CHILDREN(m_graph, m_currentNode, injectTypeConversionsForEdge);
}
- addPhantomsIfNecessary();
m_insertionSet.execute(block);
}
@@ -2017,7 +1997,6 @@
switch (node->op()) {
case MovHint:
- case Phantom:
case Check:
DFG_NODE_DO_TO_CHILDREN(m_graph, m_currentNode, fixEdgeRepresentation);
break;
@@ -2078,8 +2057,6 @@
if (edge->hasDoubleResult())
break;
- addRequiredPhantom(edge.node());
-
if (edge->isNumberConstant()) {
result = m_insertionSet.insertNode(
m_indexInBlock, SpecBytecodeDouble, DoubleConstant, node->origin,
@@ -2102,8 +2079,6 @@
if (edge->hasInt52Result())
break;
- addRequiredPhantom(edge.node());
-
if (edge->isMachineIntConstant()) {
result = m_insertionSet.insertNode(
m_indexInBlock, SpecMachineInt, Int52Constant, node->origin,
@@ -2130,8 +2105,6 @@
if (!edge->hasDoubleResult() && !edge->hasInt52Result())
break;
- addRequiredPhantom(edge.node());
-
if (edge->hasDoubleResult()) {
result = m_insertionSet.insertNode(
m_indexInBlock, SpecBytecodeDouble, ValueRep, node->origin,
@@ -2147,32 +2120,11 @@
} }
}
- void addRequiredPhantom(Node* node)
- {
- m_requiredPhantoms.append(node);
- }
-
- void addPhantomsIfNecessary()
- {
- if (m_requiredPhantoms.isEmpty())
- return;
-
- for (unsigned i = m_requiredPhantoms.size(); i--;) {
- Node* node = m_requiredPhantoms[i];
- m_insertionSet.insertNode(
- m_indexInBlock, SpecNone, Phantom, m_currentNode->origin,
- node->defaultEdge());
- }
-
- m_requiredPhantoms.resize(0);
- }
-
BasicBlock* m_block;
unsigned m_indexInBlock;
Node* m_currentNode;
InsertionSet m_insertionSet;
bool m_profitabilityChanged;
- Vector<Node*, 3> m_requiredPhantoms;
};
bool performFixup(Graph& graph)
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.cpp b/Source/JavaScriptCore/dfg/DFGGraph.cpp
index 4c2d3fb..954c228 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.cpp
+++ b/Source/JavaScriptCore/dfg/DFGGraph.cpp
@@ -593,26 +593,6 @@
determineReachability();
}
-void Graph::mergeRelevantToOSR()
-{
- for (BasicBlock* block : blocksInNaturalOrder()) {
- for (Node* node : *block) {
- switch (node->op()) {
- case MovHint:
- node->child1()->mergeFlags(NodeRelevantToOSR);
- break;
-
- case PutHint:
- node->child2()->mergeFlags(NodeRelevantToOSR);
- break;
-
- default:
- break;
- }
- }
- }
-}
-
namespace {
class RefCountCalculator {
@@ -625,12 +605,6 @@
void calculate()
{
// First reset the counts to 0 for all nodes.
- //
- // Also take this opportunity to pretend that Check nodes are not NodeMustGenerate. Check
- // nodes are MustGenerate because they are executed for effect, but they follow the same
- // DCE rules as nodes that aren't MustGenerate: they only contribute to the ref count of
- // their children if the edges require checks. Non-checking edges are removed. Note that
- // for any Checks left over, this phase will turn them back into NodeMustGenerate.
for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
@@ -654,11 +628,6 @@
DFG_NODE_DO_TO_CHILDREN(m_graph, node, findTypeCheckRoot);
if (!(node->flags() & NodeMustGenerate))
continue;
- if (node->op() == Check) {
- // We don't treat Check nodes as MustGenerate. We will gladly
- // kill them off in this phase.
- continue;
- }
if (!node->postfixRef())
m_worklist.append(node);
}
@@ -1263,12 +1232,6 @@
{
if (value->structure())
assertIsRegistered(value->structure());
- if (m_form == ThreadedCPS) {
- if (node->op() == GetLocal)
- dethread();
- else
- ASSERT(!node->hasVariableAccessData(*this));
- }
node->convertToConstant(value);
}
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index fa99f22..44b0030 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -452,8 +452,6 @@
void determineReachability();
void resetReachability();
- void mergeRelevantToOSR();
-
void computeRefCounts();
unsigned varArgNumChildren(Node* node)
diff --git a/Source/JavaScriptCore/dfg/DFGInsertionSet.h b/Source/JavaScriptCore/dfg/DFGInsertionSet.h
index 25aa9f7..c5ed4c2 100644
--- a/Source/JavaScriptCore/dfg/DFGInsertionSet.h
+++ b/Source/JavaScriptCore/dfg/DFGInsertionSet.h
@@ -125,6 +125,26 @@
return insertConstantForUse(index, origin, jsUndefined(), useKind);
}
+ Node* insertCheck(size_t index, NodeOrigin origin, AdjacencyList children)
+ {
+ children = children.justChecks();
+ if (children.isEmpty())
+ return nullptr;
+ return insertNode(index, SpecNone, Check, origin, children);
+ }
+
+ Node* insertCheck(size_t index, Node* node)
+ {
+ return insertCheck(index, node->origin, node->children);
+ }
+
+ Node* insertCheck(size_t index, NodeOrigin origin, Edge edge)
+ {
+ if (edge.willHaveCheck())
+ return insertNode(index, SpecNone, Check, origin, edge);
+ return nullptr;
+ }
+
void execute(BasicBlock* block)
{
executeInsertions(*block, m_insertions);
diff --git a/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp b/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp
index 6dd9565..5ddda08 100644
--- a/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp
@@ -292,7 +292,7 @@
break;
case ArrayBounds:
- node->convertToPhantom();
+ node->remove();
m_changed = true;
break;
diff --git a/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp b/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp
index a45a734..9f316e8 100644
--- a/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp
@@ -263,7 +263,7 @@
// code. But for now we just assert that's the case.
DFG_ASSERT(m_graph, node, !(node->flags() & NodeHasVarArgs));
- nodeRef = m_graph.addNode(SpecNone, Phantom, originalOrigin, node->children);
+ nodeRef = m_graph.addNode(SpecNone, Check, originalOrigin, node->children);
return true;
}
diff --git a/Source/JavaScriptCore/dfg/DFGNode.cpp b/Source/JavaScriptCore/dfg/DFGNode.cpp
index 10e175b..b5334c2 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGNode.cpp
@@ -85,6 +85,15 @@
}
}
+void Node::remove()
+{
+ ASSERT(!(flags() & NodeHasVarArgs));
+
+ children = children.justChecks();
+
+ setOpAndDefaultFlags(Check);
+}
+
void Node::convertToIdentity()
{
RELEASE_ASSERT(child1());
diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h
index 656fd5f..fb445b7 100644
--- a/Source/JavaScriptCore/dfg/DFGNode.h
+++ b/Source/JavaScriptCore/dfg/DFGNode.h
@@ -407,15 +407,7 @@
m_flags = defaultFlags(op);
}
- void convertToPhantom()
- {
- setOpAndDefaultFlags(Phantom);
- }
-
- void convertToCheck()
- {
- setOpAndDefaultFlags(Check);
- }
+ void remove();
void convertToCheckStructure(StructureSet* set)
{
@@ -425,7 +417,7 @@
void replaceWith(Node* other)
{
- convertToPhantom();
+ remove();
setReplacement(other);
}
@@ -1557,20 +1549,6 @@
return m_refCount;
}
- bool willHaveCodeGenOrOSR()
- {
- switch (op()) {
- case SetLocal:
- case MovHint:
- case ZombieHint:
- return true;
- case Phantom:
- return child1().useKindUnchecked() != UntypedUse || child2().useKindUnchecked() != UntypedUse || child3().useKindUnchecked() != UntypedUse;
- default:
- return shouldGenerate();
- }
- }
-
bool isSemanticallySkippable()
{
return op() == CountExecution;
diff --git a/Source/JavaScriptCore/dfg/DFGNodeFlags.h b/Source/JavaScriptCore/dfg/DFGNodeFlags.h
index 07e3a4e..4db2a43 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeFlags.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeFlags.h
@@ -65,12 +65,11 @@
#define NodeArithFlagsMask (NodeBehaviorMask | NodeBytecodeBackPropMask)
-#define NodeRelevantToOSR 0x10000
+#define NodeIsFlushed 0x10000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.
-#define NodeIsFlushed 0x20000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.
-
-#define NodeMiscFlag1 0x40000
-#define NodeMiscFlag2 0x80000
+#define NodeMiscFlag1 0x20000
+#define NodeMiscFlag2 0x40000
+#define NodeMiscFlag3 0x80000
typedef uint32_t NodeFlags;
diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h
index 521d13d..b9f025f 100644
--- a/Source/JavaScriptCore/dfg/DFGNodeType.h
+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h
@@ -60,7 +60,8 @@
/* basic block might have read a local variable in bytecode. We only remove GetLocals if it */\
/* is redundant because of an earlier GetLocal or SetLocal in the same block. We could make */\
/* these not MustGenerate and use a more sophisticated analysis to insert PhantomLocals in */\
- /* the same way that we insert Phantoms. https://bugs.webkit.org/show_bug.cgi?id=144086 */\
+ /* the same way that we insert Phantoms. That's hard and probably not profitable. See */\
+ /* https://bugs.webkit.org/show_bug.cgi?id=144086 */\
macro(GetLocal, NodeResultJS | NodeMustGenerate) \
macro(SetLocal, 0) \
\
@@ -72,8 +73,8 @@
macro(ZombieHint, NodeMustGenerate) \
macro(Phantom, NodeMustGenerate) \
macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
- macro(Upsilon, NodeRelevantToOSR) \
- macro(Phi, NodeRelevantToOSR) \
+ macro(Upsilon, 0) \
+ macro(Phi, 0) \
macro(Flush, NodeMustGenerate) \
macro(PhantomLocal, NodeMustGenerate) \
\
@@ -281,10 +282,10 @@
macro(CreateActivation, NodeResultJS) \
\
macro(CreateDirectArguments, NodeResultJS) \
- macro(PhantomDirectArguments, NodeResultJS) \
+ macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \
macro(CreateScopedArguments, NodeResultJS) \
macro(CreateClonedArguments, NodeResultJS) \
- macro(PhantomClonedArguments, NodeResultJS) \
+ macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
macro(GetFromArguments, NodeResultJS) \
macro(PutToArguments, NodeMustGenerate) \
\
diff --git a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp b/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
index d0bfe14..2355a2c 100644
--- a/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
@@ -585,7 +585,7 @@
Node* target = node->child1().node();
if (m_sinkCandidates.contains(target)) {
ASSERT(target->isPhantomObjectAllocation());
- node->convertToPhantom();
+ node->remove();
}
break;
}
@@ -795,7 +795,6 @@
break;
case MovHint:
- case Phantom:
case Check:
case PutHint:
break;
diff --git a/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp
deleted file mode 100644
index 3b3717d..0000000
--- a/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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 "DFGPhantomCanonicalizationPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include "DFGPredictionPropagationPhase.h"
-#include "DFGVariableAccessDataDump.h"
-#include "JSCInlines.h"
-
-namespace JSC { namespace DFG {
-
-static const NodeFlags NodeNeedsPhantom = NodeMiscFlag1;
-
-class PhantomCanonicalizationPhase : public Phase {
-public:
- PhantomCanonicalizationPhase(Graph& graph)
- : Phase(graph, "phantom canonicalization")
- {
- }
-
- bool run()
- {
- ASSERT(m_graph.m_form == SSA);
-
- m_graph.clearFlagsOnAllNodes(NodeNeedsPhantom | NodeRelevantToOSR);
- m_graph.mergeRelevantToOSR();
-
- for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
- BasicBlock* block = m_graph.block(blockIndex);
- if (!block)
- continue;
-
- unsigned sourceIndex = 0;
- unsigned targetIndex = 0;
- while (sourceIndex < block->size()) {
- Node* node = block->at(sourceIndex++);
- if (node->op() == Phantom || node->op() == Check) {
- for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
- Edge edge = node->children.child(i);
- if (!edge)
- break;
- if ((edge->flags() & NodeRelevantToOSR) && node->op() == Phantom) {
- // A Phantom on a node that is RelevantToOSR means that we need to keep
- // a Phantom on this node instead of just having a Check.
- edge->mergeFlags(NodeNeedsPhantom);
- }
- if (edge.willHaveCheck())
- continue; // Keep the type check.
-
- node->children.removeEdge(i--);
- }
-
- if (node->children.isEmpty()) {
- m_graph.m_allocator.free(node);
- continue;
- }
-
- node->convertToCheck();
- }
- block->at(targetIndex++) = node;
- }
- block->resize(targetIndex);
- }
-
- InsertionSet insertionSet(m_graph);
- for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
- BasicBlock* block = m_graph.block(blockIndex);
- if (!block)
- continue;
-
- for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
- Node* node = block->at(nodeIndex);
- if (node->flags() & NodeNeedsPhantom) {
- insertionSet.insertNode(
- nodeIndex + 1, SpecNone, Phantom, node->origin, node->defaultEdge());
- }
- }
- insertionSet.execute(block);
- }
-
- return true;
- }
-};
-
-bool performPhantomCanonicalization(Graph& graph)
-{
- SamplingRegion samplingRegion("DFG Phantom Canonicalization Phase");
- return runPhase<PhantomCanonicalizationPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
diff --git a/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.h b/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.h
deleted file mode 100644
index 306b3bd..0000000
--- a/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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 DFGPhantomCanonicalizationPhase_h
-#define DFGPhantomCanonicalizationPhase_h
-
-#if ENABLE(DFG_JIT)
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-// Replaces all pre-existing Phantoms with Checks or removes them if the Check is unnecessary. If
-// the Phantom was necessary (it uses a node that is relevant to OSR) then the Phantom is hoisted
-// to just below the node.
-//
-// This phase is only valid in SSA, because it's only in SSA that Phantoms are ignored for the
-// purpose of liveness-at-some-point and are only used for absolute liveness.
-//
-// This phase makes a lot of things easier, like CFG simplification: you don't have to insert any
-// phantoms when jettisoning a CFG edge.
-
-bool performPhantomCanonicalization(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGPhantomCanonicalizationPhase_h
diff --git a/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp b/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp
deleted file mode 100644
index 2844c84..0000000
--- a/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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 "DFGPhantomRemovalPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include "DFGPredictionPropagationPhase.h"
-#include "DFGVariableAccessDataDump.h"
-#include "JSCInlines.h"
-
-namespace JSC { namespace DFG {
-
-class PhantomRemovalPhase : public Phase {
-public:
- PhantomRemovalPhase(Graph& graph)
- : Phase(graph, "phantom removal")
- {
- }
-
- bool run()
- {
- bool changed = false;
-
- for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
- BasicBlock* block = m_graph.block(blockIndex);
- if (!block)
- continue;
-
- // All Phis need to already be marked as relevant to OSR.
- if (!ASSERT_DISABLED) {
- for (unsigned i = 0; i < block->phis.size(); ++i)
- ASSERT(block->phis[i]->flags() & NodeRelevantToOSR);
- }
-
- for (unsigned i = block->size(); i--;) {
- Node* node = block->at(i);
-
- switch (node->op()) {
- case SetLocal:
- case GetLocal: // FIXME: The GetLocal case is only necessary until we do https://bugs.webkit.org/show_bug.cgi?id=106707.
- node->mergeFlags(NodeRelevantToOSR);
- break;
- default:
- node->clearFlags(NodeRelevantToOSR);
- break;
- }
- }
- }
-
- m_graph.mergeRelevantToOSR();
-
- for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
- BasicBlock* block = m_graph.block(blockIndex);
- if (!block)
- continue;
-
- unsigned sourceIndex = 0;
- unsigned targetIndex = 0;
- while (sourceIndex < block->size()) {
- Node* node = block->at(sourceIndex++);
- switch (node->op()) {
- case Phantom: {
- Node* lastNode = nullptr;
- if (sourceIndex > 1) {
- lastNode = block->at(sourceIndex - 2);
-
- // This doesn't need to specialize for Phantom. lastNode could be any node
- // that isn't subject to DCE. But we keep it simple for now.
- if (lastNode->op() != Phantom
- || lastNode->origin.forExit != node->origin.forExit)
- lastNode = nullptr;
- }
- for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
- Edge edge = node->children.child(i);
- if (!edge)
- break;
- if (edge.willHaveCheck())
- continue; // Keep the type check.
- if (edge->flags() & NodeRelevantToOSR) {
- bool found = false;
- if (lastNode) {
- for (unsigned j = 0; j < AdjacencyList::Size; ++j) {
- if (lastNode->children.child(j).node() == edge.node()) {
- found = true;
- break;
- }
- }
- }
- if (!found)
- continue;
- }
-
- node->children.removeEdge(i--);
- changed = true;
- }
-
- if (node->children.isEmpty()) {
- m_graph.m_allocator.free(node);
- changed = true;
- continue;
- }
- break;
- }
-
- case Check: {
- for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
- Edge edge = node->children.child(i);
- if (!edge)
- break;
- if (edge.willHaveCheck())
- continue;
- node->children.removeEdge(i--);
- changed = true;
- }
- if (node->children.isEmpty()) {
- m_graph.m_allocator.free(node);
- changed = true;
- continue;
- }
- break;
- }
-
- default:
- break;
- }
-
- block->at(targetIndex++) = node;
- }
- block->resize(targetIndex);
- }
-
- return changed;
- }
-};
-
-bool performPhantomRemoval(Graph& graph)
-{
- SamplingRegion samplingRegion("DFG Phantom Removal Phase");
- return runPhase<PhantomRemovalPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
diff --git a/Source/JavaScriptCore/dfg/DFGPlan.cpp b/Source/JavaScriptCore/dfg/DFGPlan.cpp
index d6129fc..0b735e5 100644
--- a/Source/JavaScriptCore/dfg/DFGPlan.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPlan.cpp
@@ -35,6 +35,7 @@
#include "DFGCFGSimplificationPhase.h"
#include "DFGCPSRethreadingPhase.h"
#include "DFGCSEPhase.h"
+#include "DFGCleanUpPhase.h"
#include "DFGConstantFoldingPhase.h"
#include "DFGCriticalEdgeBreakingPhase.h"
#include "DFGDCEPhase.h"
@@ -51,13 +52,10 @@
#include "DFGOSRAvailabilityAnalysisPhase.h"
#include "DFGOSREntrypointCreationPhase.h"
#include "DFGObjectAllocationSinkingPhase.h"
-#include "DFGPhantomCanonicalizationPhase.h"
#include "DFGPhantomInsertionPhase.h"
-#include "DFGPhantomRemovalPhase.h"
#include "DFGPredictionInjectionPhase.h"
#include "DFGPredictionPropagationPhase.h"
#include "DFGPutStackSinkingPhase.h"
-#include "DFGResurrectionForValidationPhase.h"
#include "DFGSSAConversionPhase.h"
#include "DFGSSALoweringPhase.h"
#include "DFGStackLayoutPhase.h"
@@ -318,7 +316,7 @@
performTierUpCheckInjection(dfg);
performStoreBarrierElision(dfg);
- performPhantomRemoval(dfg);
+ performCleanUp(dfg);
performCPSRethreading(dfg);
performDCE(dfg);
performPhantomInsertion(dfg);
@@ -344,7 +342,7 @@
return FailPath;
}
- performPhantomRemoval(dfg); // Reduce the graph size a bit.
+ performCleanUp(dfg); // Reduce the graph size a bit.
performCriticalEdgeBreaking(dfg);
performLoopPreHeaderCreation(dfg);
performCPSRethreading(dfg);
@@ -359,7 +357,7 @@
performLivenessAnalysis(dfg);
performCFA(dfg);
performConstantFolding(dfg);
- performPhantomCanonicalization(dfg); // Reduce the graph size a lot.
+ performCleanUp(dfg); // Reduce the graph size a lot.
changed = false;
changed |= performStrengthReduction(dfg);
if (Options::enableObjectAllocationSinking()) {
@@ -381,7 +379,7 @@
// then we'd need to do some simple SSA fix-up.
performLICM(dfg);
- performPhantomCanonicalization(dfg);
+ performCleanUp(dfg);
performIntegerCheckCombining(dfg);
performGlobalCSE(dfg);
@@ -390,15 +388,11 @@
dfg.m_fixpointState = FixpointConverged;
performStoreBarrierElision(dfg);
- performPhantomCanonicalization(dfg);
performLivenessAnalysis(dfg);
performCFA(dfg);
- if (Options::validateFTLOSRExitLiveness())
- performResurrectionForValidation(dfg);
- if (Options::enableMovHintRemoval()) {
+ if (Options::enableMovHintRemoval())
performMovHintRemoval(dfg);
- performPhantomCanonicalization(dfg);
- }
+ performCleanUp(dfg);
performDCE(dfg); // We rely on this to kill dead code that won't be recognized as dead by LLVM.
performStackLayout(dfg);
performLivenessAnalysis(dfg);
diff --git a/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp b/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp
index 99efcdb..b897440 100644
--- a/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPutStackSinkingPhase.cpp
@@ -495,7 +495,7 @@
insertionSet.insertNode(
nodeIndex, SpecNone, KillStack, node->origin, OpInfo(node->stackAccessData()->local.offset()));
- node->convertToPhantom();
+ node->remove();
}
insertionSet.execute(block);
diff --git a/Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.cpp b/Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.cpp
deleted file mode 100644
index 710ad0f..0000000
--- a/Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 "DFGResurrectionForValidationPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGBasicBlockInlines.h"
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include "JSCInlines.h"
-
-namespace JSC { namespace DFG {
-
-class ResurrectionForValidationPhase : public Phase {
-public:
- ResurrectionForValidationPhase(Graph& graph)
- : Phase(graph, "resurrection for validation")
- {
- }
-
- bool run()
- {
- InsertionSet insertionSet(m_graph);
-
- for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
- BasicBlock* block = m_graph.block(blockIndex);
- if (!block)
- continue;
-
- for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
- Node* node = block->at(nodeIndex);
- if (!node->hasResult())
- continue;
- insertionSet.insertNode(
- nodeIndex + 1, SpecNone, Phantom, node->origin, node->defaultEdge());
- }
-
- insertionSet.execute(block);
- }
-
- return true;
- }
-};
-
-bool performResurrectionForValidation(Graph& graph)
-{
- SamplingRegion samplingRegion("DFG Resurrection For Validation Phase");
- return runPhase<ResurrectionForValidationPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
diff --git a/Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.h b/Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.h
deleted file mode 100644
index 64f3b2b..0000000
--- a/Source/JavaScriptCore/dfg/DFGResurrectionForValidationPhase.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 DFGResurrectionForValidationPhase_h
-#define DFGResurrectionForValidationPhase_h
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGCommon.h"
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-// Places a Phantom after every value-producing node, thereby disabling DCE from killing it.
-// This is useful for validating our OSR exit machinery by instituting the requirement that
-// any live-in-bytecode variable should be OSR-available. Without this phase, it's impossible
-// to make such an assertion because our DCE is more aggressive than the bytecode liveness
-// analysis.
-
-bool performResurrectionForValidation(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGResurrectionForValidationPhase_h
-
diff --git a/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp b/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp
index 835e348..0745d14 100644
--- a/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSSAConversionPhase.cpp
@@ -300,7 +300,7 @@
VariableAccessData* variable = node->variableAccessData();
node->children.reset();
- node->convertToPhantom();
+ node->remove();
if (verbose)
dataLog("Replacing node ", node, " with ", valueForOperand.operand(variable->local()), "\n");
node->setReplacement(valueForOperand.operand(variable->local()));
@@ -309,7 +309,7 @@
case Flush: {
node->children.reset();
- node->convertToPhantom();
+ node->remove();
break;
}
@@ -317,12 +317,12 @@
ASSERT(node->child1().useKind() == UntypedUse);
VariableAccessData* variable = node->variableAccessData();
node->child1() = valueForOperand.operand(variable->local())->defaultEdge();
- node->convertToPhantom();
+ node->remove();
break;
}
case SetArgument: {
- node->convertToPhantom();
+ node->remove();
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index b24d52b..fa48921 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -1068,6 +1068,12 @@
}
DataFormat spillFormat = info.spillFormat();
+ if (spillFormat != DataFormatDouble) {
+ DFG_CRASH(
+ m_jit.graph(), m_currentNode, toCString(
+ "Expected ", edge, " to have double format but instead it is spilled as ",
+ dataFormatToString(spillFormat)).data());
+ }
DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat == DataFormatDouble);
FPRReg fpr = fprAllocate();
m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
diff --git a/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp
index 7f4c16e..d594c14 100644
--- a/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStoreBarrierElisionPhase.cpp
@@ -95,7 +95,7 @@
void elideBarrier(Node* node)
{
ASSERT(node->isStoreBarrier());
- node->convertToPhantom();
+ node->remove();
}
void handleNode(HashSet<Node*>& dontNeedBarriers, Node* node)
diff --git a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
index d94fade..03515d5 100644
--- a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
@@ -139,7 +139,7 @@
if (yOperandValue == 1) {
convertToIdentityOverChild1();
} else if (yOperandValue == 0.5) {
- m_insertionSet.insertNode(m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->children);
+ m_insertionSet.insertCheck(m_nodeIndex, m_node);
m_node->convertToArithSqrt();
m_changed = true;
}
@@ -166,8 +166,7 @@
for (Node* node = m_node->child1().node(); ; node = node->child1().node()) {
if (canonicalResultRepresentation(node->result()) ==
canonicalResultRepresentation(m_node->result())) {
- m_insertionSet.insertNode(
- m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->child1());
+ m_insertionSet.insertCheck(m_nodeIndex, m_node);
if (hadInt32Check) {
// FIXME: Consider adding Int52RepInt32Use or even DoubleRepInt32Use,
// which would be super weird. The latter would only arise in some
@@ -175,9 +174,8 @@
if (canonicalResultRepresentation(node->result()) != NodeResultJS)
break;
- m_insertionSet.insertNode(
- m_nodeIndex, SpecNone, Phantom, m_node->origin,
- Edge(node, Int32Use));
+ m_insertionSet.insertCheck(
+ m_nodeIndex, m_node->origin, Edge(node, Int32Use));
}
m_node->child1() = node->defaultEdge();
m_node->convertToIdentity();
@@ -239,8 +237,7 @@
void convertToIdentityOverChild(unsigned childIndex)
{
- m_insertionSet.insertNode(
- m_nodeIndex, SpecNone, Phantom, m_node->origin, m_node->children);
+ m_insertionSet.insertCheck(m_nodeIndex, m_node);
m_node->children.removeEdge(childIndex ^ 1);
m_node->convertToIdentity();
m_changed = true;
diff --git a/Source/JavaScriptCore/dfg/DFGValidate.cpp b/Source/JavaScriptCore/dfg/DFGValidate.cpp
index 53e7281..d46dace 100644
--- a/Source/JavaScriptCore/dfg/DFGValidate.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValidate.cpp
@@ -146,31 +146,6 @@
break;
VALIDATE((node, edge), edge->variableAccessData() == node->variableAccessData());
break;
- case Phantom:
- switch (m_graph.m_form) {
- case LoadStore:
- if (j) {
- VALIDATE((node, edge), edge->hasResult());
- break;
- }
- switch (edge->op()) {
- case Phi:
- case SetArgument:
- case SetLocal:
- break;
- default:
- VALIDATE((node, edge), edge->hasResult());
- break;
- }
- break;
- case ThreadedCPS:
- VALIDATE((node, edge), edge->hasResult());
- break;
- case SSA:
- RELEASE_ASSERT_NOT_REACHED();
- break;
- }
- break;
default:
VALIDATE((node, edge), edge->hasResult());
break;
@@ -196,7 +171,7 @@
foundTerminal = true;
for (size_t j = i + 1; j < block->size(); ++j) {
node = block->at(j);
- VALIDATE((node), node->op() == Phantom || node->op() == PhantomLocal || node->op() == Flush);
+ VALIDATE((node), node->op() == Phantom || node->op() == PhantomLocal || node->op() == Flush || node->op() == Check);
m_graph.doToChildren(
node,
[&] (Edge edge) {
@@ -437,10 +412,6 @@
case GetLocal:
case Flush:
break;
- case Phantom:
- if (m_graph.m_form == LoadStore && !j)
- break;
- FALLTHROUGH;
default:
VALIDATE((node, edge), !phisInThisBlock.contains(edge.node()));
break;
@@ -462,6 +433,9 @@
case GetStack:
VALIDATE((node), !"unexpected node type in CPS");
break;
+ case Phantom:
+ VALIDATE((node), m_graph.m_fixpointState != FixpointNotConverged);
+ break;
default:
break;
}
@@ -541,6 +515,7 @@
case SetLocal:
case GetLocalUnlinked:
case SetArgument:
+ case Phantom:
VALIDATE((node), !"bad node type for SSA");
break;
diff --git a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp b/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp
index dedb407..1364b57 100644
--- a/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp
@@ -104,7 +104,6 @@
relevantLocals.append(node->unlinkedLocal());
break;
- case Phantom:
case Check:
case LoadVarargs:
if (m_graph.uses(node, candidate))
@@ -237,7 +236,6 @@
for (unsigned nodeIndex = candidateNodeIndex + 1; nodeIndex <= lastUserIndex; ++nodeIndex) {
Node* node = block->at(nodeIndex);
switch (node->op()) {
- case Phantom:
case Check:
case MovHint:
case PutHint:
diff --git a/Source/JavaScriptCore/ftl/FTLLink.cpp b/Source/JavaScriptCore/ftl/FTLLink.cpp
index c1fb929..188afe5 100644
--- a/Source/JavaScriptCore/ftl/FTLLink.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLink.cpp
@@ -98,8 +98,6 @@
for (size_t nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
Node* node = block->at(nodeIndex);
- if (!node->willHaveCodeGenOrOSR() && !Options::showAllDFGNodes())
- continue;
Profiler::OriginStack stack;
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
index 0132dce..aa4989b 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
@@ -463,9 +463,8 @@
case PutStack:
compilePutStack();
break;
- case Phantom:
case Check:
- compilePhantom();
+ compileNoOp();
break;
case ToThis:
compileToThis();
@@ -1162,7 +1161,7 @@
}
}
- void compilePhantom()
+ void compileNoOp()
{
DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
}