24 using namespace LegacyLegalizeActions;
26 #define DEBUG_TYPE "legalizer-info"
40 OS <<
"FewerElements";
71 setScalarAction(TargetOpcode::G_ANYEXT, 1, {{1,
Legal}});
72 setScalarAction(TargetOpcode::G_ZEXT, 1, {{1,
Legal}});
73 setScalarAction(TargetOpcode::G_SEXT, 1, {{1,
Legal}});
74 setScalarAction(TargetOpcode::G_TRUNC, 0, {{1,
Legal}});
75 setScalarAction(TargetOpcode::G_TRUNC, 1, {{1,
Legal}});
77 setScalarAction(TargetOpcode::G_INTRINSIC, 0, {{1,
Legal}});
78 setScalarAction(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, 0, {{1,
Legal}});
80 setLegalizeScalarToDifferentSizeStrategy(
81 TargetOpcode::G_IMPLICIT_DEF, 0, narrowToSmallerAndUnsupportedIfTooSmall);
82 setLegalizeScalarToDifferentSizeStrategy(
83 TargetOpcode::G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
84 setLegalizeScalarToDifferentSizeStrategy(
85 TargetOpcode::G_OR, 0, widenToLargerTypesAndNarrowToLargest);
86 setLegalizeScalarToDifferentSizeStrategy(
87 TargetOpcode::G_LOAD, 0, narrowToSmallerAndUnsupportedIfTooSmall);
88 setLegalizeScalarToDifferentSizeStrategy(
89 TargetOpcode::G_STORE, 0, narrowToSmallerAndUnsupportedIfTooSmall);
91 setLegalizeScalarToDifferentSizeStrategy(
92 TargetOpcode::G_BRCOND, 0, widenToLargerTypesUnsupportedOtherwise);
93 setLegalizeScalarToDifferentSizeStrategy(
94 TargetOpcode::G_INSERT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
95 setLegalizeScalarToDifferentSizeStrategy(
96 TargetOpcode::G_EXTRACT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
97 setLegalizeScalarToDifferentSizeStrategy(
98 TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedIfTooSmall);
99 setScalarAction(TargetOpcode::G_FNEG, 0, {{1,
Lower}});
103 assert(TablesInitialized ==
false);
105 for (
unsigned OpcodeIdx = 0; OpcodeIdx <= LastOp - FirstOp; ++OpcodeIdx) {
106 const unsigned Opcode = FirstOp + OpcodeIdx;
107 for (
unsigned TypeIdx = 0; TypeIdx != SpecifiedActions[OpcodeIdx].size();
114 std::map<uint16_t, SizeAndActionsVec> AddressSpace2SpecifiedActions;
116 std::map<uint16_t, SizeAndActionsVec> ElemSize2SpecifiedActions;
117 for (
auto LLT2Action : SpecifiedActions[OpcodeIdx][TypeIdx]) {
118 const LLT Type = LLT2Action.first;
121 auto SizeAction = std::make_pair(
Type.getSizeInBits(), Action);
122 if (
Type.isPointer())
123 AddressSpace2SpecifiedActions[
Type.getAddressSpace()].push_back(
125 else if (
Type.isVector())
126 ElemSize2SpecifiedActions[
Type.getElementType().getSizeInBits()]
127 .push_back(SizeAction);
129 ScalarSpecifiedActions.push_back(SizeAction);
137 if (TypeIdx < ScalarSizeChangeStrategies[OpcodeIdx].
size() &&
138 ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] !=
nullptr)
139 S = ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx];
141 checkPartialSizeAndActionsVector(ScalarSpecifiedActions);
142 setScalarAction(Opcode, TypeIdx,
S(ScalarSpecifiedActions));
146 for (
auto PointerSpecifiedActions : AddressSpace2SpecifiedActions) {
148 checkPartialSizeAndActionsVector(PointerSpecifiedActions.second);
152 Opcode, TypeIdx, PointerSpecifiedActions.first,
153 unsupportedForDifferentSizes(PointerSpecifiedActions.second));
158 for (
auto VectorSpecifiedActions : ElemSize2SpecifiedActions) {
160 const uint16_t ElementSize = VectorSpecifiedActions.first;
161 ElementSizesSeen.push_back({ElementSize,
Legal});
162 checkPartialSizeAndActionsVector(VectorSpecifiedActions.second);
168 for (
SizeAndAction BitsizeAndAction : VectorSpecifiedActions.second) {
169 assert(BitsizeAndAction.first % ElementSize == 0);
170 const uint16_t NumElements = BitsizeAndAction.first / ElementSize;
171 NumElementsActions.push_back({NumElements, BitsizeAndAction.second});
173 setVectorNumElementAction(
174 Opcode, TypeIdx, ElementSize,
175 moreToWiderTypesAndLessToWidest(NumElementsActions));
179 &unsupportedForDifferentSizes;
180 if (TypeIdx < VectorElementSizeChangeStrategies[OpcodeIdx].
size() &&
181 VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] !=
nullptr)
182 VectorElementSizeChangeStrategy =
183 VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx];
184 setScalarInVectorAction(
185 Opcode, TypeIdx, VectorElementSizeChangeStrategy(ElementSizesSeen));
189 TablesInitialized =
true;
196 std::pair<LegacyLegalizeAction, LLT>
197 LegacyLegalizerInfo::getAspectAction(
const InstrAspect &Aspect)
const {
198 assert(TablesInitialized &&
"backend forgot to call computeTables");
202 return findScalarLegalAction(Aspect);
204 return findVectorLegalAction(Aspect);
212 unsigned LargestSizeSoFar = 0;
213 if (v.size() >= 1 && v[0].first != 1)
214 result.push_back({1, IncreaseAction});
215 for (
size_t i = 0;
i < v.size(); ++
i) {
217 LargestSizeSoFar = v[
i].first;
218 if (
i + 1 < v.size() && v[
i + 1].first != v[
i].first + 1) {
219 result.push_back({LargestSizeSoFar + 1, IncreaseAction});
220 LargestSizeSoFar = v[
i].first + 1;
223 result.push_back({LargestSizeSoFar + 1, DecreaseAction});
232 if (v.size() == 0 || v[0].first != 1)
233 result.push_back({1, IncreaseAction});
234 for (
size_t i = 0;
i < v.size(); ++
i) {
236 if (
i + 1 == v.size() || v[
i + 1].first != v[
i].first + 1) {
237 result.push_back({v[
i].first + 1, DecreaseAction});
244 LegacyLegalizerInfo::findAction(
const SizeAndActionsVec &Vec,
const uint32_t Size) {
250 Vec, [=](
const SizeAndAction &A) {
return A.first <= Size; });
251 assert(It != Vec.begin() &&
"Does Vec not start with size 1?");
252 int VecIdx = It - Vec.begin() - 1;
261 return {Size, Action};
276 for (
int i = VecIdx - 1;
i >= 0; --
i)
277 if (!needsLegalizingToDifferentSize(Vec[
i].second) &&
279 return {Vec[
i].first, Action};
285 for (std::size_t
i = VecIdx + 1;
i < Vec.size(); ++
i)
286 if (!needsLegalizingToDifferentSize(Vec[
i].second) &&
288 return {Vec[
i].first, Action};
299 std::pair<LegacyLegalizeAction, LLT>
300 LegacyLegalizerInfo::findScalarLegalAction(
const InstrAspect &Aspect)
const {
304 const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.
Opcode);
307 AddrSpace2PointerActions[OpcodeIdx].end()) {
312 ? AddrSpace2PointerActions[OpcodeIdx]
315 : ScalarActions[OpcodeIdx];
316 if (Aspect.
Idx >= Actions.size())
318 const SizeAndActionsVec &Vec = Actions[Aspect.
Idx];
322 return {SizeAndAction.second,
325 SizeAndAction.first)};
328 std::pair<LegacyLegalizeAction, LLT>
329 LegacyLegalizerInfo::findVectorLegalAction(
const InstrAspect &Aspect)
const {
335 const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.
Opcode);
336 const unsigned TypeIdx = Aspect.
Idx;
337 if (TypeIdx >= ScalarInVectorActions[OpcodeIdx].
size())
339 const SizeAndActionsVec &ElemSizeVec =
340 ScalarInVectorActions[OpcodeIdx][TypeIdx];
342 LLT IntermediateType;
343 auto ElementSizeAndAction =
346 ElementSizeAndAction.first);
347 if (ElementSizeAndAction.second !=
Legal)
348 return {ElementSizeAndAction.second, IntermediateType};
350 auto i = NumElements2Actions[OpcodeIdx].find(
352 if (
i == NumElements2Actions[OpcodeIdx].
end()) {
353 return {
NotFound, IntermediateType};
355 const SizeAndActionsVec &NumElementsVec = (*i).second[TypeIdx];
356 auto NumElementsAndAction =
358 return {NumElementsAndAction.second,
364 assert(Opcode >= FirstOp && Opcode <= LastOp &&
"Unsupported opcode");
365 return Opcode - FirstOp;
371 for (
unsigned i = 0;
i < Query.
Types.size(); ++
i) {
372 auto Action = getAspectAction({Query.
Opcode,
i, Query.
Types[
i]});
373 if (Action.first !=
Legal) {
375 << Action.first <<
", " << Action.second <<
"\n");
376 return {Action.first,
i, Action.second};