Title: [92734] trunk/Source/_javascript_Core
Revision
92734
Author
[email protected]
Date
2011-08-09 17:51:11 -0700 (Tue, 09 Aug 2011)

Log Message

DFG JIT has no way of propagating predictions to loads and calls
https://bugs.webkit.org/show_bug.cgi?id=65883

Reviewed by Gavin Barraclough.

This introduces the capability to store predictions on graph
nodes.  To save space while being somewhat consistent, the
prediction is always stored in the second OpInfo slot (since
a GetById will use the first one for the identifier).  This
change is a natural extension of r92593 (global variable
prediction).

This is a 1.5% win on V8 in the arithmetic mean, and a 0.6%
win on V8 in the geometric mean.  It is neutral on SunSpider
and Kraken.  Interestingly, on V8 it regresses crypto by 3%
while progressing deltablue and richards by 2.6% and 4.3%,
respectively.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::addToGraph):
(JSC::DFG::ByteCodeParser::addCall):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
* dfg/DFGGraph.h:
(JSC::DFG::Graph::predict):
(JSC::DFG::Graph::getPrediction):
* dfg/DFGNode.h:
(JSC::DFG::isCellPrediction):
(JSC::DFG::isArrayPrediction):
(JSC::DFG::isInt32Prediction):
(JSC::DFG::isDoublePrediction):
(JSC::DFG::isNumberPrediction):
(JSC::DFG::predictionToString):
(JSC::DFG::Node::Node):
(JSC::DFG::Node::hasPrediction):
(JSC::DFG::Node::getPrediction):
(JSC::DFG::Node::predict):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (92733 => 92734)


--- trunk/Source/_javascript_Core/ChangeLog	2011-08-10 00:36:19 UTC (rev 92733)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-08-10 00:51:11 UTC (rev 92734)
@@ -1,5 +1,46 @@
 2011-08-09  Filip Pizlo  <[email protected]>
 
+        DFG JIT has no way of propagating predictions to loads and calls
+        https://bugs.webkit.org/show_bug.cgi?id=65883
+
+        Reviewed by Gavin Barraclough.
+        
+        This introduces the capability to store predictions on graph
+        nodes.  To save space while being somewhat consistent, the
+        prediction is always stored in the second OpInfo slot (since
+        a GetById will use the first one for the identifier).  This
+        change is a natural extension of r92593 (global variable
+        prediction).
+        
+        This is a 1.5% win on V8 in the arithmetic mean, and a 0.6%
+        win on V8 in the geometric mean.  It is neutral on SunSpider
+        and Kraken.  Interestingly, on V8 it regresses crypto by 3%
+        while progressing deltablue and richards by 2.6% and 4.3%,
+        respectively.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::addToGraph):
+        (JSC::DFG::ByteCodeParser::addCall):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::dump):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::Graph::predict):
+        (JSC::DFG::Graph::getPrediction):
+        * dfg/DFGNode.h:
+        (JSC::DFG::isCellPrediction):
+        (JSC::DFG::isArrayPrediction):
+        (JSC::DFG::isInt32Prediction):
+        (JSC::DFG::isDoublePrediction):
+        (JSC::DFG::isNumberPrediction):
+        (JSC::DFG::predictionToString):
+        (JSC::DFG::Node::Node):
+        (JSC::DFG::Node::hasPrediction):
+        (JSC::DFG::Node::getPrediction):
+        (JSC::DFG::Node::predict):
+
+2011-08-09  Filip Pizlo  <[email protected]>
+
         DFG JIT passes the this argument to constructors even though
         it's not necessary
         https://bugs.webkit.org/show_bug.cgi?id=65943

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (92733 => 92734)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-08-10 00:36:19 UTC (rev 92733)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-08-10 00:51:11 UTC (rev 92734)
@@ -394,10 +394,10 @@
         return resultIndex;
     }
     
-    NodeIndex addToGraph(Node::VarArgTag, NodeType op)
+    NodeIndex addToGraph(Node::VarArgTag, NodeType op, OpInfo info1, OpInfo info2)
     {
         NodeIndex resultIndex = (NodeIndex)m_graph.size();
-        m_graph.append(Node(Node::VarArg, op, m_currentIndex, m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs));
+        m_graph.append(Node(Node::VarArg, op, m_currentIndex, info1, info2, m_graph.m_varArgChildren.size() - m_numPassedVarArgs, m_numPassedVarArgs));
         
         m_numPassedVarArgs = 0;
         
@@ -419,7 +419,7 @@
         int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize;
         for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++)
             addVarArgChild(get(argIdx));
