LLVM 22.0.0git
LegacyLegalizerInfo.h
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.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/// \file
9/// Interface for Targets to specify which operations they can successfully
10/// select and how the others should be expanded most efficiently.
11/// This implementation has been deprecated for a long time but it still in use
12/// in a few places.
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
16#define LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
17
18#include "llvm/ADT/DenseMap.h"
22#include <unordered_map>
23#include <vector>
24
25namespace llvm {
26struct LegalityQuery;
27
28namespace LegacyLegalizeActions {
29enum LegacyLegalizeAction : std::uint8_t {
30 /// The operation is expected to be selectable directly by the target, and
31 /// no transformation is necessary.
33
34 /// The operation should be synthesized from multiple instructions acting on
35 /// a narrower scalar base-type. For example a 64-bit add might be
36 /// implemented in terms of 32-bit add-with-carry.
38
39 /// The operation should be implemented in terms of a wider scalar
40 /// base-type. For example a <2 x s8> add could be implemented as a <2
41 /// x s32> add (ignoring the high bits).
43
44 /// The (vector) operation should be implemented by splitting it into
45 /// sub-vectors where the operation is legal. For example a <8 x s64> add
46 /// might be implemented as 4 separate <2 x s64> adds.
48
49 /// The (vector) operation should be implemented by widening the input
50 /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
51 /// rarely legal, but you might perform an <8 x i8> and then only look at
52 /// the first two results.
54
55 /// Perform the operation on a different, but equivalently sized type.
57
58 /// The operation itself must be expressed in terms of simpler actions on
59 /// this target. E.g. a SREM replaced by an SDIV and subtraction.
61
62 /// The operation should be implemented as a call to some kind of runtime
63 /// support library. For example this usually happens on machines that don't
64 /// support floating-point operations natively.
66
67 /// The target wants to do something special with this combination of
68 /// operand and type. A callback will be issued when it is needed.
70
71 /// This operation is completely unsupported on the target. A programming
72 /// error has occurred.
74
75 /// Sentinel value for when no action was found in the specified table.
77};
78} // end namespace LegacyLegalizeActions
79LLVM_ABI raw_ostream &
81
82/// Legalization is decided based on an instruction's opcode, which type slot
83/// we're considering, and what the existing type is. These aspects are gathered
84/// together for convenience in the InstrAspect class.
86 unsigned Opcode;
87 unsigned Idx = 0;
89
91 InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
92 : Opcode(Opcode), Idx(Idx), Type(Type) {}
93
94 bool operator==(const InstrAspect &RHS) const {
95 return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
96 }
97};
98
99/// The result of a query. It either indicates a final answer of Legal or
100/// Unsupported or describes an action that must be taken to make an operation
101/// more legal.
103 /// The action to take or the final answer.
105 /// If describing an action, the type index to change. Otherwise zero.
106 unsigned TypeIdx;
107 /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
109
111 unsigned TypeIdx, const LLT NewType)
113
115 return std::tie(Action, TypeIdx, NewType) ==
116 std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
117 }
118};
119
120
122public:
124 std::pair<uint16_t, LegacyLegalizeActions::LegacyLegalizeAction>;
125 using SizeAndActionsVec = std::vector<SizeAndAction>;
127 std::function<SizeAndActionsVec(const SizeAndActionsVec &v)>;
128
130
133 using namespace LegacyLegalizeActions;
134 switch (Action) {
135 case NarrowScalar:
136 case WidenScalar:
137 case FewerElements:
138 case MoreElements:
139 case Unsupported:
140 return true;
141 default:
142 return false;
143 }
144 }
145
146 /// Compute any ancillary tables needed to quickly decide how an operation
147 /// should be handled. This must be called after all "set*Action"methods but
148 /// before any query is made or incorrect results may be returned.
149 LLVM_ABI void computeTables();
150
151 /// More friendly way to set an action for common types that have an LLT
152 /// representation.
153 /// The LegacyLegalizeAction must be one for which
154 /// NeedsLegalizingToDifferentSize returns false.
155 void setAction(const InstrAspect &Aspect,
158 TablesInitialized = false;
159 const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;
160 if (SpecifiedActions[OpcodeIdx].size() <= Aspect.Idx)
161 SpecifiedActions[OpcodeIdx].resize(Aspect.Idx + 1);
162 SpecifiedActions[OpcodeIdx][Aspect.Idx][Aspect.Type] = Action;
163 }
164
165 /// The setAction calls record the non-size-changing legalization actions
166 /// to take on specificly-sized types. The SizeChangeStrategy defines what
167 /// to do when the size of the type needs to be changed to reach a legally
168 /// sized type (i.e., one that was defined through a setAction call).
169 /// e.g.
170 /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);
171 /// setLegalizeScalarToDifferentSizeStrategy(
172 /// G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
173 /// will end up defining getAction({G_ADD, 0, T}) to return the following
174 /// actions for different scalar types T:
175 /// LLT::scalar(1)..LLT::scalar(31): {WidenScalar, 0, LLT::scalar(32)}
176 /// LLT::scalar(32): {Legal, 0, LLT::scalar(32)}
177 /// LLT::scalar(33)..: {NarrowScalar, 0, LLT::scalar(32)}
178 ///
179 /// If no SizeChangeAction gets defined, through this function,
180 /// the default is unsupportedForDifferentSizes.
182 const unsigned TypeIdx,
184 const unsigned OpcodeIdx = Opcode - FirstOp;
185 if (ScalarSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
186 ScalarSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
187 ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
188 }
189
190 /// See also setLegalizeScalarToDifferentSizeStrategy.
191 /// This function allows to set the SizeChangeStrategy for vector elements.
193 const unsigned TypeIdx,
195 const unsigned OpcodeIdx = Opcode - FirstOp;
196 if (VectorElementSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
197 VectorElementSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
198 VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
199 }
200
201 /// A SizeChangeStrategy for the common case where legalization for a
202 /// particular operation consists of only supporting a specific set of type
203 /// sizes. E.g.
204 /// setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);
205 /// setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);
206 /// setLegalizeScalarToDifferentSizeStrategy(
207 /// G_DIV, 0, unsupportedForDifferentSizes);
208 /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,
209 /// and Unsupported for all other scalar types T.
210 static SizeAndActionsVec
212 using namespace LegacyLegalizeActions;
213 return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
214 Unsupported);
215 }
216
217 /// A SizeChangeStrategy for the common case where legalization for a
218 /// particular operation consists of widening the type to a large legal type,
219 /// unless there is no such type and then instead it should be narrowed to the
220 /// largest legal type.
221 static SizeAndActionsVec
223 using namespace LegacyLegalizeActions;
224 assert(v.size() > 0 &&
225 "At least one size that can be legalized towards is needed"
226 " for this SizeChangeStrategy");
227 return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
228 NarrowScalar);
229 }
230
231 static SizeAndActionsVec
233 using namespace LegacyLegalizeActions;
234 return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
235 Unsupported);
236 }
237
238 static SizeAndActionsVec
240 using namespace LegacyLegalizeActions;
241 return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
242 Unsupported);
243 }
244
245 /// A SizeChangeStrategy for the common case where legalization for a
246 /// particular vector operation consists of having more elements in the
247 /// vector, to a type that is legal. Unless there is no such type and then
248 /// instead it should be legalized towards the widest vector that's still
249 /// legal. E.g.
250 /// setAction({G_ADD, LLT::vector(8, 8)}, Legal);
251 /// setAction({G_ADD, LLT::vector(16, 8)}, Legal);
252 /// setAction({G_ADD, LLT::vector(2, 32)}, Legal);
253 /// setAction({G_ADD, LLT::vector(4, 32)}, Legal);
254 /// setLegalizeVectorElementToDifferentSizeStrategy(
255 /// G_ADD, 0, moreToWiderTypesAndLessToWidest);
256 /// will result in the following getAction results:
257 /// * getAction({G_ADD, LLT::vector(8,8)}) returns
258 /// (Legal, vector(8,8)).
259 /// * getAction({G_ADD, LLT::vector(9,8)}) returns
260 /// (MoreElements, vector(16,8)).
261 /// * getAction({G_ADD, LLT::vector(8,32)}) returns
262 /// (FewerElements, vector(4,32)).
263 static SizeAndActionsVec
265 using namespace LegacyLegalizeActions;
266 return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
267 FewerElements);
268 }
269
270 /// Helper function to implement many typical SizeChangeStrategy functions.
272 const SizeAndActionsVec &v,
275 /// Helper function to implement many typical SizeChangeStrategy functions.
277 const SizeAndActionsVec &v,
280
282
283 LLVM_ABI unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
284
285private:
286 /// Determine what action should be taken to legalize the given generic
287 /// instruction opcode, type-index and type. Requires computeTables to have
288 /// been called.
289 ///
290 /// \returns a pair consisting of the kind of legalization that should be
291 /// performed and the destination type.
292 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
293 getAspectAction(const InstrAspect &Aspect) const;
294
295 /// The SizeAndActionsVec is a representation mapping between all natural
296 /// numbers and an Action. The natural number represents the bit size of
297 /// the InstrAspect. For example, for a target with native support for 32-bit
298 /// and 64-bit additions, you'd express that as:
299 /// setScalarAction(G_ADD, 0,
300 /// {{1, WidenScalar}, // bit sizes [ 1, 31[
301 /// {32, Legal}, // bit sizes [32, 33[
302 /// {33, WidenScalar}, // bit sizes [33, 64[
303 /// {64, Legal}, // bit sizes [64, 65[
304 /// {65, NarrowScalar} // bit sizes [65, +inf[
305 /// });
306 /// It may be that only 64-bit pointers are supported on your target:
307 /// setPointerAction(G_PTR_ADD, 0, LLT:pointer(1),
308 /// {{1, Unsupported}, // bit sizes [ 1, 63[
309 /// {64, Legal}, // bit sizes [64, 65[
310 /// {65, Unsupported}, // bit sizes [65, +inf[
311 /// });
312 void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,
313 const SizeAndActionsVec &SizeAndActions) {
314 const unsigned OpcodeIdx = Opcode - FirstOp;
315 SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];
316 setActions(TypeIndex, Actions, SizeAndActions);
317 }
318 void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,
319 const unsigned AddressSpace,
320 const SizeAndActionsVec &SizeAndActions) {
321 const unsigned OpcodeIdx = Opcode - FirstOp;
322 SmallVector<SizeAndActionsVec, 1> &Actions =
323 AddrSpace2PointerActions[OpcodeIdx][AddressSpace];
324 setActions(TypeIndex, Actions, SizeAndActions);
325 }
326
327 /// If an operation on a given vector type (say <M x iN>) isn't explicitly
328 /// specified, we proceed in 2 stages. First we legalize the underlying scalar
329 /// (so that there's at least one legal vector with that scalar), then we
330 /// adjust the number of elements in the vector so that it is legal. The
331 /// desired action in the first step is controlled by this function.
332 void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,
333 const SizeAndActionsVec &SizeAndActions) {
334 unsigned OpcodeIdx = Opcode - FirstOp;
335 SmallVector<SizeAndActionsVec, 1> &Actions =
336 ScalarInVectorActions[OpcodeIdx];
337 setActions(TypeIndex, Actions, SizeAndActions);
338 }
339
340 /// See also setScalarInVectorAction.
341 /// This function let's you specify the number of elements in a vector that
342 /// are legal for a legal element size.
343 void setVectorNumElementAction(const unsigned Opcode,
344 const unsigned TypeIndex,
345 const unsigned ElementSize,
346 const SizeAndActionsVec &SizeAndActions) {
347 const unsigned OpcodeIdx = Opcode - FirstOp;
348 SmallVector<SizeAndActionsVec, 1> &Actions =
349 NumElements2Actions[OpcodeIdx][ElementSize];
350 setActions(TypeIndex, Actions, SizeAndActions);
351 }
352
353 /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
354 /// i.e. it's OK if it doesn't start from size 1.
355 static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
356 using namespace LegacyLegalizeActions;
357#ifndef NDEBUG
358 // The sizes should be in increasing order
359 int prev_size = -1;
360 for(auto SizeAndAction: v) {
361 assert(SizeAndAction.first > prev_size);
362 prev_size = SizeAndAction.first;
363 }
364 // - for every Widen action, there should be a larger bitsize that
365 // can be legalized towards (e.g. Legal, Lower, Libcall or Custom
366 // action).
367 // - for every Narrow action, there should be a smaller bitsize that
368 // can be legalized towards.
369 int SmallestNarrowIdx = -1;
370 int LargestWidenIdx = -1;
371 int SmallestLegalizableToSameSizeIdx = -1;
372 int LargestLegalizableToSameSizeIdx = -1;
373 for(size_t i=0; i<v.size(); ++i) {
374 switch (v[i].second) {
375 case FewerElements:
376 case NarrowScalar:
377 if (SmallestNarrowIdx == -1)
378 SmallestNarrowIdx = i;
379 break;
380 case WidenScalar:
381 case MoreElements:
382 LargestWidenIdx = i;
383 break;
384 case Unsupported:
385 break;
386 default:
387 if (SmallestLegalizableToSameSizeIdx == -1)
388 SmallestLegalizableToSameSizeIdx = i;
389 LargestLegalizableToSameSizeIdx = i;
390 }
391 }
392 if (SmallestNarrowIdx != -1) {
393 assert(SmallestLegalizableToSameSizeIdx != -1);
394 assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
395 }
396 if (LargestWidenIdx != -1)
397 assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
398#endif
399 }
400
401 /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with
402 /// from size 1.
403 static void checkFullSizeAndActionsVector(const SizeAndActionsVec& v) {
404#ifndef NDEBUG
405 // Data structure invariant: The first bit size must be size 1.
406 assert(v.size() >= 1);
407 assert(v[0].first == 1);
408 checkPartialSizeAndActionsVector(v);
409#endif
410 }
411
412 /// Sets actions for all bit sizes on a particular generic opcode, type
413 /// index and scalar or pointer type.
414 void setActions(unsigned TypeIndex,
415 SmallVector<SizeAndActionsVec, 1> &Actions,
416 const SizeAndActionsVec &SizeAndActions) {
417 checkFullSizeAndActionsVector(SizeAndActions);
418 if (Actions.size() <= TypeIndex)
419 Actions.resize(TypeIndex + 1);
420 Actions[TypeIndex] = SizeAndActions;
421 }
422
423 static SizeAndAction findAction(const SizeAndActionsVec &Vec,
424 const uint32_t Size);
425
426 /// Returns the next action needed to get the scalar or pointer type closer
427 /// to being legal
428 /// E.g. findLegalAction({G_REM, 13}) should return
429 /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will
430 /// probably be called, which should return (Lower, 32).
431 /// This is assuming the setScalarAction on G_REM was something like:
432 /// setScalarAction(G_REM, 0,
433 /// {{1, WidenScalar}, // bit sizes [ 1, 31[
434 /// {32, Lower}, // bit sizes [32, 33[
435 /// {33, NarrowScalar} // bit sizes [65, +inf[
436 /// });
437 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
438 findScalarLegalAction(const InstrAspect &Aspect) const;
439
440 /// Returns the next action needed towards legalizing the vector type.
441 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
442 findVectorLegalAction(const InstrAspect &Aspect) const;
443
444 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
445 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
446
447 // Data structures used temporarily during construction of legality data:
448 using TypeMap = DenseMap<LLT, LegacyLegalizeActions::LegacyLegalizeAction>;
449 SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
450 SmallVector<SizeChangeStrategy, 1>
451 ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
452 SmallVector<SizeChangeStrategy, 1>
453 VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
454 bool TablesInitialized = false;
455
456 // Data structures used by getAction:
457 SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
458 SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
459 std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
460 AddrSpace2PointerActions[LastOp - FirstOp + 1];
461 std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
462 NumElements2Actions[LastOp - FirstOp + 1];
463};
464
465} // end namespace llvm
466
467#endif // LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition: Compiler.h:213
This file defines the DenseMap class.
uint64_t Size
Implement a low-level type suitable for MachineInstr level instruction selection.
raw_pwrite_stream & OS
Value * RHS
std::pair< uint16_t, LegacyLegalizeActions::LegacyLegalizeAction > SizeAndAction
static LLVM_ABI SizeAndActionsVec decreaseToSmallerTypesAndIncreaseToSmallest(const SizeAndActionsVec &v, LegacyLegalizeActions::LegacyLegalizeAction DecreaseAction, LegacyLegalizeActions::LegacyLegalizeAction IncreaseAction)
Helper function to implement many typical SizeChangeStrategy functions.
static SizeAndActionsVec widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v)
static SizeAndActionsVec moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular vector operation consist...
LLVM_ABI void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
std::vector< SizeAndAction > SizeAndActionsVec
static bool needsLegalizingToDifferentSize(const LegacyLegalizeActions::LegacyLegalizeAction Action)
LLVM_ABI unsigned getOpcodeIdxForOpcode(unsigned Opcode) const
static SizeAndActionsVec widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular operation consists of wi...
void setAction(const InstrAspect &Aspect, LegacyLegalizeActions::LegacyLegalizeAction Action)
More friendly way to set an action for common types that have an LLT representation.
LLVM_ABI LegacyLegalizeActionStep getAction(const LegalityQuery &Query) const
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...
void setLegalizeVectorElementToDifferentSizeStrategy(const unsigned Opcode, const unsigned TypeIdx, SizeChangeStrategy S)
See also setLegalizeScalarToDifferentSizeStrategy.
static SizeAndActionsVec unsupportedForDifferentSizes(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular operation consists of on...
static LLVM_ABI SizeAndActionsVec increaseToLargerTypesAndDecreaseToLargest(const SizeAndActionsVec &v, LegacyLegalizeActions::LegacyLegalizeAction IncreaseAction, LegacyLegalizeActions::LegacyLegalizeAction DecreaseAction)
Helper function to implement many typical SizeChangeStrategy functions.
static SizeAndActionsVec narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v)
std::function< SizeAndActionsVec(const SizeAndActionsVec &v)> SizeChangeStrategy
void resize(size_type N)
Definition: SmallVector.h:639
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
@ Unsupported
This operation is completely unsupported on the target.
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
@ Custom
The target wants to do something special with this combination of operand and type.
@ NotFound
Sentinel value for when no action was found in the specified table.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:1702
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:312
Legalization is decided based on an instruction's opcode, which type slot we're considering,...
bool operator==(const InstrAspect &RHS) const
InstrAspect(unsigned Opcode, LLT Type)
InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
bool operator==(const LegacyLegalizeActionStep &RHS) const
LegacyLegalizeActions::LegacyLegalizeAction Action
The action to take or the final answer.
unsigned TypeIdx
If describing an action, the type index to change. Otherwise zero.
LegacyLegalizeActionStep(LegacyLegalizeActions::LegacyLegalizeAction Action, unsigned TypeIdx, const LLT NewType)
LLT NewType
If describing an action, the new type for TypeIdx. Otherwise LLT{}.
The LegalityQuery object bundles together all the information that's needed to decide whether a given...