| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COMPILER_NODE_MATCHERS_H_ | 5 #ifndef V8_COMPILER_NODE_MATCHERS_H_ |
| 6 #define V8_COMPILER_NODE_MATCHERS_H_ | 6 #define V8_COMPILER_NODE_MATCHERS_H_ |
| 7 | 7 |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 // TODO(turbofan): Move ExternalReference out of assembler.h | 10 // TODO(turbofan): Move ExternalReference out of assembler.h |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 private: | 311 private: |
| 312 int scale_; | 312 int scale_; |
| 313 bool power_of_two_plus_one_; | 313 bool power_of_two_plus_one_; |
| 314 }; | 314 }; |
| 315 | 315 |
| 316 typedef ScaleMatcher<Int32BinopMatcher, IrOpcode::kInt32Mul, | 316 typedef ScaleMatcher<Int32BinopMatcher, IrOpcode::kInt32Mul, |
| 317 IrOpcode::kWord32Shl> Int32ScaleMatcher; | 317 IrOpcode::kWord32Shl> Int32ScaleMatcher; |
| 318 typedef ScaleMatcher<Int64BinopMatcher, IrOpcode::kInt64Mul, | 318 typedef ScaleMatcher<Int64BinopMatcher, IrOpcode::kInt64Mul, |
| 319 IrOpcode::kWord64Shl> Int64ScaleMatcher; | 319 IrOpcode::kWord64Shl> Int64ScaleMatcher; |
| 320 | 320 |
| 321 | 321 template <class BinopMatcher, IrOpcode::Value AddOpcode, |
| 322 template <class BinopMatcher, IrOpcode::Value kAddOpcode, | 322 IrOpcode::Value SubOpcode, IrOpcode::Value kMulOpcode, |
| 323 IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode> | 323 IrOpcode::Value kShiftOpcode> |
| 324 struct AddMatcher : public BinopMatcher { | 324 struct AddMatcher : public BinopMatcher { |
| 325 static const IrOpcode::Value kOpcode = kAddOpcode; | 325 static const IrOpcode::Value kAddOpcode = AddOpcode; |
| 326 static const IrOpcode::Value kSubOpcode = SubOpcode; |
| 326 typedef ScaleMatcher<BinopMatcher, kMulOpcode, kShiftOpcode> Matcher; | 327 typedef ScaleMatcher<BinopMatcher, kMulOpcode, kShiftOpcode> Matcher; |
| 327 | 328 |
| 328 AddMatcher(Node* node, bool allow_input_swap) | 329 AddMatcher(Node* node, bool allow_input_swap) |
| 329 : BinopMatcher(node, allow_input_swap), | 330 : BinopMatcher(node, allow_input_swap), |
| 330 scale_(-1), | 331 scale_(-1), |
| 331 power_of_two_plus_one_(false) { | 332 power_of_two_plus_one_(false) { |
| 332 Initialize(node, allow_input_swap); | 333 Initialize(node, allow_input_swap); |
| 333 } | 334 } |
| 334 explicit AddMatcher(Node* node) | 335 explicit AddMatcher(Node* node) |
| 335 : BinopMatcher(node, node->op()->HasProperty(Operator::kCommutative)), | 336 : BinopMatcher(node, node->op()->HasProperty(Operator::kCommutative)), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 366 if (right_matcher.matches()) { | 367 if (right_matcher.matches()) { |
| 367 scale_ = right_matcher.scale(); | 368 scale_ = right_matcher.scale(); |
| 368 power_of_two_plus_one_ = right_matcher.power_of_two_plus_one(); | 369 power_of_two_plus_one_ = right_matcher.power_of_two_plus_one(); |
| 369 this->SwapInputs(); | 370 this->SwapInputs(); |
| 370 return; | 371 return; |
| 371 } | 372 } |
| 372 | 373 |
| 373 if (this->right().opcode() == kAddOpcode && | 374 if (this->right().opcode() == kAddOpcode && |
| 374 this->left().opcode() != kAddOpcode) { | 375 this->left().opcode() != kAddOpcode) { |
| 375 this->SwapInputs(); | 376 this->SwapInputs(); |
| 377 } else if (this->right().opcode() == kSubOpcode && |
| 378 this->left().opcode() != kSubOpcode) { |
| 379 this->SwapInputs(); |
| 376 } | 380 } |
| 377 } | 381 } |
| 378 | 382 |
| 379 int scale_; | 383 int scale_; |
| 380 bool power_of_two_plus_one_; | 384 bool power_of_two_plus_one_; |
| 381 }; | 385 }; |
| 382 | 386 |
| 383 typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul, | 387 typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Sub, |
| 384 IrOpcode::kWord32Shl> Int32AddMatcher; | 388 IrOpcode::kInt32Mul, IrOpcode::kWord32Shl> |
| 385 typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Mul, | 389 Int32AddMatcher; |
| 386 IrOpcode::kWord64Shl> Int64AddMatcher; | 390 typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Sub, |
| 391 IrOpcode::kInt64Mul, IrOpcode::kWord64Shl> |
| 392 Int64AddMatcher; |
| 387 | 393 |
| 394 enum DisplacementMode { kPositiveDisplacement, kNegativeDisplacement }; |
| 388 | 395 |
| 389 template <class AddMatcher> | 396 template <class AddMatcher> |
| 390 struct BaseWithIndexAndDisplacementMatcher { | 397 struct BaseWithIndexAndDisplacementMatcher { |
| 391 BaseWithIndexAndDisplacementMatcher(Node* node, bool allow_input_swap) | 398 BaseWithIndexAndDisplacementMatcher(Node* node, bool allow_input_swap) |
| 392 : matches_(false), | 399 : matches_(false), |
| 393 index_(nullptr), | 400 index_(nullptr), |
| 394 scale_(0), | 401 scale_(0), |
| 395 base_(nullptr), | 402 base_(nullptr), |
| 396 displacement_(nullptr) { | 403 displacement_(nullptr), |
| 404 displacement_mode_(kPositiveDisplacement) { |
| 397 Initialize(node, allow_input_swap); | 405 Initialize(node, allow_input_swap); |
| 398 } | 406 } |
| 399 | 407 |
| 400 explicit BaseWithIndexAndDisplacementMatcher(Node* node) | 408 explicit BaseWithIndexAndDisplacementMatcher(Node* node) |
| 401 : matches_(false), | 409 : matches_(false), |
| 402 index_(nullptr), | 410 index_(nullptr), |
| 403 scale_(0), | 411 scale_(0), |
| 404 base_(nullptr), | 412 base_(nullptr), |
| 405 displacement_(nullptr) { | 413 displacement_(nullptr), |
| 414 displacement_mode_(kPositiveDisplacement) { |
| 406 Initialize(node, node->op()->HasProperty(Operator::kCommutative)); | 415 Initialize(node, node->op()->HasProperty(Operator::kCommutative)); |
| 407 } | 416 } |
| 408 | 417 |
| 409 bool matches() const { return matches_; } | 418 bool matches() const { return matches_; } |
| 410 Node* index() const { return index_; } | 419 Node* index() const { return index_; } |
| 411 int scale() const { return scale_; } | 420 int scale() const { return scale_; } |
| 412 Node* base() const { return base_; } | 421 Node* base() const { return base_; } |
| 413 Node* displacement() const { return displacement_; } | 422 Node* displacement() const { return displacement_; } |
| 423 DisplacementMode displacement_mode() const { return displacement_mode_; } |
| 414 | 424 |
| 415 private: | 425 private: |
| 416 bool matches_; | 426 bool matches_; |
| 417 Node* index_; | 427 Node* index_; |
| 418 int scale_; | 428 int scale_; |
| 419 Node* base_; | 429 Node* base_; |
| 420 Node* displacement_; | 430 Node* displacement_; |
| 431 DisplacementMode displacement_mode_; |
| 421 | 432 |
| 422 void Initialize(Node* node, bool allow_input_swap) { | 433 void Initialize(Node* node, bool allow_input_swap) { |
| 423 // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of | 434 // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of |
| 424 // displacements and scale factors that are used as inputs, so instead of | 435 // displacements and scale factors that are used as inputs, so instead of |
| 425 // enumerating all possible patterns by brute force, checking for node | 436 // enumerating all possible patterns by brute force, checking for node |
| 426 // clusters using the following templates in the following order suffices to | 437 // clusters using the following templates in the following order suffices to |
| 427 // find all of the interesting cases (S = index * scale, B = base input, D = | 438 // find all of the interesting cases (S = index * scale, B = base input, D = |
| 428 // displacement input): | 439 // displacement input): |
| 429 // (S + (B + D)) | 440 // (S + (B + D)) |
| 430 // (S + (B + B)) | 441 // (S + (B + B)) |
| 431 // (S + D) | 442 // (S + D) |
| 432 // (S + B) | 443 // (S + B) |
| 433 // ((S + D) + B) | 444 // ((S + D) + B) |
| 434 // ((S + B) + D) | 445 // ((S + B) + D) |
| 435 // ((B + D) + B) | 446 // ((B + D) + B) |
| 436 // ((B + B) + D) | 447 // ((B + B) + D) |
| 437 // (B + D) | 448 // (B + D) |
| 438 // (B + B) | 449 // (B + B) |
| 439 if (node->InputCount() < 2) return; | 450 if (node->InputCount() < 2) return; |
| 440 AddMatcher m(node, allow_input_swap); | 451 AddMatcher m(node, allow_input_swap); |
| 441 Node* left = m.left().node(); | 452 Node* left = m.left().node(); |
| 442 Node* right = m.right().node(); | 453 Node* right = m.right().node(); |
| 443 Node* displacement = nullptr; | 454 Node* displacement = nullptr; |
| 444 Node* base = nullptr; | 455 Node* base = nullptr; |
| 445 Node* index = nullptr; | 456 Node* index = nullptr; |
| 446 Node* scale_expression = nullptr; | 457 Node* scale_expression = nullptr; |
| 447 bool power_of_two_plus_one = false; | 458 bool power_of_two_plus_one = false; |
| 459 DisplacementMode displacement_mode = kPositiveDisplacement; |
| 448 int scale = 0; | 460 int scale = 0; |
| 449 if (m.HasIndexInput() && left->OwnedBy(node)) { | 461 if (m.HasIndexInput() && left->OwnedBy(node)) { |
| 450 index = m.IndexInput(); | 462 index = m.IndexInput(); |
| 451 scale = m.scale(); | 463 scale = m.scale(); |
| 452 scale_expression = left; | 464 scale_expression = left; |
| 453 power_of_two_plus_one = m.power_of_two_plus_one(); | 465 power_of_two_plus_one = m.power_of_two_plus_one(); |
| 454 if (right->opcode() == AddMatcher::kOpcode && right->OwnedBy(node)) { | 466 bool match_found = false; |
| 467 if (right->opcode() == AddMatcher::kSubOpcode && right->OwnedBy(node)) { |
| 455 AddMatcher right_matcher(right); | 468 AddMatcher right_matcher(right); |
| 456 if (right_matcher.right().HasValue()) { | 469 if (right_matcher.right().HasValue()) { |
| 457 // (S + (B + D)) | 470 // (S + (B - D)) |
| 458 base = right_matcher.left().node(); | 471 base = right_matcher.left().node(); |
| 459 displacement = right_matcher.right().node(); | 472 displacement = right_matcher.right().node(); |
| 473 displacement_mode = kNegativeDisplacement; |
| 474 match_found = true; |
| 475 } |
| 476 } |
| 477 if (!match_found) { |
| 478 if (right->opcode() == AddMatcher::kAddOpcode && right->OwnedBy(node)) { |
| 479 AddMatcher right_matcher(right); |
| 480 if (right_matcher.right().HasValue()) { |
| 481 // (S + (B + D)) |
| 482 base = right_matcher.left().node(); |
| 483 displacement = right_matcher.right().node(); |
| 484 } else { |
| 485 // (S + (B + B)) |
| 486 base = right; |
| 487 } |
| 488 } else if (m.right().HasValue()) { |
| 489 // (S + D) |
| 490 displacement = right; |
| 460 } else { | 491 } else { |
| 461 // (S + (B + B)) | 492 // (S + B) |
| 462 base = right; | 493 base = right; |
| 463 } | 494 } |
| 464 } else if (m.right().HasValue()) { | |
| 465 // (S + D) | |
| 466 displacement = right; | |
| 467 } else { | |
| 468 // (S + B) | |
| 469 base = right; | |
| 470 } | 495 } |
| 471 } else { | 496 } else { |
| 472 if (left->opcode() == AddMatcher::kOpcode && left->OwnedBy(node)) { | 497 bool match_found = false; |
| 498 if (left->opcode() == AddMatcher::kSubOpcode && left->OwnedBy(node)) { |
| 473 AddMatcher left_matcher(left); | 499 AddMatcher left_matcher(left); |
| 474 Node* left_left = left_matcher.left().node(); | 500 Node* left_left = left_matcher.left().node(); |
| 475 Node* left_right = left_matcher.right().node(); | 501 Node* left_right = left_matcher.right().node(); |
| 476 if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) { | 502 if (left_matcher.right().HasValue()) { |
| 477 if (left_matcher.right().HasValue()) { | 503 if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) { |
| 478 // ((S + D) + B) | 504 // ((S - D) + B) |
| 479 index = left_matcher.IndexInput(); | 505 index = left_matcher.IndexInput(); |
| 480 scale = left_matcher.scale(); | 506 scale = left_matcher.scale(); |
| 481 scale_expression = left_left; | 507 scale_expression = left_left; |
| 482 power_of_two_plus_one = left_matcher.power_of_two_plus_one(); | 508 power_of_two_plus_one = left_matcher.power_of_two_plus_one(); |
| 483 displacement = left_right; | 509 displacement = left_right; |
| 510 displacement_mode = kNegativeDisplacement; |
| 484 base = right; | 511 base = right; |
| 485 } else if (m.right().HasValue()) { | 512 } else { |
| 486 // ((S + B) + D) | 513 // ((B - D) + B) |
| 487 index = left_matcher.IndexInput(); | 514 index = left_left; |
| 488 scale = left_matcher.scale(); | 515 displacement = left_right; |
| 489 scale_expression = left_left; | 516 displacement_mode = kNegativeDisplacement; |
| 490 power_of_two_plus_one = left_matcher.power_of_two_plus_one(); | 517 base = right; |
| 491 base = left_right; | 518 } |
| 519 match_found = true; |
| 520 } |
| 521 } |
| 522 if (!match_found) { |
| 523 if (left->opcode() == AddMatcher::kAddOpcode && left->OwnedBy(node)) { |
| 524 AddMatcher left_matcher(left); |
| 525 Node* left_left = left_matcher.left().node(); |
| 526 Node* left_right = left_matcher.right().node(); |
| 527 if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) { |
| 528 if (left_matcher.right().HasValue()) { |
| 529 // ((S + D) + B) |
| 530 index = left_matcher.IndexInput(); |
| 531 scale = left_matcher.scale(); |
| 532 scale_expression = left_left; |
| 533 power_of_two_plus_one = left_matcher.power_of_two_plus_one(); |
| 534 displacement = left_right; |
| 535 base = right; |
| 536 } else if (m.right().HasValue()) { |
| 537 // ((S + B) + D) |
| 538 index = left_matcher.IndexInput(); |
| 539 scale = left_matcher.scale(); |
| 540 scale_expression = left_left; |
| 541 power_of_two_plus_one = left_matcher.power_of_two_plus_one(); |
| 542 base = left_right; |
| 543 displacement = right; |
| 544 } else { |
| 545 // (B + B) |
| 546 index = left; |
| 547 base = right; |
| 548 } |
| 549 } else { |
| 550 if (left_matcher.right().HasValue()) { |
| 551 // ((B + D) + B) |
| 552 index = left_left; |
| 553 displacement = left_right; |
| 554 base = right; |
| 555 } else if (m.right().HasValue()) { |
| 556 // ((B + B) + D) |
| 557 index = left_left; |
| 558 base = left_right; |
| 559 displacement = right; |
| 560 } else { |
| 561 // (B + B) |
| 562 index = left; |
| 563 base = right; |
| 564 } |
| 565 } |
| 566 } else { |
| 567 if (m.right().HasValue()) { |
| 568 // (B + D) |
| 569 base = left; |
| 492 displacement = right; | 570 displacement = right; |
| 493 } else { | 571 } else { |
| 494 // (B + B) | 572 // (B + B) |
| 495 index = left; | 573 base = left; |
| 496 base = right; | 574 index = right; |
| 497 } | 575 } |
| 498 } else { | |
| 499 if (left_matcher.right().HasValue()) { | |
| 500 // ((B + D) + B) | |
| 501 index = left_left; | |
| 502 displacement = left_right; | |
| 503 base = right; | |
| 504 } else if (m.right().HasValue()) { | |
| 505 // ((B + B) + D) | |
| 506 index = left_left; | |
| 507 base = left_right; | |
| 508 displacement = right; | |
| 509 } else { | |
| 510 // (B + B) | |
| 511 index = left; | |
| 512 base = right; | |
| 513 } | |
| 514 } | |
| 515 } else { | |
| 516 if (m.right().HasValue()) { | |
| 517 // (B + D) | |
| 518 base = left; | |
| 519 displacement = right; | |
| 520 } else { | |
| 521 // (B + B) | |
| 522 base = left; | |
| 523 index = right; | |
| 524 } | 576 } |
| 525 } | 577 } |
| 526 } | 578 } |
| 527 int64_t value = 0; | 579 int64_t value = 0; |
| 528 if (displacement != nullptr) { | 580 if (displacement != nullptr) { |
| 529 switch (displacement->opcode()) { | 581 switch (displacement->opcode()) { |
| 530 case IrOpcode::kInt32Constant: { | 582 case IrOpcode::kInt32Constant: { |
| 531 value = OpParameter<int32_t>(displacement); | 583 value = OpParameter<int32_t>(displacement); |
| 532 break; | 584 break; |
| 533 } | 585 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 550 // can't be folded into the match and the entire index * scale | 602 // can't be folded into the match and the entire index * scale |
| 551 // calculation must be computed separately. | 603 // calculation must be computed separately. |
| 552 index = scale_expression; | 604 index = scale_expression; |
| 553 scale = 0; | 605 scale = 0; |
| 554 } else { | 606 } else { |
| 555 base = index; | 607 base = index; |
| 556 } | 608 } |
| 557 } | 609 } |
| 558 base_ = base; | 610 base_ = base; |
| 559 displacement_ = displacement; | 611 displacement_ = displacement; |
| 612 displacement_mode_ = displacement_mode; |
| 560 index_ = index; | 613 index_ = index; |
| 561 scale_ = scale; | 614 scale_ = scale; |
| 562 matches_ = true; | 615 matches_ = true; |
| 563 } | 616 } |
| 564 }; | 617 }; |
| 565 | 618 |
| 566 typedef BaseWithIndexAndDisplacementMatcher<Int32AddMatcher> | 619 typedef BaseWithIndexAndDisplacementMatcher<Int32AddMatcher> |
| 567 BaseWithIndexAndDisplacement32Matcher; | 620 BaseWithIndexAndDisplacement32Matcher; |
| 568 typedef BaseWithIndexAndDisplacementMatcher<Int64AddMatcher> | 621 typedef BaseWithIndexAndDisplacementMatcher<Int64AddMatcher> |
| 569 BaseWithIndexAndDisplacement64Matcher; | 622 BaseWithIndexAndDisplacement64Matcher; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 Node* branch_; | 667 Node* branch_; |
| 615 Node* if_true_; | 668 Node* if_true_; |
| 616 Node* if_false_; | 669 Node* if_false_; |
| 617 }; | 670 }; |
| 618 | 671 |
| 619 } // namespace compiler | 672 } // namespace compiler |
| 620 } // namespace internal | 673 } // namespace internal |
| 621 } // namespace v8 | 674 } // namespace v8 |
| 622 | 675 |
| 623 #endif // V8_COMPILER_NODE_MATCHERS_H_ | 676 #endif // V8_COMPILER_NODE_MATCHERS_H_ |
| OLD | NEW |