Merge pull request #19304 from compnerd/what-is-a-mark

diff --git a/include/swift/AST/AccessRequests.h b/include/swift/AST/AccessRequests.h
index 65e942d..2f548c0 100644
--- a/include/swift/AST/AccessRequests.h
+++ b/include/swift/AST/AccessRequests.h
@@ -39,7 +39,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<AccessLevel> evaluate(Evaluator &evaluator,
@@ -68,7 +68,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<AccessLevel>
@@ -95,7 +95,7 @@
   using SimpleRequest::SimpleRequest;
   using DefaultAndMax = std::pair<AccessLevel, AccessLevel>;
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<DefaultAndMax>
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 956edb1..a0b4cb8 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -6482,9 +6482,8 @@
 
   static MissingMemberDecl *
   forInitializer(ASTContext &ctx, DeclContext *DC, DeclName name,
-                 bool hasNormalVTableEntry,
-                 bool hasAllocatingVTableEntry) {
-    unsigned entries = hasNormalVTableEntry + hasAllocatingVTableEntry;
+                 bool hasVTableEntry) {
+    unsigned entries = hasVTableEntry ? 1 : 0;
     return new (ctx) MissingMemberDecl(DC, name, entries, 0);
   }
   
diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def
index c5952ed..a63624f 100644
--- a/include/swift/AST/DiagnosticsCommon.def
+++ b/include/swift/AST/DiagnosticsCommon.def
@@ -17,8 +17,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if !(defined(DIAG) || (defined(ERROR) && defined(WARNING) && defined(NOTE)))
-#  error Must define either DIAG or the set {ERROR,WARNING,NOTE}
+#if !(defined(DIAG) || (defined(ERROR) && defined(WARNING) && defined(NOTE) && defined(REMARK)))
+#  error Must define either DIAG or the set {ERROR,WARNING,NOTE,REMARK}
 #endif
 
 #ifndef ERROR
@@ -36,6 +36,11 @@
   DIAG(NOTE,ID,Options,Text,Signature)
 #endif
 
+#ifndef REMARK
+#  define REMARK(ID,Options,Text,Signature) \
+  DIAG(REMARK,ID,Options,Text,Signature)
+#endif
+
 ERROR(invalid_diagnostic,none,
       "INTERNAL ERROR: this diagnostic should not be produced", ())
 
@@ -58,6 +63,9 @@
 NOTE(while_parsing_as_left_angle_bracket,none,
      "while parsing this '<' as a type parameter bracket", ())
 
+// Generic determinism-forcing override.
+REMARK(remark_max_determinism_overriding,none,
+         "SWIFTC_MAXIMUM_DETERMINISM overriding %0", (StringRef))
 
 // FIXME: This is used both as a parse error (a literal "super" outside a
 // method) and a type-checker error ("super" in a method of a non-class type).
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 55819a2..3f087fe 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -1296,8 +1296,6 @@
 
 ERROR(attr_interpolated_string,none,
 "'%0' cannot be an interpolated string literal", (StringRef))
-ERROR(attr_multiline_string,none,
-"'%0' cannot be a multiline string literal", (StringRef))
 ERROR(attr_extended_escaping_string,none,
 "'%0' cannot be an extended escaping string literal", (StringRef))
 
diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h
index 30969a2..bc00386 100644
--- a/include/swift/AST/NameLookupRequests.h
+++ b/include/swift/AST/NameLookupRequests.h
@@ -68,7 +68,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   DirectlyReferencedTypeDecls evaluate(
@@ -114,7 +114,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   DirectlyReferencedTypeDecls evaluate(
@@ -140,7 +140,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<ClassDecl *>
@@ -165,7 +165,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<NominalTypeDecl *>
@@ -193,7 +193,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::TinyPtrVector<NominalTypeDecl *> evaluate(Evaluator &evaluator,
@@ -218,7 +218,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   DirectlyReferencedTypeDecls evaluate(Evaluator &evaluator,
diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h
index 1ca226c..179b083 100644
--- a/include/swift/AST/TypeCheckRequests.h
+++ b/include/swift/AST/TypeCheckRequests.h
@@ -55,7 +55,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<Type>
@@ -86,7 +86,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<Type>
@@ -115,7 +115,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<Type>
@@ -144,7 +144,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<llvm::TinyPtrVector<ValueDecl *>>
@@ -171,7 +171,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<bool> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
@@ -197,7 +197,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<bool> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
@@ -275,7 +275,7 @@
       llvm::function_ref<bool(Requirement, RequirementRepr*)> callback);
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   /// Retrieve the requirement this request operates on.
   RequirementRepr &getRequirement() const;
@@ -308,7 +308,7 @@
   using SimpleRequest::SimpleRequest;
 
 private:
-  friend class SimpleRequest;
+  friend SimpleRequest;
 
   // Evaluation.
   llvm::Expected<std::string> evaluate(Evaluator &eval, const ValueDecl* d) const;
diff --git a/include/swift/Basic/Statistic.h b/include/swift/Basic/Statistic.h
index e047de0..f5e65ff 100644
--- a/include/swift/Basic/Statistic.h
+++ b/include/swift/Basic/Statistic.h
@@ -68,6 +68,16 @@
 class Stmt;
 class TypeRepr;
 
+// There are a handful of cases where the swift compiler can introduce
+// counter-measurement noise via nondeterminism, especially via
+// parallelism; inhibiting all such cases reliably using existing avenues
+// is a bit tricky and depends both on delicate build-setting management
+// and some build-system support that is still pending (see
+// rdar://39528362); in the meantime we support an environment variable
+// ourselves to request blanket suppression of parallelism (and anything
+// else nondeterministic we find).
+bool environmentVariableRequestedMaximumDeterminism();
+
 class UnifiedStatsReporter {
 
 public:
diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h
index 97622f5..9fa318f 100644
--- a/include/swift/Frontend/Frontend.h
+++ b/include/swift/Frontend/Frontend.h
@@ -444,9 +444,7 @@
     return TheSILModule.get();
   }
 
-  std::unique_ptr<SILModule> takeSILModule() {
-    return std::move(TheSILModule);
-  }
+  std::unique_ptr<SILModule> takeSILModule();
 
   bool hasSILModule() {
     return static_cast<bool>(TheSILModule);
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index 0b388ae..d71c0d6 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -426,15 +426,19 @@
   /// If a copy needs to be made, it will be allocated out of the provided
   /// \p Buffer.
   static StringRef getEncodedStringSegment(StringRef Str,
-                                           SmallVectorImpl<char> &Buffer) {
+                                           SmallVectorImpl<char> &Buffer,
+                                           bool IsFirstSegment = false,
+                                           bool IsLastSegment = false,
+                                           unsigned IndentToStrip = 0,
+                                           unsigned CustomDelimiterLen = 0) {
     SmallString<128> TerminatedStrBuf(Str);
     TerminatedStrBuf.push_back('\0');
     StringRef TerminatedStr = StringRef(TerminatedStrBuf).drop_back();
     StringRef Result = getEncodedStringSegmentImpl(TerminatedStr, Buffer,
-                                                   /*IsFirstSegment*/false,
-                                                   /*IsLastSegment*/false,
-                                                   /*IndentToStrip*/0,
-                                                   /*CustomDelimiterLen*/0);
+                                                   IsFirstSegment,
+                                                   IsLastSegment,
+                                                   IndentToStrip,
+                                                   CustomDelimiterLen);
     if (Result == TerminatedStr)
       return Str;
     assert(Result.data() == Buffer.data());
diff --git a/include/swift/SIL/SILDefaultWitnessTable.h b/include/swift/SIL/SILDefaultWitnessTable.h
index 87dd468..7a119a5 100644
--- a/include/swift/SIL/SILDefaultWitnessTable.h
+++ b/include/swift/SIL/SILDefaultWitnessTable.h
@@ -119,7 +119,11 @@
                                         const ProtocolDecl *Protocol,
                                         ArrayRef<Entry> entries);
 
-  Identifier getIdentifier() const;
+  /// Get a name that uniquely identifies this default witness table.
+  ///
+  /// Note that this is /not/ valid as a symbol name; it is only guaranteed to
+  /// be unique among default witness tables, not all symbols.
+  std::string getUniqueName() const;
 
   /// Get the linkage of the default witness table.
   SILLinkage getLinkage() const { return Linkage; }
diff --git a/include/swift/SIL/SILVTableVisitor.h b/include/swift/SIL/SILVTableVisitor.h
index 9549cfa..7072d9a 100644
--- a/include/swift/SIL/SILVTableVisitor.h
+++ b/include/swift/SIL/SILVTableVisitor.h
@@ -93,17 +93,12 @@
   void maybeAddConstructor(ConstructorDecl *cd) {
     assert(!cd->hasClangNode());
 
-    // Required constructors (or overrides thereof) have their allocating entry
-    // point in the vtable.
-    if (cd->isRequired()) {
-      SILDeclRef constant(cd, SILDeclRef::Kind::Allocator);
-      maybeAddEntry(constant, constant.requiresNewVTableEntry());
-    }
-
-    // All constructors have their initializing constructor in the
-    // vtable, which can be used by a convenience initializer.
-    SILDeclRef constant(cd, SILDeclRef::Kind::Initializer);
-    maybeAddEntry(constant, constant.requiresNewVTableEntry());
+    // The allocating entry point is what is used for dynamic dispatch.
+    // The initializing entry point for designated initializers is only
+    // necessary for super.init chaining, which is sufficiently constrained
+    // to never need dynamic dispatch.
+    SILDeclRef constant(cd, SILDeclRef::Kind::Allocator);
+    maybeAddEntry(constant, constant.requiresNewVTableEntry());    
   }
 
   void maybeAddEntry(SILDeclRef declRef, bool needsNewEntry) {
diff --git a/include/swift/SIL/SILWitnessTable.h b/include/swift/SIL/SILWitnessTable.h
index efa55c0..b029886 100644
--- a/include/swift/SIL/SILWitnessTable.h
+++ b/include/swift/SIL/SILWitnessTable.h
@@ -226,10 +226,6 @@
   /// object file level.
   StringRef getName() const { return Name; }
 
-  /// Return the symbol name of the witness table that will be propagated to the
-  /// object file as an Identifier.
-  Identifier getIdentifier() const;
-
   /// Returns true if this witness table is a declaration.
   bool isDeclaration() const { return IsDeclaration; }
 
diff --git a/include/swift/Serialization/ModuleFile.h b/include/swift/Serialization/ModuleFile.h
index dd656ca..e42ca6b 100644
--- a/include/swift/Serialization/ModuleFile.h
+++ b/include/swift/Serialization/ModuleFile.h
@@ -241,7 +241,7 @@
     T Value;
 
     /// The offset.
-    serialization::BitOffset Offset;
+    unsigned Offset : 31;
 
     unsigned IsFullyDeserialized : 1;
 
@@ -285,40 +285,64 @@
   };
 
 private:
+  /// An allocator for buffers owned by the file.
+  llvm::BumpPtrAllocator Allocator;
+
+  /// Allocates a buffer using #Allocator and initializes it with the contents
+  /// of the container \p rawData, then stores it in \p buffer.
+  ///
+  /// \p buffer is passed as an argument rather than returned so that the
+  /// element type can be inferred.
+  template <typename T, typename RawData>
+  void allocateBuffer(MutableArrayRef<T> &buffer, const RawData &rawData);
+
+  /// Allocates a buffer using #Allocator and initializes it with the contents
+  /// of the container \p rawData, then stores it in \p buffer.
+  ///
+  /// \p buffer is passed as an argument rather than returned so that the
+  /// element type can be inferred.
+  template <typename T, typename RawData>
+  void allocateBuffer(ArrayRef<T> &buffer, const RawData &rawData) {
+    assert(buffer.empty());
+    MutableArrayRef<T> result;
+    allocateBuffer(result, rawData);
+    buffer = result;
+  }
+
   /// Decls referenced by this module.
-  std::vector<Serialized<Decl*>> Decls;
+  MutableArrayRef<Serialized<Decl*>> Decls;
 
   /// DeclContexts referenced by this module.
-  std::vector<Serialized<DeclContext*>> DeclContexts;
+  MutableArrayRef<Serialized<DeclContext*>> DeclContexts;
 
   /// Local DeclContexts referenced by this module.
-  std::vector<Serialized<DeclContext*>> LocalDeclContexts;
+  MutableArrayRef<Serialized<DeclContext*>> LocalDeclContexts;
 
   /// Normal protocol conformances referenced by this module.
-  std::vector<Serialized<NormalProtocolConformance *>> NormalConformances;
+  MutableArrayRef<Serialized<NormalProtocolConformance *>> NormalConformances;
 
   /// SILLayouts referenced by this module.
-  std::vector<Serialized<SILLayout *>> SILLayouts;
+  MutableArrayRef<Serialized<SILLayout *>> SILLayouts;
 
   /// Types referenced by this module.
-  std::vector<Serialized<Type>> Types;
+  MutableArrayRef<Serialized<Type>> Types;
 
   /// Generic signatures referenced by this module.
-  std::vector<Serialized<GenericSignature *>> GenericSignatures;
+  MutableArrayRef<Serialized<GenericSignature *>> GenericSignatures;
 
   /// Generic environments referenced by this module.
-  std::vector<Serialized<GenericEnvironment *>> GenericEnvironments;
+  MutableArrayRef<Serialized<GenericEnvironment *>> GenericEnvironments;
 
   /// Substitution maps referenced by this module.
-  std::vector<Serialized<SubstitutionMap>> SubstitutionMaps;
+  MutableArrayRef<Serialized<SubstitutionMap>> SubstitutionMaps;
 
   /// Represents an identifier that may or may not have been deserialized yet.
   ///
-  /// If \c Offset is non-zero, the identifier has not been loaded yet.
+  /// If \c Ident is empty, the identifier has not been loaded yet.
   class SerializedIdentifier {
   public:
     Identifier Ident;
-    serialization::BitOffset Offset;
+    unsigned Offset;
 
     template <typename IntTy>
     /*implicit*/ SerializedIdentifier(IntTy rawOffset)
@@ -328,7 +352,7 @@
   };
 
   /// Identifiers referenced by this module.
-  std::vector<SerializedIdentifier> Identifiers;
+  MutableArrayRef<SerializedIdentifier> Identifiers;
 
   class DeclTableInfo;
   using SerializedDeclTable =
@@ -377,9 +401,7 @@
 
   TinyPtrVector<Decl *> ImportDecls;
 
-  using DeclIDVector = SmallVector<serialization::DeclID, 4>;
-
-  DeclIDVector OrderedTopLevelDecls;
+  ArrayRef<serialization::DeclID> OrderedTopLevelDecls;
 
   class DeclCommentTableInfo;
   using SerializedDeclCommentTable =
@@ -793,6 +815,11 @@
   /// given ID. Asserts that the name with this ID is not special.
   Identifier getIdentifier(serialization::IdentifierID IID);
 
+  /// Convenience method to retrieve the text of the name with the given ID.
+  /// This can be used if the result doesn't need to be uniqued in the
+  /// ASTContext. Asserts that the name with this ID is not special.
+  StringRef getIdentifierText(serialization::IdentifierID IID);
+
   /// Returns the decl with the given ID, deserializing it if needed.
   ///
   /// \param DID The ID for the decl within this module.
@@ -859,6 +886,19 @@
   Optional<ForeignErrorConvention> maybeReadForeignErrorConvention();
 };
 
+template <typename T, typename RawData>
+void ModuleFile::allocateBuffer(MutableArrayRef<T> &buffer,
+                                const RawData &rawData) {
+  assert(buffer.empty() && "reallocating deserialized buffer");
+  if (rawData.empty())
+    return;
+
+  void *rawBuffer = Allocator.Allocate(sizeof(T) * rawData.size(), alignof(T));
+  buffer = llvm::makeMutableArrayRef(static_cast<T *>(rawBuffer),
+                                     rawData.size());
+  std::uninitialized_copy(rawData.begin(), rawData.end(), buffer.begin());
+}
+
 } // end namespace swift
 
 #endif
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 141c9f4..a1803cf 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -5253,6 +5253,18 @@
   // Dynamic methods are always accessed by objc_msgSend().
   if (decl->isFinal() || decl->isDynamic() || decl->hasClangNode())
     return false;
+  
+  // Initializers are not normally inherited, but required initializers can
+  // be overridden for invocation from dynamic types, and convenience initializers
+  // are conditionally inherited when all designated initializers are available,
+  // working by dynamically invoking the designated initializer implementation
+  // from the subclass. Convenience initializers can also override designated
+  // initializer implementations from their superclass.
+  if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
+    if (!ctor->isRequired() && !ctor->isDesignatedInit()) {
+      return false;
+    }
+  }
 
   if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
     // Check to see if it's one of the opaque accessors for the declaration.
@@ -5264,6 +5276,16 @@
   auto base = decl->getOverriddenDecl();
   if (!base || base->hasClangNode() || base->isDynamic())
     return true;
+  
+  // As above, convenience initializers are not formally overridable in Swift
+  // vtables, although same-named initializers are modeled as overriding for
+  // various QoI and objc interop reasons. Even if we "override" a non-required
+  // convenience init, we still need a distinct vtable entry.
+  if (auto baseCtor = dyn_cast<ConstructorDecl>(base)) {
+    if (!baseCtor->isRequired() && !baseCtor->isDesignatedInit()) {
+      return true;
+    }
+  }
 
   // If the method overrides something, we only need a new entry if the
   // override has a more general AST type. However an abstraction
diff --git a/lib/Basic/Statistic.cpp b/lib/Basic/Statistic.cpp
index af00647..12f77fb 100644
--- a/lib/Basic/Statistic.cpp
+++ b/lib/Basic/Statistic.cpp
@@ -50,6 +50,12 @@
 using namespace llvm;
 using namespace llvm::sys;
 
+bool environmentVariableRequestedMaximumDeterminism() {
+  if (const char *S = ::getenv("SWIFTC_MAXIMUM_DETERMINISM"))
+    return (S[0] != '\0');
+  return false;
+}
+
 static int64_t
 getChildrenMaxResidentSetSize() {
 #if defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 6585393..bfeef09 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -297,6 +297,11 @@
       return nullptr;
     }
   }
+  if (environmentVariableRequestedMaximumDeterminism()) {
+      NumberOfParallelCommands = 1;
+      Diags.diagnose(SourceLoc(), diag::remark_max_determinism_overriding,
+                     "-j");
+  }
 
   const bool DriverSkipExecution =
     ArgList.hasArg(options::OPT_driver_skip_execution,
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 7b9d770..1094b58 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -614,8 +614,13 @@
                      A->getAsString(Args), A->getValue());
       return true;
     }
+    if (environmentVariableRequestedMaximumDeterminism()) {
+      Opts.NumThreads = 1;
+      Diags.diagnose(SourceLoc(), diag::remark_max_determinism_overriding,
+                     "-num-threads");
+    }
   }
-  
+
   if (Args.hasArg(OPT_sil_merge_partial_modules))
     Opts.MergePartialModules = true;
 
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index 35a117b..c441fd6 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -430,6 +430,10 @@
   return None;
 }
 
