//===- SelectionDAGISel.cpp - Implement the SelectionDAGISel class --------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This implements the SelectionDAGISel class.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/SelectionDAGISel.h"
#include "ScheduleDAGSDNodes.h"
#include "SelectionDAGBuilder.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/UniformityAnalysis.h"
#include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
#include "llvm/CodeGen/CodeGenCommonISel.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/StackProtector.h"
#include "llvm/CodeGen/SwiftErrorValueTracking.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <limits>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "isel"
#define ISEL_DUMP_DEBUG_TYPE DEBUG_TYPE "-dump"

STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
STATISTIC(NumFastIselSuccess, "Number of instructions fast isel selected");
STATISTIC(NumFastIselBlocks, "Number of blocks selected entirely by fast isel");
STATISTIC(NumDAGBlocks, "Number of blocks selected using DAG");
STATISTIC(NumDAGIselRetries,"Number of times dag isel has to try another path");
STATISTIC(NumEntryBlocks, "Number of entry blocks encountered");
STATISTIC(NumFastIselFailLowerArguments,
          "Number of entry blocks where fast isel failed to lower arguments");

static cl::opt<int> EnableFastISelAbort(
    "fast-isel-abort", cl::Hidden,
    cl::desc("Enable abort calls when \"fast\" instruction selection "
             "fails to lower an instruction: 0 disable the abort, 1 will "
             "abort but for args, calls and terminators, 2 will also "
             "abort for argument lowering, and 3 will never fallback "
             "to SelectionDAG."));

static cl::opt<bool> EnableFastISelFallbackReport(
    "fast-isel-report-on-fallback", cl::Hidden,
    cl::desc("Emit a diagnostic when \"fast\" instruction selection "
             "falls back to SelectionDAG."));

static cl::opt<bool>
UseMBPI("use-mbpi",
        cl::desc("use Machine Branch Probability Info"),
        cl::init(true), cl::Hidden);

#ifndef NDEBUG
static cl::opt<std::string>
FilterDAGBasicBlockName("filter-view-dags", cl::Hidden,
                        cl::desc("Only display the basic block whose name "
                                 "matches this for all view-*-dags options"));
static cl::opt<bool>
ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden,
          cl::desc("Pop up a window to show dags before the first "
                   "dag combine pass"));
static cl::opt<bool>
ViewLegalizeTypesDAGs("view-legalize-types-dags", cl::Hidden,
          cl::desc("Pop up a window to show dags before legalize types"));
static cl::opt<bool>
    ViewDAGCombineLT("view-dag-combine-lt-dags", cl::Hidden,
                     cl::desc("Pop up a window to show dags before the post "
                              "legalize types dag combine pass"));
static cl::opt<bool>
    ViewLegalizeDAGs("view-legalize-dags", cl::Hidden,
                     cl::desc("Pop up a window to show dags before legalize"));
static cl::opt<bool>
ViewDAGCombine2("view-dag-combine2-dags", cl::Hidden,
          cl::desc("Pop up a window to show dags before the second "
                   "dag combine pass"));
static cl::opt<bool>
ViewISelDAGs("view-isel-dags", cl::Hidden,
          cl::desc("Pop up a window to show isel dags as they are selected"));
static cl::opt<bool>
ViewSchedDAGs("view-sched-dags", cl::Hidden,
          cl::desc("Pop up a window to show sched dags as they are processed"));
static cl::opt<bool>
ViewSUnitDAGs("view-sunit-dags", cl::Hidden,
      cl::desc("Pop up a window to show SUnit dags after they are processed"));
#else
static const bool ViewDAGCombine1 = false, ViewLegalizeTypesDAGs = false,
                  ViewDAGCombineLT = false, ViewLegalizeDAGs = false,
                  ViewDAGCombine2 = false, ViewISelDAGs = false,
                  ViewSchedDAGs = false, ViewSUnitDAGs = false;
#endif

#ifndef NDEBUG
#define ISEL_DUMP(X)                                                           \
  do {                                                                         \
    if (llvm::DebugFlag &&                                                     \
        (isCurrentDebugType(DEBUG_TYPE) ||                                     \
         (isCurrentDebugType(ISEL_DUMP_DEBUG_TYPE) && MatchFilterFuncName))) { \
      X;                                                                       \
    }                                                                          \
  } while (false)
#else
#define ISEL_DUMP(X) do { } while (false)
#endif

//===---------------------------------------------------------------------===//
///
/// RegisterScheduler class - Track the registration of instruction schedulers.
///
//===---------------------------------------------------------------------===//
MachinePassRegistry<RegisterScheduler::FunctionPassCtor>
    RegisterScheduler::Registry;

//===---------------------------------------------------------------------===//
///
/// ISHeuristic command line option for instruction schedulers.
///
//===---------------------------------------------------------------------===//
static cl::opt<RegisterScheduler::FunctionPassCtor, false,
               RegisterPassParser<RegisterScheduler>>
ISHeuristic("pre-RA-sched",
            cl::init(&createDefaultScheduler), cl::Hidden,
            cl::desc("Instruction schedulers available (before register"
                     " allocation):"));

static RegisterScheduler
defaultListDAGScheduler("default", "Best scheduler for the target",
                        createDefaultScheduler);

static bool dontUseFastISelFor(const Function &Fn) {
  // Don't enable FastISel for functions with swiftasync Arguments.
  // Debug info on those is reliant on good Argument lowering, and FastISel is
  // not capable of lowering the entire function. Mixing the two selectors tend
  // to result in poor lowering of Arguments.
  return any_of(Fn.args(), [](const Argument &Arg) {
    return Arg.hasAttribute(Attribute::AttrKind::SwiftAsync);
  });
}

namespace llvm {

  //===--------------------------------------------------------------------===//
  /// This class is used by SelectionDAGISel to temporarily override
  /// the optimization level on a per-function basis.
  class OptLevelChanger {
    SelectionDAGISel &IS;
    CodeGenOptLevel SavedOptLevel;
    bool SavedFastISel;

  public:
    OptLevelChanger(SelectionDAGISel &ISel, CodeGenOptLevel NewOptLevel)
        : IS(ISel) {
      SavedOptLevel = IS.OptLevel;
      SavedFastISel = IS.TM.Options.EnableFastISel;
      if (NewOptLevel != SavedOptLevel) {
        IS.OptLevel = NewOptLevel;
        IS.TM.setOptLevel(NewOptLevel);
        LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
                          << IS.MF->getFunction().getName() << "\n");
        LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel)
                          << " ; After: -O" << static_cast<int>(NewOptLevel)
                          << "\n");
        if (NewOptLevel == CodeGenOptLevel::None)
          IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
      }
      if (dontUseFastISelFor(IS.MF->getFunction()))
        IS.TM.setFastISel(false);
      LLVM_DEBUG(
          dbgs() << "\tFastISel is "
                 << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled")
                 << "\n");
    }

    ~OptLevelChanger() {
      if (IS.OptLevel == SavedOptLevel)
        return;
      LLVM_DEBUG(dbgs() << "\nRestoring optimization level for Function "
                        << IS.MF->getFunction().getName() << "\n");
      LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(IS.OptLevel)
                        << " ; After: -O" << static_cast<int>(SavedOptLevel) << "\n");
      IS.OptLevel = SavedOptLevel;
      IS.TM.setOptLevel(SavedOptLevel);
      IS.TM.setFastISel(SavedFastISel);
    }
  };

  //===--------------------------------------------------------------------===//
  /// createDefaultScheduler - This creates an instruction scheduler appropriate
  /// for the target.
  ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
                                             CodeGenOptLevel OptLevel) {
    const TargetLowering *TLI = IS->TLI;
    const TargetSubtargetInfo &ST = IS->MF->getSubtarget();

    // Try first to see if the Target has its own way of selecting a scheduler
    if (auto *SchedulerCtor = ST.getDAGScheduler(OptLevel)) {
      return SchedulerCtor(IS, OptLevel);
    }

    if (OptLevel == CodeGenOptLevel::None ||
        (ST.enableMachineScheduler() && ST.enableMachineSchedDefaultSched()) ||
        TLI->getSchedulingPreference() == Sched::Source)
      return createSourceListDAGScheduler(IS, OptLevel);
    if (TLI->getSchedulingPreference() == Sched::RegPressure)
      return createBURRListDAGScheduler(IS, OptLevel);
    if (TLI->getSchedulingPreference() == Sched::Hybrid)
      return createHybridListDAGScheduler(IS, OptLevel);
    if (TLI->getSchedulingPreference() == Sched::VLIW)
      return createVLIWDAGScheduler(IS, OptLevel);
    if (TLI->getSchedulingPreference() == Sched::Fast)
      return createFastDAGScheduler(IS, OptLevel);
    if (TLI->getSchedulingPreference() == Sched::Linearize)
      return createDAGLinearizer(IS, OptLevel);
    assert(TLI->getSchedulingPreference() == Sched::ILP &&
           "Unknown sched type!");
    return createILPListDAGScheduler(IS, OptLevel);
  }

} // end namespace llvm

MachineBasicBlock *
TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
                                            MachineBasicBlock *MBB) const {
#ifndef NDEBUG
  dbgs() << "If a target marks an instruction with "
          "'usesCustomInserter', it must implement "
          "TargetLowering::EmitInstrWithCustomInserter!\n";
#endif
  llvm_unreachable(nullptr);
}

void TargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
                                                   SDNode *Node) const {
  assert(!MI.hasPostISelHook() &&
         "If a target marks an instruction with 'hasPostISelHook', "
         "it must implement TargetLowering::AdjustInstrPostInstrSelection!");
}

//===----------------------------------------------------------------------===//
// SelectionDAGISel code
//===----------------------------------------------------------------------===//

SelectionDAGISelLegacy::SelectionDAGISelLegacy(
    char &ID, std::unique_ptr<SelectionDAGISel> S)
    : MachineFunctionPass(ID), Selector(std::move(S)) {
  initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
  initializeBranchProbabilityInfoWrapperPassPass(
      *PassRegistry::getPassRegistry());
  initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
  initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}

bool SelectionDAGISelLegacy::runOnMachineFunction(MachineFunction &MF) {
  // If we already selected that function, we do not need to run SDISel.
  if (MF.getProperties().hasProperty(
          MachineFunctionProperties::Property::Selected))
    return false;

  // Do some sanity-checking on the command-line options.
  if (EnableFastISelAbort && !Selector->TM.Options.EnableFastISel)
    report_fatal_error("-fast-isel-abort > 0 requires -fast-isel");

  // Decide what flavour of variable location debug-info will be used, before
  // we change the optimisation level.
  MF.setUseDebugInstrRef(MF.shouldUseDebugInstrRef());

  // Reset the target options before resetting the optimization
  // level below.
  // FIXME: This is a horrible hack and should be processed via
  // codegen looking at the optimization level explicitly when
  // it wants to look at it.
  Selector->TM.resetTargetOptions(MF.getFunction());
  // Reset OptLevel to None for optnone functions.
  CodeGenOptLevel NewOptLevel = skipFunction(MF.getFunction())
                                    ? CodeGenOptLevel::None
                                    : Selector->OptLevel;

  Selector->MF = &MF;
  OptLevelChanger OLC(*Selector, NewOptLevel);
  Selector->initializeAnalysisResults(*this);
  return Selector->runOnMachineFunction(MF);
}

SelectionDAGISel::SelectionDAGISel(TargetMachine &tm, CodeGenOptLevel OL)
    : TM(tm), FuncInfo(new FunctionLoweringInfo()),
      SwiftError(new SwiftErrorValueTracking()),
      CurDAG(new SelectionDAG(tm, OL)),
      SDB(std::make_unique<SelectionDAGBuilder>(*CurDAG, *FuncInfo, *SwiftError,
                                                OL)),
      OptLevel(OL) {
  initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
  initializeBranchProbabilityInfoWrapperPassPass(
      *PassRegistry::getPassRegistry());
  initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
  initializeTargetLibraryInfoWrapperPassPass(*PassRegistry::getPassRegistry());
}

SelectionDAGISel::~SelectionDAGISel() {
  delete CurDAG;
  delete SwiftError;
}

void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
  CodeGenOptLevel OptLevel = Selector->OptLevel;
  if (OptLevel != CodeGenOptLevel::None)
      AU.addRequired<AAResultsWrapperPass>();
  AU.addRequired<GCModuleInfo>();
  AU.addRequired<StackProtector>();
  AU.addPreserved<GCModuleInfo>();
  AU.addRequired<TargetLibraryInfoWrapperPass>();
#ifndef NDEBUG
  AU.addRequired<TargetTransformInfoWrapperPass>();
#endif
  AU.addRequired<AssumptionCacheTracker>();
  if (UseMBPI && OptLevel != CodeGenOptLevel::None)
      AU.addRequired<BranchProbabilityInfoWrapperPass>();
  AU.addRequired<ProfileSummaryInfoWrapperPass>();
  // AssignmentTrackingAnalysis only runs if assignment tracking is enabled for
  // the module.
  AU.addRequired<AssignmentTrackingAnalysis>();
  AU.addPreserved<AssignmentTrackingAnalysis>();
  if (OptLevel != CodeGenOptLevel::None)
      LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
  MachineFunctionPass::getAnalysisUsage(AU);
}

PreservedAnalyses
SelectionDAGISelPass::run(MachineFunction &MF,
                          MachineFunctionAnalysisManager &MFAM) {
  // If we already selected that function, we do not need to run SDISel.
  if (MF.getProperties().hasProperty(
          MachineFunctionProperties::Property::Selected))
    return PreservedAnalyses::all();

  // Do some sanity-checking on the command-line options.
  if (EnableFastISelAbort && !Selector->TM.Options.EnableFastISel)
    report_fatal_error("-fast-isel-abort > 0 requires -fast-isel");

  // Decide what flavour of variable location debug-info will be used, before
  // we change the optimisation level.
  MF.setUseDebugInstrRef(MF.shouldUseDebugInstrRef());

  // Reset the target options before resetting the optimization
  // level below.
  // FIXME: This is a horrible hack and should be processed via
  // codegen looking at the optimization level explicitly when
  // it wants to look at it.
  Selector->TM.resetTargetOptions(MF.getFunction());
  // Reset OptLevel to None for optnone functions.
  // TODO: Add a function analysis to handle this.
  Selector->MF = &MF;
  // Reset OptLevel to None for optnone functions.
  CodeGenOptLevel NewOptLevel = MF.getFunction().hasOptNone()
                                    ? CodeGenOptLevel::None
                                    : Selector->OptLevel;

  OptLevelChanger OLC(*Selector, NewOptLevel);
  Selector->initializeAnalysisResults(MFAM);
  Selector->runOnMachineFunction(MF);

  return getMachineFunctionPassPreservedAnalyses();
}

void SelectionDAGISel::initializeAnalysisResults(
    MachineFunctionAnalysisManager &MFAM) {
  auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(*MF)
                  .getManager();
  auto &MAMP = MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(*MF);
  Function &Fn = MF->getFunction();
#ifndef NDEBUG
  FuncName = Fn.getName();
  MatchFilterFuncName = isFunctionInPrintList(FuncName);
#else
  (void)MatchFilterFuncName;
#endif

  TII = MF->getSubtarget().getInstrInfo();
  TLI = MF->getSubtarget().getTargetLowering();
  RegInfo = &MF->getRegInfo();
  LibInfo = &FAM.getResult<TargetLibraryAnalysis>(Fn);
  GFI = Fn.hasGC() ? &FAM.getResult<GCFunctionAnalysis>(Fn) : nullptr;
  ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn);
  AC = &FAM.getResult<AssumptionAnalysis>(Fn);
  auto *PSI = MAMP.getCachedResult<ProfileSummaryAnalysis>(*Fn.getParent());
  BlockFrequencyInfo *BFI = nullptr;
  FAM.getResult<BlockFrequencyAnalysis>(Fn);
  if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None)
    BFI = &FAM.getResult<BlockFrequencyAnalysis>(Fn);

  FunctionVarLocs const *FnVarLocs = nullptr;
  if (isAssignmentTrackingEnabled(*Fn.getParent()))
    FnVarLocs = &FAM.getResult<DebugAssignmentTrackingAnalysis>(Fn);

  auto *UA = FAM.getCachedResult<UniformityInfoAnalysis>(Fn);
  MachineModuleInfo &MMI =
      MAMP.getCachedResult<MachineModuleAnalysis>(*Fn.getParent())->getMMI();

  CurDAG->init(*MF, *ORE, MFAM, LibInfo, UA, PSI, BFI, MMI, FnVarLocs);

  // Now get the optional analyzes if we want to.
  // This is based on the possibly changed OptLevel (after optnone is taken
  // into account).  That's unfortunate but OK because it just means we won't
  // ask for passes that have been required anyway.

  if (UseMBPI && OptLevel != CodeGenOptLevel::None)
    FuncInfo->BPI = &FAM.getResult<BranchProbabilityAnalysis>(Fn);
  else
    FuncInfo->BPI = nullptr;

  if (OptLevel != CodeGenOptLevel::None)
    BatchAA.emplace(FAM.getResult<AAManager>(Fn));
  else
    BatchAA = std::nullopt;

  SP = &FAM.getResult<SSPLayoutAnalysis>(Fn);

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
  TTI = &FAM.getResult<TargetIRAnalysis>(Fn);
#endif
}

void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
  Function &Fn = MF->getFunction();
#ifndef NDEBUG
  FuncName = Fn.getName();
  MatchFilterFuncName = isFunctionInPrintList(FuncName);
#else
  (void)MatchFilterFuncName;
#endif

  TII = MF->getSubtarget().getInstrInfo();
  TLI = MF->getSubtarget().getTargetLowering();
  RegInfo = &MF->getRegInfo();
  LibInfo = &MFP.getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(Fn);
  GFI = Fn.hasGC() ? &MFP.getAnalysis<GCModuleInfo>().getFunctionInfo(Fn)
                   : nullptr;
  ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn);
  AC = &MFP.getAnalysis<AssumptionCacheTracker>().getAssumptionCache(Fn);
  auto *PSI = &MFP.getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
  BlockFrequencyInfo *BFI = nullptr;
  if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None)
    BFI = &MFP.getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();

  FunctionVarLocs const *FnVarLocs = nullptr;
  if (isAssignmentTrackingEnabled(*Fn.getParent()))
    FnVarLocs = MFP.getAnalysis<AssignmentTrackingAnalysis>().getResults();

  UniformityInfo *UA = nullptr;
  if (auto *UAPass = MFP.getAnalysisIfAvailable<UniformityInfoWrapperPass>())
    UA = &UAPass->getUniformityInfo();

  MachineModuleInfo &MMI =
      MFP.getAnalysis<MachineModuleInfoWrapperPass>().getMMI();

  CurDAG->init(*MF, *ORE, &MFP, LibInfo, UA, PSI, BFI, MMI, FnVarLocs);

  // Now get the optional analyzes if we want to.
  // This is based on the possibly changed OptLevel (after optnone is taken
  // into account).  That's unfortunate but OK because it just means we won't
  // ask for passes that have been required anyway.

  if (UseMBPI && OptLevel != CodeGenOptLevel::None)
    FuncInfo->BPI =
        &MFP.getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
  else
    FuncInfo->BPI = nullptr;

  if (OptLevel != CodeGenOptLevel::None)
    BatchAA.emplace(MFP.getAnalysis<AAResultsWrapperPass>().getAAResults());
  else
    BatchAA = std::nullopt;

  SP = &MFP.getAnalysis<StackProtector>().getLayoutInfo();

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
  TTI = &MFP.getAnalysis<TargetTransformInfoWrapperPass>().getTTI(Fn);
#endif
}

bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
  SwiftError->setFunction(mf);
  const Function &Fn = mf.getFunction();

  bool InstrRef = mf.shouldUseDebugInstrRef();

  FuncInfo->set(MF->getFunction(), *MF, CurDAG);

  ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << '\n');

  SDB->init(GFI, getBatchAA(), AC, LibInfo);

  MF->setHasInlineAsm(false);

  FuncInfo->SplitCSR = false;

  // We split CSR if the target supports it for the given function
  // and the function has only return exits.
  if (OptLevel != CodeGenOptLevel::None && TLI->supportSplitCSR(MF)) {
    FuncInfo->SplitCSR = true;

    // Collect all the return blocks.
    for (const BasicBlock &BB : Fn) {
      if (!succ_empty(&BB))
        continue;

      const Instruction *Term = BB.getTerminator();
      if (isa<UnreachableInst>(Term) || isa<ReturnInst>(Term))
        continue;

      // Bail out if the exit block is not Return nor Unreachable.
      FuncInfo->SplitCSR = false;
      break;
    }
  }

  MachineBasicBlock *EntryMBB = &MF->front();
  if (FuncInfo->SplitCSR)
    // This performs initialization so lowering for SplitCSR will be correct.
    TLI->initializeSplitCSR(EntryMBB);

  SelectAllBasicBlocks(Fn);
  if (FastISelFailed && EnableFastISelFallbackReport) {
    DiagnosticInfoISelFallback DiagFallback(Fn);
    Fn.getContext().diagnose(DiagFallback);
  }

  // Replace forward-declared registers with the registers containing
  // the desired value.
  // Note: it is important that this happens **before** the call to
  // EmitLiveInCopies, since implementations can skip copies of unused
  // registers. If we don't apply the reg fixups before, some registers may
  // appear as unused and will be skipped, resulting in bad MI.
  MachineRegisterInfo &MRI = MF->getRegInfo();
  for (DenseMap<Register, Register>::iterator I = FuncInfo->RegFixups.begin(),
                                              E = FuncInfo->RegFixups.end();
       I != E; ++I) {
    Register From = I->first;
    Register To = I->second;
    // If To is also scheduled to be replaced, find what its ultimate
    // replacement is.
    while (true) {
      DenseMap<Register, Register>::iterator J = FuncInfo->RegFixups.find(To);
      if (J == E)
        break;
      To = J->second;
    }
    // Make sure the new register has a sufficiently constrained register class.
    if (From.isVirtual() && To.isVirtual())
      MRI.constrainRegClass(To, MRI.getRegClass(From));
    // Replace it.

    // Replacing one register with another won't touch the kill flags.
    // We need to conservatively clear the kill flags as a kill on the old
    // register might dominate existing uses of the new register.
    if (!MRI.use_empty(To))
      MRI.clearKillFlags(From);
    MRI.replaceRegWith(From, To);
  }

  // If the first basic block in the function has live ins that need to be
  // copied into vregs, emit the copies into the top of the block before
  // emitting the code for the block.
  const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
  RegInfo->EmitLiveInCopies(EntryMBB, TRI, *TII);

  // Insert copies in the entry block and the return blocks.
  if (FuncInfo->SplitCSR) {
    SmallVector<MachineBasicBlock*, 4> Returns;
    // Collect all the return blocks.
    for (MachineBasicBlock &MBB : mf) {
      if (!MBB.succ_empty())
        continue;

      MachineBasicBlock::iterator Term = MBB.getFirstTerminator();
      if (Term != MBB.end() && Term->isReturn()) {
        Returns.push_back(&MBB);
        continue;
      }
    }
    TLI->insertCopiesSplitCSR(EntryMBB, Returns);
  }

  DenseMap<MCRegister, Register> LiveInMap;
  if (!FuncInfo->ArgDbgValues.empty())
    for (std::pair<MCRegister, Register> LI : RegInfo->liveins())
      if (LI.second)
        LiveInMap.insert(LI);

  // Insert DBG_VALUE instructions for function arguments to the entry block.
  for (unsigned i = 0, e = FuncInfo->ArgDbgValues.size(); i != e; ++i) {
    MachineInstr *MI = FuncInfo->ArgDbgValues[e - i - 1];
    assert(MI->getOpcode() != TargetOpcode::DBG_VALUE_LIST &&
           "Function parameters should not be described by DBG_VALUE_LIST.");
    bool hasFI = MI->getDebugOperand(0).isFI();
    Register Reg =
        hasFI ? TRI.getFrameRegister(*MF) : MI->getDebugOperand(0).getReg();
    if (Reg.isPhysical())
      EntryMBB->insert(EntryMBB->begin(), MI);
    else {
      MachineInstr *Def = RegInfo->getVRegDef(Reg);
      if (Def) {
        MachineBasicBlock::iterator InsertPos = Def;
        // FIXME: VR def may not be in entry block.
        Def->getParent()->insert(std::next(InsertPos), MI);
      } else
        LLVM_DEBUG(dbgs() << "Dropping debug info for dead vreg"
                          << printReg(Reg) << '\n');
    }

    // Don't try and extend through copies in instruction referencing mode.
    if (InstrRef)
      continue;

    // If Reg is live-in then update debug info to track its copy in a vreg.
    if (!Reg.isPhysical())
      continue;
    DenseMap<MCRegister, Register>::iterator LDI = LiveInMap.find(Reg);
    if (LDI != LiveInMap.end()) {
      assert(!hasFI && "There's no handling of frame pointer updating here yet "
                       "- add if needed");
      MachineInstr *Def = RegInfo->getVRegDef(LDI->second);
      MachineBasicBlock::iterator InsertPos = Def;
      const MDNode *Variable = MI->getDebugVariable();
      const MDNode *Expr = MI->getDebugExpression();
      DebugLoc DL = MI->getDebugLoc();
      bool IsIndirect = MI->isIndirectDebugValue();
      if (IsIndirect)
        assert(MI->getDebugOffset().getImm() == 0 &&
               "DBG_VALUE with nonzero offset");
      assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
             "Expected inlined-at fields to agree");
      assert(MI->getOpcode() != TargetOpcode::DBG_VALUE_LIST &&
             "Didn't expect to see a DBG_VALUE_LIST here");
      // Def is never a terminator here, so it is ok to increment InsertPos.
      BuildMI(*EntryMBB, ++InsertPos, DL, TII->get(TargetOpcode::DBG_VALUE),
              IsIndirect, LDI->second, Variable, Expr);

      // If this vreg is directly copied into an exported register then
      // that COPY instructions also need DBG_VALUE, if it is the only
      // user of LDI->second.
      MachineInstr *CopyUseMI = nullptr;
      for (MachineInstr &UseMI : RegInfo->use_instructions(LDI->second)) {
        if (UseMI.isDebugValue())
          continue;
        if (UseMI.isCopy() && !CopyUseMI && UseMI.getParent() == EntryMBB) {
          CopyUseMI = &UseMI;
          continue;
        }
        // Otherwise this is another use or second copy use.
        CopyUseMI = nullptr;
        break;
      }
      if (CopyUseMI &&
          TRI.getRegSizeInBits(LDI->second, MRI) ==
              TRI.getRegSizeInBits(CopyUseMI->getOperand(0).getReg(), MRI)) {
        // Use MI's debug location, which describes where Variable was
        // declared, rather than whatever is attached to CopyUseMI.
        MachineInstr *NewMI =
            BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE), IsIndirect,
                    CopyUseMI->getOperand(0).getReg(), Variable, Expr);
        MachineBasicBlock::iterator Pos = CopyUseMI;
        EntryMBB->insertAfter(Pos, NewMI);
      }
    }
  }

  // For debug-info, in instruction referencing mode, we need to perform some
  // post-isel maintenence.
  if (MF->useDebugInstrRef())
    MF->finalizeDebugInstrRefs();

  // Determine if there are any calls in this machine function.
  MachineFrameInfo &MFI = MF->getFrameInfo();
  for (const auto &MBB : *MF) {
    if (MFI.hasCalls() && MF->hasInlineAsm())
      break;

    for (const auto &MI : MBB) {
      const MCInstrDesc &MCID = TII->get(MI.getOpcode());
      if ((MCID.isCall() && !MCID.isReturn()) ||
          MI.isStackAligningInlineAsm()) {
        MFI.setHasCalls(true);
      }
      if (MI.isInlineAsm()) {
        MF->setHasInlineAsm(true);
      }
    }
  }

  // Release function-specific state. SDB and CurDAG are already cleared
  // at this point.
  FuncInfo->clear();

  ISEL_DUMP(dbgs() << "*** MachineFunction at end of ISel ***\n");
  ISEL_DUMP(MF->print(dbgs()));

  return true;
}

static void reportFastISelFailure(MachineFunction &MF,
                                  OptimizationRemarkEmitter &ORE,
                                  OptimizationRemarkMissed &R,
                                  bool ShouldAbort) {
  // Print the function name explicitly if we don't have a debug location (which
  // makes the diagnostic less useful) or if we're going to emit a raw error.
  if (!R.getLocation().isValid() || ShouldAbort)
    R << (" (in function: " + MF.getName() + ")").str();

  if (ShouldAbort)
    report_fatal_error(Twine(R.getMsg()));

  ORE.emit(R);
  LLVM_DEBUG(dbgs() << R.getMsg() << "\n");
}

// Detect any fake uses that follow a tail call and move them before the tail
// call. Ignore fake uses that use values that are def'd by or after the tail
// call.
static void preserveFakeUses(BasicBlock::iterator Begin,
                             BasicBlock::iterator End) {
  BasicBlock::iterator I = End;
  if (--I == Begin || !isa<ReturnInst>(*I))
    return;
  // Detect whether there are any fake uses trailing a (potential) tail call.
  bool HaveFakeUse = false;
  bool HaveTailCall = false;
  do {
    if (const CallInst *CI = dyn_cast<CallInst>(--I))
      if (CI->isTailCall()) {
        HaveTailCall = true;
        break;
      }
    if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
      if (II->getIntrinsicID() == Intrinsic::fake_use)
        HaveFakeUse = true;
  } while (I != Begin);

  // If we didn't find any tail calls followed by fake uses, we are done.
  if (!HaveTailCall || !HaveFakeUse)
    return;

  SmallVector<IntrinsicInst *> FakeUses;
  // Record the fake uses we found so we can move them to the front of the
  // tail call. Ignore them if they use a value that is def'd by or after
  // the tail call.
  for (BasicBlock::iterator Inst = I; Inst != End; Inst++) {
    if (IntrinsicInst *FakeUse = dyn_cast<IntrinsicInst>(Inst);
        FakeUse && FakeUse->getIntrinsicID() == Intrinsic::fake_use) {
      if (auto UsedDef = dyn_cast<Instruction>(FakeUse->getOperand(0));
          !UsedDef || UsedDef->getParent() != I->getParent() ||
          UsedDef->comesBefore(&*I))
        FakeUses.push_back(FakeUse);
    }
  }

  for (auto *Inst : FakeUses)
    Inst->moveBefore(*Inst->getParent(), I);
}

void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
                                        BasicBlock::const_iterator End,
                                        bool &HadTailCall) {
  // Allow creating illegal types during DAG building for the basic block.
  CurDAG->NewNodesMustHaveLegalTypes = false;

  // Lower the instructions. If a call is emitted as a tail call, cease emitting
  // nodes for this block. If an instruction is elided, don't emit it, but do
  // handle any debug-info attached to it.
  for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) {
    if (!ElidedArgCopyInstrs.count(&*I))
      SDB->visit(*I);
    else
      SDB->visitDbgInfo(*I);
  }

  // Make sure the root of the DAG is up-to-date.
  CurDAG->setRoot(SDB->getControlRoot());
  HadTailCall = SDB->HasTailCall;
  SDB->resolveOrClearDbgInfo();
  SDB->clear();

  // Final step, emit the lowered DAG as machine code.
  CodeGenAndEmitDAG();
}

void SelectionDAGISel::ComputeLiveOutVRegInfo() {
  SmallPtrSet<SDNode *, 16> Added;
  SmallVector<SDNode*, 128> Worklist;

  Worklist.push_back(CurDAG->getRoot().getNode());
  Added.insert(CurDAG->getRoot().getNode());

  KnownBits Known;

  do {
    SDNode *N = Worklist.pop_back_val();

    // Otherwise, add all chain operands to the worklist.
    for (const SDValue &Op : N->op_values())
      if (Op.getValueType() == MVT::Other && Added.insert(Op.getNode()).second)
        Worklist.push_back(Op.getNode());

    // If this is a CopyToReg with a vreg dest, process it.
    if (N->getOpcode() != ISD::CopyToReg)
      continue;

    Register DestReg = cast<RegisterSDNode>(N->getOperand(1))->getReg();
    if (!DestReg.isVirtual())
      continue;

    // Ignore non-integer values.
    SDValue Src = N->getOperand(2);
    EVT SrcVT = Src.getValueType();
    if (!SrcVT.isInteger())
      continue;

    unsigned NumSignBits = CurDAG->ComputeNumSignBits(Src);
    Known = CurDAG->computeKnownBits(Src);
    FuncInfo->AddLiveOutRegInfo(DestReg, NumSignBits, Known);
  } while (!Worklist.empty());
}