-        NodeIndex call = addToGraph(Node::VarArg, op);
+        NodeIndex call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(PredictNone));
         Instruction* putInstruction = currentInstruction + OPCODE_LENGTH(op_call);
         if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
             set(putInstruction[1].u.operand, call);
@@ -862,7 +862,7 @@
             predictArray(base);
             predictInt32(property);
 
-            NodeIndex getByVal = addToGraph(GetByVal, base, property, aliases.lookupGetByVal(base, property));
+            NodeIndex getByVal = addToGraph(GetByVal, OpInfo(0), OpInfo(PredictNone), base, property, aliases.lookupGetByVal(base, property));
             set(currentInstruction[1].u.operand, getByVal);
             aliases.recordGetByVal(getByVal);
 
@@ -891,7 +891,7 @@
             NodeIndex base = get(getInstruction[2].u.operand);
             unsigned identifier = getInstruction[3].u.operand;
             
-            NodeIndex getMethod = addToGraph(GetMethod, OpInfo(identifier), base);
+            NodeIndex getMethod = addToGraph(GetMethod, OpInfo(identifier), OpInfo(PredictNone), base);
             set(getInstruction[1].u.operand, getMethod);
             aliases.recordGetMethod(getMethod);
             
@@ -904,7 +904,7 @@
             NodeIndex base = get(currentInstruction[2].u.operand);
             unsigned identifier = currentInstruction[3].u.operand;
             
-            NodeIndex getById = addToGraph(GetById, OpInfo(identifier), base);
+            NodeIndex getById = addToGraph(GetById, OpInfo(identifier), OpInfo(PredictNone), base);
             set(currentInstruction[1].u.operand, getById);
             aliases.recordGetById(getById);
 

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (92733 => 92734)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2011-08-10 00:36:19 UTC (rev 92733)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2011-08-10 00:51:11 UTC (rev 92734)
@@ -138,6 +138,8 @@
         printf("  predicting %s", predictionToString(getPrediction(node.local())));
     if (node.hasVarNumber())
         printf("  predicting %s", predictionToString(getGlobalVarPrediction(node.varNumber())));
+    if (node.hasPrediction())
+        printf("  predicting %s", predictionToString(node.getPrediction()));
     
     printf("\n");
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (92733 => 92734)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2011-08-10 00:36:19 UTC (rev 92733)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2011-08-10 00:51:11 UTC (rev 92734)
@@ -44,59 +44,6 @@
 // helper function to distinguish vars & temporaries from arguments.
 inline bool operandIsArgument(int operand) { return operand < 0; }
 
-typedef uint8_t PredictedType;
-static const PredictedType PredictNone   = 0;
-static const PredictedType PredictCell   = 0x01;
-static const PredictedType PredictArray  = 0x03;
-static const PredictedType PredictInt32  = 0x04;
-static const PredictedType PredictDouble = 0x08;
-static const PredictedType PredictNumber = 0x0c;
-
-inline bool isCellPrediction(PredictedType value)
-{
-    return (value & PredictCell) == PredictCell && !(value & ~PredictArray);
-}
-
-inline bool isArrayPrediction(PredictedType value)
-{
-    return value == PredictArray;
-}
-
-inline bool isInt32Prediction(PredictedType value)
-{
-    return value == PredictInt32;
-}
-
-inline bool isDoublePrediction(PredictedType value)
-{
-    return value == PredictDouble;
-}
-
-inline bool isNumberPrediction(PredictedType value)
-{
-    return !!(value & PredictNumber) && !(value & ~PredictNumber);
-}
-
-#ifndef NDEBUG
-inline const char* predictionToString(PredictedType value)
-{
-    switch (value) {
-    case PredictNone:
-        return "p-bottom";
-    case PredictCell:
-        return "p-cell";
-    case PredictArray:
-        return "p-array";
-    case PredictInt32:
-        return "p-int32";
-    case PredictNumber:
-        return "p-number";
-    default:
-        return "p-top";
-    }
-}
-#endif
-
 struct PredictionSlot {
 public:
     PredictionSlot()
@@ -217,6 +164,13 @@
         case GetGlobalVar:
             predictGlobalVar(node.varNumber(), prediction);
             break;
+        case GetById:
+        case GetMethod:
+        case GetByVal:
+        case Call:
+        case Construct:
+            node.predict(prediction);
+            break;
         default:
             break;
         }
