[Mlir-commits] [mlir] 62e2c7f - [LLVM][TableGen] Change all `Init` pointers to const (#112705)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Oct 18 07:50:29 PDT 2024


Author: Rahul Joshi
Date: 2024-10-18T07:50:22-07:00
New Revision: 62e2c7fb2d18b43149a07526f6a3c0563d50e2fa

URL: https://github.com/llvm/llvm-project/commit/62e2c7fb2d18b43149a07526f6a3c0563d50e2fa
DIFF: https://github.com/llvm/llvm-project/commit/62e2c7fb2d18b43149a07526f6a3c0563d50e2fa.diff

LOG: [LLVM][TableGen] Change all `Init` pointers to const (#112705)

This is a part of effort to have better const correctness in TableGen
backends:


https://discourse.llvm.org/t/psa-planned-changes-to-tablegen-getallderiveddefinitions-api-potential-downstream-breakages/81089

Added: 
    

Modified: 
    clang/utils/TableGen/ClangOptionDocEmitter.cpp
    llvm/include/llvm/TableGen/Error.h
    llvm/include/llvm/TableGen/Record.h
    llvm/lib/TableGen/DetailedRecordsBackend.cpp
    llvm/lib/TableGen/Error.cpp
    llvm/lib/TableGen/Record.cpp
    llvm/lib/TableGen/TGParser.cpp
    llvm/lib/TableGen/TGParser.h
    llvm/utils/TableGen/AsmMatcherEmitter.cpp
    llvm/utils/TableGen/AsmWriterEmitter.cpp
    llvm/utils/TableGen/Attributes.cpp
    llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
    llvm/utils/TableGen/CodeEmitterGen.cpp
    llvm/utils/TableGen/CodeGenMapTable.cpp
    llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
    llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
    llvm/utils/TableGen/Common/CodeGenInstAlias.cpp
    llvm/utils/TableGen/Common/CodeGenInstAlias.h
    llvm/utils/TableGen/Common/CodeGenInstruction.cpp
    llvm/utils/TableGen/Common/CodeGenInstruction.h
    llvm/utils/TableGen/Common/CodeGenRegisters.cpp
    llvm/utils/TableGen/Common/CodeGenSchedule.cpp
    llvm/utils/TableGen/Common/CodeGenTarget.cpp
    llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
    llvm/utils/TableGen/Common/GlobalISel/Patterns.cpp
    llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp
    llvm/utils/TableGen/CompressInstEmitter.cpp
    llvm/utils/TableGen/DAGISelMatcherGen.cpp
    llvm/utils/TableGen/DFAEmitter.cpp
    llvm/utils/TableGen/DXILEmitter.cpp
    llvm/utils/TableGen/DecoderEmitter.cpp
    llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
    llvm/utils/TableGen/GlobalISelEmitter.cpp
    llvm/utils/TableGen/InstrInfoEmitter.cpp
    llvm/utils/TableGen/OptionParserEmitter.cpp
    llvm/utils/TableGen/RegisterInfoEmitter.cpp
    llvm/utils/TableGen/SearchableTableEmitter.cpp
    llvm/utils/TableGen/X86FoldTablesEmitter.cpp
    llvm/utils/TableGen/X86InstrMappingEmitter.cpp
    llvm/utils/TableGen/X86RecognizableInstr.cpp
    mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp

Removed: 
    


################################################################################
diff  --git a/clang/utils/TableGen/ClangOptionDocEmitter.cpp b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
index b67c5d1d1146c6..ba8840c1bdca78 100644
--- a/clang/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/clang/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -367,13 +367,13 @@ void emitOption(const DocumentedOption &Option, const Record *DocInfo,
   for (const Record *VisibilityHelp :
        R->getValueAsListOfDefs("HelpTextsForVariants")) {
     // This is a list of visibilities.
-    ArrayRef<Init *> Visibilities =
+    ArrayRef<const Init *> Visibilities =
         VisibilityHelp->getValueAsListInit("Visibilities")->getValues();
 
     // See if any of the program's visibilities are in the list.
     for (StringRef DocInfoMask :
          DocInfo->getValueAsListOfStrings("VisibilityMask")) {
-      for (Init *Visibility : Visibilities) {
+      for (const Init *Visibility : Visibilities) {
         if (Visibility->getAsUnquotedString() == DocInfoMask) {
           // Use the first one we find.
           Description = escapeRST(VisibilityHelp->getValueAsString("Text"));

diff  --git a/llvm/include/llvm/TableGen/Error.h b/llvm/include/llvm/TableGen/Error.h
index 512249b0160c24..b963dcba9869fb 100644
--- a/llvm/include/llvm/TableGen/Error.h
+++ b/llvm/include/llvm/TableGen/Error.h
@@ -49,8 +49,8 @@ void PrintError(const RecordVal *RecVal, const Twine &Msg);
 [[noreturn]] void PrintFatalError(function_ref<void(raw_ostream &OS)> PrintMsg);
 
 // Returns true if the assert failed.
-bool CheckAssert(SMLoc Loc, Init *Condition, Init *Message);
-void dumpMessage(SMLoc Loc, Init *Message);
+bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message);
+void dumpMessage(SMLoc Loc, const Init *Message);
 
 extern SourceMgr SrcMgr;
 extern unsigned ErrorsPrinted;

diff  --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index f856ff4cbd34b5..63267b7633f6cf 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -374,25 +374,26 @@ class Init {
   /// If this value is convertible to type \p Ty, return a value whose
   /// type is \p Ty, generating a !cast operation if required.
   /// Otherwise, return null.
-  virtual Init *getCastTo(const RecTy *Ty) const = 0;
+  virtual const Init *getCastTo(const RecTy *Ty) const = 0;
 
   /// Convert to a value whose type is \p Ty, or return null if this
   /// is not possible. This can happen if the value's type is convertible
   /// to \p Ty, but there are unresolved references.
-  virtual Init *convertInitializerTo(const RecTy *Ty) const = 0;
+  virtual const Init *convertInitializerTo(const RecTy *Ty) const = 0;
 
   /// This function is used to implement the bit range
   /// selection operator. Given a value, it selects the specified bits,
   /// returning them as a new \p Init of type \p bits. If it is not legal
   /// to use the bit selection operator on this value, null is returned.
-  virtual Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
+  virtual const Init *
+  convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
     return nullptr;
   }
 
   /// This function is used to implement the FieldInit class.
   /// Implementors of this method should return the type of the named
   /// field if they are of type record.
-  virtual const RecTy *getFieldType(StringInit *FieldName) const {
+  virtual const RecTy *getFieldType(const StringInit *FieldName) const {
     return nullptr;
   }
 
@@ -400,12 +401,12 @@ class Init {
   /// variables which may not be defined at the time the expression is formed.
   /// If a value is set for the variable later, this method will be called on
   /// users of the value to allow the value to propagate out.
-  virtual Init *resolveReferences(Resolver &R) const {
+  virtual const Init *resolveReferences(Resolver &R) const {
     return const_cast<Init *>(this);
   }
 
   /// Get the \p Init value of the specified bit.
-  virtual Init *getBit(unsigned Bit) const = 0;
+  virtual const Init *getBit(unsigned Bit) const = 0;
 };
 
 inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) {
@@ -436,15 +437,16 @@ class TypedInit : public Init {
   /// Get the record keeper that initialized this Init.
   RecordKeeper &getRecordKeeper() const { return ValueTy->getRecordKeeper(); }
 
-  Init *getCastTo(const RecTy *Ty) const override;
-  Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *getCastTo(const RecTy *Ty) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
 
-  Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
+  const Init *
+  convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
 
   /// This method is used to implement the FieldInit class.
   /// Implementors of this method should return the type of the named field if
   /// they are of type record.
-  const RecTy *getFieldType(StringInit *FieldName) const override;
+  const RecTy *getFieldType(const StringInit *FieldName) const override;
 };
 
 /// '?' - Represents an uninitialized value.
@@ -470,10 +472,10 @@ class UnsetInit : public Init {
   /// Get the record keeper that initialized this Init.
   RecordKeeper &getRecordKeeper() const { return RK; }
 
-  Init *getCastTo(const RecTy *Ty) const override;
-  Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *getCastTo(const RecTy *Ty) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     return const_cast<UnsetInit*>(this);
   }
 
@@ -487,7 +489,7 @@ class UnsetInit : public Init {
 };
 
 // Represent an argument.
-using ArgAuxType = std::variant<unsigned, Init *>;
+using ArgAuxType = std::variant<unsigned, const Init *>;
 class ArgumentInit : public Init, public FoldingSetNode {
 public:
   enum Kind {
@@ -496,11 +498,11 @@ class ArgumentInit : public Init, public FoldingSetNode {
   };
 
 private:
-  Init *Value;
+  const Init *Value;
   ArgAuxType Aux;
 
 protected:
-  explicit ArgumentInit(Init *Value, ArgAuxType Aux)
+  explicit ArgumentInit(const Init *Value, ArgAuxType Aux)
       : Init(IK_ArgumentInit), Value(Value), Aux(Aux) {}
 
 public:
@@ -511,25 +513,27 @@ class ArgumentInit : public Init, public FoldingSetNode {
 
   RecordKeeper &getRecordKeeper() const { return Value->getRecordKeeper(); }
 
-  static ArgumentInit *get(Init *Value, ArgAuxType Aux);
+  static const ArgumentInit *get(const Init *Value, ArgAuxType Aux);
 
   bool isPositional() const { return Aux.index() == Positional; }
   bool isNamed() const { return Aux.index() == Named; }
 
-  Init *getValue() const { return Value; }
+  const Init *getValue() const { return Value; }
   unsigned getIndex() const {
     assert(isPositional() && "Should be positional!");
     return std::get<Positional>(Aux);
   }
-  Init *getName() const {
+  const Init *getName() const {
     assert(isNamed() && "Should be named!");
     return std::get<Named>(Aux);
   }
-  ArgumentInit *cloneWithValue(Init *Value) const { return get(Value, Aux); }
+  const ArgumentInit *cloneWithValue(const Init *Value) const {
+    return get(Value, Aux);
+  }
 
   void Profile(FoldingSetNodeID &ID) const;
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
   std::string getAsString() const override {
     if (isPositional())
       return utostr(getIndex()) + ": " + Value->getAsString();
@@ -541,11 +545,11 @@ class ArgumentInit : public Init, public FoldingSetNode {
 
   bool isComplete() const override { return false; }
   bool isConcrete() const override { return false; }
-  Init *getBit(unsigned Bit) const override { return Value->getBit(Bit); }
-  Init *getCastTo(const RecTy *Ty) const override {
+  const Init *getBit(unsigned Bit) const override { return Value->getBit(Bit); }
+  const Init *getCastTo(const RecTy *Ty) const override {
     return Value->getCastTo(Ty);
   }
-  Init *convertInitializerTo(const RecTy *Ty) const override {
+  const Init *convertInitializerTo(const RecTy *Ty) const override {
     return Value->convertInitializerTo(Ty);
   }
 };
@@ -571,9 +575,9 @@ class BitInit final : public TypedInit {
 
   bool getValue() const { return Value; }
 
-  Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     assert(Bit < 1 && "Bit index out of range!");
     return const_cast<BitInit*>(this);
   }
@@ -584,8 +588,9 @@ class BitInit final : public TypedInit {
 
 /// '{ a, b, c }' - Represents an initializer for a BitsRecTy value.
 /// It contains a vector of bits, whose size is determined by the type.
-class BitsInit final : public TypedInit, public FoldingSetNode,
-                       public TrailingObjects<BitsInit, Init *> {
+class BitsInit final : public TypedInit,
+                       public FoldingSetNode,
+                       public TrailingObjects<BitsInit, const Init *> {
   unsigned NumBits;
 
   BitsInit(RecordKeeper &RK, unsigned N)
@@ -602,14 +607,15 @@ class BitsInit final : public TypedInit, public FoldingSetNode,
     return I->getKind() == IK_BitsInit;
   }
 
-  static BitsInit *get(RecordKeeper &RK, ArrayRef<Init *> Range);
+  static BitsInit *get(RecordKeeper &RK, ArrayRef<const Init *> Range);
 
   void Profile(FoldingSetNodeID &ID) const;
 
   unsigned getNumBits() const { return NumBits; }
 
-  Init *convertInitializerTo(const RecTy *Ty) const override;
-  Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *
+  convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
   std::optional<int64_t> convertInitializerToInt() const;
 
   bool isComplete() const override {
@@ -627,11 +633,11 @@ class BitsInit final : public TypedInit, public FoldingSetNode,
   bool isConcrete() const override;
   std::string getAsString() const override;
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     assert(Bit < NumBits && "Bit index out of range!");
-    return getTrailingObjects<Init *>()[Bit];
+    return getTrailingObjects<const Init *>()[Bit];
   }
 };
 
@@ -654,13 +660,14 @@ class IntInit : public TypedInit {
 
   int64_t getValue() const { return Value; }
 
-  Init *convertInitializerTo(const RecTy *Ty) const override;
-  Init *convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *
+  convertInitializerBitRange(ArrayRef<unsigned> Bits) const override;
 
   bool isConcrete() const override { return true; }
   std::string getAsString() const override;
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     return BitInit::get(getRecordKeeper(), (Value & (1ULL << Bit)) != 0);
   }
 };
@@ -684,13 +691,13 @@ class AnonymousNameInit : public TypedInit {
 
   unsigned getValue() const { return Value; }
 
-  StringInit *getNameInit() const;
+  const StringInit *getNameInit() const;
 
   std::string getAsString() const override;
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     llvm_unreachable("Illegal bit reference off string");
   }
 };
@@ -718,8 +725,8 @@ class StringInit : public TypedInit {
     return I->getKind() == IK_StringInit;
   }
 
-  static StringInit *get(RecordKeeper &RK, StringRef,
-                         StringFormat Fmt = SF_String);
+  static const StringInit *get(RecordKeeper &RK, StringRef,
+                               StringFormat Fmt = SF_String);
 
   static StringFormat determineFormat(StringFormat Fmt1, StringFormat Fmt2) {
     return (Fmt1 == SF_Code || Fmt2 == SF_Code) ? SF_Code : SF_String;
@@ -729,7 +736,7 @@ class StringInit : public TypedInit {
   StringFormat getFormat() const { return Format; }
   bool hasCodeFormat() const { return Format == SF_Code; }
 
-  Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
 
   bool isConcrete() const override { return true; }
 
@@ -744,19 +751,20 @@ class StringInit : public TypedInit {
     return std::string(Value);
   }
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     llvm_unreachable("Illegal bit reference off string");
   }
 };
 
 /// [AL, AH, CL] - Represent a list of defs
 ///
-class ListInit final : public TypedInit, public FoldingSetNode,
-                       public TrailingObjects<ListInit, Init *> {
+class ListInit final : public TypedInit,
+                       public FoldingSetNode,
+                       public TrailingObjects<ListInit, const Init *> {
   unsigned NumValues;
 
 public:
-  using const_iterator = Init *const *;
+  using const_iterator = const Init *const *;
 
 private:
   explicit ListInit(unsigned N, const RecTy *EltTy)
@@ -772,13 +780,13 @@ class ListInit final : public TypedInit, public FoldingSetNode,
   static bool classof(const Init *I) {
     return I->getKind() == IK_ListInit;
   }
-  static ListInit *get(ArrayRef<Init *> Range, const RecTy *EltTy);
+  static const ListInit *get(ArrayRef<const Init *> Range, const RecTy *EltTy);
 
   void Profile(FoldingSetNodeID &ID) const;
 
-  Init *getElement(unsigned i) const {
+  const Init *getElement(unsigned i) const {
     assert(i < NumValues && "List element index out of range!");
-    return getTrailingObjects<Init *>()[i];
+    return getTrailingObjects<const Init *>()[i];
   }
   const RecTy *getElementType() const {
     return cast<ListRecTy>(getType())->getElementType();
@@ -786,30 +794,30 @@ class ListInit final : public TypedInit, public FoldingSetNode,
 
   const Record *getElementAsRecord(unsigned i) const;
 
-  Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
 
   /// This method is used by classes that refer to other
   /// variables which may not be defined at the time they expression is formed.
   /// If a value is set for the variable later, this method will be called on
   /// users of the value to allow the value to propagate out.
   ///
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
   bool isComplete() const override;
   bool isConcrete() const override;
   std::string getAsString() const override;
 
-  ArrayRef<Init*> getValues() const {
-    return ArrayRef(getTrailingObjects<Init *>(), NumValues);
+  ArrayRef<const Init *> getValues() const {
+    return ArrayRef(getTrailingObjects<const Init *>(), NumValues);
   }
 
-  const_iterator begin() const { return getTrailingObjects<Init *>(); }
+  const_iterator begin() const { return getTrailingObjects<const Init *>(); }
   const_iterator end  () const { return begin() + NumValues; }
 
   size_t         size () const { return NumValues;  }
   bool           empty() const { return NumValues == 0; }
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     llvm_unreachable("Illegal bit reference off list");
   }
 };
@@ -831,12 +839,12 @@ class OpInit : public TypedInit {
   }
 
   // Clone - Clone this operator, replacing arguments with the new list
-  virtual OpInit *clone(ArrayRef<Init *> Operands) const = 0;
+  virtual const OpInit *clone(ArrayRef<const Init *> Operands) const = 0;
 
   virtual unsigned getNumOperands() const = 0;
-  virtual Init *getOperand(unsigned i) const = 0;
+  virtual const Init *getOperand(unsigned i) const = 0;
 
-  Init *getBit(unsigned Bit) const override;
+  const Init *getBit(unsigned Bit) const override;
 };
 
 /// !op (X) - Transform an init.
@@ -859,9 +867,9 @@ class UnOpInit : public OpInit, public FoldingSetNode {
   };
 
 private:
-  Init *LHS;
+  const Init *LHS;
 
-  UnOpInit(UnaryOp opc, Init *lhs, const RecTy *Type)
+  UnOpInit(UnaryOp opc, const Init *lhs, const RecTy *Type)
       : OpInit(IK_UnOpInit, Type, opc), LHS(lhs) {}
 
 public:
@@ -872,12 +880,12 @@ class UnOpInit : public OpInit, public FoldingSetNode {
     return I->getKind() == IK_UnOpInit;
   }
 
-  static UnOpInit *get(UnaryOp opc, Init *lhs, const RecTy *Type);
+  static const UnOpInit *get(UnaryOp opc, const Init *lhs, const RecTy *Type);
 
   void Profile(FoldingSetNodeID &ID) const;
 
   // Clone - Clone this operator, replacing arguments with the new list
-  OpInit *clone(ArrayRef<Init *> Operands) const override {
+  const OpInit *clone(ArrayRef<const Init *> Operands) const override {
     assert(Operands.size() == 1 &&
            "Wrong number of operands for unary operation");
     return UnOpInit::get(getOpcode(), *Operands.begin(), getType());
@@ -885,19 +893,19 @@ class UnOpInit : public OpInit, public FoldingSetNode {
 
   unsigned getNumOperands() const override { return 1; }
 
-  Init *getOperand(unsigned i) const override {
+  const Init *getOperand(unsigned i) const override {
     assert(i == 0 && "Invalid operand id for unary operator");
     return getOperand();
   }
 
   UnaryOp getOpcode() const { return (UnaryOp)Opc; }
-  Init *getOperand() const { return LHS; }
+  const Init *getOperand() const { return LHS; }
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec, bool IsFinal = false) const;
+  const Init *Fold(const Record *CurRec, bool IsFinal = false) const;
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
   std::string getAsString() const override;
 };
@@ -937,9 +945,9 @@ class BinOpInit : public OpInit, public FoldingSetNode {
   };
 
 private:
-  Init *LHS, *RHS;
+  const Init *LHS, *RHS;
 
-  BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, const RecTy *Type)
+  BinOpInit(BinaryOp opc, const Init *lhs, const Init *rhs, const RecTy *Type)
       : OpInit(IK_BinOpInit, Type, opc), LHS(lhs), RHS(rhs) {}
 
 public:
@@ -950,21 +958,22 @@ class BinOpInit : public OpInit, public FoldingSetNode {
     return I->getKind() == IK_BinOpInit;
   }
 
-  static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, const RecTy *Type);
-  static Init *getStrConcat(Init *lhs, Init *rhs);
-  static Init *getListConcat(TypedInit *lhs, Init *rhs);
+  static const BinOpInit *get(BinaryOp opc, const Init *lhs, const Init *rhs,
+                              const RecTy *Type);
+  static const Init *getStrConcat(const Init *lhs, const Init *rhs);
+  static const Init *getListConcat(const TypedInit *lhs, const Init *rhs);
 
   void Profile(FoldingSetNodeID &ID) const;
 
   // Clone - Clone this operator, replacing arguments with the new list
-  OpInit *clone(ArrayRef<Init *> Operands) const override {
+  const OpInit *clone(ArrayRef<const Init *> Operands) const override {
     assert(Operands.size() == 2 &&
            "Wrong number of operands for binary operation");
     return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType());
   }
 
   unsigned getNumOperands() const override { return 2; }
-  Init *getOperand(unsigned i) const override {
+  const Init *getOperand(unsigned i) const override {
     switch (i) {
     default: llvm_unreachable("Invalid operand id for binary operator");
     case 0: return getLHS();
@@ -973,16 +982,17 @@ class BinOpInit : public OpInit, public FoldingSetNode {
   }
 
   BinaryOp getOpcode() const { return (BinaryOp)Opc; }
-  Init *getLHS() const { return LHS; }
-  Init *getRHS() const { return RHS; }
+  const Init *getLHS() const { return LHS; }
+  const Init *getRHS() const { return RHS; }
 
-  std::optional<bool> CompareInit(unsigned Opc, Init *LHS, Init *RHS) const;
+  std::optional<bool> CompareInit(unsigned Opc, const Init *LHS,
+                                  const Init *RHS) const;
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec) const;
+  const Init *Fold(const Record *CurRec) const;
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
   std::string getAsString() const override;
 };
@@ -1004,9 +1014,10 @@ class TernOpInit : public OpInit, public FoldingSetNode {
   };
 
 private:
-  Init *LHS, *MHS, *RHS;
+  const Init *LHS, *MHS, *RHS;
 
-  TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, const RecTy *Type)
+  TernOpInit(TernaryOp opc, const Init *lhs, const Init *mhs, const Init *rhs,
+             const RecTy *Type)
       : OpInit(IK_TernOpInit, Type, opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
 
 public:
@@ -1017,13 +1028,13 @@ class TernOpInit : public OpInit, public FoldingSetNode {
     return I->getKind() == IK_TernOpInit;
   }
 
-  static TernOpInit *get(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs,
-                         const RecTy *Type);
+  static const TernOpInit *get(TernaryOp opc, const Init *lhs, const Init *mhs,
+                               const Init *rhs, const RecTy *Type);
 
   void Profile(FoldingSetNodeID &ID) const;
 
   // Clone - Clone this operator, replacing arguments with the new list
-  OpInit *clone(ArrayRef<Init *> Operands) const override {
+  const OpInit *clone(ArrayRef<const Init *> Operands) const override {
     assert(Operands.size() == 3 &&
            "Wrong number of operands for ternary operation");
     return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2],
@@ -1031,7 +1042,7 @@ class TernOpInit : public OpInit, public FoldingSetNode {
   }
 
   unsigned getNumOperands() const override { return 3; }
-  Init *getOperand(unsigned i) const override {
+  const Init *getOperand(unsigned i) const override {
     switch (i) {
     default: llvm_unreachable("Invalid operand id for ternary operator");
     case 0: return getLHS();
@@ -1041,19 +1052,19 @@ class TernOpInit : public OpInit, public FoldingSetNode {
   }
 
   TernaryOp getOpcode() const { return (TernaryOp)Opc; }
-  Init *getLHS() const { return LHS; }
-  Init *getMHS() const { return MHS; }
-  Init *getRHS() const { return RHS; }
+  const Init *getLHS() const { return LHS; }
+  const Init *getMHS() const { return MHS; }
+  const Init *getRHS() const { return RHS; }
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec) const;
+  const Init *Fold(const Record *CurRec) const;
 
   bool isComplete() const override {
     return LHS->isComplete() && MHS->isComplete() && RHS->isComplete();
   }
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
   std::string getAsString() const override;
 };
@@ -1061,8 +1072,9 @@ class TernOpInit : public OpInit, public FoldingSetNode {
 /// !cond(condition_1: value1, ... , condition_n: value)
 /// Selects the first value for which condition is true.
 /// Otherwise reports an error.
-class CondOpInit final : public TypedInit, public FoldingSetNode,
-                      public TrailingObjects<CondOpInit, Init *> {
+class CondOpInit final : public TypedInit,
+                         public FoldingSetNode,
+                         public TrailingObjects<CondOpInit, const Init *> {
   unsigned NumConds;
   const RecTy *ValType;
 
@@ -1081,8 +1093,8 @@ class CondOpInit final : public TypedInit, public FoldingSetNode,
     return I->getKind() == IK_CondOpInit;
   }
 
-  static CondOpInit *get(ArrayRef<Init *> C, ArrayRef<Init *> V,
-                         const RecTy *Type);
+  static const CondOpInit *get(ArrayRef<const Init *> C,
+                               ArrayRef<const Init *> V, const RecTy *Type);
 
   void Profile(FoldingSetNodeID &ID) const;
 
@@ -1090,34 +1102,34 @@ class CondOpInit final : public TypedInit, public FoldingSetNode,
 
   unsigned getNumConds() const { return NumConds; }
 
-  Init *getCond(unsigned Num) const {
+  const Init *getCond(unsigned Num) const {
     assert(Num < NumConds && "Condition number out of range!");
-    return getTrailingObjects<Init *>()[Num];
+    return getTrailingObjects<const Init *>()[Num];
   }
 
-  Init *getVal(unsigned Num) const {
+  const Init *getVal(unsigned Num) const {
     assert(Num < NumConds && "Val number out of range!");
-    return getTrailingObjects<Init *>()[Num+NumConds];
+    return getTrailingObjects<const Init *>()[Num + NumConds];
   }
 
-  ArrayRef<Init *> getConds() const {
-    return ArrayRef(getTrailingObjects<Init *>(), NumConds);
+  ArrayRef<const Init *> getConds() const {
+    return ArrayRef(getTrailingObjects<const Init *>(), NumConds);
   }
 
-  ArrayRef<Init *> getVals() const {
-    return ArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds);
+  ArrayRef<const Init *> getVals() const {
+    return ArrayRef(getTrailingObjects<const Init *>() + NumConds, NumConds);
   }
 
-  Init *Fold(Record *CurRec) const;
+  const Init *Fold(const Record *CurRec) const;
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
   bool isConcrete() const override;
   bool isComplete() const override;
   std::string getAsString() const override;
 
-  using const_case_iterator = SmallVectorImpl<Init*>::const_iterator;
-  using const_val_iterator = SmallVectorImpl<Init*>::const_iterator;
+  using const_case_iterator = SmallVectorImpl<const Init *>::const_iterator;
+  using const_val_iterator = SmallVectorImpl<const Init *>::const_iterator;
 
   inline const_case_iterator  arg_begin() const { return getConds().begin(); }
   inline const_case_iterator  arg_end  () const { return getConds().end(); }
@@ -1131,20 +1143,16 @@ class CondOpInit final : public TypedInit, public FoldingSetNode,
   inline size_t              val_size () const { return NumConds; }
   inline bool                val_empty() const { return NumConds == 0; }
 
-  Init *getBit(unsigned Bit) const override;
+  const Init *getBit(unsigned Bit) const override;
 };
 
 /// !foldl (a, b, expr, start, lst) - Fold over a list.
 class FoldOpInit : public TypedInit, public FoldingSetNode {
 private:
-  Init *Start;
-  Init *List;
-  Init *A;
-  Init *B;
-  Init *Expr;
+  const Init *Start, *List, *A, *B, *Expr;
 
-  FoldOpInit(Init *Start, Init *List, Init *A, Init *B, Init *Expr,
-             const RecTy *Type)
+  FoldOpInit(const Init *Start, const Init *List, const Init *A, const Init *B,
+             const Init *Expr, const RecTy *Type)
       : TypedInit(IK_FoldOpInit, Type), Start(Start), List(List), A(A), B(B),
         Expr(Expr) {}
 
@@ -1154,20 +1162,21 @@ class FoldOpInit : public TypedInit, public FoldingSetNode {
 
   static bool classof(const Init *I) { return I->getKind() == IK_FoldOpInit; }
 
-  static FoldOpInit *get(Init *Start, Init *List, Init *A, Init *B, Init *Expr,
-                         const RecTy *Type);
+  static const FoldOpInit *get(const Init *Start, const Init *List,
+                               const Init *A, const Init *B, const Init *Expr,
+                               const RecTy *Type);
 
   void Profile(FoldingSetNodeID &ID) const;
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec) const;
+  const Init *Fold(const Record *CurRec) const;
 
   bool isComplete() const override { return false; }
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
-  Init *getBit(unsigned Bit) const override;
+  const Init *getBit(unsigned Bit) const override;
 
   std::string getAsString() const override;
 };
@@ -1176,9 +1185,9 @@ class FoldOpInit : public TypedInit, public FoldingSetNode {
 class IsAOpInit : public TypedInit, public FoldingSetNode {
 private:
   const RecTy *CheckType;
-  Init *Expr;
+  const Init *Expr;
 
-  IsAOpInit(const RecTy *CheckType, Init *Expr)
+  IsAOpInit(const RecTy *CheckType, const Init *Expr)
       : TypedInit(IK_IsAOpInit, IntRecTy::get(CheckType->getRecordKeeper())),
         CheckType(CheckType), Expr(Expr) {}
 
@@ -1188,19 +1197,19 @@ class IsAOpInit : public TypedInit, public FoldingSetNode {
 
   static bool classof(const Init *I) { return I->getKind() == IK_IsAOpInit; }
 
-  static IsAOpInit *get(const RecTy *CheckType, Init *Expr);
+  static const IsAOpInit *get(const RecTy *CheckType, const Init *Expr);
 
   void Profile(FoldingSetNodeID &ID) const;
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold() const;
+  const Init *Fold() const;
 
   bool isComplete() const override { return false; }
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
-  Init *getBit(unsigned Bit) const override;
+  const Init *getBit(unsigned Bit) const override;
 
   std::string getAsString() const override;
 };
@@ -1210,9 +1219,9 @@ class IsAOpInit : public TypedInit, public FoldingSetNode {
 class ExistsOpInit : public TypedInit, public FoldingSetNode {
 private:
   const RecTy *CheckType;
-  Init *Expr;
+  const Init *Expr;
 
-  ExistsOpInit(const RecTy *CheckType, Init *Expr)
+  ExistsOpInit(const RecTy *CheckType, const Init *Expr)
       : TypedInit(IK_ExistsOpInit, IntRecTy::get(CheckType->getRecordKeeper())),
         CheckType(CheckType), Expr(Expr) {}
 
@@ -1222,28 +1231,28 @@ class ExistsOpInit : public TypedInit, public FoldingSetNode {
 
   static bool classof(const Init *I) { return I->getKind() == IK_ExistsOpInit; }
 
-  static ExistsOpInit *get(const RecTy *CheckType, Init *Expr);
+  static const ExistsOpInit *get(const RecTy *CheckType, const Init *Expr);
 
   void Profile(FoldingSetNodeID &ID) const;
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold(Record *CurRec, bool IsFinal = false) const;
+  const Init *Fold(const Record *CurRec, bool IsFinal = false) const;
 
   bool isComplete() const override { return false; }
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
-  Init *getBit(unsigned Bit) const override;
+  const Init *getBit(unsigned Bit) const override;
 
   std::string getAsString() const override;
 };
 
 /// 'Opcode' - Represent a reference to an entire variable object.
 class VarInit : public TypedInit {
-  Init *VarName;
+  const Init *VarName;
 
-  explicit VarInit(Init *VN, const RecTy *T)
+  explicit VarInit(const Init *VN, const RecTy *T)
       : TypedInit(IK_VarInit, T), VarName(VN) {}
 
 public:
@@ -1254,11 +1263,11 @@ class VarInit : public TypedInit {
     return I->getKind() == IK_VarInit;
   }
 
-  static VarInit *get(StringRef VN, const RecTy *T);
-  static VarInit *get(Init *VN, const RecTy *T);
+  static const VarInit *get(StringRef VN, const RecTy *T);
+  static const VarInit *get(const Init *VN, const RecTy *T);
 
   StringRef getName() const;
-  Init *getNameInit() const { return VarName; }
+  const Init *getNameInit() const { return VarName; }
 
   std::string getNameInitAsString() const {
     return getNameInit()->getAsUnquotedString();
@@ -1269,19 +1278,19 @@ class VarInit : public TypedInit {
   /// If a value is set for the variable later, this method will be called on
   /// users of the value to allow the value to propagate out.
   ///
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
-  Init *getBit(unsigned Bit) const override;
+  const Init *getBit(unsigned Bit) const override;
 
   std::string getAsString() const override { return std::string(getName()); }
 };
 
 /// Opcode{0} - Represent access to one bit of a variable or field.
 class VarBitInit final : public TypedInit {
-  TypedInit *TI;
+  const TypedInit *TI;
   unsigned Bit;
 
-  VarBitInit(TypedInit *T, unsigned B)
+  VarBitInit(const TypedInit *T, unsigned B)
       : TypedInit(IK_VarBitInit, BitRecTy::get(T->getRecordKeeper())), TI(T),
         Bit(B) {
     assert(T->getType() &&
@@ -1299,15 +1308,15 @@ class VarBitInit final : public TypedInit {
     return I->getKind() == IK_VarBitInit;
   }
 
-  static VarBitInit *get(TypedInit *T, unsigned B);
+  static const VarBitInit *get(const TypedInit *T, unsigned B);
 
-  Init *getBitVar() const { return TI; }
+  const Init *getBitVar() const { return TI; }
   unsigned getBitNum() const { return Bit; }
 
   std::string getAsString() const override;
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
-  Init *getBit(unsigned B) const override {
+  const Init *getBit(unsigned B) const override {
     assert(B < 1 && "Bit index out of range!");
     return const_cast<VarBitInit*>(this);
   }
@@ -1329,33 +1338,34 @@ class DefInit : public TypedInit {
     return I->getKind() == IK_DefInit;
   }
 
-  Init *convertInitializerTo(const RecTy *Ty) const override;
+  const Init *convertInitializerTo(const RecTy *Ty) const override;
 
   const Record *getDef() const { return Def; }
 
-  const RecTy *getFieldType(StringInit *FieldName) const override;
+  const RecTy *getFieldType(const StringInit *FieldName) const override;
 
   bool isConcrete() const override { return true; }
   std::string getAsString() const override;
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     llvm_unreachable("Illegal bit reference off def");
   }
 };
 
 /// classname<targs...> - Represent an uninstantiated anonymous class
 /// instantiation.
-class VarDefInit final : public TypedInit,
-                         public FoldingSetNode,
-                         public TrailingObjects<VarDefInit, ArgumentInit *> {
+class VarDefInit final
+    : public TypedInit,
+      public FoldingSetNode,
+      public TrailingObjects<VarDefInit, const ArgumentInit *> {
   SMLoc Loc;
   Record *Class;
-  DefInit *Def = nullptr; // after instantiation
+  const DefInit *Def = nullptr; // after instantiation
   unsigned NumArgs;
 
   explicit VarDefInit(SMLoc Loc, Record *Class, unsigned N);
 
-  DefInit *instantiate();
+  const DefInit *instantiate();
 
 public:
   VarDefInit(const VarDefInit &) = delete;
@@ -1367,46 +1377,46 @@ class VarDefInit final : public TypedInit,
   static bool classof(const Init *I) {
     return I->getKind() == IK_VarDefInit;
   }
-  static VarDefInit *get(SMLoc Loc, Record *Class,
-                         ArrayRef<ArgumentInit *> Args);
+  static const VarDefInit *get(SMLoc Loc, Record *Class,
+                               ArrayRef<const ArgumentInit *> Args);
 
   void Profile(FoldingSetNodeID &ID) const;
 
-  Init *resolveReferences(Resolver &R) const override;
-  Init *Fold() const;
+  const Init *resolveReferences(Resolver &R) const override;
+  const Init *Fold() const;
 
   std::string getAsString() const override;
 
-  ArgumentInit *getArg(unsigned i) const {
+  const ArgumentInit *getArg(unsigned i) const {
     assert(i < NumArgs && "Argument index out of range!");
-    return getTrailingObjects<ArgumentInit *>()[i];
+    return getTrailingObjects<const ArgumentInit *>()[i];
   }
 
-  using const_iterator = ArgumentInit *const *;
+  using const_iterator = const ArgumentInit *const *;
 
   const_iterator args_begin() const {
-    return getTrailingObjects<ArgumentInit *>();
+    return getTrailingObjects<const ArgumentInit *>();
   }
   const_iterator args_end  () const { return args_begin() + NumArgs; }
 
   size_t         args_size () const { return NumArgs; }
   bool           args_empty() const { return NumArgs == 0; }
 
-  ArrayRef<ArgumentInit *> args() const {
+  ArrayRef<const ArgumentInit *> args() const {
     return ArrayRef(args_begin(), NumArgs);
   }
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     llvm_unreachable("Illegal bit reference off anonymous def");
   }
 };
 
 /// X.Y - Represent a reference to a subfield of a variable
 class FieldInit : public TypedInit {
-  Init *Rec;                // Record we are referring to
-  StringInit *FieldName;    // Field we are accessing
+  const Init *Rec;             // Record we are referring to
+  const StringInit *FieldName; // Field we are accessing
 
-  FieldInit(Init *R, StringInit *FN)
+  FieldInit(const Init *R, const StringInit *FN)
       : TypedInit(IK_FieldInit, R->getFieldType(FN)), Rec(R), FieldName(FN) {
 #ifndef NDEBUG
     if (!getType()) {
@@ -1426,15 +1436,15 @@ class FieldInit : public TypedInit {
     return I->getKind() == IK_FieldInit;
   }
 
-  static FieldInit *get(Init *R, StringInit *FN);
+  static const FieldInit *get(const Init *R, const StringInit *FN);
 
-  Init *getRecord() const { return Rec; }
-  StringInit *getFieldName() const { return FieldName; }
+  const Init *getRecord() const { return Rec; }
+  const StringInit *getFieldName() const { return FieldName; }
 
-  Init *getBit(unsigned Bit) const override;
+  const Init *getBit(unsigned Bit) const override;
 
-  Init *resolveReferences(Resolver &R) const override;
-  Init *Fold(Record *CurRec) const;
+  const Init *resolveReferences(Resolver &R) const override;
+  const Init *Fold(const Record *CurRec) const;
 
   bool isConcrete() const override;
   std::string getAsString() const override {
@@ -1445,20 +1455,25 @@ class FieldInit : public TypedInit {
 /// (v a, b) - Represent a DAG tree value.  DAG inits are required
 /// to have at least one value then a (possibly empty) list of arguments.  Each
 /// argument can have a name associated with it.
-class DagInit final : public TypedInit, public FoldingSetNode,
-                      public TrailingObjects<DagInit, Init *, StringInit *> {
+class DagInit final
+    : public TypedInit,
+      public FoldingSetNode,
+      public TrailingObjects<DagInit, const Init *, const StringInit *> {
   friend TrailingObjects;
 
-  Init *Val;
-  StringInit *ValName;
+  const Init *Val;
+  const StringInit *ValName;
   unsigned NumArgs;
   unsigned NumArgNames;
 
-  DagInit(Init *V, StringInit *VN, unsigned NumArgs, unsigned NumArgNames)
+  DagInit(const Init *V, const StringInit *VN, unsigned NumArgs,
+          unsigned NumArgNames)
       : TypedInit(IK_DagInit, DagRecTy::get(V->getRecordKeeper())), Val(V),
         ValName(VN), NumArgs(NumArgs), NumArgNames(NumArgNames) {}
 
-  size_t numTrailingObjects(OverloadToken<Init *>) const { return NumArgs; }
+  size_t numTrailingObjects(OverloadToken<const Init *>) const {
+    return NumArgs;
+  }
 
 public:
   DagInit(const DagInit &) = delete;
@@ -1468,17 +1483,19 @@ class DagInit final : public TypedInit, public FoldingSetNode,
     return I->getKind() == IK_DagInit;
   }
 
-  static DagInit *get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
-                      ArrayRef<StringInit*> NameRange);
-  static DagInit *get(Init *V, StringInit *VN,
-                      ArrayRef<std::pair<Init*, StringInit*>> Args);
+  static const DagInit *get(const Init *V, const StringInit *VN,
+                            ArrayRef<const Init *> ArgRange,
+                            ArrayRef<const StringInit *> NameRange);
+  static const DagInit *
+  get(const Init *V, const StringInit *VN,
+      ArrayRef<std::pair<const Init *, const StringInit *>> Args);
 
   void Profile(FoldingSetNodeID &ID) const;
 
-  Init *getOperator() const { return Val; }
+  const Init *getOperator() const { return Val; }
   const Record *getOperatorAsDef(ArrayRef<SMLoc> Loc) const;
 
-  StringInit *getName() const { return ValName; }
+  const StringInit *getName() const { return ValName; }
 
   StringRef getNameStr() const {
     return ValName ? ValName->getValue() : StringRef();
@@ -1486,40 +1503,41 @@ class DagInit final : public TypedInit, public FoldingSetNode,
 
   unsigned getNumArgs() const { return NumArgs; }
 
-  Init *getArg(unsigned Num) const {
+  const Init *getArg(unsigned Num) const {
     assert(Num < NumArgs && "Arg number out of range!");
-    return getTrailingObjects<Init *>()[Num];
+    return getTrailingObjects<const Init *>()[Num];
   }
 
   /// This method looks up the specified argument name and returns its argument
   /// number or std::nullopt if that argument name does not exist.
   std::optional<unsigned> getArgNo(StringRef Name) const;
 
-  StringInit *getArgName(unsigned Num) const {
+  const StringInit *getArgName(unsigned Num) const {
     assert(Num < NumArgNames && "Arg number out of range!");
-    return getTrailingObjects<StringInit *>()[Num];
+    return getTrailingObjects<const StringInit *>()[Num];
   }
 
   StringRef getArgNameStr(unsigned Num) const {
-    StringInit *Init = getArgName(Num);
+    const StringInit *Init = getArgName(Num);
     return Init ? Init->getValue() : StringRef();
   }
 
-  ArrayRef<Init *> getArgs() const {
-    return ArrayRef(getTrailingObjects<Init *>(), NumArgs);
+  ArrayRef<const Init *> getArgs() const {
+    return ArrayRef(getTrailingObjects<const Init *>(), NumArgs);
   }
 
-  ArrayRef<StringInit *> getArgNames() const {
-    return ArrayRef(getTrailingObjects<StringInit *>(), NumArgNames);
+  ArrayRef<const StringInit *> getArgNames() const {
+    return ArrayRef(getTrailingObjects<const StringInit *>(), NumArgNames);
   }
 
-  Init *resolveReferences(Resolver &R) const override;
+  const Init *resolveReferences(Resolver &R) const override;
 
   bool isConcrete() const override;
   std::string getAsString() const override;
 
-  using const_arg_iterator = SmallVectorImpl<Init*>::const_iterator;
-  using const_name_iterator = SmallVectorImpl<StringInit*>::const_iterator;
+  using const_arg_iterator = SmallVectorImpl<const Init *>::const_iterator;
+  using const_name_iterator =
+      SmallVectorImpl<const StringInit *>::const_iterator;
 
   inline const_arg_iterator  arg_begin() const { return getArgs().begin(); }
   inline const_arg_iterator  arg_end  () const { return getArgs().end(); }
@@ -1533,7 +1551,7 @@ class DagInit final : public TypedInit, public FoldingSetNode,
   inline size_t              name_size () const { return NumArgNames; }
   inline bool                name_empty() const { return NumArgNames == 0; }
 
-  Init *getBit(unsigned Bit) const override {
+  const Init *getBit(unsigned Bit) const override {
     llvm_unreachable("Illegal bit reference off dag");
   }
 };
@@ -1555,18 +1573,18 @@ class RecordVal {
   };
 
 private:
-  Init *Name;
+  const Init *Name;
   SMLoc Loc; // Source location of definition of name.
   PointerIntPair<const RecTy *, 2, FieldKind> TyAndKind;
-  Init *Value;
+  const Init *Value;
   bool IsUsed = false;
 
   /// Reference locations to this record value.
   SmallVector<SMRange> ReferenceLocs;
 
 public:
-  RecordVal(Init *N, const RecTy *T, FieldKind K);
-  RecordVal(Init *N, SMLoc Loc, const RecTy *T, FieldKind K);
+  RecordVal(const Init *N, const RecTy *T, FieldKind K);
+  RecordVal(const Init *N, SMLoc Loc, const RecTy *T, FieldKind K);
 
   /// Get the record keeper used to unique this value.
   RecordKeeper &getRecordKeeper() const { return Name->getRecordKeeper(); }
@@ -1575,7 +1593,7 @@ class RecordVal {
   StringRef getName() const;
 
   /// Get the name of the field as an Init.
-  Init *getNameInit() const { return Name; }
+  const Init *getNameInit() const { return Name; }
 
   /// Get the name of the field as a std::string.
   std::string getNameInitAsString() const {
@@ -1602,13 +1620,13 @@ class RecordVal {
   std::string getPrintType() const;
 
   /// Get the value of the field as an Init.
-  Init *getValue() const { return Value; }
+  const Init *getValue() const { return Value; }
 
   /// Set the value of the field from an Init.
-  bool setValue(Init *V);
+  bool setValue(const Init *V);
 
   /// Set the value and source location of the field.
-  bool setValue(Init *V, SMLoc NewLoc);
+  bool setValue(const Init *V, SMLoc NewLoc);
 
   /// Add a reference to this record value.
   void addReferenceLoc(SMRange Loc) { ReferenceLocs.push_back(Loc); }
@@ -1636,35 +1654,35 @@ class Record {
 public:
   struct AssertionInfo {
     SMLoc Loc;
-    Init *Condition;
-    Init *Message;
+    const Init *Condition;
+    const Init *Message;
 
     // User-defined constructor to support std::make_unique(). It can be
     // removed in C++20 when braced initialization is supported.
-    AssertionInfo(SMLoc Loc, Init *Condition, Init *Message)
+    AssertionInfo(SMLoc Loc, const Init *Condition, const Init *Message)
         : Loc(Loc), Condition(Condition), Message(Message) {}
   };
 
   struct DumpInfo {
     SMLoc Loc;
-    Init *Message;
+    const Init *Message;
 
     // User-defined constructor to support std::make_unique(). It can be
     // removed in C++20 when braced initialization is supported.
-    DumpInfo(SMLoc Loc, Init *Message) : Loc(Loc), Message(Message) {}
+    DumpInfo(SMLoc Loc, const Init *Message) : Loc(Loc), Message(Message) {}
   };
 
   enum RecordKind { RK_Def, RK_AnonymousDef, RK_Class, RK_MultiClass };
 
 private:
-  Init *Name;
+  const Init *Name;
   // Location where record was instantiated, followed by the location of
   // multiclass prototypes used, and finally by the locations of references to
   // this record.
   SmallVector<SMLoc, 4> Locs;
   SmallVector<SMLoc, 0> ForwardDeclarationLocs;
   mutable SmallVector<SMRange, 0> ReferenceLocs;
-  SmallVector<Init *, 0> TemplateArgs;
+  SmallVector<const Init *, 0> TemplateArgs;
   SmallVector<RecordVal, 0> Values;
   SmallVector<AssertionInfo, 0> Assertions;
   SmallVector<DumpInfo, 0> Dumps;
@@ -1688,7 +1706,7 @@ class Record {
 
 public:
   // Constructs a record.
-  explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
+  explicit Record(const Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
                   RecordKind Kind = RK_Def)
       : Name(N), Locs(locs), TrackedRecords(records),
         ID(getNewUID(N->getRecordKeeper())), Kind(Kind) {
@@ -1714,15 +1732,13 @@ class Record {
 
   StringRef getName() const { return cast<StringInit>(Name)->getValue(); }
 
-  Init *getNameInit() const {
-    return Name;
-  }
+  const Init *getNameInit() const { return Name; }
 
   std::string getNameInitAsString() const {
     return getNameInit()->getAsUnquotedString();
   }
 
-  void setName(Init *Name);      // Also updates RecordKeeper.
+  void setName(const Init *Name); // Also updates RecordKeeper.
 
   ArrayRef<SMLoc> getLoc() const { return Locs; }
   void appendLoc(SMLoc Loc) { Locs.push_back(Loc); }
@@ -1752,9 +1768,7 @@ class Record {
 
   bool isAnonymous() const { return Kind == RK_AnonymousDef; }
 
-  ArrayRef<Init *> getTemplateArgs() const {
-    return TemplateArgs;
-  }
+  ArrayRef<const Init *> getTemplateArgs() const { return TemplateArgs; }
 
   ArrayRef<RecordVal> getValues() const { return Values; }
 
@@ -1771,7 +1785,7 @@ class Record {
   /// Append the direct superclasses of this record to Classes.
   void getDirectSuperClasses(SmallVectorImpl<const Record *> &Classes) const;
 
-  bool isTemplateArg(Init *Name) const {
+  bool isTemplateArg(const Init *Name) const {
     return llvm::is_contained(TemplateArgs, Name);
   }
 
@@ -1795,7 +1809,7 @@ class Record {
         static_cast<const Record *>(this)->getValue(Name));
   }
 
-  void addTemplateArg(Init *Name) {
+  void addTemplateArg(const Init *Name) {
     assert(!isTemplateArg(Name) && "Template arg already defined!");
     TemplateArgs.push_back(Name);
   }
@@ -1805,7 +1819,7 @@ class Record {
     Values.push_back(RV);
   }
 
-  void removeValue(Init *Name) {
+  void removeValue(const Init *Name) {
     for (unsigned i = 0, e = Values.size(); i != e; ++i)
       if (Values[i].getNameInit() == Name) {
         Values.erase(Values.begin()+i);
@@ -1818,11 +1832,11 @@ class Record {
     removeValue(StringInit::get(getRecords(), Name));
   }
 
-  void addAssertion(SMLoc Loc, Init *Condition, Init *Message) {
+  void addAssertion(SMLoc Loc, const Init *Condition, const Init *Message) {
     Assertions.push_back(AssertionInfo(Loc, Condition, Message));
   }
 
-  void addDump(SMLoc Loc, Init *Message) {
+  void addDump(SMLoc Loc, const Init *Message) {
     Dumps.push_back(DumpInfo(Loc, Message));
   }
 
@@ -1867,7 +1881,7 @@ class Record {
   ///
   /// This is a final resolve: any error messages, e.g. due to undefined !cast
   /// references, are generated now.
-  void resolveReferences(Init *NewName = nullptr);
+  void resolveReferences(const Init *NewName = nullptr);
 
   /// Apply the resolver to the name of the record as well as to the
   /// initializers of all fields of the record except SkipVal.
@@ -1891,7 +1905,7 @@ class Record {
 
   /// Return the initializer for a value with the specified name, or throw an
   /// exception if the field does not exist.
-  Init *getValueInit(StringRef FieldName) const;
+  const Init *getValueInit(StringRef FieldName) const;
 
   /// Return true if the named field is unset.
   bool isValueUnset(StringRef FieldName) const {
@@ -1911,12 +1925,12 @@ class Record {
   /// This method looks up the specified field and returns its value as a
   /// BitsInit, throwing an exception if the field does not exist or if the
   /// value is not the right type.
-  BitsInit *getValueAsBitsInit(StringRef FieldName) const;
+  const BitsInit *getValueAsBitsInit(StringRef FieldName) const;
 
   /// This method looks up the specified field and returns its value as a
   /// ListInit, throwing an exception if the field does not exist or if the
   /// value is not the right type.
-  ListInit *getValueAsListInit(StringRef FieldName) const;
+  const ListInit *getValueAsListInit(StringRef FieldName) const;
 
   /// This method looks up the specified field and returns its value as a
   /// vector of records, throwing an exception if the field does not exist or
@@ -1961,14 +1975,14 @@ class Record {
   /// This method looks up the specified field and returns its value as an Dag,
   /// throwing an exception if the field does not exist or if the value is not
   /// the right type.
-  DagInit *getValueAsDag(StringRef FieldName) const;
+  const DagInit *getValueAsDag(StringRef FieldName) const;
 };
 
 raw_ostream &operator<<(raw_ostream &OS, const Record &R);
 
 class RecordKeeper {
   using RecordMap = std::map<std::string, std::unique_ptr<Record>, std::less<>>;
-  using GlobalMap = std::map<std::string, Init *, std::less<>>;
+  using GlobalMap = std::map<std::string, const Init *, std::less<>>;
 
 public:
   RecordKeeper();
@@ -2002,7 +2016,7 @@ class RecordKeeper {
   }
 
   /// Get the \p Init value of the specified global variable.
-  Init *getGlobal(StringRef Name) const {
+  const Init *getGlobal(StringRef Name) const {
     if (const Record *R = getDef(Name))
       return R->getDefInit();
     auto It = ExtraGlobals.find(Name);
@@ -2027,14 +2041,14 @@ class RecordKeeper {
     assert(Ins && "Record already exists");
   }
 
-  void addExtraGlobal(StringRef Name, Init *I) {
+  void addExtraGlobal(StringRef Name, const Init *I) {
     bool Ins = ExtraGlobals.insert(std::make_pair(std::string(Name), I)).second;
     (void)Ins;
     assert(!getDef(Name));
     assert(Ins && "Global already exists");
   }
 
-  Init *getNewAnonymousName();
+  const Init *getNewAnonymousName();
 
   TGTimer &getTimer() const { return *Timer; }
 
@@ -2190,18 +2204,18 @@ raw_ostream &operator<<(raw_ostream &OS, const RecordKeeper &RK);
 /// Interface for looking up the initializer for a variable name, used by
 /// Init::resolveReferences.
 class Resolver {
-  Record *CurRec;
+  const Record *CurRec;
   bool IsFinal = false;
 
 public:
-  explicit Resolver(Record *CurRec) : CurRec(CurRec) {}
+  explicit Resolver(const Record *CurRec) : CurRec(CurRec) {}
   virtual ~Resolver() = default;
 
-  Record *getCurrentRecord() const { return CurRec; }
+  const Record *getCurrentRecord() const { return CurRec; }
 
   /// Return the initializer for the given variable name (should normally be a
   /// StringInit), or nullptr if the name could not be resolved.
-  virtual Init *resolve(Init *VarName) = 0;
+  virtual const Init *resolve(const Init *VarName) = 0;
 
   // Whether bits in a BitsInit should stay unresolved if resolving them would
   // result in a ? (UnsetInit). This behavior is used to represent instruction
@@ -2219,19 +2233,19 @@ class Resolver {
 /// Resolve arbitrary mappings.
 class MapResolver final : public Resolver {
   struct MappedValue {
-    Init *V;
+    const Init *V;
     bool Resolved;
 
     MappedValue() : V(nullptr), Resolved(false) {}
-    MappedValue(Init *V, bool Resolved) : V(V), Resolved(Resolved) {}
+    MappedValue(const Init *V, bool Resolved) : V(V), Resolved(Resolved) {}
   };
 
-  DenseMap<Init *, MappedValue> Map;
+  DenseMap<const Init *, MappedValue> Map;
 
 public:
-  explicit MapResolver(Record *CurRec = nullptr) : Resolver(CurRec) {}
+  explicit MapResolver(const Record *CurRec = nullptr) : Resolver(CurRec) {}
 
-  void set(Init *Key, Init *Value) { Map[Key] = {Value, false}; }
+  void set(const Init *Key, const Init *Value) { Map[Key] = {Value, false}; }
 
   bool isComplete(Init *VarName) const {
     auto It = Map.find(VarName);
@@ -2239,21 +2253,21 @@ class MapResolver final : public Resolver {
     return It->second.V->isComplete();
   }
 
-  Init *resolve(Init *VarName) override;
+  const Init *resolve(const Init *VarName) override;
 };
 
 /// Resolve all variables from a record except for unset variables.
 class RecordResolver final : public Resolver {
-  DenseMap<Init *, Init *> Cache;
-  SmallVector<Init *, 4> Stack;
-  Init *Name = nullptr;
+  DenseMap<const Init *, const Init *> Cache;
+  SmallVector<const Init *, 4> Stack;
+  const Init *Name = nullptr;
 
 public:
-  explicit RecordResolver(Record &R) : Resolver(&R) {}
+  explicit RecordResolver(const Record &R) : Resolver(&R) {}
 
-  void setName(Init *NewName) { Name = NewName; }
+  void setName(const Init *NewName) { Name = NewName; }
 
-  Init *resolve(Init *VarName) override;
+  const Init *resolve(const Init *VarName) override;
 
   bool keepUnsetBits() const override { return true; }
 };
@@ -2261,7 +2275,7 @@ class RecordResolver final : public Resolver {
 /// Delegate resolving to a sub-resolver, but shadow some variable names.
 class ShadowResolver final : public Resolver {
   Resolver &R;
-  DenseSet<Init *> Shadowed;
+  DenseSet<const Init *> Shadowed;
 
 public:
   explicit ShadowResolver(Resolver &R)
@@ -2269,9 +2283,9 @@ class ShadowResolver final : public Resolver {
     setFinal(R.isFinal());
   }
 
-  void addShadow(Init *Key) { Shadowed.insert(Key); }
+  void addShadow(const Init *Key) { Shadowed.insert(Key); }
 
-  Init *resolve(Init *VarName) override {
+  const Init *resolve(const Init *VarName) override {
     if (Shadowed.count(VarName))
       return nullptr;
     return R.resolve(VarName);
@@ -2290,22 +2304,22 @@ class TrackUnresolvedResolver final : public Resolver {
 
   bool foundUnresolved() const { return FoundUnresolved; }
 
-  Init *resolve(Init *VarName) override;
+  const Init *resolve(const Init *VarName) override;
 };
 
 /// Do not resolve anything, but keep track of whether a given variable was
 /// referenced.
 class HasReferenceResolver final : public Resolver {
-  Init *VarNameToTrack;
+  const Init *VarNameToTrack;
   bool Found = false;
 
 public:
-  explicit HasReferenceResolver(Init *VarNameToTrack)
+  explicit HasReferenceResolver(const Init *VarNameToTrack)
       : Resolver(nullptr), VarNameToTrack(VarNameToTrack) {}
 
   bool found() const { return Found; }
 
-  Init *resolve(Init *VarName) override;
+  const Init *resolve(const Init *VarName) override;
 };
 
 void EmitDetailedRecords(const RecordKeeper &RK, raw_ostream &OS);

diff  --git a/llvm/lib/TableGen/DetailedRecordsBackend.cpp b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
index 61fd3634902cc3..4a337248c941a1 100644
--- a/llvm/lib/TableGen/DetailedRecordsBackend.cpp
+++ b/llvm/lib/TableGen/DetailedRecordsBackend.cpp
@@ -131,7 +131,7 @@ void DetailedRecordsEmitter::printDefms(const Record &Rec, raw_ostream &OS) {
 // Print the template arguments of a class.
 void DetailedRecordsEmitter::printTemplateArgs(const Record &Rec,
                                                raw_ostream &OS) {
-  ArrayRef<Init *> Args = Rec.getTemplateArgs();
+  ArrayRef<const Init *> Args = Rec.getTemplateArgs();
   if (Args.empty()) {
     OS << "  Template args: (none)\n";
     return;

diff  --git a/llvm/lib/TableGen/Error.cpp b/llvm/lib/TableGen/Error.cpp
index 6d1d5814223ab7..91423664a84cc9 100644
--- a/llvm/lib/TableGen/Error.cpp
+++ b/llvm/lib/TableGen/Error.cpp
@@ -160,7 +160,7 @@ void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) {
 
 // Check an assertion: Obtain the condition value and be sure it is true.
 // If not, print a nonfatal error along with the message.
-bool CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {
+bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message) {
   auto *CondValue = dyn_cast_or_null<IntInit>(Condition->convertInitializerTo(
       IntRecTy::get(Condition->getRecordKeeper())));
   if (!CondValue) {
@@ -178,7 +178,7 @@ bool CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {
 }
 
 // Dump a message to stderr.
-void dumpMessage(SMLoc Loc, Init *Message) {
+void dumpMessage(SMLoc Loc, const Init *Message) {
   if (auto *MessageInit = dyn_cast<StringInit>(Message))
     PrintNote(Loc, MessageInit->getValue());
   else

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 447ecb7d74d24f..f8ea88375c48ea 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -74,8 +74,8 @@ struct RecordKeeperImpl {
   FoldingSet<ArgumentInit> TheArgumentInitPool;
   FoldingSet<BitsInit> TheBitsInitPool;
   std::map<int64_t, IntInit *> TheIntInitPool;
-  StringMap<StringInit *, BumpPtrAllocator &> StringInitStringPool;
-  StringMap<StringInit *, BumpPtrAllocator &> StringInitCodePool;
+  StringMap<const StringInit *, BumpPtrAllocator &> StringInitStringPool;
+  StringMap<const StringInit *, BumpPtrAllocator &> StringInitCodePool;
   FoldingSet<ListInit> TheListInitPool;
   FoldingSet<UnOpInit> TheUnOpInitPool;
   FoldingSet<BinOpInit> TheBinOpInitPool;
@@ -83,10 +83,12 @@ struct RecordKeeperImpl {
   FoldingSet<FoldOpInit> TheFoldOpInitPool;
   FoldingSet<IsAOpInit> TheIsAOpInitPool;
   FoldingSet<ExistsOpInit> TheExistsOpInitPool;
-  DenseMap<std::pair<const RecTy *, Init *>, VarInit *> TheVarInitPool;
-  DenseMap<std::pair<TypedInit *, unsigned>, VarBitInit *> TheVarBitInitPool;
+  DenseMap<std::pair<const RecTy *, const Init *>, VarInit *> TheVarInitPool;
+  DenseMap<std::pair<const TypedInit *, unsigned>, VarBitInit *>
+      TheVarBitInitPool;
   FoldingSet<VarDefInit> TheVarDefInitPool;
-  DenseMap<std::pair<Init *, StringInit *>, FieldInit *> TheFieldInitPool;
+  DenseMap<std::pair<const Init *, const StringInit *>, FieldInit *>
+      TheFieldInitPool;
   FoldingSet<CondOpInit> TheCondOpInitPool;
   FoldingSet<DagInit> TheDagInitPool;
   FoldingSet<RecordRecTy> RecordTypePool;
@@ -389,15 +391,13 @@ UnsetInit *UnsetInit::get(RecordKeeper &RK) {
   return &RK.getImpl().TheUnsetInit;
 }
 
-Init *UnsetInit::getCastTo(const RecTy *Ty) const {
-  return const_cast<UnsetInit *>(this);
-}
+const Init *UnsetInit::getCastTo(const RecTy *Ty) const { return this; }
 
-Init *UnsetInit::convertInitializerTo(const RecTy *Ty) const {
-  return const_cast<UnsetInit *>(this);
+const Init *UnsetInit::convertInitializerTo(const RecTy *Ty) const {
+  return this;
 }
 
-static void ProfileArgumentInit(FoldingSetNodeID &ID, Init *Value,
+static void ProfileArgumentInit(FoldingSetNodeID &ID, const Init *Value,
                                 ArgAuxType Aux) {
   auto I = Aux.index();
   ID.AddInteger(I);
@@ -412,14 +412,15 @@ void ArgumentInit::Profile(FoldingSetNodeID &ID) const {
   ProfileArgumentInit(ID, Value, Aux);
 }
 
-ArgumentInit *ArgumentInit::get(Init *Value, ArgAuxType Aux) {
+const ArgumentInit *ArgumentInit::get(const Init *Value, ArgAuxType Aux) {
   FoldingSetNodeID ID;
   ProfileArgumentInit(ID, Value, Aux);
 
   RecordKeeper &RK = Value->getRecordKeeper();
   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
   void *IP = nullptr;
-  if (ArgumentInit *I = RKImpl.TheArgumentInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const ArgumentInit *I =
+          RKImpl.TheArgumentInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   ArgumentInit *I = new (RKImpl.Allocator) ArgumentInit(Value, Aux);
@@ -427,8 +428,8 @@ ArgumentInit *ArgumentInit::get(Init *Value, ArgAuxType Aux) {
   return I;
 }
 
-Init *ArgumentInit::resolveReferences(Resolver &R) const {
-  Init *NewValue = Value->resolveReferences(R);
+const Init *ArgumentInit::resolveReferences(Resolver &R) const {
+  const Init *NewValue = Value->resolveReferences(R);
   if (NewValue != Value)
     return cloneWithValue(NewValue);
 
@@ -439,7 +440,7 @@ BitInit *BitInit::get(RecordKeeper &RK, bool V) {
   return V ? &RK.getImpl().TrueBitInit : &RK.getImpl().FalseBitInit;
 }
 
-Init *BitInit::convertInitializerTo(const RecTy *Ty) const {
+const Init *BitInit::convertInitializerTo(const RecTy *Ty) const {
   if (isa<BitRecTy>(Ty))
     return const_cast<BitInit *>(this);
 
@@ -455,15 +456,15 @@ Init *BitInit::convertInitializerTo(const RecTy *Ty) const {
   return nullptr;
 }
 
-static void
-ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) {
+static void ProfileBitsInit(FoldingSetNodeID &ID,
+                            ArrayRef<const Init *> Range) {
   ID.AddInteger(Range.size());
 
-  for (Init *I : Range)
+  for (const Init *I : Range)
     ID.AddPointer(I);
 }
 
-BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<Init *> Range) {
+BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<const Init *> Range) {
   FoldingSetNodeID ID;
   ProfileBitsInit(ID, Range);
 
@@ -472,20 +473,20 @@ BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<Init *> Range) {
   if (BitsInit *I = RKImpl.TheBitsInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
-  void *Mem = RKImpl.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
-                                        alignof(BitsInit));
+  void *Mem = RKImpl.Allocator.Allocate(
+      totalSizeToAlloc<const Init *>(Range.size()), alignof(BitsInit));
   BitsInit *I = new (Mem) BitsInit(RK, Range.size());
   std::uninitialized_copy(Range.begin(), Range.end(),
-                          I->getTrailingObjects<Init *>());
+                          I->getTrailingObjects<const Init *>());
   RKImpl.TheBitsInitPool.InsertNode(I, IP);
   return I;
 }
 
 void BitsInit::Profile(FoldingSetNodeID &ID) const {
-  ProfileBitsInit(ID, ArrayRef(getTrailingObjects<Init *>(), NumBits));
+  ProfileBitsInit(ID, ArrayRef(getTrailingObjects<const Init *>(), NumBits));
 }
 
-Init *BitsInit::convertInitializerTo(const RecTy *Ty) const {
+const Init *BitsInit::convertInitializerTo(const RecTy *Ty) const {
   if (isa<BitRecTy>(Ty)) {
     if (getNumBits() != 1) return nullptr; // Only accept if just one bit!
     return getBit(0);
@@ -517,9 +518,9 @@ std::optional<int64_t> BitsInit::convertInitializerToInt() const {
   return Result;
 }
 
-Init *
+const Init *
 BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
-  SmallVector<Init *, 16> NewBits(Bits.size());
+  SmallVector<const Init *, 16> NewBits(Bits.size());
 
   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
     if (Bits[i] >= getNumBits())
@@ -541,7 +542,7 @@ std::string BitsInit::getAsString() const {
   std::string Result = "{ ";
   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
     if (i) Result += ", ";
-    if (Init *Bit = getBit(e-i-1))
+    if (const Init *Bit = getBit(e - i - 1))
       Result += Bit->getAsString();
     else
       Result += "*";
@@ -551,18 +552,18 @@ std::string BitsInit::getAsString() const {
 
 // resolveReferences - If there are any field references that refer to fields
 // that have been filled in, we can propagate the values now.
-Init *BitsInit::resolveReferences(Resolver &R) const {
+const Init *BitsInit::resolveReferences(Resolver &R) const {
   bool Changed = false;
-  SmallVector<Init *, 16> NewBits(getNumBits());
+  SmallVector<const Init *, 16> NewBits(getNumBits());
 
-  Init *CachedBitVarRef = nullptr;
-  Init *CachedBitVarResolved = nullptr;
+  const Init *CachedBitVarRef = nullptr;
+  const Init *CachedBitVarResolved = nullptr;
 
   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
-    Init *CurBit = getBit(i);
-    Init *NewBit = CurBit;
+    const Init *CurBit = getBit(i);
+    const Init *NewBit = CurBit;
 
-    if (VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
+    if (const VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
       if (CurBitVar->getBitVar() != CachedBitVarRef) {
         CachedBitVarRef = CurBitVar->getBitVar();
         CachedBitVarResolved = CachedBitVarRef->resolveReferences(R);
@@ -583,7 +584,7 @@ Init *BitsInit::resolveReferences(Resolver &R) const {
   if (Changed)
     return BitsInit::get(getRecordKeeper(), NewBits);
 
-  return const_cast<BitsInit *>(this);
+  return this;
 }
 
 IntInit *IntInit::get(RecordKeeper &RK, int64_t V) {
@@ -603,7 +604,7 @@ static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
          (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
 }
 
-Init *IntInit::convertInitializerTo(const RecTy *Ty) const {
+const Init *IntInit::convertInitializerTo(const RecTy *Ty) const {
   if (isa<IntRecTy>(Ty))
     return const_cast<IntInit *>(this);
 
@@ -619,7 +620,7 @@ Init *IntInit::convertInitializerTo(const RecTy *Ty) const {
     if (!canFitInBitfield(Value, BRT->getNumBits()))
       return nullptr;
 
-    SmallVector<Init *, 16> NewBits(BRT->getNumBits());
+    SmallVector<const Init *, 16> NewBits(BRT->getNumBits());
     for (unsigned i = 0; i != BRT->getNumBits(); ++i)
       NewBits[i] =
           BitInit::get(getRecordKeeper(), Value & ((i < 64) ? (1LL << i) : 0));
@@ -630,9 +631,8 @@ Init *IntInit::convertInitializerTo(const RecTy *Ty) const {
   return nullptr;
 }
 
-Init *
-IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
-  SmallVector<Init *, 16> NewBits(Bits.size());
+const Init *IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
+  SmallVector<const Init *, 16> NewBits(Bits.size());
 
   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
     if (Bits[i] >= 64)
@@ -648,7 +648,7 @@ AnonymousNameInit *AnonymousNameInit::get(RecordKeeper &RK, unsigned V) {
   return new (RK.getImpl().Allocator) AnonymousNameInit(RK, V);
 }
 
-StringInit *AnonymousNameInit::getNameInit() const {
+const StringInit *AnonymousNameInit::getNameInit() const {
   return StringInit::get(getRecordKeeper(), getAsString());
 }
 
@@ -656,7 +656,7 @@ std::string AnonymousNameInit::getAsString() const {
   return "anonymous_" + utostr(Value);
 }
 
-Init *AnonymousNameInit::resolveReferences(Resolver &R) const {
+const Init *AnonymousNameInit::resolveReferences(Resolver &R) const {
   auto *Old = const_cast<Init *>(static_cast<const Init *>(this));
   auto *New = R.resolve(Old);
   New = New ? New : Old;
@@ -666,7 +666,8 @@ Init *AnonymousNameInit::resolveReferences(Resolver &R) const {
   return New;
 }
 
-StringInit *StringInit::get(RecordKeeper &RK, StringRef V, StringFormat Fmt) {
+const StringInit *StringInit::get(RecordKeeper &RK, StringRef V,
+                                  StringFormat Fmt) {
   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
   auto &InitMap = Fmt == SF_String ? RKImpl.StringInitStringPool
                                    : RKImpl.StringInitCodePool;
@@ -676,39 +677,40 @@ StringInit *StringInit::get(RecordKeeper &RK, StringRef V, StringFormat Fmt) {
   return Entry.second;
 }
 
-Init *StringInit::convertInitializerTo(const RecTy *Ty) const {
+const Init *StringInit::convertInitializerTo(const RecTy *Ty) const {
   if (isa<StringRecTy>(Ty))
     return const_cast<StringInit *>(this);
 
   return nullptr;
 }
 
-static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range,
+static void ProfileListInit(FoldingSetNodeID &ID, ArrayRef<const Init *> Range,
                             const RecTy *EltTy) {
   ID.AddInteger(Range.size());
   ID.AddPointer(EltTy);
 
-  for (Init *I : Range)
+  for (const Init *I : Range)
     ID.AddPointer(I);
 }
 
-ListInit *ListInit::get(ArrayRef<Init *> Range, const RecTy *EltTy) {
+const ListInit *ListInit::get(ArrayRef<const Init *> Range,
+                              const RecTy *EltTy) {
   FoldingSetNodeID ID;
   ProfileListInit(ID, Range, EltTy);
 
   detail::RecordKeeperImpl &RK = EltTy->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (ListInit *I = RK.TheListInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const ListInit *I = RK.TheListInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   assert(Range.empty() || !isa<TypedInit>(Range[0]) ||
          cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy));
 
-  void *Mem = RK.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
-                                    alignof(ListInit));
+  void *Mem = RK.Allocator.Allocate(
+      totalSizeToAlloc<const Init *>(Range.size()), alignof(ListInit));
   ListInit *I = new (Mem) ListInit(Range.size(), EltTy);
   std::uninitialized_copy(Range.begin(), Range.end(),
-                          I->getTrailingObjects<Init *>());
+                          I->getTrailingObjects<const Init *>());
   RK.TheListInitPool.InsertNode(I, IP);
   return I;
 }
@@ -719,20 +721,20 @@ void ListInit::Profile(FoldingSetNodeID &ID) const {
   ProfileListInit(ID, getValues(), EltTy);
 }
 
-Init *ListInit::convertInitializerTo(const RecTy *Ty) const {
+const Init *ListInit::convertInitializerTo(const RecTy *Ty) const {
   if (getType() == Ty)
     return const_cast<ListInit*>(this);
 
   if (auto *LRT = dyn_cast<ListRecTy>(Ty)) {
-    SmallVector<Init*, 8> Elements;
+    SmallVector<const Init *, 8> Elements;
     Elements.reserve(getValues().size());
 
     // Verify that all of the elements of the list are subclasses of the
     // appropriate class!
     bool Changed = false;
     const RecTy *ElementType = LRT->getElementType();
-    for (Init *I : getValues())
-      if (Init *CI = I->convertInitializerTo(ElementType)) {
+    for (const Init *I : getValues())
+      if (const Init *CI = I->convertInitializerTo(ElementType)) {
         Elements.push_back(CI);
         if (CI != I)
           Changed = true;
@@ -749,30 +751,30 @@ Init *ListInit::convertInitializerTo(const RecTy *Ty) const {
 
 const Record *ListInit::getElementAsRecord(unsigned i) const {
   assert(i < NumValues && "List element index out of range!");
-  DefInit *DI = dyn_cast<DefInit>(getElement(i));
+  const DefInit *DI = dyn_cast<DefInit>(getElement(i));
   if (!DI)
     PrintFatalError("Expected record in list!");
   return DI->getDef();
 }
 
-Init *ListInit::resolveReferences(Resolver &R) const {
-  SmallVector<Init*, 8> Resolved;
+const Init *ListInit::resolveReferences(Resolver &R) const {
+  SmallVector<const Init *, 8> Resolved;
   Resolved.reserve(size());
   bool Changed = false;
 
-  for (Init *CurElt : getValues()) {
-    Init *E = CurElt->resolveReferences(R);
+  for (const Init *CurElt : getValues()) {
+    const Init *E = CurElt->resolveReferences(R);
     Changed |= E != CurElt;
     Resolved.push_back(E);
   }
 
   if (Changed)
     return ListInit::get(Resolved, getElementType());
-  return const_cast<ListInit *>(this);
+  return this;
 }
 
 bool ListInit::isComplete() const {
-  for (Init *Element : *this) {
+  for (const Init *Element : *this) {
     if (!Element->isComplete())
       return false;
   }
@@ -780,7 +782,7 @@ bool ListInit::isComplete() const {
 }
 
 bool ListInit::isConcrete() const {
-  for (Init *Element : *this) {
+  for (const Init *Element : *this) {
     if (!Element->isConcrete())
       return false;
   }
@@ -790,7 +792,7 @@ bool ListInit::isConcrete() const {
 std::string ListInit::getAsString() const {
   std::string Result = "[";
   const char *sep = "";
-  for (Init *Element : *this) {
+  for (const Init *Element : *this) {
     Result += sep;
     sep = ", ";
     Result += Element->getAsString();
@@ -798,26 +800,26 @@ std::string ListInit::getAsString() const {
   return Result + "]";
 }
 
-Init *OpInit::getBit(unsigned Bit) const {
+const Init *OpInit::getBit(unsigned Bit) const {
   if (getType() == BitRecTy::get(getRecordKeeper()))
     return const_cast<OpInit*>(this);
-  return VarBitInit::get(const_cast<OpInit*>(this), Bit);
+  return VarBitInit::get(this, Bit);
 }
 
-static void ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op,
-                            const RecTy *Type) {
+static void ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode,
+                            const Init *Op, const RecTy *Type) {
   ID.AddInteger(Opcode);
   ID.AddPointer(Op);
   ID.AddPointer(Type);
 }
 
-UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, const RecTy *Type) {
+const UnOpInit *UnOpInit::get(UnaryOp Opc, const Init *LHS, const RecTy *Type) {
   FoldingSetNodeID ID;
   ProfileUnOpInit(ID, Opc, LHS, Type);
 
   detail::RecordKeeperImpl &RK = Type->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (UnOpInit *I = RK.TheUnOpInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const UnOpInit *I = RK.TheUnOpInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   UnOpInit *I = new (RK.Allocator) UnOpInit(Opc, LHS, Type);
@@ -829,7 +831,7 @@ void UnOpInit::Profile(FoldingSetNodeID &ID) const {
   ProfileUnOpInit(ID, getOpcode(), getOperand(), getType());
 }
 
-Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
+const Init *UnOpInit::Fold(const Record *CurRec, bool IsFinal) const {
   RecordKeeper &RK = getRecordKeeper();
   switch (getOpcode()) {
   case REPR:
@@ -851,27 +853,27 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
     }
     break;
   case TOLOWER:
-    if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+    if (const StringInit *LHSs = dyn_cast<StringInit>(LHS))
       return StringInit::get(RK, LHSs->getValue().lower());
     break;
   case TOUPPER:
-    if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+    if (const StringInit *LHSs = dyn_cast<StringInit>(LHS))
       return StringInit::get(RK, LHSs->getValue().upper());
     break;
   case CAST:
     if (isa<StringRecTy>(getType())) {
-      if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+      if (const StringInit *LHSs = dyn_cast<StringInit>(LHS))
         return LHSs;
 
-      if (DefInit *LHSd = dyn_cast<DefInit>(LHS))
+      if (const DefInit *LHSd = dyn_cast<DefInit>(LHS))
         return StringInit::get(RK, LHSd->getAsString());
 
-      if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
+      if (const IntInit *LHSi = dyn_cast_or_null<IntInit>(
               LHS->convertInitializerTo(IntRecTy::get(RK))))
         return StringInit::get(RK, LHSi->getAsString());
 
     } else if (isa<RecordRecTy>(getType())) {
-      if (StringInit *Name = dyn_cast<StringInit>(LHS)) {
+      if (const StringInit *Name = dyn_cast<StringInit>(LHS)) {
         const Record *D = RK.getDef(Name->getValue());
         if (!D && CurRec) {
           // Self-references are allowed, but their resolution is delayed until
@@ -911,25 +913,25 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
       }
     }
 
-    if (Init *NewInit = LHS->convertInitializerTo(getType()))
+    if (const Init *NewInit = LHS->convertInitializerTo(getType()))
       return NewInit;
     break;
 
   case NOT:
-    if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
+    if (const IntInit *LHSi = dyn_cast_or_null<IntInit>(
             LHS->convertInitializerTo(IntRecTy::get(RK))))
       return IntInit::get(RK, LHSi->getValue() ? 0 : 1);
     break;
 
   case HEAD:
-    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
+    if (const ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
       assert(!LHSl->empty() && "Empty list in head");
       return LHSl->getElement(0);
     }
     break;
 
   case TAIL:
-    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
+    if (const ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
       assert(!LHSl->empty() && "Empty list in tail");
       // Note the +1.  We can't just pass the result of getValues()
       // directly.
@@ -938,25 +940,25 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
     break;
 
   case SIZE:
-    if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
+    if (const ListInit *LHSl = dyn_cast<ListInit>(LHS))
       return IntInit::get(RK, LHSl->size());
-    if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
+    if (const DagInit *LHSd = dyn_cast<DagInit>(LHS))
       return IntInit::get(RK, LHSd->arg_size());
-    if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+    if (const StringInit *LHSs = dyn_cast<StringInit>(LHS))
       return IntInit::get(RK, LHSs->getValue().size());
     break;
 
   case EMPTY:
-    if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
+    if (const ListInit *LHSl = dyn_cast<ListInit>(LHS))
       return IntInit::get(RK, LHSl->empty());
-    if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
+    if (const DagInit *LHSd = dyn_cast<DagInit>(LHS))
       return IntInit::get(RK, LHSd->arg_empty());
-    if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
+    if (const StringInit *LHSs = dyn_cast<StringInit>(LHS))
       return IntInit::get(RK, LHSs->getValue().empty());
     break;
 
   case GETDAGOP:
-    if (DagInit *Dag = dyn_cast<DagInit>(LHS)) {
+    if (const DagInit *Dag = dyn_cast<DagInit>(LHS)) {
       // TI is not necessarily a def due to the late resolution in multiclasses,
       // but has to be a TypedInit.
       auto *TI = cast<TypedInit>(Dag->getOperator());
@@ -972,7 +974,7 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
     break;
 
   case LOG2:
-    if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
+    if (const IntInit *LHSi = dyn_cast_or_null<IntInit>(
             LHS->convertInitializerTo(IntRecTy::get(RK)))) {
       int64_t LHSv = LHSi->getValue();
       if (LHSv <= 0) {
@@ -989,21 +991,22 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
     break;
 
   case LISTFLATTEN:
-    if (ListInit *LHSList = dyn_cast<ListInit>(LHS)) {
+    if (const ListInit *LHSList = dyn_cast<ListInit>(LHS)) {
       const ListRecTy *InnerListTy =
           dyn_cast<ListRecTy>(LHSList->getElementType());
       // list of non-lists, !listflatten() is a NOP.
       if (!InnerListTy)
         return LHS;
 
-      auto Flatten = [](ListInit *List) -> std::optional<std::vector<Init *>> {
-        std::vector<Init *> Flattened;
+      auto Flatten =
+          [](const ListInit *List) -> std::optional<std::vector<const Init *>> {
+        std::vector<const Init *> Flattened;
         // Concatenate elements of all the inner lists.
-        for (Init *InnerInit : List->getValues()) {
-          ListInit *InnerList = dyn_cast<ListInit>(InnerInit);
+        for (const Init *InnerInit : List->getValues()) {
+          const ListInit *InnerList = dyn_cast<ListInit>(InnerInit);
           if (!InnerList)
             return std::nullopt;
-          for (Init *InnerElem : InnerList->getValues())
+          for (const Init *InnerElem : InnerList->getValues())
             Flattened.push_back(InnerElem);
         };
         return Flattened;
@@ -1018,13 +1021,13 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
   return const_cast<UnOpInit *>(this);
 }
 
-Init *UnOpInit::resolveReferences(Resolver &R) const {
-  Init *lhs = LHS->resolveReferences(R);
+const Init *UnOpInit::resolveReferences(Resolver &R) const {
+  const Init *lhs = LHS->resolveReferences(R);
 
   if (LHS != lhs || (R.isFinal() && getOpcode() == CAST))
     return (UnOpInit::get(getOpcode(), lhs, getType()))
         ->Fold(R.getCurrentRecord(), R.isFinal());
-  return const_cast<UnOpInit *>(this);
+  return this;
 }
 
 std::string UnOpInit::getAsString() const {
@@ -1054,22 +1057,23 @@ std::string UnOpInit::getAsString() const {
   return Result + "(" + LHS->getAsString() + ")";
 }
 
-static void ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS,
-                             Init *RHS, const RecTy *Type) {
+static void ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode,
+                             const Init *LHS, const Init *RHS,
+                             const RecTy *Type) {
   ID.AddInteger(Opcode);
   ID.AddPointer(LHS);
   ID.AddPointer(RHS);
   ID.AddPointer(Type);
 }
 
-BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, Init *RHS,
-                          const RecTy *Type) {
+const BinOpInit *BinOpInit::get(BinaryOp Opc, const Init *LHS, const Init *RHS,
+                                const RecTy *Type) {
   FoldingSetNodeID ID;
   ProfileBinOpInit(ID, Opc, LHS, RHS, Type);
 
   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (BinOpInit *I = RK.TheBinOpInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const BinOpInit *I = RK.TheBinOpInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   BinOpInit *I = new (RK.Allocator) BinOpInit(Opc, LHS, RHS, Type);
@@ -1081,8 +1085,8 @@ void BinOpInit::Profile(FoldingSetNodeID &ID) const {
   ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType());
 }
 
-static StringInit *ConcatStringInits(const StringInit *I0,
-                                     const StringInit *I1) {
+static const StringInit *ConcatStringInits(const StringInit *I0,
+                                           const StringInit *I1) {
   SmallString<80> Concat(I0->getValue());
   Concat.append(I1->getValue());
   return StringInit::get(
@@ -1090,11 +1094,11 @@ static StringInit *ConcatStringInits(const StringInit *I0,
       StringInit::determineFormat(I0->getFormat(), I1->getFormat()));
 }
 
-static StringInit *interleaveStringList(const ListInit *List,
-                                        const StringInit *Delim) {
+static const StringInit *interleaveStringList(const ListInit *List,
+                                              const StringInit *Delim) {
   if (List->size() == 0)
     return StringInit::get(List->getRecordKeeper(), "");
-  StringInit *Element = dyn_cast<StringInit>(List->getElement(0));
+  const StringInit *Element = dyn_cast<StringInit>(List->getElement(0));
   if (!Element)
     return nullptr;
   SmallString<80> Result(Element->getValue());
@@ -1102,7 +1106,7 @@ static StringInit *interleaveStringList(const ListInit *List,
 
   for (unsigned I = 1, E = List->size(); I < E; ++I) {
     Result.append(Delim->getValue());
-    StringInit *Element = dyn_cast<StringInit>(List->getElement(I));
+    const StringInit *Element = dyn_cast<StringInit>(List->getElement(I));
     if (!Element)
       return nullptr;
     Result.append(Element->getValue());
@@ -1111,12 +1115,12 @@ static StringInit *interleaveStringList(const ListInit *List,
   return StringInit::get(List->getRecordKeeper(), Result, Fmt);
 }
 
-static StringInit *interleaveIntList(const ListInit *List,
-                                     const StringInit *Delim) {
+static const StringInit *interleaveIntList(const ListInit *List,
+                                           const StringInit *Delim) {
   RecordKeeper &RK = List->getRecordKeeper();
   if (List->size() == 0)
     return StringInit::get(RK, "");
-  IntInit *Element = dyn_cast_or_null<IntInit>(
+  const IntInit *Element = dyn_cast_or_null<IntInit>(
       List->getElement(0)->convertInitializerTo(IntRecTy::get(RK)));
   if (!Element)
     return nullptr;
@@ -1124,7 +1128,7 @@ static StringInit *interleaveIntList(const ListInit *List,
 
   for (unsigned I = 1, E = List->size(); I < E; ++I) {
     Result.append(Delim->getValue());
-    IntInit *Element = dyn_cast_or_null<IntInit>(
+    const IntInit *Element = dyn_cast_or_null<IntInit>(
         List->getElement(I)->convertInitializerTo(IntRecTy::get(RK)));
     if (!Element)
       return nullptr;
@@ -1133,7 +1137,7 @@ static StringInit *interleaveIntList(const ListInit *List,
   return StringInit::get(RK, Result);
 }
 
-Init *BinOpInit::getStrConcat(Init *I0, Init *I1) {
+const Init *BinOpInit::getStrConcat(const Init *I0, const Init *I1) {
   // Shortcut for the common case of concatenating two strings.
   if (const StringInit *I0s = dyn_cast<StringInit>(I0))
     if (const StringInit *I1s = dyn_cast<StringInit>(I1))
@@ -1142,15 +1146,15 @@ Init *BinOpInit::getStrConcat(Init *I0, Init *I1) {
                         StringRecTy::get(I0->getRecordKeeper()));
 }
 
-static ListInit *ConcatListInits(const ListInit *LHS,
-                                 const ListInit *RHS) {
-  SmallVector<Init *, 8> Args;
+static const ListInit *ConcatListInits(const ListInit *LHS,
+                                       const ListInit *RHS) {
+  SmallVector<const Init *, 8> Args;
   llvm::append_range(Args, *LHS);
   llvm::append_range(Args, *RHS);
   return ListInit::get(Args, LHS->getElementType());
 }
 
-Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) {
+const Init *BinOpInit::getListConcat(const TypedInit *LHS, const Init *RHS) {
   assert(isa<ListRecTy>(LHS->getType()) && "First arg must be a list");
 
   // Shortcut for the common case of concatenating two lists.
@@ -1160,12 +1164,12 @@ Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) {
   return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType());
 }
 
-std::optional<bool> BinOpInit::CompareInit(unsigned Opc, Init *LHS,
-                                           Init *RHS) const {
+std::optional<bool> BinOpInit::CompareInit(unsigned Opc, const Init *LHS,
+                                           const Init *RHS) const {
   // First see if we have two bit, bits, or int.
-  IntInit *LHSi = dyn_cast_or_null<IntInit>(
+  const IntInit *LHSi = dyn_cast_or_null<IntInit>(
       LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
-  IntInit *RHSi = dyn_cast_or_null<IntInit>(
+  const IntInit *RHSi = dyn_cast_or_null<IntInit>(
       RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
 
   if (LHSi && RHSi) {
@@ -1196,8 +1200,8 @@ std::optional<bool> BinOpInit::CompareInit(unsigned Opc, Init *LHS,
   }
 
   // Next try strings.
-  StringInit *LHSs = dyn_cast<StringInit>(LHS);
-  StringInit *RHSs = dyn_cast<StringInit>(RHS);
+  const StringInit *LHSs = dyn_cast<StringInit>(LHS);
+  const StringInit *RHSs = dyn_cast<StringInit>(RHS);
 
   if (LHSs && RHSs) {
     bool Result;
@@ -1228,8 +1232,8 @@ std::optional<bool> BinOpInit::CompareInit(unsigned Opc, Init *LHS,
 
   // Finally, !eq and !ne can be used with records.
   if (Opc == EQ || Opc == NE) {
-    DefInit *LHSd = dyn_cast<DefInit>(LHS);
-    DefInit *RHSd = dyn_cast<DefInit>(RHS);
+    const DefInit *LHSd = dyn_cast<DefInit>(LHS);
+    const DefInit *RHSd = dyn_cast<DefInit>(RHS);
     if (LHSd && RHSd)
       return (Opc == EQ) ? LHSd == RHSd : LHSd != RHSd;
   }
@@ -1237,10 +1241,10 @@ std::optional<bool> BinOpInit::CompareInit(unsigned Opc, Init *LHS,
   return std::nullopt;
 }
 
-static std::optional<unsigned> getDagArgNoByKey(DagInit *Dag, Init *Key,
-                                                std::string &Error) {
+static std::optional<unsigned>
+getDagArgNoByKey(const DagInit *Dag, const Init *Key, std::string &Error) {
   // Accessor by index
-  if (IntInit *Idx = dyn_cast<IntInit>(Key)) {
+  if (const IntInit *Idx = dyn_cast<IntInit>(Key)) {
     int64_t Pos = Idx->getValue();
     if (Pos < 0) {
       // The index is negative.
@@ -1260,7 +1264,7 @@ static std::optional<unsigned> getDagArgNoByKey(DagInit *Dag, Init *Key,
   }
   assert(isa<StringInit>(Key));
   // Accessor by name
-  StringInit *Name = dyn_cast<StringInit>(Key);
+  const StringInit *Name = dyn_cast<StringInit>(Key);
   auto ArgNo = Dag->getArgNo(Name->getValue());
   if (!ArgNo) {
     // The key is not found.
@@ -1270,14 +1274,14 @@ static std::optional<unsigned> getDagArgNoByKey(DagInit *Dag, Init *Key,
   return *ArgNo;
 }
 
-Init *BinOpInit::Fold(Record *CurRec) const {
+const Init *BinOpInit::Fold(const Record *CurRec) const {
   switch (getOpcode()) {
   case CONCAT: {
-    DagInit *LHSs = dyn_cast<DagInit>(LHS);
-    DagInit *RHSs = dyn_cast<DagInit>(RHS);
+    const DagInit *LHSs = dyn_cast<DagInit>(LHS);
+    const DagInit *RHSs = dyn_cast<DagInit>(RHS);
     if (LHSs && RHSs) {
-      DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator());
-      DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator());
+      const DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator());
+      const DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator());
       if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) ||
           (!ROp && !isa<UnsetInit>(RHSs->getOperator())))
         break;
@@ -1286,12 +1290,12 @@ Init *BinOpInit::Fold(Record *CurRec) const {
                         LHSs->getAsString() + "' vs. '" + RHSs->getAsString() +
                         "'");
       }
-      Init *Op = LOp ? LOp : ROp;
+      const Init *Op = LOp ? LOp : ROp;
       if (!Op)
         Op = UnsetInit::get(getRecordKeeper());
 
-      SmallVector<Init*, 8> Args;
-      SmallVector<StringInit*, 8> ArgNames;
+      SmallVector<const Init *, 8> Args;
+      SmallVector<const StringInit *, 8> ArgNames;
       for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
         Args.push_back(LHSs->getArg(i));
         ArgNames.push_back(LHSs->getArgName(i));
@@ -1305,10 +1309,10 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     break;
   }
   case LISTCONCAT: {
-    ListInit *LHSs = dyn_cast<ListInit>(LHS);
-    ListInit *RHSs = dyn_cast<ListInit>(RHS);
+    const ListInit *LHSs = dyn_cast<ListInit>(LHS);
+    const ListInit *RHSs = dyn_cast<ListInit>(RHS);
     if (LHSs && RHSs) {
-      SmallVector<Init *, 8> Args;
+      SmallVector<const Init *, 8> Args;
       llvm::append_range(Args, *LHSs);
       llvm::append_range(Args, *RHSs);
       return ListInit::get(Args, LHSs->getElementType());
@@ -1316,22 +1320,22 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     break;
   }
   case LISTSPLAT: {
-    TypedInit *Value = dyn_cast<TypedInit>(LHS);
-    IntInit *Size = dyn_cast<IntInit>(RHS);
+    const TypedInit *Value = dyn_cast<TypedInit>(LHS);
+    const IntInit *Size = dyn_cast<IntInit>(RHS);
     if (Value && Size) {
-      SmallVector<Init *, 8> Args(Size->getValue(), Value);
+      SmallVector<const Init *, 8> Args(Size->getValue(), Value);
       return ListInit::get(Args, Value->getType());
     }
     break;
   }
   case LISTREMOVE: {
-    ListInit *LHSs = dyn_cast<ListInit>(LHS);
-    ListInit *RHSs = dyn_cast<ListInit>(RHS);
+    const ListInit *LHSs = dyn_cast<ListInit>(LHS);
+    const ListInit *RHSs = dyn_cast<ListInit>(RHS);
     if (LHSs && RHSs) {
-      SmallVector<Init *, 8> Args;
-      for (Init *EltLHS : *LHSs) {
+      SmallVector<const Init *, 8> Args;
+      for (const Init *EltLHS : *LHSs) {
         bool Found = false;
-        for (Init *EltRHS : *RHSs) {
+        for (const Init *EltRHS : *RHSs) {
           if (std::optional<bool> Result = CompareInit(EQ, EltLHS, EltRHS)) {
             if (*Result) {
               Found = true;
@@ -1361,7 +1365,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     auto *SliceIdxs = dyn_cast<ListInit>(RHS);
     if (!TheList || !SliceIdxs)
       break;
-    SmallVector<Init *, 8> Args;
+    SmallVector<const Init *, 8> Args;
     Args.reserve(SliceIdxs->size());
     for (auto *I : *SliceIdxs) {
       auto *II = dyn_cast<IntInit>(I);
@@ -1382,7 +1386,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
 
     auto Start = LHSi->getValue();
     auto End = RHSi->getValue();
-    SmallVector<Init *, 8> Args;
+    SmallVector<const Init *, 8> Args;
     if (getOpcode() == RANGEC) {
       // Closed interval
       if (Start <= End) {
@@ -1407,17 +1411,17 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     return ListInit::get(Args, LHSi->getType());
   }
   case STRCONCAT: {
-    StringInit *LHSs = dyn_cast<StringInit>(LHS);
-    StringInit *RHSs = dyn_cast<StringInit>(RHS);
+    const StringInit *LHSs = dyn_cast<StringInit>(LHS);
+    const StringInit *RHSs = dyn_cast<StringInit>(RHS);
     if (LHSs && RHSs)
       return ConcatStringInits(LHSs, RHSs);
     break;
   }
   case INTERLEAVE: {
-    ListInit *List = dyn_cast<ListInit>(LHS);
-    StringInit *Delim = dyn_cast<StringInit>(RHS);
+    const ListInit *List = dyn_cast<ListInit>(LHS);
+    const StringInit *Delim = dyn_cast<StringInit>(RHS);
     if (List && Delim) {
-      StringInit *Result;
+      const StringInit *Result;
       if (isa<StringRecTy>(List->getElementType()))
         Result = interleaveStringList(List, Delim);
       else
@@ -1438,7 +1442,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     break;
   }
   case GETDAGARG: {
-    DagInit *Dag = dyn_cast<DagInit>(LHS);
+    const DagInit *Dag = dyn_cast<DagInit>(LHS);
     if (Dag && isa<IntInit, StringInit>(RHS)) {
       std::string Error;
       auto ArgNo = getDagArgNoByKey(Dag, RHS, Error);
@@ -1447,7 +1451,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
 
       assert(*ArgNo < Dag->getNumArgs());
 
-      Init *Arg = Dag->getArg(*ArgNo);
+      const Init *Arg = Dag->getArg(*ArgNo);
       if (auto *TI = dyn_cast<TypedInit>(Arg))
         if (!TI->getType()->typeIsConvertibleTo(getType()))
           return UnsetInit::get(Dag->getRecordKeeper());
@@ -1456,8 +1460,8 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     break;
   }
   case GETDAGNAME: {
-    DagInit *Dag = dyn_cast<DagInit>(LHS);
-    IntInit *Idx = dyn_cast<IntInit>(RHS);
+    const DagInit *Dag = dyn_cast<DagInit>(LHS);
+    const IntInit *Idx = dyn_cast<IntInit>(RHS);
     if (Dag && Idx) {
       int64_t Pos = Idx->getValue();
       if (Pos < 0 || Pos >= Dag->getNumArgs()) {
@@ -1467,7 +1471,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
                        std::to_string(Dag->getNumArgs() - 1) + ": " +
                        std::to_string(Pos));
       }
-      Init *ArgName = Dag->getArgName(Pos);
+      const Init *ArgName = Dag->getArgName(Pos);
       if (!ArgName)
         return UnsetInit::get(getRecordKeeper());
       return ArgName;
@@ -1475,11 +1479,11 @@ Init *BinOpInit::Fold(Record *CurRec) const {
     break;
   }
   case SETDAGOP: {
-    DagInit *Dag = dyn_cast<DagInit>(LHS);
-    DefInit *Op = dyn_cast<DefInit>(RHS);
+    const DagInit *Dag = dyn_cast<DagInit>(LHS);
+    const DefInit *Op = dyn_cast<DefInit>(RHS);
     if (Dag && Op) {
-      SmallVector<Init*, 8> Args;
-      SmallVector<StringInit*, 8> ArgNames;
+      SmallVector<const Init *, 8> Args;
+      SmallVector<const StringInit *, 8> ArgNames;
       for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
         Args.push_back(Dag->getArg(i));
         ArgNames.push_back(Dag->getArgName(i));
@@ -1498,9 +1502,9 @@ Init *BinOpInit::Fold(Record *CurRec) const {
   case SHL:
   case SRA:
   case SRL: {
-    IntInit *LHSi = dyn_cast_or_null<IntInit>(
+    const IntInit *LHSi = dyn_cast_or_null<IntInit>(
         LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
-    IntInit *RHSi = dyn_cast_or_null<IntInit>(
+    const IntInit *RHSi = dyn_cast_or_null<IntInit>(
         RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
     if (LHSi && RHSi) {
       int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
@@ -1533,17 +1537,17 @@ Init *BinOpInit::Fold(Record *CurRec) const {
   }
   }
 unresolved:
-  return const_cast<BinOpInit *>(this);
+  return this;
 }
 
-Init *BinOpInit::resolveReferences(Resolver &R) const {
-  Init *lhs = LHS->resolveReferences(R);
-  Init *rhs = RHS->resolveReferences(R);
+const Init *BinOpInit::resolveReferences(Resolver &R) const {
+  const Init *lhs = LHS->resolveReferences(R);
+  const Init *rhs = RHS->resolveReferences(R);
 
   if (LHS != lhs || RHS != rhs)
     return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))
         ->Fold(R.getCurrentRecord());
-  return const_cast<BinOpInit *>(this);
+  return this;
 }
 
 std::string BinOpInit::getAsString() const {
@@ -1589,8 +1593,9 @@ std::string BinOpInit::getAsString() const {
   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
 }
 
-static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS,
-                              Init *MHS, Init *RHS, const RecTy *Type) {
+static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode,
+                              const Init *LHS, const Init *MHS, const Init *RHS,
+                              const RecTy *Type) {
   ID.AddInteger(Opcode);
   ID.AddPointer(LHS);
   ID.AddPointer(MHS);
@@ -1598,8 +1603,9 @@ static void ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS,
   ID.AddPointer(Type);
 }
 
-TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS,
-                            const RecTy *Type) {
+const TernOpInit *TernOpInit::get(TernaryOp Opc, const Init *LHS,
+                                  const Init *MHS, const Init *RHS,
+                                  const RecTy *Type) {
   FoldingSetNodeID ID;
   ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type);
 
@@ -1617,26 +1623,27 @@ void TernOpInit::Profile(FoldingSetNodeID &ID) const {
   ProfileTernOpInit(ID, getOpcode(), getLHS(), getMHS(), getRHS(), getType());
 }
 
-static Init *ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec) {
+static const Init *ItemApply(const Init *LHS, const Init *MHSe, const Init *RHS,
+                             const Record *CurRec) {
   MapResolver R(CurRec);
   R.set(LHS, MHSe);
   return RHS->resolveReferences(R);
 }
 
-static Init *ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS,
-                             Record *CurRec) {
+static const Init *ForeachDagApply(const Init *LHS, const DagInit *MHSd,
+                                   const Init *RHS, const Record *CurRec) {
   bool Change = false;
-  Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec);
+  const Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec);
   if (Val != MHSd->getOperator())
     Change = true;
 
-  SmallVector<std::pair<Init *, StringInit *>, 8> NewArgs;
+  SmallVector<std::pair<const Init *, const StringInit *>, 8> NewArgs;
   for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
-    Init *Arg = MHSd->getArg(i);
-    Init *NewArg;
-    StringInit *ArgName = MHSd->getArgName(i);
+    const Init *Arg = MHSd->getArg(i);
+    const Init *NewArg;
+    const StringInit *ArgName = MHSd->getArgName(i);
 
-    if (DagInit *Argd = dyn_cast<DagInit>(Arg))
+    if (const DagInit *Argd = dyn_cast<DagInit>(Arg))
       NewArg = ForeachDagApply(LHS, Argd, RHS, CurRec);
     else
       NewArg = ItemApply(LHS, Arg, RHS, CurRec);
@@ -1652,16 +1659,17 @@ static Init *ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS,
 }
 
 // Applies RHS to all elements of MHS, using LHS as a temp variable.
-static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, const RecTy *Type,
-                           Record *CurRec) {
-  if (DagInit *MHSd = dyn_cast<DagInit>(MHS))
+static const Init *ForeachHelper(const Init *LHS, const Init *MHS,
+                                 const Init *RHS, const RecTy *Type,
+                                 const Record *CurRec) {
+  if (const DagInit *MHSd = dyn_cast<DagInit>(MHS))
     return ForeachDagApply(LHS, MHSd, RHS, CurRec);
 
-  if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
-    SmallVector<Init *, 8> NewList(MHSl->begin(), MHSl->end());
+  if (const ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
+    SmallVector<const Init *, 8> NewList(MHSl->begin(), MHSl->end());
 
-    for (Init *&Item : NewList) {
-      Init *NewItem = ItemApply(LHS, Item, RHS, CurRec);
+    for (const Init *&Item : NewList) {
+      const Init *NewItem = ItemApply(LHS, Item, RHS, CurRec);
       if (NewItem != Item)
         Item = NewItem;
     }
@@ -1673,16 +1681,17 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, const RecTy *Type,
 
 // Evaluates RHS for all elements of MHS, using LHS as a temp variable.
 // Creates a new list with the elements that evaluated to true.
-static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, const RecTy *Type,
-                          Record *CurRec) {
-  if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
-    SmallVector<Init *, 8> NewList;
-
-    for (Init *Item : MHSl->getValues()) {
-      Init *Include = ItemApply(LHS, Item, RHS, CurRec);
+static const Init *FilterHelper(const Init *LHS, const Init *MHS,
+                                const Init *RHS, const RecTy *Type,
+                                const Record *CurRec) {
+  if (const ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
+    SmallVector<const Init *, 8> NewList;
+
+    for (const Init *Item : MHSl->getValues()) {
+      const Init *Include = ItemApply(LHS, Item, RHS, CurRec);
       if (!Include)
         return nullptr;
-      if (IntInit *IncludeInt =
+      if (const IntInit *IncludeInt =
               dyn_cast_or_null<IntInit>(Include->convertInitializerTo(
                   IntRecTy::get(LHS->getRecordKeeper())))) {
         if (IncludeInt->getValue())
@@ -1697,21 +1706,21 @@ static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, const RecTy *Type,
   return nullptr;
 }
 
-Init *TernOpInit::Fold(Record *CurRec) const {
+const Init *TernOpInit::Fold(const Record *CurRec) const {
   RecordKeeper &RK = getRecordKeeper();
   switch (getOpcode()) {
   case SUBST: {
-    DefInit *LHSd = dyn_cast<DefInit>(LHS);
-    VarInit *LHSv = dyn_cast<VarInit>(LHS);
-    StringInit *LHSs = dyn_cast<StringInit>(LHS);
+    const DefInit *LHSd = dyn_cast<DefInit>(LHS);
+    const VarInit *LHSv = dyn_cast<VarInit>(LHS);
+    const StringInit *LHSs = dyn_cast<StringInit>(LHS);
 
-    DefInit *MHSd = dyn_cast<DefInit>(MHS);
-    VarInit *MHSv = dyn_cast<VarInit>(MHS);
-    StringInit *MHSs = dyn_cast<StringInit>(MHS);
+    const DefInit *MHSd = dyn_cast<DefInit>(MHS);
+    const VarInit *MHSv = dyn_cast<VarInit>(MHS);
+    const StringInit *MHSs = dyn_cast<StringInit>(MHS);
 
-    DefInit *RHSd = dyn_cast<DefInit>(RHS);
-    VarInit *RHSv = dyn_cast<VarInit>(RHS);
-    StringInit *RHSs = dyn_cast<StringInit>(RHS);
+    const DefInit *RHSd = dyn_cast<DefInit>(RHS);
+    const VarInit *RHSv = dyn_cast<VarInit>(RHS);
+    const StringInit *RHSs = dyn_cast<StringInit>(RHS);
 
     if (LHSd && MHSd && RHSd) {
       const Record *Val = RHSd->getDef();
@@ -1745,19 +1754,19 @@ Init *TernOpInit::Fold(Record *CurRec) const {
   }
 
   case FOREACH: {
-    if (Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), CurRec))
+    if (const Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), CurRec))
       return Result;
     break;
   }
 
   case FILTER: {
-    if (Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec))
+    if (const Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec))
       return Result;
     break;
   }
 
   case IF: {
-    if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
+    if (const IntInit *LHSi = dyn_cast_or_null<IntInit>(
             LHS->convertInitializerTo(IntRecTy::get(RK)))) {
       if (LHSi->getValue())
         return MHS;
@@ -1767,8 +1776,8 @@ Init *TernOpInit::Fold(Record *CurRec) const {
   }
 
   case DAG: {
-    ListInit *MHSl = dyn_cast<ListInit>(MHS);
-    ListInit *RHSl = dyn_cast<ListInit>(RHS);
+    const ListInit *MHSl = dyn_cast<ListInit>(MHS);
+    const ListInit *RHSl = dyn_cast<ListInit>(RHS);
     bool MHSok = MHSl || isa<UnsetInit>(MHS);
     bool RHSok = RHSl || isa<UnsetInit>(RHS);
 
@@ -1776,11 +1785,11 @@ Init *TernOpInit::Fold(Record *CurRec) const {
       break; // Typically prevented by the parser, but might happen with template args
 
     if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
-      SmallVector<std::pair<Init *, StringInit *>, 8> Children;
+      SmallVector<std::pair<const Init *, const StringInit *>, 8> Children;
       unsigned Size = MHSl ? MHSl->size() : RHSl->size();
       for (unsigned i = 0; i != Size; ++i) {
-        Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(RK);
-        Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(RK);
+        const Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(RK);
+        const Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(RK);
         if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name))
           return const_cast<TernOpInit *>(this);
         Children.emplace_back(Node, dyn_cast<StringInit>(Name));
@@ -1803,7 +1812,7 @@ Init *TernOpInit::Fold(Record *CurRec) const {
     if (Step == 0)
       PrintError(CurRec->getLoc(), "Step of !range can't be 0");
 
-    SmallVector<Init *, 8> Args;
+    SmallVector<const Init *, 8> Args;
     if (Start < End && Step > 0) {
       Args.reserve((End - Start) / Step);
       for (auto I = Start; I < End; I += Step)
@@ -1819,9 +1828,9 @@ Init *TernOpInit::Fold(Record *CurRec) const {
   }
 
   case SUBSTR: {
-    StringInit *LHSs = dyn_cast<StringInit>(LHS);
-    IntInit *MHSi = dyn_cast<IntInit>(MHS);
-    IntInit *RHSi = dyn_cast<IntInit>(RHS);
+    const StringInit *LHSs = dyn_cast<StringInit>(LHS);
+    const IntInit *MHSi = dyn_cast<IntInit>(MHS);
+    const IntInit *RHSi = dyn_cast<IntInit>(RHS);
     if (LHSs && MHSi && RHSi) {
       int64_t StringSize = LHSs->getValue().size();
       int64_t Start = MHSi->getValue();
@@ -1840,9 +1849,9 @@ Init *TernOpInit::Fold(Record *CurRec) const {
   }
 
   case FIND: {
-    StringInit *LHSs = dyn_cast<StringInit>(LHS);
-    StringInit *MHSs = dyn_cast<StringInit>(MHS);
-    IntInit *RHSi = dyn_cast<IntInit>(RHS);
+    const StringInit *LHSs = dyn_cast<StringInit>(LHS);
+    const StringInit *MHSs = dyn_cast<StringInit>(MHS);
+    const IntInit *RHSi = dyn_cast<IntInit>(RHS);
     if (LHSs && MHSs && RHSi) {
       int64_t SourceSize = LHSs->getValue().size();
       int64_t Start = RHSi->getValue();
@@ -1860,7 +1869,7 @@ Init *TernOpInit::Fold(Record *CurRec) const {
   }
 
   case SETDAGARG: {
-    DagInit *Dag = dyn_cast<DagInit>(LHS);
+    const DagInit *Dag = dyn_cast<DagInit>(LHS);
     if (Dag && isa<IntInit, StringInit>(MHS)) {
       std::string Error;
       auto ArgNo = getDagArgNoByKey(Dag, MHS, Error);
@@ -1869,8 +1878,8 @@ Init *TernOpInit::Fold(Record *CurRec) const {
 
       assert(*ArgNo < Dag->getNumArgs());
 
-      SmallVector<Init *, 8> Args(Dag->getArgs());
-      SmallVector<StringInit *, 8> Names(Dag->getArgNames());
+      SmallVector<const Init *, 8> Args(Dag->getArgs());
+      SmallVector<const StringInit *, 8> Names(Dag->getArgNames());
       Args[*ArgNo] = RHS;
       return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
     }
@@ -1878,7 +1887,7 @@ Init *TernOpInit::Fold(Record *CurRec) const {
   }
 
   case SETDAGNAME: {
-    DagInit *Dag = dyn_cast<DagInit>(LHS);
+    const DagInit *Dag = dyn_cast<DagInit>(LHS);
     if (Dag && isa<IntInit, StringInit>(MHS)) {
       std::string Error;
       auto ArgNo = getDagArgNoByKey(Dag, MHS, Error);
@@ -1887,8 +1896,8 @@ Init *TernOpInit::Fold(Record *CurRec) const {
 
       assert(*ArgNo < Dag->getNumArgs());
 
-      SmallVector<Init *, 8> Args(Dag->getArgs());
-      SmallVector<StringInit *, 8> Names(Dag->getArgNames());
+      SmallVector<const Init *, 8> Args(Dag->getArgs());
+      SmallVector<const StringInit *, 8> Names(Dag->getArgNames());
       Names[*ArgNo] = dyn_cast<StringInit>(RHS);
       return DagInit::get(Dag->getOperator(), Dag->getName(), Args, Names);
     }
@@ -1899,11 +1908,11 @@ Init *TernOpInit::Fold(Record *CurRec) const {
   return const_cast<TernOpInit *>(this);
 }
 
-Init *TernOpInit::resolveReferences(Resolver &R) const {
-  Init *lhs = LHS->resolveReferences(R);
+const Init *TernOpInit::resolveReferences(Resolver &R) const {
+  const Init *lhs = LHS->resolveReferences(R);
 
   if (getOpcode() == IF && lhs != LHS) {
-    if (IntInit *Value = dyn_cast_or_null<IntInit>(
+    if (const IntInit *Value = dyn_cast_or_null<IntInit>(
             lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
       // Short-circuit
       if (Value->getValue())
@@ -1912,8 +1921,8 @@ Init *TernOpInit::resolveReferences(Resolver &R) const {
     }
   }
 
-  Init *mhs = MHS->resolveReferences(R);
-  Init *rhs;
+  const Init *mhs = MHS->resolveReferences(R);
+  const Init *rhs;
 
   if (getOpcode() == FOREACH || getOpcode() == FILTER) {
     ShadowResolver SR(R);
@@ -1926,7 +1935,7 @@ Init *TernOpInit::resolveReferences(Resolver &R) const {
   if (LHS != lhs || MHS != mhs || RHS != rhs)
     return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, getType()))
         ->Fold(R.getCurrentRecord());
-  return const_cast<TernOpInit *>(this);
+  return this;
 }
 
 std::string TernOpInit::getAsString() const {
@@ -1955,8 +1964,9 @@ std::string TernOpInit::getAsString() const {
           ", " + MHS->getAsString() + ", " + RHS->getAsString() + ")");
 }
 
-static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *Start, Init *List,
-                              Init *A, Init *B, Init *Expr, const RecTy *Type) {
+static void ProfileFoldOpInit(FoldingSetNodeID &ID, const Init *Start,
+                              const Init *List, const Init *A, const Init *B,
+                              const Init *Expr, const RecTy *Type) {
   ID.AddPointer(Start);
   ID.AddPointer(List);
   ID.AddPointer(A);
@@ -1965,14 +1975,15 @@ static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *Start, Init *List,
   ID.AddPointer(Type);
 }
 
-FoldOpInit *FoldOpInit::get(Init *Start, Init *List, Init *A, Init *B,
-                            Init *Expr, const RecTy *Type) {
+const FoldOpInit *FoldOpInit::get(const Init *Start, const Init *List,
+                                  const Init *A, const Init *B,
+                                  const Init *Expr, const RecTy *Type) {
   FoldingSetNodeID ID;
   ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type);
 
   detail::RecordKeeperImpl &RK = Start->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (FoldOpInit *I = RK.TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const FoldOpInit *I = RK.TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   FoldOpInit *I = new (RK.Allocator) FoldOpInit(Start, List, A, B, Expr, Type);
@@ -1984,10 +1995,10 @@ void FoldOpInit::Profile(FoldingSetNodeID &ID) const {
   ProfileFoldOpInit(ID, Start, List, A, B, Expr, getType());
 }
 
-Init *FoldOpInit::Fold(Record *CurRec) const {
-  if (ListInit *LI = dyn_cast<ListInit>(List)) {
-    Init *Accum = Start;
-    for (Init *Elt : *LI) {
+const Init *FoldOpInit::Fold(const Record *CurRec) const {
+  if (const ListInit *LI = dyn_cast<ListInit>(List)) {
+    const Init *Accum = Start;
+    for (const Init *Elt : *LI) {
       MapResolver R(CurRec);
       R.set(A, Accum);
       R.set(B, Elt);
@@ -1995,25 +2006,25 @@ Init *FoldOpInit::Fold(Record *CurRec) const {
     }
     return Accum;
   }
-  return const_cast<FoldOpInit *>(this);
+  return this;
 }
 
-Init *FoldOpInit::resolveReferences(Resolver &R) const {
-  Init *NewStart = Start->resolveReferences(R);
-  Init *NewList = List->resolveReferences(R);
+const Init *FoldOpInit::resolveReferences(Resolver &R) const {
+  const Init *NewStart = Start->resolveReferences(R);
+  const Init *NewList = List->resolveReferences(R);
   ShadowResolver SR(R);
   SR.addShadow(A);
   SR.addShadow(B);
-  Init *NewExpr = Expr->resolveReferences(SR);
+  const Init *NewExpr = Expr->resolveReferences(SR);
 
   if (Start == NewStart && List == NewList && Expr == NewExpr)
-    return const_cast<FoldOpInit *>(this);
+    return this;
 
   return get(NewStart, NewList, A, B, NewExpr, getType())
       ->Fold(R.getCurrentRecord());
 }
 
-Init *FoldOpInit::getBit(unsigned Bit) const {
+const Init *FoldOpInit::getBit(unsigned Bit) const {
   return VarBitInit::get(const_cast<FoldOpInit *>(this), Bit);
 }
 
@@ -2025,19 +2036,19 @@ std::string FoldOpInit::getAsString() const {
 }
 
 static void ProfileIsAOpInit(FoldingSetNodeID &ID, const RecTy *CheckType,
-                             Init *Expr) {
+                             const Init *Expr) {
   ID.AddPointer(CheckType);
   ID.AddPointer(Expr);
 }
 
-IsAOpInit *IsAOpInit::get(const RecTy *CheckType, Init *Expr) {
+const IsAOpInit *IsAOpInit::get(const RecTy *CheckType, const Init *Expr) {
 
   FoldingSetNodeID ID;
   ProfileIsAOpInit(ID, CheckType, Expr);
 
   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (IsAOpInit *I = RK.TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const IsAOpInit *I = RK.TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   IsAOpInit *I = new (RK.Allocator) IsAOpInit(CheckType, Expr);
@@ -2049,8 +2060,8 @@ void IsAOpInit::Profile(FoldingSetNodeID &ID) const {
   ProfileIsAOpInit(ID, CheckType, Expr);
 }
 
-Init *IsAOpInit::Fold() const {
-  if (TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
+const Init *IsAOpInit::Fold() const {
+  if (const TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
     // Is the expression type known to be (a subclass of) the desired type?
     if (TI->getType()->typeIsConvertibleTo(CheckType))
       return IntInit::get(getRecordKeeper(), 1);
@@ -2066,17 +2077,17 @@ Init *IsAOpInit::Fold() const {
       return IntInit::get(getRecordKeeper(), 0);
     }
   }
-  return const_cast<IsAOpInit *>(this);
+  return this;
 }
 
-Init *IsAOpInit::resolveReferences(Resolver &R) const {
-  Init *NewExpr = Expr->resolveReferences(R);
+const Init *IsAOpInit::resolveReferences(Resolver &R) const {
+  const Init *NewExpr = Expr->resolveReferences(R);
   if (Expr != NewExpr)
     return get(CheckType, NewExpr)->Fold();
-  return const_cast<IsAOpInit *>(this);
+  return this;
 }
 
-Init *IsAOpInit::getBit(unsigned Bit) const {
+const Init *IsAOpInit::getBit(unsigned Bit) const {
   return VarBitInit::get(const_cast<IsAOpInit *>(this), Bit);
 }
 
@@ -2087,18 +2098,20 @@ std::string IsAOpInit::getAsString() const {
 }
 
 static void ProfileExistsOpInit(FoldingSetNodeID &ID, const RecTy *CheckType,
-                                Init *Expr) {
+                                const Init *Expr) {
   ID.AddPointer(CheckType);
   ID.AddPointer(Expr);
 }
 
-ExistsOpInit *ExistsOpInit::get(const RecTy *CheckType, Init *Expr) {
+const ExistsOpInit *ExistsOpInit::get(const RecTy *CheckType,
+                                      const Init *Expr) {
   FoldingSetNodeID ID;
   ProfileExistsOpInit(ID, CheckType, Expr);
 
   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (ExistsOpInit *I = RK.TheExistsOpInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const ExistsOpInit *I =
+          RK.TheExistsOpInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   ExistsOpInit *I = new (RK.Allocator) ExistsOpInit(CheckType, Expr);
@@ -2110,9 +2123,8 @@ void ExistsOpInit::Profile(FoldingSetNodeID &ID) const {
   ProfileExistsOpInit(ID, CheckType, Expr);
 }
 
-Init *ExistsOpInit::Fold(Record *CurRec, bool IsFinal) const {
-  if (StringInit *Name = dyn_cast<StringInit>(Expr)) {
-
+const Init *ExistsOpInit::Fold(const Record *CurRec, bool IsFinal) const {
+  if (const StringInit *Name = dyn_cast<StringInit>(Expr)) {
     // Look up all defined records to see if we can find one.
     const Record *D = CheckType->getRecordKeeper().getDef(Name->getValue());
     if (D) {
@@ -2139,19 +2151,18 @@ Init *ExistsOpInit::Fold(Record *CurRec, bool IsFinal) const {
 
     if (IsFinal)
       return IntInit::get(getRecordKeeper(), 0);
-    return const_cast<ExistsOpInit *>(this);
   }
-  return const_cast<ExistsOpInit *>(this);
+  return this;
 }
 
-Init *ExistsOpInit::resolveReferences(Resolver &R) const {
-  Init *NewExpr = Expr->resolveReferences(R);
+const Init *ExistsOpInit::resolveReferences(Resolver &R) const {
+  const Init *NewExpr = Expr->resolveReferences(R);
   if (Expr != NewExpr || R.isFinal())
     return get(CheckType, NewExpr)->Fold(R.getCurrentRecord(), R.isFinal());
-  return const_cast<ExistsOpInit *>(this);
+  return this;
 }
 
-Init *ExistsOpInit::getBit(unsigned Bit) const {
+const Init *ExistsOpInit::getBit(unsigned Bit) const {
   return VarBitInit::get(const_cast<ExistsOpInit *>(this), Bit);
 }
 
@@ -2161,7 +2172,7 @@ std::string ExistsOpInit::getAsString() const {
       .str();
 }
 
-const RecTy *TypedInit::getFieldType(StringInit *FieldName) const {
+const RecTy *TypedInit::getFieldType(const StringInit *FieldName) const {
   if (const RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) {
     for (const Record *Rec : RecordType->getClasses()) {
       if (const RecordVal *Field = Rec->getValue(FieldName))
@@ -2171,7 +2182,7 @@ const RecTy *TypedInit::getFieldType(StringInit *FieldName) const {
   return nullptr;
 }
 
-Init *TypedInit::convertInitializerTo(const RecTy *Ty) const {
+const Init *TypedInit::convertInitializerTo(const RecTy *Ty) const {
   if (getType() == Ty || getType()->typeIsA(Ty))
     return const_cast<TypedInit *>(this);
 
@@ -2182,12 +2193,13 @@ Init *TypedInit::convertInitializerTo(const RecTy *Ty) const {
   return nullptr;
 }
 
-Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
+const Init *
+TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
   const BitsRecTy *T = dyn_cast<BitsRecTy>(getType());
   if (!T) return nullptr;  // Cannot subscript a non-bits variable.
   unsigned NumBits = T->getNumBits();
 
-  SmallVector<Init *, 16> NewBits;
+  SmallVector<const Init *, 16> NewBits;
   NewBits.reserve(Bits.size());
   for (unsigned Bit : Bits) {
     if (Bit >= NumBits)
@@ -2198,12 +2210,12 @@ Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
   return BitsInit::get(getRecordKeeper(), NewBits);
 }
 
-Init *TypedInit::getCastTo(const RecTy *Ty) const {
+const Init *TypedInit::getCastTo(const RecTy *Ty) const {
   // Handle the common case quickly
   if (getType() == Ty || getType()->typeIsA(Ty))
     return const_cast<TypedInit *>(this);
 
-  if (Init *Converted = convertInitializerTo(Ty)) {
+  if (const Init *Converted = convertInitializerTo(Ty)) {
     assert(!isa<TypedInit>(Converted) ||
            cast<TypedInit>(Converted)->getType()->typeIsA(Ty));
     return Converted;
@@ -2216,12 +2228,12 @@ Init *TypedInit::getCastTo(const RecTy *Ty) const {
       ->Fold(nullptr);
 }
 
-VarInit *VarInit::get(StringRef VN, const RecTy *T) {
-  Init *Value = StringInit::get(T->getRecordKeeper(), VN);
+const VarInit *VarInit::get(StringRef VN, const RecTy *T) {
+  const Init *Value = StringInit::get(T->getRecordKeeper(), VN);
   return VarInit::get(Value, T);
 }
 
-VarInit *VarInit::get(Init *VN, const RecTy *T) {
+const VarInit *VarInit::get(const Init *VN, const RecTy *T) {
   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
   VarInit *&I = RK.TheVarInitPool[std::make_pair(T, VN)];
   if (!I)
@@ -2230,23 +2242,23 @@ VarInit *VarInit::get(Init *VN, const RecTy *T) {
 }
 
 StringRef VarInit::getName() const {
-  StringInit *NameString = cast<StringInit>(getNameInit());
+  const StringInit *NameString = cast<StringInit>(getNameInit());
   return NameString->getValue();
 }
 
-Init *VarInit::getBit(unsigned Bit) const {
+const Init *VarInit::getBit(unsigned Bit) const {
   if (getType() == BitRecTy::get(getRecordKeeper()))
     return const_cast<VarInit*>(this);
   return VarBitInit::get(const_cast<VarInit*>(this), Bit);
 }
 
-Init *VarInit::resolveReferences(Resolver &R) const {
-  if (Init *Val = R.resolve(VarName))
+const Init *VarInit::resolveReferences(Resolver &R) const {
+  if (const Init *Val = R.resolve(VarName))
     return Val;
-  return const_cast<VarInit *>(this);
+  return this;
 }
 
-VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) {
+const VarBitInit *VarBitInit::get(const TypedInit *T, unsigned B) {
   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
   VarBitInit *&I = RK.TheVarBitInitPool[std::make_pair(T, B)];
   if (!I)
@@ -2258,25 +2270,25 @@ std::string VarBitInit::getAsString() const {
   return TI->getAsString() + "{" + utostr(Bit) + "}";
 }
 
-Init *VarBitInit::resolveReferences(Resolver &R) const {
-  Init *I = TI->resolveReferences(R);
+const Init *VarBitInit::resolveReferences(Resolver &R) const {
+  const Init *I = TI->resolveReferences(R);
   if (TI != I)
     return I->getBit(getBitNum());
 
-  return const_cast<VarBitInit*>(this);
+  return this;
 }
 
 DefInit::DefInit(const Record *D)
     : TypedInit(IK_DefInit, D->getType()), Def(D) {}
 
-Init *DefInit::convertInitializerTo(const RecTy *Ty) const {
+const Init *DefInit::convertInitializerTo(const RecTy *Ty) const {
   if (auto *RRT = dyn_cast<RecordRecTy>(Ty))
     if (getType()->typeIsConvertibleTo(RRT))
       return const_cast<DefInit *>(this);
   return nullptr;
 }
 
-const RecTy *DefInit::getFieldType(StringInit *FieldName) const {
+const RecTy *DefInit::getFieldType(const StringInit *FieldName) const {
   if (const RecordVal *RV = Def->getValue(FieldName))
     return RV->getType();
   return nullptr;
@@ -2285,11 +2297,11 @@ const RecTy *DefInit::getFieldType(StringInit *FieldName) const {
 std::string DefInit::getAsString() const { return std::string(Def->getName()); }
 
 static void ProfileVarDefInit(FoldingSetNodeID &ID, Record *Class,
-                              ArrayRef<ArgumentInit *> Args) {
+                              ArrayRef<const ArgumentInit *> Args) {
   ID.AddInteger(Args.size());
   ID.AddPointer(Class);
 
-  for (Init *I : Args)
+  for (const Init *I : Args)
     ID.AddPointer(I);
 }
 
@@ -2297,21 +2309,21 @@ VarDefInit::VarDefInit(SMLoc Loc, Record *Class, unsigned N)
     : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Loc(Loc), Class(Class),
       NumArgs(N) {}
 
-VarDefInit *VarDefInit::get(SMLoc Loc, Record *Class,
-                            ArrayRef<ArgumentInit *> Args) {
+const VarDefInit *VarDefInit::get(SMLoc Loc, Record *Class,
+                                  ArrayRef<const ArgumentInit *> Args) {
   FoldingSetNodeID ID;
   ProfileVarDefInit(ID, Class, Args);
 
   detail::RecordKeeperImpl &RK = Class->getRecords().getImpl();
   void *IP = nullptr;
-  if (VarDefInit *I = RK.TheVarDefInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const VarDefInit *I = RK.TheVarDefInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   void *Mem = RK.Allocator.Allocate(
-      totalSizeToAlloc<ArgumentInit *>(Args.size()), alignof(VarDefInit));
+      totalSizeToAlloc<const ArgumentInit *>(Args.size()), alignof(VarDefInit));
   VarDefInit *I = new (Mem) VarDefInit(Loc, Class, Args.size());
   std::uninitialized_copy(Args.begin(), Args.end(),
-                          I->getTrailingObjects<ArgumentInit *>());
+                          I->getTrailingObjects<const ArgumentInit *>());
   RK.TheVarDefInitPool.InsertNode(I, IP);
   return I;
 }
@@ -2320,7 +2332,7 @@ void VarDefInit::Profile(FoldingSetNodeID &ID) const {
   ProfileVarDefInit(ID, Class, args());
 }
 
-DefInit *VarDefInit::instantiate() {
+const DefInit *VarDefInit::instantiate() {
   if (Def)
     return Def;
 
@@ -2340,10 +2352,10 @@ DefInit *VarDefInit::instantiate() {
   NewRec->appendDumps(Class);
 
   // Substitute and resolve template arguments
-  ArrayRef<Init *> TArgs = Class->getTemplateArgs();
+  ArrayRef<const Init *> TArgs = Class->getTemplateArgs();
   MapResolver R(NewRec);
 
-  for (Init *Arg : TArgs) {
+  for (const Init *Arg : TArgs) {
     R.set(Arg, NewRec->getValue(Arg)->getValue());
     NewRec->removeValue(Arg);
   }
@@ -2377,13 +2389,13 @@ DefInit *VarDefInit::instantiate() {
   return Def = NewRec->getDefInit();
 }
 
-Init *VarDefInit::resolveReferences(Resolver &R) const {
+const Init *VarDefInit::resolveReferences(Resolver &R) const {
   TrackUnresolvedResolver UR(&R);
   bool Changed = false;
-  SmallVector<ArgumentInit *, 8> NewArgs;
+  SmallVector<const ArgumentInit *, 8> NewArgs;
   NewArgs.reserve(args_size());
 
-  for (ArgumentInit *Arg : args()) {
+  for (const ArgumentInit *Arg : args()) {
     auto *NewArg = cast<ArgumentInit>(Arg->resolveReferences(UR));
     NewArgs.push_back(NewArg);
     Changed |= NewArg != Arg;
@@ -2392,29 +2404,29 @@ Init *VarDefInit::resolveReferences(Resolver &R) const {
   if (Changed) {
     auto *New = VarDefInit::get(Loc, Class, NewArgs);
     if (!UR.foundUnresolved())
-      return New->instantiate();
+      return const_cast<VarDefInit *>(New)->instantiate();
     return New;
   }
-  return const_cast<VarDefInit *>(this);
+  return this;
 }
 
-Init *VarDefInit::Fold() const {
+const Init *VarDefInit::Fold() const {
   if (Def)
     return Def;
 
   TrackUnresolvedResolver R;
-  for (Init *Arg : args())
+  for (const Init *Arg : args())
     Arg->resolveReferences(R);
 
   if (!R.foundUnresolved())
     return const_cast<VarDefInit *>(this)->instantiate();
-  return const_cast<VarDefInit *>(this);
+  return this;
 }
 
 std::string VarDefInit::getAsString() const {
   std::string Result = Class->getNameInitAsString() + "<";
   const char *sep = "";
-  for (Init *Arg : args()) {
+  for (const Init *Arg : args()) {
     Result += sep;
     sep = ", ";
     Result += Arg->getAsString();
@@ -2422,7 +2434,7 @@ std::string VarDefInit::getAsString() const {
   return Result + ">";
 }
 
-FieldInit *FieldInit::get(Init *R, StringInit *FN) {
+const FieldInit *FieldInit::get(const Init *R, const StringInit *FN) {
   detail::RecordKeeperImpl &RK = R->getRecordKeeper().getImpl();
   FieldInit *&I = RK.TheFieldInitPool[std::make_pair(R, FN)];
   if (!I)
@@ -2430,28 +2442,28 @@ FieldInit *FieldInit::get(Init *R, StringInit *FN) {
   return I;
 }
 
-Init *FieldInit::getBit(unsigned Bit) const {
+const Init *FieldInit::getBit(unsigned Bit) const {
   if (getType() == BitRecTy::get(getRecordKeeper()))
     return const_cast<FieldInit*>(this);
   return VarBitInit::get(const_cast<FieldInit*>(this), Bit);
 }
 
-Init *FieldInit::resolveReferences(Resolver &R) const {
-  Init *NewRec = Rec->resolveReferences(R);
+const Init *FieldInit::resolveReferences(Resolver &R) const {
+  const Init *NewRec = Rec->resolveReferences(R);
   if (NewRec != Rec)
     return FieldInit::get(NewRec, FieldName)->Fold(R.getCurrentRecord());
-  return const_cast<FieldInit *>(this);
+  return this;
 }
 
-Init *FieldInit::Fold(Record *CurRec) const {
-  if (DefInit *DI = dyn_cast<DefInit>(Rec)) {
+const Init *FieldInit::Fold(const Record *CurRec) const {
+  if (const DefInit *DI = dyn_cast<DefInit>(Rec)) {
     const Record *Def = DI->getDef();
     if (Def == CurRec)
       PrintFatalError(CurRec->getLoc(),
                       Twine("Attempting to access field '") +
                       FieldName->getAsUnquotedString() + "' of '" +
                       Rec->getAsString() + "' is a forbidden self-reference");
-    Init *FieldVal = Def->getValue(FieldName)->getValue();
+    const Init *FieldVal = Def->getValue(FieldName)->getValue();
     if (FieldVal->isConcrete())
       return FieldVal;
   }
@@ -2459,22 +2471,22 @@ Init *FieldInit::Fold(Record *CurRec) const {
 }
 
 bool FieldInit::isConcrete() const {
-  if (DefInit *DI = dyn_cast<DefInit>(Rec)) {
-    Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
+  if (const DefInit *DI = dyn_cast<DefInit>(Rec)) {
+    const Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
     return FieldVal->isConcrete();
   }
   return false;
 }
 
 static void ProfileCondOpInit(FoldingSetNodeID &ID,
-                             ArrayRef<Init *> CondRange,
-                             ArrayRef<Init *> ValRange,
-                             const RecTy *ValType) {
+                              ArrayRef<const Init *> CondRange,
+                              ArrayRef<const Init *> ValRange,
+                              const RecTy *ValType) {
   assert(CondRange.size() == ValRange.size() &&
          "Number of conditions and values must match!");
   ID.AddPointer(ValType);
-  ArrayRef<Init *>::iterator Case = CondRange.begin();
-  ArrayRef<Init *>::iterator Val = ValRange.begin();
+  ArrayRef<const Init *>::iterator Case = CondRange.begin();
+  ArrayRef<const Init *>::iterator Val = ValRange.begin();
 
   while (Case != CondRange.end()) {
     ID.AddPointer(*Case++);
@@ -2483,13 +2495,15 @@ static void ProfileCondOpInit(FoldingSetNodeID &ID,
 }
 
 void CondOpInit::Profile(FoldingSetNodeID &ID) const {
-  ProfileCondOpInit(ID, ArrayRef(getTrailingObjects<Init *>(), NumConds),
-                    ArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds),
-                    ValType);
+  ProfileCondOpInit(
+      ID, ArrayRef(getTrailingObjects<const Init *>(), NumConds),
+      ArrayRef(getTrailingObjects<const Init *>() + NumConds, NumConds),
+      ValType);
 }
 
-CondOpInit *CondOpInit::get(ArrayRef<Init *> CondRange,
-                            ArrayRef<Init *> ValRange, const RecTy *Ty) {
+const CondOpInit *CondOpInit::get(ArrayRef<const Init *> CondRange,
+                                  ArrayRef<const Init *> ValRange,
+                                  const RecTy *Ty) {
   assert(CondRange.size() == ValRange.size() &&
          "Number of conditions and values must match!");
 
@@ -2498,33 +2512,34 @@ CondOpInit *CondOpInit::get(ArrayRef<Init *> CondRange,
 
   detail::RecordKeeperImpl &RK = Ty->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (CondOpInit *I = RK.TheCondOpInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const CondOpInit *I = RK.TheCondOpInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
   void *Mem = RK.Allocator.Allocate(
-      totalSizeToAlloc<Init *>(2 * CondRange.size()), alignof(BitsInit));
+      totalSizeToAlloc<const Init *>(2 * CondRange.size()), alignof(BitsInit));
   CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty);
 
   std::uninitialized_copy(CondRange.begin(), CondRange.end(),
-                          I->getTrailingObjects<Init *>());
+                          I->getTrailingObjects<const Init *>());
   std::uninitialized_copy(ValRange.begin(), ValRange.end(),
-                          I->getTrailingObjects<Init *>()+CondRange.size());
+                          I->getTrailingObjects<const Init *>() +
+                              CondRange.size());
   RK.TheCondOpInitPool.InsertNode(I, IP);
   return I;
 }
 
-Init *CondOpInit::resolveReferences(Resolver &R) const {
-  SmallVector<Init*, 4> NewConds;
+const Init *CondOpInit::resolveReferences(Resolver &R) const {
+  SmallVector<const Init *, 4> NewConds;
   bool Changed = false;
   for (const Init *Case : getConds()) {
-    Init *NewCase = Case->resolveReferences(R);
+    const Init *NewCase = Case->resolveReferences(R);
     NewConds.push_back(NewCase);
     Changed |= NewCase != Case;
   }
 
-  SmallVector<Init*, 4> NewVals;
+  SmallVector<const Init *, 4> NewVals;
   for (const Init *Val : getVals()) {
-    Init *NewVal = Val->resolveReferences(R);
+    const Init *NewVal = Val->resolveReferences(R);
     NewVals.push_back(NewVal);
     Changed |= NewVal != Val;
   }
@@ -2533,16 +2548,16 @@ Init *CondOpInit::resolveReferences(Resolver &R) const {
     return (CondOpInit::get(NewConds, NewVals,
             getValType()))->Fold(R.getCurrentRecord());
 
-  return const_cast<CondOpInit *>(this);
+  return this;
 }
 
-Init *CondOpInit::Fold(Record *CurRec) const {
+const Init *CondOpInit::Fold(const Record *CurRec) const {
   RecordKeeper &RK = getRecordKeeper();
-  for ( unsigned i = 0; i < NumConds; ++i) {
-    Init *Cond = getCond(i);
-    Init *Val = getVal(i);
+  for (unsigned i = 0; i < NumConds; ++i) {
+    const Init *Cond = getCond(i);
+    const Init *Val = getVal(i);
 
-    if (IntInit *CondI = dyn_cast_or_null<IntInit>(
+    if (const IntInit *CondI = dyn_cast_or_null<IntInit>(
             Cond->convertInitializerTo(IntRecTy::get(RK)))) {
       if (CondI->getValue())
         return Val->convertInitializerTo(getValType());
@@ -2593,18 +2608,19 @@ std::string CondOpInit::getAsString() const {
   return Result + ")";
 }
 
-Init *CondOpInit::getBit(unsigned Bit) const {
+const Init *CondOpInit::getBit(unsigned Bit) const {
   return VarBitInit::get(const_cast<CondOpInit *>(this), Bit);
 }
 
-static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN,
-                           ArrayRef<Init *> ArgRange,
-                           ArrayRef<StringInit *> NameRange) {
+static void ProfileDagInit(FoldingSetNodeID &ID, const Init *V,
+                           const StringInit *VN,
+                           ArrayRef<const Init *> ArgRange,
+                           ArrayRef<const StringInit *> NameRange) {
   ID.AddPointer(V);
   ID.AddPointer(VN);
 
-  ArrayRef<Init *>::iterator Arg = ArgRange.begin();
-  ArrayRef<StringInit *>::iterator Name = NameRange.begin();
+  ArrayRef<const Init *>::iterator Arg = ArgRange.begin();
+  ArrayRef<const StringInit *>::iterator Name = NameRange.begin();
   while (Arg != ArgRange.end()) {
     assert(Name != NameRange.end() && "Arg name underflow!");
     ID.AddPointer(*Arg++);
@@ -2613,34 +2629,36 @@ static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN,
   assert(Name == NameRange.end() && "Arg name overflow!");
 }
 
-DagInit *DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
-                      ArrayRef<StringInit *> NameRange) {
+const DagInit *DagInit::get(const Init *V, const StringInit *VN,
+                            ArrayRef<const Init *> ArgRange,
+                            ArrayRef<const StringInit *> NameRange) {
   assert(ArgRange.size() == NameRange.size());
   FoldingSetNodeID ID;
   ProfileDagInit(ID, V, VN, ArgRange, NameRange);
 
   detail::RecordKeeperImpl &RK = V->getRecordKeeper().getImpl();
   void *IP = nullptr;
-  if (DagInit *I = RK.TheDagInitPool.FindNodeOrInsertPos(ID, IP))
+  if (const DagInit *I = RK.TheDagInitPool.FindNodeOrInsertPos(ID, IP))
     return I;
 
-  void *Mem = RK.Allocator.Allocate(
-      totalSizeToAlloc<Init *, StringInit *>(ArgRange.size(), NameRange.size()),
-      alignof(BitsInit));
+  void *Mem =
+      RK.Allocator.Allocate(totalSizeToAlloc<const Init *, const StringInit *>(
+                                ArgRange.size(), NameRange.size()),
+                            alignof(BitsInit));
   DagInit *I = new (Mem) DagInit(V, VN, ArgRange.size(), NameRange.size());
   std::uninitialized_copy(ArgRange.begin(), ArgRange.end(),
-                          I->getTrailingObjects<Init *>());
+                          I->getTrailingObjects<const Init *>());
   std::uninitialized_copy(NameRange.begin(), NameRange.end(),
-                          I->getTrailingObjects<StringInit *>());
+                          I->getTrailingObjects<const StringInit *>());
   RK.TheDagInitPool.InsertNode(I, IP);
   return I;
 }
 
-DagInit *
-DagInit::get(Init *V, StringInit *VN,
-             ArrayRef<std::pair<Init*, StringInit*>> args) {
-  SmallVector<Init *, 8> Args;
-  SmallVector<StringInit *, 8> Names;
+const DagInit *
+DagInit::get(const Init *V, const StringInit *VN,
+             ArrayRef<std::pair<const Init *, const StringInit *>> args) {
+  SmallVector<const Init *, 8> Args;
+  SmallVector<const StringInit *, 8> Names;
 
   for (const auto &Arg : args) {
     Args.push_back(Arg.first);
@@ -2651,13 +2669,13 @@ DagInit::get(Init *V, StringInit *VN,
 }
 
 void DagInit::Profile(FoldingSetNodeID &ID) const {
-  ProfileDagInit(ID, Val, ValName,
-                 ArrayRef(getTrailingObjects<Init *>(), NumArgs),
-                 ArrayRef(getTrailingObjects<StringInit *>(), NumArgNames));
+  ProfileDagInit(
+      ID, Val, ValName, ArrayRef(getTrailingObjects<const Init *>(), NumArgs),
+      ArrayRef(getTrailingObjects<const StringInit *>(), NumArgNames));
 }
 
 const Record *DagInit::getOperatorAsDef(ArrayRef<SMLoc> Loc) const {
-  if (DefInit *DefI = dyn_cast<DefInit>(Val))
+  if (const DefInit *DefI = dyn_cast<DefInit>(Val))
     return DefI->getDef();
   PrintFatalError(Loc, "Expected record as operator");
   return nullptr;
@@ -2665,28 +2683,28 @@ const Record *DagInit::getOperatorAsDef(ArrayRef<SMLoc> Loc) const {
 
 std::optional<unsigned> DagInit::getArgNo(StringRef Name) const {
   for (unsigned i = 0, e = getNumArgs(); i < e; ++i) {
-    StringInit *ArgName = getArgName(i);
+    const StringInit *ArgName = getArgName(i);
     if (ArgName && ArgName->getValue() == Name)
       return i;
   }
   return std::nullopt;
 }
 
-Init *DagInit::resolveReferences(Resolver &R) const {
-  SmallVector<Init*, 8> NewArgs;
+const Init *DagInit::resolveReferences(Resolver &R) const {
+  SmallVector<const Init *, 8> NewArgs;
   NewArgs.reserve(arg_size());
   bool ArgsChanged = false;
   for (const Init *Arg : getArgs()) {
-    Init *NewArg = Arg->resolveReferences(R);
+    const Init *NewArg = Arg->resolveReferences(R);
     NewArgs.push_back(NewArg);
     ArgsChanged |= NewArg != Arg;
   }
 
-  Init *Op = Val->resolveReferences(R);
+  const Init *Op = Val->resolveReferences(R);
   if (Op != Val || ArgsChanged)
     return DagInit::get(Op, ValName, NewArgs, getArgNames());
 
-  return const_cast<DagInit *>(this);
+  return this;
 }
 
 bool DagInit::isConcrete() const {
@@ -2718,7 +2736,7 @@ std::string DagInit::getAsString() const {
 //    Other implementations
 //===----------------------------------------------------------------------===//
 
-RecordVal::RecordVal(Init *N, const RecTy *T, FieldKind K)
+RecordVal::RecordVal(const Init *N, const RecTy *T, FieldKind K)
     : Name(N), TyAndKind(T, K) {
   setValue(UnsetInit::get(N->getRecordKeeper()));
   assert(Value && "Cannot create unset value for current type!");
@@ -2726,7 +2744,7 @@ RecordVal::RecordVal(Init *N, const RecTy *T, FieldKind K)
 
 // This constructor accepts the same arguments as the above, but also
 // a source location.
-RecordVal::RecordVal(Init *N, SMLoc Loc, const RecTy *T, FieldKind K)
+RecordVal::RecordVal(const Init *N, SMLoc Loc, const RecTy *T, FieldKind K)
     : Name(N), Loc(Loc), TyAndKind(T, K) {
   setValue(UnsetInit::get(N->getRecordKeeper()));
   assert(Value && "Cannot create unset value for current type!");
@@ -2751,7 +2769,7 @@ std::string RecordVal::getPrintType() const {
   }
 }
 
-bool RecordVal::setValue(Init *V) {
+bool RecordVal::setValue(const Init *V) {
   if (V) {
     Value = V->getCastTo(getType());
     if (Value) {
@@ -2759,7 +2777,7 @@ bool RecordVal::setValue(Init *V) {
              cast<TypedInit>(Value)->getType()->typeIsA(getType()));
       if (const BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
         if (!isa<BitsInit>(Value)) {
-          SmallVector<Init *, 64> Bits;
+          SmallVector<const Init *, 64> Bits;
           Bits.reserve(BTy->getNumBits());
           for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
             Bits.push_back(Value->getBit(I));
@@ -2775,7 +2793,7 @@ bool RecordVal::setValue(Init *V) {
 
 // This version of setValue takes a source location and resets the
 // location in the RecordVal.
-bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
+bool RecordVal::setValue(const Init *V, SMLoc NewLoc) {
   Loc = NewLoc;
   if (V) {
     Value = V->getCastTo(getType());
@@ -2784,7 +2802,7 @@ bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
              cast<TypedInit>(Value)->getType()->typeIsA(getType()));
       if (const BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
         if (!isa<BitsInit>(Value)) {
-          SmallVector<Init *, 64> Bits;
+          SmallVector<const Init *, 64> Bits;
           Bits.reserve(BTy->getNumBits());
           for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
             Bits.push_back(Value->getBit(I));
@@ -2847,7 +2865,7 @@ unsigned Record::getNewUID(RecordKeeper &RK) {
   return RK.getImpl().LastRecordID++;
 }
 
-void Record::setName(Init *NewName) {
+void Record::setName(const Init *NewName) {
   Name = NewName;
   checkName();
   // DO NOT resolve record values to the name at this point because
@@ -2893,8 +2911,8 @@ void Record::getDirectSuperClasses(
 }
 
 void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
-  Init *OldName = getNameInit();
-  Init *NewName = Name->resolveReferences(R);
+  const Init *OldName = getNameInit();
+  const Init *NewName = Name->resolveReferences(R);
   if (NewName != OldName) {
     // Re-register with RecordKeeper.
     setName(NewName);
@@ -2904,11 +2922,11 @@ void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
   for (RecordVal &Value : Values) {
     if (SkipVal == &Value) // Skip resolve the same field as the given one
       continue;
-    if (Init *V = Value.getValue()) {
-      Init *VR = V->resolveReferences(R);
+    if (const Init *V = Value.getValue()) {
+      const Init *VR = V->resolveReferences(R);
       if (Value.setValue(VR)) {
         std::string Type;
-        if (TypedInit *VRT = dyn_cast<TypedInit>(VR))
+        if (const TypedInit *VRT = dyn_cast<TypedInit>(VR))
           Type =
               (Twine("of type '") + VRT->getType()->getAsString() + "' ").str();
         PrintFatalError(
@@ -2924,19 +2942,19 @@ void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
 
   // Resolve the assertion expressions.
   for (auto &Assertion : Assertions) {
-    Init *Value = Assertion.Condition->resolveReferences(R);
+    const Init *Value = Assertion.Condition->resolveReferences(R);
     Assertion.Condition = Value;
     Value = Assertion.Message->resolveReferences(R);
     Assertion.Message = Value;
   }
   // Resolve the dump expressions.
   for (auto &Dump : Dumps) {
-    Init *Value = Dump.Message->resolveReferences(R);
+    const Init *Value = Dump.Message->resolveReferences(R);
     Dump.Message = Value;
   }
 }
 
-void Record::resolveReferences(Init *NewName) {
+void Record::resolveReferences(const Init *NewName) {
   RecordResolver R(*this);
   R.setName(NewName);
   R.setFinal(true);
@@ -2950,7 +2968,7 @@ LLVM_DUMP_METHOD void Record::dump() const { errs() << *this; }
 raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
   OS << R.getNameInitAsString();
 
-  ArrayRef<Init *> TArgs = R.getTemplateArgs();
+  ArrayRef<const Init *> TArgs = R.getTemplateArgs();
   if (!TArgs.empty()) {
     OS << "<";
     bool NeedComma = false;
@@ -2991,7 +3009,7 @@ SMLoc Record::getFieldLoc(StringRef FieldName) const {
   return R->getLoc();
 }
 
-Init *Record::getValueInit(StringRef FieldName) const {
+const Init *Record::getValueInit(StringRef FieldName) const {
   const RecordVal *R = getValue(FieldName);
   if (!R || !R->getValue())
     PrintFatalError(getLoc(), "Record `" + getName() +
@@ -3015,7 +3033,7 @@ Record::getValueAsOptionalString(StringRef FieldName) const {
   if (isa<UnsetInit>(R->getValue()))
     return std::nullopt;
 
-  if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
+  if (const StringInit *SI = dyn_cast<StringInit>(R->getValue()))
     return SI->getValue();
 
   PrintFatalError(getLoc(),
@@ -3023,25 +3041,25 @@ Record::getValueAsOptionalString(StringRef FieldName) const {
                       "' exists but does not have a string initializer!");
 }
 
-BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
+const BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
   const RecordVal *R = getValue(FieldName);
   if (!R || !R->getValue())
     PrintFatalError(getLoc(), "Record `" + getName() +
       "' does not have a field named `" + FieldName + "'!\n");
 
-  if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
+  if (const BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
     return BI;
   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
                                 "' exists but does not have a bits value");
 }
 
-ListInit *Record::getValueAsListInit(StringRef FieldName) const {
+const ListInit *Record::getValueAsListInit(StringRef FieldName) const {
   const RecordVal *R = getValue(FieldName);
   if (!R || !R->getValue())
     PrintFatalError(getLoc(), "Record `" + getName() +
       "' does not have a field named `" + FieldName + "'!\n");
 
-  if (ListInit *LI = dyn_cast<ListInit>(R->getValue()))
+  if (const ListInit *LI = dyn_cast<ListInit>(R->getValue()))
     return LI;
   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
                                 "' exists but does not have a list value");
@@ -3049,7 +3067,7 @@ ListInit *Record::getValueAsListInit(StringRef FieldName) const {
 
 std::vector<const Record *>
 Record::getValueAsListOfDefs(StringRef FieldName) const {
-  ListInit *List = getValueAsListInit(FieldName);
+  const ListInit *List = getValueAsListInit(FieldName);
   std::vector<const Record *> Defs;
   for (const Init *I : List->getValues()) {
     if (const DefInit *DI = dyn_cast<DefInit>(I))
@@ -3068,7 +3086,7 @@ int64_t Record::getValueAsInt(StringRef FieldName) const {
     PrintFatalError(getLoc(), "Record `" + getName() +
       "' does not have a field named `" + FieldName + "'!\n");
 
-  if (IntInit *II = dyn_cast<IntInit>(R->getValue()))
+  if (const IntInit *II = dyn_cast<IntInit>(R->getValue()))
     return II->getValue();
   PrintFatalError(getLoc(), Twine("Record `") + getName() + "', field `" +
                                 FieldName +
@@ -3078,10 +3096,10 @@ int64_t Record::getValueAsInt(StringRef FieldName) const {
 
 std::vector<int64_t>
 Record::getValueAsListOfInts(StringRef FieldName) const {
-  ListInit *List = getValueAsListInit(FieldName);
+  const ListInit *List = getValueAsListInit(FieldName);
   std::vector<int64_t> Ints;
-  for (Init *I : List->getValues()) {
-    if (IntInit *II = dyn_cast<IntInit>(I))
+  for (const Init *I : List->getValues()) {
+    if (const IntInit *II = dyn_cast<IntInit>(I))
       Ints.push_back(II->getValue());
     else
       PrintFatalError(getLoc(),
@@ -3094,10 +3112,10 @@ Record::getValueAsListOfInts(StringRef FieldName) const {
 
 std::vector<StringRef>
 Record::getValueAsListOfStrings(StringRef FieldName) const {
-  ListInit *List = getValueAsListInit(FieldName);
+  const ListInit *List = getValueAsListInit(FieldName);
   std::vector<StringRef> Strings;
-  for (Init *I : List->getValues()) {
-    if (StringInit *SI = dyn_cast<StringInit>(I))
+  for (const Init *I : List->getValues()) {
+    if (const StringInit *SI = dyn_cast<StringInit>(I))
       Strings.push_back(SI->getValue());
     else
       PrintFatalError(getLoc(),
@@ -3114,7 +3132,7 @@ const Record *Record::getValueAsDef(StringRef FieldName) const {
     PrintFatalError(getLoc(), "Record `" + getName() +
       "' does not have a field named `" + FieldName + "'!\n");
 
-  if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
+  if (const DefInit *DI = dyn_cast<DefInit>(R->getValue()))
     return DI->getDef();
   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
     FieldName + "' does not have a def initializer!");
@@ -3126,7 +3144,7 @@ const Record *Record::getValueAsOptionalDef(StringRef FieldName) const {
     PrintFatalError(getLoc(), "Record `" + getName() +
       "' does not have a field named `" + FieldName + "'!\n");
 
-  if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
+  if (const DefInit *DI = dyn_cast<DefInit>(R->getValue()))
     return DI->getDef();
   if (isa<UnsetInit>(R->getValue()))
     return nullptr;
@@ -3140,7 +3158,7 @@ bool Record::getValueAsBit(StringRef FieldName) const {
     PrintFatalError(getLoc(), "Record `" + getName() +
       "' does not have a field named `" + FieldName + "'!\n");
 
-  if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
+  if (const BitInit *BI = dyn_cast<BitInit>(R->getValue()))
     return BI->getValue();
   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
     FieldName + "' does not have a bit initializer!");
@@ -3157,19 +3175,19 @@ bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
     return false;
   }
   Unset = false;
-  if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
+  if (const BitInit *BI = dyn_cast<BitInit>(R->getValue()))
     return BI->getValue();
   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
     FieldName + "' does not have a bit initializer!");
 }
 
-DagInit *Record::getValueAsDag(StringRef FieldName) const {
+const DagInit *Record::getValueAsDag(StringRef FieldName) const {
   const RecordVal *R = getValue(FieldName);
   if (!R || !R->getValue())
     PrintFatalError(getLoc(), "Record `" + getName() +
       "' does not have a field named `" + FieldName + "'!\n");
 
-  if (DagInit *DI = dyn_cast<DagInit>(R->getValue()))
+  if (const DagInit *DI = dyn_cast<DagInit>(R->getValue()))
     return DI;
   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
     FieldName + "' does not have a dag initializer!");
@@ -3185,8 +3203,8 @@ void Record::checkRecordAssertions() {
 
   bool AnyFailed = false;
   for (const auto &Assertion : getAssertions()) {
-    Init *Condition = Assertion.Condition->resolveReferences(R);
-    Init *Message = Assertion.Message->resolveReferences(R);
+    const Init *Condition = Assertion.Condition->resolveReferences(R);
+    const Init *Message = Assertion.Message->resolveReferences(R);
     AnyFailed |= CheckAssert(Assertion.Loc, Condition, Message);
   }
 
@@ -3203,7 +3221,7 @@ void Record::emitRecordDumps() {
   R.setFinal(true);
 
   for (const auto &Dump : getDumps()) {
-    Init *Message = Dump.Message->resolveReferences(R);
+    const Init *Message = Dump.Message->resolveReferences(R);
     dumpMessage(Dump.Loc, Message);
   }
 }
@@ -3241,7 +3259,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
 
 /// GetNewAnonymousName - Generate a unique anonymous name that can be used as
 /// an identifier.
-Init *RecordKeeper::getNewAnonymousName() {
+const Init *RecordKeeper::getNewAnonymousName() {
   return AnonymousNameInit::get(*this, getImpl().AnonCounter++);
 }
 
@@ -3289,12 +3307,12 @@ void RecordKeeper::dumpAllocationStats(raw_ostream &OS) const {
   Impl->dumpAllocationStats(OS);
 }
 
-Init *MapResolver::resolve(Init *VarName) {
+const Init *MapResolver::resolve(const Init *VarName) {
   auto It = Map.find(VarName);
   if (It == Map.end())
     return nullptr;
 
-  Init *I = It->second.V;
+  const Init *I = It->second.V;
 
   if (!It->second.Resolved && Map.size() > 1) {
     // Resolve mutual references among the mapped variables, but prevent
@@ -3307,15 +3325,15 @@ Init *MapResolver::resolve(Init *VarName) {
   return I;
 }
 
-Init *RecordResolver::resolve(Init *VarName) {
-  Init *Val = Cache.lookup(VarName);
+const Init *RecordResolver::resolve(const Init *VarName) {
+  const Init *Val = Cache.lookup(VarName);
   if (Val)
     return Val;
 
   if (llvm::is_contained(Stack, VarName))
     return nullptr; // prevent infinite recursion
 
-  if (RecordVal *RV = getCurrentRecord()->getValue(VarName)) {
+  if (const RecordVal *RV = getCurrentRecord()->getValue(VarName)) {
     if (!isa<UnsetInit>(RV->getValue())) {
       Val = RV->getValue();
       Stack.push_back(VarName);
@@ -3332,8 +3350,8 @@ Init *RecordResolver::resolve(Init *VarName) {
   return Val;
 }
 
-Init *TrackUnresolvedResolver::resolve(Init *VarName) {
-  Init *I = nullptr;
+const Init *TrackUnresolvedResolver::resolve(const Init *VarName) {
+  const Init *I = nullptr;
 
   if (R) {
     I = R->resolve(VarName);
@@ -3352,8 +3370,7 @@ Init *TrackUnresolvedResolver::resolve(Init *VarName) {
   return I;
 }
 
-Init *HasReferenceResolver::resolve(Init *VarName)
-{
+const Init *HasReferenceResolver::resolve(const Init *VarName) {
   if (VarName == VarNameToTrack)
     Found = true;
   return nullptr;

diff  --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index aed4f3fe0e96b5..97a7e680e0c339 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -35,7 +35,7 @@ namespace llvm {
 struct SubClassReference {
   SMRange RefRange;
   Record *Rec = nullptr;
-  SmallVector<ArgumentInit *, 4> TemplateArgs;
+  SmallVector<const ArgumentInit *, 4> TemplateArgs;
 
   SubClassReference() = default;
 
@@ -45,7 +45,7 @@ struct SubClassReference {
 struct SubMultiClassReference {
   SMRange RefRange;
   MultiClass *MC = nullptr;
-  SmallVector<ArgumentInit *, 4> TemplateArgs;
+  SmallVector<const ArgumentInit *, 4> TemplateArgs;
 
   SubMultiClassReference() = default;
 
@@ -60,7 +60,7 @@ LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {
   MC->dump();
 
   errs() << "Template args:\n";
-  for (Init *TA : TemplateArgs)
+  for (const Init *TA : TemplateArgs)
     TA->dump();
 }
 #endif
@@ -68,9 +68,9 @@ LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {
 } // end namespace llvm
 
 static bool checkBitsConcrete(Record &R, const RecordVal &RV) {
-  BitsInit *BV = cast<BitsInit>(RV.getValue());
+  const BitsInit *BV = cast<BitsInit>(RV.getValue());
   for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
-    Init *Bit = BV->getBit(i);
+    const Init *Bit = BV->getBit(i);
     bool IsReference = false;
     if (auto VBI = dyn_cast<VarBitInit>(Bit)) {
       if (auto VI = dyn_cast<VarInit>(VBI->getBitVar())) {
@@ -95,7 +95,7 @@ static void checkConcrete(Record &R) {
     if (RV.isNonconcreteOK())
       continue;
 
-    if (Init *V = RV.getValue()) {
+    if (const Init *V = RV.getValue()) {
       bool Ok = isa<BitsInit>(V) ? checkBitsConcrete(R, RV) : V->isConcrete();
       if (!Ok) {
         PrintError(R.getLoc(),
@@ -110,43 +110,45 @@ static void checkConcrete(Record &R) {
 
 /// Return an Init with a qualifier prefix referring
 /// to CurRec's name.
-static Init *QualifyName(Record &CurRec, Init *Name) {
+static const Init *QualifyName(Record &CurRec, const Init *Name) {
   RecordKeeper &RK = CurRec.getRecords();
-  Init *NewName = BinOpInit::getStrConcat(
+  const Init *NewName = BinOpInit::getStrConcat(
       CurRec.getNameInit(),
       StringInit::get(RK, CurRec.isMultiClass() ? "::" : ":"));
   NewName = BinOpInit::getStrConcat(NewName, Name);
 
-  if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
+  if (const BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
     NewName = BinOp->Fold(&CurRec);
   return NewName;
 }
 
-static Init *QualifyName(MultiClass *MC, Init *Name) {
+static const Init *QualifyName(MultiClass *MC, const Init *Name) {
   return QualifyName(MC->Rec, Name);
 }
 
 /// Return the qualified version of the implicit 'NAME' template argument.
-static Init *QualifiedNameOfImplicitName(Record &Rec) {
+static const Init *QualifiedNameOfImplicitName(Record &Rec) {
   return QualifyName(Rec, StringInit::get(Rec.getRecords(), "NAME"));
 }
 
-static Init *QualifiedNameOfImplicitName(MultiClass *MC) {
+static const Init *QualifiedNameOfImplicitName(MultiClass *MC) {
   return QualifiedNameOfImplicitName(MC->Rec);
 }
 
-Init *TGVarScope::getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass,
-                         StringInit *Name, SMRange NameLoc,
-                         bool TrackReferenceLocs) const {
+const Init *TGVarScope::getVar(RecordKeeper &Records,
+                               MultiClass *ParsingMultiClass,
+                               const StringInit *Name, SMRange NameLoc,
+                               bool TrackReferenceLocs) const {
   // First, we search in local variables.
   auto It = Vars.find(Name->getValue());
   if (It != Vars.end())
     return It->second;
 
-  auto FindValueInArgs = [&](Record *Rec, StringInit *Name) -> Init * {
+  auto FindValueInArgs = [&](Record *Rec,
+                             const StringInit *Name) -> const Init * {
     if (!Rec)
       return nullptr;
-    Init *ArgName = QualifyName(*Rec, Name);
+    const Init *ArgName = QualifyName(*Rec, Name);
     if (Rec->isTemplateArg(ArgName)) {
       RecordVal *RV = Rec->getValue(ArgName);
       assert(RV && "Template arg doesn't exist??");
@@ -184,7 +186,7 @@ Init *TGVarScope::getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass,
   case SK_ForeachLoop: {
     // The variable is a loop iterator?
     if (CurLoop->IterVar) {
-      VarInit *IterVar = dyn_cast<VarInit>(CurLoop->IterVar);
+      const VarInit *IterVar = dyn_cast<VarInit>(CurLoop->IterVar);
       if (IterVar && IterVar->getNameInit() == Name)
         return IterVar;
     }
@@ -226,8 +228,8 @@ bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
 
 /// SetValue -
 /// Return true on error, false on success.
-bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
-                        ArrayRef<unsigned> BitList, Init *V,
+bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const Init *ValName,
+                        ArrayRef<unsigned> BitList, const Init *V,
                         bool AllowSelfAssignment, bool OverrideDefLoc) {
   if (!V) return false;
 
@@ -241,7 +243,7 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
   // Do not allow assignments like 'X = X'.  This will just cause infinite loops
   // in the resolution machinery.
   if (BitList.empty())
-    if (VarInit *VI = dyn_cast<VarInit>(V))
+    if (const VarInit *VI = dyn_cast<VarInit>(V))
       if (VI->getNameInit() == ValName && !AllowSelfAssignment)
         return Error(Loc, "Recursion / self-assignment forbidden");
 
@@ -250,17 +252,17 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
   // initializer.
   //
   if (!BitList.empty()) {
-    BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue());
+    const BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue());
     if (!CurVal)
       return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
                    "' is not a bits type");
 
     // Convert the incoming value to a bits type of the appropriate size...
-    Init *BI = V->getCastTo(BitsRecTy::get(Records, BitList.size()));
+    const Init *BI = V->getCastTo(BitsRecTy::get(Records, BitList.size()));
     if (!BI)
       return Error(Loc, "Initializer is not compatible with bit range");
 
-    SmallVector<Init *, 16> NewBits(CurVal->getNumBits());
+    SmallVector<const Init *, 16> NewBits(CurVal->getNumBits());
 
     // Loop over bits, assigning values as appropriate.
     for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
@@ -280,10 +282,10 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
 
   if (OverrideDefLoc ? RV->setValue(V, Loc) : RV->setValue(V)) {
     std::string InitType;
-    if (BitsInit *BI = dyn_cast<BitsInit>(V))
+    if (const BitsInit *BI = dyn_cast<BitsInit>(V))
       InitType = (Twine("' of type bit initializer with length ") +
                   Twine(BI->getNumBits())).str();
-    else if (TypedInit *TI = dyn_cast<TypedInit>(V))
+    else if (const TypedInit *TI = dyn_cast<TypedInit>(V))
       InitType = (Twine("' of type '") + TI->getType()->getAsString()).str();
     return Error(Loc, "Field '" + ValName->getAsUnquotedString() +
                           "' of type '" + RV->getType()->getAsString() +
@@ -316,7 +318,7 @@ bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
   // Copy the subclass record's dumps to the new record.
   CurRec->appendDumps(SC);
 
-  Init *Name;
+  const Init *Name;
   if (CurRec->isClass())
     Name = VarInit::get(QualifiedNameOfImplicitName(*CurRec),
                         StringRecTy::get(Records));
@@ -427,7 +429,7 @@ bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs,
   MapResolver R;
   for (const auto &S : Substs)
     R.set(S.first, S.second);
-  Init *List = Loop.ListValue->resolveReferences(R);
+  const Init *List = Loop.ListValue->resolveReferences(R);
 
   // For if-then-else blocks, we lower to a foreach loop whose list is a
   // ternary selection between lists of 
diff erent length.  Since we don't
@@ -437,17 +439,17 @@ bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs,
   // e.g. !if(!exists<SchedWrite>("__does_not_exist__"), [1], [])
   if (auto *TI = dyn_cast<TernOpInit>(List);
       TI && TI->getOpcode() == TernOpInit::IF && Final) {
-    Init *OldLHS = TI->getLHS();
+    const Init *OldLHS = TI->getLHS();
     R.setFinal(true);
-    Init *LHS = OldLHS->resolveReferences(R);
+    const Init *LHS = OldLHS->resolveReferences(R);
     if (LHS == OldLHS) {
       PrintError(Loop.Loc,
                  Twine("unable to resolve if condition '") +
                  LHS->getAsString() + "' at end of containing scope");
       return true;
     }
-    Init *MHS = TI->getMHS();
-    Init *RHS = TI->getRHS();
+    const Init *MHS = TI->getMHS();
+    const Init *RHS = TI->getRHS();
     List = TernOpInit::get(TernOpInit::IF, LHS, MHS, RHS, TI->getType())
       ->Fold(nullptr);
   }
@@ -496,8 +498,8 @@ bool TGParser::resolve(const std::vector<RecordsEntry> &Source,
       MapResolver R;
       for (const auto &S : Substs)
         R.set(S.first, S.second);
-      Init *Condition = E.Assertion->Condition->resolveReferences(R);
-      Init *Message = E.Assertion->Message->resolveReferences(R);
+      const Init *Condition = E.Assertion->Condition->resolveReferences(R);
+      const Init *Message = E.Assertion->Message->resolveReferences(R);
 
       if (Dest)
         Dest->push_back(std::make_unique<Record::AssertionInfo>(
@@ -509,7 +511,7 @@ bool TGParser::resolve(const std::vector<RecordsEntry> &Source,
       MapResolver R;
       for (const auto &S : Substs)
         R.set(S.first, S.second);
-      Init *Message = E.Dump->Message->resolveReferences(R);
+      const Init *Message = E.Dump->Message->resolveReferences(R);
 
       if (Dest)
         Dest->push_back(
@@ -540,7 +542,7 @@ bool TGParser::resolve(const std::vector<RecordsEntry> &Source,
 
 /// Resolve the record fully and add it to the record keeper.
 bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
-  Init *NewName = nullptr;
+  const Init *NewName = nullptr;
   if (const Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
     if (!Rec->isAnonymous()) {
       PrintError(Rec->getLoc(),
@@ -586,17 +588,18 @@ bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
   return false;
 }
 
-bool TGParser::resolveArguments(Record *Rec, ArrayRef<ArgumentInit *> ArgValues,
+bool TGParser::resolveArguments(Record *Rec,
+                                ArrayRef<const ArgumentInit *> ArgValues,
                                 SMLoc Loc, ArgValueHandler ArgValueHandler) {
-  ArrayRef<Init *> ArgNames = Rec->getTemplateArgs();
+  ArrayRef<const Init *> ArgNames = Rec->getTemplateArgs();
   assert(ArgValues.size() <= ArgNames.size() &&
          "Too many template arguments allowed");
 
   // Loop over the template arguments and handle the (name, value) pair.
-  SmallVector<Init *, 2> UnsolvedArgNames(ArgNames);
+  SmallVector<const Init *, 2> UnsolvedArgNames(ArgNames);
   for (auto *Arg : ArgValues) {
-    Init *ArgName = nullptr;
-    Init *ArgValue = Arg->getValue();
+    const Init *ArgName = nullptr;
+    const Init *ArgValue = Arg->getValue();
     if (Arg->isPositional())
       ArgName = ArgNames[Arg->getIndex()];
     if (Arg->isNamed())
@@ -613,7 +616,7 @@ bool TGParser::resolveArguments(Record *Rec, ArrayRef<ArgumentInit *> ArgValues,
 
   // For unsolved arguments, if there is no default value, complain.
   for (auto *UnsolvedArgName : UnsolvedArgNames) {
-    Init *Default = Rec->getValue(UnsolvedArgName)->getValue();
+    const Init *Default = Rec->getValue(UnsolvedArgName)->getValue();
     if (!Default->isComplete()) {
       std::string Name = UnsolvedArgName->getAsUnquotedString();
       Error(Loc, "value not specified for template argument '" + Name + "'");
@@ -630,22 +633,24 @@ bool TGParser::resolveArguments(Record *Rec, ArrayRef<ArgumentInit *> ArgValues,
 /// Resolve the arguments of class and set them to MapResolver.
 /// Returns true if failed.
 bool TGParser::resolveArgumentsOfClass(MapResolver &R, Record *Rec,
-                                       ArrayRef<ArgumentInit *> ArgValues,
+                                       ArrayRef<const ArgumentInit *> ArgValues,
                                        SMLoc Loc) {
-  return resolveArguments(Rec, ArgValues, Loc,
-                          [&](Init *Name, Init *Value) { R.set(Name, Value); });
+  return resolveArguments(
+      Rec, ArgValues, Loc,
+      [&](const Init *Name, const Init *Value) { R.set(Name, Value); });
 }
 
 /// Resolve the arguments of multiclass and store them into SubstStack.
 /// Returns true if failed.
-bool TGParser::resolveArgumentsOfMultiClass(SubstStack &Substs, MultiClass *MC,
-                                            ArrayRef<ArgumentInit *> ArgValues,
-                                            Init *DefmName, SMLoc Loc) {
+bool TGParser::resolveArgumentsOfMultiClass(
+    SubstStack &Substs, MultiClass *MC,
+    ArrayRef<const ArgumentInit *> ArgValues, const Init *DefmName, SMLoc Loc) {
   // Add an implicit argument NAME.
   Substs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName);
-  return resolveArguments(
-      &MC->Rec, ArgValues, Loc,
-      [&](Init *Name, Init *Value) { Substs.emplace_back(Name, Value); });
+  return resolveArguments(&MC->Rec, ArgValues, Loc,
+                          [&](const Init *Name, const Init *Value) {
+                            Substs.emplace_back(Name, Value);
+                          });
 }
 
 //===----------------------------------------------------------------------===//
@@ -666,7 +671,7 @@ bool TGParser::consume(tgtok::TokKind K) {
 ///   ObjectName ::= Value [ '#' Value ]*
 ///   ObjectName ::= /*empty*/
 ///
-Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
+const Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
   switch (Lex.getCode()) {
   case tgtok::colon:
   case tgtok::semi:
@@ -683,12 +688,13 @@ Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
   if (CurMultiClass)
     CurRec = &CurMultiClass->Rec;
 
-  Init *Name = ParseValue(CurRec, StringRecTy::get(Records), ParseNameMode);
+  const Init *Name =
+      ParseValue(CurRec, StringRecTy::get(Records), ParseNameMode);
   if (!Name)
     return nullptr;
 
   if (CurMultiClass) {
-    Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass);
+    const Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass);
     HasReferenceResolver R(NameStr);
     Name->resolveReferences(R);
     if (!R.found())
@@ -827,14 +833,14 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
 ///
 /// SliceElement is either IntRecTy, ListRecTy, or nullptr
 ///
-TypedInit *TGParser::ParseSliceElement(Record *CurRec) {
+const TypedInit *TGParser::ParseSliceElement(Record *CurRec) {
   auto LHSLoc = Lex.getLoc();
   auto *CurVal = ParseValue(CurRec);
   if (!CurVal)
     return nullptr;
   auto *LHS = cast<TypedInit>(CurVal);
 
-  TypedInit *RHS = nullptr;
+  const TypedInit *RHS = nullptr;
   switch (Lex.getCode()) {
   case tgtok::dotdotdot:
   case tgtok::minus: { // Deprecated
@@ -891,10 +897,10 @@ TypedInit *TGParser::ParseSliceElement(Record *CurRec) {
 ///  - Single=true
 ///  - SliceElements is Value<int> w/o trailing comma
 ///
-TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
-  TypedInit *CurVal;
-  SmallVector<Init *, 2> Elems;       // int
-  SmallVector<TypedInit *, 2> Slices; // list<int>
+const TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
+  const TypedInit *CurVal;
+  SmallVector<const Init *, 2> Elems;       // int
+  SmallVector<const TypedInit *, 2> Slices; // list<int>
 
   auto FlushElems = [&] {
     if (!Elems.empty()) {
@@ -950,7 +956,7 @@ TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
   FlushElems();
 
   // Concatenate lists in Slices
-  TypedInit *Result = nullptr;
+  const TypedInit *Result = nullptr;
   for (auto *Slice : Slices) {
     Result = (Result ? cast<TypedInit>(BinOpInit::getListConcat(Result, Slice))
                      : Slice);
@@ -966,12 +972,12 @@ TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
 ///   RangePiece ::= INTVAL INTVAL 
 // The last two forms are deprecated.
 bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
-                               TypedInit *FirstItem) {
-  Init *CurVal = FirstItem;
+                               const TypedInit *FirstItem) {
+  const Init *CurVal = FirstItem;
   if (!CurVal)
     CurVal = ParseValue(nullptr);
 
-  IntInit *II = dyn_cast_or_null<IntInit>(CurVal);
+  const IntInit *II = dyn_cast_or_null<IntInit>(CurVal);
   if (!II)
     return TokError("expected integer or bitrange");
 
@@ -990,8 +996,8 @@ bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
   case tgtok::minus: {
     Lex.Lex(); // eat
 
-    Init *I_End = ParseValue(nullptr);
-    IntInit *II_End = dyn_cast_or_null<IntInit>(I_End);
+    const Init *I_End = ParseValue(nullptr);
+    const IntInit *II_End = dyn_cast_or_null<IntInit>(I_End);
     if (!II_End) {
       TokError("expected integer value as end of range");
       return true;
@@ -1149,16 +1155,16 @@ const RecTy *TGParser::ParseType() {
 }
 
 /// ParseIDValue
-Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMRange NameLoc,
-                             IDParseMode Mode) {
-  if (Init *I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
-                                 TrackReferenceLocs))
+const Init *TGParser::ParseIDValue(Record *CurRec, const StringInit *Name,
+                                   SMRange NameLoc, IDParseMode Mode) {
+  if (const Init *I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
+                                       TrackReferenceLocs))
     return I;
 
   if (Mode == ParseNameMode)
     return Name;
 
-  if (Init *I = Records.getGlobal(Name->getValue())) {
+  if (const Init *I = Records.getGlobal(Name->getValue())) {
     // Add a reference to the global if it's a record.
     if (TrackReferenceLocs) {
       if (auto *Def = dyn_cast<DefInit>(I))
@@ -1181,7 +1187,7 @@ Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMRange NameLoc,
 ///
 /// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
 ///
-Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
+const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
   switch (Lex.getCode()) {
   default:
     TokError("unknown bang operator");
@@ -1291,14 +1297,14 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *LHS = ParseValue(CurRec);
+    const Init *LHS = ParseValue(CurRec);
     if (!LHS) return nullptr;
 
     if (Code == UnOpInit::EMPTY || Code == UnOpInit::SIZE) {
-      ListInit *LHSl = dyn_cast<ListInit>(LHS);
-      StringInit *LHSs = dyn_cast<StringInit>(LHS);
-      DagInit *LHSd = dyn_cast<DagInit>(LHS);
-      TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
+      const ListInit *LHSl = dyn_cast<ListInit>(LHS);
+      const StringInit *LHSs = dyn_cast<StringInit>(LHS);
+      const DagInit *LHSd = dyn_cast<DagInit>(LHS);
+      const TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
       if (!LHSl && !LHSs && !LHSd && !LHSt) {
         TokError("expected string, list, or dag type argument in unary operator");
         return nullptr;
@@ -1313,8 +1319,8 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
 
     if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL ||
         Code == UnOpInit::LISTFLATTEN) {
-      ListInit *LHSl = dyn_cast<ListInit>(LHS);
-      TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
+      const ListInit *LHSl = dyn_cast<ListInit>(LHS);
+      const TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
       if (!LHSl && !LHSt) {
         TokError("expected list type argument in unary operator");
         return nullptr;
@@ -1333,8 +1339,8 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       bool UseElementType =
           Code == UnOpInit::HEAD || Code == UnOpInit::LISTFLATTEN;
       if (LHSl) {
-        Init *Item = LHSl->getElement(0);
-        TypedInit *Itemt = dyn_cast<TypedInit>(Item);
+        const Init *Item = LHSl->getElement(0);
+        const TypedInit *Itemt = dyn_cast<TypedInit>(Item);
         if (!Itemt) {
           TokError("untyped list element in unary operator");
           return nullptr;
@@ -1381,7 +1387,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *LHS = ParseValue(CurRec);
+    const Init *LHS = ParseValue(CurRec);
     if (!LHS)
       return nullptr;
 
@@ -1390,7 +1396,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    return (IsAOpInit::get(Type, LHS))->Fold();
+    return IsAOpInit::get(Type, LHS)->Fold();
   }
 
   case tgtok::XExists: {
@@ -1407,11 +1413,11 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
     }
 
     SMLoc ExprLoc = Lex.getLoc();
-    Init *Expr = ParseValue(CurRec);
+    const Init *Expr = ParseValue(CurRec);
     if (!Expr)
       return nullptr;
 
-    TypedInit *ExprType = dyn_cast<TypedInit>(Expr);
+    const TypedInit *ExprType = dyn_cast<TypedInit>(Expr);
     if (!ExprType) {
       Error(ExprLoc, "expected string type argument in !exists operator");
       return nullptr;
@@ -1580,7 +1586,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    SmallVector<Init*, 2> InitList;
+    SmallVector<const Init *, 2> InitList;
 
     // Note that this loop consumes an arbitrary number of arguments.
     // The actual count is checked later.
@@ -1589,7 +1595,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       InitList.push_back(ParseValue(CurRec, ArgType));
       if (!InitList.back()) return nullptr;
 
-      TypedInit *InitListBack = dyn_cast<TypedInit>(InitList.back());
+      const TypedInit *InitListBack = dyn_cast<TypedInit>(InitList.back());
       if (!InitListBack) {
         Error(OpLoc, Twine("expected value to be a typed value, got '" +
                            InitList.back()->getAsString() + "'"));
@@ -1759,7 +1765,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
         Code == BinOpInit::AND || Code == BinOpInit::OR ||
         Code == BinOpInit::XOR || Code == BinOpInit::MUL) {
       while (InitList.size() > 2) {
-        Init *RHS = InitList.pop_back_val();
+        const Init *RHS = InitList.pop_back_val();
         RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec);
         InitList.back() = RHS;
       }
@@ -1787,7 +1793,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    SmallVector<Init *, 2> Args;
+    SmallVector<const Init *, 2> Args;
     bool FirstArgIsList = false;
     for (;;) {
       if (Args.size() >= 3) {
@@ -1800,7 +1806,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       if (!Args.back())
         return nullptr;
 
-      TypedInit *ArgBack = dyn_cast<TypedInit>(Args.back());
+      const TypedInit *ArgBack = dyn_cast<TypedInit>(Args.back());
       if (!ArgBack) {
         Error(OpLoc, Twine("expected value to be a typed value, got '" +
                            Args.back()->getAsString() + "'"));
@@ -1838,7 +1844,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *LHS, *MHS, *RHS;
+    const Init *LHS, *MHS, *RHS;
     auto ArgCount = Args.size();
     assert(ArgCount >= 1);
     auto *Arg0 = cast<TypedInit>(Args[0]);
@@ -1916,7 +1922,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *LHS = ParseValue(CurRec);
+    const Init *LHS = ParseValue(CurRec);
     if (!LHS) return nullptr;
 
     if (!consume(tgtok::comma)) {
@@ -1925,7 +1931,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
     }
 
     SMLoc MHSLoc = Lex.getLoc();
-    Init *MHS = ParseValue(CurRec, ItemType);
+    const Init *MHS = ParseValue(CurRec, ItemType);
     if (!MHS)
       return nullptr;
 
@@ -1935,7 +1941,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
     }
 
     SMLoc RHSLoc = Lex.getLoc();
-    Init *RHS = ParseValue(CurRec, ItemType);
+    const Init *RHS = ParseValue(CurRec, ItemType);
     if (!RHS)
       return nullptr;
 
@@ -1947,7 +1953,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
     switch (LexCode) {
     default: llvm_unreachable("Unhandled code!");
     case tgtok::XDag: {
-      TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+      const TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
       if (!MHSt && !isa<UnsetInit>(MHS)) {
         Error(MHSLoc, "could not determine type of the child list in !dag");
         return nullptr;
@@ -1958,7 +1964,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
         return nullptr;
       }
 
-      TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+      const TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
       if (!RHSt && !isa<UnsetInit>(RHS)) {
         Error(RHSLoc, "could not determine type of the name list in !dag");
         return nullptr;
@@ -1980,16 +1986,16 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       const RecTy *MHSTy = nullptr;
       const RecTy *RHSTy = nullptr;
 
-      if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
+      if (const TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
         MHSTy = MHSt->getType();
-      if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS))
+      if (const BitsInit *MHSbits = dyn_cast<BitsInit>(MHS))
         MHSTy = BitsRecTy::get(Records, MHSbits->getNumBits());
       if (isa<BitInit>(MHS))
         MHSTy = BitRecTy::get(Records);
 
-      if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS))
+      if (const TypedInit *RHSt = dyn_cast<TypedInit>(RHS))
         RHSTy = RHSt->getType();
-      if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS))
+      if (const BitsInit *RHSbits = dyn_cast<BitsInit>(RHS))
         RHSTy = BitsRecTy::get(Records, RHSbits->getNumBits());
       if (isa<BitInit>(RHS))
         RHSTy = BitRecTy::get(Records);
@@ -2014,7 +2020,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       break;
     }
     case tgtok::XSubst: {
-      TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+      const TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
       if (!RHSt) {
         TokError("could not get type for !subst");
         return nullptr;
@@ -2023,7 +2029,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       break;
     }
     case tgtok::XSetDagArg: {
-      TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+      const TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
       if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
         Error(MHSLoc, Twine("expected integer index or string name, got ") +
                           (MHSt ? ("type '" + MHSt->getType()->getAsString())
@@ -2034,7 +2040,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       break;
     }
     case tgtok::XSetDagName: {
-      TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+      const TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
       if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
         Error(MHSLoc, Twine("expected integer index or string name, got ") +
                           (MHSt ? ("type '" + MHSt->getType()->getAsString())
@@ -2042,7 +2048,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
                           "'");
         return nullptr;
       }
-      TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+      const TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
       // The name could be a string or unset.
       if (RHSt && !isa<StringRecTy>(RHSt->getType())) {
         Error(RHSLoc, Twine("expected string or unset name, got type '") +
@@ -2072,11 +2078,11 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *StartUntyped = ParseValue(CurRec);
+    const Init *StartUntyped = ParseValue(CurRec);
     if (!StartUntyped)
       return nullptr;
 
-    TypedInit *Start = dyn_cast<TypedInit>(StartUntyped);
+    const TypedInit *Start = dyn_cast<TypedInit>(StartUntyped);
     if (!Start) {
       TokError(Twine("could not get type of !foldl start: '") +
                StartUntyped->getAsString() + "'");
@@ -2088,11 +2094,11 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *ListUntyped = ParseValue(CurRec);
+    const Init *ListUntyped = ParseValue(CurRec);
     if (!ListUntyped)
       return nullptr;
 
-    TypedInit *List = dyn_cast<TypedInit>(ListUntyped);
+    const TypedInit *List = dyn_cast<TypedInit>(ListUntyped);
     if (!List) {
       TokError(Twine("could not get type of !foldl list: '") +
                ListUntyped->getAsString() + "'");
@@ -2116,7 +2122,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *A = StringInit::get(Records, Lex.getCurStrVal());
+    const Init *A = StringInit::get(Records, Lex.getCurStrVal());
     if (CurRec && CurRec->getValue(A)) {
       TokError((Twine("left !foldl variable '") + A->getAsString() +
                 "' already defined")
@@ -2134,7 +2140,7 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
       return nullptr;
     }
 
-    Init *B = StringInit::get(Records, Lex.getCurStrVal());
+    const Init *B = StringInit::get(Records, Lex.getCurStrVal());
     if (CurRec && CurRec->getValue(B)) {
       TokError((Twine("right !foldl variable '") + B->getAsString() +
                 "' already defined")
@@ -2161,14 +2167,14 @@ Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
     ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal));
     ParseRec->addValue(
         RecordVal(B, ListType->getElementType(), RecordVal::FK_Normal));
-    Init *ExprUntyped = ParseValue(ParseRec);
+    const Init *ExprUntyped = ParseValue(ParseRec);
     ParseRec->removeValue(A);
     ParseRec->removeValue(B);
     PopScope(FoldScope);
     if (!ExprUntyped)
       return nullptr;
 
-    TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped);
+    const TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped);
     if (!Expr) {
       TokError("could not get type of !foldl expression");
       return nullptr;
@@ -2226,7 +2232,8 @@ const RecTy *TGParser::ParseOperatorType() {
 /// Parse the !substr operation. Return null on error.
 ///
 /// Substr ::= !substr(string, start-int [, length-int]) => string
-Init *TGParser::ParseOperationSubstr(Record *CurRec, const RecTy *ItemType) {
+const Init *TGParser::ParseOperationSubstr(Record *CurRec,
+                                           const RecTy *ItemType) {
   TernOpInit::TernaryOp Code = TernOpInit::SUBSTR;
   const RecTy *Type = StringRecTy::get(Records);
 
@@ -2237,7 +2244,7 @@ Init *TGParser::ParseOperationSubstr(Record *CurRec, const RecTy *ItemType) {
     return nullptr;
   }
 
-  Init *LHS = ParseValue(CurRec);
+  const Init *LHS = ParseValue(CurRec);
   if (!LHS)
     return nullptr;
 
@@ -2247,12 +2254,12 @@ Init *TGParser::ParseOperationSubstr(Record *CurRec, const RecTy *ItemType) {
   }
 
   SMLoc MHSLoc = Lex.getLoc();
-  Init *MHS = ParseValue(CurRec);
+  const Init *MHS = ParseValue(CurRec);
   if (!MHS)
     return nullptr;
 
   SMLoc RHSLoc = Lex.getLoc();
-  Init *RHS;
+  const Init *RHS;
   if (consume(tgtok::comma)) {
     RHSLoc = Lex.getLoc();
     RHS = ParseValue(CurRec);
@@ -2273,7 +2280,7 @@ Init *TGParser::ParseOperationSubstr(Record *CurRec, const RecTy *ItemType) {
                   Type->getAsString() + "'");
   }
 
-  TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
+  const TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
   if (!LHSt && !isa<UnsetInit>(LHS)) {
     TokError("could not determine type of the string in !substr");
     return nullptr;
@@ -2284,7 +2291,7 @@ Init *TGParser::ParseOperationSubstr(Record *CurRec, const RecTy *ItemType) {
     return nullptr;
   }
 
-  TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+  const TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
   if (!MHSt && !isa<UnsetInit>(MHS)) {
     TokError("could not determine type of the start position in !substr");
     return nullptr;
@@ -2296,7 +2303,7 @@ Init *TGParser::ParseOperationSubstr(Record *CurRec, const RecTy *ItemType) {
   }
 
   if (RHS) {
-    TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+    const TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
     if (!RHSt && !isa<UnsetInit>(RHS)) {
       TokError("could not determine type of the length in !substr");
       return nullptr;
@@ -2314,7 +2321,8 @@ Init *TGParser::ParseOperationSubstr(Record *CurRec, const RecTy *ItemType) {
 /// Parse the !find operation. Return null on error.
 ///
 /// Substr ::= !find(string, string [, start-int]) => int
-Init *TGParser::ParseOperationFind(Record *CurRec, const RecTy *ItemType) {
+const Init *TGParser::ParseOperationFind(Record *CurRec,
+                                         const RecTy *ItemType) {
   TernOpInit::TernaryOp Code = TernOpInit::FIND;
   const RecTy *Type = IntRecTy::get(Records);
 
@@ -2325,7 +2333,7 @@ Init *TGParser::ParseOperationFind(Record *CurRec, const RecTy *ItemType) {
     return nullptr;
   }
 
-  Init *LHS = ParseValue(CurRec);
+  const Init *LHS = ParseValue(CurRec);
   if (!LHS)
     return nullptr;
 
@@ -2335,12 +2343,12 @@ Init *TGParser::ParseOperationFind(Record *CurRec, const RecTy *ItemType) {
   }
 
   SMLoc MHSLoc = Lex.getLoc();
-  Init *MHS = ParseValue(CurRec);
+  const Init *MHS = ParseValue(CurRec);
   if (!MHS)
     return nullptr;
 
   SMLoc RHSLoc = Lex.getLoc();
-  Init *RHS;
+  const Init *RHS;
   if (consume(tgtok::comma)) {
     RHSLoc = Lex.getLoc();
     RHS = ParseValue(CurRec);
@@ -2361,7 +2369,7 @@ Init *TGParser::ParseOperationFind(Record *CurRec, const RecTy *ItemType) {
                   Type->getAsString() + "'");
   }
 
-  TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
+  const TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
   if (!LHSt && !isa<UnsetInit>(LHS)) {
     TokError("could not determine type of the source string in !find");
     return nullptr;
@@ -2372,7 +2380,7 @@ Init *TGParser::ParseOperationFind(Record *CurRec, const RecTy *ItemType) {
     return nullptr;
   }
 
-  TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+  const TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
   if (!MHSt && !isa<UnsetInit>(MHS)) {
     TokError("could not determine type of the target string in !find");
     return nullptr;
@@ -2384,7 +2392,7 @@ Init *TGParser::ParseOperationFind(Record *CurRec, const RecTy *ItemType) {
   }
 
   if (RHS) {
-    TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+    const TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
     if (!RHSt && !isa<UnsetInit>(RHS)) {
       TokError("could not determine type of the start position in !find");
       return nullptr;
@@ -2403,8 +2411,8 @@ Init *TGParser::ParseOperationFind(Record *CurRec, const RecTy *ItemType) {
 ///
 /// ForEach ::= !foreach(ID, list-or-dag, expr) => list<expr type>
 /// Filter  ::= !foreach(ID, list, predicate) ==> list<list type>
-Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
-                                            const RecTy *ItemType) {
+const Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
+                                                  const RecTy *ItemType) {
   SMLoc OpLoc = Lex.getLoc();
   tgtok::TokKind Operation = Lex.getCode();
   Lex.Lex(); // eat the operation
@@ -2418,7 +2426,7 @@ Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
     return nullptr;
   }
 
-  Init *LHS = StringInit::get(Records, Lex.getCurStrVal());
+  const Init *LHS = StringInit::get(Records, Lex.getCurStrVal());
   Lex.Lex(); // eat the ID.
 
   if (CurRec && CurRec->getValue(LHS)) {
@@ -2433,7 +2441,7 @@ Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
     return nullptr;
   }
 
-  Init *MHS = ParseValue(CurRec);
+  const Init *MHS = ParseValue(CurRec);
   if (!MHS)
     return nullptr;
 
@@ -2442,7 +2450,7 @@ Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
     return nullptr;
   }
 
-  TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
+  const TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
   if (!MHSt) {
     TokError("could not get type of !foreach/!filter list or dag");
     return nullptr;
@@ -2499,7 +2507,7 @@ Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
   }
   TGVarScope *TempScope = PushScope(ParseRec);
   ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal));
-  Init *RHS = ParseValue(ParseRec, ExprEltType);
+  const Init *RHS = ParseValue(ParseRec, ExprEltType);
   ParseRec->removeValue(LHS);
   PopScope(TempScope);
   if (!RHS)
@@ -2512,7 +2520,7 @@ Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
 
   const RecTy *OutType = InEltType;
   if (Operation == tgtok::XForEach && !IsDAG) {
-    TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
+    const TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
     if (!RHSt) {
       TokError("could not get type of !foreach result expression");
       return nullptr;
@@ -2528,7 +2536,8 @@ Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
       ->Fold(CurRec);
 }
 
-Init *TGParser::ParseOperationCond(Record *CurRec, const RecTy *ItemType) {
+const Init *TGParser::ParseOperationCond(Record *CurRec,
+                                         const RecTy *ItemType) {
   Lex.Lex();  // eat the operation 'cond'
 
   if (!consume(tgtok::l_paren)) {
@@ -2537,13 +2546,13 @@ Init *TGParser::ParseOperationCond(Record *CurRec, const RecTy *ItemType) {
   }
 
   // Parse through '[Case: Val,]+'
-  SmallVector<Init *, 4> Case;
-  SmallVector<Init *, 4> Val;
+  SmallVector<const Init *, 4> Case;
+  SmallVector<const Init *, 4> Val;
   while (true) {
     if (consume(tgtok::r_paren))
       break;
 
-    Init *V = ParseValue(CurRec);
+    const Init *V = ParseValue(CurRec);
     if (!V)
       return nullptr;
     Case.push_back(V);
@@ -2574,11 +2583,11 @@ Init *TGParser::ParseOperationCond(Record *CurRec, const RecTy *ItemType) {
 
   // resolve type
   const RecTy *Type = nullptr;
-  for (Init *V : Val) {
+  for (const Init *V : Val) {
     const RecTy *VTy = nullptr;
-    if (TypedInit *Vt = dyn_cast<TypedInit>(V))
+    if (const TypedInit *Vt = dyn_cast<TypedInit>(V))
       VTy = Vt->getType();
-    if (BitsInit *Vbits = dyn_cast<BitsInit>(V))
+    if (const BitsInit *Vbits = dyn_cast<BitsInit>(V))
       VTy = BitsRecTy::get(Records, Vbits->getNumBits());
     if (isa<BitInit>(V))
       VTy = BitRecTy::get(Records);
@@ -2633,9 +2642,9 @@ Init *TGParser::ParseOperationCond(Record *CurRec, const RecTy *ItemType) {
 ///   SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
 ///   SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
 ///
-Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
-                                 IDParseMode Mode) {
-  Init *R = nullptr;
+const Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
+                                       IDParseMode Mode) {
+  const Init *R = nullptr;
   tgtok::TokKind Code = Lex.getCode();
 
   // Parse bang operators.
@@ -2689,7 +2698,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
     break;
   case tgtok::Id: {
     SMRange NameLoc = Lex.getLocRange();
-    StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
+    const StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
     tgtok::TokKind Next = Lex.Lex();
     if (Next == tgtok::equal) // Named argument.
       return Name;
@@ -2706,7 +2715,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
       return nullptr;
     }
 
-    SmallVector<ArgumentInit *, 8> Args;
+    SmallVector<const ArgumentInit *, 8> Args;
     Lex.Lex(); // consume the <
     if (ParseTemplateArgValueList(Args, CurRec, Class))
       return nullptr; // Error parsing value list.
@@ -2724,7 +2733,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
   case tgtok::l_brace: {           // Value ::= '{' ValueList '}'
     SMLoc BraceLoc = Lex.getLoc();
     Lex.Lex(); // eat the '{'
-    SmallVector<Init*, 16> Vals;
+    SmallVector<const Init *, 16> Vals;
 
     if (Lex.getCode() != tgtok::r_brace) {
       ParseValueList(Vals, CurRec);
@@ -2735,7 +2744,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
       return nullptr;
     }
 
-    SmallVector<Init *, 16> NewBits;
+    SmallVector<const Init *, 16> NewBits;
 
     // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it
     // first.  We'll first read everything in to a vector, then we can reverse
@@ -2745,13 +2754,13 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
       //        if the API was a little more orthogonal.
 
       // bits<n> values are allowed to initialize n bits.
-      if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) {
+      if (const BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) {
         for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
           NewBits.push_back(BI->getBit((e - i) - 1));
         continue;
       }
       // bits<n> can also come from variable initializers.
-      if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) {
+      if (const VarInit *VI = dyn_cast<VarInit>(Vals[i])) {
         if (const BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) {
           for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
             NewBits.push_back(VI->getBit((e - i) - 1));
@@ -2760,7 +2769,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
         // Fallthrough to try convert this to a bit.
       }
       // All other values must be convertible to just a single bit.
-      Init *Bit = Vals[i]->getCastTo(BitRecTy::get(Records));
+      const Init *Bit = Vals[i]->getCastTo(BitRecTy::get(Records));
       if (!Bit) {
         Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
               ") is not convertable to a bit");
@@ -2773,7 +2782,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
   }
   case tgtok::l_square: {          // Value ::= '[' ValueList ']'
     Lex.Lex(); // eat the '['
-    SmallVector<Init*, 16> Vals;
+    SmallVector<const Init *, 16> Vals;
 
     const RecTy *DeducedEltTy = nullptr;
     const ListRecTy *GivenListTy = nullptr;
@@ -2815,8 +2824,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
 
     // Check elements
     const RecTy *EltTy = nullptr;
-    for (Init *V : Vals) {
-      TypedInit *TArg = dyn_cast<TypedInit>(V);
+    for (const Init *V : Vals) {
+      const TypedInit *TArg = dyn_cast<TypedInit>(V);
       if (TArg) {
         if (EltTy) {
           EltTy = resolveTypes(EltTy, TArg->getType());
@@ -2872,11 +2881,11 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
       return nullptr;
     }
 
-    Init *Operator = ParseValue(CurRec);
+    const Init *Operator = ParseValue(CurRec);
     if (!Operator) return nullptr;
 
     // If the operator name is present, parse it.
-    StringInit *OperatorName = nullptr;
+    const StringInit *OperatorName = nullptr;
     if (consume(tgtok::colon)) {
       if (Lex.getCode() != tgtok::VarName) { // eat the ':'
         TokError("expected variable name in dag operator");
@@ -2886,7 +2895,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
       Lex.Lex();  // eat the VarName.
     }
 
-    SmallVector<std::pair<llvm::Init*, StringInit*>, 8> DagArgs;
+    SmallVector<std::pair<const Init *, const StringInit *>, 8> DagArgs;
     if (Lex.getCode() != tgtok::r_paren) {
       ParseDagArgList(DagArgs, CurRec);
       if (DagArgs.empty()) return nullptr;
@@ -2911,10 +2920,10 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
 ///   ValueSuffix ::= '[' SliceElements ']'
 ///   ValueSuffix ::= '.' ID
 ///
-Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
-                           IDParseMode Mode) {
+const Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
+                                 IDParseMode Mode) {
   SMLoc LHSLoc = Lex.getLoc();
-  Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
+  const Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
   if (!Result) return nullptr;
 
   // Parse the suffixes now if present.
@@ -2962,7 +2971,7 @@ Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
       }
 
       Lex.Lex(); // eat the '['
-      TypedInit *RHS = ParseSliceElements(CurRec, /*Single=*/true);
+      const TypedInit *RHS = ParseSliceElements(CurRec, /*Single=*/true);
       if (!RHS)
         return nullptr;
 
@@ -2990,7 +2999,8 @@ Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
         return nullptr;
       }
       SMRange FieldNameLoc = Lex.getLocRange();
-      StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
+      const StringInit *FieldName =
+          StringInit::get(Records, Lex.getCurStrVal());
       if (!Result->getFieldType(FieldName)) {
         TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
                  Result->getAsString() + "'");
@@ -3018,7 +3028,7 @@ Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
 
     case tgtok::paste:
       SMLoc PasteLoc = Lex.getLoc();
-      TypedInit *LHS = dyn_cast<TypedInit>(Result);
+      const TypedInit *LHS = dyn_cast<TypedInit>(Result);
       if (!LHS) {
         Error(PasteLoc, "LHS of paste is not typed!");
         return nullptr;
@@ -3037,7 +3047,7 @@ Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
           Result = LHS; // trailing paste, ignore.
           break;
         default:
-          Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
+          const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
           if (!RHSResult)
             return nullptr;
           Result = BinOpInit::getListConcat(LHS, RHSResult);
@@ -3060,7 +3070,7 @@ Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
         LHS = CastLHS;
       }
 
-      TypedInit *RHS = nullptr;
+      const TypedInit *RHS = nullptr;
 
       Lex.Lex();  // Eat the '#'.
       switch (Lex.getCode()) {
@@ -3076,7 +3086,7 @@ Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
         break;
 
       default:
-        Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
+        const Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
         if (!RHSResult)
           return nullptr;
         RHS = dyn_cast<TypedInit>(RHSResult);
@@ -3113,26 +3123,26 @@ Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
 ///    DagArgList ::= DagArg
 ///    DagArgList ::= DagArgList ',' DagArg
 void TGParser::ParseDagArgList(
-    SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
+    SmallVectorImpl<std::pair<const Init *, const StringInit *>> &Result,
     Record *CurRec) {
 
   while (true) {
     // DagArg ::= VARNAME
     if (Lex.getCode() == tgtok::VarName) {
       // A missing value is treated like '?'.
-      StringInit *VarName = StringInit::get(Records, Lex.getCurStrVal());
+      const StringInit *VarName = StringInit::get(Records, Lex.getCurStrVal());
       Result.emplace_back(UnsetInit::get(Records), VarName);
       Lex.Lex();
     } else {
       // DagArg ::= Value (':' VARNAME)?
-      Init *Val = ParseValue(CurRec);
+      const Init *Val = ParseValue(CurRec);
       if (!Val) {
         Result.clear();
         return;
       }
 
       // If the variable name is present, add it.
-      StringInit *VarName = nullptr;
+      const StringInit *VarName = nullptr;
       if (Lex.getCode() == tgtok::colon) {
         if (Lex.Lex() != tgtok::VarName) { // eat the ':'
           TokError("expected variable name in dag literal");
@@ -3156,8 +3166,8 @@ void TGParser::ParseDagArgList(
 ///
 ///   ValueList ::= Value (',' Value)
 ///
-void TGParser::ParseValueList(SmallVectorImpl<Init *> &Result, Record *CurRec,
-                              const RecTy *ItemType) {
+void TGParser::ParseValueList(SmallVectorImpl<const Init *> &Result,
+                              Record *CurRec, const RecTy *ItemType) {
   Result.push_back(ParseValue(CurRec, ItemType));
   if (!Result.back()) {
     Result.clear();
@@ -3185,9 +3195,10 @@ void TGParser::ParseValueList(SmallVectorImpl<Init *> &Result, Record *CurRec,
 //   PostionalArgValueList ::= [Value {',' Value}*]
 //   NamedArgValueList ::= [NameValue '=' Value {',' NameValue '=' Value}*]
 bool TGParser::ParseTemplateArgValueList(
-    SmallVectorImpl<ArgumentInit *> &Result, Record *CurRec, Record *ArgsRec) {
+    SmallVectorImpl<const ArgumentInit *> &Result, Record *CurRec,
+    Record *ArgsRec) {
   assert(Result.empty() && "Result vector is not empty");
-  ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
+  ArrayRef<const Init *> TArgs = ArgsRec->getTemplateArgs();
 
   if (consume(tgtok::greater)) // empty value list
     return false;
@@ -3203,7 +3214,7 @@ bool TGParser::ParseTemplateArgValueList(
     SMLoc ValueLoc = Lex.getLoc();
     // If we are parsing named argument, we don't need to know the argument name
     // and argument type will be resolved after we know the name.
-    Init *Value = ParseValue(
+    const Init *Value = ParseValue(
         CurRec,
         HasNamedArg ? nullptr : ArgsRec->getValue(TArgs[ArgIndex])->getType());
     if (!Value)
@@ -3216,7 +3227,7 @@ bool TGParser::ParseTemplateArgValueList(
                      "The name of named argument should be a valid identifier");
 
       auto *Name = cast<StringInit>(Value);
-      Init *QualifiedName = QualifyName(*ArgsRec, Name);
+      const Init *QualifiedName = QualifyName(*ArgsRec, Name);
       auto *NamedArg = ArgsRec->getValue(QualifiedName);
       if (!NamedArg)
         return Error(ValueLoc,
@@ -3261,7 +3272,7 @@ bool TGParser::ParseTemplateArgValueList(
 ///
 ///  Declaration ::= FIELD? Type ID ('=' Value)?
 ///
-Init *TGParser::ParseDeclaration(Record *CurRec,
+const Init *TGParser::ParseDeclaration(Record *CurRec,
                                        bool ParsingTemplateArgs) {
   // Read the field prefix if present.
   bool HasField = consume(tgtok::Field);
@@ -3286,7 +3297,7 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
   }
 
   SMLoc IdLoc = Lex.getLoc();
-  Init *DeclName = StringInit::get(Records, Str);
+  const Init *DeclName = StringInit::get(Records, Str);
   Lex.Lex();
 
   bool BadField;
@@ -3313,7 +3324,7 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
   // If a value is present, parse it and set new field's value.
   if (consume(tgtok::equal)) {
     SMLoc ValLoc = Lex.getLoc();
-    Init *Val = ParseValue(CurRec, Type);
+    const Init *Val = ParseValue(CurRec, Type);
     if (!Val ||
         SetValue(CurRec, ValLoc, DeclName, {}, Val,
                  /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/false)) {
@@ -3335,13 +3346,14 @@ Init *TGParser::ParseDeclaration(Record *CurRec,
 ///  ForeachDeclaration ::= ID '=' RangePiece
 ///  ForeachDeclaration ::= ID '=' Value
 ///
-VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
+const VarInit *
+TGParser::ParseForeachDeclaration(const Init *&ForeachListValue) {
   if (Lex.getCode() != tgtok::Id) {
     TokError("Expected identifier in foreach declaration");
     return nullptr;
   }
 
-  Init *DeclName = StringInit::get(Records, Lex.getCurStrVal());
+  const Init *DeclName = StringInit::get(Records, Lex.getCurStrVal());
   Lex.Lex();
 
   // If a value is present, parse it.
@@ -3366,11 +3378,11 @@ VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
 
   default: {
     SMLoc ValueLoc = Lex.getLoc();
-    Init *I = ParseValue(nullptr);
+    const Init *I = ParseValue(nullptr);
     if (!I)
       return nullptr;
 
-    TypedInit *TI = dyn_cast<TypedInit>(I);
+    const TypedInit *TI = dyn_cast<TypedInit>(I);
     if (TI && isa<ListRecTy>(TI->getType())) {
       ForeachListValue = I;
       IterType = cast<ListRecTy>(TI->getType())->getElementType();
@@ -3422,7 +3434,7 @@ bool TGParser::ParseTemplateArgList(Record *CurRec) {
   Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
 
   // Read the first declaration.
-  Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
+  const Init *TemplArg = ParseDeclaration(CurRec, true /*templateargs*/);
   if (!TemplArg)
     return true;
 
@@ -3479,7 +3491,7 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
     return TokError("expected field identifier after let");
 
   SMLoc IdLoc = Lex.getLoc();
-  StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
+  const StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
   Lex.Lex();  // eat the field name.
 
   SmallVector<unsigned, 16> BitList;
@@ -3501,7 +3513,7 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
     Type = BitsRecTy::get(Records, BitList.size());
   }
 
-  Init *Val = ParseValue(CurRec, Type);
+  const Init *Val = ParseValue(CurRec, Type);
   if (!Val) return true;
 
   if (!consume(tgtok::semi))
@@ -3629,7 +3641,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
 
   // Parse ObjectName and make a record for it.
   std::unique_ptr<Record> CurRec;
-  Init *Name = ParseObjectName(CurMultiClass);
+  const Init *Name = ParseObjectName(CurMultiClass);
   if (!Name)
     return true;
 
@@ -3665,7 +3677,7 @@ bool TGParser::ParseDefset() {
 
   if (Lex.getCode() != tgtok::Id)
     return TokError("expected identifier");
-  StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
+  const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
   if (Records.getGlobal(DeclName->getValue()))
     return TokError("def or global variable of this name already exists");
 
@@ -3738,7 +3750,7 @@ bool TGParser::ParseDefvar(Record *CurRec) {
 
   if (Lex.getCode() != tgtok::Id)
     return TokError("expected identifier");
-  StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
+  const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
   if (CurScope->varAlreadyDefined(DeclName->getValue()))
     return TokError("local variable of this name already exists");
 
@@ -3758,7 +3770,7 @@ bool TGParser::ParseDefvar(Record *CurRec) {
   if (!consume(tgtok::equal))
     return TokError("expected '='");
 
-  Init *Value = ParseValue(CurRec);
+  const Init *Value = ParseValue(CurRec);
   if (!Value)
     return true;
 
@@ -3786,8 +3798,8 @@ bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
 
   // Make a temporary object to record items associated with the for
   // loop.
-  Init *ListValue = nullptr;
-  VarInit *IterName = ParseForeachDeclaration(ListValue);
+  const Init *ListValue = nullptr;
+  const VarInit *IterName = ParseForeachDeclaration(ListValue);
   if (!IterName)
     return TokError("expected declaration in for");
 
@@ -3840,7 +3852,7 @@ bool TGParser::ParseIf(MultiClass *CurMultiClass) {
 
   // Make a temporary object to record items associated with the for
   // loop.
-  Init *Condition = ParseValue(nullptr);
+  const Init *Condition = ParseValue(nullptr);
   if (!Condition)
     return true;
 
@@ -3853,14 +3865,14 @@ bool TGParser::ParseIf(MultiClass *CurMultiClass) {
   // loop, over a list of length 0 or 1 depending on the condition, and with no
   // iteration variable being assigned.
 
-  ListInit *EmptyList = ListInit::get({}, BitRecTy::get(Records));
-  ListInit *SingletonList =
+  const ListInit *EmptyList = ListInit::get({}, BitRecTy::get(Records));
+  const ListInit *SingletonList =
       ListInit::get({BitInit::get(Records, true)}, BitRecTy::get(Records));
   const RecTy *BitListTy = ListRecTy::get(BitRecTy::get(Records));
 
   // The foreach containing the then-clause selects SingletonList if
   // the condition is true.
-  Init *ThenClauseList =
+  const Init *ThenClauseList =
       TernOpInit::get(TernOpInit::IF, Condition, SingletonList, EmptyList,
                       BitListTy)
           ->Fold(nullptr);
@@ -3882,7 +3894,7 @@ bool TGParser::ParseIf(MultiClass *CurMultiClass) {
   if (consume(tgtok::ElseKW)) {
     // The foreach containing the else-clause uses the same pair of lists as
     // above, but this time, selects SingletonList if the condition is *false*.
-    Init *ElseClauseList =
+    const Init *ElseClauseList =
         TernOpInit::get(TernOpInit::IF, Condition, EmptyList, SingletonList,
                         BitListTy)
             ->Fold(nullptr);
@@ -3942,7 +3954,7 @@ bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
   Lex.Lex(); // Eat the 'assert' token.
 
   SMLoc ConditionLoc = Lex.getLoc();
-  Init *Condition = ParseValue(CurRec);
+  const Init *Condition = ParseValue(CurRec);
   if (!Condition)
     return true;
 
@@ -3951,7 +3963,7 @@ bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
     return true;
   }
 
-  Init *Message = ParseValue(CurRec);
+  const Init *Message = ParseValue(CurRec);
   if (!Message)
     return true;
 
@@ -4032,7 +4044,7 @@ void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) {
       return;
     }
 
-    StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
+    const StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
     SMLoc NameLoc = Lex.getLoc();
     Lex.Lex();  // Eat the identifier.
 
@@ -4050,7 +4062,7 @@ void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) {
       return;
     }
 
-    Init *Val = ParseValue(nullptr);
+    const Init *Val = ParseValue(nullptr);
     if (!Val) {
       Result.clear();
       return;
@@ -4226,7 +4238,7 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
   assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
   Lex.Lex(); // eat the defm
 
-  Init *DefmName = ParseObjectName(CurMultiClass);
+  const Init *DefmName = ParseObjectName(CurMultiClass);
   if (!DefmName)
     return true;
   if (isa<UnsetInit>(DefmName)) {
@@ -4399,11 +4411,11 @@ bool TGParser::ParseFile() {
 // If necessary, replace an argument with a cast to the required type.
 // The argument count has already been checked.
 bool TGParser::CheckTemplateArgValues(
-    SmallVectorImpl<llvm::ArgumentInit *> &Values, SMLoc Loc, Record *ArgsRec) {
-  ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
+    SmallVectorImpl<const ArgumentInit *> &Values, SMLoc Loc, Record *ArgsRec) {
+  ArrayRef<const Init *> TArgs = ArgsRec->getTemplateArgs();
 
-  for (llvm::ArgumentInit *&Value : Values) {
-    Init *ArgName = nullptr;
+  for (const ArgumentInit *&Value : Values) {
+    const Init *ArgName = nullptr;
     if (Value->isPositional())
       ArgName = TArgs[Value->getIndex()];
     if (Value->isNamed())
@@ -4412,7 +4424,7 @@ bool TGParser::CheckTemplateArgValues(
     RecordVal *Arg = ArgsRec->getValue(ArgName);
     const RecTy *ArgType = Arg->getType();
 
-    if (TypedInit *ArgValue = dyn_cast<TypedInit>(Value->getValue())) {
+    if (const TypedInit *ArgValue = dyn_cast<TypedInit>(Value->getValue())) {
       auto *CastValue = ArgValue->getCastTo(ArgType);
       if (CastValue) {
         assert((!isa<TypedInit>(CastValue) ||
@@ -4466,7 +4478,7 @@ bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {
   assert(Lex.getCode() == tgtok::Dump && "Unknown tok");
   Lex.Lex(); // eat the operation
 
-  Init *Message = ParseValue(CurRec);
+  const Init *Message = ParseValue(CurRec);
   if (!Message)
     return true;
 
@@ -4485,7 +4497,7 @@ bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {
     HasReferenceResolver resolver{nullptr};
     resolver.setFinal(true);
     // force a resolution with a dummy resolver
-    Init *ResolvedMessage = Message->resolveReferences(resolver);
+    const Init *ResolvedMessage = Message->resolveReferences(resolver);
     addEntry(std::make_unique<Record::DumpInfo>(Loc, ResolvedMessage));
   }
 

diff  --git a/llvm/lib/TableGen/TGParser.h b/llvm/lib/TableGen/TGParser.h
index f33ae1ce2c8107..a1f1db6622aceb 100644
--- a/llvm/lib/TableGen/TGParser.h
+++ b/llvm/lib/TableGen/TGParser.h
@@ -27,11 +27,11 @@ struct SubClassReference;
 struct SubMultiClassReference;
 
 struct LetRecord {
-  StringInit *Name;
+  const StringInit *Name;
   std::vector<unsigned> Bits;
-  Init *Value;
+  const Init *Value;
   SMLoc Loc;
-  LetRecord(StringInit *N, ArrayRef<unsigned> B, Init *V, SMLoc L)
+  LetRecord(const StringInit *N, ArrayRef<unsigned> B, const Init *V, SMLoc L)
       : Name(N), Bits(B), Value(V), Loc(L) {}
 };
 
@@ -62,13 +62,13 @@ struct RecordsEntry {
 /// constructed by desugaring an if statement.)
 struct ForeachLoop {
   SMLoc Loc;
-  VarInit *IterVar;
-  Init *ListValue;
+  const VarInit *IterVar;
+  const Init *ListValue;
   std::vector<RecordsEntry> Entries;
 
   void dump() const;
 
-  ForeachLoop(SMLoc Loc, VarInit *IVar, Init *LValue)
+  ForeachLoop(SMLoc Loc, const VarInit *IVar, const Init *LValue)
       : Loc(Loc), IterVar(IVar), ListValue(LValue) {}
 };
 
@@ -96,7 +96,7 @@ class TGVarScope {
   ScopeKind Kind;
   std::unique_ptr<TGVarScope> Parent;
   // A scope to hold variable definitions from defvar.
-  std::map<std::string, Init *, std::less<>> Vars;
+  std::map<std::string, const Init *, std::less<>> Vars;
   Record *CurRec = nullptr;
   ForeachLoop *CurLoop = nullptr;
   MultiClass *CurMultiClass = nullptr;
@@ -118,9 +118,9 @@ class TGVarScope {
     return std::move(Parent);
   }
 
-  Init *getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass,
-               StringInit *Name, SMRange NameLoc,
-               bool TrackReferenceLocs) const;
+  const Init *getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass,
+                     const StringInit *Name, SMRange NameLoc,
+                     bool TrackReferenceLocs) const;
 
   bool varAlreadyDefined(StringRef Name) const {
     // When we check whether a variable is already defined, for the purpose of
@@ -130,7 +130,7 @@ class TGVarScope {
     return Vars.find(Name) != Vars.end();
   }
 
-  void addVar(StringRef Name, Init *I) {
+  void addVar(StringRef Name, const Init *I) {
     bool Ins = Vars.insert(std::make_pair(std::string(Name), I)).second;
     (void)Ins;
     assert(Ins && "Local variable already exists");
@@ -228,15 +228,15 @@ class TGParser {
   /// Set the value of a RecordVal within the given record. If `OverrideDefLoc`
   /// is set, the provided location overrides any existing location of the
   /// RecordVal.
-  bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName,
-                ArrayRef<unsigned> BitList, Init *V,
+  bool SetValue(Record *TheRec, SMLoc Loc, const Init *ValName,
+                ArrayRef<unsigned> BitList, const Init *V,
                 bool AllowSelfAssignment = false, bool OverrideDefLoc = true);
   bool AddSubClass(Record *Rec, SubClassReference &SubClass);
   bool AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass);
   bool AddSubMultiClass(MultiClass *CurMC,
                         SubMultiClassReference &SubMultiClass);
 
-  using SubstStack = SmallVector<std::pair<Init *, Init *>, 8>;
+  using SubstStack = SmallVector<std::pair<const Init *, const Init *>, 8>;
 
   bool addEntry(RecordsEntry E);
   bool resolve(const ForeachLoop &Loop, SubstStack &Stack, bool Final,
@@ -246,15 +246,16 @@ class TGParser {
                SMLoc *Loc = nullptr);
   bool addDefOne(std::unique_ptr<Record> Rec);
 
-  using ArgValueHandler = std::function<void(Init *, Init *)>;
+  using ArgValueHandler = std::function<void(const Init *, const Init *)>;
   bool resolveArguments(
-      Record *Rec, ArrayRef<ArgumentInit *> ArgValues, SMLoc Loc,
-      ArgValueHandler ArgValueHandler = [](Init *, Init *) {});
+      Record *Rec, ArrayRef<const ArgumentInit *> ArgValues, SMLoc Loc,
+      ArgValueHandler ArgValueHandler = [](const Init *, const Init *) {});
   bool resolveArgumentsOfClass(MapResolver &R, Record *Rec,
-                               ArrayRef<ArgumentInit *> ArgValues, SMLoc Loc);
+                               ArrayRef<const ArgumentInit *> ArgValues,
+                               SMLoc Loc);
   bool resolveArgumentsOfMultiClass(SubstStack &Substs, MultiClass *MC,
-                                    ArrayRef<ArgumentInit *> ArgValues,
-                                    Init *DefmName, SMLoc Loc);
+                                    ArrayRef<const ArgumentInit *> ArgValues,
+                                    const Init *DefmName, SMLoc Loc);
 
 private:  // Parser methods.
   bool consume(tgtok::TokKind K);
@@ -280,45 +281,46 @@ class TGParser {
   bool ParseBodyItem(Record *CurRec);
 
   bool ParseTemplateArgList(Record *CurRec);
-  Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
-  VarInit *ParseForeachDeclaration(Init *&ForeachListValue);
+  const Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
+  const VarInit *ParseForeachDeclaration(const Init *&ForeachListValue);
 
   SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
   SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
 
-  Init *ParseIDValue(Record *CurRec, StringInit *Name, SMRange NameLoc,
-                     IDParseMode Mode = ParseValueMode);
-  Init *ParseSimpleValue(Record *CurRec, const RecTy *ItemType = nullptr,
+  const Init *ParseIDValue(Record *CurRec, const StringInit *Name,
+                           SMRange NameLoc, IDParseMode Mode = ParseValueMode);
+  const Init *ParseSimpleValue(Record *CurRec, const RecTy *ItemType = nullptr,
+                               IDParseMode Mode = ParseValueMode);
+  const Init *ParseValue(Record *CurRec, const RecTy *ItemType = nullptr,
                          IDParseMode Mode = ParseValueMode);
-  Init *ParseValue(Record *CurRec, const RecTy *ItemType = nullptr,
-                   IDParseMode Mode = ParseValueMode);
-  void ParseValueList(SmallVectorImpl<llvm::Init *> &Result, Record *CurRec,
+  void ParseValueList(SmallVectorImpl<const Init *> &Result, Record *CurRec,
                       const RecTy *ItemType = nullptr);
-  bool ParseTemplateArgValueList(SmallVectorImpl<llvm::ArgumentInit *> &Result,
+  bool ParseTemplateArgValueList(SmallVectorImpl<const ArgumentInit *> &Result,
                                  Record *CurRec, Record *ArgsRec);
   void ParseDagArgList(
-      SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
+      SmallVectorImpl<std::pair<const Init *, const StringInit *>> &Result,
       Record *CurRec);
   bool ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges);
   bool ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges);
-  TypedInit *ParseSliceElement(Record *CurRec);
-  TypedInit *ParseSliceElements(Record *CurRec, bool Single = false);
+  const TypedInit *ParseSliceElement(Record *CurRec);
+  const TypedInit *ParseSliceElements(Record *CurRec, bool Single = false);
   void ParseRangeList(SmallVectorImpl<unsigned> &Result);
   bool ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
-                       TypedInit *FirstItem = nullptr);
+                       const TypedInit *FirstItem = nullptr);
   const RecTy *ParseType();
-  Init *ParseOperation(Record *CurRec, const RecTy *ItemType);
-  Init *ParseOperationSubstr(Record *CurRec, const RecTy *ItemType);
-  Init *ParseOperationFind(Record *CurRec, const RecTy *ItemType);
-  Init *ParseOperationForEachFilter(Record *CurRec, const RecTy *ItemType);
-  Init *ParseOperationCond(Record *CurRec, const RecTy *ItemType);
+  const Init *ParseOperation(Record *CurRec, const RecTy *ItemType);
+  const Init *ParseOperationSubstr(Record *CurRec, const RecTy *ItemType);
+  const Init *ParseOperationFind(Record *CurRec, const RecTy *ItemType);
+  const Init *ParseOperationForEachFilter(Record *CurRec,
+                                          const RecTy *ItemType);
+  const Init *ParseOperationCond(Record *CurRec, const RecTy *ItemType);
   const RecTy *ParseOperatorType();
-  Init *ParseObjectName(MultiClass *CurMultiClass);
+  const Init *ParseObjectName(MultiClass *CurMultiClass);
   Record *ParseClassID();
   MultiClass *ParseMultiClassID();
   bool ApplyLetStack(Record *CurRec);
   bool ApplyLetStack(RecordsEntry &Entry);
-  bool CheckTemplateArgValues(SmallVectorImpl<llvm::ArgumentInit *> &Values,
+  bool CheckTemplateArgValues(SmallVectorImpl<const ArgumentInit *> &Values,
                               SMLoc Loc, Record *ArgsRec);
 };
 

diff  --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index fe9621a89374e0..e3d9d010f9ae35 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -1208,7 +1208,7 @@ ClassInfo *AsmMatcherInfo::getOperandClass(const Record *Rec, int SubOpIdx) {
                       "Record `" + Rec->getName() +
                           "' does not have a ParserMatchClass!\n");
 
-    if (DefInit *DI = dyn_cast<DefInit>(R->getValue())) {
+    if (const DefInit *DI = dyn_cast<DefInit>(R->getValue())) {
       const Record *MatchClass = DI->getDef();
       if (ClassInfo *CI = AsmOperandClasses[MatchClass])
         return CI;
@@ -1349,12 +1349,12 @@ void AsmMatcherInfo::buildRegisterClasses(
     } else
       CI->ValueName = CI->ValueName + "," + RC.getName();
 
-    Init *DiagnosticType = Def->getValueInit("DiagnosticType");
-    if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
+    const Init *DiagnosticType = Def->getValueInit("DiagnosticType");
+    if (const StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
       CI->DiagnosticType = std::string(SI->getValue());
 
-    Init *DiagnosticString = Def->getValueInit("DiagnosticString");
-    if (StringInit *SI = dyn_cast<StringInit>(DiagnosticString))
+    const Init *DiagnosticString = Def->getValueInit("DiagnosticString");
+    if (const StringInit *SI = dyn_cast<StringInit>(DiagnosticString))
       CI->DiagnosticString = std::string(SI->getValue());
 
     // If we have a diagnostic string but the diagnostic type is not specified
@@ -1398,9 +1398,9 @@ void AsmMatcherInfo::buildOperandClasses() {
     ClassInfo *CI = AsmOperandClasses[Rec];
     CI->Kind = ClassInfo::UserClass0 + Index;
 
-    ListInit *Supers = Rec->getValueAsListInit("SuperClasses");
-    for (Init *I : Supers->getValues()) {
-      DefInit *DI = dyn_cast<DefInit>(I);
+    const ListInit *Supers = Rec->getValueAsListInit("SuperClasses");
+    for (const Init *I : Supers->getValues()) {
+      const DefInit *DI = dyn_cast<DefInit>(I);
       if (!DI) {
         PrintError(Rec->getLoc(), "Invalid super class reference!");
         continue;
@@ -1417,8 +1417,8 @@ void AsmMatcherInfo::buildOperandClasses() {
     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)) {
+    const Init *PMName = Rec->getValueInit("PredicateMethod");
+    if (const StringInit *SI = dyn_cast<StringInit>(PMName)) {
       CI->PredicateMethod = std::string(SI->getValue());
     } else {
       assert(isa<UnsetInit>(PMName) && "Unexpected PredicateMethod field!");
@@ -1426,8 +1426,8 @@ void AsmMatcherInfo::buildOperandClasses() {
     }
 
     // Get or construct the render method name.
-    Init *RMName = Rec->getValueInit("RenderMethod");
-    if (StringInit *SI = dyn_cast<StringInit>(RMName)) {
+    const Init *RMName = Rec->getValueInit("RenderMethod");
+    if (const StringInit *SI = dyn_cast<StringInit>(RMName)) {
       CI->RenderMethod = std::string(SI->getValue());
     } else {
       assert(isa<UnsetInit>(RMName) && "Unexpected RenderMethod field!");
@@ -1435,29 +1435,29 @@ void AsmMatcherInfo::buildOperandClasses() {
     }
 
     // Get the parse method name or leave it as empty.
-    Init *PRMName = Rec->getValueInit("ParserMethod");
-    if (StringInit *SI = dyn_cast<StringInit>(PRMName))
+    const Init *PRMName = Rec->getValueInit("ParserMethod");
+    if (const StringInit *SI = dyn_cast<StringInit>(PRMName))
       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))
+    const Init *DiagnosticType = Rec->getValueInit("DiagnosticType");
+    if (const StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
       CI->DiagnosticType = std::string(SI->getValue());
-    Init *DiagnosticString = Rec->getValueInit("DiagnosticString");
-    if (StringInit *SI = dyn_cast<StringInit>(DiagnosticString))
+    const Init *DiagnosticString = Rec->getValueInit("DiagnosticString");
+    if (const StringInit *SI = dyn_cast<StringInit>(DiagnosticString))
       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())
       CI->DiagnosticType = CI->ClassName;
 
-    Init *IsOptional = Rec->getValueInit("IsOptional");
-    if (BitInit *BI = dyn_cast<BitInit>(IsOptional))
+    const Init *IsOptional = Rec->getValueInit("IsOptional");
+    if (const BitInit *BI = dyn_cast<BitInit>(IsOptional))
       CI->IsOptional = BI->getValue();
 
     // Get or construct the default method name.
-    Init *DMName = Rec->getValueInit("DefaultMethod");
-    if (StringInit *SI = dyn_cast<StringInit>(DMName)) {
+    const Init *DMName = Rec->getValueInit("DefaultMethod");
+    if (const StringInit *SI = dyn_cast<StringInit>(DMName)) {
       CI->DefaultMethod = std::string(SI->getValue());
     } else {
       assert(isa<UnsetInit>(DMName) && "Unexpected DefaultMethod field!");

diff  --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 83205b50f6e28a..3f09564cc0d650 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -1031,9 +1031,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
         bool IsOr = CombineType == "any_of";
         // Change (any_of FeatureAll, (any_of ...)) to (any_of FeatureAll, ...).
         if (IsOr && D->getNumArgs() == 2 && isa<DagInit>(D->getArg(1))) {
-          DagInit *RHS = cast<DagInit>(D->getArg(1));
-          SmallVector<Init *> Args{D->getArg(0)};
-          SmallVector<StringInit *> ArgNames{D->getArgName(0)};
+          const DagInit *RHS = cast<DagInit>(D->getArg(1));
+          SmallVector<const Init *> Args{D->getArg(0)};
+          SmallVector<const StringInit *> ArgNames{D->getArgName(0)};
           for (unsigned i = 0, e = RHS->getNumArgs(); i != e; ++i) {
             Args.push_back(RHS->getArg(i));
             ArgNames.push_back(RHS->getArgName(i));

diff  --git a/llvm/utils/TableGen/Attributes.cpp b/llvm/utils/TableGen/Attributes.cpp
index ed00debc398cb9..138275356dc954 100644
--- a/llvm/utils/TableGen/Attributes.cpp
+++ b/llvm/utils/TableGen/Attributes.cpp
@@ -122,7 +122,7 @@ void Attributes::emitAttributeProperties(raw_ostream &OS) {
     bool AllowIntersectMin = KindName == "IntAttr";
     for (auto *A : Records.getAllDerivedDefinitions(KindName)) {
       OS << "0";
-      for (Init *P : *A->getValueAsListInit("Properties")) {
+      for (const Init *P : *A->getValueAsListInit("Properties")) {
         if (!AllowIntersectAnd &&
             cast<DefInit>(P)->getDef()->getName() == "IntersectAnd")
           PrintFatalError("'IntersectAnd' only compatible with 'EnumAttr'");

diff  --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 2a246d60de6156..18e0b8fd135bb0 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -324,7 +324,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
     IS.ParamTys.push_back(TypeList->getElementAsRecord(Idx));
 
   // Parse the intrinsic properties.
-  ListInit *PropList = R->getValueAsListInit("IntrProperties");
+  const ListInit *PropList = R->getValueAsListInit("IntrProperties");
   for (unsigned i = 0, e = PropList->size(); i != e; ++i) {
     const Record *Property = PropList->getElementAsRecord(i);
     assert(Property->isSubClassOf("IntrinsicProperty") &&

diff  --git a/llvm/utils/TableGen/CodeEmitterGen.cpp b/llvm/utils/TableGen/CodeEmitterGen.cpp
index 4d356774f98dcc..be822c4815289c 100644
--- a/llvm/utils/TableGen/CodeEmitterGen.cpp
+++ b/llvm/utils/TableGen/CodeEmitterGen.cpp
@@ -348,7 +348,7 @@ CodeEmitterGen::getInstructionCases(const Record *R,
 void CodeEmitterGen::addInstructionCasesForEncoding(
     const Record *R, const Record *EncodingDef, const CodeGenTarget &Target,
     std::string &Case, std::string &BitOffsetCase) {
-  BitsInit *BI = EncodingDef->getValueAsBitsInit("Inst");
+  const BitsInit *BI = EncodingDef->getValueAsBitsInit("Inst");
 
   // Loop over all of the fields in the instruction, determining which are the
   // operands to the instruction.

diff  --git a/llvm/utils/TableGen/CodeGenMapTable.cpp b/llvm/utils/TableGen/CodeGenMapTable.cpp
index b599ee149bcd2b..7876db6f33dfdf 100644
--- a/llvm/utils/TableGen/CodeGenMapTable.cpp
+++ b/llvm/utils/TableGen/CodeGenMapTable.cpp
@@ -128,7 +128,7 @@ class InstrMap {
     // Ex: ValueCols = [['true'],['false']] -- it results two columns in the
     // table. First column requires all the instructions to have predSense
     // set to 'true' and second column requires it to be 'false'.
-    ListInit *ColValList = MapRec->getValueAsListInit("ValueCols");
+    const ListInit *ColValList = MapRec->getValueAsListInit("ValueCols");
 
     // Each instruction map must specify at least one column for it to be valid.
     if (ColValList->empty())
@@ -479,7 +479,7 @@ void MapTableEmitter::emitTablesWithFunc(raw_ostream &OS) {
   OS << "// " << InstrMapDesc.getName() << "\nLLVM_READONLY\n";
   OS << "int " << InstrMapDesc.getName() << "(uint16_t Opcode";
   if (ValueCols.size() > 1) {
-    for (Init *CF : ColFields->getValues()) {
+    for (const Init *CF : ColFields->getValues()) {
       std::string ColName = CF->getAsUnquotedString();
       OS << ", enum " << ColName << " in" << ColName;
     }

diff  --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index 751ac3dd0af10b..d2228c902a56b4 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -2639,7 +2639,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
       // If the operand has sub-operands, they may be provided by distinct
       // child patterns, so attempt to match each sub-operand separately.
       if (OperandNode->isSubClassOf("Operand")) {
-        DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
+        const DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
         if (unsigned NumArgs = MIOpInfo->getNumArgs()) {
           // But don't do that if the whole operand is being provided by
           // a single ComplexPattern-related Operand.
@@ -2786,11 +2786,11 @@ TreePattern::TreePattern(const Record *TheRec, const ListInit *RawPat,
                          bool isInput, CodeGenDAGPatterns &cdp)
     : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
       Infer(*this) {
-  for (Init *I : RawPat->getValues())
+  for (const Init *I : RawPat->getValues())
     Trees.push_back(ParseTreePattern(I, ""));
 }
 
-TreePattern::TreePattern(const Record *TheRec, DagInit *Pat, bool isInput,
+TreePattern::TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
                          CodeGenDAGPatterns &cdp)
     : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false),
       Infer(*this) {
@@ -2825,12 +2825,12 @@ void TreePattern::ComputeNamedNodes(TreePatternNode &N) {
     ComputeNamedNodes(N.getChild(i));
 }
 
-TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
+TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
                                                  StringRef OpName) {
   RecordKeeper &RK = TheInit->getRecordKeeper();
   // Here, we are creating new records (BitsInit->InitInit), so const_cast
   // TheInit back to non-const pointer.
-  if (DefInit *DI = dyn_cast<DefInit>(TheInit)) {
+  if (const DefInit *DI = dyn_cast<DefInit>(TheInit)) {
     const Record *R = DI->getDef();
 
     // Direct reference to a leaf DagNode or PatFrag?  Turn it into a
@@ -2838,8 +2838,9 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
     ///   (foo GPR, imm) -> (foo GPR, (imm))
     if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrags"))
       return ParseTreePattern(
-          DagInit::get(DI, nullptr,
-                       std::vector<std::pair<Init *, StringInit *>>()),
+          DagInit::get(
+              DI, nullptr,
+              std::vector<std::pair<const Init *, const StringInit *>>()),
           OpName);
 
     // Input argument?
@@ -2872,22 +2873,22 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
     return makeIntrusiveRefCnt<TreePatternNode>(TheInit, 1);
   }
 
-  if (BitsInit *BI = dyn_cast<BitsInit>(TheInit)) {
+  if (const BitsInit *BI = dyn_cast<BitsInit>(TheInit)) {
     // Turn this into an IntInit.
-    Init *II = BI->convertInitializerTo(IntRecTy::get(RK));
+    const Init *II = BI->convertInitializerTo(IntRecTy::get(RK));
     if (!II || !isa<IntInit>(II))
       error("Bits value must be constants!");
     return II ? ParseTreePattern(II, OpName) : nullptr;
   }
 
-  DagInit *Dag = dyn_cast<DagInit>(TheInit);
+  const DagInit *Dag = dyn_cast<DagInit>(TheInit);
   if (!Dag) {
     TheInit->print(errs());
     error("Pattern has unexpected init kind!");
     return nullptr;
   }
 
-  auto ParseCastOperand = [this](DagInit *Dag, StringRef OpName) {
+  auto ParseCastOperand = [this](const DagInit *Dag, StringRef OpName) {
     if (Dag->getNumArgs() != 1)
       error("Type cast only takes one operand!");
 
@@ -2897,7 +2898,7 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
     return ParseTreePattern(Dag->getArg(0), Dag->getArgNameStr(0));
   };
 
-  if (ListInit *LI = dyn_cast<ListInit>(Dag->getOperator())) {
+  if (const ListInit *LI = dyn_cast<ListInit>(Dag->getOperator())) {
     // If the operator is a list (of value types), then this must be "type cast"
     // of a leaf node with multiple results.
     TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
@@ -2915,7 +2916,7 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
     return New;
   }
 
-  DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator());
+  const DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator());
   if (!OpDef) {
     error("Pattern has unexpected operator type!");
     return nullptr;
@@ -3252,7 +3253,7 @@ void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) {
     if (OutFrags != Frag->isSubClassOf("OutPatFrag"))
       continue;
 
-    ListInit *LI = Frag->getValueAsListInit("Fragments");
+    const ListInit *LI = Frag->getValueAsListInit("Fragments");
     TreePattern *P = (PatternFragments[Frag] = std::make_unique<TreePattern>(
                           Frag, LI, !Frag->isSubClassOf("OutPatFrag"), *this))
                          .get();
@@ -3268,8 +3269,8 @@ void CodeGenDAGPatterns::ParsePatternFragments(bool OutFrags) {
       P->error("Cannot have unnamed 'node' values in pattern fragment!");
 
     // Parse the operands list.
-    DagInit *OpsList = Frag->getValueAsDag("Operands");
-    DefInit *OpsOp = dyn_cast<DefInit>(OpsList->getOperator());
+    const DagInit *OpsList = Frag->getValueAsDag("Operands");
+    const DefInit *OpsOp = dyn_cast<DefInit>(OpsList->getOperator());
     // Special cases: ops == outs == ins. Different names are used to
     // improve readability.
     if (!OpsOp || (OpsOp->getDef()->getName() != "ops" &&
@@ -3336,18 +3337,18 @@ void CodeGenDAGPatterns::ParseDefaultOperands() {
 
   // Find some SDNode.
   assert(!SDNodes.empty() && "No SDNodes parsed?");
-  Init *SomeSDNode = SDNodes.begin()->first->getDefInit();
+  const Init *SomeSDNode = SDNodes.begin()->first->getDefInit();
 
   for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {
-    DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
+    const DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
 
     // Clone the DefaultInfo dag node, changing the operator from 'ops' to
     // SomeSDnode so that we can parse this.
-    std::vector<std::pair<Init *, StringInit *>> Ops;
+    std::vector<std::pair<const Init *, const StringInit *>> Ops;
     for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
       Ops.push_back(
           std::pair(DefaultInfo->getArg(op), DefaultInfo->getArgName(op)));
-    DagInit *DI = DagInit::get(SomeSDNode, nullptr, Ops);
+    const DagInit *DI = DagInit::get(SomeSDNode, nullptr, Ops);
 
     // Create a TreePattern to parse this.
     TreePattern P(DefaultOps[i], DI, false, *this);
@@ -3694,8 +3695,8 @@ static bool InferFromPattern(CodeGenInstruction &InstInfo,
 
 /// hasNullFragReference - Return true if the DAG has any reference to the
 /// null_frag operator.
-static bool hasNullFragReference(DagInit *DI) {
-  DefInit *OpDef = dyn_cast<DefInit>(DI->getOperator());
+static bool hasNullFragReference(const DagInit *DI) {
+  const DefInit *OpDef = dyn_cast<DefInit>(DI->getOperator());
   if (!OpDef)
     return false;
   const Record *Operator = OpDef->getDef();
@@ -3708,7 +3709,7 @@ static bool hasNullFragReference(DagInit *DI) {
     if (auto Arg = dyn_cast<DefInit>(DI->getArg(i)))
       if (Arg->getDef()->getName() == "null_frag")
         return true;
-    DagInit *Arg = dyn_cast<DagInit>(DI->getArg(i));
+    const DagInit *Arg = dyn_cast<DagInit>(DI->getArg(i));
     if (Arg && hasNullFragReference(Arg))
       return true;
   }
@@ -3718,9 +3719,9 @@ static bool hasNullFragReference(DagInit *DI) {
 
 /// hasNullFragReference - Return true if any DAG in the list references
 /// the null_frag operator.
-static bool hasNullFragReference(ListInit *LI) {
-  for (Init *I : LI->getValues()) {
-    DagInit *DI = dyn_cast<DagInit>(I);
+static bool hasNullFragReference(const ListInit *LI) {
+  for (const Init *I : LI->getValues()) {
+    const DagInit *DI = dyn_cast<DagInit>(I);
     assert(DI && "non-dag in an instruction Pattern list?!");
     if (hasNullFragReference(DI))
       return true;
@@ -3948,7 +3949,7 @@ void CodeGenDAGPatterns::parseInstructionPattern(CodeGenInstruction &CGI,
 /// resolved instructions.
 void CodeGenDAGPatterns::ParseInstructions() {
   for (const Record *Instr : Records.getAllDerivedDefinitions("Instruction")) {
-    ListInit *LI = nullptr;
+    const ListInit *LI = nullptr;
 
     if (isa<ListInit>(Instr->getValueInit("Pattern")))
       LI = Instr->getValueAsListInit("Pattern");
@@ -4310,7 +4311,7 @@ void CodeGenDAGPatterns::ParseOnePattern(
   TreePattern Temp(Result.getRecord(), DstShared, false, *this);
   Temp.InferAllTypes();
 
-  ListInit *Preds = TheDef->getValueAsListInit("Predicates");
+  const ListInit *Preds = TheDef->getValueAsListInit("Predicates");
   int Complexity = TheDef->getValueAsInt("AddedComplexity");
 
   if (PatternRewriter)
@@ -4345,7 +4346,7 @@ void CodeGenDAGPatterns::ParseOnePattern(
 
 void CodeGenDAGPatterns::ParsePatterns() {
   for (const Record *CurPattern : Records.getAllDerivedDefinitions("Pattern")) {
-    DagInit *Tree = CurPattern->getValueAsDag("PatternToMatch");
+    const DagInit *Tree = CurPattern->getValueAsDag("PatternToMatch");
 
     // If the pattern references the null_frag, there's nothing to do.
     if (hasNullFragReference(Tree))
@@ -4353,7 +4354,7 @@ void CodeGenDAGPatterns::ParsePatterns() {
 
     TreePattern Pattern(CurPattern, Tree, true, *this);
 
-    ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs");
+    const ListInit *LI = CurPattern->getValueAsListInit("ResultInstrs");
     if (LI->empty())
       continue; // no pattern.
 

diff  --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
index 1da7deae0a8472..f85753ff5ac80b 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
@@ -910,7 +910,7 @@ class TreePattern {
   /// current record.
   TreePattern(const Record *TheRec, const ListInit *RawPat, bool isInput,
               CodeGenDAGPatterns &ise);
-  TreePattern(const Record *TheRec, DagInit *Pat, bool isInput,
+  TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput,
               CodeGenDAGPatterns &ise);
   TreePattern(const Record *TheRec, TreePatternNodePtr Pat, bool isInput,
               CodeGenDAGPatterns &ise);
@@ -975,7 +975,7 @@ class TreePattern {
   void dump() const;
 
 private:
-  TreePatternNodePtr ParseTreePattern(Init *DI, StringRef OpName);
+  TreePatternNodePtr ParseTreePattern(const Init *DI, StringRef OpName);
   void ComputeNamedNodes();
   void ComputeNamedNodes(TreePatternNode &N);
 };
@@ -1055,7 +1055,7 @@ class DAGInstruction {
 /// processed to produce isel.
 class PatternToMatch {
   const Record *SrcRecord;       // Originating Record for the pattern.
-  ListInit *Predicates;          // Top level predicate conditions to match.
+  const ListInit *Predicates;    // Top level predicate conditions to match.
   TreePatternNodePtr SrcPattern; // Source pattern to match.
   TreePatternNodePtr DstPattern; // Resulting pattern.
   std::vector<const Record *> Dstregs; // Physical register defs being matched.
@@ -1065,7 +1065,7 @@ class PatternToMatch {
   unsigned ID;            // Unique ID for the record.
 
 public:
-  PatternToMatch(const Record *srcrecord, ListInit *preds,
+  PatternToMatch(const Record *srcrecord, const ListInit *preds,
                  TreePatternNodePtr src, TreePatternNodePtr dst,
                  ArrayRef<const Record *> dstregs, int complexity, unsigned uid,
                  bool ignore, const Twine &hwmodefeatures = "")
@@ -1074,7 +1074,7 @@ class PatternToMatch {
         AddedComplexity(complexity), GISelShouldIgnore(ignore), ID(uid) {}
 
   const Record *getSrcRecord() const { return SrcRecord; }
-  ListInit *getPredicates() const { return Predicates; }
+  const ListInit *getPredicates() const { return Predicates; }
   TreePatternNode &getSrcPattern() const { return *SrcPattern; }
   TreePatternNodePtr getSrcPatternShared() const { return SrcPattern; }
   TreePatternNode &getDstPattern() const { return *DstPattern; }

diff  --git a/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp b/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp
index 69e00295bf5bb5..293ed76e0f5026 100644
--- a/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp
@@ -67,7 +67,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(const DagInit *Result,
   // Handle explicit registers.
   if (ADI && ADI->getDef()->isSubClassOf("Register")) {
     if (InstOpRec->isSubClassOf("OptionalDefOperand")) {
-      DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
+      const DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo");
       // The operand info should only have a single (register) entry. We
       // want the register class of it.
       InstOpRec = cast<DefInit>(DI->getArg(0))->getDef();
@@ -172,7 +172,7 @@ CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T)
   AsmString = std::string(R->getValueAsString("AsmString"));
 
   // Verify that the root of the result is an instruction.
-  DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
+  const DefInit *DI = dyn_cast<DefInit>(Result->getOperator());
   if (!DI || !DI->getDef()->isSubClassOf("Instruction"))
     PrintFatalError(R->getLoc(),
                     "result of inst alias should be an instruction");

diff  --git a/llvm/utils/TableGen/Common/CodeGenInstAlias.h b/llvm/utils/TableGen/Common/CodeGenInstAlias.h
index 00680b0f2da7de..f045b9f6c19905 100644
--- a/llvm/utils/TableGen/Common/CodeGenInstAlias.h
+++ b/llvm/utils/TableGen/Common/CodeGenInstAlias.h
@@ -39,7 +39,7 @@ class CodeGenInstAlias {
   std::string AsmString;
 
   /// Result - The result instruction.
-  DagInit *Result;
+  const DagInit *Result;
 
   /// ResultInst - The instruction generated by the alias (decoded from
   /// Result).

diff  --git a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
index 7fedc17701c472..1c0ab594d9310a 100644
--- a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp
@@ -27,9 +27,9 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
   hasOptionalDef = false;
   isVariadic = false;
 
-  DagInit *OutDI = R->getValueAsDag("OutOperandList");
+  const DagInit *OutDI = R->getValueAsDag("OutOperandList");
 
-  if (DefInit *Init = dyn_cast<DefInit>(OutDI->getOperator())) {
+  if (const DefInit *Init = dyn_cast<DefInit>(OutDI->getOperator())) {
     if (Init->getDef()->getName() != "outs")
       PrintFatalError(R->getLoc(),
                       R->getName() +
@@ -40,8 +40,8 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
 
   NumDefs = OutDI->getNumArgs();
 
-  DagInit *InDI = R->getValueAsDag("InOperandList");
-  if (DefInit *Init = dyn_cast<DefInit>(InDI->getOperator())) {
+  const DagInit *InDI = R->getValueAsDag("InOperandList");
+  if (const DefInit *Init = dyn_cast<DefInit>(InDI->getOperator())) {
     if (Init->getDef()->getName() != "ins")
       PrintFatalError(R->getLoc(),
                       R->getName() +
@@ -56,7 +56,7 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
   OperandList.reserve(e);
   bool VariadicOuts = false;
   for (unsigned i = 0; i != e; ++i) {
-    Init *ArgInit;
+    const Init *ArgInit;
     StringRef ArgName;
     if (i < NumDefs) {
       ArgInit = OutDI->getArg(i);
@@ -66,11 +66,11 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
       ArgName = InDI->getArgNameStr(i - NumDefs);
     }
 
-    DagInit *SubArgDag = dyn_cast<DagInit>(ArgInit);
+    const DagInit *SubArgDag = dyn_cast<DagInit>(ArgInit);
     if (SubArgDag)
       ArgInit = SubArgDag->getOperator();
 
-    DefInit *Arg = dyn_cast<DefInit>(ArgInit);
+    const DefInit *Arg = dyn_cast<DefInit>(ArgInit);
     if (!Arg)
       PrintFatalError(R->getLoc(), "Illegal operand for the '" + R->getName() +
                                        "' instruction!");
@@ -81,7 +81,7 @@ CGIOperandList::CGIOperandList(const Record *R) : TheDef(R) {
     std::string OperandType = "OPERAND_UNKNOWN";
     std::string OperandNamespace = "MCOI";
     unsigned NumOps = 1;
-    DagInit *MIOpInfo = nullptr;
+    const DagInit *MIOpInfo = nullptr;
     if (Rec->isSubClassOf("RegisterOperand")) {
       PrintMethod = std::string(Rec->getValueAsString("PrintMethod"));
       OperandType = std::string(Rec->getValueAsString("OperandType"));
@@ -280,7 +280,7 @@ CGIOperandList::ParseOperandName(StringRef Op, bool AllowWholeOp) {
   }
 
   // Find the suboperand number involved.
-  DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
+  const DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
   if (!MIOpInfo)
     PrintFatalError(TheDef->getLoc(), TheDef->getName() +
                                           ": unknown suboperand name in '" +
@@ -581,11 +581,11 @@ std::string CodeGenInstruction::FlattenAsmStringVariants(StringRef Cur,
 
 bool CodeGenInstruction::isOperandImpl(StringRef OpListName, unsigned i,
                                        StringRef PropertyName) const {
-  DagInit *ConstraintList = TheDef->getValueAsDag(OpListName);
+  const DagInit *ConstraintList = TheDef->getValueAsDag(OpListName);
   if (!ConstraintList || i >= ConstraintList->getNumArgs())
     return false;
 
-  DefInit *Constraint = dyn_cast<DefInit>(ConstraintList->getArg(i));
+  const DefInit *Constraint = dyn_cast<DefInit>(ConstraintList->getArg(i));
   if (!Constraint)
     return false;
 

diff  --git a/llvm/utils/TableGen/Common/CodeGenInstruction.h b/llvm/utils/TableGen/Common/CodeGenInstruction.h
index 18294b157fedb1..a799d023b1af43 100644
--- a/llvm/utils/TableGen/Common/CodeGenInstruction.h
+++ b/llvm/utils/TableGen/Common/CodeGenInstruction.h
@@ -110,7 +110,7 @@ class CGIOperandList {
 
     /// MIOperandInfo - Default MI operand type. Note an operand may be made
     /// up of multiple MI operands.
-    DagInit *MIOperandInfo;
+    const DagInit *MIOperandInfo;
 
     /// Constraint info for this operand.  This operand can have pieces, so we
     /// track constraint info for each.
@@ -118,7 +118,7 @@ class CGIOperandList {
 
     OperandInfo(const Record *R, const std::string &N, const std::string &PMN,
                 const std::string &OT, unsigned MION, unsigned MINO,
-                DagInit *MIOI)
+                const DagInit *MIOI)
         : Rec(R), Name(N), SubOpNames(MINO), PrinterMethodName(PMN),
           EncoderMethodNames(MINO), OperandType(OT), MIOperandNo(MION),
           MINumOperands(MINO), DoNotEncode(MINO), MIOperandInfo(MIOI),

diff  --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index b53492dafb25b6..9e1ebf32c46444 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -630,7 +630,7 @@ struct TupleExpander : SetTheory::Expander {
     std::vector<const Record *> Indices =
         Def->getValueAsListOfDefs("SubRegIndices");
     unsigned Dim = Indices.size();
-    ListInit *SubRegs = Def->getValueAsListInit("SubRegs");
+    const ListInit *SubRegs = Def->getValueAsListInit("SubRegs");
     if (Dim != SubRegs->size())
       PrintFatalError(Def->getLoc(), "SubRegIndices and SubRegs size mismatch");
     if (Dim < 2)
@@ -669,11 +669,11 @@ struct TupleExpander : SetTheory::Expander {
       }
 
       // Take the cost list of the first register in the tuple.
-      ListInit *CostList = Proto->getValueAsListInit("CostPerUse");
-      SmallVector<Init *, 2> CostPerUse;
+      const ListInit *CostList = Proto->getValueAsListInit("CostPerUse");
+      SmallVector<const Init *, 2> CostPerUse;
       CostPerUse.insert(CostPerUse.end(), CostList->begin(), CostList->end());
 
-      StringInit *AsmName = StringInit::get(RK, "");
+      const StringInit *AsmName = StringInit::get(RK, "");
       if (!RegNames.empty()) {
         if (RegNames.size() <= n)
           PrintFatalError(Def->getLoc(),
@@ -776,7 +776,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
 
   // Allocation order 0 is the full set. AltOrders provides others.
   const SetTheory::RecVec *Elements = RegBank.getSets().expand(R);
-  ListInit *AltOrders = R->getValueAsListInit("AltOrders");
+  const ListInit *AltOrders = R->getValueAsListInit("AltOrders");
   Orders.resize(1 + AltOrders->size());
 
   // Default allocation order always contains all registers.
@@ -808,7 +808,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
   Namespace = R->getValueAsString("Namespace");
 
   if (const RecordVal *RV = R->getValue("RegInfos"))
-    if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue()))
+    if (const DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue()))
       RSI = RegSizeInfoByHwMode(DI->getDef(), RegBank.getHwModes());
   unsigned Size = R->getValueAsInt("Size");
   assert((RSI.hasDefault() || Size != 0 || VTs[0].isSimple()) &&
@@ -831,9 +831,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
 
   GlobalPriority = R->getValueAsBit("GlobalPriority");
 
-  BitsInit *TSF = R->getValueAsBitsInit("TSFlags");
+  const BitsInit *TSF = R->getValueAsBitsInit("TSFlags");
   for (unsigned I = 0, E = TSF->getNumBits(); I != E; ++I) {
-    BitInit *Bit = cast<BitInit>(TSF->getBit(I));
+    const BitInit *Bit = cast<BitInit>(TSF->getBit(I));
     TSFlags |= uint8_t(Bit->getValue()) << I;
   }
 }

diff  --git a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
index 9c37fbe9c4b427..06d82daebac0d5 100644
--- a/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenSchedule.cpp
@@ -86,8 +86,8 @@ struct InstRegexOp : public SetTheory::Operator {
     auto Pseudos = Instructions.slice(NumGeneric, NumPseudos);
     auto NonPseudos = Instructions.slice(NumGeneric + NumPseudos);
 
-    for (Init *Arg : Expr->getArgs()) {
-      StringInit *SI = dyn_cast<StringInit>(Arg);
+    for (const Init *Arg : Expr->getArgs()) {
+      const StringInit *SI = dyn_cast<StringInit>(Arg);
       if (!SI)
         PrintFatalError(Loc, "instregex requires pattern string: " +
                                  Expr->getAsString());
@@ -1828,13 +1828,14 @@ void CodeGenSchedModels::collectRegisterFiles() {
 
     ConstRecVec RegisterClasses = RF->getValueAsListOfDefs("RegClasses");
     std::vector<int64_t> RegisterCosts = RF->getValueAsListOfInts("RegCosts");
-    ListInit *MoveElimInfo = RF->getValueAsListInit("AllowMoveElimination");
+    const ListInit *MoveElimInfo =
+        RF->getValueAsListInit("AllowMoveElimination");
     for (unsigned I = 0, E = RegisterClasses.size(); I < E; ++I) {
       int Cost = RegisterCosts.size() > I ? RegisterCosts[I] : 1;
 
       bool AllowMoveElim = false;
       if (MoveElimInfo->size() > I) {
-        BitInit *Val = cast<BitInit>(MoveElimInfo->getElement(I));
+        const BitInit *Val = cast<BitInit>(MoveElimInfo->getElement(I));
         AllowMoveElim = Val->getValue();
       }
 

diff  --git a/llvm/utils/TableGen/Common/CodeGenTarget.cpp b/llvm/utils/TableGen/Common/CodeGenTarget.cpp
index 9883cf5cf35fbd..b358518c4290b0 100644
--- a/llvm/utils/TableGen/Common/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenTarget.cpp
@@ -361,16 +361,16 @@ void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
         R->getValueAsBit("isPseudo"))
       continue;
 
-    BitsInit *BI = R->getValueAsBitsInit("Inst");
+    const BitsInit *BI = R->getValueAsBitsInit("Inst");
 
     unsigned numBits = BI->getNumBits();
 
-    SmallVector<Init *, 16> NewBits(numBits);
+    SmallVector<const Init *, 16> NewBits(numBits);
 
     for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
       unsigned bitSwapIdx = numBits - bit - 1;
-      Init *OrigBit = BI->getBit(bit);
-      Init *BitSwap = BI->getBit(bitSwapIdx);
+      const Init *OrigBit = BI->getBit(bit);
+      const Init *BitSwap = BI->getBit(bitSwapIdx);
       NewBits[bit] = BitSwap;
       NewBits[bitSwapIdx] = OrigBit;
     }
@@ -380,7 +380,7 @@ void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
     }
 
     RecordKeeper &MutableRC = const_cast<RecordKeeper &>(Records);
-    BitsInit *NewBI = BitsInit::get(MutableRC, NewBits);
+    const BitsInit *NewBI = BitsInit::get(MutableRC, NewBits);
 
     // Update the bits in reversed order so that emitters will get the correct
     // endianness.

diff  --git a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
index 9dcc5f43a2b53d..364b80c36bac8d 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
@@ -57,7 +57,7 @@ bool PatternParser::parsePatternList(
   // The match section consists of a list of matchers and predicates. Parse each
   // one and add the equivalent GIMatchDag nodes, predicates, and edges.
   for (unsigned I = 0; I < List.getNumArgs(); ++I) {
-    Init *Arg = List.getArg(I);
+    const Init *Arg = List.getArg(I);
     std::string Name = List.getArgName(I)
                            ? List.getArgName(I)->getValue().str()
                            : ("__" + AnonPatNamePrefix + "_" + Twine(I)).str();
@@ -138,7 +138,7 @@ PatternParser::parseInstructionPattern(const Init &Arg, StringRef Name) {
     return nullptr;
 
   for (unsigned K = 0; K < DagPat->getNumArgs(); ++K) {
-    Init *Arg = DagPat->getArg(K);
+    const Init *Arg = DagPat->getArg(K);
     if (auto *DagArg = getDagWithSpecificOperator(*Arg, "MIFlags")) {
       if (!parseInstructionPatternMIFlags(*Pat, DagArg))
         return nullptr;

diff  --git a/llvm/utils/TableGen/Common/GlobalISel/Patterns.cpp b/llvm/utils/TableGen/Common/GlobalISel/Patterns.cpp
index 52f7b0fcbd624e..0b84a9bbe6343f 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/Patterns.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/Patterns.cpp
@@ -382,7 +382,7 @@ bool CodeGenInstructionPattern::hasVariadicDefs() const {
   if (I.variadicOpsAreDefs)
     return true;
 
-  DagInit *OutOps = I.TheDef->getValueAsDag("OutOperandList");
+  const DagInit *OutOps = I.TheDef->getValueAsDag("OutOperandList");
   if (OutOps->arg_empty())
     return false;
 

diff  --git a/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp b/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp
index 9b454cf7944620..0a835bd7b0bc0c 100644
--- a/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp
+++ b/llvm/utils/TableGen/Common/VarLenCodeEmitterGen.cpp
@@ -100,7 +100,8 @@ class VarLenCodeEmitterGen {
 
 // Get the name of custom encoder or decoder, if there is any.
 // Returns `{encoder name, decoder name}`.
-static std::pair<StringRef, StringRef> getCustomCoders(ArrayRef<Init *> Args) {
+static std::pair<StringRef, StringRef>
+getCustomCoders(ArrayRef<const Init *> Args) {
   std::pair<StringRef, StringRef> Result;
   for (const auto *Arg : Args) {
     const auto *DI = dyn_cast<DagInit>(Arg);
@@ -187,8 +188,8 @@ void VarLenInst::buildRec(const DagInit *DI) {
       PrintFatalError(TheDef->getLoc(),
                       "Expecting at least 3 arguments for `slice`");
     HasDynamicSegment = true;
-    Init *OperandName = DI->getArg(0), *HiBit = DI->getArg(1),
-         *LoBit = DI->getArg(2);
+    const Init *OperandName = DI->getArg(0), *HiBit = DI->getArg(1),
+               *LoBit = DI->getArg(2);
     if (!isa<StringInit>(OperandName) || !isa<IntInit>(HiBit) ||
         !isa<IntInit>(LoBit))
       PrintFatalError(TheDef->getLoc(), "Invalid argument types for `slice`");
@@ -211,7 +212,7 @@ void VarLenInst::buildRec(const DagInit *DI) {
 
     if (NeedSwap) {
       // Normalization: Hi bit should always be the second argument.
-      Init *const NewArgs[] = {OperandName, LoBit, HiBit};
+      const Init *const NewArgs[] = {OperandName, LoBit, HiBit};
       Segments.push_back({NumBits,
                           DagInit::get(DI->getOperator(), nullptr, NewArgs, {}),
                           CustomEncoder, CustomDecoder});
@@ -241,7 +242,7 @@ void VarLenCodeEmitterGen::run(raw_ostream &OS) {
         for (const auto [Mode, EncodingDef] : EBM) {
           Modes.insert({Mode, "_" + HWM.getMode(Mode).Name.str()});
           const RecordVal *RV = EncodingDef->getValue("Inst");
-          DagInit *DI = cast<DagInit>(RV->getValue());
+          const DagInit *DI = cast<DagInit>(RV->getValue());
           VarLenInsts[R].insert({Mode, VarLenInst(DI, RV)});
         }
         continue;

diff  --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp
index 5ee02f4fbf499c..e087ff07266380 100644
--- a/llvm/utils/TableGen/CompressInstEmitter.cpp
+++ b/llvm/utils/TableGen/CompressInstEmitter.cpp
@@ -248,7 +248,8 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
                             "' in the corresponding instruction operand!");
 
       OperandMap[I].Kind = OpData::Operand;
-    } else if (IntInit *II = dyn_cast<IntInit>(Dag->getArg(I - TiedCount))) {
+    } else if (const IntInit *II =
+                   dyn_cast<IntInit>(Dag->getArg(I - TiedCount))) {
       // Validate that corresponding instruction operand expects an immediate.
       if (Inst.Operands[I].Rec->isSubClassOf("RegisterClass"))
         PrintFatalError(
@@ -428,7 +429,7 @@ void CompressInstEmitter::createInstOperandMapping(
 ///   Instruction type and generate a warning.
 void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
   // Validate input Dag operands.
-  DagInit *SourceDag = Rec->getValueAsDag("Input");
+  const DagInit *SourceDag = Rec->getValueAsDag("Input");
   assert(SourceDag && "Missing 'Input' in compress pattern!");
   LLVM_DEBUG(dbgs() << "Input: " << *SourceDag << "\n");
 
@@ -438,7 +439,7 @@ void CompressInstEmitter::evaluateCompressPat(const Record *Rec) {
   verifyDagOpCount(SourceInst, SourceDag, true);
 
   // Validate output Dag operands.
-  DagInit *DestDag = Rec->getValueAsDag("Output");
+  const DagInit *DestDag = Rec->getValueAsDag("Output");
   assert(DestDag && "Missing 'Output' in compress pattern!");
   LLVM_DEBUG(dbgs() << "Output: " << *DestDag << "\n");
 

diff  --git a/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/llvm/utils/TableGen/DAGISelMatcherGen.cpp
index 31c46d5fcbd0ac..09c1ee4fd0f3c2 100644
--- a/llvm/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherGen.cpp
@@ -844,7 +844,7 @@ void MatcherGen::EmitResultInstructionAsOperand(
     // children may themselves emit multiple MI operands.
     unsigned NumSubOps = 1;
     if (OperandNode->isSubClassOf("Operand")) {
-      DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
+      const DagInit *MIOpInfo = OperandNode->getValueAsDag("MIOperandInfo");
       if (unsigned NumArgs = MIOpInfo->getNumArgs())
         NumSubOps = NumArgs;
     }

diff  --git a/llvm/utils/TableGen/DFAEmitter.cpp b/llvm/utils/TableGen/DFAEmitter.cpp
index 7d274a1cf632e5..264cccf6ac0ca6 100644
--- a/llvm/utils/TableGen/DFAEmitter.cpp
+++ b/llvm/utils/TableGen/DFAEmitter.cpp
@@ -306,7 +306,7 @@ StringRef Automaton::getActionSymbolType(StringRef A) {
 }
 
 Transition::Transition(const Record *R, Automaton *Parent) {
-  BitsInit *NewStateInit = R->getValueAsBitsInit("NewState");
+  const BitsInit *NewStateInit = R->getValueAsBitsInit("NewState");
   NewState = 0;
   assert(NewStateInit->getNumBits() <= sizeof(uint64_t) * 8 &&
          "State cannot be represented in 64 bits!");

diff  --git a/llvm/utils/TableGen/DXILEmitter.cpp b/llvm/utils/TableGen/DXILEmitter.cpp
index 06bf7a0c0a8372..0598baea9be7a2 100644
--- a/llvm/utils/TableGen/DXILEmitter.cpp
+++ b/llvm/utils/TableGen/DXILEmitter.cpp
@@ -160,7 +160,7 @@ DXILOperationDesc::DXILOperationDesc(const Record *R) {
 
   const RecordVal *RV = R->getValue("LLVMIntrinsic");
   if (RV && RV->getValue()) {
-    if (DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
+    if (const DefInit *DI = dyn_cast<DefInit>(RV->getValue())) {
       auto *IntrinsicDef = DI->getDef();
       auto DefName = IntrinsicDef->getName();
       assert(DefName.starts_with("int_") && "invalid intrinsic name");

diff  --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index d4f4e3fa684c32..4d2320b31ea94a 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -208,7 +208,7 @@ static int Value(bit_value_t V) {
 }
 
 static bit_value_t bitFromBits(const BitsInit &bits, unsigned index) {
-  if (BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
+  if (const BitInit *bit = dyn_cast<BitInit>(bits.getBit(index)))
     return bit->getValue() ? BIT_TRUE : BIT_FALSE;
 
   // The bit is uninitialized.
@@ -234,14 +234,14 @@ static void dumpBits(raw_ostream &OS, const BitsInit &bits) {
   }
 }
 
-static BitsInit &getBitsField(const Record &def, StringRef str) {
+static const BitsInit &getBitsField(const Record &def, StringRef str) {
   const RecordVal *RV = def.getValue(str);
-  if (BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
+  if (const BitsInit *Bits = dyn_cast<BitsInit>(RV->getValue()))
     return *Bits;
 
   // variable length instruction
   VarLenInst VLI = VarLenInst(cast<DagInit>(RV->getValue()), RV);
-  SmallVector<Init *, 16> Bits;
+  SmallVector<const Init *, 16> Bits;
 
   for (const auto &SI : VLI) {
     if (const BitsInit *BI = dyn_cast<BitsInit>(SI.Value)) {
@@ -459,7 +459,7 @@ class FilterChooser {
   // Populates the insn given the uid.
   void insnWithID(insn_t &Insn, unsigned Opcode) const {
     const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;
-    BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
+    const BitsInit &Bits = getBitsField(*EncodingDef, "Inst");
     Insn.resize(std::max(BitWidth, Bits.getNumBits()), BIT_UNSET);
     // We may have a SoftFail bitmask, which specifies a mask where an encoding
     // may 
diff er from the value in "Inst" and yet still be valid, but the
@@ -1290,7 +1290,7 @@ bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
 }
 
 bool FilterChooser::emitPredicateMatch(raw_ostream &OS, unsigned Opc) const {
-  ListInit *Predicates =
+  const ListInit *Predicates =
       AllInstructions[Opc].EncodingDef->getValueAsListInit("Predicates");
   bool IsFirstEmission = true;
   for (unsigned i = 0; i < Predicates->size(); ++i) {
@@ -1374,11 +1374,11 @@ void FilterChooser::emitSoftFailTableEntry(DecoderTableInfo &TableInfo,
                                            unsigned Opc) const {
   const Record *EncodingDef = AllInstructions[Opc].EncodingDef;
   const RecordVal *RV = EncodingDef->getValue("SoftFail");
-  BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
+  const BitsInit *SFBits = RV ? dyn_cast<BitsInit>(RV->getValue()) : nullptr;
 
   if (!SFBits)
     return;
-  BitsInit *InstBits = EncodingDef->getValueAsBitsInit("Inst");
+  const BitsInit *InstBits = EncodingDef->getValueAsBitsInit("Inst");
 
   APInt PositiveMask(BitWidth, 0ULL);
   APInt NegativeMask(BitWidth, 0ULL);
@@ -1886,7 +1886,7 @@ OperandInfo getOpInfo(const Record *TypeRecord) {
 
   const RecordVal *HasCompleteDecoderVal =
       TypeRecord->getValue("hasCompleteDecoder");
-  BitInit *HasCompleteDecoderBit =
+  const BitInit *HasCompleteDecoderBit =
       HasCompleteDecoderVal
           ? dyn_cast<BitInit>(HasCompleteDecoderVal->getValue())
           : nullptr;
@@ -1976,10 +1976,10 @@ static void addOneOperandFields(const Record &EncodingDef, const BitsInit &Bits,
             OpInfo.InitValue |= 1ULL << I;
 
   for (unsigned I = 0, J = 0; I != Bits.getNumBits(); I = J) {
-    VarInit *Var;
+    const VarInit *Var;
     unsigned Offset = 0;
     for (; J != Bits.getNumBits(); ++J) {
-      VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
+      const VarBitInit *BJ = dyn_cast<VarBitInit>(Bits.getBit(J));
       if (BJ) {
         Var = dyn_cast<VarInit>(BJ->getBitVar());
         if (I == J)
@@ -2010,7 +2010,7 @@ populateInstruction(const CodeGenTarget &Target, const Record &EncodingDef,
   // We are bound to fail!  For proper disassembly, the well-known encoding bits
   // of the instruction must be fully specified.
 
-  BitsInit &Bits = getBitsField(EncodingDef, "Inst");
+  const BitsInit &Bits = getBitsField(EncodingDef, "Inst");
   if (Bits.allInComplete())
     return 0;
 
@@ -2035,9 +2035,9 @@ populateInstruction(const CodeGenTarget &Target, const Record &EncodingDef,
   // Gather the outputs/inputs of the instruction, so we can find their
   // positions in the encoding.  This assumes for now that they appear in the
   // MCInst in the order that they're listed.
-  std::vector<std::pair<Init *, StringRef>> InOutOperands;
-  DagInit *Out = Def.getValueAsDag("OutOperandList");
-  DagInit *In = Def.getValueAsDag("InOperandList");
+  std::vector<std::pair<const Init *, StringRef>> InOutOperands;
+  const DagInit *Out = Def.getValueAsDag("OutOperandList");
+  const DagInit *In = Def.getValueAsDag("InOperandList");
   for (const auto &[Idx, Arg] : enumerate(Out->getArgs()))
     InOutOperands.push_back(std::pair(Arg, Out->getArgNameStr(Idx)));
   for (const auto &[Idx, Arg] : enumerate(In->getArgs()))
@@ -2069,7 +2069,7 @@ populateInstruction(const CodeGenTarget &Target, const Record &EncodingDef,
   } else {
     // For each operand, see if we can figure out where it is encoded.
     for (const auto &Op : InOutOperands) {
-      Init *OpInit = Op.first;
+      const Init *OpInit = Op.first;
       StringRef OpName = Op.second;
 
       // We're ready to find the instruction encoding locations for this
@@ -2077,7 +2077,7 @@ populateInstruction(const CodeGenTarget &Target, const Record &EncodingDef,
 
       // First, find the operand type ("OpInit"), and sub-op names
       // ("SubArgDag") if present.
-      DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
+      const DagInit *SubArgDag = dyn_cast<DagInit>(OpInit);
       if (SubArgDag)
         OpInit = SubArgDag->getOperator();
       const Record *OpTypeRec = cast<DefInit>(OpInit)->getDef();
@@ -2521,7 +2521,7 @@ namespace llvm {
   for (const auto &NumberedInstruction : NumberedInstructions) {
     const Record *InstDef = NumberedInstruction->TheDef;
     if (const RecordVal *RV = InstDef->getValue("EncodingInfos")) {
-      if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
+      if (const DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
         EncodingInfoByHwMode EBM(DI->getDef(), HWM);
         for (auto &[ModeId, Encoding] : EBM) {
           // DecoderTables with DefaultMode should not have any suffix.

diff  --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
index 2524a443f3454d..424f1ccb067f90 100644
--- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
@@ -1375,7 +1375,7 @@ bool CombineRuleBuilder::addFeaturePredicates(RuleMatcher &M) {
   if (!RuleDef.getValue("Predicates"))
     return true;
 
-  ListInit *Preds = RuleDef.getValueAsListInit("Predicates");
+  const ListInit *Preds = RuleDef.getValueAsListInit("Predicates");
   for (const Init *PI : Preds->getValues()) {
     const DefInit *Pred = dyn_cast<DefInit>(PI);
     if (!Pred)

diff  --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index 29c64ba95ff856..e866bd983e04ea 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -579,8 +579,8 @@ Expected<InstructionMatcher &> GlobalISelEmitter::addBuiltinPredicates(
     if (const ListInit *AddrSpaces = Predicate.getAddressSpaces()) {
       SmallVector<unsigned, 4> ParsedAddrSpaces;
 
-      for (Init *Val : AddrSpaces->getValues()) {
-        IntInit *IntVal = dyn_cast<IntInit>(Val);
+      for (const Init *Val : AddrSpaces->getValues()) {
+        const IntInit *IntVal = dyn_cast<IntInit>(Val);
         if (!IntVal)
           return failedImport("Address space is not an integer");
         ParsedAddrSpaces.push_back(IntVal->getValue());

diff  --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index a7039ff7e31e9a..8c0e27215a7362 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -411,7 +411,7 @@ void InstrInfoEmitter::emitOperandTypeMappings(
           OperandRecords.push_back(Op.Rec);
           ++CurrentOffset;
         } else {
-          for (Init *Arg : MIOI->getArgs()) {
+          for (const Init *Arg : MIOI->getArgs()) {
             OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
             ++CurrentOffset;
           }
@@ -1296,7 +1296,7 @@ void InstrInfoEmitter::emitRecord(
     OS << "|(1ULL<<MCID::Authenticated)";
 
   // Emit all of the target-specific flags...
-  BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
+  const BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
   if (!TSF)
     PrintFatalError(Inst.TheDef->getLoc(), "no TSFlags?");
   uint64_t Value = 0;

diff  --git a/llvm/utils/TableGen/OptionParserEmitter.cpp b/llvm/utils/TableGen/OptionParserEmitter.cpp
index 424cf16e719d5d..2872762cc7fd96 100644
--- a/llvm/utils/TableGen/OptionParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptionParserEmitter.cpp
@@ -433,10 +433,10 @@ static void EmitOptionParser(const RecordKeeper &Records, raw_ostream &OS) {
     OS << ", ";
     int NumFlags = 0;
     const ListInit *LI = R.getValueAsListInit("Flags");
-    for (Init *I : *LI)
+    for (const Init *I : *LI)
       OS << (NumFlags++ ? " | " : "") << cast<DefInit>(I)->getDef()->getName();
     if (GroupFlags) {
-      for (Init *I : *GroupFlags)
+      for (const Init *I : *GroupFlags)
         OS << (NumFlags++ ? " | " : "")
            << cast<DefInit>(I)->getDef()->getName();
     }
@@ -447,11 +447,11 @@ static void EmitOptionParser(const RecordKeeper &Records, raw_ostream &OS) {
     OS << ", ";
     int NumVisFlags = 0;
     LI = R.getValueAsListInit("Visibility");
-    for (Init *I : *LI)
+    for (const Init *I : *LI)
       OS << (NumVisFlags++ ? " | " : "")
          << cast<DefInit>(I)->getDef()->getName();
     if (GroupVis) {
-      for (Init *I : *GroupVis)
+      for (const Init *I : *GroupVis)
         OS << (NumVisFlags++ ? " | " : "")
            << cast<DefInit>(I)->getDef()->getName();
     }
@@ -473,7 +473,7 @@ static void EmitOptionParser(const RecordKeeper &Records, raw_ostream &OS) {
         HelpTextsForVariants;
     for (const Record *VisibilityHelp :
          R.getValueAsListOfDefs("HelpTextsForVariants")) {
-      ArrayRef<Init *> Visibilities =
+      ArrayRef<const Init *> Visibilities =
           VisibilityHelp->getValueAsListInit("Visibilities")->getValues();
 
       std::vector<std::string> VisibilityNames;

diff  --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 371ee75d1b49ed..be2a2b3884c73b 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -445,7 +445,7 @@ void RegisterInfoEmitter::EmitRegMappingTables(
     if (!V || !V->getValue())
       continue;
 
-    DefInit *DI = cast<DefInit>(V->getValue());
+    const DefInit *DI = cast<DefInit>(V->getValue());
     const Record *Alias = DI->getDef();
     const auto &AliasIter = llvm::lower_bound(
         DwarfRegNums, Alias, [](const DwarfRegNumsMapPair &A, const Record *B) {
@@ -1061,10 +1061,10 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS) {
   OS << "  0,\n";
   for (const auto &RE : Regs) {
     const Record *Reg = RE.TheDef;
-    BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
+    const BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
     uint64_t Value = 0;
     for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
-      if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
+      if (const BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
         Value |= (uint64_t)B->getValue() << b;
     }
     OS << "  " << Value << ",\n";

diff  --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp
index d6cb94cdff24f1..4bf4df692acb47 100644
--- a/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -196,7 +196,7 @@ class SearchableTableEmitter {
                           bool IsPrimary, raw_ostream &OS);
   void emitIfdef(StringRef Guard, raw_ostream &OS);
 
-  bool parseFieldType(GenericField &Field, Init *II);
+  bool parseFieldType(GenericField &Field, const Init *II);
   std::unique_ptr<SearchIndex>
   parseSearchIndex(GenericTable &Table, const RecordVal *RecVal, StringRef Name,
                    ArrayRef<StringRef> Key, bool EarlyOut, bool ReturnRange);
@@ -233,8 +233,8 @@ int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index,
 bool SearchableTableEmitter::compareBy(const Record *LHS, const Record *RHS,
                                        const SearchIndex &Index) {
   for (const auto &Field : Index.Fields) {
-    Init *LHSI = LHS->getValueInit(Field.Name);
-    Init *RHSI = RHS->getValueInit(Field.Name);
+    const Init *LHSI = LHS->getValueInit(Field.Name);
+    const Init *RHSI = RHS->getValueInit(Field.Name);
 
     if (isa<BitsRecTy>(Field.RecType) || isa<IntRecTy>(Field.RecType)) {
       int64_t LHSi = getAsInt(LHSI);
@@ -574,7 +574,8 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table,
   OS << "#endif\n\n";
 }
 
-bool SearchableTableEmitter::parseFieldType(GenericField &Field, Init *TypeOf) {
+bool SearchableTableEmitter::parseFieldType(GenericField &Field,
+                                            const Init *TypeOf) {
   auto Type = dyn_cast<StringInit>(TypeOf);
   if (!Type)
     return false;

diff  --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index 8ab7bdcd2214b3..bcc5712b9154c1 100644
--- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -251,7 +251,7 @@ static uint8_t byteFromBitsInit(const BitsInit *B) {
 
   uint8_t Value = 0;
   for (unsigned I = 0; I != N; ++I) {
-    BitInit *Bit = cast<BitInit>(B->getBit(I));
+    const BitInit *Bit = cast<BitInit>(B->getBit(I));
     Value |= Bit->getValue() << I;
   }
   return Value;
@@ -487,7 +487,7 @@ void X86FoldTablesEmitter::addEntryWithFlags(FoldTable &Table,
   uint8_t Enc = byteFromBitsInit(RegRec->getValueAsBitsInit("OpEncBits"));
   if (isExplicitAlign(RegInst)) {
     // The instruction require explicitly aligned memory.
-    BitsInit *VectSize = RegRec->getValueAsBitsInit("VectSize");
+    const BitsInit *VectSize = RegRec->getValueAsBitsInit("VectSize");
     Result.Alignment = Align(byteFromBitsInit(VectSize));
   } else if (!Enc && !isExplicitUnalign(RegInst) &&
              getMemOperandSize(MemOpRec) > 64) {
@@ -512,7 +512,7 @@ void X86FoldTablesEmitter::addBroadcastEntry(
   assert(Table.find(RegInst) == Table.end() && "Override entry unexpectedly");
   X86FoldTableEntry Result = X86FoldTableEntry(RegInst, MemInst);
 
-  DagInit *In = MemInst->TheDef->getValueAsDag("InOperandList");
+  const DagInit *In = MemInst->TheDef->getValueAsDag("InOperandList");
   for (unsigned I = 0, E = In->getNumArgs(); I != E; ++I) {
     Result.BroadcastKind =
         StringSwitch<X86FoldTableEntry::BcastType>(In->getArg(I)->getAsString())

diff  --git a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
index 47df5bf0df8e5c..10fab469a0803f 100644
--- a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
+++ b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp
@@ -112,7 +112,7 @@ static uint8_t byteFromBitsInit(const BitsInit *B) {
 
   uint8_t Value = 0;
   for (unsigned I = 0; I != N; ++I) {
-    BitInit *Bit = cast<BitInit>(B->getBit(I));
+    const BitInit *Bit = cast<BitInit>(B->getBit(I));
     Value |= Bit->getValue() << I;
   }
   return Value;

diff  --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index 60fc1d1ecbfab1..26b881651ea411 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -77,17 +77,15 @@ unsigned X86Disassembler::getMemOperandSize(const Record *MemRec) {
 /// @param init - A reference to the BitsInit to be decoded.
 /// @return     - The field, with the first bit in the BitsInit as the lowest
 ///               order bit.
-static uint8_t byteFromBitsInit(BitsInit &init) {
+static uint8_t byteFromBitsInit(const BitsInit &init) {
   int width = init.getNumBits();
 
   assert(width <= 8 && "Field is too large for uint8_t!");
 
-  int index;
   uint8_t mask = 0x01;
-
   uint8_t ret = 0;
 
-  for (index = 0; index < width; index++) {
+  for (int index = 0; index < width; index++) {
     if (cast<BitInit>(init.getBit(index))->getValue())
       ret |= mask;
 
@@ -104,7 +102,7 @@ static uint8_t byteFromBitsInit(BitsInit &init) {
 /// @param name - The name of the field in the record.
 /// @return     - The field, as translated by byteFromBitsInit().
 static uint8_t byteFromRec(const Record *rec, StringRef name) {
-  BitsInit *bits = rec->getValueAsBitsInit(name);
+  const BitsInit *bits = rec->getValueAsBitsInit(name);
   return byteFromBitsInit(*bits);
 }
 

diff  --git a/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp b/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp
index 6a3d5a25e28cd9..d7967c7a77534d 100644
--- a/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp
+++ b/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp
@@ -258,8 +258,7 @@ void Generator::emitParseHelper(StringRef kind, StringRef returnType,
     SmallVector<std::string> argNames;
     if (def->isSubClassOf("CompositeBytecode")) {
       const DagInit *members = def->getValueAsDag("members");
-      args = llvm::to_vector(map_range(
-          members->getArgs(), [](Init *init) { return (const Init *)init; }));
+      args = llvm::to_vector(members->getArgs());
       argNames = llvm::to_vector(
           map_range(members->getArgNames(), [](const StringInit *init) {
             return init->getAsUnquotedString();


        


More information about the Mlir-commits mailing list