void SelectionDAGISel::CodeGenAndEmitDAG() {
  StringRef GroupName = "sdag";
  StringRef GroupDescription = "Instruction Selection and Scheduling";
  std::string BlockName;
  bool MatchFilterBB = false;
  (void)MatchFilterBB;

  // Pre-type legalization allow creation of any node types.
  CurDAG->NewNodesMustHaveLegalTypes = false;

#ifndef NDEBUG
  MatchFilterBB = (FilterDAGBasicBlockName.empty() ||
                   FilterDAGBasicBlockName ==
                       FuncInfo->MBB->getBasicBlock()->getName());
#endif
#ifdef NDEBUG
  if (ViewDAGCombine1 || ViewLegalizeTypesDAGs || ViewDAGCombineLT ||
      ViewLegalizeDAGs || ViewDAGCombine2 || ViewISelDAGs || ViewSchedDAGs ||
      ViewSUnitDAGs)
#endif
  {
    BlockName =
        (MF->getName() + ":" + FuncInfo->MBB->getBasicBlock()->getName()).str();
  }
  ISEL_DUMP(dbgs() << "\nInitial selection DAG: "
                   << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                   << "'\n";
            CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
  if (TTI->hasBranchDivergence())
    CurDAG->VerifyDAGDivergence();
#endif

  if (ViewDAGCombine1 && MatchFilterBB)
    CurDAG->viewGraph("dag-combine1 input for " + BlockName);

  // Run the DAG combiner in pre-legalize mode.
  {
    NamedRegionTimer T("combine1", "DAG Combining 1", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    CurDAG->Combine(BeforeLegalizeTypes, getBatchAA(), OptLevel);
  }

  ISEL_DUMP(dbgs() << "\nOptimized lowered selection DAG: "
                   << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                   << "'\n";
            CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
  if (TTI->hasBranchDivergence())
    CurDAG->VerifyDAGDivergence();
#endif

  // Second step, hack on the DAG until it only uses operations and types that
  // the target supports.
  if (ViewLegalizeTypesDAGs && MatchFilterBB)
    CurDAG->viewGraph("legalize-types input for " + BlockName);

  bool Changed;
  {
    NamedRegionTimer T("legalize_types", "Type Legalization", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    Changed = CurDAG->LegalizeTypes();
  }

  ISEL_DUMP(dbgs() << "\nType-legalized selection DAG: "
                   << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                   << "'\n";
            CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
  if (TTI->hasBranchDivergence())
    CurDAG->VerifyDAGDivergence();
#endif

  // Only allow creation of legal node types.
  CurDAG->NewNodesMustHaveLegalTypes = true;

  if (Changed) {
    if (ViewDAGCombineLT && MatchFilterBB)
      CurDAG->viewGraph("dag-combine-lt input for " + BlockName);

    // Run the DAG combiner in post-type-legalize mode.
    {
      NamedRegionTimer T("combine_lt", "DAG Combining after legalize types",
                         GroupName, GroupDescription, TimePassesIsEnabled);
      CurDAG->Combine(AfterLegalizeTypes, getBatchAA(), OptLevel);
    }

    ISEL_DUMP(dbgs() << "\nOptimized type-legalized selection DAG: "
                     << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                     << "'\n";
              CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
    if (TTI->hasBranchDivergence())
      CurDAG->VerifyDAGDivergence();
#endif
  }

  {
    NamedRegionTimer T("legalize_vec", "Vector Legalization", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    Changed = CurDAG->LegalizeVectors();
  }

  if (Changed) {
    ISEL_DUMP(dbgs() << "\nVector-legalized selection DAG: "
                     << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                     << "'\n";
              CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
    if (TTI->hasBranchDivergence())
      CurDAG->VerifyDAGDivergence();
#endif

    {
      NamedRegionTimer T("legalize_types2", "Type Legalization 2", GroupName,
                         GroupDescription, TimePassesIsEnabled);
      CurDAG->LegalizeTypes();
    }

    ISEL_DUMP(dbgs() << "\nVector/type-legalized selection DAG: "
                     << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                     << "'\n";
              CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
    if (TTI->hasBranchDivergence())
      CurDAG->VerifyDAGDivergence();
#endif

    if (ViewDAGCombineLT && MatchFilterBB)
      CurDAG->viewGraph("dag-combine-lv input for " + BlockName);

    // Run the DAG combiner in post-type-legalize mode.
    {
      NamedRegionTimer T("combine_lv", "DAG Combining after legalize vectors",
                         GroupName, GroupDescription, TimePassesIsEnabled);
      CurDAG->Combine(AfterLegalizeVectorOps, getBatchAA(), OptLevel);
    }

    ISEL_DUMP(dbgs() << "\nOptimized vector-legalized selection DAG: "
                     << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                     << "'\n";
              CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
    if (TTI->hasBranchDivergence())
      CurDAG->VerifyDAGDivergence();
#endif
  }

  if (ViewLegalizeDAGs && MatchFilterBB)
    CurDAG->viewGraph("legalize input for " + BlockName);

  {
    NamedRegionTimer T("legalize", "DAG Legalization", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    CurDAG->Legalize();
  }

  ISEL_DUMP(dbgs() << "\nLegalized selection DAG: "
                   << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                   << "'\n";
            CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
  if (TTI->hasBranchDivergence())
    CurDAG->VerifyDAGDivergence();
#endif

  if (ViewDAGCombine2 && MatchFilterBB)
    CurDAG->viewGraph("dag-combine2 input for " + BlockName);

  // Run the DAG combiner in post-legalize mode.
  {
    NamedRegionTimer T("combine2", "DAG Combining 2", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    CurDAG->Combine(AfterLegalizeDAG, getBatchAA(), OptLevel);
  }

  ISEL_DUMP(dbgs() << "\nOptimized legalized selection DAG: "
                   << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                   << "'\n";
            CurDAG->dump());

#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
  if (TTI->hasBranchDivergence())
    CurDAG->VerifyDAGDivergence();
#endif

  if (OptLevel != CodeGenOptLevel::None)
    ComputeLiveOutVRegInfo();

  if (ViewISelDAGs && MatchFilterBB)
    CurDAG->viewGraph("isel input for " + BlockName);

  // Third, instruction select all of the operations to machine code, adding the
  // code to the MachineBasicBlock.
  {
    NamedRegionTimer T("isel", "Instruction Selection", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    DoInstructionSelection();
  }

  ISEL_DUMP(dbgs() << "\nSelected selection DAG: "
                   << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
                   << "'\n";
            CurDAG->dump());

  if (ViewSchedDAGs && MatchFilterBB)
    CurDAG->viewGraph("scheduler input for " + BlockName);

  // Schedule machine code.
  ScheduleDAGSDNodes *Scheduler = CreateScheduler();
  {
    NamedRegionTimer T("sched", "Instruction Scheduling", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    Scheduler->Run(CurDAG, FuncInfo->MBB);
  }

  if (ViewSUnitDAGs && MatchFilterBB)
    Scheduler->viewGraph();

  // Emit machine code to BB.  This can change 'BB' to the last block being
  // inserted into.
  MachineBasicBlock *FirstMBB = FuncInfo->MBB, *LastMBB;
  {
    NamedRegionTimer T("emit", "Instruction Creation", GroupName,
                       GroupDescription, TimePassesIsEnabled);

    // FuncInfo->InsertPt is passed by reference and set to the end of the
    // scheduled instructions.
    LastMBB = FuncInfo->MBB = Scheduler->EmitSchedule(FuncInfo->InsertPt);
  }

  // If the block was split, make sure we update any references that are used to
  // update PHI nodes later on.
  if (FirstMBB != LastMBB)
    SDB->UpdateSplitBlock(FirstMBB, LastMBB);

  // Free the scheduler state.
  {
    NamedRegionTimer T("cleanup", "Instruction Scheduling Cleanup", GroupName,
                       GroupDescription, TimePassesIsEnabled);
    delete Scheduler;
  }

  // Free the SelectionDAG state, now that we're finished with it.
  CurDAG->clear();
}

namespace {

/// ISelUpdater - helper class to handle updates of the instruction selection
/// graph.
class ISelUpdater : public SelectionDAG::DAGUpdateListener {
  SelectionDAG::allnodes_iterator &ISelPosition;

public:
  ISelUpdater(SelectionDAG &DAG, SelectionDAG::allnodes_iterator &isp)
    : SelectionDAG::DAGUpdateListener(DAG), ISelPosition(isp) {}

  /// NodeDeleted - Handle nodes deleted from the graph. If the node being
  /// deleted is the current ISelPosition node, update ISelPosition.
  ///
  void NodeDeleted(SDNode *N, SDNode *E) override {
    if (ISelPosition == SelectionDAG::allnodes_iterator(N))
      ++ISelPosition;
  }

  /// NodeInserted - Handle new nodes inserted into the graph: propagate
  /// metadata from root nodes that also applies to new nodes, in case the root
  /// is later deleted.
  void NodeInserted(SDNode *N) override {
    SDNode *CurNode = &*ISelPosition;
    if (MDNode *MD = DAG.getPCSections(CurNode))
      DAG.addPCSections(N, MD);
    if (MDNode *MMRA = DAG.getMMRAMetadata(CurNode))
      DAG.addMMRAMetadata(N, MMRA);
  }
};

} // end anonymous namespace

// This function is used to enforce the topological node id property
// leveraged during instruction selection. Before the selection process all
// nodes are given a non-negative id such that all nodes have a greater id than
// their operands. As this holds transitively we can prune checks that a node N
// is a predecessor of M another by not recursively checking through M's
// operands if N's ID is larger than M's ID. This significantly improves
// performance of various legality checks (e.g. IsLegalToFold / UpdateChains).

// However, when we fuse multiple nodes into a single node during the
// selection we may induce a predecessor relationship between inputs and
// outputs of distinct nodes being merged, violating the topological property.
// Should a fused node have a successor which has yet to be selected,
// our legality checks would be incorrect. To avoid this we mark all unselected
// successor nodes, i.e. id != -1, as invalid for pruning by bit-negating (x =>
// (-(x+1))) the ids and modify our pruning check to ignore negative Ids of M.
// We use bit-negation to more clearly enforce that node id -1 can only be
// achieved by selected nodes. As the conversion is reversable to the original
// Id, topological pruning can still be leveraged when looking for unselected
// nodes. This method is called internally in all ISel replacement related
// functions.
void SelectionDAGISel::EnforceNodeIdInvariant(SDNode *Node) {
  SmallVector<SDNode *, 4> Nodes;
  Nodes.push_back(Node);

  while (!Nodes.empty()) {
    SDNode *N = Nodes.pop_back_val();
    for (auto *U : N->users()) {
      auto UId = U->getNodeId();
      if (UId > 0) {
        InvalidateNodeId(U);
        Nodes.push_back(U);
      }
    }
  }
}

// InvalidateNodeId - As explained in EnforceNodeIdInvariant, mark a
// NodeId with the equivalent node id which is invalid for topological
// pruning.
void SelectionDAGISel::InvalidateNodeId(SDNode *N) {
  int InvalidId = -(N->getNodeId() + 1);
  N->setNodeId(InvalidId);
}

// getUninvalidatedNodeId - get original uninvalidated node id.
int SelectionDAGISel::getUninvalidatedNodeId(SDNode *N) {
  int Id = N->getNodeId();
  if (Id < -1)
    return -(Id + 1);
  return Id;
}

void SelectionDAGISel::DoInstructionSelection() {
  LLVM_DEBUG(dbgs() << "===== Instruction selection begins: "
                    << printMBBReference(*FuncInfo->MBB) << " '"
                    << FuncInfo->MBB->getName() << "'\n");

  PreprocessISelDAG();

  // Select target instructions for the DAG.
  {
    // Number all nodes with a topological order and set DAGSize.
    DAGSize = CurDAG->AssignTopologicalOrder();

    // Create a dummy node (which is not added to allnodes), that adds
    // a reference to the root node, preventing it from being deleted,
    // and tracking any changes of the root.
    HandleSDNode Dummy(CurDAG->getRoot());
    SelectionDAG::allnodes_iterator ISelPosition (CurDAG->getRoot().getNode());
    ++ISelPosition;

    // Make sure that ISelPosition gets properly updated when nodes are deleted
    // in calls made from this function. New nodes inherit relevant metadata.
    ISelUpdater ISU(*CurDAG, ISelPosition);

    // The AllNodes list is now topological-sorted. Visit the
    // nodes by starting at the end of the list (the root of the
    // graph) and preceding back toward the beginning (the entry
    // node).
    while (ISelPosition != CurDAG->allnodes_begin()) {
      SDNode *Node = &*--ISelPosition;
      // Skip dead nodes. DAGCombiner is expected to eliminate all dead nodes,
      // but there are currently some corner cases that it misses. Also, this
      // makes it theoretically possible to disable the DAGCombiner.
      if (Node->use_empty())
        continue;

#ifndef NDEBUG
      SmallVector<SDNode *, 4> Nodes;
      Nodes.push_back(Node);

      while (!Nodes.empty()) {
        auto N = Nodes.pop_back_val();
        if (N->getOpcode() == ISD::TokenFactor || N->getNodeId() < 0)
          continue;
        for (const SDValue &Op : N->op_values()) {
          if (Op->getOpcode() == ISD::TokenFactor)
            Nodes.push_back(Op.getNode());
          else {
            // We rely on topological ordering of node ids for checking for
            // cycles when fusing nodes during selection. All unselected nodes
            // successors of an already selected node should have a negative id.
            // This assertion will catch such cases. If this assertion triggers
            // it is likely you using DAG-level Value/Node replacement functions
            // (versus equivalent ISEL replacement) in backend-specific
            // selections. See comment in EnforceNodeIdInvariant for more
            // details.
            assert(Op->getNodeId() != -1 &&
                   "Node has already selected predecessor node");
          }
        }
      }
#endif

      // When we are using non-default rounding modes or FP exception behavior
      // FP operations are represented by StrictFP pseudo-operations.  For
      // targets that do not (yet) understand strict FP operations directly,
      // we convert them to normal FP opcodes instead at this point.  This
      // will allow them to be handled by existing target-specific instruction
      // selectors.
      if (!TLI->isStrictFPEnabled() && Node->isStrictFPOpcode()) {
        // For some opcodes, we need to call TLI->getOperationAction using
        // the first operand type instead of the result type.  Note that this
        // must match what SelectionDAGLegalize::LegalizeOp is doing.
        EVT ActionVT;
        switch (Node->getOpcode()) {
        case ISD::STRICT_SINT_TO_FP:
        case ISD::STRICT_UINT_TO_FP:
        case ISD::STRICT_LRINT:
        case ISD::STRICT_LLRINT:
        case ISD::STRICT_LROUND:
        case ISD::STRICT_LLROUND:
        case ISD::STRICT_FSETCC:
        case ISD::STRICT_FSETCCS:
          ActionVT = Node->getOperand(1).getValueType();
          break;
        default:
          ActionVT = Node->getValueType(0);
          break;
        }
        if (TLI->getOperationAction(Node->getOpcode(), ActionVT)
            == TargetLowering::Expand)
          Node = CurDAG->mutateStrictFPToFP(Node);
      }

      LLVM_DEBUG(dbgs() << "\nISEL: Starting selection on root node: ";
                 Node->dump(CurDAG));

      Select(Node);
    }

    CurDAG->setRoot(Dummy.getValue());
  }

  LLVM_DEBUG(dbgs() << "\n===== Instruction selection ends:\n");

  PostprocessISelDAG();
}

static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI) {
  for (const User *U : CPI->users()) {
    if (const IntrinsicInst *EHPtrCall = dyn_cast<IntrinsicInst>(U)) {
      Intrinsic::ID IID = EHPtrCall->getIntrinsicID();
      if (IID == Intrinsic::eh_exceptionpointer ||
          IID == Intrinsic::eh_exceptioncode)
        return true;
    }
  }
  return false;
}

// wasm.landingpad.index intrinsic is for associating a landing pad index number
// with a catchpad instruction. Retrieve the landing pad index in the intrinsic
// and store the mapping in the function.
static void mapWasmLandingPadIndex(MachineBasicBlock *MBB,
                                   const CatchPadInst *CPI) {
  MachineFunction *MF = MBB->getParent();
  // In case of single catch (...), we don't emit LSDA, so we don't need
  // this information.
  bool IsSingleCatchAllClause =
      CPI->arg_size() == 1 &&
      cast<Constant>(CPI->getArgOperand(0))->isNullValue();
  // cathchpads for longjmp use an empty type list, e.g. catchpad within %0 []
  // and they don't need LSDA info
  bool IsCatchLongjmp = CPI->arg_size() == 0;
  if (!IsSingleCatchAllClause && !IsCatchLongjmp) {
    // Create a mapping from landing pad label to landing pad index.
    bool IntrFound = false;
    for (const User *U : CPI->users()) {
      if (const auto *Call = dyn_cast<IntrinsicInst>(U)) {
        Intrinsic::ID IID = Call->getIntrinsicID();
        if (IID == Intrinsic::wasm_landingpad_index) {
          Value *IndexArg = Call->getArgOperand(1);
          int Index = cast<ConstantInt>(IndexArg)->getZExtValue();
          MF->setWasmLandingPadIndex(MBB, Index);
          IntrFound = true;
          break;
        }
      }
    }
    assert(IntrFound && "wasm.landingpad.index intrinsic not found!");
    (void)IntrFound;
  }
}

/// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and
/// do other setup for EH landing-pad blocks.
bool SelectionDAGISel::PrepareEHLandingPad() {
  MachineBasicBlock *MBB = FuncInfo->MBB;
  const Constant *PersonalityFn = FuncInfo->Fn->getPersonalityFn();
  const BasicBlock *LLVMBB = MBB->getBasicBlock();
  const TargetRegisterClass *PtrRC =
      TLI->getRegClassFor(TLI->getPointerTy(CurDAG->getDataLayout()));

  auto Pers = classifyEHPersonality(PersonalityFn);

  // Catchpads have one live-in register, which typically holds the exception
  // pointer or code.
  if (isFuncletEHPersonality(Pers)) {
    if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHIIt())) {
      if (hasExceptionPointerOrCodeUser(CPI)) {
        // Get or create the virtual register to hold the pointer or code.  Mark
        // the live in physreg and copy into the vreg.
        MCRegister EHPhysReg = TLI->getExceptionPointerRegister(PersonalityFn);
        assert(EHPhysReg && "target lacks exception pointer register");
        MBB->addLiveIn(EHPhysReg);
        Register VReg = FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
        BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(),
                TII->get(TargetOpcode::COPY), VReg)
            .addReg(EHPhysReg, RegState::Kill);
      }
    }
    return true;
  }

  // Add a label to mark the beginning of the landing pad.  Deletion of the
  // landing pad can thus be detected via the MachineModuleInfo.
  MCSymbol *Label = MF->addLandingPad(MBB);

  const MCInstrDesc &II = TII->get(TargetOpcode::EH_LABEL);
  BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
    .addSym(Label);

  // If the unwinder does not preserve all registers, ensure that the
  // function marks the clobbered registers as used.
  const TargetRegisterInfo &TRI = *MF->getSubtarget().getRegisterInfo();
  if (auto *RegMask = TRI.getCustomEHPadPreservedMask(*MF))
    MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);

  if (Pers == EHPersonality::Wasm_CXX) {
    if (const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->getFirstNonPHIIt()))
      mapWasmLandingPadIndex(MBB, CPI);
  } else {
    // Assign the call site to the landing pad's begin label.
    MF->setCallSiteLandingPad(Label, SDB->LPadToCallSiteMap[MBB]);
    // Mark exception register as live in.
    if (MCRegister Reg = TLI->getExceptionPointerRegister(PersonalityFn))
      FuncInfo->ExceptionPointerVirtReg = MBB->addLiveIn(Reg, PtrRC);
    // Mark exception selector register as live in.
    if (MCRegister Reg = TLI->getExceptionSelectorRegister(PersonalityFn))
      FuncInfo->ExceptionSelectorVirtReg = MBB->addLiveIn(Reg, PtrRC);
  }

  return true;
}

// Mark and Report IPToState for each Block under IsEHa
void SelectionDAGISel::reportIPToStateForBlocks(MachineFunction *MF) {
  llvm::WinEHFuncInfo *EHInfo = MF->getWinEHFuncInfo();
  if (!EHInfo)
    return;
  for (MachineBasicBlock &MBB : *MF) {
    const BasicBlock *BB = MBB.getBasicBlock();
    int State = EHInfo->BlockToStateMap[BB];
    if (BB->getFirstMayFaultInst()) {
      // Report IP range only for blocks with Faulty inst
      auto MBBb = MBB.getFirstNonPHI();

      if (MBBb == MBB.end())
        continue;

      MachineInstr *MIb = &*MBBb;
      if (MIb->isTerminator())
        continue;

      // Insert EH Labels
      MCSymbol *BeginLabel = MF->getContext().createTempSymbol();
      MCSymbol *EndLabel = MF->getContext().createTempSymbol();
      EHInfo->addIPToStateRange(State, BeginLabel, EndLabel);
      BuildMI(MBB, MBBb, SDB->getCurDebugLoc(),
              TII->get(TargetOpcode::EH_LABEL))
          .addSym(BeginLabel);
      auto MBBe = MBB.instr_end();
      MachineInstr *MIe = &*(--MBBe);
      // insert before (possible multiple) terminators
      while (MIe->isTerminator())
        MIe = &*(--MBBe);
      ++MBBe;
      BuildMI(MBB, MBBe, SDB->getCurDebugLoc(),
              TII->get(TargetOpcode::EH_LABEL))
          .addSym(EndLabel);
    }
  }
}

/// isFoldedOrDeadInstruction - Return true if the specified instruction is
/// side-effect free and is either dead or folded into a generated instruction.
/// Return false if it needs to be emitted.
static bool isFoldedOrDeadInstruction(const Instruction *I,
                                      const FunctionLoweringInfo &FuncInfo) {
  return !I->mayWriteToMemory() && // Side-effecting instructions aren't folded.
         !I->isTerminator() &&     // Terminators aren't folded.
         !isa<DbgInfoIntrinsic>(I) && // Debug instructions aren't folded.
         !I->isEHPad() &&             // EH pad instructions aren't folded.
         !FuncInfo.isExportedInst(I); // Exported instrs must be computed.
}

static bool processIfEntryValueDbgDeclare(FunctionLoweringInfo &FuncInfo,
                                          const Value *Arg, DIExpression *Expr,
                                          DILocalVariable *Var,
                                          DebugLoc DbgLoc) {
  if (!Expr->isEntryValue() || !isa<Argument>(Arg))
    return false;

  auto ArgIt = FuncInfo.ValueMap.find(Arg);
  if (ArgIt == FuncInfo.ValueMap.end())
    return false;
  Register ArgVReg = ArgIt->getSecond();

  // Find the corresponding livein physical register to this argument.
  for (auto [PhysReg, VirtReg] : FuncInfo.RegInfo->liveins())
    if (VirtReg == ArgVReg) {
      // Append an op deref to account for the fact that this is a dbg_declare.
      Expr = DIExpression::append(Expr, dwarf::DW_OP_deref);
      FuncInfo.MF->setVariableDbgInfo(Var, Expr, PhysReg, DbgLoc);
      LLVM_DEBUG(dbgs() << "processDbgDeclare: setVariableDbgInfo Var=" << *Var
                        << ", Expr=" << *Expr << ",  MCRegister=" << PhysReg
                        << ", DbgLoc=" << DbgLoc << "\n");
      return true;
    }
  return false;
}

static bool processDbgDeclare(FunctionLoweringInfo &FuncInfo,
                              const Value *Address, DIExpression *Expr,
                              DILocalVariable *Var, DebugLoc DbgLoc) {
  if (!Address) {
    LLVM_DEBUG(dbgs() << "processDbgDeclares skipping " << *Var
                      << " (bad address)\n");
    return false;
  }

  if (processIfEntryValueDbgDeclare(FuncInfo, Address, Expr, Var, DbgLoc))
    return true;

  MachineFunction *MF = FuncInfo.MF;
  const DataLayout &DL = MF->getDataLayout();

  assert(Var && "Missing variable");
  assert(DbgLoc && "Missing location");

  // Look through casts and constant offset GEPs. These mostly come from
  // inalloca.
  APInt Offset(DL.getTypeSizeInBits(Address->getType()), 0);
  Address = Address->stripAndAccumulateInBoundsConstantOffsets(DL, Offset);

  // Check if the variable is a static alloca or a byval or inalloca
  // argument passed in memory. If it is not, then we will ignore this
  // intrinsic and handle this during isel like dbg.value.
  int FI = std::numeric_limits<int>::max();
  if (const auto *AI = dyn_cast<AllocaInst>(Address)) {
    auto SI = FuncInfo.StaticAllocaMap.find(AI);
    if (SI != FuncInfo.StaticAllocaMap.end())
      FI = SI->second;
  } else if (const auto *Arg = dyn_cast<Argument>(Address))
    FI = FuncInfo.getArgumentFrameIndex(Arg);

  if (FI == std::numeric_limits<int>::max())
    return false;

  if (Offset.getBoolValue())
    Expr = DIExpression::prepend(Expr, DIExpression::ApplyOffset,
                                 Offset.getZExtValue());

  LLVM_DEBUG(dbgs() << "processDbgDeclare: setVariableDbgInfo Var=" << *Var
                    << ", Expr=" << *Expr << ",  FI=" << FI
                    << ", DbgLoc=" << DbgLoc << "\n");
  MF->setVariableDbgInfo(Var, Expr, FI, DbgLoc);
  return true;
}

/// Collect llvm.dbg.declare information. This is done after argument lowering
/// in case the declarations refer to arguments.
static void processDbgDeclares(FunctionLoweringInfo &FuncInfo) {
  for (const auto &I : instructions(*FuncInfo.Fn)) {
    const auto *DI = dyn_cast<DbgDeclareInst>(&I);
    if (DI && processDbgDeclare(FuncInfo, DI->getAddress(), DI->getExpression(),
                                DI->getVariable(), DI->getDebugLoc()))
      FuncInfo.PreprocessedDbgDeclares.insert(DI);
    for (const DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
      if (DVR.Type == DbgVariableRecord::LocationType::Declare &&
          processDbgDeclare(FuncInfo, DVR.getVariableLocationOp(0),
                            DVR.getExpression(), DVR.getVariable(),
                            DVR.getDebugLoc()))
        FuncInfo.PreprocessedDVRDeclares.insert(&DVR);
    }
  }
}

/// Collect single location variable information generated with assignment
/// tracking. This is done after argument lowering in case the declarations
/// refer to arguments.
static void processSingleLocVars(FunctionLoweringInfo &FuncInfo,
                                 FunctionVarLocs const *FnVarLocs) {
  for (auto It = FnVarLocs->single_locs_begin(),
            End = FnVarLocs->single_locs_end();
       It != End; ++It) {
    assert(!It->Values.hasArgList() && "Single loc variadic ops not supported");
    processDbgDeclare(FuncInfo, It->Values.getVariableLocationOp(0), It->Expr,
                      FnVarLocs->getDILocalVariable(It->VariableID), It->DL);
  }
}

void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
  FastISelFailed = false;
  // Initialize the Fast-ISel state, if needed.
  FastISel *FastIS = nullptr;
  if (TM.Options.EnableFastISel) {
    LLVM_DEBUG(dbgs() << "Enabling fast-isel\n");
    FastIS = TLI->createFastISel(*FuncInfo, LibInfo);
  }

  ReversePostOrderTraversal<const Function*> RPOT(&Fn);

  // Lower arguments up front. An RPO iteration always visits the entry block
  // first.
  assert(*RPOT.begin() == &Fn.getEntryBlock());
  ++NumEntryBlocks;

  // Set up FuncInfo for ISel. Entry blocks never have PHIs.
  FuncInfo->MBB = FuncInfo->getMBB(&Fn.getEntryBlock());
  FuncInfo->InsertPt = FuncInfo->MBB->begin();

  CurDAG->setFunctionLoweringInfo(FuncInfo.get());

  if (!FastIS) {
    LowerArguments(Fn);
  } else {
    // See if fast isel can lower the arguments.
    FastIS->startNewBlock();
    if (!FastIS->lowerArguments()) {
      FastISelFailed = true;
      // Fast isel failed to lower these arguments
      ++NumFastIselFailLowerArguments;

      OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
                                 Fn.getSubprogram(),
                                 &Fn.getEntryBlock());
      R << "FastISel didn't lower all arguments: "
        << ore::NV("Prototype", Fn.getFunctionType());
      reportFastISelFailure(*MF, *ORE, R, EnableFastISelAbort > 1);

      // Use SelectionDAG argument lowering
      LowerArguments(Fn);
      CurDAG->setRoot(SDB->getControlRoot());
      SDB->clear();
      CodeGenAndEmitDAG();
    }

    // If we inserted any instructions at the beginning, make a note of
    // where they are, so we can be sure to emit subsequent instructions
    // after them.
    if (FuncInfo->InsertPt != FuncInfo->MBB->begin())
      FastIS->setLastLocalValue(&*std::prev(FuncInfo->InsertPt));
    else
      FastIS->setLastLocalValue(nullptr);
  }

  bool Inserted = SwiftError->createEntriesInEntryBlock(SDB->getCurDebugLoc());

  if (FastIS && Inserted)
    FastIS->setLastLocalValue(&*std::prev(FuncInfo->InsertPt));

  if (isAssignmentTrackingEnabled(*Fn.getParent())) {
    assert(CurDAG->getFunctionVarLocs() &&
           "expected AssignmentTrackingAnalysis pass results");
    processSingleLocVars(*FuncInfo, CurDAG->getFunctionVarLocs());
  } else {
    processDbgDeclares(*FuncInfo);
  }

  // Iterate over all basic blocks in the function.
  FuncInfo->VisitedBBs.assign(Fn.getMaxBlockNumber(), false);
  for (const BasicBlock *LLVMBB : RPOT) {
    if (OptLevel != CodeGenOptLevel::None) {
      bool AllPredsVisited = true;
      for (const BasicBlock *Pred : predecessors(LLVMBB)) {
        if (!FuncInfo->VisitedBBs[Pred->getNumber()]) {
          AllPredsVisited = false;
          break;
        }
      }

      if (AllPredsVisited) {
        for (const PHINode &PN : LLVMBB->phis())
          FuncInfo->ComputePHILiveOutRegInfo(&PN);
      } else {
        for (const PHINode &PN : LLVMBB->phis())
          FuncInfo->InvalidatePHILiveOutRegInfo(&PN);
      }

      FuncInfo->VisitedBBs[LLVMBB->getNumber()] = true;
    }

    // Fake uses that follow tail calls are dropped. To avoid this, move
    // such fake uses in front of the tail call, provided they don't
    // use anything def'd by or after the tail call.
    {
      BasicBlock::iterator BBStart =
          const_cast<BasicBlock *>(LLVMBB)->getFirstNonPHIIt();
      BasicBlock::iterator BBEnd = const_cast<BasicBlock *>(LLVMBB)->end();
      preserveFakeUses(BBStart, BBEnd);
    }

    BasicBlock::const_iterator const Begin = LLVMBB->getFirstNonPHIIt();
    BasicBlock::const_iterator const End = LLVMBB->end();
    BasicBlock::const_iterator BI = End;

    FuncInfo->MBB = FuncInfo->getMBB(LLVMBB);
    if (!FuncInfo->MBB)
      continue; // Some blocks like catchpads have no code or MBB.

    // Insert new instructions after any phi or argument setup code.
    FuncInfo->InsertPt = FuncInfo->MBB->end();

    // Setup an EH landing-pad block.
    FuncInfo->ExceptionPointerVirtReg = Register();
    FuncInfo->ExceptionSelectorVirtReg = Register();
    if (LLVMBB->isEHPad())
      if (!PrepareEHLandingPad())
        continue;

    // Before doing SelectionDAG ISel, see if FastISel has been requested.
    if (FastIS) {
      if (LLVMBB != &Fn.getEntryBlock())
        FastIS->startNewBlock();

      unsigned NumFastIselRemaining = std::distance(Begin, End);

      // Pre-assign swifterror vregs.
      SwiftError->preassignVRegs(FuncInfo->MBB, Begin, End);

      // Do FastISel on as many instructions as possible.
      for (; BI != Begin; --BI) {
        const Instruction *Inst = &*std::prev(BI);

        // If we no longer require this instruction, skip it.
        if (isFoldedOrDeadInstruction(Inst, *FuncInfo) ||
            ElidedArgCopyInstrs.count(Inst)) {
          --NumFastIselRemaining;
          FastIS->handleDbgInfo(Inst);
          continue;
        }

        // Bottom-up: reset the insert pos at the top, after any local-value
        // instructions.
        FastIS->recomputeInsertPt();

        // Try to select the instruction with FastISel.
        if (FastIS->selectInstruction(Inst)) {
          --NumFastIselRemaining;
          ++NumFastIselSuccess;

          FastIS->handleDbgInfo(Inst);
          // If fast isel succeeded, skip over all the folded instructions, and
          // then see if there is a load right before the selected instructions.
          // Try to fold the load if so.
          const Instruction *BeforeInst = Inst;
          while (BeforeInst != &*Begin) {
            BeforeInst = &*std::prev(BasicBlock::const_iterator(BeforeInst));
            if (!isFoldedOrDeadInstruction(BeforeInst, *FuncInfo))
              break;
          }
          if (BeforeInst != Inst && isa<LoadInst>(BeforeInst) &&
              BeforeInst->hasOneUse() &&
              FastIS->tryToFoldLoad(cast<LoadInst>(BeforeInst), Inst)) {
            // If we succeeded, don't re-select the load.
            LLVM_DEBUG(dbgs()
                       << "FastISel folded load: " << *BeforeInst << "\n");
            FastIS->handleDbgInfo(BeforeInst);
            BI = std::next(BasicBlock::const_iterator(BeforeInst));
            --NumFastIselRemaining;
            ++NumFastIselSuccess;
          }
          continue;
        }

        FastISelFailed = true;

        // Then handle certain instructions as single-LLVM-Instruction blocks.
        // We cannot separate out GCrelocates to their own blocks since we need
        // to keep track of gc-relocates for a particular gc-statepoint. This is
        // done by SelectionDAGBuilder::LowerAsSTATEPOINT, called before
        // visitGCRelocate.
        if (isa<CallInst>(Inst) && !isa<GCStatepointInst>(Inst) &&
            !isa<GCRelocateInst>(Inst) && !isa<GCResultInst>(Inst)) {
          OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
                                     Inst->getDebugLoc(), LLVMBB);

          R << "FastISel missed call";

          if (R.isEnabled() || EnableFastISelAbort) {
            std::string InstStrStorage;
            raw_string_ostream InstStr(InstStrStorage);
            InstStr << *Inst;

            R << ": " << InstStrStorage;
          }

          reportFastISelFailure(*MF, *ORE, R, EnableFastISelAbort > 2);

          if (!Inst->getType()->isVoidTy() && !Inst->getType()->isTokenTy() &&
              !Inst->use_empty()) {
            Register &R = FuncInfo->ValueMap[Inst];
            if (!R)
              R = FuncInfo->CreateRegs(Inst);
          }

          bool HadTailCall = false;
          MachineBasicBlock::iterator SavedInsertPt = FuncInfo->InsertPt;
          SelectBasicBlock(Inst->getIterator(), BI, HadTailCall);

          // If the call was emitted as a tail call, we're done with the block.
          // We also need to delete any previously emitted instructions.
          if (HadTailCall) {
            FastIS->removeDeadCode(SavedInsertPt, FuncInfo->MBB->end());
            --BI;
            break;
          }

          // Recompute NumFastIselRemaining as Selection DAG instruction
          // selection may have handled the call, input args, etc.
          unsigned RemainingNow = std::distance(Begin, BI);
          NumFastIselFailures += NumFastIselRemaining - RemainingNow;
          NumFastIselRemaining = RemainingNow;
          continue;
        }

        OptimizationRemarkMissed R("sdagisel", "FastISelFailure",
                                   Inst->getDebugLoc(), LLVMBB);

        bool ShouldAbort = EnableFastISelAbort;
        if (Inst->isTerminator()) {
          // Use a different message for terminator misses.
          R << "FastISel missed terminator";
          // Don't abort for terminator unless the level is really high
          ShouldAbort = (EnableFastISelAbort > 2);
        } else {
          R << "FastISel missed";
        }

        if (R.isEnabled() || EnableFastISelAbort) {
          std::string InstStrStorage;
          raw_string_ostream InstStr(InstStrStorage);
          InstStr << *Inst;
          R << ": " << InstStrStorage;
        }

        reportFastISelFailure(*MF, *ORE, R, ShouldAbort);

        NumFastIselFailures += NumFastIselRemaining;
        break;
      }

      FastIS->recomputeInsertPt();
    }

    if (SP->shouldEmitSDCheck(*LLVMBB)) {
      bool FunctionBasedInstrumentation =
          TLI->getSSPStackGuardCheck(*Fn.getParent());
      SDB->SPDescriptor.initialize(LLVMBB, FuncInfo->getMBB(LLVMBB),
                                   FunctionBasedInstrumentation);
    }

    if (Begin != BI)
      ++NumDAGBlocks;
    else
      ++NumFastIselBlocks;

    if (Begin != BI) {
      // Run SelectionDAG instruction selection on the remainder of the block
      // not handled by FastISel. If FastISel is not run, this is the entire
      // block.
      bool HadTailCall;
      SelectBasicBlock(Begin, BI, HadTailCall);

      // But if FastISel was run, we already selected some of the block.
      // If we emitted a tail-call, we need to delete any previously emitted
      // instruction that follows it.
      if (FastIS && HadTailCall && FuncInfo->InsertPt != FuncInfo->MBB->end())
        FastIS->removeDeadCode(FuncInfo->InsertPt, FuncInfo->MBB->end());
    }

    if (FastIS)
      FastIS->finishBasicBlock();
    FinishBasicBlock();
    FuncInfo->PHINodesToUpdate.clear();
    ElidedArgCopyInstrs.clear();
  }

  // AsynchEH: Report Block State under -AsynchEH
  if (Fn.getParent()->getModuleFlag("eh-asynch"))
    reportIPToStateForBlocks(MF);

  SP->copyToMachineFrameInfo(MF->getFrameInfo());

  SwiftError->propagateVRegs();

  delete FastIS;
  SDB->clearDanglingDebugInfo();
  SDB->SPDescriptor.resetPerFunctionState();
}

void
SelectionDAGISel::FinishBasicBlock() {
  LLVM_DEBUG(dbgs() << "Total amount of phi nodes to update: "
                    << FuncInfo->PHINodesToUpdate.size() << "\n";
             for (unsigned i = 0, e = FuncInfo->PHINodesToUpdate.size(); i != e;
                  ++i) dbgs()
             << "Node " << i << " : (" << FuncInfo->PHINodesToUpdate[i].first
             << ", " << printReg(FuncInfo->PHINodesToUpdate[i].second)
             << ")\n");

  // Next, now that we know what the last MBB the LLVM BB expanded is, update
  // PHI nodes in successors.
  for (unsigned i = 0, e = FuncInfo->PHINodesToUpdate.size(); i != e; ++i) {
    MachineInstrBuilder PHI(*MF, FuncInfo->PHINodesToUpdate[i].first);
    assert(PHI->isPHI() &&
           "This is not a machine PHI node that we are updating!");
    if (!FuncInfo->MBB->isSuccessor(PHI->getParent()))
      continue;
    PHI.addReg(FuncInfo->PHINodesToUpdate[i].second).addMBB(FuncInfo->MBB);
  }

  // Handle stack protector.
  if (SDB->SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
    // The target provides a guard check function. There is no need to
    // generate error handling code or to split current basic block.
    MachineBasicBlock *ParentMBB = SDB->SPDescriptor.getParentMBB();

    // Add load and check to the basicblock.
    FuncInfo->MBB = ParentMBB;
    FuncInfo->InsertPt =
        findSplitPointForStackProtector(ParentMBB, *TII);
    SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB);
    CurDAG->setRoot(SDB->getRoot());
    SDB->clear();
    CodeGenAndEmitDAG();

    // Clear the Per-BB State.
    SDB->SPDescriptor.resetPerBBState();
  } else if (SDB->SPDescriptor.shouldEmitStackProtector()) {
    MachineBasicBlock *ParentMBB = SDB->SPDescriptor.getParentMBB();
    MachineBasicBlock *SuccessMBB = SDB->SPDescriptor.getSuccessMBB();

    // Find the split point to split the parent mbb. At the same time copy all
    // physical registers used in the tail of parent mbb into virtual registers
    // before the split point and back into physical registers after the split
    // point. This prevents us needing to deal with Live-ins and many other
    // register allocation issues caused by us splitting the parent mbb. The
    // register allocator will clean up said virtual copies later on.
    MachineBasicBlock::iterator SplitPoint =
        findSplitPointForStackProtector(ParentMBB, *TII);

    // Splice the terminator of ParentMBB into SuccessMBB.
    SuccessMBB->splice(SuccessMBB->end(), ParentMBB,
                       SplitPoint,
                       ParentMBB->end());

    // Add compare/jump on neq/jump to the parent BB.
    FuncInfo->MBB = ParentMBB;
    FuncInfo->InsertPt = ParentMBB->end();
    SDB->visitSPDescriptorParent(SDB->SPDescriptor, ParentMBB);
    CurDAG->setRoot(SDB->getRoot());
    SDB->clear();
    CodeGenAndEmitDAG();

    // CodeGen Failure MBB if we have not codegened it yet.
    MachineBasicBlock *FailureMBB = SDB->SPDescriptor.getFailureMBB();
    if (FailureMBB->empty()) {
      FuncInfo->MBB = FailureMBB;
      FuncInfo->InsertPt = FailureMBB->end();
      SDB->visitSPDescriptorFailure(SDB->SPDescriptor);
      CurDAG->setRoot(SDB->getRoot());
      SDB->clear();
      CodeGenAndEmitDAG();
    }

    // Clear the Per-BB State.
    SDB->SPDescriptor.resetPerBBState();
  }

  // Lower each BitTestBlock.
  for (auto &BTB : SDB->SL->BitTestCases) {
    // Lower header first, if it wasn't already lowered
    if (!BTB.Emitted) {
      // Set the current basic block to the mbb we wish to insert the code into
      FuncInfo->MBB = BTB.Parent;
      FuncInfo->InsertPt = FuncInfo->MBB->end();
      // Emit the code
      SDB->visitBitTestHeader(BTB, FuncInfo->MBB);
      CurDAG->setRoot(SDB->getRoot());
      SDB->clear();
      CodeGenAndEmitDAG();
    }

    BranchProbability UnhandledProb = BTB.Prob;
    for (unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
      UnhandledProb -= BTB.Cases[j].ExtraProb;
      // Set the current basic block to the mbb we wish to insert the code into
      FuncInfo->MBB = BTB.Cases[j].ThisBB;
      FuncInfo->InsertPt = FuncInfo->MBB->end();
      // Emit the code

      // If all cases cover a contiguous range, it is not necessary to jump to
      // the default block after the last bit test fails. This is because the
      // range check during bit test header creation has guaranteed that every
      // case here doesn't go outside the range. In this case, there is no need
      // to perform the last bit test, as it will always be true. Instead, make
      // the second-to-last bit-test fall through to the target of the last bit
      // test, and delete the last bit test.

      MachineBasicBlock *NextMBB;
      if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
        // Second-to-last bit-test with contiguous range or omitted range
        // check: fall through to the target of the final bit test.
        NextMBB = BTB.Cases[j + 1].TargetBB;
      } else if (j + 1 == ej) {
        // For the last bit test, fall through to Default.
        NextMBB = BTB.Default;
      } else {
        // Otherwise, fall through to the next bit test.
        NextMBB = BTB.Cases[j + 1].ThisBB;
      }

      SDB->visitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
                            FuncInfo->MBB);

      CurDAG->setRoot(SDB->getRoot());
      SDB->clear();
      CodeGenAndEmitDAG();

      if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
        // Since we're not going to use the final bit test, remove it.
        BTB.Cases.pop_back();
        break;
      }
    }

    // Update PHI Nodes
    for (const std::pair<MachineInstr *, Register> &P :
         FuncInfo->PHINodesToUpdate) {
      MachineInstrBuilder PHI(*MF, P.first);
      MachineBasicBlock *PHIBB = PHI->getParent();
      assert(PHI->isPHI() &&
             "This is not a machine PHI node that we are updating!");
      // This is "default" BB. We have two jumps to it. From "header" BB and
      // from last "case" BB, unless the latter was skipped.
      if (PHIBB == BTB.Default) {
        PHI.addReg(P.second).addMBB(BTB.Parent);
        if (!BTB.ContiguousRange) {
          PHI.addReg(P.second).addMBB(BTB.Cases.back().ThisBB);
         }
      }
      // One of "cases" BB.
      for (const SwitchCG::BitTestCase &BT : BTB.Cases) {
        MachineBasicBlock* cBB = BT.ThisBB;
        if (cBB->isSuccessor(PHIBB))
          PHI.addReg(P.second).addMBB(cBB);
      }
    }
  }
  SDB->SL->BitTestCases.clear();

  // If the JumpTable record is filled in, then we need to emit a jump table.
  // Updating the PHI nodes is tricky in this case, since we need to determine
  // whether the PHI is a successor of the range check MBB or the jump table MBB
  for (unsigned i = 0, e = SDB->SL->JTCases.size(); i != e; ++i) {
    // Lower header first, if it wasn't already lowered
    if (!SDB->SL->JTCases[i].first.Emitted) {
      // Set the current basic block to the mbb we wish to insert the code into
      FuncInfo->MBB = SDB->SL->JTCases[i].first.HeaderBB;
      FuncInfo->InsertPt = FuncInfo->MBB->end();
      // Emit the code
      SDB->visitJumpTableHeader(SDB->SL->JTCases[i].second,
                                SDB->SL->JTCases[i].first, FuncInfo->MBB);
      CurDAG->setRoot(SDB->getRoot());
      SDB->clear();
      CodeGenAndEmitDAG();
    }

    // Set the current basic block to the mbb we wish to insert the code into
    FuncInfo->MBB = SDB->SL->JTCases[i].second.MBB;
    FuncInfo->InsertPt = FuncInfo->MBB->end();
    // Emit the code
    SDB->visitJumpTable(SDB->SL->JTCases[i].second);
    CurDAG->setRoot(SDB->getRoot());
    SDB->clear();
    CodeGenAndEmitDAG();

    // Update PHI Nodes
    for (unsigned pi = 0, pe = FuncInfo->PHINodesToUpdate.size();
         pi != pe; ++pi) {
      MachineInstrBuilder PHI(*MF, FuncInfo->PHINodesToUpdate[pi].first);
      MachineBasicBlock *PHIBB = PHI->getParent();
      assert(PHI->isPHI() &&
             "This is not a machine PHI node that we are updating!");
      // "default" BB. We can go there only from header BB.
      if (PHIBB == SDB->SL->JTCases[i].second.Default)
        PHI.addReg(FuncInfo->PHINodesToUpdate[pi].second)
           .addMBB(SDB->SL->JTCases[i].first.HeaderBB);
      // JT BB. Just iterate over successors here
      if (FuncInfo->MBB->isSuccessor(PHIBB))
        PHI.addReg(FuncInfo->PHINodesToUpdate[pi].second).addMBB(FuncInfo->MBB);
    }
  }
  SDB->SL->JTCases.clear();

  // If we generated any switch lowering information, build and codegen any
  // additional DAGs necessary.
  for (unsigned i = 0, e = SDB->SL->SwitchCases.size(); i != e; ++i) {
    // Set the current basic block to the mbb we wish to insert the code into
    FuncInfo->MBB = SDB->SL->SwitchCases[i].ThisBB;
    FuncInfo->InsertPt = FuncInfo->MBB->end();

    // Determine the unique successors.
    SmallVector<MachineBasicBlock *, 2> Succs;
    Succs.push_back(SDB->SL->SwitchCases[i].TrueBB);
    if (SDB->SL->SwitchCases[i].TrueBB != SDB->SL->SwitchCases[i].FalseBB)
      Succs.push_back(SDB->SL->SwitchCases[i].FalseBB);

    // Emit the code. Note that this could result in FuncInfo->MBB being split.
    SDB->visitSwitchCase(SDB->SL->SwitchCases[i], FuncInfo->MBB);
    CurDAG->setRoot(SDB->getRoot());
    SDB->clear();
    CodeGenAndEmitDAG();

    // Remember the last block, now that any splitting is done, for use in
    // populating PHI nodes in successors.
    MachineBasicBlock *ThisBB = FuncInfo->MBB;

    // Handle any PHI nodes in successors of this chunk, as if we were coming
    // from the original BB before switch expansion.  Note that PHI nodes can
    // occur multiple times in PHINodesToUpdate.  We have to be very careful to
    // handle them the right number of times.
    for (MachineBasicBlock *Succ : Succs) {
      FuncInfo->MBB = Succ;
      FuncInfo->InsertPt = FuncInfo->MBB->end();
      // FuncInfo->MBB may have been removed from the CFG if a branch was
      // constant folded.
      if (ThisBB->isSuccessor(FuncInfo->MBB)) {
        for (MachineBasicBlock::iterator
             MBBI = FuncInfo->MBB->begin(), MBBE = FuncInfo->MBB->end();
             MBBI != MBBE && MBBI->isPHI(); ++MBBI) {
          MachineInstrBuilder PHI(*MF, MBBI);
          // This value for this PHI node is recorded in PHINodesToUpdate.
          for (unsigned pn = 0; ; ++pn) {
            assert(pn != FuncInfo->PHINodesToUpdate.size() &&
                   "Didn't find PHI entry!");
            if (FuncInfo->PHINodesToUpdate[pn].first == PHI) {
              PHI.addReg(FuncInfo->PHINodesToUpdate[pn].second).addMBB(ThisBB);
              break;
            }
          }
        }
      }
    }
  }
  SDB->SL->SwitchCases.clear();
}

/// Create the scheduler. If a specific scheduler was specified
/// via the SchedulerRegistry, use it, otherwise select the
/// one preferred by the target.
///
ScheduleDAGSDNodes *SelectionDAGISel::CreateScheduler() {
  return ISHeuristic(this, OptLevel);
}

//===----------------------------------------------------------------------===//
// Helper functions used by the generated instruction selector.
//===----------------------------------------------------------------------===//
// Calls to these methods are generated by tblgen.

/// CheckAndMask - The isel is trying to match something like (and X, 255).  If
/// the dag combiner simplified the 255, we still want to match.  RHS is the
/// actual value in the DAG on the RHS of an AND, and DesiredMaskS is the value
/// specified in the .td file (e.g. 255).
bool SelectionDAGISel::CheckAndMask(SDValue LHS, ConstantSDNode *RHS,
                                    int64_t DesiredMaskS) const {
  const APInt &ActualMask = RHS->getAPIntValue();
  // TODO: Avoid implicit trunc?
  // See https://github.com/llvm/llvm-project/issues/112510.
  const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS,
                                   /*isSigned=*/false, /*implicitTrunc=*/true);

  // If the actual mask exactly matches, success!
  if (ActualMask == DesiredMask)
    return true;

  // If the actual AND mask is allowing unallowed bits, this doesn't match.
  if (!ActualMask.isSubsetOf(DesiredMask))
    return false;

  // Otherwise, the DAG Combiner may have proven that the value coming in is
  // either already zero or is not demanded.  Check for known zero input bits.
  APInt NeededMask = DesiredMask & ~ActualMask;
  if (CurDAG->MaskedValueIsZero(LHS, NeededMask))
    return true;

  // TODO: check to see if missing bits are just not demanded.

  // Otherwise, this pattern doesn't match.
  return false;
}

/// CheckOrMask - The isel is trying to match something like (or X, 255).  If
/// the dag combiner simplified the 255, we still want to match.  RHS is the
/// actual value in the DAG on the RHS of an OR, and DesiredMaskS is the value
/// specified in the .td file (e.g. 255).
bool SelectionDAGISel::CheckOrMask(SDValue LHS, ConstantSDNode *RHS,
                                   int64_t DesiredMaskS) const {
  const APInt &ActualMask = RHS->getAPIntValue();
  // TODO: Avoid implicit trunc?
  // See https://github.com/llvm/llvm-project/issues/112510.
  const APInt &DesiredMask = APInt(LHS.getValueSizeInBits(), DesiredMaskS,
                                   /*isSigned=*/false, /*implicitTrunc=*/true);

  // If the actual mask exactly matches, success!
  if (ActualMask == DesiredMask)
    return true;

  // If the actual AND mask is allowing unallowed bits, this doesn't match.
  if (!ActualMask.isSubsetOf(DesiredMask))
    return false;

  // Otherwise, the DAG Combiner may have proven that the value coming in is
  // either already zero or is not demanded.  Check for known zero input bits.
  APInt NeededMask = DesiredMask & ~ActualMask;
  KnownBits Known = CurDAG->computeKnownBits(LHS);

  // If all the missing bits in the or are already known to be set, match!
  if (NeededMask.isSubsetOf(Known.One))
    return true;

  // TODO: check to see if missing bits are just not demanded.

  // Otherwise, this pattern doesn't match.
  return false;
}

/// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
/// by tblgen.  Others should not call it.
void SelectionDAGISel::SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops,
                                                     const SDLoc &DL) {
  // Change the vector of SDValue into a list of SDNodeHandle for x86 might call
  // replaceAllUses when matching address.

  std::list<HandleSDNode> Handles;

  Handles.emplace_back(Ops[InlineAsm::Op_InputChain]); // 0
  Handles.emplace_back(Ops[InlineAsm::Op_AsmString]);  // 1
  Handles.emplace_back(Ops[InlineAsm::Op_MDNode]);     // 2, !srcloc
  Handles.emplace_back(
      Ops[InlineAsm::Op_ExtraInfo]); // 3 (SideEffect, AlignStack)

  unsigned i = InlineAsm::Op_FirstOperand, e = Ops.size();
  if (Ops[e - 1].getValueType() == MVT::Glue)
    --e;  // Don't process a glue operand if it is here.

  while (i != e) {
    InlineAsm::Flag Flags(Ops[i]->getAsZExtVal());
    if (!Flags.isMemKind() && !Flags.isFuncKind()) {
      // Just skip over this operand, copying the operands verbatim.
      Handles.insert(Handles.end(), Ops.begin() + i,
                     Ops.begin() + i + Flags.getNumOperandRegisters() + 1);
      i += Flags.getNumOperandRegisters() + 1;
    } else {
      assert(Flags.getNumOperandRegisters() == 1 &&
             "Memory operand with multiple values?");

      unsigned TiedToOperand;
      if (Flags.isUseOperandTiedToDef(TiedToOperand)) {
        // We need the constraint ID from the operand this is tied to.
        unsigned CurOp = InlineAsm::Op_FirstOperand;
        Flags = InlineAsm::Flag(Ops[CurOp]->getAsZExtVal());
        for (; TiedToOperand; --TiedToOperand) {
          CurOp += Flags.getNumOperandRegisters() + 1;
          Flags = InlineAsm::Flag(Ops[CurOp]->getAsZExtVal());
        }
      }

      // Otherwise, this is a memory operand.  Ask the target to select it.
      std::vector<SDValue> SelOps;
      const InlineAsm::ConstraintCode ConstraintID =
          Flags.getMemoryConstraintID();
      if (SelectInlineAsmMemoryOperand(Ops[i + 1], ConstraintID, SelOps))
        report_fatal_error("Could not match memory address.  Inline asm"
                           " failure!");

      // Add this to the output node.
      Flags = InlineAsm::Flag(Flags.isMemKind() ? InlineAsm::Kind::Mem
                                                : InlineAsm::Kind::Func,
                              SelOps.size());
      Flags.setMemConstraint(ConstraintID);
      Handles.emplace_back(CurDAG->getTargetConstant(Flags, DL, MVT::i32));
      Handles.insert(Handles.end(), SelOps.begin(), SelOps.end());
      i += 2;
    }
  }

  // Add the glue input back if present.
  if (e != Ops.size())
    Handles.emplace_back(Ops.back());

  Ops.clear();
  for (auto &handle : Handles)
    Ops.push_back(handle.getValue());
}

