//===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===//
//
// 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 file implements the CodeGenInstruction class.
//
//===----------------------------------------------------------------------===//

#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <set>
using namespace llvm;

//===----------------------------------------------------------------------===//
// CGIOperandList Implementation
//===----------------------------------------------------------------------===//

CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
  isPredicable = false;
  hasOptionalDef = false;
  isVariadic = false;

  DagInit *OutDI = R->getValueAsDag("OutOperandList");

  if (DefInit *Init = dyn_cast<DefInit>(OutDI->getOperator())) {
    if (Init->getDef()->getName() != "outs")
      PrintFatalError(R->getLoc(),
                      R->getName() +
                          ": invalid def name for output list: use 'outs'");
  } else
    PrintFatalError(R->getLoc(),
                    R->getName() + ": invalid output list: use 'outs'");

  NumDefs = OutDI->getNumArgs();

  DagInit *InDI = R->getValueAsDag("InOperandList");
  if (DefInit *Init = dyn_cast<DefInit>(InDI->getOperator())) {
    if (Init->getDef()->getName() != "ins")
      PrintFatalError(R->getLoc(),
                      R->getName() +
                          ": invalid def name for input list: use 'ins'");
  } else
    PrintFatalError(R->getLoc(),
                    R->getName() + ": invalid input list: use 'ins'");

  unsigned MIOperandNo = 0;
  std::set<std::string> OperandNames;
  unsigned e = InDI->getNumArgs() + OutDI->getNumArgs();
  OperandList.reserve(e);
  bool VariadicOuts = false;
  for (unsigned i = 0; i != e; ++i){
    Init *ArgInit;
    StringRef ArgName;
    if (i < NumDefs) {
      ArgInit = OutDI->getArg(i);
      ArgName = OutDI->getArgNameStr(i);
    } else {
      ArgInit = InDI->getArg(i-NumDefs);
      ArgName = InDI->getArgNameStr(i-NumDefs);
    }

    DagInit *SubArgDag = dyn_cast<DagInit>(ArgInit);
    if (SubArgDag)
      ArgInit = SubArgDag->getOperator();

    DefInit *Arg = dyn_cast<DefInit>(ArgInit);
    if (!Arg)
      PrintFatalError(R->getLoc(), "Illegal operand for the '" + R->getName() +
                                       "' instruction!");

    Record *Rec = Arg->getDef();
    std::string PrintMethod = "printOperand";
    std::string EncoderMethod;
    std::string OperandType = "OPERAND_UNKNOWN";
    std::string OperandNamespace = "MCOI";
    unsigned NumOps = 1;
    DagInit *MIOpInfo = nullptr;
    if (Rec->isSubClassOf("RegisterOperand")) {
      PrintMethod = std::string(Rec->getValueAsString("PrintMethod"));
      OperandType = std::string(Rec->getValueAsString("OperandType"));
      OperandNamespace = std::string(Rec->getValueAsString("OperandNamespace"));
      EncoderMethod = std::string(Rec->getValueAsString("EncoderMethod"));
    } else if (Rec->isSubClassOf("Operand")) {
      PrintMethod = std::string(Rec->getValueAsString("PrintMethod"));
      OperandType = std::string(Rec->getValueAsString("OperandType"));
      OperandNamespace = std::string(Rec->getValueAsString("OperandNamespace"));
      // If there is an explicit encoder method, use it.
      EncoderMethod = std::string(Rec->getValueAsString("EncoderMethod"));
      MIOpInfo = Rec->getValueAsDag("MIOperandInfo");

      // Verify that MIOpInfo has an 'ops' root value.
      if (!isa<DefInit>(MIOpInfo->getOperator()) ||
          cast<DefInit>(MIOpInfo->getOperator())->getDef()->getName() != "ops")
        PrintFatalError(R->getLoc(),
                        "Bad value for MIOperandInfo in operand '" +
                            Rec->getName() + "'\n");

      // If we have MIOpInfo, then we have #operands equal to number of entries
      // in MIOperandInfo.
      if (unsigned NumArgs = MIOpInfo->getNumArgs())
        NumOps = NumArgs;

      if (Rec->isSubClassOf("PredicateOp"))
        isPredicable = true;
      else if (Rec->isSubClassOf("OptionalDefOperand"))
        hasOptionalDef = true;
    } else if (Rec->getName() == "variable_ops") {
      if (i < NumDefs)
        VariadicOuts = true;
      isVariadic = true;
      continue;
    } else if (Rec->isSubClassOf("RegisterClass")) {
      OperandType = "OPERAND_REGISTER";
    } else if (!Rec->isSubClassOf("PointerLikeRegClass") &&
               !Rec->isSubClassOf("unknown_class")) {
      PrintFatalError(R->getLoc(), "Unknown operand class '" + Rec->getName() +
                                       "' in '" + R->getName() +
                                       "' instruction!");
    }

    // Check that the operand has a name and that it's unique.
    if (ArgName.empty())
      PrintFatalError(R->getLoc(), "In instruction '" + R->getName() +
                                       "', operand #" + Twine(i) +
                                       " has no name!");
    if (!OperandNames.insert(std::string(ArgName)).second)
      PrintFatalError(R->getLoc(),
                      "In instruction '" + R->getName() + "', operand #" +
                          Twine(i) +
                          " has the same name as a previous operand!");

    OperandInfo &OpInfo = OperandList.emplace_back(
        Rec, std::string(ArgName), std::string(PrintMethod),
        OperandNamespace + "::" + OperandType, MIOperandNo, NumOps, MIOpInfo);

    if (SubArgDag) {
      if (SubArgDag->getNumArgs() != NumOps) {
        PrintFatalError(R->getLoc(), "In instruction '" + R->getName() +
                                         "', operand #" + Twine(i) + " has " +
                                         Twine(SubArgDag->getNumArgs()) +
                                         " sub-arg names, expected " +
                                         Twine(NumOps) + ".");
      }

      for (unsigned j = 0; j < NumOps; ++j) {
        if (!isa<UnsetInit>(SubArgDag->getArg(j)))
          PrintFatalError(R->getLoc(),
                          "In instruction '" + R->getName() + "', operand #" +
                              Twine(i) + " sub-arg #" + Twine(j) +
                              " has unexpected operand (expected only $name).");

        StringRef SubArgName = SubArgDag->getArgNameStr(j);
        if (SubArgName.empty())
          PrintFatalError(R->getLoc(), "In instruction '" + R->getName() +
                                           "', operand #" + Twine(i) +
                                           " has no name!");
        if (!OperandNames.insert(std::string(SubArgName)).second)
          PrintFatalError(R->getLoc(),
                          "In instruction '" + R->getName() + "', operand #" +
                              Twine(i) + " sub-arg #" + Twine(j) +
                              " has the same name as a previous operand!");

        if (auto MaybeEncoderMethod =
                cast<DefInit>(MIOpInfo->getArg(j))
                    ->getDef()
                    ->getValueAsOptionalString("EncoderMethod")) {
          OpInfo.EncoderMethodNames[j] = *MaybeEncoderMethod;
        }

        OpInfo.SubOpNames[j] = SubArgName;
        SubOpAliases[SubArgName] = std::make_pair(i, j);
      }
    } else if (!EncoderMethod.empty()) {
      // If we have no explicit sub-op dag, but have an top-level encoder
      // method, the single encoder will multiple sub-ops, itself.
      OpInfo.EncoderMethodNames[0] = EncoderMethod;
      for (unsigned j = 1; j < NumOps; ++j)
        OpInfo.DoNotEncode[j] = true;
    }

    MIOperandNo += NumOps;
  }

  if (VariadicOuts)
    --NumDefs;
}