+std::unique_ptr<SILModule> CompilerInstance::takeSILModule() {
+  return std::move(TheSILModule);
+}
+
 ModuleDecl *CompilerInstance::getMainModule() {
   if (!MainModule) {
     Identifier ID = Context->getIdentifier(Invocation.getModuleName());
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index eb9bc8a..347c0a4 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -1560,9 +1560,9 @@
 
 /// getMultilineTrailingIndent:
 /// Determine trailing indent to be used for multiline literal indent stripping.
-static std::tuple<StringRef, SourceLoc>
-getMultilineTrailingIndent(const Token &Str, DiagnosticEngine *Diags) {
-  StringRef Bytes = getStringLiteralContent(Str);
+StringRef
+getMultilineTrailingIndent(StringRef Bytes, DiagnosticEngine *Diags = nullptr,
+                           unsigned CustomDelimiterLen = 0) {
   const char *begin = Bytes.begin(), *end = Bytes.end(), *start = end;
   bool sawNonWhitespace = false;
 
@@ -1575,11 +1575,9 @@
     case '\n':
     case '\r': {
       ++start;
-      auto startLoc = Lexer::getSourceLoc(start);
-      auto string = StringRef(start, end - start);
 
       // Disallow escaped newline in the last line.
-      if (Diags && Str.getCustomDelimiterLen() == 0) {
+      if (Diags && !CustomDelimiterLen) {
         auto *Ptr = start - 1;
         if (*Ptr == '\n') --Ptr;
         if (*Ptr == '\r') --Ptr;
@@ -1595,7 +1593,7 @@
         }
       }
 
-      return std::make_tuple(string, startLoc);
+      return StringRef(start, end - start);
     }
     default:
       sawNonWhitespace = true;
@@ -1609,7 +1607,7 @@
       .fixItInsert(loc, "\n");
   }
 
-  return std::make_tuple("", Lexer::getSourceLoc(end - 1));
+  return "";
 }
 
 /// diagnoseInvalidMultilineIndents:
@@ -1673,12 +1671,13 @@
 /// Diagnose contents of string literal that have inconsistent indentation.
 static void validateMultilineIndents(const Token &Str,
                                      DiagnosticEngine *Diags) {
-  StringRef Indent;
-  SourceLoc IndentStartLoc;
-  std::tie(Indent, IndentStartLoc) = getMultilineTrailingIndent(Str, Diags);
+  StringRef Bytes = getStringLiteralContent(Str);
+  StringRef Indent =
+    getMultilineTrailingIndent(Bytes, Diags, Str.getCustomDelimiterLen());
   if (Indent.empty())
     return;
-  
+  SourceLoc IndentStartLoc = Lexer::getSourceLoc(Indent.data());
+
   // The offset into the previous line where it experienced its first indentation 
   // error, or Indent.size() if every character matched.
   size_t lastMistakeOffset = std::numeric_limits<size_t>::max();
@@ -1688,7 +1687,6 @@
   // Prefix of indentation that's present on all lines in linesWithLastMatchLength.
   StringRef commonIndentation = "";
   
-  StringRef Bytes = getStringLiteralContent(Str);
   for (size_t pos = Bytes.find('\n'); pos != StringRef::npos; pos = Bytes.find('\n', pos + 1)) {
     size_t nextpos = pos + 1;
     auto restOfBytes = Bytes.substr(nextpos);
@@ -2109,6 +2107,11 @@
   // BytesPtr to avoid a range check subscripting on the StringRef.
   const char *BytesPtr = Bytes.begin();
 
+  // Special case when being called from EncodedDiagnosticMessage(...)
+  // This should allow multiline strings to work as attribute messages.
+  if (IndentToStrip == ~0U)
+    IndentToStrip = getMultilineTrailingIndent(Bytes).size();
+
   bool IsEscapedNewline = false;
   while (BytesPtr < Bytes.end()) {
     char CurChar = *BytesPtr++;
@@ -2203,8 +2206,7 @@
   bool MultilineString = Str.isMultilineString(), IsFirstSegment = true;
   unsigned IndentToStrip = 0, CustomDelimiterLen = Str.getCustomDelimiterLen();
   if (MultilineString)
-    IndentToStrip = 
-      std::get<0>(getMultilineTrailingIndent(Str, /*Diags=*/nullptr)).size();
+    IndentToStrip = getMultilineTrailingIndent(Bytes).size();
 
   // Note that it is always safe to read one over the end of "Bytes" because
   // we know that there is a terminating " character.  Use BytesPtr to avoid a
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5d31927..ce8f840 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -310,15 +310,11 @@
 static Optional<StringRef>
 getStringLiteralIfNotInterpolated(Parser &P, SourceLoc Loc, const Token &Tok,
                                   StringRef DiagText) {
-  // FIXME: Support extended escaping / multiline string literal.
+  // FIXME: Support extended escaping string literal.
   if (Tok.getCustomDelimiterLen()) {
     P.diagnose(Loc, diag::attr_extended_escaping_string, DiagText);
     return None;
   }
-  if (Tok.isMultilineString()) {
-    P.diagnose(Loc, diag::attr_multiline_string, DiagText);
-    return None;
-  }
 
   SmallVector<Lexer::StringSegment, 1> Segments;
   P.L->getStringLiteralSegments(Tok, Segments);
diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp
index 7f28cc7..359faf2 100644
--- a/lib/SIL/SILDeclRef.cpp
+++ b/lib/SIL/SILDeclRef.cpp
@@ -48,13 +48,21 @@
     if (method->isFinal())
       return MethodDispatch::Static;
 
-    // Members defined directly inside a class are dynamically dispatched.
-    if (isa<ClassDecl>(dc))
-      return MethodDispatch::Class;
-
     // Imported class methods are dynamically dispatched.
     if (method->isObjC() && method->hasClangNode())
       return MethodDispatch::Class;
+
+    // Members defined directly inside a class are dynamically dispatched.
+    if (isa<ClassDecl>(dc)) {
+      // Native convenience initializers are not dynamically dispatched unless
+      // required.
+      if (auto ctor = dyn_cast<ConstructorDecl>(method)) {
+        if (!ctor->isRequired() && !ctor->isDesignatedInit()
+            && !requiresForeignEntryPoint(ctor))
+          return MethodDispatch::Static;
+      }
+      return MethodDispatch::Class;
+    }
   }
 
   // Otherwise, it can be referenced statically.
@@ -715,16 +723,6 @@
 bool SILDeclRef::requiresNewVTableEntry() const {
   if (cast<AbstractFunctionDecl>(getDecl())->needsNewVTableEntry())
     return true;
-  if (kind == SILDeclRef::Kind::Allocator) {
-    auto *cd = cast<ConstructorDecl>(getDecl());
-    if (cd->isRequired()) {
-      auto *baseCD = cd->getOverriddenDecl();
-      if(!baseCD ||
-         !baseCD->isRequired() ||
-         baseCD->hasClangNode())
-        return true;
-    }
-  }
   return false;
 }
 
@@ -748,18 +746,34 @@
 
 SILDeclRef SILDeclRef::getNextOverriddenVTableEntry() const {
   if (auto overridden = getOverridden()) {
-    // If we overrode a foreign decl, a dynamic method, this is an
+    // If we overrode a foreign decl or dynamic method, if this is an
     // accessor for a property that overrides an ObjC decl, or if it is an
     // @NSManaged property, then it won't be in the vtable.
     if (overridden.getDecl()->hasClangNode())
       return SILDeclRef();
-
-    // If we overrode a non-required initializer, there won't be a vtable
-    // slot for the allocator.
+    
+    // An @objc convenience initializer can be "overridden" in the sense that
+    // its selector is reclaimed by a subclass's convenience init with the
+    // same name. The AST models this as an override for the purposes of
+    // ObjC selector validation, but it isn't for Swift method dispatch
+    // purposes.
     if (overridden.kind == SILDeclRef::Kind::Allocator) {
-      if (!cast<ConstructorDecl>(overridden.getDecl())->isRequired())
+      auto overriddenCtor = cast<ConstructorDecl>(overridden.getDecl());
+      if (!overriddenCtor->isDesignatedInit()
+          && !overriddenCtor->isRequired())
         return SILDeclRef();
-    } else if (overridden.getDecl()->isDynamic()) {
+    }
+
+    // Initializing entry points for initializers won't be in the vtable.
+    // For Swift designated initializers, they're only used in super.init
+    // chains, which can always be statically resolved. Other native Swift
+    // initializers only have allocating entry points. ObjC initializers always
+    // have the initializing entry point (corresponding to the -init method)
+    // but those are never in the vtable.
+    if (overridden.kind == SILDeclRef::Kind::Initializer) {
+      return SILDeclRef();
+    }
+    if (overridden.getDecl()->isDynamic()) {
       return SILDeclRef();
     }
     
diff --git a/lib/SIL/SILDefaultWitnessTable.cpp b/lib/SIL/SILDefaultWitnessTable.cpp
index 608b911..e3ae361 100644
--- a/lib/SIL/SILDefaultWitnessTable.cpp
+++ b/lib/SIL/SILDefaultWitnessTable.cpp
@@ -95,10 +95,9 @@
   }
 }
 
-Identifier SILDefaultWitnessTable::getIdentifier() const {
+std::string SILDefaultWitnessTable::getUniqueName() const {
   Mangle::ASTMangler Mangler;
-  std::string name = Mangler.mangleTypeAsUSR(getProtocol()->getDeclaredType());
-  return Mod.getASTContext().getIdentifier(name);
+  return Mangler.mangleTypeAsUSR(getProtocol()->getDeclaredType());
 }
 
 SILDefaultWitnessTable::~SILDefaultWitnessTable() {
diff --git a/lib/SIL/SILWitnessTable.cpp b/lib/SIL/SILWitnessTable.cpp
index 732c3a7..083992e 100644
--- a/lib/SIL/SILWitnessTable.cpp
+++ b/lib/SIL/SILWitnessTable.cpp
@@ -151,10 +151,6 @@
   }
 }
 
-Identifier SILWitnessTable::getIdentifier() const {
-  return Mod.getASTContext().getIdentifier(Name);
-}
-
 bool SILWitnessTable::conformanceIsSerialized(ProtocolConformance *conformance) {
   // Serialize witness tables for conformances synthesized by
   // the ClangImporter.
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index bd1c4c8..ec15742 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -757,9 +757,7 @@
 
   bool ForCoverageMapping = doesASTRequireProfiling(M, decl);
 
-  if (declCtx->getSelfClassDecl()) {
-    // Class constructors have separate entry points for allocation and
-    // initialization.
+  auto emitClassAllocatorThunk = [&]{
     emitOrDelayFunction(
         *this, constant, [this, constant, decl](SILFunction *f) {
           preEmitFunction(constant, decl, f, decl);
@@ -767,27 +765,8 @@
           SILGenFunction(*this, *f, decl).emitClassConstructorAllocator(decl);
           postEmitFunction(constant, f);
         });
-
-    // Constructors may not have bodies if they've been imported, or if they've
-    // been parsed from a textual interface.
-    if (decl->hasBody()) {
-      SILDeclRef initConstant(decl, SILDeclRef::Kind::Initializer);
-      emitOrDelayFunction(
-          *this, initConstant,
-          [this, initConstant, decl, declCtx](SILFunction *initF) {
-            preEmitFunction(initConstant, decl, initF, decl);
-            PrettyStackTraceSILFunction X("silgen constructor initializer",
-                                          initF);
-            initF->setProfiler(
-                getOrCreateProfilerForConstructors(declCtx, decl));
-            SILGenFunction(*this, *initF, decl)
-              .emitClassConstructorInitializer(decl);
-            postEmitFunction(initConstant, initF);
-          },
-          /*forceEmission=*/ForCoverageMapping);
-    }
-  } else {
-    // Struct and enum constructors do everything in a single function.
+  };
+  auto emitValueConstructorIfHasBody = [&]{
     if (decl->hasBody()) {
       emitOrDelayFunction(
           *this, constant, [this, constant, decl, declCtx](SILFunction *f) {
@@ -798,6 +777,47 @@
             postEmitFunction(constant, f);
           });
     }
+  };
+  
+  if (declCtx->getSelfClassDecl()) {
+    // Designated initializers for classes have have separate entry points for
+    // allocation and initialization.
+    if (decl->isDesignatedInit()) {
+      emitClassAllocatorThunk();
+
+      // Constructors may not have bodies if they've been imported, or if they've
+      // been parsed from a textual interface.
+      if (decl->hasBody()) {
+        SILDeclRef initConstant(decl, SILDeclRef::Kind::Initializer);
+        emitOrDelayFunction(
+            *this, initConstant,
+            [this, initConstant, decl, declCtx](SILFunction *initF) {
+              preEmitFunction(initConstant, decl, initF, decl);
+              PrettyStackTraceSILFunction X("silgen constructor initializer",
+                                            initF);
+              initF->setProfiler(
+                  getOrCreateProfilerForConstructors(declCtx, decl));
+              SILGenFunction(*this, *initF, decl)
+                .emitClassConstructorInitializer(decl);
+              postEmitFunction(initConstant, initF);
+            },
+            /*forceEmission=*/ForCoverageMapping);
+      }
+    // Convenience initializers for classes behave more like value constructors
+    // in that there's only an allocating entry point that effectively
+    // "constructs" the self reference by invoking another initializer.
+    } else {
+      emitValueConstructorIfHasBody();
+      
+      // If the convenience initializer was imported from ObjC, we still have to
+      // emit the allocator thunk.
+      if (decl->hasClangNode()) {
+        emitClassAllocatorThunk();
+      }
+    }
+  } else {
+    // Struct and enum constructors do everything in a single function.
+    emitValueConstructorIfHasBody();
   }
 }
 
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 8a6fd6e..6e764cd 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -142,6 +142,12 @@
 
   if (funcDecl->isFinal())
     return true;
+  
+  // Native initializing entry points are always statically dispatched.
+  if (constant.kind == SILDeclRef::Kind::Initializer
+      && !constant.isForeign)
+    return true;
+  
   // Extension methods currently must be statically dispatched, unless they're
   // @objc or dynamic.
   if (funcDecl->getDeclContext()->isExtensionContext()
@@ -834,30 +840,64 @@
     visit(e->getFn());
   }
 
-  /// Idempotently convert a metatype to an objc metatype.
-  std::pair<ManagedValue, SILType> convertToObjCMetatype(ManagedValue selfMeta,
-                                                         SILLocation loc) {
-    auto metaType = selfMeta.getType().castTo<AnyMetatypeType>();
-    CanType instanceType = metaType.getInstanceType();
+  static constexpr unsigned metatypeRepPair(MetatypeRepresentation a,
+                                            MetatypeRepresentation b) {
+    return assert(unsigned(a) < 256 && unsigned(b) < 256
+                  && "MetatypeRepresentation got too big for its britches"),
+      unsigned(a) << 8 | unsigned(b);
+  }
 
-    // If we are already objc, just return.
-    if (metaType->getRepresentation() == MetatypeRepresentation::ObjC) {
+  /// Idempotently convert a metatype to a thick or objc metatype, depending
+  /// on what allocation mechanism we need for a given class hierarchy.
+  std::pair<ManagedValue, SILType>
+  convertToMetatypeForAllocRefDynamic(ManagedValue selfMeta,
+                                      SILLocation loc,
+                                      bool usesObjCAllocation) {
+    auto givenMetatype = selfMeta.getType().castTo<AnyMetatypeType>();
+    CanType instanceType = givenMetatype.getInstanceType();
+
+    auto destMetatypeRep = usesObjCAllocation
+      ? MetatypeRepresentation::ObjC
+      : MetatypeRepresentation::Thick;
+
+    // If we are already the right rep, just return.
+    auto givenMetatypeRep = givenMetatype->getRepresentation();
+    if (givenMetatypeRep == destMetatypeRep) {
       return {selfMeta, SGF.SGM.getLoweredType(instanceType)};
     }
 
-    CanAnyMetatypeType objcMetaType;
-    if (isa<MetatypeType>(metaType)) {
-      objcMetaType =
-          CanMetatypeType::get(instanceType, MetatypeRepresentation::ObjC);
+    CanAnyMetatypeType destMetatype;
+    if (isa<MetatypeType>(givenMetatype)) {
+      destMetatype =
+          CanMetatypeType::get(instanceType, destMetatypeRep);
     } else {
-      objcMetaType = CanExistentialMetatypeType::get(
-          instanceType, MetatypeRepresentation::ObjC);
+      destMetatype = CanExistentialMetatypeType::get(instanceType,
+                                                        destMetatypeRep);
     }
-    // ObjC metatypes are trivial and thus do not have a cleanup. Only if we
+    // Metatypes are trivial and thus do not have a cleanup. Only if we
     // convert them to an object do they become non-trivial.
     assert(!selfMeta.hasCleanup());
-    auto result = ManagedValue::forUnmanaged(SGF.B.emitThickToObjCMetatype(
-        loc, selfMeta.getValue(), SGF.SGM.getLoweredType(objcMetaType)));
+    SILValue convertedValue;
+    switch (metatypeRepPair(givenMetatypeRep, destMetatypeRep)) {
+    case metatypeRepPair(MetatypeRepresentation::Thick,
+                         MetatypeRepresentation::ObjC):
+      convertedValue = SGF.B.emitThickToObjCMetatype(
+        loc, selfMeta.getValue(),
+        SILType::getPrimitiveObjectType(destMetatype));
+      break;
+    
+    case metatypeRepPair(MetatypeRepresentation::ObjC,
+                         MetatypeRepresentation::Thick):
+      convertedValue = SGF.B.emitObjCToThickMetatype(
+        loc, selfMeta.getValue(),
+        SILType::getPrimitiveObjectType(destMetatype));
+      break;
+
+    default:
+      llvm_unreachable("shouldn't happen");
+    }
+
+    auto result = ManagedValue::forUnmanaged(convertedValue);
     return {result, SGF.SGM.getLoweredType(instanceType)};
   }
 
@@ -865,15 +905,18 @@
   /// object (with alloc_ref_dynamic) of that type.
   ///
   /// \returns the self object.
-  ManagedValue allocateObjCObject(ManagedValue selfMeta, SILLocation loc) {
-    // Convert to an Objective-C metatype representation, if needed.
-    ManagedValue selfMetaObjC;
+  ManagedValue allocateObject(ManagedValue selfMeta,
+                              SILLocation loc,
+                              bool usesObjCAllocation) {
+    // Convert to the necessary metatype representation, if needed.
+    ManagedValue selfMetaConverted;
     SILType instanceType;
-    std::tie(selfMetaObjC, instanceType) = convertToObjCMetatype(selfMeta, loc);
+    std::tie(selfMetaConverted, instanceType) =
+       convertToMetatypeForAllocRefDynamic(selfMeta, loc, usesObjCAllocation);
 
     // Allocate the object.
-    return SGF.B.createAllocRefDynamic(loc, selfMetaObjC, instanceType,
-                                       /*objc=*/true, {}, {});
+    return SGF.B.createAllocRefDynamic(loc, selfMetaConverted, instanceType,
+                                       usesObjCAllocation, {}, {});
   }
 
   void processProtocolMethod(DeclRefExpr *e, AbstractFunctionDecl *afd,
@@ -896,7 +939,7 @@
         kind = SILDeclRef::Kind::Initializer;
 
         auto metatype = std::move(selfValue).getAsSingleValue(SGF);
-        auto allocated = allocateObjCObject(metatype, loc);
+        auto allocated = allocateObject(metatype, loc, /*objc*/ true);
         auto allocatedType = allocated.getType().getASTType();
         selfValue =
             ArgumentSource(loc, RValue(SGF, loc, allocatedType, allocated));
@@ -969,7 +1012,8 @@
       SILLocation loc = thisCallSite->getArg();
       RValue selfMetatype = SGF.emitRValue(thisCallSite->getArg());
       auto selfValue =
-          allocateObjCObject(std::move(selfMetatype).getAsSingleValue(SGF, loc), loc);
+          allocateObject(std::move(selfMetatype).getAsSingleValue(SGF, loc),
+                         loc, /*objc*/ true);
       RValue self = RValue(SGF, loc, selfValue.getType().getASTType(),
                            selfValue);
       ArgumentSource selfArgSource(thisCallSite->getArg(), std::move(self));
@@ -1188,38 +1232,27 @@
   /// subset of expressions used there.
   ManagedValue emitCorrespondingSelfValue(ManagedValue selfValue,
                                           Expr *selfArg) {
+    SILLocation loc = selfArg;
+    auto resultTy = selfArg->getType()->getCanonicalType();
     while (true) {
       // Handle archetype-to-super and derived-to-base upcasts.
       if (isa<ArchetypeToSuperExpr>(selfArg) ||
           isa<DerivedToBaseExpr>(selfArg)) {
-        auto ice = cast<ImplicitConversionExpr>(selfArg);
-        auto resultTy = ice->getType()->getCanonicalType();
-
-        // If the 'self' value is a metatype, update the target type
-        // accordingly.
-        if (auto selfMetaTy = selfValue.getType().getAs<AnyMetatypeType>()) {
-          resultTy = CanMetatypeType::get(resultTy,
-                                          selfMetaTy->getRepresentation());
-        }
-        auto loweredResultTy = SGF.getLoweredLoadableType(resultTy);
-        if (loweredResultTy != selfValue.getType()) {
-          selfValue = SGF.emitManagedRValueWithCleanup(
-              SGF.B.createUpcast(ice, selfValue.forward(SGF), loweredResultTy));
-        }
-
-        selfArg = ice->getSubExpr();
+        selfArg = cast<ImplicitConversionExpr>(selfArg)->getSubExpr();
         continue;
       }
 
       // Skip over loads.
       if (auto load = dyn_cast<LoadExpr>(selfArg)) {
         selfArg = load->getSubExpr();
+        resultTy = resultTy->getRValueType()->getCanonicalType();
         continue;
       }
 
       // Skip over inout expressions.
       if (auto inout = dyn_cast<InOutExpr>(selfArg)) {
         selfArg = inout->getSubExpr();
+        resultTy = resultTy->getInOutObjectType()->getCanonicalType();
         continue;
       }
 
@@ -1229,7 +1262,37 @@
 
       llvm_unreachable("unhandled conversion for metatype value");
     }
-
+    assert(isa<DeclRefExpr>(selfArg) &&
+           "unexpected expr kind in self argument of initializer delegation");
+  
+    // If the 'self' value is a metatype, update the target type
+    // accordingly.
+    SILType loweredResultTy;
+    auto selfMetaTy = selfValue.getType().getAs<AnyMetatypeType>();
+    if (selfMetaTy) {
+      loweredResultTy = SILType::getPrimitiveObjectType(
+        CanMetatypeType::get(resultTy, selfMetaTy->getRepresentation()));
+    } else {
+      loweredResultTy = SGF.getLoweredLoadableType(resultTy);
+    }
+    
+    if (loweredResultTy != selfValue.getType()) {
+      // Introduce dynamic Self if necessary. A class initializer receives
+      // a metatype argument that's formally the non-dynamic base class type
+      // (though always dynamically of Self type),
+      // but when invoking a protocol initializer, we need to pass it as
+      // dynamic Self.
+      if (!selfValue.getType().getASTType()->hasDynamicSelfType()
+          && loweredResultTy.getASTType()->hasDynamicSelfType()) {
+        assert(selfMetaTy);
+        selfValue = SGF.emitManagedRValueWithCleanup(
+          SGF.B.createUncheckedBitCast(loc, selfValue.forward(SGF),
+                                       loweredResultTy));
+      } else {
+        selfValue = SGF.emitManagedRValueWithCleanup(
+            SGF.B.createUpcast(loc, selfValue.forward(SGF), loweredResultTy));
+      }
+    }
     return selfValue;
   }
 
@@ -1255,19 +1318,14 @@
     // protocols, which only witness initializing initializers.
     else if (auto proto = dyn_cast<ProtocolDecl>(nominal)) {
       useAllocatingCtor = !proto->isObjC();
-    // Factory initializers are effectively "allocating" initializers with no
-    // corresponding initializing entry point.
-    } else if (ctorRef->getDecl()->isFactoryInit()) {
-      useAllocatingCtor = true;
+    // Similarly, class initializers self.init-delegate to each other via
+    // their allocating entry points, unless delegating to an ObjC-only,
+    // non-factory initializer.
     } else {
-      // We've established we're in a class initializer or a protocol extension
-      // initializer for a class-bound protocol, In either case, we're
-      // delegating initialization, but we only have an instance in the former
-      // case.
       assert(isa<ClassDecl>(nominal)
              && "some new kind of init context we haven't implemented");
-      useAllocatingCtor = static_cast<bool>(SGF.AllocatorMetatype) &&
-                          !ctorRef->getDecl()->isObjC();
+      useAllocatingCtor = ctorRef->getDecl()->isFactoryInit()
+        || !requiresForeignEntryPoint(ctorRef->getDecl());
     }
 
     // Load the 'self' argument.
@@ -1292,16 +1350,20 @@
         self = ManagedValue::forUnmanaged(SGF.emitMetatypeOfValue(expr, arg));
       }
     } else {
-      // If we're in a protocol extension initializer, we haven't allocated
-      // "self" yet at this point. Do so. Use alloc_ref_dynamic since we should
-      // only ever get here in ObjC protocol extensions currently.
+      // If we haven't allocated "self" yet at this point, do so.
       if (SGF.AllocatorMetatype) {
-        assert(ctorRef->getDecl()->isObjC()
-               && "only expect to delegate an initializer from an allocator "
-                  "in objc protocol extensions");
+        bool usesObjCAllocation;
+        if (auto clas = dyn_cast<ClassDecl>(nominal)) {
+          usesObjCAllocation = usesObjCAllocator(clas);
+        } else {
+          // In the protocol extension case, we should only be here if the callee
+          // initializer is @objc.
+          usesObjCAllocation = true;
+        }
         
-        self = allocateObjCObject(
-                        ManagedValue::forUnmanaged(SGF.AllocatorMetatype), arg);
+        self = allocateObject(
+                      ManagedValue::forUnmanaged(SGF.AllocatorMetatype), arg,
+                      usesObjCAllocation);
 
         // Perform any adjustments needed to 'self'.
         self = emitCorrespondingSelfValue(self, arg);
@@ -1325,19 +1387,15 @@
 
     constant = constant.asForeign(requiresForeignEntryPoint(ctorRef->getDecl()));
 
-    // Determine the callee. For structs and enums, this is the allocating
-    // constructor (because there is no initializing constructor). For protocol
-    // default implementations, we also use the allocating constructor, because
-    // that's the only thing that's witnessed. For classes,
-    // this is the initializing constructor, to which we will dynamically
-    // dispatch.
+    // Determine the callee. This is normally the allocating
+    // entry point, unless we're delegating to an ObjC initializer.
     if (isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
       // Look up the witness for the constructor.
       setCallee(Callee::forWitnessMethod(
           SGF, self.getType().getASTType(),
           constant, subs, expr));
-    } else if (getMethodDispatch(ctorRef->getDecl())
-                 == MethodDispatch::Class) {
+    } else if ((useAllocatingCtor || constant.isForeign)
+            && getMethodDispatch(ctorRef->getDecl()) == MethodDispatch::Class) {
       // Dynamic dispatch to the initializer.
       Scope S(SGF, expr);
       setCallee(Callee::forClassMethod(
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 5928d91..aa0e8d5 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -1377,6 +1377,21 @@
 void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
   assert(thunk.isForeign);
   SILDeclRef native = thunk.asForeign(false);
+
+  // If we're calling a native non-designated class initializer, we have to
+  // discard the `self` object we were given, since
+  // Swift convenience initializers only have allocating entry points that
+  // create whole new objects.
+  bool isInitializingToAllocatingInitThunk = false;
+  if (native.kind == SILDeclRef::Kind::Initializer) {
+    if (auto ctor = dyn_cast<ConstructorDecl>(native.getDecl())) {
+      if (!ctor->isDesignatedInit()) {
+        isInitializingToAllocatingInitThunk = true;
+        native = SILDeclRef(ctor, SILDeclRef::Kind::Allocator);
+      }
+    }
+  }
+
   auto nativeInfo = getConstantInfo(native);
   auto subs = F.getForwardingSubstitutionMap();
   auto substTy = nativeInfo.SILFnType->substGenericArgs(SGM.M, subs);
@@ -1454,6 +1469,24 @@
                                          foreignErrorSlot, foreignError,
                                          nativeFormalResultType,
                                          bridgedFormalResultType);
+
+  // Throw away the partially-initialized `self` value we were given if we're
+  // bridging from an initializing to allocating entry point.
+  if (isInitializingToAllocatingInitThunk) {
+    auto oldSelf = args.pop_back_val();
+    auto oldSelfTy = B.createValueMetatype(loc,
+         SILType::getPrimitiveObjectType(
+           CanMetatypeType::get(oldSelf->getType().getASTType(),
+                                MetatypeRepresentation::Thick)),
+         oldSelf);
+    
+    B.createDeallocPartialRef(loc, oldSelf, oldSelfTy);
+    
+    // Pass the dynamic type on to the native allocating initializer.
+    args.push_back(oldSelfTy);
+    native = SILDeclRef(native.getDecl(), SILDeclRef::Kind::Allocator);
+  }
+
   SILFunctionConventions objcConv(CanSILFunctionType(objcFnTy), SGM.M);
   SILFunctionConventions nativeConv(CanSILFunctionType(nativeInfo.SILFnType),
                                     SGM.M);
diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp
index 39f62e8..870d93a 100644
--- a/lib/SILGen/SILGenConstructor.cpp
+++ b/lib/SILGen/SILGenConstructor.cpp
@@ -204,10 +204,6 @@
   // Get the 'self' decl and type.
   VarDecl *selfDecl = ctor->getImplicitSelfDecl();
   auto &lowering = getTypeLowering(selfDecl->getType());
-  SILType selfTy = lowering.getLoweredType();
-  (void)selfTy;
-  assert(!selfTy.getClassOrBoundGenericClass()
-         && "can't emit a class ctor here");
 
   // Decide if we need to do extra work to warn on unsafe behavior in pre-Swift-5
   // modes.
@@ -485,9 +481,9 @@
   // Allocate the 'self' value.
   bool useObjCAllocation = usesObjCAllocator(selfClassDecl);
 
-  if (ctor->isConvenienceInit() || ctor->hasClangNode()) {
-    // For a convenience initializer or an initializer synthesized
-    // for an Objective-C class, allocate using the metatype.
+  if (ctor->hasClangNode()) {
+    // For an allocator thunk synthesized for an Objective-C init method,
+    // allocate using the metatype.
     SILValue allocArg = selfMetaValue;
 
     // When using Objective-C allocation, convert the metatype
@@ -503,6 +499,7 @@
     selfValue = B.createAllocRefDynamic(Loc, allocArg, selfTy,
                                         useObjCAllocation, {}, {});
   } else {
+    assert(ctor->isDesignatedInit());
     // For a designated initializer, we know that the static type being
     // allocated is the type of the class that defines the designated
     // initializer.
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 9aac1b7..4ebe99e 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -3579,9 +3579,13 @@
     return WitnessDispatchKind::Static;
 
   // If the witness is dynamic, go through dynamic dispatch.
-  if (decl->isDynamic()
-      && witness.kind != SILDeclRef::Kind::Allocator)
+  if (decl->isDynamic()) {
+    // For initializers we still emit a static allocating thunk around
+    // the dynamic initializing entry point.
+    if (witness.kind == SILDeclRef::Kind::Allocator)
+      return WitnessDispatchKind::Static;
     return WitnessDispatchKind::Dynamic;
+  }
 
   bool isFinal = (decl->isFinal() || C->isFinal());
   if (auto fnDecl = dyn_cast<AbstractFunctionDecl>(witness.getDecl()))
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
index 7e5771a..bc30fb7 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -1476,15 +1476,15 @@
 }
 
 //===----------------------------------------------------------------------===//
-//                    DelegatingValueTypeInitUseCollector
+//                         DelegatingInitUseCollector
 //===----------------------------------------------------------------------===//
 
 static void
-collectValueTypeDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
-                                   DIElementUseInfo &UseInfo,
-                                   SingleValueInstruction *I) {
+collectDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
+                          DIElementUseInfo &UseInfo,
+                          SingleValueInstruction *I) {
   for (auto *Op : I->getUses()) {
-    auto *User = Op->getUser();
+    SILInstruction *User = Op->getUser();
 
     // destroy_addr is a release of the entire value. This can result from an
     // early release due to a conditional initializer.
@@ -1519,13 +1519,48 @@
 
     // Look through begin_access
     if (auto *BAI = dyn_cast<BeginAccessInst>(User)) {
-      collectValueTypeDelegatingInitUses(TheMemory, UseInfo, BAI);
+      collectDelegatingInitUses(TheMemory, UseInfo, BAI);
       continue;
     }
 
     // Ignore end_access
     if (isa<EndAccessInst>(User))
       continue;
+    
+    // A load of the value that's only used to handle a type(of:) query before
+    // self has been initialized can just use the initializer's metatype
+    // argument. For value types, there's no metatype subtyping to worry about,
+    // and for class convenience initializers, `self` notionally has the
+    // original Self type as its dynamic type before theoretically being
+    // rebound.
+    //
+    // This is necessary for source compatibility; previously, convenience
+    // initializers behaved like in Objective-C where the initializer received
+    // an uninitialized object to fill in, and type(of: self) worked by asking
+    // for the dynamic type of that uninitialized object.
+    if (isa<LoadInst>(User)) {
+      auto UserVal = cast<SingleValueInstruction>(User);
+      if (UserVal->hasOneUse()
+          && isa<ValueMetatypeInst>(UserVal->getSingleUse()->get())) {
+        Kind = DIUseKind::LoadForTypeOfSelf;
+      }
+    }
+    // value_metatype may appear on a borrowed load, in which case there'll
+    // be an end_borrow use in addition to the value_metatype.
+    if (isa<LoadBorrowInst>(User)) {
+      auto UserVal = cast<SingleValueInstruction>(User);
+      bool onlyUseIsValueMetatype = true;
+      for (auto use : UserVal->getUses()) {
+        if (isa<EndBorrowInst>(use->getUser())
+            || isa<ValueMetatypeInst>(use->getUser()))
+          continue;
+        onlyUseIsValueMetatype = false;
+        break;
+      }
+      if (onlyUseIsValueMetatype) {
+        Kind = DIUseKind::LoadForTypeOfSelf;
+      }
+    }
 
     // We can safely handle anything else as an escape.  They should all happen
     // after self.init is invoked.
@@ -1534,17 +1569,17 @@
 }
 
 //===----------------------------------------------------------------------===//
-//                   DelegatingClassInitElementUseCollector
+//                        ClassInitElementUseCollector
 //===----------------------------------------------------------------------===//
 
 namespace {
 
-class DelegatingClassInitElementUseCollector {
+class ClassInitElementUseCollector {
   const DIMemoryObjectInfo &TheMemory;
   DIElementUseInfo &UseInfo;
 
 public:
-  DelegatingClassInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
+  ClassInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
                                          DIElementUseInfo &UseInfo)
       : TheMemory(TheMemory), UseInfo(UseInfo) {}
 
@@ -1552,15 +1587,15 @@
 
   // *NOTE* Even though this takes a SILInstruction it actually only accepts
   // load_borrow and load instructions. This is enforced via an assert.
-  void collectDelegatingClassInitSelfLoadUses(MarkUninitializedInst *MUI,
-                                              SingleValueInstruction *LI);
+  void collectClassInitSelfLoadUses(MarkUninitializedInst *MUI,
+                                    SingleValueInstruction *LI);
 };
 
 } // end anonymous namespace
 
 /// collectDelegatingClassInitSelfUses - Collect uses of the self argument in a
 /// delegating-constructor-for-a-class case.
-void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
+void ClassInitElementUseCollector::collectClassInitSelfUses() {
   // When we're analyzing a delegating constructor, we aren't field sensitive at
   // all.  Just treat all members of self as uses of the single
   // non-field-sensitive value.
@@ -1668,8 +1703,7 @@
 
     // Loads of the box produce self, so collect uses from them.
     if (isa<LoadInst>(User) || isa<LoadBorrowInst>(User)) {
-      collectDelegatingClassInitSelfLoadUses(MUI,
-                                        cast<SingleValueInstruction>(User));
+      collectClassInitSelfLoadUses(MUI, cast<SingleValueInstruction>(User));
       continue;
     }
 
@@ -1691,8 +1725,8 @@
   gatherDestroysOfContainer(MUI, UseInfo);
 }
 
-void DelegatingClassInitElementUseCollector::
-collectDelegatingClassInitSelfLoadUses(MarkUninitializedInst *MUI,
+void ClassInitElementUseCollector::
+collectClassInitSelfLoadUses(MarkUninitializedInst *MUI,
                                        SingleValueInstruction *LI) {
   assert(isa<LoadBorrowInst>(LI) || isa<LoadInst>(LI));
 
@@ -1775,10 +1809,7 @@
 //===----------------------------------------------------------------------===//
 
 static bool shouldPerformClassInitSelf(const DIMemoryObjectInfo &MemoryInfo) {
-  if (MemoryInfo.isDelegatingInit()) {
-    assert(MemoryInfo.isClassInitSelf());
-    return true;
-  }
+  assert(!MemoryInfo.isDelegatingInit());
 
   return MemoryInfo.isNonDelegatingInit() &&
          MemoryInfo.getType()->getClassOrBoundGenericClass() != nullptr &&
@@ -1792,18 +1823,17 @@
     const DIMemoryObjectInfo &MemoryInfo, DIElementUseInfo &UseInfo,
     bool isDIFinished, bool TreatAddressToPointerAsInout) {
 
-  if (MemoryInfo.isDelegatingInit() && !MemoryInfo.isClassInitSelf()) {
+  if (MemoryInfo.isDelegatingInit()) {
     // When we're analyzing a delegating constructor, we aren't field sensitive
     // at all. Just treat all members of self as uses of the single
     // non-field-sensitive value.
     assert(MemoryInfo.NumElements == 1 && "delegating inits only have 1 bit");
-    collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo,
-                                       MemoryInfo.MemoryInst);
+    collectDelegatingInitUses(MemoryInfo, UseInfo, MemoryInfo.MemoryInst);
     return;
   }
 
   if (shouldPerformClassInitSelf(MemoryInfo)) {
-    DelegatingClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
+    ClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
     UseCollector.collectClassInitSelfUses();
     return;
   }
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h
index bf9f8cc..f3feab4 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.h
@@ -116,8 +116,12 @@
     return false;
   }
 
-  /// True if the memory object is the 'self' argument of a class initializer.
+  /// True if the memory object is the 'self' argument of a class designated
+  /// initializer.
   bool isClassInitSelf() const {
+    if (isDelegatingInit())
+      return false;
+      
     if (!MemoryInst->isVar()) {
       if (auto decl = getType()->getAnyNominal()) {
         if (isa<ClassDecl>(decl)) {
@@ -226,7 +230,11 @@
 
   /// This instruction is a call to 'self.init' in a delegating initializer,
   /// or a call to 'super.init' in a designated initializer of a derived class..
-  SelfInit
+  SelfInit,
+  
+  /// This instruction is a load that's only used to answer a `type(of: self)`
+  /// question.
+  LoadForTypeOfSelf,
 };
 
 /// This struct represents a single classified access to the memory object
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index 4ed5075..44edb6e 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -480,6 +480,7 @@
 
     void handleStoreUse(unsigned UseID);
     void handleLoadUse(unsigned UseID);
+    void handleLoadForTypeOfSelfUse(const DIMemoryUse &Use);
     void handleInOutUse(const DIMemoryUse &Use);
     void handleEscapeUse(const DIMemoryUse &Use);
 
@@ -542,8 +543,21 @@
     // Keep track of all the uses that aren't loads or escapes.  These are
     // important uses that we'll visit, but we don't consider them definition
     // points for liveness computation purposes.
-    if (Use.Kind == DIUseKind::Load || Use.Kind == DIUseKind::Escape)
+    switch (Use.Kind) {
+    case DIUseKind::Load:
+    case DIUseKind::LoadForTypeOfSelf:
+    case DIUseKind::Escape:
       continue;
+    case DIUseKind::Assign:
+    case DIUseKind::IndirectIn:
+    case DIUseKind::InitOrAssign:
+    case DIUseKind::InOutArgument:
+    case DIUseKind::Initialization:
+    case DIUseKind::InOutSelfArgument:
+    case DIUseKind::PartialStore:
+    case DIUseKind::SelfInit:
+      break;
+    }
 
     NonLoadUses[Use.Inst] = ui;
 
@@ -790,6 +804,8 @@
     case DIUseKind::SelfInit:
       handleSelfInitUse(Use);
       break;
+    case DIUseKind::LoadForTypeOfSelf:
+      handleLoadForTypeOfSelfUse(Use);
     }
   }
 
@@ -826,6 +842,27 @@
     return handleLoadUseFailure(Use, IsSuperInitComplete, FailedSelfUse);
 }
 
+void LifetimeChecker::handleLoadForTypeOfSelfUse(const DIMemoryUse &Use) {
+  bool IsSuperInitComplete, FailedSelfUse;
+  // If the value is not definitively initialized, replace the
+  // value_metatype instruction with the metatype argument that was passed into
+  // the initializer.
+  if (!isInitializedAtUse(Use, &IsSuperInitComplete, &FailedSelfUse)) {
+    auto load = cast<SingleValueInstruction>(Use.Inst);
+    
+    ValueMetatypeInst *valueMetatype = nullptr;
+    for (auto use : load->getUses()) {
+      valueMetatype = dyn_cast<ValueMetatypeInst>(use->getUser());
+      if (valueMetatype)
+        break;
+    }
+    assert(valueMetatype);
+    auto metatypeArgument = load->getFunction()->getSelfMetadataArgument();
+    replaceAllSimplifiedUsesAndErase(valueMetatype, metatypeArgument,
+                                     [](SILInstruction*) { });
+  }
+}
+
 void LifetimeChecker::emitSelfConsumedDiagnostic(SILInstruction *Inst) {
   if (!shouldEmitError(Inst))
     return;
@@ -1930,12 +1967,13 @@
     auto SILMetatypeTy = SILType::getPrimitiveObjectType(MetatypeTy);
     SILValue Metatype;
 
-    // In an inherited convenience initializer, we must use the dynamic
-    // type of the object since nothing is initialized yet.
-    if (TheMemory.isDelegatingInit())
-      Metatype = B.createValueMetatype(Loc, SILMetatypeTy, Pointer);
-    else
-      Metatype = B.createMetatype(Loc, SILMetatypeTy);
+    // A convenience initializer should never deal in partially allocated
+    // objects.
+    assert(!TheMemory.isDelegatingInit());
+
+    // In a designated initializer, we know the class of the thing
+    // we're cleaning up statically.
+    Metatype = B.createMetatype(Loc, SILMetatypeTy);
 
     // We've already destroyed any instance variables initialized by this
     // constructor, now destroy instance variables initialized by subclass
diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp
index 5476f5f..a169770 100644
--- a/lib/Sema/TypeCheckAvailability.cpp
+++ b/lib/Sema/TypeCheckAvailability.cpp
@@ -1937,6 +1937,12 @@
   if (!Attr)
     return;
 
+  // We don't want deprecated declarations to trigger warnings
+  // in synthesized code.
+  if (ReferenceRange.isInvalid() &&
+      isInsideImplicitFunction(ReferenceRange, ReferenceDC)) {
+    return;
+  }
   // We match the behavior of clang to not report deprecation warnings
   // inside declarations that are themselves deprecated on all deployment
   // targets.
diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp
index 4696fd5..758eaa3 100644
--- a/lib/Sema/TypeCheckDeclOverride.cpp
+++ b/lib/Sema/TypeCheckDeclOverride.cpp
@@ -201,7 +201,6 @@
     // Factory initializers cannot be overridden.
     if (parentCtor->isFactoryInit())
       return false;
-
   } else if (auto var = dyn_cast<VarDecl>(decl)) {
     auto parentVar = cast<VarDecl>(parentDecl);
     if (var->isStatic() != parentVar->isStatic())
@@ -1309,10 +1308,9 @@
   }
 
   if (auto ctor = dyn_cast<ConstructorDecl>(overridden)) {
-    if (ctor->isDesignatedInit() && !ctor->isRequired())
-      return OverrideRequiresKeyword::Always;
-
-    return OverrideRequiresKeyword::Never;
+    return !ctor->isDesignatedInit() || ctor->isRequired()
+      ? OverrideRequiresKeyword::Never
+      : OverrideRequiresKeyword::Always;
   }
 
   return OverrideRequiresKeyword::Always;
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 06e277b..6dc3db3 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -2160,7 +2160,7 @@
 public:
   /// \param S A string with an encoded message
   EncodedDiagnosticMessage(StringRef S)
-      : Message(Lexer::getEncodedStringSegment(S, Buf)) {}
+      : Message(Lexer::getEncodedStringSegment(S, Buf, true, true, ~0U)) {}
 
   /// The unescaped message to display to the user.
   const StringRef Message;
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 989c17f..db80f3b 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -1738,20 +1738,10 @@
   assert(rawID < Identifiers.size() && "invalid identifier ID");
   auto &identRecord = Identifiers[rawID];
 
-  if (identRecord.Offset == 0)
-    return identRecord.Ident;
-
-  assert(!IdentifierData.empty() && "no identifier data in module");
-
-  StringRef rawStrPtr = IdentifierData.substr(identRecord.Offset);
-  size_t terminatorOffset = rawStrPtr.find('\0');
-  assert(terminatorOffset != StringRef::npos &&
-         "unterminated identifier string data");
-
-  // Cache the resulting identifier.
-  identRecord.Ident =
-      getContext().getIdentifier(rawStrPtr.slice(0, terminatorOffset));
-  identRecord.Offset = 0;
+  if (identRecord.Ident.empty()) {
+    StringRef text = getIdentifierText(IID);
+    identRecord.Ident = getContext().getIdentifier(text);
+  }
   return identRecord.Ident;
 }
 
@@ -1761,6 +1751,28 @@
   return name.getIdentifier();
 }
 
+StringRef ModuleFile::getIdentifierText(IdentifierID IID) {
+  if (IID == 0)
+    return StringRef();
+
+  assert(IID >= NUM_SPECIAL_IDS);
+
+  size_t rawID = IID - NUM_SPECIAL_IDS;
+  assert(rawID < Identifiers.size() && "invalid identifier ID");
+  auto identRecord = Identifiers[rawID];
+
+  if (!identRecord.Ident.empty())
+    return identRecord.Ident.str();
+
+  assert(!IdentifierData.empty() && "no identifier data in module");
+
+  StringRef rawStrPtr = IdentifierData.substr(identRecord.Offset);
+  size_t terminatorOffset = rawStrPtr.find('\0');
+  assert(terminatorOffset != StringRef::npos &&
+         "unterminated identifier string data");
+  return rawStrPtr.slice(0, terminatorOffset);
+}
+
 DeclContext *ModuleFile::getLocalDeclContext(DeclContextID DCID) {
   assert(DCID != 0 && "invalid local DeclContext ID 0");
   auto &declContextOrOffset = LocalDeclContexts[DCID-1];
@@ -2785,11 +2797,7 @@
       errorFlags |= DeclDeserializationError::NeedsVTableEntry;
       DeclAttributes attrs;
       attrs.setRawAttributeChain(DAttrs);
-      if (attrs.hasAttribute<RequiredAttr>())
-        errorFlags |= DeclDeserializationError::NeedsAllocatingVTableEntry;
     }
-    if (firstTimeRequired)
-      errorFlags |= DeclDeserializationError::NeedsAllocatingVTableEntry;
 
     auto overridden = getDeclChecked(overriddenID);
     if (!overridden) {
@@ -3661,7 +3669,7 @@
     DeclContextID contextID;
     bool isImplicit; bool hasPayload; bool isNegative;
     unsigned rawValueKindID;
-    IdentifierID blobData;
+    IdentifierID rawValueData;
     uint8_t rawResilienceExpansion;
     unsigned numArgNames;
     ArrayRef<uint64_t> argNameAndDependencyIDs;
@@ -3669,7 +3677,7 @@
     decls_block::EnumElementLayout::readRecord(scratch, contextID,
                                                isImplicit, hasPayload,
                                                rawValueKindID, isNegative,
-                                               blobData,
+                                               rawValueData,
                                                rawResilienceExpansion,
                                                numArgNames,
                                                argNameAndDependencyIDs);
@@ -3713,8 +3721,8 @@
     case EnumElementRawValueKind::None:
       break;
     case EnumElementRawValueKind::IntegerLiteral: {
-      auto literalText = getIdentifier(blobData);
-      auto literal = new (getContext()) IntegerLiteralExpr(literalText.get(),
+      auto literalText = getIdentifierText(rawValueData);
+      auto literal = new (getContext()) IntegerLiteralExpr(literalText,
                                                            SourceLoc(),
                                                            /*implicit*/ true);
       if (isNegative)
@@ -4943,13 +4951,12 @@
   auto handleMissingClassMember = [&](const DeclDeserializationError &error) {
     if (error.isDesignatedInitializer())
       containingClass->setHasMissingDesignatedInitializers();
-    if (error.needsVTableEntry() || error.needsAllocatingVTableEntry())
+    if (error.needsVTableEntry())
       containingClass->setHasMissingVTableEntries();
 
     if (error.getName().getBaseName() == DeclBaseName::createConstructor()) {
       suppliedMissingMember = MissingMemberDecl::forInitializer(
-          context, containingClass, error.getName(), error.needsVTableEntry(),
-          error.needsAllocatingVTableEntry());
+          context, containingClass, error.getName(), error.needsVTableEntry());
     } else if (error.needsVTableEntry()) {
       suppliedMissingMember = MissingMemberDecl::forMethod(
           context, containingClass, error.getName(), error.needsVTableEntry());
@@ -4971,14 +4978,13 @@
 
   auto handleMissingProtocolMember =
       [&](const DeclDeserializationError &error) {
-        assert(!error.needsAllocatingVTableEntry());
         if (error.needsVTableEntry())
           containingProto->setHasMissingRequirements(true);
 
         if (error.getName().getBaseName() == DeclBaseName::createConstructor()) {
           suppliedMissingMember = MissingMemberDecl::forInitializer(
               context, containingProto, error.getName(),
-              error.needsVTableEntry(), error.needsAllocatingVTableEntry());
+              error.needsVTableEntry());
               return;
         }
         if (error.needsVTableEntry()) {
diff --git a/lib/Serialization/DeserializationErrors.h b/lib/Serialization/DeserializationErrors.h
index ef913c8..f2f20e1 100644
--- a/lib/Serialization/DeserializationErrors.h
+++ b/lib/Serialization/DeserializationErrors.h
@@ -227,8 +227,7 @@
   enum Flag : unsigned {
     DesignatedInitializer = 1 << 0,
     NeedsVTableEntry = 1 << 1,
-    NeedsAllocatingVTableEntry = 1 << 2,
-    NeedsFieldOffsetVectorEntry = 1 << 3,
+    NeedsFieldOffsetVectorEntry = 1 << 2,
   };
   using Flags = OptionSet<Flag>;
 
@@ -247,9 +246,6 @@
   bool needsVTableEntry() const {
     return flags.contains(Flag::NeedsVTableEntry);
   }
-  bool needsAllocatingVTableEntry() const {
-    return flags.contains(Flag::NeedsAllocatingVTableEntry);
-  }
   bool needsFieldOffsetVectorEntry() const {
     return flags.contains(Flag::NeedsFieldOffsetVectorEntry);
   }
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index dc1e7e0..4f2f61c 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -87,6 +87,8 @@
 
 /// Used to deserialize entries in the on-disk func hash table.
 class SILDeserializer::FuncTableInfo {
+  ModuleFile &MF;
+
 public:
   using internal_key_type = StringRef;
   using external_key_type = StringRef;
@@ -94,6 +96,8 @@
   using hash_value_type = uint32_t;
   using offset_type = unsigned;
 
+  explicit FuncTableInfo(ModuleFile &MF) : MF(MF) {}
+
   internal_key_type GetInternalKey(external_key_type ID) { return ID; }
 
   external_key_type GetExternalKey(internal_key_type ID) { return ID; }
@@ -108,12 +112,13 @@
   }
 
   static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
-    unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
-    return { keyLength, sizeof(uint32_t) };
+    return { sizeof(uint32_t), sizeof(uint32_t) };
   }
 
-  static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
-    return StringRef(reinterpret_cast<const char *>(data), length);
+  internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+    assert(length == sizeof(uint32_t) && "Expect a single IdentifierID.");
+    IdentifierID keyID = endian::readNext<uint32_t, little, unaligned>(data);
+    return MF.getIdentifierText(keyID);
   }
 
   static data_type ReadData(internal_key_type key, const uint8_t *data,
@@ -177,7 +182,7 @@
       DefaultWitnessTableList = readFuncTable(scratch, blobData);
     else if (kind == sil_index_block::SIL_PROPERTY_OFFSETS) {
       // No matching 'names' block for property descriptors needed yet.
-      Properties.assign(scratch.begin(), scratch.end());
+      MF->allocateBuffer(Properties, scratch);
       return;
     }
 
@@ -190,27 +195,27 @@
       assert((next.Kind == llvm::BitstreamEntry::Record &&
               offKind == sil_index_block::SIL_FUNC_OFFSETS) &&
              "Expect a SIL_FUNC_OFFSETS record.");
-      Funcs.assign(scratch.begin(), scratch.end());
+      MF->allocateBuffer(Funcs, scratch);
     } else if (kind == sil_index_block::SIL_VTABLE_NAMES) {
       assert((next.Kind == llvm::BitstreamEntry::Record &&
               offKind == sil_index_block::SIL_VTABLE_OFFSETS) &&
              "Expect a SIL_VTABLE_OFFSETS record.");
-      VTables.assign(scratch.begin(), scratch.end());
+      MF->allocateBuffer(VTables, scratch);
     } else if (kind == sil_index_block::SIL_GLOBALVAR_NAMES) {
       assert((next.Kind == llvm::BitstreamEntry::Record &&
               offKind == sil_index_block::SIL_GLOBALVAR_OFFSETS) &&
              "Expect a SIL_GLOBALVAR_OFFSETS record.");
-      GlobalVars.assign(scratch.begin(), scratch.end());
+      MF->allocateBuffer(GlobalVars, scratch);
     } else if (kind == sil_index_block::SIL_WITNESS_TABLE_NAMES) {
       assert((next.Kind == llvm::BitstreamEntry::Record &&
               offKind == sil_index_block::SIL_WITNESS_TABLE_OFFSETS) &&
              "Expect a SIL_WITNESS_TABLE_OFFSETS record.");
-      WitnessTables.assign(scratch.begin(), scratch.end());
+      MF->allocateBuffer(WitnessTables, scratch);
     } else if (kind == sil_index_block::SIL_DEFAULT_WITNESS_TABLE_NAMES) {
       assert((next.Kind == llvm::BitstreamEntry::Record &&
               offKind == sil_index_block::SIL_DEFAULT_WITNESS_TABLE_OFFSETS) &&
              "Expect a SIL_DEFAULT_WITNESS_TABLE_OFFSETS record.");
-      DefaultWitnessTables.assign(scratch.begin(), scratch.end());
+      MF->allocateBuffer(DefaultWitnessTables, scratch);
     }
   }
 }
@@ -223,7 +228,8 @@
 
   using OwnedTable = std::unique_ptr<SerializedFuncTable>;
   return OwnedTable(SerializedFuncTable::Create(base + tableOffset,
-                                                base + sizeof(uint32_t), base));
+                                                base + sizeof(uint32_t), base,
+                                                FuncTableInfo(*MF)));
 }
 
 /// A high-level overview of how forward references work in serializer and
@@ -561,7 +567,7 @@
     if (clangNodeOwner)
       fn->setClangNodeOwner(clangNodeOwner);
     for (auto ID : SemanticsIDs) {
-      fn->addSemanticsAttr(MF->getIdentifier(ID).str());
+      fn->addSemanticsAttr(MF->getIdentifierText(ID));
     }
 
     if (Callback) Callback->didDeserialize(MF->getAssociatedModule(), fn);
@@ -822,8 +828,8 @@
     case KeyPathComputedComponentIdKindEncoding::Property:
       return cast<VarDecl>(MF->getDecl(ListOfValues[nextValue++]));
     case KeyPathComputedComponentIdKindEncoding::Function: {
-      auto name = MF->getIdentifier(ListOfValues[nextValue++]);
-      return getFuncForReference(name.str());
+      auto name = MF->getIdentifierText(ListOfValues[nextValue++]);
+      return getFuncForReference(name);
     }
     case KeyPathComputedComponentIdKindEncoding::DeclRef: {
       // read SILDeclRef
@@ -862,10 +868,10 @@
     
     indices = MF->getContext().AllocateCopy(indicesBuf);
     if (!indices.empty()) {
-      auto indicesEqualsName = MF->getIdentifier(ListOfValues[nextValue++]);
-      auto indicesHashName = MF->getIdentifier(ListOfValues[nextValue++]);
-      indicesEquals = getFuncForReference(indicesEqualsName.str());
-      indicesHash = getFuncForReference(indicesHashName.str());
+      auto indicesEqualsName = MF->getIdentifierText(ListOfValues[nextValue++]);
+      auto indicesHashName = MF->getIdentifierText(ListOfValues[nextValue++]);
+      indicesEquals = getFuncForReference(indicesEqualsName);
+      indicesHash = getFuncForReference(indicesHashName);
     }
   };
 
@@ -876,8 +882,8 @@
   }
   case KeyPathComponentKindEncoding::GettableProperty: {
     auto id = handleComputedId();
-    auto getterName = MF->getIdentifier(ListOfValues[nextValue++]);
-    auto getter = getFuncForReference(getterName.str());
+    auto getterName = MF->getIdentifierText(ListOfValues[nextValue++]);
+    auto getter = getFuncForReference(getterName);
     handleComputedExternalReferenceAndIndices();
     return KeyPathPatternComponent::forComputedGettableProperty(
         id, getter, indices, indicesEquals, indicesHash,
@@ -885,10 +891,10 @@
   }
   case KeyPathComponentKindEncoding::SettableProperty: {
     auto id = handleComputedId();
-    auto getterName = MF->getIdentifier(ListOfValues[nextValue++]);
-    auto getter = getFuncForReference(getterName.str());
-    auto setterName = MF->getIdentifier(ListOfValues[nextValue++]);
-    auto setter = getFuncForReference(setterName.str());
+    auto getterName = MF->getIdentifierText(ListOfValues[nextValue++]);
+    auto getter = getFuncForReference(getterName);
+    auto setterName = MF->getIdentifierText(ListOfValues[nextValue++]);
+    auto setter = getFuncForReference(setterName);
     handleComputedExternalReferenceAndIndices();
     return KeyPathPatternComponent::forComputedSettableProperty(
         id, getter, setter, indices, indicesEquals, indicesHash,
@@ -1411,10 +1417,10 @@
   }
   case SILInstructionKind::AllocGlobalInst: {
     // Format: Name and type. Use SILOneOperandLayout.
-    Identifier Name = MF->getIdentifier(ValID);
+    StringRef Name = MF->getIdentifierText(ValID);
 
     // Find the global variable.
-    SILGlobalVariable *g = getGlobalForReference(Name.str());
+    SILGlobalVariable *g = getGlobalForReference(Name);
     assert(g && "Can't deserialize global variable");
 
     ResultVal = Builder.createAllocGlobal(Loc, g);
@@ -1424,10 +1430,10 @@
   case SILInstructionKind::GlobalValueInst: {
     // Format: Name and type. Use SILOneOperandLayout.
     auto Ty = MF->getType(TyID);
-    Identifier Name = MF->getIdentifier(ValID);
+    StringRef Name = MF->getIdentifierText(ValID);
 
     // Find the global variable.
-    SILGlobalVariable *g = getGlobalForReference(Name.str());
+    SILGlobalVariable *g = getGlobalForReference(Name);
     assert(g && "Can't deserialize global variable");
     SILType expectedType = (OpCode == SILInstructionKind::GlobalAddrInst ?
                             g->getLoweredType().getAddressType() :
@@ -1470,9 +1476,9 @@
   }
   case SILInstructionKind::FunctionRefInst: {
     auto Ty = MF->getType(TyID);
-    Identifier FuncName = MF->getIdentifier(ValID);
+    StringRef FuncName = MF->getIdentifierText(ValID);
     ResultVal = Builder.createFunctionRef(Loc,
-        getFuncForReference(FuncName.str(),
+        getFuncForReference(FuncName,
                             getSILType(Ty, (SILValueCategory)TyCategory)));
     break;
   }
@@ -1527,9 +1533,9 @@
   case SILInstructionKind::IntegerLiteralInst: {
     auto Ty = MF->getType(TyID);
     auto intTy = Ty->castTo<BuiltinIntegerType>();
-    Identifier StringVal = MF->getIdentifier(ValID);
+    StringRef StringVal = MF->getIdentifierText(ValID);
     // Build APInt from string.
-    APInt value(intTy->getGreatestWidth(), StringVal.str(), 10);
+    APInt value(intTy->getGreatestWidth(), StringVal, 10);
     ResultVal = Builder.createIntegerLiteral(Loc,
         getSILType(Ty, (SILValueCategory)TyCategory),
         value);
@@ -1538,9 +1544,9 @@
   case SILInstructionKind::FloatLiteralInst: {
     auto Ty = MF->getType(TyID);
     auto floatTy = Ty->castTo<BuiltinFloatType>();
-    Identifier StringVal = MF->getIdentifier(ValID);
+    StringRef StringVal = MF->getIdentifierText(ValID);
     // Build APInt from string.
-    APInt bits(floatTy->getBitWidth(), StringVal.str(), 16);
+    APInt bits(floatTy->getBitWidth(), StringVal, 16);
     if (bits.getBitWidth() != floatTy->getBitWidth())
       bits = bits.zextOrTrunc(floatTy->getBitWidth());
 
@@ -1552,10 +1558,10 @@
     break;
   }
   case SILInstructionKind::StringLiteralInst: {
-    Identifier StringVal = MF->getIdentifier(ValID);
+    StringRef StringVal = MF->getIdentifierText(ValID);
     auto encoding = fromStableStringEncoding(Attr);
     if (!encoding) return true;
-    ResultVal = Builder.createStringLiteral(Loc, StringVal.str(),
+    ResultVal = Builder.createStringLiteral(Loc, StringVal,
                                             encoding.getValue());
     break;
   }
@@ -2346,7 +2352,7 @@
     auto numComponents = ListOfValues[nextValue++];
     auto numOperands = ListOfValues[nextValue++];
     auto subMap = MF->getSubstitutionMap(ListOfValues[nextValue++]);
-    auto objcString = MF->getIdentifier(ListOfValues[nextValue++]).str();
+    auto objcString = MF->getIdentifierText(ListOfValues[nextValue++]);
     auto numGenericParams = ListOfValues[nextValue++];
     
     SmallVector<GenericTypeParamType *, 4> genericParams;
@@ -2685,7 +2691,7 @@
 
     auto EntryKind = fromStableVTableEntryKind(RawEntryKind);
 
-    SILFunction *Func = getFuncForReference(MF->getIdentifier(NameID).str());
+    SILFunction *Func = getFuncForReference(MF->getIdentifierText(NameID));
     if (Func) {
       unsigned NextValueIndex = 0;
       vtableEntries.emplace_back(getSILDeclRef(MF, ListOfValues, NextValueIndex),
@@ -2912,7 +2918,7 @@
       WitnessMethodEntryLayout::readRecord(scratch, NameID, ListOfValues);
       SILFunction *Func = nullptr;
       if (NameID != 0) {
-        Func = getFuncForReference(MF->getIdentifier(NameID).str());
+        Func = getFuncForReference(MF->getIdentifierText(NameID));
       }
       if (Func || NameID == 0) {
         unsigned NextValueIndex = 0;
@@ -3079,7 +3085,7 @@
       DefaultWitnessTableEntryLayout::readRecord(scratch, NameID, ListOfValues);
       SILFunction *Func = nullptr;
       if (NameID != 0) {
-        Func = getFuncForReference(MF->getIdentifier(NameID).str());
+        Func = getFuncForReference(MF->getIdentifierText(NameID));
       }
       if (Func || NameID == 0) {
         unsigned NextValueIndex = 0;
@@ -3124,7 +3130,7 @@
 
   // Use the mangled name of the protocol to lookup the partially
   // deserialized value from the default witness table list.
-  auto iter = DefaultWitnessTableList->find(existingWt->getIdentifier().str());
+  auto iter = DefaultWitnessTableList->find(existingWt->getUniqueName());
   if (iter == DefaultWitnessTableList->end())
     return nullptr;
 
diff --git a/lib/Serialization/DeserializeSIL.h b/lib/Serialization/DeserializeSIL.h
index d16521c..040ee16 100644
--- a/lib/Serialization/DeserializeSIL.h
+++ b/lib/Serialization/DeserializeSIL.h
@@ -39,23 +39,23 @@
       llvm::OnDiskIterableChainedHashTable<FuncTableInfo>;
 
     std::unique_ptr<SerializedFuncTable> FuncTable;
-    std::vector<ModuleFile::PartiallySerialized<SILFunction*>> Funcs;
+    MutableArrayRef<ModuleFile::PartiallySerialized<SILFunction*>> Funcs;
 
     std::unique_ptr<SerializedFuncTable> VTableList;
-    std::vector<ModuleFile::Serialized<SILVTable*>> VTables;
+    MutableArrayRef<ModuleFile::Serialized<SILVTable*>> VTables;
 
     std::unique_ptr<SerializedFuncTable> GlobalVarList;
-    std::vector<ModuleFile::Serialized<SILGlobalVariable*>> GlobalVars;
+    MutableArrayRef<ModuleFile::Serialized<SILGlobalVariable*>> GlobalVars;
 
     std::unique_ptr<SerializedFuncTable> WitnessTableList;
-    std::vector<ModuleFile::PartiallySerialized<SILWitnessTable *>>
+    MutableArrayRef<ModuleFile::PartiallySerialized<SILWitnessTable *>>
     WitnessTables;
 
     std::unique_ptr<SerializedFuncTable> DefaultWitnessTableList;
-    std::vector<ModuleFile::PartiallySerialized<SILDefaultWitnessTable *>>
+    MutableArrayRef<ModuleFile::PartiallySerialized<SILDefaultWitnessTable *>>
     DefaultWitnessTables;
 
-    std::vector<ModuleFile::PartiallySerialized<SILProperty *>>
+    MutableArrayRef<ModuleFile::PartiallySerialized<SILProperty *>>
     Properties;
 
     /// A declaration will only
diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp
index 81f8d16..034f0b3 100644
--- a/lib/Serialization/ModuleFile.cpp
+++ b/lib/Serialization/ModuleFile.cpp
@@ -796,19 +796,19 @@
       switch (kind) {
       case index_block::DECL_OFFSETS:
         assert(blobData.empty());
-        Decls.assign(scratch.begin(), scratch.end());
+        allocateBuffer(Decls, scratch);
         break;
       case index_block::DECL_CONTEXT_OFFSETS:
         assert(blobData.empty());
-        DeclContexts.assign(scratch.begin(), scratch.end());
+        allocateBuffer(DeclContexts, scratch);
         break;
       case index_block::TYPE_OFFSETS:
         assert(blobData.empty());
-        Types.assign(scratch.begin(), scratch.end());
+        allocateBuffer(Types, scratch);
         break;
       case index_block::IDENTIFIER_OFFSETS:
         assert(blobData.empty());
-        Identifiers.assign(scratch.begin(), scratch.end());
+        allocateBuffer(Identifiers, scratch);
         break;
       case index_block::TOP_LEVEL_DECLS:
         TopLevelDecls = readDeclTable(scratch, blobData);
@@ -836,7 +836,7 @@
         setEntryPointClassID(scratch.front());
         break;
       case index_block::ORDERED_TOP_LEVEL_DECLS:
-        OrderedTopLevelDecls.assign(scratch.begin(), scratch.end());
+        allocateBuffer(OrderedTopLevelDecls, scratch);
         break;
       case index_block::LOCAL_TYPE_DECLS:
         LocalTypeDecls = readLocalDeclTable(scratch, blobData);
@@ -849,27 +849,27 @@
         break;
       case index_block::LOCAL_DECL_CONTEXT_OFFSETS:
         assert(blobData.empty());
-        LocalDeclContexts.assign(scratch.begin(), scratch.end());
+        allocateBuffer(LocalDeclContexts, scratch);
         break;
       case index_block::GENERIC_SIGNATURE_OFFSETS:
         assert(blobData.empty());
-        GenericSignatures.assign(scratch.begin(), scratch.end());
+        allocateBuffer(GenericSignatures, scratch);
         break;
       case index_block::GENERIC_ENVIRONMENT_OFFSETS:
         assert(blobData.empty());
-        GenericEnvironments.assign(scratch.begin(), scratch.end());
+        allocateBuffer(GenericEnvironments, scratch);
         break;
       case index_block::SUBSTITUTION_MAP_OFFSETS:
         assert(blobData.empty());
-        SubstitutionMaps.assign(scratch.begin(), scratch.end());
+        allocateBuffer(SubstitutionMaps, scratch);
         break;
       case index_block::NORMAL_CONFORMANCE_OFFSETS:
         assert(blobData.empty());
-        NormalConformances.assign(scratch.begin(), scratch.end());
+        allocateBuffer(NormalConformances, scratch);
         break;
       case index_block::SIL_LAYOUT_OFFSETS:
         assert(blobData.empty());
-        SILLayouts.assign(scratch.begin(), scratch.end());
+        allocateBuffer(SILLayouts, scratch);
         break;
 
       default:
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 6ac6b85..050ba0b 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -690,8 +690,8 @@
     if (id != 0)
       return id;
 
-    id = ++LastIdentifierID;
-    IdentifiersToWrite.push_back(ident.getIdentifier());
+    id = ++LastUniquedStringID;
+    StringsToWrite.push_back(ident.getIdentifier().str());
     return id;
   }
   case DeclBaseName::Kind::Subscript:
@@ -703,6 +703,24 @@
   }
 }
 
+std::pair<StringRef, IdentifierID> Serializer::addUniquedString(StringRef str) {
+  if (str.empty())
+    return {str, 0};
+
+  decltype(UniquedStringIDs)::iterator iter;
+  bool isNew;
+  std::tie(iter, isNew) =
+      UniquedStringIDs.insert({str, LastUniquedStringID + 1});
+
+  if (!isNew)
+    return {iter->getKey(), iter->getValue()};
+
+  ++LastUniquedStringID;
+  // Note that we use the string data stored in the StringMap.
+  StringsToWrite.push_back(iter->getKey());
+  return {iter->getKey(), LastUniquedStringID};
+}
+
 IdentifierID Serializer::addModuleRef(const ModuleDecl *M) {
   if (M == this->M)
     return CURRENT_MODULE_ID;
@@ -3312,12 +3330,12 @@
     // of the ABI. That isn't the case for Swift enums.
     auto RawValueKind = EnumElementRawValueKind::None;
     bool Negative = false;
-    Identifier RawValueText;
+    StringRef RawValueText;
     if (elem->getParentEnum()->isObjC()) {
       // Currently ObjC enums always have integer raw values.
       RawValueKind = EnumElementRawValueKind::IntegerLiteral;
       auto ILE = cast<IntegerLiteralExpr>(elem->getRawValueExpr());
-      RawValueText = M->getASTContext().getIdentifier(ILE->getDigitsText());
+      RawValueText = ILE->getDigitsText();
       Negative = ILE->isNegative();
     }
 
@@ -3331,7 +3349,7 @@
                                   elem->hasAssociatedValues(),
                                   (unsigned)RawValueKind,
                                   Negative,
-                                  addDeclBaseNameRef(RawValueText),
+                                  addUniquedStringRef(RawValueText),
                                   rawResilienceExpansion,
                                   elem->getFullName().getArgumentNames().size()+1,
                                   nameComponentsAndDependencies);
@@ -4155,9 +4173,9 @@
   // Make sure no identifier has an offset of 0.
   stringData.push_back('\0');
 
-  for (Identifier ident : IdentifiersToWrite) {
+  for (StringRef str : StringsToWrite) {
     IdentifierOffsets.push_back(stringData.size());
-    stringData.append(ident.get());
+    stringData.append(str);
     stringData.push_back('\0');
   }
 
diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h
index 92a0986..0508103 100644
--- a/lib/Serialization/Serialization.h
+++ b/lib/Serialization/Serialization.h
@@ -87,7 +87,17 @@
   /// A map from Types and Decls to their serialized IDs.
   llvm::DenseMap<DeclTypeUnion, DeclID> DeclAndTypeIDs;
 
+  /// A map from non-identifier uniqued strings to their serialized IDs.
+  ///
+  /// Since we never remove items from this map, we can use a BumpPtrAllocator
+  /// to back the entries.
+  llvm::StringMap<IdentifierID, llvm::BumpPtrAllocator> UniquedStringIDs;
+
   /// A map from Identifiers to their serialized IDs.
+  ///
+  /// This is stored separately from \p UniquedStringIDs because it's faster
+  /// to do lookups in, even though that may lead to some duplication between
+  /// identifier and non-identifier strings.
   llvm::DenseMap<Identifier, IdentifierID> IdentifierIDs;
 
   /// A map from DeclContexts to their serialized IDs.
@@ -185,8 +195,9 @@
   /// SILLayouts that need to be serialized.
   std::queue<SILLayout *> SILLayoutsToWrite;
 
-  /// All identifiers that need to be serialized.
-  std::vector<Identifier> IdentifiersToWrite;
+  /// All uniqued strings that need to be serialized (identifiers and
+  /// non-identifiers).
+  std::vector<StringRef> StringsToWrite;
 
   /// The abbreviation code for each record in the "decls-and-types" block.
   ///
@@ -252,11 +263,11 @@
   /// The last assigned DeclID for types from this module.
   uint32_t /*TypeID*/ LastTypeID = 0;
 
-  /// The last assigned IdentifierID for types from this module.
+  /// The last assigned IdentifierID for uniqued strings from this module.
   ///
   /// Note that special module IDs and IDs of special names must not be valid
   /// IdentifierIDs, except that 0 will always represent the empty identifier.
-  uint32_t /*IdentifierID*/ LastIdentifierID =
+  uint32_t /*IdentifierID*/ LastUniquedStringID =
       serialization::NUM_SPECIAL_IDS - 1;
 
   /// The last assigned GenericSignatureID for generic signature from this
@@ -453,6 +464,23 @@
   /// \returns The ID for the given DeclBaseName in this module.
   IdentifierID addDeclBaseNameRef(DeclBaseName ident);
 
+  /// Records the use of the given string, which will only be stored once in
+  /// the resulting module file.
+  ///
+  /// \returns A pair containing the copy of the string now owned by the
+  /// Serializer and the ID for the string in this module.
+  /// \sa addUniquedStringRef
+  std::pair<StringRef, IdentifierID> addUniquedString(StringRef str);
+
+  /// Records the use of the given string, which will only be stored once in
+  /// the resulting module file.
+  ///
+  /// \returns The ID for the given string in this module.
+  /// \sa addUniquedString
+  IdentifierID addUniquedStringRef(StringRef str) {
+    return addUniquedString(str).second;
+  }
+
   /// Records the use of the given Decl.
   ///
   /// The Decl will be scheduled for serialization if necessary.
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index aa9c006..7370241 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -92,33 +92,33 @@
 namespace {
     /// Used to serialize the on-disk func hash table.
   class FuncTableInfo {
+    Serializer &S;
+
   public:
-    using key_type = Identifier;
+    using key_type = StringRef;
     using key_type_ref = key_type;
     using data_type = DeclID;
     using data_type_ref = const data_type &;
     using hash_value_type = uint32_t;
     using offset_type = unsigned;
 
+    explicit FuncTableInfo(Serializer &S) : S(S) {}
+
     hash_value_type ComputeHash(key_type_ref key) {
       assert(!key.empty());
       // FIXME: DJB seed=0, audit whether the default seed could be used.
-      return llvm::djbHash(key.str(), 0);
+      return llvm::djbHash(key, 0);
     }
 
     std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
                                                     key_type_ref key,
                                                     data_type_ref data) {
-      uint32_t keyLength = key.str().size();
-      uint32_t dataLength = sizeof(uint32_t);
-      endian::Writer writer(out, little);
-      writer.write<uint16_t>(keyLength);
-      // No need to write the data length; it's constant.
-      return { keyLength, dataLength };
+      return { sizeof(uint32_t), sizeof(uint32_t) };
     }
 
     void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
-      out << key.str();
+      uint32_t keyID = S.addUniquedStringRef(key);
+      endian::write<uint32_t>(out, keyID, little);
     }
 
     void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
@@ -131,7 +131,6 @@
     using TypeID = serialization::TypeID;
     
     Serializer &S;
-    ASTContext &Ctx;
 
     llvm::BitstreamWriter &Out;
 
@@ -259,9 +258,8 @@
     IdentifierID addSILFunctionRef(SILFunction *F);
 
   public:
-    SILSerializer(Serializer &S, ASTContext &Ctx,
-                  llvm::BitstreamWriter &Out, bool serializeAll)
-      : S(S), Ctx(Ctx), Out(Out), ShouldSerializeAll(serializeAll) {}
+    SILSerializer(Serializer &S, llvm::BitstreamWriter &Out, bool serializeAll)
+      : S(S), Out(Out), ShouldSerializeAll(serializeAll) {}
 
     void writeSILModule(const SILModule *SILMod);
   };
@@ -349,7 +347,7 @@
   ValueIDs.clear();
   InstID = 0;
 
-  FuncTable[Ctx.getIdentifier(F.getName())] = NextFuncID++;
+  FuncTable[F.getName()] = NextFuncID++;
   Funcs.push_back(Out.GetCurrentBitNo());
   unsigned abbrCode = SILAbbrCodes[SILFunctionLayout::Code];
   TypeID FnID = S.addTypeRef(F.getLoweredType().getASTType());
@@ -360,7 +358,7 @@
 
   SmallVector<IdentifierID, 1> SemanticsIDs;
   for (auto SemanticAttr : F.getSemanticsAttrs()) {
-    SemanticsIDs.push_back(S.addDeclBaseNameRef(Ctx.getIdentifier(SemanticAttr)));
+    SemanticsIDs.push_back(S.addUniquedStringRef(SemanticAttr));
   }
 
   SILLinkage Linkage = F.getLinkage();
@@ -490,7 +488,7 @@
 /// functions.
 IdentifierID SILSerializer::addSILFunctionRef(SILFunction *F) {
   addReferencedSILFunction(F);
-  return S.addDeclBaseNameRef(Ctx.getIdentifier(F->getName()));
+  return S.addUniquedStringRef(F->getName());
 }
 
 /// Helper function to update ListOfValues for MethodInst. Format:
@@ -996,8 +994,7 @@
     SILOneOperandLayout::emitRecord(Out, ScratchRecord,
         SILAbbrCodes[SILOneOperandLayout::Code],
         (unsigned)SI.getKind(), 0, 0, 0,
-        S.addDeclBaseNameRef(
-            Ctx.getIdentifier(G->getName())));
+        S.addUniquedStringRef(G->getName()));
     break;
   }
   case SILInstructionKind::GlobalAddrInst:
@@ -1011,8 +1008,7 @@
         (unsigned)SI.getKind(), 0,
         S.addTypeRef(GI->getType().getASTType()),
         (unsigned)GI->getType().getCategory(),
-        S.addDeclBaseNameRef(
-            Ctx.getIdentifier(G->getName())));
+        S.addUniquedStringRef(G->getName()));
     break;
   }
   case SILInstructionKind::BranchInst: {
@@ -1346,7 +1342,7 @@
     unsigned encoding = toStableStringEncoding(SLI->getEncoding());
     SILOneOperandLayout::emitRecord(Out, ScratchRecord, abbrCode,
                                     (unsigned)SI.getKind(), encoding, 0, 0,
-                                    S.addDeclBaseNameRef(Ctx.getIdentifier(Str)));
+                                    S.addUniquedStringRef(Str));
     break;
   }
   case SILInstructionKind::FloatLiteralInst:
@@ -1371,7 +1367,7 @@
         (unsigned)SI.getKind(), 0,
         S.addTypeRef(Ty.getASTType()),
         (unsigned)Ty.getCategory(),
-        S.addDeclBaseNameRef(Ctx.getIdentifier(Str)));
+        S.addUniquedStringRef(Str));
     break;
   }
   case SILInstructionKind::MarkFunctionEscapeInst: {
@@ -2011,8 +2007,7 @@
     ListOfValues.push_back(pattern->getNumOperands());
     ListOfValues.push_back(S.addSubstitutionMapRef(KPI->getSubstitutions()));
 
-    ListOfValues.push_back(
-       S.addDeclBaseNameRef(Ctx.getIdentifier(pattern->getObjCString())));
+    ListOfValues.push_back(S.addUniquedStringRef(pattern->getObjCString()));
 
     ArrayRef<Requirement> reqts;
     if (auto sig = pattern->getGenericSignature()) {
@@ -2062,7 +2057,8 @@
 
 /// Depending on the RecordKind, we write the SILFunction table, the global
 /// variable table, the table for SILVTable, or the table for SILWitnessTable.
-static void writeIndexTable(const sil_index_block::ListLayout &List,
+static void writeIndexTable(Serializer &S,
+                            const sil_index_block::ListLayout &List,
                             sil_index_block::RecordKind kind,
                             const SILSerializer::Table &table) {
   assert((kind == sil_index_block::SIL_FUNC_NAMES ||
@@ -2076,13 +2072,14 @@
   uint32_t tableOffset;
   {
     llvm::OnDiskChainedHashTableGenerator<FuncTableInfo> generator;
+    FuncTableInfo tableInfo(S);
     for (auto &entry : table)
-      generator.insert(entry.first, entry.second);
+      generator.insert(entry.first, entry.second, tableInfo);
 
     llvm::raw_svector_ostream blobStream(hashTableBlob);
     // Make sure that no bucket is at offset 0.
     endian::write<uint32_t>(blobStream, 0, little);
-    tableOffset = generator.Emit(blobStream);
+    tableOffset = generator.Emit(blobStream, tableInfo);
   }
   SmallVector<uint64_t, 8> scratch;
   List.emit(scratch, kind, tableOffset, hashTableBlob);
@@ -2094,31 +2091,32 @@
   sil_index_block::ListLayout List(Out);
   sil_index_block::OffsetLayout Offset(Out);
   if (!FuncTable.empty()) {
-    writeIndexTable(List, sil_index_block::SIL_FUNC_NAMES, FuncTable);
+    writeIndexTable(S, List, sil_index_block::SIL_FUNC_NAMES, FuncTable);
     Offset.emit(ScratchRecord, sil_index_block::SIL_FUNC_OFFSETS, Funcs);
   }
 
   if (!VTableList.empty()) {
-    writeIndexTable(List, sil_index_block::SIL_VTABLE_NAMES, VTableList);
+    writeIndexTable(S, List, sil_index_block::SIL_VTABLE_NAMES, VTableList);
     Offset.emit(ScratchRecord, sil_index_block::SIL_VTABLE_OFFSETS,
                 VTableOffset);
   }
 
   if (!GlobalVarList.empty()) {
-    writeIndexTable(List, sil_index_block::SIL_GLOBALVAR_NAMES, GlobalVarList);
+    writeIndexTable(S, List, sil_index_block::SIL_GLOBALVAR_NAMES,
+                    GlobalVarList);
     Offset.emit(ScratchRecord, sil_index_block::SIL_GLOBALVAR_OFFSETS,
                 GlobalVarOffset);
   }
 
   if (!WitnessTableList.empty()) {
-    writeIndexTable(List, sil_index_block::SIL_WITNESS_TABLE_NAMES,
+    writeIndexTable(S, List, sil_index_block::SIL_WITNESS_TABLE_NAMES,
                     WitnessTableList);
     Offset.emit(ScratchRecord, sil_index_block::SIL_WITNESS_TABLE_OFFSETS,
                 WitnessTableOffset);
   }
   
   if (!DefaultWitnessTableList.empty()) {
-    writeIndexTable(List, sil_index_block::SIL_DEFAULT_WITNESS_TABLE_NAMES,
+    writeIndexTable(S, List, sil_index_block::SIL_DEFAULT_WITNESS_TABLE_NAMES,
                     DefaultWitnessTableList);
     Offset.emit(ScratchRecord,
                 sil_index_block::SIL_DEFAULT_WITNESS_TABLE_OFFSETS,
@@ -2133,7 +2131,7 @@
 }
 
 void SILSerializer::writeSILGlobalVar(const SILGlobalVariable &g) {
-  GlobalVarList[Ctx.getIdentifier(g.getName())] = NextGlobalVarID++;
+  GlobalVarList[g.getName()] = NextGlobalVarID++;
   GlobalVarOffset.push_back(Out.GetCurrentBitNo());
   TypeID TyID = S.addTypeRef(g.getLoweredType().getASTType());
   DeclID dID = S.addDeclRef(g.getDecl());
@@ -2152,7 +2150,7 @@
   if (!ShouldSerializeAll &&
       vt.getClass()->getEffectiveAccess() < swift::AccessLevel::Public)
     return;
-  VTableList[vt.getClass()->getName()] = NextVTableID++;
+  VTableList[vt.getClass()->getName().str()] = NextVTableID++;
   VTableOffset.push_back(Out.GetCurrentBitNo());
   VTableLayout::emitRecord(Out, ScratchRecord, SILAbbrCodes[VTableLayout::Code],
                            S.addDeclRef(vt.getClass()),
@@ -2172,7 +2170,7 @@
     VTableEntryLayout::emitRecord(Out, ScratchRecord,
         SILAbbrCodes[VTableEntryLayout::Code],
         // SILFunction name
-        S.addDeclBaseNameRef(Ctx.getIdentifier(entry.Implementation->getName())),
+        S.addUniquedStringRef(entry.Implementation->getName()),
         toStableVTableEntryKind(entry.TheKind),
         toStableSILLinkage(entry.Linkage),
         ListOfValues);
@@ -2204,7 +2202,7 @@
 }
 
 void SILSerializer::writeSILWitnessTable(const SILWitnessTable &wt) {
-  WitnessTableList[wt.getIdentifier()] = NextWitnessTableID++;
+  WitnessTableList[wt.getName()] = NextWitnessTableID++;
   WitnessTableOffset.push_back(Out.GetCurrentBitNo());
 
   WitnessTableLayout::emitRecord(
@@ -2257,7 +2255,7 @@
     IdentifierID witnessID = 0;
     if (SILFunction *witness = methodWitness.Witness) {
       addReferencedSILFunction(witness, true);
-      witnessID = S.addDeclBaseNameRef(Ctx.getIdentifier(witness->getName()));
+      witnessID = S.addUniquedStringRef(witness->getName());
     }
     WitnessMethodEntryLayout::emitRecord(Out, ScratchRecord,
         SILAbbrCodes[WitnessMethodEntryLayout::Code],
@@ -2282,7 +2280,8 @@
   if (wt.isDeclaration())
     return;
 
-  DefaultWitnessTableList[wt.getIdentifier()] = NextDefaultWitnessTableID++;
+  StringRef name = S.addUniquedString(wt.getUniqueName()).first;
+  DefaultWitnessTableList[name] = NextDefaultWitnessTableID++;
   DefaultWitnessTableOffset.push_back(Out.GetCurrentBitNo());
 
   DefaultWitnessTableLayout::emitRecord(
@@ -2302,8 +2301,7 @@
     handleSILDeclRef(S, entry.getRequirement(), ListOfValues);
     SILFunction *witness = entry.getWitness();
     addReferencedSILFunction(witness, true);
-    IdentifierID witnessID = S.addDeclBaseNameRef(
-        Ctx.getIdentifier(witness->getName()));
+    IdentifierID witnessID = S.addUniquedStringRef(witness->getName());
     DefaultWitnessTableEntryLayout::emitRecord(Out, ScratchRecord,
         SILAbbrCodes[DefaultWitnessTableEntryLayout::Code],
         // SILFunction name
@@ -2483,6 +2481,6 @@
   if (!SILMod)
     return;
 
-  SILSerializer SILSer(*this, M->getASTContext(), Out, serializeAllSIL);
+  SILSerializer SILSer(*this, Out, serializeAllSIL);
   SILSer.writeSILModule(SILMod);
 }
diff --git a/test/ClangImporter/MixedSource/mixed-target-using-module.swift b/test/ClangImporter/MixedSource/mixed-target-using-module.swift
index 72a483f..0c007f6 100644
--- a/test/ClangImporter/MixedSource/mixed-target-using-module.swift
+++ b/test/ClangImporter/MixedSource/mixed-target-using-module.swift
@@ -1,9 +1,9 @@
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/mixed-target/ -module-name Mixed -import-underlying-module -typecheck %s -verify -enable-objc-interop -disable-objc-attr-requires-foundation-module
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/mixed-target/ -module-name Mixed -import-underlying-module -enable-objc-interop -emit-ir %S/../../Inputs/empty.swift - | %FileCheck -check-prefix=CHECK-AUTOLINK %s
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/mixed-target/ -module-name Mixed -import-underlying-module -enable-objc-interop -emit-ir %S/../../Inputs/empty.swift | %FileCheck -check-prefix=CHECK-AUTOLINK %s
 // RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -F %S/Inputs/mixed-target/ -module-name WrongName -import-underlying-module -typecheck %s  -enable-objc-interop -disable-objc-attr-requires-foundation-module 2>&1 | %FileCheck -check-prefix=CHECK-WRONG-NAME %s
 
 // CHECK-AUTOLINK: !llvm.linker.options = !{
-// CHECK-AUTOLINK-NOT: metadata !"-framework", metadata !"Mixed"
+// CHECK-AUTOLINK-NOT: !"-framework"
 
 // CHECK-WRONG-NAME: underlying Objective-C module 'WrongName' not found
 
diff --git a/test/ClangImporter/diags_from_header.swift b/test/ClangImporter/diags_from_header.swift
index 786cd40..7393737 100644
--- a/test/ClangImporter/diags_from_header.swift
+++ b/test/ClangImporter/diags_from_header.swift
@@ -1,5 +1,15 @@
-// RUN: not %target-swift-frontend -typecheck %s -enable-objc-interop -import-objc-header %S/Inputs/diags_from_header.h 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-WARN
+// RUN: not %target-swift-frontend -typecheck %s -enable-objc-interop -import-objc-header %S/Inputs/diags_from_header.h -serialize-diagnostics-path %t.dia 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-WARN
+// RUN: test -s %t.dia
+// RUN: c-index-test -read-diagnostics %t.dia 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-WARN
 
+// Also check batch mode (multiple primary files).
+// RUN: not %target-swift-frontend -typecheck -primary-file %s -primary-file %S/../Inputs/empty.swift -enable-objc-interop -import-objc-header %S/Inputs/diags_from_header.h -serialize-diagnostics-path %t.1.dia -serialize-diagnostics-path %t.2.dia 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-WARN
+// RUN: test -s %t.1.dia
+// RUN: c-index-test -read-diagnostics %t.1.dia 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-WARN
+// RUN: test -s %t.2.dia
+// RUN: c-index-test -read-diagnostics %t.2.dia 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-WARN
+
+// Verify that -Wno-* options are applied.
 // RUN: not %target-swift-frontend -typecheck %s -enable-objc-interop -import-objc-header %S/Inputs/diags_from_header.h -Xcc -Wno-#warnings 2>&1 | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-NO-WARN
 
 // CHECK-WARN: diags_from_header.h:{{.*}}:2: warning: "here is some warning about something"
diff --git a/test/ClangImporter/diags_from_module.swift b/test/ClangImporter/diags_from_module.swift
index b761ed9..8e74e7a 100644
--- a/test/ClangImporter/diags_from_module.swift
+++ b/test/ClangImporter/diags_from_module.swift
@@ -1,17 +1,40 @@
 // RUN: %empty-directory(%t)
-// RUN: not %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck %s -F %S/Inputs/frameworks -Xcc -D -Xcc FOO -o /dev/null 2>&1 | %FileCheck %s
+// RUN: not %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck %s -F %S/Inputs/frameworks -serialize-diagnostics-path %t.dia -Xcc -D -Xcc FOO 2>&1 | %FileCheck %s
+// RUN: test -s %t.dia
+// RUN: c-index-test -read-diagnostics %t.dia 2>&1 | %FileCheck %s
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck %s -F %S/Inputs/frameworks -o /dev/null 2>&1 | %FileCheck %s -check-prefix CHECK-WARN
+// RUN: %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck %s -F %S/Inputs/frameworks -serialize-diagnostics-path %t.warn.dia 2>&1 | %FileCheck %s -check-prefix CHECK-WARN
+// RUN: test -s %t.warn.dia
+// RUN: c-index-test -read-diagnostics %t.warn.dia 2>&1 | %FileCheck %s -check-prefix CHECK-WARN
+
+
+// Also check batch mode (multiple primary files).
+// RUN: %empty-directory(%t)
+// RUN: not %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck -primary-file %s -primary-file %S/../Inputs/empty.swift -F %S/Inputs/frameworks -serialize-diagnostics-path %t.1.dia -serialize-diagnostics-path %t.2.dia -Xcc -D -Xcc FOO 2>&1 | %FileCheck %s
+// RUN: test -s %t.1.dia
+// RUN: c-index-test -read-diagnostics %t.1.dia 2>&1 | %FileCheck %s
+// RUN: c-index-test -read-diagnostics %t.1.dia 2>&1 | %FileCheck %s -check-prefix CHECK-PRIMARY
+// RUN: test -s %t.2.dia
+// RUN: c-index-test -read-diagnostics %t.2.dia 2>&1 | %FileCheck %s
 
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck %s -F %S/Inputs/frameworks -Xcc -Wno-#warnings -o /dev/null 2>&1 | %FileCheck -check-prefix CHECK-NO-WARN -allow-empty %s
+// RUN: %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck -primary-file %s -primary-file %S/../Inputs/empty.swift -F %S/Inputs/frameworks -serialize-diagnostics-path %t.warn.1.dia -serialize-diagnostics-path %t.warn.2.dia 2>&1 | %FileCheck %s -check-prefix CHECK-WARN
+// RUN: test -s %t.1.dia
+// RUN: c-index-test -read-diagnostics %t.warn.1.dia 2>&1 | %FileCheck %s -check-prefix=CHECK-WARN
+// RUN: test -s %t.2.dia
+// RUN: c-index-test -read-diagnostics %t.warn.2.dia 2>&1 | %FileCheck %s -check-prefix=CHECK-WARN
+
+
+// Verify that -Wno-* options are applied.
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -module-cache-path %t -enable-objc-interop -typecheck %s -F %S/Inputs/frameworks -Xcc -Wno-#warnings 2>&1 | %FileCheck -check-prefix CHECK-NO-WARN -allow-empty %s
 
 import Module
 
 // CHECK: Another.h:2:4: error: Module should have been built without -DFOO
 // CHECK: Sub2.h:2:9: error: could not build module 'Another'
-// CHECK: diags_from_module.swift:[[@LINE-4]]:8: error: could not build Objective-C module 'Module'
+// CHECK-PRIMARY: diags_from_module.swift:[[@LINE-4]]:8: error: could not build Objective-C module 'Module'
 
 // CHECK-WARN: Sub2.h:7:2: warning: here is some warning about something
 // CHECK-WARN: <module-includes>:1:1: warning: umbrella header for module 'Module' does not include header 'NotInModule.h'
diff --git a/test/IRGen/class_metadata.swift b/test/IRGen/class_metadata.swift
index 73e5b67..208dea7 100644
--- a/test/IRGen/class_metadata.swift
+++ b/test/IRGen/class_metadata.swift
@@ -35,8 +35,8 @@
 //   V-table entry #1: flags.
 // CHECK-SAME: i32 1
 //   V-table entry #1: invocation function.
-// CHECK-SAME: @"$S14class_metadata1ACACycfc"
-// CHECK-SAME: } }>, section
+// CHECK-SAME: @"$S14class_metadata1ACACycfC"
+// CHECK-SAME: }>, section
 
 class B : A {}
 
@@ -72,7 +72,7 @@
 //   Override table entry #1: base method.
 // CHECK-SAME: @"$S14class_metadata1ACMn", i32 0, i32 13
 //   Override table entry #1: invocation function.
-// CHECK-SAME: @"$S14class_metadata1BCACycfc"
+// CHECK-SAME: @"$S14class_metadata1BCACycfC"
 
 // CHECK-SAME: }>, section
 
@@ -128,7 +128,7 @@
 //   Override table entry #1: base method.
 // CHECK-SAME: @"$S14class_metadata1ACMn", i32 0, i32 13
 //   Override table entry #1: invocation function.
-// CHECK-SAME: @"$S14class_metadata1CCACyxGycfc"
+// CHECK-SAME: @"$S14class_metadata1CCACyxGycfC"
 // CHECK-SAME: }>, section
 
 // CHECK-LABEL: @"$S14class_metadata1CCMP" =
@@ -169,8 +169,8 @@
 //   Override table entry #1: base class.
 // CHECK-SAME: @"got.$S14class_metadata1ECMn.1"
 //   Override table entry #1: base method.
-// CHECK-SAME: @"got.$S14class_metadata1ECACycfcTq"
+// CHECK-SAME: @"got.$S14class_metadata1ECACycfCTq"
 //   Override table entry #1: invocation function.
-// CHECK-SAME: @"$S14class_metadata1DCACycfc"
+// CHECK-SAME: @"$S14class_metadata1DCACycfC"
 // CHECK-SAME: }>, section
 class E {}
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index 2ecb96b..2b385e9 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -14,8 +14,6 @@
 
 // CHECK: @"$S16class_resilience14ResilientChildC5fields5Int32VvpWvd" = hidden global [[INT]] {{8|16}}
 
-// CHECK: @"$S15resilient_class22ResilientOutsideParentCACycfcTq" = external global %swift.method_descriptor
-
 // CHECK: @"$S16class_resilience21ResilientGenericChildCMo" = {{(protected )?}}{{(dllexport )?}}global [[BOUNDS:{ (i32|i64), i32, i32 }]] zeroinitializer
 
 // CHECK: @"$S16class_resilience26ClassWithResilientPropertyCMo" = {{(protected )?}}{{(dllexport )?}}constant [[BOUNDS]]
@@ -77,9 +75,9 @@
 // --       base class:
 // CHECK-SAME:   @"got.$S15resilient_class22ResilientOutsideParentCMn"
 // --       base method:
-// CHECK-SAME:   @"got.$S15resilient_class22ResilientOutsideParentCACycfcTq"
+// CHECK-SAME:   @"got.$S15resilient_class22ResilientOutsideParentCACycfCTq"
 // --       implementation:
-// CHECK-SAME:   @"$S16class_resilience14ResilientChildCACycfc"
+// CHECK-SAME:   @"$S16class_resilience14ResilientChildCACycfC"
 // CHECK-SAME:   }
 // CHECK-SAME: }>
 
@@ -129,9 +127,9 @@
 // CHECK: @"$S16class_resilience21ResilientGenericChildC5fields5Int32VvsTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
 // CHECK: @"$S16class_resilience21ResilientGenericChildC5fields5Int32VvMTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
 
-// CHECK: @"$S16class_resilience17MyResilientParentCACycfcTq" = hidden alias %swift.method_descriptor, getelementptr inbounds
-// CHECK: @"$S16class_resilience24MyResilientGenericParentC1tACyxGx_tcfcTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
-// CHECK: @"$S16class_resilience24MyResilientConcreteChildC1xACSi_tcfcTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
+// CHECK: @"$S16class_resilience17MyResilientParentCACycfCTq" = hidden alias %swift.method_descriptor, getelementptr inbounds
+// CHECK: @"$S16class_resilience24MyResilientGenericParentC1tACyxGx_tcfCTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
+// CHECK: @"$S16class_resilience24MyResilientConcreteChildC1xACSi_tcfCTq" = {{(protected )?}}{{(dllexport )?}}alias %swift.method_descriptor, getelementptr inbounds
 
 import resilient_class
 import resilient_struct
@@ -347,23 +345,6 @@
 // CHECK-NEXT: call void @swift_endAccess
 // CHECK: ret i32 [[FIELD_VALUE]]
 
-
-// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %T16class_resilience14ResilientChildC* @"$S16class_resilience14ResilientChildCACycfc"(%T16class_resilience14ResilientChildC* swiftself)
-// CHECK:      [[SUPER_SELF:%.*]] = bitcast %T16class_resilience14ResilientChildC* %0 to %T15resilient_class22ResilientOutsideParentC*
-
-// Note: we know the superclass of ResilientChild statically, so we can emit
-// it directly.
-
-// CHECK:      [[SUPER_METADATA_RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$S15resilient_class22ResilientOutsideParentCMa"
-// CHECK-NEXT: [[SUPER_METADATA:%.*]] = extractvalue %swift.metadata_response [[SUPER_METADATA_RESPONSE]], 0
-
-// CHECK:      [[SUPER_METHOD:%.*]] = call swiftcc i8* @"$S15resilient_class22ResilientOutsideParentCMu"(%swift.type* [[SUPER_METADATA:%.*]], %swift.method_descriptor* @"$S15resilient_class22ResilientOutsideParentCACycfcTq")
-// CHECK-NEXT: [[SUPER_METHOD_FN:%.*]] = bitcast i8* [[SUPER_METHOD]] to %T15resilient_class22ResilientOutsideParentC* (%T15resilient_class22ResilientOutsideParentC*)*
-// CHECK-NEXT: [[RESULT:%.*]] = call swiftcc %T15resilient_class22ResilientOutsideParentC* [[SUPER_METHOD_FN]](%T15resilient_class22ResilientOutsideParentC* swiftself [[SUPER_SELF]])
-// CHECK-NEXT: [[NEW_SELF:%.*]] = bitcast %T15resilient_class22ResilientOutsideParentC* [[RESULT]] to %T16class_resilience14ResilientChildC*
-// CHECK:       ret %T16class_resilience14ResilientChildC* [[NEW_SELF]]
-
-
 // ResilientGenericChild.field getter
 
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @"$S16class_resilience21ResilientGenericChildC5fields5Int32Vvg"(%T16class_resilience21ResilientGenericChildC* swiftself)
diff --git a/test/IRGen/class_with_stub_initializers.swift b/test/IRGen/class_with_stub_initializers.swift
index 51c0381..61be20c 100644
--- a/test/IRGen/class_with_stub_initializers.swift
+++ b/test/IRGen/class_with_stub_initializers.swift
@@ -8,10 +8,10 @@
 
 // CHECK:       @"$S28class_with_stub_initializers3FooCN" =
 // -- The init() stub should get no vtable entry
-// CHECK-NOT:     %T28class_with_stub_initializers3FooC* (%T28class_with_stub_initializers3FooC*)*
-// CHECK:         %T28class_with_stub_initializers3FooC* (i64, %T28class_with_stub_initializers3FooC*)*
+// CHECK-NOT:     %T28class_with_stub_initializers3FooC* (%swift.type*)*
+// CHECK:         %T28class_with_stub_initializers3FooC* (i64, %swift.type*)*
 // -- The init() stub should get no vtable entry
-// CHECK-NOT:     %T28class_with_stub_initializers3FooC* (%T28class_with_stub_initializers3FooC*)*
+// CHECK-NOT:     %T28class_with_stub_initializers3FooC* (%swift.type*)*
 // CHECK:       {{^(@|define)}}
 class Foo: NSObject {
   init(x: Int64) { super.init() }
diff --git a/test/IRGen/dead_method.swift b/test/IRGen/dead_method.swift
index 7241472..2f39d38 100644
--- a/test/IRGen/dead_method.swift
+++ b/test/IRGen/dead_method.swift
@@ -20,7 +20,7 @@
 // -- vtable
 // CHECK-SAME: %swift.method_descriptor {
 // CHECK-SAME: i32 1,
-// CHECK-SAME: @"$S11dead_method5ClassCACycfc"
+// CHECK-SAME: @"$S11dead_method5ClassCACycfC"
 // CHECK-SAME: }
 
 // CHECK-SAME: %swift.method_descriptor {
@@ -46,7 +46,7 @@
 // CHECK-SAME:   i8* null,
 
 // -- vtable
-// CHECK-SAME:   %T11dead_method5ClassC* (%T11dead_method5ClassC*)* @"$S11dead_method5ClassCACycfc",
+// CHECK-SAME:   %T11dead_method5ClassC* (%swift.type*)* @"$S11dead_method5ClassCACycfC",
 // CHECK-SAME:   void (%T11dead_method5ClassC*)* @"$S11dead_method5ClassC4liveyyF",
 // CHECK-SAME:   i8* bitcast (void ()* @swift_deletedMethodError to i8*)
 
diff --git a/test/IRGen/generic_vtable.swift b/test/IRGen/generic_vtable.swift
index b3963ec..4e63b5f 100644
--- a/test/IRGen/generic_vtable.swift
+++ b/test/IRGen/generic_vtable.swift
@@ -43,7 +43,7 @@
 // -- vtable entry for 'm2()'
 // CHECK-SAME: void (%T14generic_vtable4BaseC*)* @"$S14generic_vtable4BaseC2m2yyF"
 // -- vtable entry for 'init()'
-// CHECK-SAME: %T14generic_vtable4BaseC* (%T14generic_vtable4BaseC*)* @"$S14generic_vtable4BaseCACycfc"
+// CHECK-SAME: %T14generic_vtable4BaseC* (%swift.type*)* @"$S14generic_vtable4BaseCACycfC"
 // --
 // CHECK-SAME: , align
 
@@ -69,7 +69,7 @@
 // -- override for constructor
 // CHECK-SAME: @"$S14generic_vtable4BaseCMn"
 // CHECK-SAME: @"$S14generic_vtable4BaseCMn", i32 0, i32 15
-// CHECK-SAME: @"$S14generic_vtable7DerivedCACyxGycfc"
+// CHECK-SAME: @"$S14generic_vtable7DerivedCACyxGycfC"
 // CHECK-SAME: section "{{.*}}", align 4
 
 //// Type metadata pattern for 'Derived' has an empty vtable, filled in at
@@ -103,7 +103,7 @@
 // -- override for constructor
 // CHECK-SAME: @"$S14generic_vtable4BaseCMn"
 // CHECK-SAME: @"$S14generic_vtable4BaseCMn", i32 0, i32 15
-// CHECK-SAME: @"$S14generic_vtable8ConcreteCACycfc"
+// CHECK-SAME: @"$S14generic_vtable8ConcreteCACycfC"
 // --
 // CHECK-SAME: section "{{.*}}", align 4
 
@@ -117,7 +117,7 @@
 // -- vtable entry for 'm2()'
 // CHECK-SAME: void (%T14generic_vtable7DerivedC*)* @"$S14generic_vtable7DerivedC2m2yyF"
 // -- vtable entry for 'init()'
-// CHECK-SAME: %T14generic_vtable8ConcreteC* (%T14generic_vtable8ConcreteC*)* @"$S14generic_vtable8ConcreteCACycfc"
+// CHECK-SAME: %T14generic_vtable8ConcreteC* (%swift.type*)* @"$S14generic_vtable8ConcreteCACycfC"
 // -- vtable entry for 'm3()'
 // CHECK-SAME: void (%T14generic_vtable8ConcreteC*)* @"$S14generic_vtable8ConcreteC2m3yyF"
 // -- vtable entry for 'm4()'
@@ -130,7 +130,7 @@
 
 // CHECK-LABEL: @"$S14generic_vtable4BaseC2m1yyFTq" ={{( dllexport)?}}{{( protected)?}} alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}>* @"$S14generic_vtable4BaseCMn", i32 0, i32 13)
 // CHECK-LABEL: @"$S14generic_vtable4BaseC2m2yyFTq" ={{( dllexport)?}}{{( protected)?}} alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}* @"$S14generic_vtable4BaseCMn", i32 0, i32 14)
-// CHECK-LABEL: @"$S14generic_vtable4BaseCACycfcTq" = hidden alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}* @"$S14generic_vtable4BaseCMn", i32 0, i32 15)
+// CHECK-LABEL: @"$S14generic_vtable4BaseCACycfCTq" = hidden alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}* @"$S14generic_vtable4BaseCMn", i32 0, i32 15)
 
 // CHECK-LABEL: @"$S14generic_vtable7DerivedC2m3yyFTq" ={{( dllexport)?}}{{( protected)?}} alias %swift.method_descriptor, getelementptr inbounds (<{{.*}}>* @"$S14generic_vtable7DerivedCMn", i32 0, i32 23)
 
diff --git a/test/IRGen/ivar_destroyer.sil b/test/IRGen/ivar_destroyer.sil
index eaf7dfa..b7c26f2 100644
--- a/test/IRGen/ivar_destroyer.sil
+++ b/test/IRGen/ivar_destroyer.sil
@@ -6,37 +6,36 @@
 // CHECK: [[OPAQUE:%swift.opaque]] = type opaque
 // CHECK: [[TYPE:%swift.type]] = type
 
-//   CHECK: @"$S14ivar_destroyer17NonTrivialDerivedCMf" = internal global <{ {{.*}} }> <{
-// \ CHECK:   i8* null,
-// \ CHECK:   i8** @"$SBoWV",
-// \ CHECK:   i64 ptrtoint ([[OBJCCLASS]]* @"$S14ivar_destroyer17NonTrivialDerivedCMm" to i64),
-// \ CHECK:   [[TYPE]]* bitcast (i64* getelementptr inbounds (<{ {{.*}} }>, <{ {{.*}} }>* @"$S14ivar_destroyer11TrivialBaseCMf", i32 0, i32 2) to [[TYPE]]*),
-// \ CHECK:   [[OPAQUE]]* @_objc_empty_cache,
-// \ CHECK:   [[OPAQUE]]* null,
-// \ CHECK:   i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC14ivar_destroyer17NonTrivialDerived to i64), i64 {{1|2}}),
-// \ CHECK:   i32 {{3|2}},
-// \ CHECK:   i32 0,
-// \ CHECK:   i32 24,
-// \ CHECK:   i16 7,
-// \ CHECK:   i16 0,
-// \ CHECK:   i32 120,
-// \ CHECK:   i32 16,
-// \ CHECK:   <{ {{.*}} }>* @"$S14ivar_destroyer17NonTrivialDerivedCMn"
-// \ CHECK:   void (%T14ivar_destroyer17NonTrivialDerivedC*)* @"$S14ivar_destroyer17NonTrivialDerivedCfE",
-// \ CHECK:   i8* bitcast (void ()* @swift_deletedMethodError to i8*),
-// \ CHECK:   %T14ivar_destroyer17NonTrivialDerivedC* ([[TYPE]]*)* @alloc_NonTrivialDerived,
-// \ CHECK:   i64 16
-// \ CHECK: }>
+// CHECK-LABEL: @"$S14ivar_destroyer17NonTrivialDerivedCMf" = internal global <{ {{.*}} }> <{
+// CHECK-SAME:    i8* null,
+// CHECK-SAME:    i8** @"$SBoWV",
+// CHECK-SAME:    i64 ptrtoint ([[OBJCCLASS]]* @"$S14ivar_destroyer17NonTrivialDerivedCMm" to i64),
+// CHECK-SAME:    [[TYPE]]* bitcast (i64* getelementptr inbounds (<{ {{.*}} }>, <{ {{.*}} }>* @"$S14ivar_destroyer11TrivialBaseCMf", i32 0, i32 2) to [[TYPE]]*),
+// CHECK-SAME:    [[OPAQUE]]* @_objc_empty_cache,
+// CHECK-SAME:    [[OPAQUE]]* null,
+// CHECK-SAME:    i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC14ivar_destroyer17NonTrivialDerived to i64), i64 {{1|2}}),
+// CHECK-SAME:    i32 {{3|2}},
+// CHECK-SAME:    i32 0,
+// CHECK-SAME:    i32 24,
+// CHECK-SAME:    i16 7,
+// CHECK-SAME:    i16 0,
+// CHECK-SAME:    i32 112,
+// CHECK-SAME:    i32 16,
+// CHECK-SAME:    <{ {{.*}} }>* @"$S14ivar_destroyer17NonTrivialDerivedCMn"
+// CHECK-SAME:    void (%T14ivar_destroyer17NonTrivialDerivedC*)* @"$S14ivar_destroyer17NonTrivialDerivedCfE",
+// CHECK-SAME:    %T14ivar_destroyer17NonTrivialDerivedC* ([[TYPE]]*)* @alloc_NonTrivialDerived
+// CHECK-SAME:    i64 16
+// CHECK-SAME:  }>
 
 class Pachyderm {}
 sil_vtable Pachyderm {}
 
 class TrivialBase {}
 
-sil public_external @init_TrivialBase : $@convention(method) (@owned TrivialBase) -> @owned TrivialBase
+sil public_external @alloc_TrivialBase : $@convention(method) (@thick TrivialBase.Type) -> @owned TrivialBase
 
 sil_vtable TrivialBase {
-  #TrivialBase.init!initializer.1: @init_TrivialBase
+  #TrivialBase.init!allocator.1: @alloc_TrivialBase
 }
 
 class NonTrivialDerived : TrivialBase {
@@ -45,12 +44,10 @@
   required override init()
 }
 
-sil public_external @init_NonTrivialDerived : $@convention(method) (@owned NonTrivialDerived) -> @owned NonTrivialDerived
 sil public_external @alloc_NonTrivialDerived : $@convention(method) (@thick NonTrivialDerived.Type) -> @owned NonTrivialDerived
 sil public_external @$S14ivar_destroyer17NonTrivialDerivedCfE : $@convention(method) (@guaranteed NonTrivialDerived) -> ()
 
 sil_vtable NonTrivialDerived {
-  #NonTrivialDerived.init!initializer.1: @init_NonTrivialDerived [override]
-  #NonTrivialDerived.init!allocator.1: @alloc_NonTrivialDerived
+  #TrivialBase.init!allocator.1: @alloc_NonTrivialDerived [override]
   #NonTrivialDerived!ivardestroyer.1: @$S14ivar_destroyer17NonTrivialDerivedCfE
 }
diff --git a/test/IRGen/method_linkage.swift b/test/IRGen/method_linkage.swift
index 7110068..ae1da49 100644
--- a/test/IRGen/method_linkage.swift
+++ b/test/IRGen/method_linkage.swift
@@ -7,10 +7,10 @@
 // Method descriptors linkage:
 
 // - internal initializer descriptor has hidden linkage when class is public:
-// CHECK-LABEL: @"$S14method_linkage11PublicClassCACycfcTq" = hidden alias
+// CHECK-LABEL: @"$S14method_linkage11PublicClassCACycfCTq" = hidden alias
 
 // - internal initializer descriptor has public linkage when class is open:
-// CHECK-LABEL: @"$S14method_linkage9OpenClassCACycfcTq" ={{( dllexport)?}}{{( protected)?}} alias
+// CHECK-LABEL: @"$S14method_linkage9OpenClassCACycfCTq" ={{( dllexport)?}}{{( protected)?}} alias
 
 // - private method descriptor has internal linkage even though class is open:
 // CHECK: @"$S14method_linkage9OpenClassC4pfoo0{{.*}}FTq" = internal alias
diff --git a/test/IRGen/vtable.sil b/test/IRGen/vtable.sil
index d1999b4..1687355 100644
--- a/test/IRGen/vtable.sil
+++ b/test/IRGen/vtable.sil
@@ -15,7 +15,6 @@
 // CHECK: [[C:%T6vtable1CC]] = type <{ %swift.refcounted }>
 
 sil @$S6vtable1CCACycACmcfC : $@convention(method) (@thick C.Type) -> @owned C
-sil @$S6vtable1CCACycACmcfc : $@convention(method) (@owned C) -> @owned C
 sil @$S6vtable1CCfd : $@convention(method) (@owned C) -> @owned Builtin.NativeObject
 sil @$S6vtable1CCfD : $@convention(method) (@owned C) -> ()
 
@@ -28,10 +27,9 @@
 // CHECK-objc: %swift.opaque* null,
 // CHECK-objc: i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @_DATA__TtC6vtable1C to i64), i64 {{1|2}}),
 // CHECK-objc: i32 {{3|2}}, i32 0, i32 16, i16 7, i16 0,
-// CHECK-objc: i32 112, i32 16,
+// CHECK-objc: i32 104, i32 16,
 // CHECK-objc: @"$S6vtable1CCMn"
-// CHECK-objc: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC",
-// CHECK-objc: [[C]]* ([[C]]*)* @"$S6vtable1CCACycACmcfc"
+// CHECK-objc: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC"
 // CHECK-objc: }>
 
 // CHECK-native: @"$S6vtable1CCMf" = internal global [[C_METADATA_T:<{.*\* }>]] <{
@@ -43,13 +41,11 @@
 // CHECK-native: %swift.opaque* null,
 // CHECK-native: i64 1,
 // CHECK-native: i32 {{3|2}}, i32 0, i32 16, i16 7, i16 0,
-// CHECK-native: i32 112, i32 16,
+// CHECK-native: i32 104, i32 16,
 // CHECK-native: @"$S6vtable1CCMn"
-// CHECK-native: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC",
-// CHECK-native: [[C]]* ([[C]]*)* @"$S6vtable1CCACycACmcfc"
+// CHECK-native: [[C]]* (%swift.type*)* @"$S6vtable1CCACycACmcfC"
 // CHECK-native: }>
 
 sil_vtable C {
   #C.init!allocator.1: @$S6vtable1CCACycACmcfC
-  #C.init!initializer.1: @$S6vtable1CCACycACmcfc
 }
diff --git a/test/Misc/stats_max_determinism.swift b/test/Misc/stats_max_determinism.swift
new file mode 100644
index 0000000..7c1517c
--- /dev/null
+++ b/test/Misc/stats_max_determinism.swift
@@ -0,0 +1,6 @@
+// RUN: %empty-directory(%t)
+// RUN: env SWIFTC_MAXIMUM_DETERMINISM=1 %target-swiftc_driver -j 4 -num-threads 10 -c -o %t/out.o %s >%t/out.txt 2>&1
+// RUN: %FileCheck -input-file %t/out.txt %s
+// CHECK: remark: SWIFTC_MAXIMUM_DETERMINISM overriding -j
+// CHECK: remark: SWIFTC_MAXIMUM_DETERMINISM overriding -num-threads
+print(1)
diff --git a/test/Parse/diagnose_availability.swift b/test/Parse/diagnose_availability.swift
index ad41d26..277ee7b 100644
--- a/test/Parse/diagnose_availability.swift
+++ b/test/Parse/diagnose_availability.swift
@@ -66,11 +66,19 @@
 // expected-error@-1{{'message' cannot be an interpolated string literal}}
 func interpolatedMessage() {}
 
-// expected-error@+1{{'message' cannot be a multiline string literal}}
 @available(*, unavailable, message: """
   foobar message.
   """)
 func multilineMessage() {}
+multilineMessage()
+// expected-error@-1{{'multilineMessage()' is unavailable: foobar message.}}
+// expected-note@-3{{'multilineMessage()' has been explicitly marked unavailable here}}
+
+@available(*, unavailable, message: " ")
+func emptyMessage() {}
+emptyMessage()
+// expected-error@-1{{'emptyMessage()' is unavailable:  }}
+// expected-note@-3{{'emptyMessage()' has been explicitly marked unavailable here}}
 
 // expected-error@+1{{'message' cannot be an extended escaping string literal}}
 @available(*, unavailable, message: #"""
diff --git a/test/SILGen/SILDeclRef.swift b/test/SILGen/SILDeclRef.swift
index 33d4673..73dcc86 100644
--- a/test/SILGen/SILDeclRef.swift
+++ b/test/SILGen/SILDeclRef.swift
@@ -58,7 +58,7 @@
 // CHECK-NEXT:  #Base.foo!1: (Base) -> () -> Int32 : @$S10SILDeclRef4BaseC3foos5Int32VyF	// Base.foo()
 // CHECK-NEXT:  #Base.foo!1: (Base) -> (Int32) -> () : @$S10SILDeclRef4BaseC3foo1nys5Int32V_tF	// Base.foo(n:)
 // CHECK-NEXT:  #Base.foo!1: (Base) -> (Float) -> Int32 : @$S10SILDeclRef4BaseC3foo1fs5Int32VSf_tF	// Base.foo(f:)
-// CHECK-NEXT:  #Base.init!initializer.1: (Base.Type) -> () -> Base : @$S10SILDeclRef4BaseCACycfc	// Base.init()
+// CHECK-NEXT:  #Base.init!allocator.1: (Base.Type) -> () -> Base : @$S10SILDeclRef4BaseCACycfC
 // CHECK-NEXT:  #Base.deinit!deallocator.1: @$S10SILDeclRef4BaseCfD	// Base.__deallocating_deinit
 // CHECK-NEXT: }
 
diff --git a/test/SILGen/accessibility_vtables.swift b/test/SILGen/accessibility_vtables.swift
index f8da4e5..d6ac5ca 100644
--- a/test/SILGen/accessibility_vtables.swift
+++ b/test/SILGen/accessibility_vtables.swift
@@ -21,7 +21,7 @@
 // CHECK-NEXT:  #Base.prop!getter.1: {{.*}} : @$S21accessibility_vtables3SubC4propSivg [override]  // accessibility_vtables.Sub.prop.getter : Swift.Int
 // CHECK-NEXT:  #Base.prop!setter.1: {{.*}} : @$S28accessibility_vtables_helper4BaseC4propSivs [inherited]  // accessibility_vtables_helper.Base.prop.setter : Swift.Int
 // CHECK-NEXT:  #Base.prop!modify.1: {{.*}} : @$S28accessibility_vtables_helper4BaseC4propSivM [inherited]  // accessibility_vtables_helper.Base.prop.modify : Swift.Int
-// CHECK-NEXT:  #Base.init!initializer.1: {{.*}} : @$S21accessibility_vtables3SubCACycfc [override]  // accessibility_vtables.Sub.init() -> accessibility_vtables.Sub
+// CHECK-NEXT:  #Base.init!allocator.1: {{.*}} : @$S21accessibility_vtables3SubCACycfC [override]
 // CHECK-NEXT: #Sub.internalMethod!1: {{.*}} : @$S21accessibility_vtables3SubC14internalMethodyyF
 // CHECK-NEXT: #Sub.prop!setter.1: {{.*}} : @$S21accessibility_vtables3SubC4propSivs   // accessibility_vtables.Sub.prop.setter : Swift.Int
 // CHECK-NEXT: #Sub.prop!modify.1: {{.*}} : @$S21accessibility_vtables3SubC4propSivM  // accessibility_vtables.Sub.prop.modify : Swift.Int
@@ -41,7 +41,7 @@
 // CHECK-NEXT:  #InternalBase.prop!getter.1: {{.*}} : @$S21accessibility_vtables11InternalSubC4propSivg [override] // accessibility_vtables.InternalSub.prop.getter : Swift.Int
 // CHECK-NEXT:  #InternalBase.prop!setter.1: {{.*}} : @$S21accessibility_vtables12InternalBaseC4propSivs [inherited]        // accessibility_vtables.InternalBase.prop.setter : Swift.Int
 // CHECK-NEXT:  #InternalBase.prop!modify.1: {{.*}} : @$S21accessibility_vtables12InternalBaseC4propSivM [inherited] // accessibility_vtables.InternalBase.prop.modify : Swift.Int
-// CHECK-NEXT:  #InternalBase.init!initializer.1: {{.*}} : @$S21accessibility_vtables11InternalSubCACycfc [override]
+// CHECK-NEXT:  #InternalBase.init!allocator.1: {{.*}} : @$S21accessibility_vtables11InternalSubCACycfC [override]
 // CHECK-NEXT:  #InternalSub.method!1: {{.*}} : @$S21accessibility_vtables11InternalSubC6methodyyF
 // CHECK-NEXT:  #InternalSub.prop!setter.1: {{.*}} : @$S21accessibility_vtables11InternalSubC4propSivs  // accessibility_vtables.InternalSub.prop.setter : Swift.Int
 // CHECK-NEXT:  #InternalSub.prop!modify.1: {{.*}} : @$S21accessibility_vtables11InternalSubC4propSivM // accessibility_vtables.InternalSub.prop.modify : Swift.Int
diff --git a/test/SILGen/addressors.swift b/test/SILGen/addressors.swift
index cb8d5bd..195a7e3 100644
--- a/test/SILGen/addressors.swift
+++ b/test/SILGen/addressors.swift
@@ -419,7 +419,7 @@
 // CHECK-NEXT: #Base.value!getter.1: (Base) -> () -> Int32 : @$S10addressors4BaseC5values5Int32Vvg
 // CHECK-NEXT: #Base.value!setter.1: (Base) -> (Int32) -> () : @$S10addressors4BaseC5values5Int32Vvs
 // CHECK-NEXT: #Base.value!modify.1: (Base) -> () -> () : @$S10addressors4BaseC5values5Int32VvM
-// CHECK-NEXT: #Base.init!initializer.1: (Base.Type) -> () -> Base : @$S10addressors4BaseCACycfc
+// CHECK-NEXT: #Base.init!allocator.1: (Base.Type) -> () -> Base : @$S10addressors4BaseCACycfC
 // CHECK-NEXT: #Base.deinit!deallocator.1: @$S10addressors4BaseCfD
 // CHECK-NEXT: }
 
@@ -430,6 +430,6 @@
 // CHECK-NEXT: #Base.value!getter.1: (Base) -> () -> Int32 : @$S10addressors3SubC5values5Int32Vvg
 // CHECK-NEXT: #Base.value!setter.1: (Base) -> (Int32) -> () : @$S10addressors3SubC5values5Int32Vvs
 // CHECK-NEXT: #Base.value!modify.1: (Base) -> () -> () : @$S10addressors3SubC5values5Int32VvM
-// CHECK-NEXT: #Base.init!initializer.1: (Base.Type) -> () -> Base : @$S10addressors3SubCACycfc
+// CHECK-NEXT: #Base.init!allocator.1: (Base.Type) -> () -> Base : @$S10addressors3SubCACycfC
 // CHECK-NEXT: #Sub.deinit!deallocator.1: @$S10addressors3SubCfD
 // CHECK-NEXT: }
diff --git a/test/SILGen/class_resilience.swift b/test/SILGen/class_resilience.swift
index 529ad8c..ba44f3e 100644
--- a/test/SILGen/class_resilience.swift
+++ b/test/SILGen/class_resilience.swift
@@ -41,7 +41,7 @@
 // Note: no entries for [inherited] methods
 
 // CHECK-LABEL: sil_vtable SubclassOfOutsideChild {
-// CHECK-NEXT:  #ResilientOutsideParent.init!initializer.1: (ResilientOutsideParent.Type) -> () -> ResilientOutsideParent : @$S16class_resilience22SubclassOfOutsideChildCACycfc [override]
+// CHECK-NEXT:  #ResilientOutsideParent.init!allocator.1: (ResilientOutsideParent.Type) -> () -> ResilientOutsideParent : @$S16class_resilience22SubclassOfOutsideChildCACycfC [override]
 // CHECK-NEXT:  #ResilientOutsideParent.method!1: (ResilientOutsideParent) -> () -> () : @$S16class_resilience22SubclassOfOutsideChildC6methodyyF [override]
 // CHECK-NEXT:  #SubclassOfOutsideChild.newMethod!1: (SubclassOfOutsideChild) -> () -> () : @$S16class_resilience22SubclassOfOutsideChildC9newMethodyyF
 // CHECK-NEXT:  #SubclassOfOutsideChild.deinit!deallocator.1: @$S16class_resilience22SubclassOfOutsideChildCfD
diff --git a/test/SILGen/complete_object_init.swift b/test/SILGen/complete_object_init.swift
index 89e0e3a..348bd32 100644
--- a/test/SILGen/complete_object_init.swift
+++ b/test/SILGen/complete_object_init.swift
@@ -5,24 +5,12 @@
 class A {
 // CHECK-LABEL: sil hidden @$S20complete_object_init1AC{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thick A.Type) -> @owned A
 // CHECK: bb0([[SELF_META:%[0-9]+]] : @trivial $@thick A.Type):
-// CHECK:   [[SELF:%[0-9]+]] = alloc_ref_dynamic [[SELF_META]] : $@thick A.Type, $A
-// CHECK:   [[OTHER_INIT:%[0-9]+]] = function_ref @$S20complete_object_init1AC{{[_0-9a-zA-Z]*}}fc : $@convention(method) (@owned A) -> @owned A
-// CHECK:   [[RESULT:%[0-9]+]] = apply [[OTHER_INIT]]([[SELF]]) : $@convention(method) (@owned A) -> @owned A
-// CHECK:   return [[RESULT]] : $A
-
-// CHECK-LABEL: sil hidden @$S20complete_object_init1AC{{[_0-9a-zA-Z]*}}fc : $@convention(method) (@owned A) -> @owned A
-// CHECK: bb0([[SELF_PARAM:%[0-9]+]] : @owned $A):
 // CHECK:   [[SELF_BOX:%[0-9]+]] = alloc_box ${ var A }
 // CHECK:   [[UNINIT_SELF:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]] : ${ var A }
 // CHECK:   [[PB:%.*]] = project_box [[UNINIT_SELF]]
-// CHECK:   store [[SELF_PARAM]] to [init] [[PB]] : $*A
-// CHECK:   [[SELFP:%[0-9]+]] = load [take] [[PB]] : $*A
-// CHECK:   [[X_META:%[0-9]+]] = metatype $@thin X.Type
-// CHECK:   [[X_INIT:%[0-9]+]] = function_ref @$S20complete_object_init1XV{{[_0-9a-zA-Z]*}}fC : $@convention(method) (@thin X.Type) -> X
-// CHECK:   [[X:%[0-9]+]] = apply [[X_INIT]]([[X_META]]) : $@convention(method) (@thin X.Type) -> X
-// CHECK:   [[INIT:%[0-9]+]] = class_method [[SELFP]] : $A, #A.init!initializer.1 : (A.Type) -> (X) -> A, $@convention(method) (X, @owned A) -> @owned A
-// CHECK:   [[INIT_RESULT:%[0-9]+]] = apply [[INIT]]([[X]], [[SELFP]]) : $@convention(method) (X, @owned A) -> @owned A
-// CHECK:   store [[INIT_RESULT]] to [init] [[PB]] : $*A
+// CHECK:   [[INIT:%[0-9]+]] = class_method [[SELF_META]] : $@thick A.Type, #A.init!allocator.1
+// CHECK:   [[INIT_RESULT:%[0-9]+]] = apply [[INIT]]({{%[^,]*}}, [[SELF_META]])
+// CHECK:   assign [[INIT_RESULT]] to [[PB]] : $*A
 // CHECK:   [[RESULT:%[0-9]+]] = load [copy] [[PB]] : $*A
 // CHECK:   destroy_value [[UNINIT_SELF]] : ${ var A }
 // CHECK:   return [[RESULT]] : $A
diff --git a/test/SILGen/convenience_init_peer_delegation.swift b/test/SILGen/convenience_init_peer_delegation.swift
new file mode 100644
index 0000000..c179392
--- /dev/null
+++ b/test/SILGen/convenience_init_peer_delegation.swift
@@ -0,0 +1,107 @@
+// RUN: %target-swift-emit-silgen %s | %FileCheck %s
+
+class X {
+  init() {
+  }
+
+  // Convenience inits must dynamically dispatch designated inits...
+  // CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
+  // CHECK:         class_method {{%.*}}, #X.init!allocator.1
+  convenience init(convenience: ()) {
+    self.init()
+  }
+
+  // ...but can statically invoke peer convenience inits
+  // CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfC
+  // CHECK:         function_ref @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
+  convenience init(doubleConvenience: ()) {
+    self.init(convenience: ())
+  }
+
+  // CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfC
+  required init(required: ()) {
+  }
+
+  // CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfC
+  required convenience init(requiredConvenience: ()) {
+    self.init(required: ())
+  }
+
+  // Convenience inits must dynamically dispatch required peer convenience inits
+  // CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfC
+  // CHECK:         class_method {{%.*}}, #X.init!allocator.1
+  required convenience init(requiredDoubleConvenience: ()) {
+    self.init(requiredDoubleConvenience: ())
+  }
+}
+
+class Y: X {
+  // This is really a designated initializer. Ensure that we don't try to
+  // treat it as an override of the base class convenience initializer (and
+  // override a nonexistent vtable entry) just because it has the same name.
+  init(convenience: ()) {
+    super.init()
+  }
+
+  // Conversely, a designated init *can* be overridden as a convenience
+  // initializer.
+  override convenience init() {
+    self.init(convenience: ())
+  }
+
+  required init(required: ()) { super.init() }
+  required init(requiredConvenience: ()) { super.init() }
+  required init(requiredDoubleConvenience: ()) { super.init() }
+}
+
+// CHECK-LABEL: sil hidden @$S32convenience_init_peer_delegation11invocations2xtyAA1XCm_tF
+func invocations(xt: X.Type) {
+  // CHECK: function_ref @$S32convenience_init_peer_delegation1XCACycfC
+  _ = X()
+  // CHECK: function_ref @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
+  _ = X(convenience: ())
+  // CHECK: function_ref @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfC
+  _ = X(doubleConvenience: ())
+  // CHECK: function_ref @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfC
+  _ = X(required: ())
+  // CHECK: function_ref @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfC
+  _ = X(requiredConvenience: ())
+  // CHECK: function_ref @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfC
+  _ = X(requiredDoubleConvenience: ())
+
+  // CHECK: class_method {{%.*}}, #X.init!allocator.1
+  _ = xt.init(required: ())
+  // CHECK: class_method {{%.*}}, #X.init!allocator.1
+  _ = xt.init(requiredConvenience: ())
+  // CHECK: class_method {{%.*}}, #X.init!allocator.1
+  _ = xt.init(requiredDoubleConvenience: ())
+}
+
+// CHECK-LABEL: sil_vtable X
+//                -- designated init()
+// CHECK:         @$S32convenience_init_peer_delegation1XCACycfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XCACycfc
+
+//                -- no unrequired convenience inits
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XC0A0ACyt_tcfc
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XC17doubleConvenienceACyt_tcfc
+
+//                -- designated init(required:)
+// CHECK:         @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XC8requiredACyt_tcfc
+//                -- convenience init(requiredConvenience:)
+// CHECK:         @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XC19requiredConvenienceACyt_tcfc
+//                -- convenience init(requiredDoubleConvenience:)
+// CHECK:         @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1XC25requiredDoubleConvenienceACyt_tcfc
+
+// CHECK-LABEL: sil_vtable Y
+//                -- designated init() overridden by convenience init
+// CHECK:         @$S32convenience_init_peer_delegation1YCACycfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1YCACycfc
+//                -- Y.init(convenience:) is a designated init
+// CHECK:         @$S32convenience_init_peer_delegation1YC0A0ACyt_tcfC
+// CHECK-NOT:     @$S32convenience_init_peer_delegation1YC0A0ACyt_tcfc
diff --git a/test/SILGen/dynamic.swift b/test/SILGen/dynamic.swift
index 2576416..a38d467 100644
--- a/test/SILGen/dynamic.swift
+++ b/test/SILGen/dynamic.swift
@@ -328,7 +328,7 @@
 }
 
 extension Gizmo {
-  // CHECK-LABEL: sil hidden @$SSo5GizmoC7dynamicE{{[_0-9a-zA-Z]*}}fc
+  // CHECK-LABEL: sil hidden @$SSo5GizmoC7dynamicE{{[_0-9a-zA-Z]*}}fC
   // CHECK:         objc_method {{%.*}} : $Gizmo, #Gizmo.init!initializer.1.foreign
   convenience init(convenienceInExtension: Int) {
     self.init(bellsOn: convenienceInExtension)
@@ -499,7 +499,7 @@
 
 // Vtable contains entries for native and @objc methods, but not dynamic ones
 // CHECK-LABEL: sil_vtable Foo {
-// CHECK-NEXT:   #Foo.init!initializer.1: {{.*}} :   @$S7dynamic3FooC6nativeACSi_tcfc
+// CHECK-NEXT:   #Foo.init!allocator.1: {{.*}} :   @$S7dynamic3FooC6nativeACSi_tcfC
 // CHECK-NEXT:   #Foo.nativeMethod!1: {{.*}} :       @$S7dynamic3FooC12nativeMethodyyF
 // CHECK-NEXT:   #Foo.nativeProp!getter.1: {{.*}} :  @$S7dynamic3FooC10nativePropSivg     // dynamic.Foo.nativeProp.getter : Swift.Int
 // CHECK-NEXT:   #Foo.nativeProp!setter.1: {{.*}} :  @$S7dynamic3FooC10nativePropSivs     // dynamic.Foo.nativeProp.setter : Swift.Int
@@ -507,7 +507,7 @@
 // CHECK-NEXT:   #Foo.subscript!getter.1: {{.*}} :   @$S7dynamic3FooC6nativeS2i_tcig    // dynamic.Foo.subscript.getter : (native: Swift.Int) -> Swift.Int
 // CHECK-NEXT:   #Foo.subscript!setter.1: {{.*}} :   @$S7dynamic3FooC6nativeS2i_tcis    // dynamic.Foo.subscript.setter : (native: Swift.Int) -> Swift.Int
 // CHECK-NEXT:   #Foo.subscript!modify.1:
-// CHECK-NEXT:   #Foo.init!initializer.1: {{.*}} :   @$S7dynamic3FooC4objcACSi_tcfc
+// CHECK-NEXT:   #Foo.init!allocator.1: {{.*}} :   @$S7dynamic3FooC4objcACSi_tcfC
 // CHECK-NEXT:   #Foo.objcMethod!1: {{.*}} :         @$S7dynamic3FooC10objcMethodyyF
 // CHECK-NEXT:   #Foo.objcProp!getter.1: {{.*}} :    @$S7dynamic3FooC8objcPropSivg  // dynamic.Foo.objcProp.getter : Swift.Int
 // CHECK-NEXT:   #Foo.objcProp!setter.1: {{.*}} :    @$S7dynamic3FooC8objcPropSivs  // dynamic.Foo.objcProp.setter : Swift.Int
@@ -526,20 +526,20 @@
 
 // Check vtables for implicitly-inherited initializers
 // CHECK-LABEL: sil_vtable SubclassWithInheritedInits {
-// CHECK:   #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC6nativeACSi_tcfc
-// CHECK:   #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC4objcACSi_tcfc
+// CHECK:   #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC6nativeACSi_tcfC
+// CHECK:   #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26SubclassWithInheritedInitsC4objcACSi_tcfC
 // CHECK-NOT: .init!
 // CHECK: }
 
 // CHECK-LABEL: sil_vtable GrandchildWithInheritedInits {
-// CHECK:   #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC6nativeACSi_tcfc
-// CHECK:   #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC4objcACSi_tcfc
+// CHECK:   #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC6nativeACSi_tcfC
+// CHECK:   #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic28GrandchildWithInheritedInitsC4objcACSi_tcfC
 // CHECK-NOT: .init!
 // CHECK: }
 
 // CHECK-LABEL: sil_vtable GrandchildOfInheritedInits {
-// CHECK:   #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC6nativeACSi_tcfc
-// CHECK:   #Foo.init!initializer.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC4objcACSi_tcfc
+// CHECK:   #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC6nativeACSi_tcfC
+// CHECK:   #Foo.init!allocator.1: (Foo.Type) -> (Int) -> Foo : @$S7dynamic26GrandchildOfInheritedInitsC4objcACSi_tcfC
 // CHECK-NOT: .init!
 // CHECK: }
 
@@ -551,6 +551,6 @@
 // Dynamic thunk + vtable re-abstraction
 // CHECK-LABEL: sil_vtable [serialized] ConcreteDerived {
 // CHECK-NEXT: #GenericBase.method!1: <T> (GenericBase<T>) -> (T) -> () : public @$S7dynamic15ConcreteDerivedC6methodyySiFAA11GenericBaseCADyyxFTV [override]     // vtable thunk for dynamic.GenericBase.method(A) -> () dispatching to dynamic.ConcreteDerived.method(Swift.Int) -> ()
-// CHECK-NEXT: #GenericBase.init!initializer.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : @$S7dynamic15ConcreteDerivedCACycfc [override]      // dynamic.ConcreteDerived.init() -> dynamic.ConcreteDerived
+// CHECK-NEXT: #GenericBase.init!allocator.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : @$S7dynamic15ConcreteDerivedCACycfC [override]
 // CHECK-NEXT: #ConcreteDerived.deinit!deallocator.1: @$S7dynamic15ConcreteDerivedCfD  // dynamic.ConcreteDerived.__deallocating_deinit
 // CHECK-NEXT: }
diff --git a/test/SILGen/errors.swift b/test/SILGen/errors.swift
index dadd545..d6653a0 100644
--- a/test/SILGen/errors.swift
+++ b/test/SILGen/errors.swift
@@ -882,13 +882,13 @@
 class SomeErrorClass : Error { }
 
 // CHECK-LABEL: sil_vtable SomeErrorClass
-// CHECK-NEXT:   #SomeErrorClass.init!initializer.1: {{.*}} : @$S6errors14SomeErrorClassCACycfc
+// CHECK-NEXT:   #SomeErrorClass.init!allocator.1: {{.*}} : @$S6errors14SomeErrorClassCACycfC
 // CHECK-NEXT:   #SomeErrorClass.deinit!deallocator.1: @$S6errors14SomeErrorClassCfD
 // CHECK-NEXT: }
 
 class OtherErrorSub : OtherError { }
 
 // CHECK-LABEL: sil_vtable OtherErrorSub {
-// CHECK-NEXT:  #OtherError.init!initializer.1: {{.*}} : @$S6errors13OtherErrorSubCACycfc [override]     // OtherErrorSub.init()
+// CHECK-NEXT:  #OtherError.init!allocator.1: {{.*}} : @$S6errors13OtherErrorSubCACycfC [override]
 // CHECK-NEXT:  #OtherErrorSub.deinit!deallocator.1: @$S6errors13OtherErrorSubCfD        // OtherErrorSub.__deallocating_deinit
 // CHECK-NEXT:}
diff --git a/test/SILGen/final.swift b/test/SILGen/final.swift
index 2d8e9e3..42d073c 100644
--- a/test/SILGen/final.swift
+++ b/test/SILGen/final.swift
@@ -33,13 +33,13 @@
 // Verify that the non-overriding final methods don't get emitted to the vtable.
 // CHECK-LABEL: sil_vtable TestClass {
 // CHECK-NEXT:  #TestClass.baseMethod!1: {{.*}} : @$S5final9TestClassC10baseMethod{{[_0-9a-zA-Z]*}}F
-// CHECK-NEXT:  #TestClass.init!initializer.1: {{.*}} : @$S5final9TestClassC{{[_0-9a-zA-Z]*}}fc
+// CHECK-NEXT:  #TestClass.init!allocator.1: {{.*}} : @$S5final9TestClassC{{[_0-9a-zA-Z]*}}fC
 // CHECK-NEXT:  #TestClass.deinit!
 // CHECK-NEXT: }
 
 // Verify that overriding final methods don't get emitted to the vtable.
 // CHECK-LABEL: sil_vtable TestDerived {
 // CHECK-NEXT:  #TestClass.baseMethod!1: {{.*}} : @$S5final11TestDerivedC10baseMethod{{[_0-9a-zA-Z]*}}F
-// CHECK-NEXT:  #TestClass.init!initializer.1: {{.*}} : @$S5final11TestDerivedC{{[_0-9a-zA-Z]*}}fc
+// CHECK-NEXT:  #TestClass.init!allocator.1: {{.*}} : @$S5final11TestDerivedC{{[_0-9a-zA-Z]*}}fC
 // CHECK-NEXT:  #TestDerived.deinit!
 // CHECK-NEXT: }
diff --git a/test/SILGen/import_as_member.swift b/test/SILGen/import_as_member.swift
index d550c21..d8227a3 100644
--- a/test/SILGen/import_as_member.swift
+++ b/test/SILGen/import_as_member.swift
@@ -54,7 +54,7 @@
 }
 
 extension SomeClass {
-  // CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC16import_as_memberE6doubleABSd_tcfc
+  // CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC16import_as_memberE6doubleABSd_tcfC
   // CHECK: bb0([[DOUBLE:%[0-9]+]] : @trivial $Double
   // CHECK-NOT: value_metatype
   // CHECK: [[FNREF:%[0-9]+]] = function_ref @MakeIAMSomeClass
diff --git a/test/SILGen/init_ref_delegation.swift b/test/SILGen/init_ref_delegation.swift
index d729dca..efe4fd2 100644
--- a/test/SILGen/init_ref_delegation.swift
+++ b/test/SILGen/init_ref_delegation.swift
@@ -85,18 +85,16 @@
 class C1 {
   var ivar: X
 
- // CHECK-LABEL: sil hidden @$S19init_ref_delegation2C1C{{[_0-9a-zA-Z]*}}fc : $@convention(method) (X, @owned C1) -> @owned C1
+ // CHECK-LABEL: sil hidden @$S19init_ref_delegation2C1C{{[_0-9a-zA-Z]*}}fC
   convenience init(x: X) {
-    // CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[ORIG_SELF:%[0-9]+]] : @owned $C1):
+    // CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[SELF_META:%[0-9]+]] : @trivial $@thick C1.Type):
     // CHECK:   [[SELF_BOX:%[0-9]+]] = alloc_box ${ var C1 }
     // CHECK:   [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
     // CHECK:   [[PB:%.*]] = project_box [[MARKED_SELF_BOX]]
 
-    // CHECK:   store [[ORIG_SELF]] to [init] [[PB]] : $*C1
-    // CHECK:   [[SELF_FROM_BOX:%[0-9]+]] = load [take] [[PB]] : $*C1
-    // CHECK:   [[DELEG_INIT:%[0-9]+]] = class_method [[SELF_FROM_BOX]] : $C1, #C1.init!initializer.1 : (C1.Type) -> (X, X) -> C1, $@convention(method) (X, X, @owned C1) -> @owned C1
-    // CHECK:   [[SELFP:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF_FROM_BOX]]) : $@convention(method) (X, X, @owned C1) -> @owned C1
-    // CHECK:   store [[SELFP]] to [init] [[PB]] : $*C1
+    // CHECK:   [[DELEG_INIT:%[0-9]+]] = class_method [[SELF_META]] : $@thick C1.Type, #C1.init!allocator.1
+    // CHECK:   [[SELFP:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF_META]])
+    // CHECK:   assign [[SELFP]] to [[PB]]
     // CHECK:   [[SELFP:%[0-9]+]] = load [copy] [[PB]] : $*C1
     // CHECK:   destroy_value [[MARKED_SELF_BOX]] : ${ var C1 }
     // CHECK:   return [[SELFP]] : $C1
@@ -109,17 +107,15 @@
 @objc class C2 {
   var ivar: X
 
-  // CHECK-LABEL: sil hidden @$S19init_ref_delegation2C2C{{[_0-9a-zA-Z]*}}fc : $@convention(method) (X, @owned C2) -> @owned C2
+  // CHECK-LABEL: sil hidden @$S19init_ref_delegation2C2C{{[_0-9a-zA-Z]*}}fC
   convenience init(x: X) {
-    // CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[ORIG_SELF:%[0-9]+]] : @owned $C2):
+    // CHECK: bb0([[X:%[0-9]+]] : @trivial $X, [[SELF_META:%[0-9]+]] : @trivial $@thick C2.Type):
     // CHECK:   [[SELF_BOX:%[0-9]+]] = alloc_box ${ var C2 }
     // CHECK:   [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
     // CHECK:   [[PB_SELF:%.*]] = project_box [[MARKED_SELF_BOX]]
-    // CHECK:   store [[ORIG_SELF]] to [init] [[PB_SELF]] : $*C2
-    // CHECK:   [[SELF:%[0-9]+]] = load [take] [[PB_SELF]] : $*C2
-    // CHECK:   [[DELEG_INIT:%[0-9]+]] = class_method [[SELF]] : $C2, #C2.init!initializer.1 : (C2.Type) -> (X, X) -> C2, $@convention(method) (X, X, @owned C2) -> @owned C2
-    // CHECK:   [[REPLACE_SELF:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF]]) : $@convention(method) (X, X, @owned C2) -> @owned C2
-    // CHECK:   store [[REPLACE_SELF]] to [init] [[PB_SELF]] : $*C2
+    // CHECK:   [[DELEG_INIT:%[0-9]+]] = class_method [[SELF_META]] : $@thick C2.Type, #C2.init!allocator.1
+    // CHECK:   [[REPLACE_SELF:%[0-9]+]] = apply [[DELEG_INIT]]([[X]], [[X]], [[SELF_META]])
+    // CHECK:   assign [[REPLACE_SELF]] to [[PB_SELF]] : $*C2
     // CHECK:   [[VAR_15:%[0-9]+]] = load [copy] [[PB_SELF]] : $*C2
     // CHECK:   destroy_value [[MARKED_SELF_BOX]] : ${ var C2 }
     // CHECK:   return [[VAR_15]] : $C2
@@ -137,11 +133,11 @@
 class C3 {
   var i: Int = 5
 
-  // CHECK-LABEL: sil hidden @$S19init_ref_delegation2C3C{{[_0-9a-zA-Z]*}}fc : $@convention(method) (@owned C3) -> @owned C3
+  // CHECK-LABEL: sil hidden @$S19init_ref_delegation2C3C{{[_0-9a-zA-Z]*}}fC
   convenience init() {
     // CHECK: mark_uninitialized [delegatingself]
     // CHECK-NOT: integer_literal
-    // CHECK: class_method [[SELF:%[0-9]+]] : $C3, #C3.init!initializer.1 : (C3.Type) -> (X) -> C3, $@convention(method) (X, @owned C3) -> @owned C3
+    // CHECK: class_method [[SELF:%[0-9]+]] : $@thick C3.Type, #C3.init!allocator.1
     // CHECK-NOT: integer_literal
     // CHECK: return
     self.init(x: x)
@@ -158,9 +154,9 @@
   convenience init(x1: X) {
     self.init()
   }
-  // CHECK: sil hidden @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fc
-  // CHECK: [[PEER:%[0-9]+]] = function_ref @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fc
-  // CHECK: apply [[PEER]]([[X:%[0-9]+]], [[OBJ:%[0-9]+]])
+  // CHECK: sil hidden @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fC
+  // CHECK: [[PEER:%[0-9]+]] = function_ref @$S19init_ref_delegation2C4C{{[_0-9a-zA-Z]*}}fC
+  // CHECK: apply [[PEER]]([[X:%[0-9]+]], [[META:%[0-9]+]])
   convenience init(x2: X) {
     self.init(x1: x2)
   }
diff --git a/test/SILGen/initializers.swift b/test/SILGen/initializers.swift
index 9ed8768..d22dc3c 100644
--- a/test/SILGen/initializers.swift
+++ b/test/SILGen/initializers.swift
@@ -358,20 +358,18 @@
     return nil
   }
 
-  // CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfc : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass> {
-  // CHECK: bb0([[OLD_SELF:%.*]] : @owned $FailableBaseClass):
+  // CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfC
+  // CHECK: bb0([[SELF_META:%.*]] : @trivial $@thick FailableBaseClass.Type):
   // CHECK:   [[SELF_BOX:%.*]] = alloc_box ${ var FailableBaseClass }, let, name "self"
   // CHECK:   [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
   // CHECK:   [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-  // CHECK:   store [[OLD_SELF]] to [init] [[PB_BOX]]
-  // CHECK:   [[TAKE_SELF:%.*]] = load [take] [[PB_BOX]]
-  // CHECK:   [[NEW_SELF:%.*]] = apply {{.*}}([[TAKE_SELF]]) : $@convention(method) (@owned FailableBaseClass) -> @owned FailableBaseClass
+  // CHECK:   [[NEW_SELF:%.*]] = apply {{.*}}([[SELF_META]])
   // CHECK:   destroy_value [[MARKED_SELF_BOX]]
   // CHECK:   [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
   // CHECK:   br bb2([[RESULT]] : $Optional<FailableBaseClass>)
   // CHECK: bb2([[RESULT:%.*]] : @owned $Optional<FailableBaseClass>):
   // CHECK:   return [[RESULT]]
-  // CHECK: } // end sil function '$S21failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfc
+  // CHECK-NEXT: }
   convenience init?(failAfterDelegation: ()) {
     self.init(noFail: ())
     return nil
@@ -379,14 +377,12 @@
 
   // Optional to optional
   //
-  // CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfc : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass> {
-  // CHECK: bb0([[OLD_SELF:%.*]] : @owned $FailableBaseClass):
+  // CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfC
+  // CHECK: bb0([[SELF_META:%.*]] : @trivial $@thick FailableBaseClass.Type):
   // CHECK:   [[SELF_BOX:%.*]] = alloc_box ${ var FailableBaseClass }, let, name "self"
   // CHECK:   [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
   // CHECK:   [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-  // CHECK:   store [[OLD_SELF]] to [init] [[PB_BOX]]
-  // CHECK:   [[TAKE_SELF:%.*]] = load [take] [[PB_BOX]]
-  // CHECK:   [[NEW_SELF:%.*]] = apply {{.*}}([[TAKE_SELF]]) : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass>
+  // CHECK:   [[NEW_SELF:%.*]] = apply {{.*}}([[SELF_META]])
   // CHECK:   cond_br {{.*}}, [[SUCC_BB:bb[0-9]+]], [[FAIL_BB:bb[0-9]+]]
   //
   // CHECK: [[FAIL_BB:bb[0-9]+]]:
@@ -395,7 +391,7 @@
   //
   // CHECK: [[SUCC_BB]]:
   // CHECK:   [[UNWRAPPED_NEW_SELF:%.*]] = unchecked_enum_data [[NEW_SELF]] : $Optional<FailableBaseClass>, #Optional.some!enumelt.1
-  // CHECK:   store [[UNWRAPPED_NEW_SELF]] to [init] [[PB_BOX]]
+  // CHECK:   assign [[UNWRAPPED_NEW_SELF]] to [[PB_BOX]]
   // CHECK:   [[RESULT:%.*]] = load [copy] [[PB_BOX]]
   // CHECK:   [[WRAPPED_RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.some!enumelt.1, [[RESULT]]
   // CHECK:   destroy_value [[MARKED_SELF_BOX]]
@@ -414,23 +410,19 @@
 
   // IUO to optional
   //
-  // CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC21failDuringDelegation2ACSgyt_tcfc : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass> {
-  // CHECK: bb0([[OLD_SELF:%.*]] : @owned $FailableBaseClass):
+  // CHECK-LABEL: sil hidden @$S21failable_initializers17FailableBaseClassC21failDuringDelegation2ACSgyt_tcfC
+  // CHECK: bb0([[SELF_META:%.*]] : @trivial $@thick FailableBaseClass.Type):
   // CHECK:   [[SELF_BOX:%.*]] = alloc_box ${ var FailableBaseClass }, let, name "self"
   // CHECK:   [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
   // CHECK:   [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-  // CHECK:   store [[OLD_SELF]] to [init] [[PB_BOX]]
-  // CHECK-NEXT:   [[TAKE_SELF:%.*]] = load [take] [[PB_BOX]]
-  // CHECK-NOT: [[OLD_SELF]]
-  // CHECK-NOT: copy_value
-  // CHECK:   [[NEW_SELF:%.*]] = apply {{.*}}([[TAKE_SELF]]) : $@convention(method) (@owned FailableBaseClass) -> @owned Optional<FailableBaseClass>
+  // CHECK:   [[NEW_SELF:%.*]] = apply {{.*}}([[SELF_META]])
   // CHECK:   switch_enum [[NEW_SELF]] : $Optional<FailableBaseClass>, case #Optional.some!enumelt.1: [[SUCC_BB:bb[0-9]+]], case #Optional.none!enumelt: [[FAIL_BB:bb[0-9]+]]
   //
   // CHECK: [[FAIL_BB]]:
   // CHECK:   unreachable
   //
   // CHECK: [[SUCC_BB]]([[RESULT:%.*]] : @owned $FailableBaseClass):
-  // CHECK:   store [[RESULT]] to [init] [[PB_BOX]]
+  // CHECK:   assign [[RESULT]] to [[PB_BOX]]
   // CHECK:   [[RESULT:%.*]] = load [copy] [[PB_BOX]]
   // CHECK:   [[WRAPPED_RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.some!enumelt.1, [[RESULT]] : $FailableBaseClass
   // CHECK:   destroy_value [[MARKED_SELF_BOX]]
@@ -438,7 +430,7 @@
   //
   // CHECK: [[EPILOG_BB]]([[WRAPPED_RESULT:%.*]] : @owned $Optional<FailableBaseClass>):
   // CHECK:   return [[WRAPPED_RESULT]]
-  // CHECK: } // end sil function '$S21failable_initializers17FailableBaseClassC21failDuringDelegation2ACSgyt_tcfc'
+  // CHECK-NEXT: }
   convenience init!(failDuringDelegation2: ()) {
     self.init(failBeforeFullInitialization: ())! // unnecessary-but-correct '!'
   }
@@ -875,26 +867,23 @@
     try unwrap(chainingFailAfterDelegation)
   }
 
-  // CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC39chainingFailDuringDelegationArgEmission0fghI4CallACSi_SitKcfc : $@convention(method) (Int, Int, @owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error) {
-  // CHECK: bb0({{.*}}, [[OLD_SELF:%.*]] : @owned $ThrowDerivedClass):
+  // CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC39chainingFailDuringDelegationArgEmission0fghI4CallACSi_SitKcfC
+  // CHECK: bb0({{.*}}, [[SELF_META:%.*]] : @trivial $@thick ThrowDerivedClass.Type):
   // CHECK:   [[SELF_BOX:%.*]] = alloc_box ${ var ThrowDerivedClass }, let, name "self"
   // CHECK:   [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
   // CHECK:   [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-  // CHECK:   store [[OLD_SELF]] to [init] [[PB_BOX]]
-  // CHECK:   [[MOVE_ONLY_SELF:%.*]] = load [take] [[PB_BOX]]
   // CHECK:   try_apply {{.*}}({{.*}}) : $@convention(thin) (Int) -> (Int, @error Error), normal [[SUCC_BB1:bb[0-9]+]], error [[ERROR_BB1:bb[0-9]+]]
   //
   // CHECK: [[SUCC_BB1]](
-  // CHECK:   try_apply {{.*}}({{.*}}, [[MOVE_ONLY_SELF]]) : $@convention(method) (Int, @owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error), normal [[SUCC_BB2:bb[0-9]+]], error [[ERROR_BB2:bb[0-9]+]]
+  // CHECK:   try_apply {{.*}}({{.*}}, [[SELF_META]]) : {{.*}}, normal [[SUCC_BB2:bb[0-9]+]], error [[ERROR_BB2:bb[0-9]+]]
   //
   // CHECK: [[SUCC_BB2]]([[NEW_SELF:%.*]] : @owned $ThrowDerivedClass):
-  // CHECK-NEXT: store [[NEW_SELF]] to [init] [[PB_BOX]]
+  // CHECK-NEXT: assign [[NEW_SELF]] to [[PB_BOX]]
   // CHECK-NEXT: [[RESULT:%.*]] = load [copy] [[PB_BOX]]
   // CHECK-NEXT: destroy_value [[MARKED_SELF_BOX]]
   // CHECK-NEXT: return [[RESULT]]
   //
   // CHECK: [[ERROR_BB1]]([[ERROR:%.*]] : @owned $Error):
-  // CHECK-NEXT: store [[MOVE_ONLY_SELF]] to [init] [[PB_BOX]]
   // CHECK-NEXT: br [[THROWING_BB:bb[0-9]+]]([[ERROR]]
   //
   // CHECK: [[ERROR_BB2]]([[ERROR:%.*]] : @owned $Error):
@@ -912,17 +901,15 @@
     try unwrap(chainingFailAfterDelegation)
   }
 
-  // CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC32chainingFailDuringDelegationCall0fg5AfterI0ACSi_SitKcfc : $@convention(method) (Int, Int, @owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error) {
-  // CHECK: bb0({{.*}}, [[OLD_SELF:%.*]] : @owned $ThrowDerivedClass):
+  // CHECK-LABEL: sil hidden @$S21failable_initializers17ThrowDerivedClassC32chainingFailDuringDelegationCall0fg5AfterI0ACSi_SitKcfC
+  // CHECK: bb0({{.*}}, [[SELF_META:%.*]] : @trivial $@thick ThrowDerivedClass.Type):
   // CHECK:   [[SELF_BOX:%.*]] = alloc_box ${ var ThrowDerivedClass }, let, name "self"
   // CHECK:   [[MARKED_SELF_BOX:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
   // CHECK:   [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-  // CHECK:   store [[OLD_SELF]] to [init] [[PB_BOX]]
-  // CHECK:   [[MOVE_ONLY_SELF:%.*]] = load [take] [[PB_BOX]]
-  // CHECK:   try_apply {{.*}}([[MOVE_ONLY_SELF]]) : $@convention(method) (@owned ThrowDerivedClass) -> (@owned ThrowDerivedClass, @error Error), normal [[SUCC_BB1:bb[0-9]+]], error [[ERROR_BB1:bb[0-9]+]]
+  // CHECK:   try_apply {{.*}}([[SELF_META]]) : {{.*}}, normal [[SUCC_BB1:bb[0-9]+]], error [[ERROR_BB1:bb[0-9]+]]
   //
   // CHECK: [[SUCC_BB1]]([[NEW_SELF:%.*]] : @owned $ThrowDerivedClass):
-  // CHECK-NEXT:   store [[NEW_SELF]] to [init] [[PB_BOX]]
+  // CHECK-NEXT:   assign [[NEW_SELF]] to [[PB_BOX]]
   // CHECK-NEXT:   // function_ref
   // CHECK-NEXT:   function_ref @
   // CHECK-NEXT:   try_apply {{.*}}({{.*}}) : $@convention(thin) (Int) -> (Int, @error Error), normal [[SUCC_BB2:bb[0-9]+]], error [[ERROR_BB2:bb[0-9]+]]
diff --git a/test/SILGen/ivar_destroyer.swift b/test/SILGen/ivar_destroyer.swift
index 92038be..e1cee1b 100644
--- a/test/SILGen/ivar_destroyer.swift
+++ b/test/SILGen/ivar_destroyer.swift
@@ -34,7 +34,7 @@
 // CHECK-NEXT:    return [[RESULT]]
 
 // CHECK-LABEL: sil_vtable RootClassWithoutProperties {
-// CHECK-NEXT:    #RootClassWithoutProperties.init!initializer.1
+// CHECK-NEXT:    #RootClassWithoutProperties.init!allocator.1
 // CHECK-NEXT:    #RootClassWithoutProperties.deinit!deallocator
 // CHECK-NEXT:  }
 
@@ -45,7 +45,7 @@
 // CHECK-NEXT:    #RootClassWithTrivialProperties.y!getter.1
 // CHECK-NEXT:    #RootClassWithTrivialProperties.y!setter.1
 // CHECK-NEXT:    #RootClassWithTrivialProperties.y!modify.1
-// CHECK-NEXT:    #RootClassWithTrivialProperties.init!initializer.1
+// CHECK-NEXT:    #RootClassWithTrivialProperties.init!allocator.1
 // CHECK-NEXT:    #RootClassWithTrivialProperties.deinit!deallocator
 // CHECK-NEXT:  }
 
@@ -53,12 +53,12 @@
 // CHECK-NEXT:    #RootClassWithNonTrivialProperties.x!getter.1
 // CHECK-NEXT:    #RootClassWithNonTrivialProperties.x!setter.1
 // CHECK-NEXT:    #RootClassWithNonTrivialProperties.x!modify.1
-// CHECK-NEXT:    #RootClassWithNonTrivialProperties.init!initializer.1
+// CHECK-NEXT:    #RootClassWithNonTrivialProperties.init!allocator.1
 // CHECK-NEXT:    #RootClassWithNonTrivialProperties.deinit!deallocator
 // CHECK-NEXT:  }
 
 // CHECK-LABEL: sil_vtable DerivedClassWithTrivialProperties {
-// CHECK-NEXT:    #RootClassWithoutProperties.init!initializer.1
+// CHECK-NEXT:    #RootClassWithoutProperties.init!allocator.1
 // CHECK-NEXT:    #DerivedClassWithTrivialProperties.z!getter.1
 // CHECK-NEXT:    #DerivedClassWithTrivialProperties.z!setter.1
 // CHECK-NEXT:    #DerivedClassWithTrivialProperties.z!modify.1
@@ -66,7 +66,7 @@
 // CHECK-NEXT:  }
 
 // CHECK-LABEL: sil_vtable DerivedClassWithNonTrivialProperties {
-// CHECK-NEXT:    #RootClassWithoutProperties.init!initializer.1
+// CHECK-NEXT:    #RootClassWithoutProperties.init!allocator.1
 // CHECK-NEXT:    #DerivedClassWithNonTrivialProperties.z!getter.1
 // CHECK-NEXT:    #DerivedClassWithNonTrivialProperties.z!setter.1
 // CHECK-NEXT:    #DerivedClassWithNonTrivialProperties.z!modify.1
diff --git a/test/SILGen/objc_dynamic_init.swift b/test/SILGen/objc_dynamic_init.swift
index b39acb6..1578bb3 100644
--- a/test/SILGen/objc_dynamic_init.swift
+++ b/test/SILGen/objc_dynamic_init.swift
@@ -36,10 +36,10 @@
 }
 
 // CHECK-LABEL: sil private [transparent] [thunk] @$S{{.*}}GadgetC{{.*}}CTW
-// CHECK:         class_method {{%.*}} : $@thick Gadget.Type, #Gadget.init!allocator.1 :
+// CHECK:         function_ref @{{.*}}Gadget{{.*}}fC :
 
 // CHECK-LABEL: sil_vtable Gadget {
-// CHECK:         #Gadget.init!allocator.1: (Gadget.Type) -> () -> Gadget : @$S{{.*}}GadgetC{{.*}}C //
+// CHECK-NOT:     #Gadget.init!allocator.1
 
 // CHECK-LABEL: sil_vtable Gizmo {
-// CHECK:         #Gadget.init!allocator.1: (Gadget.Type) -> () -> Gadget : @$S{{.*}}GizmoC{{.*}}C [override] //
+// CHECK-NOT:     #Gadget.init!allocator.1
diff --git a/test/SILGen/objc_factory_init.swift b/test/SILGen/objc_factory_init.swift
index 276e0bf..aa6a4b9 100644
--- a/test/SILGen/objc_factory_init.swift
+++ b/test/SILGen/objc_factory_init.swift
@@ -21,15 +21,11 @@
   // not a convenience initializer, which means it does not have an initializing
   // entry point at all.
 
-  // CHECK-LABEL: sil hidden @$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfc : $@convention(method) (@owned Bee, @owned Hive) -> @owned Hive {
-  // CHECK: bb0([[QUEEN:%.*]] : @owned $Bee, [[OLD_HIVE:%.*]] : @owned $Hive):
+  // CHECK-LABEL: sil hidden @$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfC
+  // CHECK: bb0([[QUEEN:%.*]] : @owned $Bee, [[META:%.*]] : @trivial $@thick Hive.Type):
   // CHECK:   [[SELF_BOX:%.*]] = alloc_box ${ var Hive }, let, name "self"
   // CHECK:   [[MU:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
   // CHECK:   [[PB_BOX:%.*]] = project_box [[MU]] : ${ var Hive }, 0
-  // CHECK:   store [[OLD_HIVE]] to [init] [[PB_BOX]]
-  // CHECK:   [[BORROWED_SELF:%.*]] = load_borrow [[PB_BOX]]
-  // CHECK:   [[META:%[0-9]+]] = value_metatype $@thick Hive.Type, [[BORROWED_SELF]] : $Hive
-  // CHECK:   end_borrow [[BORROWED_SELF]]
   // CHECK:   [[OBJC_META:%[0-9]+]] = thick_to_objc_metatype [[META]] : $@thick Hive.Type to $@objc_metatype Hive.Type
   // CHECK:   [[BORROWED_QUEEN:%.*]] = begin_borrow [[QUEEN]]
   // CHECK:   [[COPIED_BORROWED_QUEEN:%.*]] = copy_value [[BORROWED_QUEEN]]
@@ -42,58 +38,36 @@
   //
   // CHECK: [[SOME_BB]]([[NEW_HIVE:%.*]] : @owned $Hive):
   // CHECK:   assign [[NEW_HIVE]] to [[PB_BOX]]
-  // CHECK: } // end sil function '$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfc'
+  // CHECK: } // end sil function '$SSo4HiveC17objc_factory_initE10otherQueenABSo3BeeC_tcfC'
   convenience init(otherQueen other: Bee) {
     self.init(queen: other)
   }
-
-  // CHECK-LABEL: sil hidden @$SSo4HiveC17objc_factory_initE15otherFlakyQueenABSo3BeeC_tKcfC : $@convention(method) (@owned Bee, @thick Hive.Type) -> (@owned Hive, @error Error) {
-  // CHECK: bb0([[QUEEN:%.*]] : @owned $Bee, [[METATYPE:%.*]] : @trivial $@thick Hive.Type):
-  // CHECK:   [[OBJC_METATYPE:%.*]] = thick_to_objc_metatype [[METATYPE]]
-  // CHECK:   [[HIVE:%.*]] = alloc_ref_dynamic [objc] [[OBJC_METATYPE]]
-  // CHECK:   try_apply {{.*}}([[QUEEN]], [[HIVE]]) : $@convention(method) (@owned Bee, @owned Hive) -> (@owned Hive, @error Error), normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
-  //
-  // CHECK: [[NORMAL_BB]]([[HIVE:%.*]] : @owned $Hive):
-  // CHECK:   return [[HIVE]]
-  //
-  // CHECK: [[ERROR_BB]]([[ERROR:%.*]] : @owned $Error):
-  // CHECK:   builtin "willThrow"([[ERROR]] : $Error)
-  // CHECK:   throw [[ERROR]]
-  // CHECK: } // end sil function '$SSo4HiveC17objc_factory_initE15otherFlakyQueenABSo3BeeC_tKcfC'
-  convenience init(otherFlakyQueen other: Bee) throws {
-    try self.init(flakyQueen: other)
-  }
 }
 
 extension SomeClass {
-  // CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC17objc_factory_initE6doubleABSd_tcfc : $@convention(method) (Double, @owned SomeClass) -> @owned SomeClass {
+  // CHECK-LABEL: sil hidden @$SSo12IAMSomeClassC17objc_factory_initE6doubleABSd_tcfC
   // CHECK: bb0([[DOUBLE:%.*]] : @trivial $Double,
   // CHECK-NOT: value_metatype
   // CHECK: [[FNREF:%[0-9]+]] = function_ref @MakeIAMSomeClass
   // CHECK: apply [[FNREF]]([[DOUBLE]])
-  // CHECK: } // end sil function '$SSo12IAMSomeClassC17objc_factory_initE6doubleABSd_tcfc'
   convenience init(double: Double) {
     self.init(value: double)
   }
 }
 
 class SubHive : Hive {
-  // CHECK-LABEL: sil hidden @$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfc : $@convention(method) (@owned SubHive) -> @owned SubHive {
-  // CHECK: bb0([[SUBHIVE:%.*]] : @owned $SubHive):
+  // CHECK-LABEL: sil hidden @$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfC
+  // CHECK: bb0([[METATYPE:%.*]] : @trivial $@thick SubHive.Type):
   // CHECK:   [[SELF_BOX:%.*]] = alloc_box ${ var SubHive }, let, name "self"
   // CHECK:   [[MU:%.*]] = mark_uninitialized [delegatingself] [[SELF_BOX]] : ${ var SubHive }
   // CHECK:   [[PB_BOX:%.*]] = project_box [[MU]] : ${ var SubHive }, 0
-  // CHECK:   store [[SUBHIVE]] to [init] [[PB_BOX]]
-  // CHECK:   [[BORROWED_SELF:%.*]] = load_borrow [[PB_BOX]]
-  // CHECK:   [[UPCAST_BORROWED_SELF:%.*]] = upcast [[BORROWED_SELF]] : $SubHive to $Hive
-  // CHECK:   [[METATYPE:%.*]] = value_metatype $@thick Hive.Type, [[UPCAST_BORROWED_SELF:%.*]]
-  // CHECK:   end_borrow [[BORROWED_SELF]]
-  // CHECK:   [[OBJC_METATYPE:%.*]] = thick_to_objc_metatype [[METATYPE]]
+  // CHECK:   [[UP_METATYPE:%.*]] = upcast [[METATYPE]]
+  // CHECK:   [[OBJC_METATYPE:%.*]] = thick_to_objc_metatype [[UP_METATYPE]]
   // CHECK:   [[QUEEN:%.*]] = unchecked_ref_cast {{.*}} : $Bee to $Optional<Bee>
   // CHECK:   [[HIVE_INIT_FN:%.*]] = objc_method [[OBJC_METATYPE]] : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign
   // CHECK:   apply [[HIVE_INIT_FN]]([[QUEEN]], [[OBJC_METATYPE]]) : $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive>
   // CHECK:   destroy_value [[QUEEN]]
-  // CHECK: } // end sil function '$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfc'
+  // CHECK: } // end sil function '$S17objc_factory_init7SubHiveC20delegatesToInheritedACyt_tcfC'
   convenience init(delegatesToInherited: ()) {
     self.init(queen: Bee())
   }
diff --git a/test/SILGen/objc_init_ref_delegation.swift b/test/SILGen/objc_init_ref_delegation.swift
index 0433622..3ecc07e 100644
--- a/test/SILGen/objc_init_ref_delegation.swift
+++ b/test/SILGen/objc_init_ref_delegation.swift
@@ -3,16 +3,16 @@
 import gizmo
 
 extension Gizmo {
-  // CHECK-LABEL: sil hidden @$SSo5GizmoC24objc_init_ref_delegationE{{[_0-9a-zA-Z]*}}fc
+  // CHECK-LABEL: sil hidden @$SSo5GizmoC24objc_init_ref_delegationE{{[_0-9a-zA-Z]*}}fC
   convenience init(int i: Int) {
-    // CHECK: bb0([[I:%[0-9]+]] : @trivial $Int, [[ORIG_SELF:%[0-9]+]] : @owned $Gizmo):
+    // CHECK: bb0([[I:%[0-9]+]] : @trivial $Int, [[SELF_META:%[0-9]+]] : @trivial $@thick Gizmo.Type):
     // CHECK:   [[SELF_BOX:%[0-9]+]] = alloc_box ${ var Gizmo }
     // CHECK:   [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
     // CHECK:   [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-    // CHECK:   store [[ORIG_SELF]] to [init] [[PB_BOX]] : $*Gizmo
-    // CHECK:   [[SELF:%[0-9]+]] = load [take] [[PB_BOX]] : $*Gizmo
-    // CHECK:   [[INIT_DELEG:%[0-9]+]] = objc_method [[SELF]] : $Gizmo, #Gizmo.init!initializer.1.foreign : (Gizmo.Type) -> (Int) -> Gizmo?, $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
-    // CHECK:   [[SELF_RET:%[0-9]+]] = apply [[INIT_DELEG]]([[I]], [[SELF]]) : $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
+    // CHECK:   [[SELF_OBJC_META:%.*]] = thick_to_objc_metatype [[SELF_META]]
+    // CHECK:   [[ORIG_SELF:%.*]] = alloc_ref_dynamic [objc] [[SELF_OBJC_META]]
+    // CHECK:   [[INIT_DELEG:%[0-9]+]] = objc_method [[ORIG_SELF]] : $Gizmo, #Gizmo.init!initializer.1.foreign : (Gizmo.Type) -> (Int) -> Gizmo?, $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
+    // CHECK:   [[SELF_RET:%[0-9]+]] = apply [[INIT_DELEG]]([[I]], [[ORIG_SELF]]) : $@convention(objc_method) (Int, @owned Gizmo) -> @owned Optional<Gizmo>
     // CHECK:   [[SELF4:%.*]] = load [copy] [[PB_BOX]]
     // CHECK:   destroy_value [[MARKED_SELF_BOX]]
     // CHECK:   return [[SELF4]] : $Gizmo
diff --git a/test/SILGen/objc_required_designated_init.swift b/test/SILGen/objc_required_designated_init.swift
index a3545ee..550990c 100644
--- a/test/SILGen/objc_required_designated_init.swift
+++ b/test/SILGen/objc_required_designated_init.swift
@@ -23,17 +23,21 @@
   @objc dynamic required init() {}
 }
 
+// Because these init() hierarchies are all rooted in overriding
+// -[NSObject init], they're all dynamic whether explicitly declared so or not,
+// so do not appear in the vtable.
+
 // CHECK-LABEL: sil_vtable Baboom {
-// CHECK:   #Boom.init!allocator.1: (Boom.Type) -> () -> Boom : @$S29objc_required_designated_init6BaboomCACycfC [override]
-// CHECK:   #Baboom.deinit!deallocator.1: @$S29objc_required_designated_init6BaboomCfD
+// CHECK-NOT: #Boom.init!allocator.1: (Boom.Type) -> () -> Boom : @$S29objc_required_designated_init6BaboomCACycfC [override]
+// CHECK:     #Baboom.deinit!deallocator.1: @$S29objc_required_designated_init6BaboomCfD
 // CHECK: }
 
 // CHECK-LABEL: sil_vtable BigBadaBoom {
-// CHECK:   #Badaboom.init!allocator.1: <U> (Badaboom<U>.Type) -> () -> Badaboom<U> : @$S29objc_required_designated_init11BigBadaBoomCACyxGycfC [override]
-// CHECK:   #BigBadaBoom.deinit!deallocator.1: @$S29objc_required_designated_init11BigBadaBoomCfD
+// CHECK-NOT: #Badaboom.init!allocator.1
+// CHECK:     #BigBadaBoom.deinit!deallocator.1: @$S29objc_required_designated_init11BigBadaBoomCfD
 // CHECK: }
 
 // CHECK-LABEL: sil_vtable Root {
-// CHECK:   #Root.init!allocator.1: (Root.Type) -> () -> Root : @$S29objc_required_designated_init4RootCACycfC
-// CHECK:   #Root.deinit!deallocator.1: @$S29objc_required_designated_init4RootCfD
+// CHECK-NOT: #Root.init!allocator.1
+// CHECK:     #Root.deinit!deallocator.1: @$S29objc_required_designated_init4RootCfD
 // CHECK: }
diff --git a/test/SILGen/objc_thunks.swift b/test/SILGen/objc_thunks.swift
index ed53c7d..b6fd2f0 100644
--- a/test/SILGen/objc_thunks.swift
+++ b/test/SILGen/objc_thunks.swift
@@ -469,17 +469,9 @@
   // CHECK-LABEL: sil hidden [thunk] @$S11objc_thunks6HoozitC3intACSi_tcfcTo : $@convention(objc_method) (Int, @owned Hoozit) -> @owned Hoozit
   @objc dynamic convenience init(int i: Int) { self.init(bellsOn: i) }
 
-  // CHECK-LABEL: sil hidden @$S11objc_thunks6HoozitC6doubleACSd_tcfc : $@convention(method) (Double, @owned Hoozit) -> @owned Hoozit
+  // CHECK-LABEL: sil hidden @$S11objc_thunks6HoozitC6doubleACSd_tcfC : $@convention(method) (Double, @thick Hoozit.Type) -> @owned Hoozit
   convenience init(double d: Double) { 
-    // CHECK: [[SELF_BOX:%[0-9]+]] = alloc_box ${ var Hoozit }
-    // CHECK: [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
-    // CHECK: [[PB_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-    // CHECK: [[X_BOX:%[0-9]+]] = alloc_box ${ var X }
     var x = X()
-    // CHECK: [[CTOR:%[0-9]+]] = objc_method [[SELF:%[0-9]+]] : $Hoozit, #Hoozit.init!initializer.1.foreign : (Hoozit.Type) -> (Int) -> Hoozit, $@convention(objc_method) (Int, @owned Hoozit) -> @owned Hoozit
-    // CHECK: [[NEW_SELF:%[0-9]+]] = apply [[CTOR]]
-    // CHECK: store [[NEW_SELF]] to [init] [[PB_BOX]] : $*Hoozit
-    // CHECK: return
     self.init(int:Int(d))
     other()
   }
diff --git a/test/SILGen/protocol_extensions.swift b/test/SILGen/protocol_extensions.swift
index dab7418..d4a656a 100644
--- a/test/SILGen/protocol_extensions.swift
+++ b/test/SILGen/protocol_extensions.swift
@@ -823,11 +823,9 @@
     // CHECK:   [[SELF_BOX:%[0-9]+]] = alloc_box $<τ_0_0 where τ_0_0 : ObjCInitClass, τ_0_0 : ProtoDelegatesToObjC> { var τ_0_0 } <Self>
     // CHECK:   [[MARKED_SELF_BOX:%[0-9]+]] = mark_uninitialized [delegatingself] [[SELF_BOX]]
     // CHECK:   [[PB_SELF_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-    // CHECK:   [[SELF_META_OBJC:%[0-9]+]] = thick_to_objc_metatype [[SELF_META]] : $@thick Self.Type to $@objc_metatype Self.Type
-    // CHECK:   [[SELF_ALLOC:%[0-9]+]] = alloc_ref_dynamic [objc] [[SELF_META_OBJC]] : $@objc_metatype Self.Type, $Self
-    // CHECK:   [[SELF_ALLOC_C:%[0-9]+]] = upcast [[SELF_ALLOC]] : $Self to $ObjCInitClass
-    // CHECK:   [[OBJC_INIT:%[0-9]+]] = class_method [[SELF_ALLOC_C]] : $ObjCInitClass, #ObjCInitClass.init!initializer.1 : (ObjCInitClass.Type) -> () -> ObjCInitClass, $@convention(method) (@owned ObjCInitClass) -> @owned ObjCInitClass
-    // CHECK:   [[SELF_RESULT:%[0-9]+]] = apply [[OBJC_INIT]]([[SELF_ALLOC_C]]) : $@convention(method) (@owned ObjCInitClass) -> @owned ObjCInitClass
+    // CHECK:   [[SELF_META_C:%[0-9]+]] = upcast [[SELF_META]] : $@thick Self.Type to $@thick ObjCInitClass.Type
+    // CHECK:   [[OBJC_INIT:%[0-9]+]] = class_method [[SELF_META_C]] : $@thick ObjCInitClass.Type, #ObjCInitClass.init!allocator.1
+    // CHECK:   [[SELF_RESULT:%[0-9]+]] = apply [[OBJC_INIT]]([[SELF_META_C]])
     // CHECK:   [[SELF_RESULT_AS_SELF:%[0-9]+]] = unchecked_ref_cast [[SELF_RESULT]] : $ObjCInitClass to $Self
     // CHECK:   assign [[SELF_RESULT_AS_SELF]] to [[PB_SELF_BOX]] : $*Self
     self.init()
diff --git a/test/SILGen/required_init.swift b/test/SILGen/required_init.swift
index 80e9f75..2ce1570 100644
--- a/test/SILGen/required_init.swift
+++ b/test/SILGen/required_init.swift
@@ -19,8 +19,6 @@
 
 // CHECK-LABEL: sil_vtable Foo {
 // CHECK:         #Foo.init!allocator.1: {{.*}} : @$S13required_init3FooC{{[_0-9a-zA-Z]*}}fC
-// CHECK:         #Foo.init!initializer.1: {{.*}} : @$S13required_init3FooC{{[_0-9a-zA-Z]*}}fc
 
 // CHECK-LABEL: sil_vtable Bar {
 // CHECK:         #Foo.init!allocator.1: {{.*}} : @$S13required_init3BarC{{[_0-9a-zA-Z]*}}fC
-// CHECK:         #Foo.init!initializer.1: {{.*}} : @$S13required_init3BarC{{[_0-9a-zA-Z]*}}fc
diff --git a/test/SILGen/super_init_refcounting.swift b/test/SILGen/super_init_refcounting.swift
index 709a895..9f50635 100644
--- a/test/SILGen/super_init_refcounting.swift
+++ b/test/SILGen/super_init_refcounting.swift
@@ -27,15 +27,13 @@
 }
 
 extension Foo {
-  // CHECK-LABEL: sil hidden @$S22super_init_refcounting3FooC{{[_0-9a-zA-Z]*}}fc
+  // CHECK-LABEL: sil hidden @$S22super_init_refcounting3FooC{{[_0-9a-zA-Z]*}}fC
   // CHECK:         [[SELF_BOX:%.*]] = alloc_box ${ var Foo }
   // CHECK:         [[MARKED_SELF_BOX:%.*]] =  mark_uninitialized [delegatingself] [[SELF_BOX]]
   // CHECK:         [[PB_SELF_BOX:%.*]] = project_box [[MARKED_SELF_BOX]]
-  // CHECK:         [[ORIG_SELF:%.*]] = load [take] [[PB_SELF_BOX]]
-  // CHECK-NOT:     copy_value [[ORIG_SELF]]
-  // CHECK:         [[SUPER_INIT:%.*]] = class_method
-  // CHECK:         [[NEW_SELF:%.*]] = apply [[SUPER_INIT]]([[ORIG_SELF]])
-  // CHECK:         store [[NEW_SELF]] to [init] [[PB_SELF_BOX]]
+  // CHECK:         [[SELF_INIT:%.*]] = class_method
+  // CHECK:         [[NEW_SELF:%.*]] = apply [[SELF_INIT]](%1)
+  // CHECK:         assign [[NEW_SELF]] to [[PB_SELF_BOX]]
   convenience init(x: Int) {
     self.init()
   }
diff --git a/test/SILGen/testable-multifile.swift b/test/SILGen/testable-multifile.swift
index 87af0f8..1d38469 100644
--- a/test/SILGen/testable-multifile.swift
+++ b/test/SILGen/testable-multifile.swift
@@ -40,19 +40,19 @@
 
 // CHECK-LABEL: sil_vtable PrivateSub {
 // CHECK-NEXT:   #Base.foo!1: {{.*}} : @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLC3fooyyF
-// CHECK-NEXT:   #Base.init!initializer.1: {{.*}} : @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLCADycfc
+// CHECK-NEXT:   #Base.init!allocator.1: {{.*}} : @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLCADycfC
 // CHECK-NEXT:   #PrivateSub.deinit!deallocator.1: @$S4main10PrivateSub33_F1525133BD493492AD72BF10FBCB1C52LLCfD
 // CHECK-NEXT: }
 
 // CHECK-LABEL: sil_vtable Sub {
 // CHECK-NEXT:   #Base.foo!1: {{.*}} : @$S4main3SubC3fooyyF
-// CHECK-NEXT:   #Base.init!initializer.1: {{.*}} : @$S4main3SubCACycfc
+// CHECK-NEXT:   #Base.init!allocator.1: {{.*}} : @$S4main3SubCACycfC
 // CHECK-NEXT:   #Sub.deinit!deallocator.1: @$S4main3SubCfD
 // CHECK-NEXT: }
 
 // CHECK-LABEL: sil_vtable [serialized] PublicSub {
 // CHECK-NEXT:   #Base.foo!1: {{.*}} : @$S4main9PublicSubC3fooyyF
-// CHECK-NEXT:   #Base.init!initializer.1: {{.*}} : @$S4main9PublicSubCACycfc
+// CHECK-NEXT:   #Base.init!allocator.1: {{.*}} : @$S4main9PublicSubCACycfC
 // CHECK-NEXT:   #PublicSub.deinit!deallocator.1: @$S4main9PublicSubCfD
 // CHECK-NEXT: }
 
diff --git a/test/SILGen/vtable_thunks_reabstraction.swift b/test/SILGen/vtable_thunks_reabstraction.swift
index f7a6d9e..411d5fb 100644
--- a/test/SILGen/vtable_thunks_reabstraction.swift
+++ b/test/SILGen/vtable_thunks_reabstraction.swift
@@ -173,7 +173,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF      // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF    // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF  // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction6OpaqueCACyxGycfc       // Opaque.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction6OpaqueCACyxGycfC
 // CHECK-NEXT:   #Opaque.deinit!deallocator.1: @$S27vtable_thunks_reabstraction6OpaqueCfD        // Opaque.__deallocating_deinit
 // CHECK-NEXT: }
 
@@ -191,7 +191,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : hidden @$S27vtable_thunks_reabstraction11StillOpaqueC24variantOptionalityTuples1xx_xm_xxcttx_xm_xxcttSg_tFAA0E0CAdeFx_xm_xxctt_tFTV [override] // vtable thunk for Opaque.variantOptionalityTuples(x:) dispatching to StillOpaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11StillOpaqueCACyxGycfc [override]      // StillOpaque.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11StillOpaqueCACyxGycfC [override]
 
 // Tuple becomes more optional -- needs new vtable entry
 
@@ -222,7 +222,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : hidden @$S27vtable_thunks_reabstraction13ConcreteValueC27variantOptionalityMetatypes1xAA1SVmAGmSg_tFAA6OpaqueCAdExmSgxm_tFTV [override]       // vtable thunk for Opaque.variantOptionalityMetatypes(x:) dispatching to ConcreteValue.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : hidden @$S27vtable_thunks_reabstraction13ConcreteValueC27variantOptionalityFunctions1xAA1SVAGcA2GcSg_tFAA6OpaqueCAdExxcSgxxc_tFTV [override]  // vtable thunk for Opaque.variantOptionalityFunctions(x:) dispatching to ConcreteValue.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : hidden @$S27vtable_thunks_reabstraction13ConcreteValueC24variantOptionalityTuples1xAA1SV_AGm_A2GcttAG_AGm_A2GcttSg_tFAA6OpaqueCAdEx_xm_xxcttSgx_xm_xxctt_tFTV [override]       // vtable thunk for Opaque.variantOptionalityTuples(x:) dispatching to ConcreteValue.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteValueCACycfc [override]       // ConcreteValue.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteValueCACycfC [override]
 
 // Value types becoming more optional -- needs new vtable entry
 
@@ -255,7 +255,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction13ConcreteClassC27variantOptionalityMetatypes1xAA1CCmAGmSg_tF [override]      // ConcreteClass.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : hidden @$S27vtable_thunks_reabstraction13ConcreteClassC27variantOptionalityFunctions1xAA1CCAGcA2GcSg_tFAA6OpaqueCAdExxcSgxxc_tFTV [override]  // vtable thunk for Opaque.variantOptionalityFunctions(x:) dispatching to ConcreteClass.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : hidden @$S27vtable_thunks_reabstraction13ConcreteClassC24variantOptionalityTuples1xAA1CC_AGm_A2GcttAG_AGm_A2GcttSg_tFAA6OpaqueCAdEx_xm_xxcttSgx_xm_xxctt_tFTV [override]       // vtable thunk for Opaque.variantOptionalityTuples(x:) dispatching to ConcreteClass.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteClassCACycfc [override]       // ConcreteClass.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteClassCACycfC [override]
 
 // Class references are ABI-compatible with optional class references, and
 // similarly for class metatypes.
@@ -284,7 +284,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassVarianceCACycfc [override]       // ConcreteClassVariance.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassVarianceCACycfC [override]
 
 // No new vtable entries -- class references are ABI compatible with
 // optional class references.
@@ -307,7 +307,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11OpaqueTupleCACyxGycfc [override]      // OpaqueTuple.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction11OpaqueTupleCACyxGycfC [override]
 
 // Optionality change of tuple.
 
@@ -331,7 +331,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteTupleCACycfc [override]       // ConcreteTuple.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction13ConcreteTupleCACycfC [override]
 
 // Optionality change of tuple.
 
@@ -355,7 +355,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueFunctionCACyxq_Gycfc [override] // OpaqueFunction.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueFunctionCACyxq_GycfC [override]
 
 // Optionality change of function.
 
@@ -379,7 +379,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteFunctionCACycfc [override]    // ConcreteFunction.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteFunctionCACycfC [override]
 
 // Optionality change of function.
 
@@ -403,7 +403,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueMetatypeCACyxGycfc [override]   // OpaqueMetatype.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction14OpaqueMetatypeCACyxGycfC [override]
 
 // Optionality change of metatype.
 
@@ -427,7 +427,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteValueMetatypeCACycfc [override]       // ConcreteValueMetatype.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteValueMetatypeCACycfC [override]
 
 // Optionality change of metatype.
 
@@ -451,7 +451,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassMetatypeCACycfc [override]       // ConcreteClassMetatype.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction21ConcreteClassMetatypeCACycfC [override]
 
 // Class metatypes are ABI compatible with optional class metatypes.
 
@@ -475,7 +475,7 @@
 // CHECK-NEXT:   #Opaque.variantOptionalityMetatypes!1: <T> (Opaque<T>) -> (T.Type) -> T.Type? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityMetatypes1xxmSgxm_tF [inherited]  // Opaque.variantOptionalityMetatypes(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityFunctions!1: <T> (Opaque<T>) -> (@escaping (T) -> T) -> ((T) -> T)? : @$S27vtable_thunks_reabstraction6OpaqueC27variantOptionalityFunctions1xxxcSgxxc_tF [inherited]        // Opaque.variantOptionalityFunctions(x:)
 // CHECK-NEXT:   #Opaque.variantOptionalityTuples!1: <T> (Opaque<T>) -> ((T, (T.Type, (T) -> T))) -> (T, (T.Type, (T) -> T))? : @$S27vtable_thunks_reabstraction6OpaqueC24variantOptionalityTuples1xx_xm_xxcttSgx_xm_xxctt_tF [inherited]      // Opaque.variantOptionalityTuples(x:)
-// CHECK-NEXT:   #Opaque.init!initializer.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteOptionalCACycfc [override]    // ConcreteOptional.init()
+// CHECK-NEXT:   #Opaque.init!allocator.1: <T> (Opaque<T>.Type) -> () -> Opaque<T> : @$S27vtable_thunks_reabstraction16ConcreteOptionalCACycfC [override]
 // CHECK-NEXT:   #ConcreteOptional.deinit!deallocator.1: @$S27vtable_thunks_reabstraction16ConcreteOptionalCfD   // ConcreteOptional.__deallocating_deinit
 // CHECK-NEXT: }
 
@@ -488,7 +488,7 @@
 
 // CHECK-LABEL: sil_vtable GenericBase {
 // CHECK-NEXT:   #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : @$S27vtable_thunks_reabstraction11GenericBaseC7doStuff1t1uyx_qd__tlF        // GenericBase.doStuff<A>(t:u:)
-// CHECK-NEXT:   #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction11GenericBaseC1t1uACyxGx_qd__tclufc       // GenericBase.init<A>(t:u:)
+// CHECK-NEXT:   #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction11GenericBaseC1t1uACyxGx_qd__tclufC
 // CHECK-NEXT:   #GenericBase.deinit!deallocator.1: @$S27vtable_thunks_reabstraction11GenericBaseCfD     // GenericBase.__deallocating_deinit
 // CHECK-NEXT: }
 
@@ -503,7 +503,7 @@
 
 // CHECK-LABEL: sil_vtable ConcreteSub {
 // CHECK-NEXT:   #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : hidden @$S27vtable_thunks_reabstraction11ConcreteSubC7doStuff1t1uySi_xtlFAA11GenericBaseCAdeFyx_qd__tlFTV [override]        // vtable thunk for GenericBase.doStuff<A>(t:u:) dispatching to ConcreteSub.doStuff<A>(t:u:)
-// CHECK-NEXT:   #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : hidden @$S27vtable_thunks_reabstraction11ConcreteSubC1t1uACSi_xtclufcAA11GenericBaseCAdeGyxGx_qd__tclufcTV [override]     // vtable thunk for GenericBase.init<A>(t:u:) dispatching to ConcreteSub.init<A>(t:u:)
+// CHECK-NEXT:   #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : hidden @$S27vtable_thunks_reabstraction11ConcreteSubC1t1uACSi_xtclufCAA11GenericBaseCAdeGyxGx_qd__tclufCTV [override]
 // CHECK-NEXT:   #ConcreteSub.deinit!deallocator.1: @$S27vtable_thunks_reabstraction11ConcreteSubCfD     // ConcreteSub.__deallocating_deinit
 // CHECK-NEXT: }
 
@@ -513,7 +513,7 @@
 }
 
 // CHECK-LABEL: sil_vtable ConcreteBase {
-// CHECK-NEXT:   #ConcreteBase.init!initializer.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction12ConcreteBaseC1t1uACSi_xtclufc       // ConcreteBase.init<A>(t:u:)
+// CHECK-NEXT:   #ConcreteBase.init!allocator.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction12ConcreteBaseC1t1uACSi_xtclufC
 // CHECK-NEXT:   #ConcreteBase.doStuff!1: <U> (ConcreteBase) -> (Int, U) -> () : @$S27vtable_thunks_reabstraction12ConcreteBaseC7doStuff1t1uySi_xtlF   // ConcreteBase.doStuff<A>(t:u:)
 // CHECK-NEXT:   #ConcreteBase.deinit!deallocator.1: @$S27vtable_thunks_reabstraction12ConcreteBaseCfD   // ConcreteBase.__deallocating_deinit
 // CHECK-NEXT: }
@@ -528,7 +528,7 @@
 }
 
 // CHECK-LABEL: sil_vtable GenericSub {
-// CHECK-NEXT:   #ConcreteBase.init!initializer.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction10GenericSubC1t1uACyxGSi_qd__tclufc [override]        // GenericSub.init<A>(t:u:)
+// CHECK-NEXT:   #ConcreteBase.init!allocator.1: <U> (ConcreteBase.Type) -> (Int, U) -> ConcreteBase : @$S27vtable_thunks_reabstraction10GenericSubC1t1uACyxGSi_qd__tclufC [override]
 // CHECK-NEXT:   #ConcreteBase.doStuff!1: <U> (ConcreteBase) -> (Int, U) -> () : @$S27vtable_thunks_reabstraction10GenericSubC7doStuff1t1uySi_qd__tlF [override]       // GenericSub.doStuff<A>(t:u:)
 // CHECK-NEXT:   #GenericSub.deinit!deallocator.1: @$S27vtable_thunks_reabstraction10GenericSubCfD       // GenericSub.__deallocating_deinit
 // CHECK-NEXT: }
@@ -542,7 +542,7 @@
 
 // CHECK-LABEL: sil_vtable MoreGenericSub1 {
 // CHECK-NEXT:   #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : @$S27vtable_thunks_reabstraction15MoreGenericSub1C7doStuff1t1uyx_qd__tlF [override] // MoreGenericSub1.doStuff<A>(t:u:)
-// CHECK-NEXT:   #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub1C1t1uACyxq_Gx_qd__tclufc [override] // MoreGenericSub1.init<A>(t:u:)
+// CHECK-NEXT:   #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub1C1t1uACyxq_Gx_qd__tclufC [override]
 // CHECK-NEXT:   #MoreGenericSub1.deinit!deallocator.1: @$S27vtable_thunks_reabstraction15MoreGenericSub1CfD     // MoreGenericSub1.__deallocating_deinit
 // CHECK-NEXT: }
 
@@ -554,6 +554,6 @@
 
 // CHECK-LABEL: sil_vtable MoreGenericSub2 {
 // CHECK-NEXT:   #GenericBase.doStuff!1: <T><U> (GenericBase<T>) -> (T, U) -> () : @$S27vtable_thunks_reabstraction15MoreGenericSub2C7doStuff1t1uyq__qd__tlF [override]        // MoreGenericSub2.doStuff<A>(t:u:)
-// CHECK-NEXT:   #GenericBase.init!initializer.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub2C1t1uACyxq_Gq__qd__tclufc [override] // MoreGenericSub2.init<A>(t:u:)
+// CHECK-NEXT:   #GenericBase.init!allocator.1: <T><U> (GenericBase<T>.Type) -> (T, U) -> GenericBase<T> : @$S27vtable_thunks_reabstraction15MoreGenericSub2C1t1uACyxq_Gq__qd__tclufC [override]
 // CHECK-NEXT:   #MoreGenericSub2.deinit!deallocator.1: @$S27vtable_thunks_reabstraction15MoreGenericSub2CfD     // MoreGenericSub2.__deallocating_deinit
 // CHECK-NEXT: }
diff --git a/test/SILGen/vtables.swift b/test/SILGen/vtables.swift
index d5c978d..08a2f3c 100644
--- a/test/SILGen/vtables.swift
+++ b/test/SILGen/vtables.swift
@@ -21,7 +21,6 @@
 // CHECK:   #A.bas!1: {{.*}} : @$S7vtables1AC3bas{{[_0-9a-zA-Z]*}}F
 // CHECK:   #A.qux!1: {{.*}} : @$S7vtables1CC3qux{{[_0-9a-zA-Z]*}}F
 // CHECK:   #B.init!allocator.1: {{.*}} : @$S7vtables1CC{{[_0-9a-zA-Z]*}}fC
-// CHECK:   #B.init!initializer.1: {{.*}} : @$S7vtables1CC{{[_0-9a-zA-Z]*}}fc
 // CHECK:   #B.zim!1: {{.*}} : @$S7vtables1BC3zim{{[_0-9a-zA-Z]*}}F
 // CHECK:   #B.zang!1: {{.*}} : @$S7vtables1CC4zang{{[_0-9a-zA-Z]*}}F
 // CHECK:   #C.flopsy!1: {{.*}} : @$S7vtables1CC6flopsy{{[_0-9a-zA-Z]*}}F
@@ -40,7 +39,7 @@
 // CHECK:   #A.bar!1: {{.*}} : @$S7vtables1AC3bar{{[_0-9a-zA-Z]*}}F
 // CHECK:   #A.bas!1: {{.*}} : @$S7vtables1AC3bas{{[_0-9a-zA-Z]*}}F
 // CHECK:   #A.qux!1: {{.*}} : @$S7vtables1AC3qux{{[_0-9a-zA-Z]*}}F
-// CHECK:   #A.init!initializer.1: {{.*}} : @$S7vtables1AC{{[_0-9a-zA-Z]*}}fc
+// CHECK:   #A.init!allocator.1: {{.*}} : @$S7vtables1AC{{[_0-9a-zA-Z]*}}fC
 // CHECK: }
 
 class B : A {
@@ -61,14 +60,12 @@
 // CHECK:   #A.bas!1: {{.*}} : @$S7vtables1AC3bas{{[_0-9a-zA-Z]*}}F
 // CHECK:   #A.qux!1: {{.*}} : @$S7vtables1BC3qux{{[_0-9a-zA-Z]*}}F
 // CHECK:   #B.init!allocator.1: {{.*}} : @$S7vtables1BC{{[_0-9a-zA-Z]*}}fC
-// CHECK:   #B.init!initializer.1: {{.*}} : @$S7vtables1BC{{[_0-9a-zA-Z]*}}fc
 // CHECK:   #B.zim!1: {{.*}} : @$S7vtables1BC3zim{{[_0-9a-zA-Z]*}}F
 // CHECK:   #B.zang!1: {{.*}} : @$S7vtables1BC4zang{{[_0-9a-zA-Z]*}}F
 // CHECK: }
 
 // CHECK: sil_vtable RequiredInitDerived {
-// CHECK-NEXT: #SimpleInitBase.init!initializer.1: {{.*}} : @$S7vtables19RequiredInitDerivedC{{[_0-9a-zA-Z]*}}fc
-// CHECK-NEXT: #RequiredInitDerived.init!allocator.1: {{.*}} : @$S7vtables19RequiredInitDerivedC
+// CHECK-NEXT: #SimpleInitBase.init!allocator.1: {{.*}} : @$S7vtables19RequiredInitDerivedC{{[_0-9a-zA-Z]*}}fC
 // CHECK-NEXT: #RequiredInitDerived.deinit!deallocator.1: @$S7vtables19RequiredInitDerivedCfD
 // CHECK-NEXT: }
 
diff --git a/test/SILGen/vtables_objc.swift b/test/SILGen/vtables_objc.swift
index 8d631a0..c166fd4 100644
--- a/test/SILGen/vtables_objc.swift
+++ b/test/SILGen/vtables_objc.swift
@@ -70,10 +70,10 @@
 
 // <rdar://problem/15282548>
 // CHECK: sil_vtable Base {
-// CHECK:   #Base.init!initializer.1: {{.*}} : @$S12vtables_objc4BaseC{{[_0-9a-zA-Z]*}}fc
+// CHECK:   #Base.init!allocator.1: {{.*}} : @$S12vtables_objc4BaseC{{[_0-9a-zA-Z]*}}fC
 // CHECK: }
 // CHECK: sil_vtable Derived {
-// CHECK:   #Base.init!initializer.1: {{.*}} : @$S12vtables_objc7DerivedC{{[_0-9a-zA-Z]*}}fc
+// CHECK:   #Base.init!allocator.1: {{.*}} : @$S12vtables_objc7DerivedC{{[_0-9a-zA-Z]*}}fC
 // CHECK: }
 @objc class Base {}
 
diff --git a/test/SILGen/witness-init-requirement-with-base-class-init.swift b/test/SILGen/witness-init-requirement-with-base-class-init.swift
index 6ef86d0..a768dcc 100644
--- a/test/SILGen/witness-init-requirement-with-base-class-init.swift
+++ b/test/SILGen/witness-init-requirement-with-base-class-init.swift
@@ -36,10 +36,11 @@
 final class Derived : Base, Initable {}
 
 // CHECK-LABEL: sil hidden @$S4main4BaseC1xACSi_tcfC : $@convention(method) (Int, @thick Base.Type) -> @owned Base
-// CHECK:         [[SELF:%.*]] = alloc_ref_dynamic %1 : $@thick Base.Type, $Base
-// CHECK:         [[METHOD:%.*]] = function_ref @$S4main4BaseC1xACSi_tcfc
-// CHECK-NEXT:    [[RESULT:%.*]] = apply [[METHOD]](%0, [[SELF]])
-// CHECK-NEXT:    return [[RESULT]]
+// CHECK:         [[METHOD:%.*]] = class_method [[SELF_META:%.*]] : $@thick Base.Type, #Base.init!allocator.1
+// CHECK-NEXT:    [[RESULT:%.*]] = apply [[METHOD]]([[SELF_META]])
+// CHECK-NEXT:    assign [[RESULT]] to [[BOX:%.*]] :
+// CHECK-NEXT:    [[FINAL:%.*]] = load [copy] [[BOX]]
+// CHECK:         return [[FINAL]]
 
 // CHECK-LABEL: sil private [transparent] [thunk] @$S4main7DerivedCAA8InitableA2aDP1xxSi_tcfCTW : $@convention(witness_method: Initable) (Int, @thick Derived.Type) -> @out Derived
 // CHECK:         [[SELF:%.*]] = upcast %2 : $@thick Derived.Type to $@thick Base.Type
diff --git a/test/SILOptimizer/basic-callee-printer.sil b/test/SILOptimizer/basic-callee-printer.sil
index 598e9fc..fa69df7 100644
--- a/test/SILOptimizer/basic-callee-printer.sil
+++ b/test/SILOptimizer/basic-callee-printer.sil
@@ -637,18 +637,7 @@
   %2 = class_method %0 : $@thick SomeItem.Type, #SomeItem.init!allocator.1 : (SomeItem.Type) -> (InitVal) -> SomeItem, $@convention(method) (InitVal, @thick SomeItem.Type) -> @owned SomeItem
   %3 = apply %2(%1, %0) : $@convention(method) (InitVal, @thick SomeItem.Type) -> @owned SomeItem
 
-// CHECK-LABEL: Function call site:
-// CHECK:   %4 = class_method %3 : $SomeItem, #SomeItem.init!initializer.1 : (SomeItem.Type) -> (InitVal) -> SomeItem, $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
-// CHECK:   %5 = apply %4(%1, %3) : $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
-// CHECK-NOWMO: Incomplete callee list? : Yes
-// CHECK-WMO: Incomplete callee list? : No
-// CHECK: Known callees:
-// CHECK: SomeChildItem_initializer
-// CHECK: SomeItem_initializer
-
-  %4 = class_method %3 : $SomeItem, #SomeItem.init!initializer.1 : (SomeItem.Type) -> (InitVal) -> SomeItem, $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
-  %5 = apply %4(%1, %3) : $@convention(method) (InitVal, @owned SomeItem) -> @owned SomeItem
-  return %5 : $SomeItem
+  return %3 : $SomeItem
 }
 
 sil @SomeItem_allocator : $@convention(method) (InitVal, @thick SomeItem.Type) -> @owned SomeItem
diff --git a/test/SILOptimizer/dead_func_init_method.sil b/test/SILOptimizer/dead_func_init_method.sil
index 302ed54..7d1691a 100644
--- a/test/SILOptimizer/dead_func_init_method.sil
+++ b/test/SILOptimizer/dead_func_init_method.sil
@@ -15,28 +15,28 @@
 private class Derived : Base {
 }
 
-sil private @BaseInit : $@convention(method) (@owned Base) -> @owned Base {
-bb0(%4 : $Base):
-  return %4 : $Base
+sil private @BaseInit : $@convention(method) (@thick Base.Type) -> @owned Base {
+bb0(%4 : $@thick Base.Type):
+  return undef : $Base
 }
 
-sil private @DerivedInit : $@convention(method) (@owned Derived) -> @owned Derived {
-bb0(%4 : $Derived):
-  return %4 : $Derived
+sil private @DerivedInit : $@convention(method) (@thick Derived.Type) -> @owned Derived {
+bb0(%4 : $@thick Derived.Type):
+  return undef : $Derived
 }
 
-sil @testit : $@convention(method) (@owned Derived) -> @owned Derived {
-bb0(%1 : $Derived):
-  %157 = class_method %1 : $Derived, #Derived.init!initializer.1 : (Derived.Type) -> () -> Derived, $@convention(method) (@owned Derived) -> @owned Derived
-  return %1 : $Derived
+sil @testit : $@convention(method) (@thick Derived.Type) -> @thick Derived.Type {
+bb0(%1 : $@thick Derived.Type):
+  %157 = class_method %1 : $@thick Derived.Type, #Derived.init!allocator.1 : (Derived.Type) -> () -> Derived, $@convention(method) (@thick Derived.Type) -> @owned Derived
+  return %1 : $@thick Derived.Type
 }
 
 sil_vtable Base {
-  #Base.init!initializer.1: @BaseInit
+  #Base.init!allocator.1: @BaseInit
 }
 
 sil_vtable Derived {
-  #Base.init!initializer.1: @DerivedInit
+  #Base.init!allocator.1: @DerivedInit
 }
 
 
diff --git a/test/SILOptimizer/definite-init-wrong-scope2.swift b/test/SILOptimizer/definite-init-wrong-scope2.swift
deleted file mode 100644
index 5dec46c..0000000
--- a/test/SILOptimizer/definite-init-wrong-scope2.swift
+++ /dev/null
@@ -1,26 +0,0 @@
-// RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm -sil-print-debuginfo \
-// RUN:   -o /dev/null -Xllvm -sil-print-after=raw-sil-inst-lowering \
-// RUN:   -Xllvm -sil-print-only-functions=$S8patatino4BearC6before7before26during5afterACSb_S3btKcfc \
-// RUN:   2>&1 | %FileCheck %s
-// REQUIRES: executable_test
-
-import StdlibUnittest
-
-func unwrap(_ b: Bool) throws -> Int {
-  return 0
-}
-class Bear {
-  let x: LifetimeTracked
-  init(n: Int, before: Bool) throws {
-    self.x = LifetimeTracked(0)
-  }
-  init(n: Int, after: Bool) throws {
-    self.x = LifetimeTracked(0)
-  }
-  convenience init(before: Bool, before2: Bool, during: Bool, after: Bool) throws {
-    try self.init(n: unwrap(before2), after: during)
-  }
-}
-
-// CHECK: %7 = integer_literal $Builtin.Int1, 0, loc {{.*}}:20:15, scope 1
-// CHECK-NEXT:  store %7 to [trivial] %5 : $*Builtin.Int1, loc {{.*}}:20:15, scope 1
diff --git a/test/SILOptimizer/definite_init_diagnostics.swift b/test/SILOptimizer/definite_init_diagnostics.swift
index 87ce1b3..1c1e287 100644
--- a/test/SILOptimizer/definite_init_diagnostics.swift
+++ b/test/SILOptimizer/definite_init_diagnostics.swift
@@ -432,18 +432,18 @@
   }
   
   convenience init(x: EmptyStruct, y: EmptyStruct) {
-    _ = ivar       // expected-error {{'self' used in property access 'ivar' before 'self.init' call}}
-    ivar = x       // expected-error {{'self' used in property access 'ivar' before 'self.init' call}}
+    _ = ivar       // expected-error {{'self' used before 'self.init' call}}
+    ivar = x       // expected-error {{'self' used before 'self.init' call}}
     self.init()
   }
 
   convenience init(x: EmptyStruct, y: EmptyStruct, z: EmptyStruct) {
     self.init()
-    self.init()    // expected-error {{'self.init' called multiple times in initializer}}
+    self.init()
   }
 
   convenience init(x: (EmptyStruct, EmptyStruct)) {
-    method()       // expected-error {{'self' used in method call 'method' before 'self.init' call}}
+    method()       // expected-error {{'self' used before 'self.init' call}}
     self.init()
   }
 
@@ -1247,8 +1247,8 @@
     super.init(i)
   }
   public init(_ i1: Int, _ i2: Int, _ i3: Int) {
-    self.init(i1, i1)
-  }
+    self.init(i1, i1) // expected-error{{'self' used before 'super.init' call}}
+  } // expected-error{{'super.init' isn't called}}
 }
 
 // While testing some changes I found this regression that wasn't
diff --git a/test/SILOptimizer/definite_init_failable_initializers.swift b/test/SILOptimizer/definite_init_failable_initializers.swift
index 43abc7b..64b0c8d 100644
--- a/test/SILOptimizer/definite_init_failable_initializers.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers.swift
@@ -779,14 +779,11 @@
     return nil
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failBeforeDelegationACSgyt_tcfc
-// CHECK:       bb0(%0 : $FailableBaseClass):
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failBeforeDelegationACSgyt_tcfC
+// CHECK:       bb0(%0 : $@thick FailableBaseClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
-// CHECK:         store %0 to [[SELF_BOX]]
-// CHECK-NEXT:    br bb1
+// CHECK:         br bb1
 // CHECK:       bb1:
-// CHECK-NEXT:    [[METATYPE:%.*]] = value_metatype $@thick FailableBaseClass.Type, %0 : $FailableBaseClass
-// CHECK-NEXT:    dealloc_partial_ref %0 : $FailableBaseClass, [[METATYPE]] : $@thick FailableBaseClass.Type
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    [[RESULT:%.*]] = enum $Optional<FailableBaseClass>, #Optional.none!enumelt
 // CHECK-NEXT:    br bb2
@@ -796,10 +793,9 @@
     return nil
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfc
-// CHECK:       bb0(%0 : $FailableBaseClass):
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC19failAfterDelegationACSgyt_tcfC
+// CHECK:       bb0(%0 : $@thick FailableBaseClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
-// CHECK:         store %0 to [[SELF_BOX]]
 // CHECK:         [[INIT_FN:%.*]] = class_method %0
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0)
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
@@ -816,10 +812,9 @@
     return nil
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfc
-// CHECK:       bb0(%0 : $FailableBaseClass):
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17FailableBaseClassC20failDuringDelegationACSgyt_tcfC
+// CHECK:       bb0(%0 : $@thick FailableBaseClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass
-// CHECK:         store %0 to [[SELF_BOX]]
 // CHECK:         [[INIT_FN:%.*]] = class_method %0
 // CHECK-NEXT:    [[SELF_OPTIONAL:%.*]] = apply [[INIT_FN]](%0)
 // CHECK:         [[COND:%.*]] = select_enum [[SELF_OPTIONAL]]
@@ -1270,14 +1265,13 @@
     try! self.init()
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfc
-// CHECK:       bb0(%0 : $Int, %1 : $ThrowDerivedClass):
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfC
+// CHECK:       bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
-// CHECK:         store %1 to [[SELF_BOX]]
 // CHECK:         [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
 // CHECK-NEXT:    try_apply [[UNWRAP_FN]](%0)
 // CHECK:       bb1([[ARG:%.*]] : $Int):
-// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfc
+// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
 // CHECK-NEXT:    strong_retain [[NEW_SELF]]
@@ -1285,8 +1279,6 @@
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    return [[NEW_SELF]]
 // CHECK:       bb2([[ERROR:%.*]] : $Error):
-// CHECK-NEXT:    [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, %1 : $ThrowDerivedClass
-// CHECK-NEXT:    dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    throw [[ERROR]]
   convenience init(failBeforeDelegation: Int) throws {
@@ -1294,11 +1286,10 @@
     self.init(noFail: ())
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failDuringDelegationACSi_tKcfc
-// CHECK:       bb0(%0 : $Int, %1 : $ThrowDerivedClass):
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC20failDuringDelegationACSi_tKcfC
+// CHECK:       bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
-// CHECK:         store %1 to [[SELF_BOX]]
-// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfc
+// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfC
 // CHECK-NEXT:    try_apply [[INIT_FN]](%1)
 // CHECK:       bb1([[NEW_SELF:%.*]] : $ThrowDerivedClass):
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
@@ -1313,98 +1304,61 @@
     try self.init()
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC28failBeforeOrDuringDelegationACSi_tKcfc
-// CHECK:       bb0(%0 : $Int, %1 : $ThrowDerivedClass):
-// CHECK-NEXT:    [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC28failBeforeOrDuringDelegationACSi_tKcfC
+// CHECK:       bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
-// CHECK:         [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
-// CHECK-NEXT:    store [[ZERO]] to [[BITMAP_BOX]] : $*Builtin.Int1
-// CHECK:         store %1 to [[SELF_BOX]]
 // CHECK:         [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
 // CHECK-NEXT:    try_apply [[UNWRAP_FN]](%0)
 // CHECK:       bb1([[ARG:%.*]] : $Int):
-// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
-// CHECK-NEXT:    store [[BIT]] to [[BITMAP_BOX]]
-// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfc
+// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfC
 // CHECK-NEXT:    try_apply [[INIT_FN]](%1)
 // CHECK:       bb2([[NEW_SELF:%.*]] : $ThrowDerivedClass):
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
 // CHECK-NEXT:    strong_retain [[NEW_SELF]]
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    dealloc_stack [[BITMAP_BOX]]
 // CHECK-NEXT:    return [[NEW_SELF]]
 // CHECK:       bb3([[ERROR1:%.*]] : $Error):
 // CHECK-NEXT:    br bb5([[ERROR1]] : $Error)
 // CHECK:       bb4([[ERROR2:%.*]] : $Error):
 // CHECK-NEXT:    br bb5([[ERROR2]] : $Error)
 // CHECK:       bb5([[ERROR3:%.*]] : $Error):
-// CHECK-NEXT:    [[COND:%.*]] = load [[BITMAP_BOX]]
-// CHECK-NEXT:    cond_br [[COND]], bb6, bb7
-// CHECK:       bb6:
-// CHECK-NEXT:    br bb8
-// CHECK:       bb7:
-// CHECK-NEXT:    [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, %1 : $ThrowDerivedClass
-// CHECK-NEXT:    dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
-// CHECK-NEXT:    br bb8
-// CHECK:       bb8:
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    dealloc_stack [[BITMAP_BOX]]
 // CHECK-NEXT:    throw [[ERROR3]]
   convenience init(failBeforeOrDuringDelegation: Int) throws {
     try unwrap(failBeforeOrDuringDelegation)
     try self.init()
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC29failBeforeOrDuringDelegation2ACSi_tKcfc
-// CHECK:         bb0(%0 : $Int, %1 : $ThrowDerivedClass):
-// CHECK-NEXT:    [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC29failBeforeOrDuringDelegation2ACSi_tKcfC
+// CHECK:         bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
-// CHECK:         [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
-// CHECK-NEXT:    store [[ZERO]] to [[BITMAP_BOX]] : $*Builtin.Int1
-// CHECK:         store %1 to [[SELF_BOX]]
 // CHECK:         [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
 // CHECK-NEXT:    try_apply [[UNWRAP_FN]](%0)
 // CHECK:       bb1([[ARG:%.*]] : $Int):
-// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
-// CHECK-NEXT:    store [[BIT]] to [[BITMAP_BOX]]
-// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfc
+// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC20failBeforeDelegationACSi_tKcfC
 // CHECK-NEXT:    try_apply [[INIT_FN]]([[ARG]], %1)
 // CHECK:       bb2([[NEW_SELF:%.*]] : $ThrowDerivedClass):
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
 // CHECK-NEXT:    strong_retain [[NEW_SELF]]
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    dealloc_stack [[BITMAP_BOX]]
 // CHECK-NEXT:    return [[NEW_SELF]]
 // CHECK:       bb3([[ERROR:%.*]] : $Error):
-// CHECK-NEXT:    store %1 to [[SELF_BOX]]
-// CHECK-NEXT:    br bb5([[ERROR]] : $Error)
-// CHECK:       bb4([[ERROR1:%.*]] : $Error):
 // CHECK-NEXT:    br bb5([[ERROR1]] : $Error)
-// CHECK:       bb5([[ERROR2:%.*]] : $Error):
-// CHECK-NEXT:    [[COND:%.*]] = load [[BITMAP_BOX]]
-// CHECK-NEXT:    cond_br [[COND]], bb6, bb7
-// CHECK:       bb6:
-// CHECK-NEXT:    br bb8
-// CHECK:       bb7:
-// CHECK-NEXT:    [[RELOADED_SELF:%.*]] = load [[SELF_BOX]]
-// CHECK-NEXT:    [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, [[RELOADED_SELF]] : $ThrowDerivedClass
-// CHECK-NEXT:    dealloc_partial_ref [[RELOADED_SELF]] : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
-// CHECK-NEXT:    br bb8
-// CHECK:       bb8:
+// CHECK:       bb4([[ERROR2:%.*]] : $Error):
+// CHECK-NEXT:    br bb5([[ERROR2]] : $Error)
+// CHECK:       bb5([[ERROR3:%.*]] : $Error):
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
-// CHECK-NEXT:    dealloc_stack [[BITMAP_BOX]]
-// CHECK-NEXT:    throw [[ERROR2]]
+// CHECK-NEXT:    throw [[ERROR3]]
   convenience init(failBeforeOrDuringDelegation2: Int) throws {
     try self.init(failBeforeDelegation: unwrap(failBeforeOrDuringDelegation2))
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC19failAfterDelegationACSi_tKcfc
-// CHECK:       bb0(%0 : $Int, %1 : $ThrowDerivedClass):
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC19failAfterDelegationACSi_tKcfC
+// CHECK:       bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
-// CHECK:         store %1 to [[SELF_BOX]]
-// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfc
+// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
 // CHECK:         [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
@@ -1423,19 +1377,16 @@
     try unwrap(failAfterDelegation)
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failDuringOrAfterDelegationACSi_tKcfc
-// CHECK:       bb0(%0 : $Int, %1 : $ThrowDerivedClass):
-// CHECK-NEXT:    [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failDuringOrAfterDelegationACSi_tKcfC
+// CHECK:       bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
+// CHECK:         [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
 // CHECK:         [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
-// CHECK:         [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
+// CHECK:         [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
 // CHECK-NEXT:    store [[ZERO]] to [[BITMAP_BOX]]
-// CHECK:         store %1 to [[SELF_BOX]]
-// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int2, 1
-// CHECK-NEXT:    store [[BIT]] to [[BITMAP_BOX]]
-// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfc
+// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassCACyKcfC
 // CHECK-NEXT:    try_apply [[INIT_FN]](%1)
 // CHECK:       bb1([[NEW_SELF:%.*]] : $ThrowDerivedClass):
-// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int2, -1
+// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
 // CHECK-NEXT:    store [[BIT]] to [[BITMAP_BOX]]
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
 // CHECK:         [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
@@ -1452,14 +1403,11 @@
 // CHECK-NEXT:    br bb5([[ERROR2]] : $Error)
 // CHECK:       bb5([[ERROR3:%.*]] : $Error):
 // CHECK-NEXT:    [[BITMAP:%.*]] = load [[BITMAP_BOX]]
-// CHECK-NEXT:    [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
-// CHECK-NEXT:    [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2)
-// CHECK-NEXT:    [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2)
-// CHECK-NEXT:    cond_br [[COND]], bb6, bb7
+// CHECK:         cond_br {{.*}}, bb7, bb6
 // CHECK:       bb6:
-// CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    br bb8
 // CHECK:       bb7:
+// CHECK-NEXT:    destroy_addr [[SELF_BOX]]
 // CHECK-NEXT:    br bb8
 // CHECK:       bb8:
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
@@ -1470,22 +1418,19 @@
     try unwrap(failDuringOrAfterDelegation)
   }
 
-// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failBeforeOrAfterDelegationACSi_tKcfc
-// CHECK:       bb0(%0 : $Int, %1 : $ThrowDerivedClass):
-// CHECK-NEXT:    [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2
+// CHECK-LABEL: sil hidden @$S35definite_init_failable_initializers17ThrowDerivedClassC27failBeforeOrAfterDelegationACSi_tKcfC
+// CHECK:       bb0(%0 : $Int, %1 : $@thick ThrowDerivedClass.Type):
+// CHECK-NEXT:    [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1
 // CHECK-NEXT:    [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass
-// CHECK-NEXT:    [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
+// CHECK-NEXT:    [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
 // CHECK-NEXT:    store [[ZERO]] to [[BITMAP_BOX]]
-// CHECK:         store %1 to [[SELF_BOX]]
 // CHECK:         [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
 // CHECK-NEXT:    try_apply [[UNWRAP_FN]](%0)
 // CHECK:       bb1([[RESULT:%.*]] : $Int):
-// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int2, -2
-// CHECK-NEXT:    store [[BIT]] to [[BITMAP_BOX]]
-// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int2, -1
-// CHECK-NEXT:    store [[BIT]] to [[BITMAP_BOX]]
-// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfc
+// CHECK:         [[INIT_FN:%.*]] = function_ref @$S35definite_init_failable_initializers17ThrowDerivedClassC6noFailACyt_tcfC
 // CHECK-NEXT:    [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1)
+// CHECK-NEXT:    [[BIT:%.*]] = integer_literal $Builtin.Int1, -1
+// CHECK-NEXT:    store [[BIT]] to [[BITMAP_BOX]]
 // CHECK-NEXT:    store [[NEW_SELF]] to [[SELF_BOX]]
 // CHECK:         [[UNWRAP_FN:%.*]] = function_ref @$S35definite_init_failable_initializers6unwrapyS2iKF
 // CHECK-NEXT:    try_apply [[UNWRAP_FN]](%0)
@@ -1501,27 +1446,13 @@
 // CHECK-NEXT:    br bb5([[ERROR]] : $Error)
 // CHECK:       bb5([[ERROR:%.*]] : $Error):
 // CHECK-NEXT:    [[BITMAP:%.*]] = load [[BITMAP_BOX]]
-// CHECK-NEXT:    [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP]] : $Builtin.Int2) : $Builtin.Int1
-// CHECK-NEXT:    cond_br [[COND]], bb6, bb10
+// CHECK:         cond_br {{.*}}, bb7, bb6
 // CHECK:       bb6:
-// CHECK-NEXT:    [[BITMAP:%.*]] = load [[BITMAP_BOX]]
-// CHECK-NEXT:    [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
-// CHECK-NEXT:    [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2)
-// CHECK-NEXT:    [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2)
-// CHECK-NEXT:    cond_br [[COND]], bb7, bb8
+// CHECK-NEXT:    br bb8
 // CHECK:       bb7:
 // CHECK-NEXT:    destroy_addr [[SELF_BOX]]
-// CHECK-NEXT:    br bb9
+// CHECK-NEXT:    br bb8
 // CHECK:       bb8:
-// CHECK-NEXT:    br bb9
-// CHECK:       bb9:
-// CHECK-NEXT:    br bb11
-// CHECK:       bb10:
-// CHECK-NEXT:    [[OLD_SELF:%.*]] = load [[SELF_BOX]]
-// CHECK-NEXT:    [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, [[OLD_SELF]] : $ThrowDerivedClass
-// CHECK-NEXT:    dealloc_partial_ref [[OLD_SELF]] : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type
-// CHECK-NEXT:    br bb11
-// CHECK:       bb11:
 // CHECK-NEXT:    dealloc_stack [[SELF_BOX]]
 // CHECK-NEXT:    dealloc_stack [[BITMAP_BOX]]
 // CHECK-NEXT:    throw [[ERROR]]
diff --git a/test/SILOptimizer/definite_init_failable_initializers_diagnostics.swift b/test/SILOptimizer/definite_init_failable_initializers_diagnostics.swift
index a630d08..22c8924 100644
--- a/test/SILOptimizer/definite_init_failable_initializers_diagnostics.swift
+++ b/test/SILOptimizer/definite_init_failable_initializers_diagnostics.swift
@@ -28,7 +28,7 @@
 
 // <rdar://problem/22946400> DI needs to diagnose self usages in error block
 //
-// FIXME: crappy QoI
+// FIXME: bad QoI
 class ErrantBaseClass {
   init() throws {}
 }
@@ -87,13 +87,13 @@
     do {
       try self.init()
     } catch {}
-  } // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
+  } // expected-error {{'self.init' isn't called on all paths}}
 
-  convenience init(invalidEscapeConvenience2: ()) throws {
+  convenience init(okEscapeConvenience2: ()) throws {
     do {
       try self.init()
     } catch {
-      try self.init() // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
+      try self.init()
     }
   }
 
@@ -101,7 +101,7 @@
     do {
       try self.init()
     } catch let e {
-      print(self) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
+      print(self) // expected-error {{'self' used before 'self.init'}}
       throw e
     }
   }
@@ -128,18 +128,17 @@
     do {
       try self.init()
     } catch let e {
-      something(x) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
-      something(self.x) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
+      something(x) // expected-error {{'self' used before 'self.init'}}
+      something(self.x) // expected-error {{'self' used before 'self.init'}}
 
-      something(y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
-      something(self.y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
+      something(y) // expected-error {{'self' used before 'self.init'}}
+      something(self.y) // expected-error {{'self' used before 'self.init'}}
 
-      something(&y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
-      something(&self.y) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
+      something(&y) // expected-error {{'self' used before 'self.init'}}
+      something(&self.y) // expected-error {{'self' used before 'self.init'}}
 
-      something(self) // expected-error {{'self' used inside 'catch' block reachable from self.init call}}
+      something(self) // expected-error {{'self' used before 'self.init'}}
 
-      // FIXME: not diagnosed
       something(type(of: self))
 
       throw e
diff --git a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
index f767856..2dc4794 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
@@ -77,75 +77,6 @@
   return %13 : $()
 }
 
-// CHECK-LABEL: sil @test_delegating_box_release
-// CHECK: bb0([[ARG:%.*]] : @owned $RootClassWithNontrivialStoredProperties):
-// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
-// CHECK-NEXT: [[PB:%[0-9]+]] = project_box [[SELFBOX]]
-// CHECK-NEXT: store [[ARG]] to [init] [[PB]]
-// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[PB]]
-// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick RootClassWithNontrivialStoredProperties.Type, [[SELF]] : $RootClassWithNontrivialStoredProperties
-// CHECK-NEXT: dealloc_partial_ref [[SELF]] : $RootClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick RootClassWithNontrivialStoredProperties.Type
-// CHECK-NEXT: dealloc_box [[SELFBOX]]
-sil @test_delegating_box_release : $@convention(method) (@owned RootClassWithNontrivialStoredProperties) -> () {
-bb0(%0 : @owned $RootClassWithNontrivialStoredProperties):
-  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
-  %2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>, 0
-  %4 = mark_uninitialized [delegatingself] %2a : $*RootClassWithNontrivialStoredProperties
-  store %0 to [init] %4 : $*RootClassWithNontrivialStoredProperties
-  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
-
-  %13 = tuple ()
-  return %13 : $()
-}
-
-
-// CHECK-LABEL: sil @test_delegating_rvalue_release
-// CHECK: bb0([[ARG:%.*]] : @owned $RootClassWithNontrivialStoredProperties):
-// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
-// CHECK-NEXT: [[PB:%[0-9]+]] = project_box [[SELFBOX]]
-// CHECK-NEXT: store [[ARG]] to [init] [[PB]]
-// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[PB]]
-// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick RootClassWithNontrivialStoredProperties.Type, [[SELF]] : $RootClassWithNontrivialStoredProperties
-// CHECK-NEXT: dealloc_partial_ref [[SELF]] : $RootClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick RootClassWithNontrivialStoredProperties.Type
-// CHECK-NEXT: [[SELF2:%[0-9]+]] = load [take] [[PB]]
-// CHECK-NEXT: [[METATYPE2:%[0-9]+]] = value_metatype $@thick RootClassWithNontrivialStoredProperties.Type, [[SELF2]] : $RootClassWithNontrivialStoredProperties
-// CHECK-NEXT: dealloc_partial_ref [[SELF2]] : $RootClassWithNontrivialStoredProperties, [[METATYPE2]] : $@thick RootClassWithNontrivialStoredProperties.Type
-// CHECK-NEXT: dealloc_box [[SELFBOX]]
-sil @test_delegating_rvalue_release : $@convention(method) (@owned RootClassWithNontrivialStoredProperties) -> () {
-bb0(%0 : @owned $RootClassWithNontrivialStoredProperties):
-  %2 = alloc_box $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
-  %2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>, 0
-  %4 = mark_uninitialized [delegatingself] %2a : $*RootClassWithNontrivialStoredProperties
-  store %0 to [init] %4 : $*RootClassWithNontrivialStoredProperties
-  %6 = load [take] %4 : $*RootClassWithNontrivialStoredProperties
-  destroy_value %6 : $RootClassWithNontrivialStoredProperties
-  destroy_value %2 : $<τ_0_0> { var τ_0_0 } <RootClassWithNontrivialStoredProperties>
-
-  %13 = tuple ()
-  return %13 : $()
-}
-
-// CHECK-LABEL: sil @test_delegating_derived_release
-// CHECK: bb0([[ARG:%.*]] : @owned $DerivedClassWithNontrivialStoredProperties):
-// CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_stack $DerivedClassWithNontrivialStoredProperties
-// CHECK-NEXT: store [[ARG]] to [init] [[SELFBOX]]
-// CHECK-NEXT: [[SELF:%[0-9]+]] = load [take] [[SELFBOX]]
-// CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick DerivedClassWithNontrivialStoredProperties.Type, [[SELF]] : $DerivedClassWithNontrivialStoredProperties
-// CHECK-NEXT: dealloc_partial_ref [[SELF]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type
-// CHECK-NEXT: dealloc_stack [[SELFBOX]]
-sil @test_delegating_derived_release : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () {
-bb0(%0 : @owned $DerivedClassWithNontrivialStoredProperties):
-  %2 = alloc_stack $DerivedClassWithNontrivialStoredProperties
-  %4 = mark_uninitialized [delegatingself] %2 : $*DerivedClassWithNontrivialStoredProperties
-  store %0 to [init] %4 : $*DerivedClassWithNontrivialStoredProperties
-
-  destroy_addr %4 : $*DerivedClassWithNontrivialStoredProperties
-  dealloc_stack %2 : $*DerivedClassWithNontrivialStoredProperties
-
-  %13 = tuple ()
-  return %13 : $()
-}
-
 // <rdar://problem/20608881> DI miscompiles this testcase into a memory leak
 struct MyStruct3 {
   @sil_stored var c: C
@@ -201,74 +132,3 @@
 class MyClass3 {
 }
 sil @selfinit_myclass3 : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
-
-// CHECK-LABEL: sil hidden @test_conditional_destroy_class_delegating_init
-sil hidden @test_conditional_destroy_class_delegating_init : $@convention(thin) (Builtin.Int1, @owned MyClass3) -> () {
-bb0(%0 : @trivial $Builtin.Int1, %1 : @owned $MyClass3):
-// CHECK:  [[CONTROL:%[0-9]+]] = alloc_stack $Builtin.Int2
-// CHECK-NEXT: [[SELF_BOX:%[0-9]+]] = alloc_stack $MyClass3
-
-  %2 = alloc_stack $MyClass3
-  %3 = mark_uninitialized [delegatingself] %2 : $*MyClass3
-  store %1 to [init] %3 : $*MyClass3
-
-// CHECK:  cond_br %0, [[SUCCESS:bb[0-9]+]], [[EXIT:bb[0-9]+]]
-  cond_br %0, bb1, bb2
-
-// CHECK: [[SUCCESS]]:
-bb1:
-  %4 = load [take] %3 : $*MyClass3
-  %5 = function_ref @selfinit_myclass3 : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
-  %6 = apply %5(%4) : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
-  store %6 to [init] %3 : $*MyClass3
-
-// CHECK:       [[SET:%[0-9]+]] = integer_literal $Builtin.Int2, -2
-// CHECK-NEXT:  [[OLD:%.*]] = load [trivial] [[CONTROL]]
-// CHECK-NEXT:  [[UPDATE:%.*]] = builtin "or_Int2"([[OLD]] : $Builtin.Int2, [[SET]] : $Builtin.Int2)
-// CHECK-NEXT:  store [[UPDATE]] to [trivial] [[CONTROL]] : $*Builtin.Int2
-
-// CHECK:       [[SET:%[0-9]+]] = integer_literal $Builtin.Int2, 1
-// CHECK-NEXT:  [[OLD:%.*]] = load [trivial] [[CONTROL]]
-// CHECK-NEXT:  [[UPDATE:%.*]] = builtin "or_Int2"([[OLD]] : $Builtin.Int2, [[SET]] : $Builtin.Int2)
-// CHECK-NEXT:  store [[UPDATE]] to [trivial] [[CONTROL]] : $*Builtin.Int2
-
-// CHECK: [[NEW_SELF:%[0-9]+]] = apply {{.*}}({{.*}})  : $@convention(thin) (@owned MyClass3) -> @owned MyClass3
-// CHECK-NEXT:  store [[NEW_SELF]] to [init] [[SELF_BOX]] : $*MyClass3
-
-// CHECK-NEXT:  br [[CHECK:bb[0-9]+]]
-  br bb2
-
-// CHECK: [[CHECK]]:
-bb2:
-
-// CHECK-NEXT:  [[BIT:%.*]] = load [trivial] [[CONTROL]]
-// CHECK-NEXT:  [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BIT]] : $Builtin.Int2) : $Builtin.Int1
-// CHECK-NEXT:  cond_br [[COND]], [[PARTIAL:bb[0-9]+]], [[UNINITIALIZED:bb[0-9]+]]
-
-// CHECK: [[PARTIAL]]:
-// CHECK-NEXT:  [[BIT:%.*]] = load [trivial] [[CONTROL]]
-// CHECK-NEXT:  [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
-// CHECK-NEXT:  [[SHIFTED:%.*]] = builtin "lshr_Int2"([[BIT]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) : $Builtin.Int2
-// CHECK-NEXT:  [[COND:%.*]] = builtin "trunc_Int2_Int1"([[SHIFTED]] : $Builtin.Int2) : $Builtin.Int1
-// CHECK-NEXT:  cond_br [[COND]], [[INITIALIZED:bb[0-9]+]], [[CONSUMED:bb[0-9]+]]
-
-// CHECK: [[INITIALIZED]]:
-// CHECK-NEXT:  destroy_addr [[SELF_BOX]] : $*MyClass3
-// CHECK-NEXT:  br [[EXIT:bb[0-9]+]]
-
-// CHECK: [[CONSUMED]]:
-// CHECK-NEXT:  br [[EXIT]]
-
-// CHECK: [[UNINITIALIZED]]:
-// CHECK-NEXT:  [[OLD_SELF:%[0-9]+]] = load [take] [[SELF_BOX]] : $*MyClass3
-// CHECK-NEXT:  [[METATYPE:%[0-9]+]] = value_metatype $@thick MyClass3.Type, [[OLD_SELF]] : $MyClass3
-// CHECK-NEXT:  dealloc_partial_ref [[OLD_SELF]] : $MyClass3, [[METATYPE]] : $@thick MyClass3.Type
-// CHECK-NEXT:  br [[EXIT:bb[0-9]+]]
-
-// CHECK: [[EXIT]]:
-
-  destroy_addr %3 : $*MyClass3
-  dealloc_stack %2 : $*MyClass3
-  %7 = tuple ()
-  return %7 : $()
-}
diff --git a/test/SILOptimizer/definite_init_objc_factory_init.swift b/test/SILOptimizer/definite_init_objc_factory_init.swift
index 999978b..cdf9890 100644
--- a/test/SILOptimizer/definite_init_objc_factory_init.swift
+++ b/test/SILOptimizer/definite_init_objc_factory_init.swift
@@ -17,21 +17,14 @@
 }
 
 extension Hive {
-  // FIXME: This whole approach is wrong. This should be a factory
-  // initializer, not a convenience initializer, which means it does
-  // not have an initializing entry point at all.
-
-  // CHECK-LABEL: sil hidden @$SSo4HiveC027definite_init_objc_factory_C0E10otherQueenABSo3BeeC_tcfc : $@convention(method) (@owned Bee, @owned Hive) -> @owned Hive
+  // CHECK-LABEL: sil hidden @$SSo4HiveC027definite_init_objc_factory_C0E10otherQueenABSo3BeeC_tcfC
   convenience init(otherQueen other: Bee) {
+    // CHECK: bb0({{.*}}, [[META:%.*]] : $@thick Hive.Type)
     // CHECK: [[SELF_ADDR:%[0-9]+]] = alloc_stack $Hive
-    // CHECK: store [[OLD_SELF:%[0-9]+]] to [[SELF_ADDR]]
-    // CHECK: [[META:%[0-9]+]] = value_metatype $@thick Hive.Type, [[OLD_SELF]] : $Hive
     // CHECK: [[OBJC_META:%[0-9]+]] = thick_to_objc_metatype [[META]] : $@thick Hive.Type to $@objc_metatype Hive.Type
     // CHECK: [[FACTORY:%[0-9]+]] = objc_method [[OBJC_META]] : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign : (Hive.Type) -> (Bee?) -> Hive?, $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive>
     // CHECK: apply [[FACTORY]]([[QUEEN:%[0-9]+]], [[OBJC_META]]) : $@convention(objc_method) (Optional<Bee>, @objc_metatype Hive.Type) -> @autoreleased Optional<Hive>
     // CHECK: store [[NEW_SELF:%[0-9]+]] to [[SELF_ADDR]]
-    // CHECK: [[METATYPE:%.*]] = value_metatype $@thick Hive.Type, [[OLD_SELF]] : $Hive
-    // CHECK: dealloc_partial_ref [[OLD_SELF]] : $Hive, [[METATYPE]] : $@thick Hive.Type
     // CHECK: dealloc_stack [[SELF_ADDR]]
     // CHECK: return [[NEW_SELF]]
     self.init(queen: other)
@@ -54,17 +47,14 @@
 }
 
 class SubHive : Hive {
-  // CHECK-LABEL: sil hidden @$S027definite_init_objc_factory_B07SubHiveC20delegatesToInheritedACyt_tcfc : $@convention(method) (@owned SubHive) -> @owned SubHive
+  // CHECK-LABEL: sil hidden @$S027definite_init_objc_factory_B07SubHiveC20delegatesToInheritedACyt_tcfC
   convenience init(delegatesToInherited: ()) {
-    // CHECK: [[UPCAST:%.*]] = upcast %0 : $SubHive to $Hive
-    // CHECK: [[METATYPE:%.*]] = value_metatype $@thick Hive.Type, [[UPCAST]] : $Hive
-    // CHECK: [[OBJC:%.*]] = thick_to_objc_metatype [[METATYPE]] : $@thick Hive.Type to $@objc_metatype Hive.Type
+    // CHECK: bb0([[METATYPE:%.*]] : $@thick SubHive.Type)
+    // CHECK: [[UPMETA:%.*]] = upcast [[METATYPE]]
+    // CHECK: [[OBJC:%.*]] = thick_to_objc_metatype [[UPMETA]] : $@thick Hive.Type to $@objc_metatype Hive.Type
     // CHECK: [[METHOD:%.*]] = objc_method [[OBJC]] : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign : (Hive.Type) -> (Bee?) -> Hive?
     // CHECK: apply [[METHOD]]({{.*}}, [[OBJC]])
 
-    // CHECK: [[METATYPE:%.*]] = value_metatype $@thick SubHive.Type, %0 : $SubHive
-    // CHECK-NEXT: dealloc_partial_ref %0 : $SubHive, [[METATYPE]] : $@thick SubHive.Type
-
     // CHECK: return {{%.*}} : $SubHive
     self.init(queen: Bee())
   }
diff --git a/test/SILOptimizer/definite_init_protocol_init.swift b/test/SILOptimizer/definite_init_protocol_init.swift
index f2c19e9..13efd29 100644
--- a/test/SILOptimizer/definite_init_protocol_init.swift
+++ b/test/SILOptimizer/definite_init_protocol_init.swift
@@ -25,20 +25,17 @@
 class TrivialClass : TriviallyConstructible {
   required init(lower: Int) {}
 
-  // CHECK-LABEL: sil hidden @$S023definite_init_protocol_B012TrivialClassC5upperACSi_tcfc
-  // CHECK:     bb0(%0 : $Int, [[OLD_SELF:%.*]] : $TrivialClass):
+  // CHECK-LABEL: sil hidden @$S023definite_init_protocol_B012TrivialClassC5upperACSi_tcfC
+  // CHECK:     bb0(%0 : $Int, [[SELF_META:%.*]] : $@thick TrivialClass.Type):
   // CHECK-NEXT:  [[SELF_BOX:%.*]] = alloc_stack $TrivialClass
   // CHECK-NEXT:  debug_value
-  // CHECK-NEXT:  store [[OLD_SELF]] to [[SELF_BOX]]
-  // CHECK-NEXT:  [[METATYPE:%.*]] = value_metatype $@thick @dynamic_self TrivialClass.Type, %1
+  // CHECK-NEXT:  [[METATYPE:%.*]] = unchecked_trivial_bit_cast [[SELF_META]] {{.*}} to $@thick @dynamic_self TrivialClass.Type
   // CHECK-NEXT:  [[RESULT:%.*]] = alloc_stack $TrivialClass
   // CHECK-NEXT:  // function_ref
   // CHECK-NEXT:  [[FN:%.*]] = function_ref @$S023definite_init_protocol_B022TriviallyConstructiblePAAE6middlexSi_tcfC
   // CHECK-NEXT:  apply [[FN]]<@dynamic_self TrivialClass>([[RESULT]], %0, [[METATYPE]])
   // CHECK-NEXT:  [[NEW_SELF:%.*]] = load [[RESULT]]
   // CHECK-NEXT:  store [[NEW_SELF]] to [[SELF_BOX]]
-  // CHECK-NEXT:  [[METATYPE:%.*]] = value_metatype $@thick TrivialClass.Type, %1
-  // CHECK-NEXT:  dealloc_partial_ref %1 : $TrivialClass, [[METATYPE]] : $@thick TrivialClass.Type
   // CHECK-NEXT:  dealloc_stack [[RESULT]]
   // TODO: Once we restore arbitrary takes, the strong_retain/destroy_addr pair below will go away.
   // CHECK-NEXT:  strong_retain [[NEW_SELF]]
diff --git a/test/SILOptimizer/definite_init_type_of_self_in_convenience_init.swift b/test/SILOptimizer/definite_init_type_of_self_in_convenience_init.swift
new file mode 100644
index 0000000..d6d3ab4
--- /dev/null
+++ b/test/SILOptimizer/definite_init_type_of_self_in_convenience_init.swift
@@ -0,0 +1,40 @@
+// RUN: %target-swift-emit-sil -verify %s
+
+// Integration test to ensure that `type(of: self)` keeps working in
+// class convenience initializers, even though they are now implemented as
+// allocating entry points.
+
+class C {
+  init() { }
+  init(throwingDesignated: ()) throws {}
+
+  convenience init(normal: ()) {
+    _ = (type(of: self), type(of: self))
+    self.init()
+    _ = (type(of: self), type(of: self))
+  }
+
+  convenience init(throwing: ()) throws {
+    do {
+      _ = (type(of: self), type(of: self))
+      try self.init(throwingDesignated: ())
+      _ = (type(of: self), type(of: self))
+    } catch {
+      _ = (type(of: self), type(of: self))
+      throw error
+    }
+    _ = (type(of: self), type(of: self))
+  }
+
+  convenience init?(optional: Bool) {
+    _ = (type(of: self), type(of: self))
+    if optional {
+      _ = (type(of: self), type(of: self))
+      self.init()
+    } else {
+      _ = (type(of: self), type(of: self))
+      return nil
+    }
+    _ = (type(of: self), type(of: self))
+  }
+}
diff --git a/test/SILOptimizer/devirt_covariant_return.swift b/test/SILOptimizer/devirt_covariant_return.swift
index 360761a..22de945 100644
--- a/test/SILOptimizer/devirt_covariant_return.swift
+++ b/test/SILOptimizer/devirt_covariant_return.swift
@@ -109,9 +109,9 @@
 
   // Check that devirtualizer can handle convenience initializers, which have covariant optional
   // return types.
-  // CHECK-LABEL: sil @$S23devirt_covariant_return4BearC{{[_0-9a-zA-Z]*}}fc
-  // CHECK: checked_cast_br [exact] %{{.*}} : $Bear to $PolarBear
-  // CHECK: upcast %{{.*}} : $Optional<PolarBear> to $Optional<Bear>
+  // CHECK-LABEL: sil @$S23devirt_covariant_return4BearC{{[_0-9a-zA-Z]*}}fC
+  // CHECK: checked_cast_br [exact] %{{.*}} : $@thick Bear.Type to $@thick GummyBear.Type
+  // CHECK: upcast %{{.*}} : $Optional<GummyBear> to $Optional<Bear>
   // CHECK: }
   public convenience init?(delegateFailure: Bool, failAfter: Bool) {
     self.init(fail: delegateFailure)
@@ -119,7 +119,7 @@
   }
 }
 
-final class PolarBear: Bear {
+final class GummyBear: Bear {
 
   override init?(fail: Bool) {
     super.init(fail: fail)
diff --git a/test/SILOptimizer/mandatory_inlining_devirt.swift b/test/SILOptimizer/mandatory_inlining_devirt.swift
index cb108b9..6918d4f 100644
--- a/test/SILOptimizer/mandatory_inlining_devirt.swift
+++ b/test/SILOptimizer/mandatory_inlining_devirt.swift
@@ -5,8 +5,8 @@
 // the constructor itself is not "open".
 
 open class OpenClass {
-  // CHECK-LABEL: sil @$S4test9OpenClassC1xACSi_tcfc : $@convention(method) (Int, @owned OpenClass) -> @owned OpenClass
-  // CHECK: [[M:%[0-9]+]] = class_method %1 : $OpenClass, #OpenClass.init!initializer.1 : (OpenClass.Type) -> (Int, Int) -> OpenClass
+  // CHECK-LABEL: sil @$S4test9OpenClassC1xACSi_tcfC
+  // CHECK: [[M:%[0-9]+]] = class_method %1 : $@thick OpenClass.Type, #OpenClass.init!allocator.1
   // CHECK: apply [[M]]
   // CHECK: return
   public convenience init(x: Int) {
@@ -19,8 +19,8 @@
 // Static dispatch for not-open class (we are compiling with -wmo).
 
 public class PublicClass {
-  // CHECK-LABEL: sil @$S4test11PublicClassC1xACSi_tcfc : $@convention(method) (Int, @owned PublicClass) -> @owned PublicClass
-  // CHECK: [[M:%[0-9]+]] = function_ref @$S4test11PublicClassC1x1yACSi_Sitcfc : $@convention(method) (Int, Int, @owned PublicClass) -> @owned PublicClass
+  // CHECK-LABEL: sil @$S4test11PublicClassC1xACSi_tcfC
+  // CHECK: [[M:%[0-9]+]] = function_ref @$S4test11PublicClassC1x1yACSi_SitcfC
   // CHECK: apply [[M]]
   // CHECK: return
   public convenience init(x: Int) {
diff --git a/test/Serialization/Recovery/typedefs.swift b/test/Serialization/Recovery/typedefs.swift
index ca60dab..0bb3879 100644
--- a/test/Serialization/Recovery/typedefs.swift
+++ b/test/Serialization/Recovery/typedefs.swift
@@ -35,7 +35,7 @@
   // for the vtable slot for 'lastMethod()'. If the layout here
   // changes, please check that offset is still correct.
   // CHECK-IR-NOT: ret
-  // CHECK-IR: getelementptr inbounds void (%T3Lib4UserC*)*, void (%T3Lib4UserC*)** %{{[0-9]+}}, {{i64 30|i32 33}}
+  // CHECK-IR: getelementptr inbounds void (%T3Lib4UserC*)*, void (%T3Lib4UserC*)** %{{[0-9]+}}, {{i64 26|i32 29}}
   _ = user.lastMethod()
 } // CHECK-IR: ret void
 
@@ -180,15 +180,11 @@
 // 19 CHECK-VTABLE-NEXT: #User.constrainedWrapped!1:
 // 20 CHECK-VTABLE-NEXT: #User.subscript!getter.1:
 // 21 CHECK-VTABLE-NEXT: #User.subscript!getter.1:
-// 22 CHECK-VTABLE-NEXT: #User.init!initializer.1:
-// 23 CHECK-VTABLE-NEXT: #User.init!initializer.1:
-// 24 CHECK-VTABLE-NEXT: #User.init!initializer.1:
-// 25 CHECK-VTABLE-NEXT: #User.init!initializer.1:
-// 26 CHECK-VTABLE-NEXT: #User.init!allocator.1:
-// 27 CHECK-VTABLE-NEXT: #User.init!initializer.1:
-// 28 CHECK-VTABLE-NEXT: #User.init!initializer.1:
-// 29 CHECK-VTABLE-NEXT: #User.init!allocator.1:
-// 30 CHECK-VTABLE-NEXT: #User.lastMethod!1:
+// 22 CHECK-VTABLE-NEXT: #User.init!allocator.1:
+// 23 CHECK-VTABLE-NEXT: #User.init!allocator.1:
+// 24 CHECK-VTABLE-NEXT: #User.init!allocator.1:
+// 25 CHECK-VTABLE-NEXT: #User.init!allocator.1:
+// 26 CHECK-VTABLE-NEXT: #User.lastMethod!1:
 // CHECK-VTABLE: }
 
 
diff --git a/test/attr/attr_availability.swift b/test/attr/attr_availability.swift
index 165e103..b7972a8 100644
--- a/test/attr/attr_availability.swift
+++ b/test/attr/attr_availability.swift
@@ -1028,3 +1028,24 @@
     other[alsoUnavailable: 0] += 1 // expected-error {{'subscript(alsoUnavailable:)' is unavailable: bad subscript!}} {{none}}
   }
 }
+
+class BaseDeprecatedInit {
+  @available(*, deprecated) init(bad: Int) { }
+}
+
+class SubInheritedDeprecatedInit: BaseDeprecatedInit { }
+
+_ = SubInheritedDeprecatedInit(bad: 0) // expected-warning {{'init(bad:)' is deprecated}}
+
+// Should produce no warnings.
+enum SR8634_Enum: Int {
+  case a
+  @available(*, deprecated, message: "I must not be raised in synthesized code")
+  case b
+  case c
+}
+
+struct SR8634_Struct: Equatable {
+  @available(*, deprecated, message: "I must not be raised in synthesized code", renamed: "x")
+  let a: Int
+}
diff --git a/test/decl/protocol/special/coding/class_codable_inherited.swift b/test/decl/protocol/special/coding/class_codable_inherited.swift
index c19d32c..ba5de59 100644
--- a/test/decl/protocol/special/coding/class_codable_inherited.swift
+++ b/test/decl/protocol/special/coding/class_codable_inherited.swift
@@ -13,13 +13,11 @@
 }
 
 // CHECK-LABEL: sil_vtable SR8083_Base {
-// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseCACycfc	// SR8083_Base.init()
+// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseCACycfC
 // CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfC
-// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited11SR8083_BaseC4fromACs7Decoder_p_tKcfc	// SR8083_Base.init(from:)
 // CHECK: {{^}$}}
 
 // CHECK-LABEL: sil_vtable SR8083_Sub {
-// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubCACycfc [override]	// SR8083_Sub.init()
+// CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> () -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubCACycfC [override]
 // CHECK-DAG: #SR8083_Base.init!allocator.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfC [override]	// SR8083_Sub.__allocating_init(from:)
-// CHECK-DAG: #SR8083_Base.init!initializer.1: (SR8083_Base.Type) -> (Decoder) throws -> SR8083_Base : @$S23class_codable_inherited10SR8083_SubC4fromACs7Decoder_p_tKcfc [override]	// SR8083_Sub.init(from:)
 // CHECK: {{^}$}}