Importing rustc-1.47.0

Bug: 171280890
Change-Id: Iac01e5c09a6ae8e508762cd96c2a88d191af4f0e
diff --git a/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index ccf0959..3d63059 100644
--- a/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -1085,7 +1085,7 @@
     // Verify that any operand is only mentioned once.
     // We reject aliases and ignore instructions for now.
     if (!IsAlias && TheDef->getValueAsString("AsmMatchConverter").empty() &&
-        Tok[0] == '$' && !OperandNames.insert(Tok).second) {
+        Tok[0] == '$' && !OperandNames.insert(std::string(Tok)).second) {
       LLVM_DEBUG({
         errs() << "warning: '" << TheDef->getName() << "': "
                << "ignoring instruction with tied operand '"
@@ -1126,7 +1126,7 @@
 }
 
 ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
-  ClassInfo *&Entry = TokenClasses[Token];
+  ClassInfo *&Entry = TokenClasses[std::string(Token)];
 
   if (!Entry) {
     Classes.emplace_front();
@@ -1134,7 +1134,7 @@
     Entry->Kind = ClassInfo::Token;
     Entry->ClassName = "Token";
     Entry->Name = "MCK_" + getEnumNameForToken(Token);
-    Entry->ValueName = Token;
+    Entry->ValueName = std::string(Token);
     Entry->PredicateMethod = "<invalid>";
     Entry->RenderMethod = "<invalid>";
     Entry->ParserMethod = "";
@@ -1310,11 +1310,11 @@
 
     Init *DiagnosticType = Def->getValueInit("DiagnosticType");
     if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
-      CI->DiagnosticType = SI->getValue();
+      CI->DiagnosticType = std::string(SI->getValue());
 
     Init *DiagnosticString = Def->getValueInit("DiagnosticString");
     if (StringInit *SI = dyn_cast<StringInit>(DiagnosticString))
-      CI->DiagnosticString = SI->getValue();
+      CI->DiagnosticString = std::string(SI->getValue());
 
     // If we have a diagnostic string but the diagnostic type is not specified
     // explicitly, create an anonymous diagnostic type.
@@ -1335,9 +1335,9 @@
     assert(CI && "Missing singleton register class info!");
 
     if (CI->ValueName.empty()) {
-      CI->ClassName = Rec->getName();
+      CI->ClassName = std::string(Rec->getName());
       CI->Name = "MCK_" + Rec->getName().str();
-      CI->ValueName = Rec->getName();
+      CI->ValueName = std::string(Rec->getName());
     } else
       CI->ValueName = CI->ValueName + "," + Rec->getName().str();
   }
@@ -1372,14 +1372,14 @@
       else
         CI->SuperClasses.push_back(SC);
     }
-    CI->ClassName = Rec->getValueAsString("Name");
+    CI->ClassName = std::string(Rec->getValueAsString("Name"));
     CI->Name = "MCK_" + CI->ClassName;
-    CI->ValueName = Rec->getName();
+    CI->ValueName = std::string(Rec->getName());
 
     // Get or construct the predicate method name.
     Init *PMName = Rec->getValueInit("PredicateMethod");
     if (StringInit *SI = dyn_cast<StringInit>(PMName)) {
-      CI->PredicateMethod = SI->getValue();
+      CI->PredicateMethod = std::string(SI->getValue());
     } else {
       assert(isa<UnsetInit>(PMName) && "Unexpected PredicateMethod field!");
       CI->PredicateMethod = "is" + CI->ClassName;
@@ -1388,7 +1388,7 @@
     // Get or construct the render method name.
     Init *RMName = Rec->getValueInit("RenderMethod");
     if (StringInit *SI = dyn_cast<StringInit>(RMName)) {
-      CI->RenderMethod = SI->getValue();
+      CI->RenderMethod = std::string(SI->getValue());
     } else {
       assert(isa<UnsetInit>(RMName) && "Unexpected RenderMethod field!");
       CI->RenderMethod = "add" + CI->ClassName + "Operands";
@@ -1397,15 +1397,15 @@
     // Get the parse method name or leave it as empty.
     Init *PRMName = Rec->getValueInit("ParserMethod");
     if (StringInit *SI = dyn_cast<StringInit>(PRMName))
-      CI->ParserMethod = SI->getValue();
+      CI->ParserMethod = std::string(SI->getValue());
 
     // Get the diagnostic type and string or leave them as empty.
     Init *DiagnosticType = Rec->getValueInit("DiagnosticType");
     if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
-      CI->DiagnosticType = SI->getValue();
+      CI->DiagnosticType = std::string(SI->getValue());
     Init *DiagnosticString = Rec->getValueInit("DiagnosticString");
     if (StringInit *SI = dyn_cast<StringInit>(DiagnosticString))
-      CI->DiagnosticString = SI->getValue();
+      CI->DiagnosticString = std::string(SI->getValue());
     // If we have a DiagnosticString, we need a DiagnosticType for use within
     // the matcher.
     if (!CI->DiagnosticString.empty() && CI->DiagnosticType.empty())
@@ -1418,7 +1418,7 @@
     // Get or construct the default method name.
     Init *DMName = Rec->getValueInit("DefaultMethod");
     if (StringInit *SI = dyn_cast<StringInit>(DMName)) {
-      CI->DefaultMethod = SI->getValue();
+      CI->DefaultMethod = std::string(SI->getValue());
     } else {
       assert(isa<UnsetInit>(DMName) && "Unexpected DefaultMethod field!");
       CI->DefaultMethod = "default" + CI->ClassName + "Operands";
@@ -2601,7 +2601,7 @@
     if (Reg.TheDef->getValueAsString("AsmName").empty())
       continue;
 
-    Matches.emplace_back(Reg.TheDef->getValueAsString("AsmName"),
+    Matches.emplace_back(std::string(Reg.TheDef->getValueAsString("AsmName")),
                          "return " + utostr(Reg.EnumValue) + ";");
   }
 
@@ -2633,7 +2633,7 @@
       if (AltName.empty())
         continue;
 
-      Matches.emplace_back(AltName,
+      Matches.emplace_back(std::string(AltName),
                            "return " + utostr(Reg.EnumValue) + ";");
     }
   }
@@ -2729,7 +2729,8 @@
     StringRef AsmVariantName = R->getValueAsString("AsmVariantName");
     if (AsmVariantName != AsmParserVariantName)
       continue;
-    AliasesFromMnemonic[R->getValueAsString("FromMnemonic")].push_back(R);
+    AliasesFromMnemonic[std::string(R->getValueAsString("FromMnemonic"))]
+        .push_back(R);
   }
   if (AliasesFromMnemonic.empty())
     return;
@@ -3001,7 +3002,7 @@
                                           AsmMatcherInfo &Info,
                                           raw_ostream &OS) {
   std::string AsmParserName =
-      Info.AsmParser->getValueAsString("AsmParserClassName");
+      std::string(Info.AsmParser->getValueAsString("AsmParserClassName"));
   OS << "static bool ";
   OS << "checkAsmTiedOperandConstraints(const " << Target.getName()
      << AsmParserName << "&AsmParser,\n";
@@ -3862,7 +3863,7 @@
     OS << "    std::string Info;\n";
     OS << "    if (!getParser().getTargetParser().\n";
     OS << "        getTargetOptions().MCNoDeprecatedWarn &&\n";
-    OS << "        MII.get(Inst.getOpcode()).getDeprecatedInfo(Inst, getSTI(), Info)) {\n";
+    OS << "        MII.getDeprecatedInfo(Inst, getSTI(), Info)) {\n";
     OS << "      SMLoc Loc = ((" << Target.getName()
        << "Operand&)*Operands[0]).getStartLoc();\n";
     OS << "      getParser().Warning(Loc, Info, None);\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 58c0d32..d10ea71 100644
--- a/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -185,7 +185,7 @@
       InstIdxs[idx].push_back(i);
     } else {
       UniqueOperandCommands.push_back(std::move(Command));
-      InstrsForCase.push_back(Inst.CGI->TheDef->getName());
+      InstrsForCase.push_back(std::string(Inst.CGI->TheDef->getName()));
       InstIdxs.emplace_back();
       InstIdxs.back().push_back(i);
 
@@ -267,6 +267,27 @@
   }
 }
 
+/// UnescapeAliasString - Supports literal braces in InstAlias asm string which
+/// are escaped with '\\' to avoid being interpreted as variants. Braces must
+/// be unescaped before c++ code is generated as (e.g.):
+///
+///   AsmString = "foo \{$\x01\}";
+///
+/// causes non-standard escape character warnings.
+static void UnescapeAliasString(std::string &Str) {
+  for (unsigned i = 0; i != Str.size(); ++i) {
+    if (Str[i] == '\\' && i != Str.size()-1) {
+      switch (Str[i+1]) {
+      default: continue;  // Don't execute the code after the switch.
+      case '{': Str[i] = '{'; break;
+      case '}': Str[i] = '}'; break;
+      }
+      // Nuke the second character.
+      Str.erase(Str.begin()+i+1);
+    }
+  }
+}
+
 /// EmitPrintInstruction - Generate the code for the "printInstruction" method
 /// implementation. Destroys all instances of AsmWriterInst information, by
 /// clearing the Instructions vector.
@@ -380,9 +401,7 @@
   }
 
   // Emit the string table itself.
-  O << "  static const char AsmStrs[] = {\n";
-  StringTable.emit(O, printChar);
-  O << "  };\n\n";
+  StringTable.emitStringLiteralDef(O, "  static const char AsmStrs[]");
 
   // Emit the lookup tables in pieces to minimize wasted bytes.
   unsigned BytesNeeded = ((OpcodeInfoBits - BitsLeft) + 7) / 8;
@@ -509,9 +528,9 @@
     // "NoRegAltName" is special. We don't need to do a lookup for that,
     // as it's just a reference to the default register name.
     if (AltName == "" || AltName == "NoRegAltName") {
-      AsmName = Reg.TheDef->getValueAsString("AsmName");
+      AsmName = std::string(Reg.TheDef->getValueAsString("AsmName"));
       if (AsmName.empty())
-        AsmName = Reg.getName();
+        AsmName = std::string(Reg.getName());
     } else {
       // Make sure the register has an alternate name for this index.
       std::vector<Record*> AltNameList =
@@ -530,16 +549,15 @@
           PrintFatalError(Reg.TheDef->getLoc(),
                           "Register definition missing alt name for '" +
                           AltName + "'.");
-        AsmName = AltNames[Idx];
+        AsmName = std::string(AltNames[Idx]);
       }
     }
     StringTable.add(AsmName);
   }
 
   StringTable.layout();
-  O << "  static const char AsmStrs" << AltName << "[] = {\n";
-  StringTable.emit(O, printChar);
-  O << "  };\n\n";
+  StringTable.emitStringLiteralDef(O, Twine("  static const char AsmStrs") +
+                                          AltName + "[]");
 
   O << "  static const " << getMinimalTypeForRange(StringTable.size() - 1, 32)
     << " RegAsmOffset" << AltName << "[] = {";
@@ -786,7 +804,7 @@
   // before it can be matched to the mnemonic.
   std::map<std::string, std::vector<IAPrinter>> IAPrinterMap;
 
-  std::vector<std::string> PrintMethods;
+  std::vector<std::pair<std::string, bool>> PrintMethods;
 
   // A list of MCOperandPredicates for all operands in use, and the reverse map
   std::vector<const Record*> MCOpPredicates;
@@ -806,6 +824,7 @@
 
       std::string FlatAliasAsmString =
           CodeGenInstruction::FlattenAsmStringVariants(CGA.AsmString, Variant);
+      UnescapeAliasString(FlatAliasAsmString);
 
       // Don't emit the alias if it has more operands than what it's aliasing.
       if (NumResultOps < CountNumOperands(FlatAliasAsmString, Variant))
@@ -858,11 +877,16 @@
           if (Rec->isSubClassOf("RegisterOperand") ||
               Rec->isSubClassOf("Operand")) {
             StringRef PrintMethod = Rec->getValueAsString("PrintMethod");
+            bool IsPCRel =
+                Rec->getValueAsString("OperandType") == "OPERAND_PCREL";
             if (PrintMethod != "" && PrintMethod != "printOperand") {
-              PrintMethodIdx =
-                  llvm::find(PrintMethods, PrintMethod) - PrintMethods.begin();
+              PrintMethodIdx = llvm::find_if(PrintMethods,
+                                             [&](auto &X) {
+                                               return X.first == PrintMethod;
+                                             }) -
+                               PrintMethods.begin();
               if (static_cast<unsigned>(PrintMethodIdx) == PrintMethods.size())
-                PrintMethods.push_back(PrintMethod);
+                PrintMethods.emplace_back(std::string(PrintMethod), IsPCRel);
             }
           }
 
@@ -874,12 +898,12 @@
               Record *R = CGA.ResultOperands[i].getRecord();
               if (R->isSubClassOf("RegisterOperand"))
                 R = R->getValueAsDef("RegClass");
-              IAP.addCond(formatv(
-                  "AliasPatternCond::K_RegClass, {0}::{1}RegClassID", Namespace,
-                  R->getName()));
+              IAP.addCond(std::string(
+                  formatv("AliasPatternCond::K_RegClass, {0}::{1}RegClassID",
+                          Namespace, R->getName())));
             } else {
-              IAP.addCond(formatv("AliasPatternCond::K_TiedReg, {0}",
-                                  IAP.getOpIndex(ROName)));
+              IAP.addCond(std::string(formatv(
+                  "AliasPatternCond::K_TiedReg, {0}", IAP.getOpIndex(ROName))));
             }
           } else {
             // Assume all printable operands are desired for now. This can be
@@ -896,7 +920,8 @@
               } else
                 break; // No conditions on this operand at all
             }
-            IAP.addCond(formatv("AliasPatternCond::K_Custom, {0}", Entry));
+            IAP.addCond(
+                std::string(formatv("AliasPatternCond::K_Custom, {0}", Entry)));
           }
           break;
         }
@@ -908,7 +933,8 @@
           if (Imm != Imm32)
             PrintFatalError("Matching an alias with an immediate out of the "
                             "range of int32_t is not supported");
-          IAP.addCond(formatv("AliasPatternCond::K_Imm, uint32_t({0})", Imm32));
+          IAP.addCond(std::string(
+              formatv("AliasPatternCond::K_Imm, uint32_t({0})", Imm32)));
           break;
         }
         case CodeGenInstAlias::ResultOperand::K_Reg:
@@ -920,8 +946,8 @@
           }
 
           StringRef Reg = CGA.ResultOperands[i].getRegister()->getName();
-          IAP.addCond(
-              formatv("AliasPatternCond::K_Reg, {0}::{1}", Namespace, Reg));
+          IAP.addCond(std::string(
+              formatv("AliasPatternCond::K_Reg, {0}::{1}", Namespace, Reg)));
           break;
         }
 
@@ -942,20 +968,35 @@
 
       for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) {
         Record *R = *I;
-        StringRef AsmCondString = R->getValueAsString("AssemblerCondString");
+        const DagInit *D = R->getValueAsDag("AssemblerCondDag");
+        std::string CombineType = D->getOperator()->getAsString();
+        if (CombineType != "any_of" && CombineType != "all_of")
+          PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
+        if (D->getNumArgs() == 0)
+          PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
+        bool IsOr = CombineType == "any_of";
 
-        // AsmCondString has syntax [!]F(,[!]F)*
-        SmallVector<StringRef, 4> Ops;
-        SplitString(AsmCondString, Ops, ",");
-        assert(!Ops.empty() && "AssemblerCondString cannot be empty");
+        for (auto *Arg : D->getArgs()) {
+          bool IsNeg = false;
+          if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
+            if (NotArg->getOperator()->getAsString() != "not" ||
+                NotArg->getNumArgs() != 1)
+              PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
+            Arg = NotArg->getArg(0);
+            IsNeg = true;
+          }
+          if (!isa<DefInit>(Arg) ||
+              !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
+            PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
 
-        for (StringRef Op : Ops) {
-          assert(!Op.empty() && "Empty operator");
-          bool IsNeg = Op[0] == '!';
-          StringRef Feature = Op.drop_front(IsNeg ? 1 : 0);
-          IAP.addCond(formatv("AliasPatternCond::K_{0}Feature, {1}::{2}",
-                              IsNeg ? "Neg" : "", Namespace, Feature));
+          IAP.addCond(std::string(formatv(
+              "AliasPatternCond::K_{0}{1}Feature, {2}::{3}", IsOr ? "Or" : "",
+              IsNeg ? "Neg" : "", Namespace, Arg->getAsString())));
         }
+        // If an AssemblerPredicate with ors is used, note end of list should
+        // these be combined.
+        if (IsOr)
+          IAP.addCond("AliasPatternCond::K_EndOrFeatures, 0");
       }
 
       IAPrinterMap[Aliases.first].push_back(std::move(IAP));
@@ -971,7 +1012,8 @@
 
   HeaderO << "bool " << Target.getName() << ClassName
           << "::printAliasInstr(const MCInst"
-          << " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
+          << " *MI, uint64_t Address, "
+          << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
           << "raw_ostream &OS) {\n";
 
   std::string PatternsForOpcode;
@@ -1134,7 +1176,7 @@
   O << "          ++I;\n";
   O << "          int OpIdx = AsmString[I++] - 1;\n";
   O << "          int PrintMethodIdx = AsmString[I++] - 1;\n";
-  O << "          printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, ";
+  O << "          printCustomAliasOperand(MI, Address, OpIdx, PrintMethodIdx, ";
   O << (PassSubtarget ? "STI, " : "");
   O << "OS);\n";
   O << "        } else\n";
@@ -1156,7 +1198,7 @@
 
   O << "void " << Target.getName() << ClassName << "::"
     << "printCustomAliasOperand(\n"
-    << "         const MCInst *MI, unsigned OpIdx,\n"
+    << "         const MCInst *MI, uint64_t Address, unsigned OpIdx,\n"
     << "         unsigned PrintMethodIdx,\n"
     << (PassSubtarget ? "         const MCSubtargetInfo &STI,\n" : "")
     << "         raw_ostream &OS) {\n";
@@ -1170,7 +1212,8 @@
 
     for (unsigned i = 0; i < PrintMethods.size(); ++i) {
       O << "  case " << i << ":\n"
-        << "    " << PrintMethods[i] << "(MI, OpIdx, "
+        << "    " << PrintMethods[i].first << "(MI, "
+        << (PrintMethods[i].second ? "Address, " : "") << "OpIdx, "
         << (PassSubtarget ? "STI, " : "") << "OS);\n"
         << "    break;\n";
     }
diff --git a/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.cpp b/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.cpp
index c26e0e4..24d29ff 100644
--- a/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.cpp
@@ -36,6 +36,8 @@
     return Str;
 
   std::string Result = Str + "(MI";
+  if (PCRel)
+    Result += ", Address";
   if (MIOpNo != ~0U)
     Result += ", " + utostr(MIOpNo);
   if (PassSubtarget)
@@ -179,7 +181,9 @@
         CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo];
 
         unsigned MIOp = OpInfo.MIOperandNo;
-        Operands.emplace_back(OpInfo.PrinterMethodName, MIOp, Modifier);
+        Operands.emplace_back(OpInfo.PrinterMethodName, MIOp, Modifier,
+                              AsmWriterOperand::isMachineInstrOperand,
+                              OpInfo.OperandType == "MCOI::OPERAND_PCREL");
       }
       LastEmitted = VarEnd;
     }
diff --git a/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h b/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h
index a59112e..366c9ec 100644
--- a/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h
+++ b/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h
@@ -48,6 +48,8 @@
     /// an operand, specified with syntax like ${opname:modifier}.
     std::string MiModifier;
 
+    bool PCRel = false;
+
     // To make VS STL happy
     AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}
 
@@ -55,11 +57,11 @@
                      OpType op = isLiteralTextOperand)
     : OperandType(op), Str(LitStr) {}
 
-    AsmWriterOperand(const std::string &Printer,
-                     unsigned _MIOpNo,
+    AsmWriterOperand(const std::string &Printer, unsigned _MIOpNo,
                      const std::string &Modifier,
-                     OpType op = isMachineInstrOperand)
-    : OperandType(op), MIOpNo(_MIOpNo), Str(Printer), MiModifier(Modifier) {}
+                     OpType op = isMachineInstrOperand, bool PCRel = false)
+        : OperandType(op), MIOpNo(_MIOpNo), Str(Printer), MiModifier(Modifier),
+          PCRel(PCRel) {}
 
     bool operator!=(const AsmWriterOperand &Other) const {
       if (OperandType != Other.OperandType || Str != Other.Str) return true;
diff --git a/src/llvm-project/llvm/utils/TableGen/Attributes.cpp b/src/llvm-project/llvm/utils/TableGen/Attributes.cpp
index 6fbc595..f3f875e 100644
--- a/src/llvm-project/llvm/utils/TableGen/Attributes.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/Attributes.cpp
@@ -23,51 +23,41 @@
   void emit(raw_ostream &OS);
 
 private:
-  void emitTargetIndependentEnums(raw_ostream &OS);
-  void emitConversionFn(raw_ostream &OS);
+  void emitTargetIndependentNames(raw_ostream &OS);
   void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
 
-  void printEnumAttrClasses(raw_ostream &OS,
-                            const std::vector<Record *> &Records);
-  void printStrBoolAttrClasses(raw_ostream &OS,
-                               const std::vector<Record *> &Records);
-
   RecordKeeper &Records;
 };
 
 } // End anonymous namespace.
 
-void Attributes::emitTargetIndependentEnums(raw_ostream &OS) {
-  OS << "#ifdef GET_ATTR_ENUM\n";
-  OS << "#undef GET_ATTR_ENUM\n";
+void Attributes::emitTargetIndependentNames(raw_ostream &OS) {
+  OS << "#ifdef GET_ATTR_NAMES\n";
+  OS << "#undef GET_ATTR_NAMES\n";
 
-  std::vector<Record*> Attrs =
-      Records.getAllDerivedDefinitions("EnumAttr");
+  OS << "#ifndef ATTRIBUTE_ALL\n";
+  OS << "#define ATTRIBUTE_ALL(FIRST, SECOND)\n";
+  OS << "#endif\n\n";
 
-  for (auto A : Attrs)
-    OS << A->getName() << ",\n";
+  auto Emit = [&](ArrayRef<StringRef> KindNames, StringRef MacroName) {
+    OS << "#ifndef " << MacroName << "\n";
+    OS << "#define " << MacroName
+       << "(FIRST, SECOND) ATTRIBUTE_ALL(FIRST, SECOND)\n";
+    OS << "#endif\n\n";
+    for (StringRef KindName : KindNames) {
+      for (auto A : Records.getAllDerivedDefinitions(KindName)) {
+        OS << MacroName << "(" << A->getName() << ","
+           << A->getValueAsString("AttrString") << ")\n";
+      }
+    }
+    OS << "#undef " << MacroName << "\n\n";
+  };
 
-  OS << "#endif\n";
-}
+  // Emit attribute enums in the same order llvm::Attribute::operator< expects.
+  Emit({"EnumAttr", "TypeAttr", "IntAttr"}, "ATTRIBUTE_ENUM");
+  Emit({"StrBoolAttr"}, "ATTRIBUTE_STRBOOL");
 
-void Attributes::emitConversionFn(raw_ostream &OS) {
-  OS << "#ifdef GET_ATTR_KIND_FROM_NAME\n";
-  OS << "#undef GET_ATTR_KIND_FROM_NAME\n";
-
-  std::vector<Record*> Attrs =
-      Records.getAllDerivedDefinitions("EnumAttr");
-
-  OS << "static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {\n";
-  OS << "  return StringSwitch<Attribute::AttrKind>(AttrName)\n";
-
-  for (auto A : Attrs) {
-    OS << "    .Case(\"" << A->getValueAsString("AttrString");
-    OS << "\", Attribute::" << A->getName() << ")\n";
-  }
-
-  OS << "    .Default(Attribute::None);\n";
-  OS << "}\n\n";
-
+  OS << "#undef ATTRIBUTE_ALL\n";
   OS << "#endif\n";
 }
 
@@ -75,35 +65,6 @@
   OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
   OS << "#undef GET_ATTR_COMPAT_FUNC\n";
 
-  OS << "struct EnumAttr {\n";
-  OS << "  static bool isSet(const Function &Fn,\n";
-  OS << "                    Attribute::AttrKind Kind) {\n";
-  OS << "    return Fn.hasFnAttribute(Kind);\n";
-  OS << "  }\n\n";
-  OS << "  static void set(Function &Fn,\n";
-  OS << "                  Attribute::AttrKind Kind, bool Val) {\n";
-  OS << "    if (Val)\n";
-  OS << "      Fn.addFnAttr(Kind);\n";
-  OS << "    else\n";
-  OS << "      Fn.removeFnAttr(Kind);\n";
-  OS << "  }\n";
-  OS << "};\n\n";
-
-  OS << "struct StrBoolAttr {\n";
-  OS << "  static bool isSet(const Function &Fn,\n";
-  OS << "                    StringRef Kind) {\n";
-  OS << "    auto A = Fn.getFnAttribute(Kind);\n";
-  OS << "    return A.getValueAsString().equals(\"true\");\n";
-  OS << "  }\n\n";
-  OS << "  static void set(Function &Fn,\n";
-  OS << "                  StringRef Kind, bool Val) {\n";
-  OS << "    Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n";
-  OS << "  }\n";
-  OS << "};\n\n";
-
-  printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr"));
-  printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr"));
-
   OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
      << "                                        const Function &Callee) {\n";
   OS << "  bool Ret = true;\n\n";
@@ -135,35 +96,8 @@
   OS << "#endif\n";
 }
 
-void Attributes::printEnumAttrClasses(raw_ostream &OS,
-                                      const std::vector<Record *> &Records) {
-  OS << "// EnumAttr classes\n";
-  for (const auto *R : Records) {
-    OS << "struct " << R->getName() << "Attr : EnumAttr {\n";
-    OS << "  static enum Attribute::AttrKind getKind() {\n";
-    OS << "    return llvm::Attribute::" << R->getName() << ";\n";
-    OS << "  }\n";
-    OS << "};\n";
-  }
-  OS << "\n";
-}
-
-void Attributes::printStrBoolAttrClasses(raw_ostream &OS,
-                                         const std::vector<Record *> &Records) {
-  OS << "// StrBoolAttr classes\n";
-  for (const auto *R : Records) {
-    OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n";
-    OS << "  static StringRef getKind() {\n";
-    OS << "    return \"" << R->getValueAsString("AttrString") << "\";\n";
-    OS << "  }\n";
-    OS << "};\n";
-  }
-  OS << "\n";
-}
-
 void Attributes::emit(raw_ostream &OS) {
-  emitTargetIndependentEnums(OS);
-  emitConversionFn(OS);
+  emitTargetIndependentNames(OS);
   emitFnAttrCompatCheck(OS, false);
 }
 
diff --git a/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt b/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt
index dbca62c..8673a25 100644
--- a/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt
+++ b/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt
@@ -23,6 +23,7 @@
   DAGISelMatcher.cpp
   DFAEmitter.cpp
   DFAPacketizerEmitter.cpp
+  DirectiveEmitter.cpp
   DisassemblerEmitter.cpp
   ExegesisEmitter.cpp
   FastISelEmitter.cpp
diff --git a/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp
index 9eabb44..a4e993f 100644
--- a/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp
@@ -197,11 +197,12 @@
              "getTypeAllocSize(EVT(LocVT).getTypeForEVT(State.getContext())),"
              " ";
       if (Align)
-        O << Align;
+        O << "Align(" << Align << ")";
       else
-        O << "\n" << IndentStr
+        O << "\n"
+          << IndentStr
           << "  State.getMachineFunction().getDataLayout()."
