1 //===--- InfoByHwMode.h -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 // Classes that implement data parameterized by HW modes for instruction
10 // selection. Currently it is ValueTypeByHwMode (parameterized ValueType),
11 // and RegSizeInfoByHwMode (parameterized register/spill size and alignment
12 // data).
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
16 #define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
17 
18 #include "CodeGenHwModes.h"
19 #include "llvm/Support/MachineValueType.h"
20 
21 #include <map>
22 #include <set>
23 #include <string>
24 #include <vector>
25 
26 namespace llvm {
27 
28 struct CodeGenHwModes;
29 class Record;
30 class raw_ostream;
31 
32 template <typename InfoT> struct InfoByHwMode;
33 
34 std::string getModeName(unsigned Mode);
35 
36 enum : unsigned {
37   DefaultMode = CodeGenHwModes::DefaultMode,
38 };
39 
40 template <typename InfoT>
union_modes(const InfoByHwMode<InfoT> & A,const InfoByHwMode<InfoT> & B)41 std::vector<unsigned> union_modes(const InfoByHwMode<InfoT> &A,
42                                   const InfoByHwMode<InfoT> &B) {
43   std::vector<unsigned> V;
44   std::set<unsigned> U;
45   for (const auto &P : A)
46     U.insert(P.first);
47   for (const auto &P : B)
48     U.insert(P.first);
49   // Make sure that the default mode is last on the list.
50   bool HasDefault = false;
51   for (unsigned M : U)
52     if (M != DefaultMode)
53       V.push_back(M);
54     else
55       HasDefault = true;
56   if (HasDefault)
57     V.push_back(DefaultMode);
58   return V;
59 }
60 
61 template <typename InfoT>
62 struct InfoByHwMode {
63   typedef std::map<unsigned,InfoT> MapType;
64   typedef typename MapType::value_type PairType;
65   typedef typename MapType::iterator iterator;
66   typedef typename MapType::const_iterator const_iterator;
67 
68   InfoByHwMode() = default;
InfoByHwModeInfoByHwMode69   InfoByHwMode(const MapType &M) : Map(M) {}
70 
71   LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode72   iterator begin() { return Map.begin(); }
73   LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode74   iterator end()   { return Map.end(); }
75   LLVM_ATTRIBUTE_ALWAYS_INLINE
beginInfoByHwMode76   const_iterator begin() const { return Map.begin(); }
77   LLVM_ATTRIBUTE_ALWAYS_INLINE
endInfoByHwMode78   const_iterator end() const   { return Map.end(); }
79   LLVM_ATTRIBUTE_ALWAYS_INLINE
emptyInfoByHwMode80   bool empty() const { return Map.empty(); }
81 
82   LLVM_ATTRIBUTE_ALWAYS_INLINE
hasModeInfoByHwMode83   bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
84   LLVM_ATTRIBUTE_ALWAYS_INLINE
hasDefaultInfoByHwMode85   bool hasDefault() const { return hasMode(DefaultMode); }
86 
getInfoByHwMode87   InfoT &get(unsigned Mode) {
88     if (!hasMode(Mode)) {
89       assert(hasMode(DefaultMode));
90       Map.insert({Mode, Map.at(DefaultMode)});
91     }
92     return Map.at(Mode);
93   }
getInfoByHwMode94   const InfoT &get(unsigned Mode) const {
95     auto F = Map.find(Mode);
96     if (Mode != DefaultMode && F == Map.end())
97       F = Map.find(DefaultMode);
98     assert(F != Map.end());
99     return F->second;
100   }
101 
102   LLVM_ATTRIBUTE_ALWAYS_INLINE
isSimpleInfoByHwMode103   bool isSimple() const {
104     return Map.size() == 1 && Map.begin()->first == DefaultMode;
105   }
106   LLVM_ATTRIBUTE_ALWAYS_INLINE
getSimpleInfoByHwMode107   InfoT getSimple() const {
108     assert(isSimple());
109     return Map.begin()->second;
110   }
makeSimpleInfoByHwMode111   void makeSimple(unsigned Mode) {
112     assert(hasMode(Mode) || hasDefault());
113     InfoT I = get(Mode);
114     Map.clear();
115     Map.insert(std::make_pair(DefaultMode, I));
116   }
117 
118   MapType Map;
119 };
120 
121 struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
122   ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
ValueTypeByHwModeValueTypeByHwMode123   ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode,T}); }
124   ValueTypeByHwMode() = default;
125 
126   bool operator== (const ValueTypeByHwMode &T) const;
127   bool operator< (const ValueTypeByHwMode &T) const;
128 
isValidValueTypeByHwMode129   bool isValid() const {
130     return !Map.empty();
131   }
getTypeValueTypeByHwMode132   MVT getType(unsigned Mode) const { return get(Mode); }
133   MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type);
134 
135   static StringRef getMVTName(MVT T);
136   void writeToStream(raw_ostream &OS) const;
137   void dump() const;
138 };
139 
140 ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
141                                        const CodeGenHwModes &CGH);
142 
143 struct RegSizeInfo {
144   unsigned RegSize;
145   unsigned SpillSize;
146   unsigned SpillAlignment;
147 
148   RegSizeInfo(Record *R, const CodeGenHwModes &CGH);
149   RegSizeInfo() = default;
150   bool operator< (const RegSizeInfo &I) const;
151   bool operator== (const RegSizeInfo &I) const {
152     return std::tie(RegSize, SpillSize, SpillAlignment) ==
153            std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
154   }
155   bool operator!= (const RegSizeInfo &I) const {
156     return !(*this == I);
157   }
158 
159   bool isSubClassOf(const RegSizeInfo &I) const;
160   void writeToStream(raw_ostream &OS) const;
161 };
162 
163 struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
164   RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
165   RegSizeInfoByHwMode() = default;
166   bool operator< (const RegSizeInfoByHwMode &VI) const;
167   bool operator== (const RegSizeInfoByHwMode &VI) const;
168   bool operator!= (const RegSizeInfoByHwMode &VI) const {
169     return !(*this == VI);
170   }
171 
172   bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
173   bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
174 
175   void writeToStream(raw_ostream &OS) const;
176 };
177 
178 raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
179 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
180 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
181 
182 } // namespace llvm
183 
184 #endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
185