Changeset 96562 in webkit
- Timestamp:
- Oct 3, 2011 6:05:38 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r96545 r96562 1 2011-10-03 Filip Pizlo <fpizlo@apple.com> 2 3 DFG backends don't have access to per-node predictions from the propagator 4 https://bugs.webkit.org/show_bug.cgi?id=69291 5 6 Reviewed by Oliver Hunt. 7 8 Nodes now have two notion of predictions: the heap prediction, which is 9 what came directly from value profiling, and the propagator's predictions, 10 which arise out of abstract interpretation. Every node has a propagator 11 prediction, but not every node has a heap prediction; and there is no 12 guarantee that a node that has both will keep them consistent as the 13 propagator may have additional information available to it. 14 15 This is performance neutral. 16 17 * dfg/DFGGraph.cpp: 18 (JSC::DFG::Graph::dump): 19 * dfg/DFGGraph.h: 20 * dfg/DFGJITCompiler.h: 21 (JSC::DFG::JITCompiler::getPrediction): 22 * dfg/DFGNode.h: 23 (JSC::DFG::Node::Node): 24 (JSC::DFG::Node::hasHeapPrediction): 25 (JSC::DFG::Node::getHeapPrediction): 26 (JSC::DFG::Node::predictHeap): 27 (JSC::DFG::Node::prediction): 28 (JSC::DFG::Node::predict): 29 * dfg/DFGPropagator.cpp: 30 (JSC::DFG::Propagator::Propagator): 31 (JSC::DFG::Propagator::setPrediction): 32 (JSC::DFG::Propagator::mergePrediction): 33 (JSC::DFG::Propagator::propagateNodePredictions): 34 (JSC::DFG::Propagator::fixupNode): 35 (JSC::DFG::Propagator::isPredictedNumerical): 36 (JSC::DFG::Propagator::logicalNotIsPure): 37 (JSC::DFG::Propagator::setReplacement): 38 1 39 2011-10-03 Jer Noble <jer.noble@apple.com> 2 40 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r96527 r96562 205 205 else if (node.hasVarNumber()) 206 206 printf(" predicting %s", predictionToString(getGlobalVarPrediction(node.varNumber()))); 207 else if (node.has Prediction())208 printf(" predicting %s", predictionToString(node.get Prediction()));207 else if (node.hasHeapPrediction()) 208 printf(" predicting %s", predictionToString(node.getHeapPrediction())); 209 209 else if (node.hasMethodCheckData()) { 210 210 MethodCheckData& methodCheckData = m_methodCheckData[node.methodCheckDataIndex()]; -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r96527 r96562 187 187 } 188 188 189 bool predict(Node& node, PredictedType prediction)190 {191 switch (node.op) {192 case GetLocal:193 case SetLocal:194 case Phi:195 case SetArgument:196 return node.variableAccessData()->predict(prediction);197 case GetGlobalVar:198 return predictGlobalVar(node.varNumber(), prediction);199 case GetById:200 case GetMethod:201 case GetByVal:202 case Call:203 case Construct:204 case GetByOffset:205 case GetScopedVar:206 case Resolve:207 case ResolveBase:208 case ResolveBaseStrictPut:209 case ResolveGlobal:210 return node.predict(prediction);211 default:212 return false;213 }214 }215 216 189 PredictedType getGlobalVarPrediction(unsigned varNumber) 217 190 { … … 227 200 { 228 201 return predictionFromValue(node.valueOfJSConstantNode(codeBlock)); 229 }230 231 PredictedType getPrediction(Node& node, CodeBlock* codeBlock)232 {233 Node* nodePtr = &node;234 235 if (nodePtr->op == ValueToNumber)236 nodePtr = &(*this)[nodePtr->child1()];237 238 if (nodePtr->op == ValueToInt32)239 nodePtr = &(*this)[nodePtr->child1()];240 241 switch (nodePtr->op) {242 case GetLocal:243 case SetLocal:244 case SetArgument:245 case Phi:246 return nodePtr->variableAccessData()->prediction();247 case GetGlobalVar:248 return getGlobalVarPrediction(nodePtr->varNumber());249 case GetById:250 case GetMethod:251 case GetByVal:252 case Call:253 case Construct:254 case GetByOffset:255 return nodePtr->getPrediction();256 case CheckMethod:257 return getMethodCheckPrediction(*nodePtr);258 case JSConstant:259 return getJSConstantPrediction(*nodePtr, codeBlock);260 default:261 return PredictNone;262 }263 202 } 264 203 -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r96377 r96562 284 284 285 285 // Helper methods to get predictions 286 PredictedType getPrediction(Node& node) { return graph().getPrediction(node, codeBlock()); }286 PredictedType getPrediction(Node& node) { return node.prediction(); } 287 287 PredictedType getPrediction(NodeIndex nodeIndex) { return getPrediction(graph()[nodeIndex]); } 288 288 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r96527 r96562 429 429 , m_virtualRegister(InvalidVirtualRegister) 430 430 , m_refCount(0) 431 , m_prediction(PredictNone) 431 432 { 432 433 ASSERT(!(op & NodeHasVarArgs)); … … 444 445 , m_refCount(0) 445 446 , m_opInfo(imm.m_value) 447 , m_prediction(PredictNone) 446 448 { 447 449 ASSERT(!(op & NodeHasVarArgs)); … … 459 461 , m_opInfo(imm1.m_value) 460 462 , m_opInfo2(safeCast<unsigned>(imm2.m_value)) 463 , m_prediction(PredictNone) 461 464 { 462 465 ASSERT(!(op & NodeHasVarArgs)); … … 474 477 , m_opInfo(imm1.m_value) 475 478 , m_opInfo2(safeCast<unsigned>(imm2.m_value)) 479 , m_prediction(PredictNone) 476 480 { 477 481 ASSERT(op & NodeHasVarArgs); … … 755 759 } 756 760 757 bool has Prediction()761 bool hasHeapPrediction() 758 762 { 759 763 switch (op) { … … 775 779 } 776 780 777 PredictedType get Prediction()778 { 779 ASSERT(has Prediction());781 PredictedType getHeapPrediction() 782 { 783 ASSERT(hasHeapPrediction()); 780 784 return static_cast<PredictedType>(m_opInfo2); 781 785 } 782 786 783 bool predict (PredictedType prediction)784 { 785 ASSERT(has Prediction());787 bool predictHeap(PredictedType prediction) 788 { 789 ASSERT(hasHeapPrediction()); 786 790 787 791 return mergePrediction(m_opInfo2, prediction); … … 912 916 ASSERT(op & NodeHasVarArgs); 913 917 return children.variable.numChildren; 918 } 919 920 PredictedType prediction() 921 { 922 return m_prediction; 923 } 924 925 bool predict(PredictedType prediction) 926 { 927 return mergePrediction(m_prediction, prediction); 914 928 } 915 929 … … 938 952 uintptr_t m_opInfo; 939 953 unsigned m_opInfo2; 954 // The prediction ascribed to this node after propagation. 955 PredictedType m_prediction; 940 956 }; 941 957 -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r96527 r96562 43 43 , m_profiledBlock(profiledBlock) 44 44 { 45 // Predictions is a forward flow property that propagates the values seen at46 // a particular value source to their various uses, ensuring that uses perform47 // speculation that does not contravene the expected values.48 m_predictions.resize(m_graph.size());49 50 45 // Replacements are used to implement local common subexpression elimination. 51 46 m_replacements.resize(m_graph.size()); 52 47 53 for (unsigned i = 0; i < m_graph.size(); ++i) { 54 m_predictions[i] = PredictNone; 48 for (unsigned i = 0; i < m_graph.size(); ++i) 55 49 m_replacements[i] = NoNode; 56 }57 50 58 51 for (unsigned i = 0; i < LastNodeId; ++i) … … 286 279 ASSERT(m_graph[m_compileIndex].hasResult()); 287 280 288 if (m_predictions[m_compileIndex] == prediction) 289 return false; 290 291 m_predictions[m_compileIndex] = prediction; 292 return true; 281 // setPrediction() is used when we know that there is no way that we can change 282 // our minds about what the prediction is going to be. There is no semantic 283 // difference between setPrediction() and mergePrediction() other than the 284 // increased checking to validate this property. 285 ASSERT(m_graph[m_compileIndex].prediction() == PredictNone || m_graph[m_compileIndex].prediction() == prediction); 286 287 return m_graph[m_compileIndex].predict(prediction); 293 288 } 294 289 … … 297 292 ASSERT(m_graph[m_compileIndex].hasResult()); 298 293 299 return JSC::mergePrediction(m_predictions[m_compileIndex],prediction);294 return m_graph[m_compileIndex].predict(prediction); 300 295 } 301 296 … … 327 322 328 323 case SetLocal: { 329 changed |= node.variableAccessData()->predict(m_ predictions[node.child1()]);324 changed |= node.variableAccessData()->predict(m_graph[node.child1()].prediction()); 330 325 break; 331 326 } … … 343 338 344 339 case ArithMod: { 345 PredictedType left = m_ predictions[node.child1()];346 PredictedType right = m_ predictions[node.child2()];340 PredictedType left = m_graph[node.child1()].prediction(); 341 PredictedType right = m_graph[node.child2()].prediction(); 347 342 348 343 if (left && right) { … … 364 359 365 360 case ValueToNumber: { 366 PredictedType prediction = m_ predictions[node.child1()];361 PredictedType prediction = m_graph[node.child1()].prediction(); 367 362 368 363 if (prediction) { … … 377 372 378 373 case ValueAdd: { 379 PredictedType left = m_ predictions[node.child1()];380 PredictedType right = m_ predictions[node.child2()];374 PredictedType left = m_graph[node.child1()].prediction(); 375 PredictedType right = m_graph[node.child2()].prediction(); 381 376 382 377 if (left && right) { … … 401 396 case ArithMax: 402 397 case ArithDiv: { 403 PredictedType left = m_ predictions[node.child1()];404 PredictedType right = m_ predictions[node.child2()];398 PredictedType left = m_graph[node.child1()].prediction(); 399 PredictedType right = m_graph[node.child2()].prediction(); 405 400 406 401 if (left && right) { … … 419 414 420 415 case ArithAbs: { 421 PredictedType child = m_ predictions[node.child1()];416 PredictedType child = m_graph[node.child1()].prediction(); 422 417 if (child) { 423 418 if (nodeCanSpeculateInteger(node.arithNodeFlags())) … … 444 439 case GetMethod: 445 440 case GetByVal: { 446 if (node.get Prediction())447 changed |= mergePrediction(node.get Prediction());441 if (node.getHeapPrediction()) 442 changed |= mergePrediction(node.getHeapPrediction()); 448 443 break; 449 444 } … … 455 450 456 451 case GetByOffset: { 457 if (node.get Prediction())458 changed |= mergePrediction(node.get Prediction());452 if (node.getHeapPrediction()) 453 changed |= mergePrediction(node.getHeapPrediction()); 459 454 break; 460 455 } … … 467 462 case Call: 468 463 case Construct: { 469 if (node.get Prediction())470 changed |= mergePrediction(node.get Prediction());464 if (node.getHeapPrediction()) 465 changed |= mergePrediction(node.getHeapPrediction()); 471 466 break; 472 467 } 473 468 474 469 case ConvertThis: { 475 PredictedType prediction = m_ predictions[node.child1()];470 PredictedType prediction = m_graph[node.child1()].prediction(); 476 471 if (prediction) { 477 472 if (prediction & ~PredictObjectMask) { 478 prediction &= ~PredictObjectMask;479 prediction |= PredictObjectUnknown;473 prediction &= PredictObjectMask; 474 prediction = mergePredictions(prediction, PredictObjectUnknown); 480 475 } 481 476 changed |= mergePrediction(prediction); … … 492 487 493 488 case PutGlobalVar: { 494 changed |= m_graph.predictGlobalVar(node.varNumber(), m_ predictions[node.child1()]);489 changed |= m_graph.predictGlobalVar(node.varNumber(), m_graph[node.child1()].prediction()); 495 490 break; 496 491 } … … 501 496 case ResolveBaseStrictPut: 502 497 case ResolveGlobal: { 503 PredictedType prediction = node.get Prediction();498 PredictedType prediction = node.getHeapPrediction(); 504 499 if (prediction) 505 500 changed |= mergePrediction(prediction); … … 540 535 541 536 case ToPrimitive: { 542 PredictedType child = m_ predictions[node.child1()];537 PredictedType child = m_graph[node.child1()].prediction(); 543 538 if (child) { 544 539 if (isObjectPrediction(child)) { … … 600 595 601 596 #if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE) 602 printf("%s ", predictionToString(m_ predictions[m_compileIndex]));597 printf("%s ", predictionToString(m_graph[m_compileIndex].prediction())); 603 598 #endif 604 599 … … 653 648 } 654 649 655 PredictedType left = m_ predictions[node.child1()];656 PredictedType right = m_ predictions[node.child2()];650 PredictedType left = m_graph[node.child1()].prediction(); 651 PredictedType right = m_graph[node.child2()].prediction(); 657 652 658 653 if (left && right && isNumberPrediction(left) && isNumberPrediction(right)) { … … 678 673 } 679 674 680 PredictedType left = m_ predictions[node.child1()];681 PredictedType right = m_ predictions[node.child2()];675 PredictedType left = m_graph[node.child1()].prediction(); 676 PredictedType right = m_graph[node.child2()].prediction(); 682 677 683 678 if (left && right) { … … 696 691 } 697 692 698 PredictedType prediction = m_ predictions[node.child1()];693 PredictedType prediction = m_graph[node.child1()].prediction(); 699 694 if (prediction & PredictDouble) 700 695 toDouble(node.child1()); … … 708 703 709 704 case GetById: { 710 bool isArray = isArrayPrediction(m_ predictions[node.child1()]);711 bool isString = isStringPrediction(m_ predictions[node.child1()]);705 bool isArray = isArrayPrediction(m_graph[node.child1()].prediction()); 706 bool isString = isStringPrediction(m_graph[node.child1()].prediction()); 712 707 if (!isArray && !isString) 713 708 break; 714 if (!isInt32Prediction(m_ predictions[m_compileIndex]))709 if (!isInt32Prediction(m_graph[m_compileIndex].prediction())) 715 710 break; 716 711 if (m_codeBlock->identifier(node.identifierNumber()) != m_globalData.propertyNames->length) … … 861 856 bool isPredictedNumerical(Node& node) 862 857 { 863 PredictedType left = m_ predictions[node.child1()];864 PredictedType right = m_ predictions[node.child2()];858 PredictedType left = m_graph[node.child1()].prediction(); 859 PredictedType right = m_graph[node.child2()].prediction(); 865 860 return isNumberPrediction(left) && isNumberPrediction(right); 866 861 } … … 868 863 bool logicalNotIsPure(Node& node) 869 864 { 870 PredictedType prediction = m_ predictions[node.child1()];865 PredictedType prediction = m_graph[node.child1()].prediction(); 871 866 return isBooleanPrediction(prediction) || !prediction; 872 867 } … … 1166 1161 // Be safe. Don't try to perform replacements if the predictions don't 1167 1162 // agree. 1168 if (m_ predictions[m_compileIndex] != m_predictions[replacement])1163 if (m_graph[m_compileIndex].prediction() != m_graph[replacement].prediction()) 1169 1164 return; 1170 1165 … … 1389 1384 NodeIndex m_compileIndex; 1390 1385 1391 Vector<PredictedType, 16> m_predictions;1392 1393 1386 #if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE) 1394 1387 unsigned m_count;
Note: See TracChangeset
for help on using the changeset viewer.