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