LCOV - code coverage report
Current view: top level - include/llvm/CodeGen - MachineInstrBundleIterator.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 50 78 64.1 %
Date: 2018-10-20 13:21:21 Functions: 5 17 29.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/CodeGen/MachineInstrBundleIterator.h ----------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // Defines an iterator class that bundles MachineInstr.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
      15             : #define LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H
      16             : 
      17             : #include "llvm/ADT/ilist.h"
      18             : #include "llvm/ADT/simple_ilist.h"
      19             : #include <cassert>
      20             : #include <iterator>
      21             : #include <type_traits>
      22             : 
      23             : namespace llvm {
      24             : 
      25             : template <class T, bool IsReverse> struct MachineInstrBundleIteratorTraits;
      26             : template <class T> struct MachineInstrBundleIteratorTraits<T, false> {
      27             :   using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
      28             :   using instr_iterator = typename list_type::iterator;
      29             :   using nonconst_instr_iterator = typename list_type::iterator;
      30             :   using const_instr_iterator = typename list_type::const_iterator;
      31             : };
      32             : template <class T> struct MachineInstrBundleIteratorTraits<T, true> {
      33             :   using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
      34             :   using instr_iterator = typename list_type::reverse_iterator;
      35             :   using nonconst_instr_iterator = typename list_type::reverse_iterator;
      36             :   using const_instr_iterator = typename list_type::const_reverse_iterator;
      37             : };
      38             : template <class T> struct MachineInstrBundleIteratorTraits<const T, false> {
      39             :   using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
      40             :   using instr_iterator = typename list_type::const_iterator;
      41             :   using nonconst_instr_iterator = typename list_type::iterator;
      42             :   using const_instr_iterator = typename list_type::const_iterator;
      43             : };
      44             : template <class T> struct MachineInstrBundleIteratorTraits<const T, true> {
      45             :   using list_type = simple_ilist<T, ilist_sentinel_tracking<true>>;
      46             :   using instr_iterator = typename list_type::const_reverse_iterator;
      47             :   using nonconst_instr_iterator = typename list_type::reverse_iterator;
      48             :   using const_instr_iterator = typename list_type::const_reverse_iterator;
      49             : };
      50             : 
      51             : template <bool IsReverse> struct MachineInstrBundleIteratorHelper;
      52             : template <> struct MachineInstrBundleIteratorHelper<false> {
      53             :   /// Get the beginning of the current bundle.
      54             :   template <class Iterator> static Iterator getBundleBegin(Iterator I) {
      55             :     if (!I.isEnd())
      56   125472623 :       while (I->isBundledWithPred())
      57             :         --I;
      58             :     return I;
      59             :   }
      60             : 
      61             :   /// Get the final node of the current bundle.
      62             :   template <class Iterator> static Iterator getBundleFinal(Iterator I) {
      63             :     if (!I.isEnd())
      64   481609229 :       while (I->isBundledWithSucc())
      65             :         ++I;
      66             :     return I;
      67             :   }
      68             : 
      69             :   /// Increment forward ilist iterator.
      70             :   template <class Iterator> static void increment(Iterator &I) {
      71    34679435 :     I = std::next(getBundleFinal(I));
      72             :   }
      73             : 
      74             :   /// Decrement forward ilist iterator.
      75   106858210 :   template <class Iterator> static void decrement(Iterator &I) {
      76   106858210 :     I = getBundleBegin(std::prev(I));
      77   106858210 :   }
      78     7401380 : };
      79     7401380 : 
      80     7401380 : template <> struct MachineInstrBundleIteratorHelper<true> {
      81    60446251 :   /// Get the beginning of the current bundle.
      82    81085986 :   template <class Iterator> static Iterator getBundleBegin(Iterator I) {
      83    81085986 :     return MachineInstrBundleIteratorHelper<false>::getBundleBegin(
      84             :                I.getReverse())
      85    20639735 :         .getReverse();
      86             :   }
      87       83413 : 
      88      407763 :   /// Get the final node of the current bundle.
      89      324350 :   template <class Iterator> static Iterator getBundleFinal(Iterator I) {
      90       83413 :     return MachineInstrBundleIteratorHelper<false>::getBundleFinal(
      91      324350 :                I.getReverse())
      92       71824 :         .getReverse();
      93       71824 :   }
      94             : 
      95       71824 :   /// Increment reverse ilist iterator.
      96             :   template <class Iterator> static void increment(Iterator &I) {
      97    14561017 :     I = getBundleBegin(std::next(I));
      98             :   }
      99             : 
     100             :   /// Decrement reverse ilist iterator.
     101         354 :   template <class Iterator> static void decrement(Iterator &I) {
     102         354 :     I = std::prev(getBundleFinal(I));
     103      125401 :   }
     104             : };
     105             : 
     106             : /// MachineBasicBlock iterator that automatically skips over MIs that are
     107      133994 : /// inside bundles (i.e. walk top level MIs only).
     108             : template <typename Ty, bool IsReverse = false>
     109             : class MachineInstrBundleIterator : MachineInstrBundleIteratorHelper<IsReverse> {
     110             :   using Traits = MachineInstrBundleIteratorTraits<Ty, IsReverse>;
     111             :   using instr_iterator = typename Traits::instr_iterator;
     112             : 
     113             :   instr_iterator MII;
     114             : 
     115             : public:
     116             :   using value_type = typename instr_iterator::value_type;
     117             :   using difference_type = typename instr_iterator::difference_type;
     118             :   using pointer = typename instr_iterator::pointer;
     119             :   using reference = typename instr_iterator::reference;
     120             :   using const_pointer = typename instr_iterator::const_pointer;
     121             :   using const_reference = typename instr_iterator::const_reference;
     122             :   using iterator_category = std::bidirectional_iterator_tag;
     123             : 
     124             : private:
     125             :   using nonconst_instr_iterator = typename Traits::nonconst_instr_iterator;
     126             :   using const_instr_iterator = typename Traits::const_instr_iterator;
     127             :   using nonconst_iterator =
     128             :       MachineInstrBundleIterator<typename nonconst_instr_iterator::value_type,
     129             :                                  IsReverse>;
     130             :   using reverse_iterator = MachineInstrBundleIterator<Ty, !IsReverse>;
     131             : 
     132             : public:
     133      114225 :   MachineInstrBundleIterator(instr_iterator MI) : MII(MI) {
     134             :     assert((!MI.getNodePtr() || MI.isEnd() || !MI->isBundledWithPred()) &&
     135             :            "It's not legal to initialize MachineInstrBundleIterator with a "
     136             :            "bundled MI");
     137             :   }
     138             : 
     139        1631 :   MachineInstrBundleIterator(reference MI) : MII(MI) {
     140             :     assert(!MI.isBundledWithPred() && "It's not legal to initialize "
     141             :                                       "MachineInstrBundleIterator with a "
     142             :                                       "bundled MI");
     143             :   }
     144             : 
     145             :   MachineInstrBundleIterator(pointer MI) : MII(MI) {
     146             :     // FIXME: This conversion should be explicit.
     147             :     assert((!MI || !MI->isBundledWithPred()) && "It's not legal to initialize "
     148             :                                                 "MachineInstrBundleIterator "
     149             :                                                 "with a bundled MI");
     150             :   }
     151             : 
     152             :   // Template allows conversion from const to nonconst.
     153             :   template <class OtherTy>
     154           0 :   MachineInstrBundleIterator(
     155             :       const MachineInstrBundleIterator<OtherTy, IsReverse> &I,
     156             :       typename std::enable_if<std::is_convertible<OtherTy *, Ty *>::value,
     157             :                               void *>::type = nullptr)
     158           0 :       : MII(I.getInstrIterator()) {}
     159           0 : 
     160             :   MachineInstrBundleIterator() : MII(nullptr) {}
     161             : 
     162             :   /// Explicit conversion between forward/reverse iterators.
     163           0 :   ///
     164           0 :   /// Translate between forward and reverse iterators without changing range
     165             :   /// boundaries.  The resulting iterator will dereference (and have a handle)
     166             :   /// to the previous node, which is somewhat unexpected; but converting the
     167             :   /// two endpoints in a range will give the same range in reverse.
     168           0 :   ///
     169             :   /// This matches std::reverse_iterator conversions.
     170         451 :   explicit MachineInstrBundleIterator(
     171             :       const MachineInstrBundleIterator<Ty, !IsReverse> &I)
     172         451 :       : MachineInstrBundleIterator(++I.getReverse()) {}
     173             : 
     174             :   /// Get the bundle iterator for the given instruction's bundle.
     175             :   static MachineInstrBundleIterator getAtBundleBegin(instr_iterator MI) {
     176     1360168 :     return MachineInstrBundleIteratorHelper<IsReverse>::getBundleBegin(MI);
     177             :   }
     178             : 
     179   114061374 :   reference operator*() const { return *MII; }
     180           9 :   pointer operator->() const { return &operator*(); }
     181             : 
     182       29783 :   /// Check for null.
     183             :   bool isValid() const { return MII.getNodePtr(); }
     184             : 
     185   146874038 :   friend bool operator==(const MachineInstrBundleIterator &L,
     186       21243 :                          const MachineInstrBundleIterator &R) {
     187    84876814 :     return L.MII == R.MII;
     188             :   }
     189     1533402 :   friend bool operator==(const MachineInstrBundleIterator &L,
     190             :                          const const_instr_iterator &R) {
     191             :     return L.MII == R; // Avoid assertion about validity of R.
     192             :   }
     193   124003934 :   friend bool operator==(const const_instr_iterator &L,
     194             :                          const MachineInstrBundleIterator &R) {
     195             :     return L == R.MII; // Avoid assertion about validity of L.
     196             :   }
     197      503622 :   friend bool operator==(const MachineInstrBundleIterator &L,
     198             :                          const nonconst_instr_iterator &R) {
     199       30882 :     return L.MII == R; // Avoid assertion about validity of R.
     200             :   }
     201             :   friend bool operator==(const nonconst_instr_iterator &L,
     202             :                          const MachineInstrBundleIterator &R) {
     203    13246489 :     return L == R.MII; // Avoid assertion about validity of L.
     204             :   }
     205             :   friend bool operator==(const MachineInstrBundleIterator &L, const_pointer R) {
     206             :     return L == const_instr_iterator(R); // Avoid assertion about validity of R.
     207             :   }
     208             :   friend bool operator==(const_pointer L, const MachineInstrBundleIterator &R) {
     209             :     return const_instr_iterator(L) == R; // Avoid assertion about validity of L.
     210             :   }
     211             :   friend bool operator==(const MachineInstrBundleIterator &L,
     212             :                          const_reference R) {
     213             :     return L == &R; // Avoid assertion about validity of R.
     214             :   }
     215             :   friend bool operator==(const_reference L,
     216             :                          const MachineInstrBundleIterator &R) {
     217             :     return &L == R; // Avoid assertion about validity of L.
     218             :   }
     219             : 
     220             :   friend bool operator!=(const MachineInstrBundleIterator &L,
     221             :                          const MachineInstrBundleIterator &R) {
     222     1506784 :     return !(L == R);
     223             :   }
     224             :   friend bool operator!=(const MachineInstrBundleIterator &L,
     225             :                          const const_instr_iterator &R) {
     226             :     return !(L == R);
     227             :   }
     228             :   friend bool operator!=(const const_instr_iterator &L,
     229             :                          const MachineInstrBundleIterator &R) {
     230             :     return !(L == R);
     231             :   }
     232             :   friend bool operator!=(const MachineInstrBundleIterator &L,
     233             :                          const nonconst_instr_iterator &R) {
     234             :     return !(L == R);
     235             :   }
     236             :   friend bool operator!=(const nonconst_instr_iterator &L,
     237             :                          const MachineInstrBundleIterator &R) {
     238             :     return !(L == R);
     239             :   }
     240             :   friend bool operator!=(const MachineInstrBundleIterator &L, const_pointer R) {
     241             :     return !(L == R);
     242             :   }
     243             :   friend bool operator!=(const_pointer L, const MachineInstrBundleIterator &R) {
     244             :     return !(L == R);
     245             :   }
     246             :   friend bool operator!=(const MachineInstrBundleIterator &L,
     247             :                          const_reference R) {
     248             :     return !(L == R);
     249             :   }
     250             :   friend bool operator!=(const_reference L,
     251             :                          const MachineInstrBundleIterator &R) {
     252             :     return !(L == R);
     253             :   }
     254             : 
     255             :   // Increment and decrement operators...
     256             :   MachineInstrBundleIterator &operator--() {
     257    24804743 :     this->decrement(MII);
     258             :     return *this;
     259             :   }
     260             :   MachineInstrBundleIterator &operator++() {
     261           0 :     this->increment(MII);
     262             :     return *this;
     263    39471318 :   }
     264           0 :   MachineInstrBundleIterator operator--(int) {
     265           0 :     MachineInstrBundleIterator Temp = *this;
     266             :     --*this;
     267     1077163 :     return Temp;
     268             :   }
     269           0 :   MachineInstrBundleIterator operator++(int) {
     270      676409 :     MachineInstrBundleIterator Temp = *this;
     271           0 :     ++*this;
     272           0 :     return Temp;
     273           0 :   }
     274           0 : 
     275           0 :   instr_iterator getInstrIterator() const { return MII; }
     276           0 : 
     277           0 :   nonconst_iterator getNonConstIterator() const { return MII.getNonConst(); }
     278           0 : 
     279           0 :   /// Get a reverse iterator to the same node.
     280           0 :   ///
     281           0 :   /// Gives a reverse iterator that will dereference (and have a handle) to the
     282           0 :   /// same node.  Converting the endpoint iterators in a range will give a
     283     3951022 :   /// different range; for range operations, use the explicit conversions.
     284         451 :   reverse_iterator getReverse() const { return MII.getReverse(); }
     285           0 : };
     286             : 
     287           0 : } // end namespace llvm
     288             : 
     289           0 : #endif // LLVM_CODEGEN_MACHINEINSTRBUNDLEITERATOR_H

Generated by: LCOV version 1.13