Path: blob/main/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonBlockRanges.h
35269 views
//===- HexagonBlockRanges.h -------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H9#define LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H1011#include "llvm/ADT/BitVector.h"12#include "llvm/CodeGen/Register.h"13#include <cassert>14#include <map>15#include <set>16#include <utility>17#include <vector>1819namespace llvm {2021class HexagonSubtarget;22class MachineBasicBlock;23class MachineFunction;24class MachineInstr;25class MachineRegisterInfo;26class raw_ostream;27class TargetInstrInfo;28class TargetRegisterInfo;2930struct HexagonBlockRanges {31HexagonBlockRanges(MachineFunction &MF);3233// FIXME: Consolidate duplicate definitions of RegisterRef34struct RegisterRef {35llvm::Register Reg;36unsigned Sub;3738bool operator<(RegisterRef R) const {39return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub);40}41};42using RegisterSet = std::set<RegisterRef>;4344// This is to represent an "index", which is an abstraction of a position45// of an instruction within a basic block.46class IndexType {47public:48enum : unsigned {49None = 0,50Entry = 1,51Exit = 2,52First = 11 // 10th + 1st53};5455IndexType() {}56IndexType(unsigned Idx) : Index(Idx) {}5758static bool isInstr(IndexType X) { return X.Index >= First; }5960operator unsigned() const;61bool operator== (unsigned x) const;62bool operator== (IndexType Idx) const;63bool operator!= (unsigned x) const;64bool operator!= (IndexType Idx) const;65IndexType operator++ ();66bool operator< (unsigned Idx) const;67bool operator< (IndexType Idx) const;68bool operator<= (IndexType Idx) const;6970private:71bool operator> (IndexType Idx) const;72bool operator>= (IndexType Idx) const;7374unsigned Index = None;75};7677// A range of indices, essentially a representation of a live range.78// This is also used to represent "dead ranges", i.e. ranges where a79// register is dead.80class IndexRange : public std::pair<IndexType,IndexType> {81public:82IndexRange() = default;83IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false)84: std::pair<IndexType,IndexType>(Start, End), Fixed(F), TiedEnd(T) {}8586IndexType start() const { return first; }87IndexType end() const { return second; }8889bool operator< (const IndexRange &A) const {90return start() < A.start();91}9293bool overlaps(const IndexRange &A) const;94bool contains(const IndexRange &A) const;95void merge(const IndexRange &A);9697bool Fixed = false; // Can be renamed? "Fixed" means "no".98bool TiedEnd = false; // The end is not a use, but a dead def tied to a use.99100private:101void setStart(const IndexType &S) { first = S; }102void setEnd(const IndexType &E) { second = E; }103};104105// A list of index ranges. This represents liveness of a register106// in a basic block.107class RangeList : public std::vector<IndexRange> {108public:109void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd) {110push_back(IndexRange(Start, End, Fixed, TiedEnd));111}112void add(const IndexRange &Range) {113push_back(Range);114}115116void include(const RangeList &RL);117void unionize(bool MergeAdjacent = false);118void subtract(const IndexRange &Range);119120private:121void addsub(const IndexRange &A, const IndexRange &B);122};123124class InstrIndexMap {125public:126InstrIndexMap(MachineBasicBlock &B);127128MachineInstr *getInstr(IndexType Idx) const;129IndexType getIndex(MachineInstr *MI) const;130MachineBasicBlock &getBlock() const { return Block; }131IndexType getPrevIndex(IndexType Idx) const;132IndexType getNextIndex(IndexType Idx) const;133void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI);134135friend raw_ostream &operator<< (raw_ostream &OS, const InstrIndexMap &Map);136137IndexType First, Last;138139private:140MachineBasicBlock &Block;141std::map<IndexType,MachineInstr*> Map;142};143144using RegToRangeMap = std::map<RegisterRef, RangeList>;145146RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap);147RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap);148static RegisterSet expandToSubRegs(RegisterRef R,149const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);150151struct PrintRangeMap {152PrintRangeMap(const RegToRangeMap &M, const TargetRegisterInfo &I)153: Map(M), TRI(I) {}154155friend raw_ostream &operator<< (raw_ostream &OS, const PrintRangeMap &P);156157private:158const RegToRangeMap ⤅159const TargetRegisterInfo &TRI;160};161162private:163RegisterSet getLiveIns(const MachineBasicBlock &B,164const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);165166void computeInitialLiveRanges(InstrIndexMap &IndexMap,167RegToRangeMap &LiveMap);168169MachineFunction &MF;170const HexagonSubtarget &HST;171const TargetInstrInfo &TII;172const TargetRegisterInfo &TRI;173BitVector Reserved;174};175176inline HexagonBlockRanges::IndexType::operator unsigned() const {177assert(Index >= First);178return Index;179}180181inline bool HexagonBlockRanges::IndexType::operator== (unsigned x) const {182return Index == x;183}184185inline bool HexagonBlockRanges::IndexType::operator== (IndexType Idx) const {186return Index == Idx.Index;187}188189inline bool HexagonBlockRanges::IndexType::operator!= (unsigned x) const {190return Index != x;191}192193inline bool HexagonBlockRanges::IndexType::operator!= (IndexType Idx) const {194return Index != Idx.Index;195}196197inline198HexagonBlockRanges::IndexType HexagonBlockRanges::IndexType::operator++ () {199assert(Index != None);200assert(Index != Exit);201if (Index == Entry)202Index = First;203else204++Index;205return *this;206}207208inline bool HexagonBlockRanges::IndexType::operator< (unsigned Idx) const {209return operator< (IndexType(Idx));210}211212inline bool HexagonBlockRanges::IndexType::operator< (IndexType Idx) const {213// !(x < x).214if (Index == Idx.Index)215return false;216// !(None < x) for all x.217// !(x < None) for all x.218if (Index == None || Idx.Index == None)219return false;220// !(Exit < x) for all x.221// !(x < Entry) for all x.222if (Index == Exit || Idx.Index == Entry)223return false;224// Entry < x for all x != Entry.225// x < Exit for all x != Exit.226if (Index == Entry || Idx.Index == Exit)227return true;228229return Index < Idx.Index;230}231232inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const {233return operator==(Idx) || operator<(Idx);234}235236raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx);237raw_ostream &operator<< (raw_ostream &OS,238const HexagonBlockRanges::IndexRange &IR);239raw_ostream &operator<< (raw_ostream &OS,240const HexagonBlockRanges::RangeList &RL);241raw_ostream &operator<< (raw_ostream &OS,242const HexagonBlockRanges::InstrIndexMap &M);243raw_ostream &operator<< (raw_ostream &OS,244const HexagonBlockRanges::PrintRangeMap &P);245246} // end namespace llvm247248#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H249250251