/// getOperandNamed - Return the index of the operand with the specified
/// non-empty name.  If the instruction does not have an operand with the
/// specified name, abort.
///
unsigned CGIOperandList::getOperandNamed(StringRef Name) const {
  unsigned OpIdx;
  if (hasOperandNamed(Name, OpIdx))
    return OpIdx;
  PrintFatalError(TheDef->getLoc(), "'" + TheDef->getName() +
                                        "' does not have an operand named '$" +
                                        Name + "'!");
}

/// hasOperandNamed - Query whether the instruction has an operand of the
/// given name. If so, return true and set OpIdx to the index of the
/// operand. Otherwise, return false.
bool CGIOperandList::hasOperandNamed(StringRef Name, unsigned &OpIdx) const {
  assert(!Name.empty() && "Cannot search for operand with no name!");
  for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
    if (OperandList[i].Name == Name) {
      OpIdx = i;
      return true;
    }
  return false;
}

bool CGIOperandList::hasSubOperandAlias(
    StringRef Name, std::pair<unsigned, unsigned> &SubOp) const {
  assert(!Name.empty() && "Cannot search for operand with no name!");
  auto SubOpIter = SubOpAliases.find(Name);
  if (SubOpIter != SubOpAliases.end()) {
    SubOp = SubOpIter->second;
    return true;
  }
  return false;
}

std::pair<unsigned,unsigned>
CGIOperandList::ParseOperandName(StringRef Op, bool AllowWholeOp) {
  if (Op.empty() || Op[0] != '$')
    PrintFatalError(TheDef->getLoc(),
                    TheDef->getName() + ": Illegal operand name: '" + Op + "'");

  StringRef OpName = Op.substr(1);
  StringRef SubOpName;

  // Check to see if this is $foo.bar.
  StringRef::size_type DotIdx = OpName.find_first_of('.');
  if (DotIdx != StringRef::npos) {
    SubOpName = OpName.substr(DotIdx+1);
    if (SubOpName.empty())
      PrintFatalError(TheDef->getLoc(),
                      TheDef->getName() +
                          ": illegal empty suboperand name in '" + Op + "'");
    OpName = OpName.substr(0, DotIdx);
  }

  unsigned OpIdx;

  if (std::pair<unsigned, unsigned> SubOp; hasSubOperandAlias(OpName, SubOp)) {
    // Found a name for a piece of an operand, just return it directly.
    if (!SubOpName.empty()) {
      PrintFatalError(
          TheDef->getLoc(),
          TheDef->getName() +
              ": Cannot use dotted suboperand name within suboperand '" +
              OpName + "'");
    }
    return SubOp;
  }

  OpIdx = getOperandNamed(OpName);

  if (SubOpName.empty()) {  // If no suboperand name was specified:
    // If one was needed, throw.
    if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
        SubOpName.empty())
      PrintFatalError(TheDef->getLoc(),
                      TheDef->getName() +
                          ": Illegal to refer to"
                          " whole operand part of complex operand '" +
                          Op + "'");

    // Otherwise, return the operand.
    return std::make_pair(OpIdx, 0U);
  }

  // Find the suboperand number involved.
  DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
  if (!MIOpInfo)
    PrintFatalError(TheDef->getLoc(), TheDef->getName() +
                                          ": unknown suboperand name in '" +
                                          Op + "'");

  // Find the operand with the right name.
  for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
    if (MIOpInfo->getArgNameStr(i) == SubOpName)
      return std::make_pair(OpIdx, i);

  // Otherwise, didn't find it!
  PrintFatalError(TheDef->getLoc(), TheDef->getName() +
                                        ": unknown suboperand name in '" + Op +
                                        "'");
  return std::make_pair(0U, 0U);
}

static void ParseConstraint(StringRef CStr, CGIOperandList &Ops,
                            Record *Rec) {
  // EARLY_CLOBBER: @early $reg
  StringRef::size_type wpos = CStr.find_first_of(" \t");
  StringRef::size_type start = CStr.find_first_not_of(" \t");
  StringRef Tok = CStr.substr(start, wpos - start);
  if (Tok == "@earlyclobber") {
    StringRef Name = CStr.substr(wpos+1);
    wpos = Name.find_first_not_of(" \t");
    if (wpos == StringRef::npos)
      PrintFatalError(
        Rec->getLoc(), "Illegal format for @earlyclobber constraint in '" +
        Rec->getName() + "': '" + CStr + "'");
    Name = Name.substr(wpos);
    std::pair<unsigned,unsigned> Op = Ops.ParseOperandName(Name, false);

    // Build the string for the operand
    if (!Ops[Op.first].Constraints[Op.second].isNone())
      PrintFatalError(
        Rec->getLoc(), "Operand '" + Name + "' of '" + Rec->getName() +
        "' cannot have multiple constraints!");
    Ops[Op.first].Constraints[Op.second] =
    CGIOperandList::ConstraintInfo::getEarlyClobber();
    return;
  }

  // Only other constraint is "TIED_TO" for now.
  StringRef::size_type pos = CStr.find_first_of('=');
  if (pos == StringRef::npos)
    PrintFatalError(
      Rec->getLoc(), "Unrecognized constraint '" + CStr +
      "' in '" + Rec->getName() + "'");
  start = CStr.find_first_not_of(" \t");

  // TIED_TO: $src1 = $dst
  wpos = CStr.find_first_of(" \t", start);
  if (wpos == StringRef::npos || wpos > pos)
    PrintFatalError(
      Rec->getLoc(), "Illegal format for tied-to constraint in '" +
      Rec->getName() + "': '" + CStr + "'");
  StringRef LHSOpName = CStr.substr(start, wpos - start);
  std::pair<unsigned,unsigned> LHSOp = Ops.ParseOperandName(LHSOpName, false);

  wpos = CStr.find_first_not_of(" \t", pos + 1);
  if (wpos == StringRef::npos)
    PrintFatalError(
      Rec->getLoc(), "Illegal format for tied-to constraint: '" + CStr + "'");

  StringRef RHSOpName = CStr.substr(wpos);
  std::pair<unsigned,unsigned> RHSOp = Ops.ParseOperandName(RHSOpName, false);

  // Sort the operands into order, which should put the output one
  // first. But keep the original order, for use in diagnostics.
  bool FirstIsDest = (LHSOp < RHSOp);
  std::pair<unsigned,unsigned> DestOp = (FirstIsDest ? LHSOp : RHSOp);
  StringRef DestOpName = (FirstIsDest ? LHSOpName : RHSOpName);
  std::pair<unsigned,unsigned> SrcOp = (FirstIsDest ? RHSOp : LHSOp);
  StringRef SrcOpName = (FirstIsDest ? RHSOpName : LHSOpName);

  // Ensure one operand is a def and the other is a use.
  if (DestOp.first >= Ops.NumDefs)
    PrintFatalError(
      Rec->getLoc(), "Input operands '" + LHSOpName + "' and '" + RHSOpName +
      "' of '" + Rec->getName() + "' cannot be tied!");
  if (SrcOp.first < Ops.NumDefs)
    PrintFatalError(
      Rec->getLoc(), "Output operands '" + LHSOpName + "' and '" + RHSOpName +
      "' of '" + Rec->getName() + "' cannot be tied!");

  // The constraint has to go on the operand with higher index, i.e.
  // the source one. Check there isn't another constraint there
  // already.
  if (!Ops[SrcOp.first].Constraints[SrcOp.second].isNone())
    PrintFatalError(
      Rec->getLoc(), "Operand '" + SrcOpName + "' of '" + Rec->getName() +
      "' cannot have multiple constraints!");

  unsigned DestFlatOpNo = Ops.getFlattenedOperandNumber(DestOp);
  auto NewConstraint = CGIOperandList::ConstraintInfo::getTied(DestFlatOpNo);

  // Check that the earlier operand is not the target of another tie
  // before making it the target of this one.
  for (const CGIOperandList::OperandInfo &Op : Ops) {
    for (unsigned i = 0; i < Op.MINumOperands; i++)
      if (Op.Constraints[i] == NewConstraint)
        PrintFatalError(
          Rec->getLoc(), "Operand '" + DestOpName + "' of '" + Rec->getName() +
          "' cannot have multiple operands tied to it!");
  }

  Ops[SrcOp.first].Constraints[SrcOp.second] = NewConstraint;
}

static void ParseConstraints(StringRef CStr, CGIOperandList &Ops, Record *Rec) {
  if (CStr.empty()) return;

  StringRef delims(",");
  StringRef::size_type bidx, eidx;

  bidx = CStr.find_first_not_of(delims);
  while (bidx != StringRef::npos) {
    eidx = CStr.find_first_of(delims, bidx);
    if (eidx == StringRef::npos)
      eidx = CStr.size();

    ParseConstraint(CStr.substr(bidx, eidx - bidx), Ops, Rec);
    bidx = CStr.find_first_not_of(delims, eidx);
  }
}

void CGIOperandList::ProcessDisableEncoding(StringRef DisableEncoding) {
  while (true) {
    StringRef OpName;
    std::tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t");
    if (OpName.empty()) break;

    // Figure out which operand this is.
    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);

    // Mark the operand as not-to-be encoded.
    OperandList[Op.first].DoNotEncode[Op.second] = true;
  }

}

//===----------------------------------------------------------------------===//
// CodeGenInstruction Implementation
//===----------------------------------------------------------------------===//

CodeGenInstruction::CodeGenInstruction(Record *R)
  : TheDef(R), Operands(R), InferredFrom(nullptr) {
  Namespace = R->getValueAsString("Namespace");
  AsmString = std::string(R->getValueAsString("AsmString"));

  isPreISelOpcode = R->getValueAsBit("isPreISelOpcode");
  isReturn     = R->getValueAsBit("isReturn");
  isEHScopeReturn = R->getValueAsBit("isEHScopeReturn");
  isBranch     = R->getValueAsBit("isBranch");
  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
  isCompare    = R->getValueAsBit("isCompare");
  isMoveImm    = R->getValueAsBit("isMoveImm");
  isMoveReg    = R->getValueAsBit("isMoveReg");
  isBitcast    = R->getValueAsBit("isBitcast");
  isSelect     = R->getValueAsBit("isSelect");
  isBarrier    = R->getValueAsBit("isBarrier");
  isCall       = R->getValueAsBit("isCall");
  isAdd        = R->getValueAsBit("isAdd");
  isTrap       = R->getValueAsBit("isTrap");
  canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
  isPredicable = !R->getValueAsBit("isUnpredicable") && (
      Operands.isPredicable || R->getValueAsBit("isPredicable"));
  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
  isCommutable = R->getValueAsBit("isCommutable");
  isTerminator = R->getValueAsBit("isTerminator");
  isReMaterializable = R->getValueAsBit("isReMaterializable");
  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
  usesCustomInserter = R->getValueAsBit("usesCustomInserter");
  hasPostISelHook = R->getValueAsBit("hasPostISelHook");
  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
  isRegSequence = R->getValueAsBit("isRegSequence");
  isExtractSubreg = R->getValueAsBit("isExtractSubreg");
  isInsertSubreg = R->getValueAsBit("isInsertSubreg");
  isConvergent = R->getValueAsBit("isConvergent");
  hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo");
  FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore");
  variadicOpsAreDefs = R->getValueAsBit("variadicOpsAreDefs");
  isAuthenticated = R->getValueAsBit("isAuthenticated");

  bool Unset;
  mayLoad      = R->getValueAsBitOrUnset("mayLoad", Unset);
  mayLoad_Unset = Unset;
  mayStore     = R->getValueAsBitOrUnset("mayStore", Unset);
  mayStore_Unset = Unset;
  mayRaiseFPException = R->getValueAsBit("mayRaiseFPException");
  hasSideEffects = R->getValueAsBitOrUnset("hasSideEffects", Unset);
  hasSideEffects_Unset = Unset;

  isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove");
  hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq");
  hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq");
  isCodeGenOnly = R->getValueAsBit("isCodeGenOnly");
  isPseudo = R->getValueAsBit("isPseudo");
  isMeta = R->getValueAsBit("isMeta");
  ImplicitDefs = R->getValueAsListOfDefs("Defs");
  ImplicitUses = R->getValueAsListOfDefs("Uses");

  // This flag is only inferred from the pattern.
  hasChain = false;
  hasChain_Inferred = false;

  // Parse Constraints.
  ParseConstraints(R->getValueAsString("Constraints"), Operands, R);

  // Parse the DisableEncoding field.
  Operands.ProcessDisableEncoding(
      R->getValueAsString("DisableEncoding"));

  // First check for a ComplexDeprecationPredicate.
  if (R->getValue("ComplexDeprecationPredicate")) {
    HasComplexDeprecationPredicate = true;
    DeprecatedReason =
        std::string(R->getValueAsString("ComplexDeprecationPredicate"));
  } else if (RecordVal *Dep = R->getValue("DeprecatedFeatureMask")) {
    // Check if we have a Subtarget feature mask.
    HasComplexDeprecationPredicate = false;
    DeprecatedReason = Dep->getValue()->getAsString();
  } else {
    // This instruction isn't deprecated.
    HasComplexDeprecationPredicate = false;
    DeprecatedReason = "";
  }
}

/// HasOneImplicitDefWithKnownVT - If the instruction has at least one
/// implicit def and it has a known VT, return the VT, otherwise return
/// MVT::Other.
MVT::SimpleValueType CodeGenInstruction::
HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
  if (ImplicitDefs.empty()) return MVT::Other;

  // Check to see if the first implicit def has a resolvable type.
  Record *FirstImplicitDef = ImplicitDefs[0];
  assert(FirstImplicitDef->isSubClassOf("Register"));
  const std::vector<ValueTypeByHwMode> &RegVTs =
    TargetInfo.getRegisterVTs(FirstImplicitDef);
  if (RegVTs.size() == 1 && RegVTs[0].isSimple())
    return RegVTs[0].getSimple().SimpleTy;
  return MVT::Other;
}


/// FlattenAsmStringVariants - Flatten the specified AsmString to only
/// include text from the specified variant, returning the new string.
std::string CodeGenInstruction::
FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
  std::string Res;

  for (;;) {
    // Find the start of the next variant string.
    size_t VariantsStart = 0;
    for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
      if (Cur[VariantsStart] == '{' &&
          (VariantsStart == 0 || (Cur[VariantsStart-1] != '$' &&
                                  Cur[VariantsStart-1] != '\\')))
        break;

    // Add the prefix to the result.
    Res += Cur.slice(0, VariantsStart);
    if (VariantsStart == Cur.size())
      break;

    ++VariantsStart; // Skip the '{'.

    // Scan to the end of the variants string.
    size_t VariantsEnd = VariantsStart;
    unsigned NestedBraces = 1;
    for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
      if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') {
        if (--NestedBraces == 0)
          break;
      } else if (Cur[VariantsEnd] == '{')
        ++NestedBraces;
    }

    // Select the Nth variant (or empty).
    StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
    for (unsigned i = 0; i != Variant; ++i)
      Selection = Selection.split('|').second;
    Res += Selection.split('|').first;

    assert(VariantsEnd != Cur.size() &&
           "Unterminated variants in assembly string!");
    Cur = Cur.substr(VariantsEnd + 1);
  }

  return Res;
}

bool CodeGenInstruction::isOperandImpl(StringRef OpListName, unsigned i,
                                       StringRef PropertyName) const {
  DagInit *ConstraintList = TheDef->getValueAsDag(OpListName);
  if (!ConstraintList || i >= ConstraintList->getNumArgs())
    return false;

  DefInit *Constraint = dyn_cast<DefInit>(ConstraintList->getArg(i));
  if (!Constraint)
    return false;

  return Constraint->getDef()->isSubClassOf("TypedOperand") &&
         Constraint->getDef()->getValueAsBit(PropertyName);
}