@@ -256,6 +210,12 @@
             return getPrediction(nodePtr->local());
         case GetGlobalVar:
             return getGlobalVarPrediction(nodePtr->varNumber());
+        case GetById:
+        case GetMethod:
+        case GetByVal:
+        case Call:
+        case Construct:
+            return nodePtr->getPrediction();
         default:
             return PredictNone;
         }

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (92733 => 92734)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2011-08-10 00:36:19 UTC (rev 92733)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2011-08-10 00:51:11 UTC (rev 92734)
@@ -184,6 +184,59 @@
     unsigned m_value;
 };
 
+typedef uint8_t PredictedType;
+static const PredictedType PredictNone   = 0;
+static const PredictedType PredictCell   = 0x01;
+static const PredictedType PredictArray  = 0x03;
+static const PredictedType PredictInt32  = 0x04;
+static const PredictedType PredictDouble = 0x08;
+static const PredictedType PredictNumber = 0x0c;
+
+inline bool isCellPrediction(PredictedType value)
+{
+    return (value & PredictCell) == PredictCell && !(value & ~PredictArray);
+}
+
+inline bool isArrayPrediction(PredictedType value)
+{
+    return value == PredictArray;
+}
+
+inline bool isInt32Prediction(PredictedType value)
+{
+    return value == PredictInt32;
+}
+
+inline bool isDoublePrediction(PredictedType value)
+{
+    return value == PredictDouble;
+}
+
+inline bool isNumberPrediction(PredictedType value)
+{
+    return !!(value & PredictNumber) && !(value & ~PredictNumber);
+}
+
+#ifndef NDEBUG
+inline const char* predictionToString(PredictedType value)
+{
+    switch (value) {
+    case PredictNone:
+        return "p-bottom";
+    case PredictCell:
+        return "p-cell";
+    case PredictArray:
+        return "p-array";
+    case PredictInt32:
+        return "p-int32";
+    case PredictNumber:
+        return "p-number";
+    default:
+        return "p-top";
+    }
+}
+#endif
+
 // === Node ===
 //
 // Node represents a single operation in the data flow graph.
@@ -232,12 +285,14 @@
         children.fixed.child3 = child3;
     }
     
-    // Construct a node with a variable number of children and no immediate values.
-    Node(VarArgTag, NodeType op, ExceptionInfo exceptionInfo, unsigned firstChild, unsigned numChildren)
+    // Construct a node with a variable number of children and two immediate values.
+    Node(VarArgTag, NodeType op, ExceptionInfo exceptionInfo, OpInfo imm1, OpInfo imm2, unsigned firstChild, unsigned numChildren)
         : op(op)
         , exceptionInfo(exceptionInfo)
         , m_virtualRegister(InvalidVirtualRegister)
         , m_refCount(0)
+        , m_opInfo(imm1.m_value)
+        , m_opInfo2(imm2.m_value)
     {
         ASSERT(op & NodeHasVarArgs);
         children.variable.firstChild = firstChild;
@@ -352,6 +407,32 @@
         ASSERT(isBranch());
         return m_opInfo2;
     }
+    
+    bool hasPrediction()
+    {
+        switch (op) {
+        case GetById:
+        case GetMethod:
+        case GetByVal:
+        case Call:
+        case Construct:
+            return true;
+        default:
+            return false;
+        }
+    }
+    
+    PredictedType getPrediction()
+    {
+        ASSERT(hasPrediction());
+        return static_cast<PredictedType>(m_opInfo2);
+    }
+    
+    void predict(PredictedType prediction)
+    {
+        ASSERT(hasPrediction());
+        m_opInfo2 |= prediction;
+    }
 
     VirtualRegister virtualRegister()
     {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to