DFG FixupPhase should have one common hook for knowing if a node is ever being speculated a certain way
https://bugs.webkit.org/show_bug.cgi?id=110650
Reviewed by Mark Hahnenberg.
Changes almost all calls to edge.setUseKind(kind) to be
setUseKindAndUnboxIfProfitable<kind>(edge). This will allow us to use the latter
as a hook for deciding which locals to unbox (webkit.org/b/110433).
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(FixupPhase):
(JSC::DFG::FixupPhase::setUseKindAndUnboxIfProfitable):
(JSC::DFG::FixupPhase::fixIntEdge):
(JSC::DFG::FixupPhase::fixDoubleEdge):
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143817 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index efde5d1..652c685 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -87,17 +87,17 @@
break;
if (variable->shouldUseDoubleFormat()) {
- fixDoubleEdge(node->child1(), NumberUse, ForwardSpeculation);
+ fixDoubleEdge<NumberUse>(node->child1(), ForwardSpeculation);
break;
}
SpeculatedType predictedType = variable->argumentAwarePrediction();
if (isInt32Speculation(predictedType))
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
else if (isCellSpeculation(predictedType))
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
else if (isBooleanSpeculation(predictedType))
- node->child1().setUseKind(BooleanUse);
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
break;
}
@@ -113,7 +113,7 @@
}
case UInt32ToNumber: {
- node->child1().setUseKind(KnownInt32Use);
+ setUseKindAndUnboxIfProfitable<KnownInt32Use>(node->child1());
break;
}
@@ -124,21 +124,21 @@
case ValueToInt32: {
if (node->child1()->shouldSpeculateInteger()) {
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
}
if (node->child1()->shouldSpeculateNumber()) {
- node->child1().setUseKind(NumberUse);
+ setUseKindAndUnboxIfProfitable<NumberUse>(node->child1());
break;
}
if (node->child1()->shouldSpeculateBoolean()) {
- node->child1().setUseKind(BooleanUse);
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
break;
}
- node->child1().setUseKind(NotCellUse);
+ setUseKindAndUnboxIfProfitable<NotCellUse>(node->child1());
break;
}
@@ -151,8 +151,8 @@
if (attemptToMakeIntegerAdd(node))
break;
if (Node::shouldSpeculateNumberExpectingDefined(node->child1().node(), node->child2().node())) {
- fixDoubleEdge(node->child1());
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
}
break;
@@ -162,28 +162,28 @@
case ArithSub: {
if (attemptToMakeIntegerAdd(node))
break;
- fixDoubleEdge(node->child1());
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
}
case ArithNegate: {
if (m_graph.negateShouldSpeculateInteger(node)) {
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
}
- fixDoubleEdge(node->child1());
+ fixDoubleEdge<NumberUse>(node->child1());
break;
}
case ArithMul: {
if (m_graph.mulShouldSpeculateInteger(node)) {
- node->child1().setUseKind(Int32Use);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
- fixDoubleEdge(node->child1());
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
}
@@ -191,8 +191,8 @@
if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
&& node->canSpeculateInteger()) {
if (isX86() || isARMv7s()) {
- node->child1().setUseKind(Int32Use);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
injectInt32ToDoubleNode(node->child1());
@@ -207,8 +207,8 @@
node->children.initialize(Edge(newDivision, KnownNumberUse), Edge(), Edge());
break;
}
- fixDoubleEdge(node->child1());
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
}
@@ -217,47 +217,47 @@
case ArithMod: {
if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
&& node->canSpeculateInteger()) {
- node->child1().setUseKind(Int32Use);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
- fixDoubleEdge(node->child1());
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
}
case ArithAbs: {
if (node->child1()->shouldSpeculateIntegerForArithmetic()
&& node->canSpeculateInteger()) {
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
}
- fixDoubleEdge(node->child1());
+ fixDoubleEdge<NumberUse>(node->child1());
break;
}
case ArithSqrt: {
- fixDoubleEdge(node->child1());
+ fixDoubleEdge<NumberUse>(node->child1());
break;
}
case LogicalNot: {
if (node->child1()->shouldSpeculateBoolean())
- node->child1().setUseKind(BooleanUse);
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
else if (node->child1()->shouldSpeculateObjectOrOther())
- node->child1().setUseKind(ObjectOrOtherUse);
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
else if (node->child1()->shouldSpeculateInteger())
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
else if (node->child1()->shouldSpeculateNumber())
- fixDoubleEdge(node->child1());
+ fixDoubleEdge<NumberUse>(node->child1());
break;
}
case TypeOf: {
if (node->child1()->shouldSpeculateString())
- node->child1().setUseKind(StringUse);
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
else if (node->child1()->shouldSpeculateCell())
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
@@ -270,13 +270,13 @@
if (node->op() == CompareEqConstant)
break;
if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
- node->child1().setUseKind(Int32Use);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
- fixDoubleEdge(node->child1());
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
}
if (node->op() != CompareEq)
@@ -284,18 +284,18 @@
if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString())
break;
if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
- node->child1().setUseKind(ObjectUse);
- node->child2().setUseKind(ObjectUse);
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
break;
}
if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObjectOrOther()) {
- node->child1().setUseKind(ObjectUse);
- node->child2().setUseKind(ObjectOrOtherUse);
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child2());
break;
}
if (node->child1()->shouldSpeculateObjectOrOther() && node->child2()->shouldSpeculateObject()) {
- node->child1().setUseKind(ObjectOrOtherUse);
- node->child2().setUseKind(ObjectUse);
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
break;
}
break;
@@ -306,20 +306,20 @@
if (node->op() == CompareStrictEqConstant)
break;
if (Node::shouldSpeculateInteger(node->child1().node(), node->child2().node())) {
- node->child1().setUseKind(Int32Use);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
if (Node::shouldSpeculateNumber(node->child1().node(), node->child2().node())) {
- fixDoubleEdge(node->child1());
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<NumberUse>(node->child1());
+ fixDoubleEdge<NumberUse>(node->child2());
break;
}
if (node->child1()->shouldSpeculateString() && node->child2()->shouldSpeculateString())
break;
if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
- node->child1().setUseKind(ObjectUse);
- node->child2().setUseKind(ObjectUse);
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child2());
break;
}
break;
@@ -330,8 +330,8 @@
// Currently we have no good way of refining these.
ASSERT(node->arrayMode() == ArrayMode(Array::String));
blessArrayOperation(node->child1(), node->child2(), node->child3());
- node->child1().setUseKind(KnownCellUse);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
@@ -361,14 +361,14 @@
break;
case Array::Generic:
#if USE(JSVALUE32_64)
- node->child1().setUseKind(CellUse); // Speculating cell due to register pressure on 32-bit.
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1()); // Speculating cell due to register pressure on 32-bit.
#endif
break;
case Array::ForceExit:
break;
default:
- node->child1().setUseKind(KnownCellUse);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
@@ -401,18 +401,18 @@
// Due to register pressure on 32-bit, we speculate cell and
// ignore the base-is-not-cell case entirely by letting the
// baseline JIT handle it.
- child1.setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(child1);
#endif
break;
case Array::Int32:
- child1.setUseKind(KnownCellUse);
- child2.setUseKind(Int32Use);
- child3.setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child3);
break;
case Array::Double:
- child1.setUseKind(KnownCellUse);
- child2.setUseKind(Int32Use);
- fixDoubleEdge(child3, RealNumberUse);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ fixDoubleEdge<RealNumberUse>(child3);
break;
case Array::Int8Array:
case Array::Int16Array:
@@ -421,22 +421,22 @@
case Array::Uint8ClampedArray:
case Array::Uint16Array:
case Array::Uint32Array:
- child1.setUseKind(KnownCellUse);
- child2.setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
if (child3->shouldSpeculateInteger())
- child3.setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child3);
else
- fixDoubleEdge(child3);
+ fixDoubleEdge<NumberUse>(child3);
break;
case Array::Float32Array:
case Array::Float64Array:
- child1.setUseKind(KnownCellUse);
- child2.setUseKind(Int32Use);
- fixDoubleEdge(child3);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
+ fixDoubleEdge<NumberUse>(child3);
break;
default:
- child1.setUseKind(KnownCellUse);
- child2.setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(child1);
+ setUseKindAndUnboxIfProfitable<Int32Use>(child2);
break;
}
break;
@@ -458,14 +458,14 @@
SpecInt32,
node->child2()->prediction()));
blessArrayOperation(node->child1(), Edge(), node->child3());
- node->child1().setUseKind(KnownCellUse);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
switch (node->arrayMode().type()) {
case Array::Int32:
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
case Array::Double:
- fixDoubleEdge(node->child2());
+ fixDoubleEdge<RealNumberUse>(node->child2());
break;
default:
break;
@@ -475,26 +475,26 @@
case ArrayPop: {
blessArrayOperation(node->child1(), Edge(), node->child2());
- node->child1().setUseKind(KnownCellUse);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
break;
}
case RegExpExec:
case RegExpTest: {
- node->child1().setUseKind(CellUse);
- node->child2().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
break;
}
case Branch: {
if (node->child1()->shouldSpeculateBoolean())
- node->child1().setUseKind(BooleanUse);
+ setUseKindAndUnboxIfProfitable<BooleanUse>(node->child1());
else if (node->child1()->shouldSpeculateObjectOrOther())
- node->child1().setUseKind(ObjectOrOtherUse);
+ setUseKindAndUnboxIfProfitable<ObjectOrOtherUse>(node->child1());
else if (node->child1()->shouldSpeculateInteger())
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
else if (node->child1()->shouldSpeculateNumber())
- fixDoubleEdge(node->child1());
+ fixDoubleEdge<NumberUse>(node->child1());
Node* logicalNot = node->child1().node();
if (logicalNot->op() == LogicalNot
@@ -539,7 +539,7 @@
case ToPrimitive: {
if (node->child1()->shouldSpeculateInteger())
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
// FIXME: Add string speculation here.
// https://bugs.webkit.org/show_bug.cgi?id=110175
break;
@@ -567,11 +567,11 @@
break;
case ALL_INT32_INDEXING_TYPES:
for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
- m_graph.m_varArgChildren[node->firstChild() + operandIndex].setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
break;
case ALL_DOUBLE_INDEXING_TYPES:
for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
- m_graph.m_varArgChildren[node->firstChild() + operandIndex].setUseKind(RealNumberUse);
+ setUseKindAndUnboxIfProfitable<RealNumberUse>(m_graph.m_varArgChildren[node->firstChild() + operandIndex]);
break;
case ALL_CONTIGUOUS_INDEXING_TYPES:
case ALL_ARRAY_STORAGE_INDEXING_TYPES:
@@ -584,7 +584,7 @@
}
case NewArrayWithSize: {
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
}
@@ -592,20 +592,20 @@
// FIXME: Use Phantom(type check) and Identity instead.
// https://bugs.webkit.org/show_bug.cgi?id=110395
if (isOtherSpeculation(node->child1()->prediction()))
- node->child1().setUseKind(OtherUse);
+ setUseKindAndUnboxIfProfitable<OtherUse>(node->child1());
else if (isObjectSpeculation(node->child1()->prediction()))
- node->child1().setUseKind(ObjectUse);
+ setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
break;
}
case CreateThis: {
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
case GetMyArgumentByVal:
case GetMyArgumentByValSafe: {
- node->child1().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
break;
}
@@ -620,14 +620,14 @@
case ReallocatePropertyStorage:
case GetScope:
case GetButterfly: {
- node->child1().setUseKind(KnownCellUse);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
break;
}
case GetById: {
if (!node->child1()->shouldSpeculateCell())
break;
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
if (!isInt32Speculation(node->prediction()))
break;
if (codeBlock()->identifier(node->identifierNumber()) != globalData().propertyNames->length)
@@ -654,7 +654,7 @@
node->setOp(GetArrayLength);
ASSERT(node->flags() & NodeMustGenerate);
node->clearFlags(NodeMustGenerate | NodeClobbersWorld);
- node->child1().setUseKind(KnownCellUse);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
m_graph.deref(node);
node->setArrayMode(arrayMode);
@@ -668,7 +668,7 @@
case GetByIdFlush: {
if (node->child1()->shouldSpeculateCell())
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
@@ -681,17 +681,17 @@
case PutById:
case PutByIdDirect:
case CheckHasInstance: {
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
case CheckArray: {
switch (node->arrayMode().type()) {
case Array::String:
- node->child1().setUseKind(StringUse);
+ setUseKindAndUnboxIfProfitable<StringUse>(node->child1());
break;
default:
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
break;
}
break;
@@ -699,22 +699,22 @@
case Arrayify:
case ArrayifyToStructure: {
- node->child1().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
if (node->child2())
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
break;
}
case GetByOffset: {
if (!node->child1()->hasStorageResult())
- node->child1().setUseKind(KnownCellUse);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
break;
}
case PutByOffset: {
if (!node->child1()->hasStorageResult())
- node->child1().setUseKind(KnownCellUse);
- node->child2().setUseKind(KnownCellUse);
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<KnownCellUse>(node->child2());
break;
}
@@ -722,8 +722,8 @@
// FIXME: This appears broken: CheckHasInstance already does an unconditional cell
// check. https://bugs.webkit.org/show_bug.cgi?id=107479
if (!(node->child1()->prediction() & ~SpecCell))
- node->child1().setUseKind(CellUse);
- node->child2().setUseKind(CellUse);
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
break;
}
@@ -896,11 +896,19 @@
} }
}
+ // Set the use kind of the edge. In the future (https://bugs.webkit.org/show_bug.cgi?id=110433),
+ // this can be used to notify the GetLocal that the variable is profitable to unbox.
+ template<UseKind useKind>
+ void setUseKindAndUnboxIfProfitable(Edge& edge)
+ {
+ edge.setUseKind(useKind);
+ }
+
void fixIntEdge(Edge& edge)
{
Node* node = edge.node();
if (node->op() != ValueToInt32) {
- edge.setUseKind(KnownInt32Use);
+ setUseKindAndUnboxIfProfitable<KnownInt32Use>(edge);
return;
}
@@ -920,10 +928,13 @@
edge = newEdge;
}
- void fixDoubleEdge(Edge& edge, UseKind useKind = NumberUse, SpeculationDirection direction = BackwardSpeculation)
+ template<UseKind useKind>
+ void fixDoubleEdge(Edge& edge, SpeculationDirection direction = BackwardSpeculation)
{
+ ASSERT(useKind == NumberUse || useKind == KnownNumberUse || useKind == RealNumberUse);
+
if (edge->prediction() & SpecDouble) {
- edge.setUseKind(useKind);
+ setUseKindAndUnboxIfProfitable<useKind>(edge);
return;
}
@@ -982,8 +993,8 @@
return false;
truncateConstantsIfNecessary(node, mode);
- node->child1().setUseKind(Int32Use);
- node->child2().setUseKind(Int32Use);
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
+ setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
return true;
}