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