-             "getABITypeAlignment(EVT(LocVT).getTypeForEVT(State.getContext()"
+             "getABITypeAlign(EVT(LocVT).getTypeForEVT(State.getContext()"
              "))";
       O << ");\n" << IndentStr
         << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
@@ -224,8 +225,7 @@
       O << "\n" << IndentStr << "};\n";
 
       O << IndentStr << "unsigned Offset" << ++Counter
-        << " = State.AllocateStack("
-        << Size << ", " << Align << ", "
+        << " = State.AllocateStack(" << Size << ", Align(" << Align << "), "
         << "ShadowRegList" << ShadowRegListNumber << ");\n";
       O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
         << Counter << ", LocVT, LocInfo));\n";
@@ -275,9 +275,8 @@
     } else if (Action->isSubClassOf("CCPassByVal")) {
       int Size = Action->getValueAsInt("Size");
       int Align = Action->getValueAsInt("Align");
-      O << IndentStr
-        << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, "
-        << Size << ", " << Align << ", ArgFlags);\n";
+      O << IndentStr << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, "
+        << Size << ", Align(" << Align << "), ArgFlags);\n";
       O << IndentStr << "return false;\n";
     } else if (Action->isSubClassOf("CCCustom")) {
       O << IndentStr
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp b/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp
index 68cb8f1..6338d44 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp
@@ -313,8 +313,8 @@
     //    bits<5> RST = { ?, ?, ?, ?, ? };
     if (RV.getPrefix() || RV.getValue()->isComplete())
       continue;
-    
-    AddCodeToMergeInOperand(R, BI, RV.getName(), NumberedOp,
+
+    AddCodeToMergeInOperand(R, BI, std::string(RV.getName()), NumberedOp,
                             NamedOpIndices, Case, Target);
   }
 
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index 7e0ba98..6fdc116 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -277,7 +277,7 @@
 
   // Compute the intersection of scalars separately to account for only
   // one set containing iPTR.
-  // The itersection of iPTR with a set of integer scalar types that does not
+  // The intersection of iPTR with a set of integer scalar types that does not
   // include iPTR will result in the most specific scalar type:
   // - iPTR is more specific than any set with two elements or more
   // - iPTR is less specific than any single integer scalar type.
@@ -999,9 +999,9 @@
 
     int64_t MinAlign = getMinAlignment();
     if (MinAlign > 0) {
-      Code += "if (cast<MemSDNode>(N)->getAlignment() < ";
+      Code += "if (cast<MemSDNode>(N)->getAlign() < Align(";
       Code += utostr(MinAlign);
-      Code += ")\nreturn false;\n";
+      Code += "))\nreturn false;\n";
     }
 
     Record *MemoryVT = getMemoryVT();
@@ -1091,7 +1091,8 @@
                   .str();
   }
 
-  std::string PredicateCode = PatFragRec->getRecord()->getValueAsString("PredicateCode");
+  std::string PredicateCode =
+      std::string(PatFragRec->getRecord()->getValueAsString("PredicateCode"));
 
   Code += PredicateCode;
 
@@ -1106,7 +1107,8 @@
 }
 
 std::string TreePredicateFn::getImmCode() const {
-  return PatFragRec->getRecord()->getValueAsString("ImmediateCode");
+  return std::string(
+      PatFragRec->getRecord()->getValueAsString("ImmediateCode"));
 }
 
 bool TreePredicateFn::immCodeUsesAPInt() const {
@@ -1223,7 +1225,8 @@
               .empty();
 }
 std::string TreePredicateFn::getGISelPredicateCode() const {
-  return PatFragRec->getRecord()->getValueAsString("GISelPredicateCode");
+  return std::string(
+      PatFragRec->getRecord()->getValueAsString("GISelPredicateCode"));
 }
 
 StringRef TreePredicateFn::getImmType() const {
@@ -2517,6 +2520,9 @@
       }
     }
 
+    unsigned NumResults = Inst.getNumResults();
+    unsigned NumFixedOperands = InstInfo.Operands.size();
+
     // If one or more operands with a default value appear at the end of the
     // formal operand list for an instruction, we allow them to be overridden
     // by optional operands provided in the pattern.
@@ -2525,14 +2531,15 @@
     // operand A with a default, then we don't allow A to be overridden,
     // because there would be no way to specify whether the next operand in
     // the pattern was intended to override A or skip it.
-    unsigned NonOverridableOperands = Inst.getNumOperands();
-    while (NonOverridableOperands > 0 &&
-           CDP.operandHasDefault(Inst.getOperand(NonOverridableOperands-1)))
+    unsigned NonOverridableOperands = NumFixedOperands;
+    while (NonOverridableOperands > NumResults &&
+           CDP.operandHasDefault(InstInfo.Operands[NonOverridableOperands-1].Rec))
       --NonOverridableOperands;
 
     unsigned ChildNo = 0;
-    for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
-      Record *OperandNode = Inst.getOperand(i);
+    assert(NumResults <= NumFixedOperands);
+    for (unsigned i = NumResults, e = NumFixedOperands; i != e; ++i) {
+      Record *OperandNode = InstInfo.Operands[i].Rec;
 
       // If the operand has a default value, do we use it? We must use the
       // default if we've run out of children of the pattern DAG to consume,
@@ -2741,7 +2748,7 @@
     if (R->getName() == "node" && !OpName.empty()) {
       if (OpName.empty())
         error("'node' argument requires a name to match with operand list");
-      Args.push_back(OpName);
+      Args.push_back(std::string(OpName));
     }
 
     Res->setName(OpName);
@@ -2753,7 +2760,7 @@
     if (OpName.empty())
       error("'?' argument requires a name to match with operand list");
     TreePatternNodePtr Res = std::make_shared<TreePatternNode>(TheInit, 1);
-    Args.push_back(OpName);
+    Args.push_back(std::string(OpName));
     Res->setName(OpName);
     return Res;
   }
@@ -2915,8 +2922,15 @@
 
   // If we have a bitconvert with a resolved type and if the source and
   // destination types are the same, then the bitconvert is useless, remove it.
+  //
+  // We make an exception if the types are completely empty. This can come up
+  // when the pattern being simplified is in the Fragments list of a PatFrags,
+  // so that the operand is just an untyped "node". In that situation we leave
+  // bitconverts unsimplified, and simplify them later once the fragment is
+  // expanded into its true context.
   if (N->getOperator()->getName() == "bitconvert" &&
       N->getExtType(0).isValueTypeByHwMode(false) &&
+      !N->getExtType(0).empty() &&
       N->getExtType(0) == N->getChild(0)->getExtType(0) &&
       N->getName().empty()) {
     N = N->getChildShared(0);
@@ -3105,7 +3119,8 @@
     Record *XFormNode = Xforms.back();
     Record *SDNode = XFormNode->getValueAsDef("Opcode");
     StringRef Code = XFormNode->getValueAsString("XFormFunction");
-    SDNodeXForms.insert(std::make_pair(XFormNode, NodeXForm(SDNode, Code)));
+    SDNodeXForms.insert(
+        std::make_pair(XFormNode, NodeXForm(SDNode, std::string(Code))));
 
     Xforms.pop_back();
   }
@@ -3173,7 +3188,7 @@
         P->error("'" + ArgNameStr +
                  "' does not occur in pattern or was multiply specified!");
       OperandsSet.erase(ArgNameStr);
-      Args.push_back(ArgNameStr);
+      Args.push_back(std::string(ArgNameStr));
     }
 
     if (!OperandsSet.empty())
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h
index 2c081b6..a3b84d7 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h
@@ -430,7 +430,7 @@
   std::string Identifier;
 public:
   ScopedName(unsigned Scope, StringRef Identifier)
-    : Scope(Scope), Identifier(Identifier) {
+      : Scope(Scope), Identifier(std::string(Identifier)) {
     assert(Scope != 0 &&
            "Scope == 0 is used to indicate predicates without arguments");
   }
@@ -1075,8 +1075,9 @@
     // The string will excute in a subclass of SelectionDAGISel.
     // Cast to std::string explicitly to avoid ambiguity with StringRef.
     std::string C = IsHwMode
-        ? std::string("MF->getSubtarget().checkFeatures(\"" + Features + "\")")
-        : std::string(Def->getValueAsString("CondString"));
+                        ? std::string("MF->getSubtarget().checkFeatures(\"" +
+                                      Features + "\")")
+                        : std::string(Def->getValueAsString("CondString"));
     if (C.empty())
       return "";
     return IfCond ? C : "!("+C+')';
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.cpp
index 9052cdd..2fec46c 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.cpp
@@ -20,7 +20,7 @@
 
 HwMode::HwMode(Record *R) {
   Name = R->getName();
-  Features = R->getValueAsString("Features");
+  Features = std::string(R->getValueAsString("Features"));
 }
 
 LLVM_DUMP_METHOD
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.h b/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.h
index 1ff2faa..55507cb 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenHwModes.h
@@ -12,6 +12,7 @@
 #define LLVM_UTILS_TABLEGEN_CODEGENHWMODES_H
 
 #include "llvm/ADT/StringMap.h"
+#include <cassert>
 #include <map>
 #include <string>
 #include <vector>
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp
index 6bb4dbb..1df5902 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp
@@ -56,6 +56,7 @@
   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;
@@ -80,16 +81,16 @@
     unsigned NumOps = 1;
     DagInit *MIOpInfo = nullptr;
     if (Rec->isSubClassOf("RegisterOperand")) {
-      PrintMethod = Rec->getValueAsString("PrintMethod");
-      OperandType = Rec->getValueAsString("OperandType");
-      OperandNamespace = Rec->getValueAsString("OperandNamespace");
-      EncoderMethod = Rec->getValueAsString("EncoderMethod");
+      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 = Rec->getValueAsString("PrintMethod");
-      OperandType = Rec->getValueAsString("OperandType");
-      OperandNamespace = Rec->getValueAsString("OperandNamespace");
+      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 = Rec->getValueAsString("EncoderMethod");
+      EncoderMethod = std::string(Rec->getValueAsString("EncoderMethod"));
       MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
 
       // Verify that MIOpInfo has an 'ops' root value.
@@ -109,6 +110,8 @@
       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")) {
@@ -124,18 +127,21 @@
       PrintFatalError(R->getLoc(), "In instruction '" + R->getName() +
                                        "', operand #" + Twine(i) +
                                        " has no name!");
-    if (!OperandNames.insert(ArgName).second)
+    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!");
 
-    OperandList.emplace_back(Rec, ArgName, PrintMethod, EncoderMethod,
-                             OperandNamespace + "::" + OperandType, MIOperandNo,
-                             NumOps, MIOpInfo);
+    OperandList.emplace_back(
+        Rec, std::string(ArgName), std::string(PrintMethod),
+        std::string(EncoderMethod), OperandNamespace + "::" + OperandType,
+        MIOperandNo, NumOps, MIOpInfo);
     MIOperandNo += NumOps;
   }
 
+  if (VariadicOuts)
+    --NumDefs;
 
   // Make sure the constraints list for each operand is large enough to hold
   // constraint info, even if none is present.
@@ -265,7 +271,8 @@
     PrintFatalError(
       Rec->getLoc(), "Illegal format for tied-to constraint in '" +
       Rec->getName() + "': '" + CStr + "'");
-  std::string LHSOpName = StringRef(CStr).substr(start, wpos - start);
+  std::string LHSOpName =
+      std::string(StringRef(CStr).substr(start, wpos - start));
   std::pair<unsigned,unsigned> LHSOp = Ops.ParseOperandName(LHSOpName, false);
 
   wpos = CStr.find_first_not_of(" \t", pos + 1);
@@ -273,7 +280,7 @@
     PrintFatalError(
       Rec->getLoc(), "Illegal format for tied-to constraint: '" + CStr + "'");
 
-  std::string RHSOpName = StringRef(CStr).substr(wpos);
+  std::string RHSOpName = std::string(StringRef(CStr).substr(wpos));
   std::pair<unsigned,unsigned> RHSOp = Ops.ParseOperandName(RHSOpName, false);
 
   // Sort the operands into order, which should put the output one
@@ -339,8 +346,8 @@
 void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) {
   while (1) {
     std::pair<StringRef, StringRef> P = getToken(DisableEncoding, " ,\t");
-    std::string OpName = P.first;
-    DisableEncoding = P.second;
+    std::string OpName = std::string(P.first);
+    DisableEncoding = std::string(P.second);
     if (OpName.empty()) break;
 
     // Figure out which operand this is.
@@ -361,7 +368,7 @@
 CodeGenInstruction::CodeGenInstruction(Record *R)
   : TheDef(R), Operands(R), InferredFrom(nullptr) {
   Namespace = R->getValueAsString("Namespace");
-  AsmString = R->getValueAsString("AsmString");
+  AsmString = std::string(R->getValueAsString("AsmString"));
 
   isPreISelOpcode = R->getValueAsBit("isPreISelOpcode");
   isReturn     = R->getValueAsBit("isReturn");
@@ -420,15 +427,18 @@
   hasChain_Inferred = false;
 
   // Parse Constraints.
-  ParseConstraints(R->getValueAsString("Constraints"), Operands, R);
+  ParseConstraints(std::string(R->getValueAsString("Constraints")), Operands,
+                   R);
 
   // Parse the DisableEncoding field.
-  Operands.ProcessDisableEncoding(R->getValueAsString("DisableEncoding"));
+  Operands.ProcessDisableEncoding(
+      std::string(R->getValueAsString("DisableEncoding")));
 
   // First check for a ComplexDeprecationPredicate.
   if (R->getValue("ComplexDeprecationPredicate")) {
     HasComplexDeprecationPredicate = true;
-    DeprecatedReason = R->getValueAsString("ComplexDeprecationPredicate");
+    DeprecatedReason =
+        std::string(R->getValueAsString("ComplexDeprecationPredicate"));
   } else if (RecordVal *Dep = R->getValue("DeprecatedFeatureMask")) {
     // Check if we have a Subtarget feature mask.
     HasComplexDeprecationPredicate = false;
@@ -541,7 +551,8 @@
     if (!Result->getArgName(AliasOpNo))
       PrintFatalError(Loc, "result argument #" + Twine(AliasOpNo) +
                            " must have a name!");
-    ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo), ResultRecord);
+    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
+                          ResultRecord);
     return true;
   }
 
@@ -559,7 +570,8 @@
     if (!T.getRegisterClass(InstOpRec)
               .hasSubClass(&T.getRegisterClass(ADI->getDef())))
       return false;
-    ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo), ResultRecord);
+    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
+                          ResultRecord);
     return true;
   }
 
@@ -641,7 +653,8 @@
     // MIOperandInfo perhaps?
     if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
       return false;
-    ResOp = ResultOperand(Result->getArgNameStr(AliasOpNo), ADI->getDef());
+    ResOp = ResultOperand(std::string(Result->getArgNameStr(AliasOpNo)),
+                          ADI->getDef());
     return true;
   }
 
