aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon/HexagonBlockRanges.h
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
commit01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch)
tree4def12e759965de927d963ac65840d663ef9d1ea /lib/Target/Hexagon/HexagonBlockRanges.h
parentf0f4822ed4b66e3579e92a89f368f8fb860e218e (diff)
downloadsrc-01095a5d43bbfde13731688ddcf6048ebb8b7721.tar.gz
src-01095a5d43bbfde13731688ddcf6048ebb8b7721.zip
Vendor import of llvm release_39 branch r276489:vendor/llvm/llvm-release_39-r276489
Notes
Notes: svn path=/vendor/llvm/dist/; revision=303231 svn path=/vendor/llvm/llvm-release_39-r276489/; revision=303232; tag=vendor/llvm/llvm-release_39-r276489
Diffstat (limited to 'lib/Target/Hexagon/HexagonBlockRanges.h')
-rw-r--r--lib/Target/Hexagon/HexagonBlockRanges.h239
1 files changed, 239 insertions, 0 deletions
diff --git a/lib/Target/Hexagon/HexagonBlockRanges.h b/lib/Target/Hexagon/HexagonBlockRanges.h
new file mode 100644
index 000000000000..9c3f938f99eb
--- /dev/null
+++ b/lib/Target/Hexagon/HexagonBlockRanges.h
@@ -0,0 +1,239 @@
+//===--- HexagonBlockRanges.h ---------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef HEXAGON_BLOCK_RANGES_H
+#define HEXAGON_BLOCK_RANGES_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/MC/MCRegisterInfo.h" // For MCPhysReg.
+#include <map>
+#include <set>
+#include <vector>
+
+namespace llvm {
+ class Function;
+ class HexagonSubtarget;
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class MCInstrDesc;
+ class raw_ostream;
+ class TargetInstrInfo;
+ class TargetRegisterClass;
+ class TargetRegisterInfo;
+ class Type;
+
+struct HexagonBlockRanges {
+ HexagonBlockRanges(MachineFunction &MF);
+
+ struct RegisterRef {
+ unsigned Reg, Sub;
+ bool operator<(RegisterRef R) const {
+ return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub);
+ }
+ };
+ typedef std::set<RegisterRef> RegisterSet;
+
+ // This is to represent an "index", which is an abstraction of a position
+ // of an instruction within a basic block.
+ class IndexType {
+ public:
+ enum : unsigned {
+ None = 0,
+ Entry = 1,
+ Exit = 2,
+ First = 11 // 10th + 1st
+ };
+ static bool isInstr(IndexType X) { return X.Index >= First; }
+
+ IndexType() : Index(None) {}
+ IndexType(unsigned Idx) : Index(Idx) {}
+ operator unsigned() const;
+ bool operator== (unsigned x) const;
+ bool operator== (IndexType Idx) const;
+ bool operator!= (unsigned x) const;
+ bool operator!= (IndexType Idx) const;
+ IndexType operator++ ();
+ bool operator< (unsigned Idx) const;
+ bool operator< (IndexType Idx) const;
+ bool operator<= (IndexType Idx) const;
+
+ private:
+ bool operator> (IndexType Idx) const;
+ bool operator>= (IndexType Idx) const;
+
+ unsigned Index;
+ };
+
+ // A range of indices, essentially a representation of a live range.
+ // This is also used to represent "dead ranges", i.e. ranges where a
+ // register is dead.
+ class IndexRange : public std::pair<IndexType,IndexType> {
+ public:
+ IndexRange() : Fixed(false), TiedEnd(false) {}
+ IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false)
+ : std::pair<IndexType,IndexType>(Start, End), Fixed(F), TiedEnd(T) {}
+ IndexType start() const { return first; }
+ IndexType end() const { return second; }
+
+ bool operator< (const IndexRange &A) const {
+ return start() < A.start();
+ }
+ bool overlaps(const IndexRange &A) const;
+ bool contains(const IndexRange &A) const;
+ void merge(const IndexRange &A);
+
+ bool Fixed; // Can be renamed? "Fixed" means "no".
+ bool TiedEnd; // The end is not a use, but a dead def tied to a use.
+
+ private:
+ void setStart(const IndexType &S) { first = S; }
+ void setEnd(const IndexType &E) { second = E; }
+ };
+
+ // A list of index ranges. This represents liveness of a register
+ // in a basic block.
+ class RangeList : public std::vector<IndexRange> {
+ public:
+ void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd) {
+ push_back(IndexRange(Start, End, Fixed, TiedEnd));
+ }
+ void add(const IndexRange &Range) {
+ push_back(Range);
+ }
+ void include(const RangeList &RL);
+ void unionize(bool MergeAdjacent = false);
+ void subtract(const IndexRange &Range);
+
+ private:
+ void addsub(const IndexRange &A, const IndexRange &B);
+ };
+
+ class InstrIndexMap {
+ public:
+ InstrIndexMap(MachineBasicBlock &B);
+ MachineInstr *getInstr(IndexType Idx) const;
+ IndexType getIndex(MachineInstr *MI) const;
+ MachineBasicBlock &getBlock() const { return Block; }
+ IndexType getPrevIndex(IndexType Idx) const;
+ IndexType getNextIndex(IndexType Idx) const;
+ void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI);
+
+ friend raw_ostream &operator<< (raw_ostream &OS, const InstrIndexMap &Map);
+ IndexType First, Last;
+
+ private:
+ MachineBasicBlock &Block;
+ std::map<IndexType,MachineInstr*> Map;
+ };
+
+ typedef std::map<RegisterRef,RangeList> RegToRangeMap;
+ RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap);
+ RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap);
+ static RegisterSet expandToSubRegs(RegisterRef R,
+ const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI);
+
+ struct PrintRangeMap {
+ PrintRangeMap(const RegToRangeMap &M, const TargetRegisterInfo &I)
+ : Map(M), TRI(I) {}
+
+ friend raw_ostream &operator<< (raw_ostream &OS, const PrintRangeMap &P);
+ private:
+ const RegToRangeMap &Map;
+ const TargetRegisterInfo &TRI;
+ };
+
+private:
+ RegisterSet getLiveIns(const MachineBasicBlock &B);
+
+ void computeInitialLiveRanges(InstrIndexMap &IndexMap,
+ RegToRangeMap &LiveMap);
+
+ MachineFunction &MF;
+ const HexagonSubtarget &HST;
+ const TargetInstrInfo &TII;
+ const TargetRegisterInfo &TRI;
+ BitVector Reserved;
+};
+
+
+inline HexagonBlockRanges::IndexType::operator unsigned() const {
+ assert(Index >= First);
+ return Index;
+}
+
+inline bool HexagonBlockRanges::IndexType::operator== (unsigned x) const {
+ return Index == x;
+}
+
+inline bool HexagonBlockRanges::IndexType::operator== (IndexType Idx) const {
+ return Index == Idx.Index;
+}
+
+inline bool HexagonBlockRanges::IndexType::operator!= (unsigned x) const {
+ return Index != x;
+}
+
+inline bool HexagonBlockRanges::IndexType::operator!= (IndexType Idx) const {
+ return Index != Idx.Index;
+}
+
+inline
+HexagonBlockRanges::IndexType HexagonBlockRanges::IndexType::operator++ () {
+ assert(Index != None);
+ assert(Index != Exit);
+ if (Index == Entry)
+ Index = First;
+ else
+ ++Index;
+ return *this;
+}
+
+inline bool HexagonBlockRanges::IndexType::operator< (unsigned Idx) const {
+ return operator< (IndexType(Idx));
+}
+
+inline bool HexagonBlockRanges::IndexType::operator< (IndexType Idx) const {
+ // !(x < x).
+ if (Index == Idx.Index)
+ return false;
+ // !(None < x) for all x.
+ // !(x < None) for all x.
+ if (Index == None || Idx.Index == None)
+ return false;
+ // !(Exit < x) for all x.
+ // !(x < Entry) for all x.
+ if (Index == Exit || Idx.Index == Entry)
+ return false;
+ // Entry < x for all x != Entry.
+ // x < Exit for all x != Exit.
+ if (Index == Entry || Idx.Index == Exit)
+ return true;
+
+ return Index < Idx.Index;
+}
+
+inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const {
+ return operator==(Idx) || operator<(Idx);
+}
+
+
+raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx);
+raw_ostream &operator<< (raw_ostream &OS,
+ const HexagonBlockRanges::IndexRange &IR);
+raw_ostream &operator<< (raw_ostream &OS,
+ const HexagonBlockRanges::RangeList &RL);
+raw_ostream &operator<< (raw_ostream &OS,
+ const HexagonBlockRanges::InstrIndexMap &M);
+raw_ostream &operator<< (raw_ostream &OS,
+ const HexagonBlockRanges::PrintRangeMap &P);
+
+} // namespace llvm
+
+#endif