/// findNonImmUse - Return true if "Def" is a predecessor of "Root" via a path
/// beyond "ImmedUse".  We may ignore chains as they are checked separately.
static bool findNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse,
                          bool IgnoreChains) {
  SmallPtrSet<const SDNode *, 16> Visited;
  SmallVector<const SDNode *, 16> WorkList;
  // Only check if we have non-immediate uses of Def.
  if (ImmedUse->isOnlyUserOf(Def))
    return false;

  // We don't care about paths to Def that go through ImmedUse so mark it
  // visited and mark non-def operands as used.
  Visited.insert(ImmedUse);
  for (const SDValue &Op : ImmedUse->op_values()) {
    SDNode *N = Op.getNode();
    // Ignore chain deps (they are validated by
    // HandleMergeInputChains) and immediate uses
    if ((Op.getValueType() == MVT::Other && IgnoreChains) || N == Def)
      continue;
    if (!Visited.insert(N).second)
      continue;
    WorkList.push_back(N);
  }

  // Initialize worklist to operands of Root.
  if (Root != ImmedUse) {
    for (const SDValue &Op : Root->op_values()) {
      SDNode *N = Op.getNode();
      // Ignore chains (they are validated by HandleMergeInputChains)
      if ((Op.getValueType() == MVT::Other && IgnoreChains) || N == Def)
        continue;
      if (!Visited.insert(N).second)
        continue;
      WorkList.push_back(N);
    }
  }

  return SDNode::hasPredecessorHelper(Def, Visited, WorkList, 0, true);
}

