DFG::StrCat isn't really effectful
https://bugs.webkit.org/show_bug.cgi?id=148443
Reviewed by Geoffrey Garen.
I previously made the DFG StrCat node effectful because it is implemented by calling a
DFGOperations function that could cause arbitrary effects. But, the node is only generated from the
op_strcat bytecode operation, and that operation is only used when we first ensure that its
operands are primitives. Primitive operands to StrCat cannot cause arbitrary side-effects. The
reason why I didn't immediately mark StrCat as pure was because there was nothing in DFG IR that
guaranteed that StrCat's children were primitives.
This change adds a KnownPrimitiveUse use kind, and applies it to StrCat. This allows us to mark
StrCat as being pure. This should be a speed-up because we can CSE StrCat and because it means that
we can OSR exit after a StrCat (a pure node doesn't clobber exit state), so we can convert more
of a large string concatenation into MakeRope's.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
* dfg/DFGOperations.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::SafeToExecuteEdge::operator()):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::speculate):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGUseKind.cpp:
(WTF::printInternal):
* dfg/DFGUseKind.h:
(JSC::DFG::typeFilterFor):
(JSC::DFG::shouldNotHaveTypeCheck):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileStrCat):
(JSC::FTL::DFG::LowerDFGToLLVM::speculate):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@189075 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index ad6335a..bda4351 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -160,7 +160,18 @@
}
case StrCat: {
- attemptToMakeFastStringAdd(node);
+ if (attemptToMakeFastStringAdd(node))
+ break;
+
+ // FIXME: Remove empty string arguments and possibly turn this into a ToString operation. That
+ // would require a form of ToString that takes a KnownPrimitiveUse. This is necessary because
+ // the implementation of StrCat doesn't dynamically optimize for empty strings.
+ // https://bugs.webkit.org/show_bug.cgi?id=148540
+ m_graph.doToChildren(
+ node,
+ [&] (Edge& edge) {
+ fixEdge<KnownPrimitiveUse>(edge);
+ });
break;
}
@@ -1510,14 +1521,6 @@
bool attemptToMakeFastStringAdd(Node* node)
{
- if (!node->origin.exitOK) {
- // If this code cannot exit, then we should not convert it to a MakeRope, since MakeRope
- // can exit. This arises because we think that StrCat clobbers exit state, even though it
- // doesn't really do that.
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=148443
- return false;
- }
-
bool goodToGo = true;
m_graph.doToChildren(
node,