LLVM  13.0.0git
LegalizerInfo.cpp
Go to the documentation of this file.
1 //===- lib/CodeGen/GlobalISel/LegalizerInfo.cpp - Legalizer ---------------===//
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 //
9 // Implement an interface to specify and query how an illegal operation on a
10 // given type should be expanded.
11 //
12 // Issues to be resolved:
13 // + Make it fast.
14 // + Support weird types like i3, <7 x i3>, ...
15 // + Operations with more than one type (ICMP, CMPXCHG, intrinsics, ...)
16 //
17 //===----------------------------------------------------------------------===//
18 
26 #include "llvm/MC/MCInstrDesc.h"
27 #include "llvm/MC/MCInstrInfo.h"
28 #include "llvm/Support/Debug.h"
32 #include <algorithm>
33 #include <map>
34 
35 using namespace llvm;
36 using namespace LegalizeActions;
37 
38 #define DEBUG_TYPE "legalizer-info"
39 
41  "disable-gisel-legality-check",
42  cl::desc("Don't verify that MIR is fully legal between GlobalISel passes"),
43  cl::Hidden);
44 
46  switch (Action) {
47  case Legal:
48  OS << "Legal";
49  break;
50  case NarrowScalar:
51  OS << "NarrowScalar";
52  break;
53  case WidenScalar:
54  OS << "WidenScalar";
55  break;
56  case FewerElements:
57  OS << "FewerElements";
58  break;
59  case MoreElements:
60  OS << "MoreElements";
61  break;
62  case Bitcast:
63  OS << "Bitcast";
64  break;
65  case Lower:
66  OS << "Lower";
67  break;
68  case Libcall:
69  OS << "Libcall";
70  break;
71  case Custom:
72  OS << "Custom";
73  break;
74  case Unsupported:
75  OS << "Unsupported";
76  break;
77  case NotFound:
78  OS << "NotFound";
79  break;
80  case UseLegacyRules:
81  OS << "UseLegacyRules";
82  break;
83  }
84  return OS;
85 }
86 
88  OS << Opcode << ", Tys={";
89  for (const auto &Type : Types) {
90  OS << Type << ", ";
91  }
92  OS << "}, Opcode=";
93 
94  OS << Opcode << ", MMOs={";
95  for (const auto &MMODescr : MMODescrs) {
96  OS << MMODescr.SizeInBits << ", ";
97  }
98  OS << "}";
99 
100  return OS;
101 }
102 
103 #ifndef NDEBUG
104 // Make sure the rule won't (trivially) loop forever.
105 static bool hasNoSimpleLoops(const LegalizeRule &Rule, const LegalityQuery &Q,
106  const std::pair<unsigned, LLT> &Mutation) {
107  switch (Rule.getAction()) {
108  case Legal:
109  case Custom:
110  case Lower:
111  case MoreElements:
112  case FewerElements:
113  break;
114  default:
115  return Q.Types[Mutation.first] != Mutation.second;
116  }
117  return true;
118 }
119 
120 // Make sure the returned mutation makes sense for the match type.
121 static bool mutationIsSane(const LegalizeRule &Rule,
122  const LegalityQuery &Q,
123  std::pair<unsigned, LLT> Mutation) {
124  // If the user wants a custom mutation, then we can't really say much about
125  // it. Return true, and trust that they're doing the right thing.
126  if (Rule.getAction() == Custom || Rule.getAction() == Legal)
127  return true;
128 
129  const unsigned TypeIdx = Mutation.first;
130  const LLT OldTy = Q.Types[TypeIdx];
131  const LLT NewTy = Mutation.second;
132 
133  switch (Rule.getAction()) {
134  case FewerElements:
135  if (!OldTy.isVector())
136  return false;
138  case MoreElements: {
139  // MoreElements can go from scalar to vector.
140  const unsigned OldElts = OldTy.isVector() ? OldTy.getNumElements() : 1;
141  if (NewTy.isVector()) {
142  if (Rule.getAction() == FewerElements) {
143  // Make sure the element count really decreased.
144  if (NewTy.getNumElements() >= OldElts)
145  return false;
146  } else {
147  // Make sure the element count really increased.
148  if (NewTy.getNumElements() <= OldElts)
149  return false;
150  }
151  } else if (Rule.getAction() == MoreElements)
152  return false;
153 
154  // Make sure the element type didn't change.
155  return NewTy.getScalarType() == OldTy.getScalarType();
156  }
157  case NarrowScalar:
158  case WidenScalar: {
159  if (OldTy.isVector()) {
160  // Number of elements should not change.
161  if (!NewTy.isVector() || OldTy.getNumElements() != NewTy.getNumElements())
162  return false;
163  } else {
164  // Both types must be vectors
165  if (NewTy.isVector())
166  return false;
167  }
168 
169  if (Rule.getAction() == NarrowScalar) {
170  // Make sure the size really decreased.
171  if (NewTy.getScalarSizeInBits() >= OldTy.getScalarSizeInBits())
172  return false;
173  } else {
174  // Make sure the size really increased.
175  if (NewTy.getScalarSizeInBits() <= OldTy.getScalarSizeInBits())
176  return false;
177  }
178 
179  return true;
180  }
181  case Bitcast: {
182  return OldTy != NewTy && OldTy.getSizeInBits() == NewTy.getSizeInBits();
183  }
184  default:
185  return true;
186  }
187 }
188 #endif
189 
191  LLVM_DEBUG(dbgs() << "Applying legalizer ruleset to: "; Query.print(dbgs());
192  dbgs() << "\n");
193  if (Rules.empty()) {
194  LLVM_DEBUG(dbgs() << ".. fallback to legacy rules (no rules defined)\n");
195  return {LegalizeAction::UseLegacyRules, 0, LLT{}};
196  }
197  for (const LegalizeRule &Rule : Rules) {
198  if (Rule.match(Query)) {
199  LLVM_DEBUG(dbgs() << ".. match\n");
200  std::pair<unsigned, LLT> Mutation = Rule.determineMutation(Query);
201  LLVM_DEBUG(dbgs() << ".. .. " << Rule.getAction() << ", "
202  << Mutation.first << ", " << Mutation.second << "\n");
203  assert(mutationIsSane(Rule, Query, Mutation) &&
204  "legality mutation invalid for match");
205  assert(hasNoSimpleLoops(Rule, Query, Mutation) && "Simple loop detected");
206  return {Rule.getAction(), Mutation.first, Mutation.second};
207  } else
208  LLVM_DEBUG(dbgs() << ".. no match\n");
209  }
210  LLVM_DEBUG(dbgs() << ".. unsupported\n");
211  return {LegalizeAction::Unsupported, 0, LLT{}};
212 }
213 
214 bool LegalizeRuleSet::verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const {
215 #ifndef NDEBUG
216  if (Rules.empty()) {
217  LLVM_DEBUG(
218  dbgs() << ".. type index coverage check SKIPPED: no rules defined\n");
219  return true;
220  }
221  const int64_t FirstUncovered = TypeIdxsCovered.find_first_unset();
222  if (FirstUncovered < 0) {
223  LLVM_DEBUG(dbgs() << ".. type index coverage check SKIPPED:"
224  " user-defined predicate detected\n");
225  return true;
226  }
227  const bool AllCovered = (FirstUncovered >= NumTypeIdxs);
228  if (NumTypeIdxs > 0)
229  LLVM_DEBUG(dbgs() << ".. the first uncovered type index: " << FirstUncovered
230  << ", " << (AllCovered ? "OK" : "FAIL") << "\n");
231  return AllCovered;
232 #else
233  return true;
234 #endif
235 }
236 
237 bool LegalizeRuleSet::verifyImmIdxsCoverage(unsigned NumImmIdxs) const {
238 #ifndef NDEBUG
239  if (Rules.empty()) {
240  LLVM_DEBUG(
241  dbgs() << ".. imm index coverage check SKIPPED: no rules defined\n");
242  return true;
243  }
244  const int64_t FirstUncovered = ImmIdxsCovered.find_first_unset();
245  if (FirstUncovered < 0) {
246  LLVM_DEBUG(dbgs() << ".. imm index coverage check SKIPPED:"
247  " user-defined predicate detected\n");
248  return true;
249  }
250  const bool AllCovered = (FirstUncovered >= NumImmIdxs);
251  LLVM_DEBUG(dbgs() << ".. the first uncovered imm index: " << FirstUncovered
252  << ", " << (AllCovered ? "OK" : "FAIL") << "\n");
253  return AllCovered;
254 #else
255  return true;
256 #endif
257 }
258 
259 LegalizerInfo::LegalizerInfo() : TablesInitialized(false) {
260  // Set defaults.
261  // FIXME: these two (G_ANYEXT and G_TRUNC?) can be legalized to the
262  // fundamental load/store Jakob proposed. Once loads & stores are supported.
263  setScalarAction(TargetOpcode::G_ANYEXT, 1, {{1, Legal}});
264  setScalarAction(TargetOpcode::G_ZEXT, 1, {{1, Legal}});
265  setScalarAction(TargetOpcode::G_SEXT, 1, {{1, Legal}});
266  setScalarAction(TargetOpcode::G_TRUNC, 0, {{1, Legal}});
267  setScalarAction(TargetOpcode::G_TRUNC, 1, {{1, Legal}});
268 
269  setScalarAction(TargetOpcode::G_INTRINSIC, 0, {{1, Legal}});
270  setScalarAction(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, 0, {{1, Legal}});
271 
273  TargetOpcode::G_IMPLICIT_DEF, 0, narrowToSmallerAndUnsupportedIfTooSmall);
275  TargetOpcode::G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
277  TargetOpcode::G_OR, 0, widenToLargerTypesAndNarrowToLargest);
279  TargetOpcode::G_LOAD, 0, narrowToSmallerAndUnsupportedIfTooSmall);
281  TargetOpcode::G_STORE, 0, narrowToSmallerAndUnsupportedIfTooSmall);
282 
284  TargetOpcode::G_BRCOND, 0, widenToLargerTypesUnsupportedOtherwise);
286  TargetOpcode::G_INSERT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
288  TargetOpcode::G_EXTRACT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
290  TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedIfTooSmall);
291  setScalarAction(TargetOpcode::G_FNEG, 0, {{1, Lower}});
292 }
293 
295  assert(TablesInitialized == false);
296 
297  for (unsigned OpcodeIdx = 0; OpcodeIdx <= LastOp - FirstOp; ++OpcodeIdx) {
298  const unsigned Opcode = FirstOp + OpcodeIdx;
299  for (unsigned TypeIdx = 0; TypeIdx != SpecifiedActions[OpcodeIdx].size();
300  ++TypeIdx) {
301  // 0. Collect information specified through the setAction API, i.e.
302  // for specific bit sizes.
303  // For scalar types:
304  SizeAndActionsVec ScalarSpecifiedActions;
305  // For pointer types:
306  std::map<uint16_t, SizeAndActionsVec> AddressSpace2SpecifiedActions;
307  // For vector types:
308  std::map<uint16_t, SizeAndActionsVec> ElemSize2SpecifiedActions;
309  for (auto LLT2Action : SpecifiedActions[OpcodeIdx][TypeIdx]) {
310  const LLT Type = LLT2Action.first;
311  const LegalizeAction Action = LLT2Action.second;
312 
313  auto SizeAction = std::make_pair(Type.getSizeInBits(), Action);
314  if (Type.isPointer())
315  AddressSpace2SpecifiedActions[Type.getAddressSpace()].push_back(
316  SizeAction);
317  else if (Type.isVector())
318  ElemSize2SpecifiedActions[Type.getElementType().getSizeInBits()]
319  .push_back(SizeAction);
320  else
321  ScalarSpecifiedActions.push_back(SizeAction);
322  }
323 
324  // 1. Handle scalar types
325  {
326  // Decide how to handle bit sizes for which no explicit specification
327  // was given.
329  if (TypeIdx < ScalarSizeChangeStrategies[OpcodeIdx].size() &&
330  ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr)
331  S = ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx];
332  llvm::sort(ScalarSpecifiedActions);
333  checkPartialSizeAndActionsVector(ScalarSpecifiedActions);
334  setScalarAction(Opcode, TypeIdx, S(ScalarSpecifiedActions));
335  }
336 
337  // 2. Handle pointer types
338  for (auto PointerSpecifiedActions : AddressSpace2SpecifiedActions) {
339  llvm::sort(PointerSpecifiedActions.second);
340  checkPartialSizeAndActionsVector(PointerSpecifiedActions.second);
341  // For pointer types, we assume that there isn't a meaningfull way
342  // to change the number of bits used in the pointer.
343  setPointerAction(
344  Opcode, TypeIdx, PointerSpecifiedActions.first,
345  unsupportedForDifferentSizes(PointerSpecifiedActions.second));
346  }
347 
348  // 3. Handle vector types
349  SizeAndActionsVec ElementSizesSeen;
350  for (auto VectorSpecifiedActions : ElemSize2SpecifiedActions) {
351  llvm::sort(VectorSpecifiedActions.second);
352  const uint16_t ElementSize = VectorSpecifiedActions.first;
353  ElementSizesSeen.push_back({ElementSize, Legal});
354  checkPartialSizeAndActionsVector(VectorSpecifiedActions.second);
355  // For vector types, we assume that the best way to adapt the number
356  // of elements is to the next larger number of elements type for which
357  // the vector type is legal, unless there is no such type. In that case,
358  // legalize towards a vector type with a smaller number of elements.
359  SizeAndActionsVec NumElementsActions;
360  for (SizeAndAction BitsizeAndAction : VectorSpecifiedActions.second) {
361  assert(BitsizeAndAction.first % ElementSize == 0);
362  const uint16_t NumElements = BitsizeAndAction.first / ElementSize;
363  NumElementsActions.push_back({NumElements, BitsizeAndAction.second});
364  }
365  setVectorNumElementAction(
366  Opcode, TypeIdx, ElementSize,
367  moreToWiderTypesAndLessToWidest(NumElementsActions));
368  }
369  llvm::sort(ElementSizesSeen);
370  SizeChangeStrategy VectorElementSizeChangeStrategy =
372  if (TypeIdx < VectorElementSizeChangeStrategies[OpcodeIdx].size() &&
373  VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr)
374  VectorElementSizeChangeStrategy =
375  VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx];
376  setScalarInVectorAction(
377  Opcode, TypeIdx, VectorElementSizeChangeStrategy(ElementSizesSeen));
378  }
379  }
380 
381  TablesInitialized = true;
382 }
383 
384 // FIXME: inefficient implementation for now. Without ComputeValueVTs we're
385 // probably going to need specialized lookup structures for various types before
386 // we have any hope of doing well with something like <13 x i3>. Even the common
387 // cases should do better than what we have now.
388 std::pair<LegalizeAction, LLT>
389 LegalizerInfo::getAspectAction(const InstrAspect &Aspect) const {
390  assert(TablesInitialized && "backend forgot to call computeTables");
391  // These *have* to be implemented for now, they're the fundamental basis of
392  // how everything else is transformed.
393  if (Aspect.Type.isScalar() || Aspect.Type.isPointer())
394  return findScalarLegalAction(Aspect);
395  assert(Aspect.Type.isVector());
396  return findVectorLegalAction(Aspect);
397 }
398 
399 /// Helper function to get LLT for the given type index.
401  const MachineRegisterInfo &MRI, unsigned OpIdx,
402  unsigned TypeIdx) {
403  assert(TypeIdx < MI.getNumOperands() && "Unexpected TypeIdx");
404  // G_UNMERGE_VALUES has variable number of operands, but there is only
405  // one source type and one destination type as all destinations must be the
406  // same type. So, get the last operand if TypeIdx == 1.
407  if (MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES && TypeIdx == 1)
408  return MRI.getType(MI.getOperand(MI.getNumOperands() - 1).getReg());
409  return MRI.getType(MI.getOperand(OpIdx).getReg());
410 }
411 
412 unsigned LegalizerInfo::getOpcodeIdxForOpcode(unsigned Opcode) const {
413  assert(Opcode >= FirstOp && Opcode <= LastOp && "Unsupported opcode");
414  return Opcode - FirstOp;
415 }
416 
417 unsigned LegalizerInfo::getActionDefinitionsIdx(unsigned Opcode) const {
418  unsigned OpcodeIdx = getOpcodeIdxForOpcode(Opcode);
419  if (unsigned Alias = RulesForOpcode[OpcodeIdx].getAlias()) {
420  LLVM_DEBUG(dbgs() << ".. opcode " << Opcode << " is aliased to " << Alias
421  << "\n");
422  OpcodeIdx = getOpcodeIdxForOpcode(Alias);
423  assert(RulesForOpcode[OpcodeIdx].getAlias() == 0 && "Cannot chain aliases");
424  }
425 
426  return OpcodeIdx;
427 }
428 
429 const LegalizeRuleSet &
430 LegalizerInfo::getActionDefinitions(unsigned Opcode) const {
431  unsigned OpcodeIdx = getActionDefinitionsIdx(Opcode);
432  return RulesForOpcode[OpcodeIdx];
433 }
434 
436  unsigned OpcodeIdx = getActionDefinitionsIdx(Opcode);
437  auto &Result = RulesForOpcode[OpcodeIdx];
438  assert(!Result.isAliasedByAnother() && "Modifying this opcode will modify aliases");
439  return Result;
440 }
441 
443  std::initializer_list<unsigned> Opcodes) {
444  unsigned Representative = *Opcodes.begin();
445 
446  assert(!llvm::empty(Opcodes) && Opcodes.begin() + 1 != Opcodes.end() &&
447  "Initializer list must have at least two opcodes");
448 
449  for (unsigned Op : llvm::drop_begin(Opcodes))
450  aliasActionDefinitions(Representative, Op);
451 
452  auto &Return = getActionDefinitionsBuilder(Representative);
453  Return.setIsAliasedByAnother();
454  return Return;
455 }
456 
458  unsigned OpcodeFrom) {
459  assert(OpcodeTo != OpcodeFrom && "Cannot alias to self");
460  assert(OpcodeTo >= FirstOp && OpcodeTo <= LastOp && "Unsupported opcode");
461  const unsigned OpcodeFromIdx = getOpcodeIdxForOpcode(OpcodeFrom);
462  RulesForOpcode[OpcodeFromIdx].aliasTo(OpcodeTo);
463 }
464 
469  return Step;
470  }
471 
472  for (unsigned i = 0; i < Query.Types.size(); ++i) {
473  auto Action = getAspectAction({Query.Opcode, i, Query.Types[i]});
474  if (Action.first != Legal) {
475  LLVM_DEBUG(dbgs() << ".. (legacy) Type " << i << " Action="
476  << Action.first << ", " << Action.second << "\n");
477  return {Action.first, i, Action.second};
478  } else
479  LLVM_DEBUG(dbgs() << ".. (legacy) Type " << i << " Legal\n");
480  }
481  LLVM_DEBUG(dbgs() << ".. (legacy) Legal\n");
482  return {Legal, 0, LLT{}};
483 }
484 
487  const MachineRegisterInfo &MRI) const {
488  SmallVector<LLT, 2> Types;
489  SmallBitVector SeenTypes(8);
490  const MCOperandInfo *OpInfo = MI.getDesc().OpInfo;
491  // FIXME: probably we'll need to cache the results here somehow?
492  for (unsigned i = 0; i < MI.getDesc().getNumOperands(); ++i) {
493  if (!OpInfo[i].isGenericType())
494  continue;
495 
496  // We must only record actions once for each TypeIdx; otherwise we'd
497  // try to legalize operands multiple times down the line.
498  unsigned TypeIdx = OpInfo[i].getGenericTypeIndex();
499  if (SeenTypes[TypeIdx])
500  continue;
501 
502  SeenTypes.set(TypeIdx);
503 
504  LLT Ty = getTypeFromTypeIdx(MI, MRI, i, TypeIdx);
505  Types.push_back(Ty);
506  }
507 
509  for (const auto &MMO : MI.memoperands())
510  MemDescrs.push_back({8 * MMO->getSize() /* in bits */,
511  8 * MMO->getAlign().value(), MMO->getOrdering()});
512 
513  return getAction({MI.getOpcode(), Types, MemDescrs});
514 }
515 
517  const MachineRegisterInfo &MRI) const {
518  return getAction(MI, MRI).Action == Legal;
519 }
520 
522  const MachineRegisterInfo &MRI) const {
523  auto Action = getAction(MI, MRI).Action;
524  // If the action is custom, it may not necessarily modify the instruction,
525  // so we have to assume it's legal.
526  return Action == Legal || Action == Custom;
527 }
528 
531  const SizeAndActionsVec &v, LegalizeAction IncreaseAction,
532  LegalizeAction DecreaseAction) {
534  unsigned LargestSizeSoFar = 0;
535  if (v.size() >= 1 && v[0].first != 1)
536  result.push_back({1, IncreaseAction});
537  for (size_t i = 0; i < v.size(); ++i) {
538  result.push_back(v[i]);
539  LargestSizeSoFar = v[i].first;
540  if (i + 1 < v.size() && v[i + 1].first != v[i].first + 1) {
541  result.push_back({LargestSizeSoFar + 1, IncreaseAction});
542  LargestSizeSoFar = v[i].first + 1;
543  }
544  }
545  result.push_back({LargestSizeSoFar + 1, DecreaseAction});
546  return result;
547 }
548 
551  const SizeAndActionsVec &v, LegalizeAction DecreaseAction,
552  LegalizeAction IncreaseAction) {
554  if (v.size() == 0 || v[0].first != 1)
555  result.push_back({1, IncreaseAction});
556  for (size_t i = 0; i < v.size(); ++i) {
557  result.push_back(v[i]);
558  if (i + 1 == v.size() || v[i + 1].first != v[i].first + 1) {
559  result.push_back({v[i].first + 1, DecreaseAction});
560  }
561  }
562  return result;
563 }
564 
566 LegalizerInfo::findAction(const SizeAndActionsVec &Vec, const uint32_t Size) {
567  assert(Size >= 1);
568  // Find the last element in Vec that has a bitsize equal to or smaller than
569  // the requested bit size.
570  // That is the element just before the first element that is bigger than Size.
571  auto It = partition_point(
572  Vec, [=](const SizeAndAction &A) { return A.first <= Size; });
573  assert(It != Vec.begin() && "Does Vec not start with size 1?");
574  int VecIdx = It - Vec.begin() - 1;
575 
576  LegalizeAction Action = Vec[VecIdx].second;
577  switch (Action) {
578  case Legal:
579  case Bitcast:
580  case Lower:
581  case Libcall:
582  case Custom:
583  return {Size, Action};
584  case FewerElements:
585  // FIXME: is this special case still needed and correct?
586  // Special case for scalarization:
587  if (Vec == SizeAndActionsVec({{1, FewerElements}}))
588  return {1, FewerElements};
590  case NarrowScalar: {
591  // The following needs to be a loop, as for now, we do allow needing to
592  // go over "Unsupported" bit sizes before finding a legalizable bit size.
593  // e.g. (s8, WidenScalar), (s9, Unsupported), (s32, Legal). if Size==8,
594  // we need to iterate over s9, and then to s32 to return (s32, Legal).
595  // If we want to get rid of the below loop, we should have stronger asserts
596  // when building the SizeAndActionsVecs, probably not allowing
597  // "Unsupported" unless at the ends of the vector.
598  for (int i = VecIdx - 1; i >= 0; --i)
599  if (!needsLegalizingToDifferentSize(Vec[i].second) &&
600  Vec[i].second != Unsupported)
601  return {Vec[i].first, Action};
602  llvm_unreachable("");
603  }
604  case WidenScalar:
605  case MoreElements: {
606  // See above, the following needs to be a loop, at least for now.
607  for (std::size_t i = VecIdx + 1; i < Vec.size(); ++i)
608  if (!needsLegalizingToDifferentSize(Vec[i].second) &&
609  Vec[i].second != Unsupported)
610  return {Vec[i].first, Action};
611  llvm_unreachable("");
612  }
613  case Unsupported:
614  return {Size, Unsupported};
615  case NotFound:
616  case UseLegacyRules:
617  llvm_unreachable("NotFound");
618  }
619  llvm_unreachable("Action has an unknown enum value");
620 }
621 
622 std::pair<LegalizeAction, LLT>
623 LegalizerInfo::findScalarLegalAction(const InstrAspect &Aspect) const {
624  assert(Aspect.Type.isScalar() || Aspect.Type.isPointer());
625  if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
626  return {NotFound, LLT()};
627  const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.Opcode);
628  if (Aspect.Type.isPointer() &&
629  AddrSpace2PointerActions[OpcodeIdx].find(Aspect.Type.getAddressSpace()) ==
630  AddrSpace2PointerActions[OpcodeIdx].end()) {
631  return {NotFound, LLT()};
632  }
633  const SmallVector<SizeAndActionsVec, 1> &Actions =
634  Aspect.Type.isPointer()
635  ? AddrSpace2PointerActions[OpcodeIdx]
636  .find(Aspect.Type.getAddressSpace())
637  ->second
638  : ScalarActions[OpcodeIdx];
639  if (Aspect.Idx >= Actions.size())
640  return {NotFound, LLT()};
641  const SizeAndActionsVec &Vec = Actions[Aspect.Idx];
642  // FIXME: speed up this search, e.g. by using a results cache for repeated
643  // queries?
644  auto SizeAndAction = findAction(Vec, Aspect.Type.getSizeInBits());
645  return {SizeAndAction.second,
646  Aspect.Type.isScalar() ? LLT::scalar(SizeAndAction.first)
647  : LLT::pointer(Aspect.Type.getAddressSpace(),
648  SizeAndAction.first)};
649 }
650 
651 std::pair<LegalizeAction, LLT>
652 LegalizerInfo::findVectorLegalAction(const InstrAspect &Aspect) const {
653  assert(Aspect.Type.isVector());
654  // First legalize the vector element size, then legalize the number of
655  // lanes in the vector.
656  if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
657  return {NotFound, Aspect.Type};
658  const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.Opcode);
659  const unsigned TypeIdx = Aspect.Idx;
660  if (TypeIdx >= ScalarInVectorActions[OpcodeIdx].size())
661  return {NotFound, Aspect.Type};
662  const SizeAndActionsVec &ElemSizeVec =
663  ScalarInVectorActions[OpcodeIdx][TypeIdx];
664 
665  LLT IntermediateType;
666  auto ElementSizeAndAction =
667  findAction(ElemSizeVec, Aspect.Type.getScalarSizeInBits());
668  IntermediateType =
669  LLT::vector(Aspect.Type.getNumElements(), ElementSizeAndAction.first);
670  if (ElementSizeAndAction.second != Legal)
671  return {ElementSizeAndAction.second, IntermediateType};
672 
673  auto i = NumElements2Actions[OpcodeIdx].find(
674  IntermediateType.getScalarSizeInBits());
675  if (i == NumElements2Actions[OpcodeIdx].end()) {
676  return {NotFound, IntermediateType};
677  }
678  const SizeAndActionsVec &NumElementsVec = (*i).second[TypeIdx];
679  auto NumElementsAndAction =
680  findAction(NumElementsVec, IntermediateType.getNumElements());
681  return {NumElementsAndAction.second,
682  LLT::vector(NumElementsAndAction.first,
683  IntermediateType.getScalarSizeInBits())};
684 }
685 
687  return SmallTy.isByteSized() ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
688 }
689 
690 /// \pre Type indices of every opcode form a dense set starting from 0.
691 void LegalizerInfo::verify(const MCInstrInfo &MII) const {
692 #ifndef NDEBUG
693  std::vector<unsigned> FailedOpcodes;
694  for (unsigned Opcode = FirstOp; Opcode <= LastOp; ++Opcode) {
695  const MCInstrDesc &MCID = MII.get(Opcode);
696  const unsigned NumTypeIdxs = std::accumulate(
697  MCID.opInfo_begin(), MCID.opInfo_end(), 0U,
698  [](unsigned Acc, const MCOperandInfo &OpInfo) {
699  return OpInfo.isGenericType()
700  ? std::max(OpInfo.getGenericTypeIndex() + 1U, Acc)
701  : Acc;
702  });
703  const unsigned NumImmIdxs = std::accumulate(
704  MCID.opInfo_begin(), MCID.opInfo_end(), 0U,
705  [](unsigned Acc, const MCOperandInfo &OpInfo) {
706  return OpInfo.isGenericImm()
707  ? std::max(OpInfo.getGenericImmIndex() + 1U, Acc)
708  : Acc;
709  });
710  LLVM_DEBUG(dbgs() << MII.getName(Opcode) << " (opcode " << Opcode
711  << "): " << NumTypeIdxs << " type ind"
712  << (NumTypeIdxs == 1 ? "ex" : "ices") << ", "
713  << NumImmIdxs << " imm ind"
714  << (NumImmIdxs == 1 ? "ex" : "ices") << "\n");
715  const LegalizeRuleSet &RuleSet = getActionDefinitions(Opcode);
716  if (!RuleSet.verifyTypeIdxsCoverage(NumTypeIdxs))
717  FailedOpcodes.push_back(Opcode);
718  else if (!RuleSet.verifyImmIdxsCoverage(NumImmIdxs))
719  FailedOpcodes.push_back(Opcode);
720  }
721  if (!FailedOpcodes.empty()) {
722  errs() << "The following opcodes have ill-defined legalization rules:";
723  for (unsigned Opcode : FailedOpcodes)
724  errs() << " " << MII.getName(Opcode);
725  errs() << "\n";
726 
727  report_fatal_error("ill-defined LegalizerInfo"
728  ", try -debug-only=legalizer-info for details");
729  }
730 #endif
731 }
732 
733 #ifndef NDEBUG
734 // FIXME: This should be in the MachineVerifier, but it can't use the
735 // LegalizerInfo as it's currently in the separate GlobalISel library.
736 // Note that RegBankSelected property already checked in the verifier
737 // has the same layering problem, but we only use inline methods so
738 // end up not needing to link against the GlobalISel library.
740  if (const LegalizerInfo *MLI = MF.getSubtarget().getLegalizerInfo()) {
741  const MachineRegisterInfo &MRI = MF.getRegInfo();
742  for (const MachineBasicBlock &MBB : MF)
743  for (const MachineInstr &MI : MBB)
744  if (isPreISelGenericOpcode(MI.getOpcode()) &&
745  !MLI->isLegalOrCustom(MI, MRI))
746  return &MI;
747  }
748  return nullptr;
749 }
750 #endif
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
i
i
Definition: README.txt:29
llvm::SmallBitVector::set
SmallBitVector & set()
Definition: SmallBitVector.h:363
llvm::InstrAspect
Legalization is decided based on an instruction's opcode, which type slot we're considering,...
Definition: LegalizerInfo.h:106
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
MachineInstr.h
MathExtras.h
llvm
Definition: AllocatorList.h:23
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:275
llvm::LegalizerInfo::getOpcodeIdxForOpcode
unsigned getOpcodeIdxForOpcode(unsigned Opcode) const
Definition: LegalizerInfo.cpp:412
llvm::LLT::getScalarSizeInBits
unsigned getScalarSizeInBits() const
Definition: LowLevelTypeImpl.h:163
llvm::LegalizerInfo::setLegalizeScalarToDifferentSizeStrategy
void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode, const unsigned TypeIdx, SizeChangeStrategy S)
The setAction calls record the non-size-changing legalization actions to take on specificly-sized typ...
Definition: LegalizerInfo.h:1106
MCInstrDesc.h
llvm::LegalizeActions::MoreElements
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
Definition: LegalizerInfo.h:69
llvm::LegalizerInfo::getActionDefinitionsBuilder
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
Definition: LegalizerInfo.cpp:435
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::LegalizeActionStep::Action
LegalizeAction Action
The action to take or the final answer.
Definition: LegalizerInfo.h:152
llvm::MCInstrDesc::opInfo_end
const_opInfo_iterator opInfo_end() const
Definition: MCInstrDesc.h:234
llvm::LegalizeActionStep
The result of a query.
Definition: LegalizerInfo.h:150
llvm::LegalizerInfo::unsupportedForDifferentSizes
static SizeAndActionsVec unsupportedForDifferentSizes(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular operation consists of on...
Definition: LegalizerInfo.h:1136
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::LegalizerInfo::LegalizerInfo
LegalizerInfo()
Definition: LegalizerInfo.cpp:259
llvm::isPreISelGenericOpcode
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
Definition: TargetOpcodes.h:30
ErrorHandling.h
llvm::LegalizeActions::NarrowScalar
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
Definition: LegalizerInfo.h:53
llvm::DisableGISelLegalityCheck
cl::opt< bool > DisableGISelLegalityCheck
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::LegalizerInfo::SizeChangeStrategy
std::function< SizeAndActionsVec(const SizeAndActionsVec &v)> SizeChangeStrategy
Definition: LegalizerInfo.h:1075
llvm::LLT::getScalarType
LLT getScalarType() const
Definition: LowLevelTypeImpl.h:121
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
llvm::RTLIB::Libcall
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Definition: RuntimeLibcalls.h:30
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
llvm::LegalizeActions::WidenScalar
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:58
llvm::LegalizeActions::UseLegacyRules
@ UseLegacyRules
Fall back onto the old rules.
Definition: LegalizerInfo.h:96
llvm::LLT::isByteSized
bool isByteSized() const
Definition: LowLevelTypeImpl.h:161
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
llvm::LegalizerInfo::SizeAndAction
std::pair< uint16_t, LegalizeAction > SizeAndAction
Definition: LegalizerInfo.h:1072
LegalizerInfo.h
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:122
MachineRegisterInfo.h
result
It looks like we only need to define PPCfmarto for these because according to these instructions perform RTO on fma s result
Definition: README_P9.txt:256
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
llvm::LegalizeRuleSet::apply
LegalizeActionStep apply(const LegalityQuery &Query) const
Apply the ruleset to the given LegalityQuery.
Definition: LegalizerInfo.cpp:190
llvm::SmallBitVector
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
Definition: SmallBitVector.h:34
llvm::MCOperandInfo
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:84
llvm::LegalizerInfo::widenToLargerTypesAndNarrowToLargest
static SizeAndActionsVec widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular operation consists of wi...
Definition: LegalizerInfo.h:1147
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:565
llvm::LegalizerInfo::widenToLargerTypesUnsupportedOtherwise
static SizeAndActionsVec widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v)
Definition: LegalizerInfo.h:1157
llvm::LegalizeRule
A single rule in a legalizer info ruleset.
Definition: LegalizerInfo.h:338
llvm::LegalizeRuleSet::aliasTo
void aliasTo(unsigned Opcode)
Definition: LegalizerInfo.h:522
llvm::LegalizeActions::NotFound
@ NotFound
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:92
llvm::LLT::getSizeInBits
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:109
MCInstrInfo.h
false
Definition: StackSlotColoring.cpp:142
TargetOpcodes.h
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:196
llvm::LegalizeRuleSet
Definition: LegalizerInfo.h:363
llvm::machineFunctionIsIllegal
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it's not, nullptr otherwise.
Definition: LegalizerInfo.cpp:739
llvm::report_fatal_error
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:50
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:230
llvm::LegalizeActions::Libcall
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
Definition: LegalizerInfo.h:81
llvm::LLT::vector
static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
Definition: LowLevelTypeImpl.h:58
llvm::LegalizeActions::Custom
@ Custom
The target wants to do something special with this combination of operand and type.
Definition: LegalizerInfo.h:85
llvm::LegalizerInfo::getExtOpcodeForWideningConstant
virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const
Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while widening a constant of type Small...
Definition: LegalizerInfo.cpp:686
llvm::LegalizeActions::Legal
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:48
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
LowLevelTypeImpl.h
llvm::LLT::getAddressSpace
unsigned getAddressSpace() const
Definition: LowLevelTypeImpl.h:178
llvm::LegalizerInfo::moreToWiderTypesAndLessToWidest
static SizeAndActionsVec moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular vector operation consist...
Definition: LegalizerInfo.h:1199
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:555
llvm::cl::opt< bool >
llvm::InstrAspect::Opcode
unsigned Opcode
Definition: LegalizerInfo.h:107
llvm::IRSimilarity::Legal
@ Legal
Definition: IRSimilarityIdentifier.h:75
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::LegalizeActions::Bitcast
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition: LegalizerInfo.h:72
llvm::LLT::isVector
bool isVector() const
Definition: LowLevelTypeImpl.h:96
llvm::LLT::getNumElements
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelTypeImpl.h:100
llvm::LegalizeRuleSet::verifyImmIdxsCoverage
bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const
Check if there is no imm index which is obviously not handled by the LegalizeRuleSet in any way at al...
Definition: LegalizerInfo.cpp:237
getTypeFromTypeIdx
static LLT getTypeFromTypeIdx(const MachineInstr &MI, const MachineRegisterInfo &MRI, unsigned OpIdx, unsigned TypeIdx)
Helper function to get LLT for the given type index.
Definition: LegalizerInfo.cpp:400
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::LLT::isPointer
bool isPointer() const
Definition: LowLevelTypeImpl.h:94
llvm::LegalizerInfo::getAction
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
Definition: LegalizerInfo.cpp:466
llvm::LegalizeActions::LegalizeAction
LegalizeAction
Definition: LegalizerInfo.h:45
llvm::LegalizerInfo::SizeAndActionsVec
std::vector< SizeAndAction > SizeAndActionsVec
Definition: LegalizerInfo.h:1073
hasNoSimpleLoops
static bool hasNoSimpleLoops(const LegalizeRule &Rule, const LegalityQuery &Q, const std::pair< unsigned, LLT > &Mutation)
Definition: LegalizerInfo.cpp:105
llvm::MCInstrInfo::getName
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
Definition: MCInstrInfo.h:68
llvm::LLT::isScalar
bool isScalar() const
Definition: LowLevelTypeImpl.h:92
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::LegalizerInfo::increaseToLargerTypesAndDecreaseToLargest
static SizeAndActionsVec increaseToLargerTypesAndDecreaseToLargest(const SizeAndActionsVec &v, LegalizeAction IncreaseAction, LegalizeAction DecreaseAction)
Helper function to implement many typical SizeChangeStrategy functions.
Definition: LegalizerInfo.cpp:530
llvm::LegalityQuery::Opcode
unsigned Opcode
Definition: LegalizerInfo.h:125
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1486
llvm::LegalityQuery
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
Definition: LegalizerInfo.h:124
llvm::LegalizerInfo::needsLegalizingToDifferentSize
static bool needsLegalizingToDifferentSize(const LegalizeAction Action)
Definition: LegalizerInfo.h:1058
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
Mutation
PowerPC VSX FMA Mutation
Definition: PPCVSXFMAMutate.cpp:391
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:281
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::partition_point
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Definition: STLExtras.h:1653
llvm::TargetSubtargetInfo::getLegalizerInfo
virtual const LegalizerInfo * getLegalizerInfo() const
Definition: TargetSubtargetInfo.h:120
llvm::MCOperandInfo::getGenericTypeIndex
unsigned getGenericTypeIndex() const
Definition: MCInstrDesc.h:122
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
llvm::empty
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Definition: STLExtras.h:263
uint16_t
llvm::LegalizeRule::getAction
LegalizeAction getAction() const
Definition: LegalizerInfo.h:353
llvm::LegalizeRuleSet::verifyTypeIdxsCoverage
bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const
Check if there is no type index which is obviously not handled by the LegalizeRuleSet in any way at a...
Definition: LegalizerInfo.cpp:214
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1446
llvm::LegalizeActions::FewerElements
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:63
llvm::LegalizerInfo::narrowToSmallerAndUnsupportedIfTooSmall
static SizeAndActionsVec narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v)
Definition: LegalizerInfo.h:1164
llvm::MCInstrDesc::opInfo_begin
const_opInfo_iterator opInfo_begin() const
Definition: MCInstrDesc.h:233
llvm::LegalizerInfo::verify
void verify(const MCInstrInfo &MII) const
Perform simple self-diagnostic and assert if there is anything obviously wrong with the actions set u...
Definition: LegalizerInfo.cpp:691
llvm::LegalityQuery::print
raw_ostream & print(raw_ostream &OS) const
Definition: LegalizerInfo.cpp:87
llvm::InstrAspect::Type
LLT Type
Definition: LegalizerInfo.h:109
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:732
llvm::LegalityQuery::Types
ArrayRef< LLT > Types
Definition: LegalizerInfo.h:126
llvm::LegalizerInfo::aliasActionDefinitions
void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom)
Definition: LegalizerInfo.cpp:457
llvm::LegalizerInfo::getActionDefinitions
const LegalizeRuleSet & getActionDefinitions(unsigned Opcode) const
Get the action definitions for the given opcode.
Definition: LegalizerInfo.cpp:430
llvm::LegalizerInfo::isLegalOrCustom
bool isLegalOrCustom(const LegalityQuery &Query) const
Definition: LegalizerInfo.h:1261
SmallBitVector.h
llvm::LegalizeActions::Unsupported
@ Unsupported
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:89
MachineOperand.h
llvm::LegalizerInfo
Definition: LegalizerInfo.h:1041
llvm::LegalizerInfo::computeTables
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
Definition: LegalizerInfo.cpp:294
mutationIsSane
static bool mutationIsSane(const LegalizeRule &Rule, const LegalityQuery &Q, std::pair< unsigned, LLT > Mutation)
Definition: LegalizerInfo.cpp:121
llvm::MCInstrInfo::get
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:62
GISelChangeObserver.h
llvm::cl::desc
Definition: CommandLine.h:411
llvm::InstrAspect::Idx
unsigned Idx
Definition: LegalizerInfo.h:108
llvm::LegalizeActions::Lower
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:76
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:43
llvm::LegalizerInfo::decreaseToSmallerTypesAndIncreaseToSmallest
static SizeAndActionsVec decreaseToSmallerTypesAndIncreaseToSmallest(const SizeAndActionsVec &v, LegalizeAction DecreaseAction, LegalizeAction IncreaseAction)
Helper function to implement many typical SizeChangeStrategy functions.
Definition: LegalizerInfo.cpp:550
llvm::LegalizerInfo::isLegal
bool isLegal(const LegalityQuery &Query) const
Definition: LegalizerInfo.h:1257
Debug.h
llvm::LegalizerInfo::getActionDefinitionsIdx
unsigned getActionDefinitionsIdx(unsigned Opcode) const
Definition: LegalizerInfo.cpp:417
llvm::LLT
Definition: LowLevelTypeImpl.h:40