|
15 | 15 | #ifndef LLVM_CODEGEN_MACHINEINSTR_H
|
16 | 16 | #define LLVM_CODEGEN_MACHINEINSTR_H
|
17 | 17 |
|
| 18 | +#include "llvm/ADT/ArrayRef.h" |
18 | 19 | #include "llvm/ADT/DenseMapInfo.h"
|
19 | 20 | #include "llvm/ADT/PointerSumType.h"
|
20 | 21 | #include "llvm/ADT/ilist.h"
|
@@ -43,7 +44,6 @@ class Instruction;
|
43 | 44 | class MDNode;
|
44 | 45 | class AAResults;
|
45 | 46 | class BatchAAResults;
|
46 |
| -template <typename T> class ArrayRef; |
47 | 47 | class DIExpression;
|
48 | 48 | class DILocalVariable;
|
49 | 49 | class LiveRegUnits;
|
@@ -340,6 +340,13 @@ class MachineInstr
|
340 | 340 | return Op.isReg() && Op.isUse();
|
341 | 341 | }
|
342 | 342 |
|
| 343 | + MutableArrayRef<MachineOperand> operands_impl() { |
| 344 | + return {Operands, NumOperands}; |
| 345 | + } |
| 346 | + ArrayRef<MachineOperand> operands_impl() const { |
| 347 | + return {Operands, NumOperands}; |
| 348 | + } |
| 349 | + |
343 | 350 | public:
|
344 | 351 | MachineInstr(const MachineInstr &) = delete;
|
345 | 352 | MachineInstr &operator=(const MachineInstr &) = delete;
|
@@ -580,18 +587,12 @@ class MachineInstr
|
580 | 587 | unsigned getNumOperands() const { return NumOperands; }
|
581 | 588 |
|
582 | 589 | /// Returns the total number of operands which are debug locations.
|
583 |
| - unsigned getNumDebugOperands() const { |
584 |
| - return std::distance(debug_operands().begin(), debug_operands().end()); |
585 |
| - } |
| 590 | + unsigned getNumDebugOperands() const { return size(debug_operands()); } |
586 | 591 |
|
587 |
| - const MachineOperand& getOperand(unsigned i) const { |
588 |
| - assert(i < getNumOperands() && "getOperand() out of range!"); |
589 |
| - return Operands[i]; |
590 |
| - } |
591 |
| - MachineOperand& getOperand(unsigned i) { |
592 |
| - assert(i < getNumOperands() && "getOperand() out of range!"); |
593 |
| - return Operands[i]; |
| 592 | + const MachineOperand &getOperand(unsigned i) const { |
| 593 | + return operands_impl()[i]; |
594 | 594 | }
|
| 595 | + MachineOperand &getOperand(unsigned i) { return operands_impl()[i]; } |
595 | 596 |
|
596 | 597 | MachineOperand &getDebugOperand(unsigned Index) {
|
597 | 598 | assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!");
|
@@ -667,101 +668,100 @@ class MachineInstr
|
667 | 668 | unsigned getNumExplicitDefs() const;
|
668 | 669 |
|
669 | 670 | /// iterator/begin/end - Iterate over all operands of a machine instruction.
|
| 671 | + |
| 672 | + // The operands must always be in the following order: |
| 673 | + // - explicit reg defs, |
| 674 | + // - other explicit operands (reg uses, immediates, etc.), |
| 675 | + // - implicit reg defs |
| 676 | + // - implicit reg uses |
670 | 677 | using mop_iterator = MachineOperand *;
|
671 | 678 | using const_mop_iterator = const MachineOperand *;
|
672 | 679 |
|
| 680 | + using mop_range = iterator_range<mop_iterator>; |
| 681 | + using const_mop_range = iterator_range<const_mop_iterator>; |
| 682 | + |
673 | 683 | mop_iterator operands_begin() { return Operands; }
|
674 | 684 | mop_iterator operands_end() { return Operands + NumOperands; }
|
675 | 685 |
|
676 | 686 | const_mop_iterator operands_begin() const { return Operands; }
|
677 | 687 | const_mop_iterator operands_end() const { return Operands + NumOperands; }
|
678 | 688 |
|
679 |
| - iterator_range<mop_iterator> operands() { |
680 |
| - return make_range(operands_begin(), operands_end()); |
681 |
| - } |
682 |
| - iterator_range<const_mop_iterator> operands() const { |
683 |
| - return make_range(operands_begin(), operands_end()); |
684 |
| - } |
685 |
| - iterator_range<mop_iterator> explicit_operands() { |
686 |
| - return make_range(operands_begin(), |
687 |
| - operands_begin() + getNumExplicitOperands()); |
| 689 | + mop_range operands() { return operands_impl(); } |
| 690 | + const_mop_range operands() const { return operands_impl(); } |
| 691 | + |
| 692 | + mop_range explicit_operands() { |
| 693 | + return operands_impl().take_front(getNumExplicitOperands()); |
688 | 694 | }
|
689 |
| - iterator_range<const_mop_iterator> explicit_operands() const { |
690 |
| - return make_range(operands_begin(), |
691 |
| - operands_begin() + getNumExplicitOperands()); |
| 695 | + const_mop_range explicit_operands() const { |
| 696 | + return operands_impl().take_front(getNumExplicitOperands()); |
692 | 697 | }
|
693 |
| - iterator_range<mop_iterator> implicit_operands() { |
694 |
| - return make_range(explicit_operands().end(), operands_end()); |
| 698 | + mop_range implicit_operands() { |
| 699 | + return operands_impl().drop_front(getNumExplicitOperands()); |
695 | 700 | }
|
696 |
| - iterator_range<const_mop_iterator> implicit_operands() const { |
697 |
| - return make_range(explicit_operands().end(), operands_end()); |
| 701 | + const_mop_range implicit_operands() const { |
| 702 | + return operands_impl().drop_front(getNumExplicitOperands()); |
698 | 703 | }
|
699 |
| - /// Returns a range over all operands that are used to determine the variable |
| 704 | + |
| 705 | + /// Returns all operands that are used to determine the variable |
700 | 706 | /// location for this DBG_VALUE instruction.
|
701 |
| - iterator_range<mop_iterator> debug_operands() { |
702 |
| - assert((isDebugValueLike()) && "Must be a debug value instruction."); |
703 |
| - return isNonListDebugValue() |
704 |
| - ? make_range(operands_begin(), operands_begin() + 1) |
705 |
| - : make_range(operands_begin() + 2, operands_end()); |
| 707 | + mop_range debug_operands() { |
| 708 | + assert(isDebugValueLike() && "Must be a debug value instruction."); |
| 709 | + return isNonListDebugValue() ? operands_impl().take_front(1) |
| 710 | + : operands_impl().drop_front(2); |
706 | 711 | }
|
707 | 712 | /// \copydoc debug_operands()
|
708 |
| - iterator_range<const_mop_iterator> debug_operands() const { |
709 |
| - assert((isDebugValueLike()) && "Must be a debug value instruction."); |
710 |
| - return isNonListDebugValue() |
711 |
| - ? make_range(operands_begin(), operands_begin() + 1) |
712 |
| - : make_range(operands_begin() + 2, operands_end()); |
| 713 | + const_mop_range debug_operands() const { |
| 714 | + assert(isDebugValueLike() && "Must be a debug value instruction."); |
| 715 | + return isNonListDebugValue() ? operands_impl().take_front(1) |
| 716 | + : operands_impl().drop_front(2); |
713 | 717 | }
|
714 |
| - /// Returns a range over all explicit operands that are register definitions. |
| 718 | + /// Returns all explicit operands that are register definitions. |
715 | 719 | /// Implicit definition are not included!
|
716 |
| - iterator_range<mop_iterator> defs() { |
717 |
| - return make_range(operands_begin(), |
718 |
| - operands_begin() + getNumExplicitDefs()); |
719 |
| - } |
| 720 | + mop_range defs() { return operands_impl().take_front(getNumExplicitDefs()); } |
720 | 721 | /// \copydoc defs()
|
721 |
| - iterator_range<const_mop_iterator> defs() const { |
722 |
| - return make_range(operands_begin(), |
723 |
| - operands_begin() + getNumExplicitDefs()); |
| 722 | + const_mop_range defs() const { |
| 723 | + return operands_impl().take_front(getNumExplicitDefs()); |
724 | 724 | }
|
725 |
| - /// Returns a range that includes all operands which may be register uses. |
| 725 | + /// Returns all operands which may be register uses. |
726 | 726 | /// This may include unrelated operands which are not register uses.
|
727 |
| - iterator_range<mop_iterator> uses() { |
728 |
| - return make_range(operands_begin() + getNumExplicitDefs(), operands_end()); |
729 |
| - } |
| 727 | + mop_range uses() { return operands_impl().drop_front(getNumExplicitDefs()); } |
730 | 728 | /// \copydoc uses()
|
731 |
| - iterator_range<const_mop_iterator> uses() const { |
732 |
| - return make_range(operands_begin() + getNumExplicitDefs(), operands_end()); |
| 729 | + const_mop_range uses() const { |
| 730 | + return operands_impl().drop_front(getNumExplicitDefs()); |
733 | 731 | }
|
734 |
| - iterator_range<mop_iterator> explicit_uses() { |
735 |
| - return make_range(operands_begin() + getNumExplicitDefs(), |
736 |
| - operands_begin() + getNumExplicitOperands()); |
| 732 | + mop_range explicit_uses() { |
| 733 | + return operands_impl() |
| 734 | + .take_front(getNumExplicitOperands()) |
| 735 | + .drop_front(getNumExplicitDefs()); |
737 | 736 | }
|
738 |
| - iterator_range<const_mop_iterator> explicit_uses() const { |
739 |
| - return make_range(operands_begin() + getNumExplicitDefs(), |
740 |
| - operands_begin() + getNumExplicitOperands()); |
| 737 | + const_mop_range explicit_uses() const { |
| 738 | + return operands_impl() |
| 739 | + .take_front(getNumExplicitOperands()) |
| 740 | + .drop_front(getNumExplicitDefs()); |
741 | 741 | }
|
742 | 742 |
|
743 |
| - using filtered_mop_iterator = |
744 |
| - filter_iterator<mop_iterator, bool (*)(const MachineOperand &)>; |
745 |
| - using filtered_const_mop_iterator = |
746 |
| - filter_iterator<const_mop_iterator, bool (*)(const MachineOperand &)>; |
| 743 | + using filtered_mop_range = iterator_range< |
| 744 | + filter_iterator<mop_iterator, bool (*)(const MachineOperand &)>>; |
| 745 | + using filtered_const_mop_range = iterator_range< |
| 746 | + filter_iterator<const_mop_iterator, bool (*)(const MachineOperand &)>>; |
747 | 747 |
|
748 | 748 | /// Returns an iterator range over all operands that are (explicit or
|
749 | 749 | /// implicit) register defs.
|
750 |
| - iterator_range<filtered_mop_iterator> all_defs() { |
| 750 | + filtered_mop_range all_defs() { |
751 | 751 | return make_filter_range(operands(), opIsRegDef);
|
752 | 752 | }
|
753 | 753 | /// \copydoc all_defs()
|
754 |
| - iterator_range<filtered_const_mop_iterator> all_defs() const { |
| 754 | + filtered_const_mop_range all_defs() const { |
755 | 755 | return make_filter_range(operands(), opIsRegDef);
|
756 | 756 | }
|
757 | 757 |
|
758 | 758 | /// Returns an iterator range over all operands that are (explicit or
|
759 | 759 | /// implicit) register uses.
|
760 |
| - iterator_range<filtered_mop_iterator> all_uses() { |
| 760 | + filtered_mop_range all_uses() { |
761 | 761 | return make_filter_range(uses(), opIsRegUse);
|
762 | 762 | }
|
763 | 763 | /// \copydoc all_uses()
|
764 |
| - iterator_range<filtered_const_mop_iterator> all_uses() const { |
| 764 | + filtered_const_mop_range all_uses() const { |
765 | 765 | return make_filter_range(uses(), opIsRegUse);
|
766 | 766 | }
|
767 | 767 |
|
|
0 commit comments