xref: /freebsd/contrib/llvm-project/llvm/utils/TableGen/Common/InfoByHwMode.h (revision c5c02a131a0e2ef52771e683269bc8778fe511f3)
1 //===--- InfoByHwMode.h -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // Classes that implement data parameterized by HW modes for instruction
9 // selection. Currently it is ValueTypeByHwMode (parameterized ValueType),
10 // and RegSizeInfoByHwMode (parameterized register/spill size and alignment
11 // data).
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
15 #define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
16 
17 #include "CodeGenHwModes.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/CodeGenTypes/MachineValueType.h"
21 #include "llvm/Support/Compiler.h"
22 #include <cassert>
23 #include <limits>
24 #include <map>
25 #include <string>
26 #include <tuple>
27 #include <utility>
28 
29 namespace llvm {
30 
31 class Record;
32 class raw_ostream;
33 
34 template <typename InfoT> struct InfoByHwMode;
35 
36 std::string getModeName(unsigned Mode);
37 
38 enum : unsigned {
39   DefaultMode = CodeGenHwModes::DefaultMode,
40 };
41 
42 template <typename InfoT>
43 void union_modes(const InfoByHwMode<InfoT> &A, const InfoByHwMode<InfoT> &B,
44                  SmallVectorImpl<unsigned> &Modes) {
45   auto AI = A.begin();
46   auto BI = B.begin();
47 
48   // Skip default mode, but remember if we had one.
49   bool HasDefault = false;
50   if (AI != A.end() && AI->first == DefaultMode) {
51     HasDefault = true;
52     ++AI;
53   }
54   if (BI != B.end() && BI->first == DefaultMode) {
55     HasDefault = true;
56     ++BI;
57   }
58 
59   while (AI != A.end()) {
60     // If we're done with B, finish A.
61     if (BI == B.end()) {
62       for (; AI != A.end(); ++AI)
63         Modes.push_back(AI->first);
64       break;
65     }
66 
67     if (BI->first < AI->first) {
68       Modes.push_back(BI->first);
69       ++BI;
70     } else {
71       Modes.push_back(AI->first);
72       if (AI->first == BI->first)
73         ++BI;
74       ++AI;
75     }
76   }
77 
78   // Finish B.
79   for (; BI != B.end(); ++BI)
80     Modes.push_back(BI->first);
81 
82   // Make sure that the default mode is last on the list.
83   if (HasDefault)
84     Modes.push_back(DefaultMode);
85 }
86 
87 template <typename InfoT> struct InfoByHwMode {
88   typedef std::map<unsigned, InfoT> MapType;
89   typedef typename MapType::value_type PairType;
90   typedef typename MapType::iterator iterator;
91   typedef typename MapType::const_iterator const_iterator;
92 
93   InfoByHwMode() = default;
94   InfoByHwMode(const MapType &M) : Map(M) {}
95 
96   LLVM_ATTRIBUTE_ALWAYS_INLINE
97   iterator begin() { return Map.begin(); }
98   LLVM_ATTRIBUTE_ALWAYS_INLINE
99   iterator end() { return Map.end(); }
100   LLVM_ATTRIBUTE_ALWAYS_INLINE
101   const_iterator begin() const { return Map.begin(); }
102   LLVM_ATTRIBUTE_ALWAYS_INLINE
103   const_iterator end() const { return Map.end(); }
104   LLVM_ATTRIBUTE_ALWAYS_INLINE
105   bool empty() const { return Map.empty(); }
106 
107   LLVM_ATTRIBUTE_ALWAYS_INLINE
108   bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
109   LLVM_ATTRIBUTE_ALWAYS_INLINE
110   bool hasDefault() const {
111     return !Map.empty() && Map.begin()->first == DefaultMode;
112   }
113 
114   InfoT &get(unsigned Mode) {
115     auto F = Map.find(Mode);
116     if (F != Map.end())
117       return F->second;
118 
119     // Copy and insert the default mode which should be first.
120     assert(hasDefault());
121     auto P = Map.insert({Mode, Map.begin()->second});
122     return P.first->second;
123   }
124   const InfoT &get(unsigned Mode) const {
125     auto F = Map.find(Mode);
126     if (F != Map.end())
127       return F->second;
128     // Get the default mode which should be first.
129     F = Map.begin();
130     assert(F != Map.end() && F->first == DefaultMode);
131     return F->second;
132   }
133 
134   LLVM_ATTRIBUTE_ALWAYS_INLINE
135   bool isSimple() const {
136     return Map.size() == 1 && Map.begin()->first == DefaultMode;
137   }
138   LLVM_ATTRIBUTE_ALWAYS_INLINE
139   const InfoT &getSimple() const {
140     assert(isSimple());
141     return Map.begin()->second;
142   }
143   void makeSimple(unsigned Mode) {
144     assert(hasMode(Mode) || hasDefault());
145     InfoT I = get(Mode);
146     Map.clear();
147     Map.insert(std::pair(DefaultMode, I));
148   }
149 
150 protected:
151   MapType Map;
152 };
153 
154 struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
155   ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
156   ValueTypeByHwMode(Record *R, MVT T);
157   ValueTypeByHwMode(MVT T) { Map.insert({DefaultMode, T}); }
158   ValueTypeByHwMode() = default;
159 
160   bool operator==(const ValueTypeByHwMode &T) const;
161   bool operator<(const ValueTypeByHwMode &T) const;
162 
163   bool isValid() const { return !Map.empty(); }
164   MVT getType(unsigned Mode) const { return get(Mode); }
165   MVT &getOrCreateTypeForMode(unsigned Mode, MVT Type);
166 
167   static StringRef getMVTName(MVT T);
168   void writeToStream(raw_ostream &OS) const;
169   void dump() const;
170 
171   unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
172   bool isPointer() const {
173     return PtrAddrSpace != std::numeric_limits<unsigned>::max();
174   }
175 };
176 
177 ValueTypeByHwMode getValueTypeByHwMode(Record *Rec, const CodeGenHwModes &CGH);
178 
179 raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
180 
181 struct RegSizeInfo {
182   unsigned RegSize;
183   unsigned SpillSize;
184   unsigned SpillAlignment;
185 
186   RegSizeInfo(Record *R);
187   RegSizeInfo() = default;
188   bool operator<(const RegSizeInfo &I) const;
189   bool operator==(const RegSizeInfo &I) const {
190     return std::tie(RegSize, SpillSize, SpillAlignment) ==
191            std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
192   }
193   bool operator!=(const RegSizeInfo &I) const { return !(*this == I); }
194 
195   bool isSubClassOf(const RegSizeInfo &I) const;
196   void writeToStream(raw_ostream &OS) const;
197 };
198 
199 struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
200   RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
201   RegSizeInfoByHwMode() = default;
202   bool operator<(const RegSizeInfoByHwMode &VI) const;
203   bool operator==(const RegSizeInfoByHwMode &VI) const;
204   bool operator!=(const RegSizeInfoByHwMode &VI) const {
205     return !(*this == VI);
206   }
207 
208   bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
209   bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
210 
211   void writeToStream(raw_ostream &OS) const;
212 
213   void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) {
214     Map.insert(std::pair(Mode, Info));
215   }
216 };
217 
218 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
219 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
220 
221 struct SubRegRange {
222   uint16_t Size;
223   uint16_t Offset;
224 
225   SubRegRange(Record *R);
226   SubRegRange(uint16_t Size, uint16_t Offset) : Size(Size), Offset(Offset) {}
227 };
228 
229 struct SubRegRangeByHwMode : public InfoByHwMode<SubRegRange> {
230   SubRegRangeByHwMode(Record *R, const CodeGenHwModes &CGH);
231   SubRegRangeByHwMode(SubRegRange Range) { Map.insert({DefaultMode, Range}); }
232   SubRegRangeByHwMode() = default;
233 
234   void insertSubRegRangeForMode(unsigned Mode, SubRegRange Info) {
235     Map.insert(std::pair(Mode, Info));
236   }
237 };
238 
239 struct EncodingInfoByHwMode : public InfoByHwMode<Record *> {
240   EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
241   EncodingInfoByHwMode() = default;
242 };
243 
244 } // namespace llvm
245 
246 #endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
247