Changeset 145323 in webkit for trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
- Timestamp:
- Mar 9, 2013, 2:48:09 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r145299 r145323 107 107 } 108 108 109 bool isNotNegZero(Node* node) 110 { 111 if (!m_graph.isNumberConstant(node)) 112 return false; 113 double value = m_graph.valueOfNumberConstant(node); 114 return !value && 1.0 / value < 0.0; 115 } 116 117 bool isNotZero(Node* node) 118 { 119 if (!m_graph.isNumberConstant(node)) 120 return false; 121 return !!m_graph.valueOfNumberConstant(node); 122 } 123 124 bool isWithinPowerOfTwoForConstant(Node* node, int power) 125 { 126 JSValue immediateValue = node->valueOfJSConstant(codeBlock()); 127 if (!immediateValue.isInt32()) 128 return false; 129 int32_t intImmediate = immediateValue.asInt32(); 130 return intImmediate > -(1 << power) && intImmediate < (1 << power); 131 } 132 133 bool isWithinPowerOfTwoNonRecursive(Node* node, int power) 134 { 135 if (node->op() != JSConstant) 136 return false; 137 return isWithinPowerOfTwoForConstant(node, power); 138 } 139 140 bool isWithinPowerOfTwo(Node* node, int power) 141 { 142 switch (node->op()) { 143 case JSConstant: { 144 return isWithinPowerOfTwoForConstant(node, power); 145 } 146 147 case BitAnd: { 148 return isWithinPowerOfTwoNonRecursive(node->child1().node(), power) 149 || isWithinPowerOfTwoNonRecursive(node->child2().node(), power); 150 } 151 152 case BitRShift: 153 case BitURShift: { 154 Node* shiftAmount = node->child2().node(); 155 if (shiftAmount->op() != JSConstant) 156 return false; 157 JSValue immediateValue = shiftAmount->valueOfJSConstant(codeBlock()); 158 if (!immediateValue.isInt32()) 159 return false; 160 return immediateValue > 32 - power; 161 } 162 163 default: 164 return false; 165 } 166 } 167 109 168 SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value) 110 169 { … … 124 183 { 125 184 NodeType op = node->op(); 185 NodeFlags flags = node->flags() & NodeBackPropMask; 126 186 127 187 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) 128 dataLog(" ", Graph::opName(op), " ", m_currentNode, ": ", NodeFlagsDump(node->flags()), " ");188 dataLog(" ", Graph::opName(op), " ", m_currentNode, ": ", nodeFlagsAsString(flags), " "); 129 189 #endif 130 190 … … 143 203 if (prediction) 144 204 changed |= mergePrediction(prediction); 205 206 // Assume conservatively that a SetLocal implies that the value may flow through a loop, 207 // and so we would have overflow leading to the program "observing" numbers even if all 208 // users of the value are doing toInt32. It might be worthwhile to revisit this at some 209 // point and actually check if the data flow involves loops, but right now I don't think 210 // we have evidence that this would be beneficial for benchmarks. 211 212 changed |= variableAccessData->mergeFlags((flags & ~NodeUsedAsIntLocally) | NodeUsedAsNumber); 145 213 break; 146 214 } … … 149 217 VariableAccessData* variableAccessData = node->variableAccessData(); 150 218 changed |= variableAccessData->predict(node->child1()->prediction()); 219 220 changed |= node->child1()->mergeFlags(variableAccessData->flags()); 221 break; 222 } 223 224 case Flush: { 225 // Make sure that the analysis knows that flushed locals escape. 226 VariableAccessData* variableAccessData = node->variableAccessData(); 227 changed |= variableAccessData->mergeFlags(NodeUsedAsValue); 151 228 break; 152 229 } … … 159 236 case BitURShift: { 160 237 changed |= setPrediction(SpecInt32); 238 flags |= NodeUsedAsInt | NodeUsedAsIntLocally; 239 flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther); 240 changed |= node->child1()->mergeFlags(flags); 241 changed |= node->child2()->mergeFlags(flags); 161 242 break; 162 243 } … … 164 245 case ValueToInt32: { 165 246 changed |= setPrediction(SpecInt32); 166 break; 167 } 168 169 case ArrayPop: 170 case ArrayPush: 247 flags |= NodeUsedAsInt | NodeUsedAsIntLocally; 248 flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther); 249 changed |= node->child1()->mergeFlags(flags); 250 break; 251 } 252 253 case ArrayPop: { 254 changed |= mergePrediction(node->getHeapPrediction()); 255 changed |= mergeDefaultFlags(node); 256 break; 257 } 258 259 case ArrayPush: { 260 changed |= mergePrediction(node->getHeapPrediction()); 261 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 262 changed |= node->child2()->mergeFlags(NodeUsedAsValue); 263 break; 264 } 265 171 266 case RegExpExec: 172 case RegExpTest: 173 case GetById: 174 case GetByIdFlush: 175 case GetMyArgumentByValSafe: 176 case GetByOffset: 177 case Call: 178 case Construct: 179 case GetGlobalVar: 180 case GetScopedVar: 181 case Resolve: 182 case ResolveBase: 183 case ResolveBaseStrictPut: 184 case ResolveGlobal: { 185 changed |= setPrediction(node->getHeapPrediction()); 267 case RegExpTest: { 268 changed |= mergePrediction(node->getHeapPrediction()); 269 changed |= mergeDefaultFlags(node); 186 270 break; 187 271 } 188 272 189 273 case StringCharCodeAt: { 190 changed |= setPrediction(SpecInt32); 274 changed |= mergePrediction(SpecInt32); 275 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 276 changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally); 191 277 break; 192 278 } … … 197 283 else 198 284 changed |= mergePrediction(SpecNumber); 285 286 changed |= node->child1()->mergeFlags(flags); 199 287 break; 200 288 } … … 204 292 SpeculatedType right = node->child2()->prediction(); 205 293 294 AddSpeculationMode mode = DontSpeculateInteger; 295 206 296 if (left && right) { 207 297 if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) { 208 if ( m_graph.addSpeculationMode(node) != DontSpeculateInteger)298 if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger) 209 299 changed |= mergePrediction(SpecInt32); 210 300 else … … 216 306 changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble); 217 307 } 308 309 if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node())) 310 flags &= ~NodeNeedsNegZero; 311 if (node->child1()->hasNumberResult() || node->child2()->hasNumberResult()) 312 flags &= ~NodeUsedAsOther; 313 314 if (mode != SpeculateInteger) 315 flags |= NodeUsedAsNumber; 316 317 changed |= node->child1()->mergeFlags(flags); 318 changed |= node->child2()->mergeFlags(flags); 218 319 break; 219 320 } … … 223 324 SpeculatedType right = node->child2()->prediction(); 224 325 326 AddSpeculationMode mode = DontSpeculateInteger; 327 225 328 if (left && right) { 226 if ( m_graph.addSpeculationMode(node) != DontSpeculateInteger)329 if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger) 227 330 changed |= mergePrediction(SpecInt32); 228 331 else 229 332 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 230 333 } 334 335 if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node())) 336 flags &= ~NodeNeedsNegZero; 337 flags &= ~NodeUsedAsOther; 338 339 if (mode != SpeculateInteger) 340 flags |= NodeUsedAsNumber; 341 342 changed |= node->child1()->mergeFlags(flags); 343 changed |= node->child2()->mergeFlags(flags); 231 344 break; 232 345 } … … 236 349 SpeculatedType right = node->child2()->prediction(); 237 350 351 AddSpeculationMode mode = DontSpeculateInteger; 352 238 353 if (left && right) { 239 if ( m_graph.addSpeculationMode(node) != DontSpeculateInteger)354 if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger) 240 355 changed |= mergePrediction(SpecInt32); 241 356 else 242 357 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 243 358 } 359 360 if (isNotZero(node->child1().node()) || isNotZero(node->child2().node())) 361 flags &= ~NodeNeedsNegZero; 362 flags &= ~NodeUsedAsOther; 363 364 if (mode != SpeculateInteger) 365 flags |= NodeUsedAsNumber; 366 367 changed |= node->child1()->mergeFlags(flags); 368 changed |= node->child2()->mergeFlags(flags); 244 369 break; 245 370 } … … 252 377 changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction())); 253 378 } 379 380 flags &= ~NodeUsedAsOther; 381 382 changed |= node->child1()->mergeFlags(flags); 254 383 break; 255 384 … … 266 395 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 267 396 } 397 398 flags |= NodeUsedAsNumber; 399 flags &= ~NodeUsedAsOther; 400 401 changed |= node->child1()->mergeFlags(flags); 402 changed |= node->child2()->mergeFlags(flags); 268 403 break; 269 404 } … … 279 414 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); 280 415 } 416 417 // As soon as a multiply happens, we can easily end up in the part 418 // of the double domain where the point at which you do truncation 419 // can change the outcome. So, ArithMul always forces its inputs to 420 // check for overflow. Additionally, it will have to check for overflow 421 // itself unless we can prove that there is no way for the values 422 // produced to cause double rounding. 423 424 if (!isWithinPowerOfTwo(node->child1().node(), 22) 425 && !isWithinPowerOfTwo(node->child2().node(), 22)) 426 flags |= NodeUsedAsNumber; 427 428 changed |= node->mergeFlags(flags); 429 430 flags |= NodeUsedAsNumber | NodeNeedsNegZero; 431 flags &= ~NodeUsedAsOther; 432 433 changed |= node->child1()->mergeFlags(flags); 434 changed |= node->child2()->mergeFlags(flags); 281 435 break; 282 436 } … … 293 447 changed |= mergePrediction(SpecDouble); 294 448 } 449 450 // As soon as a multiply happens, we can easily end up in the part 451 // of the double domain where the point at which you do truncation 452 // can change the outcome. So, ArithDiv always checks for overflow 453 // no matter what, and always forces its inputs to check as well. 454 455 flags |= NodeUsedAsNumber | NodeNeedsNegZero; 456 flags &= ~NodeUsedAsOther; 457 458 changed |= node->child1()->mergeFlags(flags); 459 changed |= node->child2()->mergeFlags(flags); 295 460 break; 296 461 } … … 307 472 changed |= mergePrediction(SpecDouble); 308 473 } 474 475 flags |= NodeUsedAsNumber | NodeNeedsNegZero; 476 flags &= ~NodeUsedAsOther; 477 478 changed |= node->child1()->mergeFlags(flags); 479 changed |= node->child2()->mergeFlags(flags); 309 480 break; 310 481 } … … 312 483 case ArithSqrt: { 313 484 changed |= setPrediction(SpecDouble); 485 flags |= NodeUsedAsNumber | NodeNeedsNegZero; 486 flags &= ~NodeUsedAsOther; 487 changed |= node->child1()->mergeFlags(flags); 314 488 break; 315 489 } … … 322 496 else 323 497 changed |= mergePrediction(speculatedDoubleTypeForPrediction(child)); 498 499 changed |= node->child1()->mergeFlags(flags); 324 500 break; 325 501 } … … 342 518 case IsFunction: { 343 519 changed |= setPrediction(SpecBoolean); 520 changed |= mergeDefaultFlags(node); 344 521 break; 345 522 } … … 347 524 case TypeOf: { 348 525 changed |= setPrediction(SpecString); 349 break; 350 } 351 526 changed |= mergeDefaultFlags(node); 527 break; 528 } 529 530 case GetById: { 531 changed |= mergePrediction(node->getHeapPrediction()); 532 changed |= mergeDefaultFlags(node); 533 break; 534 } 535 536 case GetByIdFlush: 537 changed |= mergePrediction(node->getHeapPrediction()); 538 changed |= mergeDefaultFlags(node); 539 break; 540 352 541 case GetByVal: { 353 542 if (node->child1()->shouldSpeculateFloat32Array() … … 356 545 else 357 546 changed |= mergePrediction(node->getHeapPrediction()); 547 548 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 549 changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally); 550 break; 551 } 552 553 case GetMyArgumentByValSafe: { 554 changed |= mergePrediction(node->getHeapPrediction()); 555 changed |= node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally); 358 556 break; 359 557 } … … 370 568 case ReallocatePropertyStorage: { 371 569 changed |= setPrediction(SpecOther); 372 break; 373 } 374 570 changed |= mergeDefaultFlags(node); 571 break; 572 } 573 574 case GetByOffset: { 575 changed |= mergePrediction(node->getHeapPrediction()); 576 changed |= mergeDefaultFlags(node); 577 break; 578 } 579 580 case Call: 581 case Construct: { 582 changed |= mergePrediction(node->getHeapPrediction()); 583 for (unsigned childIdx = node->firstChild(); 584 childIdx < node->firstChild() + node->numChildren(); 585 ++childIdx) 586 changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue); 587 break; 588 } 589 375 590 case ConvertThis: { 376 591 SpeculatedType prediction = node->child1()->prediction(); … … 382 597 changed |= mergePrediction(prediction); 383 598 } 599 changed |= mergeDefaultFlags(node); 600 break; 601 } 602 603 case GetGlobalVar: { 604 changed |= mergePrediction(node->getHeapPrediction()); 605 break; 606 } 607 608 case PutGlobalVar: 609 case PutGlobalVarCheck: { 610 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 611 break; 612 } 613 614 case GetScopedVar: 615 case Resolve: 616 case ResolveBase: 617 case ResolveBaseStrictPut: 618 case ResolveGlobal: { 619 SpeculatedType prediction = node->getHeapPrediction(); 620 changed |= mergePrediction(prediction); 384 621 break; 385 622 } … … 400 637 case NewObject: { 401 638 changed |= setPrediction(SpecFinalObject); 402 break; 403 } 404 405 case NewArray: 406 case NewArrayWithSize: 639 changed |= mergeDefaultFlags(node); 640 break; 641 } 642 643 case NewArray: { 644 changed |= setPrediction(SpecArray); 645 for (unsigned childIdx = node->firstChild(); 646 childIdx < node->firstChild() + node->numChildren(); 647 ++childIdx) 648 changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue); 649 break; 650 } 651 652 case NewArrayWithSize: { 653 changed |= setPrediction(SpecArray); 654 changed |= node->child1()->mergeFlags(NodeUsedAsValue | NodeUsedAsInt | NodeUsedAsIntLocally); 655 break; 656 } 657 407 658 case NewArrayBuffer: { 408 659 changed |= setPrediction(SpecArray); … … 410 661 } 411 662 412 case NewRegexp: 413 case CreateActivation: { 663 case NewRegexp: { 414 664 changed |= setPrediction(SpecObjectOther); 415 665 break; 416 666 } 417 667 418 case StringCharAt: 668 case StringCharAt: { 669 changed |= setPrediction(SpecString); 670 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 671 changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally); 672 break; 673 } 674 419 675 case StrCat: { 420 676 changed |= setPrediction(SpecString); 677 for (unsigned childIdx = node->firstChild(); 678 childIdx < node->firstChild() + node->numChildren(); 679 ++childIdx) 680 changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther); 421 681 break; 422 682 } … … 440 700 changed |= mergePrediction(child); 441 701 } 702 changed |= node->child1()->mergeFlags(flags); 703 break; 704 } 705 706 case CreateActivation: { 707 changed |= setPrediction(SpecObjectOther); 442 708 break; 443 709 } … … 478 744 } 479 745 746 case PutByVal: 747 changed |= m_graph.varArgChild(node, 0)->mergeFlags(NodeUsedAsValue); 748 changed |= m_graph.varArgChild(node, 1)->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally); 749 changed |= m_graph.varArgChild(node, 2)->mergeFlags(NodeUsedAsValue); 750 break; 751 752 case PutScopedVar: 753 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 754 changed |= node->child3()->mergeFlags(NodeUsedAsValue); 755 break; 756 757 case Return: 758 case Throw: 759 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 760 break; 761 762 case PutById: 763 case PutByIdDirect: 764 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 765 changed |= node->child2()->mergeFlags(NodeUsedAsValue); 766 break; 767 768 case PutByOffset: 769 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 770 changed |= node->child3()->mergeFlags(NodeUsedAsValue); 771 break; 772 480 773 case Phi: 481 774 // Phis should not be visible here since we're iterating the all-but-Phi's … … 484 777 break; 485 778 779 case SetCallee: 780 case SetMyScope: 781 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 782 break; 783 486 784 case GetScope: 785 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 487 786 changed |= setPrediction(SpecCellOther); 488 787 break; … … 490 789 #ifndef NDEBUG 491 790 // These get ignored because they don't return anything. 492 case PutByVal:493 case PutScopedVar:494 case Return:495 case Throw:496 case PutById:497 case PutByIdDirect:498 case PutByOffset:499 case SetCallee:500 case SetMyScope:501 791 case DFG::Jump: 502 792 case Branch: … … 520 810 case AllocationProfileWatchpoint: 521 811 case Phantom: 522 case PutGlobalVar: 523 case PutGlobalVarCheck: 812 changed |= mergeDefaultFlags(node); 524 813 break; 525 814 … … 529 818 case CountExecution: 530 819 case PhantomLocal: 531 case Flush:532 820 break; 533 821 … … 537 825 #else 538 826 default: 827 changed |= mergeDefaultFlags(node); 539 828 break; 540 829 #endif … … 548 837 } 549 838 839 bool mergeDefaultFlags(Node* node) 840 { 841 bool changed = false; 842 if (node->flags() & NodeHasVarArgs) { 843 for (unsigned childIdx = node->firstChild(); 844 childIdx < node->firstChild() + node->numChildren(); 845 childIdx++) { 846 if (!!m_graph.m_varArgChildren[childIdx]) 847 changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue); 848 } 849 } else { 850 if (!node->child1()) 851 return changed; 852 changed |= node->child1()->mergeFlags(NodeUsedAsValue); 853 if (!node->child2()) 854 return changed; 855 changed |= node->child2()->mergeFlags(NodeUsedAsValue); 856 if (!node->child3()) 857 return changed; 858 changed |= node->child3()->mergeFlags(NodeUsedAsValue); 859 } 860 return changed; 861 } 862 550 863 void propagateForward() 551 864 {
Note:
See TracChangeset
for help on using the changeset viewer.