DFG should have a KnownBooleanUse for cases where we are required to know that the child is a boolean and it's not OK to speculate
https://bugs.webkit.org/show_bug.cgi?id=148286
Reviewed by Benjamin Poulain.
This enables us to ensure that the Branch or LogicalNot after an effectful CompareXYZ can
be marked as !mayExit(). I need that for https://bugs.webkit.org/show_bug.cgi?id=145204.
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::observeUseKindOnNode):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::SafeToExecuteEdge::operator()):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::speculate):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):
* 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::boolify):
(JSC::FTL::DFG::LowerDFGToLLVM::lowBoolean):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@188747 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 98b009e..ff675d9 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -356,9 +356,19 @@
}
case LogicalNot: {
- if (node->child1()->shouldSpeculateBoolean())
- fixEdge<BooleanUse>(node->child1());
- else if (node->child1()->shouldSpeculateObjectOrOther())
+ if (node->child1()->shouldSpeculateBoolean()) {
+ if (node->child1()->result() == NodeResultBoolean) {
+ // This is necessary in case we have a bytecode instruction implemented by:
+ //
+ // a: CompareEq(...)
+ // b: LogicalNot(@a)
+ //
+ // In that case, CompareEq might have a side-effect. Then, we need to make
+ // sure that we know that Branch does not exit.
+ fixEdge<KnownBooleanUse>(node->child1());
+ } else
+ fixEdge<BooleanUse>(node->child1());
+ } else if (node->child1()->shouldSpeculateObjectOrOther())
fixEdge<ObjectOrOtherUse>(node->child1());
else if (node->child1()->shouldSpeculateInt32OrBoolean())
fixIntOrBooleanEdge(node->child1());
@@ -819,9 +829,19 @@
}
case Branch: {
- if (node->child1()->shouldSpeculateBoolean())
- fixEdge<BooleanUse>(node->child1());
- else if (node->child1()->shouldSpeculateObjectOrOther())
+ if (node->child1()->shouldSpeculateBoolean()) {
+ if (node->child1()->result() == NodeResultBoolean) {
+ // This is necessary in case we have a bytecode instruction implemented by:
+ //
+ // a: CompareEq(...)
+ // b: Branch(@a)
+ //
+ // In that case, CompareEq might have a side-effect. Then, we need to make
+ // sure that we know that Branch does not exit.
+ fixEdge<KnownBooleanUse>(node->child1());
+ } else
+ fixEdge<BooleanUse>(node->child1());
+ } else if (node->child1()->shouldSpeculateObjectOrOther())
fixEdge<ObjectOrOtherUse>(node->child1());
else if (node->child1()->shouldSpeculateInt32OrBoolean())
fixIntOrBooleanEdge(node->child1());
@@ -1777,6 +1797,7 @@
VariableAccessData* variable = node->variableAccessData();
switch (useKind) {
case Int32Use:
+ case KnownInt32Use:
if (alwaysUnboxSimplePrimitives()
|| isInt32Speculation(variable->prediction()))
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
@@ -1789,6 +1810,7 @@
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
break;
case BooleanUse:
+ case KnownBooleanUse:
if (alwaysUnboxSimplePrimitives()
|| isBooleanSpeculation(variable->prediction()))
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);