@@ -668,8 +681,7 @@
 CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
     : TheDef(R) {
   Result = R->getValueAsDag("ResultInst");
-  AsmString = R->getValueAsString("AsmString");
-
+  AsmString = std::string(R->getValueAsString("AsmString"));
 
   // Verify that the root of the result is an instruction.
   DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h
index 1f08ce4..af851a1 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h
@@ -16,6 +16,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MachineValueType.h"
 #include "llvm/Support/SMLoc.h"
+#include <cassert>
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h b/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h
index 723bbe0..af59c1f 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h
@@ -123,6 +123,12 @@
   /// True if the intrinsic is no-return.
   bool isNoReturn;
 
+  /// True if the intrinsic is no-sync.
+  bool isNoSync;
+
+  /// True if the intrinsic is no-free.
+  bool isNoFree;
+
   /// True if the intrinsic is will-return.
   bool isWillReturn;
 
@@ -139,17 +145,32 @@
   // True if the intrinsic is marked as speculatable.
   bool isSpeculatable;
 
-  enum ArgAttribute {
+  enum ArgAttrKind {
     NoCapture,
     NoAlias,
     Returned,
     ReadOnly,
     WriteOnly,
     ReadNone,
-    ImmArg
+    ImmArg,
+    Alignment
   };
 
-  std::vector<std::pair<unsigned, ArgAttribute>> ArgumentAttributes;
+  struct ArgAttribute {
+    unsigned Index;
+    ArgAttrKind Kind;
+    uint64_t Value;
+
+    ArgAttribute(unsigned Idx, ArgAttrKind K, uint64_t V)
+        : Index(Idx), Kind(K), Value(V) {}
+
+    bool operator<(const ArgAttribute &Other) const {
+      return std::tie(Index, Kind, Value) <
+             std::tie(Other.Index, Other.Kind, Other.Value);
+    }
+  };
+
+  std::vector<ArgAttribute> ArgumentAttributes;
 
   bool hasProperty(enum SDNP Prop) const {
     return Properties & (1 << Prop);
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp
index 793bb61..baca076 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp
@@ -98,7 +98,7 @@
 
 public:
   InstrMap(Record* MapRec) {
-    Name = MapRec->getName();
+    Name = std::string(MapRec->getName());
 
     // FilterClass - It's used to reduce the search space only to the
     // instructions that define the kind of relationship modeled by
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp
index 6153c75..4584bc7 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp
@@ -52,18 +52,18 @@
 
 CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
   : TheDef(R), EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) {
-  Name = R->getName();
+  Name = std::string(R->getName());
   if (R->getValue("Namespace"))
-    Namespace = R->getValueAsString("Namespace");
+    Namespace = std::string(R->getValueAsString("Namespace"));
   Size = R->getValueAsInt("Size");
   Offset = R->getValueAsInt("Offset");
 }
 
 CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
                                        unsigned Enum)
-  : TheDef(nullptr), Name(N), Namespace(Nspace), Size(-1), Offset(-1),
-    EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) {
-}
+    : TheDef(nullptr), Name(std::string(N)), Namespace(std::string(Nspace)),
+      Size(-1), Offset(-1), EnumValue(Enum), AllSuperRegsCovered(true),
+      Artificial(true) {}
 
 std::string CodeGenSubRegIndex::getQualifiedName() const {
   std::string N = getNamespace();
@@ -739,11 +739,9 @@
 }
 
 CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
-  : TheDef(R),
-    Name(R->getName()),
-    TopoSigs(RegBank.getNumTopoSigs()),
-    EnumValue(-1) {
-
+    : TheDef(R), Name(std::string(R->getName())),
+      TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1) {
+  GeneratePressureSet = R->getValueAsBit("GeneratePressureSet");
   std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
   for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
     Record *Type = TypeList[i];
@@ -816,16 +814,11 @@
 // class structure has been computed.
 CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
                                            StringRef Name, Key Props)
-  : Members(*Props.Members),
-    TheDef(nullptr),
-    Name(Name),
-    TopoSigs(RegBank.getNumTopoSigs()),
-    EnumValue(-1),
-    RSI(Props.RSI),
-    CopyCost(0),
-    Allocatable(true),
-    AllocationPriority(0) {
+    : Members(*Props.Members), TheDef(nullptr), Name(std::string(Name)),
+      TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI),
+      CopyCost(0), Allocatable(true), AllocationPriority(0) {
   Artificial = true;
+  GeneratePressureSet = false;
   for (const auto R : Members) {
     TopoSigs.set(R->getTopoSig());
     Artificial &= R->Artificial;
@@ -848,6 +841,7 @@
   Allocatable = Super.Allocatable;
   AltOrderSelect = Super.AltOrderSelect;
   AllocationPriority = Super.AllocationPriority;
+  GeneratePressureSet |= Super.GeneratePressureSet;
 
   // Copy all allocation orders, filter out foreign registers from the larger
   // super-class.
@@ -863,6 +857,16 @@
                             deref<std::less<>>());
 }
 
+unsigned CodeGenRegisterClass::getWeight(const CodeGenRegBank& RegBank) const {
+  if (TheDef && !TheDef->isValueUnset("Weight"))
+    return TheDef->getValueAsInt("Weight");
+
+  if (Members.empty() || Artificial)
+    return 0;
+
+  return (*Members.begin())->getWeight(RegBank);
+}
+
 namespace llvm {
 
   raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) {
@@ -990,8 +994,12 @@
 Optional<std::pair<CodeGenRegisterClass *, CodeGenRegisterClass *>>
 CodeGenRegisterClass::getMatchingSubClassWithSubRegs(
     CodeGenRegBank &RegBank, const CodeGenSubRegIndex *SubIdx) const {
-  auto SizeOrder = [](const CodeGenRegisterClass *A,
+  auto SizeOrder = [this](const CodeGenRegisterClass *A,
                       const CodeGenRegisterClass *B) {
+    // If there are multiple, identical register classes, prefer the original
+    // register class.
+    if (A->getMembers().size() == B->getMembers().size())
+      return A == this;
     return A->getMembers().size() > B->getMembers().size();
   };
 
@@ -1007,8 +1015,10 @@
   for (auto &RC : RegClasses)
     if (SuperRegRCsBV[RC.EnumValue])
       SuperRegRCs.emplace_back(&RC);
-  llvm::sort(SuperRegRCs, SizeOrder);
-  assert(SuperRegRCs.front() == BiggestSuperRegRC && "Biggest class wasn't first");
+  llvm::stable_sort(SuperRegRCs, SizeOrder);
+
+  assert(SuperRegRCs.front() == BiggestSuperRegRC &&
+         "Biggest class wasn't first");
 
   // Find all the subreg classes and order them by size too.
   std::vector<std::pair<CodeGenRegisterClass *, BitVector>> SuperRegClasses;
@@ -1223,6 +1233,12 @@
   return Idx;
 }
 
+const CodeGenSubRegIndex *
+CodeGenRegBank::findSubRegIdx(const Record* Def) const {
+  auto I = Def2SubRegIdx.find(Def);
+  return (I == Def2SubRegIdx.end()) ? nullptr : I->second;
+}
+
 CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
   CodeGenRegister *&Reg = Def2Reg[Def];
   if (Reg)
@@ -1259,8 +1275,8 @@
   return &RegClasses.back();
 }
 
-CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) {
-  if (CodeGenRegisterClass *RC = Def2RC[Def])
+CodeGenRegisterClass *CodeGenRegBank::getRegClass(const Record *Def) const {
+  if (CodeGenRegisterClass *RC = Def2RC.lookup(Def))
     return RC;
 
   PrintFatalError(Def->getLoc(), "Not a known RegisterClass!");
@@ -1879,7 +1895,7 @@
   // Compute a unique RegUnitSet for each RegClass.
   auto &RegClasses = getRegClasses();
   for (auto &RC : RegClasses) {
-    if (!RC.Allocatable || RC.Artificial)
+    if (!RC.Allocatable || RC.Artificial || !RC.GeneratePressureSet)
       continue;
 
     // Speculatively grow the RegUnitSets to hold the new set.
@@ -1940,7 +1956,7 @@
       // Speculatively grow the RegUnitSets to hold the new set.
       RegUnitSets.resize(RegUnitSets.size() + 1);
       RegUnitSets.back().Name =
-        RegUnitSets[Idx].Name + "+" + RegUnitSets[SearchIdx].Name;
+        RegUnitSets[Idx].Name + "_with_" + RegUnitSets[SearchIdx].Name;
 
       std::set_union(RegUnitSets[Idx].Units.begin(),
                      RegUnitSets[Idx].Units.end(),
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h
index a8e9e0f..2b200ad 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h
@@ -86,6 +86,7 @@
 
     CodeGenSubRegIndex(Record *R, unsigned Enum);
     CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
+    CodeGenSubRegIndex(CodeGenSubRegIndex&) = delete;
 
     const std::string &getName() const { return Name; }
     const std::string &getNamespace() const { return Namespace; }
@@ -338,6 +339,9 @@
     bool CoveredBySubRegs;
     /// A register class is artificial if all its members are artificial.
     bool Artificial;
+    /// Generate register pressure set for this register class and any class
+    /// synthesized from it.
+    bool GeneratePressureSet;
 
     // Return the Record that defined this class, or NULL if the class was
     // created by TableGen.
@@ -437,11 +441,15 @@
     // Get a bit vector of TopoSigs present in this register class.
     const BitVector &getTopoSigs() const { return TopoSigs; }
 
+    // Get a weight of this register class.
+    unsigned getWeight(const CodeGenRegBank&) const;
+
     // Populate a unique sorted list of units from a register set.
     void buildRegUnitSet(const CodeGenRegBank &RegBank,
                          std::vector<unsigned> &RegUnits) const;
 
     CodeGenRegisterClass(CodeGenRegBank&, Record *R);
+    CodeGenRegisterClass(CodeGenRegisterClass&) = delete;
 
     // A key representing the parts of a register class used for forming
     // sub-classes.  Note the ordering provided by this key is not the same as
@@ -611,6 +619,7 @@
 
   public:
     CodeGenRegBank(RecordKeeper&, const CodeGenHwModes&);
+    CodeGenRegBank(CodeGenRegBank&) = delete;
 
     SetTheory &getSets() { return Sets; }
 
@@ -623,9 +632,13 @@
       return SubRegIndices;
     }
 
-    // Find a SubRegIndex form its Record def.
+    // Find a SubRegIndex from its Record def or add to the list if it does
+    // not exist there yet.
     CodeGenSubRegIndex *getSubRegIdx(Record*);
 
+    // Find a SubRegIndex from its Record def.
+    const CodeGenSubRegIndex *findSubRegIdx(const Record* Def) const;
+
     // Find or create a sub-register index representing the A+B composition.
     CodeGenSubRegIndex *getCompositeSubRegIndex(CodeGenSubRegIndex *A,
                                                 CodeGenSubRegIndex *B);
@@ -706,7 +719,7 @@
     }
 
     // Find a register class from its def.
-    CodeGenRegisterClass *getRegClass(Record*);
+    CodeGenRegisterClass *getRegClass(const Record *) const;
 
     /// getRegisterClassForRegister - Find the register class that contains the
     /// specified physical register.  If the register is not in a register
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp
index f12d7d4..67583c7 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -106,7 +106,7 @@
       StringRef PatStr = Original.substr(FirstMeta);
       if (!PatStr.empty()) {
         // For the rest use a python-style prefix match.
-        std::string pat = PatStr;
+        std::string pat = std::string(PatStr);
         if (pat[0] != '^') {
           pat.insert(0, "^(");
           pat.insert(pat.end(), ')');
@@ -546,7 +546,7 @@
   if (!ProcModelMap.insert(std::make_pair(ModelKey, ProcModels.size())).second)
     return;
 
-  std::string Name = ModelKey->getName();
+  std::string Name = std::string(ModelKey->getName());
   if (ModelKey->isSubClassOf("SchedMachineModel")) {
     Record *ItinsDef = ModelKey->getValueAsDef("Itineraries");
     ProcModels.emplace_back(ProcModels.size(), Name, ModelKey, ItinsDef);
@@ -977,7 +977,7 @@
 
   std::string Name;
   if (ItinClassDef && ItinClassDef->getName() != "NoItinerary")
-    Name = ItinClassDef->getName();
+    Name = std::string(ItinClassDef->getName());
   for (unsigned Idx : OperWrites) {
     if (!Name.empty())
       Name += '_';
@@ -1082,15 +1082,14 @@
           for (Record *RWD : RWDefs) {
             if (RWD->getValueAsDef("SchedModel") == RWModelDef &&
                 RWModelDef->getValueAsBit("FullInstRWOverlapCheck")) {
-              for (Record *Inst : InstDefs) {
-                PrintFatalError
-                    (InstRWDef->getLoc(),
-                     "Overlapping InstRW definition for \"" +
-                     Inst->getName() +
-                     "\" also matches previous \"" +
-                     RWD->getValue("Instrs")->getValue()->getAsString() +
-                     "\".");
-              }
+              assert(!InstDefs.empty()); // Checked at function start.
+              PrintFatalError
+                  (InstRWDef->getLoc(),
+                   "Overlapping InstRW definition for \"" +
+                   InstDefs.front()->getName() +
+                   "\" also matches previous \"" +
+                   RWD->getValue("Instrs")->getValue()->getAsString() +
+                   "\".");
             }
           }
           LLVM_DEBUG(dbgs() << "InstRW: Reuse SC " << OldSCIdx << ":"
@@ -1118,15 +1117,14 @@
       Record *RWModelDef = InstRWDef->getValueAsDef("SchedModel");
       for (Record *OldRWDef : SchedClasses[OldSCIdx].InstRWs) {
         if (OldRWDef->getValueAsDef("SchedModel") == RWModelDef) {
-          for (Record *InstDef : InstDefs) {
-            PrintFatalError
-                (InstRWDef->getLoc(),
-                 "Overlapping InstRW definition for \"" +
-                 InstDef->getName() +
-                 "\" also matches previous \"" +
-                 OldRWDef->getValue("Instrs")->getValue()->getAsString() +
-                 "\".");
-          }
+          assert(!InstDefs.empty()); // Checked at function start.
+          PrintFatalError
+              (InstRWDef->getLoc(),
+               "Overlapping InstRW definition for \"" +
+               InstDefs.front()->getName() +
+               "\" also matches previous \"" +
+               OldRWDef->getValue("Instrs")->getValue()->getAsString() +
+               "\".");
         }
         assert(OldRWDef != InstRWDef &&
                "SchedClass has duplicate InstRW def");
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.h b/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.h
index c26fb1f..c487d14 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.h
@@ -58,7 +58,7 @@
       HasVariants(false), IsVariadic(false), IsSequence(false) {}
   CodeGenSchedRW(unsigned Idx, Record *Def)
     : Index(Idx), TheDef(Def), IsAlias(false), IsVariadic(false) {
-    Name = Def->getName();
+    Name = std::string(Def->getName());
     IsRead = Def->isSubClassOf("SchedRead");
     HasVariants = Def->isSubClassOf("SchedVariant");
     if (HasVariants)
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp
index acfb143..891a08e 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -69,6 +69,7 @@
   case MVT::fAny:     return "MVT::fAny";
   case MVT::vAny:     return "MVT::vAny";
   case MVT::f16:      return "MVT::f16";
+  case MVT::bf16:     return "MVT::bf16";
   case MVT::f32:      return "MVT::f32";
   case MVT::f64:      return "MVT::f64";
   case MVT::f80:      return "MVT::f80";
@@ -132,6 +133,16 @@
   case MVT::v8f16:    return "MVT::v8f16";
   case MVT::v16f16:   return "MVT::v16f16";
   case MVT::v32f16:   return "MVT::v32f16";
+  case MVT::v64f16:   return "MVT::v64f16";
+  case MVT::v128f16:  return "MVT::v128f16";
+  case MVT::v2bf16:   return "MVT::v2bf16";
+  case MVT::v3bf16:   return "MVT::v3bf16";
+  case MVT::v4bf16:   return "MVT::v4bf16";
+  case MVT::v8bf16:   return "MVT::v8bf16";
+  case MVT::v16bf16:  return "MVT::v16bf16";
+  case MVT::v32bf16:  return "MVT::v32bf16";
+  case MVT::v64bf16:  return "MVT::v64bf16";
+  case MVT::v128bf16: return "MVT::v128bf16";
   case MVT::v1f32:    return "MVT::v1f32";
   case MVT::v2f32:    return "MVT::v2f32";
   case MVT::v3f32:    return "MVT::v3f32";
@@ -150,18 +161,22 @@
   case MVT::v2f64:    return "MVT::v2f64";
   case MVT::v4f64:    return "MVT::v4f64";
   case MVT::v8f64:    return "MVT::v8f64";
+  case MVT::v16f64:   return "MVT::v16f64";
+  case MVT::v32f64:   return "MVT::v32f64";
   case MVT::nxv1i1:   return "MVT::nxv1i1";
   case MVT::nxv2i1:   return "MVT::nxv2i1";
   case MVT::nxv4i1:   return "MVT::nxv4i1";
   case MVT::nxv8i1:   return "MVT::nxv8i1";
   case MVT::nxv16i1:  return "MVT::nxv16i1";
   case MVT::nxv32i1:  return "MVT::nxv32i1";
+  case MVT::nxv64i1:  return "MVT::nxv64i1";
   case MVT::nxv1i8:   return "MVT::nxv1i8";
   case MVT::nxv2i8:   return "MVT::nxv2i8";
   case MVT::nxv4i8:   return "MVT::nxv4i8";
   case MVT::nxv8i8:   return "MVT::nxv8i8";
   case MVT::nxv16i8:  return "MVT::nxv16i8";
   case MVT::nxv32i8:  return "MVT::nxv32i8";
+  case MVT::nxv64i8:  return "MVT::nxv64i8";
   case MVT::nxv1i16:  return "MVT::nxv1i16";
   case MVT::nxv2i16:  return "MVT::nxv2i16";
   case MVT::nxv4i16:  return "MVT::nxv4i16";
@@ -173,14 +188,22 @@
   case MVT::nxv4i32:  return "MVT::nxv4i32";
   case MVT::nxv8i32:  return "MVT::nxv8i32";
   case MVT::nxv16i32: return "MVT::nxv16i32";
+  case MVT::nxv32i32: return "MVT::nxv32i32";
   case MVT::nxv1i64:  return "MVT::nxv1i64";
   case MVT::nxv2i64:  return "MVT::nxv2i64";
   case MVT::nxv4i64:  return "MVT::nxv4i64";
   case MVT::nxv8i64:  return "MVT::nxv8i64";
   case MVT::nxv16i64: return "MVT::nxv16i64";
+  case MVT::nxv32i64: return "MVT::nxv32i64";
+  case MVT::nxv1f16:  return "MVT::nxv1f16";
   case MVT::nxv2f16:  return "MVT::nxv2f16";
   case MVT::nxv4f16:  return "MVT::nxv4f16";
   case MVT::nxv8f16:  return "MVT::nxv8f16";
+  case MVT::nxv16f16: return "MVT::nxv16f16";
+  case MVT::nxv32f16: return "MVT::nxv32f16";
+  case MVT::nxv2bf16:  return "MVT::nxv2bf16";
+  case MVT::nxv4bf16:  return "MVT::nxv4bf16";
+  case MVT::nxv8bf16:  return "MVT::nxv8bf16";
   case MVT::nxv1f32:  return "MVT::nxv1f32";
   case MVT::nxv2f32:  return "MVT::nxv2f32";
   case MVT::nxv4f32:  return "MVT::nxv4f32";
@@ -206,8 +229,9 @@
 std::string llvm::getQualifiedName(const Record *R) {
   std::string Namespace;
   if (R->getValue("Namespace"))
-     Namespace = R->getValueAsString("Namespace");
-  if (Namespace.empty()) return R->getName();
+    Namespace = std::string(R->getValueAsString("Namespace"));
+  if (Namespace.empty())
+    return std::string(R->getName());
   return Namespace + "::" + R->getName().str();
 }
 
@@ -526,7 +550,7 @@
 ComplexPattern::ComplexPattern(Record *R) {
   Ty          = ::getValueType(R->getValueAsDef("Ty"));
   NumOperands = R->getValueAsInt("NumOperands");
-  SelectFunc  = R->getValueAsString("SelectFunc");
+  SelectFunc = std::string(R->getValueAsString("SelectFunc"));
   RootNodes   = R->getValueAsListOfDefs("RootNodes");
 
   // FIXME: This is a hack to statically increase the priority of patterns which
@@ -598,7 +622,7 @@
 
 CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
   TheDef = R;
-  std::string DefName = R->getName();
+  std::string DefName = std::string(R->getName());
   ArrayRef<SMLoc> DefLoc = R->getLoc();
   ModRef = ReadWriteMem;
   Properties = 0;
@@ -606,6 +630,8 @@
   isCommutative = false;
   canThrow = false;
   isNoReturn = false;
+  isNoSync = false;
+  isNoFree = false;
   isWillReturn = false;
   isCold = false;
   isNoDuplicate = false;
@@ -621,12 +647,12 @@
   EnumName = std::string(DefName.begin()+4, DefName.end());
 
   if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
-    GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
+    GCCBuiltinName = std::string(R->getValueAsString("GCCBuiltinName"));
   if (R->getValue("MSBuiltinName"))   // Ignore a missing MSBuiltinName field.
-    MSBuiltinName = R->getValueAsString("MSBuiltinName");
+    MSBuiltinName = std::string(R->getValueAsString("MSBuiltinName"));
 
-  TargetPrefix = R->getValueAsString("TargetPrefix");
-  Name = R->getValueAsString("LLVMName");
+  TargetPrefix = std::string(R->getValueAsString("TargetPrefix"));
+  Name = std::string(R->getValueAsString("LLVMName"));
 
   if (Name == "") {
     // If an explicit name isn't specified, derive one from the DefName.
@@ -725,8 +751,7 @@
       // variants with iAny types; otherwise, if the intrinsic is not
       // overloaded, all the types can be specified directly.
       assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
-               !TyEl->isSubClassOf("LLVMTruncatedType") &&
-               !TyEl->isSubClassOf("LLVMScalarOrSameVectorWidth")) ||
+               !TyEl->isSubClassOf("LLVMTruncatedType")) ||
               VT == MVT::iAny || VT == MVT::vAny) &&
              "Expected iAny or vAny type");
     } else
@@ -771,6 +796,10 @@
       isConvergent = true;
     else if (Property->getName() == "IntrNoReturn")
       isNoReturn = true;
+    else if (Property->getName() == "IntrNoSync")
+      isNoSync = true;
+    else if (Property->getName() == "IntrNoFree")
+      isNoFree = true;
     else if (Property->getName() == "IntrWillReturn")
       isWillReturn = true;
     else if (Property->getName() == "IntrCold")
@@ -781,25 +810,29 @@
       hasSideEffects = true;
     else if (Property->isSubClassOf("NoCapture")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
-      ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
+      ArgumentAttributes.emplace_back(ArgNo, NoCapture, 0);
     } else if (Property->isSubClassOf("NoAlias")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
-      ArgumentAttributes.push_back(std::make_pair(ArgNo, NoAlias));
+      ArgumentAttributes.emplace_back(ArgNo, NoAlias, 0);
     } else if (Property->isSubClassOf("Returned")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
-      ArgumentAttributes.push_back(std::make_pair(ArgNo, Returned));
+      ArgumentAttributes.emplace_back(ArgNo, Returned, 0);
     } else if (Property->isSubClassOf("ReadOnly")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
-      ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
+      ArgumentAttributes.emplace_back(ArgNo, ReadOnly, 0);
     } else if (Property->isSubClassOf("WriteOnly")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
-      ArgumentAttributes.push_back(std::make_pair(ArgNo, WriteOnly));
+      ArgumentAttributes.emplace_back(ArgNo, WriteOnly, 0);
     } else if (Property->isSubClassOf("ReadNone")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
-      ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
+      ArgumentAttributes.emplace_back(ArgNo, ReadNone, 0);
     } else if (Property->isSubClassOf("ImmArg")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
-      ArgumentAttributes.push_back(std::make_pair(ArgNo, ImmArg));
+      ArgumentAttributes.emplace_back(ArgNo, ImmArg, 0);
+    } else if (Property->isSubClassOf("Align")) {
+      unsigned ArgNo = Property->getValueAsInt("ArgNo");
+      uint64_t Align = Property->getValueAsInt("Align");
+      ArgumentAttributes.emplace_back(ArgNo, Alignment, Align);
     } else
       llvm_unreachable("Unknown property!");
   }
@@ -819,7 +852,8 @@
 }
 
 bool CodeGenIntrinsic::isParamImmArg(unsigned ParamIdx) const {
-  std::pair<unsigned, ArgAttribute> Val = {ParamIdx, ImmArg};
+  // Convert argument index to attribute index starting from `FirstArgIndex`.
+  ArgAttribute Val{ParamIdx + 1, ImmArg, 0};
   return std::binary_search(ArgumentAttributes.begin(),
                             ArgumentAttributes.end(), Val);
 }
diff --git a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index e9f1fb9..d9ec14a 100644
--- a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -281,7 +281,7 @@
 unsigned MatcherTableEmitter::
 EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx,
             raw_ostream &OS) {
-  OS.indent(Indent*2);
+  OS.indent(Indent);
 
   switch (N->getKind()) {
   case Matcher::Scope: {
@@ -291,6 +291,7 @@
     unsigned StartIdx = CurrentIdx;
 
     // Emit all of the children.
+    SmallString<128> TmpBuf;
     for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
       if (i == 0) {
         OS << "OPC_Scope, ";
@@ -298,9 +299,9 @@
       } else  {
         if (!OmitComments) {
           OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
-          OS.indent(Indent*2) << "/*Scope*/ ";
+          OS.indent(Indent) << "/*Scope*/ ";
         } else
-          OS.indent(Indent*2);
+          OS.indent(Indent);
       }
 
       // We need to encode the child and the offset of the failure code before
@@ -308,7 +309,6 @@
       // string while we get the size.  Unfortunately, the offset of the
       // children depends on the VBR size of the child, so for large children we
       // have to iterate a bit.
-      SmallString<128> TmpBuf;
       unsigned ChildSize = 0;
       unsigned VBRSize = 0;
       do {
@@ -337,7 +337,7 @@
     // Emit a zero as a sentinel indicating end of 'Scope'.
     if (!OmitComments)
       OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
-    OS.indent(Indent*2) << "0, ";
+    OS.indent(Indent) << "0, ";
     if (!OmitComments)
       OS << "/*End of Scope*/";
     OS << '\n';
@@ -450,6 +450,7 @@
     ++CurrentIdx;
 
     // For each case we emit the size, then the opcode, then the matcher.
+    SmallString<128> TmpBuf;
     for (unsigned i = 0, e = NumCases; i != e; ++i) {
       const Matcher *Child;
       unsigned IdxSize;
@@ -466,7 +467,6 @@
       // string while we get the size.  Unfortunately, the offset of the
       // children depends on the VBR size of the child, so for large children we
       // have to iterate a bit.
-      SmallString<128> TmpBuf;
       unsigned ChildSize = 0;
       unsigned VBRSize = 0;
       do {
@@ -483,7 +483,7 @@
       if (i != 0) {
         if (!OmitComments)
           OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
-        OS.indent(Indent*2);
+        OS.indent(Indent);
         if (!OmitComments)
           OS << (isa<SwitchOpcodeMatcher>(N) ?
                      "/*SwitchOpcode*/ " : "/*SwitchType*/ ");
@@ -509,7 +509,7 @@
     // Emit the final zero to terminate the switch.
     if (!OmitComments)
       OS << "/*" << format_decimal(CurrentIdx, IndexWidth) << "*/";
-    OS.indent(Indent*2) << "0,";
+    OS.indent(Indent) << "0,";
     if (!OmitComments)
       OS << (isa<SwitchOpcodeMatcher>(N) ?
              " // EndSwitchOpcode" : " // EndSwitchType");
@@ -619,7 +619,7 @@
   }
   case Matcher::EmitStringInteger: {
     const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
-    // These should always fit into one byte.
+    // These should always fit into 7 bits.
     OS << "OPC_EmitInteger, "
       << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
       << Val << ",\n";
@@ -712,7 +712,7 @@
         unsigned Offset =
             getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
         OS << "TARGET_VAL(" << Offset << "),\n";
-        OS.indent(FullIndexWidth + Indent * 2);
+        OS.indent(FullIndexWidth + Indent);
       }
     }
     const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N);
@@ -731,7 +731,7 @@
       OS << "|OPFL_Variadic" << EN->getNumFixedArityOperands();
     OS << ",\n";
 
-    OS.indent(FullIndexWidth + Indent*2+4);
+    OS.indent(FullIndexWidth + Indent+4);
     if (!CompressVTs) {
       OS << EN->getNumVTs();
       if (!OmitComments)
@@ -762,10 +762,10 @@
       OS << '\n';
 
       if (const MorphNodeToMatcher *SNT = dyn_cast<MorphNodeToMatcher>(N)) {
-        OS.indent(FullIndexWidth + Indent*2) << "// Src: "
+        OS.indent(FullIndexWidth + Indent) << "// Src: "
           << *SNT->getPattern().getSrcPattern() << " - Complexity = "
           << SNT->getPattern().getPatternComplexity(CGP) << '\n';
-        OS.indent(FullIndexWidth + Indent*2) << "// Dst: "
+        OS.indent(FullIndexWidth + Indent) << "// Dst: "
           << *SNT->getPattern().getDstPattern() << '\n';
       }
     } else
@@ -789,7 +789,7 @@
       unsigned Offset =
           getPatternIdxFromTable(src + " -> " + dst, std::move(include_src));
       OS << "TARGET_VAL(" << Offset << "),\n";
-      OS.indent(FullIndexWidth + Indent * 2);
+      OS.indent(FullIndexWidth + Indent);
     }
     OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
     unsigned NumResultBytes = 0;
@@ -797,10 +797,10 @@
       NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
     OS << '\n';
     if (!OmitComments) {
-      OS.indent(FullIndexWidth + Indent*2) << " // Src: "
+      OS.indent(FullIndexWidth + Indent) << " // Src: "
         << *CM->getPattern().getSrcPattern() << " - Complexity = "
         << CM->getPattern().getPatternComplexity(CGP) << '\n';
-      OS.indent(FullIndexWidth + Indent*2) << " // Dst: "
+      OS.indent(FullIndexWidth + Indent) << " // Dst: "
         << *CM->getPattern().getDstPattern();
     }
     OS << '\n';
@@ -960,7 +960,8 @@
         OS << "// " << NodeXForms[i]->getName();
       OS << '\n';
 
-      std::string ClassName = CGP.getSDNodeInfo(SDNode).getSDClassName();
+      std::string ClassName =
+          std::string(CGP.getSDNodeInfo(SDNode).getSDClassName());
       if (ClassName == "SDNode")
         OS << "    SDNode *N = V.getNode();\n";
       else
diff --git a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp
index 6a86868..123ea33 100644
--- a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp
@@ -311,7 +311,7 @@
     // The "name" of a non-leaf complex pattern (MY_PAT $op1, $op2) is
     // "MY_PAT:op1:op2". We should already have validated that the uses are
     // consistent.
-    std::string PatternName = N->getOperator()->getName();
+    std::string PatternName = std::string(N->getOperator()->getName());
     for (unsigned i = 0; i < N->getNumChildren(); ++i) {
       PatternName += ":";
       PatternName += N->getChild(i)->getName();
@@ -707,14 +707,36 @@
     if (Def->isSubClassOf("RegisterOperand"))
       Def = Def->getValueAsDef("RegClass");
     if (Def->isSubClassOf("RegisterClass")) {
-      std::string Value = getQualifiedName(Def) + "RegClassID";
-      AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
-      ResultOps.push_back(NextRecordedOperandNo++);
+      // If the register class has an enum integer value greater than 127, the
+      // encoding overflows the limit of 7 bits, which precludes the use of
+      // StringIntegerMatcher. In this case, fallback to using IntegerMatcher.
+      const CodeGenRegisterClass &RC =
+          CGP.getTargetInfo().getRegisterClass(Def);
+      if (RC.EnumValue <= 127) {
+        std::string Value = getQualifiedName(Def) + "RegClassID";
+        AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
+        ResultOps.push_back(NextRecordedOperandNo++);
+      } else {
+        AddMatcher(new EmitIntegerMatcher(RC.EnumValue, MVT::i32));
+        ResultOps.push_back(NextRecordedOperandNo++);
+      }
       return;
     }
 
     // Handle a subregister index. This is used for INSERT_SUBREG etc.
     if (Def->isSubClassOf("SubRegIndex")) {
+      const CodeGenRegBank &RB = CGP.getTargetInfo().getRegBank();
+      // If we have more than 127 subreg indices the encoding can overflow
+      // 7 bit and we cannot use StringInteger.
+      if (RB.getSubRegIndices().size() > 127) {
+        const CodeGenSubRegIndex *I = RB.findSubRegIdx(Def);
+        assert(I && "Cannot find subreg index by name!");
+        if (I->EnumValue > 127) {
+          AddMatcher(new EmitIntegerMatcher(I->EnumValue, MVT::i32));
+          ResultOps.push_back(NextRecordedOperandNo++);
+          return;
+        }
+      }
       std::string Value = getQualifiedName(Def);
       AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32));
       ResultOps.push_back(NextRecordedOperandNo++);
diff --git a/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp
index c392651..7391f684 100644
--- a/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp
@@ -122,7 +122,7 @@
   for (auto &T : DfaTransitions)
     Table.add(T.second.second);
   Table.layout();
-  OS << "std::array<NfaStatePair, " << Table.size() << "> " << Name
+  OS << "const std::array<NfaStatePair, " << Table.size() << "> " << Name
      << "TransitionInfo = {{\n";
   Table.emit(
       OS,
@@ -146,8 +146,8 @@
 
   OS << "// A table of DFA transitions, ordered by {FromDfaState, Action}.\n";
   OS << "// The initial state is 1, not zero.\n";
-  OS << "std::array<" << Name << "Transition, " << DfaTransitions.size() << "> "
-     << Name << "Transitions = {{\n";
+  OS << "const std::array<" << Name << "Transition, "
+     << DfaTransitions.size() << "> " << Name << "Transitions = {{\n";
   for (auto &KV : DfaTransitions) {
     dfa_state_type From = KV.first.first;
     dfa_state_type To = KV.second.first;
@@ -348,7 +348,7 @@
       Types.emplace_back("unsigned");
     } else if (isa<StringRecTy>(SymbolV->getType()) ||
                isa<CodeRecTy>(SymbolV->getType())) {
-      Actions.emplace_back(nullptr, 0, R->getValueAsString(A));
+      Actions.emplace_back(nullptr, 0, std::string(R->getValueAsString(A)));
       Types.emplace_back("std::string");
     } else {
       report_fatal_error("Unhandled symbol type!");
@@ -356,7 +356,7 @@
 
     StringRef TypeOverride = Parent->getActionSymbolType(A);
     if (!TypeOverride.empty())
-      Types.back() = TypeOverride;
+      Types.back() = std::string(TypeOverride);
   }
 }
 
diff --git a/src/llvm-project/llvm/utils/TableGen/DFAEmitter.h b/src/llvm-project/llvm/utils/TableGen/DFAEmitter.h
index f7724ce..44e5d97 100644
--- a/src/llvm-project/llvm/utils/TableGen/DFAEmitter.h
+++ b/src/llvm-project/llvm/utils/TableGen/DFAEmitter.h
@@ -17,16 +17,16 @@
 #ifndef LLVM_UTILS_TABLEGEN_DFAEMITTER_H
 #define LLVM_UTILS_TABLEGEN_DFAEMITTER_H
 
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/UniqueVector.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/TableGen/Record.h"
+#include <map>
 #include <set>
-#include <unordered_map>
 
 namespace llvm {
 
 class raw_ostream;
+class StringRef;
+
 /// Construct a deterministic finite state automaton from possible
 /// nondeterministic state and transition data.
 ///
diff --git a/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
index 018bda1..bc4a084 100644
--- a/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
@@ -93,7 +93,7 @@
 } // end anonymous namespace
 
 DFAPacketizerEmitter::DFAPacketizerEmitter(RecordKeeper &R)
-    : TargetName(CodeGenTarget(R).getName()), Records(R) {}
+    : TargetName(std::string(CodeGenTarget(R).getName())), Records(R) {}
 
 int DFAPacketizerEmitter::collectAllFuncUnits(
     ArrayRef<const CodeGenProcModel *> ProcModels) {
@@ -120,7 +120,7 @@
       assert((j < DFA_MAX_RESOURCES) &&
              "Exceeded maximum number of representable resources");
       uint64_t FuncResources = 1ULL << j;
-      FUNameToBitsMap[FUs[j]->getName()] = FuncResources;
+      FUNameToBitsMap[std::string(FUs[j]->getName())] = FuncResources;
       LLVM_DEBUG(dbgs() << " " << FUs[j]->getName() << ":0x"
                         << Twine::utohexstr(FuncResources));
     }
@@ -152,13 +152,13 @@
       Record *ComboFunc = FuncData->getValueAsDef("TheComboFunc");
       const std::vector<Record *> &FuncList =
           FuncData->getValueAsListOfDefs("FuncList");
-      const std::string &ComboFuncName = ComboFunc->getName();
+      const std::string &ComboFuncName = std::string(ComboFunc->getName());
       uint64_t ComboBit = FUNameToBitsMap[ComboFuncName];
       uint64_t ComboResources = ComboBit;
       LLVM_DEBUG(dbgs() << "      combo: " << ComboFuncName << ":0x"
                         << Twine::utohexstr(ComboResources) << "\n");
       for (unsigned k = 0, M = FuncList.size(); k < M; ++k) {
-        std::string FuncName = FuncList[k]->getName();
+        std::string FuncName = std::string(FuncList[k]->getName());
         uint64_t FuncResources = FUNameToBitsMap[FuncName];
         LLVM_DEBUG(dbgs() << "        " << FuncName << ":0x"
                           << Twine::utohexstr(FuncResources) << "\n");
@@ -181,7 +181,7 @@
   for (Record *StageDef : Itinerary->getValueAsListOfDefs("Stages")) {
     uint64_t StageResources = 0;
     for (Record *Unit : StageDef->getValueAsListOfDefs("Units")) {
-      StageResources |= FUNameToBitsMap[Unit->getName()];
+      StageResources |= FUNameToBitsMap[std::string(Unit->getName())];
     }
     if (StageResources != 0)
       Resources.push_back(StageResources);
@@ -219,7 +219,7 @@
   for (const CodeGenProcModel &ProcModel : CGS.procModels()) {
     if (ProcModel.hasItineraries()) {
       auto NS = ProcModel.ItinsDef->getValueAsString("PacketizerNamespace");
-      ItinsByNamespace[NS].push_back(&ProcModel);
+      ItinsByNamespace[std::string(NS)].push_back(&ProcModel);
     }
   }
 
@@ -246,7 +246,8 @@
 
   // Output the mapping from ScheduleClass to ResourcesIdx.
   unsigned Idx = 0;
-  OS << "unsigned " << TargetName << DFAName << "ResourceIndices[] = {";
+  OS << "constexpr unsigned " << TargetName << DFAName
+     << "ResourceIndices[] = {";
   for (const ScheduleClass &SC : ScheduleClasses) {
     if (Idx++ % 32 == 0)
       OS << "\n  ";
@@ -255,7 +256,7 @@
   OS << "\n};\n\n";
 
   // And the mapping from Itinerary index into the previous table.
-  OS << "unsigned " << TargetName << DFAName
+  OS << "constexpr unsigned " << TargetName << DFAName
      << "ProcResourceIndexStart[] = {\n";
   OS << "  0, // NoSchedModel\n";
   for (const CodeGenProcModel *Model : ProcModels) {
diff --git a/src/llvm-project/llvm/utils/TableGen/DirectiveEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DirectiveEmitter.cpp
new file mode 100644
index 0000000..2061ff1
--- /dev/null
+++ b/src/llvm-project/llvm/utils/TableGen/DirectiveEmitter.cpp
@@ -0,0 +1,524 @@
+//===- DirectiveEmitter.cpp - Directive Language Emitter ------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// DirectiveEmitter uses the descriptions of directives and clauses to construct
+// common code declarations to be used in Frontends.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+
+using namespace llvm;
+
+namespace {
+// Simple RAII helper for defining ifdef-undef-endif scopes.
+class IfDefScope {
+public:
+  IfDefScope(StringRef Name, raw_ostream &OS) : Name(Name), OS(OS) {
+    OS << "#ifdef " << Name << "\n"
+       << "#undef " << Name << "\n";
+  }
+
+  ~IfDefScope() { OS << "\n#endif // " << Name << "\n\n"; }
+
+private:
+  StringRef Name;
+  raw_ostream &OS;
+};
+} // end anonymous namespace
+
+namespace llvm {
+
+// Get Directive or Clause name formatted by replacing whitespaces with
+// underscores.
+std::string getFormattedName(StringRef Name) {
+  std::string N = Name.str();
+  std::replace(N.begin(), N.end(), ' ', '_');
+  return N;
+}
+
+// Generate enum class
+void GenerateEnumClass(const std::vector<Record *> &Records, raw_ostream &OS,
+                       StringRef Enum, StringRef Prefix, StringRef CppNamespace,
+                       bool MakeEnumAvailableInNamespace) {
+  OS << "\n";
+  OS << "enum class " << Enum << " {\n";
+  for (const auto &R : Records) {
+    const auto Name = R->getValueAsString("name");
+    OS << "  " << Prefix << getFormattedName(Name) << ",\n";
+  }
+  OS << "};\n";
+  OS << "\n";
+  OS << "static constexpr std::size_t " << Enum
+     << "_enumSize = " << Records.size() << ";\n";
+
+  // Make the enum values available in the defined namespace. This allows us to
+  // write something like Enum_X if we have a `using namespace <CppNamespace>`.
+  // At the same time we do not loose the strong type guarantees of the enum
+  // class, that is we cannot pass an unsigned as Directive without an explicit
+  // cast.
+  if (MakeEnumAvailableInNamespace) {
+    OS << "\n";
+    for (const auto &R : Records) {
+      const auto FormattedName = getFormattedName(R->getValueAsString("name"));
+      OS << "constexpr auto " << Prefix << FormattedName << " = "
+         << "llvm::" << CppNamespace << "::" << Enum << "::" << Prefix
+         << FormattedName << ";\n";
+    }
+  }
+}
+
+// Generate the declaration section for the enumeration in the directive
+// language
+void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) {
+
+  const auto &DirectiveLanguages =
+      Records.getAllDerivedDefinitions("DirectiveLanguage");
+
+  if (DirectiveLanguages.size() != 1) {
+    PrintError("A single definition of DirectiveLanguage is needed.");
+    return;
+  }
+
+  const auto &DirectiveLanguage = DirectiveLanguages[0];
+  StringRef LanguageName = DirectiveLanguage->getValueAsString("name");
+  StringRef DirectivePrefix =
+      DirectiveLanguage->getValueAsString("directivePrefix");
+  StringRef ClausePrefix = DirectiveLanguage->getValueAsString("clausePrefix");
+  StringRef CppNamespace = DirectiveLanguage->getValueAsString("cppNamespace");
+  bool MakeEnumAvailableInNamespace =
+      DirectiveLanguage->getValueAsBit("makeEnumAvailableInNamespace");
+  bool EnableBitmaskEnumInNamespace =
+      DirectiveLanguage->getValueAsBit("enableBitmaskEnumInNamespace");
+
+  OS << "#ifndef LLVM_" << LanguageName << "_INC\n";
+  OS << "#define LLVM_" << LanguageName << "_INC\n";
+
+  if (EnableBitmaskEnumInNamespace)
+    OS << "\n#include \"llvm/ADT/BitmaskEnum.h\"\n";
+
+  OS << "\n";
+  OS << "namespace llvm {\n";
+  OS << "class StringRef;\n";
+
+  // Open namespaces defined in the directive language
+  llvm::SmallVector<StringRef, 2> Namespaces;
+  llvm::SplitString(CppNamespace, Namespaces, "::");
+  for (auto Ns : Namespaces)
+    OS << "namespace " << Ns << " {\n";
+
+  if (EnableBitmaskEnumInNamespace)
+    OS << "\nLLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n";
+
+  // Emit Directive enumeration
+  const auto &Directives = Records.getAllDerivedDefinitions("Directive");
+  GenerateEnumClass(Directives, OS, "Directive", DirectivePrefix, CppNamespace,
+                    MakeEnumAvailableInNamespace);
+
+  // Emit Clause enumeration
+  const auto &Clauses = Records.getAllDerivedDefinitions("Clause");
+  GenerateEnumClass(Clauses, OS, "Clause", ClausePrefix, CppNamespace,
+                    MakeEnumAvailableInNamespace);
+
+  // Generic function signatures
+  OS << "\n";
+  OS << "// Enumeration helper functions\n";
+  OS << "Directive get" << LanguageName
+     << "DirectiveKind(llvm::StringRef Str);\n";
+  OS << "\n";
+  OS << "llvm::StringRef get" << LanguageName
+     << "DirectiveName(Directive D);\n";
+  OS << "\n";
+  OS << "Clause get" << LanguageName << "ClauseKind(llvm::StringRef Str);\n";
+  OS << "\n";
+  OS << "llvm::StringRef get" << LanguageName << "ClauseName(Clause C);\n";
+  OS << "\n";
+  OS << "/// Return true if \\p C is a valid clause for \\p D in version \\p "
+     << "Version.\n";
+  OS << "bool isAllowedClauseForDirective(Directive D, "
+     << "Clause C, unsigned Version);\n";
+  OS << "\n";
+
+  // Closing namespaces
+  for (auto Ns : llvm::reverse(Namespaces))
+    OS << "} // namespace " << Ns << "\n";
+
+  OS << "} // namespace llvm\n";
+
+  OS << "#endif // LLVM_" << LanguageName << "_INC\n";
+}
+
+// Generate function implementation for get<Enum>Name(StringRef Str)
+void GenerateGetName(const std::vector<Record *> &Records, raw_ostream &OS,
+                     StringRef Enum, StringRef Prefix, StringRef LanguageName,
+                     StringRef Namespace) {
+  OS << "\n";
+  OS << "llvm::StringRef llvm::" << Namespace << "::get" << LanguageName << Enum
+     << "Name(" << Enum << " Kind) {\n";
+  OS << "  switch (Kind) {\n";
+  for (const auto &R : Records) {
+    const auto Name = R->getValueAsString("name");
+    const auto AlternativeName = R->getValueAsString("alternativeName");
+    OS << "    case " << Prefix << getFormattedName(Name) << ":\n";
+    OS << "      return \"";
+    if (AlternativeName.empty())
+      OS << Name;
+    else
+      OS << AlternativeName;
+    OS << "\";\n";
+  }
+  OS << "  }\n"; // switch
+  OS << "  llvm_unreachable(\"Invalid " << LanguageName << " " << Enum
+     << " kind\");\n";
+  OS << "}\n";
+}
+
+// Generate function implementation for get<Enum>Kind(StringRef Str)
+void GenerateGetKind(const std::vector<Record *> &Records, raw_ostream &OS,
+                     StringRef Enum, StringRef Prefix, StringRef LanguageName,
+                     StringRef Namespace, bool ImplicitAsUnknown) {
+
+  auto DefaultIt = std::find_if(Records.begin(), Records.end(), [](Record *R) {
+    return R->getValueAsBit("isDefault") == true;
+  });
+
+  if (DefaultIt == Records.end()) {
+    PrintError("A least one " + Enum + " must be defined as default.");
+    return;
+  }
+
+  const auto FormattedDefaultName =
+      getFormattedName((*DefaultIt)->getValueAsString("name"));
+
+  OS << "\n";
+  OS << Enum << " llvm::" << Namespace << "::get" << LanguageName << Enum
+     << "Kind(llvm::StringRef Str) {\n";
+  OS << "  return llvm::StringSwitch<" << Enum << ">(Str)\n";
+
+  for (const auto &R : Records) {
+    const auto Name = R->getValueAsString("name");
+    if (ImplicitAsUnknown && R->getValueAsBit("isImplicit")) {
+      OS << "    .Case(\"" << Name << "\"," << Prefix << FormattedDefaultName
+         << ")\n";
+    } else {
+      OS << "    .Case(\"" << Name << "\"," << Prefix << getFormattedName(Name)
+         << ")\n";
+    }
+  }
+  OS << "    .Default(" << Prefix << FormattedDefaultName << ");\n";
+  OS << "}\n";
+}
+
+void GenerateCaseForVersionedClauses(const std::vector<Record *> &Clauses,
+                                     raw_ostream &OS, StringRef DirectiveName,
+                                     StringRef DirectivePrefix,
+                                     StringRef ClausePrefix,
+                                     llvm::StringSet<> &Cases) {
+  for (const auto &C : Clauses) {
+    const auto MinVersion = C->getValueAsInt("minVersion");
+    const auto MaxVersion = C->getValueAsInt("maxVersion");
+    const auto SpecificClause = C->getValueAsDef("clause");
+    const auto ClauseName =
+        getFormattedName(SpecificClause->getValueAsString("name"));
+
+    if (Cases.find(ClauseName) == Cases.end()) {
+      Cases.insert(ClauseName);
+      OS << "        case " << ClausePrefix << ClauseName << ":\n";
+      OS << "          return " << MinVersion << " <= Version && " << MaxVersion
+         << " >= Version;\n";
+    }
+  }
+}
+
+// Generate the isAllowedClauseForDirective function implementation.
+void GenerateIsAllowedClause(const std::vector<Record *> &Directives,
+                             raw_ostream &OS, StringRef LanguageName,
+                             StringRef DirectivePrefix, StringRef ClausePrefix,
+                             StringRef CppNamespace) {
+  OS << "\n";
+  OS << "bool llvm::" << CppNamespace << "::isAllowedClauseForDirective("
+     << "Directive D, Clause C, unsigned Version) {\n";
+  OS << "  assert(unsigned(D) <= llvm::" << CppNamespace
+     << "::Directive_enumSize);\n";
+  OS << "  assert(unsigned(C) <= llvm::" << CppNamespace
+     << "::Clause_enumSize);\n";
+
+  OS << "  switch (D) {\n";
+
+  for (const auto &D : Directives) {
+
+    const auto DirectiveName = D->getValueAsString("name");
+    const auto &AllowedClauses = D->getValueAsListOfDefs("allowedClauses");
+    const auto &AllowedOnceClauses =
+        D->getValueAsListOfDefs("allowedOnceClauses");
+    const auto &AllowedExclusiveClauses =
+        D->getValueAsListOfDefs("allowedExclusiveClauses");
+    const auto &RequiredClauses = D->getValueAsListOfDefs("requiredClauses");
+
+    OS << "    case " << DirectivePrefix << getFormattedName(DirectiveName)
+       << ":\n";
+    if (AllowedClauses.size() == 0 && AllowedOnceClauses.size() == 0 &&
+        AllowedExclusiveClauses.size() == 0 && RequiredClauses.size() == 0) {
+      OS << "      return false;\n";
+    } else {
+      OS << "      switch (C) {\n";
+
+      llvm::StringSet<> Cases;
+
+      GenerateCaseForVersionedClauses(AllowedClauses, OS, DirectiveName,
+                                      DirectivePrefix, ClausePrefix, Cases);
+
+      GenerateCaseForVersionedClauses(AllowedOnceClauses, OS, DirectiveName,
+                                      DirectivePrefix, ClausePrefix, Cases);
+
+      GenerateCaseForVersionedClauses(AllowedExclusiveClauses, OS,
+                                      DirectiveName, DirectivePrefix,
+                                      ClausePrefix, Cases);
+
+      GenerateCaseForVersionedClauses(RequiredClauses, OS, DirectiveName,
+                                      DirectivePrefix, ClausePrefix, Cases);
+
+      OS << "        default:\n";
+      OS << "          return false;\n";
+      OS << "      }\n"; // End of clauses switch
+    }
+    OS << "      break;\n";
+  }
+
+  OS << "  }\n"; // End of directives switch
+  OS << "  llvm_unreachable(\"Invalid " << LanguageName
+     << " Directive kind\");\n";
+  OS << "}\n"; // End of function isAllowedClauseForDirective
+}
+
+// Generate a simple enum set with the give clauses.
+void GenerateClauseSet(const std::vector<Record *> &Clauses, raw_ostream &OS,
+                       StringRef ClauseEnumSetClass, StringRef ClauseSetPrefix,
+                       StringRef DirectiveName, StringRef DirectivePrefix,
+                       StringRef ClausePrefix, StringRef CppNamespace) {
+
+  OS << "\n";
+  OS << "  static " << ClauseEnumSetClass << " " << ClauseSetPrefix
+     << DirectivePrefix << getFormattedName(DirectiveName) << " {\n";
+
+  for (const auto &C : Clauses) {
+    const auto SpecificClause = C->getValueAsDef("clause");
+    const auto ClauseName = SpecificClause->getValueAsString("name");
+    OS << "    llvm::" << CppNamespace << "::Clause::" << ClausePrefix
+       << getFormattedName(ClauseName) << ",\n";
+  }
+  OS << "  };\n";
+}
+
+// Generate an enum set for the 4 kinds of clauses linked to a directive.
+void GenerateDirectiveClauseSets(const std::vector<Record *> &Directives,
+                                 raw_ostream &OS, StringRef LanguageName,
+                                 StringRef ClauseEnumSetClass,
+                                 StringRef DirectivePrefix,
+                                 StringRef ClausePrefix,
+                                 StringRef CppNamespace) {
+
+  IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_SETS", OS);
+
+  OS << "\n";
+  OS << "namespace llvm {\n";
+
+  // Open namespaces defined in the directive language.
+  llvm::SmallVector<StringRef, 2> Namespaces;
+  llvm::SplitString(CppNamespace, Namespaces, "::");
+  for (auto Ns : Namespaces)
+    OS << "namespace " << Ns << " {\n";
+
+  for (const auto &D : Directives) {
+    const auto DirectiveName = D->getValueAsString("name");
+
+    const auto &AllowedClauses = D->getValueAsListOfDefs("allowedClauses");
+    const auto &AllowedOnceClauses =
+        D->getValueAsListOfDefs("allowedOnceClauses");
+    const auto &AllowedExclusiveClauses =
+        D->getValueAsListOfDefs("allowedExclusiveClauses");
+    const auto &RequiredClauses = D->getValueAsListOfDefs("requiredClauses");
+
+    OS << "\n";
+    OS << "  // Sets for " << DirectiveName << "\n";
+
+    GenerateClauseSet(AllowedClauses, OS, ClauseEnumSetClass, "allowedClauses_",
+                      DirectiveName, DirectivePrefix, ClausePrefix,
+                      CppNamespace);
+    GenerateClauseSet(AllowedOnceClauses, OS, ClauseEnumSetClass,
+                      "allowedOnceClauses_", DirectiveName, DirectivePrefix,
+                      ClausePrefix, CppNamespace);
+    GenerateClauseSet(AllowedExclusiveClauses, OS, ClauseEnumSetClass,
+                      "allowedExclusiveClauses_", DirectiveName,
+                      DirectivePrefix, ClausePrefix, CppNamespace);
+    GenerateClauseSet(RequiredClauses, OS, ClauseEnumSetClass,
+                      "requiredClauses_", DirectiveName, DirectivePrefix,
+                      ClausePrefix, CppNamespace);
+  }
+
+  // Closing namespaces
+  for (auto Ns : llvm::reverse(Namespaces))
+    OS << "} // namespace " << Ns << "\n";
+
+  OS << "} // namespace llvm\n";
+}
+
+// Generate a map of directive (key) with DirectiveClauses struct as values.
+// The struct holds the 4 sets of enumeration for the 4 kinds of clauses
+// allowances (allowed, allowed once, allowed exclusive and required).
+void GenerateDirectiveClauseMap(const std::vector<Record *> &Directives,
+                                raw_ostream &OS, StringRef LanguageName,
+                                StringRef ClauseEnumSetClass,
+                                StringRef DirectivePrefix,
+                                StringRef ClausePrefix,
+                                StringRef CppNamespace) {
+
+  IfDefScope Scope("GEN_FLANG_DIRECTIVE_CLAUSE_MAP", OS);
+
+  OS << "\n";
+  OS << "struct " << LanguageName << "DirectiveClauses {\n";
+  OS << "  const " << ClauseEnumSetClass << " allowed;\n";
+  OS << "  const " << ClauseEnumSetClass << " allowedOnce;\n";
+  OS << "  const " << ClauseEnumSetClass << " allowedExclusive;\n";
+  OS << "  const " << ClauseEnumSetClass << " requiredOneOf;\n";
+  OS << "};\n";
+
+  OS << "\n";
+
+  OS << "std::unordered_map<llvm::" << CppNamespace << "::Directive, "
+     << LanguageName << "DirectiveClauses>\n";
+  OS << "    directiveClausesTable = {\n";
+
+  for (const auto &D : Directives) {
+    const auto FormattedDirectiveName =
+        getFormattedName(D->getValueAsString("name"));
+    OS << "  {llvm::" << CppNamespace << "::Directive::" << DirectivePrefix
+       << FormattedDirectiveName << ",\n";
+    OS << "    {\n";
+    OS << "      llvm::" << CppNamespace << "::allowedClauses_"
+       << DirectivePrefix << FormattedDirectiveName << ",\n";
+    OS << "      llvm::" << CppNamespace << "::allowedOnceClauses_"
+       << DirectivePrefix << FormattedDirectiveName << ",\n";
+    OS << "      llvm::" << CppNamespace << "::allowedExclusiveClauses_"
+       << DirectivePrefix << FormattedDirectiveName << ",\n";
+    OS << "      llvm::" << CppNamespace << "::requiredClauses_"
+       << DirectivePrefix << FormattedDirectiveName << ",\n";
+    OS << "    }\n";
+    OS << "  },\n";
+  }
+
+  OS << "};\n";
+}
+
+// Generate the implemenation section for the enumeration in the directive
+// language
+void EmitDirectivesFlangImpl(const std::vector<Record *> &Directives,
+                             raw_ostream &OS, StringRef LanguageName,
+                             StringRef ClauseEnumSetClass,
+                             StringRef DirectivePrefix, StringRef ClausePrefix,
+                             StringRef CppNamespace) {
+
+  GenerateDirectiveClauseSets(Directives, OS, LanguageName, ClauseEnumSetClass,
+                              DirectivePrefix, ClausePrefix, CppNamespace);
+
+  GenerateDirectiveClauseMap(Directives, OS, LanguageName, ClauseEnumSetClass,
+                             DirectivePrefix, ClausePrefix, CppNamespace);
+}
+
+// Generate the implemenation section for the enumeration in the directive
+// language.
+void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
+
+  const auto &DirectiveLanguages =
+      Records.getAllDerivedDefinitions("DirectiveLanguage");
+
+  if (DirectiveLanguages.size() != 1) {
+    PrintError("A single definition of DirectiveLanguage is needed.");
+    return;
+  }
+
+  const auto &DirectiveLanguage = DirectiveLanguages[0];
+  StringRef DirectivePrefix =
+      DirectiveLanguage->getValueAsString("directivePrefix");
+  StringRef LanguageName = DirectiveLanguage->getValueAsString("name");
+  StringRef ClausePrefix = DirectiveLanguage->getValueAsString("clausePrefix");
+  StringRef CppNamespace = DirectiveLanguage->getValueAsString("cppNamespace");
+  StringRef ClauseEnumSetClass =
+      DirectiveLanguage->getValueAsString("clauseEnumSetClass");
+
+  const auto &Directives = Records.getAllDerivedDefinitions("Directive");
+
+  EmitDirectivesFlangImpl(Directives, OS, LanguageName, ClauseEnumSetClass,
+                          DirectivePrefix, ClausePrefix, CppNamespace);
+}
+
+// Generate the implemenation for the enumeration in the directive
+// language. This code can be included in library.
+void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
+
+  const auto &DirectiveLanguages =
+      Records.getAllDerivedDefinitions("DirectiveLanguage");
+
+  if (DirectiveLanguages.size() != 1) {
+    PrintError("A single definition of DirectiveLanguage is needed.");
+    return;
+  }
+
+  const auto &DirectiveLanguage = DirectiveLanguages[0];
+  StringRef DirectivePrefix =
+      DirectiveLanguage->getValueAsString("directivePrefix");
+  StringRef LanguageName = DirectiveLanguage->getValueAsString("name");
+  StringRef ClausePrefix = DirectiveLanguage->getValueAsString("clausePrefix");
+  StringRef CppNamespace = DirectiveLanguage->getValueAsString("cppNamespace");
+  const auto &Directives = Records.getAllDerivedDefinitions("Directive");
+  const auto &Clauses = Records.getAllDerivedDefinitions("Clause");
+
+  StringRef IncludeHeader =
+      DirectiveLanguage->getValueAsString("includeHeader");
+
+  if (!IncludeHeader.empty())
+    OS << "#include \"" << IncludeHeader << "\"\n\n";
+
+  OS << "#include \"llvm/ADT/StringRef.h\"\n";
+  OS << "#include \"llvm/ADT/StringSwitch.h\"\n";
+  OS << "#include \"llvm/Support/ErrorHandling.h\"\n";
+  OS << "\n";
+  OS << "using namespace llvm;\n";
+  llvm::SmallVector<StringRef, 2> Namespaces;
+  llvm::SplitString(CppNamespace, Namespaces, "::");
+  for (auto Ns : Namespaces)
+    OS << "using namespace " << Ns << ";\n";
+
+  // getDirectiveKind(StringRef Str)
+  GenerateGetKind(Directives, OS, "Directive", DirectivePrefix, LanguageName,
+                  CppNamespace, /*ImplicitAsUnknown=*/false);
+
+  // getDirectiveName(Directive Kind)
+  GenerateGetName(Directives, OS, "Directive", DirectivePrefix, LanguageName,
+                  CppNamespace);
+
+  // getClauseKind(StringRef Str)
+  GenerateGetKind(Clauses, OS, "Clause", ClausePrefix, LanguageName,
+                  CppNamespace, /*ImplicitAsUnknown=*/true);
+
+  // getClauseName(Clause Kind)
+  GenerateGetName(Clauses, OS, "Clause", ClausePrefix, LanguageName,
+                  CppNamespace);
+
+  // isAllowedClauseForDirective(Directive D, Clause C, unsigned Version)
+  GenerateIsAllowedClause(Directives, OS, LanguageName, DirectivePrefix,
+                          ClausePrefix, CppNamespace);
+}
+
+} // namespace llvm
diff --git a/src/llvm-project/llvm/utils/TableGen/DisassemblerEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DisassemblerEmitter.cpp
index 0002b0e..7c3f53b 100644
--- a/src/llvm-project/llvm/utils/TableGen/DisassemblerEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DisassemblerEmitter.cpp
@@ -136,7 +136,7 @@
   // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses.
   if (Target.getName() == "ARM" || Target.getName() == "Thumb" ||
       Target.getName() == "AArch64" || Target.getName() == "ARM64") {
-    std::string PredicateNamespace = Target.getName();
+    std::string PredicateNamespace = std::string(Target.getName());
     if (PredicateNamespace == "Thumb")
       PredicateNamespace = "ARM";
 
@@ -148,9 +148,9 @@
     return;
   }
 
-  EmitFixedLenDecoder(Records, OS, Target.getName(),
-                      "if (", " == MCDisassembler::Fail)",
-                      "MCDisassembler::Success", "MCDisassembler::Fail", "");
+  EmitFixedLenDecoder(Records, OS, std::string(Target.getName()), "if (",
+                      " == MCDisassembler::Fail)", "MCDisassembler::Success",
+                      "MCDisassembler::Fail", "");
 }
 
 } // end namespace llvm
diff --git a/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp
index 976d5f5..8f784e4 100644
--- a/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp
@@ -101,7 +101,7 @@
     PrintFatalError("ERROR: No 'Target' subclasses defined!");
   if (Targets.size() != 1)
     PrintFatalError("ERROR: Multiple subclasses of Target defined!");
-  Target = Targets[0]->getName();
+  Target = std::string(Targets[0]->getName());
 }
 
 void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,
diff --git a/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp
index b399568..0729ab7 100644
--- a/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp
@@ -414,7 +414,7 @@
 } // End anonymous namespace
 
 static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
-  return CGP.getSDNodeInfo(Op).getEnumName();
+  return std::string(CGP.getSDNodeInfo(Op).getEnumName());
 }
 
 static std::string getLegalCName(std::string OpName) {
@@ -719,22 +719,20 @@
             MVT::SimpleValueType RetVT = RI->first;
             const PredMap &PM = RI->second;
 
-            OS << "unsigned fastEmit_"
-               << getLegalCName(Opcode)
-               << "_" << getLegalCName(getName(VT))
-               << "_" << getLegalCName(getName(RetVT)) << "_";
+            OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
+               << getLegalCName(std::string(getName(VT))) << "_"
+               << getLegalCName(std::string(getName(RetVT))) << "_";
             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
             OS << "(";
             Operands.PrintParameters(OS);
             OS << ") {\n";
 
-            emitInstructionCode(OS, Operands, PM, getName(RetVT));
+            emitInstructionCode(OS, Operands, PM, std::string(getName(RetVT)));
           }
 
           // Emit one function for the type that demultiplexes on return type.
-          OS << "unsigned fastEmit_"
-             << getLegalCName(Opcode) << "_"
-             << getLegalCName(getName(VT)) << "_";
+          OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
+             << getLegalCName(std::string(getName(VT))) << "_";
           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
           OS << "(MVT RetVT";
           if (!Operands.empty())
@@ -745,8 +743,9 @@
                RI != RE; ++RI) {
             MVT::SimpleValueType RetVT = RI->first;
             OS << "  case " << getName(RetVT) << ": return fastEmit_"
-               << getLegalCName(Opcode) << "_" << getLegalCName(getName(VT))
-               << "_" << getLegalCName(getName(RetVT)) << "_";
+               << getLegalCName(Opcode) << "_"
+               << getLegalCName(std::string(getName(VT))) << "_"
+               << getLegalCName(std::string(getName(RetVT))) << "_";
             Operands.PrintManglingSuffix(OS, ImmediatePredicates);
             OS << "(";
             Operands.PrintArguments(OS);
@@ -756,9 +755,8 @@
 
         } else {
           // Non-variadic return type.
-          OS << "unsigned fastEmit_"
-             << getLegalCName(Opcode) << "_"
-             << getLegalCName(getName(VT)) << "_";
+          OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
+             << getLegalCName(std::string(getName(VT))) << "_";
           Operands.PrintManglingSuffix(OS, ImmediatePredicates);
           OS << "(MVT RetVT";
           if (!Operands.empty())
@@ -788,7 +786,7 @@
       for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end();
            TI != TE; ++TI) {
         MVT::SimpleValueType VT = TI->first;
-        std::string TypeName = getName(VT);
+        std::string TypeName = std::string(getName(VT));
         OS << "  case " << TypeName << ": return fastEmit_"
            << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_";
         Operands.PrintManglingSuffix(OS, ImmediatePredicates);
diff --git a/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index 21ec589..88d210f 100644
--- a/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -1182,15 +1182,6 @@
   return (unsigned)(P - Decoders.begin());
 }
 
-static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
-                                     const std::string &PredicateNamespace) {
-  if (str[0] == '!')
-    o << "!Bits[" << PredicateNamespace << "::"
-      << str.slice(1,str.size()) << "]";
-  else
-    o << "Bits[" << PredicateNamespace << "::" << str << "]";
-}
-
 bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
                                        unsigned Opc) const {
   ListInit *Predicates =
@@ -1201,21 +1192,50 @@
     if (!Pred->getValue("AssemblerMatcherPredicate"))
       continue;
 
-    StringRef P = Pred->getValueAsString("AssemblerCondString");
-
-    if (P.empty())
+    if (!dyn_cast<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
       continue;
 
+    const DagInit *D = Pred->getValueAsDag("AssemblerCondDag");
+    std::string CombineType = D->getOperator()->getAsString();
+    if (CombineType != "any_of" && CombineType != "all_of")
+      PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
+    if (D->getNumArgs() == 0)
+      PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
+    bool IsOr = CombineType == "any_of";
+
     if (!IsFirstEmission)
       o << " && ";
 
-    std::pair<StringRef, StringRef> pairs = P.split(',');
-    while (!pairs.second.empty()) {
-      emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
-      o << " && ";
-      pairs = pairs.second.split(',');
+    if (IsOr)
+      o << "(";
+
+    bool First = true;
+    for (auto *Arg : D->getArgs()) {
+      if (!First) {
+        if (IsOr)
+          o << " || ";
+        else
+          o << " && ";
+      }
+      if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
+        if (NotArg->getOperator()->getAsString() != "not" ||
+            NotArg->getNumArgs() != 1)
+          PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
+        Arg = NotArg->getArg(0);
+        o << "!";
+      }
+      if (!isa<DefInit>(Arg) ||
+          !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
+        PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
+      o << "Bits[" << Emitter->PredicateNamespace << "::" << Arg->getAsString()
+        << "]";
+
+      First = false;
     }
-    emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
+
+    if (IsOr)
+      o << ")";
+
     IsFirstEmission = false;
   }
   return !Predicates->empty();
@@ -1229,12 +1249,8 @@
     if (!Pred->getValue("AssemblerMatcherPredicate"))
       continue;
 
-    StringRef P = Pred->getValueAsString("AssemblerCondString");
-
-    if (P.empty())
-      continue;
-
-    return true;
+    if (dyn_cast<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
+      return true;
   }
   return false;
 }
@@ -1772,7 +1788,7 @@
   StringInit *String = DecoderString ?
     dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
   if (String) {
-    Decoder = String->getValue();
+    Decoder = std::string(String->getValue());
     if (!Decoder.empty())
       return Decoder;
   }
@@ -1809,7 +1825,8 @@
   StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");
   if (InstDecoder != "") {
     bool HasCompleteInstDecoder = EncodingDef.getValueAsBit("hasCompleteDecoder");
-    InsnOperands.push_back(OperandInfo(InstDecoder, HasCompleteInstDecoder));
+    InsnOperands.push_back(
+        OperandInfo(std::string(InstDecoder), HasCompleteInstDecoder));
     Operands[Opc] = InsnOperands;
     return true;
   }
@@ -1839,8 +1856,10 @@
     if (tiedTo != -1) {
       std::pair<unsigned, unsigned> SO =
         CGI.Operands.getSubOperandNumber(tiedTo);
-      TiedNames[InOutOperands[i].second] = InOutOperands[SO.first].second;
-      TiedNames[InOutOperands[SO.first].second] = InOutOperands[i].second;
+      TiedNames[std::string(InOutOperands[i].second)] =
+          std::string(InOutOperands[SO.first].second);
+      TiedNames[std::string(InOutOperands[SO.first].second)] =
+          std::string(InOutOperands[i].second);
     }
   }
 
@@ -1936,7 +1955,7 @@
       StringInit *String = DecoderString ?
         dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
       if (String && String->getValue() != "")
-        Decoder = String->getValue();
+        Decoder = std::string(String->getValue());
 
       if (Decoder == "" &&
           CGI.Operands[SO.first].MIOperandInfo &&
@@ -1963,7 +1982,7 @@
       String = DecoderString ?
         dyn_cast<StringInit>(DecoderString->getValue()) : nullptr;
       if (!isReg && String && String->getValue() != "")
-        Decoder = String->getValue();
+        Decoder = std::string(String->getValue());
 
       RecordVal *HasCompleteDecoderVal =
         TypeRecord->getValue("hasCompleteDecoder");
@@ -1989,16 +2008,17 @@
 
   // For each operand, see if we can figure out where it is encoded.
   for (const auto &Op : InOutOperands) {
-    if (!NumberedInsnOperands[Op.second].empty()) {
+    if (!NumberedInsnOperands[std::string(Op.second)].empty()) {
       InsnOperands.insert(InsnOperands.end(),
-                          NumberedInsnOperands[Op.second].begin(),
-                          NumberedInsnOperands[Op.second].end());
+                          NumberedInsnOperands[std::string(Op.second)].begin(),
+                          NumberedInsnOperands[std::string(Op.second)].end());
       continue;
     }
-    if (!NumberedInsnOperands[TiedNames[Op.second]].empty()) {
-      if (!NumberedInsnOperandsNoTie.count(TiedNames[Op.second])) {
+    if (!NumberedInsnOperands[TiedNames[std::string(Op.second)]].empty()) {
+      if (!NumberedInsnOperandsNoTie.count(TiedNames[std::string(Op.second)])) {
         // Figure out to which (sub)operand we're tied.
-        unsigned i = CGI.Operands.getOperandNamed(TiedNames[Op.second]);
+        unsigned i =
+            CGI.Operands.getOperandNamed(TiedNames[std::string(Op.second)]);
         int tiedTo = CGI.Operands[i].getTiedRegister();
         if (tiedTo == -1) {
           i = CGI.Operands.getOperandNamed(Op.second);
@@ -2009,8 +2029,9 @@
           std::pair<unsigned, unsigned> SO =
             CGI.Operands.getSubOperandNumber(tiedTo);
 
-          InsnOperands.push_back(NumberedInsnOperands[TiedNames[Op.second]]
-                                   [SO.second]);
+          InsnOperands.push_back(
+              NumberedInsnOperands[TiedNames[std::string(Op.second)]]
+                                  [SO.second]);
         }
       }
       continue;
@@ -2065,7 +2086,7 @@
       }
 
       if (Var->getName() != Op.second &&
-          Var->getName() != TiedNames[Op.second]) {
+          Var->getName() != TiedNames[std::string(Op.second)]) {
         if (Base != ~0U) {
           OpInfo.addField(Base, Width, Offset);
           Base = ~0U;
@@ -2460,7 +2481,7 @@
 
     if (populateInstruction(Target, *EncodingDef, *Inst, i, Operands)) {
       std::string DecoderNamespace =
-          EncodingDef->getValueAsString("DecoderNamespace");
+          std::string(EncodingDef->getValueAsString("DecoderNamespace"));
       if (!NumberedEncodings[i].HwModeName.empty())
         DecoderNamespace +=
             std::string("_") + NumberedEncodings[i].HwModeName.str();
diff --git a/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp
index 34eb4ed..e2a6700 100644
--- a/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp
@@ -636,7 +636,8 @@
     std::string Code;
     raw_string_ostream SS(Code);
     SS << "return " << EnumeratedRule.getID() << ";\n";
-    Cases.push_back(std::make_pair(EnumeratedRule.getName(), SS.str()));
+    Cases.push_back(
+        std::make_pair(std::string(EnumeratedRule.getName()), SS.str()));
   }
 
   OS << "static Optional<uint64_t> getRuleIdxForIdentifier(StringRef "
@@ -742,7 +743,8 @@
     const Record &RuleDef = Rule->getDef();
 
     OS << Indent << "// Rule: " << RuleDef.getName() << "\n"
-       << Indent << "if (!isRuleDisabled(" << Rule->getID() << ")) {\n";
+       << Indent << "if (!RuleConfig->isRuleDisabled(" << Rule->getID()
+       << ")) {\n";
 
     CodeExpansions Expansions;
     for (const auto &VarBinding : Leaf.var_bindings()) {
@@ -840,6 +842,13 @@
     OS << Indent << "return false;\n";
 }
 
+static void emitAdditionalHelperMethodArguments(raw_ostream &OS,
+                                                Record *Combiner) {
+  for (Record *Arg : Combiner->getValueAsListOfDefs("AdditionalArguments"))
+    OS << ",\n    " << Arg->getValueAsString("Type")
+       << Arg->getValueAsString("Name");
+}
+
 void GICombinerEmitter::run(raw_ostream &OS) {
   gatherRules(Rules, Combiner->getValueAsListOfDefs("Rules"));
   if (StopAfterParse) {
@@ -889,81 +898,136 @@
      << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_DEPS\n\n";
 
   OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n"
-     << "class " << getClassName() << " {\n"
+     << "class " << getClassName() << "RuleConfig {\n"
      << "  SparseBitVector<> DisabledRules;\n"
      << "\n"
      << "public:\n"
      << "  bool parseCommandLineOption();\n"
      << "  bool isRuleDisabled(unsigned ID) const;\n"
+     << "  bool setRuleEnabled(StringRef RuleIdentifier);\n"
      << "  bool setRuleDisabled(StringRef RuleIdentifier);\n"
      << "\n"
+     << "};\n"
+     << "\n"
+     << "class " << getClassName();
+  StringRef StateClass = Combiner->getValueAsString("StateClass");
+  if (!StateClass.empty())
+    OS << " : public " << StateClass;
+  OS << " {\n"
+     << " const " << getClassName() << "RuleConfig *RuleConfig;\n"
+     << "\n"
+     << "public:\n"
+     << "  template<typename ... Args>" << getClassName() << "(const "
+     << getClassName() << "RuleConfig &RuleConfig, Args &&... args) : ";
+  if (!StateClass.empty())
+    OS << StateClass << "(std::forward<Args>(args)...), ";
+  OS << "RuleConfig(&RuleConfig) {}\n"
+     << "\n"
      << "  bool tryCombineAll(\n"
      << "    GISelChangeObserver &Observer,\n"
      << "    MachineInstr &MI,\n"
-     << "    MachineIRBuilder &B,\n"
-     << "    CombinerHelper &Helper) const;\n"
-     << "};\n\n";
+     << "    MachineIRBuilder &B";
+  emitAdditionalHelperMethodArguments(OS, Combiner);
+  OS << ") const;\n";
+  OS << "};\n\n";
 
   emitNameMatcher(OS);
 
-  OS << "bool " << getClassName()
-     << "::setRuleDisabled(StringRef RuleIdentifier) {\n"
+  OS << "static Optional<std::pair<uint64_t, uint64_t>> "
+        "getRuleRangeForIdentifier(StringRef RuleIdentifier) {\n"
      << "  std::pair<StringRef, StringRef> RangePair = "
         "RuleIdentifier.split('-');\n"
      << "  if (!RangePair.second.empty()) {\n"
-     << "    const auto First = getRuleIdxForIdentifier(RangePair.first);\n"
-     << "    const auto Last = getRuleIdxForIdentifier(RangePair.second);\n"
+     << "    const auto First = "
+        "getRuleIdxForIdentifier(RangePair.first);\n"
+     << "    const auto Last = "
+        "getRuleIdxForIdentifier(RangePair.second);\n"
      << "    if (!First.hasValue() || !Last.hasValue())\n"
-     << "      return false;\n"
+     << "      return None;\n"
      << "    if (First >= Last)\n"
-     << "      report_fatal_error(\"Beginning of range should be before end of "
-        "range\");\n"
-     << "    for (auto I = First.getValue(); I < Last.getValue(); ++I)\n"
-     << "      DisabledRules.set(I);\n"
-     << "    return true;\n"
+     << "      report_fatal_error(\"Beginning of range should be before "
+        "end of range\");\n"
+     << "    return {{ *First, *Last + 1 }};\n"
+     << "  } else if (RangePair.first == \"*\") {\n"
+     << "    return {{ 0, " << Rules.size() << " }};\n"
      << "  } else {\n"
      << "    const auto I = getRuleIdxForIdentifier(RangePair.first);\n"
      << "    if (!I.hasValue())\n"
-     << "      return false;\n"
-     << "    DisabledRules.set(I.getValue());\n"
-     << "    return true;\n"
+     << "      return None;\n"
+     << "    return {{*I, *I + 1}};\n"
      << "  }\n"
-     << "  return false;\n"
-     << "}\n";
+     << "  return None;\n"
+     << "}\n\n";
+
+  for (bool Enabled : {true, false}) {
+    OS << "bool " << getClassName() << "RuleConfig::setRule"
+       << (Enabled ? "Enabled" : "Disabled") << "(StringRef RuleIdentifier) {\n"
+       << "  auto MaybeRange = getRuleRangeForIdentifier(RuleIdentifier);\n"
+       << "  if(!MaybeRange.hasValue())\n"
+       << "    return false;\n"
+       << "  for (auto I = MaybeRange->first; I < MaybeRange->second; ++I)\n"
+       << "    DisabledRules." << (Enabled ? "reset" : "set") << "(I);\n"
+       << "  return true;\n"
+       << "}\n\n";
+  }
 
   OS << "bool " << getClassName()
-     << "::isRuleDisabled(unsigned RuleID) const {\n"
+     << "RuleConfig::isRuleDisabled(unsigned RuleID) const {\n"
      << "  return DisabledRules.test(RuleID);\n"
      << "}\n";
   OS << "#endif // ifdef " << Name.upper() << "_GENCOMBINERHELPER_H\n\n";
 
   OS << "#ifdef " << Name.upper() << "_GENCOMBINERHELPER_CPP\n"
      << "\n"
-     << "cl::list<std::string> " << Name << "Option(\n"
+     << "std::vector<std::string> " << Name << "Option;\n"
+     << "cl::list<std::string> " << Name << "DisableOption(\n"
      << "    \"" << Name.lower() << "-disable-rule\",\n"
      << "    cl::desc(\"Disable one or more combiner rules temporarily in "
      << "the " << Name << " pass\"),\n"
      << "    cl::CommaSeparated,\n"
      << "    cl::Hidden,\n"
-     << "    cl::cat(GICombinerOptionCategory));\n"
+     << "    cl::cat(GICombinerOptionCategory),\n"
+     << "    cl::callback([](const std::string &Str) {\n"
+     << "      " << Name << "Option.push_back(Str);\n"
+     << "    }));\n"
+     << "cl::list<std::string> " << Name << "OnlyEnableOption(\n"
+     << "    \"" << Name.lower() << "-only-enable-rule\",\n"
+     << "    cl::desc(\"Disable all rules in the " << Name
+     << " pass then re-enable the specified ones\"),\n"
+     << "    cl::Hidden,\n"
+     << "    cl::cat(GICombinerOptionCategory),\n"
+     << "    cl::callback([](const std::string &CommaSeparatedArg) {\n"
+     << "      StringRef Str = CommaSeparatedArg;\n"
+     << "      " << Name << "Option.push_back(\"*\");\n"
+     << "      do {\n"
+     << "        auto X = Str.split(\",\");\n"
+     << "        " << Name << "Option.push_back((\"!\" + X.first).str());\n"
+     << "        Str = X.second;\n"
+     << "      } while (!Str.empty());\n"
+     << "    }));\n"
      << "\n"
-     << "bool " << getClassName() << "::parseCommandLineOption() {\n"
-     << "  for (const auto &Identifier : " << Name << "Option)\n"
-     << "    if (!setRuleDisabled(Identifier))\n"
+     << "bool " << getClassName() << "RuleConfig::parseCommandLineOption() {\n"
+     << "  for (StringRef Identifier : " << Name << "Option) {\n"
+     << "    bool Enabled = Identifier.consume_front(\"!\");\n"
+     << "    if (Enabled && !setRuleEnabled(Identifier))\n"
      << "      return false;\n"
+     << "    if (!Enabled && !setRuleDisabled(Identifier))\n"
+     << "      return false;\n"
+     << "  }\n"
      << "  return true;\n"
      << "}\n\n";
 
   OS << "bool " << getClassName() << "::tryCombineAll(\n"
      << "    GISelChangeObserver &Observer,\n"
      << "    MachineInstr &MI,\n"
-     << "    MachineIRBuilder &B,\n"
-     << "    CombinerHelper &Helper) const {\n"
+     << "    MachineIRBuilder &B";
+  emitAdditionalHelperMethodArguments(OS, Combiner);
+  OS << ") const {\n"
      << "  MachineBasicBlock *MBB = MI.getParent();\n"
      << "  MachineFunction *MF = MBB->getParent();\n"
      << "  MachineRegisterInfo &MRI = MF->getRegInfo();\n"
      << "  SmallVector<MachineInstr *, 8> MIs = { &MI };\n\n"
-     << "  (void)MBB; (void)MF; (void)MRI;\n\n";
+     << "  (void)MBB; (void)MF; (void)MRI; (void)RuleConfig;\n\n";
 
   OS << "  // Match data\n";
   for (const auto &Rule : Rules)
diff --git a/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt b/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
index 292a1bd..25fff72 100644
--- a/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
+++ b/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
@@ -1,5 +1,6 @@
 set(LLVM_LINK_COMPONENTS
   Support
+  TableGen
   )
 
 llvm_add_library(LLVMTableGenGlobalISel STATIC DISABLE_LLVM_LINK_LLVM_DYLIB
diff --git a/src/llvm-project/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp b/src/llvm-project/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp
index 4884bda..96dc4fc 100644
--- a/src/llvm-project/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/GlobalISel/GIMatchTree.cpp
@@ -10,6 +10,7 @@
 
 #include "../CodeGenInstruction.h"
 
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/raw_ostream.h"
@@ -611,18 +612,23 @@
 
 void GIMatchTreeOpcodePartitioner::generatePartitionSelectorCode(
     raw_ostream &OS, StringRef Indent) const {
-  OS << Indent << "Partition = -1;\n"
-     << Indent << "switch (MIs[" << InstrID << "]->getOpcode()) {\n";
-  for (const auto &EnumInstr : enumerate(PartitionToInstr)) {
-    if (EnumInstr.value() == nullptr)
-      OS << Indent << "default:";
-    else
-      OS << Indent << "case " << EnumInstr.value()->Namespace
-         << "::" << EnumInstr.value()->TheDef->getName() << ":";
-    OS << " Partition = " << EnumInstr.index() << "; break;\n";
+  // Make sure not to emit empty switch or switch with just default
+  if (PartitionToInstr.size() == 1 && PartitionToInstr[0] == nullptr) {
+    OS << Indent << "Partition = 0;\n";
+  } else if (PartitionToInstr.size()) {
+    OS << Indent << "Partition = -1;\n"
+       << Indent << "switch (MIs[" << InstrID << "]->getOpcode()) {\n";
+    for (const auto &EnumInstr : enumerate(PartitionToInstr)) {
+      if (EnumInstr.value() == nullptr)
+        OS << Indent << "default:";
+      else
+        OS << Indent << "case " << EnumInstr.value()->Namespace
+           << "::" << EnumInstr.value()->TheDef->getName() << ":";
+      OS << " Partition = " << EnumInstr.index() << "; break;\n";
+    }
+    OS << Indent << "}\n";
   }
-  OS << Indent << "}\n"
-     << Indent
+  OS << Indent
      << "// Default case but without conflicting with potential default case "
         "in selection.\n"
      << Indent << "if (Partition == -1) return false;\n";
@@ -774,4 +780,3 @@
 
   OS << Indent << "if (Partition == -1) return false;\n";
 }
-
diff --git a/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp
index c142949..4e8dcc5 100644
--- a/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -448,7 +448,6 @@
       : LabelID(LabelID_.hasValue() ? LabelID_.getValue() : ~0u),
         EmitStr(EmitStr), NumElements(NumElements), Flags(Flags),
         RawValue(RawValue) {
-
     assert((!LabelID_.hasValue() || LabelID != ~0u) &&
            "This value is reserved for non-labels");
   }
@@ -1044,6 +1043,28 @@
     for (const auto &Predicate : predicates())
       Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
   }
+
+  /// Provide a function to avoid emitting certain predicates. This is used to
+  /// defer some predicate checks until after others
+  using PredicateFilterFunc = std::function<bool(const PredicateTy&)>;
+
+  /// Emit MatchTable opcodes for predicates which satisfy \p
+  /// ShouldEmitPredicate. This should be called multiple times to ensure all
+  /// predicates are eventually added to the match table.
+  template <class... Args>
+  void emitFilteredPredicateListOpcodes(PredicateFilterFunc ShouldEmitPredicate,
+                                        MatchTable &Table, Args &&... args) {
+    if (Predicates.empty() && !Optimized) {
+      Table << MatchTable::Comment(getNoPredicateComment())
+            << MatchTable::LineBreak;
+      return;
+    }
+
+    for (const auto &Predicate : predicates()) {
+      if (ShouldEmitPredicate(*Predicate))
+        Predicate->emitPredicateOpcodes(Table, std::forward<Args>(args)...);
+    }
+  }
 };
 
 class PredicateMatcher {
@@ -1101,6 +1122,13 @@
 
   PredicateKind getKind() const { return Kind; }
 
+  bool dependsOnOperands() const {
+    // Custom predicates really depend on the context pattern of the
+    // instruction, not just the individual instruction. This therefore
+    // implicitly depends on all other pattern constraints.
+    return Kind == IPM_GenericPredicate;
+  }
+
   virtual bool isIdentical(const PredicateMatcher &B) const {
     return B.getKind() == getKind() && InsnVarID == B.InsnVarID &&
            OpIdx == B.OpIdx;
@@ -1498,7 +1526,7 @@
   const StringRef getSymbolicName() const { return SymbolicName; }
   void setSymbolicName(StringRef Name) {
     assert(SymbolicName.empty() && "Operand already has a symbolic name");
-    SymbolicName = Name;
+    SymbolicName = std::string(Name);
   }
 
   /// Construct a new operand predicate and add it to the matcher.
@@ -2128,10 +2156,23 @@
       InstructionNumOperandsMatcher(InsnVarID, getNumOperands())
           .emitPredicateOpcodes(Table, Rule);
 
-    emitPredicateListOpcodes(Table, Rule);
+    // First emit all instruction level predicates need to be verified before we
+    // can verify operands.
+    emitFilteredPredicateListOpcodes(
+      [](const PredicateMatcher &P) {
+        return !P.dependsOnOperands();
+      }, Table, Rule);
 
+    // Emit all operand constraints.
     for (const auto &Operand : Operands)
       Operand->emitPredicateOpcodes(Table, Rule);
+
+    // All of the tablegen defined predicates should now be matched. Now emit
+    // any custom predicates that rely on all generated checks.
+    emitFilteredPredicateListOpcodes(
+      [](const PredicateMatcher &P) {
+        return P.dependsOnOperands();
+      }, Table, Rule);
   }
 
   /// Compare the priority of this object and B.
@@ -2585,26 +2626,37 @@
 protected:
   unsigned InsnID;
   unsigned TempRegID;
+  const CodeGenSubRegIndex *SubRegIdx;
   bool IsDef;
 
 public:
-  TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false)
+  TempRegRenderer(unsigned InsnID, unsigned TempRegID, bool IsDef = false,
+                  const CodeGenSubRegIndex *SubReg = nullptr)
       : OperandRenderer(OR_Register), InsnID(InsnID), TempRegID(TempRegID),
-        IsDef(IsDef) {}
+        SubRegIdx(SubReg), IsDef(IsDef) {}
 
   static bool classof(const OperandRenderer *R) {
     return R->getKind() == OR_TempRegister;
   }
 
   void emitRenderOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
-    Table << MatchTable::Opcode("GIR_AddTempRegister")
-          << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
+    if (SubRegIdx) {
+      assert(!IsDef);
+      Table << MatchTable::Opcode("GIR_AddTempSubRegister");
+    } else
+      Table << MatchTable::Opcode("GIR_AddTempRegister");
+
+    Table << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
           << MatchTable::Comment("TempRegID") << MatchTable::IntValue(TempRegID)
           << MatchTable::Comment("TempRegFlags");
+
     if (IsDef)
       Table << MatchTable::NamedValue("RegState::Define");
     else
       Table << MatchTable::IntValue(0);
+
+    if (SubRegIdx)
+      Table << MatchTable::NamedValue(SubRegIdx->getQualifiedName());
     Table << MatchTable::LineBreak;
   }
 };
@@ -2779,7 +2831,7 @@
   std::string S;
 
 public:
-  DebugCommentAction(StringRef S) : S(S) {}
+  DebugCommentAction(StringRef S) : S(std::string(S)) {}
 
   void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override {
     Table << MatchTable::Comment(S) << MatchTable::LineBreak;
@@ -2950,8 +3002,8 @@
     Table << MatchTable::Opcode("GIR_ConstrainOperandRC")
           << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID)
           << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx)
-          << MatchTable::Comment("RC " + RC.getName())
-          << MatchTable::IntValue(RC.EnumValue) << MatchTable::LineBreak;
+          << MatchTable::NamedValue(RC.getQualifiedName() + "RegClassID")
+          << MatchTable::LineBreak;
   }
 };
 
@@ -3260,6 +3312,22 @@
 
 //===- GlobalISelEmitter class --------------------------------------------===//
 
+static Expected<LLTCodeGen> getInstResultType(const TreePatternNode *Dst) {
+  ArrayRef<TypeSetByHwMode> ChildTypes = Dst->getExtTypes();
+  if (ChildTypes.size() != 1)
+    return failedImport("Dst pattern child has multiple results");
+
+  Optional<LLTCodeGen> MaybeOpTy;
+  if (ChildTypes.front().isMachineValueType()) {
+    MaybeOpTy =
+      MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
+  }
+
+  if (!MaybeOpTy)
+    return failedImport("Dst operand has an unsupported type");
+  return *MaybeOpTy;
+}
+
 class GlobalISelEmitter {
 public:
   explicit GlobalISelEmitter(RecordKeeper &RK);
@@ -3269,7 +3337,7 @@
   const RecordKeeper &RK;
   const CodeGenDAGPatterns CGP;
   const CodeGenTarget &Target;
-  CodeGenRegBank CGRegs;
+  CodeGenRegBank &CGRegs;
 
   /// Keep track of the equivalence between SDNodes and Instruction by mapping
   /// SDNodes to the GINodeEquiv mapping. We need to map to the GINodeEquiv to
@@ -3477,7 +3545,7 @@
 
 GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
     : RK(RK), CGP(RK), Target(CGP.getTargetInfo()),
-      CGRegs(RK, Target.getHwModes()) {}
+      CGRegs(Target.getRegBank()) {}
 
 //===- Emitter ------------------------------------------------------------===//
 
@@ -3737,7 +3805,7 @@
                                       CCDef->getValueAsString("ICmpPredicate");
 
         if (!PredType.empty()) {
-          OM.addPredicate<CmpPredicateOperandMatcher>(PredType);
+          OM.addPredicate<CmpPredicateOperandMatcher>(std::string(PredType));
           // Process the other 2 operands normally.
           --NumChildren;
         }
@@ -3836,9 +3904,10 @@
   Record *PhysReg = nullptr;
   StringRef SrcChildName = getSrcChildName(SrcChild, PhysReg);
 
-  OperandMatcher &OM = PhysReg ?
-    InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx) :
-    InsnMatcher.addOperand(OpIdx, SrcChildName, TempOpIdx);
+  OperandMatcher &OM =
+      PhysReg
+          ? InsnMatcher.addPhysRegInput(PhysReg, OpIdx, TempOpIdx)
+          : InsnMatcher.addOperand(OpIdx, std::string(SrcChildName), TempOpIdx);
   if (OM.isSameAsAnotherOperand())
     return Error::success();
 
@@ -3971,6 +4040,10 @@
           "Src pattern child def is an unsupported tablegen class (ImmLeaf)");
     }
 
+    // Place holder for SRCVALUE nodes. Nothing to do here.
+    if (ChildRec->getName() == "srcvalue")
+      return Error::success();
+
     return failedImport(
         "Src pattern child def is an unsupported tablegen class");
   }
@@ -4040,20 +4113,13 @@
     }
 
     if (DstChild->getOperator()->isSubClassOf("Instruction")) {
-      ArrayRef<TypeSetByHwMode> ChildTypes = DstChild->getExtTypes();
-      if (ChildTypes.size() != 1)
-        return failedImport("Dst pattern child has multiple results");
-
-      Optional<LLTCodeGen> OpTyOrNone = None;
-      if (ChildTypes.front().isMachineValueType())
-        OpTyOrNone =
-            MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy);
-      if (!OpTyOrNone)
-        return failedImport("Dst operand has an unsupported type");
+      auto OpTy = getInstResultType(DstChild);
+      if (!OpTy)
+        return OpTy.takeError();
 
       unsigned TempRegID = Rule.allocateTempRegID();
       InsertPt = Rule.insertAction<MakeTempRegisterAction>(
-          InsertPt, OpTyOrNone.getValue(), TempRegID);
+          InsertPt, *OpTy, TempRegID);
       DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
 
       auto InsertPtOrError = createAndImportSubInstructionRenderer(
@@ -4225,7 +4291,7 @@
     if (!SubIdx)
       return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
 
-    const auto &SrcRCDstRCPair =
+    const auto SrcRCDstRCPair =
       (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
     assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
     M.insertAction<ConstrainOperandToRegClassAction>(
@@ -4257,6 +4323,29 @@
     return InsertPtOrError.get();
   }
 
+  if (OpName == "REG_SEQUENCE") {
+    auto SuperClass = inferRegClassFromPattern(Dst->getChild(0));
+    M.insertAction<ConstrainOperandToRegClassAction>(
+      InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass);
+
+    unsigned Num = Dst->getNumChildren();
+    for (unsigned I = 1; I != Num; I += 2) {
+      TreePatternNode *SubRegChild = Dst->getChild(I + 1);
+
+      auto SubIdx = inferSubRegIndexForNode(SubRegChild);
+      if (!SubIdx)
+        return failedImport("REG_SEQUENCE child is not a subreg index");
+
+      const auto SrcRCDstRCPair =
+        (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
+      assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
+      M.insertAction<ConstrainOperandToRegClassAction>(
+        InsertPt, DstMIBuilder.getInsnID(), I, *SrcRCDstRCPair->second);
+    }
+
+    return InsertPtOrError.get();
+  }
+
   M.insertAction<ConstrainOperandsToDefinitionAction>(InsertPt,
                                                       DstMIBuilder.getInsnID());
   return InsertPtOrError.get();
@@ -4303,33 +4392,51 @@
 
   // EXTRACT_SUBREG needs to use a subregister COPY.
   if (Name == "EXTRACT_SUBREG") {
-    if (!Dst->getChild(0)->isLeaf())
-      return failedImport("EXTRACT_SUBREG child #1 is not a leaf");
+    DefInit *SubRegInit = dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue());
+    if (!SubRegInit)
+      return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
 
-    if (DefInit *SubRegInit =
-            dyn_cast<DefInit>(Dst->getChild(1)->getLeafValue())) {
-      Record *RCDef = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
-      if (!RCDef)
-        return failedImport("EXTRACT_SUBREG child #0 could not "
-                            "be coerced to a register class");
+    CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
+    TreePatternNode *ValChild = Dst->getChild(0);
+    if (!ValChild->isLeaf()) {
+      // We really have to handle the source instruction, and then insert a
+      // copy from the subregister.
+      auto ExtractSrcTy = getInstResultType(ValChild);
+      if (!ExtractSrcTy)
+        return ExtractSrcTy.takeError();
 
-      CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
-      CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef());
+      unsigned TempRegID = M.allocateTempRegID();
+      InsertPt = M.insertAction<MakeTempRegisterAction>(
+        InsertPt, *ExtractSrcTy, TempRegID);
 
-      const auto &SrcRCDstRCPair =
-          RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
-      if (SrcRCDstRCPair.hasValue()) {
-        assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
-        if (SrcRCDstRCPair->first != RC)
-          return failedImport("EXTRACT_SUBREG requires an additional COPY");
-      }
+      auto InsertPtOrError = createAndImportSubInstructionRenderer(
+        ++InsertPt, M, ValChild, TempRegID);
+      if (auto Error = InsertPtOrError.takeError())
+        return std::move(Error);
 
-      DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
-                                                   SubIdx);
+      DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, false, SubIdx);
       return InsertPt;
     }
 
-    return failedImport("EXTRACT_SUBREG child #1 is not a subreg index");
+    // If this is a source operand, this is just a subregister copy.
+    Record *RCDef = getInitValueAsRegClass(ValChild->getLeafValue());
+    if (!RCDef)
+      return failedImport("EXTRACT_SUBREG child #0 could not "
+                          "be coerced to a register class");
+
+    CodeGenRegisterClass *RC = CGRegs.getRegClass(RCDef);
+
+    const auto SrcRCDstRCPair =
+      RC->getMatchingSubClassWithSubRegs(CGRegs, SubIdx);
+    if (SrcRCDstRCPair.hasValue()) {
+      assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
+      if (SrcRCDstRCPair->first != RC)
+        return failedImport("EXTRACT_SUBREG requires an additional COPY");
+    }
+
+    DstMIBuilder.addRenderer<CopySubRegRenderer>(Dst->getChild(0)->getName(),
+                                                 SubIdx);
+    return InsertPt;
   }
 
   if (Name == "REG_SEQUENCE") {
@@ -4731,15 +4838,13 @@
       if (DstIOpRec == nullptr)
         return failedImport("REG_SEQUENCE operand #0 isn't a register class");
     } else if (DstIName == "EXTRACT_SUBREG") {
-      if (!Dst->getChild(0)->isLeaf())
-        return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf");
+      auto InferredClass = inferRegClassFromPattern(Dst->getChild(0));
+      if (!InferredClass)
+        return failedImport("Could not infer class for EXTRACT_SUBREG operand #0");
 
       // We can assume that a subregister is in the same bank as it's super
       // register.
-      DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue());
-
-      if (DstIOpRec == nullptr)
-        return failedImport("EXTRACT_SUBREG operand #0 isn't a register class");
+      DstIOpRec = (*InferredClass)->getDef();
     } else if (DstIName == "INSERT_SUBREG") {
       auto MaybeSuperClass = inferSuperRegisterClassForNode(
           VTy, Dst->getChild(0), Dst->getChild(2));
@@ -4832,8 +4937,13 @@
     assert(Src->getExtTypes().size() == 1 &&
              "Expected Src of EXTRACT_SUBREG to have one result type");
 
-    const auto &SrcRCDstRCPair =
+    const auto SrcRCDstRCPair =
       (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
+    if (!SrcRCDstRCPair) {
+      return failedImport("subreg index is incompatible "
+                          "with inferred reg class");
+    }
+
     assert(SrcRCDstRCPair->second && "Couldn't find a matching subclass");
     M.addAction<ConstrainOperandToRegClassAction>(0, 0, *SrcRCDstRCPair->second);
     M.addAction<ConstrainOperandToRegClassAction>(0, 1, *SrcRCDstRCPair->first);
@@ -4889,6 +4999,30 @@
     return std::move(M);
   }
 
+  if (DstIName == "REG_SEQUENCE") {
+    auto SuperClass = inferRegClassFromPattern(Dst->getChild(0));
+
+    M.addAction<ConstrainOperandToRegClassAction>(0, 0, **SuperClass);
+
+    unsigned Num = Dst->getNumChildren();
+    for (unsigned I = 1; I != Num; I += 2) {
+      TreePatternNode *SubRegChild = Dst->getChild(I + 1);
+
+      auto SubIdx = inferSubRegIndexForNode(SubRegChild);
+      if (!SubIdx)
+        return failedImport("REG_SEQUENCE child is not a subreg index");
+
+      const auto SrcRCDstRCPair =
+        (*SuperClass)->getMatchingSubClassWithSubRegs(CGRegs, *SubIdx);
+
+      M.addAction<ConstrainOperandToRegClassAction>(0, I,
+                                                    *SrcRCDstRCPair->second);
+    }
+
+    ++NumPatternImported;
+    return std::move(M);
+  }
+
   M.addAction<ConstrainOperandsToDefinitionAction>(0);
 
   // We're done with this pattern!  It's eligible for GISel emission; return it.
diff --git a/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp
index 07efa18..66744bf 100644
--- a/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp
@@ -61,7 +61,7 @@
   unsigned VariantCount = Target.getAsmParserVariantCount();
 
   // Page title.
-  std::string Title = Target.getName();
+  std::string Title = std::string(Target.getName());
   Title += " Instructions";
   writeTitle(Title, OS);
   OS << "\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 6ab58bd..f314173 100644
--- a/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -524,7 +524,7 @@
   OS << "namespace llvm {\n\n";
 
   CodeGenTarget &Target = CDP.getTargetInfo();
-  const std::string &TargetName = Target.getName();
+  const std::string &TargetName = std::string(Target.getName());
   Record *InstrInfo = Target.getInstructionSet();
 
   // Keep track of all of the def lists we have emitted already.
@@ -561,7 +561,7 @@
   unsigned Num = 0;
   for (const CodeGenInstruction *Inst : NumberedInstructions) {
     // Keep a list of the instruction names.
-    InstrNames.add(Inst->TheDef->getName());
+    InstrNames.add(std::string(Inst->TheDef->getName()));
     // Emit the record into the table.
     emitRecord(*Inst, Num++, InstrInfo, EmittedLists, OperandInfoIDs, OS);
   }
@@ -569,9 +569,8 @@
 
   // Emit the array of instruction names.
   InstrNames.layout();
-  OS << "extern const char " << TargetName << "InstrNameData[] = {\n";
-  InstrNames.emit(OS, printChar);
-  OS << "};\n\n";
+  InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
+                                          "InstrNameData[]");
 
   OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {";
   Num = 0;
@@ -579,18 +578,69 @@
     // Newline every eight entries.
     if (Num % 8 == 0)
       OS << "\n    ";
-    OS << InstrNames.get(Inst->TheDef->getName()) << "U, ";
+    OS << InstrNames.get(std::string(Inst->TheDef->getName())) << "U, ";
     ++Num;
   }
-
   OS << "\n};\n\n";
 
+  bool HasDeprecationFeatures =
+      llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
+        return !Inst->HasComplexDeprecationPredicate &&
+               !Inst->DeprecatedReason.empty();
+      });
+  if (HasDeprecationFeatures) {
+    OS << "extern const uint8_t " << TargetName
+       << "InstrDeprecationFeatures[] = {";
+    Num = 0;
+    for (const CodeGenInstruction *Inst : NumberedInstructions) {
+      if (Num % 8 == 0)
+        OS << "\n    ";
+      if (!Inst->HasComplexDeprecationPredicate &&
+          !Inst->DeprecatedReason.empty())
+        OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
+           << ", ";
+      else
+        OS << "uint8_t(-1), ";
+      ++Num;
+    }
+    OS << "\n};\n\n";
+  }
+
+  bool HasComplexDeprecationInfos =
+      llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
+        return Inst->HasComplexDeprecationPredicate;
+      });
+  if (HasComplexDeprecationInfos) {
+    OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
+       << "InstrComplexDeprecationInfos[] = {";
+    Num = 0;
+    for (const CodeGenInstruction *Inst : NumberedInstructions) {
+      if (Num % 8 == 0)
+        OS << "\n    ";
+      if (Inst->HasComplexDeprecationPredicate)
+        // Emit a function pointer to the complex predicate method.
+        OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
+      else
+        OS << "nullptr, ";
+      ++Num;
+    }
+    OS << "\n};\n\n";
+  }
+
   // MCInstrInfo initialization routine.
   OS << "static inline void Init" << TargetName
      << "MCInstrInfo(MCInstrInfo *II) {\n";
-  OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, "
-     << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
-     << NumberedInstructions.size() << ");\n}\n\n";
+  OS << "  II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
+     << "InstrNameIndices, " << TargetName << "InstrNameData, ";
+  if (HasDeprecationFeatures)
+    OS << TargetName << "InstrDeprecationFeatures, ";
+  else
+    OS << "nullptr, ";
+  if (HasComplexDeprecationInfos)
+    OS << TargetName << "InstrComplexDeprecationInfos, ";
+  else
+    OS << "nullptr, ";
+  OS << NumberedInstructions.size() << ");\n}\n\n";
 
   OS << "} // end namespace llvm\n";
 
@@ -630,12 +680,28 @@
   OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n";
   OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
   OS << "extern const char " << TargetName << "InstrNameData[];\n";
+  if (HasDeprecationFeatures)
+    OS << "extern const uint8_t " << TargetName
+       << "InstrDeprecationFeatures[];\n";
+  if (HasComplexDeprecationInfos)
+    OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
+       << "InstrComplexDeprecationInfos[];\n";
   OS << ClassName << "::" << ClassName
-     << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int ReturnOpcode)\n"
-     << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, ReturnOpcode) {\n"
+     << "(int CFSetupOpcode, int CFDestroyOpcode, int CatchRetOpcode, int "
+        "ReturnOpcode)\n"
+     << "  : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
+        "ReturnOpcode) {\n"
      << "  InitMCInstrInfo(" << TargetName << "Insts, " << TargetName
-     << "InstrNameIndices, " << TargetName << "InstrNameData, "
-     << NumberedInstructions.size() << ");\n}\n";
+     << "InstrNameIndices, " << TargetName << "InstrNameData, ";
+  if (HasDeprecationFeatures)
+    OS << TargetName << "InstrDeprecationFeatures, ";
+  else
+    OS << "nullptr, ";
+  if (HasComplexDeprecationInfos)
+    OS << TargetName << "InstrComplexDeprecationInfos, ";
+  else
+    OS << "nullptr, ";
+  OS << NumberedInstructions.size() << ");\n}\n";
   OS << "} // end namespace llvm\n";
 
   OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
@@ -746,18 +812,6 @@
   else
     OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
 
-  if (Inst.HasComplexDeprecationPredicate)
-    // Emit a function pointer to the complex predicate method.
-    OS << ", -1 "
-       << ",&get" << Inst.DeprecatedReason << "DeprecationInfo";
-  else if (!Inst.DeprecatedReason.empty())
-    // Emit the Subtarget feature.
-    OS << ", " << Target.getInstNamespace() << "::" << Inst.DeprecatedReason
-       << " ,nullptr";
-  else
-    // Instruction isn't deprecated.
-    OS << ", -1 ,nullptr";
-
   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
 }
 
@@ -768,7 +822,7 @@
 
   OS << "namespace llvm {\n\n";
 
-  CodeGenTarget Target(Records);
+  const CodeGenTarget &Target = CDP.getTargetInfo();
 
   // We must emit the PHI opcode first...
   StringRef Namespace = Target.getInstNamespace();
diff --git a/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp
index 9a12571..7e41914 100644
--- a/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -244,7 +244,9 @@
   IIT_SCALABLE_VEC = 43,
   IIT_SUBDIVIDE2_ARG = 44,
   IIT_SUBDIVIDE4_ARG = 45,
-  IIT_VEC_OF_BITCASTS_TO_INT = 46
+  IIT_VEC_OF_BITCASTS_TO_INT = 46,
+  IIT_V128 = 47,
+  IIT_BF16 = 48
 };
 
 static void EncodeFixedValueType(MVT::SimpleValueType VT,
@@ -265,6 +267,7 @@
   switch (VT) {
   default: PrintFatalError("unhandled MVT in intrinsic!");
   case MVT::f16: return Sig.push_back(IIT_F16);
+  case MVT::bf16: return Sig.push_back(IIT_BF16);
   case MVT::f32: return Sig.push_back(IIT_F32);
   case MVT::f64: return Sig.push_back(IIT_F64);
   case MVT::f128: return Sig.push_back(IIT_F128);
@@ -380,6 +383,7 @@
     case 16: Sig.push_back(IIT_V16); break;
     case 32: Sig.push_back(IIT_V32); break;
     case 64: Sig.push_back(IIT_V64); break;
+    case 128: Sig.push_back(IIT_V128); break;
     case 512: Sig.push_back(IIT_V512); break;
     case 1024: Sig.push_back(IIT_V1024); break;
     }
@@ -577,6 +581,12 @@
     if (L->isNoReturn != R->isNoReturn)
       return R->isNoReturn;
 
+    if (L->isNoSync != R->isNoSync)
+      return R->isNoSync;
+
+    if (L->isNoFree != R->isNoFree)
+      return R->isNoFree;
+
     if (L->isWillReturn != R->isWillReturn)
       return R->isWillReturn;
 
@@ -656,14 +666,15 @@
     unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size();
     if (ae) {
       while (ai != ae) {
-        unsigned argNo = intrinsic.ArgumentAttributes[ai].first;
-        unsigned attrIdx = argNo + 1; // Must match AttributeList::FirstArgIndex
+        unsigned attrIdx = intrinsic.ArgumentAttributes[ai].Index;
 
         OS << "      const Attribute::AttrKind AttrParam" << attrIdx << "[]= {";
         bool addComma = false;
 
+        bool AllValuesAreZero = true;
+        SmallVector<uint64_t, 8> Values;
         do {
-          switch (intrinsic.ArgumentAttributes[ai].second) {
+          switch (intrinsic.ArgumentAttributes[ai].Kind) {
           case CodeGenIntrinsic::NoCapture:
             if (addComma)
               OS << ",";
@@ -706,21 +717,48 @@
             OS << "Attribute::ImmArg";
             addComma = true;
             break;
+          case CodeGenIntrinsic::Alignment:
+            if (addComma)
+              OS << ',';
+            OS << "Attribute::Alignment";
+            addComma = true;
+            break;
           }
+          uint64_t V = intrinsic.ArgumentAttributes[ai].Value;
+          Values.push_back(V);
+          AllValuesAreZero &= (V == 0);
 
           ++ai;
-        } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo);
+        } while (ai != ae && intrinsic.ArgumentAttributes[ai].Index == attrIdx);
         OS << "};\n";
+
+        // Generate attribute value array if not all attribute values are zero.
+        if (!AllValuesAreZero) {
+          OS << "      const uint64_t AttrValParam" << attrIdx << "[]= {";
+          addComma = false;
+          for (const auto V : Values) {
+            if (addComma)
+              OS << ',';
+            OS << V;
+            addComma = true;
+          }
+          OS << "};\n";
+        }
+
         OS << "      AS[" << numAttrs++ << "] = AttributeList::get(C, "
-           << attrIdx << ", AttrParam" << attrIdx << ");\n";
+           << attrIdx << ", AttrParam" << attrIdx;
+        if (!AllValuesAreZero)
+          OS << ", AttrValParam" << attrIdx;
+        OS << ");\n";
       }
     }
 
     if (!intrinsic.canThrow ||
-        (intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem && !intrinsic.hasSideEffects) ||
-        intrinsic.isNoReturn || intrinsic.isWillReturn || intrinsic.isCold ||
-        intrinsic.isNoDuplicate || intrinsic.isConvergent ||
-        intrinsic.isSpeculatable) {
+        (intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem &&
+         !intrinsic.hasSideEffects) ||
+        intrinsic.isNoReturn || intrinsic.isNoSync || intrinsic.isNoFree ||
+        intrinsic.isWillReturn || intrinsic.isCold || intrinsic.isNoDuplicate ||
+        intrinsic.isConvergent || intrinsic.isSpeculatable) {
       OS << "      const Attribute::AttrKind Atts[] = {";
       bool addComma = false;
       if (!intrinsic.canThrow) {
@@ -733,6 +771,18 @@
         OS << "Attribute::NoReturn";
         addComma = true;
       }
+      if (intrinsic.isNoSync) {
+        if (addComma)
+          OS << ",";
+        OS << "Attribute::NoSync";
+        addComma = true;
+      }
+      if (intrinsic.isNoFree) {
+        if (addComma)
+          OS << ",";
+        OS << "Attribute::NoFree";
+        addComma = true;
+      }
       if (intrinsic.isWillReturn) {
         if (addComma)
           OS << ",";
diff --git a/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp
index c1978ac..251533a 100644
--- a/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -10,20 +10,22 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/TableGenBackend.h"
 #include <cctype>
 #include <cstring>
 #include <map>
+#include <memory>
 
 using namespace llvm;
 
 static const std::string getOptionName(const Record &R) {
   // Use the record name unless EnumName is defined.
   if (isa<UnsetInit>(R.getValueInit("EnumName")))
-    return R.getName();
+    return std::string(R.getName());
 
-  return R.getValueAsString("EnumName");
+  return std::string(R.getValueAsString("EnumName"));
 }
 
 static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {
@@ -33,6 +35,210 @@
   return OS;
 }
 
+static const std::string getOptionSpelling(const Record &R,
+                                           size_t &PrefixLength) {
+  std::vector<StringRef> Prefixes = R.getValueAsListOfStrings("Prefixes");
+  StringRef Name = R.getValueAsString("Name");
+  if (Prefixes.empty()) {
+    PrefixLength = 0;
+    return Name.str();
+  }
+  PrefixLength = Prefixes[0].size();
+  return (Twine(Prefixes[0]) + Twine(Name)).str();
+}
+
+static const std::string getOptionSpelling(const Record &R) {
+  size_t PrefixLength;
+  return getOptionSpelling(R, PrefixLength);
+}
+
+static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) {
+  size_t PrefixLength;
+  OS << "&";
+  write_cstring(OS, StringRef(getOptionSpelling(R, PrefixLength)));
+  OS << "[" << PrefixLength << "]";
+}
+
+class MarshallingKindInfo {
+public:
+  const Record &R;
+  const char *MacroName;
+  bool ShouldAlwaysEmit;
+  StringRef KeyPath;
+  StringRef DefaultValue;
+  StringRef NormalizedValuesScope;
+
+  void emit(raw_ostream &OS) const {
+    write_cstring(OS, StringRef(getOptionSpelling(R)));
+    OS << ", ";
+    OS << ShouldAlwaysEmit;
+    OS << ", ";
+    OS << KeyPath;
+    OS << ", ";
+    emitScopedNormalizedValue(OS, DefaultValue);
+    OS << ", ";
+    emitSpecific(OS);
+  }
+
+  virtual Optional<StringRef> emitValueTable(raw_ostream &OS) const {
+    return None;
+  }
+
+  virtual ~MarshallingKindInfo() = default;
+
+  static std::unique_ptr<MarshallingKindInfo> create(const Record &R);
+
+protected:
+  void emitScopedNormalizedValue(raw_ostream &OS,
+                                 StringRef NormalizedValue) const {
+    if (!NormalizedValuesScope.empty())
+      OS << NormalizedValuesScope << "::";
+    OS << NormalizedValue;
+  }
+
+  virtual void emitSpecific(raw_ostream &OS) const = 0;
+  MarshallingKindInfo(const Record &R, const char *MacroName)
+      : R(R), MacroName(MacroName) {}
+};
+
+class MarshallingFlagInfo final : public MarshallingKindInfo {
+public:
+  bool IsPositive;
+
+  void emitSpecific(raw_ostream &OS) const override { OS << IsPositive; }
+
+  static std::unique_ptr<MarshallingKindInfo> create(const Record &R) {
+    std::unique_ptr<MarshallingFlagInfo> Ret(new MarshallingFlagInfo(R));
+    Ret->IsPositive = R.getValueAsBit("IsPositive");
+    return Ret;
+  }
+
+private:
+  MarshallingFlagInfo(const Record &R)
+      : MarshallingKindInfo(R, "OPTION_WITH_MARSHALLING_FLAG") {}
+};
+
+class MarshallingStringInfo final : public MarshallingKindInfo {
+public:
+  StringRef NormalizerRetTy;
+  StringRef Normalizer;
+  StringRef Denormalizer;
+  int TableIndex = -1;
+  std::vector<StringRef> Values;
+  std::vector<StringRef> NormalizedValues;
+  std::string ValueTableName;
+
+  static constexpr const char *ValueTablePreamble = R"(
+struct SimpleEnumValue {
+  const char *Name;
+  unsigned Value;
+};
+
+struct SimpleEnumValueTable {
+  const SimpleEnumValue *Table;
+  unsigned Size;
+};
+)";
+
+  static constexpr const char *ValueTablesDecl =
+      "static const SimpleEnumValueTable SimpleEnumValueTables[] = ";
+
+  void emitSpecific(raw_ostream &OS) const override {
+    emitScopedNormalizedValue(OS, NormalizerRetTy);
+    OS << ", ";
+    OS << Normalizer;
+    OS << ", ";
+    OS << Denormalizer;
+    OS << ", ";
+    OS << TableIndex;
+  }
+
+  Optional<StringRef> emitValueTable(raw_ostream &OS) const override {
+    if (TableIndex == -1)
+      return {};
+    OS << "static const SimpleEnumValue " << ValueTableName << "[] = {\n";
+    for (unsigned I = 0, E = Values.size(); I != E; ++I) {
+      OS << "{";
+      write_cstring(OS, Values[I]);
+      OS << ",";
+      OS << "static_cast<unsigned>(";
+      emitScopedNormalizedValue(OS, NormalizedValues[I]);
+      OS << ")},";
+    }
+    OS << "};\n";
+    return StringRef(ValueTableName);
+  }
+
+  static std::unique_ptr<MarshallingKindInfo> create(const Record &R) {
+    assert(!isa<UnsetInit>(R.getValueInit("NormalizerRetTy")) &&
+           "String options must have a type");
+
+    std::unique_ptr<MarshallingStringInfo> Ret(new MarshallingStringInfo(R));
+    Ret->NormalizerRetTy = R.getValueAsString("NormalizerRetTy");
+
+    Ret->Normalizer = R.getValueAsString("Normalizer");
+    Ret->Denormalizer = R.getValueAsString("Denormalizer");
+
+    if (!isa<UnsetInit>(R.getValueInit("NormalizedValues"))) {
+      assert(!isa<UnsetInit>(R.getValueInit("Values")) &&
+             "Cannot provide normalized values for value-less options");
+      Ret->TableIndex = NextTableIndex++;
+      Ret->NormalizedValues = R.getValueAsListOfStrings("NormalizedValues");
+      Ret->Values.reserve(Ret->NormalizedValues.size());
+      Ret->ValueTableName = getOptionName(R) + "ValueTable";
+
+      StringRef ValuesStr = R.getValueAsString("Values");
+      for (;;) {
+        size_t Idx = ValuesStr.find(',');
+        if (Idx == StringRef::npos)
+          break;
+        if (Idx > 0)
+          Ret->Values.push_back(ValuesStr.slice(0, Idx));
+        ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos);
+      }
+      if (!ValuesStr.empty())
+        Ret->Values.push_back(ValuesStr);
+
+      assert(Ret->Values.size() == Ret->NormalizedValues.size() &&
+             "The number of normalized values doesn't match the number of "
+             "values");
+    }
+
+    return Ret;
+  }
+
+private:
+  MarshallingStringInfo(const Record &R)
+      : MarshallingKindInfo(R, "OPTION_WITH_MARSHALLING_STRING") {}
+
+  static size_t NextTableIndex;
+};
+
+size_t MarshallingStringInfo::NextTableIndex = 0;
+
+std::unique_ptr<MarshallingKindInfo>
+MarshallingKindInfo::create(const Record &R) {
+  assert(!isa<UnsetInit>(R.getValueInit("KeyPath")) &&
+         !isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
+         "Must provide at least a key-path and a default value for emitting "
+         "marshalling information");
+
+  std::unique_ptr<MarshallingKindInfo> Ret = nullptr;
+  StringRef MarshallingKindStr = R.getValueAsString("MarshallingKind");
+
+  if (MarshallingKindStr == "flag")
+    Ret = MarshallingFlagInfo::create(R);
+  else if (MarshallingKindStr == "string")
+    Ret = MarshallingStringInfo::create(R);
+
+  Ret->ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit");
+  Ret->KeyPath = R.getValueAsString("KeyPath");
+  Ret->DefaultValue = R.getValueAsString("DefaultValue");
+  if (!isa<UnsetInit>(R.getValueInit("NormalizedValuesScope")))
+    Ret->NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope");
+  return Ret;
+}
+
 /// OptParserEmitter - This tablegen backend takes an input .td file
 /// describing a list of options and emits a data structure for parsing and
 /// working with those options when given an input command line.
@@ -102,7 +308,7 @@
     OS << ", \"" << R.getValueAsString("Name") << '"';
 
     // The option identifier name.
-    OS  << ", "<< getOptionName(R);
+    OS << ", " << getOptionName(R);
 
     // The option kind.
     OS << ", Group";
@@ -135,21 +341,17 @@
 
   OS << "//////////\n";
   OS << "// Options\n\n";
