DFG SSA should use GetLocal for arguments, and the GetArgument node type should be removed
https://bugs.webkit.org/show_bug.cgi?id=141623
Reviewed by Oliver Hunt.
During development of https://bugs.webkit.org/show_bug.cgi?id=141332, I realized that I
needed to use GetArgument for loading something that has magically already appeared on the
stack, so currently trunk sort of allows this. But then I realized three things:
- A GetArgument with a non-JSValue flush format means speculating that the value on the
stack obeys that format, rather than just assuming that that it already has that format.
In bug 141332, I want it to assume rather than speculate. That also happens to be more
intuitive; I don't think I was wrong to expect that.
- The node I really want is GetLocal. I'm just getting the value of the local and I don't
want to do anything else.
- Maybe it would be easier if we just used GetLocal for all of the cases where we currently
use GetArgument.
This changes the FTL to do argument speculations in the prologue just like the DFG does.
This brings some consistency to our system, and allows us to get rid of the GetArgument
node. The speculations that the FTL must do are now made explicit in the m_argumentFormats
vector in DFG::Graph. This has natural DCE behavior: even if all uses of the argument are
dead we will still speculate. We already have safeguards to ensure we only speculate if
there are uses that benefit from speculation (which is a much more conservative criterion
than DCE).
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDCEPhase.cpp:
(JSC::DFG::DCEPhase::run):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGFlushFormat.h:
(JSC::DFG::typeFilterFor):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::valueProfileFor):
(JSC::DFG::Graph::methodOfGettingAValueProfileFor):
* dfg/DFGInPlaceAbstractState.cpp:
(JSC::DFG::InPlaceAbstractState::initialize):
* dfg/DFGNode.cpp:
(JSC::DFG::Node::hasVariableAccessData):
* dfg/DFGNodeType.h:
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
(JSC::DFG::LocalOSRAvailabilityCalculator::executeNode):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGPutLocalSinkingPhase.cpp:
* dfg/DFGSSAConversionPhase.cpp:
(JSC::DFG::SSAConversionPhase::run):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::lower):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileGetLocal):
(JSC::FTL::LowerDFGToLLVM::compileGetArgument): Deleted.
* tests/stress/dead-speculating-argument-use.js: Added.
(foo):
(o.valueOf):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@180160 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
index bf7d041..bb73e97 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
@@ -141,18 +141,6 @@
break;
}
- case GetArgument: {
- ASSERT(m_graph.m_form == SSA);
- VariableAccessData* variable = node->variableAccessData();
- AbstractValue& value = m_state.variables().operand(variable->local().offset());
- ASSERT(value.isHeapTop());
- FiltrationResult result =
- value.filter(typeFilterFor(useKindFor(variable->flushFormat())));
- ASSERT_UNUSED(result, result == FiltrationOK);
- forNode(node) = value;
- break;
- }
-
case ExtractOSREntryLocal: {
if (!(node->unlinkedLocal().isArgument())
&& m_graph.m_lazyVars.get(node->unlinkedLocal().toLocal())) {
@@ -170,6 +158,8 @@
case GetLocal: {
VariableAccessData* variableAccessData = node->variableAccessData();
AbstractValue value = m_state.variables().operand(variableAccessData->local().offset());
+ // The value in the local should already be checked.
+ DFG_ASSERT(m_graph, node, value.isType(typeFilterFor(variableAccessData->flushFormat())));
if (value.value())
m_state.setFoundConstants(true);
forNode(node) = value;