/// IsProfitableToFold - Returns true if it's profitable to fold the specific
/// operand node N of U during instruction selection that starts at Root.
bool SelectionDAGISel::IsProfitableToFold(SDValue N, SDNode *U,
                                          SDNode *Root) const {
  if (OptLevel == CodeGenOptLevel::None)
    return false;
  return N.hasOneUse();
}

/// IsLegalToFold - Returns true if the specific operand node N of
/// U can be folded during instruction selection that starts at Root.
bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
                                     CodeGenOptLevel OptLevel,
                                     bool IgnoreChains) {
  if (OptLevel == CodeGenOptLevel::None)
    return false;

  // If Root use can somehow reach N through a path that doesn't contain
  // U then folding N would create a cycle. e.g. In the following
  // diagram, Root can reach N through X. If N is folded into Root, then
  // X is both a predecessor and a successor of U.
  //
  //          [N*]           //
  //         ^   ^           //
  //        /     \          //
  //      [U*]    [X]?       //
  //        ^     ^          //
  //         \   /           //
  //          \ /            //
  //         [Root*]         //
  //
  // * indicates nodes to be folded together.
  //
  // If Root produces glue, then it gets (even more) interesting. Since it
  // will be "glued" together with its glue use in the scheduler, we need to
  // check if it might reach N.
  //
  //          [N*]           //
  //         ^   ^           //
  //        /     \          //
  //      [U*]    [X]?       //
  //        ^       ^        //
  //         \       \       //
  //          \      |       //
  //         [Root*] |       //
  //          ^      |       //
  //          f      |       //
  //          |      /       //
  //         [Y]    /        //
  //           ^   /         //
  //           f  /          //
  //           | /           //
  //          [GU]           //
  //
  // If GU (glue use) indirectly reaches N (the load), and Root folds N
  // (call it Fold), then X is a predecessor of GU and a successor of
  // Fold. But since Fold and GU are glued together, this will create
  // a cycle in the scheduling graph.

  // If the node has glue, walk down the graph to the "lowest" node in the
  // glueged set.
  EVT VT = Root->getValueType(Root->getNumValues()-1);
  while (VT == MVT::Glue) {
    SDNode *GU = Root->getGluedUser();
    if (!GU)
      break;
    Root = GU;
    VT = Root->getValueType(Root->getNumValues()-1);

    // If our query node has a glue result with a use, we've walked up it.  If
    // the user (which has already been selected) has a chain or indirectly uses
    // the chain, HandleMergeInputChains will not consider it.  Because of
    // this, we cannot ignore chains in this predicate.
    IgnoreChains = false;
  }

  return !findNonImmUse(Root, N.getNode(), U, IgnoreChains);
}

void SelectionDAGISel::Select_INLINEASM(SDNode *N) {
  SDLoc DL(N);

  std::vector<SDValue> Ops(N->op_begin(), N->op_end());
  SelectInlineAsmMemoryOperands(Ops, DL);

  const EVT VTs[] = {MVT::Other, MVT::Glue};
  SDValue New = CurDAG->getNode(N->getOpcode(), DL, VTs, Ops);
  New->setNodeId(-1);
  ReplaceUses(N, New.getNode());
  CurDAG->RemoveDeadNode(N);
}

void SelectionDAGISel::Select_READ_REGISTER(SDNode *Op) {
  SDLoc dl(Op);
  MDNodeSDNode *MD = cast<MDNodeSDNode>(Op->getOperand(1));
  const MDString *RegStr = cast<MDString>(MD->getMD()->getOperand(0));

  EVT VT = Op->getValueType(0);
  LLT Ty = VT.isSimple() ? getLLTForMVT(VT.getSimpleVT()) : LLT();
  Register Reg =
      TLI->getRegisterByName(RegStr->getString().data(), Ty,
                             CurDAG->getMachineFunction());
  SDValue New = CurDAG->getCopyFromReg(
                        Op->getOperand(0), dl, Reg, Op->getValueType(0));
  New->setNodeId(-1);
  ReplaceUses(Op, New.getNode());
  CurDAG->RemoveDeadNode(Op);
}

void SelectionDAGISel::Select_WRITE_REGISTER(SDNode *Op) {
  SDLoc dl(Op);
  MDNodeSDNode *MD = cast<MDNodeSDNode>(Op->getOperand(1));
  const MDString *RegStr = cast<MDString>(MD->getMD()->getOperand(0));

  EVT VT = Op->getOperand(2).getValueType();
  LLT Ty = VT.isSimple() ? getLLTForMVT(VT.getSimpleVT()) : LLT();

  Register Reg = TLI->getRegisterByName(RegStr->getString().data(), Ty,
                                        CurDAG->getMachineFunction());
  SDValue New = CurDAG->getCopyToReg(
                        Op->getOperand(0), dl, Reg, Op->getOperand(2));
  New->setNodeId(-1);
  ReplaceUses(Op, New.getNode());
  CurDAG->RemoveDeadNode(Op);
}

void SelectionDAGISel::Select_UNDEF(SDNode *N) {
  CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, N->getValueType(0));
}

// Use the generic target FAKE_USE target opcode. The chain operand
// must come last, because InstrEmitter::AddOperand() requires it.
void SelectionDAGISel::Select_FAKE_USE(SDNode *N) {
  CurDAG->SelectNodeTo(N, TargetOpcode::FAKE_USE, N->getValueType(0),
                       N->getOperand(1), N->getOperand(0));
}

void SelectionDAGISel::Select_FREEZE(SDNode *N) {
  // TODO: We don't have FREEZE pseudo-instruction in MachineInstr-level now.
  // If FREEZE instruction is added later, the code below must be changed as
  // well.
  CurDAG->SelectNodeTo(N, TargetOpcode::COPY, N->getValueType(0),
                       N->getOperand(0));
}

void SelectionDAGISel::Select_ARITH_FENCE(SDNode *N) {
  CurDAG->SelectNodeTo(N, TargetOpcode::ARITH_FENCE, N->getValueType(0),
                       N->getOperand(0));
}

void SelectionDAGISel::Select_MEMBARRIER(SDNode *N) {
  CurDAG->SelectNodeTo(N, TargetOpcode::MEMBARRIER, N->getValueType(0),
                       N->getOperand(0));
}

void SelectionDAGISel::Select_CONVERGENCECTRL_ANCHOR(SDNode *N) {
  CurDAG->SelectNodeTo(N, TargetOpcode::CONVERGENCECTRL_ANCHOR,
                       N->getValueType(0));
}

void SelectionDAGISel::Select_CONVERGENCECTRL_ENTRY(SDNode *N) {
  CurDAG->SelectNodeTo(N, TargetOpcode::CONVERGENCECTRL_ENTRY,
                       N->getValueType(0));
}

void SelectionDAGISel::Select_CONVERGENCECTRL_LOOP(SDNode *N) {
  CurDAG->SelectNodeTo(N, TargetOpcode::CONVERGENCECTRL_LOOP,
                       N->getValueType(0), N->getOperand(0));
}

void SelectionDAGISel::pushStackMapLiveVariable(SmallVectorImpl<SDValue> &Ops,
                                                SDValue OpVal, SDLoc DL) {
  SDNode *OpNode = OpVal.getNode();

  // FrameIndex nodes should have been directly emitted to TargetFrameIndex
  // nodes at DAG-construction time.
  assert(OpNode->getOpcode() != ISD::FrameIndex);

  if (OpNode->getOpcode() == ISD::Constant) {
    Ops.push_back(
        CurDAG->getTargetConstant(StackMaps::ConstantOp, DL, MVT::i64));
    Ops.push_back(CurDAG->getTargetConstant(OpNode->getAsZExtVal(), DL,
                                            OpVal.getValueType()));
  } else {
    Ops.push_back(OpVal);
  }
}

void SelectionDAGISel::Select_STACKMAP(SDNode *N) {
  SmallVector<SDValue, 32> Ops;
  auto *It = N->op_begin();
  SDLoc DL(N);

  // Stash the chain and glue operands so we can move them to the end.
  SDValue Chain = *It++;
  SDValue InGlue = *It++;

  // <id> operand.
  SDValue ID = *It++;
  assert(ID.getValueType() == MVT::i64);
  Ops.push_back(ID);

  // <numShadowBytes> operand.
  SDValue Shad = *It++;
  assert(Shad.getValueType() == MVT::i32);
  Ops.push_back(Shad);

  // Live variable operands.
  for (; It != N->op_end(); It++)
    pushStackMapLiveVariable(Ops, *It, DL);

  Ops.push_back(Chain);
  Ops.push_back(InGlue);

  SDVTList NodeTys = CurDAG->getVTList(MVT::Other, MVT::Glue);
  CurDAG->SelectNodeTo(N, TargetOpcode::STACKMAP, NodeTys, Ops);
}

void SelectionDAGISel::Select_PATCHPOINT(SDNode *N) {
  SmallVector<SDValue, 32> Ops;
  auto *It = N->op_begin();
  SDLoc DL(N);

  // Cache arguments that will be moved to the end in the target node.
  SDValue Chain = *It++;
  std::optional<SDValue> Glue;
  if (It->getValueType() == MVT::Glue)
    Glue = *It++;
  SDValue RegMask = *It++;

  // <id> operand.
  SDValue ID = *It++;
  assert(ID.getValueType() == MVT::i64);
  Ops.push_back(ID);

  // <numShadowBytes> operand.
  SDValue Shad = *It++;
  assert(Shad.getValueType() == MVT::i32);
  Ops.push_back(Shad);

  // Add the callee.
  Ops.push_back(*It++);

  // Add <numArgs>.
  SDValue NumArgs = *It++;
  assert(NumArgs.getValueType() == MVT::i32);
  Ops.push_back(NumArgs);

  // Calling convention.
  Ops.push_back(*It++);

  // Push the args for the call.
  for (uint64_t I = NumArgs->getAsZExtVal(); I != 0; I--)
    Ops.push_back(*It++);

  // Now push the live variables.
  for (; It != N->op_end(); It++)
    pushStackMapLiveVariable(Ops, *It, DL);

  // Finally, the regmask, chain and (if present) glue are moved to the end.
  Ops.push_back(RegMask);
  Ops.push_back(Chain);
  if (Glue.has_value())
    Ops.push_back(*Glue);

  SDVTList NodeTys = N->getVTList();
  CurDAG->SelectNodeTo(N, TargetOpcode::PATCHPOINT, NodeTys, Ops);
}

/// GetVBR - decode a vbr encoding whose top bit is set.
LLVM_ATTRIBUTE_ALWAYS_INLINE static uint64_t
GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
  assert(Val >= 128 && "Not a VBR");
  Val &= 127;  // Remove first vbr bit.

  unsigned Shift = 7;
  uint64_t NextBits;
  do {
    NextBits = MatcherTable[Idx++];
    Val |= (NextBits&127) << Shift;
    Shift += 7;
  } while (NextBits & 128);

  return Val;
}

/// getSimpleVT - Decode a value in MatcherTable, if it's a VBR encoded value,
/// use GetVBR to decode it.
LLVM_ATTRIBUTE_ALWAYS_INLINE static MVT::SimpleValueType
getSimpleVT(const unsigned char *MatcherTable, unsigned &MatcherIndex) {
  unsigned SimpleVT = MatcherTable[MatcherIndex++];
  if (SimpleVT & 128)
    SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);

  return static_cast<MVT::SimpleValueType>(SimpleVT);
}

void SelectionDAGISel::Select_JUMP_TABLE_DEBUG_INFO(SDNode *N) {
  SDLoc dl(N);
  CurDAG->SelectNodeTo(N, TargetOpcode::JUMP_TABLE_DEBUG_INFO, MVT::Glue,
                       CurDAG->getTargetConstant(N->getConstantOperandVal(1),
                                                 dl, MVT::i64, true));
}

/// When a match is complete, this method updates uses of interior chain results
/// to use the new results.
void SelectionDAGISel::UpdateChains(
    SDNode *NodeToMatch, SDValue InputChain,
    SmallVectorImpl<SDNode *> &ChainNodesMatched, bool isMorphNodeTo) {
  SmallVector<SDNode*, 4> NowDeadNodes;

  // Now that all the normal results are replaced, we replace the chain and
  // glue results if present.
  if (!ChainNodesMatched.empty()) {
    assert(InputChain.getNode() &&
           "Matched input chains but didn't produce a chain");
    // Loop over all of the nodes we matched that produced a chain result.
    // Replace all the chain results with the final chain we ended up with.
    for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
      SDNode *ChainNode = ChainNodesMatched[i];
      // If ChainNode is null, it's because we replaced it on a previous
      // iteration and we cleared it out of the map. Just skip it.
      if (!ChainNode)
        continue;

      assert(ChainNode->getOpcode() != ISD::DELETED_NODE &&
             "Deleted node left in chain");

      // Don't replace the results of the root node if we're doing a
      // MorphNodeTo.
      if (ChainNode == NodeToMatch && isMorphNodeTo)
        continue;

      SDValue ChainVal = SDValue(ChainNode, ChainNode->getNumValues()-1);
      if (ChainVal.getValueType() == MVT::Glue)
        ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2);
      assert(ChainVal.getValueType() == MVT::Other && "Not a chain?");
      SelectionDAG::DAGNodeDeletedListener NDL(
          *CurDAG, [&](SDNode *N, SDNode *E) {
            std::replace(ChainNodesMatched.begin(), ChainNodesMatched.end(), N,
                         static_cast<SDNode *>(nullptr));
          });
      if (ChainNode->getOpcode() != ISD::TokenFactor)
        ReplaceUses(ChainVal, InputChain);

      // If the node became dead and we haven't already seen it, delete it.
      if (ChainNode != NodeToMatch && ChainNode->use_empty() &&
          !llvm::is_contained(NowDeadNodes, ChainNode))
        NowDeadNodes.push_back(ChainNode);
    }
  }

  if (!NowDeadNodes.empty())
    CurDAG->RemoveDeadNodes(NowDeadNodes);

  LLVM_DEBUG(dbgs() << "ISEL: Match complete!\n");
}

/// HandleMergeInputChains - This implements the OPC_EmitMergeInputChains
/// operation for when the pattern matched at least one node with a chains.  The
/// input vector contains a list of all of the chained nodes that we match.  We
/// must determine if this is a valid thing to cover (i.e. matching it won't
/// induce cycles in the DAG) and if so, creating a TokenFactor node. that will
/// be used as the input node chain for the generated nodes.
static SDValue
HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched,
                       SelectionDAG *CurDAG) {

  SmallPtrSet<const SDNode *, 16> Visited;
  SmallVector<const SDNode *, 8> Worklist;
  SmallVector<SDValue, 3> InputChains;
  unsigned int Max = 8192;

  // Quick exit on trivial merge.
  if (ChainNodesMatched.size() == 1)
    return ChainNodesMatched[0]->getOperand(0);

  // Add chains that aren't already added (internal). Peek through
  // token factors.
  std::function<void(const SDValue)> AddChains = [&](const SDValue V) {
    if (V.getValueType() != MVT::Other)
      return;
    if (V->getOpcode() == ISD::EntryToken)
      return;
    if (!Visited.insert(V.getNode()).second)
      return;
    if (V->getOpcode() == ISD::TokenFactor) {
      for (const SDValue &Op : V->op_values())
        AddChains(Op);
    } else
      InputChains.push_back(V);
  };

  for (auto *N : ChainNodesMatched) {
    Worklist.push_back(N);
    Visited.insert(N);
  }

  while (!Worklist.empty())
    AddChains(Worklist.pop_back_val()->getOperand(0));

  // Skip the search if there are no chain dependencies.
  if (InputChains.size() == 0)
    return CurDAG->getEntryNode();

  // If one of these chains is a successor of input, we must have a
  // node that is both the predecessor and successor of the
  // to-be-merged nodes. Fail.
  Visited.clear();
  for (SDValue V : InputChains)
    Worklist.push_back(V.getNode());

  for (auto *N : ChainNodesMatched)
    if (SDNode::hasPredecessorHelper(N, Visited, Worklist, Max, true))
      return SDValue();

  // Return merged chain.
  if (InputChains.size() == 1)
    return InputChains[0];
  return CurDAG->getNode(ISD::TokenFactor, SDLoc(ChainNodesMatched[0]),
                         MVT::Other, InputChains);
}

/// MorphNode - Handle morphing a node in place for the selector.
SDNode *SelectionDAGISel::
MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,
          ArrayRef<SDValue> Ops, unsigned EmitNodeInfo) {
  // It is possible we're using MorphNodeTo to replace a node with no
  // normal results with one that has a normal result (or we could be
  // adding a chain) and the input could have glue and chains as well.
  // In this case we need to shift the operands down.
  // FIXME: This is a horrible hack and broken in obscure cases, no worse
  // than the old isel though.
  int OldGlueResultNo = -1, OldChainResultNo = -1;

  unsigned NTMNumResults = Node->getNumValues();
  if (Node->getValueType(NTMNumResults-1) == MVT::Glue) {
    OldGlueResultNo = NTMNumResults-1;
    if (NTMNumResults != 1 &&
        Node->getValueType(NTMNumResults-2) == MVT::Other)
      OldChainResultNo = NTMNumResults-2;
  } else if (Node->getValueType(NTMNumResults-1) == MVT::Other)
    OldChainResultNo = NTMNumResults-1;

  // Call the underlying SelectionDAG routine to do the transmogrification. Note
  // that this deletes operands of the old node that become dead.
  SDNode *Res = CurDAG->MorphNodeTo(Node, ~TargetOpc, VTList, Ops);

  // MorphNodeTo can operate in two ways: if an existing node with the
  // specified operands exists, it can just return it.  Otherwise, it
  // updates the node in place to have the requested operands.
  if (Res == Node) {
    // If we updated the node in place, reset the node ID.  To the isel,
    // this should be just like a newly allocated machine node.
    Res->setNodeId(-1);
  }

  unsigned ResNumResults = Res->getNumValues();
  // Move the glue if needed.
  if ((EmitNodeInfo & OPFL_GlueOutput) && OldGlueResultNo != -1 &&
      static_cast<unsigned>(OldGlueResultNo) != ResNumResults - 1)
    ReplaceUses(SDValue(Node, OldGlueResultNo),
                SDValue(Res, ResNumResults - 1));

  if ((EmitNodeInfo & OPFL_GlueOutput) != 0)
    --ResNumResults;

  // Move the chain reference if needed.
  if ((EmitNodeInfo & OPFL_Chain) && OldChainResultNo != -1 &&
      static_cast<unsigned>(OldChainResultNo) != ResNumResults - 1)
    ReplaceUses(SDValue(Node, OldChainResultNo),
                SDValue(Res, ResNumResults - 1));

  // Otherwise, no replacement happened because the node already exists. Replace
  // Uses of the old node with the new one.
  if (Res != Node) {
    ReplaceNode(Node, Res);
  } else {
    EnforceNodeIdInvariant(Res);
  }

  return Res;
}

