[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