1*9880d681SAndroid Build Coastguard Worker //===--- HexagonBlockRanges.h ---------------------------------------------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker #ifndef HEXAGON_BLOCK_RANGES_H 10*9880d681SAndroid Build Coastguard Worker #define HEXAGON_BLOCK_RANGES_H 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h" 13*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h" 14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h" // For MCPhysReg. 15*9880d681SAndroid Build Coastguard Worker #include <map> 16*9880d681SAndroid Build Coastguard Worker #include <set> 17*9880d681SAndroid Build Coastguard Worker #include <vector> 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Worker namespace llvm { 20*9880d681SAndroid Build Coastguard Worker class Function; 21*9880d681SAndroid Build Coastguard Worker class HexagonSubtarget; 22*9880d681SAndroid Build Coastguard Worker class MachineBasicBlock; 23*9880d681SAndroid Build Coastguard Worker class MachineFunction; 24*9880d681SAndroid Build Coastguard Worker class MachineInstr; 25*9880d681SAndroid Build Coastguard Worker class MCInstrDesc; 26*9880d681SAndroid Build Coastguard Worker class raw_ostream; 27*9880d681SAndroid Build Coastguard Worker class TargetInstrInfo; 28*9880d681SAndroid Build Coastguard Worker class TargetRegisterClass; 29*9880d681SAndroid Build Coastguard Worker class TargetRegisterInfo; 30*9880d681SAndroid Build Coastguard Worker class Type; 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker struct HexagonBlockRanges { 33*9880d681SAndroid Build Coastguard Worker HexagonBlockRanges(MachineFunction &MF); 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker struct RegisterRef { 36*9880d681SAndroid Build Coastguard Worker unsigned Reg, Sub; 37*9880d681SAndroid Build Coastguard Worker bool operator<(RegisterRef R) const { 38*9880d681SAndroid Build Coastguard Worker return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub); 39*9880d681SAndroid Build Coastguard Worker } 40*9880d681SAndroid Build Coastguard Worker }; 41*9880d681SAndroid Build Coastguard Worker typedef std::set<RegisterRef> RegisterSet; 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker // This is to represent an "index", which is an abstraction of a position 44*9880d681SAndroid Build Coastguard Worker // of an instruction within a basic block. 45*9880d681SAndroid Build Coastguard Worker class IndexType { 46*9880d681SAndroid Build Coastguard Worker public: 47*9880d681SAndroid Build Coastguard Worker enum : unsigned { 48*9880d681SAndroid Build Coastguard Worker None = 0, 49*9880d681SAndroid Build Coastguard Worker Entry = 1, 50*9880d681SAndroid Build Coastguard Worker Exit = 2, 51*9880d681SAndroid Build Coastguard Worker First = 11 // 10th + 1st 52*9880d681SAndroid Build Coastguard Worker }; isInstrHexagonBlockRanges53*9880d681SAndroid Build Coastguard Worker static bool isInstr(IndexType X) { return X.Index >= First; } 54*9880d681SAndroid Build Coastguard Worker IndexTypeHexagonBlockRanges55*9880d681SAndroid Build Coastguard Worker IndexType() : Index(None) {} IndexTypeHexagonBlockRanges56*9880d681SAndroid Build Coastguard Worker IndexType(unsigned Idx) : Index(Idx) {} 57*9880d681SAndroid Build Coastguard Worker operator unsigned() const; 58*9880d681SAndroid Build Coastguard Worker bool operator== (unsigned x) const; 59*9880d681SAndroid Build Coastguard Worker bool operator== (IndexType Idx) const; 60*9880d681SAndroid Build Coastguard Worker bool operator!= (unsigned x) const; 61*9880d681SAndroid Build Coastguard Worker bool operator!= (IndexType Idx) const; 62*9880d681SAndroid Build Coastguard Worker IndexType operator++ (); 63*9880d681SAndroid Build Coastguard Worker bool operator< (unsigned Idx) const; 64*9880d681SAndroid Build Coastguard Worker bool operator< (IndexType Idx) const; 65*9880d681SAndroid Build Coastguard Worker bool operator<= (IndexType Idx) const; 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker private: 68*9880d681SAndroid Build Coastguard Worker bool operator> (IndexType Idx) const; 69*9880d681SAndroid Build Coastguard Worker bool operator>= (IndexType Idx) const; 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker unsigned Index; 72*9880d681SAndroid Build Coastguard Worker }; 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker // A range of indices, essentially a representation of a live range. 75*9880d681SAndroid Build Coastguard Worker // This is also used to represent "dead ranges", i.e. ranges where a 76*9880d681SAndroid Build Coastguard Worker // register is dead. 77*9880d681SAndroid Build Coastguard Worker class IndexRange : public std::pair<IndexType,IndexType> { 78*9880d681SAndroid Build Coastguard Worker public: IndexRangeHexagonBlockRanges79*9880d681SAndroid Build Coastguard Worker IndexRange() : Fixed(false), TiedEnd(false) {} 80*9880d681SAndroid Build Coastguard Worker IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false) 81*9880d681SAndroid Build Coastguard Worker : std::pair<IndexType,IndexType>(Start, End), Fixed(F), TiedEnd(T) {} startHexagonBlockRanges82*9880d681SAndroid Build Coastguard Worker IndexType start() const { return first; } endHexagonBlockRanges83*9880d681SAndroid Build Coastguard Worker IndexType end() const { return second; } 84*9880d681SAndroid Build Coastguard Worker 85*9880d681SAndroid Build Coastguard Worker bool operator< (const IndexRange &A) const { 86*9880d681SAndroid Build Coastguard Worker return start() < A.start(); 87*9880d681SAndroid Build Coastguard Worker } 88*9880d681SAndroid Build Coastguard Worker bool overlaps(const IndexRange &A) const; 89*9880d681SAndroid Build Coastguard Worker bool contains(const IndexRange &A) const; 90*9880d681SAndroid Build Coastguard Worker void merge(const IndexRange &A); 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker bool Fixed; // Can be renamed? "Fixed" means "no". 93*9880d681SAndroid Build Coastguard Worker bool TiedEnd; // The end is not a use, but a dead def tied to a use. 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker private: setStartHexagonBlockRanges96*9880d681SAndroid Build Coastguard Worker void setStart(const IndexType &S) { first = S; } setEndHexagonBlockRanges97*9880d681SAndroid Build Coastguard Worker void setEnd(const IndexType &E) { second = E; } 98*9880d681SAndroid Build Coastguard Worker }; 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker // A list of index ranges. This represents liveness of a register 101*9880d681SAndroid Build Coastguard Worker // in a basic block. 102*9880d681SAndroid Build Coastguard Worker class RangeList : public std::vector<IndexRange> { 103*9880d681SAndroid Build Coastguard Worker public: addHexagonBlockRanges104*9880d681SAndroid Build Coastguard Worker void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd) { 105*9880d681SAndroid Build Coastguard Worker push_back(IndexRange(Start, End, Fixed, TiedEnd)); 106*9880d681SAndroid Build Coastguard Worker } addHexagonBlockRanges107*9880d681SAndroid Build Coastguard Worker void add(const IndexRange &Range) { 108*9880d681SAndroid Build Coastguard Worker push_back(Range); 109*9880d681SAndroid Build Coastguard Worker } 110*9880d681SAndroid Build Coastguard Worker void include(const RangeList &RL); 111*9880d681SAndroid Build Coastguard Worker void unionize(bool MergeAdjacent = false); 112*9880d681SAndroid Build Coastguard Worker void subtract(const IndexRange &Range); 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Worker private: 115*9880d681SAndroid Build Coastguard Worker void addsub(const IndexRange &A, const IndexRange &B); 116*9880d681SAndroid Build Coastguard Worker }; 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker class InstrIndexMap { 119*9880d681SAndroid Build Coastguard Worker public: 120*9880d681SAndroid Build Coastguard Worker InstrIndexMap(MachineBasicBlock &B); 121*9880d681SAndroid Build Coastguard Worker MachineInstr *getInstr(IndexType Idx) const; 122*9880d681SAndroid Build Coastguard Worker IndexType getIndex(MachineInstr *MI) const; getBlockHexagonBlockRanges123*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &getBlock() const { return Block; } 124*9880d681SAndroid Build Coastguard Worker IndexType getPrevIndex(IndexType Idx) const; 125*9880d681SAndroid Build Coastguard Worker IndexType getNextIndex(IndexType Idx) const; 126*9880d681SAndroid Build Coastguard Worker void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI); 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker friend raw_ostream &operator<< (raw_ostream &OS, const InstrIndexMap &Map); 129*9880d681SAndroid Build Coastguard Worker IndexType First, Last; 130*9880d681SAndroid Build Coastguard Worker 131*9880d681SAndroid Build Coastguard Worker private: 132*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &Block; 133*9880d681SAndroid Build Coastguard Worker std::map<IndexType,MachineInstr*> Map; 134*9880d681SAndroid Build Coastguard Worker }; 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker typedef std::map<RegisterRef,RangeList> RegToRangeMap; 137*9880d681SAndroid Build Coastguard Worker RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap); 138*9880d681SAndroid Build Coastguard Worker RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap); 139*9880d681SAndroid Build Coastguard Worker static RegisterSet expandToSubRegs(RegisterRef R, 140*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI); 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker struct PrintRangeMap { PrintRangeMapHexagonBlockRanges::PrintRangeMap143*9880d681SAndroid Build Coastguard Worker PrintRangeMap(const RegToRangeMap &M, const TargetRegisterInfo &I) 144*9880d681SAndroid Build Coastguard Worker : Map(M), TRI(I) {} 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker friend raw_ostream &operator<< (raw_ostream &OS, const PrintRangeMap &P); 147*9880d681SAndroid Build Coastguard Worker private: 148*9880d681SAndroid Build Coastguard Worker const RegToRangeMap ⤅ 149*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &TRI; 150*9880d681SAndroid Build Coastguard Worker }; 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker private: 153*9880d681SAndroid Build Coastguard Worker RegisterSet getLiveIns(const MachineBasicBlock &B); 154*9880d681SAndroid Build Coastguard Worker 155*9880d681SAndroid Build Coastguard Worker void computeInitialLiveRanges(InstrIndexMap &IndexMap, 156*9880d681SAndroid Build Coastguard Worker RegToRangeMap &LiveMap); 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker MachineFunction &MF; 159*9880d681SAndroid Build Coastguard Worker const HexagonSubtarget &HST; 160*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII; 161*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &TRI; 162*9880d681SAndroid Build Coastguard Worker BitVector Reserved; 163*9880d681SAndroid Build Coastguard Worker }; 164*9880d681SAndroid Build Coastguard Worker 165*9880d681SAndroid Build Coastguard Worker 166*9880d681SAndroid Build Coastguard Worker inline HexagonBlockRanges::IndexType::operator unsigned() const { 167*9880d681SAndroid Build Coastguard Worker assert(Index >= First); 168*9880d681SAndroid Build Coastguard Worker return Index; 169*9880d681SAndroid Build Coastguard Worker } 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator== (unsigned x) const { 172*9880d681SAndroid Build Coastguard Worker return Index == x; 173*9880d681SAndroid Build Coastguard Worker } 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator== (IndexType Idx) const { 176*9880d681SAndroid Build Coastguard Worker return Index == Idx.Index; 177*9880d681SAndroid Build Coastguard Worker } 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator!= (unsigned x) const { 180*9880d681SAndroid Build Coastguard Worker return Index != x; 181*9880d681SAndroid Build Coastguard Worker } 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator!= (IndexType Idx) const { 184*9880d681SAndroid Build Coastguard Worker return Index != Idx.Index; 185*9880d681SAndroid Build Coastguard Worker } 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker inline 188*9880d681SAndroid Build Coastguard Worker HexagonBlockRanges::IndexType HexagonBlockRanges::IndexType::operator++ () { 189*9880d681SAndroid Build Coastguard Worker assert(Index != None); 190*9880d681SAndroid Build Coastguard Worker assert(Index != Exit); 191*9880d681SAndroid Build Coastguard Worker if (Index == Entry) 192*9880d681SAndroid Build Coastguard Worker Index = First; 193*9880d681SAndroid Build Coastguard Worker else 194*9880d681SAndroid Build Coastguard Worker ++Index; 195*9880d681SAndroid Build Coastguard Worker return *this; 196*9880d681SAndroid Build Coastguard Worker } 197*9880d681SAndroid Build Coastguard Worker 198*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator< (unsigned Idx) const { 199*9880d681SAndroid Build Coastguard Worker return operator< (IndexType(Idx)); 200*9880d681SAndroid Build Coastguard Worker } 201*9880d681SAndroid Build Coastguard Worker 202*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator< (IndexType Idx) const { 203*9880d681SAndroid Build Coastguard Worker // !(x < x). 204*9880d681SAndroid Build Coastguard Worker if (Index == Idx.Index) 205*9880d681SAndroid Build Coastguard Worker return false; 206*9880d681SAndroid Build Coastguard Worker // !(None < x) for all x. 207*9880d681SAndroid Build Coastguard Worker // !(x < None) for all x. 208*9880d681SAndroid Build Coastguard Worker if (Index == None || Idx.Index == None) 209*9880d681SAndroid Build Coastguard Worker return false; 210*9880d681SAndroid Build Coastguard Worker // !(Exit < x) for all x. 211*9880d681SAndroid Build Coastguard Worker // !(x < Entry) for all x. 212*9880d681SAndroid Build Coastguard Worker if (Index == Exit || Idx.Index == Entry) 213*9880d681SAndroid Build Coastguard Worker return false; 214*9880d681SAndroid Build Coastguard Worker // Entry < x for all x != Entry. 215*9880d681SAndroid Build Coastguard Worker // x < Exit for all x != Exit. 216*9880d681SAndroid Build Coastguard Worker if (Index == Entry || Idx.Index == Exit) 217*9880d681SAndroid Build Coastguard Worker return true; 218*9880d681SAndroid Build Coastguard Worker 219*9880d681SAndroid Build Coastguard Worker return Index < Idx.Index; 220*9880d681SAndroid Build Coastguard Worker } 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Worker inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const { 223*9880d681SAndroid Build Coastguard Worker return operator==(Idx) || operator<(Idx); 224*9880d681SAndroid Build Coastguard Worker } 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Worker 227*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx); 228*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS, 229*9880d681SAndroid Build Coastguard Worker const HexagonBlockRanges::IndexRange &IR); 230*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS, 231*9880d681SAndroid Build Coastguard Worker const HexagonBlockRanges::RangeList &RL); 232*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS, 233*9880d681SAndroid Build Coastguard Worker const HexagonBlockRanges::InstrIndexMap &M); 234*9880d681SAndroid Build Coastguard Worker raw_ostream &operator<< (raw_ostream &OS, 235*9880d681SAndroid Build Coastguard Worker const HexagonBlockRanges::PrintRangeMap &P); 236*9880d681SAndroid Build Coastguard Worker 237*9880d681SAndroid Build Coastguard Worker } // namespace llvm 238*9880d681SAndroid Build Coastguard Worker 239*9880d681SAndroid Build Coastguard Worker #endif 240