/// CheckSame - Implements OP_CheckSame.
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
          const SmallVectorImpl<std::pair<SDValue, SDNode *>> &RecordedNodes) {
  // Accept if it is exactly the same as a previously recorded node.
  unsigned RecNo = MatcherTable[MatcherIndex++];
  assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
  return N == RecordedNodes[RecNo].first;
}

/// CheckChildSame - Implements OP_CheckChildXSame.
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckChildSame(
    const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
    const SmallVectorImpl<std::pair<SDValue, SDNode *>> &RecordedNodes,
    unsigned ChildNo) {
  if (ChildNo >= N.getNumOperands())
    return false;  // Match fails if out of range child #.
  return ::CheckSame(MatcherTable, MatcherIndex, N.getOperand(ChildNo),
                     RecordedNodes);
}

/// CheckPatternPredicate - Implements OP_CheckPatternPredicate.
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckPatternPredicate(unsigned Opcode, const unsigned char *MatcherTable,
                      unsigned &MatcherIndex, const SelectionDAGISel &SDISel) {
  bool TwoBytePredNo =
      Opcode == SelectionDAGISel::OPC_CheckPatternPredicateTwoByte;
  unsigned PredNo =
      TwoBytePredNo || Opcode == SelectionDAGISel::OPC_CheckPatternPredicate
          ? MatcherTable[MatcherIndex++]
          : Opcode - SelectionDAGISel::OPC_CheckPatternPredicate0;
  if (TwoBytePredNo)
    PredNo |= MatcherTable[MatcherIndex++] << 8;
  return SDISel.CheckPatternPredicate(PredNo);
}

/// CheckNodePredicate - Implements OP_CheckNodePredicate.
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckNodePredicate(unsigned Opcode, const unsigned char *MatcherTable,
                   unsigned &MatcherIndex, const SelectionDAGISel &SDISel,
                   SDNode *N) {
  unsigned PredNo = Opcode == SelectionDAGISel::OPC_CheckPredicate
                        ? MatcherTable[MatcherIndex++]
                        : Opcode - SelectionDAGISel::OPC_CheckPredicate0;
  return SDISel.CheckNodePredicate(N, PredNo);
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
            SDNode *N) {
  uint16_t Opc = MatcherTable[MatcherIndex++];
  Opc |= static_cast<uint16_t>(MatcherTable[MatcherIndex++]) << 8;
  return N->getOpcode() == Opc;
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckType(MVT::SimpleValueType VT,
                                                   SDValue N,
                                                   const TargetLowering *TLI,
                                                   const DataLayout &DL) {
  if (N.getValueType() == VT)
    return true;

  // Handle the case when VT is iPTR.
  return VT == MVT::iPTR && N.getValueType() == TLI->getPointerTy(DL);
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckChildType(MVT::SimpleValueType VT, SDValue N, const TargetLowering *TLI,
               const DataLayout &DL, unsigned ChildNo) {
  if (ChildNo >= N.getNumOperands())
    return false; // Match fails if out of range child #.
  return ::CheckType(VT, N.getOperand(ChildNo), TLI, DL);
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckCondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
              SDValue N) {
  return cast<CondCodeSDNode>(N)->get() ==
         static_cast<ISD::CondCode>(MatcherTable[MatcherIndex++]);
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckChild2CondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
                    SDValue N) {
  if (2 >= N.getNumOperands())
    return false;
  return ::CheckCondCode(MatcherTable, MatcherIndex, N.getOperand(2));
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
               SDValue N, const TargetLowering *TLI, const DataLayout &DL) {
  MVT::SimpleValueType VT = getSimpleVT(MatcherTable, MatcherIndex);
  if (cast<VTSDNode>(N)->getVT() == VT)
    return true;

  // Handle the case when VT is iPTR.
  return VT == MVT::iPTR && cast<VTSDNode>(N)->getVT() == TLI->getPointerTy(DL);
}

// Bit 0 stores the sign of the immediate. The upper bits contain the magnitude
// shifted left by 1.
static uint64_t decodeSignRotatedValue(uint64_t V) {
  if ((V & 1) == 0)
    return V >> 1;
  if (V != 1)
    return -(V >> 1);
  // There is no such thing as -0 with integers.  "-0" really means MININT.
  return 1ULL << 63;
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
             SDValue N) {
  int64_t Val = MatcherTable[MatcherIndex++];
  if (Val & 128)
    Val = GetVBR(Val, MatcherTable, MatcherIndex);

  Val = decodeSignRotatedValue(Val);

  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N);
  return C && C->getAPIntValue().trySExtValue() == Val;
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckChildInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex,
                  SDValue N, unsigned ChildNo) {
  if (ChildNo >= N.getNumOperands())
    return false;  // Match fails if out of range child #.
  return ::CheckInteger(MatcherTable, MatcherIndex, N.getOperand(ChildNo));
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckAndImm(const unsigned char *MatcherTable, unsigned &MatcherIndex,
            SDValue N, const SelectionDAGISel &SDISel) {
  int64_t Val = MatcherTable[MatcherIndex++];
  if (Val & 128)
    Val = GetVBR(Val, MatcherTable, MatcherIndex);

  if (N->getOpcode() != ISD::AND) return false;

  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
  return C && SDISel.CheckAndMask(N.getOperand(0), C, Val);
}

LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckOrImm(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
           const SelectionDAGISel &SDISel) {
  int64_t Val = MatcherTable[MatcherIndex++];
  if (Val & 128)
    Val = GetVBR(Val, MatcherTable, MatcherIndex);

  if (N->getOpcode() != ISD::OR) return false;

  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
  return C && SDISel.CheckOrMask(N.getOperand(0), C, Val);
}

/// IsPredicateKnownToFail - If we know how and can do so without pushing a
/// scope, evaluate the current node.  If the current predicate is known to
/// fail, set Result=true and return anything.  If the current predicate is
/// known to pass, set Result=false and return the MatcherIndex to continue
/// with.  If the current predicate is unknown, set Result=false and return the
/// MatcherIndex to continue with.
static unsigned IsPredicateKnownToFail(const unsigned char *Table,
                                       unsigned Index, SDValue N,
                                       bool &Result,
                                       const SelectionDAGISel &SDISel,
                  SmallVectorImpl<std::pair<SDValue, SDNode*>> &RecordedNodes) {
  unsigned Opcode = Table[Index++];
  switch (Opcode) {
  default:
    Result = false;
    return Index-1;  // Could not evaluate this predicate.
  case SelectionDAGISel::OPC_CheckSame:
    Result = !::CheckSame(Table, Index, N, RecordedNodes);
    return Index;
  case SelectionDAGISel::OPC_CheckChild0Same:
  case SelectionDAGISel::OPC_CheckChild1Same:
  case SelectionDAGISel::OPC_CheckChild2Same:
  case SelectionDAGISel::OPC_CheckChild3Same:
    Result = !::CheckChildSame(Table, Index, N, RecordedNodes,
                        Table[Index-1] - SelectionDAGISel::OPC_CheckChild0Same);
    return Index;
  case SelectionDAGISel::OPC_CheckPatternPredicate:
  case SelectionDAGISel::OPC_CheckPatternPredicate0:
  case SelectionDAGISel::OPC_CheckPatternPredicate1:
  case SelectionDAGISel::OPC_CheckPatternPredicate2:
  case SelectionDAGISel::OPC_CheckPatternPredicate3:
  case SelectionDAGISel::OPC_CheckPatternPredicate4:
  case SelectionDAGISel::OPC_CheckPatternPredicate5:
  case SelectionDAGISel::OPC_CheckPatternPredicate6:
  case SelectionDAGISel::OPC_CheckPatternPredicate7:
  case SelectionDAGISel::OPC_CheckPatternPredicateTwoByte:
    Result = !::CheckPatternPredicate(Opcode, Table, Index, SDISel);
    return Index;
  case SelectionDAGISel::OPC_CheckPredicate:
  case SelectionDAGISel::OPC_CheckPredicate0:
  case SelectionDAGISel::OPC_CheckPredicate1:
  case SelectionDAGISel::OPC_CheckPredicate2:
  case SelectionDAGISel::OPC_CheckPredicate3:
  case SelectionDAGISel::OPC_CheckPredicate4:
  case SelectionDAGISel::OPC_CheckPredicate5:
  case SelectionDAGISel::OPC_CheckPredicate6:
  case SelectionDAGISel::OPC_CheckPredicate7:
    Result = !::CheckNodePredicate(Opcode, Table, Index, SDISel, N.getNode());
    return Index;
  case SelectionDAGISel::OPC_CheckOpcode:
    Result = !::CheckOpcode(Table, Index, N.getNode());
    return Index;
  case SelectionDAGISel::OPC_CheckType:
  case SelectionDAGISel::OPC_CheckTypeI32:
  case SelectionDAGISel::OPC_CheckTypeI64: {
    MVT::SimpleValueType VT;
    switch (Opcode) {
    case SelectionDAGISel::OPC_CheckTypeI32:
      VT = MVT::i32;
      break;
    case SelectionDAGISel::OPC_CheckTypeI64:
      VT = MVT::i64;
      break;
    default:
      VT = getSimpleVT(Table, Index);
      break;
    }
    Result = !::CheckType(VT, N, SDISel.TLI, SDISel.CurDAG->getDataLayout());
    return Index;
  }
  case SelectionDAGISel::OPC_CheckTypeRes: {
    unsigned Res = Table[Index++];
    Result = !::CheckType(getSimpleVT(Table, Index), N.getValue(Res),
                          SDISel.TLI, SDISel.CurDAG->getDataLayout());
    return Index;
  }
  case SelectionDAGISel::OPC_CheckChild0Type:
  case SelectionDAGISel::OPC_CheckChild1Type:
  case SelectionDAGISel::OPC_CheckChild2Type:
  case SelectionDAGISel::OPC_CheckChild3Type:
  case SelectionDAGISel::OPC_CheckChild4Type:
  case SelectionDAGISel::OPC_CheckChild5Type:
  case SelectionDAGISel::OPC_CheckChild6Type:
  case SelectionDAGISel::OPC_CheckChild7Type:
  case SelectionDAGISel::OPC_CheckChild0TypeI32:
  case SelectionDAGISel::OPC_CheckChild1TypeI32:
  case SelectionDAGISel::OPC_CheckChild2TypeI32:
  case SelectionDAGISel::OPC_CheckChild3TypeI32:
  case SelectionDAGISel::OPC_CheckChild4TypeI32:
  case SelectionDAGISel::OPC_CheckChild5TypeI32:
  case SelectionDAGISel::OPC_CheckChild6TypeI32:
  case SelectionDAGISel::OPC_CheckChild7TypeI32:
  case SelectionDAGISel::OPC_CheckChild0TypeI64:
  case SelectionDAGISel::OPC_CheckChild1TypeI64:
  case SelectionDAGISel::OPC_CheckChild2TypeI64:
  case SelectionDAGISel::OPC_CheckChild3TypeI64:
  case SelectionDAGISel::OPC_CheckChild4TypeI64:
  case SelectionDAGISel::OPC_CheckChild5TypeI64:
  case SelectionDAGISel::OPC_CheckChild6TypeI64:
  case SelectionDAGISel::OPC_CheckChild7TypeI64: {
    MVT::SimpleValueType VT;
    unsigned ChildNo;
    if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI32 &&
        Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI32) {
      VT = MVT::i32;
      ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI32;
    } else if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI64 &&
               Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI64) {
      VT = MVT::i64;
      ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI64;
    } else {
      VT = getSimpleVT(Table, Index);
      ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0Type;
    }
    Result = !::CheckChildType(VT, N, SDISel.TLI,
                               SDISel.CurDAG->getDataLayout(), ChildNo);
    return Index;
  }
  case SelectionDAGISel::OPC_CheckCondCode:
    Result = !::CheckCondCode(Table, Index, N);
    return Index;
  case SelectionDAGISel::OPC_CheckChild2CondCode:
    Result = !::CheckChild2CondCode(Table, Index, N);
    return Index;
  case SelectionDAGISel::OPC_CheckValueType:
    Result = !::CheckValueType(Table, Index, N, SDISel.TLI,
                               SDISel.CurDAG->getDataLayout());
    return Index;
  case SelectionDAGISel::OPC_CheckInteger:
    Result = !::CheckInteger(Table, Index, N);
    return Index;
  case SelectionDAGISel::OPC_CheckChild0Integer:
  case SelectionDAGISel::OPC_CheckChild1Integer:
  case SelectionDAGISel::OPC_CheckChild2Integer:
  case SelectionDAGISel::OPC_CheckChild3Integer:
  case SelectionDAGISel::OPC_CheckChild4Integer:
    Result = !::CheckChildInteger(Table, Index, N,
                     Table[Index-1] - SelectionDAGISel::OPC_CheckChild0Integer);
    return Index;
  case SelectionDAGISel::OPC_CheckAndImm:
    Result = !::CheckAndImm(Table, Index, N, SDISel);
    return Index;
  case SelectionDAGISel::OPC_CheckOrImm:
    Result = !::CheckOrImm(Table, Index, N, SDISel);
    return Index;
  }
}

namespace {

struct MatchScope {
  /// FailIndex - If this match fails, this is the index to continue with.
  unsigned FailIndex;

  /// NodeStack - The node stack when the scope was formed.
  SmallVector<SDValue, 4> NodeStack;

  /// NumRecordedNodes - The number of recorded nodes when the scope was formed.
  unsigned NumRecordedNodes;

  /// NumMatchedMemRefs - The number of matched memref entries.
  unsigned NumMatchedMemRefs;

  /// InputChain/InputGlue - The current chain/glue
  SDValue InputChain, InputGlue;

  /// HasChainNodesMatched - True if the ChainNodesMatched list is non-empty.
  bool HasChainNodesMatched;
};

/// \A DAG update listener to keep the matching state
/// (i.e. RecordedNodes and MatchScope) uptodate if the target is allowed to
/// change the DAG while matching.  X86 addressing mode matcher is an example
/// for this.
class MatchStateUpdater : public SelectionDAG::DAGUpdateListener
{
  SDNode **NodeToMatch;
  SmallVectorImpl<std::pair<SDValue, SDNode *>> &RecordedNodes;
  SmallVectorImpl<MatchScope> &MatchScopes;

public:
  MatchStateUpdater(SelectionDAG &DAG, SDNode **NodeToMatch,
                    SmallVectorImpl<std::pair<SDValue, SDNode *>> &RN,
                    SmallVectorImpl<MatchScope> &MS)
      : SelectionDAG::DAGUpdateListener(DAG), NodeToMatch(NodeToMatch),
        RecordedNodes(RN), MatchScopes(MS) {}

  void NodeDeleted(SDNode *N, SDNode *E) override {
    // Some early-returns here to avoid the search if we deleted the node or
    // if the update comes from MorphNodeTo (MorphNodeTo is the last thing we
    // do, so it's unnecessary to update matching state at that point).
    // Neither of these can occur currently because we only install this
    // update listener during matching a complex patterns.
    if (!E || E->isMachineOpcode())
      return;
    // Check if NodeToMatch was updated.
    if (N == *NodeToMatch)
      *NodeToMatch = E;
    // Performing linear search here does not matter because we almost never
    // run this code.  You'd have to have a CSE during complex pattern
    // matching.
    for (auto &I : RecordedNodes)
      if (I.first.getNode() == N)
        I.first.setNode(E);

    for (auto &I : MatchScopes)
      for (auto &J : I.NodeStack)
        if (J.getNode() == N)
          J.setNode(E);
  }
};

} // end anonymous namespace

