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/Support/MachineValueType.h"
19 
20 #include <map>
21 #include <set>
22 #include <string>
23 #include <vector>
24 
25 namespace llvm {
26 
27 struct CodeGenHwModes;
28 class Record;
29 class raw_ostream;
30 
31 template <typename InfoT> struct InfoByHwMode;
32 
33 std::string getModeName(unsigned Mode);
34 
35 enum : unsigned {
36   DefaultMode = CodeGenHwModes::DefaultMode,
37 };
38 
39 template <typename InfoT>
40 std::vector<unsigned> union_modes(const InfoByHwMode<InfoT> &A,
41                                   const InfoByHwMode<InfoT> &B) {
42   std::vector<unsigned> V;
43   std::set<unsigned> U;
44   for (const auto &P : A)
45     U.insert(P.first);
46   for (const auto &P : B)
47     U.insert(P.first);
48   // Make sure that the default mode is last on the list.
49   bool HasDefault = false;
50   for (unsigned M : U)
51     if (M != DefaultMode)
52       V.push_back(M);
53     else
54       HasDefault = true;
55   if (HasDefault)
56     V.push_back(DefaultMode);
57   return V;
58 }
59 
60 template <typename InfoT>
61 struct InfoByHwMode {
62   typedef std::map<unsigned,InfoT> MapType;
63   typedef typename MapType::value_type PairType;
64   typedef typename MapType::iterator iterator;
65   typedef typename MapType::const_iterator const_iterator;
66 
67   InfoByHwMode() = default;
68   InfoByHwMode(const MapType &M) : Map(M) {}
69 
70   LLVM_ATTRIBUTE_ALWAYS_INLINE
71   iterator begin() { return Map.begin(); }
72   LLVM_ATTRIBUTE_ALWAYS_INLINE
73   iterator end()   { return Map.end(); }
74   LLVM_ATTRIBUTE_ALWAYS_INLINE
75   const_iterator begin() const { return Map.begin(); }
76   LLVM_ATTRIBUTE_ALWAYS_INLINE
77   const_iterator end() const   { return Map.end(); }
78   LLVM_ATTRIBUTE_ALWAYS_INLINE
79   bool empty() const { return Map.empty(); }
80 
81   LLVM_ATTRIBUTE_ALWAYS_INLINE
82   bool hasMode(unsigned M) const { return Map.find(M) != Map.end(); }
83   LLVM_ATTRIBUTE_ALWAYS_INLINE
84   bool hasDefault() const { return hasMode(DefaultMode); }
85 
86   InfoT &get(unsigned Mode) {
87     if (!hasMode(Mode)) {
88       assert(hasMode(DefaultMode));
89       Map.insert({Mode, Map.at(DefaultMode)});
90     }
91     return Map.at(Mode);
92   }
93   const InfoT &get(unsigned Mode) const {
94     auto F = Map.find(Mode);
95     if (Mode != DefaultMode && F == Map.end())
96       F = Map.find(DefaultMode);
97     assert(F != Map.end());
98     return F->second;
99   }
100 
101   LLVM_ATTRIBUTE_ALWAYS_INLINE
102   bool isSimple() const {
103     return Map.size() == 1 && Map.begin()->first == DefaultMode;
104   }
105   LLVM_ATTRIBUTE_ALWAYS_INLINE
106   InfoT getSimple() const {
107     assert(isSimple());
108     return Map.begin()->second;
109   }
110   void makeSimple(unsigned Mode) {
111     assert(hasMode(Mode) || hasDefault());
112     InfoT I = get(Mode);
113     Map.clear();
114     Map.insert(std::make_pair(DefaultMode, I));
115   }
116 
117   MapType Map;
118 };
119 
120 struct ValueTypeByHwMode : public InfoByHwMode<MVT> {
121   ValueTypeByHwMode(Record *R, const CodeGenHwModes &CGH);
122   ValueTypeByHwMode(Record *R, MVT T);
123   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 
129   bool isValid() const {
130     return !Map.empty();
131   }
132   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   unsigned PtrAddrSpace = std::numeric_limits<unsigned>::max();
140   bool isPointer() const {
141     return PtrAddrSpace != std::numeric_limits<unsigned>::max();
142   }
143 };
144 
145 ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
146                                        const CodeGenHwModes &CGH);
147 
148 struct RegSizeInfo {
149   unsigned RegSize;
150   unsigned SpillSize;
151   unsigned SpillAlignment;
152 
153   RegSizeInfo(Record *R, const CodeGenHwModes &CGH);
154   RegSizeInfo() = default;
155   bool operator< (const RegSizeInfo &I) const;
156   bool operator== (const RegSizeInfo &I) const {
157     return std::tie(RegSize, SpillSize, SpillAlignment) ==
158            std::tie(I.RegSize, I.SpillSize, I.SpillAlignment);
159   }
160   bool operator!= (const RegSizeInfo &I) const {
161     return !(*this == I);
162   }
163 
164   bool isSubClassOf(const RegSizeInfo &I) const;
165   void writeToStream(raw_ostream &OS) const;
166 };
167 
168 struct RegSizeInfoByHwMode : public InfoByHwMode<RegSizeInfo> {
169   RegSizeInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
170   RegSizeInfoByHwMode() = default;
171   bool operator< (const RegSizeInfoByHwMode &VI) const;
172   bool operator== (const RegSizeInfoByHwMode &VI) const;
173   bool operator!= (const RegSizeInfoByHwMode &VI) const {
174     return !(*this == VI);
175   }
176 
177   bool isSubClassOf(const RegSizeInfoByHwMode &I) const;
178   bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
179 
180   void writeToStream(raw_ostream &OS) const;
181 };
182 
183 raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
184 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
185 raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
186 
187 } // namespace llvm
188 
189 #endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
190