[llvm] aaac268 - [globalisel][legalizer] Separate the deprecated LegalizerInfo from the current one
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 1 13:23:59 PDT 2021
Author: Daniel Sanders
Date: 2021-06-01T13:23:48-07:00
New Revision: aaac268285ff596b4cbffbb1ce8dbe516811eda8
URL: https://github.com/llvm/llvm-project/commit/aaac268285ff596b4cbffbb1ce8dbe516811eda8
DIFF: https://github.com/llvm/llvm-project/commit/aaac268285ff596b4cbffbb1ce8dbe516811eda8.diff
LOG: [globalisel][legalizer] Separate the deprecated LegalizerInfo from the current one
It's still in use in a few places so we can't delete it yet but there's not
many at this point.
Differential Revision: https://reviews.llvm.org/D103352
Added:
llvm/include/llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h
llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
Modified:
llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
llvm/lib/Target/RISCV/RISCVLegalizerInfo.cpp
llvm/lib/Target/X86/X86LegalizerInfo.cpp
llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h
new file mode 100644
index 0000000000000..fb616d2d5fda7
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h
@@ -0,0 +1,479 @@
+//===- llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// Interface for Targets to specify which operations they can successfully
+/// select and how the others should be expanded most efficiently.
+/// This implementation has been deprecated for a long time but it still in use
+/// in a few places.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
+#define LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/Support/LowLevelTypeImpl.h"
+#include <unordered_map>
+
+namespace llvm {
+struct LegalityQuery;
+
+namespace LegacyLegalizeActions {
+enum LegacyLegalizeAction : std::uint8_t {
+ /// The operation is expected to be selectable directly by the target, and
+ /// no transformation is necessary.
+ Legal,
+
+ /// The operation should be synthesized from multiple instructions acting on
+ /// a narrower scalar base-type. For example a 64-bit add might be
+ /// implemented in terms of 32-bit add-with-carry.
+ NarrowScalar,
+
+ /// The operation should be implemented in terms of a wider scalar
+ /// base-type. For example a <2 x s8> add could be implemented as a <2
+ /// x s32> add (ignoring the high bits).
+ WidenScalar,
+
+ /// The (vector) operation should be implemented by splitting it into
+ /// sub-vectors where the operation is legal. For example a <8 x s64> add
+ /// might be implemented as 4 separate <2 x s64> adds.
+ FewerElements,
+
+ /// The (vector) operation should be implemented by widening the input
+ /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
+ /// rarely legal, but you might perform an <8 x i8> and then only look at
+ /// the first two results.
+ MoreElements,
+
+ /// Perform the operation on a
diff erent, but equivalently sized type.
+ Bitcast,
+
+ /// The operation itself must be expressed in terms of simpler actions on
+ /// this target. E.g. a SREM replaced by an SDIV and subtraction.
+ Lower,
+
+ /// The operation should be implemented as a call to some kind of runtime
+ /// support library. For example this usually happens on machines that don't
+ /// support floating-point operations natively.
+ Libcall,
+
+ /// The target wants to do something special with this combination of
+ /// operand and type. A callback will be issued when it is needed.
+ Custom,
+
+ /// This operation is completely unsupported on the target. A programming
+ /// error has occurred.
+ Unsupported,
+
+ /// Sentinel value for when no action was found in the specified table.
+ NotFound,
+};
+} // end namespace LegacyLegalizeActions
+
+/// Legalization is decided based on an instruction's opcode, which type slot
+/// we're considering, and what the existing type is. These aspects are gathered
+/// together for convenience in the InstrAspect class.
+struct InstrAspect {
+ unsigned Opcode;
+ unsigned Idx = 0;
+ LLT Type;
+
+ InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {}
+ InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
+ : Opcode(Opcode), Idx(Idx), Type(Type) {}
+
+ bool operator==(const InstrAspect &RHS) const {
+ return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
+ }
+};
+
+/// The result of a query. It either indicates a final answer of Legal or
+/// Unsupported or describes an action that must be taken to make an operation
+/// more legal.
+struct LegacyLegalizeActionStep {
+ /// The action to take or the final answer.
+ LegacyLegalizeActions::LegacyLegalizeAction Action;
+ /// If describing an action, the type index to change. Otherwise zero.
+ unsigned TypeIdx;
+ /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
+ LLT NewType;
+
+ LegacyLegalizeActionStep(LegacyLegalizeActions::LegacyLegalizeAction Action,
+ unsigned TypeIdx, const LLT NewType)
+ : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
+
+ bool operator==(const LegacyLegalizeActionStep &RHS) const {
+ return std::tie(Action, TypeIdx, NewType) ==
+ std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
+ }
+};
+
+
+class LegacyLegalizerInfo {
+public:
+ using SizeAndAction =
+ std::pair<uint16_t, LegacyLegalizeActions::LegacyLegalizeAction>;
+ using SizeAndActionsVec = std::vector<SizeAndAction>;
+ using SizeChangeStrategy =
+ std::function<SizeAndActionsVec(const SizeAndActionsVec &v)>;
+
+ LegacyLegalizerInfo();
+
+ static bool needsLegalizingToDifferentSize(
+ const LegacyLegalizeActions::LegacyLegalizeAction Action) {
+ using namespace LegacyLegalizeActions;
+ switch (Action) {
+ case NarrowScalar:
+ case WidenScalar:
+ case FewerElements:
+ case MoreElements:
+ case Unsupported:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// Compute any ancillary tables needed to quickly decide how an operation
+ /// should be handled. This must be called after all "set*Action"methods but
+ /// before any query is made or incorrect results may be returned.
+ void computeTables();
+
+ /// More friendly way to set an action for common types that have an LLT
+ /// representation.
+ /// The LegacyLegalizeAction must be one for which
+ /// NeedsLegalizingToDifferentSize returns false.
+ void setAction(const InstrAspect &Aspect,
+ LegacyLegalizeActions::LegacyLegalizeAction Action) {
+ assert(!needsLegalizingToDifferentSize(Action));
+ TablesInitialized = false;
+ const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;
+ if (SpecifiedActions[OpcodeIdx].size() <= Aspect.Idx)
+ SpecifiedActions[OpcodeIdx].resize(Aspect.Idx + 1);
+ SpecifiedActions[OpcodeIdx][Aspect.Idx][Aspect.Type] = Action;
+ }
+
+ /// The setAction calls record the non-size-changing legalization actions
+ /// to take on specificly-sized types. The SizeChangeStrategy defines what
+ /// to do when the size of the type needs to be changed to reach a legally
+ /// sized type (i.e., one that was defined through a setAction call).
+ /// e.g.
+ /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);
+ /// setLegalizeScalarToDifferentSizeStrategy(
+ /// G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
+ /// will end up defining getAction({G_ADD, 0, T}) to return the following
+ /// actions for
diff erent scalar types T:
+ /// LLT::scalar(1)..LLT::scalar(31): {WidenScalar, 0, LLT::scalar(32)}
+ /// LLT::scalar(32): {Legal, 0, LLT::scalar(32)}
+ /// LLT::scalar(33)..: {NarrowScalar, 0, LLT::scalar(32)}
+ ///
+ /// If no SizeChangeAction gets defined, through this function,
+ /// the default is unsupportedForDifferentSizes.
+ void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode,
+ const unsigned TypeIdx,
+ SizeChangeStrategy S) {
+ const unsigned OpcodeIdx = Opcode - FirstOp;
+ if (ScalarSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
+ ScalarSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
+ ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
+ }
+
+ /// See also setLegalizeScalarToDifferentSizeStrategy.
+ /// This function allows to set the SizeChangeStrategy for vector elements.
+ void setLegalizeVectorElementToDifferentSizeStrategy(const unsigned Opcode,
+ const unsigned TypeIdx,
+ SizeChangeStrategy S) {
+ const unsigned OpcodeIdx = Opcode - FirstOp;
+ if (VectorElementSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
+ VectorElementSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
+ VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
+ }
+
+ /// A SizeChangeStrategy for the common case where legalization for a
+ /// particular operation consists of only supporting a specific set of type
+ /// sizes. E.g.
+ /// setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);
+ /// setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);
+ /// setLegalizeScalarToDifferentSizeStrategy(
+ /// G_DIV, 0, unsupportedForDifferentSizes);
+ /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,
+ /// and Unsupported for all other scalar types T.
+ static SizeAndActionsVec
+ unsupportedForDifferentSizes(const SizeAndActionsVec &v) {
+ using namespace LegacyLegalizeActions;
+ return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
+ Unsupported);
+ }
+
+ /// A SizeChangeStrategy for the common case where legalization for a
+ /// particular operation consists of widening the type to a large legal type,
+ /// unless there is no such type and then instead it should be narrowed to the
+ /// largest legal type.
+ static SizeAndActionsVec
+ widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v) {
+ using namespace LegacyLegalizeActions;
+ assert(v.size() > 0 &&
+ "At least one size that can be legalized towards is needed"
+ " for this SizeChangeStrategy");
+ return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
+ NarrowScalar);
+ }
+
+ static SizeAndActionsVec
+ widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v) {
+ using namespace LegacyLegalizeActions;
+ return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
+ Unsupported);
+ }
+
+ static SizeAndActionsVec
+ narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v) {
+ using namespace LegacyLegalizeActions;
+ return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
+ Unsupported);
+ }
+
+ static SizeAndActionsVec
+ narrowToSmallerAndWidenToSmallest(const SizeAndActionsVec &v) {
+ using namespace LegacyLegalizeActions;
+ assert(v.size() > 0 &&
+ "At least one size that can be legalized towards is needed"
+ " for this SizeChangeStrategy");
+ return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
+ WidenScalar);
+ }
+
+ /// A SizeChangeStrategy for the common case where legalization for a
+ /// particular vector operation consists of having more elements in the
+ /// vector, to a type that is legal. Unless there is no such type and then
+ /// instead it should be legalized towards the widest vector that's still
+ /// legal. E.g.
+ /// setAction({G_ADD, LLT::vector(8, 8)}, Legal);
+ /// setAction({G_ADD, LLT::vector(16, 8)}, Legal);
+ /// setAction({G_ADD, LLT::vector(2, 32)}, Legal);
+ /// setAction({G_ADD, LLT::vector(4, 32)}, Legal);
+ /// setLegalizeVectorElementToDifferentSizeStrategy(
+ /// G_ADD, 0, moreToWiderTypesAndLessToWidest);
+ /// will result in the following getAction results:
+ /// * getAction({G_ADD, LLT::vector(8,8)}) returns
+ /// (Legal, vector(8,8)).
+ /// * getAction({G_ADD, LLT::vector(9,8)}) returns
+ /// (MoreElements, vector(16,8)).
+ /// * getAction({G_ADD, LLT::vector(8,32)}) returns
+ /// (FewerElements, vector(4,32)).
+ static SizeAndActionsVec
+ moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v) {
+ using namespace LegacyLegalizeActions;
+ return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
+ FewerElements);
+ }
+
+ /// Helper function to implement many typical SizeChangeStrategy functions.
+ static SizeAndActionsVec increaseToLargerTypesAndDecreaseToLargest(
+ const SizeAndActionsVec &v,
+ LegacyLegalizeActions::LegacyLegalizeAction IncreaseAction,
+ LegacyLegalizeActions::LegacyLegalizeAction DecreaseAction);
+ /// Helper function to implement many typical SizeChangeStrategy functions.
+ static SizeAndActionsVec decreaseToSmallerTypesAndIncreaseToSmallest(
+ const SizeAndActionsVec &v,
+ LegacyLegalizeActions::LegacyLegalizeAction DecreaseAction,
+ LegacyLegalizeActions::LegacyLegalizeAction IncreaseAction);
+
+ LegacyLegalizeActionStep getAction(const LegalityQuery &Query) const;
+
+ unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
+
+private:
+ /// Determine what action should be taken to legalize the given generic
+ /// instruction opcode, type-index and type. Requires computeTables to have
+ /// been called.
+ ///
+ /// \returns a pair consisting of the kind of legalization that should be
+ /// performed and the destination type.
+ std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
+ getAspectAction(const InstrAspect &Aspect) const;
+
+ /// The SizeAndActionsVec is a representation mapping between all natural
+ /// numbers and an Action. The natural number represents the bit size of
+ /// the InstrAspect. For example, for a target with native support for 32-bit
+ /// and 64-bit additions, you'd express that as:
+ /// setScalarAction(G_ADD, 0,
+ /// {{1, WidenScalar}, // bit sizes [ 1, 31[
+ /// {32, Legal}, // bit sizes [32, 33[
+ /// {33, WidenScalar}, // bit sizes [33, 64[
+ /// {64, Legal}, // bit sizes [64, 65[
+ /// {65, NarrowScalar} // bit sizes [65, +inf[
+ /// });
+ /// It may be that only 64-bit pointers are supported on your target:
+ /// setPointerAction(G_PTR_ADD, 0, LLT:pointer(1),
+ /// {{1, Unsupported}, // bit sizes [ 1, 63[
+ /// {64, Legal}, // bit sizes [64, 65[
+ /// {65, Unsupported}, // bit sizes [65, +inf[
+ /// });
+ void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,
+ const SizeAndActionsVec &SizeAndActions) {
+ const unsigned OpcodeIdx = Opcode - FirstOp;
+ SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];
+ setActions(TypeIndex, Actions, SizeAndActions);
+ }
+ void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,
+ const unsigned AddressSpace,
+ const SizeAndActionsVec &SizeAndActions) {
+ const unsigned OpcodeIdx = Opcode - FirstOp;
+ if (AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace) ==
+ AddrSpace2PointerActions[OpcodeIdx].end())
+ AddrSpace2PointerActions[OpcodeIdx][AddressSpace] = {{}};
+ SmallVector<SizeAndActionsVec, 1> &Actions =
+ AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace)->second;
+ setActions(TypeIndex, Actions, SizeAndActions);
+ }
+
+ /// If an operation on a given vector type (say <M x iN>) isn't explicitly
+ /// specified, we proceed in 2 stages. First we legalize the underlying scalar
+ /// (so that there's at least one legal vector with that scalar), then we
+ /// adjust the number of elements in the vector so that it is legal. The
+ /// desired action in the first step is controlled by this function.
+ void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,
+ const SizeAndActionsVec &SizeAndActions) {
+ unsigned OpcodeIdx = Opcode - FirstOp;
+ SmallVector<SizeAndActionsVec, 1> &Actions =
+ ScalarInVectorActions[OpcodeIdx];
+ setActions(TypeIndex, Actions, SizeAndActions);
+ }
+
+ /// See also setScalarInVectorAction.
+ /// This function let's you specify the number of elements in a vector that
+ /// are legal for a legal element size.
+ void setVectorNumElementAction(const unsigned Opcode,
+ const unsigned TypeIndex,
+ const unsigned ElementSize,
+ const SizeAndActionsVec &SizeAndActions) {
+ const unsigned OpcodeIdx = Opcode - FirstOp;
+ if (NumElements2Actions[OpcodeIdx].find(ElementSize) ==
+ NumElements2Actions[OpcodeIdx].end())
+ NumElements2Actions[OpcodeIdx][ElementSize] = {{}};
+ SmallVector<SizeAndActionsVec, 1> &Actions =
+ NumElements2Actions[OpcodeIdx].find(ElementSize)->second;
+ setActions(TypeIndex, Actions, SizeAndActions);
+ }
+
+ /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
+ /// i.e. it's OK if it doesn't start from size 1.
+ static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
+ using namespace LegacyLegalizeActions;
+#ifndef NDEBUG
+ // The sizes should be in increasing order
+ int prev_size = -1;
+ for(auto SizeAndAction: v) {
+ assert(SizeAndAction.first > prev_size);
+ prev_size = SizeAndAction.first;
+ }
+ // - for every Widen action, there should be a larger bitsize that
+ // can be legalized towards (e.g. Legal, Lower, Libcall or Custom
+ // action).
+ // - for every Narrow action, there should be a smaller bitsize that
+ // can be legalized towards.
+ int SmallestNarrowIdx = -1;
+ int LargestWidenIdx = -1;
+ int SmallestLegalizableToSameSizeIdx = -1;
+ int LargestLegalizableToSameSizeIdx = -1;
+ for(size_t i=0; i<v.size(); ++i) {
+ switch (v[i].second) {
+ case FewerElements:
+ case NarrowScalar:
+ if (SmallestNarrowIdx == -1)
+ SmallestNarrowIdx = i;
+ break;
+ case WidenScalar:
+ case MoreElements:
+ LargestWidenIdx = i;
+ break;
+ case Unsupported:
+ break;
+ default:
+ if (SmallestLegalizableToSameSizeIdx == -1)
+ SmallestLegalizableToSameSizeIdx = i;
+ LargestLegalizableToSameSizeIdx = i;
+ }
+ }
+ if (SmallestNarrowIdx != -1) {
+ assert(SmallestLegalizableToSameSizeIdx != -1);
+ assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
+ }
+ if (LargestWidenIdx != -1)
+ assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
+#endif
+ }
+
+ /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with
+ /// from size 1.
+ static void checkFullSizeAndActionsVector(const SizeAndActionsVec& v) {
+#ifndef NDEBUG
+ // Data structure invariant: The first bit size must be size 1.
+ assert(v.size() >= 1);
+ assert(v[0].first == 1);
+ checkPartialSizeAndActionsVector(v);
+#endif
+ }
+
+ /// Sets actions for all bit sizes on a particular generic opcode, type
+ /// index and scalar or pointer type.
+ void setActions(unsigned TypeIndex,
+ SmallVector<SizeAndActionsVec, 1> &Actions,
+ const SizeAndActionsVec &SizeAndActions) {
+ checkFullSizeAndActionsVector(SizeAndActions);
+ if (Actions.size() <= TypeIndex)
+ Actions.resize(TypeIndex + 1);
+ Actions[TypeIndex] = SizeAndActions;
+ }
+
+ static SizeAndAction findAction(const SizeAndActionsVec &Vec,
+ const uint32_t Size);
+
+ /// Returns the next action needed to get the scalar or pointer type closer
+ /// to being legal
+ /// E.g. findLegalAction({G_REM, 13}) should return
+ /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will
+ /// probably be called, which should return (Lower, 32).
+ /// This is assuming the setScalarAction on G_REM was something like:
+ /// setScalarAction(G_REM, 0,
+ /// {{1, WidenScalar}, // bit sizes [ 1, 31[
+ /// {32, Lower}, // bit sizes [32, 33[
+ /// {33, NarrowScalar} // bit sizes [65, +inf[
+ /// });
+ std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
+ findScalarLegalAction(const InstrAspect &Aspect) const;
+
+ /// Returns the next action needed towards legalizing the vector type.
+ std::pair<LegacyLegalizeActions::LegacyLegalizeAction, LLT>
+ findVectorLegalAction(const InstrAspect &Aspect) const;
+
+ static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
+ static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
+
+ // Data structures used temporarily during construction of legality data:
+ using TypeMap = DenseMap<LLT, LegacyLegalizeActions::LegacyLegalizeAction>;
+ SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
+ SmallVector<SizeChangeStrategy, 1>
+ ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
+ SmallVector<SizeChangeStrategy, 1>
+ VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
+ bool TablesInitialized;
+
+ // Data structures used by getAction:
+ SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
+ SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
+ std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
+ AddrSpace2PointerActions[LastOp - FirstOp + 1];
+ std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
+ NumElements2Actions[LastOp - FirstOp + 1];
+};
+
+} // end namespace llvm
+
+#endif // define LLVM_CODEGEN_GLOBALISEL_LEGACYLEGALIZERINFO_H
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index 37144be8dc79e..647eaf4e7a0d2 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/Support/CommandLine.h"
@@ -100,23 +101,6 @@ raw_ostream &operator<<(raw_ostream &OS, LegalizeActions::LegalizeAction Action)
using LegalizeActions::LegalizeAction;
-/// Legalization is decided based on an instruction's opcode, which type slot
-/// we're considering, and what the existing type is. These aspects are gathered
-/// together for convenience in the InstrAspect class.
-struct InstrAspect {
- unsigned Opcode;
- unsigned Idx = 0;
- LLT Type;
-
- InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {}
- InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
- : Opcode(Opcode), Idx(Idx), Type(Type) {}
-
- bool operator==(const InstrAspect &RHS) const {
- return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
- }
-};
-
/// The LegalityQuery object bundles together all the information that's needed
/// to decide whether a given operation is legal or not.
/// For efficiency, it doesn't make a copy of Types so care must be taken not
@@ -159,6 +143,45 @@ struct LegalizeActionStep {
const LLT NewType)
: Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
+ LegalizeActionStep(LegacyLegalizeActionStep Step)
+ : TypeIdx(Step.TypeIdx), NewType(Step.NewType) {
+ switch (Step.Action) {
+ case LegacyLegalizeActions::Legal:
+ Action = LegalizeActions::Legal;
+ break;
+ case LegacyLegalizeActions::NarrowScalar:
+ Action = LegalizeActions::NarrowScalar;
+ break;
+ case LegacyLegalizeActions::WidenScalar:
+ Action = LegalizeActions::WidenScalar;
+ break;
+ case LegacyLegalizeActions::FewerElements:
+ Action = LegalizeActions::FewerElements;
+ break;
+ case LegacyLegalizeActions::MoreElements:
+ Action = LegalizeActions::MoreElements;
+ break;
+ case LegacyLegalizeActions::Bitcast:
+ Action = LegalizeActions::Bitcast;
+ break;
+ case LegacyLegalizeActions::Lower:
+ Action = LegalizeActions::Lower;
+ break;
+ case LegacyLegalizeActions::Libcall:
+ Action = LegalizeActions::Libcall;
+ break;
+ case LegacyLegalizeActions::Custom:
+ Action = LegalizeActions::Custom;
+ break;
+ case LegacyLegalizeActions::Unsupported:
+ Action = LegalizeActions::Unsupported;
+ break;
+ case LegacyLegalizeActions::NotFound:
+ Action = LegalizeActions::NotFound;
+ break;
+ }
+ }
+
bool operator==(const LegalizeActionStep &RHS) const {
return std::tie(Action, TypeIdx, NewType) ==
std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
@@ -1057,179 +1080,20 @@ class LegalizeRuleSet {
class LegalizerInfo {
public:
- LegalizerInfo();
virtual ~LegalizerInfo() = default;
+ const LegacyLegalizerInfo &getLegacyLegalizerInfo() const {
+ return LegacyInfo;
+ }
+ LegacyLegalizerInfo &getLegacyLegalizerInfo() { return LegacyInfo; }
+
unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
unsigned getActionDefinitionsIdx(unsigned Opcode) const;
- /// Compute any ancillary tables needed to quickly decide how an operation
- /// should be handled. This must be called after all "set*Action"methods but
- /// before any query is made or incorrect results may be returned.
- void computeTables();
-
/// Perform simple self-diagnostic and assert if there is anything obviously
/// wrong with the actions set up.
void verify(const MCInstrInfo &MII) const;
- static bool needsLegalizingToDifferentSize(const LegalizeAction Action) {
- using namespace LegalizeActions;
- switch (Action) {
- case NarrowScalar:
- case WidenScalar:
- case FewerElements:
- case MoreElements:
- case Unsupported:
- return true;
- default:
- return false;
- }
- }
-
- using SizeAndAction = std::pair<uint16_t, LegalizeAction>;
- using SizeAndActionsVec = std::vector<SizeAndAction>;
- using SizeChangeStrategy =
- std::function<SizeAndActionsVec(const SizeAndActionsVec &v)>;
-
- /// More friendly way to set an action for common types that have an LLT
- /// representation.
- /// The LegalizeAction must be one for which NeedsLegalizingToDifferentSize
- /// returns false.
- void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
- assert(!needsLegalizingToDifferentSize(Action));
- TablesInitialized = false;
- const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;
- if (SpecifiedActions[OpcodeIdx].size() <= Aspect.Idx)
- SpecifiedActions[OpcodeIdx].resize(Aspect.Idx + 1);
- SpecifiedActions[OpcodeIdx][Aspect.Idx][Aspect.Type] = Action;
- }
-
- /// The setAction calls record the non-size-changing legalization actions
- /// to take on specificly-sized types. The SizeChangeStrategy defines what
- /// to do when the size of the type needs to be changed to reach a legally
- /// sized type (i.e., one that was defined through a setAction call).
- /// e.g.
- /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);
- /// setLegalizeScalarToDifferentSizeStrategy(
- /// G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
- /// will end up defining getAction({G_ADD, 0, T}) to return the following
- /// actions for
diff erent scalar types T:
- /// LLT::scalar(1)..LLT::scalar(31): {WidenScalar, 0, LLT::scalar(32)}
- /// LLT::scalar(32): {Legal, 0, LLT::scalar(32)}
- /// LLT::scalar(33)..: {NarrowScalar, 0, LLT::scalar(32)}
- ///
- /// If no SizeChangeAction gets defined, through this function,
- /// the default is unsupportedForDifferentSizes.
- void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode,
- const unsigned TypeIdx,
- SizeChangeStrategy S) {
- const unsigned OpcodeIdx = Opcode - FirstOp;
- if (ScalarSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
- ScalarSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
- ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
- }
-
- /// See also setLegalizeScalarToDifferentSizeStrategy.
- /// This function allows to set the SizeChangeStrategy for vector elements.
- void setLegalizeVectorElementToDifferentSizeStrategy(const unsigned Opcode,
- const unsigned TypeIdx,
- SizeChangeStrategy S) {
- const unsigned OpcodeIdx = Opcode - FirstOp;
- if (VectorElementSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
- VectorElementSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
- VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
- }
-
- /// A SizeChangeStrategy for the common case where legalization for a
- /// particular operation consists of only supporting a specific set of type
- /// sizes. E.g.
- /// setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);
- /// setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);
- /// setLegalizeScalarToDifferentSizeStrategy(
- /// G_DIV, 0, unsupportedForDifferentSizes);
- /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,
- /// and Unsupported for all other scalar types T.
- static SizeAndActionsVec
- unsupportedForDifferentSizes(const SizeAndActionsVec &v) {
- using namespace LegalizeActions;
- return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
- Unsupported);
- }
-
- /// A SizeChangeStrategy for the common case where legalization for a
- /// particular operation consists of widening the type to a large legal type,
- /// unless there is no such type and then instead it should be narrowed to the
- /// largest legal type.
- static SizeAndActionsVec
- widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v) {
- using namespace LegalizeActions;
- assert(v.size() > 0 &&
- "At least one size that can be legalized towards is needed"
- " for this SizeChangeStrategy");
- return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
- NarrowScalar);
- }
-
- static SizeAndActionsVec
- widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v) {
- using namespace LegalizeActions;
- return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
- Unsupported);
- }
-
- static SizeAndActionsVec
- narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v) {
- using namespace LegalizeActions;
- return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
- Unsupported);
- }
-
- static SizeAndActionsVec
- narrowToSmallerAndWidenToSmallest(const SizeAndActionsVec &v) {
- using namespace LegalizeActions;
- assert(v.size() > 0 &&
- "At least one size that can be legalized towards is needed"
- " for this SizeChangeStrategy");
- return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
- WidenScalar);
- }
-
- /// A SizeChangeStrategy for the common case where legalization for a
- /// particular vector operation consists of having more elements in the
- /// vector, to a type that is legal. Unless there is no such type and then
- /// instead it should be legalized towards the widest vector that's still
- /// legal. E.g.
- /// setAction({G_ADD, LLT::vector(8, 8)}, Legal);
- /// setAction({G_ADD, LLT::vector(16, 8)}, Legal);
- /// setAction({G_ADD, LLT::vector(2, 32)}, Legal);
- /// setAction({G_ADD, LLT::vector(4, 32)}, Legal);
- /// setLegalizeVectorElementToDifferentSizeStrategy(
- /// G_ADD, 0, moreToWiderTypesAndLessToWidest);
- /// will result in the following getAction results:
- /// * getAction({G_ADD, LLT::vector(8,8)}) returns
- /// (Legal, vector(8,8)).
- /// * getAction({G_ADD, LLT::vector(9,8)}) returns
- /// (MoreElements, vector(16,8)).
- /// * getAction({G_ADD, LLT::vector(8,32)}) returns
- /// (FewerElements, vector(4,32)).
- static SizeAndActionsVec
- moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v) {
- using namespace LegalizeActions;
- return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
- FewerElements);
- }
-
- /// Helper function to implement many typical SizeChangeStrategy functions.
- static SizeAndActionsVec
- increaseToLargerTypesAndDecreaseToLargest(const SizeAndActionsVec &v,
- LegalizeAction IncreaseAction,
- LegalizeAction DecreaseAction);
- /// Helper function to implement many typical SizeChangeStrategy functions.
- static SizeAndActionsVec
- decreaseToSmallerTypesAndIncreaseToSmallest(const SizeAndActionsVec &v,
- LegalizeAction DecreaseAction,
- LegalizeAction IncreaseAction);
-
/// Get the action definitions for the given opcode. Use this to run a
/// LegalityQuery through the definitions.
const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
@@ -1306,191 +1170,11 @@ class LegalizerInfo {
virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
private:
- /// Determine what action should be taken to legalize the given generic
- /// instruction opcode, type-index and type. Requires computeTables to have
- /// been called.
- ///
- /// \returns a pair consisting of the kind of legalization that should be
- /// performed and the destination type.
- std::pair<LegalizeAction, LLT>
- getAspectAction(const InstrAspect &Aspect) const;
-
- /// The SizeAndActionsVec is a representation mapping between all natural
- /// numbers and an Action. The natural number represents the bit size of
- /// the InstrAspect. For example, for a target with native support for 32-bit
- /// and 64-bit additions, you'd express that as:
- /// setScalarAction(G_ADD, 0,
- /// {{1, WidenScalar}, // bit sizes [ 1, 31[
- /// {32, Legal}, // bit sizes [32, 33[
- /// {33, WidenScalar}, // bit sizes [33, 64[
- /// {64, Legal}, // bit sizes [64, 65[
- /// {65, NarrowScalar} // bit sizes [65, +inf[
- /// });
- /// It may be that only 64-bit pointers are supported on your target:
- /// setPointerAction(G_PTR_ADD, 0, LLT:pointer(1),
- /// {{1, Unsupported}, // bit sizes [ 1, 63[
- /// {64, Legal}, // bit sizes [64, 65[
- /// {65, Unsupported}, // bit sizes [65, +inf[
- /// });
- void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,
- const SizeAndActionsVec &SizeAndActions) {
- const unsigned OpcodeIdx = Opcode - FirstOp;
- SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];
- setActions(TypeIndex, Actions, SizeAndActions);
- }
- void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,
- const unsigned AddressSpace,
- const SizeAndActionsVec &SizeAndActions) {
- const unsigned OpcodeIdx = Opcode - FirstOp;
- if (AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace) ==
- AddrSpace2PointerActions[OpcodeIdx].end())
- AddrSpace2PointerActions[OpcodeIdx][AddressSpace] = {{}};
- SmallVector<SizeAndActionsVec, 1> &Actions =
- AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace)->second;
- setActions(TypeIndex, Actions, SizeAndActions);
- }
-
- /// If an operation on a given vector type (say <M x iN>) isn't explicitly
- /// specified, we proceed in 2 stages. First we legalize the underlying scalar
- /// (so that there's at least one legal vector with that scalar), then we
- /// adjust the number of elements in the vector so that it is legal. The
- /// desired action in the first step is controlled by this function.
- void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,
- const SizeAndActionsVec &SizeAndActions) {
- unsigned OpcodeIdx = Opcode - FirstOp;
- SmallVector<SizeAndActionsVec, 1> &Actions =
- ScalarInVectorActions[OpcodeIdx];
- setActions(TypeIndex, Actions, SizeAndActions);
- }
-
- /// See also setScalarInVectorAction.
- /// This function let's you specify the number of elements in a vector that
- /// are legal for a legal element size.
- void setVectorNumElementAction(const unsigned Opcode,
- const unsigned TypeIndex,
- const unsigned ElementSize,
- const SizeAndActionsVec &SizeAndActions) {
- const unsigned OpcodeIdx = Opcode - FirstOp;
- if (NumElements2Actions[OpcodeIdx].find(ElementSize) ==
- NumElements2Actions[OpcodeIdx].end())
- NumElements2Actions[OpcodeIdx][ElementSize] = {{}};
- SmallVector<SizeAndActionsVec, 1> &Actions =
- NumElements2Actions[OpcodeIdx].find(ElementSize)->second;
- setActions(TypeIndex, Actions, SizeAndActions);
- }
-
- /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
- /// i.e. it's OK if it doesn't start from size 1.
- static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
- using namespace LegalizeActions;
-#ifndef NDEBUG
- // The sizes should be in increasing order
- int prev_size = -1;
- for(auto SizeAndAction: v) {
- assert(SizeAndAction.first > prev_size);
- prev_size = SizeAndAction.first;
- }
- // - for every Widen action, there should be a larger bitsize that
- // can be legalized towards (e.g. Legal, Lower, Libcall or Custom
- // action).
- // - for every Narrow action, there should be a smaller bitsize that
- // can be legalized towards.
- int SmallestNarrowIdx = -1;
- int LargestWidenIdx = -1;
- int SmallestLegalizableToSameSizeIdx = -1;
- int LargestLegalizableToSameSizeIdx = -1;
- for(size_t i=0; i<v.size(); ++i) {
- switch (v[i].second) {
- case FewerElements:
- case NarrowScalar:
- if (SmallestNarrowIdx == -1)
- SmallestNarrowIdx = i;
- break;
- case WidenScalar:
- case MoreElements:
- LargestWidenIdx = i;
- break;
- case Unsupported:
- break;
- default:
- if (SmallestLegalizableToSameSizeIdx == -1)
- SmallestLegalizableToSameSizeIdx = i;
- LargestLegalizableToSameSizeIdx = i;
- }
- }
- if (SmallestNarrowIdx != -1) {
- assert(SmallestLegalizableToSameSizeIdx != -1);
- assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
- }
- if (LargestWidenIdx != -1)
- assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
-#endif
- }
-
- /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with
- /// from size 1.
- static void checkFullSizeAndActionsVector(const SizeAndActionsVec& v) {
-#ifndef NDEBUG
- // Data structure invariant: The first bit size must be size 1.
- assert(v.size() >= 1);
- assert(v[0].first == 1);
- checkPartialSizeAndActionsVector(v);
-#endif
- }
-
- /// Sets actions for all bit sizes on a particular generic opcode, type
- /// index and scalar or pointer type.
- void setActions(unsigned TypeIndex,
- SmallVector<SizeAndActionsVec, 1> &Actions,
- const SizeAndActionsVec &SizeAndActions) {
- checkFullSizeAndActionsVector(SizeAndActions);
- if (Actions.size() <= TypeIndex)
- Actions.resize(TypeIndex + 1);
- Actions[TypeIndex] = SizeAndActions;
- }
-
- static SizeAndAction findAction(const SizeAndActionsVec &Vec,
- const uint32_t Size);
-
- /// Returns the next action needed to get the scalar or pointer type closer
- /// to being legal
- /// E.g. findLegalAction({G_REM, 13}) should return
- /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will
- /// probably be called, which should return (Lower, 32).
- /// This is assuming the setScalarAction on G_REM was something like:
- /// setScalarAction(G_REM, 0,
- /// {{1, WidenScalar}, // bit sizes [ 1, 31[
- /// {32, Lower}, // bit sizes [32, 33[
- /// {33, NarrowScalar} // bit sizes [65, +inf[
- /// });
- std::pair<LegalizeAction, LLT>
- findScalarLegalAction(const InstrAspect &Aspect) const;
-
- /// Returns the next action needed towards legalizing the vector type.
- std::pair<LegalizeAction, LLT>
- findVectorLegalAction(const InstrAspect &Aspect) const;
-
static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
- // Data structures used temporarily during construction of legality data:
- using TypeMap = DenseMap<LLT, LegalizeAction>;
- SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
- SmallVector<SizeChangeStrategy, 1>
- ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
- SmallVector<SizeChangeStrategy, 1>
- VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
- bool TablesInitialized;
-
- // Data structures used by getAction:
- SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
- SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
- std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
- AddrSpace2PointerActions[LastOp - FirstOp + 1];
- std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
- NumElements2Actions[LastOp - FirstOp + 1];
-
LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
+ LegacyLegalizerInfo LegacyInfo;
};
#ifndef NDEBUG
diff --git a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
index f97ec66c18c3a..f65f5237555e3 100644
--- a/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
+++ b/llvm/lib/CodeGen/GlobalISel/CMakeLists.txt
@@ -16,6 +16,7 @@ add_llvm_component_library(LLVMGlobalISel
Legalizer.cpp
LegalizerHelper.cpp
LegalizerInfo.cpp
+ LegacyLegalizerInfo.cpp
Localizer.cpp
LostDebugLocObserver.cpp
MachineIRBuilder.cpp
diff --git a/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
new file mode 100644
index 0000000000000..f7e68e2691cf1
--- /dev/null
+++ b/llvm/lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp
@@ -0,0 +1,344 @@
+//===- lib/CodeGen/GlobalISel/LegacyLegalizerInfo.cpp - Legalizer ---------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implement an interface to specify and query how an illegal operation on a
+// given type should be expanded.
+//
+// Issues to be resolved:
+// + Make it fast.
+// + Support weird types like i3, <7 x i3>, ...
+// + Operations with more than one type (ICMP, CMPXCHG, intrinsics, ...)
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include <map>
+
+using namespace llvm;
+using namespace LegacyLegalizeActions;
+
+#define DEBUG_TYPE "legalizer-info"
+
+LegacyLegalizerInfo::LegacyLegalizerInfo() : TablesInitialized(false) {
+ // Set defaults.
+ // FIXME: these two (G_ANYEXT and G_TRUNC?) can be legalized to the
+ // fundamental load/store Jakob proposed. Once loads & stores are supported.
+ setScalarAction(TargetOpcode::G_ANYEXT, 1, {{1, Legal}});
+ setScalarAction(TargetOpcode::G_ZEXT, 1, {{1, Legal}});
+ setScalarAction(TargetOpcode::G_SEXT, 1, {{1, Legal}});
+ setScalarAction(TargetOpcode::G_TRUNC, 0, {{1, Legal}});
+ setScalarAction(TargetOpcode::G_TRUNC, 1, {{1, Legal}});
+
+ setScalarAction(TargetOpcode::G_INTRINSIC, 0, {{1, Legal}});
+ setScalarAction(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, 0, {{1, Legal}});
+
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_IMPLICIT_DEF, 0, narrowToSmallerAndUnsupportedIfTooSmall);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_OR, 0, widenToLargerTypesAndNarrowToLargest);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_LOAD, 0, narrowToSmallerAndUnsupportedIfTooSmall);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_STORE, 0, narrowToSmallerAndUnsupportedIfTooSmall);
+
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_BRCOND, 0, widenToLargerTypesUnsupportedOtherwise);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_INSERT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_EXTRACT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
+ setLegalizeScalarToDifferentSizeStrategy(
+ TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedIfTooSmall);
+ setScalarAction(TargetOpcode::G_FNEG, 0, {{1, Lower}});
+}
+
+void LegacyLegalizerInfo::computeTables() {
+ assert(TablesInitialized == false);
+
+ for (unsigned OpcodeIdx = 0; OpcodeIdx <= LastOp - FirstOp; ++OpcodeIdx) {
+ const unsigned Opcode = FirstOp + OpcodeIdx;
+ for (unsigned TypeIdx = 0; TypeIdx != SpecifiedActions[OpcodeIdx].size();
+ ++TypeIdx) {
+ // 0. Collect information specified through the setAction API, i.e.
+ // for specific bit sizes.
+ // For scalar types:
+ SizeAndActionsVec ScalarSpecifiedActions;
+ // For pointer types:
+ std::map<uint16_t, SizeAndActionsVec> AddressSpace2SpecifiedActions;
+ // For vector types:
+ std::map<uint16_t, SizeAndActionsVec> ElemSize2SpecifiedActions;
+ for (auto LLT2Action : SpecifiedActions[OpcodeIdx][TypeIdx]) {
+ const LLT Type = LLT2Action.first;
+ const LegacyLegalizeAction Action = LLT2Action.second;
+
+ auto SizeAction = std::make_pair(Type.getSizeInBits(), Action);
+ if (Type.isPointer())
+ AddressSpace2SpecifiedActions[Type.getAddressSpace()].push_back(
+ SizeAction);
+ else if (Type.isVector())
+ ElemSize2SpecifiedActions[Type.getElementType().getSizeInBits()]
+ .push_back(SizeAction);
+ else
+ ScalarSpecifiedActions.push_back(SizeAction);
+ }
+
+ // 1. Handle scalar types
+ {
+ // Decide how to handle bit sizes for which no explicit specification
+ // was given.
+ SizeChangeStrategy S = &unsupportedForDifferentSizes;
+ if (TypeIdx < ScalarSizeChangeStrategies[OpcodeIdx].size() &&
+ ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr)
+ S = ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx];
+ llvm::sort(ScalarSpecifiedActions);
+ checkPartialSizeAndActionsVector(ScalarSpecifiedActions);
+ setScalarAction(Opcode, TypeIdx, S(ScalarSpecifiedActions));
+ }
+
+ // 2. Handle pointer types
+ for (auto PointerSpecifiedActions : AddressSpace2SpecifiedActions) {
+ llvm::sort(PointerSpecifiedActions.second);
+ checkPartialSizeAndActionsVector(PointerSpecifiedActions.second);
+ // For pointer types, we assume that there isn't a meaningfull way
+ // to change the number of bits used in the pointer.
+ setPointerAction(
+ Opcode, TypeIdx, PointerSpecifiedActions.first,
+ unsupportedForDifferentSizes(PointerSpecifiedActions.second));
+ }
+
+ // 3. Handle vector types
+ SizeAndActionsVec ElementSizesSeen;
+ for (auto VectorSpecifiedActions : ElemSize2SpecifiedActions) {
+ llvm::sort(VectorSpecifiedActions.second);
+ const uint16_t ElementSize = VectorSpecifiedActions.first;
+ ElementSizesSeen.push_back({ElementSize, Legal});
+ checkPartialSizeAndActionsVector(VectorSpecifiedActions.second);
+ // For vector types, we assume that the best way to adapt the number
+ // of elements is to the next larger number of elements type for which
+ // the vector type is legal, unless there is no such type. In that case,
+ // legalize towards a vector type with a smaller number of elements.
+ SizeAndActionsVec NumElementsActions;
+ for (SizeAndAction BitsizeAndAction : VectorSpecifiedActions.second) {
+ assert(BitsizeAndAction.first % ElementSize == 0);
+ const uint16_t NumElements = BitsizeAndAction.first / ElementSize;
+ NumElementsActions.push_back({NumElements, BitsizeAndAction.second});
+ }
+ setVectorNumElementAction(
+ Opcode, TypeIdx, ElementSize,
+ moreToWiderTypesAndLessToWidest(NumElementsActions));
+ }
+ llvm::sort(ElementSizesSeen);
+ SizeChangeStrategy VectorElementSizeChangeStrategy =
+ &unsupportedForDifferentSizes;
+ if (TypeIdx < VectorElementSizeChangeStrategies[OpcodeIdx].size() &&
+ VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr)
+ VectorElementSizeChangeStrategy =
+ VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx];
+ setScalarInVectorAction(
+ Opcode, TypeIdx, VectorElementSizeChangeStrategy(ElementSizesSeen));
+ }
+ }
+
+ TablesInitialized = true;
+}
+
+// FIXME: inefficient implementation for now. Without ComputeValueVTs we're
+// probably going to need specialized lookup structures for various types before
+// we have any hope of doing well with something like <13 x i3>. Even the common
+// cases should do better than what we have now.
+std::pair<LegacyLegalizeAction, LLT>
+LegacyLegalizerInfo::getAspectAction(const InstrAspect &Aspect) const {
+ assert(TablesInitialized && "backend forgot to call computeTables");
+ // These *have* to be implemented for now, they're the fundamental basis of
+ // how everything else is transformed.
+ if (Aspect.Type.isScalar() || Aspect.Type.isPointer())
+ return findScalarLegalAction(Aspect);
+ assert(Aspect.Type.isVector());
+ return findVectorLegalAction(Aspect);
+}
+
+LegacyLegalizerInfo::SizeAndActionsVec
+LegacyLegalizerInfo::increaseToLargerTypesAndDecreaseToLargest(
+ const SizeAndActionsVec &v, LegacyLegalizeAction IncreaseAction,
+ LegacyLegalizeAction DecreaseAction) {
+ SizeAndActionsVec result;
+ unsigned LargestSizeSoFar = 0;
+ if (v.size() >= 1 && v[0].first != 1)
+ result.push_back({1, IncreaseAction});
+ for (size_t i = 0; i < v.size(); ++i) {
+ result.push_back(v[i]);
+ LargestSizeSoFar = v[i].first;
+ if (i + 1 < v.size() && v[i + 1].first != v[i].first + 1) {
+ result.push_back({LargestSizeSoFar + 1, IncreaseAction});
+ LargestSizeSoFar = v[i].first + 1;
+ }
+ }
+ result.push_back({LargestSizeSoFar + 1, DecreaseAction});
+ return result;
+}
+
+LegacyLegalizerInfo::SizeAndActionsVec
+LegacyLegalizerInfo::decreaseToSmallerTypesAndIncreaseToSmallest(
+ const SizeAndActionsVec &v, LegacyLegalizeAction DecreaseAction,
+ LegacyLegalizeAction IncreaseAction) {
+ SizeAndActionsVec result;
+ if (v.size() == 0 || v[0].first != 1)
+ result.push_back({1, IncreaseAction});
+ for (size_t i = 0; i < v.size(); ++i) {
+ result.push_back(v[i]);
+ if (i + 1 == v.size() || v[i + 1].first != v[i].first + 1) {
+ result.push_back({v[i].first + 1, DecreaseAction});
+ }
+ }
+ return result;
+}
+
+LegacyLegalizerInfo::SizeAndAction
+LegacyLegalizerInfo::findAction(const SizeAndActionsVec &Vec, const uint32_t Size) {
+ assert(Size >= 1);
+ // Find the last element in Vec that has a bitsize equal to or smaller than
+ // the requested bit size.
+ // That is the element just before the first element that is bigger than Size.
+ auto It = partition_point(
+ Vec, [=](const SizeAndAction &A) { return A.first <= Size; });
+ assert(It != Vec.begin() && "Does Vec not start with size 1?");
+ int VecIdx = It - Vec.begin() - 1;
+
+ LegacyLegalizeAction Action = Vec[VecIdx].second;
+ switch (Action) {
+ case Legal:
+ case Bitcast:
+ case Lower:
+ case Libcall:
+ case Custom:
+ return {Size, Action};
+ case FewerElements:
+ // FIXME: is this special case still needed and correct?
+ // Special case for scalarization:
+ if (Vec == SizeAndActionsVec({{1, FewerElements}}))
+ return {1, FewerElements};
+ LLVM_FALLTHROUGH;
+ case NarrowScalar: {
+ // The following needs to be a loop, as for now, we do allow needing to
+ // go over "Unsupported" bit sizes before finding a legalizable bit size.
+ // e.g. (s8, WidenScalar), (s9, Unsupported), (s32, Legal). if Size==8,
+ // we need to iterate over s9, and then to s32 to return (s32, Legal).
+ // If we want to get rid of the below loop, we should have stronger asserts
+ // when building the SizeAndActionsVecs, probably not allowing
+ // "Unsupported" unless at the ends of the vector.
+ for (int i = VecIdx - 1; i >= 0; --i)
+ if (!needsLegalizingToDifferentSize(Vec[i].second) &&
+ Vec[i].second != Unsupported)
+ return {Vec[i].first, Action};
+ llvm_unreachable("");
+ }
+ case WidenScalar:
+ case MoreElements: {
+ // See above, the following needs to be a loop, at least for now.
+ for (std::size_t i = VecIdx + 1; i < Vec.size(); ++i)
+ if (!needsLegalizingToDifferentSize(Vec[i].second) &&
+ Vec[i].second != Unsupported)
+ return {Vec[i].first, Action};
+ llvm_unreachable("");
+ }
+ case Unsupported:
+ return {Size, Unsupported};
+ case NotFound:
+ llvm_unreachable("NotFound");
+ }
+ llvm_unreachable("Action has an unknown enum value");
+}
+
+std::pair<LegacyLegalizeAction, LLT>
+LegacyLegalizerInfo::findScalarLegalAction(const InstrAspect &Aspect) const {
+ assert(Aspect.Type.isScalar() || Aspect.Type.isPointer());
+ if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
+ return {NotFound, LLT()};
+ const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.Opcode);
+ if (Aspect.Type.isPointer() &&
+ AddrSpace2PointerActions[OpcodeIdx].find(Aspect.Type.getAddressSpace()) ==
+ AddrSpace2PointerActions[OpcodeIdx].end()) {
+ return {NotFound, LLT()};
+ }
+ const SmallVector<SizeAndActionsVec, 1> &Actions =
+ Aspect.Type.isPointer()
+ ? AddrSpace2PointerActions[OpcodeIdx]
+ .find(Aspect.Type.getAddressSpace())
+ ->second
+ : ScalarActions[OpcodeIdx];
+ if (Aspect.Idx >= Actions.size())
+ return {NotFound, LLT()};
+ const SizeAndActionsVec &Vec = Actions[Aspect.Idx];
+ // FIXME: speed up this search, e.g. by using a results cache for repeated
+ // queries?
+ auto SizeAndAction = findAction(Vec, Aspect.Type.getSizeInBits());
+ return {SizeAndAction.second,
+ Aspect.Type.isScalar() ? LLT::scalar(SizeAndAction.first)
+ : LLT::pointer(Aspect.Type.getAddressSpace(),
+ SizeAndAction.first)};
+}
+
+std::pair<LegacyLegalizeAction, LLT>
+LegacyLegalizerInfo::findVectorLegalAction(const InstrAspect &Aspect) const {
+ assert(Aspect.Type.isVector());
+ // First legalize the vector element size, then legalize the number of
+ // lanes in the vector.
+ if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
+ return {NotFound, Aspect.Type};
+ const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.Opcode);
+ const unsigned TypeIdx = Aspect.Idx;
+ if (TypeIdx >= ScalarInVectorActions[OpcodeIdx].size())
+ return {NotFound, Aspect.Type};
+ const SizeAndActionsVec &ElemSizeVec =
+ ScalarInVectorActions[OpcodeIdx][TypeIdx];
+
+ LLT IntermediateType;
+ auto ElementSizeAndAction =
+ findAction(ElemSizeVec, Aspect.Type.getScalarSizeInBits());
+ IntermediateType =
+ LLT::vector(Aspect.Type.getNumElements(), ElementSizeAndAction.first);
+ if (ElementSizeAndAction.second != Legal)
+ return {ElementSizeAndAction.second, IntermediateType};
+
+ auto i = NumElements2Actions[OpcodeIdx].find(
+ IntermediateType.getScalarSizeInBits());
+ if (i == NumElements2Actions[OpcodeIdx].end()) {
+ return {NotFound, IntermediateType};
+ }
+ const SizeAndActionsVec &NumElementsVec = (*i).second[TypeIdx];
+ auto NumElementsAndAction =
+ findAction(NumElementsVec, IntermediateType.getNumElements());
+ return {NumElementsAndAction.second,
+ LLT::vector(NumElementsAndAction.first,
+ IntermediateType.getScalarSizeInBits())};
+}
+
+unsigned LegacyLegalizerInfo::getOpcodeIdxForOpcode(unsigned Opcode) const {
+ assert(Opcode >= FirstOp && Opcode <= LastOp && "Unsupported opcode");
+ return Opcode - FirstOp;
+}
+
+
+LegacyLegalizeActionStep
+LegacyLegalizerInfo::getAction(const LegalityQuery &Query) const {
+ for (unsigned i = 0; i < Query.Types.size(); ++i) {
+ auto Action = getAspectAction({Query.Opcode, i, Query.Types[i]});
+ if (Action.first != Legal) {
+ LLVM_DEBUG(dbgs() << ".. (legacy) Type " << i << " Action="
+ << Action.first << ", " << Action.second << "\n");
+ return {Action.first, i, Action.second};
+ } else
+ LLVM_DEBUG(dbgs() << ".. (legacy) Type " << i << " Legal\n");
+ }
+ LLVM_DEBUG(dbgs() << ".. (legacy) Legal\n");
+ return {Legal, 0, LLT{}};
+}
+
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
index 5a7908ed8118e..d7621667578aa 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
@@ -9,11 +9,6 @@
// Implement an interface to specify and query how an illegal operation on a
// given type should be expanded.
//
-// Issues to be resolved:
-// + Make it fast.
-// + Support weird types like i3, <7 x i3>, ...
-// + Operations with more than one type (ICMP, CMPXCHG, intrinsics, ...)
-//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
@@ -256,146 +251,6 @@ bool LegalizeRuleSet::verifyImmIdxsCoverage(unsigned NumImmIdxs) const {
#endif
}
-LegalizerInfo::LegalizerInfo() : TablesInitialized(false) {
- // Set defaults.
- // FIXME: these two (G_ANYEXT and G_TRUNC?) can be legalized to the
- // fundamental load/store Jakob proposed. Once loads & stores are supported.
- setScalarAction(TargetOpcode::G_ANYEXT, 1, {{1, Legal}});
- setScalarAction(TargetOpcode::G_ZEXT, 1, {{1, Legal}});
- setScalarAction(TargetOpcode::G_SEXT, 1, {{1, Legal}});
- setScalarAction(TargetOpcode::G_TRUNC, 0, {{1, Legal}});
- setScalarAction(TargetOpcode::G_TRUNC, 1, {{1, Legal}});
-
- setScalarAction(TargetOpcode::G_INTRINSIC, 0, {{1, Legal}});
- setScalarAction(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS, 0, {{1, Legal}});
-
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_IMPLICIT_DEF, 0, narrowToSmallerAndUnsupportedIfTooSmall);
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_OR, 0, widenToLargerTypesAndNarrowToLargest);
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_LOAD, 0, narrowToSmallerAndUnsupportedIfTooSmall);
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_STORE, 0, narrowToSmallerAndUnsupportedIfTooSmall);
-
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_BRCOND, 0, widenToLargerTypesUnsupportedOtherwise);
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_INSERT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_EXTRACT, 0, narrowToSmallerAndUnsupportedIfTooSmall);
- setLegalizeScalarToDifferentSizeStrategy(
- TargetOpcode::G_EXTRACT, 1, narrowToSmallerAndUnsupportedIfTooSmall);
- setScalarAction(TargetOpcode::G_FNEG, 0, {{1, Lower}});
-}
-
-void LegalizerInfo::computeTables() {
- assert(TablesInitialized == false);
-
- for (unsigned OpcodeIdx = 0; OpcodeIdx <= LastOp - FirstOp; ++OpcodeIdx) {
- const unsigned Opcode = FirstOp + OpcodeIdx;
- for (unsigned TypeIdx = 0; TypeIdx != SpecifiedActions[OpcodeIdx].size();
- ++TypeIdx) {
- // 0. Collect information specified through the setAction API, i.e.
- // for specific bit sizes.
- // For scalar types:
- SizeAndActionsVec ScalarSpecifiedActions;
- // For pointer types:
- std::map<uint16_t, SizeAndActionsVec> AddressSpace2SpecifiedActions;
- // For vector types:
- std::map<uint16_t, SizeAndActionsVec> ElemSize2SpecifiedActions;
- for (auto LLT2Action : SpecifiedActions[OpcodeIdx][TypeIdx]) {
- const LLT Type = LLT2Action.first;
- const LegalizeAction Action = LLT2Action.second;
-
- auto SizeAction = std::make_pair(Type.getSizeInBits(), Action);
- if (Type.isPointer())
- AddressSpace2SpecifiedActions[Type.getAddressSpace()].push_back(
- SizeAction);
- else if (Type.isVector())
- ElemSize2SpecifiedActions[Type.getElementType().getSizeInBits()]
- .push_back(SizeAction);
- else
- ScalarSpecifiedActions.push_back(SizeAction);
- }
-
- // 1. Handle scalar types
- {
- // Decide how to handle bit sizes for which no explicit specification
- // was given.
- SizeChangeStrategy S = &unsupportedForDifferentSizes;
- if (TypeIdx < ScalarSizeChangeStrategies[OpcodeIdx].size() &&
- ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr)
- S = ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx];
- llvm::sort(ScalarSpecifiedActions);
- checkPartialSizeAndActionsVector(ScalarSpecifiedActions);
- setScalarAction(Opcode, TypeIdx, S(ScalarSpecifiedActions));
- }
-
- // 2. Handle pointer types
- for (auto PointerSpecifiedActions : AddressSpace2SpecifiedActions) {
- llvm::sort(PointerSpecifiedActions.second);
- checkPartialSizeAndActionsVector(PointerSpecifiedActions.second);
- // For pointer types, we assume that there isn't a meaningfull way
- // to change the number of bits used in the pointer.
- setPointerAction(
- Opcode, TypeIdx, PointerSpecifiedActions.first,
- unsupportedForDifferentSizes(PointerSpecifiedActions.second));
- }
-
- // 3. Handle vector types
- SizeAndActionsVec ElementSizesSeen;
- for (auto VectorSpecifiedActions : ElemSize2SpecifiedActions) {
- llvm::sort(VectorSpecifiedActions.second);
- const uint16_t ElementSize = VectorSpecifiedActions.first;
- ElementSizesSeen.push_back({ElementSize, Legal});
- checkPartialSizeAndActionsVector(VectorSpecifiedActions.second);
- // For vector types, we assume that the best way to adapt the number
- // of elements is to the next larger number of elements type for which
- // the vector type is legal, unless there is no such type. In that case,
- // legalize towards a vector type with a smaller number of elements.
- SizeAndActionsVec NumElementsActions;
- for (SizeAndAction BitsizeAndAction : VectorSpecifiedActions.second) {
- assert(BitsizeAndAction.first % ElementSize == 0);
- const uint16_t NumElements = BitsizeAndAction.first / ElementSize;
- NumElementsActions.push_back({NumElements, BitsizeAndAction.second});
- }
- setVectorNumElementAction(
- Opcode, TypeIdx, ElementSize,
- moreToWiderTypesAndLessToWidest(NumElementsActions));
- }
- llvm::sort(ElementSizesSeen);
- SizeChangeStrategy VectorElementSizeChangeStrategy =
- &unsupportedForDifferentSizes;
- if (TypeIdx < VectorElementSizeChangeStrategies[OpcodeIdx].size() &&
- VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr)
- VectorElementSizeChangeStrategy =
- VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx];
- setScalarInVectorAction(
- Opcode, TypeIdx, VectorElementSizeChangeStrategy(ElementSizesSeen));
- }
- }
-
- TablesInitialized = true;
-}
-
-// FIXME: inefficient implementation for now. Without ComputeValueVTs we're
-// probably going to need specialized lookup structures for various types before
-// we have any hope of doing well with something like <13 x i3>. Even the common
-// cases should do better than what we have now.
-std::pair<LegalizeAction, LLT>
-LegalizerInfo::getAspectAction(const InstrAspect &Aspect) const {
- assert(TablesInitialized && "backend forgot to call computeTables");
- // These *have* to be implemented for now, they're the fundamental basis of
- // how everything else is transformed.
- if (Aspect.Type.isScalar() || Aspect.Type.isPointer())
- return findScalarLegalAction(Aspect);
- assert(Aspect.Type.isVector());
- return findVectorLegalAction(Aspect);
-}
-
/// Helper function to get LLT for the given type index.
static LLT getTypeFromTypeIdx(const MachineInstr &MI,
const MachineRegisterInfo &MRI, unsigned OpIdx,
@@ -469,17 +324,7 @@ LegalizerInfo::getAction(const LegalityQuery &Query) const {
return Step;
}
- for (unsigned i = 0; i < Query.Types.size(); ++i) {
- auto Action = getAspectAction({Query.Opcode, i, Query.Types[i]});
- if (Action.first != Legal) {
- LLVM_DEBUG(dbgs() << ".. (legacy) Type " << i << " Action="
- << Action.first << ", " << Action.second << "\n");
- return {Action.first, i, Action.second};
- } else
- LLVM_DEBUG(dbgs() << ".. (legacy) Type " << i << " Legal\n");
- }
- LLVM_DEBUG(dbgs() << ".. (legacy) Legal\n");
- return {Legal, 0, LLT{}};
+ return getLegacyLegalizerInfo().getAction(Query);
}
LegalizeActionStep
@@ -526,163 +371,6 @@ bool LegalizerInfo::isLegalOrCustom(const MachineInstr &MI,
return Action == Legal || Action == Custom;
}
-LegalizerInfo::SizeAndActionsVec
-LegalizerInfo::increaseToLargerTypesAndDecreaseToLargest(
- const SizeAndActionsVec &v, LegalizeAction IncreaseAction,
- LegalizeAction DecreaseAction) {
- SizeAndActionsVec result;
- unsigned LargestSizeSoFar = 0;
- if (v.size() >= 1 && v[0].first != 1)
- result.push_back({1, IncreaseAction});
- for (size_t i = 0; i < v.size(); ++i) {
- result.push_back(v[i]);
- LargestSizeSoFar = v[i].first;
- if (i + 1 < v.size() && v[i + 1].first != v[i].first + 1) {
- result.push_back({LargestSizeSoFar + 1, IncreaseAction});
- LargestSizeSoFar = v[i].first + 1;
- }
- }
- result.push_back({LargestSizeSoFar + 1, DecreaseAction});
- return result;
-}
-
-LegalizerInfo::SizeAndActionsVec
-LegalizerInfo::decreaseToSmallerTypesAndIncreaseToSmallest(
- const SizeAndActionsVec &v, LegalizeAction DecreaseAction,
- LegalizeAction IncreaseAction) {
- SizeAndActionsVec result;
- if (v.size() == 0 || v[0].first != 1)
- result.push_back({1, IncreaseAction});
- for (size_t i = 0; i < v.size(); ++i) {
- result.push_back(v[i]);
- if (i + 1 == v.size() || v[i + 1].first != v[i].first + 1) {
- result.push_back({v[i].first + 1, DecreaseAction});
- }
- }
- return result;
-}
-
-LegalizerInfo::SizeAndAction
-LegalizerInfo::findAction(const SizeAndActionsVec &Vec, const uint32_t Size) {
- assert(Size >= 1);
- // Find the last element in Vec that has a bitsize equal to or smaller than
- // the requested bit size.
- // That is the element just before the first element that is bigger than Size.
- auto It = partition_point(
- Vec, [=](const SizeAndAction &A) { return A.first <= Size; });
- assert(It != Vec.begin() && "Does Vec not start with size 1?");
- int VecIdx = It - Vec.begin() - 1;
-
- LegalizeAction Action = Vec[VecIdx].second;
- switch (Action) {
- case Legal:
- case Bitcast:
- case Lower:
- case Libcall:
- case Custom:
- return {Size, Action};
- case FewerElements:
- // FIXME: is this special case still needed and correct?
- // Special case for scalarization:
- if (Vec == SizeAndActionsVec({{1, FewerElements}}))
- return {1, FewerElements};
- LLVM_FALLTHROUGH;
- case NarrowScalar: {
- // The following needs to be a loop, as for now, we do allow needing to
- // go over "Unsupported" bit sizes before finding a legalizable bit size.
- // e.g. (s8, WidenScalar), (s9, Unsupported), (s32, Legal). if Size==8,
- // we need to iterate over s9, and then to s32 to return (s32, Legal).
- // If we want to get rid of the below loop, we should have stronger asserts
- // when building the SizeAndActionsVecs, probably not allowing
- // "Unsupported" unless at the ends of the vector.
- for (int i = VecIdx - 1; i >= 0; --i)
- if (!needsLegalizingToDifferentSize(Vec[i].second) &&
- Vec[i].second != Unsupported)
- return {Vec[i].first, Action};
- llvm_unreachable("");
- }
- case WidenScalar:
- case MoreElements: {
- // See above, the following needs to be a loop, at least for now.
- for (std::size_t i = VecIdx + 1; i < Vec.size(); ++i)
- if (!needsLegalizingToDifferentSize(Vec[i].second) &&
- Vec[i].second != Unsupported)
- return {Vec[i].first, Action};
- llvm_unreachable("");
- }
- case Unsupported:
- return {Size, Unsupported};
- case NotFound:
- case UseLegacyRules:
- llvm_unreachable("NotFound");
- }
- llvm_unreachable("Action has an unknown enum value");
-}
-
-std::pair<LegalizeAction, LLT>
-LegalizerInfo::findScalarLegalAction(const InstrAspect &Aspect) const {
- assert(Aspect.Type.isScalar() || Aspect.Type.isPointer());
- if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
- return {NotFound, LLT()};
- const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.Opcode);
- if (Aspect.Type.isPointer() &&
- AddrSpace2PointerActions[OpcodeIdx].find(Aspect.Type.getAddressSpace()) ==
- AddrSpace2PointerActions[OpcodeIdx].end()) {
- return {NotFound, LLT()};
- }
- const SmallVector<SizeAndActionsVec, 1> &Actions =
- Aspect.Type.isPointer()
- ? AddrSpace2PointerActions[OpcodeIdx]
- .find(Aspect.Type.getAddressSpace())
- ->second
- : ScalarActions[OpcodeIdx];
- if (Aspect.Idx >= Actions.size())
- return {NotFound, LLT()};
- const SizeAndActionsVec &Vec = Actions[Aspect.Idx];
- // FIXME: speed up this search, e.g. by using a results cache for repeated
- // queries?
- auto SizeAndAction = findAction(Vec, Aspect.Type.getSizeInBits());
- return {SizeAndAction.second,
- Aspect.Type.isScalar() ? LLT::scalar(SizeAndAction.first)
- : LLT::pointer(Aspect.Type.getAddressSpace(),
- SizeAndAction.first)};
-}
-
-std::pair<LegalizeAction, LLT>
-LegalizerInfo::findVectorLegalAction(const InstrAspect &Aspect) const {
- assert(Aspect.Type.isVector());
- // First legalize the vector element size, then legalize the number of
- // lanes in the vector.
- if (Aspect.Opcode < FirstOp || Aspect.Opcode > LastOp)
- return {NotFound, Aspect.Type};
- const unsigned OpcodeIdx = getOpcodeIdxForOpcode(Aspect.Opcode);
- const unsigned TypeIdx = Aspect.Idx;
- if (TypeIdx >= ScalarInVectorActions[OpcodeIdx].size())
- return {NotFound, Aspect.Type};
- const SizeAndActionsVec &ElemSizeVec =
- ScalarInVectorActions[OpcodeIdx][TypeIdx];
-
- LLT IntermediateType;
- auto ElementSizeAndAction =
- findAction(ElemSizeVec, Aspect.Type.getScalarSizeInBits());
- IntermediateType =
- LLT::vector(Aspect.Type.getNumElements(), ElementSizeAndAction.first);
- if (ElementSizeAndAction.second != Legal)
- return {ElementSizeAndAction.second, IntermediateType};
-
- auto i = NumElements2Actions[OpcodeIdx].find(
- IntermediateType.getScalarSizeInBits());
- if (i == NumElements2Actions[OpcodeIdx].end()) {
- return {NotFound, IntermediateType};
- }
- const SizeAndActionsVec &NumElementsVec = (*i).second[TypeIdx];
- auto NumElementsAndAction =
- findAction(NumElementsVec, IntermediateType.getNumElements());
- return {NumElementsAndAction.second,
- LLT::vector(NumElementsAndAction.first,
- IntermediateType.getScalarSizeInBits())};
-}
-
unsigned LegalizerInfo::getExtOpcodeForWideningConstant(LLT SmallTy) const {
return SmallTy.isByteSized() ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 78fbf531ba02b..0a8203d94cdb9 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -69,7 +69,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
// FIXME: support subtargets which have neon/fp-armv8 disabled.
if (!ST.hasNEON() || !ST.hasFPARMv8()) {
- computeTables();
+ getLegacyLegalizerInfo().computeTables();
return;
}
@@ -751,7 +751,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.maxScalarEltSameAsIf(always, 1, 0)
.customFor({{s32, s32}, {s64, s64}});
- computeTables();
+ getLegacyLegalizerInfo().computeTables();
verify(*ST.getInstrInfo());
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index 2fc619efd4339..fc9e9a103f28c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -501,8 +501,11 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
const LLT MinScalarFPTy = ST.has16BitInsts() ? S16 : S32;
- setAction({G_BRCOND, S1}, Legal); // VCC branches
- setAction({G_BRCOND, S32}, Legal); // SCC branches
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+ LegacyInfo.setAction({G_BRCOND, S1},
+ LegacyLegalizeActions::Legal); // VCC branches
+ LegacyInfo.setAction({G_BRCOND, S32},
+ LegacyLegalizeActions::Legal); // SCC branches
// TODO: All multiples of 32, vectors of pointers, all v2s16 pairs, more
// elements for v3s16
@@ -650,7 +653,8 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
.widenScalarToNextPow2(0, 32)
.clampMaxNumElements(0, S32, 16);
- setAction({G_FRAME_INDEX, PrivatePtr}, Legal);
+ LegacyInfo.setAction({G_FRAME_INDEX, PrivatePtr},
+ LegacyLegalizeActions::Legal);
// If the amount is divergent, we have to do a wave reduction to get the
// maximum value, so this is expanded during RegBankSelect.
@@ -660,7 +664,7 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
getActionDefinitionsBuilder(G_GLOBAL_VALUE)
.customIf(typeIsNot(0, PrivatePtr));
- setAction({G_BLOCK_ADDR, CodePtr}, Legal);
+ LegacyInfo.setAction({G_BLOCK_ADDR, CodePtr}, LegacyLegalizeActions::Legal);
auto &FPOpActions = getActionDefinitionsBuilder(
{ G_FADD, G_FMUL, G_FMA, G_FCANONICALIZE})
@@ -1664,7 +1668,7 @@ AMDGPULegalizerInfo::AMDGPULegalizerInfo(const GCNSubtarget &ST_,
G_INDEXED_ZEXTLOAD, G_INDEXED_STORE})
.unsupported();
- computeTables();
+ getLegacyLegalizerInfo().computeTables();
verify(*ST.getInstrInfo());
}
diff --git a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
index d9b60f4c4eba7..9db001cf153e1 100644
--- a/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
@@ -33,29 +33,30 @@ using namespace LegalizeActions;
/// In practice, not specifying those isn't a problem, and the below functions
/// should disappear quickly as we add support for legalizing non-power-of-2
/// sized types further.
-static void
-addAndInterleaveWithUnsupported(LegalizerInfo::SizeAndActionsVec &result,
- const LegalizerInfo::SizeAndActionsVec &v) {
+static void addAndInterleaveWithUnsupported(
+ LegacyLegalizerInfo::SizeAndActionsVec &result,
+ const LegacyLegalizerInfo::SizeAndActionsVec &v) {
for (unsigned i = 0; i < v.size(); ++i) {
result.push_back(v[i]);
if (i + 1 < v[i].first && i + 1 < v.size() &&
v[i + 1].first != v[i].first + 1)
- result.push_back({v[i].first + 1, Unsupported});
+ result.push_back({v[i].first + 1, LegacyLegalizeActions::Unsupported});
}
}
-static LegalizerInfo::SizeAndActionsVec
-widen_8_16(const LegalizerInfo::SizeAndActionsVec &v) {
+static LegacyLegalizerInfo::SizeAndActionsVec
+widen_8_16(const LegacyLegalizerInfo::SizeAndActionsVec &v) {
assert(v.size() >= 1);
assert(v[0].first > 17);
- LegalizerInfo::SizeAndActionsVec result = {{1, Unsupported},
- {8, WidenScalar},
- {9, Unsupported},
- {16, WidenScalar},
- {17, Unsupported}};
+ LegacyLegalizerInfo::SizeAndActionsVec result = {
+ {1, LegacyLegalizeActions::Unsupported},
+ {8, LegacyLegalizeActions::WidenScalar},
+ {9, LegacyLegalizeActions::Unsupported},
+ {16, LegacyLegalizeActions::WidenScalar},
+ {17, LegacyLegalizeActions::Unsupported}};
addAndInterleaveWithUnsupported(result, v);
auto Largest = result.back().first;
- result.push_back({Largest + 1, Unsupported});
+ result.push_back({Largest + 1, LegacyLegalizeActions::Unsupported});
return result;
}
@@ -74,9 +75,10 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
if (ST.isThumb1Only()) {
// Thumb1 is not supported yet.
- computeTables();
+ LegacyInfo.computeTables();
verify(*ST.getInstrInfo());
return;
}
@@ -116,13 +118,13 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
.clampScalar(0, s32, s32);
for (unsigned Op : {G_SREM, G_UREM}) {
- setLegalizeScalarToDifferentSizeStrategy(Op, 0, widen_8_16);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(Op, 0, widen_8_16);
if (HasHWDivide)
- setAction({Op, s32}, Lower);
+ LegacyInfo.setAction({Op, s32}, LegacyLegalizeActions::Lower);
else if (AEABI(ST))
- setAction({Op, s32}, Custom);
+ LegacyInfo.setAction({Op, s32}, LegacyLegalizeActions::Custom);
else
- setAction({Op, s32}, Libcall);
+ LegacyInfo.setAction({Op, s32}, LegacyLegalizeActions::Libcall);
}
getActionDefinitionsBuilder(G_INTTOPTR)
@@ -198,7 +200,7 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
LoadStoreBuilder.maxScalar(0, s32);
for (auto Ty : {s32, s64})
- setAction({G_FNEG, Ty}, Lower);
+ LegacyInfo.setAction({G_FNEG, Ty}, LegacyLegalizeActions::Lower);
getActionDefinitionsBuilder(G_FCONSTANT).customFor({s32, s64});
@@ -246,7 +248,7 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
.clampScalar(0, s32, s32);
}
- computeTables();
+ LegacyInfo.computeTables();
verify(*ST.getInstrInfo());
}
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
index 03aa88d31e6e4..51e1c5f7fc65f 100644
--- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp
@@ -321,7 +321,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
- computeTables();
+ getLegacyLegalizerInfo().computeTables();
verify(*ST.getInstrInfo());
}
diff --git a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
index c16bcaea592bf..5d196df80d50c 100644
--- a/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
+++ b/llvm/lib/Target/PowerPC/GISel/PPCLegalizerInfo.cpp
@@ -17,4 +17,6 @@
using namespace llvm;
using namespace LegalizeActions;
-PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) { computeTables(); }
+PPCLegalizerInfo::PPCLegalizerInfo(const PPCSubtarget &ST) {
+ getLegacyLegalizerInfo().computeTables();
+}
diff --git a/llvm/lib/Target/RISCV/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/RISCVLegalizerInfo.cpp
index c92f4a3ee17b3..f6256defe5d30 100644
--- a/llvm/lib/Target/RISCV/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVLegalizerInfo.cpp
@@ -19,5 +19,5 @@
using namespace llvm;
RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST) {
- computeTables();
+ getLegacyLegalizerInfo().computeTables();
}
diff --git a/llvm/lib/Target/X86/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/X86LegalizerInfo.cpp
index 1b371ac2a1086..72dacf3938503 100644
--- a/llvm/lib/Target/X86/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/X86LegalizerInfo.cpp
@@ -32,26 +32,27 @@ using namespace LegalizeActions;
/// In practice, not specifying those isn't a problem, and the below functions
/// should disappear quickly as we add support for legalizing non-power-of-2
/// sized types further.
-static void
-addAndInterleaveWithUnsupported(LegalizerInfo::SizeAndActionsVec &result,
- const LegalizerInfo::SizeAndActionsVec &v) {
+static void addAndInterleaveWithUnsupported(
+ LegacyLegalizerInfo::SizeAndActionsVec &result,
+ const LegacyLegalizerInfo::SizeAndActionsVec &v) {
for (unsigned i = 0; i < v.size(); ++i) {
result.push_back(v[i]);
if (i + 1 < v[i].first && i + 1 < v.size() &&
v[i + 1].first != v[i].first + 1)
- result.push_back({v[i].first + 1, Unsupported});
+ result.push_back({v[i].first + 1, LegacyLegalizeActions::Unsupported});
}
}
-static LegalizerInfo::SizeAndActionsVec
-widen_1(const LegalizerInfo::SizeAndActionsVec &v) {
+static LegacyLegalizerInfo::SizeAndActionsVec
+widen_1(const LegacyLegalizerInfo::SizeAndActionsVec &v) {
assert(v.size() >= 1);
assert(v[0].first > 1);
- LegalizerInfo::SizeAndActionsVec result = {{1, WidenScalar},
- {2, Unsupported}};
+ LegacyLegalizerInfo::SizeAndActionsVec result = {
+ {1, LegacyLegalizeActions::WidenScalar},
+ {2, LegacyLegalizeActions::Unsupported}};
addAndInterleaveWithUnsupported(result, v);
auto Largest = result.back().first;
- result.push_back({Largest + 1, Unsupported});
+ result.push_back({Largest + 1, LegacyLegalizeActions::Unsupported});
return result;
}
@@ -75,20 +76,23 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
.minScalar(0, LLT::scalar(32))
.libcall();
- setLegalizeScalarToDifferentSizeStrategy(G_PHI, 0, widen_1);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(G_PHI, 0, widen_1);
for (unsigned BinOp : {G_SUB, G_MUL, G_AND, G_OR, G_XOR})
- setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(BinOp, 0, widen_1);
for (unsigned MemOp : {G_LOAD, G_STORE})
- setLegalizeScalarToDifferentSizeStrategy(MemOp, 0,
- narrowToSmallerAndWidenToSmallest);
- setLegalizeScalarToDifferentSizeStrategy(
- G_PTR_ADD, 1, widenToLargerTypesUnsupportedOtherwise);
- setLegalizeScalarToDifferentSizeStrategy(
- G_CONSTANT, 0, widenToLargerTypesAndNarrowToLargest);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
+ MemOp, 0, LegacyLegalizerInfo::narrowToSmallerAndWidenToSmallest);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
+ G_PTR_ADD, 1,
+ LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
+ G_CONSTANT, 0,
+ LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest);
getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
- computeTables();
+ LegacyInfo.computeTables();
verify(*STI.getInstrInfo());
}
@@ -107,35 +111,37 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
const LLT s64 = LLT::scalar(64);
const LLT s128 = LLT::scalar(128);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
for (auto Ty : {p0, s1, s8, s16, s32})
- setAction({G_IMPLICIT_DEF, Ty}, Legal);
+ LegacyInfo.setAction({G_IMPLICIT_DEF, Ty}, LegacyLegalizeActions::Legal);
for (auto Ty : {s8, s16, s32, p0})
- setAction({G_PHI, Ty}, Legal);
+ LegacyInfo.setAction({G_PHI, Ty}, LegacyLegalizeActions::Legal);
for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})
for (auto Ty : {s8, s16, s32})
- setAction({BinOp, Ty}, Legal);
+ LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
for (unsigned Op : {G_UADDE}) {
- setAction({Op, s32}, Legal);
- setAction({Op, 1, s1}, Legal);
+ LegacyInfo.setAction({Op, s32}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({Op, 1, s1}, LegacyLegalizeActions::Legal);
}
for (unsigned MemOp : {G_LOAD, G_STORE}) {
for (auto Ty : {s8, s16, s32, p0})
- setAction({MemOp, Ty}, Legal);
+ LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
// And everything's fine in addrspace 0.
- setAction({MemOp, 1, p0}, Legal);
+ LegacyInfo.setAction({MemOp, 1, p0}, LegacyLegalizeActions::Legal);
}
// Pointer-handling
- setAction({G_FRAME_INDEX, p0}, Legal);
- setAction({G_GLOBAL_VALUE, p0}, Legal);
+ LegacyInfo.setAction({G_FRAME_INDEX, p0}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_GLOBAL_VALUE, p0}, LegacyLegalizeActions::Legal);
- setAction({G_PTR_ADD, p0}, Legal);
- setAction({G_PTR_ADD, 1, s32}, Legal);
+ LegacyInfo.setAction({G_PTR_ADD, p0}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_PTR_ADD, 1, s32}, LegacyLegalizeActions::Legal);
if (!Subtarget.is64Bit()) {
getActionDefinitionsBuilder(G_PTRTOINT)
@@ -163,29 +169,31 @@ void X86LegalizerInfo::setLegalizerInfo32bit() {
}
// Control-flow
- setAction({G_BRCOND, s1}, Legal);
+ LegacyInfo.setAction({G_BRCOND, s1}, LegacyLegalizeActions::Legal);
// Constants
for (auto Ty : {s8, s16, s32, p0})
- setAction({TargetOpcode::G_CONSTANT, Ty}, Legal);
+ LegacyInfo.setAction({TargetOpcode::G_CONSTANT, Ty},
+ LegacyLegalizeActions::Legal);
// Extensions
for (auto Ty : {s8, s16, s32}) {
- setAction({G_ZEXT, Ty}, Legal);
- setAction({G_SEXT, Ty}, Legal);
- setAction({G_ANYEXT, Ty}, Legal);
+ LegacyInfo.setAction({G_ZEXT, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_SEXT, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_ANYEXT, Ty}, LegacyLegalizeActions::Legal);
}
- setAction({G_ANYEXT, s128}, Legal);
+ LegacyInfo.setAction({G_ANYEXT, s128}, LegacyLegalizeActions::Legal);
getActionDefinitionsBuilder(G_SEXT_INREG).lower();
// Merge/Unmerge
for (const auto &Ty : {s16, s32, s64}) {
- setAction({G_MERGE_VALUES, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, 1, Ty}, Legal);
+ LegacyInfo.setAction({G_MERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
+ LegacyLegalizeActions::Legal);
}
for (const auto &Ty : {s8, s16, s32}) {
- setAction({G_MERGE_VALUES, 1, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, Ty}, Legal);
+ LegacyInfo.setAction({G_MERGE_VALUES, 1, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
}
}
@@ -202,21 +210,23 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
const LLT s64 = LLT::scalar(64);
const LLT s128 = LLT::scalar(128);
- setAction({G_IMPLICIT_DEF, s64}, Legal);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
+ LegacyInfo.setAction({G_IMPLICIT_DEF, s64}, LegacyLegalizeActions::Legal);
// Need to have that, as tryFoldImplicitDef will create this pattern:
// s128 = EXTEND (G_IMPLICIT_DEF s32/s64) -> s128 = G_IMPLICIT_DEF
- setAction({G_IMPLICIT_DEF, s128}, Legal);
+ LegacyInfo.setAction({G_IMPLICIT_DEF, s128}, LegacyLegalizeActions::Legal);
- setAction({G_PHI, s64}, Legal);
+ LegacyInfo.setAction({G_PHI, s64}, LegacyLegalizeActions::Legal);
for (unsigned BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR})
- setAction({BinOp, s64}, Legal);
+ LegacyInfo.setAction({BinOp, s64}, LegacyLegalizeActions::Legal);
for (unsigned MemOp : {G_LOAD, G_STORE})
- setAction({MemOp, s64}, Legal);
+ LegacyInfo.setAction({MemOp, s64}, LegacyLegalizeActions::Legal);
// Pointer-handling
- setAction({G_PTR_ADD, 1, s64}, Legal);
+ LegacyInfo.setAction({G_PTR_ADD, 1, s64}, LegacyLegalizeActions::Legal);
getActionDefinitionsBuilder(G_PTRTOINT)
.legalForCartesianProduct({s1, s8, s16, s32, s64}, {p0})
.maxScalar(0, s64)
@@ -224,11 +234,12 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
getActionDefinitionsBuilder(G_INTTOPTR).legalFor({{p0, s64}});
// Constants
- setAction({TargetOpcode::G_CONSTANT, s64}, Legal);
+ LegacyInfo.setAction({TargetOpcode::G_CONSTANT, s64},
+ LegacyLegalizeActions::Legal);
// Extensions
for (unsigned extOp : {G_ZEXT, G_SEXT, G_ANYEXT}) {
- setAction({extOp, s64}, Legal);
+ LegacyInfo.setAction({extOp, s64}, LegacyLegalizeActions::Legal);
}
getActionDefinitionsBuilder(G_SITOFP)
@@ -270,10 +281,11 @@ void X86LegalizerInfo::setLegalizerInfo64bit() {
.clampScalar(1, s8, s8);
// Merge/Unmerge
- setAction({G_MERGE_VALUES, s128}, Legal);
- setAction({G_UNMERGE_VALUES, 1, s128}, Legal);
- setAction({G_MERGE_VALUES, 1, s128}, Legal);
- setAction({G_UNMERGE_VALUES, s128}, Legal);
+ LegacyInfo.setAction({G_MERGE_VALUES, s128}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, 1, s128},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_MERGE_VALUES, 1, s128}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, s128}, LegacyLegalizeActions::Legal);
}
void X86LegalizerInfo::setLegalizerInfoSSE1() {
@@ -285,24 +297,28 @@ void X86LegalizerInfo::setLegalizerInfoSSE1() {
const LLT v4s32 = LLT::vector(4, 32);
const LLT v2s64 = LLT::vector(2, 64);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
for (auto Ty : {s32, v4s32})
- setAction({BinOp, Ty}, Legal);
+ LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
for (unsigned MemOp : {G_LOAD, G_STORE})
for (auto Ty : {v4s32, v2s64})
- setAction({MemOp, Ty}, Legal);
+ LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
// Constants
- setAction({TargetOpcode::G_FCONSTANT, s32}, Legal);
+ LegacyInfo.setAction({TargetOpcode::G_FCONSTANT, s32},
+ LegacyLegalizeActions::Legal);
// Merge/Unmerge
for (const auto &Ty : {v4s32, v2s64}) {
- setAction({G_CONCAT_VECTORS, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, 1, Ty}, Legal);
+ LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
+ LegacyLegalizeActions::Legal);
}
- setAction({G_MERGE_VALUES, 1, s64}, Legal);
- setAction({G_UNMERGE_VALUES, s64}, Legal);
+ LegacyInfo.setAction({G_MERGE_VALUES, 1, s64}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, s64}, LegacyLegalizeActions::Legal);
}
void X86LegalizerInfo::setLegalizerInfoSSE2() {
@@ -321,34 +337,39 @@ void X86LegalizerInfo::setLegalizerInfoSSE2() {
const LLT v8s32 = LLT::vector(8, 32);
const LLT v4s64 = LLT::vector(4, 64);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
for (auto Ty : {s64, v2s64})
- setAction({BinOp, Ty}, Legal);
+ LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
for (unsigned BinOp : {G_ADD, G_SUB})
for (auto Ty : {v16s8, v8s16, v4s32, v2s64})
- setAction({BinOp, Ty}, Legal);
+ LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
- setAction({G_MUL, v8s16}, Legal);
+ LegacyInfo.setAction({G_MUL, v8s16}, LegacyLegalizeActions::Legal);
- setAction({G_FPEXT, s64}, Legal);
- setAction({G_FPEXT, 1, s32}, Legal);
+ LegacyInfo.setAction({G_FPEXT, s64}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_FPEXT, 1, s32}, LegacyLegalizeActions::Legal);
- setAction({G_FPTRUNC, s32}, Legal);
- setAction({G_FPTRUNC, 1, s64}, Legal);
+ LegacyInfo.setAction({G_FPTRUNC, s32}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_FPTRUNC, 1, s64}, LegacyLegalizeActions::Legal);
// Constants
- setAction({TargetOpcode::G_FCONSTANT, s64}, Legal);
+ LegacyInfo.setAction({TargetOpcode::G_FCONSTANT, s64},
+ LegacyLegalizeActions::Legal);
// Merge/Unmerge
for (const auto &Ty :
{v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) {
- setAction({G_CONCAT_VECTORS, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, 1, Ty}, Legal);
+ LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
+ LegacyLegalizeActions::Legal);
}
for (const auto &Ty : {v16s8, v8s16, v4s32, v2s64}) {
- setAction({G_CONCAT_VECTORS, 1, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, Ty}, Legal);
+ LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
}
}
@@ -358,7 +379,9 @@ void X86LegalizerInfo::setLegalizerInfoSSE41() {
const LLT v4s32 = LLT::vector(4, 32);
- setAction({G_MUL, v4s32}, Legal);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
+ LegacyInfo.setAction({G_MUL, v4s32}, LegacyLegalizeActions::Legal);
}
void X86LegalizerInfo::setLegalizerInfoAVX() {
@@ -379,28 +402,32 @@ void X86LegalizerInfo::setLegalizerInfoAVX() {
const LLT v4s64 = LLT::vector(4, 64);
const LLT v8s64 = LLT::vector(8, 64);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
for (unsigned MemOp : {G_LOAD, G_STORE})
for (auto Ty : {v8s32, v4s64})
- setAction({MemOp, Ty}, Legal);
+ LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
for (auto Ty : {v32s8, v16s16, v8s32, v4s64}) {
- setAction({G_INSERT, Ty}, Legal);
- setAction({G_EXTRACT, 1, Ty}, Legal);
+ LegacyInfo.setAction({G_INSERT, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_EXTRACT, 1, Ty}, LegacyLegalizeActions::Legal);
}
for (auto Ty : {v16s8, v8s16, v4s32, v2s64}) {
- setAction({G_INSERT, 1, Ty}, Legal);
- setAction({G_EXTRACT, Ty}, Legal);
+ LegacyInfo.setAction({G_INSERT, 1, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_EXTRACT, Ty}, LegacyLegalizeActions::Legal);
}
// Merge/Unmerge
for (const auto &Ty :
{v32s8, v64s8, v16s16, v32s16, v8s32, v16s32, v4s64, v8s64}) {
- setAction({G_CONCAT_VECTORS, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, 1, Ty}, Legal);
+ LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
+ LegacyLegalizeActions::Legal);
}
for (const auto &Ty :
{v16s8, v32s8, v8s16, v16s16, v4s32, v8s32, v2s64, v4s64}) {
- setAction({G_CONCAT_VECTORS, 1, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, Ty}, Legal);
+ LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
}
}
@@ -418,21 +445,25 @@ void X86LegalizerInfo::setLegalizerInfoAVX2() {
const LLT v16s32 = LLT::vector(16, 32);
const LLT v8s64 = LLT::vector(8, 64);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
for (unsigned BinOp : {G_ADD, G_SUB})
for (auto Ty : {v32s8, v16s16, v8s32, v4s64})
- setAction({BinOp, Ty}, Legal);
+ LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
for (auto Ty : {v16s16, v8s32})
- setAction({G_MUL, Ty}, Legal);
+ LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
// Merge/Unmerge
for (const auto &Ty : {v64s8, v32s16, v16s32, v8s64}) {
- setAction({G_CONCAT_VECTORS, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, 1, Ty}, Legal);
+ LegacyInfo.setAction({G_CONCAT_VECTORS, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, 1, Ty},
+ LegacyLegalizeActions::Legal);
}
for (const auto &Ty : {v32s8, v16s16, v8s32, v4s64}) {
- setAction({G_CONCAT_VECTORS, 1, Ty}, Legal);
- setAction({G_UNMERGE_VALUES, Ty}, Legal);
+ LegacyInfo.setAction({G_CONCAT_VECTORS, 1, Ty},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_UNMERGE_VALUES, Ty}, LegacyLegalizeActions::Legal);
}
}
@@ -455,23 +486,25 @@ void X86LegalizerInfo::setLegalizerInfoAVX512() {
const LLT v16s32 = LLT::vector(16, 32);
const LLT v8s64 = LLT::vector(8, 64);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
for (unsigned BinOp : {G_ADD, G_SUB})
for (auto Ty : {v16s32, v8s64})
- setAction({BinOp, Ty}, Legal);
+ LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
- setAction({G_MUL, v16s32}, Legal);
+ LegacyInfo.setAction({G_MUL, v16s32}, LegacyLegalizeActions::Legal);
for (unsigned MemOp : {G_LOAD, G_STORE})
for (auto Ty : {v16s32, v8s64})
- setAction({MemOp, Ty}, Legal);
+ LegacyInfo.setAction({MemOp, Ty}, LegacyLegalizeActions::Legal);
for (auto Ty : {v64s8, v32s16, v16s32, v8s64}) {
- setAction({G_INSERT, Ty}, Legal);
- setAction({G_EXTRACT, 1, Ty}, Legal);
+ LegacyInfo.setAction({G_INSERT, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_EXTRACT, 1, Ty}, LegacyLegalizeActions::Legal);
}
for (auto Ty : {v32s8, v16s16, v8s32, v4s64, v16s8, v8s16, v4s32, v2s64}) {
- setAction({G_INSERT, 1, Ty}, Legal);
- setAction({G_EXTRACT, Ty}, Legal);
+ LegacyInfo.setAction({G_INSERT, 1, Ty}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_EXTRACT, Ty}, LegacyLegalizeActions::Legal);
}
/************ VLX *******************/
@@ -479,7 +512,7 @@ void X86LegalizerInfo::setLegalizerInfoAVX512() {
return;
for (auto Ty : {v4s32, v8s32})
- setAction({G_MUL, Ty}, Legal);
+ LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
}
void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
@@ -488,7 +521,9 @@ void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
const LLT v8s64 = LLT::vector(8, 64);
- setAction({G_MUL, v8s64}, Legal);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
+ LegacyInfo.setAction({G_MUL, v8s64}, LegacyLegalizeActions::Legal);
/************ VLX *******************/
if (!Subtarget.hasVLX())
@@ -498,7 +533,7 @@ void X86LegalizerInfo::setLegalizerInfoAVX512DQ() {
const LLT v4s64 = LLT::vector(4, 64);
for (auto Ty : {v2s64, v4s64})
- setAction({G_MUL, Ty}, Legal);
+ LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
}
void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
@@ -508,11 +543,13 @@ void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
const LLT v64s8 = LLT::vector(64, 8);
const LLT v32s16 = LLT::vector(32, 16);
+ auto &LegacyInfo = getLegacyLegalizerInfo();
+
for (unsigned BinOp : {G_ADD, G_SUB})
for (auto Ty : {v64s8, v32s16})
- setAction({BinOp, Ty}, Legal);
+ LegacyInfo.setAction({BinOp, Ty}, LegacyLegalizeActions::Legal);
- setAction({G_MUL, v32s16}, Legal);
+ LegacyInfo.setAction({G_MUL, v32s16}, LegacyLegalizeActions::Legal);
/************ VLX *******************/
if (!Subtarget.hasVLX())
@@ -522,5 +559,5 @@ void X86LegalizerInfo::setLegalizerInfoAVX512BW() {
const LLT v16s16 = LLT::vector(16, 16);
for (auto Ty : {v8s16, v16s16})
- setAction({G_MUL, Ty}, Legal);
+ LegacyInfo.setAction({G_MUL, Ty}, LegacyLegalizeActions::Legal);
}
diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
index 336915ce86512..0eee92cffadc3 100644
--- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
+++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h
@@ -169,7 +169,7 @@ class AMDGPUGISelMITest : public GISelMITest {
(void)s128; \
do \
SettingUpActionsBlock while (0); \
- computeTables(); \
+ getLegacyLegalizerInfo().computeTables(); \
verify(*ST.getInstrInfo()); \
} \
};
diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index bce74e3f9806d..3bdb1b4c42014 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -1409,7 +1409,7 @@ TEST_F(AArch64GISelMITest, MoreElementsAnd) {
LI.getActionDefinitionsBuilder(TargetOpcode::G_AND)
.legalFor({v6s32})
.clampMinNumElements(0, s32, 6);
- LI.computeTables();
+ LI.getLegacyLegalizerInfo().computeTables();
DummyGISelObserver Observer;
LegalizerHelper Helper(*MF, LI, Observer, B);
@@ -1454,7 +1454,7 @@ TEST_F(AArch64GISelMITest, FewerElementsPhi) {
LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)
.legalFor({v2s32})
.clampMinNumElements(0, s32, 2);
- LI.computeTables();
+ LI.getLegacyLegalizerInfo().computeTables();
LLT PhiTy = v5s32;
DummyGISelObserver Observer;
diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
index ac9112fe5aa49..ed7f3944a697f 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerInfoTest.cpp
@@ -48,15 +48,17 @@ namespace {
TEST(LegalizerInfoTest, ScalarRISC) {
using namespace TargetOpcode;
LegalizerInfo L;
+ auto &LegacyInfo = L.getLegacyLegalizerInfo();
// Typical RISCy set of operations based on AArch64.
for (unsigned Op : {G_ADD, G_SUB}) {
for (unsigned Size : {32, 64})
- L.setAction({Op, 0, LLT::scalar(Size)}, Legal);
- L.setLegalizeScalarToDifferentSizeStrategy(
- Op, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest);
+ LegacyInfo.setAction({Op, 0, LLT::scalar(Size)},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
+ Op, 0, LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest);
}
- L.computeTables();
+ LegacyInfo.computeTables();
for (unsigned opcode : {G_ADD, G_SUB}) {
// Check we infer the correct types and actually do what we're told.
@@ -89,20 +91,28 @@ TEST(LegalizerInfoTest, ScalarRISC) {
TEST(LegalizerInfoTest, VectorRISC) {
using namespace TargetOpcode;
LegalizerInfo L;
+ auto &LegacyInfo = L.getLegacyLegalizerInfo();
// Typical RISCy set of operations based on ARM.
- L.setAction({G_ADD, LLT::vector(8, 8)}, Legal);
- L.setAction({G_ADD, LLT::vector(16, 8)}, Legal);
- L.setAction({G_ADD, LLT::vector(4, 16)}, Legal);
- L.setAction({G_ADD, LLT::vector(8, 16)}, Legal);
- L.setAction({G_ADD, LLT::vector(2, 32)}, Legal);
- L.setAction({G_ADD, LLT::vector(4, 32)}, Legal);
-
- L.setLegalizeVectorElementToDifferentSizeStrategy(
- G_ADD, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
-
- L.setAction({G_ADD, 0, LLT::scalar(32)}, Legal);
-
- L.computeTables();
+ LegacyInfo.setAction({G_ADD, LLT::vector(8, 8)},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_ADD, LLT::vector(16, 8)},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_ADD, LLT::vector(4, 16)},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_ADD, LLT::vector(8, 16)},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_ADD, LLT::vector(2, 32)},
+ LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_ADD, LLT::vector(4, 32)},
+ LegacyLegalizeActions::Legal);
+
+ LegacyInfo.setLegalizeVectorElementToDifferentSizeStrategy(
+ G_ADD, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
+
+ LegacyInfo.setAction({G_ADD, 0, LLT::scalar(32)},
+ LegacyLegalizeActions::Legal);
+
+ LegacyInfo.computeTables();
// Check we infer the correct types and actually do what we're told for some
// simple cases.
@@ -124,17 +134,18 @@ TEST(LegalizerInfoTest, VectorRISC) {
TEST(LegalizerInfoTest, MultipleTypes) {
using namespace TargetOpcode;
LegalizerInfo L;
+ auto &LegacyInfo = L.getLegacyLegalizerInfo();
LLT p0 = LLT::pointer(0, 64);
LLT s64 = LLT::scalar(64);
// Typical RISCy set of operations based on AArch64.
- L.setAction({G_PTRTOINT, 0, s64}, Legal);
- L.setAction({G_PTRTOINT, 1, p0}, Legal);
+ LegacyInfo.setAction({G_PTRTOINT, 0, s64}, LegacyLegalizeActions::Legal);
+ LegacyInfo.setAction({G_PTRTOINT, 1, p0}, LegacyLegalizeActions::Legal);
- L.setLegalizeScalarToDifferentSizeStrategy(
- G_PTRTOINT, 0, LegalizerInfo::widenToLargerTypesAndNarrowToLargest);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
+ G_PTRTOINT, 0, LegacyLegalizerInfo::widenToLargerTypesAndNarrowToLargest);
- L.computeTables();
+ LegacyInfo.computeTables();
// Check we infer the correct types and actually do what we're told.
EXPECT_EQ(L.getAction({G_PTRTOINT, {s64, p0}}),
@@ -152,15 +163,16 @@ TEST(LegalizerInfoTest, MultipleTypes) {
TEST(LegalizerInfoTest, MultipleSteps) {
using namespace TargetOpcode;
LegalizerInfo L;
+ auto &LegacyInfo = L.getLegacyLegalizerInfo();
LLT s32 = LLT::scalar(32);
LLT s64 = LLT::scalar(64);
- L.setLegalizeScalarToDifferentSizeStrategy(
- G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
- L.setAction({G_UREM, 0, s32}, Lower);
- L.setAction({G_UREM, 0, s64}, Lower);
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
+ G_UREM, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
+ LegacyInfo.setAction({G_UREM, 0, s32}, LegacyLegalizeActions::Lower);
+ LegacyInfo.setAction({G_UREM, 0, s64}, LegacyLegalizeActions::Lower);
- L.computeTables();
+ LegacyInfo.computeTables();
EXPECT_EQ(L.getAction({G_UREM, {LLT::scalar(16)}}),
LegalizeActionStep(WidenScalar, 0, LLT::scalar(32)));
@@ -171,12 +183,14 @@ TEST(LegalizerInfoTest, MultipleSteps) {
TEST(LegalizerInfoTest, SizeChangeStrategy) {
using namespace TargetOpcode;
LegalizerInfo L;
+ auto &LegacyInfo = L.getLegacyLegalizerInfo();
for (unsigned Size : {1, 8, 16, 32})
- L.setAction({G_UREM, 0, LLT::scalar(Size)}, Legal);
+ LegacyInfo.setAction({G_UREM, 0, LLT::scalar(Size)},
+ LegacyLegalizeActions::Legal);
- L.setLegalizeScalarToDifferentSizeStrategy(
- G_UREM, 0, LegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
- L.computeTables();
+ LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
+ G_UREM, 0, LegacyLegalizerInfo::widenToLargerTypesUnsupportedOtherwise);
+ LegacyInfo.computeTables();
// Check we infer the correct types and actually do what we're told.
for (unsigned Size : {1, 8, 16, 32}) {
@@ -229,11 +243,12 @@ TEST(LegalizerInfoTest, RuleSets) {
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_IMPLICIT_DEF)
.legalFor({v4s32, v4p0})
.moreElementsToNextPow2(0);
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {s32}));
EXPECT_ACTION(Unsupported, 0, LLT(), LegalityQuery(G_IMPLICIT_DEF, {v2s32}));
@@ -244,10 +259,11 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test minScalarOrElt
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_OR)
.legalFor({s32})
.minScalarOrElt(0, s32);
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
EXPECT_ACTION(WidenScalar, 0, v2s32, LegalityQuery(G_OR, {v2s16}));
@@ -256,10 +272,11 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test maxScalarOrELt
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_AND)
.legalFor({s16})
.maxScalarOrElt(0, s16);
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
EXPECT_ACTION(NarrowScalar, 0, v2s16, LegalityQuery(G_AND, {v2s32}));
@@ -268,10 +285,11 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test clampScalarOrElt
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_XOR)
.legalFor({s16})
.clampScalarOrElt(0, s16, s32);
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
@@ -284,10 +302,11 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test minScalar
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_OR)
.legalFor({s32})
.minScalar(0, s32);
- LI.computeTables();
+ LegacyInfo.computeTables();
// Only handle scalars, ignore vectors.
EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_OR, {s16}));
@@ -297,10 +316,11 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test maxScalar
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_AND)
.legalFor({s16})
.maxScalar(0, s16);
- LI.computeTables();
+ LegacyInfo.computeTables();
// Only handle scalars, ignore vectors.
EXPECT_ACTION(NarrowScalar, 0, s16, LegalityQuery(G_AND, {s32}));
@@ -310,11 +330,12 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test clampScalar
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_XOR)
.legalFor({s16})
.clampScalar(0, s16, s32);
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(NarrowScalar, 0, s32, LegalityQuery(G_XOR, {s64}));
EXPECT_ACTION(WidenScalar, 0, s16, LegalityQuery(G_XOR, {s8}));
@@ -327,11 +348,12 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test widenScalarOrEltToNextPow2
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_AND)
.legalFor({s32})
.widenScalarOrEltToNextPow2(0, 32);
- LI.computeTables();
+ LegacyInfo.computeTables();
// Handle scalars and vectors
EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
@@ -343,11 +365,12 @@ TEST(LegalizerInfoTest, RuleSets) {
// Test widenScalarToNextPow2
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_AND)
.legalFor({s32})
.widenScalarToNextPow2(0, 32);
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(WidenScalar, 0, s32, LegalityQuery(G_AND, {s5}));
EXPECT_ACTION(WidenScalar, 0, s64, LegalityQuery(G_AND, {s33}));
@@ -366,10 +389,11 @@ TEST(LegalizerInfoTest, MMOAlignment) {
{
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_LOAD)
.legalForTypesWithMemDesc({{s32, p0, 32, 32}});
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(Legal, 0, LLT(),
LegalityQuery(G_LOAD, {s32, p0},
@@ -391,10 +415,11 @@ TEST(LegalizerInfoTest, MMOAlignment) {
const uint64_t MaxAlignment = UINT64_C(1) << 29;
const uint64_t MaxAlignInBits = 8 * MaxAlignment;
LegalizerInfo LI;
+ auto &LegacyInfo = LI.getLegacyLegalizerInfo();
LI.getActionDefinitionsBuilder(G_LOAD)
.legalForTypesWithMemDesc({{s32, p0, 32, MaxAlignInBits}});
- LI.computeTables();
+ LegacyInfo.computeTables();
EXPECT_ACTION(Legal, 0, LLT(),
LegalityQuery(G_LOAD, {s32, p0},
More information about the llvm-commits
mailing list