void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
                                        const unsigned char *MatcherTable,
                                        unsigned TableSize) {
  // FIXME: Should these even be selected?  Handle these cases in the caller?
  switch (NodeToMatch->getOpcode()) {
  default:
    break;
  case ISD::EntryToken:       // These nodes remain the same.
  case ISD::BasicBlock:
  case ISD::Register:
  case ISD::RegisterMask:
  case ISD::HANDLENODE:
  case ISD::MDNODE_SDNODE:
  case ISD::TargetConstant:
  case ISD::TargetConstantFP:
  case ISD::TargetConstantPool:
  case ISD::TargetFrameIndex:
  case ISD::TargetExternalSymbol:
  case ISD::MCSymbol:
  case ISD::TargetBlockAddress:
  case ISD::TargetJumpTable:
  case ISD::TargetGlobalTLSAddress:
  case ISD::TargetGlobalAddress:
  case ISD::TokenFactor:
  case ISD::CopyFromReg:
  case ISD::CopyToReg:
  case ISD::EH_LABEL:
  case ISD::ANNOTATION_LABEL:
  case ISD::LIFETIME_START:
  case ISD::LIFETIME_END:
  case ISD::PSEUDO_PROBE:
    NodeToMatch->setNodeId(-1); // Mark selected.
    return;
  case ISD::AssertSext:
  case ISD::AssertZext:
  case ISD::AssertAlign:
    ReplaceUses(SDValue(NodeToMatch, 0), NodeToMatch->getOperand(0));
    CurDAG->RemoveDeadNode(NodeToMatch);
    return;
  case ISD::INLINEASM:
  case ISD::INLINEASM_BR:
    Select_INLINEASM(NodeToMatch);
    return;
  case ISD::READ_REGISTER:
    Select_READ_REGISTER(NodeToMatch);
    return;
  case ISD::WRITE_REGISTER:
    Select_WRITE_REGISTER(NodeToMatch);
    return;
  case ISD::UNDEF:
    Select_UNDEF(NodeToMatch);
    return;
  case ISD::FAKE_USE:
    Select_FAKE_USE(NodeToMatch);
    return;
  case ISD::FREEZE:
    Select_FREEZE(NodeToMatch);
    return;
  case ISD::ARITH_FENCE:
    Select_ARITH_FENCE(NodeToMatch);
    return;
  case ISD::MEMBARRIER:
    Select_MEMBARRIER(NodeToMatch);
    return;
  case ISD::STACKMAP:
    Select_STACKMAP(NodeToMatch);
    return;
  case ISD::PATCHPOINT:
    Select_PATCHPOINT(NodeToMatch);
    return;
  case ISD::JUMP_TABLE_DEBUG_INFO:
    Select_JUMP_TABLE_DEBUG_INFO(NodeToMatch);
    return;
  case ISD::CONVERGENCECTRL_ANCHOR:
    Select_CONVERGENCECTRL_ANCHOR(NodeToMatch);
    return;
  case ISD::CONVERGENCECTRL_ENTRY:
    Select_CONVERGENCECTRL_ENTRY(NodeToMatch);
    return;
  case ISD::CONVERGENCECTRL_LOOP:
    Select_CONVERGENCECTRL_LOOP(NodeToMatch);
    return;
  }

  assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");

  // Set up the node stack with NodeToMatch as the only node on the stack.
  SmallVector<SDValue, 8> NodeStack;
  SDValue N = SDValue(NodeToMatch, 0);
  NodeStack.push_back(N);

  // MatchScopes - Scopes used when matching, if a match failure happens, this
  // indicates where to continue checking.
  SmallVector<MatchScope, 8> MatchScopes;

  // RecordedNodes - This is the set of nodes that have been recorded by the
  // state machine.  The second value is the parent of the node, or null if the
  // root is recorded.
  SmallVector<std::pair<SDValue, SDNode*>, 8> RecordedNodes;

  // MatchedMemRefs - This is the set of MemRef's we've seen in the input
  // pattern.
  SmallVector<MachineMemOperand*, 2> MatchedMemRefs;

  // These are the current input chain and glue for use when generating nodes.
  // Various Emit operations change these.  For example, emitting a copytoreg
  // uses and updates these.
  SDValue InputChain, InputGlue;

  // ChainNodesMatched - If a pattern matches nodes that have input/output
  // chains, the OPC_EmitMergeInputChains operation is emitted which indicates
  // which ones they are.  The result is captured into this list so that we can
  // update the chain results when the pattern is complete.
  SmallVector<SDNode*, 3> ChainNodesMatched;

  LLVM_DEBUG(dbgs() << "ISEL: Starting pattern match\n");

  // Determine where to start the interpreter.  Normally we start at opcode #0,
  // but if the state machine starts with an OPC_SwitchOpcode, then we
  // accelerate the first lookup (which is guaranteed to be hot) with the
  // OpcodeOffset table.
  unsigned MatcherIndex = 0;

  if (!OpcodeOffset.empty()) {
    // Already computed the OpcodeOffset table, just index into it.
    if (N.getOpcode() < OpcodeOffset.size())
      MatcherIndex = OpcodeOffset[N.getOpcode()];
    LLVM_DEBUG(dbgs() << "  Initial Opcode index to " << MatcherIndex << "\n");

  } else if (MatcherTable[0] == OPC_SwitchOpcode) {
    // Otherwise, the table isn't computed, but the state machine does start
    // with an OPC_SwitchOpcode instruction.  Populate the table now, since this
    // is the first time we're selecting an instruction.
    unsigned Idx = 1;
    while (true) {
      // Get the size of this case.
      unsigned CaseSize = MatcherTable[Idx++];
      if (CaseSize & 128)
        CaseSize = GetVBR(CaseSize, MatcherTable, Idx);
      if (CaseSize == 0) break;

      // Get the opcode, add the index to the table.
      uint16_t Opc = MatcherTable[Idx++];
      Opc |= static_cast<uint16_t>(MatcherTable[Idx++]) << 8;
      if (Opc >= OpcodeOffset.size())
        OpcodeOffset.resize((Opc+1)*2);
      OpcodeOffset[Opc] = Idx;
      Idx += CaseSize;
    }

    // Okay, do the lookup for the first opcode.
    if (N.getOpcode() < OpcodeOffset.size())
      MatcherIndex = OpcodeOffset[N.getOpcode()];
  }

  while (true) {
    assert(MatcherIndex < TableSize && "Invalid index");
#ifndef NDEBUG
    unsigned CurrentOpcodeIndex = MatcherIndex;
#endif
    BuiltinOpcodes Opcode =
        static_cast<BuiltinOpcodes>(MatcherTable[MatcherIndex++]);
    switch (Opcode) {
    case OPC_Scope: {
      // Okay, the semantics of this operation are that we should push a scope
      // then evaluate the first child.  However, pushing a scope only to have
      // the first check fail (which then pops it) is inefficient.  If we can
      // determine immediately that the first check (or first several) will
      // immediately fail, don't even bother pushing a scope for them.
      unsigned FailIndex;

      while (true) {
        unsigned NumToSkip = MatcherTable[MatcherIndex++];
        if (NumToSkip & 128)
          NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex);
        // Found the end of the scope with no match.
        if (NumToSkip == 0) {
          FailIndex = 0;
          break;
        }

        FailIndex = MatcherIndex+NumToSkip;

        unsigned MatcherIndexOfPredicate = MatcherIndex;
        (void)MatcherIndexOfPredicate; // silence warning.

        // If we can't evaluate this predicate without pushing a scope (e.g. if
        // it is a 'MoveParent') or if the predicate succeeds on this node, we
        // push the scope and evaluate the full predicate chain.
        bool Result;
        MatcherIndex = IsPredicateKnownToFail(MatcherTable, MatcherIndex, N,
                                              Result, *this, RecordedNodes);
        if (!Result)
          break;

        LLVM_DEBUG(
            dbgs() << "  Skipped scope entry (due to false predicate) at "
                   << "index " << MatcherIndexOfPredicate << ", continuing at "
                   << FailIndex << "\n");
        ++NumDAGIselRetries;

        // Otherwise, we know that this case of the Scope is guaranteed to fail,
        // move to the next case.
        MatcherIndex = FailIndex;
      }

      // If the whole scope failed to match, bail.
      if (FailIndex == 0) break;

      // Push a MatchScope which indicates where to go if the first child fails
      // to match.
      MatchScope NewEntry;
      NewEntry.FailIndex = FailIndex;
      NewEntry.NodeStack.append(NodeStack.begin(), NodeStack.end());
      NewEntry.NumRecordedNodes = RecordedNodes.size();
      NewEntry.NumMatchedMemRefs = MatchedMemRefs.size();
      NewEntry.InputChain = InputChain;
      NewEntry.InputGlue = InputGlue;
      NewEntry.HasChainNodesMatched = !ChainNodesMatched.empty();
      MatchScopes.push_back(NewEntry);
      continue;
    }
    case OPC_RecordNode: {
      // Remember this node, it may end up being an operand in the pattern.
      SDNode *Parent = nullptr;
      if (NodeStack.size() > 1)
        Parent = NodeStack[NodeStack.size()-2].getNode();
      RecordedNodes.push_back(std::make_pair(N, Parent));
      continue;
    }

    case OPC_RecordChild0: case OPC_RecordChild1:
    case OPC_RecordChild2: case OPC_RecordChild3:
    case OPC_RecordChild4: case OPC_RecordChild5:
    case OPC_RecordChild6: case OPC_RecordChild7: {
      unsigned ChildNo = Opcode-OPC_RecordChild0;
      if (ChildNo >= N.getNumOperands())
        break;  // Match fails if out of range child #.

      RecordedNodes.push_back(std::make_pair(N->getOperand(ChildNo),
                                             N.getNode()));
      continue;
    }
    case OPC_RecordMemRef:
      if (auto *MN = dyn_cast<MemSDNode>(N))
        MatchedMemRefs.push_back(MN->getMemOperand());
      else {
        LLVM_DEBUG(dbgs() << "Expected MemSDNode "; N->dump(CurDAG);
                   dbgs() << '\n');
      }

      continue;

    case OPC_CaptureGlueInput:
      // If the current node has an input glue, capture it in InputGlue.
      if (N->getNumOperands() != 0 &&
          N->getOperand(N->getNumOperands()-1).getValueType() == MVT::Glue)
        InputGlue = N->getOperand(N->getNumOperands()-1);
      continue;

    case OPC_MoveChild: {
      unsigned ChildNo = MatcherTable[MatcherIndex++];
      if (ChildNo >= N.getNumOperands())
        break;  // Match fails if out of range child #.
      N = N.getOperand(ChildNo);
      NodeStack.push_back(N);
      continue;
    }

    case OPC_MoveChild0: case OPC_MoveChild1:
    case OPC_MoveChild2: case OPC_MoveChild3:
    case OPC_MoveChild4: case OPC_MoveChild5:
    case OPC_MoveChild6: case OPC_MoveChild7: {
      unsigned ChildNo = Opcode-OPC_MoveChild0;
      if (ChildNo >= N.getNumOperands())
        break;  // Match fails if out of range child #.
      N = N.getOperand(ChildNo);
      NodeStack.push_back(N);
      continue;
    }

    case OPC_MoveSibling:
    case OPC_MoveSibling0:
    case OPC_MoveSibling1:
    case OPC_MoveSibling2:
    case OPC_MoveSibling3:
    case OPC_MoveSibling4:
    case OPC_MoveSibling5:
    case OPC_MoveSibling6:
    case OPC_MoveSibling7: {
      // Pop the current node off the NodeStack.
      NodeStack.pop_back();
      assert(!NodeStack.empty() && "Node stack imbalance!");
      N = NodeStack.back();

      unsigned SiblingNo = Opcode == OPC_MoveSibling
                               ? MatcherTable[MatcherIndex++]
                               : Opcode - OPC_MoveSibling0;
      if (SiblingNo >= N.getNumOperands())
        break; // Match fails if out of range sibling #.
      N = N.getOperand(SiblingNo);
      NodeStack.push_back(N);
      continue;
    }
    case OPC_MoveParent:
      // Pop the current node off the NodeStack.
      NodeStack.pop_back();
      assert(!NodeStack.empty() && "Node stack imbalance!");
      N = NodeStack.back();
      continue;

    case OPC_CheckSame:
      if (!::CheckSame(MatcherTable, MatcherIndex, N, RecordedNodes)) break;
      continue;

    case OPC_CheckChild0Same: case OPC_CheckChild1Same:
    case OPC_CheckChild2Same: case OPC_CheckChild3Same:
      if (!::CheckChildSame(MatcherTable, MatcherIndex, N, RecordedNodes,
                            Opcode-OPC_CheckChild0Same))
        break;
      continue;

    case OPC_CheckPatternPredicate:
    case OPC_CheckPatternPredicate0:
    case OPC_CheckPatternPredicate1:
    case OPC_CheckPatternPredicate2:
    case OPC_CheckPatternPredicate3:
    case OPC_CheckPatternPredicate4:
    case OPC_CheckPatternPredicate5:
    case OPC_CheckPatternPredicate6:
    case OPC_CheckPatternPredicate7:
    case OPC_CheckPatternPredicateTwoByte:
      if (!::CheckPatternPredicate(Opcode, MatcherTable, MatcherIndex, *this))
        break;
      continue;
    case SelectionDAGISel::OPC_CheckPredicate0:
    case SelectionDAGISel::OPC_CheckPredicate1:
    case SelectionDAGISel::OPC_CheckPredicate2:
    case SelectionDAGISel::OPC_CheckPredicate3:
    case SelectionDAGISel::OPC_CheckPredicate4:
    case SelectionDAGISel::OPC_CheckPredicate5:
    case SelectionDAGISel::OPC_CheckPredicate6:
    case SelectionDAGISel::OPC_CheckPredicate7:
    case OPC_CheckPredicate:
      if (!::CheckNodePredicate(Opcode, MatcherTable, MatcherIndex, *this,
                                N.getNode()))
        break;
      continue;
    case OPC_CheckPredicateWithOperands: {
      unsigned OpNum = MatcherTable[MatcherIndex++];
      SmallVector<SDValue, 8> Operands;

      for (unsigned i = 0; i < OpNum; ++i)
        Operands.push_back(RecordedNodes[MatcherTable[MatcherIndex++]].first);

      unsigned PredNo = MatcherTable[MatcherIndex++];
      if (!CheckNodePredicateWithOperands(N.getNode(), PredNo, Operands))
        break;
      continue;
    }
    case OPC_CheckComplexPat:
    case OPC_CheckComplexPat0:
    case OPC_CheckComplexPat1:
    case OPC_CheckComplexPat2:
    case OPC_CheckComplexPat3:
    case OPC_CheckComplexPat4:
    case OPC_CheckComplexPat5:
    case OPC_CheckComplexPat6:
    case OPC_CheckComplexPat7: {
      unsigned CPNum = Opcode == OPC_CheckComplexPat
                           ? MatcherTable[MatcherIndex++]
                           : Opcode - OPC_CheckComplexPat0;
      unsigned RecNo = MatcherTable[MatcherIndex++];
      assert(RecNo < RecordedNodes.size() && "Invalid CheckComplexPat");

      // If target can modify DAG during matching, keep the matching state
      // consistent.
      std::unique_ptr<MatchStateUpdater> MSU;
      if (ComplexPatternFuncMutatesDAG())
        MSU.reset(new MatchStateUpdater(*CurDAG, &NodeToMatch, RecordedNodes,
                                        MatchScopes));

      if (!CheckComplexPattern(NodeToMatch, RecordedNodes[RecNo].second,
                               RecordedNodes[RecNo].first, CPNum,
                               RecordedNodes))
        break;
      continue;
    }
    case OPC_CheckOpcode:
      if (!::CheckOpcode(MatcherTable, MatcherIndex, N.getNode())) break;
      continue;

    case OPC_CheckType:
    case OPC_CheckTypeI32:
    case OPC_CheckTypeI64:
      MVT::SimpleValueType VT;
      switch (Opcode) {
      case OPC_CheckTypeI32:
        VT = MVT::i32;
        break;
      case OPC_CheckTypeI64:
        VT = MVT::i64;
        break;
      default:
        VT = getSimpleVT(MatcherTable, MatcherIndex);
        break;
      }
      if (!::CheckType(VT, N, TLI, CurDAG->getDataLayout()))
        break;
      continue;

    case OPC_CheckTypeRes: {
      unsigned Res = MatcherTable[MatcherIndex++];
      if (!::CheckType(getSimpleVT(MatcherTable, MatcherIndex), N.getValue(Res),
                       TLI, CurDAG->getDataLayout()))
        break;
      continue;
    }

    case OPC_SwitchOpcode: {
      unsigned CurNodeOpcode = N.getOpcode();
      unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart;
      unsigned CaseSize;
      while (true) {
        // Get the size of this case.
        CaseSize = MatcherTable[MatcherIndex++];
        if (CaseSize & 128)
          CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex);
        if (CaseSize == 0) break;

        uint16_t Opc = MatcherTable[MatcherIndex++];
        Opc |= static_cast<uint16_t>(MatcherTable[MatcherIndex++]) << 8;

        // If the opcode matches, then we will execute this case.
        if (CurNodeOpcode == Opc)
          break;

        // Otherwise, skip over this case.
        MatcherIndex += CaseSize;
      }

      // If no cases matched, bail out.
      if (CaseSize == 0) break;

      // Otherwise, execute the case we found.
      LLVM_DEBUG(dbgs() << "  OpcodeSwitch from " << SwitchStart << " to "
                        << MatcherIndex << "\n");
      continue;
    }

    case OPC_SwitchType: {
      MVT CurNodeVT = N.getSimpleValueType();
      unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart;
      unsigned CaseSize;
      while (true) {
        // Get the size of this case.
        CaseSize = MatcherTable[MatcherIndex++];
        if (CaseSize & 128)
          CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex);
        if (CaseSize == 0) break;

        MVT CaseVT = getSimpleVT(MatcherTable, MatcherIndex);
        if (CaseVT == MVT::iPTR)
          CaseVT = TLI->getPointerTy(CurDAG->getDataLayout());

        // If the VT matches, then we will execute this case.
        if (CurNodeVT == CaseVT)
          break;

        // Otherwise, skip over this case.
        MatcherIndex += CaseSize;
      }

      // If no cases matched, bail out.
      if (CaseSize == 0) break;

      // Otherwise, execute the case we found.
      LLVM_DEBUG(dbgs() << "  TypeSwitch[" << CurNodeVT
                        << "] from " << SwitchStart << " to " << MatcherIndex
                        << '\n');
      continue;
    }
    case OPC_CheckChild0Type:
    case OPC_CheckChild1Type:
    case OPC_CheckChild2Type:
    case OPC_CheckChild3Type:
    case OPC_CheckChild4Type:
    case OPC_CheckChild5Type:
    case OPC_CheckChild6Type:
    case OPC_CheckChild7Type:
    case OPC_CheckChild0TypeI32:
    case OPC_CheckChild1TypeI32:
    case OPC_CheckChild2TypeI32:
    case OPC_CheckChild3TypeI32:
    case OPC_CheckChild4TypeI32:
    case OPC_CheckChild5TypeI32:
    case OPC_CheckChild6TypeI32:
    case OPC_CheckChild7TypeI32:
    case OPC_CheckChild0TypeI64:
    case OPC_CheckChild1TypeI64:
    case OPC_CheckChild2TypeI64:
    case OPC_CheckChild3TypeI64:
    case OPC_CheckChild4TypeI64:
    case OPC_CheckChild5TypeI64:
    case OPC_CheckChild6TypeI64:
    case OPC_CheckChild7TypeI64: {
      MVT::SimpleValueType VT;
      unsigned ChildNo;
      if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI32 &&
          Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI32) {
        VT = MVT::i32;
        ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI32;
      } else if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI64 &&
                 Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI64) {
        VT = MVT::i64;
        ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI64;
      } else {
        VT = getSimpleVT(MatcherTable, MatcherIndex);
        ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0Type;
      }
      if (!::CheckChildType(VT, N, TLI, CurDAG->getDataLayout(), ChildNo))
        break;
      continue;
    }
    case OPC_CheckCondCode:
      if (!::CheckCondCode(MatcherTable, MatcherIndex, N)) break;
      continue;
    case OPC_CheckChild2CondCode:
      if (!::CheckChild2CondCode(MatcherTable, MatcherIndex, N)) break;
      continue;
    case OPC_CheckValueType:
      if (!::CheckValueType(MatcherTable, MatcherIndex, N, TLI,
                            CurDAG->getDataLayout()))
        break;
      continue;
    case OPC_CheckInteger:
      if (!::CheckInteger(MatcherTable, MatcherIndex, N)) break;
      continue;
    case OPC_CheckChild0Integer: case OPC_CheckChild1Integer:
    case OPC_CheckChild2Integer: case OPC_CheckChild3Integer:
    case OPC_CheckChild4Integer:
      if (!::CheckChildInteger(MatcherTable, MatcherIndex, N,
                               Opcode-OPC_CheckChild0Integer)) break;
      continue;
    case OPC_CheckAndImm:
      if (!::CheckAndImm(MatcherTable, MatcherIndex, N, *this)) break;
      continue;
    case OPC_CheckOrImm:
      if (!::CheckOrImm(MatcherTable, MatcherIndex, N, *this)) break;
      continue;
    case OPC_CheckImmAllOnesV:
      if (!ISD::isConstantSplatVectorAllOnes(N.getNode()))
        break;
      continue;
    case OPC_CheckImmAllZerosV:
      if (!ISD::isConstantSplatVectorAllZeros(N.getNode()))
        break;
      continue;

    case OPC_CheckFoldableChainNode: {
      assert(NodeStack.size() != 1 && "No parent node");
      // Verify that all intermediate nodes between the root and this one have
      // a single use (ignoring chains, which are handled in UpdateChains).
      bool HasMultipleUses = false;
      for (unsigned i = 1, e = NodeStack.size()-1; i != e; ++i) {
        unsigned NNonChainUses = 0;
        SDNode *NS = NodeStack[i].getNode();
        for (const SDUse &U : NS->uses())
          if (U.getValueType() != MVT::Other)
            if (++NNonChainUses > 1) {
              HasMultipleUses = true;
              break;
            }
        if (HasMultipleUses) break;
      }
      if (HasMultipleUses) break;

      // Check to see that the target thinks this is profitable to fold and that
      // we can fold it without inducing cycles in the graph.
      if (!IsProfitableToFold(N, NodeStack[NodeStack.size()-2].getNode(),
                              NodeToMatch) ||
          !IsLegalToFold(N, NodeStack[NodeStack.size()-2].getNode(),
                         NodeToMatch, OptLevel,
                         true/*We validate our own chains*/))
        break;

      continue;
    }
    case OPC_EmitInteger:
    case OPC_EmitInteger8:
    case OPC_EmitInteger16:
    case OPC_EmitInteger32:
    case OPC_EmitInteger64:
    case OPC_EmitStringInteger:
    case OPC_EmitStringInteger32: {
      MVT::SimpleValueType VT;
      switch (Opcode) {
      case OPC_EmitInteger8:
        VT = MVT::i8;
        break;
      case OPC_EmitInteger16:
        VT = MVT::i16;
        break;
      case OPC_EmitInteger32:
      case OPC_EmitStringInteger32:
        VT = MVT::i32;
        break;
      case OPC_EmitInteger64:
        VT = MVT::i64;
        break;
      default:
        VT = getSimpleVT(MatcherTable, MatcherIndex);
        break;
      }
      int64_t Val = MatcherTable[MatcherIndex++];
      if (Val & 128)
        Val = GetVBR(Val, MatcherTable, MatcherIndex);
      if (Opcode >= OPC_EmitInteger && Opcode <= OPC_EmitInteger64)
        Val = decodeSignRotatedValue(Val);
      RecordedNodes.push_back(std::pair<SDValue, SDNode *>(
          CurDAG->getSignedConstant(Val, SDLoc(NodeToMatch), VT,
                                    /*isTarget=*/true),
          nullptr));
      continue;
    }
    case OPC_EmitRegister:
    case OPC_EmitRegisterI32:
    case OPC_EmitRegisterI64: {
      MVT::SimpleValueType VT;
      switch (Opcode) {
      case OPC_EmitRegisterI32:
        VT = MVT::i32;
        break;
      case OPC_EmitRegisterI64:
        VT = MVT::i64;
        break;
      default:
        VT = getSimpleVT(MatcherTable, MatcherIndex);
        break;
      }
      unsigned RegNo = MatcherTable[MatcherIndex++];
      RecordedNodes.push_back(std::pair<SDValue, SDNode *>(
          CurDAG->getRegister(RegNo, VT), nullptr));
      continue;
    }
    case OPC_EmitRegister2: {
      // For targets w/ more than 256 register names, the register enum
      // values are stored in two bytes in the matcher table (just like
      // opcodes).
      MVT::SimpleValueType VT = getSimpleVT(MatcherTable, MatcherIndex);
      unsigned RegNo = MatcherTable[MatcherIndex++];
      RegNo |= MatcherTable[MatcherIndex++] << 8;
      RecordedNodes.push_back(std::pair<SDValue, SDNode*>(
                              CurDAG->getRegister(RegNo, VT), nullptr));
      continue;
    }

    case OPC_EmitConvertToTarget:
    case OPC_EmitConvertToTarget0:
    case OPC_EmitConvertToTarget1:
    case OPC_EmitConvertToTarget2:
    case OPC_EmitConvertToTarget3:
    case OPC_EmitConvertToTarget4:
    case OPC_EmitConvertToTarget5:
    case OPC_EmitConvertToTarget6:
    case OPC_EmitConvertToTarget7: {
      // Convert from IMM/FPIMM to target version.
      unsigned RecNo = Opcode == OPC_EmitConvertToTarget
                           ? MatcherTable[MatcherIndex++]
                           : Opcode - OPC_EmitConvertToTarget0;
      assert(RecNo < RecordedNodes.size() && "Invalid EmitConvertToTarget");
      SDValue Imm = RecordedNodes[RecNo].first;

      if (Imm->getOpcode() == ISD::Constant) {
        const ConstantInt *Val=cast<ConstantSDNode>(Imm)->getConstantIntValue();
        Imm = CurDAG->getTargetConstant(*Val, SDLoc(NodeToMatch),
                                        Imm.getValueType());
      } else if (Imm->getOpcode() == ISD::ConstantFP) {
        const ConstantFP *Val=cast<ConstantFPSDNode>(Imm)->getConstantFPValue();
        Imm = CurDAG->getTargetConstantFP(*Val, SDLoc(NodeToMatch),
                                          Imm.getValueType());
      }

      RecordedNodes.push_back(std::make_pair(Imm, RecordedNodes[RecNo].second));
      continue;
    }

    case OPC_EmitMergeInputChains1_0:    // OPC_EmitMergeInputChains, 1, 0
    case OPC_EmitMergeInputChains1_1:    // OPC_EmitMergeInputChains, 1, 1
    case OPC_EmitMergeInputChains1_2: {  // OPC_EmitMergeInputChains, 1, 2
      // These are space-optimized forms of OPC_EmitMergeInputChains.
      assert(!InputChain.getNode() &&
             "EmitMergeInputChains should be the first chain producing node");
      assert(ChainNodesMatched.empty() &&
             "Should only have one EmitMergeInputChains per match");

      // Read all of the chained nodes.
      unsigned RecNo = Opcode - OPC_EmitMergeInputChains1_0;
      assert(RecNo < RecordedNodes.size() && "Invalid EmitMergeInputChains");
      ChainNodesMatched.push_back(RecordedNodes[RecNo].first.getNode());

      // If the chained node is not the root, we can't fold it if it has
      // multiple uses.
      // FIXME: What if other value results of the node have uses not matched
      // by this pattern?
      if (ChainNodesMatched.back() != NodeToMatch &&
          !RecordedNodes[RecNo].first.hasOneUse()) {
        ChainNodesMatched.clear();
        break;
      }

      // Merge the input chains if they are not intra-pattern references.
      InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG);

      if (!InputChain.getNode())
        break;  // Failed to merge.
      continue;
    }

    case OPC_EmitMergeInputChains: {
      assert(!InputChain.getNode() &&
             "EmitMergeInputChains should be the first chain producing node");
      // This node gets a list of nodes we matched in the input that have
      // chains.  We want to token factor all of the input chains to these nodes
      // together.  However, if any of the input chains is actually one of the
      // nodes matched in this pattern, then we have an intra-match reference.
      // Ignore these because the newly token factored chain should not refer to
      // the old nodes.
      unsigned NumChains = MatcherTable[MatcherIndex++];
      assert(NumChains != 0 && "Can't TF zero chains");

      assert(ChainNodesMatched.empty() &&
             "Should only have one EmitMergeInputChains per match");

      // Read all of the chained nodes.
      for (unsigned i = 0; i != NumChains; ++i) {
        unsigned RecNo = MatcherTable[MatcherIndex++];
        assert(RecNo < RecordedNodes.size() && "Invalid EmitMergeInputChains");
        ChainNodesMatched.push_back(RecordedNodes[RecNo].first.getNode());

        // If the chained node is not the root, we can't fold it if it has
        // multiple uses.
        // FIXME: What if other value results of the node have uses not matched
        // by this pattern?
        if (ChainNodesMatched.back() != NodeToMatch &&
            !RecordedNodes[RecNo].first.hasOneUse()) {
          ChainNodesMatched.clear();
          break;
        }
      }

      // If the inner loop broke out, the match fails.
      if (ChainNodesMatched.empty())
        break;

      // Merge the input chains if they are not intra-pattern references.
      InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG);

      if (!InputChain.getNode())
        break;  // Failed to merge.

      continue;
    }

    case OPC_EmitCopyToReg:
    case OPC_EmitCopyToReg0:
    case OPC_EmitCopyToReg1:
    case OPC_EmitCopyToReg2:
    case OPC_EmitCopyToReg3:
    case OPC_EmitCopyToReg4:
    case OPC_EmitCopyToReg5:
    case OPC_EmitCopyToReg6:
    case OPC_EmitCopyToReg7:
    case OPC_EmitCopyToRegTwoByte: {
      unsigned RecNo =
          Opcode >= OPC_EmitCopyToReg0 && Opcode <= OPC_EmitCopyToReg7
              ? Opcode - OPC_EmitCopyToReg0
              : MatcherTable[MatcherIndex++];
      assert(RecNo < RecordedNodes.size() && "Invalid EmitCopyToReg");
      unsigned DestPhysReg = MatcherTable[MatcherIndex++];
      if (Opcode == OPC_EmitCopyToRegTwoByte)
        DestPhysReg |= MatcherTable[MatcherIndex++] << 8;

      if (!InputChain.getNode())
        InputChain = CurDAG->getEntryNode();

      InputChain = CurDAG->getCopyToReg(InputChain, SDLoc(NodeToMatch),
                                        DestPhysReg, RecordedNodes[RecNo].first,
                                        InputGlue);

      InputGlue = InputChain.getValue(1);
      continue;
    }

    case OPC_EmitNodeXForm: {
      unsigned XFormNo = MatcherTable[MatcherIndex++];
      unsigned RecNo = MatcherTable[MatcherIndex++];
      assert(RecNo < RecordedNodes.size() && "Invalid EmitNodeXForm");
      SDValue Res = RunSDNodeXForm(RecordedNodes[RecNo].first, XFormNo);
      RecordedNodes.push_back(std::pair<SDValue,SDNode*>(Res, nullptr));
      continue;
    }
    case OPC_Coverage: {
      // This is emitted right before MorphNode/EmitNode.
      // So it should be safe to assume that this node has been selected
      unsigned index = MatcherTable[MatcherIndex++];
      index |= (MatcherTable[MatcherIndex++] << 8);
      index |= (MatcherTable[MatcherIndex++] << 16);
      index |= (MatcherTable[MatcherIndex++] << 24);
      dbgs() << "COVERED: " << getPatternForIndex(index) << "\n";
      dbgs() << "INCLUDED: " << getIncludePathForIndex(index) << "\n";
      continue;
    }

    case OPC_EmitNode:
    case OPC_EmitNode0:
    case OPC_EmitNode1:
    case OPC_EmitNode2:
    case OPC_EmitNode0None:
    case OPC_EmitNode1None:
    case OPC_EmitNode2None:
    case OPC_EmitNode0Chain:
    case OPC_EmitNode1Chain:
    case OPC_EmitNode2Chain:
    case OPC_MorphNodeTo:
    case OPC_MorphNodeTo0:
    case OPC_MorphNodeTo1:
    case OPC_MorphNodeTo2:
    case OPC_MorphNodeTo0None:
    case OPC_MorphNodeTo1None:
    case OPC_MorphNodeTo2None:
    case OPC_MorphNodeTo0Chain:
    case OPC_MorphNodeTo1Chain:
    case OPC_MorphNodeTo2Chain:
    case OPC_MorphNodeTo0GlueInput:
    case OPC_MorphNodeTo1GlueInput:
    case OPC_MorphNodeTo2GlueInput:
    case OPC_MorphNodeTo0GlueOutput:
    case OPC_MorphNodeTo1GlueOutput:
    case OPC_MorphNodeTo2GlueOutput: {
      uint16_t TargetOpc = MatcherTable[MatcherIndex++];
      TargetOpc |= static_cast<uint16_t>(MatcherTable[MatcherIndex++]) << 8;
      unsigned EmitNodeInfo;
      if (Opcode >= OPC_EmitNode0None && Opcode <= OPC_EmitNode2Chain) {
        if (Opcode >= OPC_EmitNode0Chain && Opcode <= OPC_EmitNode2Chain)
          EmitNodeInfo = OPFL_Chain;
        else
          EmitNodeInfo = OPFL_None;
      } else if (Opcode >= OPC_MorphNodeTo0None &&
                 Opcode <= OPC_MorphNodeTo2GlueOutput) {
        if (Opcode >= OPC_MorphNodeTo0Chain && Opcode <= OPC_MorphNodeTo2Chain)
          EmitNodeInfo = OPFL_Chain;
        else if (Opcode >= OPC_MorphNodeTo0GlueInput &&
                 Opcode <= OPC_MorphNodeTo2GlueInput)
          EmitNodeInfo = OPFL_GlueInput;
        else if (Opcode >= OPC_MorphNodeTo0GlueOutput &&
                 Opcode <= OPC_MorphNodeTo2GlueOutput)
          EmitNodeInfo = OPFL_GlueOutput;
        else
          EmitNodeInfo = OPFL_None;
      } else
        EmitNodeInfo = MatcherTable[MatcherIndex++];
      // Get the result VT list.
      unsigned NumVTs;
      // If this is one of the compressed forms, get the number of VTs based
      // on the Opcode. Otherwise read the next byte from the table.
      if (Opcode >= OPC_MorphNodeTo0 && Opcode <= OPC_MorphNodeTo2)
        NumVTs = Opcode - OPC_MorphNodeTo0;
      else if (Opcode >= OPC_MorphNodeTo0None && Opcode <= OPC_MorphNodeTo2None)
        NumVTs = Opcode - OPC_MorphNodeTo0None;
      else if (Opcode >= OPC_MorphNodeTo0Chain &&
               Opcode <= OPC_MorphNodeTo2Chain)
        NumVTs = Opcode - OPC_MorphNodeTo0Chain;
      else if (Opcode >= OPC_MorphNodeTo0GlueInput &&
               Opcode <= OPC_MorphNodeTo2GlueInput)
        NumVTs = Opcode - OPC_MorphNodeTo0GlueInput;
      else if (Opcode >= OPC_MorphNodeTo0GlueOutput &&
               Opcode <= OPC_MorphNodeTo2GlueOutput)
        NumVTs = Opcode - OPC_MorphNodeTo0GlueOutput;
      else if (Opcode >= OPC_EmitNode0 && Opcode <= OPC_EmitNode2)
        NumVTs = Opcode - OPC_EmitNode0;
      else if (Opcode >= OPC_EmitNode0None && Opcode <= OPC_EmitNode2None)
        NumVTs = Opcode - OPC_EmitNode0None;
      else if (Opcode >= OPC_EmitNode0Chain && Opcode <= OPC_EmitNode2Chain)
        NumVTs = Opcode - OPC_EmitNode0Chain;
      else
        NumVTs = MatcherTable[MatcherIndex++];
      SmallVector<EVT, 4> VTs;
      for (unsigned i = 0; i != NumVTs; ++i) {
        MVT::SimpleValueType VT = getSimpleVT(MatcherTable, MatcherIndex);
        if (VT == MVT::iPTR)
          VT = TLI->getPointerTy(CurDAG->getDataLayout()).SimpleTy;
        VTs.push_back(VT);
      }

      if (EmitNodeInfo & OPFL_Chain)
        VTs.push_back(MVT::Other);
      if (EmitNodeInfo & OPFL_GlueOutput)
        VTs.push_back(MVT::Glue);

      // This is hot code, so optimize the two most common cases of 1 and 2
      // results.
      SDVTList VTList;
      if (VTs.size() == 1)
        VTList = CurDAG->getVTList(VTs[0]);
      else if (VTs.size() == 2)
        VTList = CurDAG->getVTList(VTs[0], VTs[1]);
      else
        VTList = CurDAG->getVTList(VTs);

      // Get the operand list.
      unsigned NumOps = MatcherTable[MatcherIndex++];
      SmallVector<SDValue, 8> Ops;
      for (unsigned i = 0; i != NumOps; ++i) {
        unsigned RecNo = MatcherTable[MatcherIndex++];
        if (RecNo & 128)
          RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex);

        assert(RecNo < RecordedNodes.size() && "Invalid EmitNode");
        Ops.push_back(RecordedNodes[RecNo].first);
      }

      // If there are variadic operands to add, handle them now.
      if (EmitNodeInfo & OPFL_VariadicInfo) {
        // Determine the start index to copy from.
        unsigned FirstOpToCopy = getNumFixedFromVariadicInfo(EmitNodeInfo);
        FirstOpToCopy += (EmitNodeInfo & OPFL_Chain) ? 1 : 0;
        assert(NodeToMatch->getNumOperands() >= FirstOpToCopy &&
               "Invalid variadic node");
        // Copy all of the variadic operands, not including a potential glue
        // input.
        for (unsigned i = FirstOpToCopy, e = NodeToMatch->getNumOperands();
             i != e; ++i) {
          SDValue V = NodeToMatch->getOperand(i);
          if (V.getValueType() == MVT::Glue) break;
          Ops.push_back(V);
        }
      }

      // If this has chain/glue inputs, add them.
      if (EmitNodeInfo & OPFL_Chain)
        Ops.push_back(InputChain);
      if ((EmitNodeInfo & OPFL_GlueInput) && InputGlue.getNode() != nullptr)
        Ops.push_back(InputGlue);

      // Check whether any matched node could raise an FP exception.  Since all
      // such nodes must have a chain, it suffices to check ChainNodesMatched.
      // We need to perform this check before potentially modifying one of the
      // nodes via MorphNode.
      bool MayRaiseFPException =
          llvm::any_of(ChainNodesMatched, [this](SDNode *N) {
            return mayRaiseFPException(N) && !N->getFlags().hasNoFPExcept();
          });

      // Create the node.
      MachineSDNode *Res = nullptr;
      bool IsMorphNodeTo =
          Opcode == OPC_MorphNodeTo ||
          (Opcode >= OPC_MorphNodeTo0 && Opcode <= OPC_MorphNodeTo2GlueOutput);
      if (!IsMorphNodeTo) {
        // If this is a normal EmitNode command, just create the new node and
        // add the results to the RecordedNodes list.
        Res = CurDAG->getMachineNode(TargetOpc, SDLoc(NodeToMatch),
                                     VTList, Ops);

        // Add all the non-glue/non-chain results to the RecordedNodes list.
        for (unsigned i = 0, e = VTs.size(); i != e; ++i) {
          if (VTs[i] == MVT::Other || VTs[i] == MVT::Glue) break;
          RecordedNodes.push_back(std::pair<SDValue,SDNode*>(SDValue(Res, i),
                                                             nullptr));
        }
      } else {
        assert(NodeToMatch->getOpcode() != ISD::DELETED_NODE &&
               "NodeToMatch was removed partway through selection");
        SelectionDAG::DAGNodeDeletedListener NDL(*CurDAG, [&](SDNode *N,
                                                              SDNode *E) {
          CurDAG->salvageDebugInfo(*N);
          auto &Chain = ChainNodesMatched;
          assert((!E || !is_contained(Chain, N)) &&
                 "Chain node replaced during MorphNode");
          llvm::erase(Chain, N);
        });
        Res = cast<MachineSDNode>(MorphNode(NodeToMatch, TargetOpc, VTList,
                                            Ops, EmitNodeInfo));
      }

      // Set the NoFPExcept flag when no original matched node could
      // raise an FP exception, but the new node potentially might.
      if (!MayRaiseFPException && mayRaiseFPException(Res))
        Res->setFlags(Res->getFlags() | SDNodeFlags::NoFPExcept);

      // If the node had chain/glue results, update our notion of the current
      // chain and glue.
      if (EmitNodeInfo & OPFL_GlueOutput) {
        InputGlue = SDValue(Res, VTs.size()-1);
        if (EmitNodeInfo & OPFL_Chain)
          InputChain = SDValue(Res, VTs.size()-2);
      } else if (EmitNodeInfo & OPFL_Chain)
        InputChain = SDValue(Res, VTs.size()-1);

      // If the OPFL_MemRefs glue is set on this node, slap all of the
      // accumulated memrefs onto it.
      //
      // FIXME: This is vastly incorrect for patterns with multiple outputs
      // instructions that access memory and for ComplexPatterns that match
      // loads.
      if (EmitNodeInfo & OPFL_MemRefs) {
        // Only attach load or store memory operands if the generated
        // instruction may load or store.
        const MCInstrDesc &MCID = TII->get(TargetOpc);
        bool mayLoad = MCID.mayLoad();
        bool mayStore = MCID.mayStore();

        // We expect to have relatively few of these so just filter them into a
        // temporary buffer so that we can easily add them to the instruction.
        SmallVector<MachineMemOperand *, 4> FilteredMemRefs;
        for (MachineMemOperand *MMO : MatchedMemRefs) {
          if (MMO->isLoad()) {
            if (mayLoad)
              FilteredMemRefs.push_back(MMO);
          } else if (MMO->isStore()) {
            if (mayStore)
              FilteredMemRefs.push_back(MMO);
          } else {
            FilteredMemRefs.push_back(MMO);
          }
        }

        CurDAG->setNodeMemRefs(Res, FilteredMemRefs);
      }

      LLVM_DEBUG({
        if (!MatchedMemRefs.empty() && Res->memoperands_empty())
          dbgs() << "  Dropping mem operands\n";
        dbgs() << "  " << (IsMorphNodeTo ? "Morphed" : "Created") << " node: ";
        Res->dump(CurDAG);
      });

      // If this was a MorphNodeTo then we're completely done!
      if (IsMorphNodeTo) {
        // Update chain uses.
        UpdateChains(Res, InputChain, ChainNodesMatched, true);
        return;
      }
      continue;
    }

    case OPC_CompleteMatch: {
      // The match has been completed, and any new nodes (if any) have been
      // created.  Patch up references to the matched dag to use the newly
      // created nodes.
      unsigned NumResults = MatcherTable[MatcherIndex++];

      for (unsigned i = 0; i != NumResults; ++i) {
        unsigned ResSlot = MatcherTable[MatcherIndex++];
        if (ResSlot & 128)
          ResSlot = GetVBR(ResSlot, MatcherTable, MatcherIndex);

        assert(ResSlot < RecordedNodes.size() && "Invalid CompleteMatch");
        SDValue Res = RecordedNodes[ResSlot].first;

        assert(i < NodeToMatch->getNumValues() &&
               NodeToMatch->getValueType(i) != MVT::Other &&
               NodeToMatch->getValueType(i) != MVT::Glue &&
               "Invalid number of results to complete!");
        assert((NodeToMatch->getValueType(i) == Res.getValueType() ||
                NodeToMatch->getValueType(i) == MVT::iPTR ||
                Res.getValueType() == MVT::iPTR ||
                NodeToMatch->getValueType(i).getSizeInBits() ==
                    Res.getValueSizeInBits()) &&
               "invalid replacement");
        ReplaceUses(SDValue(NodeToMatch, i), Res);
      }

      // Update chain uses.
      UpdateChains(NodeToMatch, InputChain, ChainNodesMatched, false);

      // If the root node defines glue, we need to update it to the glue result.
      // TODO: This never happens in our tests and I think it can be removed /
      // replaced with an assert, but if we do it this the way the change is
      // NFC.
      if (NodeToMatch->getValueType(NodeToMatch->getNumValues() - 1) ==
              MVT::Glue &&
          InputGlue.getNode())
        ReplaceUses(SDValue(NodeToMatch, NodeToMatch->getNumValues() - 1),
                    InputGlue);

      assert(NodeToMatch->use_empty() &&
             "Didn't replace all uses of the node?");
      CurDAG->RemoveDeadNode(NodeToMatch);

      return;
    }
    }

    // If the code reached this point, then the match failed.  See if there is
    // another child to try in the current 'Scope', otherwise pop it until we
    // find a case to check.
    LLVM_DEBUG(dbgs() << "  Match failed at index " << CurrentOpcodeIndex
                      << "\n");
    ++NumDAGIselRetries;
    while (true) {
      if (MatchScopes.empty()) {
        CannotYetSelect(NodeToMatch);
        return;
      }

      // Restore the interpreter state back to the point where the scope was
      // formed.
      MatchScope &LastScope = MatchScopes.back();
      RecordedNodes.resize(LastScope.NumRecordedNodes);
      NodeStack.clear();
      NodeStack.append(LastScope.NodeStack.begin(), LastScope.NodeStack.end());
      N = NodeStack.back();

      if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size())
        MatchedMemRefs.resize(LastScope.NumMatchedMemRefs);
      MatcherIndex = LastScope.FailIndex;

      LLVM_DEBUG(dbgs() << "  Continuing at " << MatcherIndex << "\n");

      InputChain = LastScope.InputChain;
      InputGlue = LastScope.InputGlue;
      if (!LastScope.HasChainNodesMatched)
        ChainNodesMatched.clear();

      // Check to see what the offset is at the new MatcherIndex.  If it is zero
      // we have reached the end of this scope, otherwise we have another child
      // in the current scope to try.
      unsigned NumToSkip = MatcherTable[MatcherIndex++];
      if (NumToSkip & 128)
        NumToSkip = GetVBR(NumToSkip, MatcherTable, MatcherIndex);

      // If we have another child in this scope to match, update FailIndex and
      // try it.
      if (NumToSkip != 0) {
        LastScope.FailIndex = MatcherIndex+NumToSkip;
        break;
      }

      // End of this scope, pop it and try the next child in the containing
      // scope.
      MatchScopes.pop_back();
    }
  }
}

