1 //===--- InfoByHwMode.cpp -------------------------------------------------===//
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
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
12 //===----------------------------------------------------------------------===//
14 #include "CodeGenTarget.h"
15 #include "InfoByHwMode.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/raw_ostream.h"
26 std::string
llvm::getModeName(unsigned Mode
) {
27 if (Mode
== DefaultMode
)
29 return (Twine('m') + Twine(Mode
)).str();
32 ValueTypeByHwMode::ValueTypeByHwMode(Record
*R
, const CodeGenHwModes
&CGH
) {
33 const HwModeSelect
&MS
= CGH
.getHwModeSelect(R
);
34 for (const HwModeSelect::PairType
&P
: MS
.Items
) {
35 auto I
= Map
.insert({P
.first
, MVT(llvm::getValueType(P
.second
))});
36 assert(I
.second
&& "Duplicate entry?");
41 ValueTypeByHwMode::ValueTypeByHwMode(Record
*R
, MVT T
) : ValueTypeByHwMode(T
) {
42 if (R
->isSubClassOf("PtrValueType"))
43 PtrAddrSpace
= R
->getValueAsInt("AddrSpace");
46 bool ValueTypeByHwMode::operator== (const ValueTypeByHwMode
&T
) const {
47 assert(isValid() && T
.isValid() && "Invalid type in assignment");
48 bool Simple
= isSimple();
49 if (Simple
!= T
.isSimple())
52 return getSimple() == T
.getSimple();
57 bool ValueTypeByHwMode::operator< (const ValueTypeByHwMode
&T
) const {
58 assert(isValid() && T
.isValid() && "Invalid type in comparison");
59 // Default order for maps.
63 MVT
&ValueTypeByHwMode::getOrCreateTypeForMode(unsigned Mode
, MVT Type
) {
64 auto F
= Map
.find(Mode
);
67 // If Mode is not in the map, look up the default mode. If it exists,
68 // make a copy of it for Mode and return it.
69 auto D
= Map
.find(DefaultMode
);
71 return Map
.insert(std::make_pair(Mode
, D
->second
)).first
->second
;
72 // If default mode is not present either, use provided Type.
73 return Map
.insert(std::make_pair(Mode
, Type
)).first
->second
;
76 StringRef
ValueTypeByHwMode::getMVTName(MVT T
) {
77 StringRef N
= llvm::getEnumName(T
.SimpleTy
);
78 N
.consume_front("MVT::");
82 void ValueTypeByHwMode::writeToStream(raw_ostream
&OS
) const {
84 OS
<< getMVTName(getSimple());
88 std::vector
<const PairType
*> Pairs
;
89 for (const auto &P
: Map
)
91 llvm::sort(Pairs
, deref
<std::less
<PairType
>>());
94 ListSeparator
LS(",");
95 for (const PairType
*P
: Pairs
)
96 OS
<< LS
<< '(' << getModeName(P
->first
) << ':'
97 << getMVTName(P
->second
).str() << ')';
102 void ValueTypeByHwMode::dump() const {
103 dbgs() << *this << '\n';
106 ValueTypeByHwMode
llvm::getValueTypeByHwMode(Record
*Rec
,
107 const CodeGenHwModes
&CGH
) {
109 if (!Rec
->isSubClassOf("ValueType"))
112 assert(Rec
->isSubClassOf("ValueType") &&
113 "Record must be derived from ValueType");
114 if (Rec
->isSubClassOf("HwModeSelect"))
115 return ValueTypeByHwMode(Rec
, CGH
);
116 return ValueTypeByHwMode(Rec
, llvm::getValueType(Rec
));
119 RegSizeInfo::RegSizeInfo(Record
*R
, const CodeGenHwModes
&CGH
) {
120 RegSize
= R
->getValueAsInt("RegSize");
121 SpillSize
= R
->getValueAsInt("SpillSize");
122 SpillAlignment
= R
->getValueAsInt("SpillAlignment");
125 bool RegSizeInfo::operator< (const RegSizeInfo
&I
) const {
126 return std::tie(RegSize
, SpillSize
, SpillAlignment
) <
127 std::tie(I
.RegSize
, I
.SpillSize
, I
.SpillAlignment
);
130 bool RegSizeInfo::isSubClassOf(const RegSizeInfo
&I
) const {
131 return RegSize
<= I
.RegSize
&&
132 SpillAlignment
&& I
.SpillAlignment
% SpillAlignment
== 0 &&
133 SpillSize
<= I
.SpillSize
;
136 void RegSizeInfo::writeToStream(raw_ostream
&OS
) const {
137 OS
<< "[R=" << RegSize
<< ",S=" << SpillSize
138 << ",A=" << SpillAlignment
<< ']';
141 RegSizeInfoByHwMode::RegSizeInfoByHwMode(Record
*R
,
142 const CodeGenHwModes
&CGH
) {
143 const HwModeSelect
&MS
= CGH
.getHwModeSelect(R
);
144 for (const HwModeSelect::PairType
&P
: MS
.Items
) {
145 auto I
= Map
.insert({P
.first
, RegSizeInfo(P
.second
, CGH
)});
146 assert(I
.second
&& "Duplicate entry?");
151 bool RegSizeInfoByHwMode::operator< (const RegSizeInfoByHwMode
&I
) const {
152 unsigned M0
= Map
.begin()->first
;
153 return get(M0
) < I
.get(M0
);
156 bool RegSizeInfoByHwMode::operator== (const RegSizeInfoByHwMode
&I
) const {
157 unsigned M0
= Map
.begin()->first
;
158 return get(M0
) == I
.get(M0
);
161 bool RegSizeInfoByHwMode::isSubClassOf(const RegSizeInfoByHwMode
&I
) const {
162 unsigned M0
= Map
.begin()->first
;
163 return get(M0
).isSubClassOf(I
.get(M0
));
166 bool RegSizeInfoByHwMode::hasStricterSpillThan(const RegSizeInfoByHwMode
&I
)
168 unsigned M0
= Map
.begin()->first
;
169 const RegSizeInfo
&A0
= get(M0
);
170 const RegSizeInfo
&B0
= I
.get(M0
);
171 return std::tie(A0
.SpillSize
, A0
.SpillAlignment
) >
172 std::tie(B0
.SpillSize
, B0
.SpillAlignment
);
175 void RegSizeInfoByHwMode::writeToStream(raw_ostream
&OS
) const {
176 typedef typename
decltype(Map
)::value_type PairType
;
177 std::vector
<const PairType
*> Pairs
;
178 for (const auto &P
: Map
)
180 llvm::sort(Pairs
, deref
<std::less
<PairType
>>());
183 ListSeparator
LS(",");
184 for (const PairType
*P
: Pairs
)
185 OS
<< LS
<< '(' << getModeName(P
->first
) << ':' << P
->second
<< ')';
189 EncodingInfoByHwMode::EncodingInfoByHwMode(Record
*R
, const CodeGenHwModes
&CGH
) {
190 const HwModeSelect
&MS
= CGH
.getHwModeSelect(R
);
191 for (const HwModeSelect::PairType
&P
: MS
.Items
) {
192 assert(P
.second
&& P
.second
->isSubClassOf("InstructionEncoding") &&
193 "Encoding must subclass InstructionEncoding");
194 auto I
= Map
.insert({P
.first
, P
.second
});
195 assert(I
.second
&& "Duplicate entry?");
201 raw_ostream
&operator<<(raw_ostream
&OS
, const ValueTypeByHwMode
&T
) {
206 raw_ostream
&operator<<(raw_ostream
&OS
, const RegSizeInfo
&T
) {
211 raw_ostream
&operator<<(raw_ostream
&OS
, const RegSizeInfoByHwMode
&T
) {