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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 | 387 |
388 typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Sub, | 388 typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Sub, |
389 IrOpcode::kInt32Mul, IrOpcode::kWord32Shl> | 389 IrOpcode::kInt32Mul, IrOpcode::kWord32Shl> |
390 Int32AddMatcher; | 390 Int32AddMatcher; |
391 typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Sub, | 391 typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Sub, |
392 IrOpcode::kInt64Mul, IrOpcode::kWord64Shl> | 392 IrOpcode::kInt64Mul, IrOpcode::kWord64Shl> |
393 Int64AddMatcher; | 393 Int64AddMatcher; |
394 | 394 |
395 enum DisplacementMode { kPositiveDisplacement, kNegativeDisplacement }; | 395 enum DisplacementMode { kPositiveDisplacement, kNegativeDisplacement }; |
396 | 396 |
| 397 enum class AddressOption : uint8_t { |
| 398 kAllowNone = 0u, |
| 399 kAllowInputSwap = 1u << 0, |
| 400 kAllowScale = 1u << 1, |
| 401 kAllowAll = kAllowInputSwap | kAllowScale |
| 402 }; |
| 403 |
| 404 typedef base::Flags<AddressOption, uint8_t> AddressOptions; |
| 405 DEFINE_OPERATORS_FOR_FLAGS(AddressOptions); |
| 406 |
397 template <class AddMatcher> | 407 template <class AddMatcher> |
398 struct BaseWithIndexAndDisplacementMatcher { | 408 struct BaseWithIndexAndDisplacementMatcher { |
399 BaseWithIndexAndDisplacementMatcher(Node* node, bool allow_input_swap) | 409 BaseWithIndexAndDisplacementMatcher(Node* node, AddressOptions options) |
400 : matches_(false), | 410 : matches_(false), |
401 index_(nullptr), | 411 index_(nullptr), |
402 scale_(0), | 412 scale_(0), |
403 base_(nullptr), | 413 base_(nullptr), |
404 displacement_(nullptr), | 414 displacement_(nullptr), |
405 displacement_mode_(kPositiveDisplacement) { | 415 displacement_mode_(kPositiveDisplacement) { |
406 Initialize(node, allow_input_swap); | 416 Initialize(node, options); |
407 } | 417 } |
408 | 418 |
409 explicit BaseWithIndexAndDisplacementMatcher(Node* node) | 419 explicit BaseWithIndexAndDisplacementMatcher(Node* node) |
410 : matches_(false), | 420 : matches_(false), |
411 index_(nullptr), | 421 index_(nullptr), |
412 scale_(0), | 422 scale_(0), |
413 base_(nullptr), | 423 base_(nullptr), |
414 displacement_(nullptr), | 424 displacement_(nullptr), |
415 displacement_mode_(kPositiveDisplacement) { | 425 displacement_mode_(kPositiveDisplacement) { |
416 Initialize(node, node->op()->HasProperty(Operator::kCommutative)); | 426 Initialize(node, AddressOption::kAllowScale | |
| 427 (node->op()->HasProperty(Operator::kCommutative) |
| 428 ? AddressOption::kAllowInputSwap |
| 429 : AddressOption::kAllowNone)); |
417 } | 430 } |
418 | 431 |
419 bool matches() const { return matches_; } | 432 bool matches() const { return matches_; } |
420 Node* index() const { return index_; } | 433 Node* index() const { return index_; } |
421 int scale() const { return scale_; } | 434 int scale() const { return scale_; } |
422 Node* base() const { return base_; } | 435 Node* base() const { return base_; } |
423 Node* displacement() const { return displacement_; } | 436 Node* displacement() const { return displacement_; } |
424 DisplacementMode displacement_mode() const { return displacement_mode_; } | 437 DisplacementMode displacement_mode() const { return displacement_mode_; } |
425 | 438 |
426 private: | 439 private: |
427 bool matches_; | 440 bool matches_; |
428 Node* index_; | 441 Node* index_; |
429 int scale_; | 442 int scale_; |
430 Node* base_; | 443 Node* base_; |
431 Node* displacement_; | 444 Node* displacement_; |
432 DisplacementMode displacement_mode_; | 445 DisplacementMode displacement_mode_; |
433 | 446 |
434 void Initialize(Node* node, bool allow_input_swap) { | 447 void Initialize(Node* node, AddressOptions options) { |
435 // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of | 448 // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of |
436 // displacements and scale factors that are used as inputs, so instead of | 449 // displacements and scale factors that are used as inputs, so instead of |
437 // enumerating all possible patterns by brute force, checking for node | 450 // enumerating all possible patterns by brute force, checking for node |
438 // clusters using the following templates in the following order suffices to | 451 // clusters using the following templates in the following order suffices to |
439 // find all of the interesting cases (S = index * scale, B = base input, D = | 452 // find all of the interesting cases (S = index * scale, B = base input, D = |
440 // displacement input): | 453 // displacement input): |
441 // (S + (B + D)) | 454 // (S + (B + D)) |
442 // (S + (B + B)) | 455 // (S + (B + B)) |
443 // (S + D) | 456 // (S + D) |
444 // (S + B) | 457 // (S + B) |
445 // ((S + D) + B) | 458 // ((S + D) + B) |
446 // ((S + B) + D) | 459 // ((S + B) + D) |
447 // ((B + D) + B) | 460 // ((B + D) + B) |
448 // ((B + B) + D) | 461 // ((B + B) + D) |
449 // (B + D) | 462 // (B + D) |
450 // (B + B) | 463 // (B + B) |
451 if (node->InputCount() < 2) return; | 464 if (node->InputCount() < 2) return; |
452 AddMatcher m(node, allow_input_swap); | 465 AddMatcher m(node, options & AddressOption::kAllowInputSwap); |
453 Node* left = m.left().node(); | 466 Node* left = m.left().node(); |
454 Node* right = m.right().node(); | 467 Node* right = m.right().node(); |
455 Node* displacement = nullptr; | 468 Node* displacement = nullptr; |
456 Node* base = nullptr; | 469 Node* base = nullptr; |
457 Node* index = nullptr; | 470 Node* index = nullptr; |
458 Node* scale_expression = nullptr; | 471 Node* scale_expression = nullptr; |
459 bool power_of_two_plus_one = false; | 472 bool power_of_two_plus_one = false; |
460 DisplacementMode displacement_mode = kPositiveDisplacement; | 473 DisplacementMode displacement_mode = kPositiveDisplacement; |
461 int scale = 0; | 474 int scale = 0; |
462 if (m.HasIndexInput() && left->OwnedBy(node)) { | 475 if (m.HasIndexInput() && left->OwnedBy(node)) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 // If the scale requires explicitly using the index as the base, but a | 614 // If the scale requires explicitly using the index as the base, but a |
602 // base is already part of the match, then the (1 << N + 1) scale factor | 615 // base is already part of the match, then the (1 << N + 1) scale factor |
603 // can't be folded into the match and the entire index * scale | 616 // can't be folded into the match and the entire index * scale |
604 // calculation must be computed separately. | 617 // calculation must be computed separately. |
605 index = scale_expression; | 618 index = scale_expression; |
606 scale = 0; | 619 scale = 0; |
607 } else { | 620 } else { |
608 base = index; | 621 base = index; |
609 } | 622 } |
610 } | 623 } |
| 624 if (!(options & AddressOption::kAllowScale) && scale != 0) { |
| 625 index = scale_expression; |
| 626 scale = 0; |
| 627 } |
611 base_ = base; | 628 base_ = base; |
612 displacement_ = displacement; | 629 displacement_ = displacement; |
613 displacement_mode_ = displacement_mode; | 630 displacement_mode_ = displacement_mode; |
614 index_ = index; | 631 index_ = index; |
615 scale_ = scale; | 632 scale_ = scale; |
616 matches_ = true; | 633 matches_ = true; |
617 } | 634 } |
618 }; | 635 }; |
619 | 636 |
620 typedef BaseWithIndexAndDisplacementMatcher<Int32AddMatcher> | 637 typedef BaseWithIndexAndDisplacementMatcher<Int32AddMatcher> |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 Node* branch_; | 685 Node* branch_; |
669 Node* if_true_; | 686 Node* if_true_; |
670 Node* if_false_; | 687 Node* if_false_; |
671 }; | 688 }; |
672 | 689 |
673 } // namespace compiler | 690 } // namespace compiler |
674 } // namespace internal | 691 } // namespace internal |
675 } // namespace v8 | 692 } // namespace v8 |
676 | 693 |
677 #endif // V8_COMPILER_NODE_MATCHERS_H_ | 694 #endif // V8_COMPILER_NODE_MATCHERS_H_ |
OLD | NEW |