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 for (unsigned i
= 0, e
= Pairs
.size(); i
!= e
; ++i
) {
95 const PairType
*P
= Pairs
[i
];
96 OS
<< '(' << getModeName(P
->first
)
97 << ':' << getMVTName(P
->second
).str() << ')';
105 void ValueTypeByHwMode::dump() const {
106 dbgs() << *this << '\n';
109 ValueTypeByHwMode
llvm::getValueTypeByHwMode(Record
*Rec
,
110 const CodeGenHwModes
&CGH
) {
112 if (!Rec
->isSubClassOf("ValueType"))
115 assert(Rec
->isSubClassOf("ValueType") &&
116 "Record must be derived from ValueType");
117 if (Rec
->isSubClassOf("HwModeSelect"))
118 return ValueTypeByHwMode(Rec
, CGH
);
119 return ValueTypeByHwMode(Rec
, llvm::getValueType(Rec
));
122 RegSizeInfo::RegSizeInfo(Record
*R
, const CodeGenHwModes
&CGH
) {
123 RegSize
= R
->getValueAsInt("RegSize");
124 SpillSize
= R
->getValueAsInt("SpillSize");
125 SpillAlignment
= R
->getValueAsInt("SpillAlignment");
128 bool RegSizeInfo::operator< (const RegSizeInfo
&I
) const {
129 return std::tie(RegSize
, SpillSize
, SpillAlignment
) <
130 std::tie(I
.RegSize
, I
.SpillSize
, I
.SpillAlignment
);
133 bool RegSizeInfo::isSubClassOf(const RegSizeInfo
&I
) const {
134 return RegSize
<= I
.RegSize
&&
135 SpillAlignment
&& I
.SpillAlignment
% SpillAlignment
== 0 &&
136 SpillSize
<= I
.SpillSize
;
139 void RegSizeInfo::writeToStream(raw_ostream
&OS
) const {
140 OS
<< "[R=" << RegSize
<< ",S=" << SpillSize
141 << ",A=" << SpillAlignment
<< ']';
144 RegSizeInfoByHwMode::RegSizeInfoByHwMode(Record
*R
,
145 const CodeGenHwModes
&CGH
) {
146 const HwModeSelect
&MS
= CGH
.getHwModeSelect(R
);
147 for (const HwModeSelect::PairType
&P
: MS
.Items
) {
148 auto I
= Map
.insert({P
.first
, RegSizeInfo(P
.second
, CGH
)});
149 assert(I
.second
&& "Duplicate entry?");
154 bool RegSizeInfoByHwMode::operator< (const RegSizeInfoByHwMode
&I
) const {
155 unsigned M0
= Map
.begin()->first
;
156 return get(M0
) < I
.get(M0
);
159 bool RegSizeInfoByHwMode::operator== (const RegSizeInfoByHwMode
&I
) const {
160 unsigned M0
= Map
.begin()->first
;
161 return get(M0
) == I
.get(M0
);
164 bool RegSizeInfoByHwMode::isSubClassOf(const RegSizeInfoByHwMode
&I
) const {
165 unsigned M0
= Map
.begin()->first
;
166 return get(M0
).isSubClassOf(I
.get(M0
));
169 bool RegSizeInfoByHwMode::hasStricterSpillThan(const RegSizeInfoByHwMode
&I
)
171 unsigned M0
= Map
.begin()->first
;
172 const RegSizeInfo
&A0
= get(M0
);
173 const RegSizeInfo
&B0
= I
.get(M0
);
174 return std::tie(A0
.SpillSize
, A0
.SpillAlignment
) >
175 std::tie(B0
.SpillSize
, B0
.SpillAlignment
);
178 void RegSizeInfoByHwMode::writeToStream(raw_ostream
&OS
) const {
179 typedef typename
decltype(Map
)::value_type PairType
;
180 std::vector
<const PairType
*> Pairs
;
181 for (const auto &P
: Map
)
183 llvm::sort(Pairs
, deref
<std::less
<PairType
>>());
186 for (unsigned i
= 0, e
= Pairs
.size(); i
!= e
; ++i
) {
187 const PairType
*P
= Pairs
[i
];
188 OS
<< '(' << getModeName(P
->first
) << ':' << P
->second
<< ')';
195 EncodingInfoByHwMode::EncodingInfoByHwMode(Record
*R
, const CodeGenHwModes
&CGH
) {
196 const HwModeSelect
&MS
= CGH
.getHwModeSelect(R
);
197 for (const HwModeSelect::PairType
&P
: MS
.Items
) {
198 assert(P
.second
&& P
.second
->isSubClassOf("InstructionEncoding") &&
199 "Encoding must subclass InstructionEncoding");
200 auto I
= Map
.insert({P
.first
, P
.second
});
201 assert(I
.second
&& "Duplicate entry?");
207 raw_ostream
&operator<<(raw_ostream
&OS
, const ValueTypeByHwMode
&T
) {
212 raw_ostream
&operator<<(raw_ostream
&OS
, const RegSizeInfo
&T
) {
217 raw_ostream
&operator<<(raw_ostream
&OS
, const RegSizeInfoByHwMode
&T
) {