15#ifndef LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
16#define LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
21#include <unordered_map>
27namespace LegacyLegalizeActions {
115 std::tie(
RHS.Action,
RHS.TypeIdx,
RHS.NewType);
123 std::pair<uint16_t, LegacyLegalizeActions::LegacyLegalizeAction>;
132 using namespace LegacyLegalizeActions;
157 TablesInitialized =
false;
158 const unsigned OpcodeIdx = Aspect.
Opcode - FirstOp;
159 if (SpecifiedActions[OpcodeIdx].
size() <= Aspect.
Idx)
160 SpecifiedActions[OpcodeIdx].resize(Aspect.
Idx + 1);
161 SpecifiedActions[OpcodeIdx][Aspect.
Idx][Aspect.
Type] = Action;
181 const unsigned TypeIdx,
183 const unsigned OpcodeIdx = Opcode - FirstOp;
184 if (ScalarSizeChangeStrategies[OpcodeIdx].
size() <= TypeIdx)
185 ScalarSizeChangeStrategies[OpcodeIdx].
resize(TypeIdx + 1);
186 ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
192 const unsigned TypeIdx,
194 const unsigned OpcodeIdx = Opcode - FirstOp;
195 if (VectorElementSizeChangeStrategies[OpcodeIdx].
size() <= TypeIdx)
196 VectorElementSizeChangeStrategies[OpcodeIdx].
resize(TypeIdx + 1);
197 VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
211 using namespace LegacyLegalizeActions;
222 using namespace LegacyLegalizeActions;
224 "At least one size that can be legalized towards is needed"
225 " for this SizeChangeStrategy");
232 using namespace LegacyLegalizeActions;
239 using namespace LegacyLegalizeActions;
264 using namespace LegacyLegalizeActions;
291 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
311 void setScalarAction(
const unsigned Opcode,
const unsigned TypeIndex,
313 const unsigned OpcodeIdx = Opcode - FirstOp;
315 setActions(TypeIndex, Actions, SizeAndActions);
317 void setPointerAction(
const unsigned Opcode,
const unsigned TypeIndex,
320 const unsigned OpcodeIdx = Opcode - FirstOp;
321 SmallVector<SizeAndActionsVec, 1> &Actions =
323 setActions(TypeIndex, Actions, SizeAndActions);
331 void setScalarInVectorAction(
const unsigned Opcode,
const unsigned TypeIndex,
333 unsigned OpcodeIdx = Opcode - FirstOp;
334 SmallVector<SizeAndActionsVec, 1> &Actions =
335 ScalarInVectorActions[OpcodeIdx];
336 setActions(TypeIndex, Actions, SizeAndActions);
342 void setVectorNumElementAction(
const unsigned Opcode,
343 const unsigned TypeIndex,
344 const unsigned ElementSize,
346 const unsigned OpcodeIdx = Opcode - FirstOp;
347 SmallVector<SizeAndActionsVec, 1> &Actions =
348 NumElements2Actions[OpcodeIdx][ElementSize];
349 setActions(TypeIndex, Actions, SizeAndActions);
355 using namespace LegacyLegalizeActions;
368 int SmallestNarrowIdx = -1;
369 int LargestWidenIdx = -1;
370 int SmallestLegalizableToSameSizeIdx = -1;
371 int LargestLegalizableToSameSizeIdx = -1;
372 for(
size_t i=0; i<
v.size(); ++i) {
373 switch (v[i].second) {
376 if (SmallestNarrowIdx == -1)
377 SmallestNarrowIdx = i;
386 if (SmallestLegalizableToSameSizeIdx == -1)
387 SmallestLegalizableToSameSizeIdx = i;
388 LargestLegalizableToSameSizeIdx = i;
391 if (SmallestNarrowIdx != -1) {
392 assert(SmallestLegalizableToSameSizeIdx != -1);
393 assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
395 if (LargestWidenIdx != -1)
396 assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
407 checkPartialSizeAndActionsVector(v);
413 void setActions(
unsigned TypeIndex,
414 SmallVector<SizeAndActionsVec, 1> &Actions,
416 checkFullSizeAndActionsVector(SizeAndActions);
417 if (Actions.size() <= TypeIndex)
418 Actions.resize(TypeIndex + 1);
419 Actions[TypeIndex] = SizeAndActions;
436 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
437 findScalarLegalAction(
const InstrAspect &Aspect)
const;
440 std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
441 findVectorLegalAction(
const InstrAspect &Aspect)
const;
443 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
444 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
447 using TypeMap = DenseMap<LLT, LegacyLegalizeActions::LegacyLegalizeAction>;
448 SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
449 SmallVector<SizeChangeStrategy, 1>
450 ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
451 SmallVector<SizeChangeStrategy, 1>
452 VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
453 bool TablesInitialized =
false;
456 SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
457 SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
458 std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
459 AddrSpace2PointerActions[LastOp - FirstOp + 1];
460 std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
461 NumElements2Actions[LastOp - FirstOp + 1];
This file defines the DenseMap class.
Implement a low-level type suitable for MachineInstr level instruction selection.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 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
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...