https://bugs.webkit.org/show_bug.cgi?id=115129
Reviewed by Geoffrey Garen.
Based on Oliver's patch. Implements to_jsnumber as Identity(Number:@thingy), and then does
an optimization in Fixup to turn Identity(Number:) into Identity(Int32:) if the predictions
tell us to. Identity is later turned into Phantom.
Also fixed BackPropMask, which appeared to have NodeDoesNotExit included in it. That's
wrong; NodeDoesNotExit is not a backward propagation property.
Also fixed Identity to be marked as CanExit (i.e. not NodeDoesNotExit).
This more than doubles the FPS on ammo.
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::canCompileOpcode):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(FixupPhase):
(JSC::DFG::FixupPhase::observeUseKindOnNode):
(JSC::DFG::FixupPhase::observeUseKindOnEdge):
* dfg/DFGNodeFlags.h:
(DFG):
* dfg/DFGNodeType.h:
(DFG):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@149162
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2013-04-25 Filip Pizlo <fpizlo@apple.com>
+
+ DFG doesn't support to_jsnumber
+ https://bugs.webkit.org/show_bug.cgi?id=115129
+
+ Reviewed by Geoffrey Garen.
+
+ Based on Oliver's patch. Implements to_jsnumber as Identity(Number:@thingy), and then does
+ an optimization in Fixup to turn Identity(Number:) into Identity(Int32:) if the predictions
+ tell us to. Identity is later turned into Phantom.
+
+ Also fixed BackPropMask, which appeared to have NodeDoesNotExit included in it. That's
+ wrong; NodeDoesNotExit is not a backward propagation property.
+
+ Also fixed Identity to be marked as CanExit (i.e. not NodeDoesNotExit).
+
+ This more than doubles the FPS on ammo.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGCapabilities.h:
+ (JSC::DFG::canCompileOpcode):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (FixupPhase):
+ (JSC::DFG::FixupPhase::observeUseKindOnNode):
+ (JSC::DFG::FixupPhase::observeUseKindOnEdge):
+ * dfg/DFGNodeFlags.h:
+ (DFG):
+ * dfg/DFGNodeType.h:
+ (DFG):
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+
2013-04-24 Oliver Hunt <oliver@apple.com>
Add support for Math.imul
NEXT_OPCODE(op_typeof);
}
+ case op_to_jsnumber: {
+ set(currentInstruction[1].u.operand,
+ addToGraph(Identity, Edge(get(currentInstruction[2].u.operand), NumberUse)));
+ NEXT_OPCODE(op_to_jsnumber);
+ }
+
default:
// Parse failed! This should not happen because the capabilities checker
// should have caught it.
case op_put_to_base_variable:
case op_put_to_base:
case op_typeof:
+ case op_to_jsnumber:
return CanCompile;
case op_call_varargs:
setUseKindAndUnboxIfProfitable<CellUse>(node->child2());
break;
}
-
+
+ case Phantom:
+ case Identity: {
+ switch (node->child1().useKind()) {
+ case NumberUse:
+ if (node->child1()->shouldSpeculateIntegerForArithmetic())
+ node->child1().setUseKind(Int32Use);
+ break;
+ default:
+ break;
+ }
+ observeUseKindOnEdge(node->child1());
+ break;
+ }
+
case GetArrayLength:
- case Identity:
case Nop:
case Phi:
case ForwardInt32ToDouble:
#if !ASSERT_DISABLED
// Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
case SetArgument:
- case Phantom:
case JSConstant:
case WeakJSConstant:
case GetLocal:
return true;
#endif
}
-
+
template<UseKind useKind>
void observeUseKindOnNode(Node* node)
{
+ observeUseKindOnNode(node, useKind);
+ }
+
+ void observeUseKindOnEdge(Edge edge)
+ {
+ observeUseKindOnNode(edge.node(), edge.useKind());
+ }
+
+ void observeUseKindOnNode(Node* node, UseKind useKind)
+ {
if (node->op() != GetLocal)
return;
#define NodeMayOverflow 0x080
#define NodeMayNegZero 0x100
-#define NodeBackPropMask 0x3E00
+#define NodeBackPropMask 0x1E00
#define NodeUseBottom 0x0000
#define NodeUsedAsNumber 0x0200 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
#define NodeNeedsNegZero 0x0400 // The result of this computation may be used in a context that observes -0.
/* Marker to indicate that an operation was optimized entirely and all that is left */\
/* is to make one node alias another. CSE will later usually eliminate this node, */\
/* though it may choose not to if it would corrupt predictions (very rare). */\
- macro(Identity, NodeResultJS | NodeDoesNotExit) \
+ macro(Identity, NodeResultJS) \
\
/* Nodes for handling functions (both as call and as construct). */\
macro(ConvertThis, NodeResultJS) \
case CheckArray:
case Arrayify:
case ArrayifyToStructure:
- case Identity:
case MovHint:
case MovHintAndCheck:
case ZombieHint: {
changed |= setPrediction(SpecCellOther);
break;
+ case Identity:
+ changed |= mergePrediction(node->child1()->prediction());
+ break;
+
#ifndef NDEBUG
// These get ignored because they don't return anything.
case PutByVal: