Merge pull request #13236 from troughton/windows-toolchain-pr

[driver] Implement a Windows toolchain for cross-compiling
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000..56edf36
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,134 @@
+Adrian-Constantin Popescu <epsilon.gamma@gmail.com> <adrian-constantin.popescu@outlook.com>
+Alex Blewitt <alblue@apple.com> <alex.blewitt@gmail.com>
+Alex Hoppen <alex@alexhoppen.de> <alex@ateamer.de>
+Alexis Beingessner <abeingessner@apple.com> <a.beingessner@gmail.com>
+Alper Çugun <github@alper.nl> <alper@users.noreply.github.com>
+Amr Aboelela <amraboelela@gmail.com> <amraboelela@users.noreply.github.com>
+Ankit Aggarwal <ankit_aggarwal@apple.com> <ankit.spd@gmail.com>
+Argyrios Kyrtzidis <kyrtzidis@apple.com> <akyrtzi@gmail.com>
+Arsen Gasparyan <to.arsen.gasparyan@gmail.com> <frootloops@users.noreply.github.com>
+Ben Cohen <ben_cohen@apple.com>
+Ben Cohen <ben_cohen@apple.com> <airspeedswift@users.noreply.github.com>
+Ben Cohen <ben_cohen@apple.com> <ben@airspeedvelocity.net>
+Ben Langmuir <blangmuir@apple.com> <ben.langmuir@gmail.com>
+Brent Royal-Gordon <brent@brentdax.com> <brent@architechies.com>
+Brian Croom <bcroom@apple.com> <brian.s.croom@gmail.com>
+Brian Gesiak <bgesiak@fb.com> <modocache@gmail.com>
+Bryan Chan <bryan.chan@ca.ibm.com> <bryanpkc@gmail.com>
+Calvin Hill <mr_j.c.h@hotmail.com> <return@users.noreply.github.com>
+Chris Bieneman <beanz@apple.com>
+Chris Bieneman <beanz@apple.com> <cbieneman@apple.com>
+Chris Lattner <clattner@nondot.org> <clattner@apple.com>
+Chris Lattner <clattner@nondot.org> <lattner@users.noreply.github.com>
+Chris Lattner <clattner@nondot.org> <sabre@iMac.local>
+Chris Williams <cwilliams@fitbit.com> <ultramiraculous@users.noreply.github.com>
+codester <sahil.profile@gmail.com> codestergit <sahil.profile@gmail.com>
+Dan Liew <dliew@apple.com> <36706441+danliew-apple@users.noreply.github.com>
+Daniel Duan <daniel@duan.org> <danmarner@gmail.com>
+Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com>
+Dave <davesweeris@mac.com>
+Dave Abrahams <dabrahams@apple.com> <dave@boostpro.com>
+Dave Abrahams <dabrahams@apple.com> <dave@fripp.apple.com>
+Dave Abrahams <dabrahams@apple.com> <dave@Skree.local>
+Dave Abrahams <dabrahams@apple.com> <dave@Wingy.local>
+Dave Lee <davelee@lyft.com> <davelee.com@gmail.com>
+David Rönnqvist <david.ronnqvist@gmail.com> <david.ronnqvist@skype.net>
+David Zarzycki <dave@znu.io> <zarzycki@icloud.com>
+David Zarzycki <dave@znu.io> <zarzycki@mac.com>
+Davide Italiano <ditaliano@apple.com> <dcci@users.noreply.github.com>
+Davide Italiano <ditaliano@apple.com> <dccitaliano@gmail.com>
+Dmitri Gribenko <gribozavr@gmail.com> <dgribenko@apple.com>
+Doug Coleman <doug_coleman@apple.com> <doug.coleman@gmail.com>
+Enrico Granata <egranata@apple.com> <egranata@egranata.apple.com>
+Enrico Granata <egranata@apple.com> <granata.enrico@gmail.com>
+Erik Eckstein <eeckstein@apple.com> <eeckstein@apple.com>
+Erik Eckstein <eeckstein@apple.com> <eeckstein@rad-main.corp.apple.com>
+Erik Verbruggen <erik.verbruggen@me.com> <erikjv@users.noreply.github.com>
+Ewa Matejska <ematejska@apple.com> <ematejska@apple.com>
+Ewa Matejska <ematejska@apple.com> <ematejska@Ewas-MacBook-Pro.local>
+Ewa Matejska <ematejska@apple.com> <ewamatejska@Ewas-iMac.local>
+Florent Bruneau <florent.bruneau@intersec.com> <florent.bruneau_github@m4x.org>
+Francis Ricci <fjricci@fb.com> <francisjricci@gmail.com>
+GauravDS <er.gauravds@gmail.com> <gaurav.sharma@punchh.com>
+Graydon Hoare <ghoare@apple.com> <graydon@users.noreply.github.com>
+Greg Parker <gparker@apple.com> <gparker-github@sealiesoftware.com>
+Guillaume Lessard <dhtnstff@gmail.com> <glessard@users.noreply.github.com>
+Hamish <hamish2knight@gmail.com> <hamish2knight@gmail.com>
+Han Sangjin <tinysun@jssolution.co.kr> <tinysun.net@gmail.com>
+Harlan Haskins <harlan@apple.com> <harlan@harlanhaskins.com>
+Hitster GTD <hitstergtd@users.noreply.github.com> <hitstergtd@users.noreply.github.com>
+Huon Wilson <huon@apple.com> <dbau.pp+github@gmail.com>
+Ingmar Stein <IngmarStein@users.noreply.github.com>
+Itai Ferber <iferber@apple.com> <itai@itaiferber.net>
+Jacob Bandes-Storch <jacob@bandes-stor.ch> <jacob@bandes-storch.net>
+Jacob Mizraji <jmizraji@apple.com> <jacobmizraji@gmail.com>
+Janosch Hildebrand <jnosh@jnosh.com> <jnosh+git@jnosh.com>
+Janosch Hildebrand <jnosh@jnosh.com> <jnosh+github@jnosh.com>
+Javier Soto <jsbustos@twitch.tv> <javier.api@gmail.com>
+Javier Soto <jsbustos@twitch.tv> <javiers@twitter.com>
+Joe <joe@iachieved.it>
+Joe <joewillsher@icloud.com>
+joe DeCapo <joe@polka.cat>
+Joe Groff <jgroff@apple.com> <arcata@gmail.com>
+Joe Shajrawi <shajrawi@apple.com> <joeshajrawi@iMac-2.local>
+Joe Shajrawi <shajrawi@apple.com> <joeshajrawi@Joes-iMac-Pro.local>
+Johannes Weiß <johannesweiss@apple.com> <github@tux4u.de>
+John Regner <john@johnregner.com> <regnerjr@gmail.com>
+Karoy Lorentey <klorentey@apple.com> <karoly@lorentey.hu>
+Keith Smiley <k@keith.so> <keithbsmiley@gmail.com>
+Kevin Ballard <kevin@sb.org> <kevin.ballard@postmates.com>
+Kosuke Ogawa <ogawa_kousuke@aratana.jp> <koogawa.app@gmail.com>
+Kuba Mracek <mracek@apple.com> <jbrecka@apple.com>
+Luiz Fernando Silva <luizinho_mack@yahoo.com.br>
+Luqman Aden <luqman@apple.com> <luqman_aden@apple.com>
+Marcelo Fabri <me@marcelofabri.com> <marcelofabri@users.noreply.github.com>
+Mark Lacey <mark.lacey@apple.com> <rudkx@icloud.com>
+Mark Lacey <mark.lacey@apple.com> <rudkx@users.noreply.github.com>
+Matt Rajca <matt.rajca@me.com> <mattrajca@users.noreply.github.com>
+Max Moiseev <moiseev@apple.com> <maxim.moiseev@gmail.com>
+Max Moiseev <moiseev@apple.com> <moiseev@users.noreply.github.com>
+Maxwell Swadling <maxs@apple.com> <maxwellswadling@gmail.com>
+Maxwell Swadling <maxs@apple.com> <mswadling@apple.com>
+Mayur Raiturkar <mayur@mayur.xyz> <mayurkr@users.noreply.github.com>
+Michael Gottesman <mgottesman@apple.com> <gottesmm@users.noreply.github.com>
+Michael Ilseman <milseman@apple.com> <michael.ilseman@gmail.com>
+Mike Ash <mikeash@apple.com> <mike@mikeash.com>
+Mike Ferris <mferris@apple.com> <mike@lorax.com>
+Mishal Awadah <mawadah@apple.com>
+Mishal Shah <mishal_shah@apple.com> <shahmishal@users.noreply.github.com>
+Nadav Rotem <nrotem@apple.com> <nadavrot@users.noreply.github.com>
+Nate Cook <natecook@apple.com> <nate@Nates-MacBook-Pro.local>
+Nate Cook <natecook@apple.com> <natecook@gmail.com>
+Nate Cook <natecook@apple.com> <natecook1000@users.noreply.github.com>
+Nate Cook <natecook@apple.com> <nmersethcook@apple.com>
+Nathan Lanza <lanza@fb.com> <nathan@lanza.io>
+Nicole Jacque <jacque@apple.com>
+Niels Andriesse <andriesseniels@gmail.com> <nielsandriesse@users.noreply.github.com>
+Paul Meng <mno2@mno2.org> <mno2.csie@gmail.com>
+Pavel Yaskevich <pyaskevich@apple.com> <xedin@apache.org>
+Paweł Szot <pszot@pgs-soft.com>
+Paweł Szot <pszot@pgs-soft.com> <qwertyszot@gmail.com>
+Pete Cooper <peter_cooper@apple.com>
+Philip Ridgeway <pridgeway@vernier.com> <philip.ridgeway@gmail.com>
+Richard Wei <rxwei@apple.com> <rxwei@google.com>
+Rintaro Ishizaki <rishizaki@apple.com> <fs.output@gmail.com>
+Robert Widmann <rwidmann@apple.com> <devteam.codafi@gmail.com>
+Roman Levenstein <rlevenstein@apple.com> <swiftix@users.noreply.github.com>
+Ross Bayer <ross.m.bayer@gmail.com> <Rostepher@users.noreply.github.com>
+Russ Bishop <rbishopjr@apple.com> <russ@plangrid.com>
+Ryan Lovelett <ryan@lovelett.me> <RLovelett@users.noreply.github.com>
+Shawn Erickson <shawn.erickson@citrix.com> <shawnce@gmail.com>
+Slava Pestov <spestov@apple.com> <spestov@rad-main.corp.apple.com>
+Slava Pestov <spestov@apple.com> <sviatoslav.pestov@gmail.com>
+Stephen Canon <scanon@apple.com>
+Stephen Canon <scanon@apple.com> <stephentyrone@gmail.com>
+Sukolsak Sakshuwong <sukolsak@gmail.com>
+Todd Fiala <tfiala@apple.com> <todd.fiala@gmail.com>
+Toni Suter <tonisuter@me.com> <tonisuter@users.noreply.github.com>
+Vedant Kumar <vsk@apple.com> <vk@vedantk.com>
+Xi Ge <xi_ge@apple.com> <xi_ge@rad-main.corp.apple.com>
+Xin Tong <xin_tong@apple.com> <trent.xin.tong@gmail.com>
+Xin Tong <xin_tong@apple.com> <trentxintong@Xins-MacBook-Pro.local>
+Yuka Ezura <ezura@users.noreply.github.com> <2020337+ezura@users.noreply.github.com>
+Yurii Samsoniuk <ura@google.com> <mr.sigito@gmail.com>
+Zac Bowling <zbowling@google.com> <zac@zacbowling.com>
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index b12e620..dd142af 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -227,12 +227,12 @@
     if(NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
       list(APPEND result -Xclang;--dependent-lib=oldnames)
       # TODO(compnerd) handle /MT, /MTd, /MD, /MDd
-      if("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
-        list(APPEND result "-D_MD")
-        list(APPEND result -Xclang;--dependent-lib=msvcrt)
-      else()
+      if("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
         list(APPEND result "-D_MDd")
         list(APPEND result -Xclang;--dependent-lib=msvcrtd)
+      else()
+        list(APPEND result "-D_MD")
+        list(APPEND result -Xclang;--dependent-lib=msvcrt)
       endif()
     endif()
 
@@ -425,7 +425,7 @@
     list(APPEND library_search_directories "${SWIFT_${sdk}_${arch}_ICU_UC_LIBDIR}")
   endif()
   if(NOT "${SWIFT_${LFLAGS_SDK}_${LFLAGS_ARCH}_ICU_I18N}" STREQUAL "")
-    get_filename_component(SWIFT_${sdk}_${arch}_ICU_I18N_LIBDIR "${SWIFT_${sdk}_${arch}_IC_I18N}" DIRECTORY)
+    get_filename_component(SWIFT_${sdk}_${arch}_ICU_I18N_LIBDIR "${SWIFT_${sdk}_${arch}_ICU_I18N}" DIRECTORY)
     list(APPEND library_search_directories "${SWIFT_${sdk}_${arch}_ICU_I18N_LIBDIR}")
   endif()
 
@@ -792,6 +792,7 @@
     swift_windows_generate_sdk_vfs_overlay(SWIFTLIB_SINGLE_VFS_OVERLAY_FLAGS)
     foreach(flag ${SWIFTLIB_SINGLE_VFS_OVERLAY_FLAGS})
       list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS -Xcc;${flag})
+      list(APPEND SWIFTLIB_SINGLE_C_COMPILE_FLAGS ${flag})
     endforeach()
     foreach(directory ${SWIFTLIB_INCLUDE})
       list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS -Xfrontend;-I${directory})
@@ -1719,6 +1720,19 @@
          endif()
        endif()
 
+       # We unconditionally removed "-z,defs" from CMAKE_SHARED_LINKER_FLAGS in 
+       # swift_common_standalone_build_config_llvm within SwiftSharedCMakeConfig.cmake,
+       # where it was added by a call to HandleLLVMOptions. 
+       #
+       # Rather than applying it to all targets and libraries, we here add it back to 
+       # supported targets and libraries only. 
+       # This is needed for ELF targets only; however, RemoteMirror needs to build 
+       # with undefined symbols.
+       if("${SWIFT_SDK_${LFLAGS_SDK}_OBJECT_FORMAT}" STREQUAL "ELF" 
+          AND NOT "${name}" STREQUAL "swiftRemoteMirror")
+          list(APPEND swiftlib_link_flags_all "-Wl,-z,defs")
+       endif()
+
         # Add this library variant.
         _add_swift_library_single(
           ${VARIANT_NAME}
diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake
index 0aaec27..9aeaefb 100644
--- a/cmake/modules/SwiftConfigureSDK.cmake
+++ b/cmake/modules/SwiftConfigureSDK.cmake
@@ -14,10 +14,10 @@
     message(STATUS "  UCRT Version: $ENV{UCRTVersion}")
     message(STATUS "  UCRT SDK Dir: $ENV{UniversalCRTSdkDir}")
     message(STATUS "  VC Dir: $ENV{VCToolsInstallDir}")
-    if("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
-      message(STATUS "  ${CMAKE_BUILD_TYPE} VC++ CRT: MD")
-    else()
+    if("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG")
       message(STATUS "  ${CMAKE_BUILD_TYPE} VC++ CRT: MDd")
+    else()
+      message(STATUS "  ${CMAKE_BUILD_TYPE} VC++ CRT: MD")
     endif()
 
     foreach(arch ${SWIFT_SDK_${prefix}_ARCHITECTURES})
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index 498ca90..48243be 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -78,9 +78,17 @@
   include(AddSwiftTableGen) # This imports TableGen from LLVM.
   include(HandleLLVMOptions)
 
-  # HACK: this ugly tweaking is to prevent the propagation of the flag from LLVM
-  # into swift.  The use of this flag pollutes all targets, and we are not able
-  # to remove it on a per-target basis which breaks cross-compilation.
+  # HACK: Not all targets support -z,defs as a linker flag. 
+  #
+  # Normally, LLVM would only add it as an option for known ELF targets;
+  # however, due to the custom scheme Swift uses for cross-compilation, the 
+  # CMAKE_SHARED_LINKER_FLAGS are determined based on the host system and 
+  # then applied to all targets. This causes issues in cross-compiling to
+  # Windows from a Linux host.
+  # 
+  # To work around this, we unconditionally remove the flag here and then 
+  # selectively add it to the per-target link flags; this is currently done
+  # in add_swift_library within AddSwift.cmake.
   string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
 
   set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst
index 602d79f..4787fd0 100644
--- a/docs/Lexicon.rst
+++ b/docs/Lexicon.rst
@@ -339,6 +339,10 @@
 
   script mode
     The parsing mode that allows top-level imperative code in a source file.
+    
+  Sema
+    Short for 'Semantic Analysis', the compiler pass that performs type checking,
+    validation, and expression rewriting before SILGen.
 
   SIL
     "Swift Intermediate Language". A high-level IR used by the Swift compiler
diff --git a/docs/SIL.rst b/docs/SIL.rst
index c2001d9..2a81532 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -4649,6 +4649,14 @@
 function type. Something must guarantee the lifetime of the input ``%0`` for the
 duration of the use ``%1``.
 
+A ``convert_escape_to_noescape [not_guaranteed] %opd`` indicates that the
+lifetime of its operand was not guaranteed by SILGen and a mandatory pass must
+be run to ensure the lifetime of ``%opd``` for the conversion's uses.
+
+A ``convert_escape_to_noescape [escaped]`` indiciates that the result was
+passed to a function (materializeForSet) which escapes the closure in a way not
+expressed by the convert's users. The mandatory pass must ensure the lifetime
+in a conservative way.
 
 thin_function_to_pointer
 ````````````````````````
diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h
index 78f21c4..191dfe4 100644
--- a/include/swift/AST/Attr.h
+++ b/include/swift/AST/Attr.h
@@ -17,6 +17,7 @@
 #ifndef SWIFT_ATTR_H
 #define SWIFT_ATTR_H
 
+#include "swift/Basic/InlineBitfield.h"
 #include "swift/Basic/SourceLoc.h"
 #include "swift/Basic/UUID.h"
 #include "swift/Basic/STLExtras.h"
@@ -182,60 +183,82 @@
 class DeclAttribute : public AttributeBase {
   friend class DeclAttributes;
 protected:
-  class DeclAttrBitFields {
-    friend class DeclAttribute;
-
-    // The kind.
-    unsigned Kind : 8;
-
-    // Whether this attribute was implicitly added.
-    unsigned Implicit : 1;
-
-    unsigned Invalid : 1;
-  };
-  enum { NumDeclAttrBits = 10 };
-  static_assert(NumDeclAttrBits <= 32, "fits in an unsigned");
-
-  class ObjCAttrBitFields {
-    friend class ObjCAttr;
-    unsigned : NumDeclAttrBits;
-
-    /// Whether this attribute has location information that trails the main
-    /// record, which contains the locations of the parentheses and any names.
-    unsigned HasTrailingLocationInfo : 1;
-
-    /// Whether the name is implicit, produced as the result of caching.
-    unsigned ImplicitName : 1;
-
-    /// Whether the @objc was inferred using Swift 3's deprecated inference
-    /// rules.
-    unsigned Swift3Inferred : 1;
-  };
-  enum { NumObjCAttrBits = NumDeclAttrBits + 3 };
-  static_assert(NumObjCAttrBits <= 32, "fits in an unsigned");
-
-  class AccessControlAttrBitFields {
-    friend class AbstractAccessControlAttr;
-    unsigned : NumDeclAttrBits;
-
-    unsigned AccessLevel : 3;
-  };
-  enum { NumAccessControlAttrBits = NumDeclAttrBits + 3 };
-  static_assert(NumAccessControlAttrBits <= 32, "fits in an unsigned");
-
   union {
-    DeclAttrBitFields DeclAttrBits;
-    ObjCAttrBitFields ObjCAttrBits;
-    AccessControlAttrBitFields AccessControlAttrBits;
-  };
+    uint64_t OpaqueBits;
+
+    SWIFT_INLINE_BITFIELD_BASE(DeclAttribute, bitmax(NumDeclAttrKindBits,8)+1+1,
+      Kind : bitmax(NumDeclAttrKindBits,8),
+      // Whether this attribute was implicitly added.
+      Implicit : 1,
+
+      Invalid : 1
+    );
+
+    SWIFT_INLINE_BITFIELD(ObjCAttr, DeclAttribute, 1+1+1,
+      /// Whether this attribute has location information that trails the main
+      /// record, which contains the locations of the parentheses and any names.
+      HasTrailingLocationInfo : 1,
+
+      /// Whether the name is implicit, produced as the result of caching.
+      ImplicitName : 1,
+
+      /// Whether the @objc was inferred using Swift 3's deprecated inference
+      /// rules.
+      Swift3Inferred : 1
+    );
+
+    SWIFT_INLINE_BITFIELD(AbstractAccessControlAttr, DeclAttribute, 3,
+      AccessLevel : 3
+    );
+
+    SWIFT_INLINE_BITFIELD_FULL(AlignmentAttr, DeclAttribute, 32,
+      : NumPadBits,
+      // The alignment value.
+      Value : 32
+    );
+
+    SWIFT_INLINE_BITFIELD(ClangImporterSynthesizedTypeAttr, DeclAttribute, 1,
+      kind : 1
+    );
+
+    SWIFT_INLINE_BITFIELD(EffectsAttr, DeclAttribute, NumEffectsKindBits,
+      kind : NumEffectsKindBits
+    );
+
+    SWIFT_INLINE_BITFIELD(InlineAttr, DeclAttribute, NumInlineKindBits,
+      kind : NumInlineKindBits
+    );
+
+    SWIFT_INLINE_BITFIELD(OptimizeAttr, DeclAttribute, NumOptimizationModeBits,
+      mode : NumOptimizationModeBits
+    );
+
+    SWIFT_INLINE_BITFIELD(ReferenceOwnershipAttr, DeclAttribute,
+                          NumReferenceOwnershipBits,
+      ownership : NumReferenceOwnershipBits
+    );
+
+    SWIFT_INLINE_BITFIELD_FULL(SpecializeAttr, DeclAttribute, 1+1+32,
+      exported : 1,
+      kind : 1,
+      : NumPadBits,
+      numRequirements : 32
+    );
+
+    SWIFT_INLINE_BITFIELD(SynthesizedProtocolAttr, DeclAttribute,
+                          NumKnownProtocolKindBits,
+      kind : NumKnownProtocolKindBits
+    );
+  } Bits;
 
   DeclAttribute *Next = nullptr;
 
   DeclAttribute(DeclAttrKind DK, SourceLoc AtLoc, SourceRange Range,
                 bool Implicit) : AttributeBase(AtLoc, Range) {
-    DeclAttrBits.Kind = static_cast<unsigned>(DK);
-    DeclAttrBits.Implicit = Implicit;
-    DeclAttrBits.Invalid = 0;
+    Bits.OpaqueBits = 0;
+    Bits.DeclAttribute.Kind = static_cast<unsigned>(DK);
+    Bits.DeclAttribute.Implicit = Implicit;
+    Bits.DeclAttribute.Invalid = false;
   }
 
 public:
@@ -326,22 +349,22 @@
 
 public:
   DeclAttrKind getKind() const {
-    return static_cast<DeclAttrKind>(DeclAttrBits.Kind);
+    return static_cast<DeclAttrKind>(Bits.DeclAttribute.Kind);
   }
 
   /// Whether this attribute was implicitly added.
-  bool isImplicit() const { return DeclAttrBits.Implicit; }
+  bool isImplicit() const { return Bits.DeclAttribute.Implicit; }
 
   /// Set whether this attribute was implicitly added.
-  void setImplicit(bool Implicit) {
-    DeclAttrBits.Implicit = Implicit;
+  void setImplicit(bool Implicit = true) {
+    Bits.DeclAttribute.Implicit = Implicit;
   }
 
   /// Returns true if this attribute was find to be invalid in some way by
   /// semantic analysis.  In that case, the attribute should not be considered,
   /// the attribute node should be only used to retrieve source information.
-  bool isInvalid() const { return DeclAttrBits.Invalid; }
-  void setInvalid() { DeclAttrBits.Invalid = true; }
+  bool isInvalid() const { return Bits.DeclAttribute.Invalid; }
+  void setInvalid() { Bits.DeclAttribute.Invalid = true; }
 
   bool isValid() const { return !isInvalid(); }
 
@@ -518,11 +541,11 @@
 public:
   AlignmentAttr(unsigned Value, SourceLoc AtLoc, SourceRange Range,
                 bool Implicit)
-    : DeclAttribute(DAK_Alignment, AtLoc, Range, Implicit),
-      Value(Value) {}
-  
-  // The alignment value.
-  const unsigned Value;
+      : DeclAttribute(DAK_Alignment, AtLoc, Range, Implicit) {
+    Bits.AlignmentAttr.Value = Value;
+  }
+
+  unsigned getValue() const { return Bits.AlignmentAttr.Value; }
   
   static bool classof(const DeclAttribute *DA) {
     return DA->getKind() == DAK_Alignment;
@@ -722,9 +745,9 @@
     : DeclAttribute(DAK_ObjC, SourceLoc(), SourceRange(), /*Implicit=*/true),
       NameData(nullptr)
   {
-    ObjCAttrBits.HasTrailingLocationInfo = false;
-    ObjCAttrBits.ImplicitName = implicitName;
-    ObjCAttrBits.Swift3Inferred = false;
+    Bits.ObjCAttr.HasTrailingLocationInfo = false;
+    Bits.ObjCAttr.ImplicitName = implicitName;
+    Bits.ObjCAttr.Swift3Inferred = false;
 
     if (name) {
       NameData = name->getOpaqueValue();
@@ -737,7 +760,7 @@
 
   /// Determine whether this attribute has trailing location information.
   bool hasTrailingLocationInfo() const {
-    return ObjCAttrBits.HasTrailingLocationInfo;
+    return Bits.ObjCAttr.HasTrailingLocationInfo;
   }
 
   /// Retrieve the trailing location information.
@@ -815,7 +838,7 @@
 
   /// Determine whether the name associated with this attribute was
   /// implicit.
-  bool isNameImplicit() const { return ObjCAttrBits.ImplicitName; }
+  bool isNameImplicit() const { return Bits.ObjCAttr.ImplicitName; }
 
   /// Set the name of this entity.
   void setName(ObjCSelector name, bool implicit) {
@@ -825,23 +848,23 @@
     if (hasTrailingLocationInfo() &&
         (!hasName() ||
          getName()->getNumSelectorPieces() < name.getNumSelectorPieces())) {
-      ObjCAttrBits.HasTrailingLocationInfo = false;
+      Bits.ObjCAttr.HasTrailingLocationInfo = false;
     }
 
     NameData = name.getOpaqueValue();
-    ObjCAttrBits.ImplicitName = implicit;
+    Bits.ObjCAttr.ImplicitName = implicit;
   }
 
   /// Determine whether this attribute was inferred based on Swift 3's
   /// deprecated @objc inference rules.
   bool isSwift3Inferred() const {
-    return ObjCAttrBits.Swift3Inferred;
+    return Bits.ObjCAttr.Swift3Inferred;
   }
 
   /// Set whether this attribute was inferred based on Swift 3's deprecated
   /// @objc inference rules.
   void setSwift3Inferred(bool inferred = true) {
-    ObjCAttrBits.Swift3Inferred = inferred;
+    Bits.ObjCAttr.Swift3Inferred = inferred;
   }
 
   /// Clear the name of this entity.
@@ -874,13 +897,13 @@
   AbstractAccessControlAttr(DeclAttrKind DK, SourceLoc atLoc, SourceRange range,
                             AccessLevel access, bool implicit)
       : DeclAttribute(DK, atLoc, range, implicit) {
-    AccessControlAttrBits.AccessLevel = static_cast<unsigned>(access);
+    Bits.AbstractAccessControlAttr.AccessLevel = static_cast<unsigned>(access);
     assert(getAccess() == access && "not enough bits for access control");
   }
 
 public:
   AccessLevel getAccess() const {
-    return static_cast<AccessLevel>(AccessControlAttrBits.AccessLevel);
+    return static_cast<AccessLevel>(Bits.AbstractAccessControlAttr.AccessLevel);
   }
 
   static bool classof(const DeclAttribute *DA) {
@@ -918,16 +941,16 @@
 
 /// Represents an inline attribute.
 class InlineAttr : public DeclAttribute {
-  InlineKind Kind;
 public:
   InlineAttr(SourceLoc atLoc, SourceRange range, InlineKind kind)
-    : DeclAttribute(DAK_Inline, atLoc, range, /*Implicit=*/false), 
-      Kind(kind) {}
+      : DeclAttribute(DAK_Inline, atLoc, range, /*Implicit=*/false) {
+    Bits.InlineAttr.kind = unsigned(kind);
+  }
 
   InlineAttr(InlineKind kind)
     : InlineAttr(SourceLoc(), SourceRange(), kind) {}
 
-  InlineKind getKind() const { return Kind; }
+  InlineKind getKind() const { return InlineKind(Bits.InlineAttr.kind); }
   static bool classof(const DeclAttribute *DA) {
     return DA->getKind() == DAK_Inline;
   }
@@ -935,16 +958,18 @@
 
 /// Represents the optimize attribute.
 class OptimizeAttr : public DeclAttribute {
-  OptimizationMode Mode;
 public:
   OptimizeAttr(SourceLoc atLoc, SourceRange range, OptimizationMode mode)
-    : DeclAttribute(DAK_Optimize, atLoc, range, /*Implicit=*/false),
-      Mode(mode) {}
+      : DeclAttribute(DAK_Optimize, atLoc, range, /*Implicit=*/false) {
+    Bits.OptimizeAttr.mode = unsigned(mode);
+  }
 
   OptimizeAttr(OptimizationMode mode)
     : OptimizeAttr(SourceLoc(), SourceRange(), mode) {}
 
-  OptimizationMode getMode() const { return Mode; }
+  OptimizationMode getMode() const {
+    return OptimizationMode(Bits.OptimizeAttr.mode);
+  }
   static bool classof(const DeclAttribute *DA) {
     return DA->getKind() == DAK_Optimize;
   }
@@ -952,16 +977,16 @@
 
 /// Represents the side effects attribute.
 class EffectsAttr : public DeclAttribute {
-  EffectsKind Kind;
 public:
   EffectsAttr(SourceLoc atLoc, SourceRange range, EffectsKind kind)
-  : DeclAttribute(DAK_Effects, atLoc, range, /*Implicit=*/false),
-  Kind(kind) {}
+      : DeclAttribute(DAK_Effects, atLoc, range, /*Implicit=*/false) {
+    Bits.EffectsAttr.kind = unsigned(kind);
+  }
 
   EffectsAttr(EffectsKind kind)
   : EffectsAttr(SourceLoc(), SourceRange(), kind) {}
 
-  EffectsKind getKind() const { return Kind; }
+  EffectsKind getKind() const { return EffectsKind(Bits.EffectsAttr.kind); }
   static bool classof(const DeclAttribute *DA) {
     return DA->getKind() == DAK_Effects;
   }
@@ -971,18 +996,19 @@
 
 /// Represents weak/unowned/unowned(unsafe) decl modifiers.
 class ReferenceOwnershipAttr : public DeclAttribute {
-  const ReferenceOwnership ownership;
-
 public:
   ReferenceOwnershipAttr(SourceRange range, ReferenceOwnership kind)
       : DeclAttribute(DAK_ReferenceOwnership, range.Start, range,
-                      /*Implicit=*/false),
-        ownership(kind) {}
+                      /*Implicit=*/false) {
+    Bits.ReferenceOwnershipAttr.ownership = unsigned(kind);
+  }
 
   ReferenceOwnershipAttr(ReferenceOwnership kind)
       : ReferenceOwnershipAttr(SourceRange(), kind) {}
 
-  ReferenceOwnership get() const { return ownership; }
+  ReferenceOwnership get() const {
+    return ReferenceOwnership(Bits.ReferenceOwnershipAttr.ownership);
+  }
 
   /// Returns a copy of this attribute without any source information.
   ReferenceOwnershipAttr *clone(ASTContext &context) const {
@@ -1045,21 +1071,22 @@
 /// rather, it is introduced by the Clang importer to indicate
 /// synthesized conformances.
 class SynthesizedProtocolAttr : public DeclAttribute {
-  KnownProtocolKind ProtocolKind;
   LazyConformanceLoader *Loader;
 
 public:
   SynthesizedProtocolAttr(KnownProtocolKind protocolKind,
                           LazyConformanceLoader *Loader)
     : DeclAttribute(DAK_SynthesizedProtocol, SourceLoc(), SourceRange(),
-                    /*Implicit=*/true),
-      ProtocolKind(protocolKind), Loader(Loader)
+                    /*Implicit=*/true), Loader(Loader)
   {
+    Bits.SynthesizedProtocolAttr.kind = unsigned(protocolKind);
   }
 
   /// Retrieve the known protocol kind naming the protocol to be
   /// synthesized.
-  KnownProtocolKind getProtocolKind() const { return ProtocolKind; }
+  KnownProtocolKind getProtocolKind() const {
+    return KnownProtocolKind(Bits.SynthesizedProtocolAttr.kind);
+  }
 
   /// Retrieve the lazy loader that will be used to populate the
   /// synthesized conformance.
@@ -1074,16 +1101,14 @@
 /// type list.
 class SpecializeAttr : public DeclAttribute {
 public:
+  // NOTE: When adding new kinds, you must update the inline bitfield macro.
   enum class SpecializationKind {
     Full,
     Partial
   };
 
 private:
-  unsigned numRequirements;
   TrailingWhereClause *trailingWhereClause;
-  SpecializationKind kind;
-  bool exported;
 
   Requirement *getRequirementsData() {
     return reinterpret_cast<Requirement *>(this+1);
@@ -1113,25 +1138,25 @@
   ArrayRef<Requirement> getRequirements() const;
 
   MutableArrayRef<Requirement> getRequirements() {
-    return { getRequirementsData(), numRequirements };
+    return { getRequirementsData(), Bits.SpecializeAttr.numRequirements };
   }
 
   void setRequirements(ASTContext &Ctx, ArrayRef<Requirement> requirements);
 
   bool isExported() const {
-    return exported;
+    return Bits.SpecializeAttr.exported;
   }
 
   SpecializationKind getSpecializationKind() const {
-    return kind;
+    return SpecializationKind(Bits.SpecializeAttr.kind);
   }
 
   bool isFullSpecialization() const {
-    return kind == SpecializationKind::Full;
+    return getSpecializationKind() == SpecializationKind::Full;
   }
 
   bool isPartialSpecialization() const {
-    return kind == SpecializationKind::Partial;
+    return getSpecializationKind() == SpecializationKind::Partial;
   }
 
   static bool classof(const DeclAttribute *DA) {
@@ -1214,6 +1239,7 @@
 /// Used to control manglings.
 class ClangImporterSynthesizedTypeAttr : public DeclAttribute {
 public:
+  // NOTE: When adding new kinds, you must update the inline bitfield macro.
   enum class Kind : char {
     /// A struct synthesized by the importer to represent an NSError with a
     /// particular domain, as specified by an enum with the \c ns_error_domain
@@ -1236,18 +1262,22 @@
   ///
   /// Must be a valid Swift identifier as well, for mangling purposes.
   const StringRef originalTypeName;
-  const Kind kind;
 
   explicit ClangImporterSynthesizedTypeAttr(StringRef originalTypeName,
                                             Kind kind)
     : DeclAttribute(DAK_ClangImporterSynthesizedType, SourceLoc(),
                     SourceRange(), /*Implicit=*/true),
-      originalTypeName(originalTypeName), kind(kind) {
+      originalTypeName(originalTypeName) {
     assert(!originalTypeName.empty());
+    Bits.ClangImporterSynthesizedTypeAttr.kind = unsigned(kind);
+  }
+
+  Kind getKind() const {
+    return Kind(Bits.ClangImporterSynthesizedTypeAttr.kind);
   }
 
   StringRef getManglingName() const {
-    return manglingNameForKind(kind);
+    return manglingNameForKind(getKind());
   }
 
   static StringRef manglingNameForKind(Kind kind) {
diff --git a/include/swift/AST/AttrKind.h b/include/swift/AST/AttrKind.h
index e67569a..5c02ce6 100644
--- a/include/swift/AST/AttrKind.h
+++ b/include/swift/AST/AttrKind.h
@@ -17,6 +17,7 @@
 #ifndef SWIFT_ATTRKIND_H
 #define SWIFT_ATTRKIND_H
 
+#include "swift/Basic/InlineBitfield.h"
 #include "swift/Config.h"
 #include "llvm/Support/DataTypes.h"
 
@@ -64,9 +65,13 @@
 
 enum class InlineKind : uint8_t {
   Never = 0,
-  Always = 1
+  Always = 1,
+  Last_InlineKind = Always
 };
 
+enum : unsigned { NumInlineKindBits =
+  countBitsUsed(static_cast<unsigned>(InlineKind::Last_InlineKind)) };
+
 /// This enum represents the possible values of the @effects attribute.
 /// These values are ordered from the strongest guarantee to the weakest,
 /// so please do not reorder existing values.
@@ -75,9 +80,13 @@
   ReadOnly,
   ReleaseNone,
   ReadWrite,
-  Unspecified
+  Unspecified,
+  Last_EffectsKind = Unspecified
 };
 
+enum : unsigned { NumEffectsKindBits =
+  countBitsUsed(static_cast<unsigned>(EffectsKind::Last_EffectsKind)) };
+
   
 enum DeclAttrKind : unsigned {
 #define DECL_ATTR(_, NAME, ...) DAK_##NAME,
@@ -85,6 +94,9 @@
   DAK_Count
 };
 
+enum : unsigned { NumDeclAttrKindBits =
+  countBitsUsed(static_cast<unsigned>(DeclAttrKind::DAK_Count - 1)) };
+
 // Define enumerators for each type attribute, e.g. TAK_weak.
 enum TypeAttrKind {
 #define TYPE_ATTR(X) TAK_##X,
diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def
index 2f05bbc..170e537 100644
--- a/include/swift/AST/Builtins.def
+++ b/include/swift/AST/Builtins.def
@@ -294,6 +294,27 @@
 /// allocated element type 'E'.
 BUILTIN_SIL_OPERATION(GetTailAddr, "getTailAddr", Integer)
 
+/// performInstantaneousReadAccess(Builtin.RawPointer, T.Type) -> ()
+/// Begin and then immediately end a read access to the given raw pointer,
+/// which will be treated as an address of type 'T'.
+BUILTIN_SIL_OPERATION(PerformInstantaneousReadAccess,
+                      "performInstantaneousReadAccess", Special)
+
+/// beginUnpairedModifyAccess(Builtin.RawPointer, Builtin.RawPointer,
+///                           T.Type) -> ()
+/// Begins but does not end a 'modify' access to the first raw pointer argument.
+/// The second raw pointer must be a pointer to an UnsafeValueBuffer, which
+/// will be used by the runtime to record the access. The lifetime of the
+/// value buffer must be longer than that of the access itself. The accessed
+/// address will be treated as having type 'T'.
+BUILTIN_SIL_OPERATION(BeginUnpairedModifyAccess, "beginUnpairedModifyAccess",
+                      Special)
+
+/// endUnpairedAccess(Builtin.RawPointer) -> ()
+/// Ends an in-progress unpaired access. The raw pointer argument must be
+/// be a pointer to an UnsafeValueBuffer that records an in progress access.
+BUILTIN_SIL_OPERATION(EndUnpairedAccess, "endUnpairedAccess", Special)
+
 /// condfail(Int1) -> ()
 /// Triggers a runtime failure if the condition is true.
 BUILTIN_SIL_OPERATION(CondFail, "condfail", Special)
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index acf7142..ed129ae 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -2304,8 +2304,14 @@
                        bool treatUsableFromInlineAsPublic = false) const;
 
 
-  /// Copy the formal access level and @usableFromInline attribute from source.
-  void copyFormalAccessFrom(ValueDecl *source);
+  /// Copy the formal access level and @usableFromInline attribute from
+  /// \p source.
+  ///
+  /// If \p sourceIsParentContext is true, an access level of \c private will
+  /// be copied as \c fileprivate, to ensure that this declaration will be
+  /// available everywhere \p source is.
+  void copyFormalAccessFrom(const ValueDecl *source,
+                            bool sourceIsParentContext = false);
 
   /// Returns the access level that actually controls how a declaration should
   /// be emitted and may be used.
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 15e16df..271fa99 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -3937,6 +3937,9 @@
 NOTE(missing_unknown_case,none,
      "handle unknown values using \"@unknown default\"", ())
 
+NOTE(non_exhaustive_switch_drop_unknown,none,
+     "remove '@unknown' to handle remaining values", ())
+
 NOTE(missing_particular_case,none,
      "add missing case: '%0'", (StringRef))
 WARNING(redundant_particular_case,none,
diff --git a/include/swift/AST/KnownProtocols.h b/include/swift/AST/KnownProtocols.h
index f388fdd..f70bc07 100644
--- a/include/swift/AST/KnownProtocols.h
+++ b/include/swift/AST/KnownProtocols.h
@@ -13,6 +13,7 @@
 #ifndef SWIFT_AST_KNOWNPROTOCOLS_H
 #define SWIFT_AST_KNOWNPROTOCOLS_H
 
+#include "swift/Basic/InlineBitfield.h"
 #include "swift/Config.h"
 
 namespace llvm {
@@ -37,6 +38,9 @@
 #include "swift/AST/KnownProtocols.def"
 };
 
+enum : unsigned { NumKnownProtocolKindBits =
+  countBitsUsed(static_cast<unsigned>(NumKnownProtocols - 1)) };
+
 /// Retrieve the name of the given known protocol.
 llvm::StringRef getProtocolName(KnownProtocolKind kind);
 
diff --git a/include/swift/AST/Ownership.h b/include/swift/AST/Ownership.h
index a3dbfe5..ac6599e 100644
--- a/include/swift/AST/Ownership.h
+++ b/include/swift/AST/Ownership.h
@@ -19,6 +19,7 @@
 #ifndef SWIFT_OWNERSHIP_H
 #define SWIFT_OWNERSHIP_H
 
+#include "swift/Basic/InlineBitfield.h"
 #include <stdint.h>
 
 namespace swift {
@@ -38,8 +39,13 @@
 
   /// \brief an 'unowned(unsafe)' reference
   Unmanaged,
+
+  Last_Kind = Unmanaged
 };
 
+enum : unsigned { NumReferenceOwnershipBits =
+  countBitsUsed(static_cast<unsigned>(ReferenceOwnership::Last_Kind)) };
+
 /// Different kinds of value ownership supported by Swift.
 enum class ValueOwnership : uint8_t {
   /// \brief the context-dependent default ownership (sometimes shared,
diff --git a/include/swift/AST/SILOptions.h b/include/swift/AST/SILOptions.h
index e0c0eb4..309c529 100644
--- a/include/swift/AST/SILOptions.h
+++ b/include/swift/AST/SILOptions.h
@@ -42,20 +42,6 @@
   /// The number of threads for multi-threaded code generation.
   int NumThreads = 0;
   
-  enum LinkingMode {
-    /// Skip SIL linking.
-    LinkNone,
-
-    /// Perform normal SIL linking.
-    LinkNormal,
-
-    /// Link all functions during SIL linking.
-    LinkAll
-  };
-
-  /// Controls how to perform SIL linking.
-  LinkingMode LinkMode = LinkNormal;
-
   /// Controls whether to pull in SIL from partial modules during the
   /// merge modules step. Could perhaps be merged with the link mode
   /// above but the interactions between all the flags are tricky.
diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h
index b731336..59c0c77 100644
--- a/include/swift/AST/TypeRepr.h
+++ b/include/swift/AST/TypeRepr.h
@@ -92,6 +92,11 @@
     NumTypes : 32
   );
 
+  SWIFT_INLINE_BITFIELD_FULL(SILBoxTypeRepr, TypeRepr, 32,
+    NumGenericArgs : NumPadBits,
+    NumFields : 32
+  );
+
   } Bits;
 
   TypeRepr(TypeReprKind K) {
@@ -996,29 +1001,44 @@
   friend class TypeRepr;
 };
 
+class SILBoxTypeReprField {
+  SourceLoc VarOrLetLoc;
+  llvm::PointerIntPair<TypeRepr*, 1, bool> FieldTypeAndMutable;
+
+public:
+  SILBoxTypeReprField(SourceLoc loc, bool isMutable, TypeRepr *fieldType)
+     : VarOrLetLoc(loc), FieldTypeAndMutable(fieldType, isMutable) {
+  }
+
+  SourceLoc getLoc() const { return VarOrLetLoc; }
+  TypeRepr *getFieldType() const { return FieldTypeAndMutable.getPointer(); }
+  bool isMutable() const { return FieldTypeAndMutable.getInt(); }
+};
+
 /// SIL-only TypeRepr for box types.
 ///
 /// Boxes are either concrete: { var Int, let String }
 /// or generic:                <T: Runcible> { var T, let String } <Int>
-class SILBoxTypeRepr : public TypeRepr {
+class SILBoxTypeRepr final : public TypeRepr,
+    private llvm::TrailingObjects<SILBoxTypeRepr,
+                                  SILBoxTypeReprField, TypeRepr *> {
+  friend TrailingObjects;
   GenericParamList *GenericParams;
   GenericEnvironment *GenericEnv = nullptr;
 
   SourceLoc LBraceLoc, RBraceLoc;
   SourceLoc ArgLAngleLoc, ArgRAngleLoc;
+
+  size_t numTrailingObjects(OverloadToken<SILBoxTypeReprField>) const {
+    return Bits.SILBoxTypeRepr.NumFields;
+  }
+  size_t numTrailingObjects(OverloadToken<TypeRepr*>) const {
+    return Bits.SILBoxTypeRepr.NumGenericArgs;
+  }
   
 public:
-  struct Field {
-    SourceLoc VarOrLetLoc;
-    bool Mutable;
-    TypeRepr *FieldType;
-  };
-  
-private:
-  ArrayRef<Field> Fields;
-  ArrayRef<TypeRepr *> GenericArgs;
-  
-public:
+  using Field = SILBoxTypeReprField;
+
   SILBoxTypeRepr(GenericParamList *GenericParams,
                  SourceLoc LBraceLoc, ArrayRef<Field> Fields,
                  SourceLoc RBraceLoc,
@@ -1026,9 +1046,17 @@
                  SourceLoc ArgRAngleLoc)
     : TypeRepr(TypeReprKind::SILBox),
       GenericParams(GenericParams), LBraceLoc(LBraceLoc), RBraceLoc(RBraceLoc),
-      ArgLAngleLoc(ArgLAngleLoc), ArgRAngleLoc(ArgRAngleLoc),
-      Fields(Fields), GenericArgs(GenericArgs)
-  {}  
+      ArgLAngleLoc(ArgLAngleLoc), ArgRAngleLoc(ArgRAngleLoc)
+  {
+    Bits.SILBoxTypeRepr.NumFields = Fields.size();
+    Bits.SILBoxTypeRepr.NumGenericArgs = GenericArgs.size();
+
+    std::uninitialized_copy(Fields.begin(), Fields.end(),
+                            getTrailingObjects<SILBoxTypeReprField>());
+
+    std::uninitialized_copy(GenericArgs.begin(), GenericArgs.end(),
+                            getTrailingObjects<TypeRepr*>());
+  }
   
   static SILBoxTypeRepr *create(ASTContext &C,
                       GenericParamList *GenericParams,
@@ -1043,10 +1071,12 @@
   }
   
   ArrayRef<Field> getFields() const {
-    return Fields;
+    return {getTrailingObjects<Field>(),
+            Bits.SILBoxTypeRepr.NumFields};
   }
   ArrayRef<TypeRepr *> getGenericArguments() const {
-    return GenericArgs;
+    return {getTrailingObjects<TypeRepr*>(),
+            Bits.SILBoxTypeRepr.NumGenericArgs};
   }
   
   GenericParamList *getGenericParams() const {
diff --git a/include/swift/Basic/OptimizationMode.h b/include/swift/Basic/OptimizationMode.h
index e57b8e6..9f1e6b9 100644
--- a/include/swift/Basic/OptimizationMode.h
+++ b/include/swift/Basic/OptimizationMode.h
@@ -13,6 +13,7 @@
 #ifndef SWIFT_BASIC_OPTIMIZATIONMODE_H
 #define SWIFT_BASIC_OPTIMIZATIONMODE_H
 
+#include "swift/Basic/InlineBitfield.h"
 #include "llvm/Support/DataTypes.h"
 
 namespace swift {
@@ -27,6 +28,9 @@
   LastMode = ForSize
 };
 
+enum : unsigned { NumOptimizationModeBits =
+  countBitsUsed(static_cast<unsigned>(OptimizationMode::LastMode)) };
+
 } // end namespace swift
 
 #endif // SWIFT_BASIC_OPTIMIZATIONMODE_H
diff --git a/include/swift/IDE/RefactoringKinds.def b/include/swift/IDE/RefactoringKinds.def
index 3e26049..cbb0e1e 100644
--- a/include/swift/IDE/RefactoringKinds.def
+++ b/include/swift/IDE/RefactoringKinds.def
@@ -10,6 +10,10 @@
 #define RANGE_REFACTORING(KIND, NAME, ID) SEMANTIC_REFACTORING(KIND, NAME, ID)
 #endif
 
+#ifndef INTERNAL_RANGE_REFACTORING
+#define INTERNAL_RANGE_REFACTORING(KIND, NAME, ID) RANGE_REFACTORING(KIND, NAME, ID)
+#endif
+
 #ifndef CURSOR_REFACTORING
 #define CURSOR_REFACTORING(KIND, NAME, ID) SEMANTIC_REFACTORING(KIND, NAME, ID)
 #endif
@@ -60,9 +64,14 @@
 
 RANGE_REFACTORING(ConvertToTernaryExpr, "Convert To Ternary Expression", convert.ternary.expr)
 
-RANGE_REFACTORING(ReplaceBodiesWithFatalError, "Replace function bodies with fatalError", replace.bodies.with.fatalError)
+// These internal refactorings are designed to be helpful for working on
+// the compiler/standard library, etc., but are likely to be just confusing and
+// noise for general development.
+
+INTERNAL_RANGE_REFACTORING(ReplaceBodiesWithFatalError, "Replace Function Bodies With 'fatalError()'", replace.bodies.with.fatalError)
 
 #undef CURSOR_REFACTORING
+#undef INTERNAL_RANGE_REFACTORING
 #undef RANGE_REFACTORING
 #undef SEMANTIC_REFACTORING
 #undef REFACTORING
diff --git a/include/swift/Migrator/EditorAdapter.h b/include/swift/Migrator/EditorAdapter.h
index b6a9ec4..1a00e50 100644
--- a/include/swift/Migrator/EditorAdapter.h
+++ b/include/swift/Migrator/EditorAdapter.h
@@ -51,6 +51,8 @@
   /// below. That doesn't handle duplicate or redundant changes.
   mutable llvm::SmallSet<Replacement, 32> Replacements;
 
+  bool CacheEnabled;
+
   /// A running transactional collection of basic edit operations.
   /// Clang uses this transaction concept to cancel a batch of edits due to
   /// incompatibilities, such as those due to macro expansions, but we don't
@@ -82,7 +84,7 @@
 public:
   EditorAdapter(swift::SourceManager &SwiftSrcMgr,
                 clang::SourceManager &ClangSrcMgr)
-    : SwiftSrcMgr(SwiftSrcMgr), ClangSrcMgr(ClangSrcMgr),
+    : SwiftSrcMgr(SwiftSrcMgr), ClangSrcMgr(ClangSrcMgr), CacheEnabled(true),
       Edits(clang::edit::Commit(ClangSrcMgr, clang::LangOptions())) {}
 
   /// Lookup the BufferID in the SwiftToClangBufferMap. If it doesn't exist,
@@ -128,6 +130,8 @@
   const clang::edit::Commit &getEdits() const {
     return Edits;
   }
+  void enableCache() { CacheEnabled = true; }
+  void disableCache() { CacheEnabled = false; }
 };
 
 } // end namespace migrator
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index e3ebc8e..4a2e739 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -243,9 +243,6 @@
   HelpText<"Limit the size of stack promoted objects to the provided number "
            "of bytes.">;
 
-def disable_sil_linking : Flag<["-"], "disable-sil-linking">,
-  HelpText<"Don't link SIL functions">;
-
 def dump_clang_diagnostics : Flag<["-"], "dump-clang-diagnostics">,
   HelpText<"Dump Clang diagnostics to stderr">;
 
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index a198c8c..37e5a11 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -799,10 +799,10 @@
 
   ConvertEscapeToNoEscapeInst *
   createConvertEscapeToNoEscape(SILLocation Loc, SILValue Op, SILType Ty,
-                                bool lifetimeGuaranteed) {
+                                bool isEscapedByUser, bool lifetimeGuaranteed) {
     return insert(ConvertEscapeToNoEscapeInst::create(
         getSILDebugLocation(Loc), Op, Ty, getFunction(), OpenedArchetypes,
-        lifetimeGuaranteed));
+        isEscapedByUser, lifetimeGuaranteed));
   }
 
   ThinFunctionToPointerInst *
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 4c18ec2..681891c 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -986,10 +986,11 @@
 void SILCloner<ImplClass>::visitConvertEscapeToNoEscapeInst(
     ConvertEscapeToNoEscapeInst *Inst) {
   getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
-  doPostProcess(
-      Inst, getBuilder().createConvertEscapeToNoEscape(
-                getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
-                getOpType(Inst->getType()), Inst->isLifetimeGuaranteed()));
+  doPostProcess(Inst,
+                getBuilder().createConvertEscapeToNoEscape(
+                    getOpLocation(Inst->getLoc()),
+                    getOpValue(Inst->getOperand()), getOpType(Inst->getType()),
+                    Inst->isEscapedByUser(), Inst->isLifetimeGuaranteed()));
 }
 
 template<typename ImplClass>
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index d8b5acc..cc356bc 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -3995,13 +3995,18 @@
   friend SILBuilder;
 
   bool lifetimeGuaranteed;
+  bool isEscaped; // Even if we can analyze this
+                        // instruction the user might have
+                        // escaped it.
 
   ConvertEscapeToNoEscapeInst(SILDebugLocation DebugLoc, SILValue Operand,
                               ArrayRef<SILValue> TypeDependentOperands,
-                              SILType Ty, bool isLifetimeGuaranteed)
+                              SILType Ty, bool isEscapedByUser,
+                              bool isLifetimeGuaranteed)
       : UnaryInstructionWithTypeDependentOperandsBase(
             DebugLoc, Operand, TypeDependentOperands, Ty),
-        lifetimeGuaranteed(isLifetimeGuaranteed) {
+        lifetimeGuaranteed(isLifetimeGuaranteed),
+        isEscaped(isEscapedByUser) {
     assert(!Operand->getType().castTo<SILFunctionType>()->isNoEscape());
     assert(Ty.castTo<SILFunctionType>()->isNoEscape());
   }
@@ -4009,11 +4014,17 @@
   static ConvertEscapeToNoEscapeInst *
   create(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
          SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes,
-         bool lifetimeGuaranteed);
+         bool isEscapedByUser, bool lifetimeGuaranteed);
 public:
   bool isLifetimeGuaranteed() const {
     return lifetimeGuaranteed;
   }
+
+  bool isEscapedByUser() const {
+    return isEscaped;
+  }
+
+  void setEscapedByUser(bool isEscaped = true) { this->isEscaped = isEscaped; }
 };
 
 /// ThinFunctionToPointerInst - Convert a thin function pointer to a
diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h
index a6760a6..66251e7 100644
--- a/include/swift/SIL/SILModule.h
+++ b/include/swift/SIL/SILModule.h
@@ -110,7 +110,15 @@
   using DefaultWitnessTableListType = llvm::ilist<SILDefaultWitnessTable>;
   using CoverageMapCollectionType =
       llvm::MapVector<StringRef, SILCoverageMap *>;
-  using LinkingMode = SILOptions::LinkingMode;
+
+  enum class LinkingMode : uint8_t {
+    /// Link functions with non-public linkage. Used by the mandatory pipeline.
+    LinkNormal,
+
+    /// Link all functions. Used by the performance pipeine.
+    LinkAll
+  };
+
   using ActionCallback = std::function<void()>;
 
 private:
@@ -499,7 +507,7 @@
   ///
   /// \return false if the linking failed.
   bool linkFunction(SILFunction *F,
-                    LinkingMode LinkAll = LinkingMode::LinkNormal);
+                    LinkingMode LinkMode = LinkingMode::LinkNormal);
 
   /// Check if a given function exists in any of the modules with a
   /// required linkage, i.e. it can be linked by linkFunction.
diff --git a/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h b/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h
index a950db4..7fc56cb 100644
--- a/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
@@ -34,103 +34,215 @@
   RetainObserveKindEnd
 };
 
-/// The SideEffectAnalysis provides information about side-effects of SIL
-/// functions. Side-effect information is provided per function and includes:
-/// Does the function read or write memory? Does the function retain or release
-/// objects? etc.
-/// For details see SideEffectAnalysis::FunctionEffects and
-/// SideEffectAnalysis::Effects.
-class SideEffectAnalysis : public BottomUpIPAnalysis {
-public:
+/// Generic base class for any bottom up analysis that summarizes per-function
+/// "effects" by first computing local effects, then propagating those effects
+/// bottom-up through the call graph.
+///
+/// FunctionEffects constraints:
+/// - void clear()
+/// - void setWorstEffects()
+/// - bool summarizeFunction(SILFunction *)
+/// - bool summarizeCall(FullApplySite)
+/// - bool mergeFrom(const FunctionSideEffects &)
+/// - bool mergeFromApply(const FunctionEffects &, FullApplySite)
+/// - void analyzeInstruction(SILInstruction *)
+template <typename FunctionEffects>
+class GenericFunctionEffectAnalysis : public BottomUpIPAnalysis {
 
-  using MemoryBehavior = SILInstruction::MemoryBehavior;
-  /// Set \p dest if \p src is set and return true if \p dest was not set
-  /// before.
-  static bool updateFlag(bool &dest, bool src) {
-    if (src && !dest) {
-      dest = src;
-      return true;
-    }
-    return false;
-  }
+  /// Stores the analysis data, e.g. side-effects, for a function.
+  struct FunctionInfo : public FunctionInfoBase<FunctionInfo> {
 
-  /// Side-effect information for the function (global effects) or a specific
-  /// parameter of the function. See FunctionEffects.
-  class Effects {
-    bool Reads = false;
-    bool Writes = false;
-    bool Retains = false;
-    bool Releases = false;
-    
-    /// Sets the most conservative effects.
-    void setWorstEffects() {
-      Reads = true;
-      Writes = true;
-      Retains = true;
-      Releases = true;
-    }
+    /// The function effects.
+    FunctionEffects functionEffects;
 
-    /// Clears all effects.
-    void clear() {
-      Reads = false;
-      Writes = false;
-      Retains = false;
-      Releases = false;
-    }
+    /// Back-link to the function.
+    SILFunction *F;
 
-    friend class SideEffectAnalysis;
-    
-  public:
-    
-    /// Does the function read from memory (excluding reads from locally
-    /// allocated memory)?
-    bool mayRead() const { return Reads; }
+    /// Used during recomputation to indicate if the side-effects of a caller
+    /// must be updated.
+    bool needUpdateCallers = false;
 
-    /// Does the function write to memory (excluding writes to locally
-    /// allocated memory)?
-    bool mayWrite() const { return Writes; }
-    
-    /// Does the function retain objects (excluding retains of locally
-    /// allocated objects)?
-    bool mayRetain() const { return Retains; }
+    FunctionInfo(SILFunction *F) : F(F) {}
 
-    /// Does the function release objects (excluding releases of locally
-    /// allocated objects)?
-    bool mayRelease() const { return Releases; }
-
-    /// Gets the memory behavior considering the global effects and
-    /// all parameter effects. If \p ScanKind equals ignoreRetains then retain
-    /// instructions are considered as side effects.
-    MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const {
-      if (mayRelease())
-        return MemoryBehavior::MayHaveSideEffects;
-      
-      if (ScanKind == RetainObserveKind::ObserveRetains && mayRetain())
-        return MemoryBehavior::MayHaveSideEffects;
-      
-      if (mayWrite())
-        return mayRead() ? MemoryBehavior::MayReadWrite :
-                           MemoryBehavior::MayWrite;
-      
-      if (mayRead())
-        return MemoryBehavior::MayRead;
-      
-      return MemoryBehavior::None;
-    }
-
-    /// Merge effects from \p RHS.
-    bool mergeFrom(const Effects &RHS) {
-      bool Changed = false;
-      Changed |= updateFlag(Reads, RHS.Reads);
-      Changed |= updateFlag(Writes, RHS.Writes);
-      Changed |= updateFlag(Retains, RHS.Retains);
-      Changed |= updateFlag(Releases, RHS.Releases);
-      return Changed;
-    }
+    /// Clears the analysis data on invalidation.
+    void clear() { functionEffects.clear(); }
   };
 
+  typedef BottomUpFunctionOrder<FunctionInfo> FunctionOrder;
+
+  enum {
+    /// The maximum call-graph recursion depth for recomputing the analysis.
+    /// This is a relatively small number to reduce compile time in case of
+    /// large cycles in the call-graph.
+    /// In case of no cycles, we should not hit this limit at all because the
+    /// pass manager processes functions in bottom-up order.
+    MaxRecursionDepth = 5
+  };
+
+  /// All the function effect information for the whole module.
+  llvm::DenseMap<SILFunction *, FunctionInfo *> functionInfoMap;
+
+  /// The allocator for the map of values in FunctionInfoMap.
+  llvm::SpecificBumpPtrAllocator<FunctionInfo> allocator;
+
+  /// Callee analysis, used for determining the callees at call sites.
+  BasicCalleeAnalysis *BCA;
+
+public:
+  GenericFunctionEffectAnalysis(AnalysisKind kind) : BottomUpIPAnalysis(kind) {}
+
+  const FunctionEffects &getEffects(SILFunction *F) {
+    FunctionInfo *functionInfo = getFunctionInfo(F);
+    if (!functionInfo->isValid())
+      recompute(functionInfo);
+    return functionInfo->functionEffects;
+  }
+
+  /// Get the merged effects of all callees at the given call site from the
+  /// callee's perspective (don't transform parameter effects).
+  void getCalleeEffects(FunctionEffects &calleeEffects,
+                        FullApplySite fullApply);
+
+  /// Get the merge effects of all callees at the given call site from the
+  /// caller's perspective. Parameter effects are translated into information
+  /// for the caller's arguments, and local effects are dropped.
+  void getCallSiteEffects(FunctionEffects &callEffects,
+                          FullApplySite fullApply) {
+    FunctionEffects calleeEffects;
+    getCalleeEffects(calleeEffects, fullApply);
+    callEffects.mergeFromApply(calleeEffects, fullApply);
+  }
+
+  virtual void initialize(SILPassManager *PM) override;
+
+  /// Invalidate all information in this analysis.
+  virtual void invalidate() override;
+
+  /// Invalidate all of the information for a specific function.
+  virtual void invalidate(SILFunction *F, InvalidationKind K) override;
+
+  /// Notify the analysis about a newly created function.
+  virtual void notifyAddFunction(SILFunction *F) override {}
+
+  /// Notify the analysis about a function which will be deleted from the
+  /// module.
+  virtual void notifyDeleteFunction(SILFunction *F) override {
+    invalidate(F, InvalidationKind::Nothing);
+  }
+
+  /// Notify the analysis about changed witness or vtables.
+  virtual void invalidateFunctionTables() override {}
+
+private:
+  /// Gets or creates FunctionEffects for \p F.
+  FunctionInfo *getFunctionInfo(SILFunction *F) {
+    FunctionInfo *&functionInfo = functionInfoMap[F];
+    if (!functionInfo) {
+      functionInfo = new (allocator.Allocate()) FunctionInfo(F);
+    }
+    return functionInfo;
+  }
+
+  /// Analyze the side-effects of a function, including called functions.
+  /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth
+  /// reaches MaxRecursionDepth.
+  void analyzeFunction(FunctionInfo *functionInfo, FunctionOrder &bottomUpOrder,
+                       int recursionDepth);
+
+  void analyzeCall(FunctionInfo *functionInfo, FullApplySite fullApply,
+                   FunctionOrder &bottomUpOrder, int recursionDepth);
+
+  /// Recomputes the side-effect information for the function \p Initial and
+  /// all called functions, up to a recursion depth of MaxRecursionDepth.
+  void recompute(FunctionInfo *initialInfo);
+};
+
+/// Set \p dest if \p src is set and return true if \p dest was not set
+/// before.
+static bool changedFlagByInPlaceOr(bool &dest, bool src) {
+  if (src && !dest) {
+    dest = src;
+    return true;
+  }
+  return false;
+}
+
+/// Side-effect information for the function (global effects) or a specific
+/// parameter of the function. See FunctionSideEffects.
+class FunctionSideEffectFlags {
+  friend class FunctionSideEffects;
+  using MemoryBehavior = SILInstruction::MemoryBehavior;
+
+  bool Reads = false;
+  bool Writes = false;
+  bool Retains = false;
+  bool Releases = false;
+
+  /// Sets the most conservative effects.
+  void setWorstEffects() {
+    Reads = true;
+    Writes = true;
+    Retains = true;
+    Releases = true;
+  }
+
+  /// Clears all effects.
+  void clear() {
+    Reads = false;
+    Writes = false;
+    Retains = false;
+    Releases = false;
+  }
+
+public:
+  /// Does the function read from memory (excluding reads from locally
+  /// allocated memory)?
+  bool mayRead() const { return Reads; }
+
+  /// Does the function write to memory (excluding writes to locally
+  /// allocated memory)?
+  bool mayWrite() const { return Writes; }
+
+  /// Does the function retain objects (excluding retains of locally
+  /// allocated objects)?
+  bool mayRetain() const { return Retains; }
+
+  /// Does the function release objects (excluding releases of locally
+  /// allocated objects)?
+  bool mayRelease() const { return Releases; }
+
+  /// Gets the memory behavior considering the global effects and
+  /// all parameter effects. If \p ScanKind equals ignoreRetains then retain
+  /// instructions are considered as side effects.
+  MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const {
+    if (mayRelease())
+      return MemoryBehavior::MayHaveSideEffects;
+
+    if (ScanKind == RetainObserveKind::ObserveRetains && mayRetain())
+      return MemoryBehavior::MayHaveSideEffects;
+
+    if (mayWrite())
+      return mayRead() ? MemoryBehavior::MayReadWrite
+                       : MemoryBehavior::MayWrite;
+
+    if (mayRead())
+      return MemoryBehavior::MayRead;
+
+    return MemoryBehavior::None;
+  }
+
+  /// Merge effects from \p RHS.
+  bool mergeFrom(const FunctionSideEffectFlags &RHS) {
+    bool Changed = false;
+    Changed |= changedFlagByInPlaceOr(Reads, RHS.Reads);
+    Changed |= changedFlagByInPlaceOr(Writes, RHS.Writes);
+    Changed |= changedFlagByInPlaceOr(Retains, RHS.Retains);
+    Changed |= changedFlagByInPlaceOr(Releases, RHS.Releases);
+    return Changed;
+  }
+
   friend raw_ostream &operator<<(raw_ostream &os,
-                                 const SideEffectAnalysis::Effects &Effects) {
+                                 const FunctionSideEffectFlags &Effects) {
     if (Effects.mayRead())
       os << 'r';
     if (Effects.mayWrite())
@@ -141,134 +253,169 @@
       os << '-';
     return os;
   }
+};
 
-  /// Summarizes the side-effects of a function. The side-effect information
-  /// is divided into global effects and effects for specific function
-  /// parameters.
-  /// If a side-effect can be associated to a specific function parameter, it is
-  /// not added to the global effects of the function. E.g. if a memory write is
-  /// only done through an @inout parameter, the mayWrite side-effect is only
-  /// accounted for this parameter.
-  /// Effects for a parameter make only sense if the parameter is implemented as
-  /// a pointer or contains a pointer:
-  /// *) The parameter is an address parameter, e.g. @out, @inout, etc.
-  /// *) The parameter is a reference
-  /// *) The parameter is a value type (e.g. struct) and contains a reference.
-  ///    In this case the effects refer to all references in the value type.
-  ///    E.g. if a struct contains 2 references, a mayWrite effect means that
-  ///    memory is written to one of the referenced objects (or to both).
-  class FunctionEffects {
-    
-    /// Side-effects which can be associated to a parameter.
-    llvm::SmallVector<Effects, 6> ParamEffects;
-    
-    /// All other side-effects which cannot be associated to a parameter.
-    Effects GlobalEffects;
-    
-    /// Side-effects on locally allocated storage. Such side-effects are not
-    /// relevant to optimizations. The LocalEffects are only used to return
-    /// "something" for local storage in getEffectsOn().
-    Effects LocalEffects;
-    
-    /// Does the function allocate objects, boxes, etc., i.e. everything which
-    /// has a reference count.
-    bool AllocsObjects = false;
-    
-    /// Can this function trap or exit the program in any way?
-    bool Traps = false;
-    
-    /// Does this function read a reference count other than with retain or
-    /// release instructions, e.g. isUnique?
-    bool ReadsRC = false;
-    
-    /// Returns the effects for an address or reference. This might be a
-    /// parameter, the LocalEffects or, if the value cannot be associated to one
-    /// of them, the GlobalEffects.
-    Effects *getEffectsOn(SILValue Addr);
-    
-    FunctionEffects(unsigned numParams) : ParamEffects(numParams) { }
+/// Summarizes the side-effects of a function. The side-effect information
+/// is divided into global effects and effects for specific function
+/// parameters.
+/// If a side-effect can be associated to a specific function parameter, it is
+/// not added to the global effects of the function. E.g. if a memory write is
+/// only done through an @inout parameter, the mayWrite side-effect is only
+/// accounted for this parameter.
+/// Effects for a parameter make only sense if the parameter is implemented as
+/// a pointer or contains a pointer:
+/// *) The parameter is an address parameter, e.g. @out, @inout, etc.
+/// *) The parameter is a reference
+/// *) The parameter is a value type (e.g. struct) and contains a reference.
+///    In this case the effects refer to all references in the value type.
+///    E.g. if a struct contains 2 references, a mayWrite effect means that
+///    memory is written to one of the referenced objects (or to both).
+class FunctionSideEffects {
+  using MemoryBehavior = SILInstruction::MemoryBehavior;
 
-    /// Sets the most conservative effects, if we don't know anything about the
-    /// function.
-    void setWorstEffects() {
-      GlobalEffects.setWorstEffects();
-      AllocsObjects = true;
-      Traps = true;
-      ReadsRC = true;
-    }
-    
-    /// Clears all effects.
-    void clear() {
-      GlobalEffects.clear();
-      for (Effects &PE : ParamEffects)
-        PE.clear();
-      AllocsObjects = false;
-      Traps = false;
-      ReadsRC = false;
-    }
-  
-    /// Merge the flags from \p RHS.
-    bool mergeFlags(const FunctionEffects &RHS) {
-      bool Changed = false;
-      Changed |= updateFlag(Traps, RHS.Traps);
-      Changed |= updateFlag(AllocsObjects, RHS.AllocsObjects);
-      Changed |= updateFlag(ReadsRC, RHS.ReadsRC);
-      return Changed;
-    }
-    
-    friend class SideEffectAnalysis;
-    
-  public:
-    
-    /// Constructs "empty" function effects.
-    FunctionEffects() { }
+  /// Side-effects which can be associated to a parameter.
+  llvm::SmallVector<FunctionSideEffectFlags, 6> ParamEffects;
 
-    /// Does the function allocate objects, boxes, etc., i.e. everything which
-    /// has a reference count.
-    bool mayAllocObjects() const { return AllocsObjects; }
+  /// All other side-effects which cannot be associated to a parameter.
+  FunctionSideEffectFlags GlobalEffects;
 
-    /// Can this function trap or exit the program in any way?
-    bool mayTrap() const { return Traps; }
+  /// Side-effects on locally allocated storage. Such side-effects are not
+  /// relevant to optimizations. The LocalEffects are only used to return
+  /// "something" for local storage in getEffectsOn().
+  FunctionSideEffectFlags LocalEffects;
 
-    /// Does this function read a reference count other than with retain or
-    /// release instructions, e.g. isUnique?
-    bool mayReadRC() const { return ReadsRC; }
+  /// Does the function allocate objects, boxes, etc., i.e. everything which
+  /// has a reference count.
+  bool AllocsObjects = false;
 
-    /// Gets the memory behavior considering the global effects and
-    /// all parameter effects. If \p ScanKind equals ignoreRetains then retain
-    /// instructions are considered as side effects.
-    MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const;
+  /// Can this function trap or exit the program in any way?
+  bool Traps = false;
 
-    /// Get the global effects for the function. These are effects which cannot
-    /// be associated to a specific parameter, e.g. writes to global variables
-    /// or writes to unknown pointers.
-    const Effects &getGlobalEffects() const { return GlobalEffects; }
-    
-    /// Get the array of parameter effects. If a side-effect can be associated
-    /// to a specific parameter, it is contained here instead of the global
-    /// effects.
-    /// Note that if a parameter effect is mayRelease(), it means that the
-    /// global function effects can be anything, because the destructor of an
-    /// object can have arbitrary side effects.
-    ArrayRef<Effects> getParameterEffects() const { return ParamEffects; }
-    
-    /// Merge effects from \p RHS.
-    bool mergeFrom(const FunctionEffects &RHS);
+  /// Does this function read a reference count other than with retain or
+  /// release instructions, e.g. isUnique?
+  bool ReadsRC = false;
 
-    /// Merge effects from a function apply site within the function.
-    bool mergeFromApply(const FunctionEffects &CalleeEffects,
-                        SILInstruction *FAS);
+  /// Returns the effects for an address or reference. This might be a
+  /// parameter, the LocalEffects or, if the value cannot be associated to one
+  /// of them, the GlobalEffects.
+  FunctionSideEffectFlags *getEffectsOn(SILValue Addr);
 
-    /// Merge effects from an apply site within the function.
-    bool mergeFromApply(const FunctionEffects &CalleeEffects,
-                        FullApplySite FAS);
-    
-    /// Print the function effects.
-    void dump() const;
-  };
+public:
+  /// Constructs "empty" function effects. This effects object can later be
+  /// populated by summarizeFunction or summarizeCall.
+  FunctionSideEffects() {}
+
+  /// Sets the most conservative effects, if we don't know anything about the
+  /// function.
+  void setWorstEffects() {
+    GlobalEffects.setWorstEffects();
+    AllocsObjects = true;
+    Traps = true;
+    ReadsRC = true;
+  }
+
+  /// Clears all effects.
+  void clear() {
+    ParamEffects.clear();
+    GlobalEffects.clear();
+    AllocsObjects = false;
+    Traps = false;
+    ReadsRC = false;
+  }
+
+  /// Merge the flags from \p RHS.
+  bool mergeFlags(const FunctionSideEffects &RHS) {
+    bool Changed = false;
+    Changed |= changedFlagByInPlaceOr(Traps, RHS.Traps);
+    Changed |= changedFlagByInPlaceOr(AllocsObjects, RHS.AllocsObjects);
+    Changed |= changedFlagByInPlaceOr(ReadsRC, RHS.ReadsRC);
+    return Changed;
+  }
+
+  // Summarize the given function's effects using this FunctionSideEffects
+  // object.
+  //
+  // Return true if the function's' effects have been fully summarized without
+  // visiting it's body.
+  bool summarizeFunction(SILFunction *F);
+
+  /// Summarize the callee side effects of a call instruction using this
+  /// FunctionSideEffects object without analyzing the callee function bodies or
+  /// scheduling the callees for bottom-up propagation.
+  ///
+  /// The side effects are represented from the callee's perspective. Parameter
+  /// effects are not translated into information on the caller's argument, and
+  /// local effects are not dropped.
+  ///
+  /// Return true if this call-site's effects are summarized without visiting
+  /// the callee.
+  bool summarizeCall(FullApplySite fullApply);
+
+  /// Merge effects directly from \p RHS.
+  bool mergeFrom(const FunctionSideEffects &RHS);
+
+  /// Merge the effects represented in CalleeEffects into this
+  /// FunctionSideEffects object. CalleeEffects must correspond to at least one
+  /// callee at the apply site `FAS`. Merging drops any local effects, and
+  /// translates parameter effects into effects on the caller-side arguments.
+  ///
+  /// The full caller-side effects at a call site can be obtained with
+  /// SideEffectsAnalysis::getCallSiteEffects().
+  bool mergeFromApply(const FunctionSideEffects &CalleeEffects,
+                      FullApplySite FAS);
+
+  /// Analyze the side-effects of a single SIL instruction \p I.
+  /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth
+  /// reaches MaxRecursionDepth.
+  void analyzeInstruction(SILInstruction *I);
+
+  /// Print the function effects.
+  void dump() const;
+
+  /// Does the function allocate objects, boxes, etc., i.e. everything which
+  /// has a reference count.
+  bool mayAllocObjects() const { return AllocsObjects; }
+
+  /// Can this function trap or exit the program in any way?
+  bool mayTrap() const { return Traps; }
+
+  /// Does this function read a reference count other than with retain or
+  /// release instructions, e.g. isUnique?
+  bool mayReadRC() const { return ReadsRC; }
+
+  /// Gets the memory behavior considering the global effects and
+  /// all parameter effects. If \p ScanKind equals ignoreRetains then retain
+  /// instructions are considered as side effects.
+  MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const;
+
+  /// Get the global effects for the function. These are effects which cannot
+  /// be associated to a specific parameter, e.g. writes to global variables
+  /// or writes to unknown pointers.
+  const FunctionSideEffectFlags &getGlobalEffects() const {
+    return GlobalEffects;
+  }
+
+  /// Get the array of parameter effects. If a side-effect can be associated
+  /// to a specific parameter, it is contained here instead of the global
+  /// effects.
+  /// Note that if a parameter effect is mayRelease(), it means that the
+  /// global function effects can be anything, because the destructor of an
+  /// object can have arbitrary side effects.
+  ArrayRef<FunctionSideEffectFlags> getParameterEffects() const {
+    return ParamEffects;
+  }
+
+protected:
+  /// Set the side-effects of a function, which has an @effects attribute.
+  /// Returns true if \a F has an @effects attribute which could be handled.
+  bool setDefinedEffects(SILFunction *F);
+
+  /// Set the side-effects of a semantic call.
+  /// Return true if \p ASC could be handled.
+  bool setSemanticEffects(ArraySemanticsCall ASC);
 
   friend raw_ostream &operator<<(raw_ostream &os,
-                          const SideEffectAnalysis::FunctionEffects &Effects) {
+                                 const FunctionSideEffects &Effects) {
     os << "func=" << Effects.getGlobalEffects();
     int ParamIdx = 0;
     for (auto &E : Effects.getParameterEffects()) {
@@ -282,126 +429,25 @@
       os << ";readrc";
     return os;
   }
+};
 
-private:
-
-  /// Stores the analysis data, i.e. the side-effects, for a function.
-  struct FunctionInfo : public FunctionInfoBase<FunctionInfo> {
-
-    /// The side-effects of the function.
-    FunctionEffects FE;
-
-    /// Back-link to the function.
-    SILFunction *F;
-
-    /// Used during recomputation to indicate if the side-effects of a caller
-    /// must be updated.
-    bool NeedUpdateCallers = false;
-
-    FunctionInfo(SILFunction *F) :
-      FE(F->empty() ? 0 : F->getArguments().size()), F(F) { }
-
-    /// Clears the analysis data on invalidation.
-    void clear() { FE.clear(); }
-  };
-  
-  typedef BottomUpFunctionOrder<FunctionInfo> FunctionOrder;
-
-  enum {
-    /// The maximum call-graph recursion depth for recomputing the analysis.
-    /// This is a relatively small number to reduce compile time in case of
-    /// large cycles in the call-graph.
-    /// In case of no cycles, we should not hit this limit at all because the
-    /// pass manager processes functions in bottom-up order.
-    MaxRecursionDepth = 5
-  };
-
-  /// All the side-effect information for the whole module.
-  llvm::DenseMap<SILFunction *, FunctionInfo *> Function2Info;
-  
-  /// The allocator for the map values in Function2Info.
-  llvm::SpecificBumpPtrAllocator<FunctionInfo> Allocator;
-  
-  /// Callee analysis, used for determining the callees at call sites.
-  BasicCalleeAnalysis *BCA;
-
-  /// Get the side-effects of a function, which has an @effects attribute.
-  /// Returns true if \a F has an @effects attribute which could be handled.
-  static bool getDefinedEffects(FunctionEffects &Effects, SILFunction *F);
-  
-  /// Get the side-effects of a semantic call.
-  /// Return true if \p ASC could be handled.
-  bool getSemanticEffects(FunctionEffects &Effects, ArraySemanticsCall ASC);
-  
-  /// Analyze the side-effects of a function, including called functions.
-  /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth
-  /// reaches MaxRecursionDepth.
-  void analyzeFunction(FunctionInfo *FInfo,
-                       FunctionOrder &BottomUpOrder,
-                       int RecursionDepth);
-
-  /// Analyze the side-effects of a single SIL instruction \p I.
-  /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth
-  /// reaches MaxRecursionDepth.
-  void analyzeInstruction(FunctionInfo *FInfo,
-                          SILInstruction *I,
-                          FunctionOrder &BottomUpOrder,
-                          int RecursionDepth);
-
-  /// Gets or creates FunctionEffects for \p F.
-  FunctionInfo *getFunctionInfo(SILFunction *F) {
-    FunctionInfo *&FInfo = Function2Info[F];
-    if (!FInfo) {
-      FInfo = new (Allocator.Allocate()) FunctionInfo(F);
-    }
-    return FInfo;
-  }
-
-  /// Recomputes the side-effect information for the function \p Initial and
-  /// all called functions, up to a recursion depth of MaxRecursionDepth.
-  void recompute(FunctionInfo *Initial);
-
+/// The SideEffectAnalysis provides information about side-effects of SIL
+/// functions. Side-effect information is provided per function and includes:
+/// Does the function read or write memory? Does the function retain or release
+/// objects? etc.
+/// For details see FunctionSideEffects.
+class SideEffectAnalysis
+    : public GenericFunctionEffectAnalysis<FunctionSideEffects> {
 public:
   SideEffectAnalysis()
-      : BottomUpIPAnalysis(AnalysisKind::SideEffect) {}
+      : GenericFunctionEffectAnalysis<FunctionSideEffects>(
+            AnalysisKind::SideEffect) {}
 
   static bool classof(const SILAnalysis *S) {
     return S->getKind() == AnalysisKind::SideEffect;
   }
-  
-  virtual void initialize(SILPassManager *PM) override;
-  
-  /// Get the side-effects of a function.
-  const FunctionEffects &getEffects(SILFunction *F) {
-    FunctionInfo *FInfo = getFunctionInfo(F);
-    if (!FInfo->isValid())
-      recompute(FInfo);
-    return FInfo->FE;
-  }
-
-  /// Get the side-effects of a call site.
-  void getEffects(FunctionEffects &ApplyEffects, FullApplySite FAS);
-  
-  /// Invalidate all information in this analysis.
-  virtual void invalidate() override;
-  
-  /// Invalidate all of the information for a specific function.
-  virtual void invalidate(SILFunction *F, InvalidationKind K)  override;
-
-  /// Notify the analysis about a newly created function.
-  virtual void notifyAddFunction(SILFunction *F) override { }
-
-  /// Notify the analysis about a function which will be deleted from the
-  /// module.
-  virtual void notifyDeleteFunction(SILFunction *F) override {
-    invalidate(F, InvalidationKind::Nothing);
-  }
-
-  /// Notify the analysis about changed witness or vtables.
-  virtual void invalidateFunctionTables() override { }
 };
 
 } // end namespace swift
 
-#endif
-
+#endif // SWIFT_SILOPTIMIZER_ANALYSIS_SIDEEFFECTANALYSIS_H_
diff --git a/include/swift/SILOptimizer/PassManager/Passes.def b/include/swift/SILOptimizer/PassManager/Passes.def
index c74bf64..a5062e5 100644
--- a/include/swift/SILOptimizer/PassManager/Passes.def
+++ b/include/swift/SILOptimizer/PassManager/Passes.def
@@ -90,6 +90,8 @@
      "Captured Constant Propagation")
 PASS(ClosureSpecializer, "closure-specialize",
      "Closure Specialization on Constant Function Arguments")
+PASS(ClosureLifetimeFixup, "closure-lifetime-fixup",
+     "Closure Lifetime Fixup")
 PASS(CodeSinking, "code-sinking",
      "Code Sinking")
 PASS(ComputeDominanceInfo, "compute-dominance-info",
@@ -226,20 +228,22 @@
      "Late SIL release Hoisting Preserving Epilogues")
 IRGEN_PASS(LoadableByAddress, "loadable-address",
      "SIL Large Loadable type by-address lowering.")
+PASS(MandatorySILLinker, "mandatory-linker",
+     "Deserialize all referenced SIL functions that are shared or transparent")
+PASS(PerformanceSILLinker, "performance-linker",
+     "Deserialize all referenced SIL functions")
 PASS(RemovePins, "remove-pins",
      "Remove SIL pin/unpin pairs")
 PASS(TempRValueOpt, "temp-rvalue-opt",
      "Remove short-lived immutable temporary copies")
 PASS(SideEffectsDumper, "side-effects-dump",
      "Print Side-Effect Information for all Functions")
-PASS(SILCleanup, "cleanup",
-     "SIL Cleanup Preparation for IRGen")
+PASS(IRGenPrepare, "irgen-prepare",
+     "Cleanup SIL in preparation for IRGen")
 PASS(SILCombine, "sil-combine",
      "Combine SIL Instructions via Peephole Optimization")
 PASS(SILDebugInfoGenerator, "sil-debuginfo-gen",
      "Generate Debug Information with Source Locations into Textual SIL")
-PASS(SILLinker, "linker",
-     "Link all SIL Referenced within the Module via Deserialization")
 PASS(SROA, "sroa",
      "Scalar Replacement of Aggregate Stack Objects")
 PASS(SROABBArgs, "sroa-bb-args",
diff --git a/include/swift/Sema/TypeCheckRequestKinds.def b/include/swift/Sema/TypeCheckRequestKinds.def
index d7c3536..e783285 100644
--- a/include/swift/Sema/TypeCheckRequestKinds.def
+++ b/include/swift/Sema/TypeCheckRequestKinds.def
@@ -45,10 +45,6 @@
 /// Compute the set of inherited protocols for a given protocol.
 TYPE_CHECK_REQUEST(InheritedProtocols, Protocol)
 
-/// Partially resolve a type, forming enough of its structure to make
-/// structural queries but not determining correctness.
-TYPE_CHECK_REQUEST(ResolveTypeRepr, TypeResolution)
-
 /// Resolve the given type declaration to the requested type
 /// resolution stage.
 TYPE_CHECK_REQUEST(ResolveTypeDecl, TypeDeclResolution)
diff --git a/include/swift/Strings.h b/include/swift/Strings.h
index 40afd01..4d02d9d 100644
--- a/include/swift/Strings.h
+++ b/include/swift/Strings.h
@@ -16,73 +16,79 @@
 namespace swift {
 
 /// The extension for serialized modules.
-static const char SERIALIZED_MODULE_EXTENSION[] = "swiftmodule";
+constexpr static const char SERIALIZED_MODULE_EXTENSION[] = "swiftmodule";
 /// The extension for serialized documentation comments.
-static const char SERIALIZED_MODULE_DOC_EXTENSION[] = "swiftdoc";
+constexpr static const char SERIALIZED_MODULE_DOC_EXTENSION[] = "swiftdoc";
 /// The extension for PCH files.
-static const char PCH_EXTENSION[] = "pch";
+constexpr static const char PCH_EXTENSION[] = "pch";
 /// The extension for replacement map files.
-static const char REMAP_EXTENSION[] = "remap";
+constexpr static const char REMAP_EXTENSION[] = "remap";
 /// The extension for SIL files.
-static const char SIL_EXTENSION[] = "sil";
+constexpr static const char SIL_EXTENSION[] = "sil";
 /// The extension for SIB files.
-static const char SIB_EXTENSION[] = "sib";
+constexpr static const char SIB_EXTENSION[] = "sib";
 /// The extension for LLVM IR files.
-static const char LLVM_BC_EXTENSION[] = "bc";
-static const char LLVM_IR_EXTENSION[] = "ll";
+constexpr static const char LLVM_BC_EXTENSION[] = "bc";
+constexpr static const char LLVM_IR_EXTENSION[] = "ll";
 /// The name of the standard library, which is a reserved module name.
-static const char STDLIB_NAME[] = "Swift";
+constexpr static const char STDLIB_NAME[] = "Swift";
 /// The name of the Onone support library, which is a reserved module name.
-static const char SWIFT_ONONE_SUPPORT[] = "SwiftOnoneSupport";
+constexpr static const char SWIFT_ONONE_SUPPORT[] = "SwiftOnoneSupport";
 /// The name of the SwiftShims module, which contains private stdlib decls.
-static const char SWIFT_SHIMS_NAME[] = "SwiftShims";
+constexpr static const char SWIFT_SHIMS_NAME[] = "SwiftShims";
 /// The name of the Builtin module, which contains Builtin functions.
-static const char BUILTIN_NAME[] = "Builtin";
+constexpr static const char BUILTIN_NAME[] = "Builtin";
 /// The prefix of module names used by LLDB to capture Swift expressions
-static const char LLDB_EXPRESSIONS_MODULE_NAME_PREFIX[] = "__lldb_expr_";
+constexpr static const char LLDB_EXPRESSIONS_MODULE_NAME_PREFIX[] =
+    "__lldb_expr_";
 
 /// The name of the fake module used to hold imported Objective-C things.
-static const char MANGLING_MODULE_OBJC[] = "__C";
+constexpr static const char MANGLING_MODULE_OBJC[] = "__C";
 /// The name of the fake module used to hold synthesized ClangImporter things.
-static const char MANGLING_MODULE_CLANG_IMPORTER[] = "__C_Synthesized";
+constexpr static const char MANGLING_MODULE_CLANG_IMPORTER[] =
+    "__C_Synthesized";
 
 /// The name of the Builtin type prefix
-static const char BUILTIN_TYPE_NAME_PREFIX[] = "Builtin.";
+constexpr static const char BUILTIN_TYPE_NAME_PREFIX[] = "Builtin.";
 /// The name of the Builtin type for Int
-static const char BUILTIN_TYPE_NAME_INT[] = "Builtin.Int";
+constexpr static const char BUILTIN_TYPE_NAME_INT[] = "Builtin.Int";
 /// The name of the Builtin type for Int8
-static const char BUILTIN_TYPE_NAME_INT8[] = "Builtin.Int8";
+constexpr static const char BUILTIN_TYPE_NAME_INT8[] = "Builtin.Int8";
 /// The name of the Builtin type for Int16
-static const char BUILTIN_TYPE_NAME_INT16[] = "Builtin.Int16";
+constexpr static const char BUILTIN_TYPE_NAME_INT16[] = "Builtin.Int16";
 /// The name of the Builtin type for Int32
-static const char BUILTIN_TYPE_NAME_INT32[] = "Builtin.Int32";
+constexpr static const char BUILTIN_TYPE_NAME_INT32[] = "Builtin.Int32";
 /// The name of the Builtin type for Int64
-static const char BUILTIN_TYPE_NAME_INT64[] = "Builtin.Int64";
+constexpr static const char BUILTIN_TYPE_NAME_INT64[] = "Builtin.Int64";
 /// The name of the Builtin type for Int128
-static const char BUILTIN_TYPE_NAME_INT128[] = "Builtin.Int128";
+constexpr static const char BUILTIN_TYPE_NAME_INT128[] = "Builtin.Int128";
 /// The name of the Builtin type for Int256
-static const char BUILTIN_TYPE_NAME_INT256[] = "Builtin.Int256";
+constexpr static const char BUILTIN_TYPE_NAME_INT256[] = "Builtin.Int256";
 /// The name of the Builtin type for Int512
-static const char BUILTIN_TYPE_NAME_INT512[] = "Builtin.Int512";
+constexpr static const char BUILTIN_TYPE_NAME_INT512[] = "Builtin.Int512";
 /// The name of the Builtin type for Float
-static const char BUILTIN_TYPE_NAME_FLOAT[] = "Builtin.Float";
+constexpr static const char BUILTIN_TYPE_NAME_FLOAT[] = "Builtin.Float";
 /// The name of the Builtin type for NativeObject
-static const char BUILTIN_TYPE_NAME_NATIVEOBJECT[] = "Builtin.NativeObject";
+constexpr static const char BUILTIN_TYPE_NAME_NATIVEOBJECT[] =
+    "Builtin.NativeObject";
 /// The name of the Builtin type for BridgeObject
-static const char BUILTIN_TYPE_NAME_BRIDGEOBJECT[] = "Builtin.BridgeObject";
+constexpr static const char BUILTIN_TYPE_NAME_BRIDGEOBJECT[] =
+    "Builtin.BridgeObject";
 /// The name of the Builtin type for RawPointer
-static const char BUILTIN_TYPE_NAME_RAWPOINTER[] = "Builtin.RawPointer";
+constexpr static const char BUILTIN_TYPE_NAME_RAWPOINTER[] =
+    "Builtin.RawPointer";
 /// The name of the Builtin type for UnsafeValueBuffer
-static const char BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER[] = "Builtin.UnsafeValueBuffer";
+constexpr static const char BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER[] =
+    "Builtin.UnsafeValueBuffer";
 /// The name of the Builtin type for UnknownObject
-static const char BUILTIN_TYPE_NAME_UNKNOWNOBJECT[] = "Builtin.UnknownObject";
+constexpr static const char BUILTIN_TYPE_NAME_UNKNOWNOBJECT[] =
+    "Builtin.UnknownObject";
 /// The name of the Builtin type for Vector
-static const char BUILTIN_TYPE_NAME_VEC[] = "Builtin.Vec";
+constexpr static const char BUILTIN_TYPE_NAME_VEC[] = "Builtin.Vec";
 /// The name of the Builtin type for SILToken
-static const char BUILTIN_TYPE_NAME_SILTOKEN[] = "Builtin.SILToken";
+constexpr static const char BUILTIN_TYPE_NAME_SILTOKEN[] = "Builtin.SILToken";
 /// The name of the Builtin type for Word
-static const char BUILTIN_TYPE_NAME_WORD[] = "Builtin.Word";
-
+constexpr static const char BUILTIN_TYPE_NAME_WORD[] = "Builtin.Word";
 } // end namespace swift
 
 #endif // SWIFT_STRINGS_H
diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp
index 1d0861d..4fedbe7 100644
--- a/lib/AST/ASTWalker.cpp
+++ b/lib/AST/ASTWalker.cpp
@@ -1705,7 +1705,7 @@
 
 bool Traversal::visitSILBoxTypeRepr(SILBoxTypeRepr *T) {
   for (auto &field : T->getFields()) {
-    if (doIt(field.FieldType))
+    if (doIt(field.getFieldType()))
       return true;
   }
   for (auto &arg : T->getGenericArguments()) {
diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp
index 671b16c..a64b887 100644
--- a/lib/AST/Attr.cpp
+++ b/lib/AST/Attr.cpp
@@ -370,7 +370,7 @@
 
   case DAK_Alignment:
     Printer.printAttrName("@_alignment");
-    Printer << "(" << cast<AlignmentAttr>(this)->Value << ")";
+    Printer << "(" << cast<AlignmentAttr>(this)->getValue() << ")";
     break;
 
   case DAK_SILGenName:
@@ -664,17 +664,17 @@
     NameData = name->getOpaqueValue();
 
     // Store location information.
-    ObjCAttrBits.HasTrailingLocationInfo = true;
+    Bits.ObjCAttr.HasTrailingLocationInfo = true;
     getTrailingLocations()[0] = parenRange.Start;
     getTrailingLocations()[1] = parenRange.End;
     std::memcpy(getTrailingLocations().slice(2).data(), nameLocs.data(),
                 nameLocs.size() * sizeof(SourceLoc));
   } else {
-    ObjCAttrBits.HasTrailingLocationInfo = false;
+    Bits.ObjCAttr.HasTrailingLocationInfo = false;
   }
 
-  ObjCAttrBits.ImplicitName = false;
-  ObjCAttrBits.Swift3Inferred = false;
+  Bits.ObjCAttr.ImplicitName = false;
+  Bits.ObjCAttr.Swift3Inferred = false;
 }
 
 ObjCAttr *ObjCAttr::create(ASTContext &Ctx, Optional<ObjCSelector> name,
@@ -865,17 +865,20 @@
                                bool exported,
                                SpecializationKind kind)
     : DeclAttribute(DAK_Specialize, atLoc, range, /*Implicit=*/false),
-      numRequirements(0), trailingWhereClause(clause),
-      kind(kind), exported(exported) {
+      trailingWhereClause(clause) {
+  Bits.SpecializeAttr.exported = exported;
+  Bits.SpecializeAttr.kind = unsigned(kind);
+  Bits.SpecializeAttr.numRequirements = 0;
 }
 
 SpecializeAttr::SpecializeAttr(SourceLoc atLoc, SourceRange range,
                                ArrayRef<Requirement> requirements,
                                bool exported,
                                SpecializationKind kind)
-    : DeclAttribute(DAK_Specialize, atLoc, range, /*Implicit=*/false),
-      numRequirements(0), kind(kind), exported(exported) {
-  numRequirements = requirements.size();
+    : DeclAttribute(DAK_Specialize, atLoc, range, /*Implicit=*/false) {
+  Bits.SpecializeAttr.exported = exported;
+  Bits.SpecializeAttr.kind = unsigned(kind);
+  Bits.SpecializeAttr.numRequirements = requirements.size();
   std::copy(requirements.begin(), requirements.end(), getRequirementsData());
 }
 
@@ -886,7 +889,7 @@
   assert(requirements.size() <= numClauseRequirements);
   if (!numClauseRequirements)
     return;
-  numRequirements = requirements.size();
+  Bits.SpecializeAttr.numRequirements = requirements.size();
   std::copy(requirements.begin(), requirements.end(), getRequirementsData());
 }
 
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index 6d2a220..0e5b40b 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -738,6 +738,31 @@
   return builder.build(Id);
 }
 
+static ValueDecl *getBeginUnpairedAccessOperation(ASTContext &Context,
+                                                  Identifier Id) {
+  BuiltinGenericSignatureBuilder builder(Context);
+  builder.addParameter(makeConcrete(Context.TheRawPointerType));
+  builder.addParameter(makeConcrete(Context.TheRawPointerType));
+  builder.addParameter(makeMetatype(makeGenericParam(0)));
+  builder.setResult(makeConcrete(Context.TheEmptyTupleType));
+  return builder.build(Id);
+}
+
+static ValueDecl *
+getPerformInstantaneousReadAccessOperation(ASTContext &Context,
+                                           Identifier Id) {
+  BuiltinGenericSignatureBuilder builder(Context);
+  builder.addParameter(makeConcrete(Context.TheRawPointerType));
+  builder.addParameter(makeMetatype(makeGenericParam(0)));
+  builder.setResult(makeConcrete(Context.TheEmptyTupleType));
+  return builder.build(Id);
+}
+
+static ValueDecl *getEndUnpairedAccessOperation(ASTContext &Context,
+                                                Identifier Id) {
+  return getBuiltinFunction(Id, { Context.TheRawPointerType },
+                                Context.TheEmptyTupleType);
+}
 static ValueDecl *getSizeOrAlignOfOperation(ASTContext &Context,
                                             Identifier Id) {
   BuiltinGenericSignatureBuilder builder(Context);
@@ -1644,6 +1669,18 @@
     if (Types.size() != 1) return nullptr;
     return getGetTailAddrOperation(Context, Id, Types[0]);
 
+  case BuiltinValueKind::PerformInstantaneousReadAccess:
+    if (!Types.empty()) return nullptr;
+      return getPerformInstantaneousReadAccessOperation(Context, Id);
+
+  case BuiltinValueKind::BeginUnpairedModifyAccess:
+    if (!Types.empty()) return nullptr;
+    return getBeginUnpairedAccessOperation(Context, Id);
+
+  case BuiltinValueKind::EndUnpairedAccess:
+    if (!Types.empty()) return nullptr;
+    return getEndUnpairedAccessOperation(Context, Id);
+
 #define BUILTIN(id, name, Attrs)
 #define BUILTIN_BINARY_OPERATION(id, name, attrs, overload)  case BuiltinValueKind::id:
 #include "swift/AST/Builtins.def"
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index ed4d355..6293513 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -2259,9 +2259,24 @@
   llvm_unreachable("unknown access level");
 }
 
-void ValueDecl::copyFormalAccessFrom(ValueDecl *source) {
+void ValueDecl::copyFormalAccessFrom(const ValueDecl *source,
+                                     bool sourceIsParentContext) {
   if (!hasAccess()) {
-    setAccess(source->getFormalAccess());
+    AccessLevel access = source->getFormalAccess();
+
+    // To make something have the same access as a 'private' parent, it has to
+    // be 'fileprivate' or greater.
+    if (sourceIsParentContext && access == AccessLevel::Private)
+      access = AccessLevel::FilePrivate;
+
+    // Only certain declarations can be 'open'.
+    if (access == AccessLevel::Open && !isPotentiallyOverridable()) {
+      assert(!isa<ClassDecl>(this) &&
+             "copying 'open' onto a class has complications");
+      access = AccessLevel::Public;
+    }
+
+    setAccess(access);
   }
 
   // Inherit the @usableFromInline attribute.
@@ -2816,7 +2831,7 @@
   setHasDestructor();
 
   // Propagate access control and versioned-ness.
-  DD->copyFormalAccessFrom(this);
+  DD->copyFormalAccessFrom(this, /*sourceIsParentContext*/true);
 
   // Wire up generic environment of DD.
   DD->setGenericEnvironment(getGenericEnvironmentOfContext());
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index 77723d5..8edf627 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -345,17 +345,30 @@
   auto genericParams = getGenericParams();
   unsigned curGenericParamIdx = 0, numGenericParams = genericParams.size();
 
-  // Figure out which generic parameters are complete.
-  SmallVector<bool, 4> genericParamsAreConcrete(genericParams.size(), false);
+  // Figure out which generic parameters are concrete or same-typed to another
+  // generic parameter.
+  auto genericParamsAreNonCanonical =
+    SmallVector<bool, 4>(genericParams.size(), false);
   for (auto req : reqs) {
     if (req.getKind() != RequirementKind::SameType) continue;
-    if (req.getSecondType()->isTypeParameter()) continue;
-
-    auto gp = req.getFirstType()->getAs<GenericTypeParamType>();
-    if (!gp) continue;
+    
+    GenericTypeParamType *gp;
+    if (auto secondGP = req.getSecondType()->getAs<GenericTypeParamType>()) {
+      // If two generic parameters are same-typed, then the left-hand one
+      // is canonical.
+      gp = secondGP;
+    } else {
+      // If an associated type is same-typed, it doesn't constrain the generic
+      // parameter itself.
+      if (req.getSecondType()->isTypeParameter()) continue;
+      
+      // Otherwise, the generic parameter is concrete.
+      gp = req.getFirstType()->getAs<GenericTypeParamType>();
+      if (!gp) continue;
+    }
 
     unsigned index = GenericParamKey(gp).findIndexIn(genericParams);
-    genericParamsAreConcrete[index] = true;
+    genericParamsAreNonCanonical[index] = true;
   }
 
   /// Local function to 'catch up' to the next dependent type we're going to
@@ -382,7 +395,7 @@
       if (curGenericParam->getDepth() < stopDepth ||
           (curGenericParam->getDepth() == stopDepth &&
            curGenericParam->getIndex() < stopIndex)) {
-        if (!genericParamsAreConcrete[curGenericParamIdx] &&
+        if (!genericParamsAreNonCanonical[curGenericParamIdx] &&
             fn(curGenericParam, { }))
           return true;
 
@@ -441,7 +454,7 @@
     // parameter we can't skip, invoke the callback.
     if ((startIdx != endIdx ||
          (isa<GenericTypeParamType>(depTy) &&
-          !genericParamsAreConcrete[
+          !genericParamsAreNonCanonical[
             GenericParamKey(cast<GenericTypeParamType>(depTy))
               .findIndexIn(genericParams)])) &&
         fn(depTy, reqs.slice(startIdx, endIdx-startIdx)))
@@ -807,7 +820,7 @@
 }
 
 bool GenericSignature::isCanonicalTypeInContext(Type type,
-                                                GenericSignatureBuilder &builder) {
+                                             GenericSignatureBuilder &builder) {
   // If the type isn't independently canonical, it's certainly not canonical
   // in this context.
   if (!type->isCanonical())
@@ -835,7 +848,7 @@
 }
 
 CanType GenericSignature::getCanonicalTypeInContext(Type type,
-                                                    GenericSignatureBuilder &builder) {
+                                             GenericSignatureBuilder &builder) {
   type = type->getCanonicalType();
 
   // All the contextual canonicality rules apply to type parameters, so if the
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 6ed4015..fb8e895 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -190,6 +190,12 @@
       }
     if (auto *NTD = dyn_cast<NominalTypeDecl>(D))
       doPopulateCache(NTD->getMembers(), true);
+
+    // Avoid populating the cache with the members of invalid extension
+    // declarations.  These members can be used to point validation inside of
+    // a malformed context.
+    if (D->isInvalid()) continue;
+
     if (auto *ED = dyn_cast<ExtensionDecl>(D))
       doPopulateCache(ED->getMembers(), true);
   }
diff --git a/lib/AST/RequirementEnvironment.cpp b/lib/AST/RequirementEnvironment.cpp
index 8a29803..8989f1a 100644
--- a/lib/AST/RequirementEnvironment.cpp
+++ b/lib/AST/RequirementEnvironment.cpp
@@ -209,13 +209,6 @@
   // Next, add each of the requirements (mapped from the requirement's
   // interface types into the abstract type parameters).
   for (auto &rawReq : reqSig->getRequirements()) {
-    // FIXME: This should not be necessary, since the constraint is redundant,
-    // but we need it to work around some crashes for now.
-    if (rawReq.getKind() == RequirementKind::Conformance &&
-        rawReq.getFirstType()->isEqual(selfType) &&
-        rawReq.getSecondType()->isEqual(proto->getDeclaredType()))
-      continue;
-
     if (auto req = rawReq.subst(reqToSyntheticEnvMap))
       builder.addRequirement(*req, source, conformanceDC->getParentModule());
   }
diff --git a/lib/AST/TypeRepr.cpp b/lib/AST/TypeRepr.cpp
index f848364..9ac6c10 100644
--- a/lib/AST/TypeRepr.cpp
+++ b/lib/AST/TypeRepr.cpp
@@ -237,8 +237,8 @@
   SmallVector<TypeRepr *, 4> cloneArgs;
   
   for (auto &field : type->getFields())
-    cloneFields.push_back({field.VarOrLetLoc, field.Mutable,
-                           visit(field.FieldType)});
+    cloneFields.push_back({field.getLoc(), field.isMutable(),
+                           visit(field.getFieldType())});
   for (auto *arg : type->getGenericArguments())
     cloneArgs.push_back(visit(arg));
   
@@ -471,10 +471,11 @@
                       SourceLoc RBraceLoc,
                       SourceLoc ArgLAngleLoc, ArrayRef<TypeRepr *> GenericArgs,
                       SourceLoc ArgRAngleLoc) {
-  return new (C) SILBoxTypeRepr(GenericParams,
-                                LBraceLoc, C.AllocateCopy(Fields), RBraceLoc,
-                                ArgLAngleLoc, C.AllocateCopy(GenericArgs),
-                                ArgRAngleLoc);
+  auto size = totalSizeToAlloc<Field, TypeRepr*>(Fields.size(),
+                                                 GenericArgs.size());
+  auto mem = C.Allocate(size, alignof(SILBoxTypeRepr));
+  return new (mem) SILBoxTypeRepr(GenericParams, LBraceLoc, Fields, RBraceLoc,
+                                  ArgLAngleLoc, GenericArgs, ArgRAngleLoc);
 }
 
 SourceLoc SILBoxTypeRepr::getStartLocImpl() const {
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 217bb57..415adcc 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -27,6 +27,7 @@
 #include "swift/AST/Module.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/Types.h"
+#include "swift/Basic/Defer.h"
 #include "swift/Basic/Platform.h"
 #include "swift/Basic/Range.h"
 #include "swift/Basic/StringExtras.h"
@@ -715,16 +716,32 @@
   CompilerInstance &CI = *Impl.Instance;
   auto clangDiags = CompilerInstance::createDiagnostics(
                                               new clang::DiagnosticOptions());
+
+  // Note: Reusing the file manager is safe; this is a component that's already
+  // reused when building PCM files for the module cache.
   clang::SourceManager clangSrcMgr(*clangDiags, CI.getFileManager());
   auto FID = clangSrcMgr.createFileID(
                         llvm::make_unique<ZeroFilledMemoryBuffer>(1, "<main>"));
   clangSrcMgr.setMainFileID(FID);
+
+  // Note: Reusing the real HeaderSearch is dangerous, but it's not easy to
+  // copy. We put in some effort to reset it to the way it was below.
+  clang::HeaderSearch &headerSearchInfo =
+      CI.getPreprocessor().getHeaderSearchInfo();
+  assert(headerSearchInfo.getExternalLookup() == nullptr &&
+         "already configured an ASTReader");
+
+  // Note: Reusing the PCM cache is safe because that's already shared when
+  // building PCM files for the module cache. Using the top-level compiler
+  // instance as a module loader does seem a little dangerous but does not
+  // appear to cause problems at the moment.
   clang::Preprocessor PP(CI.getInvocation().getPreprocessorOptsPtr(),
                          *clangDiags,
                          CI.getLangOpts(),
                          clangSrcMgr,
                          CI.getPCMCache(),
-                         CI.getPreprocessor().getHeaderSearchInfo(), CI,
+                         headerSearchInfo,
+                         (clang::ModuleLoader &)CI,
                          /*IILookup=*/nullptr,
                          /*OwnsHeaderSearch=*/false);
   PP.Initialize(CI.getTarget());
@@ -732,6 +749,8 @@
                         PP.getIdentifierTable(), PP.getSelectorTable(),
                         PP.getBuiltinInfo());
 
+  // Note: Reusing the PCHContainerReader or ModuleFileExtensions could be
+  // dangerous.
   std::unique_ptr<clang::ASTReader> Reader(new clang::ASTReader(
       PP, &ctx, CI.getPCHContainerReader(),
       CI.getFrontendOpts().ModuleFileExtensions,
@@ -740,6 +759,12 @@
       /*AllowPCHWithCompilerErrors*/ false,
       /*AllowConfigurationMismatch*/ false,
       /*ValidateSystemInputs*/ true));
+  SWIFT_DEFER {
+    assert(headerSearchInfo.getExternalLookup() == Reader.get() ||
+           headerSearchInfo.getExternalLookup() == nullptr);
+    headerSearchInfo.SetExternalLookup(nullptr);
+    headerSearchInfo.SetExternalSource(nullptr);
+  };
   ctx.InitBuiltinTypes(CI.getTarget());
 
   auto result = Reader->ReadAST(PCHFilename,
@@ -2837,6 +2862,11 @@
     ModuleDecl::LinkLibraryCallback callback) const {
   if (!clangModule)
     return;
+
+  // Skip this lib name in favor of export_as name.
+  if (clangModule->UseExportAsModuleLinkName)
+    return;
+
   for (auto clangLinkLib : clangModule->LinkLibraries) {
     LibraryKind kind;
     if (clangLinkLib.IsFramework)
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 821fac2..679bc8d 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -576,9 +576,6 @@
     }
   }
   
-  if (const Arg *A = Args.getLastArg(OPT_disable_sil_linking))
-    Opts.LinkMode = SILOptions::LinkNone;
-
   if (Args.hasArg(OPT_sil_merge_partial_modules))
     Opts.MergePartialModules = true;
 
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 88fe861..080e7ed 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -1827,36 +1827,47 @@
 
   void addImportModuleNames() {
     // FIXME: Add user-defined swift modules
-    SmallVector<clang::Module*, 20> Modules;
-    Ctx.getVisibleTopLevelClangModules(Modules);
-    std::sort(Modules.begin(), Modules.end(),
-              [](clang::Module* LHS , clang::Module* RHS) {
-                return LHS->getTopLevelModuleName().compare_lower(
-                  RHS->getTopLevelModuleName()) < 0;
+    SmallVector<StringRef, 20> ModuleNames;
+
+    // Collect clang module names.
+    {
+      SmallVector<clang::Module*, 20> ClangModules;
+      Ctx.getVisibleTopLevelClangModules(ClangModules);
+      for (auto *M : ClangModules) {
+        if (!M->isAvailable())
+          continue;
+        if (M->getTopLevelModuleName().startswith("_"))
+          continue;
+        if (M->getTopLevelModuleName() == Ctx.SwiftShimsModuleName.str())
+          continue;
+
+        ModuleNames.push_back(M->getTopLevelModuleName());
+      }
+    }
+
+    std::sort(ModuleNames.begin(), ModuleNames.end(),
+              [](StringRef LHS, StringRef RHS) {
+                return LHS.compare_lower(RHS) < 0;
               });
+
     llvm::StringSet<> ImportedModules;
     collectImportedModules(ImportedModules);
-    for (auto *M : Modules) {
-      if (M->isAvailable() &&
-          !M->getTopLevelModuleName().startswith("_") &&
-          M->getTopLevelModuleName() != CurrDeclContext->getASTContext().
-            SwiftShimsModuleName.str()) {
-        auto MD = ModuleDecl::create(Ctx.getIdentifier(M->getTopLevelModuleName()),
-                                     Ctx);
-        CodeCompletionResultBuilder Builder(Sink,
-                                            CodeCompletionResult::ResultKind::
-                                              Declaration,
-                                            SemanticContextKind::OtherModule,
-                                            ExpectedTypes);
-        Builder.setAssociatedDecl(MD);
-        Builder.addTextChunk(MD->getNameStr());
-        Builder.addTypeAnnotation("Module");
 
-        // Imported modules are not recommended.
-        if (ImportedModules.count(MD->getNameStr()) != 0)
-          Builder.setNotRecommended(CodeCompletionResult::NotRecommendedReason::
-                                      Redundant);
-      }
+    for (auto ModuleName : ModuleNames) {
+      auto MD = ModuleDecl::create(Ctx.getIdentifier(ModuleName), Ctx);
+      CodeCompletionResultBuilder Builder(
+          Sink,
+          CodeCompletionResult::ResultKind::Declaration,
+          SemanticContextKind::OtherModule,
+          ExpectedTypes);
+      Builder.setAssociatedDecl(MD);
+      Builder.addTextChunk(MD->getNameStr());
+      Builder.addTypeAnnotation("Module");
+
+      // Imported modules are not recommended.
+      if (ImportedModules.count(MD->getNameStr()) != 0)
+        Builder.setNotRecommended(
+            CodeCompletionResult::NotRecommendedReason::Redundant);
     }
   }
 
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index b299a86..9d3974d 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -1639,7 +1639,7 @@
 }
 
 bool RefactoringActionReplaceBodiesWithFatalError::performChange() {
-  const StringRef replacement = "{ fatalError() }";
+  const StringRef replacement = "{\nfatalError()\n}";
   llvm::SmallPtrSet<Decl *, 16> Found;
   for (auto decl : RangeInfo.DeclaredDecls) {
     FindAllSubDecls(Found).walk(decl.VD);
@@ -3099,9 +3099,14 @@
                          Range.getEnd(SF->getASTContext().SourceMgr));
   ResolvedRangeInfo Result = Resolver.resolve();
 
+  bool enableInternalRefactoring = getenv("SWIFT_ENABLE_INTERNAL_REFACTORING_ACTIONS");
+
 #define RANGE_REFACTORING(KIND, NAME, ID)                                     \
   if (RefactoringAction##KIND::isApplicable(Result, DiagEngine))              \
     Scratch.push_back(RefactoringKind::KIND);
+#define INTERNAL_RANGE_REFACTORING(KIND, NAME, ID)                            \
+  if (enableInternalRefactoring)                                              \
+    RANGE_REFACTORING(KIND, NAME, ID)
 #include "swift/IDE/RefactoringKinds.def"
 
   RangeStartMayNeedRename = rangeStartMayNeedRename(Result);
diff --git a/lib/IRGen/GenArchetype.cpp b/lib/IRGen/GenArchetype.cpp
index 16415ed..f99a067 100644
--- a/lib/IRGen/GenArchetype.cpp
+++ b/lib/IRGen/GenArchetype.cpp
@@ -99,7 +99,7 @@
   void collectMetadataForOutlining(OutliningMetadataCollector &collector,
                                    SILType T) const override {
     // We'll need formal type metadata for this archetype.
-    collector.collectFormalTypeMetadata(T.getSwiftRValueType());
+    collector.collectTypeMetadataForLayout(T);
   }
 };
 
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index bbc4482..47b3c78 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -548,6 +548,7 @@
                                       init, name);
   var->setSection(section);
   var->setAlignment(alignment.getValue());
+  disableAddressSanitizer(IGM, var);
 
   // Mark the variable as used if doesn't have external linkage.
   // (Note that we'd specifically like to not put @llvm.used in itself.)
@@ -1984,6 +1985,31 @@
   return var;
 }
 
+void swift::irgen::disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariable *var) {
+  // Add an operand to llvm.asan.globals blacklisting this global variable.
+  llvm::Metadata *metadata[] = {
+    // The global variable to blacklist.
+    llvm::ConstantAsMetadata::get(var),
+    
+    // Source location. Optional, unnecessary here.
+    nullptr,
+    
+    // Name. Optional, unnecessary here.
+    nullptr,
+    
+    // Whether the global is dynamically initialized.
+    llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
+      llvm::Type::getInt1Ty(IGM.Module.getContext()), false)),
+    
+    // Whether the global is blacklisted.
+    llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
+      llvm::Type::getInt1Ty(IGM.Module.getContext()), true))};
+  
+  auto *globalNode = llvm::MDNode::get(IGM.Module.getContext(), metadata);
+  auto *asanMetadata = IGM.Module.getOrInsertNamedMetadata("llvm.asan.globals");
+  asanMetadata->addOperand(globalNode);
+}
+
 /// Emit a global declaration.
 void IRGenModule::emitGlobalDecl(Decl *D) {
   switch (D->getKind()) {
@@ -2729,6 +2755,9 @@
   }
 
   var->setSection(sectionName);
+  
+  disableAddressSanitizer(*this, var);
+  
   addUsedGlobal(var);
   return var;
 }
@@ -2915,8 +2944,10 @@
   }
 
   var->setSection(sectionName);
-  addUsedGlobal(var);
+
+  disableAddressSanitizer(*this, var);
   
+  addUsedGlobal(var);
   return var;
 }
 
@@ -2982,8 +3013,10 @@
   var->setInitializer(initializer);
   var->setSection(sectionName);
   var->setAlignment(4);
-  addUsedGlobal(var);
+
+  disableAddressSanitizer(*this, var);
   
+  addUsedGlobal(var);
   return var;
 }
 
@@ -3029,6 +3062,9 @@
   var->setInitializer(llvm::ConstantArray::get(arrayTy, elts));
   var->setSection(sectionName);
   var->setAlignment(4);
+  
+  disableAddressSanitizer(*this, var);
+  
   addUsedGlobal(var);
   return var;
 }
diff --git a/lib/IRGen/GenDecl.h b/lib/IRGen/GenDecl.h
index f06269a..3e5eb42 100644
--- a/lib/IRGen/GenDecl.h
+++ b/lib/IRGen/GenDecl.h
@@ -54,6 +54,7 @@
                                        Optional<SILLocation> DebugLoc = None,
                                        StringRef DebugName = StringRef());
 
+  void disableAddressSanitizer(IRGenModule &IGM, llvm::GlobalVariable *var);
 }
 }
 
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index e66b9b9..df147e2 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -101,6 +101,8 @@
 }
 
 void IRGenModule::setTrueConstGlobal(llvm::GlobalVariable *var) {
+  disableAddressSanitizer(*this, var);
+  
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::UnknownObjectFormat:
     llvm_unreachable("unknown object format");
@@ -223,10 +225,10 @@
       
       for (auto param : canSig->getGenericParams()) {
         // Currently, there are only type parameters. The parameter is a key
-        // argument if it hasn't been grounded by a same-type constraint.
+        // argument if it's canonical in its generic context.
         asImpl().addGenericParameter(GenericParamKind::Type,
-                               /*key argument*/ !canSig->isConcreteType(param),
-                               /*extra argument*/ false);
+                 /*key argument*/ canSig->isCanonicalTypeInContext(param),
+                 /*extra argument*/ false);
       }
       
       // Pad the structure up to four bytes for the following requirements.
@@ -3719,6 +3721,7 @@
   auto var = cast<llvm::GlobalVariable>(
           getAddrOfProtocolDescriptor(protocol, init.finishAndCreateFuture()));
   var->setConstant(true);
+  disableAddressSanitizer(*this, var);
 
   // Note that we emitted this protocol.
   SwiftProtocols.push_back(protocol);
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index 57d9cb7..bb61f72 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -273,6 +273,8 @@
 
     IGM.addUsedGlobal(var);
 
+    disableAddressSanitizer(IGM, var);
+
     return var;
   }
 
@@ -845,6 +847,7 @@
 
   entry = createStringConstant(Name, /*willBeRelativelyAddressed*/ true,
                                getReflectionStringsSectionName());
+  disableAddressSanitizer(*this, entry.first);
   return entry.second;
 }
 
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 1b3c561..dc5c3df 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -2520,7 +2520,7 @@
       auto instr = cast<ConvertEscapeToNoEscapeInst>(convInstr);
       newInstr = convBuilder.createConvertEscapeToNoEscape(
           instr->getLoc(), instr->getOperand(), newType,
-          instr->isLifetimeGuaranteed());
+          instr->isEscapedByUser(), instr->isLifetimeGuaranteed());
       break;
     }
     case SILInstructionKind::MarkDependenceInst: {
diff --git a/lib/IRGen/Outlining.cpp b/lib/IRGen/Outlining.cpp
index cae28be..c4c60dc 100644
--- a/lib/IRGen/Outlining.cpp
+++ b/lib/IRGen/Outlining.cpp
@@ -35,10 +35,14 @@
     return;
   }
 
+  CanType formalType = type.getSwiftRValueType();
+  if (isa<FixedTypeInfo>(IGF.IGM.getTypeInfoForLowered(formalType))) {
+    return;
+  }
+
   // If the type is a legal formal type, add it as a formal type.
   // FIXME: does this force us to emit a more expensive metadata than we need
   // to?
-  CanType formalType = type.getSwiftRValueType();
   if (formalType->isLegalFormalType()) {
     return collectFormalTypeMetadata(formalType);
   }
@@ -53,9 +57,7 @@
 
 void OutliningMetadataCollector::collectFormalTypeMetadata(CanType type) {
   // If the type has no archetypes, we can emit it from scratch in the callee.
-  if (!type->hasArchetype()) {
-    return;
-  }
+  assert(type->hasArchetype());
 
   auto key = LocalTypeDataKey(type, LocalTypeDataKind::forFormalTypeMetadata());
   if (Values.count(key)) return;
diff --git a/lib/IRGen/StructLayout.cpp b/lib/IRGen/StructLayout.cpp
index d8faf8c..de18d75 100644
--- a/lib/IRGen/StructLayout.cpp
+++ b/lib/IRGen/StructLayout.cpp
@@ -114,18 +114,18 @@
     return;
   
   if (auto alignment = decl->getAttrs().getAttribute<AlignmentAttr>()) {
-    assert(alignment->Value != 0
-           && ((alignment->Value - 1) & alignment->Value) == 0
+    auto value = alignment->getValue();
+    assert(value != 0 && ((value - 1) & value) == 0
            && "alignment not a power of two!");
     
     if (!IsFixedLayout)
       Diags.diagnose(alignment->getLocation(),
                      diag::alignment_dynamic_type_layout_unsupported);
-    else if (alignment->Value < MinimumAlign.getValue())
+    else if (value < MinimumAlign.getValue())
       Diags.diagnose(alignment->getLocation(),
                    diag::alignment_less_than_natural, MinimumAlign.getValue());
     else
-      MinimumAlign = Alignment(alignment->Value);
+      MinimumAlign = Alignment(value);
   }
 }
 
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index 137af75..b829d1f 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -28,6 +28,7 @@
 #include "clang/Rewrite/Core/RewriteBuffer.h"
 #include "llvm/Support/FileSystem.h"
 #include "swift/IDE/APIDigesterData.h"
+#include "swift/Basic/Defer.h"
 
 using namespace swift;
 using namespace swift::migrator;
@@ -302,13 +303,12 @@
     return false;
   }
 
+  std::set<std::string> InsertedFunctions;
   SourceLoc FileEndLoc;
-  llvm::SmallSet<StringRef, 4> InsertedFunctions;
-
   APIDiffMigratorPass(EditorAdapter &Editor, SourceFile *SF,
-                      const MigratorOptions &Opts)
-    : ASTMigratorPass(Editor, SF, Opts),
-      FileEndLoc(SM.getRangeForBuffer(BufferID).getEnd()) {}
+                      const MigratorOptions &Opts):
+    ASTMigratorPass(Editor, SF, Opts),
+    FileEndLoc(SM.getRangeForBuffer(BufferID).getEnd()) {}
 
   void run() {
     if (Opts.APIDigesterDataStorePaths.empty())
@@ -686,67 +686,77 @@
       return false;
     for (auto *Item: getRelatedDiffItems(RD)) {
       if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
-        switch(CI->DiffKind) {
-        case NodeAnnotation::SimpleStringRepresentableUpdate: {
-          Editor.insertBefore(ASE->getSrc()->getStartLoc(),
-            (Twine(CI->RightComment) + "(rawValue: ").str());
+        if (CI->isStringRepresentableChange() &&
+            CI->NodeKind == SDKNodeKind::DeclVar) {
+          SmallString<256> Buffer;
+          auto Func = insertHelperFunction(CI->DiffKind, CI->RightComment,
+                                           Buffer, true);
+          Editor.insert(ASE->getSrc()->getStartLoc(), (Twine(Func) + "(").str());
           Editor.insertAfterToken(ASE->getSrc()->getEndLoc(), ")");
           return true;
         }
-        default:
-          continue;
-        }
       }
     }
     return false;
   }
 
   StringRef insertHelperFunction(NodeAnnotation Anno, StringRef NewType,
-                                 SmallString<256> &Buffer) {
+                                 SmallString<256> &Buffer, bool FromString) {
     llvm::raw_svector_ostream OS(Buffer);
     OS << "\n";
     OS << "// Helper function inserted by Swift 4.2 migrator.\n";
     OS << "fileprivate func ";
     unsigned FuncNameStart = Buffer.size();
-    OS << "converTo";
+    OS << (FromString ? "convertTo" : "convertFrom");
     SmallVector<std::string, 8> Segs;
+    StringRef guard = "\tguard let input = input else { return nil }\n";
     switch(Anno) {
     case NodeAnnotation::OptionalArrayMemberUpdate:
       Segs = {"Optional", "Array", "[String]?"};
       Segs.push_back((Twine("[") + NewType +"]?").str());
-      Segs.push_back("// Not implemented");
+      Segs.push_back((Twine(guard) + "\treturn input.map { key in " + NewType +"(key) }").str());
+      Segs.push_back((Twine(guard) + "\treturn input.map { key in key.rawValue }").str());
       break;
     case NodeAnnotation::OptionalDictionaryKeyUpdate:
       Segs = {"Optional", "Dictionary", "[String: Any]?"};
       Segs.push_back((Twine("[") + NewType +": Any]?").str());
-      Segs.push_back((Twine("\tguard let input = input else { return nil }\n"
-                            "\treturn Dictionary(uniqueKeysWithValues: input.map"
-        " { key, value in (") + NewType + "(rawValue: key), value)})").str());
+      Segs.push_back((Twine(guard) +
+                      "\treturn Dictionary(uniqueKeysWithValues: input.map"
+                      " { key, value in (" + NewType + "(rawValue: key), value)})").str());
+      Segs.push_back((Twine(guard) +
+                      "\treturn Dictionary(uniqueKeysWithValues: input.map"
+                      " {key, value in (key.rawValue, value)})").str());
       break;
     case NodeAnnotation::ArrayMemberUpdate:
       Segs = {"", "Array", "[String]"};
       Segs.push_back((Twine("[") + NewType +"]").str());
-      Segs.push_back("// Not implemented");
+      Segs.push_back((Twine("\treturn input.map { key in ") + NewType +"(key) }").str());
+      Segs.push_back("\treturn input.map { key in key.rawValue }");
       break;
     case NodeAnnotation::DictionaryKeyUpdate:
       Segs = {"", "Dictionary", "[String: Any]"};
       Segs.push_back((Twine("[") + NewType +": Any]").str());
       Segs.push_back((Twine("\treturn Dictionary(uniqueKeysWithValues: input.map"
         " { key, value in (") + NewType + "(rawValue: key), value)})").str());
+      Segs.push_back("\treturn Dictionary(uniqueKeysWithValues: input.map"
+                     " {key, value in (key.rawValue, value)})");
       break;
     case NodeAnnotation::SimpleStringRepresentableUpdate:
       Segs = {"", "", "String"};
       Segs.push_back(NewType);
-      Segs.push_back("// Not implemented");
+      Segs.push_back((Twine("\treturn ") + NewType + "(rawValue: input)").str());
+      Segs.push_back("\treturn input.rawValue");
       break;
     case NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
       Segs = {"Optional", "", "String?"};
       Segs.push_back((Twine(NewType) +"?").str());
-      Segs.push_back("// Not implemented");
+      Segs.push_back((Twine(guard) + "\treturn " + NewType + "(rawValue: input)").str());
+      Segs.push_back((Twine(guard) + "\treturn input.rawValue").str());
       break;
     default:
       llvm_unreachable("shouldn't handle this key.");
     }
+    assert(Segs.size() == 6);
     OS << Segs[0];
     SmallVector<StringRef, 4> Parts;
     NewType.split(Parts, '.');
@@ -755,15 +765,22 @@
     OS << Segs[1];
     auto FuncName = Buffer.str().substr(FuncNameStart);
     if (!InsertedFunctions.count(FuncName)) {
-      OS << "(_ input: " << Segs[2] << ") -> " << Segs[3] << " {\n";
-      OS << Segs[4] << "\n}\n";
+      if (FromString) {
+        OS << "(_ input: " << Segs[2] << ") -> " << Segs[3] << " {\n";
+        OS << Segs[4] << "\n}\n";
+      } else {
+        OS << "(_ input: " << Segs[3] << ") -> " << Segs[2] << " {\n";
+        OS << Segs[5] << "\n}\n";
+      }
       Editor.insert(FileEndLoc, OS.str());
       InsertedFunctions.insert(FuncName);
     }
     return FuncName;
   }
 
-  void handleStringRepresentableArg(ValueDecl *FD, Expr *Arg) {
+  void handleStringRepresentableArg(ValueDecl *FD, Expr *Arg, Expr *Call) {
+    Editor.disableCache();
+    SWIFT_DEFER { Editor.enableCache(); };
     NodeAnnotation Kind;
     StringRef NewAttributeType;
     uint8_t ArgIdx;
@@ -778,17 +795,23 @@
         }
       }
     }
-    if (NewAttributeType.empty() || !ArgIdx)
-      return;
-    ArgIdx --;
-    auto AllArgs = getCallArgInfo(SM, Arg, LabelRangeEndAt::LabelNameOnly);
-    if (AllArgs.size() <= ArgIdx)
+    if (NewAttributeType.empty())
       return;
     SmallString<256> Buffer;
-    auto FuncName = insertHelperFunction(Kind, NewAttributeType, Buffer);
-    auto Exp = AllArgs[ArgIdx].ArgExp;
-    Editor.insert(Exp->getStartLoc(), (Twine(FuncName) + "(").str());
-    Editor.insertAfterToken(Exp->getEndLoc(), ")");
+    auto FuncName = insertHelperFunction(Kind, NewAttributeType, Buffer,
+                                         /*FromString*/ArgIdx);
+    if (ArgIdx) {
+      ArgIdx --;
+      auto AllArgs = getCallArgInfo(SM, Arg, LabelRangeEndAt::LabelNameOnly);
+      if (AllArgs.size() <= ArgIdx)
+        return;
+      auto Exp = AllArgs[ArgIdx].ArgExp;
+      Editor.insert(Exp->getStartLoc(), (Twine(FuncName) + "(").str());
+      Editor.insertAfterToken(Exp->getEndLoc(), ")");
+    } else {
+      Editor.insert(Call->getStartLoc(), (Twine(FuncName) + "(").str());
+      Editor.insertAfterToken(Call->getEndLoc(), ")");
+    }
   }
 
   bool walkToExprPre(Expr *E) override {
@@ -805,7 +828,7 @@
           handleFuncRename(FD, Fn, Args);
           handleTypeHoist(FD, CE, Args);
           handleSpecialCases(FD, CE, Args);
-          handleStringRepresentableArg(FD, Args);
+          handleStringRepresentableArg(FD, Args, CE);
         }
         break;
       }
@@ -815,7 +838,7 @@
           handleFuncRename(FD, DSC->getFn(), Args);
           handleFunctionCallToPropertyChange(FD, DSC->getFn(), Args);
           handleSpecialCases(FD, CE, Args);
-          handleStringRepresentableArg(FD, Args);
+          handleStringRepresentableArg(FD, Args, CE);
         }
         break;
       }
@@ -824,7 +847,7 @@
         if (auto FD = CCE->getFn()->getReferencedDecl().getDecl()) {
           auto *CE = CCE->getFn();
           handleFuncRename(FD, CE, Args);
-          handleStringRepresentableArg(FD, Args);
+          handleStringRepresentableArg(FD, Args, CE);
         }
         break;
       }
diff --git a/lib/Migrator/EditorAdapter.cpp b/lib/Migrator/EditorAdapter.cpp
index 6b99711..ee77d52 100644
--- a/lib/Migrator/EditorAdapter.cpp
+++ b/lib/Migrator/EditorAdapter.cpp
@@ -29,6 +29,8 @@
 
 bool
 EditorAdapter::cacheReplacement(CharSourceRange Range, StringRef Text) const {
+  if (!CacheEnabled)
+    return false;
   unsigned SwiftBufferID, Offset;
   std::tie(SwiftBufferID, Offset) = getLocInfo(Range.getStart());
   Replacement R { Offset, Range.getByteLength(), Text };
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index d1f626d..64fcfc2 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -2979,10 +2979,21 @@
     SILType Ty;
     Identifier ToToken;
     SourceLoc ToLoc;
-    bool guaranteed = true;
-    if (Opcode == SILInstructionKind::ConvertEscapeToNoEscapeInst)
-      if(parseSILOptional(guaranteed, *this, "not_guaranteed"))
+    bool not_guaranteed = false;
+    bool escaped = false;
+    if (Opcode == SILInstructionKind::ConvertEscapeToNoEscapeInst) {
+      StringRef attrName;
+      if (parseSILOptional(attrName, *this)) {
+        if (attrName.equals("escaped"))
+          escaped = true;
+        else if (attrName.equals("not_guaranteed"))
+          not_guaranteed = true;
+        else
+          return true;
+      }
+      if (parseSILOptional(escaped, *this, "escaped"))
         return true;
+    }
     if (parseTypedValueRef(Val, B) ||
         parseSILIdentifier(ToToken, ToLoc,
                            diag::expected_tok_in_sil_instr, "to") ||
@@ -3016,7 +3027,8 @@
       ResultVal = B.createConvertFunction(InstLoc, Val, Ty);
       break;
     case SILInstructionKind::ConvertEscapeToNoEscapeInst:
-      ResultVal = B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, guaranteed);
+      ResultVal = B.createConvertEscapeToNoEscape(InstLoc, Val, Ty, escaped,
+                                                  !not_guaranteed);
       break;
     case SILInstructionKind::AddressToPointerInst:
       ResultVal = B.createAddressToPointer(InstLoc, Val, Ty);
diff --git a/lib/SIL/Linker.cpp b/lib/SIL/Linker.cpp
index 9f64ff5..9dc4c7a 100644
--- a/lib/SIL/Linker.cpp
+++ b/lib/SIL/Linker.cpp
@@ -10,6 +10,45 @@
 //
 //===----------------------------------------------------------------------===//
 
+/// \file The SIL linker walks the call graph beginning at a starting function,
+/// deserializing functions, vtables and witness tables.
+///
+/// The behavior of the linker is controlled by a LinkMode value. The LinkMode
+/// has three possible values:
+///
+/// - LinkNone: The linker does not deserialize anything. This is only used for
+///   debugging and testing purposes, and never during normal operation.
+///
+/// - LinkNormal: The linker deserializes bodies for declarations that must be
+///   emitted into the client because they do not have definitions available
+///   externally. This includes:
+///
+///   - witness tables for imported conformances
+///
+///   - functions with shared linkage
+///
+/// - LinkAll: All reachable functions (including public functions) are
+///   deserialized, including public functions.
+///
+/// The primary entry point into the linker is the SILModule::linkFunction()
+/// function, which recursively walks the call graph starting from the given
+/// function.
+///
+/// In the mandatory pipeline (-Onone), the linker is invoked from the mandatory
+/// SIL linker pass, which pulls in just enough to allow us to emit code, using
+/// LinkNormal mode.
+///
+/// In the performance pipeline, after guaranteed optimizations but before
+/// performance optimizations, the 'performance SILLinker' pass links
+/// transitively all reachable functions, to uncover optimization opportunities
+/// that might be missed from deserializing late. The performance pipeline uses
+/// LinkAll mode.
+///
+/// *NOTE*: In LinkAll mode, we deserialize all vtables and witness tables,
+/// even those with public linkage. This is not strictly necessary, since the
+/// devirtualizer deserializes vtables and witness tables as needed. However,
+/// doing so early creates more opportunities for optimization.
+
 #define DEBUG_TYPE "sil-linker"
 #include "Linker.h"
 #include "llvm/ADT/Statistic.h"
@@ -55,18 +94,29 @@
   if (!F->isExternalDeclaration())
     return;
 
-  if (isLinkAll() || hasSharedVisibility(F->getLinkage()))
+  // In the performance pipeline, we deserialize all reachable functions.
+  if (isLinkAll())
+    return addFunctionToWorklist(F);
+
+  // Otherwise, make sure to deserialize shared functions; we need to
+  // emit them into the client binary since they're not available
+  // externally.
+  if (hasSharedVisibility(F->getLinkage()))
+    return addFunctionToWorklist(F);
+
+  // Functions with PublicNonABI linkage are deserialized as having
+  // HiddenExternal linkage when they are declarations, then they
+  // become SharedExternal after the body has been deserialized.
+  // So try deserializing HiddenExternal functions too.
+  if (F->getLinkage() == SILLinkage::HiddenExternal)
     return addFunctionToWorklist(F);
 }
 
 /// Process F, recursively deserializing any thing F may reference.
 bool SILLinkerVisitor::processFunction(SILFunction *F) {
-  if (Mode == LinkingMode::LinkNone)
-    return false;
-
   // If F is a declaration, first deserialize it.
   if (F->isExternalDeclaration()) {
-    addFunctionToWorklist(F);
+    maybeAddFunctionToWorklist(F);
   } else {
     Worklist.push_back(F);
   }
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index dec0573..60f1565 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -1998,7 +1998,8 @@
 
 ConvertEscapeToNoEscapeInst *ConvertEscapeToNoEscapeInst::create(
     SILDebugLocation DebugLoc, SILValue Operand, SILType Ty, SILFunction &F,
-    SILOpenedArchetypesState &OpenedArchetypes, bool isLifetimeGuaranteed) {
+    SILOpenedArchetypesState &OpenedArchetypes, bool isEscapedByUser,
+    bool isLifetimeGuaranteed) {
   SILModule &Mod = F.getModule();
   SmallVector<SILValue, 8> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
@@ -2006,8 +2007,9 @@
   unsigned size =
     totalSizeToAlloc<swift::Operand>(1 + TypeDependentOperands.size());
   void *Buffer = Mod.allocateInst(size, alignof(ConvertEscapeToNoEscapeInst));
-  auto *CFI = ::new (Buffer) ConvertEscapeToNoEscapeInst(
-      DebugLoc, Operand, TypeDependentOperands, Ty, isLifetimeGuaranteed);
+  auto *CFI = ::new (Buffer)
+      ConvertEscapeToNoEscapeInst(DebugLoc, Operand, TypeDependentOperands, Ty,
+                                  isEscapedByUser, isLifetimeGuaranteed);
   // If we do not have lowered SIL, make sure that are not performing
   // ABI-incompatible conversions.
   //
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index bd49d6c..c0fd911 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -1431,6 +1431,9 @@
 BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(GepRaw)
 BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(Gep)
 BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(GetTailAddr)
+BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(PerformInstantaneousReadAccess)
+BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(BeginUnpairedModifyAccess)
+BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(EndUnpairedAccess)
 BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(CondFail)
 BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(FixLifetime)
 BUILTINS_THAT_SHOULD_HAVE_BEEN_LOWERED_TO_SILINSTS(IsUnique)
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index baaecac..db3b52f 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -1436,6 +1436,7 @@
   }
   void visitConvertEscapeToNoEscapeInst(ConvertEscapeToNoEscapeInst *CI) {
     *this << (CI->isLifetimeGuaranteed() ? "" : "[not_guaranteed] ")
+          << (CI->isEscapedByUser() ? "[escaped] " : "")
           << getIDAndType(CI->getOperand()) << " to " << CI->getType();
   }
   void visitThinFunctionToPointerInst(ThinFunctionToPointerInst *CI) {
@@ -2215,6 +2216,14 @@
 /// Pretty-print the SILBasicBlock to the designated stream.
 void SILBasicBlock::print(raw_ostream &OS) const {
   SILPrintContext Ctx(OS);
+
+  // Print the debug scope (and compute if we didn't do it already).
+  auto &SM = this->getParent()->getModule().getASTContext().SourceMgr;
+  for (auto &I : *this) {
+    SILPrinter P(Ctx);
+    P.printDebugScope(I.getDebugScope(), SM);
+  }
+
   SILPrinter(Ctx).print(this);
 }
 
@@ -2681,7 +2690,7 @@
       if (!WholeModuleMode && !(D->getDeclContext() == AssociatedDeclContext))
           continue;
       if ((isa<ValueDecl>(D) || isa<OperatorDecl>(D) ||
-           isa<ExtensionDecl>(D)) &&
+           isa<ExtensionDecl>(D) || isa<ImportDecl>(D)) &&
           !D->isImplicit()) {
         if (isa<AccessorDecl>(D))
           continue;
diff --git a/lib/SIL/SILProfiler.cpp b/lib/SIL/SILProfiler.cpp
index 6f0a738..6a6f755 100644
--- a/lib/SIL/SILProfiler.cpp
+++ b/lib/SIL/SILProfiler.cpp
@@ -26,7 +26,8 @@
 
 using namespace swift;
 
-static bool isClosureWithBody(AbstractClosureExpr *ACE) {
+/// Check if a closure has a body.
+static bool doesClosureHaveBody(AbstractClosureExpr *ACE) {
   if (auto *CE = dyn_cast<ClosureExpr>(ACE))
     return CE->getBody();
   if (auto *autoCE = dyn_cast<AutoClosureExpr>(ACE))
@@ -34,79 +35,43 @@
   return false;
 }
 
+/// Check whether a root AST node is unmapped, i.e not profiled.
 static bool isUnmapped(ASTNode N) {
   if (auto *E = N.dyn_cast<Expr *>()) {
     auto *CE = dyn_cast<AbstractClosureExpr>(E);
-    return !CE || (!isa<AutoClosureExpr>(CE) && CE->isImplicit()) ||
-           !isClosureWithBody(CE);
+
+    // Only map closure expressions with bodies.
+    if (!CE || !doesClosureHaveBody(CE))
+      return true;
+
+    // Don't map implicit closures, unless they're autoclosures.
+    if (!isa<AutoClosureExpr>(CE) && CE->isImplicit())
+      return true;
+
+    return false;
   }
 
   auto *D = N.get<Decl *>();
   if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
+    // Don't map functions without bodies.
     if (!AFD->getBody())
       return true;
 
+    // Map all *structors, even if they are implicit.
+    if (isa<ConstructorDecl>(D) || isa<DestructorDecl>(D))
+      return false;
+
+    // Map implicit getters.
     if (auto *accessor = dyn_cast<AccessorDecl>(AFD))
       if (accessor->isImplicit() && accessor->isGetter())
         return false;
   }
 
-  if (isa<ConstructorDecl>(D) || isa<DestructorDecl>(D))
-    return false;
+  // Skip any remaining implicit, or otherwise unsupported decls.
+  if (D->isImplicit() || isa<EnumCaseDecl>(D))
+    return true;
 
-  return D->isImplicit() || isa<EnumCaseDecl>(D);
-}
-
-/// A simple heuristic to determine whether \p E contains a definition of a
-/// closure. This is not complete, but it suffices to cheaply filter away some
-/// redundant coverage mappings.
-static bool containsClosure(Expr *E) {
-  Expr *candidateExpr = E;
-  if (auto *ce = dyn_cast<CallExpr>(E))
-    candidateExpr = ce->getDirectCallee();
-  return dyn_cast_or_null<AbstractClosureExpr>(candidateExpr);
-}
-
-/// Walk the non-static initializers in \p PBD.
-static void walkPatternForProfiling(PatternBindingDecl *PBD, ASTWalker &Walker,
-                                    bool AllowClosures = true) {
-  if (PBD && !PBD->isStatic())
-    for (auto E : PBD->getPatternList())
-      if (E.getInit())
-        if (AllowClosures || !containsClosure(E.getInit()))
-          E.getInit()->walk(Walker);
-}
-
-/// Walk the AST of \c Root and related nodes that are relevant for profiling.
-static void walkFunctionForProfiling(AbstractFunctionDecl *Root,
-                                     ASTWalker &Walker) {
-  Root->walk(Walker);
-
-  // We treat non-closure member initializers as part of the constructor for
-  // profiling.
-  if (auto *CD = dyn_cast<ConstructorDecl>(Root)) {
-    auto *NominalType =
-        CD->getDeclContext()->getAsNominalTypeOrNominalTypeExtensionContext();
-    for (auto *Member : NominalType->getMembers()) {
-      // Find pattern binding declarations that have initializers.
-      if (auto *PBD = dyn_cast<PatternBindingDecl>(Member))
-        walkPatternForProfiling(PBD, Walker, /*AllowClosures=*/false);
-    }
-  }
-}
-
-/// Walk \p D for profiling.
-static void walkForProfiling(ASTNode N, ASTWalker &Walker) {
-  if (auto *D = N.dyn_cast<Decl *>()) {
-    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
-      walkFunctionForProfiling(AFD, Walker);
-    else if (auto *PBD = dyn_cast<PatternBindingDecl>(D))
-      walkPatternForProfiling(PBD, Walker);
-    else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
-      TLCD->walk(Walker);
-  } else if (auto *E = N.dyn_cast<Expr *>()) {
-    cast<AbstractClosureExpr>(E)->walk(Walker);
-  }
+  return false;
 }
 
 namespace swift {
@@ -123,27 +88,43 @@
   return !SF || SF->ASTStage >= SourceFile::TypeChecked;
 }
 
+/// Check whether a mapped AST node requires a new profiler.
+static bool canCreateProfilerForAST(ASTNode N) {
+  assert(hasASTBeenTypeChecked(N) && "Cannot use this AST for profiling");
+
+  if (auto *D = N.dyn_cast<Decl *>()) {
+    // Any mapped function may be profiled. There's an exception for
+    // constructors because all of the constructors for a type share a single
+    // profiler.
+    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D))
+      return !isa<ConstructorDecl>(AFD);
+
+    if (isa<TopLevelCodeDecl>(D))
+      return true;
+
+    if (isa<NominalTypeDecl>(D))
+      return true;
+  } else {
+    auto *E = N.get<Expr *>();
+    if (isa<AbstractClosureExpr>(E))
+      return true;
+  }
+  return false;
+}
+
 SILProfiler *SILProfiler::create(SILModule &M, ForDefinition_t forDefinition,
                                  ASTNode N) {
   // Avoid generating profiling state for declarations.
   if (!forDefinition)
     return nullptr;
 
-  assert(hasASTBeenTypeChecked(N) && "Cannot use this AST for code coverage");
-
-  if (auto *D = N.dyn_cast<Decl *>()) {
-    assert(isa<AbstractFunctionDecl>(D) ||
-           isa<TopLevelCodeDecl>(D) && "Cannot create profiler");
-  } else if (auto *E = N.dyn_cast<Expr *>()) {
-    assert(isa<AbstractClosureExpr>(E) && "Cannot create profiler");
-  } else {
-    llvm_unreachable("Invalid AST node for profiling");
-  }
-
   const auto &Opts = M.getOptions();
   if (!doesASTRequireProfiling(M, N) && Opts.UseProfile.empty())
     return nullptr;
 
+  if (!canCreateProfilerForAST(N))
+    llvm_unreachable("Invalid AST node for profiling");
+
   auto *Buf = M.allocate<SILProfiler>(1);
   auto *SP = ::new (Buf) SILProfiler(M, N, Opts.EmitProfileCoverageMapping);
   SP->assignRegionCounters();
@@ -152,6 +133,15 @@
 
 namespace {
 
+/// Walk the non-static initializers in \p PBD.
+static void walkPatternForProfiling(PatternBindingDecl *PBD,
+                                    ASTWalker &Walker) {
+  if (PBD && !PBD->isStatic())
+    for (auto E : PBD->getPatternList())
+      if (E.getInit())
+        E.getInit()->walk(Walker);
+}
+
 /// Special logic for handling closure visitation.
 ///
 /// To prevent a closure from being mapped twice, avoid recursively walking
@@ -170,25 +160,35 @@
 /// An ASTWalker that maps ASTNodes to profiling counters.
 struct MapRegionCounters : public ASTWalker {
   /// The next counter value to assign.
-  unsigned NextCounter;
+  unsigned NextCounter = 0;
 
   /// The map of statements to counters.
   llvm::DenseMap<ASTNode, unsigned> &CounterMap;
 
+  /// A flag indicating whether we're walking a nominal type.
+  bool WithinNominalType = false;
+
   MapRegionCounters(llvm::DenseMap<ASTNode, unsigned> &CounterMap)
-      : NextCounter(0), CounterMap(CounterMap) {}
+      : CounterMap(CounterMap) {}
 
   bool walkToDeclPre(Decl *D) override {
     if (isUnmapped(D))
       return false;
+
     if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
-      bool FirstDecl = Parent.isNull();
-      if (FirstDecl)
+      // Don't map a nested function unless it's a constructor.
+      bool continueWalk = Parent.isNull() || isa<ConstructorDecl>(AFD);
+      if (continueWalk)
         CounterMap[AFD->getBody()] = NextCounter++;
-      return FirstDecl;
-    }
-    if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
+      return continueWalk;
+    } else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
       CounterMap[TLCD->getBody()] = NextCounter++;
+    } else if (isa<NominalTypeDecl>(D)) {
+      bool continueWalk = Parent.isNull();
+      if (continueWalk)
+        WithinNominalType = true;
+      return continueWalk;
+    }
     return true;
   }
 
@@ -560,7 +560,11 @@
   /// \brief A stack of active repeat-while loops.
   std::vector<RepeatWhileStmt *> RepeatWhileStack;
 
-  CounterExpr *ExitCounter;
+  CounterExpr *ExitCounter = nullptr;
+
+  Stmt *ImplicitTopLevelBody = nullptr;
+
+  NominalTypeDecl *ParentNominalType = nullptr;
 
   /// \brief Return true if \c Node has an associated counter.
   bool hasCounter(ASTNode Node) { return CounterMap.count(Node); }
@@ -762,19 +766,40 @@
   bool walkToDeclPre(Decl *D) override {
     if (isUnmapped(D))
       return false;
+
     if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
-      bool FirstDecl = Parent.isNull();
-      if (FirstDecl)
-        assignCounter(AFD->getBody());
-      return FirstDecl;
-    }
-    else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
+      // Don't map a nested function unless it's a constructor.
+      bool continueWalk = Parent.isNull() || isa<ConstructorDecl>(AFD);
+      if (continueWalk) {
+        CounterExpr &funcCounter = assignCounter(AFD->getBody());
+
+        if (isa<ConstructorDecl>(AFD))
+          addToCounter(ParentNominalType, funcCounter);
+      }
+      return continueWalk;
+    } else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
       assignCounter(TLCD->getBody());
+      ImplicitTopLevelBody = TLCD->getBody();
+    } else if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
+      bool continueWalk = Parent.isNull();
+      if (continueWalk) {
+        ParentNominalType = NTD;
+        assignCounter(NTD, CounterExpr::Zero());
+        pushRegion(NTD);
+      }
+      return continueWalk;
+    }
+    return true;
+  }
+
+  bool walkToDeclPost(Decl *D) override {
+    if (isa<TopLevelCodeDecl>(D))
+      ImplicitTopLevelBody = nullptr;
     return true;
   }
 
   std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
-    if (S->isImplicit())
+    if (S->isImplicit() && S != ImplicitTopLevelBody)
       return {true, S};
 
     if (!RegionStack.empty())
@@ -835,7 +860,7 @@
   }
 
   Stmt *walkToStmtPost(Stmt *S) override {
-    if (S->isImplicit())
+    if (S->isImplicit() && S != ImplicitTopLevelBody)
       return S;
 
     if (isa<BraceStmt>(S)) {
@@ -907,11 +932,8 @@
         return Result;
     } else if (auto *IE = dyn_cast<IfExpr>(E)) {
       CounterExpr &ThenCounter = assignCounter(IE->getThenExpr());
-      if (RegionStack.empty())
-        assignCounter(IE->getElseExpr());
-      else
-        assignCounter(IE->getElseExpr(),
-                      CounterExpr::Sub(getCurrentCounter(), ThenCounter));
+      assignCounter(IE->getElseExpr(),
+                    CounterExpr::Sub(getCurrentCounter(), ThenCounter));
     }
 
     if (hasCounter(E))
@@ -951,6 +973,16 @@
   return {};
 }
 
+static void walkTopLevelNodeForProfiling(ASTNode Root, ASTWalker &Walker) {
+  Root.walk(Walker);
+
+  // Visit extensions when walking through a nominal type.
+  auto *NTD = dyn_cast_or_null<NominalTypeDecl>(Root.dyn_cast<Decl *>());
+  if (NTD)
+    for (ExtensionDecl *ED : NTD->getExtensions())
+      ED->walk(Walker);
+}
+
 void SILProfiler::assignRegionCounters() {
   const auto &SM = M.getASTContext().SourceMgr;
 
@@ -970,23 +1002,23 @@
       TLCD->getStartLoc().printLineAndColumn(OS, SM);
       CurrentFuncLinkage = FormalLinkage::HiddenUnique;
     } else {
-      llvm_unreachable("Unsupported decl");
+      auto *NTD = cast<NominalTypeDecl>(D);
+      llvm::raw_string_ostream OS{CurrentFuncName};
+      OS << "__ntd_" << NTD->getNameStr() << "_";
+      NTD->getStartLoc().printLineAndColumn(OS, SM);
+      CurrentFuncLinkage = FormalLinkage::HiddenUnique;
     }
   } else {
-    auto *E = Root.get<Expr *>();
-    if (auto *CE = dyn_cast<AbstractClosureExpr>(E)) {
-      CurrentFuncName = SILDeclRef(CE).mangle();
-      CurrentFuncLinkage = FormalLinkage::HiddenUnique;
-    } else {
-      llvm_unreachable("Unsupported expr");
-    }
+    auto *CE = cast<AbstractClosureExpr>(Root.get<Expr *>());
+    CurrentFuncName = SILDeclRef(CE).mangle();
+    CurrentFuncLinkage = FormalLinkage::HiddenUnique;
   }
 
   PGOFuncName = llvm::getPGOFuncName(
       CurrentFuncName, getEquivalentPGOLinkage(CurrentFuncLinkage),
       CurrentFileName);
 
-  walkForProfiling(Root, Mapper);
+  walkTopLevelNodeForProfiling(Root, Mapper);
 
   NumRegionCounters = Mapper.NextCounter;
   // TODO: Mapper needs to calculate a function hash as it goes.
@@ -994,7 +1026,7 @@
 
   if (EmitCoverageMapping) {
     CoverageMapping Coverage(SM);
-    walkForProfiling(Root, Coverage);
+    walkTopLevelNodeForProfiling(Root, Coverage);
     CovMap =
         Coverage.emitSourceRegions(M, CurrentFuncName, PGOFuncName, PGOFuncHash,
                                    RegionCounterMap, CurrentFileName);
@@ -1012,7 +1044,7 @@
     }
     PGOMapping pgoMapper(RegionLoadedCounterMap, LoadedCounts,
                          RegionCondToParentMap);
-    walkForProfiling(Root, pgoMapper);
+    walkTopLevelNodeForProfiling(Root, pgoMapper);
   }
 }
 
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 13ab1e0..0ac3d43 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -62,6 +62,9 @@
                               "verify-di-holes",
                               llvm::cl::init(true));
 
+static llvm::cl::opt<bool> SkipConvertEscapeToNoescapeAttributes(
+    "verify-skip-convert-escape-to-noescape-attributes", llvm::cl::init(false));
+
 // The verifier is basically all assertions, so don't compile it with NDEBUG to
 // prevent release builds from triggering spurious unused variable warnings.
 
@@ -1418,14 +1421,17 @@
 
     SILFunction *RefF = FRI->getReferencedFunction();
 
-    // A direct reference to a shared_external declaration is an error; we
-    // should have deserialized a body.
-    if (RefF->isExternalDeclaration()) {
-      require(SingleFunction ||
-              !hasSharedVisibility(RefF->getLinkage()) ||
-              RefF->hasForeignBody(),
-              "external declarations of SILFunctions with shared visibility is "
-              "not allowed");
+    // In canonical SIL, direct reference to a shared_external declaration
+    // is an error; we should have deserialized a body. In raw SIL, we may
+    // not have deserialized the body yet.
+    if (F.getModule().getStage() >= SILStage::Canonical) {
+      if (RefF->isExternalDeclaration()) {
+        require(SingleFunction ||
+                !hasSharedVisibility(RefF->getLinkage()) ||
+                RefF->hasForeignBody(),
+                "external declarations of SILFunctions with shared visibility is "
+                "not allowed");
+      }
     }
 
     // A direct reference to a non-public or shared but not fragile function
@@ -3520,6 +3526,18 @@
     requireABICompatibleFunctionTypes(
         opTI, resTI->getWithExtInfo(resTI->getExtInfo().withNoEscape(false)),
         "convert_escape_to_noescape cannot change function ABI");
+
+    // After mandatory passes convert_escape_to_noescape should not have the
+    // '[not_guaranteed]' or '[escaped]' attributes.
+    if (!SkipConvertEscapeToNoescapeAttributes &&
+        F.getModule().getStage() != SILStage::Raw) {
+      require(!ICI->isEscapedByUser(),
+              "convert_escape_to_noescape [escaped] not "
+              "allowed after mandatory passes");
+      require(ICI->isLifetimeGuaranteed(),
+              "convert_escape_to_noescape [not_guaranteed] not "
+              "allowed after mandatory passes");
+    }
   }
 
   void checkThinFunctionToPointerInst(ThinFunctionToPointerInst *CI) {
diff --git a/lib/SIL/ValueOwnershipKindClassifier.cpp b/lib/SIL/ValueOwnershipKindClassifier.cpp
index d201e3f..3813009 100644
--- a/lib/SIL/ValueOwnershipKindClassifier.cpp
+++ b/lib/SIL/ValueOwnershipKindClassifier.cpp
@@ -475,6 +475,9 @@
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, GepRaw)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, Gep)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, GetTailAddr)
+CONSTANT_OWNERSHIP_BUILTIN(Trivial, PerformInstantaneousReadAccess)
+CONSTANT_OWNERSHIP_BUILTIN(Trivial, BeginUnpairedModifyAccess)
+CONSTANT_OWNERSHIP_BUILTIN(Trivial, EndUnpairedAccess)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, OnFastPath)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, IsUnique)
 CONSTANT_OWNERSHIP_BUILTIN(Trivial, IsUniqueOrPinned)
diff --git a/lib/SILGen/Cleanup.h b/lib/SILGen/Cleanup.h
index 6d66c18..28dc213 100644
--- a/lib/SILGen/Cleanup.h
+++ b/lib/SILGen/Cleanup.h
@@ -129,7 +129,6 @@
   friend class CleanupStateRestorationScope;
   friend class SharedBorrowFormalEvaluation;
   friend class FormalEvaluationScope;
-  friend class PostponedCleanup;
 
 public:
   CleanupManager(SILGenFunction &SGF)
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index 7c462eb..ff77f9c 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -488,6 +488,20 @@
          constant.isCurried;
 }
 
+SILProfiler *
+SILGenModule::getOrCreateProfilerForConstructors(NominalTypeDecl *decl) {
+  assert(decl && "No nominal type for constructor lookup");
+
+  const auto &Opts = M.getOptions();
+  if (!Opts.GenerateProfile && Opts.UseProfile.empty())
+    return nullptr;
+
+  SILProfiler *&profiler = constructorProfilers[decl];
+  if (!profiler)
+    profiler = SILProfiler::create(M, ForDefinition, decl);
+  return profiler;
+}
+
 SILFunction *SILGenModule::getFunction(SILDeclRef constant,
                                        ForDefinition_t forDefinition) {
   // If we already emitted the function, return it (potentially preparing it
@@ -737,42 +751,45 @@
     return;
 
   SILDeclRef constant(decl);
+  DeclContext *declCtx = decl->getDeclContext();
 
   bool ForCoverageMapping = doesASTRequireProfiling(M, decl);
 
-  if (decl->getDeclContext()->getAsClassOrClassExtensionContext()) {
+  if (auto *clsDecl = declCtx->getAsClassOrClassExtensionContext()) {
     // Class constructors have separate entry points for allocation and
     // initialization.
     emitOrDelayFunction(
-        *this, constant,
-        [this, constant, decl](SILFunction *f) {
+        *this, constant, [this, constant, decl](SILFunction *f) {
           preEmitFunction(constant, decl, f, decl);
           PrettyStackTraceSILFunction X("silgen emitConstructor", f);
-          f->createProfiler(decl, ForDefinition);
           SILGenFunction(*this, *f).emitClassConstructorAllocator(decl);
           postEmitFunction(constant, f);
-        },
-        /*forceEmission=*/ForCoverageMapping);
+        });
 
     // If this constructor was imported, we don't need the initializing
     // constructor to be emitted.
     if (!decl->hasClangNode()) {
       SILDeclRef initConstant(decl, SILDeclRef::Kind::Initializer);
-      emitOrDelayFunction(*this, initConstant,
-                          [this,initConstant,decl](SILFunction *initF){
-        preEmitFunction(initConstant, decl, initF, decl);
-        PrettyStackTraceSILFunction X("silgen constructor initializer", initF);
-        SILGenFunction(*this, *initF).emitClassConstructorInitializer(decl);
-        postEmitFunction(initConstant, initF);
-      });
+      emitOrDelayFunction(
+          *this, initConstant,
+          [this, initConstant, decl, clsDecl](SILFunction *initF) {
+            preEmitFunction(initConstant, decl, initF, decl);
+            PrettyStackTraceSILFunction X("silgen constructor initializer",
+                                          initF);
+            initF->setProfiler(getOrCreateProfilerForConstructors(clsDecl));
+            SILGenFunction(*this, *initF).emitClassConstructorInitializer(decl);
+            postEmitFunction(initConstant, initF);
+          },
+          /*forceEmission=*/ForCoverageMapping);
     }
   } else {
     // Struct and enum constructors do everything in a single function.
+    auto *nomDecl = declCtx->getAsNominalTypeOrNominalTypeExtensionContext();
     emitOrDelayFunction(
-        *this, constant, [this, constant, decl](SILFunction *f) {
+        *this, constant, [this, constant, decl, nomDecl](SILFunction *f) {
           preEmitFunction(constant, decl, f, decl);
           PrettyStackTraceSILFunction X("silgen emitConstructor", f);
-          f->createProfiler(decl, ForDefinition);
+          f->setProfiler(getOrCreateProfilerForConstructors(nomDecl));
           SILGenFunction(*this, *f).emitValueConstructor(decl);
           postEmitFunction(constant, f);
         });
@@ -975,9 +992,16 @@
   auto *init = pbdEntry.getInit();
 
   SILDeclRef constant(var, SILDeclRef::Kind::StoredPropertyInitializer);
-  emitOrDelayFunction(*this, constant, [this,constant,init](SILFunction *f) {
+  emitOrDelayFunction(*this, constant, [this,constant,init,var](SILFunction *f) {
     preEmitFunction(constant, init, f, init);
     PrettyStackTraceSILFunction X("silgen emitStoredPropertyInitialization", f);
+
+    // Inherit a profiler instance from the constructor.
+    auto *nominalDecl =
+        var->getDeclContext()->getAsNominalTypeOrNominalTypeExtensionContext();
+    if (nominalDecl)
+      f->setProfiler(getOrCreateProfilerForConstructors(nominalDecl));
+
     SILGenFunction(*this, *f).emitGeneratorFunction(constant, init);
     postEmitFunction(constant, f);
   });
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index c6c1c3a..66ae0b9 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -96,6 +96,10 @@
   /// The most recent conformance...
   NormalProtocolConformance *lastEmittedConformance = nullptr;
 
+  /// Profiler instances for constructors, grouped by associated nominal type.
+  /// Each profiler is shared by all member initializers for a nominal type.
+  llvm::DenseMap<NominalTypeDecl *, SILProfiler *> constructorProfilers;
+
   SILFunction *emitTopLevelFunction(SILLocation Loc);
 
   size_t anonymousSymbolCounter = 0;
@@ -435,6 +439,9 @@
 
   /// Emit a property descriptor for the given storage decl if it needs one.
   void tryEmitPropertyDescriptor(AbstractStorageDecl *decl);
+
+  /// Get or create the profiler instance for a nominal type's constructors.
+  SILProfiler *getOrCreateProfilerForConstructors(NominalTypeDecl *decl);
   
 private:
   /// Emit the deallocator for a class that uses the objc allocator.
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index e143dbe..a370fd7 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -259,6 +259,8 @@
 
   const Kind kind;
 
+  bool isMaterializeForSet = false;
+
   // Move, don't copy.
   Callee(const Callee &) = delete;
   Callee &operator=(const Callee &) = delete;
@@ -3674,7 +3676,7 @@
       SGF, calleeTypeInfo, uncurriedSites.back().Loc, uncurriedContext);
 
   ArgumentScope argScope(SGF, uncurriedSites.back().Loc);
-  PostponedCleanup postpone(SGF);
+
   // Emit the arguments.
   SmallVector<ManagedValue, 4> uncurriedArgs;
   Optional<SILLocation> uncurriedLoc;
@@ -3695,11 +3697,20 @@
 
   auto mv = callee.getFnValue(SGF, isCurried, borrowedSelf);
 
+  // Materialize for set could temporarily escape its arguments.
+  if (callee.isMaterializeForSet) {
+    auto indices = ArrayRef<ManagedValue>(uncurriedArgs).slice(2);
+    for (auto index : indices) {
+      auto *toNoEscape = dyn_cast<ConvertEscapeToNoEscapeInst>(index.getValue());
+      if (!toNoEscape) continue;
+      toNoEscape->setEscapedByUser();
+    }
+  }
   // Emit the uncurried call.
   firstLevelResult.value = SGF.emitApply(
       std::move(resultPlan), std::move(argScope), uncurriedLoc.getValue(), mv,
       callee.getSubstitutions(), uncurriedArgs, calleeTypeInfo, options,
-      uncurriedContext, postpone);
+      uncurriedContext);
   firstLevelResult.foreignSelf = calleeTypeInfo.foreignSelf;
   return firstLevelResult;
 }
@@ -4024,7 +4035,6 @@
     ResultPlanPtr resultPtr =
         ResultPlanBuilder::computeResultPlan(SGF, calleeTypeInfo, loc, context);
     ArgumentScope argScope(SGF, loc);
-    PostponedCleanup postpone(SGF);
 
     std::move(extraSites[i])
         .emit(SGF, origParamType, paramLowering, siteArgs, delayedArgs,
@@ -4035,7 +4045,7 @@
 
     result = SGF.emitApply(std::move(resultPtr), std::move(argScope), loc,
                            functionMV, {}, siteArgs, calleeTypeInfo,
-                           ApplyOptions::None, context, postpone);
+                           ApplyOptions::None, context);
   }
 
   return std::move(result);
@@ -4088,8 +4098,7 @@
                                  ManagedValue fn, SubstitutionList subs,
                                  ArrayRef<ManagedValue> args,
                                  const CalleeTypeInfo &calleeTypeInfo,
-                                 ApplyOptions options, SGFContext evalContext,
-                                 PostponedCleanup &postponedCleanup) {
+                                 ApplyOptions options, SGFContext evalContext) {
   auto substFnType = calleeTypeInfo.substFnType;
   auto substResultType = calleeTypeInfo.substResultType;
 
@@ -4150,7 +4159,6 @@
 
   // Emit the raw application.
   loc.decodeDebugLoc(SGM.M.getASTContext().SourceMgr);
-  postponedCleanup.end();
   SILValue rawDirectResult = emitRawApply(
       *this, loc, fn, subs, args, substFnType, options, indirectResultAddrs);
 
@@ -4271,9 +4279,8 @@
   ResultPlanPtr resultPlan = ResultPlanBuilder::computeResultPlan(
       *this, calleeTypeInfo, loc, evalContext);
   ArgumentScope argScope(*this, loc);
-  PostponedCleanup postpone(*this);
   return emitApply(std::move(resultPlan), std::move(argScope), loc, fn, {},
-                   args, calleeTypeInfo, options, evalContext, postpone);
+                   args, calleeTypeInfo, options, evalContext);
 }
 
 /// Emit either an 'apply' or a 'try_apply', with the error branch of
@@ -4463,10 +4470,8 @@
   ResultPlanPtr resultPlan =
       ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, ctx);
   ArgumentScope argScope(*this, loc);
-  PostponedCleanup postpone(*this);
   return emitApply(std::move(resultPlan), std::move(argScope), loc, mv, subs,
-                   finalArgs, calleeTypeInfo, ApplyOptions::None, ctx,
-                   postpone);
+                   finalArgs, calleeTypeInfo, ApplyOptions::None, ctx);
 }
 
 static StringRef
@@ -5121,6 +5126,8 @@
                                                      materializeForSet,
                                                      substitutions, selfValue,
                                                      isSuper, isDirectUse);
+  callee.isMaterializeForSet = true;
+
   bool hasSelf = (bool)selfValue;
   auto accessType = callee.getSubstFormalType();
 
diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp
index 8466b22..ff595a4 100644
--- a/lib/SILGen/SILGenBridging.cpp
+++ b/lib/SILGen/SILGenBridging.cpp
@@ -241,12 +241,11 @@
   ResultPlanPtr resultPlan =
       ResultPlanBuilder::computeResultPlan(SGF, calleeTypeInfo, loc, context);
   ArgumentScope argScope(SGF, loc);
-  PostponedCleanup postpone(SGF);
   RValue result =
       SGF.emitApply(std::move(resultPlan), std::move(argScope), loc,
                     ManagedValue::forUnmanaged(witnessRef), subs,
                     {objcValue, ManagedValue::forUnmanaged(metatypeValue)},
-                    calleeTypeInfo, ApplyOptions::None, context, postpone);
+                    calleeTypeInfo, ApplyOptions::None, context);
   return std::move(result).getAsSingleValue(SGF, loc);
 }
 
@@ -940,8 +939,8 @@
 
   // Handle the escaping to noescape conversion.
   assert(loweredFuncTy->isNoEscape());
-  return B.createConvertEscapeToNoEscape(loc, thunkedFn,
-                          SILType::getPrimitiveObjectType(loweredFuncTy));
+  return B.createConvertEscapeToNoEscape(
+      loc, thunkedFn, SILType::getPrimitiveObjectType(loweredFuncTy), false);
 }
 
 static ManagedValue emitCBridgedToNativeValue(SILGenFunction &SGF,
@@ -1760,11 +1759,10 @@
     ResultPlanPtr resultPlan = ResultPlanBuilder::computeResultPlan(
         *this, calleeTypeInfo, fd, context);
     ArgumentScope argScope(*this, fd);
-    PostponedCleanup postpone(*this);
     ManagedValue resultMV =
         emitApply(std::move(resultPlan), std::move(argScope), fd,
                   ManagedValue::forUnmanaged(fn), subs, args, calleeTypeInfo,
-                  ApplyOptions::None, context, postpone)
+                  ApplyOptions::None, context)
             .getAsSingleValue(*this, fd);
 
     if (indirectResult) {
diff --git a/lib/SILGen/SILGenBuilder.cpp b/lib/SILGen/SILGenBuilder.cpp
index c4f4353..87a517b 100644
--- a/lib/SILGen/SILGenBuilder.cpp
+++ b/lib/SILGen/SILGenBuilder.cpp
@@ -209,7 +209,7 @@
 
 ManagedValue SILGenBuilder::createConvertEscapeToNoEscape(
     SILLocation loc, ManagedValue fn, SILType resultTy,
-    bool postponeToNoEscapeCleanup) {
+    bool isEscapedByUser) {
 
   auto fnType = fn.getType().castTo<SILFunctionType>();
   auto resultFnType = resultTy.castTo<SILFunctionType>();
@@ -221,14 +221,9 @@
              SILFunctionTypeRepresentation::Thick &&
          !fnType->isNoEscape() && resultFnType->isNoEscape() &&
          "Expect a escaping to noescape conversion");
-
-  SILValue fnValue = postponeToNoEscapeCleanup
-                         ? fn.ensurePlusOne(SGF, loc).forward(SGF)
-                         : fn.getValue();
-  SILValue result = createConvertEscapeToNoEscape(loc, fnValue, resultTy,
-                                                  postponeToNoEscapeCleanup);
-  if (postponeToNoEscapeCleanup)
-    getSILGenFunction().enterPostponedCleanup(fnValue);
+  SILValue fnValue = fn.getValue();
+  SILValue result = createConvertEscapeToNoEscape(
+      loc, fnValue, resultTy, isEscapedByUser, false);
   return ManagedValue::forTrivialObjectRValue(result);
 }
 
diff --git a/lib/SILGen/SILGenBuilder.h b/lib/SILGen/SILGenBuilder.h
index a59d8fe..82e216b 100644
--- a/lib/SILGen/SILGenBuilder.h
+++ b/lib/SILGen/SILGenBuilder.h
@@ -364,7 +364,7 @@
   ManagedValue
   createConvertEscapeToNoEscape(SILLocation loc, ManagedValue fn,
                                 SILType resultTy,
-                                bool postponeToNoEscapeCleanup = true);
+                                bool isEscapedByUser);
 
   using SILBuilder::createStore;
   /// Forward \p value into \p address.
diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp
index f8953fe..59cc412 100644
--- a/lib/SILGen/SILGenBuiltin.cpp
+++ b/lib/SILGen/SILGenBuiltin.cpp
@@ -517,6 +517,90 @@
   return ManagedValue::forUnmanaged(addr);
 }
 
+/// Specialized emitter for Builtin.beginUnpairedModifyAccess.
+static ManagedValue emitBuiltinBeginUnpairedModifyAccess(SILGenFunction &SGF,
+                                                    SILLocation loc,
+                                           SubstitutionList substitutions,
+                                           ArrayRef<ManagedValue> args,
+                                           SGFContext C) {
+  assert(substitutions.size() == 1 &&
+        "Builtin.beginUnpairedModifyAccess should have one substitution");
+  assert(args.size() == 3 &&
+         "beginUnpairedModifyAccess should be given three arguments");
+
+  SILType elemTy = SGF.getLoweredType(substitutions[0].getReplacement());
+  SILValue addr = SGF.B.createPointerToAddress(loc, args[0].getUnmanagedValue(),
+                                               elemTy.getAddressType(),
+                                               /*strict*/ true,
+                                               /*invariant*/ false);
+
+  SILType valueBufferTy =
+      SGF.getLoweredType(SGF.getASTContext().TheUnsafeValueBufferType);
+
+  SILValue buffer = SGF.B.createPointerToAddress(loc, args[1].getUnmanagedValue(),
+                                                 valueBufferTy.getAddressType(),
+                                                 /*strict*/ true,
+                                                 /*invariant*/ false);
+  SGF.B.createBeginUnpairedAccess(loc, addr, buffer, SILAccessKind::Modify,
+                                  SILAccessEnforcement::Dynamic,
+                                  /*noNestedConflict*/ false);
+
+  return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));
+}
+
+/// Specialized emitter for Builtin.performInstantaneousReadAccess
+static ManagedValue emitBuiltinPerformInstantaneousReadAccess(SILGenFunction &SGF,
+                                                       SILLocation loc,
+                                                       SubstitutionList substitutions,
+                                                       ArrayRef<ManagedValue> args,
+                                                       SGFContext C) {
+  assert(substitutions.size() == 1 &&
+         "Builtin.performInstantaneousReadAccess should have one substitution");
+  assert(args.size() == 2 &&
+         "Builtin.performInstantaneousReadAccess should be given "
+         "two arguments");
+
+  SILType elemTy = SGF.getLoweredType(substitutions[0].getReplacement());
+  SILValue addr = SGF.B.createPointerToAddress(loc, args[0].getUnmanagedValue(),
+                                               elemTy.getAddressType(),
+                                               /*strict*/ true,
+                                               /*invariant*/ false);
+
+  // Begin and then immediately end a read access. No nested conflict is
+  // possible because there are no instructions between the begin and the
+  // end of the access.
+  SILValue access = SGF.B.createBeginAccess(loc, addr, SILAccessKind::Read,
+                                            SILAccessEnforcement::Dynamic,
+                                            /*noNestedConflict*/ true);
+  SGF.B.createEndAccess(loc, access, /*aborted*/ false);
+
+  return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));
+}
+
+/// Specialized emitter for Builtin.endUnpairedAccessModifyAccess.
+static ManagedValue emitBuiltinEndUnpairedAccess(SILGenFunction &SGF,
+                                                    SILLocation loc,
+                                           SubstitutionList substitutions,
+                                           ArrayRef<ManagedValue> args,
+                                           SGFContext C) {
+  assert(substitutions.size() == 0 &&
+        "Builtin.endUnpairedAccess should have no substitutions");
+  assert(args.size() == 1 &&
+         "endUnpairedAccess should be given one argument");
+
+  SILType valueBufferTy =
+      SGF.getLoweredType(SGF.getASTContext().TheUnsafeValueBufferType);
+
+  SILValue buffer = SGF.B.createPointerToAddress(loc, args[0].getUnmanagedValue(),
+                                                 valueBufferTy.getAddressType(),
+                                                 /*strict*/ true,
+                                                 /*invariant*/ false);
+  SGF.B.createEndUnpairedAccess(loc, buffer, SILAccessEnforcement::Dynamic,
+                                /*aborted*/ false);
+
+  return ManagedValue::forUnmanaged(SGF.emitEmptyTuple(loc));
+}
+
 /// Specialized emitter for Builtin.condfail.
 static ManagedValue emitBuiltinCondFail(SILGenFunction &SGF,
                                         SILLocation loc,
diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp
index 21c297f..ebf4264 100644
--- a/lib/SILGen/SILGenDecl.cpp
+++ b/lib/SILGen/SILGenDecl.cpp
@@ -1289,51 +1289,6 @@
   return Cleanups.getTopCleanup();
 }
 
-PostponedCleanup::PostponedCleanup(SILGenFunction &sgf, bool recursive)
-    : depth(sgf.Cleanups.innermostScope), SGF(sgf),
-      previouslyActiveCleanup(sgf.CurrentlyActivePostponedCleanup),
-      active(true), applyRecursively(recursive) {
-  SGF.CurrentlyActivePostponedCleanup = this;
-}
-
-PostponedCleanup::PostponedCleanup(SILGenFunction &sgf)
-    : depth(sgf.Cleanups.innermostScope), SGF(sgf),
-      previouslyActiveCleanup(sgf.CurrentlyActivePostponedCleanup),
-      active(true),
-      applyRecursively(previouslyActiveCleanup
-                           ? previouslyActiveCleanup->applyRecursively
-                           : false) {
-  SGF.CurrentlyActivePostponedCleanup = this;
-}
-
-PostponedCleanup::~PostponedCleanup() {
-  if (active) {
-    end();
-  }
-}
-
-void PostponedCleanup::end() {
-  if (previouslyActiveCleanup && applyRecursively &&
-      previouslyActiveCleanup->applyRecursively) {
-    previouslyActiveCleanup->deferredCleanups.append(deferredCleanups.begin(),
-                                                     deferredCleanups.end());
-  }
-
-  SGF.CurrentlyActivePostponedCleanup = previouslyActiveCleanup;
-  active = false;
-}
-
-void PostponedCleanup::postponeCleanup(CleanupHandle cleanup,
-                                       SILValue forValue) {
-  deferredCleanups.push_back(std::make_pair(cleanup, forValue));
-}
-
-void SILGenFunction::enterPostponedCleanup(SILValue forValue) {
-  auto handle = enterDestroyCleanup(forValue);
-  if (CurrentlyActivePostponedCleanup)
-    CurrentlyActivePostponedCleanup->postponeCleanup(handle, forValue);
-}
-
 namespace {
   /// A cleanup that deinitializes an opaque existential container
   /// before a value has been stored into it, or after its value was taken.
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index fbb86e7..df5da72 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -368,7 +368,6 @@
   // Handle the special case of copying an lvalue.
   if (auto load = dyn_cast<LoadExpr>(E)) {
     FormalEvaluationScope writeback(*this);
-    PostponedCleanup postpone(*this);
     auto lv = emitLValue(load->getSubExpr(), AccessKind::Read);
     emitCopyLValueInto(E, std::move(lv), I);
     return;
@@ -920,7 +919,6 @@
 
   // Any writebacks for this access are tightly scoped.
   FormalEvaluationScope scope(*this);
-  PostponedCleanup postpone(*this);
 
   // If this is a decl that we have an lvalue for, produce and return it.
   ValueDecl *decl = declRef.getDecl();
@@ -1400,7 +1398,6 @@
 RValue RValueEmitter::visitLoadExpr(LoadExpr *E, SGFContext C) {
   // Any writebacks here are tightly scoped.
   FormalEvaluationScope writeback(SGF);
-  PostponedCleanup postpone(SGF);
   LValue lv = SGF.emitLValue(E->getSubExpr(), AccessKind::Read);
   // We can't load at immediate +0 from the lvalue without deeper analysis,
   // since the access will be immediately ended and might invalidate the value
@@ -2091,9 +2088,7 @@
     result = convertFunctionRepresentation(SGF, e, result, srcRepTy, srcTy);
 
   if (srcTy != destTy) {
-    bool postponeToNoEscapeCleanup = !isa<BindOptionalExpr>(e->getSubExpr());
-    result = SGF.emitTransformedValue(e, result, srcTy, destTy, SGFContext(),
-                                      postponeToNoEscapeCleanup);
+    result = SGF.emitTransformedValue(e, result, srcTy, destTy, SGFContext());
   }
 
   if (destTy != destRepTy)
@@ -2577,7 +2572,6 @@
 
   // Any writebacks for this access are tightly scoped.
   FormalEvaluationScope scope(SGF);
-  PostponedCleanup postpone(SGF);
 
   LValue lv = SGF.emitLValue(E, AccessKind::Read);
   // We can't load at +0 without further analysis, since the formal access into
@@ -2599,7 +2593,6 @@
 RValue RValueEmitter::visitSubscriptExpr(SubscriptExpr *E, SGFContext C) {
   // Any writebacks for this access are tightly scoped.
   FormalEvaluationScope scope(SGF);
-  PostponedCleanup postpone(SGF);
 
   LValue lv = SGF.emitLValue(E, AccessKind::Read);
   // We can't load at +0 without further analysis, since the formal access into
@@ -2654,9 +2647,8 @@
   ResultPlanPtr resultPtr =
       ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, C);
   ArgumentScope argScope(*this, loc);
-  PostponedCleanup postpone(*this);
   return emitApply(std::move(resultPtr), std::move(argScope), loc, fnRef, subs,
-                   {}, calleeTypeInfo, ApplyOptions::None, C, postpone);
+                   {}, calleeTypeInfo, ApplyOptions::None, C);
 }
 
 RValue SILGenFunction::emitApplyOfStoredPropertyInitializer(
@@ -2678,9 +2670,8 @@
   ResultPlanPtr resultPlan =
       ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, C);
   ArgumentScope argScope(*this, loc);
-  PostponedCleanup postpone(*this);
   return emitApply(std::move(resultPlan), std::move(argScope), loc, fnRef, subs,
-                   {}, calleeTypeInfo, ApplyOptions::None, C, postpone);
+                   {}, calleeTypeInfo, ApplyOptions::None, C);
 }
 
 static void emitTupleShuffleExprInto(RValueEmitter &emitter,
@@ -3561,7 +3552,6 @@
         auto equalsResultPlan = ResultPlanBuilder::computeResultPlan(subSGF,
           equalsInfo, loc, SGFContext());
         ArgumentScope argScope(subSGF, loc);
-        PostponedCleanup postpone(subSGF);
         SmallVector<Substitution, 1> equatableSubListBuf;
         equatableProtocol->getGenericSignature()
           ->getSubstitutions(equatableSub, equatableSubListBuf);
@@ -3570,8 +3560,7 @@
                      loc, ManagedValue::forUnmanaged(equalsWitness),
                      C.AllocateCopy(equatableSubListBuf),
                      {lhsArg, rhsArg, metatyValue},
-                     equalsInfo, ApplyOptions::None, SGFContext(),
-                     postpone)
+                     equalsInfo, ApplyOptions::None, SGFContext())
           .getUnmanagedSingleValue(subSGF, loc);
       }
       
@@ -3700,13 +3689,11 @@
         auto hashResultPlan = ResultPlanBuilder::computeResultPlan(subSGF,
           hashInfo, loc, SGFContext());
         ArgumentScope argScope(subSGF, loc);
-        PostponedCleanup postpone(subSGF);
         hashCode =
             subSGF
                 .emitApply(std::move(hashResultPlan), std::move(argScope), loc,
                            ManagedValue::forUnmanaged(hashWitness), hashableSub,
-                           {arg}, hashInfo, ApplyOptions::None, SGFContext(),
-                           postpone)
+                           {arg}, hashInfo, ApplyOptions::None, SGFContext())
                 .getUnmanagedSingleValue(subSGF, loc);
       }
     }
@@ -4313,7 +4300,6 @@
   // Get newSelf, forward the cleanup for newSelf and clean everything else
   // up.
   FormalEvaluationScope Scope(SGF);
-  PostponedCleanup postpone(SGF);
   ManagedValue newSelfWithCleanup =
       SGF.emitRValueAsSingleValue(E->getSubExpr());
 
@@ -4867,7 +4853,6 @@
     if (dest->getType()->isEqual(srcLoad->getSubExpr()->getType())) {
       assert(!dest->getType()->is<TupleType>());
       FormalEvaluationScope writeback(SGF);
-      PostponedCleanup postpone(SGF);
       auto destLV = SGF.emitLValue(dest, AccessKind::Write);
       auto srcLV = SGF.emitLValue(srcLoad->getSubExpr(), AccessKind::Read);
       SGF.emitAssignLValueToLValue(loc, std::move(srcLV), std::move(destLV));
@@ -4889,14 +4874,12 @@
     }
     
     FormalEvaluationScope writeback(SGF);
-    PostponedCleanup postpone(SGF);
     LValue destLV = SGF.emitLValue(dest, AccessKind::Write);
     SGF.emitAssignToLValue(loc, src, std::move(destLV));
     return;
   }
 
   FormalEvaluationScope writeback(SGF);
-  PostponedCleanup postpone(SGF);
 
   // Produce a flattened queue of LValues.
   SmallVector<Optional<LValue>, 4> destLVs;
@@ -5700,7 +5683,6 @@
 RValue RValueEmitter::visitArrayToPointerExpr(ArrayToPointerExpr *E,
                                               SGFContext C) {
   FormalEvaluationScope writeback(SGF);
-  PostponedCleanup postpone(SGF);
 
   auto subExpr = E->getSubExpr();
   auto accessInfo = SGF.getArrayAccessInfo(E->getType(),
@@ -5885,7 +5867,6 @@
   if (E->getType()->hasLValueType()) {
     // Emit the l-value, but don't perform an access.
     FormalEvaluationScope scope(*this);
-    PostponedCleanup postpone(*this);
     emitLValue(E, AccessKind::Read);
     return;
   }
@@ -5894,7 +5875,6 @@
   // (which could materialize a potentially expensive value with cleanups).
   if (auto *LE = dyn_cast<LoadExpr>(E)) {
     FormalEvaluationScope scope(*this);
-    PostponedCleanup postpone(*this);
     LValue lv = emitLValue(LE->getSubExpr(), AccessKind::Read);
 
     // If loading from the lvalue is guaranteed to have no side effects, we
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index fb77e77..df211b6 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -43,7 +43,6 @@
 class ResultPlan;
 using ResultPlanPtr = std::unique_ptr<ResultPlan>;
 class ArgumentScope;
-class PostponedCleanup;
 class Scope;
 
 enum class ApplyOptions : unsigned {
@@ -248,10 +247,6 @@
   /// \brief The current context where formal evaluation cleanups are managed.
   FormalEvaluationContext FormalEvalContext;
 
-  /// Currently active postponed cleanups.
-  PostponedCleanup *CurrentlyActivePostponedCleanup = nullptr;
-  void enterPostponedCleanup(SILValue forValue);
-
   /// \brief Values to end dynamic access enforcement on.  A hack for
   /// materializeForSet.
   struct UnpairedAccesses {
@@ -1305,7 +1300,7 @@
                    SILLocation loc, ManagedValue fn, SubstitutionList subs,
                    ArrayRef<ManagedValue> args,
                    const CalleeTypeInfo &calleeTypeInfo, ApplyOptions options,
-                   SGFContext evalContext, PostponedCleanup &cleanup);
+                   SGFContext evalContext);
 
   RValue emitApplyOfDefaultArgGenerator(SILLocation loc,
                                         ConcreteDeclRef defaultArgsOwner,
@@ -1617,8 +1612,7 @@
   ManagedValue emitTransformedValue(SILLocation loc, ManagedValue input,
                                     CanType inputType,
                                     CanType outputType,
-                                    SGFContext ctx = SGFContext(),
-                                    bool postponeToNoEscapeCleanup = true);
+                                    SGFContext ctx = SGFContext());
 
   /// Most general form of the above.
   ManagedValue emitTransformedValue(SILLocation loc, ManagedValue input,
@@ -1626,8 +1620,7 @@
                                     CanType inputSubstType,
                                     AbstractionPattern outputOrigType,
                                     CanType outputSubstType,
-                                    SGFContext ctx = SGFContext(),
-                                    bool postponeToNoEscapeCleanup = true);
+                                    SGFContext ctx = SGFContext());
   RValue emitTransformedValue(SILLocation loc, RValue &&input,
                               AbstractionPattern inputOrigType,
                               CanType inputSubstType,
@@ -1869,37 +1862,6 @@
   }
 };
 
-/// Utility class to facilitate posponment of cleanup of @noescape
-/// partial_apply arguments into the 'right' scope.
-///
-/// If a Postponed cleanup is active at the end of a scope. The scope will
-/// actively push the cleanup into its surrounding scope.
-class PostponedCleanup {
-  friend SILGenFunction;
-  friend Scope;
-
-  SmallVector<std::pair<CleanupHandle, SILValue>, 16> deferredCleanups;
-  CleanupsDepth depth;
-  SILGenFunction &SGF;
-  PostponedCleanup *previouslyActiveCleanup;
-  bool active;
-  bool applyRecursively;
-
-  void postponeCleanup(CleanupHandle cleanup, SILValue forValue);
-public:
-  PostponedCleanup(SILGenFunction &SGF);
-  PostponedCleanup(SILGenFunction &SGF, bool applyRecursively);
-  ~PostponedCleanup();
-
-  void end();
-
-  PostponedCleanup() = delete;
-  PostponedCleanup(const PostponedCleanup &) = delete;
-  PostponedCleanup &operator=(const PostponedCleanup &) = delete;
-  PostponedCleanup &operator=(PostponedCleanup &&other) = delete;
-  PostponedCleanup(PostponedCleanup &&) = delete;
-};
-
 } // end namespace Lowering
 } // end namespace swift
 
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 16af207..5d81218 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -1243,9 +1243,6 @@
       SILValue buffer =
         SGF.emitTemporaryAllocation(loc, getTypeOfRValue());
 
-      // Postpone cleanup for noescape closures.
-      PostponedCleanup postpone(SGF, true);
-
       // Clone the component without cloning the indices.  We don't actually
       // consume them in writeback().
       std::unique_ptr<LogicalPathComponent> clonedComponent(
@@ -1303,7 +1300,6 @@
       // access for stored properties with didSet.
       pushWriteback(SGF, loc, std::move(clonedComponent), base, materialized);
 
-      postpone.end();
       return ManagedValue::forLValue(materialized.temporary.getValue());
     }
 
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index bbc0ea5..052e590 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -136,8 +136,7 @@
                            CanType inputSubstType,
                            AbstractionPattern outputOrigType,
                            CanType outputSubstType,
-                           SGFContext ctxt,
-                           bool postponeToNoEscapeCleanup = true);
+                           SGFContext ctxt);
 
     /// Transform a metatype value.
     ManagedValue transformMetatype(ManagedValue fn,
@@ -160,8 +159,7 @@
                                    CanAnyFunctionType inputSubstType,
                                    AbstractionPattern outputOrigType,
                                    CanAnyFunctionType outputSubstType,
-                                   const TypeLowering &expectedTL,
-                                   bool postponeToNoEscapeCleanup = true);
+                                   const TypeLowering &expectedTL);
   };
 } // end anonymous namespace
 ;
@@ -358,8 +356,7 @@
                                   CanType inputSubstType,
                                   AbstractionPattern outputOrigType,
                                   CanType outputSubstType,
-                                  SGFContext ctxt,
-                                  bool postponeToNoEscapeCleanup) {
+                                  SGFContext ctxt) {
   // Look through inout types.
   if (isa<InOutType>(inputSubstType))
     inputSubstType = CanType(inputSubstType->getInOutObjectType());
@@ -443,8 +440,7 @@
     return transformFunction(v,
                              inputOrigType, inputFnType,
                              outputOrigType, outputFnType,
-                             expectedTL,
-                             postponeToNoEscapeCleanup);
+                             expectedTL);
   }
 
   //  - tuples of transformable values
@@ -2937,8 +2933,8 @@
 
   // Handle the escaping to noescape conversion.
   assert(expectedType->isNoEscape());
-  return SGF.B.createConvertEscapeToNoEscape(loc, thunkedFn,
-                               SILType::getPrimitiveObjectType(expectedType));
+  return SGF.B.createConvertEscapeToNoEscape(
+      loc, thunkedFn, SILType::getPrimitiveObjectType(expectedType), false);
 }
 
 static CanSILFunctionType buildWithoutActuallyEscapingThunkType(
@@ -3045,8 +3041,7 @@
                                           CanAnyFunctionType inputSubstType,
                                           AbstractionPattern outputOrigType,
                                           CanAnyFunctionType outputSubstType,
-                                          const TypeLowering &expectedTL,
-                                          bool postponeToNoEscapeCleanup) {
+                                          const TypeLowering &expectedTL) {
   assert(fn.getType().isObject() &&
          "expected input to emitTransformedFunctionValue to be loaded");
 
@@ -3105,8 +3100,7 @@
   } else if (newFnType != expectedFnType) {
     // Escaping to noescape conversion.
     SILType resTy = SILType::getPrimitiveObjectType(expectedFnType);
-    fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy,
-                                             postponeToNoEscapeCleanup);
+    fn = SGF.B.createConvertEscapeToNoEscape(Loc, fn, resTy, false);
   }
 
   return fn;
@@ -3202,12 +3196,11 @@
 SILGenFunction::emitTransformedValue(SILLocation loc, ManagedValue v,
                                      CanType inputType,
                                      CanType outputType,
-                                     SGFContext ctxt,
-                                     bool postponeToNoEscapeCleanup) {
+                                     SGFContext ctxt) {
   return emitTransformedValue(loc, v,
                               AbstractionPattern(inputType), inputType,
                               AbstractionPattern(outputType), outputType,
-                              ctxt, postponeToNoEscapeCleanup);
+                              ctxt);
 }
 
 ManagedValue
@@ -3216,14 +3209,12 @@
                                      CanType inputSubstType,
                                      AbstractionPattern outputOrigType,
                                      CanType outputSubstType,
-                                     SGFContext ctxt,
-                                     bool postponeToNoEscapeCleanup) {
+                                     SGFContext ctxt) {
   return Transform(*this, loc).transform(v,
                                          inputOrigType,
                                          inputSubstType,
                                          outputOrigType,
-                                         outputSubstType, ctxt,
-                                         postponeToNoEscapeCleanup);
+                                         outputSubstType, ctxt);
 }
 
 RValue
diff --git a/lib/SILGen/Scope.cpp b/lib/SILGen/Scope.cpp
index 1fc5c9d..0606c59 100644
--- a/lib/SILGen/Scope.cpp
+++ b/lib/SILGen/Scope.cpp
@@ -122,26 +122,6 @@
 void Scope::popImpl() {
   SmallVector<SILValue, 16> cleanupsToPropagateToOuterScope;
 
-  // Deactivate any postpone cleanups in the current scope.
-  if (currentlyActivePostponedCleanup) {
-    bool inScope;
-    do {
-      inScope = false;
-      auto &deferredCleanups =
-          currentlyActivePostponedCleanup->deferredCleanups;
-      if (deferredCleanups.empty())
-        break;
-      auto &top = deferredCleanups.back();
-      auto topCleanupDepth = top.first.getDepth();
-      if (topCleanupDepth > depth.getDepth()) {
-        cleanups.forwardCleanup(top.first);
-        cleanupsToPropagateToOuterScope.push_back(top.second);
-        deferredCleanups.pop_back();
-        inScope = true;
-      }
-    } while (inScope);
-  }
-
   cleanups.stack.checkIterator(depth);
   cleanups.stack.checkIterator(cleanups.innermostScope);
   assert(cleanups.innermostScope == depth && "popping scopes out of order");
@@ -150,14 +130,4 @@
   cleanups.endScope(depth, loc);
   cleanups.stack.checkIterator(cleanups.innermostScope);
   cleanups.popTopDeadCleanups(cleanups.innermostScope);
-
-  // Propagate the cleanup to the current parent scope.
-  for (auto valueToCleanup : cleanupsToPropagateToOuterScope) {
-    auto handle = cleanups.SGF.enterDestroyCleanup(valueToCleanup);
-    // Propagate cleanup to parent Scope.
-    if (currentlyActivePostponedCleanup->depth.getDepth() < depth.getDepth()) {
-      currentlyActivePostponedCleanup->deferredCleanups.push_back(
-          std::make_pair(handle, valueToCleanup));
-    }
-  }
 }
diff --git a/lib/SILGen/Scope.h b/lib/SILGen/Scope.h
index 8b67e71..89ce3c8 100644
--- a/lib/SILGen/Scope.h
+++ b/lib/SILGen/Scope.h
@@ -31,14 +31,11 @@
   CleanupsDepth depth;
   CleanupsDepth savedInnermostScope;
   CleanupLocation loc;
-  PostponedCleanup *currentlyActivePostponedCleanup;
 
 public:
   explicit Scope(CleanupManager &cleanups, CleanupLocation loc)
       : cleanups(cleanups), depth(cleanups.getCleanupsDepth()),
-        savedInnermostScope(cleanups.innermostScope), loc(loc),
-        currentlyActivePostponedCleanup(
-            cleanups.SGF.CurrentlyActivePostponedCleanup) {
+        savedInnermostScope(cleanups.innermostScope), loc(loc) {
     assert(depth.isValid());
     cleanups.stack.checkIterator(cleanups.innermostScope);
     cleanups.innermostScope = depth;
diff --git a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp
index 5b2d77f..385b016 100644
--- a/lib/SILOptimizer/Analysis/AliasAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp
@@ -652,8 +652,8 @@
   if (!EA->canEscapeTo(Ptr, FAS))
     return false;
 
-  SideEffectAnalysis::FunctionEffects ApplyEffects;
-  SEA->getEffects(ApplyEffects, FAS);
+  FunctionSideEffects ApplyEffects;
+  SEA->getCalleeEffects(ApplyEffects, FAS);
 
   auto &GlobalEffects = ApplyEffects.getGlobalEffects();
   if (ApplyEffects.mayReadRC() || GlobalEffects.mayRelease())
diff --git a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
index 17ebb80..0b255a6 100644
--- a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
+++ b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
@@ -237,8 +237,8 @@
 
 MemBehavior MemoryBehaviorVisitor::visitApplyInst(ApplyInst *AI) {
 
-  SideEffectAnalysis::FunctionEffects ApplyEffects;
-  SEA->getEffects(ApplyEffects, AI);
+  FunctionSideEffects ApplyEffects;
+  SEA->getCalleeEffects(ApplyEffects, AI);
 
   MemBehavior Behavior = MemBehavior::None;
 
diff --git a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
index 28fb7d0..26e83a0 100644
--- a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp
@@ -2,7 +2,7 @@
 //
 // This source file is part of the Swift.org open source project
 //
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
 // Licensed under Apache License v2.0 with Runtime Library Exception
 //
 // See https://swift.org/LICENSE.txt for license information
@@ -19,12 +19,183 @@
 
 using namespace swift;
 
-using FunctionEffects = SideEffectAnalysis::FunctionEffects;
-using Effects = SideEffectAnalysis::Effects;
+// -----------------------------------------------------------------------------
+// GenericFunctionEffectAnalysis
+// -----------------------------------------------------------------------------
+
+template <typename FunctionEffects>
+void GenericFunctionEffectAnalysis<FunctionEffects>::initialize(
+    SILPassManager *PM) {
+  BCA = PM->getAnalysis<BasicCalleeAnalysis>();
+}
+
+template <typename FunctionEffects>
+void GenericFunctionEffectAnalysis<FunctionEffects>::invalidate() {
+  functionInfoMap.clear();
+  allocator.DestroyAll();
+  DEBUG(llvm::dbgs() << "invalidate all\n");
+}
+
+template <typename FunctionEffects>
+void GenericFunctionEffectAnalysis<FunctionEffects>::invalidate(
+    SILFunction *F, InvalidationKind K) {
+  if (FunctionInfo *FInfo = functionInfoMap.lookup(F)) {
+    DEBUG(llvm::dbgs() << "  invalidate " << FInfo->F->getName() << '\n');
+    invalidateIncludingAllCallers(FInfo);
+  }
+}
+
+template <typename FunctionEffects>
+void GenericFunctionEffectAnalysis<FunctionEffects>::getCalleeEffects(
+    FunctionEffects &calleeEffects, FullApplySite fullApply) {
+  if (calleeEffects.summarizeCall(fullApply))
+    return;
+
+  auto callees = BCA->getCalleeList(fullApply);
+  if (!callees.allCalleesVisible() ||
+      // @callee_owned function calls implicitly release the context, which
+      // may call deinits of boxed values.
+      // TODO: be less conservative about what destructors might be called.
+      fullApply.getOrigCalleeType()->isCalleeConsumed()) {
+    calleeEffects.setWorstEffects();
+    return;
+  }
+
+  // We can see all the callees, so merge the effects from all of them.
+  for (auto *callee : callees)
+    calleeEffects.mergeFrom(getEffects(callee));
+}
+
+template <typename FunctionEffects>
+void GenericFunctionEffectAnalysis<FunctionEffects>::analyzeFunction(
+    FunctionInfo *functionInfo, FunctionOrder &bottomUpOrder,
+    int recursionDepth) {
+  functionInfo->needUpdateCallers = true;
+
+  if (bottomUpOrder.prepareForVisiting(functionInfo))
+    return;
+
+  auto *F = functionInfo->F;
+  if (functionInfo->functionEffects.summarizeFunction(F))
+    return;
+
+  DEBUG(llvm::dbgs() << "  >> analyze " << F->getName() << '\n');
+
+  // Check all instructions of the function
+  for (auto &BB : *F) {
+    for (auto &I : BB) {
+      if (auto fullApply = FullApplySite::isa(&I))
+        analyzeCall(functionInfo, fullApply, bottomUpOrder, recursionDepth);
+      else
+        functionInfo->functionEffects.analyzeInstruction(&I);
+    }
+  }
+  DEBUG(llvm::dbgs() << "  << finished " << F->getName() << '\n');
+}
+
+template <typename FunctionEffects>
+void GenericFunctionEffectAnalysis<FunctionEffects>::analyzeCall(
+    FunctionInfo *functionInfo, FullApplySite fullApply,
+    FunctionOrder &bottomUpOrder, int recursionDepth) {
+
+  FunctionEffects applyEffects;
+  if (applyEffects.summarizeCall(fullApply)) {
+    functionInfo->functionEffects.mergeFromApply(applyEffects, fullApply);
+    return;
+  }
+
+  if (recursionDepth >= MaxRecursionDepth) {
+    functionInfo->functionEffects.setWorstEffects();
+    return;
+  }
+  CalleeList callees = BCA->getCalleeList(fullApply);
+  if (!callees.allCalleesVisible() ||
+      // @callee_owned function calls implicitly release the context, which
+      // may call deinits of boxed values.
+      // TODO: be less conservative about what destructors might be called.
+      fullApply.getOrigCalleeType()->isCalleeConsumed()) {
+    functionInfo->functionEffects.setWorstEffects();
+    return;
+  }
+  // Derive the effects of the apply from the known callees.
+  // Defer merging callee effects until the callee is scheduled
+  for (SILFunction *callee : callees) {
+    FunctionInfo *calleeInfo = getFunctionInfo(callee);
+    calleeInfo->addCaller(functionInfo, fullApply);
+    if (!calleeInfo->isVisited()) {
+      // Recursively visit the called function.
+      analyzeFunction(calleeInfo, bottomUpOrder, recursionDepth + 1);
+      bottomUpOrder.tryToSchedule(calleeInfo);
+    }
+  }
+}
+
+template <typename FunctionEffects>
+void GenericFunctionEffectAnalysis<FunctionEffects>::recompute(
+    FunctionInfo *initialInfo) {
+  allocNewUpdateID();
+
+  DEBUG(llvm::dbgs() << "recompute function-effect analysis with UpdateID "
+                     << getCurrentUpdateID() << '\n');
+
+  // Collect and analyze all functions to recompute, starting at initialInfo.
+  FunctionOrder bottomUpOrder(getCurrentUpdateID());
+  analyzeFunction(initialInfo, bottomUpOrder, 0);
+
+  // Build the bottom-up order.
+  bottomUpOrder.tryToSchedule(initialInfo);
+  bottomUpOrder.finishScheduling();
+
+  // Second step: propagate the side-effect information up the call-graph until
+  // it stabilizes.
+  bool needAnotherIteration;
+  do {
+    DEBUG(llvm::dbgs() << "new iteration\n");
+    needAnotherIteration = false;
+
+    for (FunctionInfo *functionInfo : bottomUpOrder) {
+      if (!functionInfo->needUpdateCallers)
+        continue;
+
+      DEBUG(llvm::dbgs() << "  update callers of " << functionInfo->F->getName()
+                         << '\n');
+      functionInfo->needUpdateCallers = false;
+
+      // Propagate the function effects to all callers.
+      for (const auto &E : functionInfo->getCallers()) {
+        assert(E.isValid());
+
+        // Only include callers which we are actually recomputing.
+        if (!bottomUpOrder.wasRecomputedWithCurrentUpdateID(E.Caller))
+          continue;
+
+        DEBUG(llvm::dbgs() << "    merge into caller " << E.Caller->F->getName()
+                           << '\n');
+
+        if (E.Caller->functionEffects.mergeFromApply(
+                functionInfo->functionEffects, FullApplySite(E.FAS))) {
+          E.Caller->needUpdateCallers = true;
+          if (!E.Caller->isScheduledAfter(functionInfo)) {
+            // This happens if we have a cycle in the call-graph.
+            needAnotherIteration = true;
+          }
+        }
+      }
+    }
+  } while (needAnotherIteration);
+}
+
+// Instantiate template members.
+template class swift::GenericFunctionEffectAnalysis<FunctionSideEffects>;
+
+// -----------------------------------------------------------------------------
+// FunctionSideEffects
+// -----------------------------------------------------------------------------
+
 using MemoryBehavior = SILInstruction::MemoryBehavior;
 
 MemoryBehavior
-FunctionEffects::getMemBehavior(RetainObserveKind ScanKind) const {
+FunctionSideEffects::getMemBehavior(RetainObserveKind ScanKind) const {
 
   bool Observe = (ScanKind == RetainObserveKind::ObserveRetains);
   if ((Observe && mayAllocObjects()) || mayReadRC())
@@ -46,7 +217,7 @@
   return Behavior;
 }
 
-bool FunctionEffects::mergeFrom(const FunctionEffects &RHS) {
+bool FunctionSideEffects::mergeFrom(const FunctionSideEffects &RHS) {
   bool Changed = mergeFlags(RHS);
   Changed |= GlobalEffects.mergeFrom(RHS.GlobalEffects);
   Changed |= LocalEffects.mergeFrom(RHS.LocalEffects);
@@ -64,33 +235,26 @@
   return Changed;
 }
 
-bool FunctionEffects::mergeFromApply(
-                  const FunctionEffects &ApplyEffects, FullApplySite FAS) {
-  return mergeFromApply(ApplyEffects, FAS.getInstruction());
-}
-
-bool FunctionEffects::mergeFromApply(
-                  const FunctionEffects &ApplyEffects, SILInstruction *AS) {
+bool FunctionSideEffects::mergeFromApply(
+    const FunctionSideEffects &ApplyEffects, FullApplySite FAS) {
   bool Changed = mergeFlags(ApplyEffects);
   Changed |= GlobalEffects.mergeFrom(ApplyEffects.GlobalEffects);
-  auto FAS = FullApplySite::isa(AS);
-  unsigned numCallerArgs = FAS ? FAS.getNumArguments() : 1;
+  unsigned numCallerArgs = FAS.getNumArguments();
   unsigned numCalleeArgs = ApplyEffects.ParamEffects.size();
   assert(numCalleeArgs >= numCallerArgs);
   for (unsigned Idx = 0; Idx < numCalleeArgs; Idx++) {
     // Map the callee argument effects to parameters of this function.
     // If there are more callee parameters than arguments it means that the
     // callee is the result of a partial_apply.
-    Effects *E = (Idx < numCallerArgs ? getEffectsOn(FAS ? FAS.getArgument(Idx) : AS->getOperand(Idx)) :
-                  &GlobalEffects);
+    FunctionSideEffectFlags *E = (Idx < numCallerArgs
+                                  ? getEffectsOn(FAS.getArgument(Idx))
+                                  : &GlobalEffects);
     Changed |= E->mergeFrom(ApplyEffects.ParamEffects[Idx]);
   }
   return Changed;
 }
 
-void FunctionEffects::dump() const {
-  llvm::errs() << *this << '\n';
-}
+void FunctionSideEffects::dump() const { llvm::errs() << *this << '\n'; }
 
 static SILValue skipAddrProjections(SILValue V) {
   for (;;) {
@@ -130,7 +294,7 @@
   llvm_unreachable("there is no escape from an infinite loop");
 }
 
-Effects *FunctionEffects::getEffectsOn(SILValue Addr) {
+FunctionSideEffectFlags *FunctionSideEffects::getEffectsOn(SILValue Addr) {
   SILValue BaseAddr = skipValueProjections(skipAddrProjections(Addr));
   switch (BaseAddr->getKind()) {
   case swift::ValueKind::SILFunctionArgument: {
@@ -152,17 +316,18 @@
   return &GlobalEffects;
 }
 
-bool SideEffectAnalysis::getDefinedEffects(FunctionEffects &Effects,
-                                           SILFunction *F) {
+// Return true if the given function has defined effects that were successfully
+// recorded in this FunctionSideEffects object.
+bool FunctionSideEffects::setDefinedEffects(SILFunction *F) {
   if (F->hasSemanticsAttr("arc.programtermination_point")) {
-    Effects.Traps = true;
+    Traps = true;
     return true;
   }
   switch (F->getEffectsKind()) {
     case EffectsKind::ReleaseNone:
-      Effects.GlobalEffects.Reads = true;
-      Effects.GlobalEffects.Writes = true;
-      Effects.GlobalEffects.Releases = false;
+      GlobalEffects.Reads = true;
+      GlobalEffects.Writes = true;
+      GlobalEffects.Releases = false;
       return true;
     case EffectsKind::ReadNone:
       return true;
@@ -171,7 +336,7 @@
       // the release inside the callee may call a deinit, which itself can do
       // anything.
       if (!F->hasOwnedParameters()) {
-        Effects.GlobalEffects.Reads = true;
+        GlobalEffects.Reads = true;
         return true;
       }
       break;
@@ -182,10 +347,34 @@
   return false;
 }
 
-bool SideEffectAnalysis::getSemanticEffects(FunctionEffects &FE,
-                                            ArraySemanticsCall ASC) {
+// Return true if this function's effects have been fully summarized in this
+// FunctionSideEffects object without visiting its body.
+bool FunctionSideEffects::summarizeFunction(SILFunction *F) {
+  assert(ParamEffects.empty() && "Expect uninitialized effects.");
+  if (!F->empty())
+    ParamEffects.resize(F->getArguments().size());
+
+  // Handle @effects attributes
+  if (setDefinedEffects(F)) {
+    DEBUG(llvm::dbgs() << "  -- has defined effects " << F->getName() << '\n');
+    return true;
+  }
+
+  if (!F->isDefinition()) {
+    // We can't assume anything about external functions.
+    DEBUG(llvm::dbgs() << "  -- is external " << F->getName() << '\n');
+    setWorstEffects();
+    return true;
+  }
+  return false;
+}
+
+// Return true if the side effects of this semantic call are fully known without
+// visiting the callee and have been recorded in this FunctionSideEffects
+// object.
+bool FunctionSideEffects::setSemanticEffects(ArraySemanticsCall ASC) {
   assert(ASC.hasSelf());
-  auto &SelfEffects = FE.ParamEffects[FE.ParamEffects.size() - 1];
+  auto &SelfEffects = ParamEffects[ParamEffects.size() - 1];
 
   // Currently we only handle array semantics.
   // TODO: also handle other semantic functions.
@@ -205,7 +394,7 @@
       if (!ASC.mayHaveBridgedObjectElementType()) {
         SelfEffects.Reads = true;
         SelfEffects.Releases |= !ASC.hasGuaranteedSelf();
-        FE.Traps = true;
+        Traps = true;
         return true;
       }
       return false;
@@ -218,7 +407,7 @@
                                 ->getOrigCalleeConv()
                                 .getNumIndirectSILResults())) {
           assert(!ASC.hasGetElementDirectResult());
-          FE.ParamEffects[i].Writes = true;
+          ParamEffects[i].Writes = true;
         }
         return true;
       }
@@ -240,9 +429,9 @@
     case ArrayCallKind::kMakeMutable:
       if (!ASC.mayHaveBridgedObjectElementType()) {
         SelfEffects.Writes = true;
-        FE.GlobalEffects.Releases = true;
-        FE.AllocsObjects = true;
-        FE.ReadsRC = true;
+        GlobalEffects.Releases = true;
+        AllocsObjects = true;
+        ReadsRC = true;
         return true;
       }
       return false;
@@ -252,290 +441,134 @@
   }
 }
 
-void SideEffectAnalysis::analyzeFunction(FunctionInfo *FInfo,
-                                         FunctionOrder &BottomUpOrder,
-                                         int RecursionDepth) {
-  FInfo->NeedUpdateCallers = true;
+// Summarize the callee side effects of a call instruction using this
+// FunctionSideEffects object without analyzing the callee function bodies or
+// scheduling the callees for bottom-up propagation.
+//
+// Return true if this call-site's effects are summarized without visiting the
+// callee.
+bool FunctionSideEffects::summarizeCall(FullApplySite fullApply) {
+  assert(ParamEffects.empty() && "Expect uninitialized effects.");
+  ParamEffects.resize(fullApply.getNumArguments());
 
-  if (BottomUpOrder.prepareForVisiting(FInfo))
-    return;
-
-  // Handle @effects attributes
-  if (getDefinedEffects(FInfo->FE, FInfo->F)) {
-    DEBUG(llvm::dbgs() << "  -- has defined effects " <<
-          FInfo->F->getName() << '\n');
-    return;
-  }
-  
-  if (!FInfo->F->isDefinition()) {
-    // We can't assume anything about external functions.
-    DEBUG(llvm::dbgs() << "  -- is external " << FInfo->F->getName() << '\n');
-    FInfo->FE.setWorstEffects();
-    return;
-  }
-  
-  DEBUG(llvm::dbgs() << "  >> analyze " << FInfo->F->getName() << '\n');
-
-  // Check all instructions of the function
-  for (auto &BB : *FInfo->F) {
-    for (auto &I : BB) {
-      analyzeInstruction(FInfo, &I, BottomUpOrder, RecursionDepth);
+  // Is this a call to a semantics function?
+  if (auto apply = dyn_cast<ApplyInst>(fullApply.getInstruction())) {
+    ArraySemanticsCall ASC(apply);
+    if (ASC && ASC.hasSelf()) {
+      if (setSemanticEffects(ASC))
+        return true;
     }
   }
-  DEBUG(llvm::dbgs() << "  << finished " << FInfo->F->getName() << '\n');
+
+  if (SILFunction *SingleCallee = fullApply.getReferencedFunction()) {
+    // Does the function have any @effects?
+    if (setDefinedEffects(SingleCallee))
+      return true;
+  }
+  return false;
 }
 
-void SideEffectAnalysis::analyzeInstruction(FunctionInfo *FInfo,
-                                            SILInstruction *I,
-                                            FunctionOrder &BottomUpOrder,
-                                            int RecursionDepth) {
-  if (FullApplySite FAS = FullApplySite::isa(I)) {
-    // Is this a call to a semantics function?
-    if (auto apply = dyn_cast<ApplyInst>(FAS.getInstruction())) {
-      ArraySemanticsCall ASC(apply);
-      if (ASC && ASC.hasSelf()) {
-        FunctionEffects ApplyEffects(FAS.getNumArguments());
-        if (getSemanticEffects(ApplyEffects, ASC)) {
-          FInfo->FE.mergeFromApply(ApplyEffects, FAS);
-          return;
-        }
-      }
-    }
-
-    if (SILFunction *SingleCallee = FAS.getReferencedFunction()) {
-      // Does the function have any @effects?
-      if (getDefinedEffects(FInfo->FE, SingleCallee))
-        return;
-    }
-
-    if (RecursionDepth < MaxRecursionDepth) {
-      CalleeList Callees = BCA->getCalleeList(FAS);
-      if (Callees.allCalleesVisible() &&
-          // @callee_owned function calls implicitly release the context, which
-          // may call deinits of boxed values.
-          // TODO: be less conservative about what destructors might be called.
-          !FAS.getOrigCalleeType()->isCalleeConsumed()) {
-        // Derive the effects of the apply from the known callees.
-        for (SILFunction *Callee : Callees) {
-          FunctionInfo *CalleeInfo = getFunctionInfo(Callee);
-          CalleeInfo->addCaller(FInfo, FAS);
-          if (!CalleeInfo->isVisited()) {
-            // Recursively visit the called function.
-            analyzeFunction(CalleeInfo, BottomUpOrder, RecursionDepth + 1);
-            BottomUpOrder.tryToSchedule(CalleeInfo);
-          }
-        }
-        return;
-      }
-    }
-    // Be conservative for everything else.
-    FInfo->FE.setWorstEffects();
-    return;
-  }
+void FunctionSideEffects::analyzeInstruction(SILInstruction *I) {
   // Handle some kind of instructions specially.
   switch (I->getKind()) {
-    case SILInstructionKind::FixLifetimeInst:
-      // A fix_lifetime instruction acts like a read on the operand. Retains can move after it
-      // but the last release can't move before it.
-      FInfo->FE.getEffectsOn(I->getOperand(0))->Reads = true;
-      return;
-    case SILInstructionKind::AllocStackInst:
-    case SILInstructionKind::DeallocStackInst:
-      return;
-    case SILInstructionKind::StrongRetainInst:
-    case SILInstructionKind::StrongRetainUnownedInst:
-    case SILInstructionKind::RetainValueInst:
-    case SILInstructionKind::UnownedRetainInst:
-      FInfo->FE.getEffectsOn(I->getOperand(0))->Retains = true;
-      return;
-    case SILInstructionKind::StrongReleaseInst:
-    case SILInstructionKind::ReleaseValueInst:
-    case SILInstructionKind::UnownedReleaseInst:
-      FInfo->FE.getEffectsOn(I->getOperand(0))->Releases = true;
-      return;
-    case SILInstructionKind::UnconditionalCheckedCastInst:
-      FInfo->FE.getEffectsOn(cast<UnconditionalCheckedCastInst>(I)->getOperand())->Reads = true;
-      FInfo->FE.Traps = true;
-      return;
-    case SILInstructionKind::LoadInst:
-      FInfo->FE.getEffectsOn(cast<LoadInst>(I)->getOperand())->Reads = true;
-      return;
-    case SILInstructionKind::StoreInst:
-      FInfo->FE.getEffectsOn(cast<StoreInst>(I)->getDest())->Writes = true;
-      return;
-    case SILInstructionKind::CondFailInst:
-      FInfo->FE.Traps = true;
-      return;
-    case SILInstructionKind::PartialApplyInst: {
-      FInfo->FE.AllocsObjects = true;
-      auto *PAI = cast<PartialApplyInst>(I);
-      auto Args = PAI->getArguments();
-      auto Params = PAI->getSubstCalleeType()->getParameters();
-      Params = Params.slice(Params.size() - Args.size(), Args.size());
-      for (unsigned Idx : indices(Args)) {
-        if (isIndirectFormalParameter(Params[Idx].getConvention()))
-          FInfo->FE.getEffectsOn(Args[Idx])->Reads = true;
-      }
-      return;
+  case SILInstructionKind::FixLifetimeInst:
+    // A fix_lifetime instruction acts like a read on the operand. Retains can
+    // move after it but the last release can't move before it.
+    getEffectsOn(I->getOperand(0))->Reads = true;
+    return;
+  case SILInstructionKind::AllocStackInst:
+  case SILInstructionKind::DeallocStackInst:
+    return;
+  case SILInstructionKind::StrongRetainInst:
+  case SILInstructionKind::StrongRetainUnownedInst:
+  case SILInstructionKind::RetainValueInst:
+  case SILInstructionKind::UnownedRetainInst:
+    getEffectsOn(I->getOperand(0))->Retains = true;
+    return;
+  case SILInstructionKind::StrongReleaseInst:
+  case SILInstructionKind::ReleaseValueInst:
+  case SILInstructionKind::UnownedReleaseInst:
+    getEffectsOn(I->getOperand(0))->Releases = true;
+    return;
+  case SILInstructionKind::UnconditionalCheckedCastInst:
+    getEffectsOn(cast<UnconditionalCheckedCastInst>(I)->getOperand())->Reads =
+        true;
+    Traps = true;
+    return;
+  case SILInstructionKind::LoadInst:
+    getEffectsOn(cast<LoadInst>(I)->getOperand())->Reads = true;
+    return;
+  case SILInstructionKind::StoreInst:
+    getEffectsOn(cast<StoreInst>(I)->getDest())->Writes = true;
+    return;
+  case SILInstructionKind::CondFailInst:
+    Traps = true;
+    return;
+  case SILInstructionKind::PartialApplyInst: {
+    AllocsObjects = true;
+    auto *PAI = cast<PartialApplyInst>(I);
+    auto Args = PAI->getArguments();
+    auto Params = PAI->getSubstCalleeType()->getParameters();
+    Params = Params.slice(Params.size() - Args.size(), Args.size());
+    for (unsigned Idx : indices(Args)) {
+      if (isIndirectFormalParameter(Params[Idx].getConvention()))
+        getEffectsOn(Args[Idx])->Reads = true;
     }
-    case SILInstructionKind::BuiltinInst: {
-      auto *BInst = cast<BuiltinInst>(I);
-      auto &BI = BInst->getBuiltinInfo();
-      switch (BI.ID) {
-        case BuiltinValueKind::IsUnique:
-          // TODO: derive this information in a more general way, e.g. add it
-          // to Builtins.def
-          FInfo->FE.ReadsRC = true;
-          break;
-        case BuiltinValueKind::CondUnreachable:
-          FInfo->FE.Traps = true;
-          return;
-        default:
-          break;
-      }
-      const IntrinsicInfo &IInfo = BInst->getIntrinsicInfo();
-      if (IInfo.ID == llvm::Intrinsic::trap) {
-        FInfo->FE.Traps = true;
-        return;
-      }
-      // Detailed memory effects of builtins are handled below by checking the
-      // memory behavior of the instruction.
+    return;
+  }
+  case SILInstructionKind::BuiltinInst: {
+    auto *BInst = cast<BuiltinInst>(I);
+    auto &BI = BInst->getBuiltinInfo();
+    switch (BI.ID) {
+    case BuiltinValueKind::IsUnique:
+      // TODO: derive this information in a more general way, e.g. add it
+      // to Builtins.def
+      ReadsRC = true;
       break;
-    }
+    case BuiltinValueKind::CondUnreachable:
+      Traps = true;
+      return;
     default:
       break;
+    }
+    const IntrinsicInfo &IInfo = BInst->getIntrinsicInfo();
+    if (IInfo.ID == llvm::Intrinsic::trap) {
+      Traps = true;
+      return;
+    }
+    // Detailed memory effects of builtins are handled below by checking the
+    // memory behavior of the instruction.
+    break;
+  }
+  default:
+    break;
   }
 
   if (isa<AllocationInst>(I)) {
     // Excluding AllocStackInst (which is handled above).
-    FInfo->FE.AllocsObjects = true;
+    AllocsObjects = true;
   }
   
   // Check the general memory behavior for instructions we didn't handle above.
   switch (I->getMemoryBehavior()) {
-    case MemoryBehavior::None:
-      break;
-    case MemoryBehavior::MayRead:
-      FInfo->FE.GlobalEffects.Reads = true;
-      break;
-    case MemoryBehavior::MayWrite:
-      FInfo->FE.GlobalEffects.Writes = true;
-      break;
-    case MemoryBehavior::MayReadWrite:
-      FInfo->FE.GlobalEffects.Reads = true;
-      FInfo->FE.GlobalEffects.Writes = true;
-      break;
-    case MemoryBehavior::MayHaveSideEffects:
-      FInfo->FE.setWorstEffects();
-      break;
+  case MemoryBehavior::None:
+    break;
+  case MemoryBehavior::MayRead:
+    GlobalEffects.Reads = true;
+    break;
+  case MemoryBehavior::MayWrite:
+    GlobalEffects.Writes = true;
+    break;
+  case MemoryBehavior::MayReadWrite:
+    GlobalEffects.Reads = true;
+    GlobalEffects.Writes = true;
+    break;
+  case MemoryBehavior::MayHaveSideEffects:
+    setWorstEffects();
+    break;
   }
   if (I->mayTrap())
-    FInfo->FE.Traps = true;
-}
-
-void SideEffectAnalysis::initialize(SILPassManager *PM) {
-  BCA = PM->getAnalysis<BasicCalleeAnalysis>();
-}
-
-void SideEffectAnalysis::recompute(FunctionInfo *Initial) {
-  allocNewUpdateID();
-
-  DEBUG(llvm::dbgs() << "recompute side-effect analysis with UpdateID " <<
-        getCurrentUpdateID() << '\n');
-
-  // Collect and analyze all functions to recompute, starting at Initial.
-  FunctionOrder BottomUpOrder(getCurrentUpdateID());
-  analyzeFunction(Initial, BottomUpOrder, 0);
-
-  // Build the bottom-up order.
-  BottomUpOrder.tryToSchedule(Initial);
-  BottomUpOrder.finishScheduling();
-
-  // Second step: propagate the side-effect information up the call-graph until
-  // it stabilizes.
-  bool NeedAnotherIteration;
-  do {
-    DEBUG(llvm::dbgs() << "new iteration\n");
-    NeedAnotherIteration = false;
-
-    for (FunctionInfo *FInfo : BottomUpOrder) {
-      if (FInfo->NeedUpdateCallers) {
-        DEBUG(llvm::dbgs() << "  update callers of " << FInfo->F->getName() <<
-              '\n');
-        FInfo->NeedUpdateCallers = false;
-
-        // Propagate the side-effects to all callers.
-        for (const auto &E : FInfo->getCallers()) {
-          assert(E.isValid());
-
-          // Only include callers which we are actually recomputing.
-          if (BottomUpOrder.wasRecomputedWithCurrentUpdateID(E.Caller)) {
-            DEBUG(llvm::dbgs() << "    merge into caller " <<
-                  E.Caller->F->getName() << '\n');
-
-            if (E.Caller->FE.mergeFromApply(FInfo->FE, E.FAS)) {
-              E.Caller->NeedUpdateCallers = true;
-              if (!E.Caller->isScheduledAfter(FInfo)) {
-                // This happens if we have a cycle in the call-graph.
-                NeedAnotherIteration = true;
-              }
-            }
-          }
-        }
-      }
-    }
-  } while (NeedAnotherIteration);
-}
-
-void SideEffectAnalysis::getEffects(FunctionEffects &ApplyEffects, FullApplySite FAS) {
-  assert(ApplyEffects.ParamEffects.empty() &&
-         "Not using a new ApplyEffects?");
-  ApplyEffects.ParamEffects.resize(FAS.getNumArguments());
-
-  // Is this a call to a semantics function?
-  if (auto apply = dyn_cast<ApplyInst>(FAS.getInstruction())) {
-    ArraySemanticsCall ASC(apply);
-    if (ASC && ASC.hasSelf()) {
-      if (getSemanticEffects(ApplyEffects, ASC))
-        return;
-    }
-  }
-
-  if (SILFunction *SingleCallee = FAS.getReferencedFunction()) {
-    // Does the function have any @effects?
-    if (getDefinedEffects(ApplyEffects, SingleCallee))
-      return;
-  }
-
-  auto Callees = BCA->getCalleeList(FAS);
-  if (!Callees.allCalleesVisible() ||
-      // @callee_owned function calls implicitly release the context, which
-      // may call deinits of boxed values.
-      // TODO: be less conservative about what destructors might be called.
-      FAS.getOrigCalleeType()->isCalleeConsumed()) {
-    ApplyEffects.setWorstEffects();
-    return;
-  }
-
-  // We can see all the callees. So we just merge the effects from all of
-  // them.
-  for (auto *Callee : Callees) {
-    const FunctionEffects &CalleeFE = getEffects(Callee);
-    ApplyEffects.mergeFrom(CalleeFE);
-  }
-}
-
-void SideEffectAnalysis::invalidate() {
-  Function2Info.clear();
-  Allocator.DestroyAll();
-  DEBUG(llvm::dbgs() << "invalidate all\n");
-}
-
-void SideEffectAnalysis::invalidate(SILFunction *F, InvalidationKind K) {
-  if (FunctionInfo *FInfo = Function2Info.lookup(F)) {
-    DEBUG(llvm::dbgs() << "  invalidate " << FInfo->F->getName() << '\n');
-    invalidateIncludingAllCallers(FInfo);
-  }
+    Traps = true;
 }
 
 SILAnalysis *swift::createSideEffectAnalysis(SILModule *M) {
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index 6beb3d7..2614281 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -663,7 +663,7 @@
   auto *Cvt = cast<ConvertEscapeToNoEscapeInst>(calleeValue);
   calleeValue = cloneCalleeConversion(Cvt->getOperand(), NewClosure, Builder);
   return Builder.createConvertEscapeToNoEscape(
-      CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), true);
+      CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), false, true);
 }
 
 /// \brief Populate the body of the cloned closure, modifying instructions as
diff --git a/lib/SILOptimizer/LoopTransforms/LICM.cpp b/lib/SILOptimizer/LoopTransforms/LICM.cpp
index 00ad534..e0ec846 100644
--- a/lib/SILOptimizer/LoopTransforms/LICM.cpp
+++ b/lib/SILOptimizer/LoopTransforms/LICM.cpp
@@ -59,8 +59,8 @@
 /// alias with any memory which is read by \p AI.
 static bool mayWriteTo(AliasAnalysis *AA, SideEffectAnalysis *SEA,
                        WriteSet &MayWrites, ApplyInst *AI) {
-  SideEffectAnalysis::FunctionEffects E;
-  SEA->getEffects(E, AI);
+  FunctionSideEffects E;
+  SEA->getCalleeEffects(E, AI);
   assert(E.getMemBehavior(RetainObserveKind::IgnoreRetains) <=
          SILInstruction::MemoryBehavior::MayRead &&
          "apply should only read from memory");
@@ -495,8 +495,8 @@
       if (auto *AI = dyn_cast<ApplyInst>(&Inst)) {
         // In contrast to load instructions, we first collect all read-only
         // function calls and add them later to SafeReads.
-        SideEffectAnalysis::FunctionEffects E;
-        SEA->getEffects(E, AI);
+        FunctionSideEffects E;
+        SEA->getCalleeEffects(E, AI);
 
         auto MB = E.getMemBehavior(RetainObserveKind::ObserveRetains);
         if (MB <= SILInstruction::MemoryBehavior::MayRead)
diff --git a/lib/SILOptimizer/Mandatory/CMakeLists.txt b/lib/SILOptimizer/Mandatory/CMakeLists.txt
index 6eeef3a..b4c29d5 100644
--- a/lib/SILOptimizer/Mandatory/CMakeLists.txt
+++ b/lib/SILOptimizer/Mandatory/CMakeLists.txt
@@ -2,6 +2,7 @@
   Mandatory/AccessEnforcementSelection.cpp
   Mandatory/AccessMarkerElimination.cpp
   Mandatory/AddressLowering.cpp
+  Mandatory/ConstantPropagation.cpp
   Mandatory/DefiniteInitialization.cpp
   Mandatory/DIMemoryUseCollector.cpp
   Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -10,8 +11,9 @@
   Mandatory/DiagnoseStaticExclusivity.cpp
   Mandatory/DiagnoseUnreachable.cpp
   Mandatory/GuaranteedARCOpts.cpp
+  Mandatory/IRGenPrepare.cpp
   Mandatory/MandatoryInlining.cpp
   Mandatory/PredictableMemOpt.cpp
-  Mandatory/ConstantPropagation.cpp
   Mandatory/SemanticARCOpts.cpp
+  Mandatory/ClosureLifetimeFixup.cpp
   PARENT_SCOPE)
diff --git a/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
new file mode 100644
index 0000000..8493ac7
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
@@ -0,0 +1,374 @@
+//===--- ClosureLifetimeFixup.cpp - Fixup the lifetime of closures --------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "closure-lifetime-fixup"
+
+#include "swift/SIL/DebugUtils.h"
+#include "swift/SIL/InstructionUtils.h"
+#include "swift/SIL/SILArgument.h"
+#include "swift/SIL/SILBuilder.h"
+#include "swift/SIL/SILInstruction.h"
+#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/SILOptimizer/PassManager/Transforms.h"
+#include "swift/SILOptimizer/Utils/CFG.h"
+#include "swift/SILOptimizer/Utils/Local.h"
+
+#include "llvm/Support/CommandLine.h"
+
+llvm::cl::opt<bool> DisableConvertEscapeToNoEscapeSwitchEnumPeephole(
+    "sil-disable-convert-escape-to-noescape-switch-peephole",
+    llvm::cl::init(false),
+    llvm::cl::desc(
+        "Disable the convert_escape_to_noescape switch enum peephole. "),
+    llvm::cl::Hidden);
+
+using namespace swift;
+
+static SILBasicBlock *getOptionalDiamondSuccessor(SwitchEnumInst *SEI) {
+   auto numSuccs = SEI->getNumSuccessors();
+   if (numSuccs != 2)
+     return nullptr;
+   auto *SuccSome = SEI->getCase(0).second;
+   auto *SuccNone = SEI->getCase(1).second;
+   if (SuccSome->args_size() != 1)
+     std::swap(SuccSome, SuccNone);
+
+   if (SuccSome->args_size() != 1 || SuccNone->args_size() != 0)
+     return nullptr;
+
+   auto *Succ = SuccSome->getSingleSuccessorBlock();
+   if (!Succ)
+     return nullptr;
+
+   if (SuccNone == Succ)
+     return Succ;
+
+   SuccNone = SuccNone->getSingleSuccessorBlock();
+   if (SuccNone == Succ)
+     return Succ;
+
+   SuccNone = SuccNone->getSingleSuccessorBlock();
+   if (SuccNone == Succ)
+     return Succ;
+
+   return nullptr;
+}
+
+/// Extend the lifetime of the convert_escape_to_noescape's operand to the end
+/// of the function.
+static void extendLifetimeToEndOfFunction(SILFunction &Fn,
+                                          ConvertEscapeToNoEscapeInst *Cvt) {
+  auto EscapingClosure = Cvt->getOperand();
+  auto EscapingClosureTy = EscapingClosure->getType();
+  auto OptionalEscapingClosureTy = SILType::getOptionalType(EscapingClosureTy);
+  auto loc = RegularLocation::getAutoGeneratedLocation();
+
+  SILBuilderWithScope B(Cvt);
+  auto NewCvt = B.createConvertEscapeToNoEscape(
+      Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
+  Cvt->replaceAllUsesWith(NewCvt);
+  Cvt->eraseFromParent();
+  Cvt = NewCvt;
+
+  // Create an alloc_stack Optional<() -> ()> at the beginning of the function.
+  AllocStackInst *Slot;
+  auto &Context = Cvt->getModule().getASTContext();
+  {
+    SILBuilderWithScope B(Fn.getEntryBlock()->begin());
+    Slot = B.createAllocStack(loc, OptionalEscapingClosureTy);
+    auto *NoneDecl = Context.getOptionalNoneDecl();
+    // Store None to it.
+    B.createStore(
+        loc, B.createEnum(loc, SILValue(), NoneDecl, OptionalEscapingClosureTy),
+        Slot, StoreOwnershipQualifier::Init);
+  }
+  // Insert a copy before the convert_escape_to_noescape and store it to the
+  // alloc_stack location.
+  {
+    SILBuilderWithScope B(Cvt);
+    auto *SomeDecl = Context.getOptionalSomeDecl();
+    B.createDestroyAddr(loc, Slot);
+    auto ClosureCopy = B.createCopyValue(loc, EscapingClosure);
+    B.createStore(
+        loc,
+        B.createEnum(loc, ClosureCopy, SomeDecl, OptionalEscapingClosureTy),
+        Slot, StoreOwnershipQualifier::Init);
+  }
+  // Insert destroys at the function exits.
+  SmallVector<SILBasicBlock *, 4> ExitingBlocks;
+  Fn.findExitingBlocks(ExitingBlocks);
+  for (auto *Exit : ExitingBlocks) {
+    auto *Term = Exit->getTerminator();
+    SILBuilderWithScope B(Term);
+    B.setInsertionPoint(Term);
+    B.createDestroyAddr(loc, Slot);
+    B.createDeallocStack(loc, Slot);
+  }
+}
+
+static SILInstruction *lookThroughRebastractionUsers(
+    SILInstruction *Inst,
+    llvm::DenseMap<SILInstruction *, SILInstruction *> &Memoized) {
+
+  if (Inst == nullptr)
+    return nullptr;
+
+  // Try a cached lookup.
+  auto Res = Memoized.find(Inst);
+  if (Res != Memoized.end())
+    return Res->second;
+
+  // Cache recursive results.
+  auto memoizeResult = [&] (SILInstruction *from, SILInstruction *toResult) {
+    Memoized[from] = toResult;
+    return toResult;
+  };
+
+  // If we have a convert_function, just look at its user.
+  if (auto *Cvt = dyn_cast<ConvertFunctionInst>(Inst))
+    return memoizeResult(Inst, lookThroughRebastractionUsers(
+                                   getSingleNonDebugUser(Cvt), Memoized));
+  if (auto *Cvt = dyn_cast<ConvertEscapeToNoEscapeInst>(Inst))
+    return memoizeResult(Inst, lookThroughRebastractionUsers(
+                                   getSingleNonDebugUser(Cvt), Memoized));
+
+  // If we have a partial_apply user look at its single (non release) user.
+  auto *PA = dyn_cast<PartialApplyInst>(Inst);
+  if (!PA) return Inst;
+
+  SILInstruction *SingleNonDebugNonRefCountUser = nullptr;
+  for (auto *Usr : getNonDebugUses(PA)) {
+    auto *I = Usr->getUser();
+    if (onlyAffectsRefCount(I))
+      continue;
+    if (SingleNonDebugNonRefCountUser) {
+      SingleNonDebugNonRefCountUser = nullptr;
+      break;
+    }
+    SingleNonDebugNonRefCountUser = I;
+  }
+
+  return memoizeResult(Inst, lookThroughRebastractionUsers(
+                                 SingleNonDebugNonRefCountUser, Memoized));
+}
+
+static bool tryExtendLifetimeToLastUse(
+    ConvertEscapeToNoEscapeInst *Cvt,
+    llvm::DenseMap<SILInstruction *, SILInstruction *> &Memoized) {
+  // Don't optimize converts that might have been escaped by the function call
+  // (materializeForSet 'escapes' its arguments into the writeback buffer).
+  if (Cvt->isEscapedByUser())
+    return false;
+
+  // If there is a single user that is an apply this is simple: extend the
+  // lifetime of the operand until after the apply.
+  auto SingleUser = lookThroughRebastractionUsers(Cvt, Memoized);
+  if (!SingleUser)
+    return false;
+
+  // Handle an apply.
+  if (auto SingleApplyUser = FullApplySite::isa(SingleUser)) {
+    // FIXME: Don't know how-to handle begin_apply/end_apply yet.
+    if (auto *Begin =
+            dyn_cast<BeginApplyInst>(SingleApplyUser.getInstruction())) {
+      return false;
+    }
+
+    auto loc = RegularLocation::getAutoGeneratedLocation();
+
+    // Insert a copy at the convert_escape_to_noescape [not_guaranteed] and
+    // change the instruction to the guaranteed form.
+    auto EscapingClosure = Cvt->getOperand();
+    {
+      SILBuilderWithScope B(Cvt);
+      auto NewCvt = B.createConvertEscapeToNoEscape(
+          Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
+      Cvt->replaceAllUsesWith(NewCvt);
+      Cvt->eraseFromParent();
+      Cvt = NewCvt;
+    }
+
+    SILBuilderWithScope B2(Cvt);
+    auto ClosureCopy = B2.createCopyValue(loc, EscapingClosure);
+
+    // Insert a destroy after the apply.
+    if (auto *Apply = dyn_cast<ApplyInst>(SingleApplyUser.getInstruction())) {
+      auto InsertPt = std::next(SILBasicBlock::iterator(Apply));
+      SILBuilderWithScope B3(InsertPt);
+      B3.createDestroyValue(loc, ClosureCopy);
+
+    } else if (auto *Try =
+                   dyn_cast<TryApplyInst>(SingleApplyUser.getInstruction())) {
+      for (auto *SuccBB : Try->getSuccessorBlocks()) {
+        SILBuilderWithScope B3(SuccBB->begin());
+        B3.createDestroyValue(loc, ClosureCopy);
+      }
+    } else {
+      llvm_unreachable("Unknown FullApplySite instruction kind");
+    }
+    return true;
+  }
+  return false;
+}
+
+/// Ensure the lifetime of the closure accross an
+///
+///   optional<@escaping () -> ()> to
+///   optional<@noescape @convention(block) () -> ()>
+///
+///   conversion and its use.
+///
+///   The pattern this is looking for
+///                            switch_enum %closure
+///                           /           \
+///     convert_escape_to_noescape          nil
+///                             switch_enum
+///                           /           \
+///                convertToBlock          nil
+///                           \            /
+///                     (%convertOptionalBlock :)
+///   We will insert a copy_value of the original %closure before the two
+///   diamonds. And a destroy of %closure at the last destroy of
+///   %convertOptionalBlock.
+static bool trySwitchEnumPeephole(ConvertEscapeToNoEscapeInst *Cvt) {
+  // Don't optimize converts that might have been escaped by the function call
+  // (materializeForSet 'escapes' its arguments into the writeback buffer).
+  if (Cvt->isEscapedByUser())
+    return false;
+
+  auto *blockArg = dyn_cast<SILArgument>(Cvt->getOperand());
+  if (!blockArg)
+    return false;
+  auto *PredBB = Cvt->getParent()->getSinglePredecessorBlock();
+  if (!PredBB)
+    return false;
+  auto *ConvertSuccessorBlock = Cvt->getParent()->getSingleSuccessorBlock();
+  if (!ConvertSuccessorBlock)
+    return false;
+  auto *SwitchEnum1 = dyn_cast<SwitchEnumInst>(PredBB->getTerminator());
+  if (!SwitchEnum1)
+    return false;
+  auto *DiamondSucc = getOptionalDiamondSuccessor(SwitchEnum1);
+  if (!DiamondSucc)
+    return false;
+  auto *SwitchEnum2 = dyn_cast<SwitchEnumInst>(DiamondSucc->getTerminator());
+  if (!SwitchEnum2)
+    return false;
+  auto *DiamondSucc2 = getOptionalDiamondSuccessor(SwitchEnum2);
+  if (!DiamondSucc2)
+    return false;
+  if (DiamondSucc2->getNumArguments() != 1)
+    return false;
+
+  // Look for the last and only destroy.
+  SILInstruction *onlyDestroy = [&]() -> SILInstruction * {
+    SILInstruction *lastDestroy = nullptr;
+    for (auto *Use : DiamondSucc2->getArgument(0)->getUses()) {
+      SILInstruction *Usr = Use->getUser();
+      if (isa<ReleaseValueInst>(Usr) || isa<StrongReleaseInst>(Usr) ||
+          isa<DestroyValueInst>(Usr)) {
+        if (lastDestroy)
+          return nullptr;
+        lastDestroy = Usr;
+      }
+    }
+    return lastDestroy;
+  }();
+  if (!onlyDestroy)
+    return false;
+
+  // Replace the convert_escape_to_noescape instruction.
+  {
+    SILBuilderWithScope B(Cvt);
+    auto NewCvt = B.createConvertEscapeToNoEscape(
+        Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), false, true);
+    Cvt->replaceAllUsesWith(NewCvt);
+    Cvt->eraseFromParent();
+    Cvt = NewCvt;
+  }
+
+  // Extend the lifetime.
+  SILBuilderWithScope B(SwitchEnum1);
+  auto loc = RegularLocation::getAutoGeneratedLocation();
+  auto copy =
+      B.createCopyValue(loc, SwitchEnum1->getOperand());
+  B.setInsertionPoint(onlyDestroy);
+  B.createDestroyValue(loc, copy);
+  return true;
+}
+
+static bool fixupConvertEscapeToNoEscapeLifetime(SILFunction &Fn) {
+  bool Changed = false;
+
+  // tryExtendLifetimeToLastUse uses a cache of recursive instruction use
+  // queries.
+  llvm::DenseMap<SILInstruction *, SILInstruction *> MemoizedQueries;
+
+  for (auto &BB : Fn) {
+    auto I = BB.begin();
+    while (I != BB.end()) {
+      SILInstruction *Inst = &*I;
+      ++I;
+      auto *Cvt = dyn_cast<ConvertEscapeToNoEscapeInst>(Inst);
+      if (!Cvt || Cvt->isLifetimeGuaranteed())
+        continue;
+
+      // First try to peephole a known pattern.
+      if (!DisableConvertEscapeToNoEscapeSwitchEnumPeephole &&
+          trySwitchEnumPeephole(Cvt)) {
+        Changed |= true;
+        continue;
+      }
+
+      if (tryExtendLifetimeToLastUse(Cvt, MemoizedQueries)) {
+        Changed |= true;
+        continue;
+      }
+
+      // Otherwise, extend the lifetime of the operand to the end of the
+      // function.
+      extendLifetimeToEndOfFunction(Fn, Cvt);
+      Changed |= true;
+    }
+  }
+  return Changed;
+}
+
+/// Fix-up the lifetime of the escaping closure argument of
+/// convert_escape_to_noescape [not_guaranteed] instructions.
+///
+/// convert_escape_to_noescape [not_guaranteed] assume that someone guarantees
+/// the lifetime of the operand for the duration of the trivial closure result.
+/// SILGen does not guarantee this for '[not_guaranteed]' instructions so we
+/// ensure it here.
+namespace {
+class ClosureLifetimeFixup : public SILFunctionTransform {
+
+  /// The entry point to the transformation.
+  void run() override {
+    // Don't rerun diagnostics on deserialized functions.
+    if (getFunction()->wasDeserializedCanonical())
+      return;
+
+    // Fixup lifetimes of optional convertEscapeToNoEscape.
+    if (fixupConvertEscapeToNoEscapeLifetime(*getFunction()))
+      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
+    DEBUG(getFunction()->verify());
+
+  }
+
+};
+} // end anonymous namespace
+
+SILTransform *swift::createClosureLifetimeFixup() {
+  return new ClosureLifetimeFixup();
+}
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index bc5b5a4..3d3a29e 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -2952,210 +2952,6 @@
   return Changed;
 }
 
-static SILBasicBlock *getOptionalDiamondSuccessor(SwitchEnumInst *SEI) {
-   auto numSuccs = SEI->getNumSuccessors();
-   if (numSuccs != 2)
-     return nullptr;
-   auto *SuccSome = SEI->getCase(0).second;
-   auto *SuccNone = SEI->getCase(1).second;
-   if (SuccSome->args_size() != 1)
-     std::swap(SuccSome, SuccNone);
-
-   if (SuccSome->args_size() != 1 || SuccNone->args_size() != 0)
-     return nullptr;
-
-   auto *Succ = SuccSome->getSingleSuccessorBlock();
-   if (!Succ)
-     return nullptr;
-
-   if (SuccNone == Succ)
-     return Succ;
-
-   SuccNone = SuccNone->getSingleSuccessorBlock();
-   if (SuccNone == Succ)
-     return Succ;
-
-   SuccNone = SuccNone->getSingleSuccessorBlock();
-   if (SuccNone == Succ)
-     return Succ;
-
-   return nullptr;
-}
-
-/// Extend the lifetime of the convert_escape_to_noescape's operand to the end
-/// of the function.
-void extendLifetimeToEndOfFunction(SILFunction &Fn,
-                                   ConvertEscapeToNoEscapeInst *Cvt) {
-  auto EscapingClosure = Cvt->getOperand();
-  auto EscapingClosureTy = EscapingClosure->getType();
-  auto OptionalEscapingClosureTy = SILType::getOptionalType(EscapingClosureTy);
-  auto loc = RegularLocation::getAutoGeneratedLocation();
-
-  SILBuilderWithScope B(Cvt);
-  auto NewCvt = B.createConvertEscapeToNoEscape(
-      Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
-  Cvt->replaceAllUsesWith(NewCvt);
-  Cvt->eraseFromParent();
-  Cvt = NewCvt;
-
-  // Create an alloc_stack Optional<() -> ()> at the beginning of the function.
-  AllocStackInst *Slot;
-  auto &Context = Cvt->getModule().getASTContext();
-  {
-    SILBuilderWithScope B(Fn.getEntryBlock()->begin());
-    Slot = B.createAllocStack(loc, OptionalEscapingClosureTy);
-    auto *NoneDecl = Context.getOptionalNoneDecl();
-    // Store None to it.
-    B.createStore(
-        loc, B.createEnum(loc, SILValue(), NoneDecl, OptionalEscapingClosureTy),
-        Slot, StoreOwnershipQualifier::Init);
-  }
-  // Insert a copy before the convert_escape_to_noescape and store it to the
-  // alloc_stack location.
-  {
-    SILBuilderWithScope B(Cvt);
-    auto *SomeDecl = Context.getOptionalSomeDecl();
-    B.createDestroyAddr(loc, Slot);
-    auto ClosureCopy = B.createCopyValue(loc, EscapingClosure);
-    B.createStore(
-        loc,
-        B.createEnum(loc, ClosureCopy, SomeDecl, OptionalEscapingClosureTy),
-        Slot, StoreOwnershipQualifier::Init);
-  }
-  // Insert destroys at the function exits.
-  SmallVector<SILBasicBlock *, 4> ExitingBlocks;
-  Fn.findExitingBlocks(ExitingBlocks);
-  for (auto *Exit : ExitingBlocks) {
-    auto *Term = Exit->getTerminator();
-    SILBuilderWithScope B(Term);
-    B.setInsertionPoint(Term);
-    B.createDestroyAddr(loc, Slot);
-    B.createDeallocStack(loc, Slot);
-  }
-}
-
-/// Ensure the lifetime of the closure accross an
-///
-///   optional<@escaping () -> ()> to
-///   optional<@noescape @convention(block) () -> ()>
-///
-///   conversion and its use.
-///
-///   The pattern this is looking for
-///                            switch_enum %closure
-///                           /           \
-///     convert_escape_to_noescape          nil
-///                             switch_enum
-///                           /           \
-///                convertToBlock          nil
-///                           \            /
-///                     (%convertOptionalBlock :)
-///   We will insert a copy_value of the original %closure before the two
-///   diamonds. And a destroy of %closure at the last destroy of
-///   %convertOptionalBlock.
-static bool trySwitchEnumPeephole(ConvertEscapeToNoEscapeInst *Cvt) {
-  auto *blockArg = dyn_cast<SILArgument>(Cvt->getOperand());
-  if (!blockArg)
-    return false;
-  auto *PredBB = Cvt->getParent()->getSinglePredecessorBlock();
-  if (!PredBB)
-    return false;
-  auto *ConvertSuccessorBlock = Cvt->getParent()->getSingleSuccessorBlock();
-  if (!ConvertSuccessorBlock)
-    return false;
-  auto *SwitchEnum1 = dyn_cast<SwitchEnumInst>(PredBB->getTerminator());
-  if (!SwitchEnum1)
-    return false;
-  auto *DiamondSucc = getOptionalDiamondSuccessor(SwitchEnum1);
-  if (!DiamondSucc)
-    return false;
-  auto *SwitchEnum2 = dyn_cast<SwitchEnumInst>(DiamondSucc->getTerminator());
-  if (!SwitchEnum2)
-    return false;
-  auto *DiamondSucc2 = getOptionalDiamondSuccessor(SwitchEnum2);
-  if (!DiamondSucc2)
-    return false;
-  if (DiamondSucc2->getNumArguments() != 1)
-    return false;
-
-  // Look for the last and only destroy.
-  SILInstruction *onlyDestroy = [&]() -> SILInstruction * {
-    SILInstruction *lastDestroy = nullptr;
-    for (auto *Use : DiamondSucc2->getArgument(0)->getUses()) {
-      SILInstruction *Usr = Use->getUser();
-      if (isa<ReleaseValueInst>(Usr) || isa<StrongReleaseInst>(Usr) ||
-          isa<DestroyValueInst>(Usr)) {
-        if (lastDestroy)
-          return nullptr;
-        lastDestroy = Usr;
-      }
-    }
-    return lastDestroy;
-  }();
-  if (!onlyDestroy)
-    return false;
-
-  // Replace the convert_escape_to_noescape instruction.
-  {
-    SILBuilderWithScope B(Cvt);
-    auto NewCvt = B.createConvertEscapeToNoEscape(
-        Cvt->getLoc(), Cvt->getOperand(), Cvt->getType(), true);
-    Cvt->replaceAllUsesWith(NewCvt);
-    Cvt->eraseFromParent();
-    Cvt = NewCvt;
-  }
-
-  // Extend the lifetime.
-  SILBuilderWithScope B(SwitchEnum1);
-  auto loc = RegularLocation::getAutoGeneratedLocation();
-  auto copy =
-      B.createCopyValue(loc, SwitchEnum1->getOperand());
-  B.setInsertionPoint(onlyDestroy);
-  B.createDestroyValue(loc, copy);
-  return true;
-}
-
-llvm::cl::opt<bool> DIDisableConvertEscapeToNoEscapeSwitchEnumPeephole(
-    "sil-di-disable-convert-escape-to-noescape-switch-peephole",
-    llvm::cl::init(false),
-    llvm::cl::desc(
-        "Disable the convert_escape_to_noescape switch enum peephole. "),
-    llvm::cl::Hidden);
-
-/// Fix-up the lifetime of the escaping closure argument of
-/// convert_escape_to_noescape [not_guaranteed] instructions.
-///
-/// convert_escape_to_noescape [not_guaranteed] assume that someone guarantees
-/// the lifetime of the operand for the duration of the trivial closure result.
-/// SILGen does not guarantee this for '[not_guaranteed]' instructions so we
-/// ensure it here.
-static bool fixupConvertEscapeToNoEscapeLifetime(SILFunction &Fn) {
-  bool Changed = false;
-  for (auto &BB : Fn) {
-    auto I = BB.begin();
-    while (I != BB.end()) {
-      SILInstruction *Inst = &*I;
-      ++I;
-      auto *Cvt = dyn_cast<ConvertEscapeToNoEscapeInst>(Inst);
-      if (!Cvt || Cvt->isLifetimeGuaranteed())
-        continue;
-
-      // First try to peephole a known pattern.
-      if (!DIDisableConvertEscapeToNoEscapeSwitchEnumPeephole &&
-          trySwitchEnumPeephole(Cvt)) {
-        Changed |= true;
-        continue;
-      }
-
-      // Otherwise, extend the lifetime of the operand to the end of the
-      // function.
-      extendLifetimeToEndOfFunction(Fn, Cvt);
-      Changed |= true;
-    }
-  }
-  return Changed;
-}
-
 namespace {
 /// Perform definitive initialization analysis and promote alloc_box uses into
 /// SSA registers for later SSA-based dataflow passes.
@@ -3178,10 +2974,6 @@
     if (lowerRawSILOperations(*getFunction()))
       invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
 
-    // Fixup lifetimes of optional convertEscapeToNoEscape.
-    if (fixupConvertEscapeToNoEscapeLifetime(*getFunction()))
-      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
-
   }
 
 };
diff --git a/lib/SILOptimizer/Mandatory/IRGenPrepare.cpp b/lib/SILOptimizer/Mandatory/IRGenPrepare.cpp
new file mode 100644
index 0000000..ee9f4c3
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/IRGenPrepare.cpp
@@ -0,0 +1,83 @@
+//===--- IRGenPrepare.cpp -------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Cleanup SIL to make it suitable for IRGen.
+///
+/// We perform the following canonicalizations:
+///
+/// 1. We remove calls to Builtin.staticReport(), which are not needed post SIL.
+///
+//===----------------------------------------------------------------------===//
+
+#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/SIL/SILFunction.h"
+#include "swift/SIL/SILInstruction.h"
+#include "swift/SIL/SILModule.h"
+#include "swift/SILOptimizer/Utils/Local.h"
+#include "swift/SILOptimizer/PassManager/Transforms.h"
+
+using namespace swift;
+
+static bool cleanFunction(SILFunction &fn) {
+  bool madeChange = false;
+
+  for (auto &bb : fn) {
+    for (auto i = bb.begin(), e = bb.end(); i != e;) {
+      // Make sure there is no iterator invalidation if the inspected
+      // instruction gets removed from the block.
+      SILInstruction *inst = &*i;
+      ++i;
+
+      // Remove calls to Builtin.staticReport().
+      auto *bi = dyn_cast<BuiltinInst>(inst);
+      if (!bi) {
+        continue;
+      }
+
+      const BuiltinInfo &bInfo = bi->getBuiltinInfo();
+      if (bInfo.ID != BuiltinValueKind::StaticReport) {
+        continue;
+      }
+
+      // The call to the builtin should get removed before we reach
+      // IRGen.
+      recursivelyDeleteTriviallyDeadInstructions(bi, /* Force */ true);
+      madeChange = true;
+    }
+  }
+
+  return madeChange;
+}
+
+//===----------------------------------------------------------------------===//
+//                            Top Level Entrypoint
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class IRGenPrepare : public SILFunctionTransform {
+  void run() override {
+    bool shouldInvalidate = cleanFunction(*getFunction());
+    if (!shouldInvalidate)
+      return;
+    invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
+  }
+};
+
+} // end anonymous namespace
+
+
+SILTransform *swift::createIRGenPrepare() {
+  return new IRGenPrepare();
+}
diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
index 0fd434d..6895c54 100644
--- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
+++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
@@ -259,8 +259,7 @@
 static SILFunction *getCalleeFunction(
     SILFunction *F, FullApplySite AI, bool &IsThick,
     SmallVectorImpl<std::pair<SILValue, ParameterConvention>> &CaptureArgs,
-    SmallVectorImpl<SILValue> &FullArgs, PartialApplyInst *&PartialApply,
-    SILModule::LinkingMode Mode) {
+    SmallVectorImpl<SILValue> &FullArgs, PartialApplyInst *&PartialApply) {
   IsThick = false;
   PartialApply = nullptr;
   CaptureArgs.clear();
@@ -404,17 +403,19 @@
     return nullptr;
   }
 
-  // If CalleeFunction is a declaration, see if we can load it. If we fail to
-  // load it, bail.
-  if (CalleeFunction->empty()
-      && !AI.getModule().linkFunction(CalleeFunction, Mode))
-    return nullptr;
-
   // If the CalleeFunction is a not-transparent definition, we can not process
   // it.
   if (CalleeFunction->isTransparent() == IsNotTransparent)
     return nullptr;
 
+  // If CalleeFunction is a declaration, see if we can load it.
+  if (CalleeFunction->empty())
+    AI.getModule().loadFunction(CalleeFunction);
+
+  // If we fail to load it, bail.
+  if (CalleeFunction->empty())
+    return nullptr;
+
   if (F->isSerialized() &&
       !CalleeFunction->hasValidLinkageForFragileInline()) {
     if (!CalleeFunction->hasValidLinkageForFragileRef()) {
@@ -462,7 +463,6 @@
 /// \returns true if successful, false if failed due to circular inlining.
 static bool
 runOnFunctionRecursively(SILFunction *F, FullApplySite AI,
-                         SILModule::LinkingMode Mode,
                          DenseFunctionSet &FullyInlinedSet,
                          ImmutableFunctionSet::Factory &SetFactory,
                          ImmutableFunctionSet CurrentInliningSet,
@@ -510,13 +510,13 @@
       bool IsThick;
       PartialApplyInst *PAI;
       SILFunction *CalleeFunction = getCalleeFunction(
-          F, InnerAI, IsThick, CaptureArgs, FullArgs, PAI, Mode);
+          F, InnerAI, IsThick, CaptureArgs, FullArgs, PAI);
 
       if (!CalleeFunction)
         continue;
 
       // Then recursively process it first before trying to inline it.
-      if (!runOnFunctionRecursively(CalleeFunction, InnerAI, Mode,
+      if (!runOnFunctionRecursively(CalleeFunction, InnerAI,
                                     FullyInlinedSet, SetFactory,
                                     CurrentInliningSet, CHA)) {
         // If we failed due to circular inlining, then emit some notes to
@@ -619,25 +619,12 @@
 //===----------------------------------------------------------------------===//
 
 namespace {
-/// MandatoryInlining reruns on deserialized functions for two reasons, both
-/// unrelated to mandatory inlining:
-///
-/// 1. It recursively visits the entire call tree rooted at transparent
-/// functions. This has the effect of linking all reachable functions. If they
-/// aren't linked until the explicit SILLinker pass, then they don't benefit
-/// from rerunning optimizations like PredictableMemOps. Ideally we wouldn't
-/// need to rerun PredictableMemOps and wouldn't need to eagerly link anything
-/// in the mandatory pipeline.
-///
-/// 2. It may devirtualize non-transparent methods. It's not clear whether we
-/// really need to devirtualize this early without actually inlining, but it can
-/// unblock other optimizations in the mandatory pipeline.
+
 class MandatoryInlining : public SILModuleTransform {
   /// The entry point to the transformation.
   void run() override {
     ClassHierarchyAnalysis *CHA = getAnalysis<ClassHierarchyAnalysis>();
     SILModule *M = getModule();
-    SILModule::LinkingMode Mode = getOptions().LinkMode;
     bool ShouldCleanup = !getOptions().DebugSerialization;
     DenseFunctionSet FullyInlinedSet;
     ImmutableFunctionSet::Factory SetFactory;
@@ -647,21 +634,15 @@
       if (F.isThunk())
         continue;
 
+      // Skip deserialized functions.
+      if (F.wasDeserializedCanonical())
+        continue;
+
       runOnFunctionRecursively(&F,
-                               FullApplySite(static_cast<ApplyInst*>(nullptr)),
-                               Mode, FullyInlinedSet,
-                               SetFactory, SetFactory.getEmptySet(), CHA);
+                               FullApplySite(), FullyInlinedSet, SetFactory,
+                               SetFactory.getEmptySet(), CHA);
     }
 
-    // Make sure that we de-serialize all transparent functions,
-    // even if we didn't inline them for some reason.
-    // Transparent functions are not available externally, so we
-    // have to generate code for them.
-    for (auto &F : *M) {
-      if (F.isTransparent())
-        M->linkFunction(&F, Mode);
-    }
-    
     if (!ShouldCleanup)
       return;
 
diff --git a/lib/SILOptimizer/PassManager/PassPipeline.cpp b/lib/SILOptimizer/PassManager/PassPipeline.cpp
index bd46d84..98bcfae 100644
--- a/lib/SILOptimizer/PassManager/PassPipeline.cpp
+++ b/lib/SILOptimizer/PassManager/PassPipeline.cpp
@@ -88,8 +88,10 @@
   P.addNoReturnFolding();
   P.addMarkUninitializedFixup();
   P.addDefiniteInitialization();
+  P.addClosureLifetimeFixup();
   P.addOwnershipModelEliminator();
   P.addMandatoryInlining();
+  P.addMandatorySILLinker();
   P.addPredictableMemoryOptimizations();
 
   // Diagnostic ConstantPropagation must be rerun on deserialized functions
@@ -222,6 +224,10 @@
   // Split up operations on stack-allocated aggregates (struct, tuple).
   P.addSROA();
 
+  // Re-run predictable memory optimizations, since previous optimization
+  // passes sometimes expose oppotunities here.
+  P.addPredictableMemoryOptimizations();
+
   // Promote stack allocations to values.
   P.addMem2Reg();
 
@@ -314,7 +320,7 @@
 
 static void addPerfDebugSerializationPipeline(SILPassPipelinePlan &P) {
   P.startPipeline("Performance Debug Serialization");
-  P.addSILLinker();
+  P.addPerformanceSILLinker();
 }
 
 static void addPerfEarlyModulePassPipeline(SILPassPipelinePlan &P) {
@@ -324,7 +330,7 @@
   // we do not spend time optimizing them.
   P.addDeadFunctionElimination();
   // Start by cloning functions from stdlib.
-  P.addSILLinker();
+  P.addPerformanceSILLinker();
 
   // Cleanup after SILGen: remove trivial copies to temporaries.
   P.addTempRValueOpt();
@@ -344,7 +350,7 @@
 static void addMidModulePassesStackPromotePassPipeline(SILPassPipelinePlan &P) {
   P.startPipeline("MidModulePasses+StackPromote");
   P.addDeadFunctionElimination();
-  P.addSILLinker();
+  P.addPerformanceSILLinker();
   P.addDeadObjectElimination();
   P.addGlobalPropertyOpt();
 
@@ -456,7 +462,7 @@
 SILPassPipelinePlan::getLoweringPassPipeline() {
   SILPassPipelinePlan P;
   P.startPipeline("Address Lowering");
-  P.addSILCleanup();
+  P.addIRGenPrepare();
   P.addAddressLowering();
 
   return P;
diff --git a/lib/SILOptimizer/Transforms/CMakeLists.txt b/lib/SILOptimizer/Transforms/CMakeLists.txt
index 0f454d8..49d140e 100644
--- a/lib/SILOptimizer/Transforms/CMakeLists.txt
+++ b/lib/SILOptimizer/Transforms/CMakeLists.txt
@@ -23,7 +23,6 @@
   Transforms/RedundantOverflowCheckRemoval.cpp
   Transforms/ReleaseDevirtualizer.cpp
   Transforms/RemovePin.cpp
-  Transforms/SILCleanup.cpp
   Transforms/SILCodeMotion.cpp
   Transforms/SILLowerAggregateInstrs.cpp
   Transforms/SILMem2Reg.cpp
diff --git a/lib/SILOptimizer/Transforms/CSE.cpp b/lib/SILOptimizer/Transforms/CSE.cpp
index 4f7c206..85f5a62 100644
--- a/lib/SILOptimizer/Transforms/CSE.cpp
+++ b/lib/SILOptimizer/Transforms/CSE.cpp
@@ -874,8 +874,8 @@
     
     // We can CSE function calls which do not read or write memory and don't
     // have any other side effects.
-    SideEffectAnalysis::FunctionEffects Effects;
-    SEA->getEffects(Effects, AI);
+    FunctionSideEffects Effects;
+    SEA->getCalleeEffects(Effects, AI);
 
     // Note that the function also may not contain any retains. And there are
     // functions which are read-none and have a retain, e.g. functions which
diff --git a/lib/SILOptimizer/Transforms/Devirtualizer.cpp b/lib/SILOptimizer/Transforms/Devirtualizer.cpp
index e37210f..2ddd68a 100644
--- a/lib/SILOptimizer/Transforms/Devirtualizer.cpp
+++ b/lib/SILOptimizer/Transforms/Devirtualizer.cpp
@@ -93,11 +93,9 @@
     assert(CalleeFn && "Expected devirtualized callee!");
 
     // We need to ensure that we link after devirtualizing in order to pull in
-    // everything we reference from another module. This is especially important
-    // for transparent functions, because if transparent functions are not
-    // inlined for some reason, we need to generate code for them.
-    // Note that functions, which are only referenced from witness/vtables, are
-    // not linked upfront by the SILLinker.
+    // everything we reference from another module, which may expose optimization
+    // opportunities and is also needed for correctness if we reference functions
+    // with non-public linkage. See lib/SIL/Linker.cpp for details.
     if (!CalleeFn->isDefinition())
       F.getModule().linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll);
 
diff --git a/lib/SILOptimizer/Transforms/SILCleanup.cpp b/lib/SILOptimizer/Transforms/SILCleanup.cpp
deleted file mode 100644
index 3fd0d64..0000000
--- a/lib/SILOptimizer/Transforms/SILCleanup.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//===--- SILCleanup.cpp - Removes diagnostics instructions ----------------===//
-//
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//===----------------------------------------------------------------------===//
-//
-// Cleanup SIL to make it suitable for IRGen. Specifically, removes the calls to
-// Builtin.staticReport(), which are not needed post SIL.
-//
-// FIXME: This pass is mandatory so should probably be in
-// SILOptimizer/Mandatory.
-//
-//===----------------------------------------------------------------------===//
-
-#include "swift/SILOptimizer/PassManager/Passes.h"
-#include "swift/SIL/SILFunction.h"
-#include "swift/SIL/SILInstruction.h"
-#include "swift/SIL/SILModule.h"
-#include "swift/SILOptimizer/Utils/Local.h"
-#include "swift/SILOptimizer/PassManager/Transforms.h"
-
-using namespace swift;
-
-static void cleanFunction(SILFunction &Fn) {
-  for (auto &BB : Fn) {
-    auto I = BB.begin(), E = BB.end();
-    while (I != E) {
-      // Make sure there is no iterator invalidation if the inspected
-      // instruction gets removed from the block.
-      SILInstruction *Inst = &*I;
-      ++I;
-
-      // Remove calls to Builtin.staticReport().
-      if (auto *BI = dyn_cast<BuiltinInst>(Inst)) {
-        const BuiltinInfo &B = BI->getBuiltinInfo();
-        if (B.ID == BuiltinValueKind::StaticReport) {
-          // The call to the builtin should get removed before we reach
-          // IRGen.
-          recursivelyDeleteTriviallyDeadInstructions(BI, /* Force */true);
-        }
-      }
-    }
-  }
-}
-
-namespace {
-class SILCleanup : public swift::SILFunctionTransform {
-
-  /// The entry point to the transformation.
-  void run() override {
-    cleanFunction(*getFunction());
-    invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
-  }
-
-};
-} // end anonymous namespace
-
-
-SILTransform *swift::createSILCleanup() {
-  return new SILCleanup();
-}
diff --git a/lib/SILOptimizer/UtilityPasses/Link.cpp b/lib/SILOptimizer/UtilityPasses/Link.cpp
index 06c094b..bf080a3 100644
--- a/lib/SILOptimizer/UtilityPasses/Link.cpp
+++ b/lib/SILOptimizer/UtilityPasses/Link.cpp
@@ -25,11 +25,15 @@
 /// Copies code from the standard library into the user program to enable
 /// optimizations.
 class SILLinker : public SILModuleTransform {
+  SILModule::LinkingMode LinkMode;
+
+public:
+  explicit SILLinker(SILModule::LinkingMode LinkMode) : LinkMode(LinkMode) {}
 
   void run() override {
     SILModule &M = *getModule();
     for (auto &Fn : M)
-      if (M.linkFunction(&Fn, SILModule::LinkingMode::LinkAll))
+      if (M.linkFunction(&Fn, LinkMode))
         invalidateAnalysis(&Fn, SILAnalysis::InvalidationKind::Everything);
   }
 
@@ -37,6 +41,10 @@
 } // end anonymous namespace
 
 
-SILTransform *swift::createSILLinker() {
-  return new SILLinker();
+SILTransform *swift::createMandatorySILLinker() {
+  return new SILLinker(SILModule::LinkingMode::LinkNormal);
+}
+
+SILTransform *swift::createPerformanceSILLinker() {
+  return new SILLinker(SILModule::LinkingMode::LinkAll);
 }
diff --git a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
index bf98cea..86c69a3 100644
--- a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
+++ b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
@@ -852,8 +852,8 @@
   // If a call has only constant arguments and the call is pure, i.e. has
   // no side effects, then we should always inline it.
   // This includes arguments which are objects initialized with constant values.
-  SideEffectAnalysis::FunctionEffects ApplyEffects;
-  SEA->getEffects(ApplyEffects, AI);
+  FunctionSideEffects ApplyEffects;
+  SEA->getCalleeEffects(ApplyEffects, AI);
   auto GE = ApplyEffects.getGlobalEffects();
   if (GE.mayRead() || GE.mayWrite() || GE.mayRetain() || GE.mayRelease())
     return false;
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index db1ed26..c01fb95 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -27,7 +27,6 @@
   DerivedConformances.cpp
   ITCDecl.cpp
   ITCNameLookup.cpp
-  ITCType.cpp
   InstrumenterSupport.cpp
   IterativeTypeChecker.cpp
   MiscDiagnostics.cpp
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index c8ebc30..4da4ffa 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -543,6 +543,25 @@
     /// look-through.
     Expr *coerceImplicitlyUnwrappedOptionalToValue(Expr *expr, Type objTy);
 
+    /// Peephole an array upcast.
+    void peepholeArrayUpcast(ArrayExpr *expr, Type toType, bool bridged,
+                             Type elementType,
+                             ConstraintLocatorBuilder locator);
+
+    /// Peephole a dictionary upcast.
+    void peepholeDictionaryUpcast(DictionaryExpr *expr, Type toType,
+                                  bool bridged, Type keyType,
+                                  Type valueType,
+                                  ConstraintLocatorBuilder locator);
+
+    /// Try to peephole the collection upcast, eliminating the need for
+    /// a separate collection-upcast expression.
+    ///
+    /// \returns true if the peephole operation succeeded, in which case
+    /// \c expr already subsumes the upcast.
+    bool peepholeCollectionUpcast(Expr *expr, Type toType,  bool bridged,
+                                  ConstraintLocatorBuilder locator);
+
     /// \brief Build a collection upcast expression.
     ///
     /// \param bridged Whether this is a bridging conversion, meaning that the
@@ -2946,9 +2965,9 @@
                             expr->getAccessSemantics());
     }
 
-    Expr *visitArrayExpr(ArrayExpr *expr) {
-      Type openedType = cs.getType(expr);
-      Type arrayTy = simplifyType(openedType);
+    /// "Finish" an array expression by filling in the semantic expression.
+    ArrayExpr *finishArrayExpr(ArrayExpr *expr) {
+      Type arrayTy = cs.getType(expr);
       auto &tc = cs.getTypeChecker();
 
       ProtocolDecl *arrayProto
@@ -2987,7 +3006,7 @@
 
           first = false;
           continue;
-        } 
+        }
 
         typeElements.push_back(cs.getType(elt));
         names.push_back(Identifier());
@@ -2997,13 +3016,13 @@
       assert(isa<TupleType>(argType.getPointer()));
 
       Expr *arg =
-          TupleExpr::create(tc.Context, SourceLoc(),
-                            expr->getElements(),
-                            names,
-                            { },
-                            SourceLoc(), /*HasTrailingClosure=*/false,
-                            /*Implicit=*/true,
-                            argType);
+        TupleExpr::create(tc.Context, SourceLoc(),
+                          expr->getElements(),
+                          names,
+                          { },
+                          SourceLoc(), /*HasTrailingClosure=*/false,
+                          /*Implicit=*/true,
+                          argType);
 
       cs.cacheExprTypes(arg);
 
@@ -3018,7 +3037,14 @@
       cs.cacheExprTypes(result);
 
       expr->setSemanticExpr(result);
+      return expr;
+    }
+
+    Expr *visitArrayExpr(ArrayExpr *expr) {
+      Type openedType = cs.getType(expr);
+      Type arrayTy = simplifyType(openedType);
       cs.setType(expr, arrayTy);
+      if (!finishArrayExpr(expr)) return nullptr;
 
       // If the array element type was defaulted, note that in the expression.
       if (solution.DefaultedConstraints.count(cs.getConstraintLocator(expr)))
@@ -3027,11 +3053,11 @@
       return expr;
     }
 
-    Expr *visitDictionaryExpr(DictionaryExpr *expr) {
-      Type openedType = cs.getType(expr);
-      Type dictionaryTy = simplifyType(openedType);
-      auto &tc = cs.getTypeChecker();
+    /// "Finish" a dictionary expression by filling in the semantic expression.
+    DictionaryExpr *finishDictionaryExpr(DictionaryExpr *expr) {
+      Type dictionaryTy = cs.getType(expr);
 
+      auto &tc = cs.getTypeChecker();
       ProtocolDecl *dictionaryProto
         = tc.getProtocol(expr->getLoc(),
                          KnownProtocolKind::ExpressibleByDictionaryLiteral);
@@ -3068,7 +3094,7 @@
 
           first = false;
           continue;
-        } 
+        }
 
         typeElements.push_back(cs.getType(elt));
         names.push_back(Identifier());
@@ -3101,7 +3127,14 @@
       cs.cacheExprTypes(result);
 
       expr->setSemanticExpr(result);
+      return expr;
+    }
+
+    Expr *visitDictionaryExpr(DictionaryExpr *expr) {
+      Type openedType = cs.getType(expr);
+      Type dictionaryTy = simplifyType(openedType);
       cs.setType(expr, dictionaryTy);
+      if (!finishDictionaryExpr(expr)) return nullptr;
 
       // If the dictionary key or value type was defaulted, note that in the
       // expression.
@@ -6201,14 +6234,38 @@
   }
 }
 
+/// Build the conversion of an element in a collection upcast.
+static Expr *buildElementConversion(ExprRewriter &rewriter,
+                                    SourceLoc srcLoc,
+                                    Type srcType,
+                                    Type destType,
+                                    bool bridged,
+                                    ConstraintLocatorBuilder locator,
+                                    Expr *element) {
+  auto &cs = rewriter.getConstraintSystem();
+
+  auto &tc = rewriter.getConstraintSystem().getTypeChecker();
+  if (bridged &&
+      tc.typeCheckCheckedCast(srcType, destType,
+                              CheckedCastContextKind::None, cs.DC,
+                              SourceLoc(), nullptr, SourceRange())
+        != CheckedCastKind::Coercion) {
+    if (auto conversion =
+          rewriter.buildObjCBridgeExpr(element, destType, locator))
+        return conversion;
+  }
+
+  return rewriter.coerceToType(element, destType, locator);
+}
+
 static CollectionUpcastConversionExpr::ConversionPair
-buildElementConversion(ExprRewriter &rewriter,
-                       SourceLoc srcLoc,
-                       Type srcCollectionType,
-                       Type destCollectionType,
-                       bool bridged,
-                       ConstraintLocatorBuilder locator,
-                       unsigned typeArgIndex) {
+buildOpaqueElementConversion(ExprRewriter &rewriter,
+                             SourceLoc srcLoc,
+                             Type srcCollectionType,
+                             Type destCollectionType,
+                             bool bridged,
+                             ConstraintLocatorBuilder locator,
+                             unsigned typeArgIndex) {
   // We don't need this stuff unless we've got generalized casts.
   Type srcType = srcCollectionType->castTo<BoundGenericType>()
                                   ->getGenericArgs()[typeArgIndex];
@@ -6220,35 +6277,138 @@
   ASTContext &ctx = cs.getASTContext();
   auto opaque =
     rewriter.cs.cacheType(new (ctx) OpaqueValueExpr(srcLoc, srcType));
-  Expr *conversion = nullptr;
 
-  auto &tc = rewriter.getConstraintSystem().getTypeChecker();
-  if (bridged &&
-      tc.typeCheckCheckedCast(srcType, destType,
-                              CheckedCastContextKind::None, cs.DC,
-                              SourceLoc(), nullptr, SourceRange())
-        != CheckedCastKind::Coercion) {
-    conversion = rewriter.buildObjCBridgeExpr(opaque, destType,
-           locator.withPathElement(
-             ConstraintLocator::PathElement::getGenericArgument(typeArgIndex)));
-  }
-
-  if (!conversion) {
-    conversion = rewriter.coerceToType(opaque, destType,
-           locator.withPathElement(
-             ConstraintLocator::PathElement::getGenericArgument(typeArgIndex)));
-  }
+  Expr *conversion =
+    buildElementConversion(rewriter, srcLoc, srcType, destType, bridged,
+                           locator.withPathElement(
+                             ConstraintLocator::PathElement::getGenericArgument(
+                                typeArgIndex)),
+                           opaque);
 
   return { opaque, conversion };
 }
 
-Expr *ExprRewriter::buildCollectionUpcastExpr(Expr *expr, Type toType,
-                                              bool bridged,
-                                              ConstraintLocatorBuilder locator) {
+void ExprRewriter::peepholeArrayUpcast(ArrayExpr *expr, Type toType,
+                                       bool bridged, Type elementType,
+                                       ConstraintLocatorBuilder locator) {
+  // Update the type of the array literal.
+  cs.setType(expr, toType);
+
+  // Convert the elements.
+  ConstraintLocatorBuilder innerLocator =
+    locator.withPathElement(
+                        ConstraintLocator::PathElement::getGenericArgument(0));
+  for (auto &element : expr->getElements()) {
+    if (auto newElement = buildElementConversion(*this, expr->getLoc(),
+                                                 cs.getType(element),
+                                                 elementType,
+                                                 bridged, innerLocator,
+                                                 element)) {
+      element = newElement;
+    }
+  }
+
+  (void)finishArrayExpr(expr);
+}
+
+void ExprRewriter::peepholeDictionaryUpcast(DictionaryExpr *expr,
+                                            Type toType, bool bridged,
+                                            Type keyType, Type valueType,
+                                            ConstraintLocatorBuilder locator) {
+  // Update the type of the dictionary literal.
+  cs.setType(expr, toType);
+
+  ConstraintLocatorBuilder keyLocator =
+    locator.withPathElement(
+      ConstraintLocator::PathElement::getGenericArgument(0));
+  ConstraintLocatorBuilder valueLocator =
+    locator.withPathElement(
+      ConstraintLocator::PathElement::getGenericArgument(1));
+
+  // Convert the elements.
+  TupleTypeElt tupleTypeElts[2] = { keyType, valueType };
+  auto tupleType = TupleType::get(tupleTypeElts, cs.getASTContext());
+  for (auto element : expr->getElements()) {
+    if (auto tuple = dyn_cast<TupleExpr>(element)) {
+      auto key = tuple->getElement(0);
+      if (auto newKey = buildElementConversion(*this, expr->getLoc(),
+                                               cs.getType(key), keyType,
+                                               bridged, valueLocator, key))
+        tuple->setElement(0, newKey);
+
+      auto value = tuple->getElement(1);
+      if (auto newValue = buildElementConversion(*this, expr->getLoc(),
+                                                 cs.getType(value), valueType,
+                                                 bridged, valueLocator,
+                                                 value)) {
+        tuple->setElement(1, newValue);
+      }
+
+      cs.setType(tuple, tupleType);
+    }
+  }
+
+  (void)finishDictionaryExpr(expr);
+}
+
+bool ExprRewriter::peepholeCollectionUpcast(Expr *expr, Type toType,
+                                            bool bridged,
+                                            ConstraintLocatorBuilder locator) {
+  // Recurse into parenthesized expressions.
+  if (auto paren = dyn_cast<ParenExpr>(expr)) {
+    // If we can't peephole the subexpression, we're done.
+    if (!peepholeCollectionUpcast(paren->getSubExpr(), toType, bridged,
+                                  locator))
+      return false;
+
+    // Update the type of this expression.
+    cs.setType(paren, ParenType::get(cs.getASTContext(),
+                                     cs.getType(paren->getSubExpr())));
+    return true;
+  }
+
+  // Array literals.
+  if (auto arrayLiteral = dyn_cast<ArrayExpr>(expr)) {
+    if (Optional<Type> elementType = ConstraintSystem::isArrayType(toType)) {
+      peepholeArrayUpcast(arrayLiteral, toType, bridged, *elementType, locator);
+      return true;
+    }
+
+    if (Optional<Type> elementType = ConstraintSystem::isSetType(toType)) {
+      peepholeArrayUpcast(arrayLiteral, toType, bridged, *elementType, locator);
+      return true;
+    }
+
+    return false;
+  }
+
+  // Dictionary literals.
+  if (auto dictLiteral = dyn_cast<DictionaryExpr>(expr)) {
+    if (auto elementType = ConstraintSystem::isDictionaryType(toType)) {
+      peepholeDictionaryUpcast(dictLiteral, toType, bridged,
+                               elementType->first, elementType->second,
+                               locator);
+      return true;
+    }
+
+    return false;
+  }
+
+  return false;
+}
+
+Expr *ExprRewriter::buildCollectionUpcastExpr(
+                                            Expr *expr, Type toType,
+                                            bool bridged,
+                                            ConstraintLocatorBuilder locator) {
+  if (peepholeCollectionUpcast(expr, toType, bridged, locator))
+    return expr;
+
   ASTContext &ctx = cs.getASTContext();
   // Build the first value conversion.
-  auto conv = buildElementConversion(*this, expr->getLoc(), cs.getType(expr),
-                                     toType, bridged, locator, 0);
+  auto conv =
+    buildOpaqueElementConversion(*this, expr->getLoc(), cs.getType(expr),
+                                 toType, bridged, locator, 0);
 
   // For single-parameter collections, form the upcast.
   if (ConstraintSystem::isArrayType(toType) ||
@@ -6261,8 +6421,9 @@
          "Unhandled collection upcast");
 
   // Build the second value conversion.
-  auto conv2 = buildElementConversion(*this, expr->getLoc(), cs.getType(expr),
-                                      toType, bridged, locator, 1);
+  auto conv2 =
+    buildOpaqueElementConversion(*this, expr->getLoc(), cs.getType(expr),
+                                 toType, bridged, locator, 1);
 
   return cs.cacheType(
            new (ctx) CollectionUpcastConversionExpr(expr, toType, conv, conv2));
diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp
index 85a0f27..e807468 100644
--- a/lib/Sema/DerivedConformanceCodable.cpp
+++ b/lib/Sema/DerivedConformanceCodable.cpp
@@ -767,7 +767,7 @@
 
   encodeDecl->setInterfaceType(interfaceType);
   encodeDecl->setValidationStarted();
-  encodeDecl->setAccess(target->getFormalAccess());
+  encodeDecl->copyFormalAccessFrom(target, /*sourceIsParentContext*/true);
 
   tc.Context.addSynthesizedDecl(encodeDecl);
 
@@ -1106,7 +1106,7 @@
   initDecl->setInterfaceType(interfaceType);
   initDecl->setValidationStarted();
   initDecl->setInitializerInterfaceType(initializerType);
-  initDecl->setAccess(target->getFormalAccess());
+  initDecl->copyFormalAccessFrom(target, /*sourceIsParentContext*/true);
 
   tc.Context.addSynthesizedDecl(initDecl);
 
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 9e6db9f..cbba981 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -655,7 +655,7 @@
                                     FunctionType::ExtInfo());
   }
   eqDecl->setInterfaceType(interfaceTy);
-  eqDecl->copyFormalAccessFrom(typeDecl);
+  eqDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
   eqDecl->setValidationStarted();
 
   tc.Context.addSynthesizedDecl(eqDecl);
@@ -1044,7 +1044,7 @@
 
   getterDecl->setInterfaceType(interfaceType);
   getterDecl->setValidationStarted();
-  getterDecl->copyFormalAccessFrom(typeDecl);
+  getterDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
 
   // Finish creating the property.
   hashValueDecl->setImplicit();
@@ -1052,7 +1052,7 @@
   hashValueDecl->setValidationStarted();
   hashValueDecl->makeComputed(SourceLoc(), getterDecl,
                               nullptr, nullptr, SourceLoc());
-  hashValueDecl->copyFormalAccessFrom(typeDecl);
+  hashValueDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
 
   Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
   hashValuePat->setType(intType);
diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp
index 37ef181..dfdb730 100644
--- a/lib/Sema/DerivedConformanceRawRepresentable.cpp
+++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp
@@ -340,7 +340,7 @@
   }
   initDecl->setInterfaceType(allocIfaceType);
   initDecl->setInitializerInterfaceType(initIfaceType);
-  initDecl->copyFormalAccessFrom(enumDecl);
+  initDecl->copyFormalAccessFrom(enumDecl, /*sourceIsParentContext*/true);
   initDecl->setValidationStarted();
 
   tc.Context.addSynthesizedDecl(initDecl);
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index e7d056e..c2b44b9 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -303,7 +303,7 @@
                                       /*IsCaptureList*/false, SourceLoc(), name,
                                       propertyContextType, parentDC);
   propDecl->setImplicit();
-  propDecl->copyFormalAccessFrom(typeDecl);
+  propDecl->copyFormalAccessFrom(typeDecl, /*sourceIsParentContext*/true);
   propDecl->setInterfaceType(propertyInterfaceType);
   propDecl->setValidationStarted();
 
diff --git a/lib/Sema/ITCType.cpp b/lib/Sema/ITCType.cpp
deleted file mode 100644
index 598fbb6..0000000
--- a/lib/Sema/ITCType.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-//===--- ITCType.cpp - Iterative Type Checker for Types -------------------===//
-//
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file implements the portions of the IterativeTypeChecker
-//  class that involve types.
-//
-//===----------------------------------------------------------------------===//
-#include "GenericTypeResolver.h"
-#include "TypeChecker.h"
-#include "swift/Sema/IterativeTypeChecker.h"
-#include "swift/AST/ASTContext.h"
-#include "swift/AST/ASTWalker.h"
-#include "swift/AST/Decl.h"
-using namespace swift;
-
-//===----------------------------------------------------------------------===//
-// Type resolution.
-//===----------------------------------------------------------------------===//
-bool IterativeTypeChecker::isResolveTypeReprSatisfied(
-       std::tuple<TypeRepr *, DeclContext *, unsigned> payload) {
-  auto typeRepr = std::get<0>(payload);
-  auto options = static_cast<TypeResolutionOptions>(std::get<2>(payload));
-
-  // FIXME: Introduce a bit indicating when everything in the TypeRepr
-  // has been name-bound, which indicates that we can always compute a
-  // structural type.
-  struct FindUnboundTypeRepr : public ASTWalker {
-    TypeResolutionOptions Options;
-
-    // Whether we've found an unbound type.
-    bool HasUnbound = false;
-
-    FindUnboundTypeRepr(TypeResolutionOptions options) : Options(options) { }
-
-    bool walkToTypeReprPre(TypeRepr *T) override {
-      // If we already found an unbound type, we're done.
-      if (HasUnbound) return false;
-
-      if (auto ident = dyn_cast<ComponentIdentTypeRepr>(T)) {
-        if (!ident->isBound()) {
-          HasUnbound = true;
-          return false;
-        }
-
-        // If we're only looking to resolve the structure of the type,
-        // don't walk into generic arguments. They don't affect the
-        // structure.
-        if (Options.contains(TypeResolutionFlags::ResolveStructure) &&
-            isa<GenericIdentTypeRepr>(ident))
-          return false;
-      }
-
-      // Keep walking.
-      return true;
-    }
-  } findUnboundTypeRepr(options);
-
-  typeRepr->walk(findUnboundTypeRepr);
-  return findUnboundTypeRepr.HasUnbound;
-}
-
-void IterativeTypeChecker::processResolveTypeRepr(
-       std::tuple<TypeRepr *, DeclContext *, unsigned> payload,
-       UnsatisfiedDependency unsatisfiedDependency) {
-  auto typeRepr = std::get<0>(payload);
-  auto dc = std::get<1>(payload);
-  auto options = static_cast<TypeResolutionOptions>(std::get<2>(payload));
-  
-  // FIXME: TypeChecker::resolveType() is mostly non-ad-hoc-recursive
-  // when given an UnsatisfiedDependency.
-  TC.resolveType(typeRepr, dc, options, nullptr, &unsatisfiedDependency);
-}
-
-bool IterativeTypeChecker::breakCycleForResolveTypeRepr(
-       std::tuple<TypeRepr *, DeclContext *, unsigned> payload) {
-  std::get<0>(payload)->setInvalid();
-  return true;
-}
-
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 2c6ae5c..6d02cec 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -185,7 +185,7 @@
 
   void visitAlignmentAttr(AlignmentAttr *attr) {
     // Alignment must be a power of two.
-    unsigned value = attr->Value;
+    auto value = attr->getValue();
     if (value == 0 || (value & (value - 1)) != 0)
       TC.diagnose(attr->getLocation(), diag::alignment_not_power_of_two);
   }
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index f7de22e..3d3aae9 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -7605,7 +7605,7 @@
            && "Decl parsing must prevent destructors outside of types!");
 
     checkDeclAttributesEarly(DD);
-    DD->copyFormalAccessFrom(enclosingClass);
+    DD->copyFormalAccessFrom(enclosingClass, /*sourceIsParentContext*/true);
 
     configureImplicitSelf(*this, DD);
 
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index 8ced660..0ed25a7 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -377,6 +377,7 @@
   
   template<typename StmtTy>
   bool typeCheckStmt(StmtTy *&S) {
+    PrettyStackTraceStmt trace(TC.Context, "type-checking", S);
     StmtTy *S2 = cast_or_null<StmtTy>(visit(S));
     if (S2 == nullptr)
       return true;
@@ -821,7 +822,7 @@
     // Type-check the subject expression.
     Expr *subjectExpr = S->getSubjectExpr();
     auto resultTy = TC.typeCheckExpression(subjectExpr, DC);
-    auto hadError = !resultTy;
+    auto limitExhaustivityChecks = !resultTy;
     if (Expr *newSubjectExpr = TC.coerceToRValue(subjectExpr))
       subjectExpr = newSubjectExpr;
     S->setSubjectExpr(subjectExpr);
@@ -856,7 +857,7 @@
           // Coerce the pattern to the subject's type.
           if (!subjectType || TC.coercePatternToType(pattern, DC, subjectType,
                                      TypeResolutionFlags::InExpression)) {
-            hadError = true;
+            limitExhaustivityChecks = true;
 
             // If that failed, mark any variables binding pieces of the pattern
             // as invalid to silence follow-on errors.
@@ -907,7 +908,7 @@
         }
         // Check the guard expression, if present.
         if (auto *guard = labelItem.getGuardExpr()) {
-          hadError |= TC.typeCheckCondition(guard, DC);
+          limitExhaustivityChecks |= TC.typeCheckCondition(guard, DC);
           labelItem.setGuardExpr(guard);
         }
       }
@@ -920,11 +921,13 @@
           TC.diagnose(caseBlock->getLoc(),
                       diag::unknown_case_multiple_patterns)
             .highlight(caseBlock->getCaseLabelItems()[1].getSourceRange());
+          limitExhaustivityChecks = true;
         }
 
-        if (!caseBlock->isDefault() && FallthroughDest != nullptr) {
-          TC.diagnose(caseBlock->getLoc(),
-                      diag::unknown_case_must_be_last);
+        if (FallthroughDest != nullptr) {
+          if (!caseBlock->isDefault())
+            TC.diagnose(caseBlock->getLoc(), diag::unknown_case_must_be_last);
+          limitExhaustivityChecks = true;
         }
 
         const CaseLabelItem &labelItem = caseBlock->getCaseLabelItems().front();
@@ -981,13 +984,13 @@
       // Type-check the body statements.
       PreviousFallthrough = nullptr;
       Stmt *body = caseBlock->getBody();
-      hadError |= typeCheckStmt(body);
+      limitExhaustivityChecks |= typeCheckStmt(body);
       caseBlock->setBody(body);
       previousBlock = caseBlock;
     }
 
     if (!S->isImplicit()) {
-      TC.checkSwitchExhaustiveness(S, DC, /*limitChecking*/hadError);
+      TC.checkSwitchExhaustiveness(S, DC, limitExhaustivityChecks);
     }
 
     return S;
diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp
index 6a221cd..d2a448d 100644
--- a/lib/Sema/TypeCheckSwitchStmt.cpp
+++ b/lib/Sema/TypeCheckSwitchStmt.cpp
@@ -1219,7 +1219,7 @@
       SmallVector<Space, 4> spaces;
       for (auto *caseBlock : Switch->getCases()) {
         if (caseBlock->hasUnknownAttr()) {
-          assert(unknownCase == nullptr);
+          assert(unknownCase == nullptr && "multiple unknown cases");
           unknownCase = caseBlock;
           continue;
         }
@@ -1345,10 +1345,25 @@
 
       // Decide whether we want an error or a warning.
       auto mainDiagType = diag::non_exhaustive_switch;
-      if (!uncovered.isEmpty() && unknownCase) {
-        assert(defaultReason == RequiresDefault::No);
-        mainDiagType = diag::non_exhaustive_switch_warn;
+      if (unknownCase) {
+        switch (defaultReason) {
+        case RequiresDefault::EmptySwitchBody:
+          llvm_unreachable("there's an @unknown case; the body can't be empty");
+        case RequiresDefault::No:
+          if (!uncovered.isEmpty())
+            mainDiagType = diag::non_exhaustive_switch_warn;
+          break;
+        case RequiresDefault::UncoveredSwitch:
+        case RequiresDefault::SpaceTooLarge:
+          TC.diagnose(startLoc, diag::non_exhaustive_switch);
+          TC.diagnose(unknownCase->getLoc(),
+                      diag::non_exhaustive_switch_drop_unknown)
+            .fixItRemoveChars(unknownCase->getStartLoc(),
+                              unknownCase->getLoc());
+          return;
+        }
       }
+
       switch (uncovered.checkDowngradeToWarning()) {
       case DowngradeToWarning::No:
         break;
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 8ec7f1b..3d34299 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -2277,8 +2277,8 @@
     }
     
     for (auto &fieldRepr : repr->getFields()) {
-      auto fieldTy = resolveType(fieldRepr.FieldType, options);
-      fields.push_back({fieldTy->getCanonicalType(), fieldRepr.Mutable});
+      auto fieldTy = resolveType(fieldRepr.getFieldType(), options);
+      fields.push_back({fieldTy->getCanonicalType(), fieldRepr.isMutable()});
     }
   }
 
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 670f821..11a919d 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -1107,11 +1107,12 @@
     assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
            "Layout should be OneTypeOneOperand.");
     bool isLifetimeGuaranteed = Attr & 0x01;
+    bool isEscaped = Attr & 0x02;
     ResultVal = Builder.createConvertEscapeToNoEscape(
         Loc,
         getLocalValue(ValID, getSILType(MF->getType(TyID2),
                                         (SILValueCategory)TyCategory2)),
-        getSILType(MF->getType(TyID), (SILValueCategory)TyCategory),
+        getSILType(MF->getType(TyID), (SILValueCategory)TyCategory), isEscaped,
         isLifetimeGuaranteed);
     break;
   }
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 006469b..0219e97 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -2232,7 +2232,7 @@
     auto abbrCode = DeclTypeAbbrCodes[AlignmentDeclAttrLayout::Code];
     AlignmentDeclAttrLayout::emitRecord(Out, ScratchRecord, abbrCode,
                                         theAlignment->isImplicit(),
-                                        theAlignment->Value);
+                                        theAlignment->getValue());
     return;
   }
   
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index 5c670b8..3aafb45 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -252,7 +252,7 @@
     void writeIndexTables();
 
     void writeConversionLikeInstruction(const SingleValueInstruction *I,
-                                        bool guaranteed);
+                                        bool guaranteed, bool escaped);
     void writeOneTypeLayout(SILInstructionKind valueKind, SILType type);
     void writeOneTypeOneOperandLayout(SILInstructionKind valueKind,
                                       unsigned attrs,
@@ -601,10 +601,11 @@
 /// Write an instruction that looks exactly like a conversion: all
 /// important information is encoded in the operand and the result type.
 void SILSerializer::writeConversionLikeInstruction(
-    const SingleValueInstruction *I, bool guaranteed) {
+    const SingleValueInstruction *I, bool guaranteed, bool escaped) {
   assert(I->getNumOperands() - I->getTypeDependentOperands().size() == 1);
-  writeOneTypeOneOperandLayout(I->getKind(), guaranteed ? 1 : 0, I->getType(),
-                               I->getOperand(0));
+  writeOneTypeOneOperandLayout(I->getKind(),
+                               (guaranteed ? 1 : 0) | (escaped ? 2 : 0),
+                               I->getType(), I->getOperand(0));
 }
 
 void
@@ -1473,10 +1474,13 @@
   case SILInstructionKind::ObjCExistentialMetatypeToObjectInst:
   case SILInstructionKind::ProjectBlockStorageInst: {
     bool guaranteed = false;
-    if (SI.getKind() == SILInstructionKind::ConvertEscapeToNoEscapeInst)
+    bool escaped = false;
+    if (SI.getKind() == SILInstructionKind::ConvertEscapeToNoEscapeInst) {
+      escaped = cast<ConvertEscapeToNoEscapeInst>(SI).isEscapedByUser();
       guaranteed = cast<ConvertEscapeToNoEscapeInst>(SI).isLifetimeGuaranteed();
+    }
     writeConversionLikeInstruction(cast<SingleValueInstruction>(&SI),
-                                   guaranteed);
+                                   guaranteed, escaped);
     break;
   }
   case SILInstructionKind::PointerToAddressInst: {
diff --git a/stdlib/public/SDK/Foundation/Decimal.swift b/stdlib/public/SDK/Foundation/Decimal.swift
index 8af713e..6e0cd4b 100644
--- a/stdlib/public/SDK/Foundation/Decimal.swift
+++ b/stdlib/public/SDK/Foundation/Decimal.swift
@@ -59,6 +59,7 @@
     public mutating func formTruncatingRemainder(dividingBy other: Decimal) { fatalError("Decimal does not yet fully adopt FloatingPoint") }
 
     public mutating func negate() {
+        guard _length != 0 else { return }
         _isNegative = _isNegative == 0 ? 1 : 0
     }
 
diff --git a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
index 93255e9..af4a8e9 100644
--- a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
+++ b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
@@ -1,6 +1,3 @@
-# HACK: Force this library to build with undefined symbols.
-string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
-
 # libswiftRemoteMirror.dylib should not have runtime dependencies; it's
 # always built as a shared library.
 if(SWIFT_BUILD_DYNAMIC_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR)
diff --git a/stdlib/public/core/ClosedRange.swift b/stdlib/public/core/ClosedRange.swift
index c95fc7d..df64925 100644
--- a/stdlib/public/core/ClosedRange.swift
+++ b/stdlib/public/core/ClosedRange.swift
@@ -498,6 +498,7 @@
 
 @available(*, deprecated, renamed: "ClosedRange.Index")
 public typealias ClosedRangeIndex<T> = ClosedRange<T>.Index where T: Strideable, T.Stride: SignedInteger
-@available(*, deprecated, renamed: "ClosedRange")
+
+@available(*, deprecated: 4.2, renamed: "ClosedRange")
 public typealias CountableClosedRange<Bound: Strideable> = ClosedRange<Bound>
   where Bound.Stride : SignedInteger
diff --git a/stdlib/public/core/NewtypeWrapper.swift b/stdlib/public/core/NewtypeWrapper.swift
index fe74178..08aa9f9 100644
--- a/stdlib/public/core/NewtypeWrapper.swift
+++ b/stdlib/public/core/NewtypeWrapper.swift
@@ -15,11 +15,16 @@
 /// attribute.
 public protocol _SwiftNewtypeWrapper : RawRepresentable { }
 
-extension _SwiftNewtypeWrapper where Self.RawValue : Hashable {
+extension _SwiftNewtypeWrapper where Self: Hashable, Self.RawValue : Hashable {
   @inlinable // FIXME(sil-serialize-all)
   public var hashValue: Int {
     return rawValue.hashValue
   }
+
+  @inlinable // FIXME(sil-serialize-all)
+  public func _hash(into hasher: inout _Hasher) {
+    hasher.append(rawValue)
+  }
 }
 
 #if _runtime(_ObjC)
diff --git a/stdlib/public/core/Range.swift b/stdlib/public/core/Range.swift
index bac7c3e..b7aac8d 100644
--- a/stdlib/public/core/Range.swift
+++ b/stdlib/public/core/Range.swift
@@ -907,3 +907,7 @@
 @available(*, deprecated, renamed: "Range")
 public typealias CountableRange<Bound: Strideable> = Range<Bound>
   where Bound.Stride : SignedInteger
+
+@available(*, deprecated: 4.2, renamed: "PartialRangeFrom")
+public typealias CountablePartialRangeFrom<Bound: Strideable> = PartialRangeFrom<Bound>
+  where Bound.Stride : SignedInteger
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index 517e449..4bedefe 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -1031,7 +1031,7 @@
       // Call the associated type access function.
       // TODO: can we just request abstract metadata?  If so, do we have
       //   a responsibility to try to finish it later?
-      return ((const AssociatedTypeAccessFunction * const *)witnessTable)[*assocTypeReqIndex]
+      return ((AssociatedTypeAccessFunction * const *)witnessTable)[*assocTypeReqIndex]
                 (MetadataState::Complete, base, witnessTable).Value;
     });
 
diff --git a/stdlib/public/stubs/MathStubs.cpp b/stdlib/public/stubs/MathStubs.cpp
index f6bc8f2..9f8de55 100644
--- a/stdlib/public/stubs/MathStubs.cpp
+++ b/stdlib/public/stubs/MathStubs.cpp
@@ -29,9 +29,29 @@
 #define SWIFT_MODE_TI
 #endif
 
+typedef int si_int;
 typedef int di_int SWIFT_MODE_DI;
 typedef int ti_int SWIFT_MODE_TI;
 
+typedef unsigned su_int;
+typedef unsigned du_int SWIFT_MODE_DI;
+typedef unsigned tu_int SWIFT_MODE_TI;
+
+typedef union
+{
+    tu_int all;
+    struct
+    {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+        du_int low;
+        du_int high;
+#else
+        du_int high;
+        du_int low;
+#endif /* __BYTE_ORDER__ == __LITTLE_ENDIAN__ */
+    }s;
+} utwords;
+
 extern "C" {
 
 // Although this builtin is provided by clang rt builtins,
@@ -142,5 +162,265 @@
 
 #endif
 
+#if defined(_WIN32)
+
+tu_int
+__udivmodti4(tu_int a, tu_int b, tu_int* rem)
+{
+    const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
+    const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
+    utwords n;
+    n.all = a;
+    utwords d;
+    d.all = b;
+    utwords q;
+    utwords r;
+    unsigned sr;
+    /* special cases, X is unknown, K != 0 */
+    if (n.s.high == 0)
+    {
+        if (d.s.high == 0)
+        {
+            /* 0 X
+             * ---
+             * 0 X
+             */
+            if (rem)
+                *rem = n.s.low % d.s.low;
+            return n.s.low / d.s.low;
+        }
+        /* 0 X
+         * ---
+         * K X
+         */
+        if (rem)
+            *rem = n.s.low;
+        return 0;
+    }
+    /* n.s.high != 0 */
+    if (d.s.low == 0)
+    {
+        if (d.s.high == 0)
+        {
+            /* K X
+             * ---
+             * 0 0
+             */
+            if (rem)
+                *rem = n.s.high % d.s.low;
+            return n.s.high / d.s.low;
+        }
+        /* d.s.high != 0 */
+        if (n.s.low == 0)
+        {
+            /* K 0
+             * ---
+             * K 0
+             */
+            if (rem)
+            {
+                r.s.high = n.s.high % d.s.high;
+                r.s.low = 0;
+                *rem = r.all;
+            }
+            return n.s.high / d.s.high;
+        }
+        /* K K
+         * ---
+         * K 0
+         */
+        if ((d.s.high & (d.s.high - 1)) == 0)     /* if d is a power of 2 */
+        {
+            if (rem)
+            {
+                r.s.low = n.s.low;
+                r.s.high = n.s.high & (d.s.high - 1);
+                *rem = r.all;
+            }
+            return n.s.high >> __builtin_ctzll(d.s.high);
+        }
+        /* K K
+         * ---
+         * K 0
+         */
+        sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
+        /* 0 <= sr <= n_udword_bits - 2 or sr large */
+        if (sr > n_udword_bits - 2)
+        {
+           if (rem)
+                *rem = n.all;
+            return 0;
+        }
+        ++sr;
+        /* 1 <= sr <= n_udword_bits - 1 */
+        /* q.all = n.all << (n_utword_bits - sr); */
+        q.s.low = 0;
+        q.s.high = n.s.low << (n_udword_bits - sr);
+        /* r.all = n.all >> sr; */
+        r.s.high = n.s.high >> sr;
+        r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+    }
+    else  /* d.s.low != 0 */
+    {
+        if (d.s.high == 0)
+        {
+            /* K X
+             * ---
+             * 0 K
+             */
+            if ((d.s.low & (d.s.low - 1)) == 0)     /* if d is a power of 2 */
+            {
+                if (rem)
+                    *rem = n.s.low & (d.s.low - 1);
+                if (d.s.low == 1)
+                    return n.all;
+                sr = __builtin_ctzll(d.s.low);
+                q.s.high = n.s.high >> sr;
+                q.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+                return q.all;
+            }
+            /* K X
+             * ---
+             * 0 K
+             */
+            sr = 1 + n_udword_bits + __builtin_clzll(d.s.low)
+                                   - __builtin_clzll(n.s.high);
+            /* 2 <= sr <= n_utword_bits - 1
+             * q.all = n.all << (n_utword_bits - sr);
+             * r.all = n.all >> sr;
+             */
+            if (sr == n_udword_bits)
+            {
+                q.s.low = 0;
+                q.s.high = n.s.low;
+                r.s.high = 0;
+                r.s.low = n.s.high;
+            }
+            else if (sr < n_udword_bits)  // 2 <= sr <= n_udword_bits - 1
+            {
+                q.s.low = 0;
+                q.s.high = n.s.low << (n_udword_bits - sr);
+                r.s.high = n.s.high >> sr;
+                r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+            }
+            else              // n_udword_bits + 1 <= sr <= n_utword_bits - 1
+            {
+                q.s.low = n.s.low << (n_utword_bits - sr);
+                q.s.high = (n.s.high << (n_utword_bits - sr)) |
+                           (n.s.low >> (sr - n_udword_bits));
+                r.s.high = 0;
+                r.s.low = n.s.high >> (sr - n_udword_bits);
+            }
+        }
+        else
+        {
+            /* K X
+             * ---
+             * K K
+             */
+            sr = __builtin_clzll(d.s.high) - __builtin_clzll(n.s.high);
+            /*0 <= sr <= n_udword_bits - 1 or sr large */
+            if (sr > n_udword_bits - 1)
+            {
+               if (rem)
+                    *rem = n.all;
+                return 0;
+            }
+            ++sr;
+            /* 1 <= sr <= n_udword_bits
+             * q.all = n.all << (n_utword_bits - sr);
+             * r.all = n.all >> sr;
+             */
+            q.s.low = 0;
+            if (sr == n_udword_bits)
+            {
+                q.s.high = n.s.low;
+                r.s.high = 0;
+                r.s.low = n.s.high;
+            }
+            else
+            {
+                r.s.high = n.s.high >> sr;
+                r.s.low = (n.s.high << (n_udword_bits - sr)) | (n.s.low >> sr);
+                q.s.high = n.s.low << (n_udword_bits - sr);
+            }
+        }
+    }
+    /* Not a special case
+     * q and r are initialized with:
+     * q.all = n.all << (n_utword_bits - sr);
+     * r.all = n.all >> sr;
+     * 1 <= sr <= n_utword_bits - 1
+     */
+    su_int carry = 0;
+    for (; sr > 0; --sr)
+    {
+        /* r:q = ((r:q)  << 1) | carry */
+        r.s.high = (r.s.high << 1) | (r.s.low  >> (n_udword_bits - 1));
+        r.s.low  = (r.s.low  << 1) | (q.s.high >> (n_udword_bits - 1));
+        q.s.high = (q.s.high << 1) | (q.s.low  >> (n_udword_bits - 1));
+        q.s.low  = (q.s.low  << 1) | carry;
+        /* carry = 0;
+         * if (r.all >= d.all)
+         * {
+         *     r.all -= d.all;
+         *      carry = 1;
+         * }
+         */
+        const ti_int s = (ti_int)(d.all - r.all - 1) >> (n_utword_bits - 1);
+        carry = s & 1;
+        r.all -= d.all & s;
+    }
+    q.all = (q.all << 1) | carry;
+    if (rem)
+        *rem = r.all;
+    return q.all;
+}
+
+SWIFT_RUNTIME_STDLIB_INTERFACE
+tu_int
+__udivti3(tu_int a, tu_int b)
+{
+    return __udivmodti4(a, b, NULL);
+}
+
+SWIFT_RUNTIME_STDLIB_INTERFACE
+tu_int
+__umodti3(tu_int a, tu_int b)
+{
+    tu_int r;
+    __udivmodti4(a, b, &r);
+    return r;
+}
+
+SWIFT_RUNTIME_STDLIB_INTERFACE
+ti_int
+__divti3(ti_int a, ti_int b)
+{
+    const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
+    ti_int s_a = a >> bits_in_tword_m1;                   /* s_a = a < 0 ? -1 : 0 */
+    ti_int s_b = b >> bits_in_tword_m1;                   /* s_b = b < 0 ? -1 : 0 */
+    a = (a ^ s_a) - s_a;                                  /* negate if s_a == -1 */
+    b = (b ^ s_b) - s_b;                                  /* negate if s_b == -1 */
+    s_a ^= s_b;                                           /* sign of quotient */
+    return (__udivmodti4(a, b, (tu_int*)0) ^ s_a) - s_a;  /* negate if s_a == -1 */
+}
+
+SWIFT_RUNTIME_STDLIB_INTERFACE
+ti_int
+__modti3(ti_int a, ti_int b)
+{
+    const int bits_in_tword_m1 = (int)(sizeof(ti_int) * CHAR_BIT) - 1;
+    ti_int s = b >> bits_in_tword_m1;  /* s = b < 0 ? -1 : 0 */
+    b = (b ^ s) - s;                   /* negate if s == -1 */
+    s = a >> bits_in_tword_m1;         /* s = a < 0 ? -1 : 0 */
+    a = (a ^ s) - s;                   /* negate if s == -1 */
+    tu_int r;
+    __udivmodti4(a, b, &r);
+    return ((ti_int)r ^ s) - s;        /* negate if s == -1 */
+}
+
+#endif
+
 }
 
diff --git a/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/app.h b/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/app.h
new file mode 100644
index 0000000..154f4ef
--- /dev/null
+++ b/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/app.h
@@ -0,0 +1,5 @@
+#include "has_warning.h"
+
+static inline int app_function(int x) {
+  return x + 27;
+}
diff --git a/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/has_warning.h b/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/has_warning.h
new file mode 100644
index 0000000..b516ee9
--- /dev/null
+++ b/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/has_warning.h
@@ -0,0 +1,6 @@
+#ifndef HAS_WARNING_H
+#define HAS_WARNING_H
+
+#warning "warning in bridging header"
+
+#endif
diff --git a/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/unit-tests.h b/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/unit-tests.h
new file mode 100644
index 0000000..a78913e
--- /dev/null
+++ b/test/ClangImporter/Inputs/pch-bridging-header-with-another-bridging-header/unit-tests.h
@@ -0,0 +1 @@
+#include "has_warning.h"
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Headers/SKWidget.h b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Headers/SKWidget.h
new file mode 100644
index 0000000..dd99ff7
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Headers/SKWidget.h
@@ -0,0 +1 @@
+#import <SomeKitCore/SKWidget.h>
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Headers/SomeKit.h b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Headers/SomeKit.h
new file mode 100644
index 0000000..17a4cc8
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Headers/SomeKit.h
@@ -0,0 +1 @@
+#import <SomeKit/SKWidget.h>
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Modules/module.modulemap b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..ae4b276
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module SomeKit {
+  umbrella header "SomeKit.h"
+  module * {
+    export *
+  }
+}
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/SomeKit.tbd b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/SomeKit.tbd
new file mode 100644
index 0000000..fcb8b10
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKit.framework/SomeKit.tbd
@@ -0,0 +1 @@
+// dummy file to trigger autolink
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Headers/SKWidget.h b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Headers/SKWidget.h
new file mode 100644
index 0000000..0370e85
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Headers/SKWidget.h
@@ -0,0 +1,27 @@
+@import ObjectiveC;
+@import Foundation;
+
+@interface SKWidget : NSObject
+- (void)someObjCMethod;
+@end
+
+@interface SKWidget(ObjCAPI)
+- (void)someObjCExtensionMethod;
+@property (readwrite,strong,nonnull) NSObject *anObject;
+@end
+
+@interface NSObject (SKWidget)
+- (void)doSomethingWithWidget:(nonnull SKWidget *)widget;
+@end
+
+extern NSString * _Nonnull const SKWidgetErrorDomain;
+typedef enum __attribute__((ns_error_domain(SKWidgetErrorDomain))) __attribute__((swift_name("SKWidget.Error"))) SKWidgetErrorCode : NSInteger {
+  SKWidgetErrorNone = 0,
+  SKWidgetErrorBoom = 1
+} SKWidgetErrorCode;
+
+@interface SKWidget(Erroneous)
+- (SKWidgetErrorCode)getCurrentError;
+@end
+
+extern void someKitGlobalFunc(void);
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Headers/SomeKitCore.h b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Headers/SomeKitCore.h
new file mode 100644
index 0000000..dd99ff7
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Headers/SomeKitCore.h
@@ -0,0 +1 @@
+#import <SomeKitCore/SKWidget.h>
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Modules/module.modulemap b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Modules/module.modulemap
new file mode 100644
index 0000000..30f9770
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/Modules/module.modulemap
@@ -0,0 +1,7 @@
+framework module SomeKitCore {
+  umbrella header "SomeKitCore.h"
+  export_as SomeKit
+  module * {
+    export *
+  }
+}
diff --git a/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/SomeKitCore.tbd b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/SomeKitCore.tbd
new file mode 100644
index 0000000..fcb8b10
--- /dev/null
+++ b/test/ClangImporter/Inputs/privateframeworks/withprivate-autolink/SomeKitCore.framework/SomeKitCore.tbd
@@ -0,0 +1 @@
+// dummy file to trigger autolink
diff --git a/test/ClangImporter/pch-bridging-header-with-another-bridging-header.swift b/test/ClangImporter/pch-bridging-header-with-another-bridging-header.swift
new file mode 100644
index 0000000..63d2326
--- /dev/null
+++ b/test/ClangImporter/pch-bridging-header-with-another-bridging-header.swift
@@ -0,0 +1,21 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -emit-module -import-objc-header %S/Inputs/pch-bridging-header-with-another-bridging-header/app.h -I %S/Inputs/pch-bridging-header-with-another-bridging-header -module-name App -emit-module-path %t/App.swiftmodule %S/../Inputs/empty.swift
+// RUN: llvm-bcanalyzer -dump %t/App.swiftmodule | %FileCheck %s
+
+// CHECK: IMPORTED_HEADER{{.*}}Inputs/pch-bridging-header-with-another-bridging-header/app.h
+
+// Now load the app-module-with-bridging-header along with another bridging
+// header that we precompile. This is going to the frontend directly to make
+// sure we validate PCH inputs (because -pch-disable-validation wasn't passed).
+// This is deliberately run twice to test what happens when the PCH is already
+// there. (It used to crash.)
+
+// RUN: cp %S/Inputs/pch-bridging-header-with-another-bridging-header/unit-tests.h %t/unit-tests.h
+// RUN: %target-swift-frontend -typecheck -pch-output-dir %t -import-objc-header %t/unit-tests.h -I %S/Inputs/pch-bridging-header-with-another-bridging-header -I %t %s
+// RUN: %target-swift-frontend -typecheck -pch-output-dir %t -import-objc-header %t/unit-tests.h -I %S/Inputs/pch-bridging-header-with-another-bridging-header -I %t %s
+// RUN: echo >> %t/unit-tests.h
+// RUN: %target-swift-frontend -typecheck -pch-output-dir %t -import-objc-header %t/unit-tests.h -I %S/Inputs/pch-bridging-header-with-another-bridging-header -I %t %s
+
+import App
+
+_ = app_function(2)
\ No newline at end of file
diff --git a/test/ClangImporter/private_frameworks_autolink.swift b/test/ClangImporter/private_frameworks_autolink.swift
new file mode 100644
index 0000000..545b180
--- /dev/null
+++ b/test/ClangImporter/private_frameworks_autolink.swift
@@ -0,0 +1,16 @@
+// RUN: %empty-directory(%t)
+
+// FIXME: BEGIN -enable-source-import hackaround
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -emit-module -o %t %clang-importer-sdk-path/swift-modules/CoreGraphics.swift
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -o %t %clang-importer-sdk-path/swift-modules/Foundation.swift
+// FIXME: END -enable-source-import hackaround
+
+// Check that the autolink information is appropriate (do not link against SomeKitCore).
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-ir -o %t/private_frameworks_autolink.ll -F %S/Inputs/privateframeworks/withprivate-autolink %s
+// RUN: %FileCheck %s < %t/private_frameworks_autolink.ll
+// CHECK-NOT: !{!"-framework", !"SomeKitCore"}
+
+// REQUIRES: objc_interop
+
+import SomeKitCore
+import SomeKit
diff --git a/test/ClangImporter/private_frameworks_autolink2.swift b/test/ClangImporter/private_frameworks_autolink2.swift
new file mode 100644
index 0000000..7d09ba9
--- /dev/null
+++ b/test/ClangImporter/private_frameworks_autolink2.swift
@@ -0,0 +1,16 @@
+// RUN: %empty-directory(%t)
+
+// FIXME: BEGIN -enable-source-import hackaround
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource) -emit-module -o %t %clang-importer-sdk-path/swift-modules/CoreGraphics.swift
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-module -o %t %clang-importer-sdk-path/swift-modules/Foundation.swift
+// FIXME: END -enable-source-import hackaround
+
+// Check that the autolink information is appropriate (do not link against SomeKitCore).
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-ir -o %t/private_frameworks_autolink2.ll -F %S/Inputs/privateframeworks/withprivate-autolink %s
+// RUN: %FileCheck %s < %t/private_frameworks_autolink2.ll
+// CHECK-NOT: !{!"-framework", !"SomeKit"}
+// CHECK: !{!"-framework", !"SomeKitCore"}
+
+// REQUIRES: objc_interop
+
+import SomeKitCore
diff --git a/test/Compatibility/exhaustive_switch.swift b/test/Compatibility/exhaustive_switch.swift
index 9e0b392..a3d3e57 100644
--- a/test/Compatibility/exhaustive_switch.swift
+++ b/test/Compatibility/exhaustive_switch.swift
@@ -473,6 +473,21 @@
   case (.case10, _): return true
   }
 
+  switch (OverlyLargeSpaceEnum.case1, OverlyLargeSpaceEnum.case2) { // expected-error {{switch must be exhaustive}}
+  case (.case0, _): return true
+  case (.case1, _): return true
+  case (.case2, _): return true
+  case (.case3, _): return true
+  case (.case4, _): return true
+  case (.case5, _): return true
+  case (.case6, _): return true
+  case (.case7, _): return true
+  case (.case8, _): return true
+  case (.case9, _): return true
+  case (.case10, _): return true
+  @unknown default: return false // expected-note {{remove '@unknown' to handle remaining values}} {{3-12=}}
+  }
+
 
   // No diagnostic
   switch (OverlyLargeSpaceEnum.case1, OverlyLargeSpaceEnum.case2) {
@@ -526,6 +541,10 @@
   case .two: return true
   case .three: return true
   }
+
+  // Make sure we haven't just stopped emitting diagnostics.
+  switch OverlyLargeSpaceEnum.case1 { // expected-error {{switch must be exhaustive}} expected-note 12 {{add missing case}} expected-note {{handle unknown values}}
+  }
 }
 
 indirect enum InfinitelySized {
diff --git a/test/Constraints/rdar39209245.swift b/test/Constraints/rdar39209245.swift
new file mode 100644
index 0000000..b7e15d5
--- /dev/null
+++ b/test/Constraints/rdar39209245.swift
@@ -0,0 +1,15 @@
+// RUN: %target-typecheck-verify-swift
+
+struct S: Hashable {
+  let e: E?
+}
+
+enum E: Hashable {
+  case foo
+  case bar
+}
+
+let a = S(e: .foo)
+let b = S(e: .bar)
+
+_ = a == b
diff --git a/test/DebugInfo/DumpDeclFromMangledName.swift b/test/DebugInfo/DumpDeclFromMangledName.swift
index 154afd3..4b8bcef 100644
--- a/test/DebugInfo/DumpDeclFromMangledName.swift
+++ b/test/DebugInfo/DumpDeclFromMangledName.swift
@@ -7,6 +7,22 @@
 // RUN: sed -ne '/--->/s/^.*---> *//p' < %S/Inputs/decl-reconstr-names.txt > %t.check
 
 // RUN: %target-build-swift -emit-executable %s -g -o %t/DeclReconstr -emit-module
+
+// Input validation tests.
+// RUN: not %lldb-moduleimport-test patatino 2>&1 | %FileCheck %s \
+// RUN:   --check-prefix=INVALID-INPUT
+// INVALID-INPUT: patatino does not exists, exiting.
+
+// RUN: not %lldb-moduleimport-test %t/DeclReconstr \
+// RUN:   --decl-from-mangled=patatino 2>&1 | \
+// RUN:   %FileCheck %s --check-prefix=INVALID-DECL
+// INVALID-DECL: patatino does not exists, exiting.
+
+// RUN: not %lldb-moduleimport-test %t/DeclReconstr \
+// RUN:   --type-from-mangled=patatino 2>&1 | \
+// RUN:   %FileCheck %s --check-prefix=INVALID-TYPE
+// INVALID-TYPE: patatino does not exists, exiting.
+
 // RUN: %lldb-moduleimport-test %t/DeclReconstr \
 // RUN:   -decl-from-mangled=%t.input > %t.output 2>&1
 // RUN: diff %t.check %t.output
diff --git a/test/DebugInfo/LinetableArtificialFn.swift b/test/DebugInfo/LinetableArtificialFn.swift
deleted file mode 100644
index 4f985ff..0000000
--- a/test/DebugInfo/LinetableArtificialFn.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %target-swift-frontend %s -emit-ir -g -o - -disable-sil-linking | %FileCheck %s
-
-// Verify that a helper function that is generated on-the-fly does
-// not mess up the linetable of the calling function.
-// CHECK:  store i2048 10, i2048* [[STKLOC:%.*]], align
-// CHECK:  call swiftcc {{(i32|i64)}} @"$SSi22_builtinIntegerLiteralSiBi2048__tcfC"(i2048* {{.*}} [[STKLOC]]
-// CHECK: store {{(i32|i64)}} {{.*}}getelementptr
-// CHECK: store {{(i32|i64)}} {{.*}}getelementptr{{.*}}, !dbg ![[DBG:[0-9]+]]
-// CHECK-NOT: ![[DBG]] = !{i32 0, i32 0,
-
-class TurnBasedPolicy {
-
-	typealias Rules = (onWin : Int, onHint : Int, onLose : Int, onWrongGuess: Int, numAttempts : Int, numHints : Int, secretRange : (Int, Int))
-
-	init (r : Rules) {
-		self.rules = r
-	}
-	var rules : Rules
-	var secret = 0
-	var attempts = 0
-	var hints = 0
-	var hintedRange = (0, 0)
-}
-
-var easyPolicy : TurnBasedPolicy.Rules = (
-	onWin : 2,
-	onHint : -1,
-	onLose : -2,
-	onWrongGuess : 0,
-	numAttempts : 7,
-	numHints : 7,
-	secretRange : (1,10)
-)
-
diff --git a/test/DebugInfo/basic.swift b/test/DebugInfo/basic.swift
index d9b6bbb..4755a0f 100644
--- a/test/DebugInfo/basic.swift
+++ b/test/DebugInfo/basic.swift
@@ -20,8 +20,6 @@
 // --------------------------------------------------------------------
 // Now check that we do generate line+scope info with -g.
 // RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
-// RUN: %target-swift-frontend %s -emit-ir -g -o - -disable-sil-linking \
-// RUN:   | %FileCheck %s --check-prefix=CHECK-NOSIL
 // --------------------------------------------------------------------
 // Currently -gdwarf-types should give the same results as -g.
 // RUN: %target-swift-frontend %s -emit-ir -gdwarf-types -o - | %FileCheck %s
@@ -49,10 +47,7 @@
        // CHECK-DAG: !DILexicalBlock({{.*}} line: [[@LINE-1]]
        // Transparent inlined multiply:
        // CHECK-DAG: smul{{.*}}, !dbg ![[MUL:[0-9]+]]
-       // CHECK-DAG: [[MUL]] = !DILocation(line: [[@LINE+4]], column: 16,
-       // Runtime call to multiply function:
-       // CHECK-NOSIL: @"$Ss5Int64V1moiyA2B_ABtFZ{{.*}}, !dbg ![[MUL:[0-9]+]]
-       // CHECK-NOSIL: [[MUL]] = !DILocation(line: [[@LINE+1]], column: 16,
+       // CHECK-DAG: [[MUL]] = !DILocation(line: [[@LINE+1]], column: 16,
        return a*b
      } else {
        // CHECK-DAG: ![[PARENT:[0-9]+]] = distinct !DILexicalBlock({{.*}} line: [[@LINE-1]], column: 13)
diff --git a/test/IRGen/objc_super.swift b/test/IRGen/objc_super.swift
index 5cd6f84..c8b86cb 100644
--- a/test/IRGen/objc_super.swift
+++ b/test/IRGen/objc_super.swift
@@ -76,7 +76,7 @@
 class PartialApply : Gizmo {
   // CHECK: define hidden swiftcc void @"$S10objc_super12PartialApplyC4frobyyF"([[PARTIAL_APPLY_CLASS]]* swiftself) {{.*}} {
   override func frob() {
-    // CHECK: call swiftcc void @"$S10objc_super8acceptFnyyyyXEF"(i8* bitcast (void (%swift.refcounted*)* [[PARTIAL_FORWARDING_THUNK:@"\$[A-Za-z0-9_]+"]] to i8*), %swift.opaque* %7)
+    // CHECK: call swiftcc void @"$S10objc_super8acceptFnyyyyXEF"(i8* bitcast (void (%swift.refcounted*)* [[PARTIAL_FORWARDING_THUNK:@"\$[A-Za-z0-9_]+"]] to i8*), %swift.opaque* %{{[0-9]+}})
     acceptFn(super.frob)
   }
   // CHECK: }
diff --git a/test/IRGen/outlined_copy_addr.swift b/test/IRGen/outlined_copy_addr.swift
index a4973b4..b68a57b 100644
--- a/test/IRGen/outlined_copy_addr.swift
+++ b/test/IRGen/outlined_copy_addr.swift
@@ -18,9 +18,33 @@
     var elem2: BaseStruct<Element>
 }
 
-// CHECK-LABEL: define hidden swiftcc void @"$S11outcopyaddr010StructWithbc4BaseB0V4elemAA0bcdB0VyxGvg"(%T11outcopyaddr014StructWithBaseB0V.0* noalias nocapture sret, %swift.type* %"StructWithStructWithBaseStruct<T>", %T11outcopyaddr010StructWithbc4BaseB0V* noalias nocapture swiftself)
-// CHECK: call %T11outcopyaddr014StructWithBaseB0V.0* @"$S11outcopyaddr014StructWithBaseB0VyxGAA9ChildProtRzlWOc"
+// CHECK-LABEL: define hidden swiftcc void @"$S11outcopyaddr010StructWithbc4BaseB0V4elemAA0bcdB0VyxGvg"(%T11outcopyaddr014StructWithBaseB0V.4* noalias nocapture sret, %swift.type* %"StructWithStructWithBaseStruct<T>", %T11outcopyaddr010StructWithbc4BaseB0V* noalias nocapture swiftself)
+// CHECK: call %T11outcopyaddr014StructWithBaseB0V.4* @"$S11outcopyaddr014StructWithBaseB0VyxGAA9ChildProtRzlWOc"
 public struct StructWithStructWithBaseStruct<T: ChildProt> {
     public typealias Element = T
     let elem: StructWithBaseStruct<Element>
 }
+
+protocol P { }
+
+class OtherPrivate<T> { }
+
+struct OtherInternal<T> {
+  var myPrivate: OtherPrivate<T>? = nil
+}
+
+struct MyPrivate<T: P> {
+  var otherHelper: OtherInternal<T>? = nil
+
+  // CHECK-LABEL: define hidden swiftcc {{i32|i64}} @"$S11outcopyaddr9MyPrivateVyACyxGxcfC"(%swift.opaque* noalias nocapture, %swift.type* %T, i8** %T.P) {{.*}} {
+  // CHECK: call %T11outcopyaddr9MyPrivateV* @"$S11outcopyaddr9MyPrivateVyxGAA1PRzlWOh"(%T11outcopyaddr9MyPrivateV* %self)
+  // CHECK: ret
+  init(_: T) { }
+}
+
+extension P {
+  func foo(data: Any) {
+    _ = MyPrivate(data as! Self)
+  }
+}
+
diff --git a/test/IRGen/same_type_constraints.swift b/test/IRGen/same_type_constraints.swift
index a8ca7fe..881ac82 100644
--- a/test/IRGen/same_type_constraints.swift
+++ b/test/IRGen/same_type_constraints.swift
@@ -1,6 +1,12 @@
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-ir -primary-file %s -disable-objc-attr-requires-foundation-module | %FileCheck %s
 // RUN: %target-swift-frontend -Osize -assume-parsing-unqualified-ownership-sil -emit-ir -primary-file %s -disable-objc-attr-requires-foundation-module | %FileCheck %s --check-prefix=OSIZE
 
+// Ensure that same-type constraints between generic arguments get reflected
+// correctly in the type context descriptor.
+// CHECK-LABEL: @"$S21same_type_constraints4SG11VA2A2P2Rzq_RszrlE13InnerTEqualsUVMn" = 
+//                  T       U(==T) V        padding
+// CHECK-SAME:    , i8 -128, i8 0, i8 -128, i8 0,
+
 // <rdar://problem/21665983> IRGen crash with protocol extension involving same-type constraint to X<T>
 public struct DefaultFoo<T> {
   var t: T?
@@ -16,7 +22,8 @@
   }
 }
 
-// CHECK: define{{( protected)?}} swiftcc void @"$S21same_type_constraints1PPA2A10DefaultFooVyxG0E0RtzrlE3fooAFyF"
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S21same_type_constraints1PPA2A10DefaultFooVyxG0E0RtzrlE3fooAFyF"
 
 // <rdar://26873036> IRGen crash with derived class declaring same-type constraint on constrained associatedtype.
 public class C1<T: Equatable> { }
@@ -62,3 +69,40 @@
 
 // OSIZE: define internal swiftcc i8** @"$S21same_type_constraints12GenericKlazzCyxq_GAA1EAA4Data_AA0F4TypePWT"(%swift.type* %"GenericKlazz<T, R>.Data", %swift.type* nocapture readonly %"GenericKlazz<T, R>", i8** nocapture readnone %"GenericKlazz<T, R>.E") [[ATTRS:#[0-9]+]] {
 // OSIZE: [[ATTRS]] = {{{.*}}noinline
+
+// Check that same-typing two generic parameters together lowers correctly.
+
+protocol P1 {}
+protocol P2 {}
+protocol P3 {}
+struct ConformsToP1: P1 {}
+struct ConformsToP2: P2 {}
+struct ConformsToP3: P3 {}
+
+struct SG11<T: P1, U: P2> {}
+
+struct ConformsToP1AndP2 : P1, P2 { }
+
+extension SG11 where U == T {
+  struct InnerTEqualsU<V: P3> { }
+}
+
+extension SG11 where T == ConformsToP1 {
+  struct InnerTEqualsConformsToP1<V: P3> { }
+}
+
+extension SG11 where U == ConformsToP2 {
+  struct InnerUEqualsConformsToP2<V: P3> { }
+}
+
+func inner1() -> Any.Type {
+  return SG11<ConformsToP1AndP2, ConformsToP1AndP2>.InnerTEqualsU<ConformsToP3>.self
+}
+
+func inner2() -> Any.Type {
+  return SG11<ConformsToP1, ConformsToP2>.InnerTEqualsConformsToP1<ConformsToP3>.self
+}
+
+func inner3() -> Any.Type {
+  return SG11<ConformsToP1, ConformsToP2>.InnerTEqualsConformsToP1<ConformsToP3>.self
+}
diff --git a/test/Migrator/Inputs/Cities.swift b/test/Migrator/Inputs/Cities.swift
index b7ae3d2..7c6f5a1 100644
--- a/test/Migrator/Inputs/Cities.swift
+++ b/test/Migrator/Inputs/Cities.swift
@@ -36,8 +36,20 @@
 
 public class Container {
   public var Value: String = ""
+  public var attrDict: [String: Any] = [:]
+  public var attrArr: [String] = []
   public func addingAttributes(_ input: [String: Any]) {}
   public func adding(attributes: [String: Any]) {}
   public func adding(optionalAttributes: [String: Any]?) {}
   public init(optionalAttributes: [String: Any]?) {}
+  public func adding(attrArray: [String]) {}
+  public init(optionalAttrArray: [String]?) {}
+  public func add(single: String) {}
+  public func add(singleOptional: String?) {}
+  public func getAttrArray() -> [String] { return [] }
+  public func getOptionalAttrArray() -> [String]? { return [] }
+  public func getAttrDictionary() -> [String: Any] { return [:] }
+  public func getOptionalAttrDictionary() -> [String: Any]? { return nil }
+  public func getSingleAttr() -> String { return "" }
+  public func getOptionalSingleAttr() -> String? { return nil }
 }
diff --git a/test/Migrator/Inputs/string-representable.json b/test/Migrator/Inputs/string-representable.json
index 947a889..9c24902 100644
--- a/test/Migrator/Inputs/string-representable.json
+++ b/test/Migrator/Inputs/string-representable.json
@@ -54,4 +54,136 @@
     "RightComment": "SimpleAttribute",
     "ModuleName": "Cities"
   },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "ArrayMemberUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "s:6Cities9ContainerC6adding9attrArrayySaySSG_tF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "OptionalArrayMemberUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "s:6Cities9ContainerC17optionalAttrArrayACSaySSGSg_tcfc",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "SimpleStringRepresentableUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "s:6Cities9ContainerC3add6singleySS_tF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "SimpleOptionalStringRepresentableUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "s:6Cities9ContainerC3add14singleOptionalySSSg_tF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "SimpleStringRepresentableUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC13getSingleAttrSSyF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "SimpleOptionalStringRepresentableUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC21getOptionalSingleAttrSSSgyF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "ArrayMemberUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC12getAttrArraySaySSGyF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "OptionalArrayMemberUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC20getOptionalAttrArraySaySSGSgyF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "OptionalDictionaryKeyUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC25getOptionalAttrDictionarys0F0VySSypGSgyF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "DictionaryKeyUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC17getAttrDictionarys0E0VySSypGyF",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Var",
+    "NodeAnnotation": "DictionaryKeyUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC8attrDicts10DictionaryVySSypGvp",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
+    {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Var",
+    "NodeAnnotation": "ArrayMemberUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "s:6Cities9ContainerC7attrArrSaySSGvp",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "SimpleAttribute",
+    "ModuleName": "Cities"
+  },
 ]
diff --git a/test/Migrator/string-representable.swift b/test/Migrator/string-representable.swift
index 20d5dee..94fe882 100644
--- a/test/Migrator/string-representable.swift
+++ b/test/Migrator/string-representable.swift
@@ -13,5 +13,21 @@
   c.adding(attributes: ["a": 1, "a": 2, "a": 3])
   c.adding(optionalAttributes: ["a": 1, "a": 2, "a": 3])
   _ = Container(optionalAttributes: nil)
+  _ = Container(optionalAttrArray: nil)
+  c.adding(attrArray: ["key1", "key2"])
+  c.add(single: "")
+  c.add(singleOptional: nil)
+  _ = c.getAttrDictionary()
+  _ = c.getOptionalAttrDictionary()
+  _ = c.getSingleAttr()
+  _ = c.getOptionalSingleAttr()
+  _ = c.getAttrArray()
+  _ = c.getOptionalAttrArray()
+
+  c.addingAttributes(c.getAttrDictionary())
+  c.adding(optionalAttributes: c.getAttrDictionary())
+
+  c.attrDict = ["a": "b", "a": "b", "a": "b"]
+  c.attrArr = ["key1", "key2"]
   return c.Value
 }
diff --git a/test/Migrator/string-representable.swift.expected b/test/Migrator/string-representable.swift.expected
index 0957441..7dee8cd 100644
--- a/test/Migrator/string-representable.swift.expected
+++ b/test/Migrator/string-representable.swift.expected
@@ -7,27 +7,103 @@
 import Cities
 
 func foo(_ c: Container) -> String {
-  c.Value = NewAttribute(rawValue: "")
-  c.addingAttributes(converToCitiesContainerAttributeDictionary(["a": "b", "a": "b", "a": "b"]))
-  c.addingAttributes(converToCitiesContainerAttributeDictionary(["a": "b", "a": "b", "a": "b"]))
-  c.adding(attributes: converToSimpleAttributeDictionary(["a": 1, "a": 2, "a": 3]))
-  c.adding(optionalAttributes: converToOptionalSimpleAttributeDictionary(["a": 1, "a": 2, "a": 3]))
-  _ = Container(optionalAttributes: converToOptionalSimpleAttributeDictionary(nil))
+  c.Value = convertToNewAttribute("")
+  c.addingAttributes(convertToCitiesContainerAttributeDictionary(["a": "b", "a": "b", "a": "b"]))
+  c.addingAttributes(convertToCitiesContainerAttributeDictionary(["a": "b", "a": "b", "a": "b"]))
+  c.adding(attributes: convertToSimpleAttributeDictionary(["a": 1, "a": 2, "a": 3]))
+  c.adding(optionalAttributes: convertToOptionalSimpleAttributeDictionary(["a": 1, "a": 2, "a": 3]))
+  _ = Container(optionalAttributes: convertToOptionalSimpleAttributeDictionary(nil))
+  _ = Container(optionalAttrArray: convertToOptionalSimpleAttributeArray(nil))
+  c.adding(attrArray: convertToSimpleAttributeArray(["key1", "key2"]))
+  c.add(single: convertToSimpleAttribute(""))
+  c.add(singleOptional: convertToOptionalSimpleAttribute(nil))
+  _ = convertFromSimpleAttributeDictionary(c.getAttrDictionary())
+  _ = convertFromOptionalSimpleAttributeDictionary(c.getOptionalAttrDictionary())
+  _ = convertFromSimpleAttribute(c.getSingleAttr())
+  _ = convertFromOptionalSimpleAttribute(c.getOptionalSingleAttr())
+  _ = convertFromSimpleAttributeArray(c.getAttrArray())
+  _ = convertFromOptionalSimpleAttributeArray(c.getOptionalAttrArray())
+
+  c.addingAttributes(convertToCitiesContainerAttributeDictionary(convertFromSimpleAttributeDictionary(c.getAttrDictionary())))
+  c.adding(optionalAttributes: convertToOptionalSimpleAttributeDictionary(convertFromSimpleAttributeDictionary(c.getAttrDictionary())))
+
+  c.attrDict = convertToSimpleAttributeDictionary(["a": "b", "a": "b", "a": "b"])
+  c.attrArr = convertToSimpleAttributeArray(["key1", "key2"])
   return c.Value.rawValue
 }
 
 // Helper function inserted by Swift 4.2 migrator.
-fileprivate func converToCitiesContainerAttributeDictionary(_ input: [String: Any]) -> [Cities.Container.Attribute: Any] {
+fileprivate func convertToNewAttribute(_ input: String) -> NewAttribute {
+	return NewAttribute(rawValue: input)
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertToCitiesContainerAttributeDictionary(_ input: [String: Any]) -> [Cities.Container.Attribute: Any] {
 	return Dictionary(uniqueKeysWithValues: input.map { key, value in (Cities.Container.Attribute(rawValue: key), value)})
 }
 
 // Helper function inserted by Swift 4.2 migrator.
-fileprivate func converToSimpleAttributeDictionary(_ input: [String: Any]) -> [SimpleAttribute: Any] {
+fileprivate func convertToSimpleAttributeDictionary(_ input: [String: Any]) -> [SimpleAttribute: Any] {
 	return Dictionary(uniqueKeysWithValues: input.map { key, value in (SimpleAttribute(rawValue: key), value)})
 }
 
 // Helper function inserted by Swift 4.2 migrator.
-fileprivate func converToOptionalSimpleAttributeDictionary(_ input: [String: Any]?) -> [SimpleAttribute: Any]? {
+fileprivate func convertToOptionalSimpleAttributeDictionary(_ input: [String: Any]?) -> [SimpleAttribute: Any]? {
 	guard let input = input else { return nil }
 	return Dictionary(uniqueKeysWithValues: input.map { key, value in (SimpleAttribute(rawValue: key), value)})
 }
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertToOptionalSimpleAttributeArray(_ input: [String]?) -> [SimpleAttribute]? {
+	guard let input = input else { return nil }
+	return input.map { key in SimpleAttribute(key) }
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertToSimpleAttributeArray(_ input: [String]) -> [SimpleAttribute] {
+	return input.map { key in SimpleAttribute(key) }
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertToSimpleAttribute(_ input: String) -> SimpleAttribute {
+	return SimpleAttribute(rawValue: input)
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertToOptionalSimpleAttribute(_ input: String?) -> SimpleAttribute? {
+	guard let input = input else { return nil }
+	return SimpleAttribute(rawValue: input)
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertFromSimpleAttributeDictionary(_ input: [SimpleAttribute: Any]) -> [String: Any] {
+	return Dictionary(uniqueKeysWithValues: input.map {key, value in (key.rawValue, value)})
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertFromOptionalSimpleAttributeDictionary(_ input: [SimpleAttribute: Any]?) -> [String: Any]? {
+	guard let input = input else { return nil }
+	return Dictionary(uniqueKeysWithValues: input.map {key, value in (key.rawValue, value)})
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertFromSimpleAttribute(_ input: SimpleAttribute) -> String {
+	return input.rawValue
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertFromOptionalSimpleAttribute(_ input: SimpleAttribute?) -> String? {
+	guard let input = input else { return nil }
+	return input.rawValue
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertFromSimpleAttributeArray(_ input: [SimpleAttribute]) -> [String] {
+	return input.map { key in key.rawValue }
+}
+
+// Helper function inserted by Swift 4.2 migrator.
+fileprivate func convertFromOptionalSimpleAttributeArray(_ input: [SimpleAttribute]?) -> [String]? {
+	guard let input = input else { return nil }
+	return input.map { key in key.rawValue }
+}
diff --git a/test/Parse/switch.swift b/test/Parse/switch.swift
index e3945f6..08368cd 100644
--- a/test/Parse/switch.swift
+++ b/test/Parse/switch.swift
@@ -427,12 +427,12 @@
   break
 }
 
-switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}}
+switch Whatever.Thing {
 @unknown case _, _: // expected-error {{'@unknown' cannot be applied to multiple patterns}}
   break
 }
 
-switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note{{add missing case: '.Thing'}}
+switch Whatever.Thing {
 @unknown case _, _, _: // expected-error {{'@unknown' cannot be applied to multiple patterns}}
   break
 }
@@ -522,3 +522,90 @@
 case _:
   break
 }
+
+switch x { // expected-error {{switch must be exhaustive}}
+case 1:
+  break
+@unknown case _: // expected-note {{remove '@unknown' to handle remaining values}} {{1-10=}}
+  break
+}
+
+switch x { // expected-error {{switch must be exhaustive}}
+@unknown case _: // expected-note {{remove '@unknown' to handle remaining values}} {{1-10=}}
+  break
+}
+
+switch x { // expected-error {{switch must be exhaustive}}
+@unknown default: // expected-note {{remove '@unknown' to handle remaining values}} {{1-10=}}
+  break
+}
+
+switch Whatever.Thing {
+case .Thing:
+  break
+@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}}
+  break
+@unknown case _:
+  break
+}
+
+switch Whatever.Thing {
+case .Thing:
+  break
+@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}}
+  break
+@unknown default:
+  break
+}
+
+switch Whatever.Thing {
+case .Thing:
+  break
+@unknown default:
+  break
+@unknown default: // expected-error {{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}}
+  break
+}
+
+switch Whatever.Thing {
+@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}}
+  break
+@unknown case _:
+  break
+}
+
+switch Whatever.Thing {
+@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}}
+  break
+@unknown default:
+  break
+}
+
+switch Whatever.Thing {
+@unknown default:
+  break
+@unknown default: // expected-error {{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}}
+  break
+}
+
+
+switch x {
+@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}}
+  break
+@unknown case _:
+  break
+}
+
+switch x {
+@unknown case _: // expected-error {{'@unknown' can only be applied to the last case in a switch}}
+  break
+@unknown default:
+  break
+}
+
+switch x {
+@unknown default:
+  break
+@unknown default: // expected-error {{additional 'case' blocks cannot appear after the 'default' block of a 'switch'}}
+  break
+}
diff --git a/test/Reflection/typeref_decoding_asan.swift b/test/Reflection/typeref_decoding_asan.swift
new file mode 100644
index 0000000..3532397
--- /dev/null
+++ b/test/Reflection/typeref_decoding_asan.swift
@@ -0,0 +1,732 @@
+// REQUIRES: asan_runtime
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift %S/Inputs/ConcreteTypes.swift %S/Inputs/GenericTypes.swift %S/Inputs/Protocols.swift %S/Inputs/Extensions.swift %S/Inputs/Closures.swift -parse-as-library -emit-module -emit-library -module-name TypesToReflect -sanitize=address -o %t/libTypesToReflect.%target-dylib-extension
+// RUN: %target-swift-reflection-dump -binary-filename %t/libTypesToReflect.%target-dylib-extension | %FileCheck %s
+
+// CHECK: FIELDS:
+// CHECK: =======
+// CHECK: TypesToReflect.Box
+// CHECK: ------------------
+// CHECK: item: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: TypesToReflect.C
+// CHECK: ----------------
+// CHECK: aClass: TypesToReflect.C
+// CHECK: (class TypesToReflect.C)
+
+// CHECK: aStruct: TypesToReflect.S
+// CHECK: (struct TypesToReflect.S)
+
+// CHECK: anEnum: TypesToReflect.E
+// CHECK: (enum TypesToReflect.E)
+
+// CHECK: aTuple: (TypesToReflect.C, TypesToReflect.S, TypesToReflect.E, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (class TypesToReflect.C)
+// CHECK:   (struct TypesToReflect.S)
+// CHECK:   (enum TypesToReflect.E)
+// CHECK:   (struct Swift.Int))
+
+// CHECK: aTupleWithLabels: (a: TypesToReflect.C, s: TypesToReflect.S, e: TypesToReflect.E)
+// CHECK: (tuple
+// CHECK:   (class TypesToReflect.C)
+// CHECK:   (struct TypesToReflect.S)
+// CHECK:   (enum TypesToReflect.E))
+
+// CHECK: aMetatype: TypesToReflect.C.Type
+// CHECK: (metatype
+// CHECK:   (class TypesToReflect.C))
+
+// CHECK: aFunction: (TypesToReflect.C, TypesToReflect.S, TypesToReflect.E, Swift.Int) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (class TypesToReflect.C)
+// CHECK:     (struct TypesToReflect.S)
+// CHECK:     (enum TypesToReflect.E)
+// CHECK:     (struct Swift.Int)
+// CHECK:   (result
+// CHECK:     (struct Swift.Int))
+
+// CHECK: aFunctionWithVarArgs: (TypesToReflect.C, TypesToReflect.S...) -> ()
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (class TypesToReflect.C)
+// CHECK:     (variadic
+// CHECK:       (struct TypesToReflect.S))
+// CHECK:   (result
+// CHECK:     (tuple))
+
+// CHECK: aFunctionWithInout1: (inout TypesToReflect.C) -> ()
+// CHECK: (function
+// CHECK:  (parameters
+// CHECK:    (inout
+// CHECK:      (class TypesToReflect.C))
+// CHECK:  (result
+// CHECK:    (tuple))
+
+// CHECK: aFunctionWithInout2: (TypesToReflect.C, inout Swift.Int) -> ()
+// CHECK: (function
+// CHECK:  (parameters
+// CHECK:    (class TypesToReflect.C)
+// CHECK:    (inout
+// CHECK:      (struct Swift.Int))
+// CHECK:  (result
+// CHECK:    (tuple))
+
+// CHECK: aFunctionWithInout3: (inout TypesToReflect.C, inout Swift.Int) -> ()
+// CHECK: (function
+// CHECK:  (parameters
+// CHECK:    (inout
+// CHECK:      (class TypesToReflect.C))
+// CHECK:    (inout
+// CHECK:      (struct Swift.Int))
+// CHECK:  (result
+// CHECK:    (tuple))
+
+// CHECK: aFunctionWithShared: (__shared TypesToReflect.C) -> ()
+// CHECK: (function
+// CHECK:  (parameters
+// CHECK:    (shared
+// CHECK:      (class TypesToReflect.C))
+// CHECK:  (result
+// CHECK:    (tuple))
+
+// CHECK: TypesToReflect.S.NestedS
+// CHECK: ------------------------
+// CHECK: aField: Swift.Int
+// CHECK: (struct Swift.Int)
+
+// CHECK: TypesToReflect.S
+// CHECK: ----------------
+// CHECK: aClass: TypesToReflect.C
+// CHECK: (class TypesToReflect.C)
+
+// CHECK: aStruct: TypesToReflect.Box<TypesToReflect.S>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (struct TypesToReflect.S))
+
+// CHECK: anEnum: TypesToReflect.Box<TypesToReflect.E>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (enum TypesToReflect.E))
+
+// CHECK: aTuple: (TypesToReflect.C, TypesToReflect.Box<TypesToReflect.S>, TypesToReflect.Box<TypesToReflect.E>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (class TypesToReflect.C)
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (struct TypesToReflect.S))
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (enum TypesToReflect.E))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: aMetatype: TypesToReflect.C.Type
+// CHECK: (metatype
+// CHECK:   (class TypesToReflect.C))
+
+// CHECK: aFunction: (TypesToReflect.C, TypesToReflect.S, TypesToReflect.E, Swift.Int) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (class TypesToReflect.C)
+// CHECK:     (struct TypesToReflect.S)
+// CHECK:     (enum TypesToReflect.E)
+// CHECK:     (struct Swift.Int)
+// CHECK:   (result
+// CHECK:     (struct Swift.Int))
+
+// CHECK: aFunctionWithThinRepresentation: @convention(thin) () -> ()
+// CHECK: (function convention=thin
+// CHECK:   (tuple))
+
+// CHECK: aFunctionWithCRepresentation: @convention(c) () -> ()
+// CHECK: (function convention=c
+// CHECK:   (tuple))
+
+// CHECK: TypesToReflect.E
+// CHECK: ----------------
+// CHECK: Class: TypesToReflect.C
+// CHECK: (class TypesToReflect.C)
+
+// CHECK: Struct: TypesToReflect.S
+// CHECK: (struct TypesToReflect.S)
+
+// CHECK: Enum: TypesToReflect.E
+// CHECK: (enum TypesToReflect.E)
+
+// CHECK: Function: (TypesToReflect.C, TypesToReflect.S, TypesToReflect.E, Swift.Int) -> ()
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (class TypesToReflect.C)
+// CHECK:     (struct TypesToReflect.S)
+// CHECK:     (enum TypesToReflect.E)
+// CHECK:     (struct Swift.Int)
+// CHECK:   (result
+// CHECK:     (tuple))
+
+// CHECK: Tuple: (TypesToReflect.C, TypesToReflect.S, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (class TypesToReflect.C)
+// CHECK:   (struct TypesToReflect.S)
+// CHECK:   (struct Swift.Int))
+
+// CHECK: IndirectTuple: (TypesToReflect.C, TypesToReflect.S, TypesToReflect.E, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (class TypesToReflect.C)
+// CHECK:   (struct TypesToReflect.S)
+// CHECK:   (enum TypesToReflect.E)
+// CHECK:   (struct Swift.Int))
+
+// CHECK: NestedStruct: TypesToReflect.S.NestedS
+// CHECK: (struct TypesToReflect.S.NestedS
+// CHECK:   (struct TypesToReflect.S))
+
+// CHECK: Metatype
+
+// CHECK: EmptyCase
+
+// CHECK: TypesToReflect.References
+// CHECK: -------------------------
+// CHECK: strongRef: TypesToReflect.C
+// CHECK: (class TypesToReflect.C)
+
+// CHECK: weakRef: weak Swift.Optional<TypesToReflect.C>
+// CHECK: (weak_storage
+// CHECK:   (bound_generic_enum Swift.Optional
+// CHECK:     (class TypesToReflect.C)))
+
+// CHECK: unownedRef: unowned TypesToReflect.C
+// CHECK: (unowned_storage
+// CHECK:   (class TypesToReflect.C))
+
+// CHECK: unownedUnsafeRef: unowned(unsafe) TypesToReflect.C
+// CHECK: (unmanaged_storage
+// CHECK:   (class TypesToReflect.C))
+
+// CHECK: TypesToReflect.C1
+// CHECK: -----------------
+// CHECK: aClass: TypesToReflect.C1<A>
+// CHECK: (bound_generic_class TypesToReflect.C1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: aStruct: TypesToReflect.S1<A>
+// CHECK: (bound_generic_struct TypesToReflect.S1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: anEnum: TypesToReflect.E1<A>
+// CHECK: (bound_generic_enum TypesToReflect.E1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: function: (TypesToReflect.C1<A>) -> (TypesToReflect.S1<A>) -> (TypesToReflect.E1<A>) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (bound_generic_class TypesToReflect.C1
+// CHECK:       (generic_type_parameter depth=0 index=0))
+// CHECK:   (result
+// CHECK:     (function
+// CHECK:       (parameters
+// CHECK:         (bound_generic_struct TypesToReflect.S1
+// CHECK:           (generic_type_parameter depth=0 index=0))
+// CHECK:       (result
+// CHECK:         (function
+// CHECK:           (parameters
+// CHECK:             (bound_generic_enum TypesToReflect.E1
+// CHECK:               (generic_type_parameter depth=0 index=0))
+// CHECK:           (result
+// CHECK:             (struct Swift.Int))))
+
+// CHECK: tuple: (TypesToReflect.C1<A>, TypesToReflect.S1<A>, TypesToReflect.E1<A>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C1
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_struct TypesToReflect.S1
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_enum TypesToReflect.E1
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: dependentMember: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: TypesToReflect.C2
+// CHECK: -----------------
+// CHECK: aClass: TypesToReflect.C1<A>
+// CHECK: (bound_generic_class TypesToReflect.C1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: aStruct: TypesToReflect.S1<A>
+// CHECK: (bound_generic_struct TypesToReflect.S1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: anEnum: TypesToReflect.E1<A>
+// CHECK: (bound_generic_enum TypesToReflect.E1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: function: (TypesToReflect.C1<A>) -> (TypesToReflect.S1<A>) -> (TypesToReflect.E1<A>) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (bound_generic_class TypesToReflect.C1
+// CHECK:       (generic_type_parameter depth=0 index=0))
+// CHECK:   (result
+// CHECK:     (function
+// CHECK:       (parameters
+// CHECK:         (bound_generic_struct TypesToReflect.S1
+// CHECK:           (generic_type_parameter depth=0 index=0))
+// CHECK:       (result
+// CHECK:         (function
+// CHECK:           (parameters
+// CHECK:             (bound_generic_enum TypesToReflect.E1
+// CHECK:               (generic_type_parameter depth=0 index=0))
+// CHECK:           (result
+// CHECK:             (struct Swift.Int))))
+
+// CHECK: tuple: (TypesToReflect.C2<A>, TypesToReflect.S2<A>, TypesToReflect.E2<A>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C2
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_struct TypesToReflect.S2
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_enum TypesToReflect.E2
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: primaryArchetype: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: dependentMember1: A.Inner
+// CHECK: (dependent_member protocol=14TypesToReflect2P1P
+// CHECK:   (generic_type_parameter depth=0 index=0) member=Inner)
+
+// CHECK: TypesToReflect.C3
+// CHECK: -----------------
+// CHECK: aClass: TypesToReflect.C3<A>
+// CHECK: (bound_generic_class TypesToReflect.C3
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: aStruct: TypesToReflect.S3<A>
+// CHECK: (bound_generic_struct TypesToReflect.S3
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: anEnum: TypesToReflect.E3<A>
+// CHECK: (bound_generic_enum TypesToReflect.E3
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: function: (TypesToReflect.C3<A>) -> (TypesToReflect.S3<A>) -> (TypesToReflect.E3<A>) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (bound_generic_class TypesToReflect.C3
+// CHECK:       (generic_type_parameter depth=0 index=0))
+// CHECK:   (result
+// CHECK:     (function
+// CHECK:       (parameters
+// CHECK:         (bound_generic_struct TypesToReflect.S3
+// CHECK:           (generic_type_parameter depth=0 index=0))
+// CHECK:       (result
+// CHECK:         (function
+// CHECK:           (parameters
+// CHECK:             (bound_generic_enum TypesToReflect.E3
+// CHECK:               (generic_type_parameter depth=0 index=0))
+// CHECK:           (result
+// CHECK:             (struct Swift.Int))))
+
+// CHECK: tuple: (TypesToReflect.C3<A>, TypesToReflect.S3<A>, TypesToReflect.E3<A>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C3
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_struct TypesToReflect.S3
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_enum TypesToReflect.E3
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: primaryArchetype: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: dependentMember1: A.Outer
+// CHECK: (dependent_member protocol=14TypesToReflect2P2P
+// CHECK:   (generic_type_parameter depth=0 index=0) member=Outer)
+
+// CHECK: dependentMember2: A.Outer.Inner
+// CHECK: (dependent_member protocol=14TypesToReflect2P1P
+// CHECK:   (dependent_member protocol=14TypesToReflect2P2P
+// CHECK:     (generic_type_parameter depth=0 index=0) member=Outer) member=Inner)
+
+// CHECK: TypesToReflect.C4
+// CHECK: -----------------
+// CHECK: TypesToReflect.S1
+// CHECK: -----------------
+// CHECK: aClass: TypesToReflect.C1<A>
+// CHECK: (bound_generic_class TypesToReflect.C1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: aStruct: TypesToReflect.Box<TypesToReflect.S1<A>>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (bound_generic_struct TypesToReflect.S1
+// CHECK:     (generic_type_parameter depth=0 index=0)))
+
+// CHECK: anEnum: TypesToReflect.Box<TypesToReflect.E1<A>>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (bound_generic_enum TypesToReflect.E1
+// CHECK:     (generic_type_parameter depth=0 index=0)))
+
+// CHECK: function: (TypesToReflect.C1<A>) -> (TypesToReflect.S1<A>) -> (TypesToReflect.E1<A>) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (bound_generic_class TypesToReflect.C1
+// CHECK:       (generic_type_parameter depth=0 index=0))
+// CHECK:   (result
+// CHECK:     (function
+// CHECK:       (parameters
+// CHECK:         (bound_generic_struct TypesToReflect.S1
+// CHECK:           (generic_type_parameter depth=0 index=0))
+// CHECK:     (result
+// CHECK:       (function
+// CHECK:         (parameters
+// CHECK:           (bound_generic_enum TypesToReflect.E1
+// CHECK:             (generic_type_parameter depth=0 index=0))
+// CHECK:         (result
+// CHECK:           (struct Swift.Int))))
+
+// CHECK: tuple: (TypesToReflect.C1<A>, TypesToReflect.Box<TypesToReflect.S1<A>>, TypesToReflect.Box<TypesToReflect.E1<A>>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C1
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (bound_generic_struct TypesToReflect.S1
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (bound_generic_enum TypesToReflect.E1
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: primaryArchetype: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: TypesToReflect.S2
+// CHECK: -----------------
+// CHECK: aClass: TypesToReflect.C2<A>
+// CHECK: (bound_generic_class TypesToReflect.C2
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: aStruct: TypesToReflect.Box<TypesToReflect.S2<A>>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (bound_generic_struct TypesToReflect.S2
+// CHECK:     (generic_type_parameter depth=0 index=0)))
+
+// CHECK: anEnum: TypesToReflect.Box<TypesToReflect.E2<A>>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (bound_generic_enum TypesToReflect.E2
+// CHECK:     (generic_type_parameter depth=0 index=0)))
+
+// CHECK: function: (TypesToReflect.C2<A>) -> (TypesToReflect.S2<A>) -> (TypesToReflect.E2<A>) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (bound_generic_class TypesToReflect.C2
+// CHECK:       (generic_type_parameter depth=0 index=0))
+// CHECK:   (result
+// CHECK:     (function
+// CHECK:       (parameters
+// CHECK:         (bound_generic_struct TypesToReflect.S2
+// CHECK:           (generic_type_parameter depth=0 index=0))
+// CHECK:       (result
+// CHECK:         (function
+// CHECK:           (parameters
+// CHECK:             (bound_generic_enum TypesToReflect.E2
+// CHECK:               (generic_type_parameter depth=0 index=0))
+// CHECK:           (result
+// CHECK:             (struct Swift.Int))))
+
+// CHECK: tuple: (TypesToReflect.C2<A>, TypesToReflect.Box<TypesToReflect.S2<A>>, TypesToReflect.Box<TypesToReflect.E2<A>>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C2
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (bound_generic_struct TypesToReflect.S2
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (bound_generic_enum TypesToReflect.E2
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: primaryArchetype: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: dependentMember1: A.Inner
+// CHECK: (dependent_member protocol=14TypesToReflect2P1P
+// CHECK:   (generic_type_parameter depth=0 index=0) member=Inner)
+
+// CHECK: TypesToReflect.S3
+// CHECK: -----------------
+// CHECK: aClass: TypesToReflect.C3<A>
+// CHECK: (bound_generic_class TypesToReflect.C3
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: aStruct: TypesToReflect.Box<TypesToReflect.S3<A>>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (bound_generic_struct TypesToReflect.S3
+// CHECK:     (generic_type_parameter depth=0 index=0)))
+
+// CHECK: anEnum: TypesToReflect.Box<TypesToReflect.E3<A>>
+// CHECK: (bound_generic_class TypesToReflect.Box
+// CHECK:   (bound_generic_enum TypesToReflect.E3
+// CHECK:     (generic_type_parameter depth=0 index=0)))
+
+// CHECK: function: (TypesToReflect.C3<A>) -> (TypesToReflect.S3<A>) -> (TypesToReflect.E3<A>) -> Swift.Int
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (bound_generic_class TypesToReflect.C3
+// CHECK:       (generic_type_parameter depth=0 index=0))
+// CHECK:   (result
+// CHECK:     (function
+// CHECK:       (parameters
+// CHECK:         (bound_generic_struct TypesToReflect.S3
+// CHECK:           (generic_type_parameter depth=0 index=0))
+// CHECK:       (result
+// CHECK:         (function
+// CHECK:           (parameters
+// CHECK:             (bound_generic_enum TypesToReflect.E3
+// CHECK:               (generic_type_parameter depth=0 index=0))
+// CHECK:           (result
+// CHECK:             (struct Swift.Int))))
+
+// CHECK: tuple: (TypesToReflect.C3<A>, TypesToReflect.Box<TypesToReflect.S3<A>>, TypesToReflect.Box<TypesToReflect.E3<A>>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C3
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (bound_generic_struct TypesToReflect.S3
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+// CHECK:   (bound_generic_class TypesToReflect.Box
+// CHECK:     (bound_generic_enum TypesToReflect.E3
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: primaryArchetype: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: dependentMember1: A.Outer
+// CHECK: (dependent_member protocol=14TypesToReflect2P2P
+// CHECK:   (generic_type_parameter depth=0 index=0) member=Outer)
+
+// CHECK: dependentMember2: A.Outer.Inner
+// CHECK: (dependent_member protocol=14TypesToReflect2P1P
+// CHECK:   (dependent_member protocol=14TypesToReflect2P2P
+// CHECK:     (generic_type_parameter depth=0 index=0) member=Outer) member=Inner)
+
+// CHECK: TypesToReflect.S4
+// CHECK: -----------------
+// CHECK: TypesToReflect.E1
+// CHECK: -----------------
+// CHECK: Class: TypesToReflect.C1<A>
+// CHECK: (bound_generic_class TypesToReflect.C1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Struct: TypesToReflect.S1<A>
+// CHECK: (bound_generic_struct TypesToReflect.S1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Enum: TypesToReflect.E1<A>
+// CHECK: (bound_generic_enum TypesToReflect.E1
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Int: Swift.Int
+// CHECK: (struct Swift.Int)
+
+// CHECK: Function: (A) -> TypesToReflect.E1<A>
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (generic_type_parameter depth=0 index=0)
+// CHECK:   (result
+// CHECK:     (bound_generic_enum TypesToReflect.E1
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+
+// CHECK: Tuple: (TypesToReflect.C1<A>, TypesToReflect.S1<A>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C1
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_struct TypesToReflect.S1
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: Primary: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: Metatype: A.Type
+// CHECK: (metatype
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: TypesToReflect.E2
+// CHECK: -----------------
+// CHECK: Class: TypesToReflect.C2<A>
+// CHECK: (bound_generic_class TypesToReflect.C2
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Struct: TypesToReflect.S2<A>
+// CHECK: (bound_generic_struct TypesToReflect.S2
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Enum: TypesToReflect.E2<A>
+// CHECK: (bound_generic_enum TypesToReflect.E2
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Function: (A.Type) -> TypesToReflect.E1<A>
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (metatype
+// CHECK:       (generic_type_parameter depth=0 index=0))
+// CHECK:   (result
+// CHECK:     (bound_generic_enum TypesToReflect.E1
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+
+// CHECK: Tuple: (TypesToReflect.C2<A>, TypesToReflect.S2<A>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C2
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_struct TypesToReflect.S2
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: Primary: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: DependentMemberInner: A.Inner
+// CHECK: (dependent_member protocol=14TypesToReflect2P1P
+// CHECK:   (generic_type_parameter depth=0 index=0) member=Inner)
+
+// CHECK: ExistentialMetatype: A.Type
+// CHECK: (metatype
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: TypesToReflect.E3
+// CHECK: -----------------
+// CHECK: Class: TypesToReflect.C3<A>
+// CHECK: (bound_generic_class TypesToReflect.C3
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Struct: TypesToReflect.S3<A>
+// CHECK: (bound_generic_struct TypesToReflect.S3
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Enum: TypesToReflect.E3<A>
+// CHECK: (bound_generic_enum TypesToReflect.E3
+// CHECK:   (generic_type_parameter depth=0 index=0))
+
+// CHECK: Function: (A.Type.Type) -> TypesToReflect.E1<A>
+// CHECK: (function
+// CHECK:   (parameters
+// CHECK:     (metatype
+// CHECK:       (metatype
+// CHECK:         (generic_type_parameter depth=0 index=0)))
+// CHECK:   (result
+// CHECK:     (bound_generic_enum TypesToReflect.E1
+// CHECK:       (generic_type_parameter depth=0 index=0)))
+
+// CHECK: Tuple: (TypesToReflect.C3<A>, TypesToReflect.S3<A>, Swift.Int)
+// CHECK: (tuple
+// CHECK:   (bound_generic_class TypesToReflect.C3
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (bound_generic_struct TypesToReflect.S3
+// CHECK:     (generic_type_parameter depth=0 index=0))
+// CHECK:   (struct Swift.Int))
+
+// CHECK: Primary: A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: DependentMemberOuter: A.Outer
+// CHECK: (dependent_member protocol=14TypesToReflect2P2P
+// CHECK:   (generic_type_parameter depth=0 index=0) member=Outer)
+
+// CHECK: DependentMemberInner: A.Outer.Inner
+// CHECK: (dependent_member protocol=14TypesToReflect2P1P
+// CHECK:   (dependent_member protocol=14TypesToReflect2P2P
+// CHECK:     (generic_type_parameter depth=0 index=0) member=Outer) member=Inner)
+
+// CHECK: TypesToReflect.E4
+// CHECK: -----------------
+// CHECK: TypesToReflect.P1
+// CHECK: -----------------
+// CHECK: TypesToReflect.P2
+// CHECK: -----------------
+// CHECK: TypesToReflect.P3
+// CHECK: -----------------
+// CHECK: TypesToReflect.P4
+// CHECK: -----------------
+// CHECK: TypesToReflect.ClassBoundP
+// CHECK: --------------------------
+
+// CHECK: TypesToReflect.(FileprivateProtocol in _{{[0-9A-F]+}})
+// CHECK: -------------------------------------------------------------------------
+
+// CHECK: TypesToReflect.HasFileprivateProtocol
+// CHECK: -------------------------------------
+// CHECK: x: TypesToReflect.(FileprivateProtocol in _{{[0-9A-F]+}})
+// CHECK: (protocol_composition
+// CHECK-NEXT: (protocol TypesToReflect.(FileprivateProtocol in _{{[0-9A-F]+}})))
+
+// CHECK: ASSOCIATED TYPES:
+// CHECK: =================
+// CHECK: - TypesToReflect.C1 : TypesToReflect.ClassBoundP
+// CHECK: typealias Inner = A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: - TypesToReflect.C4 : TypesToReflect.P1
+// CHECK: typealias Inner = A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: - TypesToReflect.C4 : TypesToReflect.P2
+// CHECK: typealias Outer = A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: - TypesToReflect.S4 : TypesToReflect.P1
+// CHECK: typealias Inner = A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: - TypesToReflect.S4 : TypesToReflect.P2
+// CHECK: typealias Outer = A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: - TypesToReflect.E4 : TypesToReflect.P1
+// CHECK: typealias Inner = A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: - TypesToReflect.E4 : TypesToReflect.P2
+// CHECK: typealias Outer = B
+// CHECK: (generic_type_parameter depth=0 index=1)
+
+// CHECK: - TypesToReflect.E4 : TypesToReflect.P3
+// CHECK: typealias First = A
+// CHECK: (generic_type_parameter depth=0 index=0)
+
+// CHECK: typealias Second = B
+// CHECK: (generic_type_parameter depth=0 index=1)
+
+// CHECK: - TypesToReflect.S : TypesToReflect.P4
+// CHECK: typealias Result = Swift.Int
+// CHECK: (struct Swift.Int)
+
+// CHECK: BUILTIN TYPES:
+// CHECK: ==============
+
+// CHECK: CAPTURE DESCRIPTORS:
+// CHECK: ====================
+// CHECK: - Capture types:
+// CHECK: (sil_box
+// CHECK:   (generic_type_parameter depth=0 index=0))
+// CHECK: - Metadata sources:
+// CHECK: (generic_type_parameter depth=0 index=0)
+// CHECK: (closure_binding index=0)
+// CHECK: (generic_type_parameter depth=0 index=1)
+// CHECK: (closure_binding index=1)
+
+// CHECK: - Capture types:
+// CHECK: (struct Swift.Int)
+// CHECK: - Metadata sources:
+
+// CHECK: - Capture types:
+// CHECK: (bound_generic_class TypesToReflect.C1
+// CHECK:   (generic_type_parameter depth=0 index=1))
+// CHECK: - Metadata sources:
+// CHECK: (generic_type_parameter depth=0 index=0)
+// CHECK: (closure_binding index=0)
+// CHECK: (generic_type_parameter depth=0 index=1)
+// CHECK: (generic_argument index=0
+// CHECK:   (reference_capture index=0))
+
diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil
index 4e0631c..5b3a646 100644
--- a/test/SIL/Parser/basic.sil
+++ b/test/SIL/Parser/basic.sil
@@ -1343,10 +1343,16 @@
 }
 // CHECK-LABEL: sil @convert_function_trivial
 // CHECK:  %1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
+// CHECK:  %2 = convert_escape_to_noescape [not_guaranteed] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
+// CHECK:  %3 = convert_escape_to_noescape [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
+// CHECK:  %4 = convert_escape_to_noescape [not_guaranteed] [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
 // CHECK: return
 sil @convert_function_trivial : $@convention(thin) (@owned @callee_guaranteed (AnyObject) -> Optional<AnyObject>) -> () {
 entry(%0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject>):
   %1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
+  %2 = convert_escape_to_noescape [not_guaranteed] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
+  %3 = convert_escape_to_noescape [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
+  %4 = convert_escape_to_noescape [not_guaranteed] [escaped] %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
   return undef : $()
 }
 
diff --git a/test/SIL/Serialization/Inputs/def_public_non_abi.sil b/test/SIL/Serialization/Inputs/def_public_non_abi.sil
index 4010b44..927ccef 100644
--- a/test/SIL/Serialization/Inputs/def_public_non_abi.sil
+++ b/test/SIL/Serialization/Inputs/def_public_non_abi.sil
@@ -1,4 +1,10 @@
+sil non_abi [serialized] @other_public_non_abi_function : $@convention(thin) () -> () {
+  %0 = tuple ()
+  return %0 : $()
+}
+
 sil non_abi [serialized] @public_non_abi_function : $@convention(thin) () -> () {
+  %fn = function_ref @other_public_non_abi_function : $@convention(thin) () -> ()
   %0 = tuple ()
   return %0 : $()
 }
\ No newline at end of file
diff --git a/test/SIL/Serialization/deserialize_generic.sil b/test/SIL/Serialization/deserialize_generic.sil
index d4873c2..6e1c1b9 100644
--- a/test/SIL/Serialization/deserialize_generic.sil
+++ b/test/SIL/Serialization/deserialize_generic.sil
@@ -1,7 +1,7 @@
 
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_generic.swift
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -linker -I %t %s | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -performance-linker -I %t %s | %FileCheck %s
 
 // Make sure that SILFunctionType with GenericSignature can match up with
 // SILFunctionType deserialized from module.
diff --git a/test/SIL/Serialization/deserialize_generic_marker.sil b/test/SIL/Serialization/deserialize_generic_marker.sil
index 2cb3109..766b322 100644
--- a/test/SIL/Serialization/deserialize_generic_marker.sil
+++ b/test/SIL/Serialization/deserialize_generic_marker.sil
@@ -1,7 +1,7 @@
 
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_generic_marker.swift
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -linker -I %t %s | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -performance-linker -I %t %s | %FileCheck %s
 
 // Make sure that SILFunctionType with GenericSignature can match up with
 // SILFunctionType deserialized from module.
diff --git a/test/SIL/Serialization/function_param_convention.sil b/test/SIL/Serialization/function_param_convention.sil
index 80fe6ef..9503baa 100644
--- a/test/SIL/Serialization/function_param_convention.sil
+++ b/test/SIL/Serialization/function_param_convention.sil
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -parse-sil -sil-inline-threshold 0 %S/Inputs/function_param_convention_input.sil -o %t/FunctionInput.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-name FunctionInput -O
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -I %t -linker %s -o - | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -I %t -performance-linker %s -o - | %FileCheck %s
 
 import Swift
 import FunctionInput
diff --git a/test/SIL/Serialization/public_non_abi.sil b/test/SIL/Serialization/public_non_abi.sil
index 68ef9d8..32f14a9 100644
--- a/test/SIL/Serialization/public_non_abi.sil
+++ b/test/SIL/Serialization/public_non_abi.sil
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_public_non_abi.sil
-// RUN: %target-sil-opt -linker -I %t %s | %FileCheck %s
+// RUN: %target-swift-frontend -emit-sil -I %t %s | %FileCheck %s
 
 sil_stage raw
 
@@ -20,6 +20,11 @@
 }
 
 // Make sure the function body is deserialized.
-// CHECK-LABEL: sil shared_external [serialized] [canonical] @public_non_abi_function : $@convention(thin) () -> ()
+// CHECK-LABEL: sil shared_external [serialized] @public_non_abi_function : $@convention(thin) () -> ()
+// CHECK: function_ref @other_public_non_abi_function
 // CHECK: return
 sil hidden_external [serialized] @public_non_abi_function : $@convention(thin) () -> ()
+
+// Make sure the function body is deserialized.
+// CHECK-LABEL: sil shared_external [serialized] @other_public_non_abi_function : $@convention(thin) () -> ()
+// CHECK: return
\ No newline at end of file
diff --git a/test/SIL/Serialization/shared_function_serialization.sil b/test/SIL/Serialization/shared_function_serialization.sil
index c784fb7..afcf991 100644
--- a/test/SIL/Serialization/shared_function_serialization.sil
+++ b/test/SIL/Serialization/shared_function_serialization.sil
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend %S/Inputs/shared_function_serialization_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift -O
-// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -I %t -linker -inline %s -o - | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -I %t -performance-linker -inline %s -o - | %FileCheck %s
 
 // CHECK: sil private @top_level_code
 // CHECK: sil public_external [serialized] @$Ss1XVABycfC{{.*}}
diff --git a/test/SIL/Serialization/vtable_deserialization.swift b/test/SIL/Serialization/vtable_deserialization.swift
index fb2862e..8efc0eb 100644
--- a/test/SIL/Serialization/vtable_deserialization.swift
+++ b/test/SIL/Serialization/vtable_deserialization.swift
@@ -11,13 +11,10 @@
 Class.firstMethod()
 
 
-// For now, we also deserialize the body of firstMethod(), even though it
-// is not transparent.
-// CHECK-LABEL: sil public_external [serialized] @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
-// OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
+// The methods should not be deserialized in the mandatory pipeline.
 
-// The other two methods should not be deserialized in the mandatory
-// pipeline.
+// CHECK-LABEL: sil [serialized] @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ : $@convention(method) (@thick Class.Type) -> (){{$}}
+// OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
 
 // CHECK-LABEL: sil [serialized] @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ : $@convention(method) (@thick Class.Type) -> (){{$}}
 // OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
diff --git a/test/SILGen/auto_closures.swift b/test/SILGen/auto_closures.swift
index 5390dbe..3d69064 100644
--- a/test/SILGen/auto_closures.swift
+++ b/test/SILGen/auto_closures.swift
@@ -16,7 +16,7 @@
 func test_auto_closure_with_capture(_ x: Bool) -> Bool {
   // CHECK: [[CLOSURE:%.*]] = function_ref @$S13auto_closures05test_A21_closure_with_capture
   // CHECK: [[WITHCAPTURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]](
-  // CHECK: [[CVT:%.*]] = convert_escape_to_noescape [[WITHCAPTURE]]
+  // CHECK: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[WITHCAPTURE]]
   // CHECK: [[RET:%.*]] = apply {{%.*}}([[CVT]])
   // CHECK: return [[RET]]
   return call_auto_closure(x)
@@ -42,7 +42,7 @@
   // CHECK: [[AUTOCLOSURE_FUNC:%.*]] = function_ref @$S13auto_closures3SubC1xAA4BoolVvgAFyXKfu_ : $@convention(thin) (@guaranteed Sub) -> Bool
   // CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
   // CHECK: [[AUTOCLOSURE:%.*]] = partial_apply [callee_guaranteed] [[AUTOCLOSURE_FUNC]]([[SELF_COPY]])
-  // CHECK: [[CVT:%.*]] = convert_escape_to_noescape [[AUTOCLOSURE]]
+  // CHECK: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[AUTOCLOSURE]]
   // CHECK: [[AUTOCLOSURE_CONSUMER:%.*]] = function_ref @$S13auto_closures05call_A8_closureyAA4BoolVADyXKF : $@convention(thin)
   // CHECK: [[RET:%.*]] = apply [[AUTOCLOSURE_CONSUMER]]([[CVT]])
   // CHECK: return [[RET]] : $Bool
diff --git a/test/SILGen/builtins.swift b/test/SILGen/builtins.swift
index 3261aa3..588c682 100644
--- a/test/SILGen/builtins.swift
+++ b/test/SILGen/builtins.swift
@@ -369,6 +369,35 @@
   return Builtin.getTailAddr_Word(start, i, ty1, ty2)
 }
 
+// CHECK-LABEL: sil hidden @$S8builtins25beginUnpairedModifyAccess{{[_0-9a-zA-Z]*}}F
+// CHECK: [[P2A_ADDR:%.*]] = pointer_to_address %0
+// CHECK: [[P2A_SCRATCH:%.*]] = pointer_to_address %1
+// CHECK: begin_unpaired_access [modify] [dynamic] [[P2A_ADDR]] : $*T1, [[P2A_SCRATCH]] : $*Builtin.UnsafeValueBuffer
+// CHECK: [[RESULT:%.*]] = tuple ()
+// CHECK: [[RETURN:%.*]] = tuple ()
+// CHECK: return [[RETURN]] : $()
+// CHECK: } // end sil function '$S8builtins25beginUnpairedModifyAccess{{[_0-9a-zA-Z]*}}F'
+func beginUnpairedModifyAccess<T1>(address: Builtin.RawPointer, scratch: Builtin.RawPointer, ty1: T1.Type) {
+  Builtin.beginUnpairedModifyAccess(address, scratch, ty1);
+}
+
+// CHECK-LABEL: sil hidden @$S8builtins17endUnpairedAccess{{[_0-9a-zA-Z]*}}F : $@convention(thin) (Builtin.RawPointer) -> () {
+// CHECK: [[P2A_ADDR:%.*]] = pointer_to_address %0
+// CHECK: end_unpaired_access [dynamic] [[P2A_ADDR]]
+// CHECK: } // end sil function '$S8builtins17endUnpairedAccess{{[_0-9a-zA-Z]*}}F'
+func endUnpairedAccess(address: Builtin.RawPointer) {
+  Builtin.endUnpairedAccess(address)
+}
+
+// CHECK-LABEL: sil hidden @$S8builtins30performInstantaneousReadAccess{{[_0-9a-zA-Z]*}}F
+// CHECK: [[P2A_ADDR:%.*]] = pointer_to_address %0
+// CHECK: [[ACCESS:%.*]] = begin_access [read] [dynamic] [no_nested_conflict] [[P2A_ADDR]] : $*T1
+// CHECK-NEXT: end_access [[ACCESS]] : $*T1
+// CHECK: } // end sil function '$S8builtins30performInstantaneousReadAccess{{[_0-9a-zA-Z]*}}F'
+func performInstantaneousReadAccess<T1>(address: Builtin.RawPointer, scratch: Builtin.RawPointer, ty1: T1.Type) {
+  Builtin.performInstantaneousReadAccess(address, ty1);
+}
+
 // CHECK-LABEL: sil hidden @$S8builtins8condfail{{[_0-9a-zA-Z]*}}F
 func condfail(_ i: Builtin.Int1) {
   Builtin.condfail(i)
diff --git a/test/SILGen/closures.swift b/test/SILGen/closures.swift
index 1a38391..ca8fd5f 100644
--- a/test/SILGen/closures.swift
+++ b/test/SILGen/closures.swift
@@ -614,9 +614,9 @@
     // CHECK:   [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$S8closures8SuperSubC1fyyFyycfU_yyKXKfu_]] : $@convention(thin) (@guaranteed SuperSub) -> @error Error
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
     // CHECK:   [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[ARG_COPY]])
-    // CHECK:   [[CVT:%.*]] = convert_escape_to_noescape [[PA]]
+    // CHECK:   [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]]
     // CHECK:   [[REABSTRACT_PA:%.*]] = partial_apply [callee_guaranteed] {{.*}}([[CVT]])
-    // CHECK:   [[REABSTRACT_CVT:%.*]] = convert_escape_to_noescape [[REABSTRACT_PA]]
+    // CHECK:   [[REABSTRACT_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[REABSTRACT_PA]]
     // CHECK:   [[TRY_APPLY_AUTOCLOSURE:%.*]] = function_ref @$Ss2qqoiyxxSg_xyKXKtKlF : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @noescape @callee_guaranteed () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error)
     // CHECK:   try_apply [[TRY_APPLY_AUTOCLOSURE]]<()>({{.*}}, {{.*}}, [[REABSTRACT_CVT]]) : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @noescape @callee_guaranteed () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error), normal [[NORMAL_BB:bb1]], error [[ERROR_BB:bb2]]
     // CHECK: [[NORMAL_BB]]{{.*}}
@@ -646,9 +646,9 @@
     // CHECK:   [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$S8closures8SuperSubC1g.*]] : $@convention(thin) (@guaranteed SuperSub) -> @error Error
     // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
     // CHECK:   [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[ARG_COPY]])
-    // CHECK:   [[CVT:%.*]] = convert_escape_to_noescape [[PA]] : $@callee_guaranteed () -> @error Error to $@noescape @callee_guaranteed () -> @error Error
+    // CHECK:   [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed () -> @error Error to $@noescape @callee_guaranteed () -> @error Error
     // CHECK:   [[REABSTRACT_PA:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[CVT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> @error Error) -> (@out (), @error Error)
-    // CHECK:   [[REABSTRACT_CVT:%.*]] = convert_escape_to_noescape [[REABSTRACT_PA]]
+    // CHECK:   [[REABSTRACT_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[REABSTRACT_PA]]
     // CHECK:   [[TRY_APPLY_FUNC:%.*]] = function_ref @$Ss2qqoiyxxSg_xyKXKtKlF : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @noescape @callee_guaranteed () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error)
     // CHECK:   try_apply [[TRY_APPLY_FUNC]]<()>({{.*}}, {{.*}}, [[REABSTRACT_CVT]]) : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @noescape @callee_guaranteed () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error), normal [[NORMAL_BB:bb1]], error [[ERROR_BB:bb2]]
     // CHECK: [[NORMAL_BB]]{{.*}}
@@ -694,7 +694,7 @@
 // CHECK:         destroy_value [[SELF]]
 // -- closure takes unowned ownership
 // CHECK:         [[OUTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[UNOWNED_SELF2_COPY]])
-// CHECK:         [[OUTER_CONVERT:%.*]] = convert_escape_to_noescape [[OUTER_CLOSURE]]
+// CHECK:         [[OUTER_CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[OUTER_CLOSURE]]
 // -- call consumes closure
 // -- strong +1, unowned +1
 // CHECK:         [[INNER_CLOSURE:%.*]] = apply [[OUTER_CONVERT]]
diff --git a/test/SILGen/coverage_class.swift b/test/SILGen/coverage_class.swift
index d27df0a..97fee71 100644
--- a/test/SILGen/coverage_class.swift
+++ b/test/SILGen/coverage_class.swift
@@ -3,7 +3,8 @@
 class C {
   // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.C.foo
   func foo() {}
-  // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.C.__allocating_init
+  // CHECK: sil_coverage_map {{.*}}// __ntd_C_line:[[@LINE-3]]:1
+  // CHECK-NEXT: [[@LINE+1]]:10 -> [[@LINE+1]]:12
   init() {}
   // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.C.__deallocating_deinit
   deinit {}
@@ -17,7 +18,7 @@
 struct S {
   // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.S.foo
   func foo() {}
-  // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.S.init
+  // CHECK: sil_coverage_map {{.*}}// __ntd_S_line:[[@LINE-3]]:1
   init() {}
 }
 
@@ -25,6 +26,16 @@
   case X, Y, Z
   // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.E.foo
   func foo() {}
-  // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_class.E.init
+  // CHECK: sil_coverage_map {{.*}}// __ntd_E_line:[[@LINE-4]]:1
+  // CHECK-NEXT: [[@LINE+1]]:10 -> [[@LINE+1]]:23
   init() { self = .Y }
 }
+
+var g1: Bool = true
+
+struct S2 {
+  // CHECK: sil_coverage_map {{.*}}// __ntd_S2_line:[[@LINE-1]]:1
+  // CHECK-NEXT: [[@LINE+2]]:22 -> [[@LINE+2]]:23 : 0
+  // CHECK-NEXT: [[@LINE+1]]:26 -> [[@LINE+1]]:27 : (1 - 0)
+  var m1: Int = g1 ? 0 : 1
+}
diff --git a/test/SILGen/coverage_closures.swift b/test/SILGen/coverage_closures.swift
index 837e662..6fdf8d9 100644
--- a/test/SILGen/coverage_closures.swift
+++ b/test/SILGen/coverage_closures.swift
@@ -3,15 +3,10 @@
 // rdar://39200851: Closure in init method covered twice
 
 class C2 {
-// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_closures.C2.__allocating_init()
-// CHECK-NEXT:  [[@LINE+7]]:10 -> [[@LINE+11]]:4 : 0
-// CHECK-NEXT: }
-
-// CHECK-LABEL: sil_coverage_map {{.*}}// closure #1 () -> () in coverage_closures.C2.init()
-// CHECK-NEXT:  [[@LINE+4]]:13 -> [[@LINE+6]]:6 : 0
-// CHECK-NEXT: }
-
   init() {
+// CHECK-LABEL: sil_coverage_map {{.*}}// closure #1 () -> () in coverage_closures.C2.init()
+// CHECK-NEXT:  [[@LINE+2]]:13 -> [[@LINE+4]]:6 : 0
+// CHECK-NEXT: }
     let _ = { () in
       print("hello")
     }
diff --git a/test/SILGen/coverage_exceptions.swift b/test/SILGen/coverage_exceptions.swift
index e0c68fb..c434f82 100644
--- a/test/SILGen/coverage_exceptions.swift
+++ b/test/SILGen/coverage_exceptions.swift
@@ -5,17 +5,6 @@
   case Err2
 }
 
-struct S {
-  // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_catch.S.init
-  init() {
-    do {
-      throw SomeErr.Err1
-    } catch {
-      // CHECK: [[@LINE-1]]:13 -> [[@LINE+1]]:6 : 2
-    } // CHECK: [[@LINE]]:6 -> [[@LINE+1]]:4 : 1
-  }
-}
-
 // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_catch.bar
 func bar() throws {
   // CHECK-NEXT: [[@LINE-1]]:19 -> [[@LINE+2]]:2 : 0
@@ -62,3 +51,14 @@
 }
 
 foo()
+
+struct S {
+  // CHECK: sil_coverage_map {{.*}}// __ntd_S_line:[[@LINE-1]]
+  init() {
+    do {
+      throw SomeErr.Err1
+    } catch {
+      // CHECK: [[@LINE-1]]:13 -> [[@LINE+1]]:6 : 2
+    } // CHECK: [[@LINE]]:6 -> [[@LINE+1]]:4 : 1
+  }
+}
diff --git a/test/SILGen/coverage_member_closure.swift b/test/SILGen/coverage_member_closure.swift
index 21af473..4e2b022 100644
--- a/test/SILGen/coverage_member_closure.swift
+++ b/test/SILGen/coverage_member_closure.swift
@@ -1,13 +1,6 @@
 // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sil -module-name coverage_member_closure %s | %FileCheck %s
 
 class C {
-  // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_member_closure.C.__allocating_init
-  init() {
-    if (false) { // CHECK: [[@LINE]]:16 -> [[@LINE+2]]:6 : 1
-      // ...
-    }
-  }
-
   // Closures in members receive their own coverage mapping.
   // CHECK: sil_coverage_map {{.*}} $S23coverage_member_closure1CC17completionHandleryySS_SaySSGtcvpfiySS_AEtcfU_
   // CHECK: [[@LINE+1]]:55 -> [[@LINE+1]]:79 : 0
diff --git a/test/SILGen/coverage_smoke.swift b/test/SILGen/coverage_smoke.swift
index 1303d7a..31d4918 100644
--- a/test/SILGen/coverage_smoke.swift
+++ b/test/SILGen/coverage_smoke.swift
@@ -35,7 +35,7 @@
   deinit {}
 }
 
-// CHECK-MAIN: Maximum function count: 3
+// CHECK-MAIN: Maximum function count: 4
 func main() {
 // CHECK-COV: {{ *}}[[@LINE+1]]|{{ *}}1{{.*}}f_public
   f_public()
@@ -85,9 +85,69 @@
   let _ = use_auto_closure(true) // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}3
 }
 
+class Class2 {
+  var field: Int
+  init(field: Int) {
+    if field > 0 {
+      self.field = 0 // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+    } else {
+      self.field = 1 // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}3
+    }
+  }
+}
+
+extension Class2 {
+  convenience init() {
+    self.init(field: 0) // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+  }
+}
+
+class SubClass1: Class2 {
+  override init(field: Int) {
+    super.init(field: field) // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+  }
+}
+
+struct Struct1 {
+  var field: Int
+  init(field: Int) {
+    if field > 0 {
+      self.field = 0 // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+    } else {
+      self.field = 1 // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+    }
+  }
+}
+
+extension Struct1 {
+  init() {
+    self.init(field: 0) // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+  }
+}
+
+var g2: Int = 0
+
+class Class3 {
+  var m1 = g2 == 0
+             ? "false" // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+             : "true"; // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
+}
+
 main() // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
 foo()  // CHECK-COV: {{ *}}[[@LINE]]|{{ *}}1
 call_closure()
 call_auto_closure()
 
+let _ = Class2(field: 0)
+let _ = Class2(field: 1)
+let _ = Class2()
+let _ = SubClass1(field: 0)
+
+let _ = Class3()
+g2 = 1
+let _ = Class3()
+
+let _ = Struct1(field: 1)
+let _ = Struct1()
+
 // CHECK-REPORT: TOTAL {{.*}} 100.00% {{.*}} 100.00%
diff --git a/test/SILGen/coverage_ternary.swift b/test/SILGen/coverage_ternary.swift
index 6eb7b1d..a32b612 100644
--- a/test/SILGen/coverage_ternary.swift
+++ b/test/SILGen/coverage_ternary.swift
@@ -1,6 +1,6 @@
 // RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_ternary %s | %FileCheck %s
 
-// CHECK-LABEL: sil hidden @$S16coverage_ternary3barCACycfC
+// CHECK-LABEL: sil hidden @$S16coverage_ternary3barCACycfc
 // CHECK-NOT: return
 // CHECK: builtin "int_instrprof_increment"
 
@@ -8,13 +8,7 @@
 // CHECK-NOT: return
 // CHECK: builtin "int_instrprof_increment"
 
-// rdar://problem/23256795 - Avoid crash if an if_expr has no parent
-// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_ternary.bar.__allocating_init
-class bar {
-  var m1 = 0 == 1
-             ? "false" // CHECK: [[@LINE]]:16 -> [[@LINE]]:23 : 1
-             : "true"; // CHECK: [[@LINE]]:16 -> [[@LINE]]:22 : 0
-}
+var flag: Int = 0
 
 // CHECK-LABEL: sil_coverage_map {{.*}}// coverage_ternary.foo
 func foo(_ x : Int32) -> Int32 {
@@ -27,5 +21,13 @@
 foo(2)
 foo(3)
 
+// rdar://problem/23256795 - Avoid crash if an if_expr has no parent
+// CHECK: sil_coverage_map {{.*}}// __ntd_bar_line:[[@LINE+1]]
+class bar {
+  var m1 = flag == 0
+             ? "false" // CHECK: [[@LINE]]:16 -> [[@LINE]]:23 : 0
+             : "true"; // CHECK: [[@LINE]]:16 -> [[@LINE]]:22 : (1 - 0)
+}
+
 // Note: We didn't instantiate bar, but we still expect to see instrumentation
 // for its *structors, and coverage mapping information for it.
diff --git a/test/SILGen/coverage_toplevel.swift b/test/SILGen/coverage_toplevel.swift
index 8e7c26b..ca1bc48 100644
--- a/test/SILGen/coverage_toplevel.swift
+++ b/test/SILGen/coverage_toplevel.swift
@@ -17,7 +17,7 @@
 
 // CHECK: sil_coverage_map{{.*}}__tlcd_line:[[@LINE+3]]:1
 // CHECK-NEXT:  [[@LINE+2]]:17 -> [[@LINE+2]]:18 : 1
-// CHECK-NEXT:  [[@LINE+1]]:21 -> [[@LINE+1]]:22 : 0
+// CHECK-NEXT:  [[@LINE+1]]:21 -> [[@LINE+1]]:22 : (0 - 1)
 var i2 = true ? 1 : 0;
 
 // CHECK: sil_coverage_map{{.*}}__tlcd_line:[[@LINE+4]]:1
diff --git a/test/SILGen/default_arguments.swift b/test/SILGen/default_arguments.swift
index 044e6d4..c0996e8 100644
--- a/test/SILGen/default_arguments.swift
+++ b/test/SILGen/default_arguments.swift
@@ -227,11 +227,11 @@
 // CHECK-NEXT: function_ref reabstraction thunk helper from @escaping @callee_guaranteed (@in_guaranteed Swift.Int, @in_guaranteed Swift.Int) -> (@unowned Swift.Bool) to @escaping @callee_guaranteed (@unowned Swift.Int, @unowned Swift.Int) -> (@unowned Swift.Bool)
 // CHECK-NEXT: [[THUNK:%.*]] = function_ref @$SS2iSbIegnnd_S2iSbIegyyd_TR : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Int, @in_guaranteed Int) -> Bool) -> Bool
 // CHECK-NEXT: [[FN:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[RESULT]]) : $@convention(thin) (Int, Int, @guaranteed @callee_guaranteed (@in_guaranteed Int, @in_guaranteed Int) -> Bool) -> Bool
-// CHECK-NEXT: [[CONV_FN:%.*]] = convert_escape_to_noescape [[FN]]
+// CHECK-NEXT: [[CONV_FN:%.*]] = convert_escape_to_noescape [not_guaranteed] [[FN]]
 // function_ref reabstraction thunk helper from @callee_guaranteed (@unowned Swift.Int, @unowned Swift.Int) -> (@unowned Swift.Bool) to @callee_guaranteed (@in_guaranteed Swift.Int, @in_guaranteed Swift.Int) -> (@unowned Swift.Bool)
 // CHECK: [[THUNK:%.*]] = function_ref @$SS2iSbIgyyd_S2iSbIegnnd_TR : $@convention(thin) (@in_guaranteed Int, @in_guaranteed Int, @noescape @callee_guaranteed (Int, Int) -> Bool) -> Bool
 // CHECK-NEXT: [[FN:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[CONV_FN]]) : $@convention(thin) (@in_guaranteed Int, @in_guaranteed Int, @noescape @callee_guaranteed (Int, Int) -> Bool) -> Bool
-// CHECK-NEXT: [[CONV_FN:%.*]] = convert_escape_to_noescape [[FN]]
+// CHECK-NEXT: [[CONV_FN:%.*]] = convert_escape_to_noescape [not_guaranteed] [[FN]]
 // CHECK: [[INITFN:%[0-9]+]] = function_ref @$S17default_arguments25ReabstractDefaultArgumentC{{[_0-9a-zA-Z]*}}fC
 // CHECK-NEXT: apply [[INITFN]]<Int>([[CONV_FN]], 
 
@@ -320,25 +320,25 @@
 
 // CHECK:  [[F:%.*]] = function_ref @$S17default_arguments15throwingDefault7closureySbyKXE_tKFfA_ : $@convention(thin) () -> @owned @callee_guaranteed () -> (Bool, @error Error)
 // CHECK:  [[C:%.*]] = apply [[F]]() : $@convention(thin) () -> @owned @callee_guaranteed () -> (Bool, @error Error)
-// CHECK:  [[E:%.*]] = convert_escape_to_noescape [[C]]
+// CHECK:  [[E:%.*]] = convert_escape_to_noescape [not_guaranteed] [[C]]
 // CHECK:  [[R:%.*]] = function_ref @$S17default_arguments15throwingDefault7closureySbyKXE_tKF : $@convention(thin) (@noescape @callee_guaranteed () -> (Bool, @error Error)) -> @error Error
 // CHECK:  try_apply [[R]]([[E]])
 
 // CHECK:  [[F:%.*]] = function_ref @$S17default_arguments26throwingAutoclosureDefault7closureySbyKXK_tKFfA_ : $@convention(thin) () -> @owned @callee_guaranteed () -> (Bool, @error Error)
 // CHECK:  [[C:%.*]] = apply [[F]]() : $@convention(thin) () -> @owned @callee_guaranteed () -> (Bool, @error Error)
-// CHECK:  [[E:%.*]] = convert_escape_to_noescape [[C]]
+// CHECK:  [[E:%.*]] = convert_escape_to_noescape [not_guaranteed] [[C]]
 // CHECK:  [[R:%.*]] = function_ref @$S17default_arguments26throwingAutoclosureDefault7closureySbyKXK_tKF : $@convention(thin) (@noescape @callee_guaranteed () -> (Bool, @error Error)) -> @error Error
 // CHECK:  try_apply [[R]]([[E]])
 
 // CHECK:   [[F:%.*]] = function_ref @$S17default_arguments0A3Arg7closureySbyXE_tFfA_ : $@convention(thin) () -> @owned @callee_guaranteed () -> Bool
 // CHECK:   [[C:%.*]] = apply [[F]]() : $@convention(thin) () -> @owned @callee_guaranteed () -> Bool
-// CHECK:   [[E:%.*]] = convert_escape_to_noescape [[C]]
+// CHECK:   [[E:%.*]] = convert_escape_to_noescape [not_guaranteed] [[C]]
 // CHECK:   [[R:%.*]] = function_ref @$S17default_arguments0A3Arg7closureySbyXE_tF : $@convention(thin) (@noescape @callee_guaranteed () -> Bool) -> ()
 // CHECK:   apply [[R]]([[E]])
 
 // CHECK:  [[F:%.*]] = function_ref @$S17default_arguments21autoclosureDefaultArg7closureySbyXK_tFfA_ : $@convention(thin) () -> @owned @callee_guaranteed () -> Boo
 // CHECK:  [[C:%.*]] = apply [[F]]() : $@convention(thin) () -> @owned @callee_guaranteed () -> Bool
-// CHECK:  [[E:%.*]] = convert_escape_to_noescape [[C]]
+// CHECK:  [[E:%.*]] = convert_escape_to_noescape [not_guaranteed] [[C]]
 // CHECK:  [[R:%.*]] = function_ref @$S17default_arguments21autoclosureDefaultArg7closureySbyXK_tF : $@convention(thin) (@noescape @callee_guaranteed () -> Bool) -> ()
 // CHECK:  apply [[R]]([[E]])
 
diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift
index b0922a8..09af86f 100644
--- a/test/SILGen/function_conversion.swift
+++ b/test/SILGen/function_conversion.swift
@@ -628,16 +628,16 @@
 
   // CHECK: [[FN:%.*]] = function_ref @$SSays11AnyHashableVGSgIegg_Say19function_conversion1BCGSgIegg_TR : $@convention(thin) (@guaranteed Optional<Array<B>>, @guaranteed @callee_guaranteed (@guaranteed Optional<Array<AnyHashable>>) -> ()) -> ()
   // CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[FN]](%{{[0-9]+}}) : $@convention(thin) (@guaranteed Optional<Array<B>>, @guaranteed @callee_guaranteed (@guaranteed Optional<Array<AnyHashable>>) -> ()) -> ()
-  // CHECK: convert_escape_to_noescape [[PA]] : $@callee_guaranteed (@guaranteed Optional<Array<B>>) -> () to $@noescape @callee_guaranteed (@guaranteed Optional<Array<B>>) -> ()
+  // CHECK: convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed (@guaranteed Optional<Array<B>>) -> () to $@noescape @callee_guaranteed (@guaranteed Optional<Array<B>>) -> ()
   bar_arr(type: B.self, fn_arr)
 
   // CHECK: [[FN:%.*]] = function_ref @$Ss10DictionaryVys11AnyHashableVSiGIegg_ABy19function_conversion1BCSiGIegg_TR : $@convention(thin) (@guaranteed Dictionary<B, Int>, @guaranteed @callee_guaranteed (@guaranteed Dictionary<AnyHashable, Int>) -> ()) -> ()
   // CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[FN]](%{{[0-9]+}}) : $@convention(thin) (@guaranteed Dictionary<B, Int>, @guaranteed @callee_guaranteed (@guaranteed Dictionary<AnyHashable, Int>) -> ()) -> ()
-  // CHECK: convert_escape_to_noescape [[PA]] : $@callee_guaranteed (@guaranteed Dictionary<B, Int>) -> () to $@noescape @callee_guaranteed (@guaranteed Dictionary<B, Int>) -> ()
+  // CHECK: convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed (@guaranteed Dictionary<B, Int>) -> () to $@noescape @callee_guaranteed (@guaranteed Dictionary<B, Int>) -> ()
   bar_map(type: B.self, fn_map)
 
   // CHECK: [[FN:%.*]] = function_ref @$Ss3SetVys11AnyHashableVGIegg_ABy19function_conversion1BCGIegg_TR : $@convention(thin) (@guaranteed Set<B>, @guaranteed @callee_guaranteed (@guaranteed Set<AnyHashable>) -> ()) -> ()
   // CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[FN]](%{{[0-9]+}}) : $@convention(thin) (@guaranteed Set<B>, @guaranteed @callee_guaranteed (@guaranteed Set<AnyHashable>) -> ()) -> ()
-  // CHECK: convert_escape_to_noescape [[PA]] : $@callee_guaranteed (@guaranteed Set<B>) -> () to $@noescape @callee_guaranteed (@guaranteed Set<B>) -> ()
+  // CHECK: convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed (@guaranteed Set<B>) -> () to $@noescape @callee_guaranteed (@guaranteed Set<B>) -> ()
   bar_set(type: B.self, fn_set)
 }
diff --git a/test/SILGen/functions.swift b/test/SILGen/functions.swift
index f6333e1..c7b4892 100644
--- a/test/SILGen/functions.swift
+++ b/test/SILGen/functions.swift
@@ -348,7 +348,7 @@
 
   // CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @$S9functions19standalone_function{{[_0-9a-zA-Z]*}}F : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
   // CHECK: [[FUNC_THICK:%[0-9]+]] = thin_to_thick_function [[FUNC_THIN]]
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[FUNC_THICK]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[FUNC_THICK]]
   // CHECK: [[READI:%.*]] = begin_access [read] [unknown] [[IADDR]]
   // CHECK: [[I:%[0-9]+]] = load [trivial] [[READI]]
   // CHECK: [[READJ:%.*]] = begin_access [read] [unknown] [[JADDR]]
@@ -359,7 +359,7 @@
 
   // CHECK: [[FUNC_THIN:%[0-9]+]] = function_ref @$S9functions19standalone_function{{[_0-9a-zA-Z]*}}F : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> Builtin.Int64
   // CHECK: [[FUNC_THICK:%.*]] = thin_to_thick_function [[FUNC_THIN]]
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[FUNC_THICK]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[FUNC_THICK]]
   // CHECK: [[READI:%.*]] = begin_access [read] [unknown] [[IADDR]]
   // CHECK: [[I:%[0-9]+]] = load [trivial] [[READI]]
   // CHECK: [[READJ:%.*]] = begin_access [read] [unknown] [[JADDR]]
diff --git a/test/SILGen/guaranteed_closure_context.swift b/test/SILGen/guaranteed_closure_context.swift
index 91306be..f5884a1 100644
--- a/test/SILGen/guaranteed_closure_context.swift
+++ b/test/SILGen/guaranteed_closure_context.swift
@@ -60,7 +60,7 @@
   // CHECK: [[IMMUTABLE_RETAINABLE_COPY:%.*]] = copy_value [[IMMUTABLE_RETAINABLE]]
   // CHECK: [[IMMUTABLE_AO_BOX:%.*]] = alloc_box ${ var P }
   // CHECK: [[CLOSURE:%.*]] = partial_apply {{.*}}([[MUTABLE_TRIVIAL_BOX_COPY]], [[MUTABLE_RETAINABLE_BOX_COPY]], [[MUTABLE_ADDRESS_ONLY_BOX_COPY]], [[IMMUTABLE_TRIVIAL]], [[IMMUTABLE_RETAINABLE_COPY]], [[IMMUTABLE_AO_BOX]])
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[CLOSURE]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CLOSURE]]
   // CHECK: apply {{.*}}[[CONVERT]]
 
   // CHECK-NOT: copy_value [[MUTABLE_TRIVIAL_BOX]]
diff --git a/test/SILGen/objc_blocks_bridging.swift b/test/SILGen/objc_blocks_bridging.swift
index c5d8d0a..7b1508a 100644
--- a/test/SILGen/objc_blocks_bridging.swift
+++ b/test/SILGen/objc_blocks_bridging.swift
@@ -15,7 +15,7 @@
   // CHECK:         [[SELF_COPY:%.*]] = copy_value [[SELF]]
   // CHECK:         [[THUNK:%.*]] = function_ref @$SS2iIyByd_S2iIegyd_TR
   // CHECK:         [[BRIDGED:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[ARG1_COPY]])
-  // CHECK:         [[CONVERT:%.*]] = convert_escape_to_noescape [[BRIDGED]]
+  // CHECK:         [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[BRIDGED]]
   // CHECK:         [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
   // CHECK:         [[NATIVE:%.*]] = function_ref @$S20objc_blocks_bridging3FooC3foo{{[_0-9a-zA-Z]*}}F : $@convention(method) (@noescape @callee_guaranteed (Int) -> Int, Int, @guaranteed Foo) -> Int
   // CHECK:         apply [[NATIVE]]([[CONVERT]], {{.*}}, [[BORROWED_SELF_COPY]])
@@ -32,7 +32,7 @@
   // CHECK:         [[SELF_COPY:%.*]] = copy_value [[SELF]]
   // CHECK:         [[THUNK:%.*]] = function_ref @$SSo8NSStringCABIyBya_S2SIeggo_TR
   // CHECK:         [[BRIDGED:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[BLOCK_COPY]])
-  // CHECK:         [[CONVERT:%.*]] = convert_escape_to_noescape [[BRIDGED]]
+  // CHECK:         [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[BRIDGED]]
   // CHECK:         [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
   // CHECK:         [[NATIVE:%.*]] = function_ref @$S20objc_blocks_bridging3FooC3bar{{[_0-9a-zA-Z]*}}F : $@convention(method) (@noescape @callee_guaranteed (@guaranteed String) -> @owned String, @guaranteed String, @guaranteed Foo) -> @owned String
   // CHECK:         apply [[NATIVE]]([[CONVERT]], {{%.*}}, [[BORROWED_SELF_COPY]])
@@ -56,7 +56,7 @@
   // CHECK:         [[SELF_COPY:%.*]] = copy_value [[SELF]]
   // CHECK:         [[THUNK:%.*]] = function_ref @$SSo8NSStringCSgACIyBya_SSSgADIeggo_TR
   // CHECK:         [[BRIDGED:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[BLOCK_COPY]])
-  // CHECK:         [[CONVERT:%.*]] = convert_escape_to_noescape [[BRIDGED]]
+  // CHECK:         [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[BRIDGED]]
   // CHECK:         [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
   // CHECK:         [[NATIVE:%.*]] = function_ref @$S20objc_blocks_bridging3FooC3bas{{[_0-9a-zA-Z]*}}F : $@convention(method) (@noescape @callee_guaranteed (@guaranteed Optional<String>) -> @owned Optional<String>, @guaranteed Optional<String>, @guaranteed Foo) -> @owned Optional<String>
   // CHECK:         apply [[NATIVE]]([[CONVERT]], {{%.*}}, [[BORROWED_SELF_COPY]])
@@ -112,7 +112,7 @@
 ) -> (Int, String, String?, String?) {
   // CHECK: bb0([[ARG0:%.*]] : @guaranteed $Foo, [[ARG1:%.*]] : @guaranteed $@callee_guaranteed (Int) -> Int, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed (@guaranteed String) -> @owned String, [[ARG3:%.*]] : @guaranteed $@callee_guaranteed (@guaranteed Optional<String>) -> @owned Optional<String>):
   // CHECK: [[CLOSURE_COPY:%.*]] = copy_value [[ARG1]]
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[CLOSURE_COPY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CLOSURE_COPY]]
   // CHECK: [[F_BLOCK_STORAGE:%.*]] = alloc_stack $@block_storage
   // CHECK: [[F_BLOCK_CAPTURE:%.*]] = project_block_storage [[F_BLOCK_STORAGE]]
   // CHECK: store [[CONVERT]] to [trivial] [[F_BLOCK_CAPTURE]]
@@ -147,7 +147,7 @@
 // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @$SS2iIgyd_SiIegyd_S2iIyByd_SiIeyByd_TR
 // CHECK:         [[BLOCK_COPY:%.*]] = copy_block [[ORIG_BLOCK:%.*]] :
 // CHECK:         [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BLOCK_COPY]])
-// CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[CLOSURE]]
+// CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[CLOSURE]]
 // CHECK:         [[RESULT:%.*]] = apply {{%.*}}([[CONVERT]])
 // CHECK:         return [[RESULT]]
 
diff --git a/test/SILGen/objc_bridging_any.swift b/test/SILGen/objc_bridging_any.swift
index bf79086..264ca2a 100644
--- a/test/SILGen/objc_bridging_any.swift
+++ b/test/SILGen/objc_bridging_any.swift
@@ -464,7 +464,7 @@
   // CHECK-NEXT:  [[SELF_COPY:%.*]] = copy_value [[SELF]]
   // CHECK:       [[THUNK_FN:%.*]] = function_ref @$SyXlIyBy_ypIegn_TR
   // CHECK-NEXT:  [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[BLOCK_COPY]])
-  // CHECK-NEXT:  [[THUNK_CVT:%.*]] = convert_escape_to_noescape [[THUNK]]
+  // CHECK-NEXT:  [[THUNK_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[THUNK]]
   // CHECK:       [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
   // CHECK-NEXT:  // function_ref
   // CHECK-NEXT:  [[METHOD:%.*]] = function_ref @$S17objc_bridging_any12SwiftIdLoverC017methodTakingBlockH3AnyyyyypXEF
@@ -543,7 +543,7 @@
   // CHECK-NEXT:  // function_ref
   // CHECK-NEXT:  [[THUNK_FN:%.*]] = function_ref @$SyXlIyBa_ypIegr_TR
   // CHECK-NEXT:  [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[BLOCK_COPY]])
-  // CHECK-NEXT:  [[THUNK_CVT:%.*]] = convert_escape_to_noescape [[THUNK]]
+  // CHECK-NEXT:  [[THUNK_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[THUNK]]
   // CHECK-NEXT:  [[BORROWED_ANY_COPY:%.*]] = begin_borrow [[ANY_COPY]]
   // CHECK-NEXT:  // function_ref
   // CHECK-NEXT:  [[METHOD:%.*]] = function_ref @$S17objc_bridging_any12SwiftIdLoverC29methodTakingBlockReturningAnyyyypyXEF
diff --git a/test/SILGen/partial_apply_super.swift b/test/SILGen/partial_apply_super.swift
index 42d2bd4..3c7b250 100644
--- a/test/SILGen/partial_apply_super.swift
+++ b/test/SILGen/partial_apply_super.swift
@@ -37,7 +37,7 @@
   // CHECK:   [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]]
   // CHECK:   [[SUPER_METHOD:%.*]] = function_ref @$S19partial_apply_super6ParentC6methodyyFTcTd : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> ()
   // CHECK:   [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]([[BORROWED_CASTED_SELF_COPY]]) : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> ()
-  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:   [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:   apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super5ChildC6methodyyF'
@@ -49,7 +49,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick Child.Type to $@thick Parent.Type
   // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$S19partial_apply_super6ParentC11classMethodyyFZTcTd : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> ()
   // CHECK: [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> ()
-  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super5ChildC11classMethodyyFZ'
@@ -64,7 +64,7 @@
   // CHECK:     [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]]
   // CHECK:     [[SUPER_METHOD:%.*]] = function_ref @$S19partial_apply_super6ParentC11finalMethodyyFTc : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> ()
   // CHECK:     [[APPLIED_SELF:%.*]] = apply [[SUPER_METHOD]]([[BORROWED_CASTED_SELF_COPY]]) : $@convention(thin) (@guaranteed Parent) -> @owned @callee_guaranteed () -> ()
-  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [[APPLIED_SELF]]
+  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[APPLIED_SELF]]
   // CHECK:     [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:     apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super5ChildC20callFinalSuperMethodyyF'
@@ -77,7 +77,7 @@
   // CHECK:   [[CASTED_SELF:%.*]] = upcast [[ARG]] : $@thick Child.Type to $@thick Parent.Type
   // CHECK:   [[SUPER_METHOD:%.*]] = function_ref @$S19partial_apply_super6ParentC16finalClassMethodyyFZTc : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> ()
   // CHECK:   [[APPLIED_SELF:%.*]] = apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> @owned @callee_guaranteed () -> ()
-  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [[APPLIED_SELF]]
+  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[APPLIED_SELF]]
   // CHECK:   [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:   apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super5ChildC25callFinalSuperClassMethodyyFZ'
@@ -97,7 +97,7 @@
   // CHECK:     [[BORROWED_CASTED_SELF_COPY:%.*]] = begin_borrow [[CASTED_SELF_COPY]]
   // CHECK:     [[SUPER_METHOD:%.*]] = function_ref @$S19partial_apply_super13GenericParentC6methodyyFTcTd : $@convention(thin) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> @owned @callee_guaranteed () -> ()
   // CHECK:     [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]<A>([[BORROWED_CASTED_SELF_COPY]]) : $@convention(thin) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> @owned @callee_guaranteed () -> ()
-  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:     [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:     apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super12GenericChildC6methodyyF'
@@ -109,7 +109,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GenericChild<A>.Type to $@thick GenericParent<A>.Type
   // CHECK: [[SUPER_METHOD:%.*]] = function_ref @$S19partial_apply_super13GenericParentC11classMethodyyFZTcTd : $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> @owned @callee_guaranteed () -> ()
   // CHECK: [[PARTIAL_APPLY:%.*]] = apply [[SUPER_METHOD]]<A>([[CASTED_SELF]]) : $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> @owned @callee_guaranteed () -> ()
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super12GenericChildC11classMethodyyFZ'
@@ -133,7 +133,7 @@
   // turn on +0.
   // CHECK:   [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $OutsideParent, #OutsideParent.method!1 : (OutsideParent) -> () -> (), $@convention(method) (@guaranteed OutsideParent) -> ()
   // CHECK:   [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed OutsideParent) -> ()
-  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:   [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:   apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super25ChildToFixedOutsideParentC6methodyyF'
@@ -145,7 +145,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick ChildToFixedOutsideParent.Type to $@thick OutsideParent.Type
   // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick ChildToFixedOutsideParent.Type, #OutsideParent.classMethod!1 : (OutsideParent.Type) -> () -> (), $@convention(method) (@thick OutsideParent.Type) -> (){{.*}}
   // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick OutsideParent.Type) -> ()
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super25ChildToFixedOutsideParentC11classMethodyyFZ'
@@ -166,7 +166,7 @@
   // CHECK:   [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $ResilientOutsideParent, #ResilientOutsideParent.method!1 : (ResilientOutsideParent) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
   // CHECK:   end_borrow [[BORROWED_CASTED_SELF_COPY]] from [[CASTED_SELF_COPY]]
   // CHECK:   [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed ResilientOutsideParent) -> ()
-  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:   [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:   [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:   apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super29ChildToResilientOutsideParentC6methodyyF'
@@ -178,7 +178,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick ChildToResilientOutsideParent.Type to $@thick ResilientOutsideParent.Type
   // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick ChildToResilientOutsideParent.Type, #ResilientOutsideParent.classMethod!1 : (ResilientOutsideParent.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
   // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick ResilientOutsideParent.Type) -> ()
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super29ChildToResilientOutsideParentC11classMethodyyFZ'
@@ -199,7 +199,7 @@
   // CHECK:     [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $OutsideChild, #OutsideChild.method!1 : (OutsideChild) -> () -> (), $@convention(method) (@guaranteed OutsideChild) -> ()
   // CHECK:     end_borrow [[BORROWED_CASTED_SELF_COPY]] from [[CASTED_SELF_COPY]]
   // CHECK:     [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed OutsideChild) -> ()
-  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:     [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:     apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super29GrandchildToFixedOutsideChildC6methodyyF'
@@ -211,7 +211,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GrandchildToFixedOutsideChild.Type to $@thick OutsideChild.Type
   // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GrandchildToFixedOutsideChild.Type, #OutsideChild.classMethod!1 : (OutsideChild.Type) -> () -> (), $@convention(method) (@thick OutsideChild.Type) -> ()
   // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick OutsideChild.Type) -> ()
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super29GrandchildToFixedOutsideChildC11classMethodyyFZ'
@@ -232,7 +232,7 @@
   // CHECK:     [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $ResilientOutsideChild, #ResilientOutsideChild.method!1 : (ResilientOutsideChild) -> () -> (), $@convention(method) (@guaranteed ResilientOutsideChild) -> ()
   // CHEC:      end_borrow [[BORROWED_CASTED_SELF_COPY]] from [[CASTED_SELF_COPY]]
   // CHECK:     [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF_COPY]]) : $@convention(method) (@guaranteed ResilientOutsideChild) -> ()
-  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:     [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:     apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super33GrandchildToResilientOutsideChildC6methodyyF'
@@ -244,7 +244,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GrandchildToResilientOutsideChild.Type to $@thick ResilientOutsideChild.Type
   // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GrandchildToResilientOutsideChild.Type, #ResilientOutsideChild.classMethod!1 : (ResilientOutsideChild.Type) -> () -> (), $@convention(method) (@thick ResilientOutsideChild.Type) -> ()
   // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@thick ResilientOutsideChild.Type) -> ()
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super33GrandchildToResilientOutsideChildC11classMethodyyFZ'
@@ -265,7 +265,7 @@
   // CHECK:     [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $GenericOutsideParent<A>, #GenericOutsideParent.method!1 : <A> (GenericOutsideParent<A>) -> () -> (), $@convention(method) <τ_0_0> (@guaranteed GenericOutsideParent<τ_0_0>) -> ()
   // CHECK:     end_borrow [[BORROWED_CASTED_SELF_COPY]] from [[CASTED_SELF_COPY]]
   // CHECK:     [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]<A>([[CASTED_SELF_COPY]]) : $@convention(method) <τ_0_0> (@guaranteed GenericOutsideParent<τ_0_0>) -> ()
-  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:     [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:     apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super019GenericChildToFixedD13OutsideParentC6methodyyF'
@@ -277,7 +277,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GenericChildToFixedGenericOutsideParent<A>.Type to $@thick GenericOutsideParent<A>.Type
   // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GenericChildToFixedGenericOutsideParent<A>.Type, #GenericOutsideParent.classMethod!1 : <A> (GenericOutsideParent<A>.Type) -> () -> (), $@convention(method) <τ_0_0> (@thick GenericOutsideParent<τ_0_0>.Type) -> ()
   // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]<A>([[CASTED_SELF]]) : $@convention(method) <τ_0_0> (@thick GenericOutsideParent<τ_0_0>.Type) -> ()
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super019GenericChildToFixedD13OutsideParentC11classMethodyyFZ'
@@ -298,7 +298,7 @@
   // CHECK:     [[SUPER_METHOD:%.*]] = super_method [[DOWNCAST_BORROWED_CASTED_SELF_COPY]] : $ResilientGenericOutsideParent<A>, #ResilientGenericOutsideParent.method!1 : <A> (ResilientGenericOutsideParent<A>) -> () -> (), $@convention(method) <τ_0_0> (@guaranteed ResilientGenericOutsideParent<τ_0_0>) -> ()
   // CHECK:     end_borrow [[BORROWED_CASTED_SELF_COPY]] from [[CASTED_SELF_COPY]]
   // CHECK:     [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]<A>([[CASTED_SELF_COPY]]) : $@convention(method) <τ_0_0> (@guaranteed ResilientGenericOutsideParent<τ_0_0>) -> ()
-  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK:     [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK:     [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK:     apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super023GenericChildToResilientD13OutsideParentC6methodyyF'
@@ -310,7 +310,7 @@
   // CHECK: [[CASTED_SELF:%.*]] = upcast %0 : $@thick GenericChildToResilientGenericOutsideParent<A>.Type to $@thick ResilientGenericOutsideParent<A>.Type
   // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $@thick GenericChildToResilientGenericOutsideParent<A>.Type, #ResilientGenericOutsideParent.classMethod!1 : <A> (ResilientGenericOutsideParent<A>.Type) -> () -> (), $@convention(method) <τ_0_0> (@thick ResilientGenericOutsideParent<τ_0_0>.Type) -> ()
   // CHECK: [[PARTIAL_APPLY:%.*]] = partial_apply [callee_guaranteed] [[SUPER_METHOD]]<A>([[CASTED_SELF]]) : $@convention(method) <τ_0_0> (@thick ResilientGenericOutsideParent<τ_0_0>.Type) -> ()
-  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [[PARTIAL_APPLY]]
+  // CHECK: [[CONVERT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_APPLY]]
   // CHECK: [[DOFOO:%.*]] = function_ref @$S19partial_apply_super5doFooyyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: apply [[DOFOO]]([[CONVERT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   // CHECK: } // end sil function '$S19partial_apply_super023GenericChildToResilientD13OutsideParentC11classMethodyyFZ'
diff --git a/test/SILGen/reabstract.swift b/test/SILGen/reabstract.swift
index 2266f20..08df15a 100644
--- a/test/SILGen/reabstract.swift
+++ b/test/SILGen/reabstract.swift
@@ -1,5 +1,6 @@
 
 // RUN: %target-swift-frontend -module-name reabstract -Xllvm -sil-full-demangle -emit-silgen -enable-sil-ownership %s | %FileCheck %s
+// RUN: %target-swift-frontend -module-name reabstract -Xllvm -sil-full-demangle -emit-sil -enable-sil-ownership %s | %FileCheck %s --check-prefix=MANDATORY
 
 func takeFn<T>(_ f : (T) -> T?) {}
 func liftOptional(_ x : Int) -> Int? { return x }
@@ -13,19 +14,41 @@
 // CHECK:      reabstract.liftOptional
 // CHECK-NEXT: [[T1:%.*]] = function_ref @$S10reabstract12liftOptional{{[_0-9a-zA-Z]*}}F
 // CHECK-NEXT: [[T2:%.*]] = thin_to_thick_function [[T1]]
-// CHECK-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[T2]]
+// CHECK-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[T2]]
 // CHECK-NEXT: reabstraction thunk
 // CHECK-NEXT: [[T3:%.*]] = function_ref [[THUNK:@.*]] :
 // CHECK-NEXT: [[T4:%.*]] = partial_apply [callee_guaranteed] [[T3]]([[CVT]])
-// CHECK-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[T4]]
+// CHECK-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[T4]]
+// CHECK: destroy_value [[T4]]
+// CHECK-NEXT: destroy_value [[T2]]
 // CHECK:      [[T0:%.*]] = function_ref @$S10reabstract6takeFn{{[_0-9a-zA-Z]*}}F
 // CHECK-NEXT: apply [[T0]]<Int>([[CVT]])
-// CHECK-NEXT: destroy_value [[T2]]
-// CHECK-NEXT: destroy_value [[T4]]
 // CHECK-NEXT: tuple ()
 // CHECK-NEXT: return
 // CHECK-NEXT: } // end sil function '$S10reabstract5test0yyF'
 
+// MANDATORY:    sil hidden @$S10reabstract5test0yyF : $@convention(thin) () -> () {
+//   Emit a generalized reference to liftOptional.
+//   TODO: just emit a globalized thunk
+// MANDATORY:      reabstract.liftOptional
+// MANDATORY-NEXT: [[T1:%.*]] = function_ref @$S10reabstract12liftOptional{{[_0-9a-zA-Z]*}}F
+// MANDATORY-NEXT: [[T2:%.*]] = thin_to_thick_function [[T1]]
+// MANDATORY-NEXT: strong_retain [[T2]]
+// MANDATORY-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[T2]]
+// MANDATORY-NEXT: //{{.*}}reabstraction thunk
+// MANDATORY-NEXT: [[T3:%.*]] = function_ref [[THUNK:@.*]] :
+// MANDATORY-NEXT: [[T4:%.*]] = partial_apply [callee_guaranteed] [[T3]]([[CVT]])
+// MANDATORY-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[T4]]
+// MANDATORY-NEXT: strong_release [[T2]]
+// MANDATORY-NEXT: // function_ref
+// MANDATORY-NEXT: [[T0:%.*]] = function_ref @$S10reabstract6takeFn{{[_0-9a-zA-Z]*}}F
+// MANDATORY-NEXT: apply [[T0]]<Int>([[CVT]])
+// MANDATORY-NEXT: strong_release [[T4]]
+// MANDATORY-NEXT: strong_release [[T2]]
+// MANDATORY-NEXT: tuple ()
+// MANDATORY-NEXT: return
+// MANDATORY-NEXT: } // end sil function '$S10reabstract5test0yyF'
+
 // CHECK:    sil shared [transparent] [serializable] [reabstraction_thunk] [[THUNK]] : $@convention(thin) (@in_guaranteed Int, @noescape @callee_guaranteed (Int) -> Optional<Int>) -> @out Optional<Int> {
 // CHECK:      [[T0:%.*]] = load [trivial] %1 : $*Int
 // CHECK-NEXT: [[T1:%.*]] = apply %2([[T0]])
diff --git a/test/SILGen/rethrows.swift b/test/SILGen/rethrows.swift
index 0239d4d..d77971b 100644
--- a/test/SILGen/rethrows.swift
+++ b/test/SILGen/rethrows.swift
@@ -17,11 +17,13 @@
 // CHECK:     [[NORMAL]]([[RESULT_T0:%.*]] : $Int):
 // FIXME - SR-6979: We should be able to eliminate this strong_release.
 // CHECK-NEXT:  strong_release [[T0]]
+// CHECK-NEXT:  strong_release [[T0]]
 // CHECK-NEXT:  [[T1:%.*]] = tuple ()
 // CHECK-NEXT:  return [[T1]]
 // CHECK:     [[ERROR]]([[RESULT_T0:%.*]] : $Error):
 // FIXME - SR-6979: We should be able to eliminate this strong_release.
 // CHECK-NEXT:  strong_release [[T0]]
+// CHECK-NEXT:  strong_release [[T0]]
 // CHECK-NEXT:  throw [[RESULT_T0]]
 func test0() throws {
   try rethrower(thrower)
@@ -47,9 +49,11 @@
 // CHECK:       try_apply [[RETHROWER]]([[CVT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (Int, @error Error), normal [[NORMAL:bb1]], error [[ERROR:bb2]]
 // CHECK:     [[NORMAL]]([[RESULT:%.*]] : $Int):
 // CHECK-NEXT:  strong_release [[T0]]
+// CHECK-NEXT:  strong_release [[T0]]
 // CHECK-NEXT:  return [[RESULT]]
 // CHECK:     [[ERROR]]([[ERROR:%.*]] : $Error):
 // CHECK-NEXT:  strong_release [[T0]]
+// CHECK-NEXT:  strong_release [[T0]]
 // CHECK-NEXT:  throw [[ERROR]]
 func test1() throws {
   try rethrower { try rethrower(thrower) }
@@ -64,9 +68,11 @@
 // CHECK:       try_apply [[RETHROWER]]([[T2]]) : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (Int, @error Error), normal [[NORMAL:bb1]], error [[ERROR:bb2]]
 // CHECK:     [[NORMAL]]([[T0:%.*]] : $Int):
 // CHECK-NEXT:  strong_release [[T1]]
+// CHECK-NEXT:  strong_release [[T1]]
 // CHECK-NEXT:  [[RESULT:%.*]] = tuple ()
 // CHECK-NEXT:  return [[RESULT]]
 // CHECK:     [[ERROR]]([[T0:%.*]] : $Error):
+// CHECK-NEXT:  strong_release [[T1]]
 // CHECK-NEXT:  unreachable
 func test2() {
   rethrower(nonthrower)
diff --git a/test/SILGen/witnesses.swift b/test/SILGen/witnesses.swift
index e1b4f1e..fe4f550 100644
--- a/test/SILGen/witnesses.swift
+++ b/test/SILGen/witnesses.swift
@@ -520,8 +520,8 @@
 
 // CHECK-LABEL: sil private [transparent] [thunk] @$S9witnesses18EscapingCovarianceVAA0B3ReqA2aDP1fyyS2icFTW : $@convention(witness_method: EscapingReq) (@guaranteed @callee_guaranteed (Int) -> Int, @in_guaranteed EscapingCovariance) -> ()
 // CHECK-NOT: return
-// CHECK: [[COPIED:%.*]] = copy_value %0
-// CHECK: convert_escape_to_noescape [[COPIED]]
+// CHECK: convert_escape_to_noescape [not_guaranteed] %0
+// CHECK: return
 struct EscapingCovariance: EscapingReq {
   func f(_: (Int) -> Int) { }
 }
diff --git a/test/SILOptimizer/Inputs/linker_pass_input.swift b/test/SILOptimizer/Inputs/linker_pass_input.swift
index 8b58310..18fff65 100644
--- a/test/SILOptimizer/Inputs/linker_pass_input.swift
+++ b/test/SILOptimizer/Inputs/linker_pass_input.swift
@@ -2,6 +2,7 @@
 @_silgen_name("unknown")
 public func unknown() -> ()
 
+@inline(never)
 @inlinable
 public func doSomething() {
   unknown()
diff --git a/test/SILOptimizer/access_marker_verify.swift b/test/SILOptimizer/access_marker_verify.swift
index 4318270..87ebc96 100644
--- a/test/SILOptimizer/access_marker_verify.swift
+++ b/test/SILOptimizer/access_marker_verify.swift
@@ -969,7 +969,7 @@
 // CHECK: mark_uninitialized [rootself] %{{.*}} : ${ var StructWithLayout }
 // CHECK: [[PROJ:%.*]] = project_box %{{.*}} : ${ var StructWithLayout }, 0
 // CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] %{{.*}}([[PROJ]]) : $@convention(thin) (@inout_aliasable StructWithLayout) -> Bool
-// CHECK: [[CLOSURE:%.*]] = convert_escape_to_noescape [[PA]] : $@callee_guaranteed () -> Bool to $@noescape @callee_guaranteed () -> Bool
+// CHECK: [[CLOSURE:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed () -> Bool to $@noescape @callee_guaranteed () -> Bool
 // call default argument
 // CHECK: apply %{{.*}}() : $@convention(thin) () -> StaticString
 // call StaticString.init
diff --git a/test/SILOptimizer/access_marker_verify_objc.swift b/test/SILOptimizer/access_marker_verify_objc.swift
index c9f4c07..6d24335 100644
--- a/test/SILOptimizer/access_marker_verify_objc.swift
+++ b/test/SILOptimizer/access_marker_verify_objc.swift
@@ -40,7 +40,7 @@
             // function_ref thunk for @callee_unowned @convention(block) (@unowned Int) -> (@unowned Int)
 // CHECK:   [[THUNK:%.*]] = function_ref @$SS2iIyByd_S2iIegyd_TR : $@convention(thin) (Int, @guaranteed @convention(block) @noescape (Int) -> Int) -> Int
 // CHECK:   [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[CP]]) : $@convention(thin) (Int, @guaranteed @convention(block) @noescape (Int) -> Int) -> Int
-// CHECK:   [[CVT:%.*]] = convert_escape_to_noescape [[PA]] : $@callee_guaranteed (Int) -> Int to $@noescape @callee_guaranteed (Int) -> Int
+// CHECK:   [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed (Int) -> Int to $@noescape @callee_guaranteed (Int) -> Int
 // CHECK:   [[F:%.*]] = function_ref @$S25access_marker_verify_objc12HasBlockImplC5blockyyS2iXEF : $@convention(method) (@noescape @callee_guaranteed (Int) -> Int, @guaranteed HasBlockImpl) -> ()
 // CHECK:   %{{.*}} = apply [[F]]([[CVT]], %{{.*}}) : $@convention(method) (@noescape @callee_guaranteed (Int) -> Int, @guaranteed HasBlockImpl) -> ()
 // CHECK:   return %{{.*}} : $()                                
diff --git a/test/SILOptimizer/capture_promotion_ownership.swift b/test/SILOptimizer/capture_promotion_ownership.swift
index c74a886..28794f5 100644
--- a/test/SILOptimizer/capture_promotion_ownership.swift
+++ b/test/SILOptimizer/capture_promotion_ownership.swift
@@ -1,9 +1,4 @@
-// RUN: %target-swift-frontend %s -enable-sil-ownership -disable-sil-linking -emit-sil -o - | %FileCheck %s
-
-// NOTE: We add -disable-sil-linking to the compile line to ensure that we have
-// access to declarations for standard library types, but not definitions. This
-// ensures that we are able to safely use standard library types for this test
-// without needing the standard library to be ownership correct in its body.
+// RUN: %target-swift-frontend %s -enable-sil-ownership -emit-sil -o - | %FileCheck %s
 
 class Foo {
   func foo() -> Int {
diff --git a/test/SILOptimizer/closure_lifetime_fixup.swift b/test/SILOptimizer/closure_lifetime_fixup.swift
new file mode 100644
index 0000000..c50a4fb
--- /dev/null
+++ b/test/SILOptimizer/closure_lifetime_fixup.swift
@@ -0,0 +1,84 @@
+// RUN: %target-swift-frontend %s -emit-sil -o - | %FileCheck %s
+
+func use_closure(_ c : () -> () ) {
+  c()
+}
+
+func use_closureGeneric<T>(_ c : () -> T ) {
+  _ = c()
+}
+
+public class C {
+  func doIt() {}
+  func returnInt() -> Int { return 0 }
+}
+
+// CHECK-LABEL: sil @$S22closure_lifetime_fixup10testSimple1cyAA1CC_tF : $@convention(thin) (@guaranteed C) -> () {
+// CHECK: bb0([[ARG:%.*]] : $C):
+// CHECK: [[F:%.*]]  = function_ref @$S22closure_lifetime_fixup10testSimple1cyAA1CC_tFyyXEfU_
+// CHECK-NEXT:  strong_retain [[ARG]] : $C
+// CHECK-NEXT:  [[PA:%.*]] = partial_apply [callee_guaranteed] [[F]]([[ARG]]) : $@convention(thin) (@guaranteed C) -> ()
+// CHECK-NEXT: strong_retain [[PA]] : $@callee_guaranteed () -> ()
+// CHECK-NEXT:  [[CVT:%.*]] = convert_escape_to_noescape [[PA]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK-NEXT:  // function_ref use_closure(_:)
+// CHECK-NEXT:  [[F2:%.*]] = function_ref @$S22closure_lifetime_fixup04use_A0yyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+// CHECK-NEXT:  apply [[F2]]([[CVT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> ()
+// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> ()
+// CHECK-NEXT:  tuple ()
+// CHECK-NEXT:  return {{.*}} : $()
+public func testSimple(c: C) {
+  use_closure { c.doIt() }
+}
+
+// CHECK-LABEL: sil @$S22closure_lifetime_fixup11testGeneric1cyAA1CC_tF : $@convention(thin) (@guaranteed C) -> () {
+// CHECK:bb0([[ARG:%.*]] : $C):
+// CHECK:  [[F:%.*]] = function_ref @$S22closure_lifetime_fixup11testGeneric1cyAA1CC_tFSiyXEfU_ : $@convention(thin) (@guaranteed C) -> Int
+// CHECK-NEXT:  strong_retain [[ARG]] : $C
+// CHECK-NEXT:  [[PA:%.*]] = partial_apply [callee_guaranteed] [[F]]([[ARG]]) : $@convention(thin) (@guaranteed C) -> Int
+// CHECK-NEXT:  strong_retain [[PA]] : $@callee_guaranteed () -> Int
+// CHECK-NEXT:  [[CVT:%.*]] = convert_escape_to_noescape [[PA]] : $@callee_guaranteed () -> Int to $@noescape @callee_guaranteed () -> Int
+// CHECK-NEXT:  // function_ref thunk for @callee_guaranteed () -> (@unowned Int)
+// CHECK-NEXT:  [[F:%.*]] = function_ref @$SSiIgd_SiIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int
+// CHECK-NEXT:  [[PA2:%.*]] = partial_apply [callee_guaranteed] [[F]]([[CVT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int
+// CHECK-NEXT:  [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> @out Int to $@noescape @callee_guaranteed () -> @out Int
+// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> Int
+// CHECK-NEXT:  // function_ref use_closureGeneric<A>(_:)
+// CHECK-NEXT:  [[F2:%.*]] = function_ref @$S22closure_lifetime_fixup04use_A7GenericyyxyXElF : $@convention(thin) <τ_0_0> (@noescape @callee_guaranteed () -> @out τ_0_0) -> ()
+// CHECK-NEXT:  %12 = apply [[F2]]<Int>([[CVT2]]) : $@convention(thin) <τ_0_0> (@noescape @callee_guaranteed () -> @out τ_0_0) -> ()
+// CHECK-NEXT:  strong_release [[PA2]] : $@callee_guaranteed () -> @out Int
+// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> Int
+// CHECK-NEXT:  tuple ()
+// CHECK-NEXT:  return {{.*}} : $()
+
+public func testGeneric(c: C) {
+  use_closureGeneric { return c.returnInt() }
+}
+
+public protocol P {
+  associatedtype Element
+  subscript<U>(a: (Element) -> U, b: (U) -> Element) -> U { get set }
+}
+
+// Make sure we keep the closure alive up until after the write back.
+
+// CHECK-LABEL: sil @$S22closure_lifetime_fixup21testMaterializeForSet1pyxz_tAA1PRzSS7ElementRtzlF : $@convention(thin) <T where T : P, T.Element == String> (@inout T) -> () {
+// CHECK: bb0
+// CHECK:  [[PA1:%.*]] = partial_apply [callee_guaranteed]
+// CHECK:  [[ENUM1:%.*]] = enum $Optional<@callee_guaranteed (@in_guaranteed String) -> @out Int>, #Optional.some!enumelt.1, [[PA1]] 
+// CHECK:  [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]]
+// CHECK:  [[PA2:%.*]] = partial_apply [callee_guaranteed]
+// CHECK:  [[ENUM2:%.*]] = enum $Optional<@callee_guaranteed (@in_guaranteed Int) -> @out String>, #Optional.some!enumelt.1, [[PA2]]
+// CHECK:  [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]]
+// CHECK:  [[W:%.*]] = witness_method $T, #P.subscript!materializeForSet.1
+// CHECK:  [[BUFFER:%.*]] = apply [[W]]<T, Int>({{.*}}, [[CVT1]], [[CVT2]]
+// CHECK: bb1:
+// CHECK: br bb3
+// CHECK: bb2({{.*}}):
+// CHECK: br bb3
+// CHECK: bb3:
+// CHECK:  release_value [[ENUM1]]
+// CHECK:  release_value [[ENUM2]]
+public func testMaterializeForSet<T : P>(p: inout T) where T.Element == String {
+  p[{Int($0)!}, {String($0)}] += 1
+}
diff --git a/test/SILOptimizer/definite-init-convert-to-escape.swift b/test/SILOptimizer/definite-init-convert-to-escape.swift
index 74d8d99..f6569ea 100644
--- a/test/SILOptimizer/definite-init-convert-to-escape.swift
+++ b/test/SILOptimizer/definite-init-convert-to-escape.swift
@@ -1,5 +1,5 @@
 // RUN: %target-swift-frontend -module-name A -verify -emit-sil -import-objc-header %S/Inputs/Closure.h -disable-objc-attr-requires-foundation-module -enable-sil-ownership %s | %FileCheck %s
-// RUN: %target-swift-frontend -module-name A -verify -emit-sil -import-objc-header %S/Inputs/Closure.h -disable-objc-attr-requires-foundation-module -enable-sil-ownership -Xllvm -sil-di-disable-convert-escape-to-noescape-switch-peephole %s | %FileCheck %s --check-prefix=NOPEEPHOLE
+// RUN: %target-swift-frontend -module-name A -verify -emit-sil -import-objc-header %S/Inputs/Closure.h -disable-objc-attr-requires-foundation-module -enable-sil-ownership -Xllvm -sil-disable-convert-escape-to-noescape-switch-peephole %s | %FileCheck %s --check-prefix=NOPEEPHOLE
 
 // REQUIRES: objc_interop
 
diff --git a/test/SILOptimizer/hello-world.swift b/test/SILOptimizer/hello-world.swift
new file mode 100644
index 0000000..4e7c19a
--- /dev/null
+++ b/test/SILOptimizer/hello-world.swift
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t && mkdir -p %t/stats
+// RUN: %target-swift-frontend -emit-sil -stats-output-dir %t/stats %s -o /dev/null
+// RUN: %utils/process-stats-dir.py --evaluate 'NumSILGenFunctions < 10' %t/stats
+// RUN: %utils/process-stats-dir.py --evaluate 'NumSILOptFunctions < 10' %t/stats
+
+print("Hello world")
diff --git a/test/SILOptimizer/linker.swift b/test/SILOptimizer/linker.swift
index d411077..7b41bde 100644
--- a/test/SILOptimizer/linker.swift
+++ b/test/SILOptimizer/linker.swift
@@ -1,21 +1,23 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module %S/Inputs/linker_pass_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -module-link-name swiftCore
-// RUN: %target-swift-frontend %s -O -I %t -sil-debug-serialization -o - -emit-sil | %FileCheck %s
+// RUN: %target-swift-frontend %s -I %t -emit-sil | %FileCheck %s
+// RUN: %target-swift-frontend %s -I %t -O -emit-sil | %FileCheck %s --check-prefix=OPT
 
-// CHECK: sil public_external [serialized] [canonical] @$Ss11doSomethingyyF : $@convention(thin) () -> () {
+// CHECK: sil [serialized] [noinline] @$Ss11doSomethingyyF : $@convention(thin) () -> (){{$}}
+// OPT: sil public_external [noinline] @$Ss11doSomethingyyF : $@convention(thin) () -> () {
 doSomething()
 
 // CHECK: sil @$Ss12doSomething2yyF : $@convention(thin) () -> ()
 // CHECK-NOT: return
 doSomething2()
 
-// CHECK: sil public_external [serialized] [noinline] [canonical] @$Ss16callDoSomething3yyF
+// CHECK: sil [serialized] [noinline] @$Ss16callDoSomething3yyF : $@convention(thin) () -> (){{$}}
+// OPT: sil public_external [noinline] @$Ss16callDoSomething3yyF : $@convention(thin) () -> () {
 
-// CHECK: sil [canonical] @unknown
+// OPT: sil @unknown
 
-// CHECK: sil [canonical] @$Ss1AVABycfC
+// OPT: sil @$Ss1AVABycfC
 
-// CHECK: sil [noinline] [canonical] @$Ss12doSomething3yyxlF
-// CHECK-NOT: return
+// OPT: sil [noinline] @$Ss12doSomething3yyxlF : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> (){{$}}
 
 callDoSomething3()
diff --git a/test/Sema/exhaustive_switch.swift b/test/Sema/exhaustive_switch.swift
index 6333287..8ebbd02 100644
--- a/test/Sema/exhaustive_switch.swift
+++ b/test/Sema/exhaustive_switch.swift
@@ -472,6 +472,21 @@
   case (.case10, _): return true
   }
 
+  switch (OverlyLargeSpaceEnum.case1, OverlyLargeSpaceEnum.case2) { // expected-error {{switch must be exhaustive}}
+  case (.case0, _): return true
+  case (.case1, _): return true
+  case (.case2, _): return true
+  case (.case3, _): return true
+  case (.case4, _): return true
+  case (.case5, _): return true
+  case (.case6, _): return true
+  case (.case7, _): return true
+  case (.case8, _): return true
+  case (.case9, _): return true
+  case (.case10, _): return true
+  @unknown default: return false // expected-note {{remove '@unknown' to handle remaining values}} {{3-12=}}
+  }
+
 
   // No diagnostic
   switch (OverlyLargeSpaceEnum.case1, OverlyLargeSpaceEnum.case2) {
@@ -525,6 +540,10 @@
   case .two: return true
   case .three: return true
   }
+
+  // Make sure we haven't just stopped emitting diagnostics.
+  switch OverlyLargeSpaceEnum.case1 { // expected-error {{switch must be exhaustive}} expected-note 12 {{add missing case}} expected-note {{handle unknown values}}
+  }
 }
 
 indirect enum InfinitelySized {
diff --git a/test/Sema/struct_equatable_hashable_access.swift b/test/Sema/struct_equatable_hashable_access.swift
new file mode 100644
index 0000000..8672c98
--- /dev/null
+++ b/test/Sema/struct_equatable_hashable_access.swift
@@ -0,0 +1,10 @@
+// RUN: %target-swift-frontend -print-ast %s 2>&1 | %FileCheck %s
+
+// Check that synthesized members show up as 'fileprivate', not 'private.
+
+// CHECK-LABEL: private struct PrivateConformer : Hashable {
+private struct PrivateConformer: Hashable {
+  var value: Int
+  // CHECK-DAG: fileprivate var hashValue: Int { get }
+  // CHECK-DAG: @_implements(Equatable, ==(_:_:)) fileprivate static func __derived_struct_equals
+}
diff --git a/test/Serialization/Inputs/def_basic.sil b/test/Serialization/Inputs/def_basic.sil
index 673a9bd..b14ff89 100644
--- a/test/Serialization/Inputs/def_basic.sil
+++ b/test/Serialization/Inputs/def_basic.sil
@@ -1132,37 +1132,23 @@
   return %y : $Int
 }
 
-// Make sure we serialize the body of closure even without -sil-serialize-all.
-// CHECK_DECL-LABEL:  @partial_apply_with_closure
-sil [transparent] [serialized] [transparent] @partial_apply_with_closure : $@convention(thin) (@owned @callee_owned () -> Bool, @owned String, UnsafePointer<Int8>, Int64) -> () {
+// CHECK-LABEL:  @partial_apply_with_closure
+sil [transparent] [serialized] @partial_apply_with_closure : $@convention(thin) (@owned @callee_owned () -> Bool, @owned String, UnsafePointer<Int8>, Int64) -> () {
 bb0(%0 : $@callee_owned () -> Bool, %1 : $String, %2 : $UnsafePointer<Int8>, %3 : $Int64):
   %17 = function_ref @closure_body : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
-// CHECK_DECL: function_ref @closure_body
+// CHECK: function_ref @closure_body
   %18 = partial_apply %17(%2, %3) : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
-// CHECK_DECL: partial_apply
+// CHECK: partial_apply
   %30 = tuple ()
   return %30 : $()
 }
 
-sil shared [serialized] @closure_body : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> () {
-bb0(%0 : $UnsafePointer<Int8>, %1 : $UnsafePointer<Int8>, %2 : $Int64):
-  %3 = function_ref @assert_fail : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
-  %4 = apply %3(%0, %1, %2) : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
-  %5 = tuple ()
-  return %5 : $()
-}
-
-// CHECK_DECL-LABEL: @closure_body : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> () {
-// CHECK_DECL: function_ref @assert_fail
-
-sil [transparent] [serialized] @assert_fail : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
-
 // rdar: 15893086
 struct GenericStruct<T> {
   var x : T
 }
 
-// CHECK-LABEL: @extract_generic_struct
+// CHECK-LABEL: sil public_external [transparent] [serialized] @extract_generic_struct
 sil [transparent] [serialized] @extract_generic_struct : $@convention(thin) GenericStruct<Int64> -> Int64 {
 entry(%0 : $GenericStruct<Int64>):
   // CHECK: %1 = struct_extract %0 : $GenericStruct<Int64>, #GenericStruct.x
@@ -1347,6 +1333,19 @@
 }
 
 
+sil [transparent] [serialized] @assert_fail : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
+
+sil shared [serialized] @closure_body : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> () {
+bb0(%0 : $UnsafePointer<Int8>, %1 : $UnsafePointer<Int8>, %2 : $Int64):
+  %3 = function_ref @assert_fail : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
+  %4 = apply %3(%0, %1, %2) : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> ()
+  %5 = tuple ()
+  return %5 : $()
+}
+
+// CHECK-LABEL: @closure_body : $@convention(thin) (UnsafePointer<Int8>, UnsafePointer<Int8>, Int64) -> () {
+// CHECK: function_ref @assert_fail
+
 sil_vtable [serialized] Foo {
   #Foo.subscript!getter.1: @$S3tmp3FooC9subscriptSiSi1x_Si1ytcfg
   #Foo.subscript!setter.1: @$S3tmp3FooC9subscriptSiSi1x_Si1ytcfs
diff --git a/test/Serialization/Inputs/def_transparent.swift b/test/Serialization/Inputs/def_transparent.swift
index 73bf8d4..20da66e 100644
--- a/test/Serialization/Inputs/def_transparent.swift
+++ b/test/Serialization/Inputs/def_transparent.swift
@@ -44,7 +44,8 @@
   case Right(String)
   case Both(Int32, String)
 }
-@inlinable
+
+@_transparent
 public func do_switch(u u: MaybePair) {
   switch u {
   case .Neither:
diff --git a/test/Serialization/always_inline.swift b/test/Serialization/always_inline.swift
index 5a354e5..2a8ec45 100644
--- a/test/Serialization/always_inline.swift
+++ b/test/Serialization/always_inline.swift
@@ -1,12 +1,17 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_always_inline.swift
 // RUN: llvm-bcanalyzer %t/def_always_inline.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -emit-sil -I %t %s | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -emit-sib -I %t %s -o %t/always_inline.sib
+// RUN: %target-sil-opt -performance-linker %t/always_inline.sib -I %t | %FileCheck %s -check-prefix=SIL
 
 // CHECK-NOT: UnknownCode
 
 import def_always_inline
 
+// SIL-LABEL: sil public_external [serialized] [always_inline] [canonical] @$S17def_always_inline22AlwaysInlineInitStructV1xACSb_tcfC : $@convention(method) (Bool, @thin AlwaysInlineInitStruct.Type) -> AlwaysInlineInitStruct {
+
+// SIL-LABEL: sil public_external [serialized] [always_inline] [canonical] @$S17def_always_inline16testAlwaysInline1xS2b_tF : $@convention(thin) (Bool) -> Bool {
+
 // SIL-LABEL: sil @main
 // SIL: [[RAW:%.+]] = global_addr @$S13always_inline3rawSbvp : $*Bool
 // SIL: [[FUNC:%.+]] = function_ref @$S17def_always_inline16testAlwaysInline1xS2b_tF : $@convention(thin) (Bool) -> Bool
@@ -16,10 +21,5 @@
 
 // SIL: [[FUNC2:%.+]] = function_ref @$S17def_always_inline22AlwaysInlineInitStructV1xACSb_tcfC : $@convention(method) (Bool, @thin AlwaysInlineInitStruct.Type) -> AlwaysInlineInitStruct
 // SIL: apply [[FUNC2]]({{%.+}}, {{%.+}}) : $@convention(method) (Bool, @thin AlwaysInlineInitStruct.Type) -> AlwaysInlineInitStruct
-
 var a = AlwaysInlineInitStruct(x: false)
 
-// SIL-LABEL: [always_inline] @$S17def_always_inline16testAlwaysInline1xS2b_tF : $@convention(thin) (Bool) -> Bool
-
-// SIL-LABEL: sil public_external [serialized] [always_inline] @$S17def_always_inline22AlwaysInlineInitStructV1xACSb_tcfC : $@convention(method) (Bool, @thin AlwaysInlineInitStruct.Type) -> AlwaysInlineInitStruct {
-
diff --git a/test/Serialization/basic_sil.swift b/test/Serialization/basic_sil.swift
index 12cbe2e..a81df0e 100644
--- a/test/Serialization/basic_sil.swift
+++ b/test/Serialization/basic_sil.swift
@@ -1,11 +1,8 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil
 // RUN: llvm-bcanalyzer %t/def_basic.swiftmodule | %FileCheck %s
-// RUN: %target-build-swift -emit-sil -I %t %s | %FileCheck %S/Inputs/def_basic.sil
-
-// RUN: %empty-directory(%t)
-// RUN: %target-build-swift  -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil
-// RUN: %target-build-swift -emit-sil -I %t %s | %FileCheck -check-prefix=CHECK_DECL %S/Inputs/def_basic.sil
+// RUN: %target-build-swift -emit-sil -I %t %s -o %t/basic_sil.sil
+// RUN: %target-sil-opt -I %t %t/basic_sil.sil -performance-linker | %FileCheck %S/Inputs/def_basic.sil
 
 // This test currently is written such that no optimizations are assumed.
 // REQUIRES: swift_test_mode_optimize_none
diff --git a/test/Serialization/basic_sil_objc.swift b/test/Serialization/basic_sil_objc.swift
index 0a83a07..cfaeaa6 100644
--- a/test/Serialization/basic_sil_objc.swift
+++ b/test/Serialization/basic_sil_objc.swift
@@ -1,7 +1,9 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-build-swift -Xfrontend %clang-importer-sdk -I %S/../Inputs/clang-importer-sdk/swift-modules -emit-module -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -o %t/def_basic_objc.swiftmodule %S/Inputs/def_basic_objc.sil
 // RUN: llvm-bcanalyzer %t/def_basic_objc.swiftmodule | %FileCheck %s
-// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -emit-sil -I %t %s | %FileCheck %S/Inputs/def_basic_objc.sil
+
+// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -emit-sil -I %t %s -o %t/basic_sil_objc.sil
+// RUN: %target-sil-opt %t/basic_sil_objc.sil -performance-linker -I %t | %FileCheck %S/Inputs/def_basic_objc.sil
 
 // This test currently is written such that no optimizations are assumed.
 // REQUIRES: swift_test_mode_optimize_none
@@ -10,6 +12,7 @@
 // CHECK-NOT: UnknownCode
 
 import def_basic_objc
+import Foundation
 
 func test_all() {
   serialize_all()
diff --git a/test/Serialization/noinline.swift b/test/Serialization/noinline.swift
index f7d9052..719e076 100644
--- a/test/Serialization/noinline.swift
+++ b/test/Serialization/noinline.swift
@@ -1,12 +1,17 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_noinline.swift
 // RUN: llvm-bcanalyzer %t/def_noinline.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -emit-sil -I %t %s | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -emit-sib -I %t %s -o %t/noinline.sib
+// RUN: %target-sil-opt -performance-linker %t/noinline.sib -I %t | %FileCheck %s -check-prefix=SIL
 
 // CHECK-NOT: UnknownCode
 
 import def_noinline
 
+// SIL-LABEL: sil public_external [serialized] [noinline] [canonical] @$S12def_noinline18NoInlineInitStructV1xACSb_tcfC : $@convention(method) (Bool, @thin NoInlineInitStruct.Type) -> NoInlineInitStruct {
+
+// SIL-LABEL: sil public_external [serialized] [noinline] [canonical] @$S12def_noinline12testNoinline1xS2b_tF : $@convention(thin) (Bool) -> Bool {
+
 // SIL-LABEL: sil @main
 // SIL: [[RAW:%.+]] = global_addr @$S8noinline3rawSbvp : $*Bool
 // SIL: [[FUNC:%.+]] = function_ref @$S12def_noinline12testNoinline1xS2b_tF : $@convention(thin) (Bool) -> Bool
@@ -18,7 +23,3 @@
 // SIL: apply [[FUNC2]]({{%.+}}, {{%.+}}) : $@convention(method) (Bool, @thin NoInlineInitStruct.Type) -> NoInlineInitStruct
 
 var a = NoInlineInitStruct(x: false)
-
-// SIL-LABEL: [serialized] [noinline] @$S12def_noinline12testNoinline1xS2b_tF : $@convention(thin) (Bool) -> Bool
-
-// SIL-LABEL: sil public_external [serialized] [noinline] @$S12def_noinline18NoInlineInitStructV1xACSb_tcfC : $@convention(method) (Bool, @thin NoInlineInitStruct.Type) -> NoInlineInitStruct {
diff --git a/test/Serialization/sil_partial_apply_ownership.sil b/test/Serialization/sil_partial_apply_ownership.sil
index 09dc7b6..7c6216a 100644
--- a/test/Serialization/sil_partial_apply_ownership.sil
+++ b/test/Serialization/sil_partial_apply_ownership.sil
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -o %t/sil_partial_apply_ownership.swiftmodule %s
-// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-sil -I %t %s | %FileCheck %s
+// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xllvm -verify-skip-convert-escape-to-noescape-attributes -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -o %t/sil_partial_apply_ownership.swiftmodule %s
+// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -Xllvm -verify-skip-convert-escape-to-noescape-attributes -emit-sil -I %t %s | %FileCheck %s
 
 import Builtin
 
@@ -47,12 +47,18 @@
 
 // CHECK-LABEL: sil @partial_apply_convert
 // CHECK:   convert_escape_to_noescape %{{.*}} : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK:   convert_escape_to_noescape [not_guaranteed] %
+// CHECK:   convert_escape_to_noescape [escaped] %
+// CHECK:   convert_escape_to_noescape [not_guaranteed] [escaped] %
 sil @partial_apply_convert : $@convention(thin) () -> () {
 entry:
   %f = function_ref @subject : $@convention(thin) (Builtin.Int64) -> ()
   %z = integer_literal $Builtin.Int64, 0
   %e = partial_apply [callee_guaranteed] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
   %n = convert_escape_to_noescape %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+  %x2 = convert_escape_to_noescape [not_guaranteed] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+  %x3 = convert_escape_to_noescape [escaped] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+  %x4 = convert_escape_to_noescape [not_guaranteed] [escaped] %e : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
   %n2 = mark_dependence %n : $@noescape @callee_guaranteed () -> () on %e : $@callee_guaranteed () -> ()
   %f2 = function_ref @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
   apply %f2(%n2) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
diff --git a/test/Serialization/transparent.swift b/test/Serialization/transparent.swift
index b887699..48d7ace 100644
--- a/test/Serialization/transparent.swift
+++ b/test/Serialization/transparent.swift
@@ -2,7 +2,7 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_transparent.swift
 // RUN: llvm-bcanalyzer %t/def_transparent.swiftmodule | %FileCheck %s
-// RUN: %target-swift-frontend -module-name transparent -emit-sil -I %t %s | tee /tmp/xxx | %FileCheck %s -check-prefix=SIL
+// RUN: %target-swift-frontend -module-name transparent -emit-sil -I %t %s | %FileCheck %s -check-prefix=SIL
 
 // CHECK-NOT: UnknownCode
 
@@ -40,7 +40,7 @@
   test_br()
 }
 
-// SIL-LABEL: sil public_external [serialized] @$S15def_transparent9do_switch1uyAA9MaybePairO_tF : $@convention(thin) (@guaranteed MaybePair) -> () {
+// SIL-LABEL: sil public_external [transparent] [serialized] @$S15def_transparent9do_switch1uyAA9MaybePairO_tF : $@convention(thin) (@guaranteed MaybePair) -> () {
 // SIL: bb0(%0 : $MaybePair):
 // SIL: retain_value %0 : $MaybePair
 // SIL: switch_enum %0 : $MaybePair, case #MaybePair.Neither!enumelt: bb[[CASE1:[0-9]+]], case #MaybePair.Left!enumelt.1: bb[[CASE2:[0-9]+]], case #MaybePair.Right!enumelt.1: bb[[CASE3:[0-9]+]], case #MaybePair.Both!enumelt.1: bb[[CASE4:[0-9]+]]
diff --git a/test/decl/protocol/conforms/self.swift b/test/decl/protocol/conforms/self.swift
index 1aa9fb8..7fe8e4e 100644
--- a/test/decl/protocol/conforms/self.swift
+++ b/test/decl/protocol/conforms/self.swift
@@ -70,3 +70,19 @@
 }
 
 extension SeriousClass : HasDefault {}
+
+// https://bugs.swift.org/browse/SR-7428
+
+protocol Node {
+  associatedtype ValueType = Int
+
+  func addChild<ChildType>(_ child: ChildType)
+    where ChildType: Node, ChildType.ValueType == Self.ValueType
+}
+
+extension Node {
+  func addChild<ChildType>(_ child: ChildType)
+    where ChildType: Node, ChildType.ValueType == Self.ValueType {}
+}
+
+class IntNode: Node {}
diff --git a/test/decl/protocol/special/coding/class_codable_inheritance.swift b/test/decl/protocol/special/coding/class_codable_inheritance.swift
index 2f29331..baa2173 100644
--- a/test/decl/protocol/special/coding/class_codable_inheritance.swift
+++ b/test/decl/protocol/special/coding/class_codable_inheritance.swift
@@ -50,3 +50,30 @@
 // The synthesized CodingKeys type should not be accessible from outside the
 // class.
 let _ = SimpleChildClass.CodingKeys.self // expected-error {{'CodingKeys' is inaccessible due to 'private' protection level}}
+
+// Check access level issues around 'private'.
+private class PrivateClass: Codable {
+  var x: Int = 1
+}
+
+private class PrivateClassChild: PrivateClass {}
+
+_ = PrivateClass.init(from:)
+_ = PrivateClass.encode(to:)
+_ = PrivateClassChild.init(from:)
+_ = PrivateClassChild.encode(to:)
+
+_ = PrivateClass.CodingKeys.self // expected-error {{'CodingKeys' is inaccessible due to 'private' protection level}}
+
+// Check access level issues around 'open'.
+open class OpenClass: Codable {
+  var x: Int = 1
+}
+open class OpenClassChild: OpenClass {}
+
+_ = OpenClass.init(from:)
+_ = OpenClass.encode(to:)
+_ = OpenClassChild.init(from:)
+_ = OpenClassChild.encode(to:)
+
+_ = OpenClass.CodingKeys.self // expected-error {{'CodingKeys' is inaccessible due to 'private' protection level}}
diff --git a/test/expr/primary/literal/collection_upcast_opt.swift b/test/expr/primary/literal/collection_upcast_opt.swift
new file mode 100644
index 0000000..d105716
--- /dev/null
+++ b/test/expr/primary/literal/collection_upcast_opt.swift
@@ -0,0 +1,38 @@
+// RUN: %target-typecheck-verify-swift -dump-ast 2> %t.ast
+// RUN: %FileCheck %s < %t.ast
+
+// Verify that upcasts of array literals upcast the individual elements in place
+// rather than introducing a collection_upcast_expr.
+
+protocol P { }
+struct X : P { }
+
+struct TakesArray<T> {
+  init(_: [(T) -> Void]) { }
+}
+
+// CHECK-LABEL: func_decl "arrayUpcast(_:_:)"
+// CHECK: assign_expr
+// CHECK-NOT: collection_upcast_expr
+// CHECK: array_expr type='[(X) -> Void]'
+// CHECK-NEXT: function_conversion_expr implicit type='(X) -> Void'
+// CHECK-NEXT: {{declref_expr.*x1}}
+// CHECK-NEXT: function_conversion_expr implicit type='(X) -> Void'
+// CHECK-NEXT: {{declref_expr.*x2}}
+func arrayUpcast(_ x1: @escaping (P) -> Void, _ x2: @escaping (P) -> Void) {
+  _ = TakesArray<X>([x1, x2])
+}
+
+struct TakesDictionary<T> {
+  init(_: [Int : (T) -> Void]) { }
+}
+
+// CHECK-LABEL: func_decl "dictionaryUpcast(_:_:)"
+// CHECK: assign_expr
+// CHECK-NOT: collection_upcast_expr
+// CHECK: paren_expr type='([Int : (X) -> Void])'
+// CHECK-NOT: collection_upcast_expr
+// CHECK: (dictionary_expr type='[Int : (X) -> Void]'
+func dictionaryUpcast(_ x1: @escaping (P) -> Void, _ x2: @escaping (P) -> Void) {
+  _ = TakesDictionary<X>(([1: x1, 2: x2]))
+}
diff --git a/test/multifile/Inputs/outlined-thunks-other.swift b/test/multifile/Inputs/outlined-thunks-other.swift
new file mode 100644
index 0000000..95da403
--- /dev/null
+++ b/test/multifile/Inputs/outlined-thunks-other.swift
@@ -0,0 +1,5 @@
+private class OtherPrivate<T> { }
+
+struct OtherInternal<T> {
+  fileprivate var myPrivate: OtherPrivate<T>? = nil
+}
diff --git a/test/multifile/outlined-thunks.swift b/test/multifile/outlined-thunks.swift
new file mode 100644
index 0000000..b24a959
--- /dev/null
+++ b/test/multifile/outlined-thunks.swift
@@ -0,0 +1,18 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -emit-library -module-name outlined_thunks %S/Inputs/outlined-thunks-other.swift %s
+// RUN: %target-build-swift -emit-library -module-name outlined_thunks -whole-module-optimization %S/Inputs/outlined-thunks-other.swift %s
+
+// rdar://problem/39470607
+
+protocol P { }
+
+private struct MyPrivate<T: P> {
+  private var otherHelper: OtherInternal<T>? = nil
+  init(_: T) { }
+}
+
+extension P {
+  func foo(data: Any) {
+    _ = MyPrivate(data as! Self)
+  }
+}
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L12-14.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L12-14.swift.expected
index 388f8cf..d57e401 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L12-14.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L12-14.swift.expected
@@ -9,7 +9,9 @@
     didSet { print("bye") }
 }
 
-func generic<T>(_: T) -> Int { fatalError() }
+func generic<T>(_: T) -> Int {
+fatalError()
+}
 
 class Foo {
     var foo: Int
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L16-49.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L16-49.swift.expected
index 6ad8406..3ee21a6 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L16-49.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L16-49.swift.expected
@@ -16,25 +16,43 @@
 class Foo {
     var foo: Int
 
-    var bar: Int { fatalError() }
+    var bar: Int {
+fatalError()
+}
 
     var baz: Int {
-        get { fatalError() }
-        set { fatalError() }
+        get {
+fatalError()
+}
+        set {
+fatalError()
+}
     }
 
     var qux: Int {
-        willSet { fatalError() }
-        didSet { fatalError() }
+        willSet {
+fatalError()
+}
+        didSet {
+fatalError()
+}
     }
 
-    init() { fatalError() }
+    init() {
+fatalError()
+}
 
-    func nonGeneric() -> Int { fatalError() }
+    func nonGeneric() -> Int {
+fatalError()
+}
 
-    func generic<T>(_: T) -> Int { fatalError() }
+    func generic<T>(_: T) -> Int {
+fatalError()
+}
 
-    deinit { fatalError() }
+    deinit {
+fatalError()
+}
 }
 
 extension Foo {
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L19-22.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L19-22.swift.expected
index 0e6dbc5..cd68c9f 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L19-22.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L19-22.swift.expected
@@ -16,7 +16,9 @@
 class Foo {
     var foo: Int
 
-    var bar: Int { fatalError() }
+    var bar: Int {
+fatalError()
+}
 
     var baz: Int {
         get { return 0 }
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L3-5.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L3-5.swift.expected
index 5d0d2e8..d4ea890 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L3-5.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L3-5.swift.expected
@@ -1,6 +1,8 @@
 var foo: Int = 0
 
-var bar: Int { fatalError() }
+var bar: Int {
+fatalError()
+}
 
 var qux: Int = 0 {
     willSet { print("hi") }
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L30-44.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L30-44.swift.expected
index ed96bab..053b5bc 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L30-44.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L30-44.swift.expected
@@ -27,14 +27,22 @@
 
     var qux: Int {
         willSet { print("hi") }
-        didSet { fatalError() }
+        didSet {
+fatalError()
+}
     }
 
-    init() { fatalError() }
+    init() {
+fatalError()
+}
 
-    func nonGeneric() -> Int { fatalError() }
+    func nonGeneric() -> Int {
+fatalError()
+}
 
-    func generic<T>(_: T) -> Int { fatalError() }
+    func generic<T>(_: T) -> Int {
+fatalError()
+}
 
     deinit {
         print("bye")
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L51-59.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L51-59.swift.expected
index 8a73c00..95bd535 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L51-59.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L51-59.swift.expected
@@ -49,9 +49,13 @@
 }
 
 extension Foo {
-    func nonGeneric2() -> Int { fatalError() }
+    func nonGeneric2() -> Int {
+fatalError()
+}
 
-    func generic2<T>(_: T) -> Int { fatalError() }
+    func generic2<T>(_: T) -> Int {
+fatalError()
+}
 }
 
 
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L7-10.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L7-10.swift.expected
index 02d3f7b..06ce662 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L7-10.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L7-10.swift.expected
@@ -5,8 +5,12 @@
 }
 
 var qux: Int = 0 {
-    willSet { fatalError() }
-    didSet { fatalError() }
+    willSet {
+fatalError()
+}
+    didSet {
+fatalError()
+}
 }
 
 func generic<T>(_: T) -> Int {
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L8.swift.expected b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L8.swift.expected
index f9fa570..68a1e53 100644
--- a/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L8.swift.expected
+++ b/test/refactoring/ReplaceBodiesWithFatalError/Outputs/basic/L8.swift.expected
@@ -5,7 +5,9 @@
 }
 
 var qux: Int = 0 {
-    willSet { fatalError() }
+    willSet {
+fatalError()
+}
     didSet { print("bye") }
 }
 
diff --git a/test/refactoring/ReplaceBodiesWithFatalError/requires-env-var.swift b/test/refactoring/ReplaceBodiesWithFatalError/requires-env-var.swift
new file mode 100644
index 0000000..bd21695
--- /dev/null
+++ b/test/refactoring/ReplaceBodiesWithFatalError/requires-env-var.swift
@@ -0,0 +1,16 @@
+var bar: Int {
+    return 0
+}
+// CHECK-NO-ENV-LABEL: Action begins
+// CHECK-NO-ENV-NEXT: Action ends
+
+// CHECK-ENV-LABEL: Action begins
+// CHECK-ENV-NEXT: Replace Function Bodies With 'fatalError()'
+// CHECK-ENV-NEXT: Action ends
+
+// replace.bodies.with.fatalError/-replace-bodies-with-fatalError should only be
+// found if the appropriate environment variable is set.
+
+// RUN: %refactor -actions -source-filename %s -pos=1:1 -end-pos=3:2 | %FileCheck %s -check-prefix CHECK-NO-ENV
+
+// RUN: env SWIFT_ENABLE_INTERNAL_REFACTORING_ACTIONS=1 %refactor -actions -source-filename %s -pos=1:1 -end-pos=3:2 | %FileCheck %s -check-prefix CHECK-ENV
diff --git a/test/stdlib/TestDecimal.swift b/test/stdlib/TestDecimal.swift
index 00dda26..3d2a304 100644
--- a/test/stdlib/TestDecimal.swift
+++ b/test/stdlib/TestDecimal.swift
@@ -272,6 +272,9 @@
         expectEqual(.minus, d.sign)
         d.negate()
         expectEqual(.plus, d.sign)
+        var e = Decimal(0)
+        e.negate()
+        expectEqual(e, 0)
         expectTrue(Decimal(3.5).isEqual(to: Decimal(3.5)))
         expectTrue(Decimal.nan.isEqual(to: Decimal.nan))
         expectTrue(Decimal(1.28).isLess(than: Decimal(2.24)))
diff --git a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp
index 140bedb..1ac528d 100644
--- a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp
+++ b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp
@@ -199,6 +199,28 @@
   DumpTypeFromMangled.removeArgument();
   InputNames.removeArgument();
 
+  auto validateInputFile = [](std::string Filename) {
+    if (Filename.empty())
+      return true;
+    if (!llvm::sys::fs::exists(llvm::Twine(Filename))) {
+      llvm::errs() << Filename << " does not exists, exiting.\n";
+      return false;
+    }
+    if (!llvm::sys::fs::is_regular_file(llvm::Twine(Filename))) {
+      llvm::errs() << Filename << " is not a regular file, exiting.\n";
+      return false;
+    }
+    return true;
+  };
+
+  for (auto &InputFilename : InputNames)
+    if (!validateInputFile(InputFilename))
+      return 1;
+  if (!validateInputFile(DumpTypeFromMangled))
+    return 1;
+  if (!validateInputFile(DumpDeclFromMangled))
+    return 1;
+
   // Fetch the serialized module bitstreams from the Mach-O files and
   // register them with the module loader.
   llvm::SmallVector<std::pair<char *, uint64_t>, 8> Modules;
diff --git a/utils/pass-pipeline/src/passes.py b/utils/pass-pipeline/src/passes.py
index 5a28a83..c5e5afd 100644
--- a/utils/pass-pipeline/src/passes.py
+++ b/utils/pass-pipeline/src/passes.py
@@ -40,7 +40,7 @@
 PerfInliner = Pass('PerfInliner')
 PerformanceConstantPropagation = Pass('PerformanceConstantPropagation')
 PredictableMemoryOptimizations = Pass('PredictableMemoryOptimizations')
-SILCleanup = Pass('SILCleanup')
+IRGenPrepare = Pass('IRGenPrepare')
 SILCombine = Pass('SILCombine')
 SILLinker = Pass('SILLinker')
 SROA = Pass('SROA')
@@ -89,7 +89,7 @@
     PerfInliner,
     PerformanceConstantPropagation,
     PredictableMemoryOptimizations,
-    SILCleanup,
+    IRGenPrepare,
     SILCombine,
     SILLinker,
     SROA,
diff --git a/validation-test/compiler_crashers_2/0153-rdar39130543.swift b/validation-test/compiler_crashers_2/0153-rdar39130543.swift
new file mode 100644
index 0000000..40d25aa
--- /dev/null
+++ b/validation-test/compiler_crashers_2/0153-rdar39130543.swift
@@ -0,0 +1,21 @@
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+
+protocol P20 { }
+
+protocol P21b {
+	associatedtype T
+
+	func foo(_: (T?) -> Void)
+}
+
+protocol P21a {
+	associatedtype T
+
+	func bar(_: ([T]) -> Void)
+}
+
+extension P21b where Self: P21a, T: P20 {
+	func foo(_: (T?) -> Void) {
+		bar { _ in }
+	}
+}
diff --git a/validation-test/compiler_crashers/28598-issatisfied-request.swift b/validation-test/compiler_crashers_fixed/28598-issatisfied-request.swift
similarity index 84%
rename from validation-test/compiler_crashers/28598-issatisfied-request.swift
rename to validation-test/compiler_crashers_fixed/28598-issatisfied-request.swift
index c7da4d8..b617169 100644
--- a/validation-test/compiler_crashers/28598-issatisfied-request.swift
+++ b/validation-test/compiler_crashers_fixed/28598-issatisfied-request.swift
@@ -5,8 +5,8 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
-// REQUIRES: asserts
+// RUN: not %target-swift-frontend %s -emit-ir
+
 class a{
 let d= <H
 class B{extension{protocol A{{
diff --git a/validation-test/compiler_crashers/28778-hasaccessibility-accessibility-not-computed-yet.swift b/validation-test/compiler_crashers_fixed/28778-hasaccessibility-accessibility-not-computed-yet.swift
similarity index 83%
rename from validation-test/compiler_crashers/28778-hasaccessibility-accessibility-not-computed-yet.swift
rename to validation-test/compiler_crashers_fixed/28778-hasaccessibility-accessibility-not-computed-yet.swift
index 6bf0b84..20c2b30 100644
--- a/validation-test/compiler_crashers/28778-hasaccessibility-accessibility-not-computed-yet.swift
+++ b/validation-test/compiler_crashers_fixed/28778-hasaccessibility-accessibility-not-computed-yet.swift
@@ -5,6 +5,6 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+
+// RUN: not %target-swift-frontend %s -emit-ir
 extension{let d=r protocol A{{}extension{func<(Int=
diff --git a/validation-test/stdlib/Range.swift.gyb b/validation-test/stdlib/Range.swift.gyb
index 9ae0fdd..bf34c58 100644
--- a/validation-test/stdlib/Range.swift.gyb
+++ b/validation-test/stdlib/Range.swift.gyb
@@ -788,5 +788,11 @@
     result)
 }
 
+MiscTestSuite.test("Compatibility typealiases") {
+  let _: CountablePartialRangeFrom = 1...
+  let _: CountableRange = MinimalStrideableValue(3)..<MinimalStrideableValue(3)
+  let _: CountableClosedRange = MinimalStrideableValue(3)...MinimalStrideableValue(3)
+}
+
 runAllTests()