Diff
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ChangeLog (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ChangeLog 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ChangeLog 2015-09-14 08:34:21 UTC (rev 189692)
@@ -1,5 +1,43 @@
2015-08-20 Filip Pizlo <fpi...@apple.com>
+ 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):
+
+2015-08-20 Filip Pizlo <fpi...@apple.com>
+
Overflow check elimination fails for a simple test case
https://bugs.webkit.org/show_bug.cgi?id=147387
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2015-09-14 08:34:21 UTC (rev 189692)
@@ -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());
@@ -796,9 +806,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());
@@ -1743,6 +1763,7 @@
VariableAccessData* variable = node->variableAccessData();
switch (useKind) {
case Int32Use:
+ case KnownInt32Use:
if (alwaysUnboxSimplePrimitives()
|| isInt32Speculation(variable->prediction()))
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
@@ -1755,6 +1776,7 @@
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
break;
case BooleanUse:
+ case KnownBooleanUse:
if (alwaysUnboxSimplePrimitives()
|| isBooleanSpeculation(variable->prediction()))
m_profitabilityChanged |= variable->mergeIsProfitableToUnbox(true);
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSafeToExecute.h (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2015-09-14 08:34:21 UTC (rev 189692)
@@ -74,6 +74,11 @@
if (m_state.forNode(edge).m_type & ~SpecInt32)
m_result = false;
return;
+
+ case KnownBooleanUse:
+ if (m_state.forNode(edge).m_type & ~SpecBoolean)
+ m_result = false;
+ return;
case KnownCellUse:
if (m_state.forNode(edge).m_type & ~SpecCell)
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2015-09-14 08:34:21 UTC (rev 189692)
@@ -5864,6 +5864,9 @@
case BooleanUse:
speculateBoolean(edge);
break;
+ case KnownBooleanUse:
+ ASSERT(!needsTypeCheck(edge, SpecBoolean));
+ break;
case CellUse:
speculateCell(edge);
break;
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2015-09-14 08:34:21 UTC (rev 189692)
@@ -3226,7 +3226,7 @@
, m_gprOrInvalid(InvalidGPRReg)
{
ASSERT(m_jit);
- ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse || edge.useKind() == KnownBooleanUse);
if (jit->isFilled(node()))
gpr();
}
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2015-09-14 08:34:21 UTC (rev 189692)
@@ -1055,6 +1055,7 @@
{
AbstractValue& value = m_state.forNode(edge);
SpeculatedType type = value.m_type;
+ ASSERT(edge.useKind() != KnownBooleanUse || !(value.m_type & ~SpecBoolean));
m_interpreter.filter(value, SpecBoolean);
if (value.isClear()) {
@@ -1485,7 +1486,8 @@
void SpeculativeJIT::compileLogicalNot(Node* node)
{
switch (node->child1().useKind()) {
- case BooleanUse: {
+ case BooleanUse:
+ case KnownBooleanUse: {
SpeculateBooleanOperand value(this, node->child1());
GPRTemporary result(this, Reuse, value);
m_jit.xor32(TrustedImm32(1), value.gpr(), result.gpr());
@@ -1604,7 +1606,8 @@
BasicBlock* notTaken = node->branchData()->notTaken.block;
switch (node->child1().useKind()) {
- case BooleanUse: {
+ case BooleanUse:
+ case KnownBooleanUse: {
SpeculateBooleanOperand value(this, node->child1());
MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2015-09-14 08:34:21 UTC (rev 189692)
@@ -1167,6 +1167,7 @@
{
AbstractValue& value = m_state.forNode(edge);
SpeculatedType type = value.m_type;
+ ASSERT(edge.useKind() != KnownBooleanUse || !(value.m_type & ~SpecBoolean));
m_interpreter.filter(value, SpecBoolean);
if (value.isClear()) {
@@ -1645,7 +1646,8 @@
return;
}
- case BooleanUse: {
+ case BooleanUse:
+ case KnownBooleanUse: {
if (!needsTypeCheck(node->child1(), SpecBoolean)) {
SpeculateBooleanOperand value(this, node->child1());
GPRTemporary result(this, Reuse, value);
@@ -1797,11 +1799,12 @@
}
case UntypedUse:
- case BooleanUse: {
+ case BooleanUse:
+ case KnownBooleanUse: {
JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
GPRReg valueGPR = value.gpr();
- if (node->child1().useKind() == BooleanUse) {
+ if (node->child1().useKind() == BooleanUse || node->child1().useKind() == KnownBooleanUse) {
if (!needsTypeCheck(node->child1(), SpecBoolean)) {
MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGUseKind.cpp (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGUseKind.cpp 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGUseKind.cpp 2015-09-14 08:34:21 UTC (rev 189692)
@@ -70,6 +70,9 @@
case BooleanUse:
out.print("Boolean");
return;
+ case KnownBooleanUse:
+ out.print("KnownBoolean");
+ return;
case CellUse:
out.print("Cell");
return;
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGUseKind.h (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGUseKind.h 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/dfg/DFGUseKind.h 2015-09-14 08:34:21 UTC (rev 189692)
@@ -48,6 +48,7 @@
NumberUse,
RealNumberUse,
BooleanUse,
+ KnownBooleanUse,
CellUse,
KnownCellUse,
ObjectUse,
@@ -101,6 +102,7 @@
case DoubleRepMachineIntUse:
return SpecInt52AsDouble;
case BooleanUse:
+ case KnownBooleanUse:
return SpecBoolean;
case CellUse:
case KnownCellUse:
@@ -145,6 +147,7 @@
case KnownInt32Use:
case KnownCellUse:
case KnownStringUse:
+ case KnownBooleanUse:
case Int52RepUse:
case DoubleRepUse:
return true;
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ftl/FTLCapabilities.cpp (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2015-09-14 08:34:21 UTC (rev 189692)
@@ -408,6 +408,7 @@
case DoubleRepUse:
case DoubleRepRealUse:
case BooleanUse:
+ case KnownBooleanUse:
case CellUse:
case KnownCellUse:
case ObjectUse:
Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (189691 => 189692)
--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-09-14 08:25:56 UTC (rev 189691)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2015-09-14 08:34:21 UTC (rev 189692)
@@ -6076,6 +6076,7 @@
{
switch (edge.useKind()) {
case BooleanUse:
+ case KnownBooleanUse:
return lowBoolean(edge);
case Int32Use:
return m_out.notZero32(lowInt32(edge));
@@ -7066,7 +7067,7 @@
LValue lowBoolean(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
{
- ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
+ ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse || edge.useKind() == KnownBooleanUse);
if (edge->hasConstant()) {
JSValue value = edge->asJSValue();