-  for (unsigned i = 0, e = Opts.size(); i != e; ++i) {
-    const Record &R = *Opts[i];
 
-    // Start a single option entry.
-    OS << "OPTION(";
-
+  auto WriteOptRecordFields = [&](raw_ostream &OS, const Record &R) {
     // The option prefix;
     std::vector<StringRef> prf = R.getValueAsListOfStrings("Prefixes");
     OS << Prefixes[PrefixKeyT(prf.begin(), prf.end())] << ", ";
 
     // The option string.
-    write_cstring(OS, R.getValueAsString("Name"));
+    emitNameUsingSpelling(OS, R);
 
     // The option identifier name.
-    OS  << ", "<< getOptionName(R);
+    OS << ", " << getOptionName(R);
 
     // The option kind.
     OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name");
@@ -190,8 +392,7 @@
     int NumFlags = 0;
     const ListInit *LI = R.getValueAsListInit("Flags");
     for (Init *I : *LI)
-      OS << (NumFlags++ ? " | " : "")
-         << cast<DefInit>(I)->getDef()->getName();
+      OS << (NumFlags++ ? " | " : "") << cast<DefInit>(I)->getDef()->getName();
     if (GroupFlags) {
       for (Init *I : *GroupFlags)
         OS << (NumFlags++ ? " | " : "")
@@ -224,11 +425,52 @@
       write_cstring(OS, R.getValueAsString("Values"));
     else
       OS << "nullptr";
+  };
 
+  std::vector<std::unique_ptr<MarshallingKindInfo>> OptsWithMarshalling;
+  for (unsigned I = 0, E = Opts.size(); I != E; ++I) {
+    const Record &R = *Opts[I];
+
+    // Start a single option entry.
+    OS << "OPTION(";
+    WriteOptRecordFields(OS, R);
     OS << ")\n";
+    if (!isa<UnsetInit>(R.getValueInit("MarshallingKind")))
+      OptsWithMarshalling.push_back(MarshallingKindInfo::create(R));
   }
   OS << "#endif // OPTION\n";
 
+  for (const auto &KindInfo : OptsWithMarshalling) {
+    OS << "#ifdef " << KindInfo->MacroName << "\n";
+    OS << KindInfo->MacroName << "(";
+    WriteOptRecordFields(OS, KindInfo->R);
+    OS << ", ";
+    KindInfo->emit(OS);
+    OS << ")\n";
+    OS << "#endif // " << KindInfo->MacroName << "\n";
+  }
+
+  OS << "\n";
+  OS << "#ifdef SIMPLE_ENUM_VALUE_TABLE";
+  OS << "\n";
+  OS << MarshallingStringInfo::ValueTablePreamble;
+  std::vector<StringRef> ValueTableNames;
+  for (const auto &KindInfo : OptsWithMarshalling)
+    if (auto MaybeValueTableName = KindInfo->emitValueTable(OS))
+      ValueTableNames.push_back(*MaybeValueTableName);
+
+  OS << MarshallingStringInfo::ValueTablesDecl << "{";
+  for (auto ValueTableName : ValueTableNames)
+    OS << "{" << ValueTableName << ", sizeof(" << ValueTableName
+       << ") / sizeof(SimpleEnumValue)"
+       << "},\n";
+  OS << "};\n";
+  OS << "static const unsigned SimpleEnumValueTablesSize = "
+        "sizeof(SimpleEnumValueTables) / sizeof(SimpleEnumValueTable);\n";
+
+  OS << "#endif // SIMPLE_ENUM_VALUE_TABLE\n";
+  OS << "\n";
+
   OS << "\n";
   OS << "#ifdef OPTTABLE_ARG_INIT\n";
   OS << "//////////\n";
@@ -241,8 +483,9 @@
     OS << "bool ValuesWereAdded;\n";
     OS << R.getValueAsString("ValuesCode");
     OS << "\n";
-    for (std::string S : R.getValueAsListOfStrings("Prefixes")) {
+    for (StringRef Prefix : R.getValueAsListOfStrings("Prefixes")) {
       OS << "ValuesWereAdded = Opt.addValues(";
+      std::string S(Prefix);
       S += R.getValueAsString("Name");
       write_cstring(OS, S);
       OS << ", Values);\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/OptRSTEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/OptRSTEmitter.cpp
index 3102f37..5e44d03 100644
--- a/src/llvm-project/llvm/utils/TableGen/OptRSTEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/OptRSTEmitter.cpp
@@ -9,6 +9,7 @@
 #include "OptEmitter.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
diff --git a/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
index 96e4f95..f298e63 100644
--- a/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
@@ -85,7 +85,7 @@
     MapKind Kind;
     union {
       unsigned Operand; // Operand number mapped to.
-      uint64_t Imm;     // Integer immediate value.
+      int64_t Imm;      // Integer immediate value.
       Record *Reg;      // Physical register.
     } Data;
     int TiedOpIdx = -1; // Tied operand index within the instruction.
@@ -141,7 +141,7 @@
   assert(Reg->isSubClassOf("Register") && "Reg record should be a Register\n");
   assert(RegClass->isSubClassOf("RegisterClass") && "RegClass record should be"
                                                     " a RegisterClass\n");
-  CodeGenRegisterClass RC = Target.getRegisterClass(RegClass);
+  const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass);
   const CodeGenRegister *R = Target.getRegisterByName(Reg->getName().lower());
   assert((R != nullptr) &&
          ("Register" + Reg->getName().str() + " not defined!!\n").c_str());
@@ -160,8 +160,8 @@
 
   if (DagOpType->isSubClassOf("RegisterClass") &&
       InstOpType->isSubClassOf("RegisterClass")) {
-    CodeGenRegisterClass RC = Target.getRegisterClass(InstOpType);
-    CodeGenRegisterClass SubRC = Target.getRegisterClass(DagOpType);
+    const CodeGenRegisterClass &RC = Target.getRegisterClass(InstOpType);
+    const CodeGenRegisterClass &SubRC = Target.getRegisterClass(DagOpType);
     return RC.hasSubClass(&SubRC);
   }
 
@@ -474,19 +474,40 @@
                                          SourceOperandMap, DestOperandMap));
 }
 
-static void getReqFeatures(std::set<StringRef> &FeaturesSet,
-                           const std::vector<Record *> &ReqFeatures) {
+static void
+getReqFeatures(std::set<std::pair<bool, StringRef>> &FeaturesSet,
+               std::set<std::set<std::pair<bool, StringRef>>> &AnyOfFeatureSets,
+               const std::vector<Record *> &ReqFeatures) {
   for (auto &R : ReqFeatures) {
-    StringRef AsmCondString = R->getValueAsString("AssemblerCondString");
+    const DagInit *D = R->getValueAsDag("AssemblerCondDag");
+    std::string CombineType = D->getOperator()->getAsString();
+    if (CombineType != "any_of" && CombineType != "all_of")
+      PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
+    if (D->getNumArgs() == 0)
+      PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
+    bool IsOr = CombineType == "any_of";
+    std::set<std::pair<bool, StringRef>> AnyOfSet;
 
-    // AsmCondString has syntax [!]F(,[!]F)*
-    SmallVector<StringRef, 4> Ops;
-    SplitString(AsmCondString, Ops, ",");
-    assert(!Ops.empty() && "AssemblerCondString cannot be empty");
-    for (auto &Op : Ops) {
-      assert(!Op.empty() && "Empty operator");
-      FeaturesSet.insert(Op);
+    for (auto *Arg : D->getArgs()) {
+      bool IsNot = false;
+      if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
+        if (NotArg->getOperator()->getAsString() != "not" ||
+            NotArg->getNumArgs() != 1)
+          PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
+        Arg = NotArg->getArg(0);
+        IsNot = true;
+      }
+      if (!isa<DefInit>(Arg) ||
+          !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
+        PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
+      if (IsOr)
+        AnyOfSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()});
+      else
+        FeaturesSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()});
     }
+
+    if (IsOr)
+      AnyOfFeatureSets.insert(AnyOfSet);
   }
 }
 
@@ -547,7 +568,7 @@
                     "'PassSubtarget' is false. SubTargetInfo object is needed "
                     "for target features.\n");
 
-  std::string Namespace = Target.getName();
+  std::string Namespace = std::string(Target.getName());
 
   // Sort entries in CompressPatterns to handle instructions that can have more
   // than one candidate for compression\uncompression, e.g ADD can be
@@ -651,9 +672,10 @@
       CaseStream.indent(4) << "case " + Namespace + "::" + CurOp + ": {\n";
     }
 
-    std::set<StringRef> FeaturesSet;
+    std::set<std::pair<bool, StringRef>> FeaturesSet;
+    std::set<std::set<std::pair<bool, StringRef>>> AnyOfFeatureSets;
     // Add CompressPat required features.
-    getReqFeatures(FeaturesSet, CompressPat.PatReqFeatures);
+    getReqFeatures(FeaturesSet, AnyOfFeatureSets, CompressPat.PatReqFeatures);
 
     // Add Dest instruction required features.
     std::vector<Record *> ReqFeatures;
@@ -661,19 +683,28 @@
     copy_if(RF, std::back_inserter(ReqFeatures), [](Record *R) {
       return R->getValueAsBit("AssemblerMatcherPredicate");
     });
-    getReqFeatures(FeaturesSet, ReqFeatures);
+    getReqFeatures(FeaturesSet, AnyOfFeatureSets, ReqFeatures);
 
     // Emit checks for all required features.
     for (auto &Op : FeaturesSet) {
-      if (Op[0] == '!')
-        CondStream.indent(6) << ("!STI.getFeatureBits()[" + Namespace +
-                                 "::" + Op.substr(1) + "]")
-                                        .str() +
-                                    " &&\n";
-      else
-        CondStream.indent(6)
-            << ("STI.getFeatureBits()[" + Namespace + "::" + Op + "]").str() +
-                   " &&\n";
+      StringRef Not = Op.first ? "!" : "";
+      CondStream.indent(6)
+          << Not << ("STI.getFeatureBits()[" + Namespace + "::" + Op.second + "]").str() +
+                  " &&\n";
+    }
+
+    // Emit checks for all required feature groups.
+    for (auto &Set : AnyOfFeatureSets) {
+      CondStream.indent(6) << "(";
+      for (auto &Op : Set) {
+        bool isLast = &Op == &*Set.rbegin();
+        StringRef Not = Op.first ? "!" : "";
+        CondStream << Not << ("STI.getFeatureBits()[" + Namespace + "::" + Op.second +
+                          "]").str();
+        if (!isLast)
+          CondStream << " || ";
+      }
+      CondStream << ") &&\n";
     }
 
     // Start Source Inst operands validation.
diff --git a/src/llvm-project/llvm/utils/TableGen/RegisterBankEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 7f6b393..586f857 100644
--- a/src/llvm-project/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -19,6 +19,7 @@
 
 #include "CodeGenHwModes.h"
 #include "CodeGenRegisters.h"
+#include "CodeGenTarget.h"
 
 #define DEBUG_TYPE "register-bank-emitter"
 
@@ -60,10 +61,10 @@
 
   /// Get the register classes listed in the RegisterBank.RegisterClasses field.
   std::vector<const CodeGenRegisterClass *>
-  getExplictlySpecifiedRegisterClasses(
-      CodeGenRegBank &RegisterClassHierarchy) const {
+  getExplicitlySpecifiedRegisterClasses(
+      const CodeGenRegBank &RegisterClassHierarchy) const {
     std::vector<const CodeGenRegisterClass *> RCs;
-    for (const auto &RCDef : getDef().getValueAsListOfDefs("RegisterClasses"))
+    for (const auto *RCDef : getDef().getValueAsListOfDefs("RegisterClasses"))
       RCs.push_back(RegisterClassHierarchy.getRegClass(RCDef));
     return RCs;
   }
@@ -104,8 +105,8 @@
 
 class RegisterBankEmitter {
 private:
+  CodeGenTarget Target;
   RecordKeeper &Records;
-  CodeGenRegBank RegisterClassHierarchy;
 
   void emitHeader(raw_ostream &OS, const StringRef TargetName,
                   const std::vector<RegisterBank> &Banks);
@@ -115,8 +116,7 @@
                                    std::vector<RegisterBank> &Banks);
 
 public:
-  RegisterBankEmitter(RecordKeeper &R)
-      : Records(R), RegisterClassHierarchy(Records, CodeGenHwModes(R)) {}
+  RegisterBankEmitter(RecordKeeper &R) : Target(R), Records(R) {}
 
   void run(raw_ostream &OS);
 };
@@ -167,8 +167,8 @@
 ///                multiple times for a given class if there are multiple paths
 ///                to the class.
 static void visitRegisterBankClasses(
-    CodeGenRegBank &RegisterClassHierarchy, const CodeGenRegisterClass *RC,
-    const Twine Kind,
+    const CodeGenRegBank &RegisterClassHierarchy,
+    const CodeGenRegisterClass *RC, const Twine Kind,
     std::function<void(const CodeGenRegisterClass *, StringRef)> VisitFn,
     SmallPtrSetImpl<const CodeGenRegisterClass *> &VisitedRCs) {
 
@@ -212,6 +212,7 @@
 void RegisterBankEmitter::emitBaseClassImplementation(
     raw_ostream &OS, StringRef TargetName,
     std::vector<RegisterBank> &Banks) {
+  const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
 
   OS << "namespace llvm {\n"
      << "namespace " << TargetName << " {\n";
@@ -275,10 +276,8 @@
 }
 
 void RegisterBankEmitter::run(raw_ostream &OS) {
-  std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
-  if (Targets.size() != 1)
-    PrintFatalError("ERROR: Too many or too few subclasses of Target defined!");
-  StringRef TargetName = Targets[0]->getName();
+  StringRef TargetName = Target.getName();
+  const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
 
   std::vector<RegisterBank> Banks;
   for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) {
@@ -286,7 +285,7 @@
     RegisterBank Bank(*V);
 
     for (const CodeGenRegisterClass *RC :
-         Bank.getExplictlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
+         Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
       visitRegisterBankClasses(
           RegisterClassHierarchy, RC, "explicit",
           [&Bank](const CodeGenRegisterClass *RC, StringRef Kind) {
@@ -301,14 +300,14 @@
   }
 
   // Warn about ambiguous MIR caused by register bank/class name clashes.
-  for (const auto &Class : Records.getAllDerivedDefinitions("RegisterClass")) {
+  for (const auto &Class : RegisterClassHierarchy.getRegClasses()) {
     for (const auto &Bank : Banks) {
-      if (Bank.getName().lower() == Class->getName().lower()) {
+      if (Bank.getName().lower() == StringRef(Class.getName()).lower()) {
         PrintWarning(Bank.getDef().getLoc(), "Register bank names should be "
                                              "distinct from register classes "
                                              "to avoid ambiguous MIR");
         PrintNote(Bank.getDef().getLoc(), "RegisterBank was declared here");
-        PrintNote(Class->getLoc(), "RegisterClass was declared here");
+        PrintNote(Class.getDef()->getLoc(), "RegisterClass was declared here");
       }
     }
   }
diff --git a/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 2586ec6..a615587 100644
--- a/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -173,7 +173,7 @@
     std::string Namespace = SubRegIndices.front().getNamespace();
     if (!Namespace.empty())
       OS << "namespace " << Namespace << " {\n";
-    OS << "enum {\n  NoSubRegister,\n";
+    OS << "enum : uint16_t {\n  NoSubRegister,\n";
     unsigned i = 0;
     for (const auto &Idx : SubRegIndices)
       OS << "  " << Idx.getName() << ",\t// " << ++i << "\n";
@@ -182,6 +182,20 @@
       OS << "} // end namespace " << Namespace << "\n\n";
   }
 
+  OS << "// Register pressure sets enum.\n";
+  if (!Namespace.empty())
+    OS << "namespace " << Namespace << " {\n";
+  OS << "enum RegisterPressureSets {\n";
+  unsigned NumSets = Bank.getNumRegPressureSets();
+  for (unsigned i = 0; i < NumSets; ++i ) {
+    const RegUnitSet &RegUnits = Bank.getRegSetAt(i);
+    OS << "  " << RegUnits.Name << " = " << i << ",\n";
+  }
+  OS << "};\n";
+  if (!Namespace.empty())
+    OS << "} // end namespace " << Namespace << '\n';
+  OS << '\n';
+
   OS << "} // end namespace llvm\n\n";
   OS << "#endif // GET_REGINFO_ENUM\n\n";
 }
@@ -202,13 +216,13 @@
      << "  static const RegClassWeight RCWeightTable[] = {\n";
   for (const auto &RC : RegBank.getRegClasses()) {
     const CodeGenRegister::Vec &Regs = RC.getMembers();
+    OS << "    {" << RC.getWeight(RegBank) << ", ";
     if (Regs.empty() || RC.Artificial)
-      OS << "    {0, 0";
+      OS << '0';
     else {
       std::vector<unsigned> RegUnits;
       RC.buildRegUnitSet(RegBank, RegUnits);
-      OS << "    {" << (*Regs.begin())->getWeight(RegBank)
-         << ", " << RegBank.getRegUnitSetWeight(RegUnits);
+      OS << RegBank.getRegUnitSetWeight(RegUnits);
     }
     OS << "},  \t// " << RC.getName() << "\n";
   }
@@ -897,7 +911,7 @@
   unsigned i = 0;
   for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
     const auto &Reg = *I;
-    RegStrings.add(Reg.getName());
+    RegStrings.add(std::string(Reg.getName()));
 
     // Compute the ordered sub-register list.
     SetVector<const CodeGenRegister*> SR;
@@ -963,7 +977,7 @@
 
   OS << "namespace llvm {\n\n";
 
-  const std::string &TargetName = Target.getName();
+  const std::string &TargetName = std::string(Target.getName());
 
   // Emit the shared table of differential lists.
   OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n";
@@ -992,9 +1006,8 @@
 
   // Emit the string table.
   RegStrings.layout();
-  OS << "extern const char " << TargetName << "RegStrings[] = {\n";
-  RegStrings.emit(OS, printChar);
-  OS << "};\n\n";
+  RegStrings.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
+                                          "RegStrings[]");
 
   OS << "extern const MCRegisterDesc " << TargetName
      << "RegDesc[] = { // Descriptors\n";
@@ -1003,7 +1016,7 @@
   // Emit the register descriptors now.
   i = 0;
   for (const auto &Reg : Regs) {
-    OS << "  { " << RegStrings.get(Reg.getName()) << ", "
+    OS << "  { " << RegStrings.get(std::string(Reg.getName())) << ", "
        << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])
        << ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
        << (DiffSeqs.get(RegUnitLists[i]) * 16 + RegUnitInitScale[i]) << ", "
@@ -1065,9 +1078,8 @@
   OS << "} // end anonymous namespace\n\n";
 
   RegClassStrings.layout();
-  OS << "extern const char " << TargetName << "RegClassStrings[] = {\n";
-  RegClassStrings.emit(OS, printChar);
-  OS << "};\n\n";
+  RegClassStrings.emitStringLiteralDef(
+      OS, Twine("extern const char ") + TargetName + "RegClassStrings[]");
 
   OS << "extern const MCRegisterClass " << TargetName
      << "MCRegisterClasses[] = {\n";
@@ -1134,7 +1146,7 @@
   OS << "\n#ifdef GET_REGINFO_HEADER\n";
   OS << "#undef GET_REGINFO_HEADER\n\n";
 
-  const std::string &TargetName = Target.getName();
+  const std::string &TargetName = std::string(Target.getName());
   std::string ClassName = TargetName + "GenRegisterInfo";
 
   OS << "#include \"llvm/CodeGen/TargetRegisterInfo.h\"\n\n";
@@ -1430,7 +1442,7 @@
   OS << "} // end anonymous namespace\n";
 
   // Emit extra information about registers.
-  const std::string &TargetName = Target.getName();
+  const std::string &TargetName = std::string(Target.getName());
   OS << "\nstatic const TargetRegisterInfoDesc "
      << TargetName << "RegInfoDesc[] = { // Extra Descriptors\n";
   OS << "  { 0, false },\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp
index cfe48eb..326cb4e 100644
--- a/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -57,7 +57,7 @@
   bool IsInstruction = false;
   GenericEnum *Enum = nullptr;
 
-  GenericField(StringRef Name) : Name(Name) {}
+  GenericField(StringRef Name) : Name(std::string(Name)) {}
 };
 
 struct SearchIndex {
@@ -114,13 +114,17 @@
     else if (BitInit *BI = dyn_cast<BitInit>(I))
       return BI->getValue() ? "true" : "false";
     else if (CodeInit *CI = dyn_cast<CodeInit>(I))
-      return CI->getValue();
+      return std::string(CI->getValue());
     else if (Field.IsIntrinsic)
       return "Intrinsic::" + getIntrinsic(I).EnumName;
     else if (Field.IsInstruction)
       return I->getAsString();
-    else if (Field.Enum)
-      return Field.Enum->EntryMap[cast<DefInit>(I)->getDef()]->first;
+    else if (Field.Enum) {
+      auto *Entry = Field.Enum->EntryMap[cast<DefInit>(I)->getDef()];
+      if (!Entry)
+        PrintFatalError(Twine("Entry for field '") + Field.Name + "' is null");
+      return std::string(Entry->first);
+    }
     PrintFatalError(Twine("invalid field type for field '") + Field.Name +
                     "', expected: string, bits, bit or code");
   }
@@ -274,7 +278,7 @@
 
 void SearchableTableEmitter::emitIfdef(StringRef Guard, raw_ostream &OS) {
   OS << "#ifdef " << Guard << "\n";
-  PreprocessorGuards.insert(Guard);
+  PreprocessorGuards.insert(std::string(Guard));
 }
 
 /// Emit a generic enum.
@@ -542,7 +546,7 @@
                                          const std::vector<StringRef> &Key,
                                          bool EarlyOut) {
   auto Index = std::make_unique<SearchIndex>();
-  Index->Name = Name;
+  Index->Name = std::string(Name);
   Index->EarlyOut = EarlyOut;
 
   for (const auto &FieldName : Key) {
@@ -595,10 +599,13 @@
 
 void SearchableTableEmitter::collectTableEntries(
     GenericTable &Table, const std::vector<Record *> &Items) {
+  if (Items.empty())
+    PrintWarning(Twine("Table '") + Table.Name + "' has no items");
+
   for (auto EntryRec : Items) {
     for (auto &Field : Table.Fields) {
       auto TI = dyn_cast<TypedInit>(EntryRec->getValueInit(Field.Name));
-      if (!TI) {
+      if (!TI || !TI->isComplete()) {
         PrintFatalError(EntryRec->getLoc(),
                         Twine("Record '") + EntryRec->getName() +
                             "' in table '" + Table.Name +
@@ -623,6 +630,10 @@
   Record *IntrinsicClass = Records.getClass("Intrinsic");
   Record *InstructionClass = Records.getClass("Instruction");
   for (auto &Field : Table.Fields) {
+    if (!Field.RecType)
+      PrintFatalError(Twine("Cannot determine type of field '") + Field.Name +
+                      "' in table '" + Table.Name + "'. Maybe it is not used?");
+
     if (auto RecordTy = dyn_cast<RecordRecTy>(Field.RecType)) {
       if (IntrinsicClass && RecordTy->isSubClassOf(IntrinsicClass))
         Field.IsIntrinsic = true;
@@ -648,8 +659,8 @@
       ValueField = EnumRec->getValueAsString("ValueField");
 
     auto Enum = std::make_unique<GenericEnum>();
-    Enum->Name = EnumRec->getName();
-    Enum->PreprocessorGuard = EnumRec->getName();
+    Enum->Name = std::string(EnumRec->getName());
+    Enum->PreprocessorGuard = std::string(EnumRec->getName());
 
     StringRef FilterClass = EnumRec->getValueAsString("FilterClass");
     Enum->Class = Records.getClass(FilterClass);
@@ -665,9 +676,9 @@
 
   for (auto TableRec : Records.getAllDerivedDefinitions("GenericTable")) {
     auto Table = std::make_unique<GenericTable>();
-    Table->Name = TableRec->getName();
-    Table->PreprocessorGuard = TableRec->getName();
-    Table->CppTypeName = TableRec->getValueAsString("CppTypeName");
+    Table->Name = std::string(TableRec->getName());
+    Table->PreprocessorGuard = std::string(TableRec->getName());
+    Table->CppTypeName = std::string(TableRec->getValueAsString("CppTypeName"));
 
     std::vector<StringRef> Fields = TableRec->getValueAsListOfStrings("Fields");
     for (const auto &FieldName : Fields) {
@@ -746,10 +757,10 @@
     auto Table = std::make_unique<GenericTable>();
     Table->Name = (Twine(Class->getName()) + "sList").str();
     Table->PreprocessorGuard = Class->getName().upper();
-    Table->CppTypeName = Class->getName();
+    Table->CppTypeName = std::string(Class->getName());
 
     for (const RecordVal &Field : Class->getValues()) {
-      std::string FieldName = Field.getName();
+      std::string FieldName = std::string(Field.getName());
 
       // Skip uninteresting fields: either special to us, or injected
       // template parameters (if they contain a ':').
diff --git a/src/llvm-project/llvm/utils/TableGen/SequenceToOffsetTable.h b/src/llvm-project/llvm/utils/TableGen/SequenceToOffsetTable.h
index 327da39..41cdefd 100644
--- a/src/llvm-project/llvm/utils/TableGen/SequenceToOffsetTable.h
+++ b/src/llvm-project/llvm/utils/TableGen/SequenceToOffsetTable.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_UTILS_TABLEGEN_SEQUENCETOOFFSETTABLE_H
 #define LLVM_UTILS_TABLEGEN_SEQUENCETOOFFSETTABLE_H
 
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
@@ -23,6 +24,61 @@
 #include <map>
 
 namespace llvm {
+extern llvm::cl::opt<bool> EmitLongStrLiterals;
+
+// Helper function for SequenceToOffsetTable<string>.
+static inline void printStrLitEscChar(raw_ostream &OS, char C) {
+  const char *Escapes[] = {
+      "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\007",
+      "\\010", "\\t",   "\\n",   "\\013", "\\014", "\\r",   "\\016", "\\017",
+      "\\020", "\\021", "\\022", "\\023", "\\024", "\\025", "\\026", "\\027",
+      "\\030", "\\031", "\\032", "\\033", "\\034", "\\035", "\\036", "\\037",
+      " ",     "!",     "\\\"",  "#",     "$",     "%",     "&",     "'",
+      "(",     ")",     "*",     "+",     ",",     "-",     ".",     "/",
+      "0",     "1",     "2",     "3",     "4",     "5",     "6",     "7",
+      "8",     "9",     ":",     ";",     "<",     "=",     ">",     "?",
+      "@",     "A",     "B",     "C",     "D",     "E",     "F",     "G",
+      "H",     "I",     "J",     "K",     "L",     "M",     "N",     "O",
+      "P",     "Q",     "R",     "S",     "T",     "U",     "V",     "W",
+      "X",     "Y",     "Z",     "[",     "\\\\",  "]",     "^",     "_",
+      "`",     "a",     "b",     "c",     "d",     "e",     "f",     "g",
+      "h",     "i",     "j",     "k",     "l",     "m",     "n",     "o",
+      "p",     "q",     "r",     "s",     "t",     "u",     "v",     "w",
+      "x",     "y",     "z",     "{",     "|",     "}",     "~",     "\\177",
+      "\\200", "\\201", "\\202", "\\203", "\\204", "\\205", "\\206", "\\207",
+      "\\210", "\\211", "\\212", "\\213", "\\214", "\\215", "\\216", "\\217",
+      "\\220", "\\221", "\\222", "\\223", "\\224", "\\225", "\\226", "\\227",
+      "\\230", "\\231", "\\232", "\\233", "\\234", "\\235", "\\236", "\\237",
+      "\\240", "\\241", "\\242", "\\243", "\\244", "\\245", "\\246", "\\247",
+      "\\250", "\\251", "\\252", "\\253", "\\254", "\\255", "\\256", "\\257",
+      "\\260", "\\261", "\\262", "\\263", "\\264", "\\265", "\\266", "\\267",
+      "\\270", "\\271", "\\272", "\\273", "\\274", "\\275", "\\276", "\\277",
+      "\\300", "\\301", "\\302", "\\303", "\\304", "\\305", "\\306", "\\307",
+      "\\310", "\\311", "\\312", "\\313", "\\314", "\\315", "\\316", "\\317",
+      "\\320", "\\321", "\\322", "\\323", "\\324", "\\325", "\\326", "\\327",
+      "\\330", "\\331", "\\332", "\\333", "\\334", "\\335", "\\336", "\\337",
+      "\\340", "\\341", "\\342", "\\343", "\\344", "\\345", "\\346", "\\347",
+      "\\350", "\\351", "\\352", "\\353", "\\354", "\\355", "\\356", "\\357",
+      "\\360", "\\361", "\\362", "\\363", "\\364", "\\365", "\\366", "\\367",
+      "\\370", "\\371", "\\372", "\\373", "\\374", "\\375", "\\376", "\\377"};
+
+  static_assert(sizeof Escapes / sizeof Escapes[0] ==
+                    std::numeric_limits<unsigned char>::max() + 1,
+                "unsupported character type");
+  OS << Escapes[static_cast<unsigned char>(C)];
+}
+
+static inline void printChar(raw_ostream &OS, char C) {
+  unsigned char UC(C);
+  if (isalnum(UC) || ispunct(UC)) {
+    OS << '\'';
+    if (C == '\\' || C == '\'')
+      OS << '\\';
+    OS << C << '\'';
+  } else {
+    OS << unsigned(UC);
+  }
+}
 
 /// SequenceToOffsetTable - Collect a number of terminated sequences of T.
 /// Compute the layout of a table that contains all the sequences, possibly by
@@ -108,6 +164,37 @@
     return I->second + (I->first.size() - Seq.size());
   }
 
+  /// `emitStringLiteralDef` - Print out the table as the body of an array
+  /// initializer, where each element is a C string literal terminated by
+  /// `\0`. Falls back to emitting a comma-separated integer list if
+  /// `EmitLongStrLiterals` is false
+  void emitStringLiteralDef(raw_ostream &OS, const llvm::Twine &Decl) const {
+    assert(Entries && "Call layout() before emitStringLiteralDef()");
+    if (EmitLongStrLiterals) {
+      OS << "\n#ifdef __GNUC__\n"
+         << "#pragma GCC diagnostic push\n"
+         << "#pragma GCC diagnostic ignored \"-Woverlength-strings\"\n"
+         << "#endif\n"
+         << Decl << " = {\n";
+    } else {
+      OS << Decl << " = {\n";
+      emit(OS, printChar, "0");
+      OS << "\n};\n\n";
+      return;
+    }
+    for (auto I : Seqs) {
+      OS << "  /* " << I.second << " */ \"";
+      for (auto C : I.first) {
+        printStrLitEscChar(OS, C);
+      }
+      OS << "\\0\"\n";
+    }
+    OS << "};\n"
+       << "#ifdef __GNUC__\n"
+       << "#pragma GCC diagnostic pop\n"
+       << "#endif\n\n";
+  }
+
   /// emit - Print out the table as the body of an array initializer.
   /// Use the Print function to print elements.
   void emit(raw_ostream &OS,
@@ -127,19 +214,6 @@
   }
 };
 
-// Helper function for SequenceToOffsetTable<string>.
-static inline void printChar(raw_ostream &OS, char C) {
-  unsigned char UC(C);
-  if (isalnum(UC) || ispunct(UC)) {
-    OS << '\'';
-    if (C == '\\' || C == '\'')
-      OS << '\\';
-    OS << C << '\'';
-  } else {
-    OS << unsigned(UC);
-  }
-}
-
 } // end namespace llvm
 
 #endif
diff --git a/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp
index 9b094ad..68ee839 100644
--- a/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -128,8 +128,8 @@
 
 public:
   SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT)
-    : TGT(TGT), Records(R), SchedModels(TGT.getSchedModels()),
-      Target(TGT.getName()) {}
+      : TGT(TGT), Records(R), SchedModels(TGT.getSchedModels()),
+        Target(TGT.getName()) {}
 
   void run(raw_ostream &o);
 };
@@ -396,8 +396,8 @@
        << "namespace " << Name << "FU {\n";
 
     for (unsigned j = 0, FUN = FUs.size(); j < FUN; ++j)
-      OS << "  const unsigned " << FUs[j]->getName()
-         << " = 1 << " << j << ";\n";
+      OS << "  const InstrStage::FuncUnits " << FUs[j]->getName()
+         << " = 1ULL << " << j << ";\n";
 
     OS << "} // end namespace " << Name << "FU\n";
 
@@ -460,7 +460,8 @@
       std::string ItinStageString;
       unsigned NStages = 0;
       if (ItinData)
-        FormItineraryStageString(Name, ItinData, ItinStageString, NStages);
+        FormItineraryStageString(std::string(Name), ItinData, ItinStageString,
+                                 NStages);
 
       // Get string and operand cycle count
       std::string ItinOperandCycleString;
@@ -470,7 +471,7 @@
         FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
                                         NOperandCycles);
 
-        FormItineraryBypassString(Name, ItinData, ItinBypassString,
+        FormItineraryBypassString(std::string(Name), ItinData, ItinBypassString,
                                   NOperandCycles);
       }
 
diff --git a/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp b/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
index 5430f73..3821f47 100644
--- a/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
@@ -119,33 +119,43 @@
     const SubtargetFeatureInfo &SFI = SF.second;
 
     OS << "  if (";
-    std::string CondStorage =
-        SFI.TheDef->getValueAsString("AssemblerCondString");
-    StringRef Conds = CondStorage;
-    std::pair<StringRef, StringRef> Comma = Conds.split(',');
-    bool First = true;
-    do {
-      if (!First)
-        OS << " && ";
 
-      bool Neg = false;
-      StringRef Cond = Comma.first;
-      if (Cond[0] == '!') {
-        Neg = true;
-        Cond = Cond.substr(1);
-      }
+    const DagInit *D = SFI.TheDef->getValueAsDag("AssemblerCondDag");
+    std::string CombineType = D->getOperator()->getAsString();
+    if (CombineType != "any_of" && CombineType != "all_of")
+      PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
+    if (D->getNumArgs() == 0)
+      PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
+    bool IsOr = CombineType == "any_of";
 
+    if (IsOr)
       OS << "(";
-      if (Neg)
-        OS << "!";
-      OS << "FB[" << TargetName << "::" << Cond << "])";
 
-      if (Comma.second.empty())
-        break;
+    bool First = true;
+    for (auto *Arg : D->getArgs()) {
+      if (!First) {
+        if (IsOr)
+          OS << " || ";
+        else
+          OS << " && ";
+      }
+      if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
+        if (NotArg->getOperator()->getAsString() != "not" ||
+            NotArg->getNumArgs() != 1)
+          PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
+        Arg = NotArg->getArg(0);
+        OS << "!";
+      }
+      if (!isa<DefInit>(Arg) ||
+          !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
+        PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
+      OS << "FB[" << TargetName << "::" << Arg->getAsString() << "]";
 
       First = false;
-      Comma = Comma.second.split(',');
-    } while (true);
+    }
+
+    if (IsOr)
+      OS << ")";
 
     OS << ")\n";
     OS << "    Features.set(" << SFI.getEnumBitName() << ");\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/TableGen.cpp b/src/llvm-project/llvm/utils/TableGen/TableGen.cpp
index bdb963c..8015a58 100644
--- a/src/llvm-project/llvm/utils/TableGen/TableGen.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/TableGen.cpp
@@ -54,12 +54,21 @@
   GenRegisterBank,
   GenExegesis,
   GenAutomata,
+  GenDirectivesEnumDecl,
+  GenDirectivesEnumImpl,
+  GenDirectivesEnumGen,
 };
 
 namespace llvm {
 /// Storage for TimeRegionsOpt as a global so that backends aren't required to
 /// include CommandLine.h
 bool TimeRegions = false;
+cl::opt<bool> EmitLongStrLiterals(
+    "long-string-literals",
+    cl::desc("when emitting large string tables, prefer string literals over "
+             "comma-separated char literals. This can be a readability and "
+             "compile-time performance win, but upsets some compilers"),
+    cl::Hidden, cl::init(true));
 } // end namespace llvm
 
 namespace {
@@ -122,7 +131,13 @@
                    "Generate registers bank descriptions"),
         clEnumValN(GenExegesis, "gen-exegesis",
                    "Generate llvm-exegesis tables"),
-        clEnumValN(GenAutomata, "gen-automata", "Generate generic automata")));
+        clEnumValN(GenAutomata, "gen-automata", "Generate generic automata"),
+        clEnumValN(GenDirectivesEnumDecl, "gen-directive-decl",
+                   "Generate directive related declaration code (header file)"),
+        clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl",
+                   "Generate directive related implementation code"),
+        clEnumValN(GenDirectivesEnumGen, "gen-directive-gen",
+                   "Generate directive related implementation code part")));
 
 cl::OptionCategory PrintEnumsCat("Options for -print-enums");
 cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"),
@@ -247,6 +262,15 @@
   case GenAutomata:
     EmitAutomata(Records, OS);
     break;
+  case GenDirectivesEnumDecl:
+    EmitDirectivesDecl(Records, OS);
+    break;
+  case GenDirectivesEnumImpl:
+    EmitDirectivesImpl(Records, OS);
+    break;
+  case GenDirectivesEnumGen:
+    EmitDirectivesGen(Records, OS);
+    break;
   }
 
   return false;
diff --git a/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h b/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h
index 9eef77a..92204f3 100644
--- a/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h
+++ b/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h
@@ -90,6 +90,9 @@
 void EmitRegisterBank(RecordKeeper &RK, raw_ostream &OS);
 void EmitExegesis(RecordKeeper &RK, raw_ostream &OS);
 void EmitAutomata(RecordKeeper &RK, raw_ostream &OS);
+void EmitDirectivesDecl(RecordKeeper &RK, raw_ostream &OS);
+void EmitDirectivesImpl(RecordKeeper &RK, raw_ostream &OS);
+void EmitDirectivesGen(RecordKeeper &RK, raw_ostream &OS);
 
 } // End llvm namespace
 
