xref: /llvm-project/llvm/lib/Target/Hexagon/HexagonBlockRanges.h (revision 06fcc4f06f1401d6fa47759f282efdc7f494999f)
13b87336aSEugene Zelenko //===- HexagonBlockRanges.h -------------------------------------*- C++ -*-===//
27793ddb0SKrzysztof Parzyszek //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67793ddb0SKrzysztof Parzyszek //
77793ddb0SKrzysztof Parzyszek //===----------------------------------------------------------------------===//
83b87336aSEugene Zelenko 
93b87336aSEugene Zelenko #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
103b87336aSEugene Zelenko #define LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
117793ddb0SKrzysztof Parzyszek 
127793ddb0SKrzysztof Parzyszek #include "llvm/ADT/BitVector.h"
13*06fcc4f0SGaurav Jain #include "llvm/CodeGen/Register.h"
1482085927SEugene Zelenko #include <cassert>
157793ddb0SKrzysztof Parzyszek #include <map>
167793ddb0SKrzysztof Parzyszek #include <set>
1782085927SEugene Zelenko #include <utility>
186bda14b3SChandler Carruth #include <vector>
197793ddb0SKrzysztof Parzyszek 
207793ddb0SKrzysztof Parzyszek namespace llvm {
2182085927SEugene Zelenko 
227793ddb0SKrzysztof Parzyszek class HexagonSubtarget;
237793ddb0SKrzysztof Parzyszek class MachineBasicBlock;
247793ddb0SKrzysztof Parzyszek class MachineFunction;
257793ddb0SKrzysztof Parzyszek class MachineInstr;
263b87336aSEugene Zelenko class MachineRegisterInfo;
277793ddb0SKrzysztof Parzyszek class raw_ostream;
287793ddb0SKrzysztof Parzyszek class TargetInstrInfo;
297793ddb0SKrzysztof Parzyszek class TargetRegisterInfo;
307793ddb0SKrzysztof Parzyszek 
317793ddb0SKrzysztof Parzyszek struct HexagonBlockRanges {
327793ddb0SKrzysztof Parzyszek   HexagonBlockRanges(MachineFunction &MF);
337793ddb0SKrzysztof Parzyszek 
34*06fcc4f0SGaurav Jain   // FIXME: Consolidate duplicate definitions of RegisterRef
357793ddb0SKrzysztof Parzyszek   struct RegisterRef {
36*06fcc4f0SGaurav Jain     llvm::Register Reg;
37*06fcc4f0SGaurav Jain     unsigned Sub;
383b87336aSEugene Zelenko 
397793ddb0SKrzysztof Parzyszek     bool operator<(RegisterRef R) const {
407793ddb0SKrzysztof Parzyszek       return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub);
417793ddb0SKrzysztof Parzyszek     }
427793ddb0SKrzysztof Parzyszek   };
433b87336aSEugene Zelenko   using RegisterSet = std::set<RegisterRef>;
447793ddb0SKrzysztof Parzyszek 
457793ddb0SKrzysztof Parzyszek   // This is to represent an "index", which is an abstraction of a position
467793ddb0SKrzysztof Parzyszek   // of an instruction within a basic block.
477793ddb0SKrzysztof Parzyszek   class IndexType {
487793ddb0SKrzysztof Parzyszek   public:
497793ddb0SKrzysztof Parzyszek     enum : unsigned {
507793ddb0SKrzysztof Parzyszek       None  = 0,
517793ddb0SKrzysztof Parzyszek       Entry = 1,
527793ddb0SKrzysztof Parzyszek       Exit  = 2,
537793ddb0SKrzysztof Parzyszek       First = 11  // 10th + 1st
547793ddb0SKrzysztof Parzyszek     };
557793ddb0SKrzysztof Parzyszek 
IndexTypeHexagonBlockRanges563b87336aSEugene Zelenko     IndexType() {}
IndexTypeHexagonBlockRanges577793ddb0SKrzysztof Parzyszek     IndexType(unsigned Idx) : Index(Idx) {}
5882085927SEugene Zelenko 
isInstrHexagonBlockRanges5982085927SEugene Zelenko     static bool isInstr(IndexType X) { return X.Index >= First; }
6082085927SEugene Zelenko 
617793ddb0SKrzysztof Parzyszek     operator unsigned() const;
627793ddb0SKrzysztof Parzyszek     bool operator== (unsigned x) const;
637793ddb0SKrzysztof Parzyszek     bool operator== (IndexType Idx) const;
647793ddb0SKrzysztof Parzyszek     bool operator!= (unsigned x) const;
657793ddb0SKrzysztof Parzyszek     bool operator!= (IndexType Idx) const;
667793ddb0SKrzysztof Parzyszek     IndexType operator++ ();
677793ddb0SKrzysztof Parzyszek     bool operator< (unsigned Idx) const;
687793ddb0SKrzysztof Parzyszek     bool operator< (IndexType Idx) const;
697793ddb0SKrzysztof Parzyszek     bool operator<= (IndexType Idx) const;
707793ddb0SKrzysztof Parzyszek 
717793ddb0SKrzysztof Parzyszek   private:
727793ddb0SKrzysztof Parzyszek     bool operator>  (IndexType Idx) const;
737793ddb0SKrzysztof Parzyszek     bool operator>= (IndexType Idx) const;
747793ddb0SKrzysztof Parzyszek 
753b87336aSEugene Zelenko     unsigned Index = None;
767793ddb0SKrzysztof Parzyszek   };
777793ddb0SKrzysztof Parzyszek 
787793ddb0SKrzysztof Parzyszek   // A range of indices, essentially a representation of a live range.
797793ddb0SKrzysztof Parzyszek   // This is also used to represent "dead ranges", i.e. ranges where a
807793ddb0SKrzysztof Parzyszek   // register is dead.
817793ddb0SKrzysztof Parzyszek   class IndexRange : public std::pair<IndexType,IndexType> {
827793ddb0SKrzysztof Parzyszek   public:
8382085927SEugene Zelenko     IndexRange() = default;
847793ddb0SKrzysztof Parzyszek     IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false)
857793ddb0SKrzysztof Parzyszek       : std::pair<IndexType,IndexType>(Start, End), Fixed(F), TiedEnd(T) {}
8682085927SEugene Zelenko 
startHexagonBlockRanges877793ddb0SKrzysztof Parzyszek     IndexType start() const { return first; }
endHexagonBlockRanges887793ddb0SKrzysztof Parzyszek     IndexType end() const   { return second; }
897793ddb0SKrzysztof Parzyszek 
907793ddb0SKrzysztof Parzyszek     bool operator< (const IndexRange &A) const {
917793ddb0SKrzysztof Parzyszek       return start() < A.start();
927793ddb0SKrzysztof Parzyszek     }
9382085927SEugene Zelenko 
947793ddb0SKrzysztof Parzyszek     bool overlaps(const IndexRange &A) const;
957793ddb0SKrzysztof Parzyszek     bool contains(const IndexRange &A) const;
967793ddb0SKrzysztof Parzyszek     void merge(const IndexRange &A);
977793ddb0SKrzysztof Parzyszek 
9882085927SEugene Zelenko     bool Fixed = false;   // Can be renamed?  "Fixed" means "no".
9982085927SEugene Zelenko     bool TiedEnd = false; // The end is not a use, but a dead def tied to a use.
1007793ddb0SKrzysztof Parzyszek 
1017793ddb0SKrzysztof Parzyszek   private:
setStartHexagonBlockRanges1027793ddb0SKrzysztof Parzyszek     void setStart(const IndexType &S) { first = S; }
setEndHexagonBlockRanges1037793ddb0SKrzysztof Parzyszek     void setEnd(const IndexType &E)   { second = E; }
1047793ddb0SKrzysztof Parzyszek   };
1057793ddb0SKrzysztof Parzyszek 
1067793ddb0SKrzysztof Parzyszek   // A list of index ranges. This represents liveness of a register
1077793ddb0SKrzysztof Parzyszek   // in a basic block.
1087793ddb0SKrzysztof Parzyszek   class RangeList : public std::vector<IndexRange> {
1097793ddb0SKrzysztof Parzyszek   public:
addHexagonBlockRanges1107793ddb0SKrzysztof Parzyszek     void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd) {
1117793ddb0SKrzysztof Parzyszek       push_back(IndexRange(Start, End, Fixed, TiedEnd));
1127793ddb0SKrzysztof Parzyszek     }
addHexagonBlockRanges1137793ddb0SKrzysztof Parzyszek     void add(const IndexRange &Range) {
1147793ddb0SKrzysztof Parzyszek       push_back(Range);
1157793ddb0SKrzysztof Parzyszek     }
11682085927SEugene Zelenko 
1177793ddb0SKrzysztof Parzyszek     void include(const RangeList &RL);
1187793ddb0SKrzysztof Parzyszek     void unionize(bool MergeAdjacent = false);
1197793ddb0SKrzysztof Parzyszek     void subtract(const IndexRange &Range);
1207793ddb0SKrzysztof Parzyszek 
1217793ddb0SKrzysztof Parzyszek   private:
1227793ddb0SKrzysztof Parzyszek     void addsub(const IndexRange &A, const IndexRange &B);
1237793ddb0SKrzysztof Parzyszek   };
1247793ddb0SKrzysztof Parzyszek 
1257793ddb0SKrzysztof Parzyszek   class InstrIndexMap {
1267793ddb0SKrzysztof Parzyszek   public:
1277793ddb0SKrzysztof Parzyszek     InstrIndexMap(MachineBasicBlock &B);
12882085927SEugene Zelenko 
1297793ddb0SKrzysztof Parzyszek     MachineInstr *getInstr(IndexType Idx) const;
1307793ddb0SKrzysztof Parzyszek     IndexType getIndex(MachineInstr *MI) const;
getBlockHexagonBlockRanges1317793ddb0SKrzysztof Parzyszek     MachineBasicBlock &getBlock() const { return Block; }
1327793ddb0SKrzysztof Parzyszek     IndexType getPrevIndex(IndexType Idx) const;
1337793ddb0SKrzysztof Parzyszek     IndexType getNextIndex(IndexType Idx) const;
1347793ddb0SKrzysztof Parzyszek     void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI);
1357793ddb0SKrzysztof Parzyszek 
1367793ddb0SKrzysztof Parzyszek     friend raw_ostream &operator<< (raw_ostream &OS, const InstrIndexMap &Map);
13782085927SEugene Zelenko 
1387793ddb0SKrzysztof Parzyszek     IndexType First, Last;
1397793ddb0SKrzysztof Parzyszek 
1407793ddb0SKrzysztof Parzyszek   private:
1417793ddb0SKrzysztof Parzyszek     MachineBasicBlock &Block;
1427793ddb0SKrzysztof Parzyszek     std::map<IndexType,MachineInstr*> Map;
1437793ddb0SKrzysztof Parzyszek   };
1447793ddb0SKrzysztof Parzyszek 
1453b87336aSEugene Zelenko   using RegToRangeMap = std::map<RegisterRef, RangeList>;
1463b87336aSEugene Zelenko 
1477793ddb0SKrzysztof Parzyszek   RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap);
1487793ddb0SKrzysztof Parzyszek   RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap);
1497793ddb0SKrzysztof Parzyszek   static RegisterSet expandToSubRegs(RegisterRef R,
1507793ddb0SKrzysztof Parzyszek       const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);
1517793ddb0SKrzysztof Parzyszek 
1527793ddb0SKrzysztof Parzyszek   struct PrintRangeMap {
PrintRangeMapHexagonBlockRanges::PrintRangeMap1537793ddb0SKrzysztof Parzyszek     PrintRangeMap(const RegToRangeMap &M, const TargetRegisterInfo &I)
1547793ddb0SKrzysztof Parzyszek         : Map(M), TRI(I) {}
1557793ddb0SKrzysztof Parzyszek 
1567793ddb0SKrzysztof Parzyszek     friend raw_ostream &operator<< (raw_ostream &OS, const PrintRangeMap &P);
15782085927SEugene Zelenko 
1587793ddb0SKrzysztof Parzyszek   private:
1597793ddb0SKrzysztof Parzyszek     const RegToRangeMap &Map;
1607793ddb0SKrzysztof Parzyszek     const TargetRegisterInfo &TRI;
1617793ddb0SKrzysztof Parzyszek   };
1627793ddb0SKrzysztof Parzyszek 
1637793ddb0SKrzysztof Parzyszek private:
1645bb417beSKrzysztof Parzyszek   RegisterSet getLiveIns(const MachineBasicBlock &B,
1655bb417beSKrzysztof Parzyszek       const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);
1667793ddb0SKrzysztof Parzyszek 
1677793ddb0SKrzysztof Parzyszek   void computeInitialLiveRanges(InstrIndexMap &IndexMap,
1687793ddb0SKrzysztof Parzyszek       RegToRangeMap &LiveMap);
1697793ddb0SKrzysztof Parzyszek 
1707793ddb0SKrzysztof Parzyszek   MachineFunction &MF;
1717793ddb0SKrzysztof Parzyszek   const HexagonSubtarget &HST;
1727793ddb0SKrzysztof Parzyszek   const TargetInstrInfo &TII;
1737793ddb0SKrzysztof Parzyszek   const TargetRegisterInfo &TRI;
1747793ddb0SKrzysztof Parzyszek   BitVector Reserved;
1757793ddb0SKrzysztof Parzyszek };
1767793ddb0SKrzysztof Parzyszek 
1777793ddb0SKrzysztof Parzyszek inline HexagonBlockRanges::IndexType::operator unsigned() const {
1787793ddb0SKrzysztof Parzyszek   assert(Index >= First);
1797793ddb0SKrzysztof Parzyszek   return Index;
1807793ddb0SKrzysztof Parzyszek }
1817793ddb0SKrzysztof Parzyszek 
1827793ddb0SKrzysztof Parzyszek inline bool HexagonBlockRanges::IndexType::operator== (unsigned x) const {
1837793ddb0SKrzysztof Parzyszek   return Index == x;
1847793ddb0SKrzysztof Parzyszek }
1857793ddb0SKrzysztof Parzyszek 
1867793ddb0SKrzysztof Parzyszek inline bool HexagonBlockRanges::IndexType::operator== (IndexType Idx) const {
1877793ddb0SKrzysztof Parzyszek   return Index == Idx.Index;
1887793ddb0SKrzysztof Parzyszek }
1897793ddb0SKrzysztof Parzyszek 
1907793ddb0SKrzysztof Parzyszek inline bool HexagonBlockRanges::IndexType::operator!= (unsigned x) const {
1917793ddb0SKrzysztof Parzyszek   return Index != x;
1927793ddb0SKrzysztof Parzyszek }
1937793ddb0SKrzysztof Parzyszek 
1947793ddb0SKrzysztof Parzyszek inline bool HexagonBlockRanges::IndexType::operator!= (IndexType Idx) const {
1957793ddb0SKrzysztof Parzyszek   return Index != Idx.Index;
1967793ddb0SKrzysztof Parzyszek }
1977793ddb0SKrzysztof Parzyszek 
1987793ddb0SKrzysztof Parzyszek inline
1997793ddb0SKrzysztof Parzyszek HexagonBlockRanges::IndexType HexagonBlockRanges::IndexType::operator++ () {
2007793ddb0SKrzysztof Parzyszek   assert(Index != None);
2017793ddb0SKrzysztof Parzyszek   assert(Index != Exit);
2027793ddb0SKrzysztof Parzyszek   if (Index == Entry)
2037793ddb0SKrzysztof Parzyszek     Index = First;
2047793ddb0SKrzysztof Parzyszek   else
2057793ddb0SKrzysztof Parzyszek     ++Index;
2067793ddb0SKrzysztof Parzyszek   return *this;
2077793ddb0SKrzysztof Parzyszek }
2087793ddb0SKrzysztof Parzyszek 
2097793ddb0SKrzysztof Parzyszek inline bool HexagonBlockRanges::IndexType::operator< (unsigned Idx) const {
2107793ddb0SKrzysztof Parzyszek   return operator< (IndexType(Idx));
2117793ddb0SKrzysztof Parzyszek }
2127793ddb0SKrzysztof Parzyszek 
2137793ddb0SKrzysztof Parzyszek inline bool HexagonBlockRanges::IndexType::operator< (IndexType Idx) const {
2147793ddb0SKrzysztof Parzyszek   // !(x < x).
2157793ddb0SKrzysztof Parzyszek   if (Index == Idx.Index)
2167793ddb0SKrzysztof Parzyszek     return false;
2177793ddb0SKrzysztof Parzyszek   // !(None < x) for all x.
2187793ddb0SKrzysztof Parzyszek   // !(x < None) for all x.
2197793ddb0SKrzysztof Parzyszek   if (Index == None || Idx.Index == None)
2207793ddb0SKrzysztof Parzyszek     return false;
2217793ddb0SKrzysztof Parzyszek   // !(Exit < x) for all x.
2227793ddb0SKrzysztof Parzyszek   // !(x < Entry) for all x.
2237793ddb0SKrzysztof Parzyszek   if (Index == Exit || Idx.Index == Entry)
2247793ddb0SKrzysztof Parzyszek     return false;
2257793ddb0SKrzysztof Parzyszek   // Entry < x for all x != Entry.
2267793ddb0SKrzysztof Parzyszek   // x < Exit for all x != Exit.
2277793ddb0SKrzysztof Parzyszek   if (Index == Entry || Idx.Index == Exit)
2287793ddb0SKrzysztof Parzyszek     return true;
2297793ddb0SKrzysztof Parzyszek 
2307793ddb0SKrzysztof Parzyszek   return Index < Idx.Index;
2317793ddb0SKrzysztof Parzyszek }
2327793ddb0SKrzysztof Parzyszek 
2337793ddb0SKrzysztof Parzyszek inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const {
2347793ddb0SKrzysztof Parzyszek   return operator==(Idx) || operator<(Idx);
2357793ddb0SKrzysztof Parzyszek }
2367793ddb0SKrzysztof Parzyszek 
2377793ddb0SKrzysztof Parzyszek raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx);
2387793ddb0SKrzysztof Parzyszek raw_ostream &operator<< (raw_ostream &OS,
2397793ddb0SKrzysztof Parzyszek       const HexagonBlockRanges::IndexRange &IR);
2407793ddb0SKrzysztof Parzyszek raw_ostream &operator<< (raw_ostream &OS,
2417793ddb0SKrzysztof Parzyszek       const HexagonBlockRanges::RangeList &RL);
2427793ddb0SKrzysztof Parzyszek raw_ostream &operator<< (raw_ostream &OS,
2437793ddb0SKrzysztof Parzyszek       const HexagonBlockRanges::InstrIndexMap &M);
2447793ddb0SKrzysztof Parzyszek raw_ostream &operator<< (raw_ostream &OS,
2457793ddb0SKrzysztof Parzyszek       const HexagonBlockRanges::PrintRangeMap &P);
2467793ddb0SKrzysztof Parzyszek 
24782085927SEugene Zelenko } // end namespace llvm
248922efd7aSBenjamin Kramer 
2493b87336aSEugene Zelenko #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
250