15#ifndef LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
16#define LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
22#include <unordered_map>
28namespace LegacyLegalizeActions {
116 std::tie(
RHS.Action,
RHS.TypeIdx,
RHS.NewType);
124 std::pair<uint16_t, LegacyLegalizeActions::LegacyLegalizeAction>;
133 using namespace LegacyLegalizeActions;
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;
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;
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;
212 using namespace LegacyLegalizeActions;
223 using namespace LegacyLegalizeActions;
225 "At least one size that can be legalized towards is needed"
226 " for this SizeChangeStrategy");
233 using namespace LegacyLegalizeActions;
240 using namespace LegacyLegalizeActions;
265 using namespace LegacyLegalizeActions;
292 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
312 void setScalarAction(
const unsigned Opcode,
const unsigned TypeIndex,
314 const unsigned OpcodeIdx = Opcode - FirstOp;
316 setActions(TypeIndex, Actions, SizeAndActions);
318 void setPointerAction(
const unsigned Opcode,
const unsigned TypeIndex,
321 const unsigned OpcodeIdx = Opcode - FirstOp;
322 SmallVector<SizeAndActionsVec, 1> &Actions =
324 setActions(TypeIndex, Actions, SizeAndActions);
332 void setScalarInVectorAction(
const unsigned Opcode,
const unsigned TypeIndex,
334 unsigned OpcodeIdx = Opcode - FirstOp;
335 SmallVector<SizeAndActionsVec, 1> &Actions =
336 ScalarInVectorActions[OpcodeIdx];
337 setActions(TypeIndex, Actions, SizeAndActions);
343 void setVectorNumElementAction(
const unsigned Opcode,
344 const unsigned TypeIndex,
345 const unsigned ElementSize,
347 const unsigned OpcodeIdx = Opcode - FirstOp;
348 SmallVector<SizeAndActionsVec, 1> &Actions =
349 NumElements2Actions[OpcodeIdx][ElementSize];
350 setActions(TypeIndex, Actions, SizeAndActions);
356 using namespace LegacyLegalizeActions;
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) {
377 if (SmallestNarrowIdx == -1)
378 SmallestNarrowIdx = i;
387 if (SmallestLegalizableToSameSizeIdx == -1)
388 SmallestLegalizableToSameSizeIdx = i;
389 LargestLegalizableToSameSizeIdx = i;
392 if (SmallestNarrowIdx != -1) {
393 assert(SmallestLegalizableToSameSizeIdx != -1);
394 assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
396 if (LargestWidenIdx != -1)
397 assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
408 checkPartialSizeAndActionsVector(v);
414 void setActions(
unsigned TypeIndex,
415 SmallVector<SizeAndActionsVec, 1> &Actions,
417 checkFullSizeAndActionsVector(SizeAndActions);
418 if (Actions.size() <= TypeIndex)
419 Actions.resize(TypeIndex + 1);
420 Actions[TypeIndex] = SizeAndActions;
437 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
438 findScalarLegalAction(
const InstrAspect &Aspect)
const;
441 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
442 findVectorLegalAction(
const InstrAspect &Aspect)
const;
444 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
445 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
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;
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];
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the DenseMap class.
Implement a low-level type suitable for MachineInstr level instruction selection.
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
LLVM_ABI LegacyLegalizerInfo()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
@ 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.
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.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
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...