/// Return whether the node may raise an FP exception.
bool SelectionDAGISel::mayRaiseFPException(SDNode *N) const {
  // For machine opcodes, consult the MCID flag.
  if (N->isMachineOpcode()) {
    const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
    return MCID.mayRaiseFPException();
  }

  // For ISD opcodes, only StrictFP opcodes may raise an FP
  // exception.
  if (N->isTargetOpcode()) {
    const SelectionDAGTargetInfo &TSI = CurDAG->getSelectionDAGInfo();
    return TSI.mayRaiseFPException(N->getOpcode());
  }
  return N->isStrictFPOpcode();
}

bool SelectionDAGISel::isOrEquivalentToAdd(const SDNode *N) const {
  assert(N->getOpcode() == ISD::OR && "Unexpected opcode");
  auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
  if (!C)
    return false;

  // Detect when "or" is used to add an offset to a stack object.
  if (auto *FN = dyn_cast<FrameIndexSDNode>(N->getOperand(0))) {
    MachineFrameInfo &MFI = MF->getFrameInfo();
    Align A = MFI.getObjectAlign(FN->getIndex());
    int32_t Off = C->getSExtValue();
    // If the alleged offset fits in the zero bits guaranteed by
    // the alignment, then this or is really an add.
    return (Off >= 0) && (((A.value() - 1) & Off) == unsigned(Off));
  }
  return false;
}

void SelectionDAGISel::CannotYetSelect(SDNode *N) {
  std::string msg;
  raw_string_ostream Msg(msg);
  Msg << "Cannot select: ";

  if (N->getOpcode() != ISD::INTRINSIC_W_CHAIN &&
      N->getOpcode() != ISD::INTRINSIC_WO_CHAIN &&
      N->getOpcode() != ISD::INTRINSIC_VOID) {
    N->printrFull(Msg, CurDAG);
    Msg << "\nIn function: " << MF->getName();
  } else {
    bool HasInputChain = N->getOperand(0).getValueType() == MVT::Other;
    unsigned iid = N->getConstantOperandVal(HasInputChain);
    if (iid < Intrinsic::num_intrinsics)
      Msg << "intrinsic %" << Intrinsic::getBaseName((Intrinsic::ID)iid);
    else
      Msg << "unknown intrinsic #" << iid;
  }
  report_fatal_error(Twine(msg));
}
