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
25namespace llvm {
26
27struct CodeGenHwModes;
28class Record;
29class raw_ostream;
30
31template <typename InfoT> struct InfoByHwMode;
32
33std::string getModeName(unsigned Mode);
34
35enum : unsigned {
36  DefaultMode = CodeGenHwModes::DefaultMode,
37};
38
39template <typename InfoT>
40std::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
60template <typename InfoT>
61struct 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
120struct 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
145ValueTypeByHwMode getValueTypeByHwMode(Record *Rec,
146                                       const CodeGenHwModes &CGH);
147
148struct 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
168struct 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
183raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
184raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T);
185raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T);
186
187struct EncodingInfoByHwMode : public InfoByHwMode<Record*> {
188  EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH);
189  EncodingInfoByHwMode() = default;
190};
191
192} // namespace llvm
193
194#endif // LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
195