diff --git a/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp b/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp
index 5dc653a..76e4fd9 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp
@@ -669,7 +669,7 @@
 
   if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) {
     // Empty table.
-    o2 << "{ " << stringForDecisionType(dt) << ", 0 }";
+    o2 << "{" << stringForDecisionType(dt) << ", 0}";
     return;
   }
 
@@ -708,18 +708,17 @@
     EntryNumber = ModRMTableNum;
 
     ModRMTableNum += ModRMDecision.size();
-    o1 << "/* Table" << EntryNumber << " */\n";
+    o1 << "/*Table" << EntryNumber << "*/\n";
     i1++;
     for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(),
            E = ModRMDecision.end(); I != E; ++I) {
-      o1.indent(i1 * 2) << format("0x%hx", *I) << ", /* "
-                        << InstructionSpecifiers[*I].name << " */\n";
+      o1.indent(i1 * 2) << format("0x%hx", *I) << ", /*"
+                        << InstructionSpecifiers[*I].name << "*/\n";
     }
     i1--;
   }
 
-  o2 << "{ " << stringForDecisionType(dt) << ", " << EntryNumber << " /* Table"
-     << EntryNumber << " */ }";
+  o2 << "{" << stringForDecisionType(dt) << ", " << EntryNumber << "}";
 
   switch (dt) {
     default:
@@ -769,11 +768,10 @@
     o2 << "},\n";
   } else {
     o2 << " /* struct OpcodeDecision */ {\n";
-    ++i2;
     for (index = 0; index < 256; ++index) {
       o2.indent(i2);
 
-      o2 << "/* 0x" << format("%02hhx", index) << " */ ";
+      o2 << "/*0x" << format("%02hhx", index) << "*/";
 
       emitModRMDecision(o1, o2, i1, i2, ModRMTableNum,
                         opDecision.modRMDecisions[index]);
@@ -783,7 +781,6 @@
 
       o2 << "\n";
     }
-    --i2;
     o2.indent(i2) << "}\n";
     --i2;
     o2.indent(i2) << "},\n";
@@ -795,24 +792,20 @@
                                              unsigned &ModRMTableNum,
                                              ContextDecision &decision,
                                              const char* name) const {
-  o2.indent(i2) << "static const struct ContextDecision " << name << " = {\n";
-  i2++;
-  o2.indent(i2) << "{ /* opcodeDecisions */" << "\n";
+  o2.indent(i2) << "static const struct ContextDecision " << name << " = {{/* opcodeDecisions */\n";
   i2++;
 
   for (unsigned index = 0; index < IC_max; ++index) {
-    o2.indent(i2) << "/* ";
+    o2.indent(i2) << "/*";
     o2 << stringForContext((InstructionContext)index);
-    o2 << " */ ";
+    o2 << "*/ ";
 
     emitOpcodeDecision(o1, o2, i1, i2, ModRMTableNum,
                        decision.opcodeDecisions[index]);
   }
 
   i2--;
-  o2.indent(i2) << "}" << "\n";
-  i2--;
-  o2.indent(i2) << "};" << "\n";
+  o2.indent(i2) << "}};" << "\n";
 }
 
 void DisassemblerTables::emitInstructionInfo(raw_ostream &o,
@@ -976,9 +969,7 @@
     else
       o << "IC";
 
-    o << ", /* " << index << " */";
-
-    o << "\n";
+    o << ", // " << index << "\n";
   }
 
   i--;
@@ -1021,7 +1012,7 @@
   std::vector<unsigned> EmptyTable(1, 0);
   ModRMTable[EmptyTable] = ModRMTableNum;
   ModRMTableNum += EmptyTable.size();
-  o1 << "/* EmptyTable */\n";
+  o1 << "/*EmptyTable*/\n";
   o1.indent(i1 * 2) << "0x0,\n";
   i1--;
   emitContextDecisions(o1, o2, i1, i2, ModRMTableNum);
diff --git a/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.cpp b/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.cpp
index 98e6fb6..cf75070 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.cpp
@@ -18,4 +18,6 @@
 
 void ExtendedFilter::anchor() { }
 
+void ExtendedRMFilter::anchor() { }
+
 void ExactFilter::anchor() { }
diff --git a/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.h b/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.h
index c77b4c2..f0b8af5 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.h
+++ b/src/llvm-project/llvm/utils/TableGen/X86ModRMFilters.h
@@ -108,6 +108,29 @@
   }
 };
 
+/// ExtendedRMFilter - Extended opcodes are classified based on the value of the
+///   mod field [bits 7-6] and the value of the nnn field [bits 2-0].
+class ExtendedRMFilter : public ModRMFilter {
+  void anchor() override;
+  bool R;
+  uint8_t NNN;
+public:
+  /// Constructor
+  ///
+  /// \param r   True if the mod field must be set to 11; false otherwise.
+  ///            The name is explained at ModFilter.
+  /// \param nnn The required value of the nnn field.
+  ExtendedRMFilter(bool r, uint8_t nnn) :
+    ModRMFilter(),
+    R(r),
+    NNN(nnn) {
+  }
+
+  bool accepts(uint8_t modRM) const override {
+    return ((R && ((modRM & 0xc0) == 0xc0)) &&
+            ((modRM & 0x7) == NNN));
+  }
+};
 /// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR)
 ///   requires the ModR/M byte to have a specific value.
 class ExactFilter : public ModRMFilter {
diff --git a/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp b/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
index 1048ef8..6a245b5 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -65,7 +65,7 @@
   UID = uid;
 
   Rec = insn.TheDef;
-  Name = Rec->getName();
+  Name = std::string(Rec->getName());
   Spec = &tables.specForUID(UID);
 
   if (!Rec->isSubClassOf("X86Inst")) {
@@ -94,7 +94,7 @@
   ForceDisassemble   = Rec->getValueAsBit("ForceDisassemble");
   CD8_Scale          = byteFromRec(Rec, "CD8_Scale");
 
-  Name      = Rec->getName();
+  Name = std::string(Rec->getName());
 
   Operands = &insn.Operands.OperandList;
 
@@ -352,10 +352,13 @@
   // The scaling factor for AVX512 compressed displacement encoding is an
   // instruction attribute.  Adjust the ModRM encoding type to include the
   // scale for compressed displacement.
-  if ((encoding != ENCODING_RM && encoding != ENCODING_VSIB) ||CD8_Scale == 0)
+  if ((encoding != ENCODING_RM &&
+       encoding != ENCODING_VSIB &&
+       encoding != ENCODING_SIB) ||CD8_Scale == 0)
     return;
   encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale));
   assert(((encoding >= ENCODING_RM && encoding <= ENCODING_RM_CD64) ||
+          (encoding == ENCODING_SIB) ||
           (encoding >= ENCODING_VSIB && encoding <= ENCODING_VSIB_CD64)) &&
          "Invalid CDisp scaling");
 }
@@ -383,12 +386,12 @@
 
   StringRef typeName = (*Operands)[operandIndex].Rec->getName();
 
-  OperandEncoding encoding = encodingFromString(typeName, OpSize);
+  OperandEncoding encoding = encodingFromString(std::string(typeName), OpSize);
   // Adjust the encoding type for an operand based on the instruction.
   adjustOperandEncoding(encoding);
   Spec->operands[operandIndex].encoding = encoding;
-  Spec->operands[operandIndex].type = typeFromString(typeName,
-                                                     HasREX_WPrefix, OpSize);
+  Spec->operands[operandIndex].type =
+      typeFromString(std::string(typeName), HasREX_WPrefix, OpSize);
 
   ++operandIndex;
   ++physicalOperandIndex;
@@ -459,6 +462,8 @@
 
   switch (Form) {
   default: llvm_unreachable("Unhandled form");
+  case X86Local::PrefixByte:
+    return;
   case X86Local::RawFrmSrc:
     HANDLE_OPERAND(relocation);
     return;
@@ -517,6 +522,7 @@
     HANDLE_OPTIONAL(immediate)
     break;
   case X86Local::MRMDestMem:
+  case X86Local::MRMDestMemFSIB:
     // Operand 1 is a memory operand (possibly SIB-extended)
     // Operand 2 is a register operand in the Reg/Opcode field.
     // - In AVX, there is a register operand in the VEX.vvvv field here -
@@ -587,6 +593,7 @@
     HANDLE_OPERAND(opcodeModifier)
     break;
   case X86Local::MRMSrcMem:
+  case X86Local::MRMSrcMemFSIB:
     // Operand 1 is a register operand in the Reg/Opcode field.
     // Operand 2 is a memory operand (possibly SIB-extended)
     // - In AVX, there is a register operand in the VEX.vvvv field here -
@@ -639,6 +646,10 @@
     HANDLE_OPERAND(rmRegister)
     HANDLE_OPERAND(opcodeModifier)
     break;
+  case X86Local::MRMr0:
+    // Operand 1 is a register operand in the R/M field.
+    HANDLE_OPERAND(roRegister)
+    break;
   case X86Local::MRMXr:
   case X86Local::MRM0r:
   case X86Local::MRM1r:
@@ -706,6 +717,14 @@
     HANDLE_OPERAND(immediate)
     HANDLE_OPERAND(immediate)
     break;
+  case X86Local::MRM0X:
+  case X86Local::MRM1X:
+  case X86Local::MRM2X:
+  case X86Local::MRM3X:
+  case X86Local::MRM4X:
+  case X86Local::MRM5X:
+  case X86Local::MRM6X:
+  case X86Local::MRM7X:
 #define MAP(from, to) case X86Local::MRM_##from:
   X86_INSTR_MRM_MAPPING
 #undef MAP
@@ -749,6 +768,7 @@
   case X86Local::RawFrmImm8:
   case X86Local::RawFrmImm16:
   case X86Local::AddCCFrm:
+  case X86Local::PrefixByte:
     filter = std::make_unique<DumbFilter>();
     break;
   case X86Local::MRMDestReg:
@@ -761,7 +781,9 @@
     filter = std::make_unique<ModFilter>(true);
     break;
   case X86Local::MRMDestMem:
+  case X86Local::MRMDestMemFSIB:
   case X86Local::MRMSrcMem:
+  case X86Local::MRMSrcMemFSIB:
   case X86Local::MRMSrcMem4VOp3:
   case X86Local::MRMSrcMemOp4:
   case X86Local::MRMSrcMemCC:
@@ -775,6 +797,15 @@
   case X86Local::MRM6r: case X86Local::MRM7r:
     filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0r);
     break;
+  case X86Local::MRM0X: case X86Local::MRM1X:
+  case X86Local::MRM2X: case X86Local::MRM3X:
+  case X86Local::MRM4X: case X86Local::MRM5X:
+  case X86Local::MRM6X: case X86Local::MRM7X:
+    filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0X);
+    break;
+  case X86Local::MRMr0:
+    filter = std::make_unique<ExtendedRMFilter>(true, Form - X86Local::MRMr0);
+    break;
   case X86Local::MRM0m: case X86Local::MRM1m:
   case X86Local::MRM2m: case X86Local::MRM3m:
   case X86Local::MRM4m: case X86Local::MRM5m:
@@ -843,6 +874,7 @@
   TYPE("i16imm",              TYPE_IMM)
   TYPE("i16i8imm",            TYPE_IMM)
   TYPE("GR16",                TYPE_R16)
+  TYPE("GR16orGR32orGR64",    TYPE_R16)
   TYPE("i32mem",              TYPE_M)
   TYPE("i32imm",              TYPE_IMM)
   TYPE("i32i8imm",            TYPE_IMM)
@@ -894,6 +926,7 @@
   TYPE("i64imm",              TYPE_IMM)
   TYPE("anymem",              TYPE_M)
   TYPE("opaquemem",           TYPE_M)
+  TYPE("sibmem",              TYPE_MSIB)
   TYPE("SEGMENT_REG",         TYPE_SEGMENTREG)
   TYPE("DEBUG_REG",           TYPE_DEBUGREG)
   TYPE("CONTROL_REG",         TYPE_CONTROLREG)
@@ -952,6 +985,7 @@
   TYPE("vz256mem",            TYPE_MVSIBZ)
   TYPE("vz512mem",            TYPE_MVSIBZ)
   TYPE("BNDR",                TYPE_BNDR)
+  TYPE("TILE",                TYPE_TMM)
   errs() << "Unhandled type string " << s << "\n";
   llvm_unreachable("Unhandled type string");
 }
@@ -991,6 +1025,7 @@
   ENCODING("VR128X",          ENCODING_IB)
   ENCODING("VR256X",          ENCODING_IB)
   ENCODING("VR512",           ENCODING_IB)
+  ENCODING("TILE",            ENCODING_IB)
   errs() << "Unhandled immediate encoding " << s << "\n";
   llvm_unreachable("Unhandled immediate encoding");
 }
@@ -1001,6 +1036,7 @@
   ENCODING("RST",             ENCODING_FP)
   ENCODING("RSTi",            ENCODING_FP)
   ENCODING("GR16",            ENCODING_RM)
+  ENCODING("GR16orGR32orGR64",ENCODING_RM)
   ENCODING("GR32",            ENCODING_RM)
   ENCODING("GR32orGR64",      ENCODING_RM)
   ENCODING("GR64",            ENCODING_RM)
@@ -1029,6 +1065,7 @@
   ENCODING("VK8PAIR",         ENCODING_RM)
   ENCODING("VK16PAIR",        ENCODING_RM)
   ENCODING("BNDR",            ENCODING_RM)
+  ENCODING("TILE",            ENCODING_RM)
   errs() << "Unhandled R/M register encoding " << s << "\n";
   llvm_unreachable("Unhandled R/M register encoding");
 }
@@ -1037,6 +1074,7 @@
 RecognizableInstr::roRegisterEncodingFromString(const std::string &s,
                                                 uint8_t OpSize) {
   ENCODING("GR16",            ENCODING_REG)
+  ENCODING("GR16orGR32orGR64",ENCODING_REG)
   ENCODING("GR32",            ENCODING_REG)
   ENCODING("GR32orGR64",      ENCODING_REG)
   ENCODING("GR64",            ENCODING_REG)
@@ -1075,6 +1113,7 @@
   ENCODING("VK32WM",          ENCODING_REG)
   ENCODING("VK64WM",          ENCODING_REG)
   ENCODING("BNDR",            ENCODING_REG)
+  ENCODING("TILE",            ENCODING_REG)
   errs() << "Unhandled reg/opcode register encoding " << s << "\n";
   llvm_unreachable("Unhandled reg/opcode register encoding");
 }
@@ -1106,6 +1145,7 @@
   ENCODING("VK4PAIR",         ENCODING_VVVV)
   ENCODING("VK8PAIR",         ENCODING_VVVV)
   ENCODING("VK16PAIR",        ENCODING_VVVV)
+  ENCODING("TILE",            ENCODING_VVVV)
   errs() << "Unhandled VEX.vvvv register encoding " << s << "\n";
   llvm_unreachable("Unhandled VEX.vvvv register encoding");
 }
@@ -1146,6 +1186,7 @@
   ENCODING("lea64mem",        ENCODING_RM)
   ENCODING("anymem",          ENCODING_RM)
   ENCODING("opaquemem",       ENCODING_RM)
+  ENCODING("sibmem",          ENCODING_SIB)
   ENCODING("vx64mem",         ENCODING_VSIB)
   ENCODING("vx128mem",        ENCODING_VSIB)
   ENCODING("vx256mem",        ENCODING_VSIB)
diff --git a/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.h b/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.h
index b15bef4..a7b88b4 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.h
+++ b/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.h
@@ -102,22 +102,28 @@
     RawFrmImm8    = 7,
     RawFrmImm16   = 8,
     AddCCFrm      = 9,
-    MRMDestMem     = 32,
-    MRMSrcMem      = 33,
-    MRMSrcMem4VOp3 = 34,
-    MRMSrcMemOp4   = 35,
-    MRMSrcMemCC    = 36,
-    MRMXmCC = 38, MRMXm = 39,
-    MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43,
-    MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47,
-    MRMDestReg     = 48,
-    MRMSrcReg      = 49,
-    MRMSrcReg4VOp3 = 50,
-    MRMSrcRegOp4   = 51,
-    MRMSrcRegCC    = 52,
-    MRMXrCC = 54, MRMXr = 55,
-    MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59,
-    MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63,
+    PrefixByte    = 10,
+    MRMr0          = 21,
+    MRMSrcMemFSIB  = 22,
+    MRMDestMemFSIB = 23,
+    MRMDestMem     = 24,
+    MRMSrcMem      = 25,
+    MRMSrcMem4VOp3 = 26,
+    MRMSrcMemOp4   = 27,
+    MRMSrcMemCC    = 28,
+    MRMXmCC = 30, MRMXm = 31,
+    MRM0m = 32, MRM1m = 33, MRM2m = 34, MRM3m = 35,
+    MRM4m = 36, MRM5m = 37, MRM6m = 38, MRM7m = 39,
+    MRMDestReg     = 40,
+    MRMSrcReg      = 41,
+    MRMSrcReg4VOp3 = 42,
+    MRMSrcRegOp4   = 43,
+    MRMSrcRegCC    = 44,
+    MRMXrCC = 46, MRMXr = 47,
+    MRM0r = 48, MRM1r = 49, MRM2r = 50, MRM3r = 51,
+    MRM4r = 52, MRM5r = 53, MRM6r = 54, MRM7r = 55,
+    MRM0X = 56, MRM1X = 57, MRM2X = 58, MRM3X = 59,
+    MRM4X = 60, MRM5X = 61, MRM6X = 62, MRM7X = 63,
 #define MAP(from, to) MRM_##from = to,
     X86_INSTR_MRM_MAPPING
 #undef MAP