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 ⤅ 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