Merge pull request #12267 from arguiot/master

Created a clone of the code of conduct on Swift.org
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 53040c5..0c04168 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -103,6 +103,7 @@
     single-source/RC4
     single-source/RGBHistogram
     single-source/RangeAssignment
+    single-source/RangeIteration
     single-source/RecursiveOwnedParameter
     single-source/ReduceInto
     single-source/ReversedCollections
@@ -198,7 +199,7 @@
 # Syntax for an optset:  <optimization-level>_<configuration>
 #    where "_<configuration>" is optional.
 if(NOT SWIFT_OPTIMIZATION_LEVELS)
-  set(SWIFT_OPTIMIZATION_LEVELS "Onone" "O" "Ounchecked"
+  set(SWIFT_OPTIMIZATION_LEVELS "Onone" "O" "Osize"
                                 ${SWIFT_EXTRA_BENCH_CONFIGS})
 endif()
 
diff --git a/benchmark/README.md b/benchmark/README.md
index f854897..0fbda3e 100644
--- a/benchmark/README.md
+++ b/benchmark/README.md
@@ -48,7 +48,7 @@
       (default: "macosx;iphoneos;appletvos;watchos")
 * `-DSWIFT_OPTIMIZATION_LEVELS`
     * A list of Swift optimization levels to build against
-      (default: "O;Onone;Ounchecked")
+      (default: "O;Onone;Osize")
 * `-DSWIFT_BENCHMARK_EMIT_SIB`
     * A boolean value indicating whether .sib files should be generated
       alongside .o files (default: FALSE)
@@ -92,7 +92,7 @@
 
 * `$ ./Benchmark_O --num-iters=1 --num-samples=1`
 * `$ ./Benchmark_Onone --list`
-* `$ ./Benchmark_Ounchecked Ackermann`
+* `$ ./Benchmark_Osize Ackermann`
 
 ### Note
 As a shortcut, you can also refer to benchmarks by their ordinal numbers.
diff --git a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
index ba17253..e7cf286 100644
--- a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
+++ b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
@@ -204,7 +204,7 @@
   set(common_swift4_options ${common_options} "-swift-version" "4")
 
   # Always optimize the driver modules.
-  # Note that we compile the driver for Ounchecked also with -Ounchecked
+  # Note that we compile the driver for Osize also with -Osize
   # (and not with -O), because of <rdar://problem/19614516>.
   string(REPLACE "Onone" "O" driver_opt "${optflag}")
 
diff --git a/benchmark/multi-source/PrimsSplit/main.swift b/benchmark/multi-source/PrimsSplit/main.swift
index 0609e92..380eca5 100644
--- a/benchmark/multi-source/PrimsSplit/main.swift
+++ b/benchmark/multi-source/PrimsSplit/main.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let PrimsSplit = BenchmarkInfo(
+  name: "PrimsSplit",
+  runFunction: run_PrimsSplit,
+  tags: [.validation, .algorithm])
+
 @inline(never)
 public func run_PrimsSplit(_ N: Int) {
   for _ in 1...5*N {
diff --git a/benchmark/scripts/Benchmark_DTrace.in b/benchmark/scripts/Benchmark_DTrace.in
index 8bdc6b0..dc50118 100644
--- a/benchmark/scripts/Benchmark_DTrace.in
+++ b/benchmark/scripts/Benchmark_DTrace.in
@@ -23,7 +23,7 @@
 
 import perf_test_driver  # noqa (E402 module level import not at top of file)
 
-# Regexes for the XFAIL_LIST. Matches against '([Onone|O|Ounchecked],TestName)'
+# Regexes for the XFAIL_LIST. Matches against '([Onone|O|Osize],TestName)'
 XFAIL_LIST = [
 ]
 
diff --git a/benchmark/scripts/Benchmark_Driver b/benchmark/scripts/Benchmark_Driver
index bd817f0f..f8805f7 100755
--- a/benchmark/scripts/Benchmark_Driver
+++ b/benchmark/scripts/Benchmark_Driver
@@ -401,7 +401,7 @@
         'multiple filters are supported', metavar="PATTERN")
     parent_parser.add_argument(
         '-t', '--tests',
-        help='directory containing Benchmark_O{,none,unchecked} ' +
+        help='directory containing Benchmark_O{,none,size} ' +
         '(default: DRIVER_DIR)',
         default=DRIVER_DIR)
 
@@ -411,8 +411,8 @@
         parents=[parent_parser])
     submit_parser.add_argument(
         '-o', '--optimization', nargs='+',
-        help='optimization levels to use (default: O Onone Ounchecked)',
-        default=['O', 'Onone', 'Ounchecked'])
+        help='optimization levels to use (default: O Onone Osize)',
+        default=['O', 'Onone', 'Osize'])
     submit_parser.add_argument(
         '-i', '--iterations',
         help='number of times to run each test (default: 10)',
@@ -435,8 +435,8 @@
     run_parser.add_argument(
         '-o', '--optimization',
         metavar='OPT',
-        choices=['O', 'Onone', 'Ounchecked'],
-        help='optimization level to use: {O,Onone,Ounchecked}, (default: O)',
+        choices=['O', 'Onone', 'Osize'],
+        help='optimization level to use: {O,Onone,Osize}, (default: O)',
         default='O')
     run_parser.add_argument(
         '-i', '--iterations',
diff --git a/benchmark/scripts/Benchmark_GuardMalloc.in b/benchmark/scripts/Benchmark_GuardMalloc.in
index 012fe8d..e7d001d 100644
--- a/benchmark/scripts/Benchmark_GuardMalloc.in
+++ b/benchmark/scripts/Benchmark_GuardMalloc.in
@@ -20,7 +20,7 @@
 
 import perf_test_driver  # noqa (E402 module level import not at top of file)
 
-# Regexes for the XFAIL_LIST. Matches against '([Onone|O|Ounchecked],TestName)'
+# Regexes for the XFAIL_LIST. Matches against '([Onone|O|Osize],TestName)'
 XFAIL_LIST = [
 ]
 
diff --git a/benchmark/scripts/compare_perf_tests.py b/benchmark/scripts/compare_perf_tests.py
index d99a6e2..4243dee 100755
--- a/benchmark/scripts/compare_perf_tests.py
+++ b/benchmark/scripts/compare_perf_tests.py
@@ -24,7 +24,7 @@
 class PerformanceTestResult(object):
     """PerformanceTestResult holds results from executing an individual
     benchmark from the Swift Benchmark Suite as reported by the test driver
-    (Benchmark_O, Benchmark_Onone, Benchmark_Ounchecked or Benchmark_Driver).
+    (Benchmark_O, Benchmark_Onone, Benchmark_Osize or Benchmark_Driver).
 
     It depends on the log format emitted by the test driver in the form:
     #,TEST,SAMPLES,MIN(μs),MAX(μs),MEAN(μs),SD(μs),MEDIAN(μs),MAX_RSS(B)
diff --git a/benchmark/scripts/perf_test_driver/perf_test_driver.py b/benchmark/scripts/perf_test_driver/perf_test_driver.py
index c790463..89a5562 100644
--- a/benchmark/scripts/perf_test_driver/perf_test_driver.py
+++ b/benchmark/scripts/perf_test_driver/perf_test_driver.py
@@ -61,7 +61,7 @@
     return type(args[0]).process_input(*args)
 
 
-BenchmarkDriver_OptLevels = ['Onone', 'O', 'Ounchecked']
+BenchmarkDriver_OptLevels = ['Onone', 'O', 'Osize']
 
 
 class BenchmarkDriver(object):
diff --git a/benchmark/single-source/Ackermann.swift b/benchmark/single-source/Ackermann.swift
index 460e622..a76024f 100644
--- a/benchmark/single-source/Ackermann.swift
+++ b/benchmark/single-source/Ackermann.swift
@@ -14,6 +14,11 @@
 // for performance measuring.
 import TestsUtils
 
+public let Ackermann = BenchmarkInfo(
+  name: "Ackermann",
+  runFunction: run_Ackermann,
+  tags: [.unstable, .algorithm])
+
 func ackermann(_ M: Int, _ N : Int) -> Int {
   if (M == 0) { return N + 1 }
   if (N == 0) { return ackermann(M - 1, 1) }
diff --git a/benchmark/single-source/AngryPhonebook.swift b/benchmark/single-source/AngryPhonebook.swift
index 0131a1a..a61c977 100644
--- a/benchmark/single-source/AngryPhonebook.swift
+++ b/benchmark/single-source/AngryPhonebook.swift
@@ -15,6 +15,11 @@
 import TestsUtils
 import Foundation
 
+public let AngryPhonebook = BenchmarkInfo(
+  name: "AngryPhonebook",
+  runFunction: run_AngryPhonebook,
+  tags: [.validation, .api, .String])
+
 var words = [
   "James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph",
   "Charles", "Thomas", "Christopher", "Daniel", "Matthew", "Donald", "Anthony",
diff --git a/benchmark/single-source/Array2D.swift b/benchmark/single-source/Array2D.swift
index d38e0fa..0b6e55f 100644
--- a/benchmark/single-source/Array2D.swift
+++ b/benchmark/single-source/Array2D.swift
@@ -10,6 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let Array2D = BenchmarkInfo(
+  name: "Array2D",
+  runFunction: run_Array2D,
+  tags: [.validation, .api, .Array])
+
 @inline(never)
 public func run_Array2D(_ N: Int) {
   var A: [[Int]] = []
diff --git a/benchmark/single-source/ArrayAppend.swift b/benchmark/single-source/ArrayAppend.swift
index 834c94f..8ed0959 100644
--- a/benchmark/single-source/ArrayAppend.swift
+++ b/benchmark/single-source/ArrayAppend.swift
@@ -14,6 +14,28 @@
 
 import TestsUtils
 
+public let ArrayAppend = [
+  BenchmarkInfo(name: "ArrayAppend", runFunction: run_ArrayAppend, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendArrayOfInt", runFunction: run_ArrayAppendArrayOfInt, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendAscii", runFunction: run_ArrayAppendAscii, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendFromGeneric", runFunction: run_ArrayAppendFromGeneric, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendGenericStructs", runFunction: run_ArrayAppendGenericStructs, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendLatin1", runFunction: run_ArrayAppendLatin1, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendLazyMap", runFunction: run_ArrayAppendLazyMap, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendOptionals", runFunction: run_ArrayAppendOptionals, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendRepeatCol", runFunction: run_ArrayAppendRepeatCol, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendReserved", runFunction: run_ArrayAppendReserved, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendSequence", runFunction: run_ArrayAppendSequence, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendStrings", runFunction: run_ArrayAppendStrings, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendToFromGeneric", runFunction: run_ArrayAppendToFromGeneric, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendToGeneric", runFunction: run_ArrayAppendToGeneric, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayAppendUTF16", runFunction: run_ArrayAppendUTF16, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayPlusEqualArrayOfInt", runFunction: run_ArrayPlusEqualArrayOfInt, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayPlusEqualFiveElementCollection", runFunction: run_ArrayPlusEqualFiveElementCollection, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayPlusEqualSingleElementCollection", runFunction: run_ArrayPlusEqualSingleElementCollection, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayPlusEqualThreeElements", runFunction: run_ArrayPlusEqualThreeElements, tags: [.validation, .api, .Array]),
+]
+
 // Append single element
 @inline(never)
 public func run_ArrayAppend(_ N: Int) {
diff --git a/benchmark/single-source/ArrayInClass.swift b/benchmark/single-source/ArrayInClass.swift
index d214851..1f064a1 100644
--- a/benchmark/single-source/ArrayInClass.swift
+++ b/benchmark/single-source/ArrayInClass.swift
@@ -10,6 +10,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+public let ArrayInClass = BenchmarkInfo(
+  name: "ArrayInClass",
+  runFunction: run_ArrayInClass,
+  tags: [.validation, .api, .Array])
+
 class ArrayContainer {
   final var arr : [Int]
 
diff --git a/benchmark/single-source/ArrayLiteral.swift b/benchmark/single-source/ArrayLiteral.swift
index 60ab3d1..234ab91 100644
--- a/benchmark/single-source/ArrayLiteral.swift
+++ b/benchmark/single-source/ArrayLiteral.swift
@@ -15,6 +15,14 @@
 // It is reported to be slow: <rdar://problem/17297449>
 import TestsUtils
 
+public let ArrayLiteral = [
+  BenchmarkInfo(name: "ArrayLiteral", runFunction: run_ArrayLiteral, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayValueProp", runFunction: run_ArrayValueProp, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayValueProp2", runFunction: run_ArrayValueProp2, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayValueProp3", runFunction: run_ArrayValueProp3, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ArrayValueProp4", runFunction: run_ArrayValueProp4, tags: [.validation, .api, .Array]),
+]
+
 @inline(never)
 func makeArray() -> [Int] {
   return [1,2,3]
diff --git a/benchmark/single-source/ArrayOfGenericPOD.swift b/benchmark/single-source/ArrayOfGenericPOD.swift
index d2d2558..5cdc4c7 100644
--- a/benchmark/single-source/ArrayOfGenericPOD.swift
+++ b/benchmark/single-source/ArrayOfGenericPOD.swift
@@ -18,6 +18,13 @@
 // For comparison, we always create three arrays of 200,000 words.
 // An integer enum takes two words.
 
+import TestsUtils
+
+public let ArrayOfGenericPOD = BenchmarkInfo(
+  name: "ArrayOfGenericPOD",
+  runFunction: run_ArrayOfGenericPOD,
+  tags: [.validation, .api, .Array])
+
 class RefArray<T> {
   var array: [T]
 
diff --git a/benchmark/single-source/ArrayOfGenericRef.swift b/benchmark/single-source/ArrayOfGenericRef.swift
index e8870c9..f92d0aa 100644
--- a/benchmark/single-source/ArrayOfGenericRef.swift
+++ b/benchmark/single-source/ArrayOfGenericRef.swift
@@ -15,6 +15,13 @@
 //
 // For comparison, we always create three arrays of 10,000 words.
 
+import TestsUtils
+
+public let ArrayOfGenericRef = BenchmarkInfo(
+  name: "ArrayOfGenericRef",
+  runFunction: run_ArrayOfGenericRef,
+  tags: [.validation, .api, .Array])
+
 protocol Constructible {
   associatedtype Element
   init(e:Element)
diff --git a/benchmark/single-source/ArrayOfPOD.swift b/benchmark/single-source/ArrayOfPOD.swift
index 1a9cffd..173ea91 100644
--- a/benchmark/single-source/ArrayOfPOD.swift
+++ b/benchmark/single-source/ArrayOfPOD.swift
@@ -16,6 +16,13 @@
 //
 // For comparison, we always create three arrays of 200,000 words.
 
+import TestsUtils
+
+public let ArrayOfPOD = BenchmarkInfo(
+  name: "ArrayOfPOD",
+  runFunction: run_ArrayOfPOD,
+  tags: [.validation, .api, .Array])
+
 class RefArray<T> {
   var array : [T]
 
diff --git a/benchmark/single-source/ArrayOfRef.swift b/benchmark/single-source/ArrayOfRef.swift
index 9034884..4f7d936 100644
--- a/benchmark/single-source/ArrayOfRef.swift
+++ b/benchmark/single-source/ArrayOfRef.swift
@@ -16,6 +16,13 @@
 //
 // For comparison, we always create four arrays of 10,000 words.
 
+import TestsUtils
+
+public let ArrayOfRef = BenchmarkInfo(
+  name: "ArrayOfRef",
+  runFunction: run_ArrayOfRef,
+  tags: [.validation, .api, .Array])
+
 protocol Constructible {
   associatedtype Element
   init(e:Element)
diff --git a/benchmark/single-source/ArraySubscript.swift b/benchmark/single-source/ArraySubscript.swift
index 2e857b0..5303959 100644
--- a/benchmark/single-source/ArraySubscript.swift
+++ b/benchmark/single-source/ArraySubscript.swift
@@ -13,6 +13,11 @@
 // This test checks the performance of modifying an array element.
 import TestsUtils
 
+public let ArraySubscript = BenchmarkInfo(
+  name: "ArraySubscript",
+  runFunction: run_ArraySubscript,
+  tags: [.validation, .api, .Array])
+
 @inline(never)
 public func run_ArraySubscript(_ N: Int) {
   SRand()
diff --git a/benchmark/single-source/BitCount.swift b/benchmark/single-source/BitCount.swift
index d0d0209..b318aa0 100644
--- a/benchmark/single-source/BitCount.swift
+++ b/benchmark/single-source/BitCount.swift
@@ -16,6 +16,11 @@
 import Foundation
 import TestsUtils
 
+public let BitCount = BenchmarkInfo(
+  name: "BitCount",
+  runFunction: run_BitCount,
+  tags: [.validation, .algorithm])
+
 func countBitSet(_ num: Int) -> Int {
   let bits = MemoryLayout<Int>.size * 8
   var cnt: Int = 0
diff --git a/benchmark/single-source/ByteSwap.swift b/benchmark/single-source/ByteSwap.swift
index d0487ca..3fab1ed 100644
--- a/benchmark/single-source/ByteSwap.swift
+++ b/benchmark/single-source/ByteSwap.swift
@@ -16,6 +16,11 @@
 import Foundation
 import TestsUtils
 
+public let ByteSwap = BenchmarkInfo(
+  name: "ByteSwap",
+  runFunction: run_ByteSwap,
+  tags: [.validation, .algorithm])
+
 // a naive O(n) implementation of byteswap.
 @inline(never)
 func byteswap_n(_ a: UInt64) -> UInt64 {
diff --git a/benchmark/single-source/CString.swift b/benchmark/single-source/CString.swift
index d175c29..9167d97 100644
--- a/benchmark/single-source/CString.swift
+++ b/benchmark/single-source/CString.swift
@@ -17,6 +17,13 @@
 import Darwin
 #endif
 
+public let CString = [
+  BenchmarkInfo(name: "CStringLongAscii", runFunction: run_CStringLongAscii, tags: [.validation, .api, .String, .bridging]),
+  BenchmarkInfo(name: "CStringLongNonAscii", runFunction: run_CStringLongNonAscii, tags: [.validation, .api, .String, .bridging]),
+  BenchmarkInfo(name: "CStringShortAscii", runFunction: run_CStringShortAscii, tags: [.validation, .api, .String, .bridging]),
+  BenchmarkInfo(name: "StringWithCString", runFunction: run_StringWithCString, tags: [.validation, .api, .String, .bridging]),
+]
+
 let ascii = "Swift is a multi-paradigm, compiled programming language created for iOS, OS X, watchOS, tvOS and Linux development by Apple Inc. Swift is designed to work with Apple's Cocoa and Cocoa Touch frameworks and the large body of existing Objective-C code written for Apple products. Swift is intended to be more resilient to erroneous code (\"safer\") than Objective-C and also more concise. It is built with the LLVM compiler framework included in Xcode 6 and later and uses the Objective-C runtime, which allows C, Objective-C, C++ and Swift code to run within a single program."
 let japanese = "日本語(にほんご、にっぽんご)は、主に日本国内や日本人同士の間で使われている言語である。"
 
diff --git a/benchmark/single-source/Calculator.swift b/benchmark/single-source/Calculator.swift
index 00b3de4..ffe6d61 100644
--- a/benchmark/single-source/Calculator.swift
+++ b/benchmark/single-source/Calculator.swift
@@ -13,6 +13,11 @@
 import TestsUtils
 import Foundation
 
+public let Calculator = BenchmarkInfo(
+  name: "Calculator",
+  runFunction: run_Calculator,
+  tags: [.validation])
+
 @inline(never)
 func my_atoi_impl(_ input : String) -> Int {
   switch input {
diff --git a/benchmark/single-source/CaptureProp.swift b/benchmark/single-source/CaptureProp.swift
index 6bec5a9..ff16c43 100644
--- a/benchmark/single-source/CaptureProp.swift
+++ b/benchmark/single-source/CaptureProp.swift
@@ -10,6 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let CaptureProp = BenchmarkInfo(
+  name: "CaptureProp",
+  runFunction: run_CaptureProp,
+  tags: [.validation, .api, .refcount])
+
 func sum(_ x:Int, y:Int) -> Int {
   return x + y
 }
diff --git a/benchmark/single-source/CharacterLiteralsLarge.swift b/benchmark/single-source/CharacterLiteralsLarge.swift
index fd94a4b..673eccba 100644
--- a/benchmark/single-source/CharacterLiteralsLarge.swift
+++ b/benchmark/single-source/CharacterLiteralsLarge.swift
@@ -15,6 +15,11 @@
 // and retain a StringBuffer.
 import TestsUtils
 
+public let CharacterLiteralsLarge = BenchmarkInfo(
+  name: "CharacterLiteralsLarge",
+  runFunction: run_CharacterLiteralsLarge,
+  tags: [.validation, .api, .String])
+
 @inline(never)
 func makeCharacter_UTF8Length9() -> Character {
   return "a\u{0300}\u{0301}\u{0302}\u{0303}"
diff --git a/benchmark/single-source/CharacterLiteralsSmall.swift b/benchmark/single-source/CharacterLiteralsSmall.swift
index 0156c3b..a9892e3 100644
--- a/benchmark/single-source/CharacterLiteralsSmall.swift
+++ b/benchmark/single-source/CharacterLiteralsSmall.swift
@@ -15,6 +15,11 @@
 // represented as a packed integer.
 import TestsUtils
 
+public let CharacterLiteralsSmall = BenchmarkInfo(
+  name: "CharacterLiteralsSmall",
+  runFunction: run_CharacterLiteralsSmall,
+  tags: [.validation, .api, .String])
+
 @inline(never)
 func makeCharacter_UTF8Length1() -> Character {
   return "a"
diff --git a/benchmark/single-source/Chars.swift b/benchmark/single-source/Chars.swift
index 1606cd7..62cefc6 100644
--- a/benchmark/single-source/Chars.swift
+++ b/benchmark/single-source/Chars.swift
@@ -13,6 +13,11 @@
 // This test tests the performance of ASCII Character comparison.
 import TestsUtils
 
+public let Chars = BenchmarkInfo(
+  name: "Chars",
+  runFunction: run_Chars,
+  tags: [.validation, .api, .String])
+
 @inline(never)
 public func run_Chars(_ N: Int) {
   // Permute some characters.
diff --git a/benchmark/single-source/ClassArrayGetter.swift b/benchmark/single-source/ClassArrayGetter.swift
index 0130cfd..6eaec5d 100644
--- a/benchmark/single-source/ClassArrayGetter.swift
+++ b/benchmark/single-source/ClassArrayGetter.swift
@@ -10,6 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let ClassArrayGetter = BenchmarkInfo(
+  name: "ClassArrayGetter",
+  runFunction: run_ClassArrayGetter,
+  tags: [.validation, .api, .Array])
+
 class Box {
   var v: Int
   init(v: Int) { self.v = v }
diff --git a/benchmark/single-source/DeadArray.swift b/benchmark/single-source/DeadArray.swift
index a7466fa..b8ebcc3 100644
--- a/benchmark/single-source/DeadArray.swift
+++ b/benchmark/single-source/DeadArray.swift
@@ -13,6 +13,11 @@
 // rdar://problem/20980377
 import TestsUtils
 
+public let DeadArray = BenchmarkInfo(
+  name: "DeadArray",
+  runFunction: run_DeadArray,
+  tags: [.regression])
+
 @inline(__always)
 func debug(_ m:String) {}
 
diff --git a/benchmark/single-source/DictTest.swift b/benchmark/single-source/DictTest.swift
index 4a926b8..ef46ce9 100644
--- a/benchmark/single-source/DictTest.swift
+++ b/benchmark/single-source/DictTest.swift
@@ -12,6 +12,12 @@
 
 import TestsUtils
 
+
+public let Dictionary = [
+  BenchmarkInfo(name: "Dictionary", runFunction: run_Dictionary, tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "DictionaryOfObjects", runFunction: run_DictionaryOfObjects, tags: [.validation, .api, .Dictionary]),
+]
+
 @inline(never)
 public func run_Dictionary(scale: Int) {
   let Input = [
diff --git a/benchmark/single-source/DictTest2.swift b/benchmark/single-source/DictTest2.swift
index 9f2f4ef..535578b 100644
--- a/benchmark/single-source/DictTest2.swift
+++ b/benchmark/single-source/DictTest2.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let Dictionary2 = [
+  BenchmarkInfo(name: "Dictionary2", runFunction: run_Dictionary2, tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "Dictionary2OfObjects", runFunction: run_Dictionary2OfObjects, tags: [.validation, .api, .Dictionary]),
+]
+
 @inline(never)
 public func run_Dictionary2(_ N: Int) {
   let size = 500
@@ -55,6 +60,7 @@
 
 @inline(never)
 public func run_Dictionary2OfObjects(_ N: Int) {
+
   let size = 500
   let ref_result = 199
   var res = 0
diff --git a/benchmark/single-source/DictTest3.swift b/benchmark/single-source/DictTest3.swift
index 92c6e3e..a35bc0b 100644
--- a/benchmark/single-source/DictTest3.swift
+++ b/benchmark/single-source/DictTest3.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let Dictionary3 = [
+  BenchmarkInfo(name: "Dictionary3", runFunction: run_Dictionary3, tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "Dictionary3OfObjects", runFunction: run_Dictionary3OfObjects, tags: [.validation, .api, .Dictionary]),
+]
+
 @inline(never)
 public func run_Dictionary3(_ N: Int) {
   let size1 = 100
diff --git a/benchmark/single-source/DictionaryBridge.swift b/benchmark/single-source/DictionaryBridge.swift
index 999f89b..dde1cc6 100644
--- a/benchmark/single-source/DictionaryBridge.swift
+++ b/benchmark/single-source/DictionaryBridge.swift
@@ -16,6 +16,11 @@
 import Foundation
 import TestsUtils
 
+public let DictionaryBridge = BenchmarkInfo(
+  name: "DictionaryBridge",
+  runFunction: run_DictionaryBridge,
+  tags: [.validation, .api, .Dictionary, .bridging])
+
 #if _runtime(_ObjC)
 class Thing : NSObject {
 
diff --git a/benchmark/single-source/DictionaryGroup.swift b/benchmark/single-source/DictionaryGroup.swift
index 9ea5393..6376ebd 100644
--- a/benchmark/single-source/DictionaryGroup.swift
+++ b/benchmark/single-source/DictionaryGroup.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let DictionaryGroup = [
+  BenchmarkInfo(name: "DictionaryGroup", runFunction: run_DictionaryGroup, tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "DictionaryGroupOfObjects", runFunction: run_DictionaryGroupOfObjects, tags: [.validation, .api, .Dictionary]),
+]
+
 let count = 10_000
 let result = count / 10
 
diff --git a/benchmark/single-source/DictionaryLiteral.swift b/benchmark/single-source/DictionaryLiteral.swift
index 51d9bc7..64f4b86 100644
--- a/benchmark/single-source/DictionaryLiteral.swift
+++ b/benchmark/single-source/DictionaryLiteral.swift
@@ -14,6 +14,11 @@
 // rdar://problem/19804127
 import TestsUtils
 
+public let DictionaryLiteral = BenchmarkInfo(
+  name: "DictionaryLiteral",
+  runFunction: run_DictionaryLiteral,
+  tags: [.validation, .api, .Dictionary])
+
 @inline(never)
 func makeDictionary() -> [Int: Int] {
   return [1: 3, 2: 2, 3: 1]
diff --git a/benchmark/single-source/DictionaryRemove.swift b/benchmark/single-source/DictionaryRemove.swift
index 64a2f7c..7051df3 100644
--- a/benchmark/single-source/DictionaryRemove.swift
+++ b/benchmark/single-source/DictionaryRemove.swift
@@ -14,6 +14,11 @@
 // rdar://problem/19804127
 import TestsUtils
 
+public let DictionaryRemove = [
+  BenchmarkInfo(name: "DictionaryRemove", runFunction: run_DictionaryRemove, tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "DictionaryRemoveOfObjects", runFunction: run_DictionaryRemoveOfObjects, tags: [.validation, .api, .Dictionary]),
+]
+
 @inline(never)
 public func run_DictionaryRemove(_ N: Int) {
     let size = 100
diff --git a/benchmark/single-source/DictionarySwap.swift b/benchmark/single-source/DictionarySwap.swift
index efe99f4..3ece889 100644
--- a/benchmark/single-source/DictionarySwap.swift
+++ b/benchmark/single-source/DictionarySwap.swift
@@ -14,6 +14,11 @@
 // rdar://problem/19804127
 import TestsUtils
 
+public let DictionarySwap = [
+  BenchmarkInfo(name: "DictionarySwap", runFunction: run_DictionarySwap, tags: [.validation, .api, .Dictionary]),
+  BenchmarkInfo(name: "DictionarySwapOfObjects", runFunction: run_DictionarySwapOfObjects, tags: [.validation, .api, .Dictionary]),
+]
+
 @inline(never)
 public func run_DictionarySwap(_ N: Int) {
     let size = 100
diff --git a/benchmark/single-source/DropFirst.swift b/benchmark/single-source/DropFirst.swift
index 7baca6f..a717bc9 100644
--- a/benchmark/single-source/DropFirst.swift
+++ b/benchmark/single-source/DropFirst.swift
@@ -23,6 +23,66 @@
 let suffixCount = sequenceCount - dropCount
 let sumCount = suffixCount * (2 * sequenceCount - suffixCount - 1) / 2
 
+
+public let DropFirst = [
+  BenchmarkInfo(
+    name: "DropFirstCountableRange",
+    runFunction: run_DropFirstCountableRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstSequence",
+    runFunction: run_DropFirstSequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnySequence",
+    runFunction: run_DropFirstAnySequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnySeqCntRange",
+    runFunction: run_DropFirstAnySeqCntRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnySeqCRangeIter",
+    runFunction: run_DropFirstAnySeqCRangeIter,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnyCollection",
+    runFunction: run_DropFirstAnyCollection,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstArray",
+    runFunction: run_DropFirstArray,
+    tags: [.validation, .api, .Array]),
+  BenchmarkInfo(
+    name: "DropFirstCountableRangeLazy",
+    runFunction: run_DropFirstCountableRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstSequenceLazy",
+    runFunction: run_DropFirstSequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnySequenceLazy",
+    runFunction: run_DropFirstAnySequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnySeqCntRangeLazy",
+    runFunction: run_DropFirstAnySeqCntRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnySeqCRangeIterLazy",
+    runFunction: run_DropFirstAnySeqCRangeIterLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstAnyCollectionLazy",
+    runFunction: run_DropFirstAnyCollectionLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropFirstArrayLazy",
+    runFunction: run_DropFirstArrayLazy,
+    tags: [.validation, .api]),
+]
+
 @inline(never)
 public func run_DropFirstCountableRange(_ N: Int) {
   let s = 0..<sequenceCount
diff --git a/benchmark/single-source/DropFirst.swift.gyb b/benchmark/single-source/DropFirst.swift.gyb
index d3df5bd..79ce501 100644
--- a/benchmark/single-source/DropFirst.swift.gyb
+++ b/benchmark/single-source/DropFirst.swift.gyb
@@ -42,6 +42,16 @@
 Sequences = Sequences + map(lazy, Sequences)
 }%
 
+
+public let DropFirst = [
+% for (Name, Expr) in Sequences:
+  BenchmarkInfo(
+    name: "DropFirst${Name}",
+    runFunction: run_DropFirst${Name},
+    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+% end
+]
+
 % for (Name, Expr) in Sequences:
 @inline(never)
 public func run_DropFirst${Name}(_ N: Int) {
diff --git a/benchmark/single-source/DropLast.swift b/benchmark/single-source/DropLast.swift
index f97e6d2..83f2a3b 100644
--- a/benchmark/single-source/DropLast.swift
+++ b/benchmark/single-source/DropLast.swift
@@ -23,6 +23,65 @@
 let dropCount = sequenceCount - prefixCount
 let sumCount = prefixCount * (prefixCount - 1) / 2
 
+public let DropLast = [
+  BenchmarkInfo(
+    name: "DropLastCountableRange",
+    runFunction: run_DropLastCountableRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastSequence",
+    runFunction: run_DropLastSequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnySequence",
+    runFunction: run_DropLastAnySequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnySeqCntRange",
+    runFunction: run_DropLastAnySeqCntRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnySeqCRangeIter",
+    runFunction: run_DropLastAnySeqCRangeIter,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnyCollection",
+    runFunction: run_DropLastAnyCollection,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastArray",
+    runFunction: run_DropLastArray,
+    tags: [.validation, .api, .Array]),
+  BenchmarkInfo(
+    name: "DropLastCountableRangeLazy",
+    runFunction: run_DropLastCountableRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastSequenceLazy",
+    runFunction: run_DropLastSequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnySequenceLazy",
+    runFunction: run_DropLastAnySequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnySeqCntRangeLazy",
+    runFunction: run_DropLastAnySeqCntRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnySeqCRangeIterLazy",
+    runFunction: run_DropLastAnySeqCRangeIterLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastAnyCollectionLazy",
+    runFunction: run_DropLastAnyCollectionLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropLastArrayLazy",
+    runFunction: run_DropLastArrayLazy,
+    tags: [.validation, .api]),
+]
+
 @inline(never)
 public func run_DropLastCountableRange(_ N: Int) {
   let s = 0..<sequenceCount
diff --git a/benchmark/single-source/DropLast.swift.gyb b/benchmark/single-source/DropLast.swift.gyb
index 0a9a6ff..f91dc5f 100644
--- a/benchmark/single-source/DropLast.swift.gyb
+++ b/benchmark/single-source/DropLast.swift.gyb
@@ -42,6 +42,15 @@
 Sequences = Sequences + map(lazy, Sequences)
 }%
 
+public let DropLast = [
+% for (Name, Expr) in Sequences:
+  BenchmarkInfo(
+    name: "DropLast${Name}",
+    runFunction: run_DropLast${Name},
+    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+% end
+]
+
 % for (Name, Expr) in Sequences:
 @inline(never)
 public func run_DropLast${Name}(_ N: Int) {
diff --git a/benchmark/single-source/DropWhile.swift b/benchmark/single-source/DropWhile.swift
index 51d6d7d..d3aa4ae 100644
--- a/benchmark/single-source/DropWhile.swift
+++ b/benchmark/single-source/DropWhile.swift
@@ -23,6 +23,65 @@
 let suffixCount = sequenceCount - dropCount
 let sumCount = suffixCount * (2 * sequenceCount - suffixCount - 1) / 2
 
+public let DropWhile = [
+  BenchmarkInfo(
+    name: "DropWhileCountableRange",
+    runFunction: run_DropWhileCountableRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileSequence",
+    runFunction: run_DropWhileSequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnySequence",
+    runFunction: run_DropWhileAnySequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnySeqCntRange",
+    runFunction: run_DropWhileAnySeqCntRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnySeqCRangeIter",
+    runFunction: run_DropWhileAnySeqCRangeIter,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnyCollection",
+    runFunction: run_DropWhileAnyCollection,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileArray",
+    runFunction: run_DropWhileArray,
+    tags: [.validation, .api, .Array]),
+  BenchmarkInfo(
+    name: "DropWhileCountableRangeLazy",
+    runFunction: run_DropWhileCountableRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileSequenceLazy",
+    runFunction: run_DropWhileSequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnySequenceLazy",
+    runFunction: run_DropWhileAnySequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnySeqCntRangeLazy",
+    runFunction: run_DropWhileAnySeqCntRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnySeqCRangeIterLazy",
+    runFunction: run_DropWhileAnySeqCRangeIterLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileAnyCollectionLazy",
+    runFunction: run_DropWhileAnyCollectionLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "DropWhileArrayLazy",
+    runFunction: run_DropWhileArrayLazy,
+    tags: [.validation, .api]),
+]
+
 @inline(never)
 public func run_DropWhileCountableRange(_ N: Int) {
   let s = 0..<sequenceCount
diff --git a/benchmark/single-source/DropWhile.swift.gyb b/benchmark/single-source/DropWhile.swift.gyb
index 20df6e0..295a651 100644
--- a/benchmark/single-source/DropWhile.swift.gyb
+++ b/benchmark/single-source/DropWhile.swift.gyb
@@ -42,6 +42,15 @@
 Sequences = Sequences + map(lazy, Sequences)
 }%
 
+public let DropWhile = [
+% for (Name, Expr) in Sequences:
+  BenchmarkInfo(
+    name: "DropWhile${Name}",
+    runFunction: run_DropWhile${Name},
+    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+% end
+]
+
 % for (Name, Expr) in Sequences:
 @inline(never)
 public func run_DropWhile${Name}(_ N: Int) {
diff --git a/benchmark/single-source/ErrorHandling.swift b/benchmark/single-source/ErrorHandling.swift
index 64d27b1..8e3ca66 100644
--- a/benchmark/single-source/ErrorHandling.swift
+++ b/benchmark/single-source/ErrorHandling.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let ErrorHandling = BenchmarkInfo(
+  name: "ErrorHandling",
+  runFunction: run_ErrorHandling,
+  tags: [.validation, .exceptions])
+
 enum PizzaError : Error {
   case Pepperoni, Olives, Anchovy
 }
diff --git a/benchmark/single-source/Exclusivity.swift b/benchmark/single-source/Exclusivity.swift
index e75dca9..c3a93fc 100644
--- a/benchmark/single-source/Exclusivity.swift
+++ b/benchmark/single-source/Exclusivity.swift
@@ -17,35 +17,37 @@
 
 import TestsUtils
 
-// At -Onone
-// 25% swift_beginAccess
-// 15% tlv_get_addr
-// 15% swift_endAccess
-public var ExclusivityGlobal = BenchmarkInfo(
-  name: "ExclusivityGlobal",
-  runFunction: run_accessGlobal,
-  tags: [.runtime, .cpubench]
-)
-// At -Onone
-// 23% swift_retain
-// 22% swift_release
-//  9% swift_beginAccess
-//  3% swift_endAccess
-public var ExclusivityInMatSet = BenchmarkInfo(
-  name: "ExclusivityInMatSet",
-  runFunction: run_accessInMatSet,
-  tags: [.runtime, .cpubench]
-)
-// At -Onone
-// 25% swift_release
-// 23% swift_retain
-// 16% swift_beginAccess
-//  8% swift_endAccess
-public var ExclusivityIndependent = BenchmarkInfo(
-  name: "ExclusivityIndependent",
-  runFunction: run_accessIndependent,
-  tags: [.runtime, .cpubench]
-)
+public let Exclusivity = [
+  // At -Onone
+  // 25% swift_beginAccess
+  // 15% tlv_get_addr
+  // 15% swift_endAccess
+  BenchmarkInfo(
+    name: "ExclusivityGlobal",
+    runFunction: run_accessGlobal,
+    tags: [.runtime, .cpubench]
+  ),
+  // At -Onone
+  // 23% swift_retain
+  // 22% swift_release
+  //  9% swift_beginAccess
+  //  3% swift_endAccess
+  BenchmarkInfo(
+    name: "ExclusivityInMatSet",
+    runFunction: run_accessInMatSet,
+    tags: [.runtime, .cpubench]
+  ),
+  // At -Onone
+  // 25% swift_release
+  // 23% swift_retain
+  // 16% swift_beginAccess
+  //  8% swift_endAccess
+  BenchmarkInfo(
+    name: "ExclusivityIndependent",
+    runFunction: run_accessIndependent,
+    tags: [.runtime, .cpubench]
+  ),
+]
 
 // Initially these benchmarks only measure access checks at -Onone. In
 // the future, access checks will also be emitted at -O.
diff --git a/benchmark/single-source/ExistentialPerformance.swift b/benchmark/single-source/ExistentialPerformance.swift
index f8cc0d3..67f68c8 100644
--- a/benchmark/single-source/ExistentialPerformance.swift
+++ b/benchmark/single-source/ExistentialPerformance.swift
@@ -10,6 +10,110 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let ExistentialPerformance = [
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_ClassValueBuffer1", runFunction: run_ExistentialTestArrayConditionalShift_ClassValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_ClassValueBuffer2", runFunction: run_ExistentialTestArrayConditionalShift_ClassValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_ClassValueBuffer3", runFunction: run_ExistentialTestArrayConditionalShift_ClassValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_ClassValueBuffer4", runFunction: run_ExistentialTestArrayConditionalShift_ClassValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_IntValueBuffer0", runFunction: run_ExistentialTestArrayConditionalShift_IntValueBuffer0, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_IntValueBuffer1", runFunction: run_ExistentialTestArrayConditionalShift_IntValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_IntValueBuffer2", runFunction: run_ExistentialTestArrayConditionalShift_IntValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_IntValueBuffer3", runFunction: run_ExistentialTestArrayConditionalShift_IntValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayConditionalShift_IntValueBuffer4", runFunction: run_ExistentialTestArrayConditionalShift_IntValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_ClassValueBuffer1", runFunction: run_ExistentialTestArrayMutating_ClassValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_ClassValueBuffer2", runFunction: run_ExistentialTestArrayMutating_ClassValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_ClassValueBuffer3", runFunction: run_ExistentialTestArrayMutating_ClassValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_ClassValueBuffer4", runFunction: run_ExistentialTestArrayMutating_ClassValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_IntValueBuffer0", runFunction: run_ExistentialTestArrayMutating_IntValueBuffer0, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_IntValueBuffer1", runFunction: run_ExistentialTestArrayMutating_IntValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_IntValueBuffer2", runFunction: run_ExistentialTestArrayMutating_IntValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_IntValueBuffer3", runFunction: run_ExistentialTestArrayMutating_IntValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayMutating_IntValueBuffer4", runFunction: run_ExistentialTestArrayMutating_IntValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_ClassValueBuffer1", runFunction: run_ExistentialTestArrayOneMethodCall_ClassValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_ClassValueBuffer2", runFunction: run_ExistentialTestArrayOneMethodCall_ClassValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_ClassValueBuffer3", runFunction: run_ExistentialTestArrayOneMethodCall_ClassValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_ClassValueBuffer4", runFunction: run_ExistentialTestArrayOneMethodCall_ClassValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_IntValueBuffer0", runFunction: run_ExistentialTestArrayOneMethodCall_IntValueBuffer0, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_IntValueBuffer1", runFunction: run_ExistentialTestArrayOneMethodCall_IntValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_IntValueBuffer2", runFunction: run_ExistentialTestArrayOneMethodCall_IntValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_IntValueBuffer3", runFunction: run_ExistentialTestArrayOneMethodCall_IntValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayOneMethodCall_IntValueBuffer4", runFunction: run_ExistentialTestArrayOneMethodCall_IntValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_ClassValueBuffer1", runFunction: run_ExistentialTestArrayShift_ClassValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_ClassValueBuffer2", runFunction: run_ExistentialTestArrayShift_ClassValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_ClassValueBuffer3", runFunction: run_ExistentialTestArrayShift_ClassValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_ClassValueBuffer4", runFunction: run_ExistentialTestArrayShift_ClassValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_IntValueBuffer0", runFunction: run_ExistentialTestArrayShift_IntValueBuffer0, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_IntValueBuffer1", runFunction: run_ExistentialTestArrayShift_IntValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_IntValueBuffer2", runFunction: run_ExistentialTestArrayShift_IntValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_IntValueBuffer3", runFunction: run_ExistentialTestArrayShift_IntValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayShift_IntValueBuffer4", runFunction: run_ExistentialTestArrayShift_IntValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer1", runFunction: run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer2", runFunction: run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer3", runFunction: run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer4", runFunction: run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_IntValueBuffer0", runFunction: run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer0, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_IntValueBuffer1", runFunction: run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer1, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_IntValueBuffer2", runFunction: run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer2, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_IntValueBuffer3", runFunction: run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer3, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestArrayTwoMethodCalls_IntValueBuffer4", runFunction: run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer4, tags: [.unstable, .api, .Array]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_ClassValueBuffer1", runFunction: run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_ClassValueBuffer2", runFunction: run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_ClassValueBuffer3", runFunction: run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_ClassValueBuffer4", runFunction: run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_IntValueBuffer0", runFunction: run_ExistentialTestMutatingAndNonMutating_IntValueBuffer0, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_IntValueBuffer1", runFunction: run_ExistentialTestMutatingAndNonMutating_IntValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_IntValueBuffer2", runFunction: run_ExistentialTestMutatingAndNonMutating_IntValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_IntValueBuffer3", runFunction: run_ExistentialTestMutatingAndNonMutating_IntValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutatingAndNonMutating_IntValueBuffer4", runFunction: run_ExistentialTestMutatingAndNonMutating_IntValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_ClassValueBuffer1", runFunction: run_ExistentialTestMutating_ClassValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_ClassValueBuffer2", runFunction: run_ExistentialTestMutating_ClassValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_ClassValueBuffer3", runFunction: run_ExistentialTestMutating_ClassValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_ClassValueBuffer4", runFunction: run_ExistentialTestMutating_ClassValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_IntValueBuffer0", runFunction: run_ExistentialTestMutating_IntValueBuffer0, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_IntValueBuffer1", runFunction: run_ExistentialTestMutating_IntValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_IntValueBuffer2", runFunction: run_ExistentialTestMutating_IntValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_IntValueBuffer3", runFunction: run_ExistentialTestMutating_IntValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestMutating_IntValueBuffer4", runFunction: run_ExistentialTestMutating_IntValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_ClassValueBuffer1", runFunction: run_ExistentialTestOneMethodCall_ClassValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_ClassValueBuffer2", runFunction: run_ExistentialTestOneMethodCall_ClassValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_ClassValueBuffer3", runFunction: run_ExistentialTestOneMethodCall_ClassValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_ClassValueBuffer4", runFunction: run_ExistentialTestOneMethodCall_ClassValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_IntValueBuffer0", runFunction: run_ExistentialTestOneMethodCall_IntValueBuffer0, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_IntValueBuffer1", runFunction: run_ExistentialTestOneMethodCall_IntValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_IntValueBuffer2", runFunction: run_ExistentialTestOneMethodCall_IntValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_IntValueBuffer3", runFunction: run_ExistentialTestOneMethodCall_IntValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestOneMethodCall_IntValueBuffer4", runFunction: run_ExistentialTestOneMethodCall_IntValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer1", runFunction: run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer2", runFunction: run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer3", runFunction: run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer4", runFunction: run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer0", runFunction: run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer0, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer1", runFunction: run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer2", runFunction: run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer3", runFunction: run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer4", runFunction: run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer1", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer2", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer3", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer4", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer0", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer0, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer1", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer2", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer3", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer4", runFunction: run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_ClassValueBuffer1", runFunction: run_ExistentialTestTwoMethodCalls_ClassValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_ClassValueBuffer2", runFunction: run_ExistentialTestTwoMethodCalls_ClassValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_ClassValueBuffer3", runFunction: run_ExistentialTestTwoMethodCalls_ClassValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_ClassValueBuffer4", runFunction: run_ExistentialTestTwoMethodCalls_ClassValueBuffer4, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_IntValueBuffer0", runFunction: run_ExistentialTestTwoMethodCalls_IntValueBuffer0, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_IntValueBuffer1", runFunction: run_ExistentialTestTwoMethodCalls_IntValueBuffer1, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_IntValueBuffer2", runFunction: run_ExistentialTestTwoMethodCalls_IntValueBuffer2, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_IntValueBuffer3", runFunction: run_ExistentialTestTwoMethodCalls_IntValueBuffer3, tags: [.unstable]),
+  BenchmarkInfo(name: "ExistentialTestTwoMethodCalls_IntValueBuffer4", runFunction: run_ExistentialTestTwoMethodCalls_IntValueBuffer4, tags: [.unstable]),
+]
+
 protocol Existential {
   init()
   func doIt() -> Bool
diff --git a/benchmark/single-source/Fibonacci.swift b/benchmark/single-source/Fibonacci.swift
index 044fb98..b6588f7 100644
--- a/benchmark/single-source/Fibonacci.swift
+++ b/benchmark/single-source/Fibonacci.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let Fibonacci = BenchmarkInfo(
+  name: "Fibonacci",
+  runFunction: run_Fibonacci,
+  tags: [.unstable, .algorithm])
+
 func fibonacci(_ n: Int) -> Int {
   if (n < 2) { return 1 }
   return fibonacci(n - 2) + fibonacci(n - 1)
diff --git a/benchmark/single-source/Hanoi.swift b/benchmark/single-source/Hanoi.swift
index 4de111c..9f21acd 100644
--- a/benchmark/single-source/Hanoi.swift
+++ b/benchmark/single-source/Hanoi.swift
@@ -15,6 +15,11 @@
 import Foundation
 import TestsUtils
 
+public let Hanoi = BenchmarkInfo(
+  name: "Hanoi",
+  runFunction: run_Hanoi,
+  tags: [.validation, .algorithm])
+
 struct Move {
    var from: String
    var to: String
diff --git a/benchmark/single-source/Hash.swift b/benchmark/single-source/Hash.swift
index b813be8..646fcd4 100644
--- a/benchmark/single-source/Hash.swift
+++ b/benchmark/single-source/Hash.swift
@@ -15,6 +15,11 @@
 //         http://en.wikipedia.org/wiki/SHA-1
 import TestsUtils
 
+public let HashTest = BenchmarkInfo(
+  name: "HashTest",
+  runFunction: run_HashTest,
+  tags: [.validation, .algorithm])
+
 class Hash {
   /// \brief C'tor.
   init(_ bs: Int) {
diff --git a/benchmark/single-source/HashQuadratic.swift b/benchmark/single-source/HashQuadratic.swift
index 6be3f60..3966554 100644
--- a/benchmark/single-source/HashQuadratic.swift
+++ b/benchmark/single-source/HashQuadratic.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let HashQuadratic = BenchmarkInfo(
+  name: "HashQuadratic",
+  runFunction: run_HashQuadratic,
+  tags: [.unstable, .api, .Dictionary])
+
 let size = 3_000_000
 
 @inline(never)
diff --git a/benchmark/single-source/Histogram.swift b/benchmark/single-source/Histogram.swift
index 3bb350e..e6bd196 100644
--- a/benchmark/single-source/Histogram.swift
+++ b/benchmark/single-source/Histogram.swift
@@ -14,6 +14,11 @@
 // <rdar://problem/17384894>
 import TestsUtils
 
+public let Histogram = BenchmarkInfo(
+  name: "Histogram",
+  runFunction: run_Histogram,
+  tags: [.validation, .algorithm])
+
 typealias rrggbb_t = UInt32
 
 func output_sorted_sparse_rgb_histogram<S: Sequence>(_ samples: S, _ N: Int)
diff --git a/benchmark/single-source/Integrate.swift b/benchmark/single-source/Integrate.swift
index b10c5fb..2d5b1aa 100644
--- a/benchmark/single-source/Integrate.swift
+++ b/benchmark/single-source/Integrate.swift
@@ -15,6 +15,11 @@
 // A micro-benchmark for recursive divide and conquer problems.
 // The program performs integration via Gaussian Quadrature
 
+public let IntegrateTest = BenchmarkInfo(
+  name: "Integrate",
+  runFunction: run_Integrate,
+  tags: [.validation, .algorithm])
+
 class Integrate {
   static let epsilon = 1.0e-9
 
diff --git a/benchmark/single-source/IterateData.swift b/benchmark/single-source/IterateData.swift
index a455890..95d9444 100644
--- a/benchmark/single-source/IterateData.swift
+++ b/benchmark/single-source/IterateData.swift
@@ -13,6 +13,11 @@
 import TestsUtils
 import Foundation
 
+public let IterateData = BenchmarkInfo(
+  name: "IterateData",
+  runFunction: run_IterateData,
+  tags: [.validation, .api])
+
 @inline(never)
 func generateData() -> Data {
   var data = Data(count: 16 * 1024)
diff --git a/benchmark/single-source/Join.swift b/benchmark/single-source/Join.swift
index 6960cdb..0934996 100644
--- a/benchmark/single-source/Join.swift
+++ b/benchmark/single-source/Join.swift
@@ -13,6 +13,11 @@
 // This test tests the performance of ASCII Character comparison.
 import TestsUtils
 
+public let Join = BenchmarkInfo(
+  name: "Join",
+  runFunction: run_Join,
+  tags: [.validation, .api, .String, .Array])
+
 @inline(never)
 public func run_Join(_ N: Int) {
   var array: [String] = []
diff --git a/benchmark/single-source/LazyFilter.swift b/benchmark/single-source/LazyFilter.swift
index 27f56e1..dc672d0 100644
--- a/benchmark/single-source/LazyFilter.swift
+++ b/benchmark/single-source/LazyFilter.swift
@@ -14,6 +14,11 @@
 // collections.
 import TestsUtils
 
+public let LazyFilter = [
+  BenchmarkInfo(name: "LazilyFilteredArrays", runFunction: run_LazilyFilteredArrays, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "LazilyFilteredRange", runFunction: run_LazilyFilteredRange, tags: [.validation, .api, .Array]),
+]
+
 @inline(never)
 public func run_LazilyFilteredRange(_ N: Int) {
   var res = 123
diff --git a/benchmark/single-source/MapReduce.swift b/benchmark/single-source/MapReduce.swift
index dd396b0..c852578 100644
--- a/benchmark/single-source/MapReduce.swift
+++ b/benchmark/single-source/MapReduce.swift
@@ -13,6 +13,21 @@
 import TestsUtils
 import Foundation
 
+public let MapReduce = [
+  BenchmarkInfo(name: "MapReduce", runFunction: run_MapReduce, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceAnyCollection", runFunction: run_MapReduceAnyCollection, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceAnyCollectionShort", runFunction: run_MapReduceAnyCollectionShort, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceClass", runFunction: run_MapReduceClass, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceClassShort", runFunction: run_MapReduceClassShort, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceLazyCollection", runFunction: run_MapReduceLazyCollection, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceLazyCollectionShort", runFunction: run_MapReduceLazyCollectionShort, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceLazySequence", runFunction: run_MapReduceLazySequence, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceSequence", runFunction: run_MapReduceSequence, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceShort", runFunction: run_MapReduceShort, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "MapReduceShortString", runFunction: run_MapReduceShortString, tags: [.validation, .algorithm, .String]),
+  BenchmarkInfo(name: "MapReduceString", runFunction: run_MapReduceString, tags: [.validation, .algorithm, .String]),
+]
+
 @inline(never)
 public func run_MapReduce(_ N: Int) {
   var numbers = [Int](0..<1000)
diff --git a/benchmark/single-source/Memset.swift b/benchmark/single-source/Memset.swift
index c7ae7b2..226a2e1 100644
--- a/benchmark/single-source/Memset.swift
+++ b/benchmark/single-source/Memset.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let Memset = BenchmarkInfo(
+  name: "Memset",
+  runFunction: run_Memset,
+  tags: [.validation])
+
 @inline(never)
 func memset(_ a: inout [Int], _ c: Int) {
   for i in 0..<a.count {
diff --git a/benchmark/single-source/MonteCarloE.swift b/benchmark/single-source/MonteCarloE.swift
index 148b37d..db69534 100644
--- a/benchmark/single-source/MonteCarloE.swift
+++ b/benchmark/single-source/MonteCarloE.swift
@@ -19,6 +19,11 @@
 // Thus, e = N / Nempty.
 import TestsUtils
 
+public let MonteCarloE = BenchmarkInfo(
+  name: "MonteCarloE",
+  runFunction: run_MonteCarloE,
+  tags: [.validation, .algorithm])
+
 public func run_MonteCarloE(scale: Int) {
   let N = 200000*scale
   var intervals = [Bool](repeating: false, count: N)
diff --git a/benchmark/single-source/MonteCarloPi.swift b/benchmark/single-source/MonteCarloPi.swift
index 00dd0c0..39cfb76 100644
--- a/benchmark/single-source/MonteCarloPi.swift
+++ b/benchmark/single-source/MonteCarloPi.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let MonteCarloPi = BenchmarkInfo(
+  name: "MonteCarloPi",
+  runFunction: run_MonteCarloPi,
+  tags: [.validation, .algorithm])
+
 public func run_MonteCarloPi(scale: Int) {
   var pointsInside = 0
   let r = 10000
diff --git a/benchmark/single-source/NSDictionaryCastToSwift.swift b/benchmark/single-source/NSDictionaryCastToSwift.swift
index e88495a..c9d0550 100644
--- a/benchmark/single-source/NSDictionaryCastToSwift.swift
+++ b/benchmark/single-source/NSDictionaryCastToSwift.swift
@@ -18,6 +18,11 @@
 import Foundation
 import TestsUtils
 
+public let NSDictionaryCastToSwift = BenchmarkInfo(
+  name: "NSDictionaryCastToSwift",
+  runFunction: run_NSDictionaryCastToSwift,
+  tags: [.validation, .api, .Dictionary, .bridging])
+
 @inline(never)
 public func run_NSDictionaryCastToSwift(_ N: Int) {
 #if _runtime(_ObjC)
diff --git a/benchmark/single-source/NSError.swift b/benchmark/single-source/NSError.swift
index 339b812..4be909c 100644
--- a/benchmark/single-source/NSError.swift
+++ b/benchmark/single-source/NSError.swift
@@ -13,6 +13,11 @@
 import TestsUtils
 import Foundation
 
+public let NSErrorTest = BenchmarkInfo(
+  name: "NSError",
+  runFunction: run_NSError,
+  tags: [.validation, .exceptions, .bridging])
+
 protocol P {
   func buzz() throws -> Int
 }
diff --git a/benchmark/single-source/NSStringConversion.swift b/benchmark/single-source/NSStringConversion.swift
index 40b312f..b582088 100644
--- a/benchmark/single-source/NSStringConversion.swift
+++ b/benchmark/single-source/NSStringConversion.swift
@@ -14,6 +14,11 @@
 import TestsUtils
 import Foundation
 
+public let NSStringConversion = BenchmarkInfo(
+  name: "NSStringConversion",
+  runFunction: run_NSStringConversion,
+  tags: [.validation, .api, .String, .bridging])
+
 public func run_NSStringConversion(_ N: Int) {
 #if _runtime(_ObjC)
 let test:NSString = NSString(cString: "test", encoding: String.Encoding.ascii.rawValue)!
diff --git a/benchmark/single-source/NopDeinit.swift b/benchmark/single-source/NopDeinit.swift
index 7311162..eb1192f 100644
--- a/benchmark/single-source/NopDeinit.swift
+++ b/benchmark/single-source/NopDeinit.swift
@@ -13,6 +13,11 @@
 // <rdar://problem/17838787>
 import TestsUtils
 
+public let NopDeinit = BenchmarkInfo(
+  name: "NopDeinit",
+  runFunction: run_NopDeinit,
+  tags: [.regression])
+
 class X<T : Comparable> {
   let deinitIters = 10000
   var elem: T
diff --git a/benchmark/single-source/ObjectiveCBridging.swift b/benchmark/single-source/ObjectiveCBridging.swift
index ac3594b..281d802 100644
--- a/benchmark/single-source/ObjectiveCBridging.swift
+++ b/benchmark/single-source/ObjectiveCBridging.swift
@@ -13,6 +13,27 @@
 import TestsUtils
 import Foundation
 
+public let ObjectiveCBridging = [
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSString", runFunction: run_ObjectiveCBridgeFromNSString, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSStringForced", runFunction: run_ObjectiveCBridgeFromNSStringForced, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeToNSString", runFunction: run_ObjectiveCBridgeToNSString, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSArrayAnyObject", runFunction: run_ObjectiveCBridgeFromNSArrayAnyObject, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSArrayAnyObjectForced", runFunction: run_ObjectiveCBridgeFromNSArrayAnyObjectForced, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeToNSArray", runFunction: run_ObjectiveCBridgeToNSArray, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSArrayAnyObjectToString", runFunction: run_ObjectiveCBridgeFromNSArrayAnyObjectToString, tags: [.validation, .bridging, .String]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSArrayAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSArrayAnyObjectToStringForced, tags: [.validation, .bridging, .String]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObject", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObject, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectForced", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectForced, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeToNSDictionary", runFunction: run_ObjectiveCBridgeToNSDictionary, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectToString", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectToString, tags: [.validation, .bridging, .String]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced, tags: [.validation, .bridging, .String]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObject", runFunction: run_ObjectiveCBridgeFromNSSetAnyObject, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObjectForced", runFunction: run_ObjectiveCBridgeFromNSSetAnyObjectForced, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeToNSSet", runFunction: run_ObjectiveCBridgeToNSSet, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObjectToString", runFunction: run_ObjectiveCBridgeFromNSSetAnyObjectToString, tags: [.validation, .bridging, .String]),
+  BenchmarkInfo(name: "ObjectiveCBridgeFromNSSetAnyObjectToStringForced", runFunction: run_ObjectiveCBridgeFromNSSetAnyObjectToStringForced, tags: [.validation, .bridging, .String]),
+]
+
 #if _runtime(_ObjC)
 @inline(never)
 public func forcedCast<NS, T>(_ ns: NS) -> T {
diff --git a/benchmark/single-source/ObjectiveCBridgingStubs.swift b/benchmark/single-source/ObjectiveCBridgingStubs.swift
index 430ed66..f5d1c4c 100644
--- a/benchmark/single-source/ObjectiveCBridgingStubs.swift
+++ b/benchmark/single-source/ObjectiveCBridgingStubs.swift
@@ -16,6 +16,19 @@
 import ObjectiveCTests
 #endif
 
+public let ObjectiveCBridgingStubs = [
+  BenchmarkInfo(name: "ObjectiveCBridgeStubDataAppend", runFunction: run_ObjectiveCBridgeStubDataAppend, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubDateAccess", runFunction: run_ObjectiveCBridgeStubDateAccess, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubDateMutation", runFunction: run_ObjectiveCBridgeStubDateMutation, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubFromArrayOfNSString", runFunction: run_ObjectiveCBridgeStubFromArrayOfNSString, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSDate", runFunction: run_ObjectiveCBridgeStubFromNSDate, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSString", runFunction: run_ObjectiveCBridgeStubFromNSString, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubToArrayOfNSString", runFunction: run_ObjectiveCBridgeStubToArrayOfNSString, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubToNSDate", runFunction: run_ObjectiveCBridgeStubToNSDate, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubToNSString", runFunction: run_ObjectiveCBridgeStubToNSString, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubURLAppendPath", runFunction: run_ObjectiveCBridgeStubURLAppendPath, tags: [.validation, .bridging]),
+]
+
 #if _runtime(_ObjC)
 @inline(never)
 func testObjectiveCBridgeStubFromNSString() {
diff --git a/benchmark/single-source/ObjectiveCNoBridgingStubs.swift b/benchmark/single-source/ObjectiveCNoBridgingStubs.swift
index e77534a..46b8cd6 100644
--- a/benchmark/single-source/ObjectiveCNoBridgingStubs.swift
+++ b/benchmark/single-source/ObjectiveCNoBridgingStubs.swift
@@ -21,6 +21,17 @@
 import ObjectiveCTests
 #endif
 
+public let ObjectiveCNoBridgingStubs = [
+  BenchmarkInfo(name: "ObjectiveCBridgeStubToNSStringRef", runFunction: run_ObjectiveCBridgeStubToNSStringRef, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubToNSDateRef", runFunction: run_ObjectiveCBridgeStubToNSDateRef, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubNSDateRefAccess", runFunction: run_ObjectiveCBridgeStubNSDateRefAccess, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubNSDateMutationRef", runFunction: run_ObjectiveCBridgeStubNSDateMutationRef, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubNSDataAppend", runFunction: run_ObjectiveCBridgeStubNSDataAppend, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSStringRef", runFunction: run_ObjectiveCBridgeStubFromNSStringRef, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubFromNSDateRef", runFunction: run_ObjectiveCBridgeStubFromNSDateRef, tags: [.validation, .bridging]),
+  BenchmarkInfo(name: "ObjectiveCBridgeStubURLAppendPathRef", runFunction: run_ObjectiveCBridgeStubURLAppendPathRef, tags: [.validation, .bridging]),
+]
+
 #if _runtime(_ObjC)
 @inline(never)
 func testObjectiveCBridgeStubFromNSStringRef() {
diff --git a/benchmark/single-source/ObserverClosure.swift b/benchmark/single-source/ObserverClosure.swift
index 2f9a888..debbf03 100644
--- a/benchmark/single-source/ObserverClosure.swift
+++ b/benchmark/single-source/ObserverClosure.swift
@@ -10,6 +10,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+
+public let ObserverClosure = BenchmarkInfo(
+  name: "ObserverClosure",
+  runFunction: run_ObserverClosure,
+  tags: [.validation])
+
 class Observer {
   @inline(never)
   func receive(_ value: Int) {
diff --git a/benchmark/single-source/ObserverForwarderStruct.swift b/benchmark/single-source/ObserverForwarderStruct.swift
index 74c73c0..54334e4 100644
--- a/benchmark/single-source/ObserverForwarderStruct.swift
+++ b/benchmark/single-source/ObserverForwarderStruct.swift
@@ -10,6 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let ObserverForwarderStruct = BenchmarkInfo(
+  name: "ObserverForwarderStruct",
+  runFunction: run_ObserverForwarderStruct,
+  tags: [.validation])
+
 class Observer {
   @inline(never)
   func receive(_ value: Int) {
diff --git a/benchmark/single-source/ObserverPartiallyAppliedMethod.swift b/benchmark/single-source/ObserverPartiallyAppliedMethod.swift
index 6ff262b..6aea587 100644
--- a/benchmark/single-source/ObserverPartiallyAppliedMethod.swift
+++ b/benchmark/single-source/ObserverPartiallyAppliedMethod.swift
@@ -10,6 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let ObserverPartiallyAppliedMethod = BenchmarkInfo(
+  name: "ObserverPartiallyAppliedMethod",
+  runFunction: run_ObserverPartiallyAppliedMethod,
+  tags: [.validation])
+
 class Observer {
   @inline(never)
   func receive(_ value: Int) {
diff --git a/benchmark/single-source/ObserverUnappliedMethod.swift b/benchmark/single-source/ObserverUnappliedMethod.swift
index 07de3f9..52a4b3e 100644
--- a/benchmark/single-source/ObserverUnappliedMethod.swift
+++ b/benchmark/single-source/ObserverUnappliedMethod.swift
@@ -10,6 +10,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let ObserverUnappliedMethod = BenchmarkInfo(
+  name: "ObserverUnappliedMethod",
+  runFunction: run_ObserverUnappliedMethod,
+  tags: [.validation])
+
 class Observer {
   @inline(never)
   func receive(_ value: Int) {
diff --git a/benchmark/single-source/OpenClose.swift b/benchmark/single-source/OpenClose.swift
index 7c411c6..d215d9e 100644
--- a/benchmark/single-source/OpenClose.swift
+++ b/benchmark/single-source/OpenClose.swift
@@ -15,6 +15,10 @@
 
 
 // A micro benchmark for checking the speed of string-based enums.
+public let OpenClose = BenchmarkInfo(
+  name: "OpenClose",
+  runFunction: run_OpenClose,
+  tags: [.validation, .api, .String])
 
 enum MyState : String {
     case Closed = "Closed"
diff --git a/benchmark/single-source/Phonebook.swift b/benchmark/single-source/Phonebook.swift
index 8a36a1e..043cd53 100644
--- a/benchmark/single-source/Phonebook.swift
+++ b/benchmark/single-source/Phonebook.swift
@@ -14,6 +14,11 @@
 // for performance measuring.
 import TestsUtils
 
+public let Phonebook = BenchmarkInfo(
+  name: "Phonebook",
+  runFunction: run_Phonebook,
+  tags: [.validation, .api, .String])
+
 var words = [
   "James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph",
   "Charles", "Thomas", "Christopher", "Daniel", "Matthew", "Donald", "Anthony",
diff --git a/benchmark/single-source/PopFront.swift b/benchmark/single-source/PopFront.swift
index 0ceca23..9abe8a7 100644
--- a/benchmark/single-source/PopFront.swift
+++ b/benchmark/single-source/PopFront.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let PopFront = [
+  BenchmarkInfo(name: "PopFrontArray", runFunction: run_PopFrontArray, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "PopFrontUnsafePointer", runFunction: run_PopFrontUnsafePointer, tags: [.validation, .api]),
+]
+
 let reps = 1
 let arrayCount = 1024
 
diff --git a/benchmark/single-source/PopFrontGeneric.swift b/benchmark/single-source/PopFrontGeneric.swift
index b1cd5d5..01ec74e 100644
--- a/benchmark/single-source/PopFrontGeneric.swift
+++ b/benchmark/single-source/PopFrontGeneric.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let PopFrontArrayGeneric = BenchmarkInfo(
+  name: "PopFrontArrayGeneric",
+  runFunction: run_PopFrontArrayGeneric,
+  tags: [.validation, .api, .Array])
+
 let reps = 1
 let arrayCount = 1024
 
diff --git a/benchmark/single-source/Prefix.swift b/benchmark/single-source/Prefix.swift
index d1cd354..3f0905f 100644
--- a/benchmark/single-source/Prefix.swift
+++ b/benchmark/single-source/Prefix.swift
@@ -22,6 +22,65 @@
 let prefixCount = sequenceCount - 1024
 let sumCount = prefixCount * (prefixCount - 1) / 2
 
+public let Prefix = [
+  BenchmarkInfo(
+    name: "PrefixCountableRange",
+    runFunction: run_PrefixCountableRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixSequence",
+    runFunction: run_PrefixSequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnySequence",
+    runFunction: run_PrefixAnySequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnySeqCntRange",
+    runFunction: run_PrefixAnySeqCntRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnySeqCRangeIter",
+    runFunction: run_PrefixAnySeqCRangeIter,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnyCollection",
+    runFunction: run_PrefixAnyCollection,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixArray",
+    runFunction: run_PrefixArray,
+    tags: [.validation, .api, .Array]),
+  BenchmarkInfo(
+    name: "PrefixCountableRangeLazy",
+    runFunction: run_PrefixCountableRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixSequenceLazy",
+    runFunction: run_PrefixSequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnySequenceLazy",
+    runFunction: run_PrefixAnySequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnySeqCntRangeLazy",
+    runFunction: run_PrefixAnySeqCntRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnySeqCRangeIterLazy",
+    runFunction: run_PrefixAnySeqCRangeIterLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixAnyCollectionLazy",
+    runFunction: run_PrefixAnyCollectionLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixArrayLazy",
+    runFunction: run_PrefixArrayLazy,
+    tags: [.validation, .api]),
+]
+
 @inline(never)
 public func run_PrefixCountableRange(_ N: Int) {
   let s = 0..<sequenceCount
diff --git a/benchmark/single-source/Prefix.swift.gyb b/benchmark/single-source/Prefix.swift.gyb
index 19ba2b1..ceec6cf 100644
--- a/benchmark/single-source/Prefix.swift.gyb
+++ b/benchmark/single-source/Prefix.swift.gyb
@@ -41,6 +41,15 @@
 Sequences = Sequences + map(lazy, Sequences)
 }%
 
+public let Prefix = [
+% for (Name, Expr) in Sequences:
+  BenchmarkInfo(
+    name: "Prefix${Name}",
+    runFunction: run_Prefix${Name},
+    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+% end
+]
+
 % for (Name, Expr) in Sequences:
 @inline(never)
 public func run_Prefix${Name}(_ N: Int) {
diff --git a/benchmark/single-source/PrefixWhile.swift b/benchmark/single-source/PrefixWhile.swift
index 8877caf..f8da0c9 100644
--- a/benchmark/single-source/PrefixWhile.swift
+++ b/benchmark/single-source/PrefixWhile.swift
@@ -22,6 +22,65 @@
 let prefixCount = sequenceCount - 1024
 let sumCount = prefixCount * (prefixCount - 1) / 2
 
+public let PrefixWhile = [
+  BenchmarkInfo(
+    name: "PrefixWhileCountableRange",
+    runFunction: run_PrefixWhileCountableRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileSequence",
+    runFunction: run_PrefixWhileSequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnySequence",
+    runFunction: run_PrefixWhileAnySequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnySeqCntRange",
+    runFunction: run_PrefixWhileAnySeqCntRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnySeqCRangeIter",
+    runFunction: run_PrefixWhileAnySeqCRangeIter,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnyCollection",
+    runFunction: run_PrefixWhileAnyCollection,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileArray",
+    runFunction: run_PrefixWhileArray,
+    tags: [.validation, .api, .Array]),
+  BenchmarkInfo(
+    name: "PrefixWhileCountableRangeLazy",
+    runFunction: run_PrefixWhileCountableRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileSequenceLazy",
+    runFunction: run_PrefixWhileSequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnySequenceLazy",
+    runFunction: run_PrefixWhileAnySequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnySeqCntRangeLazy",
+    runFunction: run_PrefixWhileAnySeqCntRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnySeqCRangeIterLazy",
+    runFunction: run_PrefixWhileAnySeqCRangeIterLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileAnyCollectionLazy",
+    runFunction: run_PrefixWhileAnyCollectionLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "PrefixWhileArrayLazy",
+    runFunction: run_PrefixWhileArrayLazy,
+    tags: [.validation, .api]),
+]
+
 @inline(never)
 public func run_PrefixWhileCountableRange(_ N: Int) {
   let s = 0..<sequenceCount
diff --git a/benchmark/single-source/PrefixWhile.swift.gyb b/benchmark/single-source/PrefixWhile.swift.gyb
index e2018a2..302611e 100644
--- a/benchmark/single-source/PrefixWhile.swift.gyb
+++ b/benchmark/single-source/PrefixWhile.swift.gyb
@@ -41,6 +41,15 @@
 Sequences = Sequences + map(lazy, Sequences)
 }%
 
+public let PrefixWhile = [
+% for (Name, Expr) in Sequences:
+  BenchmarkInfo(
+    name: "PrefixWhile${Name}",
+    runFunction: run_PrefixWhile${Name},
+    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+% end
+]
+
 % for (Name, Expr) in Sequences:
 @inline(never)
 public func run_PrefixWhile${Name}(_ N: Int) {
diff --git a/benchmark/single-source/Prims.swift b/benchmark/single-source/Prims.swift
index efd8834..d763f20 100644
--- a/benchmark/single-source/Prims.swift
+++ b/benchmark/single-source/Prims.swift
@@ -22,6 +22,11 @@
 // update the heap fast when we add a new node to the tree.
 import TestsUtils
 
+public let Prims = BenchmarkInfo(
+  name: "Prims",
+  runFunction: run_Prims,
+  tags: [.validation, .algorithm])
+
 class PriorityQueue {
   final var heap: Array<EdgeCost>
   final var graphIndexToHeapIndexMap: Array<Int?>
diff --git a/benchmark/single-source/ProtocolDispatch.swift b/benchmark/single-source/ProtocolDispatch.swift
index 3da8d84..515c875 100644
--- a/benchmark/single-source/ProtocolDispatch.swift
+++ b/benchmark/single-source/ProtocolDispatch.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let ProtocolDispatch = BenchmarkInfo(
+  name: "ProtocolDispatch",
+  runFunction: run_ProtocolDispatch,
+  tags: [.validation, .abstraction])
+
 @inline(never)
 public func run_ProtocolDispatch(_ N: Int) {
 
diff --git a/benchmark/single-source/ProtocolDispatch2.swift b/benchmark/single-source/ProtocolDispatch2.swift
index f2e21f8..8fda9c7 100644
--- a/benchmark/single-source/ProtocolDispatch2.swift
+++ b/benchmark/single-source/ProtocolDispatch2.swift
@@ -17,6 +17,11 @@
 import TestsUtils
 import Foundation
 
+public let ProtocolDispatch2 = BenchmarkInfo(
+  name: "ProtocolDispatch2",
+  runFunction: run_ProtocolDispatch2,
+  tags: [.validation, .abstraction])
+
 protocol Pingable { func ping() -> Int;  func pong() -> Int}
 
 struct Game : Pingable {
diff --git a/benchmark/single-source/RC4.swift b/benchmark/single-source/RC4.swift
index e774d2c..345caa9 100644
--- a/benchmark/single-source/RC4.swift
+++ b/benchmark/single-source/RC4.swift
@@ -14,6 +14,11 @@
 // for performance measuring.
 import TestsUtils
 
+public let RC4Test = BenchmarkInfo(
+  name: "RC4",
+  runFunction: run_RC4,
+  tags: [.validation, .algorithm])
+
 struct RC4 {
   var State : [UInt8]
   var I: UInt8 = 0
diff --git a/benchmark/single-source/RGBHistogram.swift b/benchmark/single-source/RGBHistogram.swift
index 179243d..c2853bc 100644
--- a/benchmark/single-source/RGBHistogram.swift
+++ b/benchmark/single-source/RGBHistogram.swift
@@ -18,6 +18,11 @@
 import Foundation
 import TestsUtils
 
+public let RGBHistogram = [
+  BenchmarkInfo(name: "RGBHistogram", runFunction: run_RGBHistogram, tags: [.validation, .algorithm]),
+  BenchmarkInfo(name: "RGBHistogramOfObjects", runFunction: run_RGBHistogramOfObjects, tags: [.validation, .algorithm]),
+]
+
 @inline(never)
 public func run_RGBHistogram(_ N: Int) {
     var histogram = [(key: rrggbb_t, value: Int)]()
diff --git a/benchmark/single-source/RangeAssignment.swift b/benchmark/single-source/RangeAssignment.swift
index d423261..330852c 100644
--- a/benchmark/single-source/RangeAssignment.swift
+++ b/benchmark/single-source/RangeAssignment.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let RangeAssignment = BenchmarkInfo(
+  name: "RangeAssignment",
+  runFunction: run_RangeAssignment,
+  tags: [.validation, .api])
+
 @inline(never)
 public func run_RangeAssignment(_ scale: Int) {
   let range: Range = 100..<200
diff --git a/benchmark/single-source/RangeIteration.swift b/benchmark/single-source/RangeIteration.swift
new file mode 100644
index 0000000..2465954
--- /dev/null
+++ b/benchmark/single-source/RangeIteration.swift
@@ -0,0 +1,77 @@
+//===--- RangeAssignment.swift --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+import TestsUtils
+
+public let RangeIteration = [
+  BenchmarkInfo(
+    name: "RangeIterationSigned",
+    runFunction: run_RangeIterationSigned,
+    tags: [.validation, .api]
+  ),
+  BenchmarkInfo(
+    name: "RangeIterationSigned64",
+    runFunction: run_RangeIterationSigned64,
+    tags: [.validation, .api]
+  ),
+  BenchmarkInfo(
+    name: "RangeIterationUnsigned",
+    runFunction: run_RangeIterationUnsigned,
+    tags: [.validation, .api]
+  ),
+]
+
+public var check: UInt64 = 0
+
+@inline(never)
+func sum(_ x: UInt64, _ y: UInt64) -> UInt64 {
+  return x &+ y
+}
+
+@inline(never)
+public func run_RangeIterationSigned(_ N: Int) {
+  let range = 0..<100000
+  check = 0
+  for _ in 1...N {
+    for e in range {
+      check = sum(check, UInt64(e))
+    }
+  }
+
+  CheckResults(check == 4999950000 * UInt64(N))
+}
+
+@inline(never)
+public func run_RangeIterationSigned64(_ N: Int) {
+  let range: CountableRange<Int64> = 0..<100000
+  check = 0
+  for _ in 1...N {
+    for e in range {
+      check = sum(check, UInt64(e))
+    }
+  }
+
+  CheckResults(check == 4999950000 * UInt64(N))
+}
+
+@inline(never)
+public func run_RangeIterationUnsigned(_ N: Int) {
+  let range: CountableRange<UInt> = 0..<100000
+  check = 0
+  for _ in 1...N {
+    for e in range {
+      check = sum(check, UInt64(e))
+    }
+  }
+
+  CheckResults(check == 4999950000 * UInt64(N))
+}
diff --git a/benchmark/single-source/RecursiveOwnedParameter.swift b/benchmark/single-source/RecursiveOwnedParameter.swift
index 01e134d..6585d38 100644
--- a/benchmark/single-source/RecursiveOwnedParameter.swift
+++ b/benchmark/single-source/RecursiveOwnedParameter.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let RecursiveOwnedParameter = BenchmarkInfo(
+  name: "RecursiveOwnedParameter",
+  runFunction: run_RecursiveOwnedParameter,
+  tags: [.validation, .api, .Array, .refcount])
+
 // This test recursively visits each element of an array in a class and compares
 // it with every value in a different array stored in a different class. The
 // idea is to make sure that we can get rid of the overhead from guaranteed
diff --git a/benchmark/single-source/ReduceInto.swift b/benchmark/single-source/ReduceInto.swift
index e587373..b29b48c 100644
--- a/benchmark/single-source/ReduceInto.swift
+++ b/benchmark/single-source/ReduceInto.swift
@@ -13,6 +13,15 @@
 import TestsUtils
 import Foundation
 
+public let ReduceInto = [
+  BenchmarkInfo(name: "FilterEvenUsingReduce", runFunction: run_FilterEvenUsingReduce, tags: [.validation, .api]),
+  BenchmarkInfo(name: "FilterEvenUsingReduceInto", runFunction: run_FilterEvenUsingReduceInto, tags: [.validation, .api]),
+  BenchmarkInfo(name: "FrequenciesUsingReduce", runFunction: run_FrequenciesUsingReduce, tags: [.validation, .api]),
+  BenchmarkInfo(name: "FrequenciesUsingReduceInto", runFunction: run_FrequenciesUsingReduceInto, tags: [.validation, .api]),
+  BenchmarkInfo(name: "SumUsingReduce", runFunction: run_SumUsingReduce, tags: [.validation, .api]),
+  BenchmarkInfo(name: "SumUsingReduceInto", runFunction: run_SumUsingReduceInto, tags: [.validation, .api]),
+]
+
 // Sum
 
 @inline(never)
diff --git a/benchmark/single-source/ReversedCollections.swift b/benchmark/single-source/ReversedCollections.swift
index bd0e629..58898b5 100644
--- a/benchmark/single-source/ReversedCollections.swift
+++ b/benchmark/single-source/ReversedCollections.swift
@@ -10,6 +10,14 @@
 //
 //===----------------------------------------------------------------------===//
 
+import TestsUtils
+
+public let ReversedCollections = [
+  BenchmarkInfo(name: "ReversedArray", runFunction: run_ReversedArray, tags: [.validation, .api, .Array]),
+  BenchmarkInfo(name: "ReversedBidirectional", runFunction: run_ReversedBidirectional, tags: [.validation, .api]),
+  BenchmarkInfo(name: "ReversedDictionary", runFunction: run_ReversedDictionary, tags: [.validation, .api, .Dictionary]),
+]
+
 // These benchmarks compare the performance of iteration through several
 // collection types after being reversed.
 var x = 0
diff --git a/benchmark/single-source/SetTests.swift b/benchmark/single-source/SetTests.swift
index 9f8faa9..887ee91 100644
--- a/benchmark/single-source/SetTests.swift
+++ b/benchmark/single-source/SetTests.swift
@@ -12,6 +12,17 @@
 
 import TestsUtils
 
+public let SetTests = [
+  BenchmarkInfo(name: "SetExclusiveOr", runFunction: run_SetExclusiveOr, tags: [.validation, .api, .Set]),
+  BenchmarkInfo(name: "SetExclusiveOr_OfObjects", runFunction: run_SetExclusiveOr_OfObjects, tags: [.validation, .api, .Set]),
+  BenchmarkInfo(name: "SetIntersect", runFunction: run_SetIntersect, tags: [.validation, .api, .Set]),
+  BenchmarkInfo(name: "SetIntersect_OfObjects", runFunction: run_SetIntersect_OfObjects, tags: [.validation, .api, .Set]),
+  BenchmarkInfo(name: "SetIsSubsetOf", runFunction: run_SetIsSubsetOf, tags: [.validation, .api, .Set]),
+  BenchmarkInfo(name: "SetIsSubsetOf_OfObjects", runFunction: run_SetIsSubsetOf_OfObjects, tags: [.validation, .api, .Set]),
+  BenchmarkInfo(name: "SetUnion", runFunction: run_SetUnion, tags: [.validation, .api, .Set]),
+  BenchmarkInfo(name: "SetUnion_OfObjects", runFunction: run_SetUnion_OfObjects, tags: [.validation, .api, .Set]),
+]
+
 @inline(never)
 public func run_SetIsSubsetOf(_ N: Int) {
   let size = 200
diff --git a/benchmark/single-source/Sim2DArray.swift b/benchmark/single-source/Sim2DArray.swift
index bb73267..84ebd61 100644
--- a/benchmark/single-source/Sim2DArray.swift
+++ b/benchmark/single-source/Sim2DArray.swift
@@ -9,6 +9,12 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
+import TestsUtils
+
+public let Sim2DArray = BenchmarkInfo(
+  name: "Sim2DArray",
+  runFunction: run_Sim2DArray,
+  tags: [.validation, .api, .Array])
 
 struct Array2D {
   var storage : [Int]
diff --git a/benchmark/single-source/SortLargeExistentials.swift b/benchmark/single-source/SortLargeExistentials.swift
index 69bf91b..7f89982 100644
--- a/benchmark/single-source/SortLargeExistentials.swift
+++ b/benchmark/single-source/SortLargeExistentials.swift
@@ -14,6 +14,11 @@
 
 import TestsUtils
 
+public let SortLargeExistentials = BenchmarkInfo(
+  name: "SortLargeExistentials",
+  runFunction: run_SortLargeExistentials,
+  tags: [.validation, .api, .algorithm])
+
 protocol LetterKind {
   var value: String { get }
   func lessthan(_ rhs: LetterKind) -> Bool
diff --git a/benchmark/single-source/SortLettersInPlace.swift b/benchmark/single-source/SortLettersInPlace.swift
index 2649f02..eae671e 100644
--- a/benchmark/single-source/SortLettersInPlace.swift
+++ b/benchmark/single-source/SortLettersInPlace.swift
@@ -15,6 +15,11 @@
 import Foundation
 import TestsUtils
 
+public let SortLettersInPlace = BenchmarkInfo(
+  name: "SortLettersInPlace",
+  runFunction: run_SortLettersInPlace,
+  tags: [.validation, .api, .algorithm, .String])
+
 class Letter {
   let value: String
   init(_ value: String) {
diff --git a/benchmark/single-source/SortStrings.swift b/benchmark/single-source/SortStrings.swift
index 107392f..6c07960 100644
--- a/benchmark/single-source/SortStrings.swift
+++ b/benchmark/single-source/SortStrings.swift
@@ -9,8 +9,14 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
+import TestsUtils
 
 // Sort an array of strings using an explicit sort predicate.
+public let SortStrings = [
+  BenchmarkInfo(name: "SortSortedStrings", runFunction: run_SortSortedStrings, tags: [.validation, .api, .algorithm, .String]),
+  BenchmarkInfo(name: "SortStrings", runFunction: run_SortStrings, tags: [.validation, .api, .algorithm, .String]),
+  BenchmarkInfo(name: "SortStringsUnicode", runFunction: run_SortStringsUnicode, tags: [.validation, .api, .algorithm, .String]),
+]
 
 var stringBenchmarkWords: [String] = [
   "woodshed",
diff --git a/benchmark/single-source/StackPromo.swift b/benchmark/single-source/StackPromo.swift
index 4426724..392b205 100644
--- a/benchmark/single-source/StackPromo.swift
+++ b/benchmark/single-source/StackPromo.swift
@@ -9,6 +9,12 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
+import TestsUtils
+
+public let StackPromo = BenchmarkInfo(
+  name: "StackPromo",
+  runFunction: run_StackPromo,
+  tags: [.regression])
 
 protocol Proto {
   func at() -> Int
diff --git a/benchmark/single-source/StaticArray.swift b/benchmark/single-source/StaticArray.swift
index 9b6de28..7821f7e 100644
--- a/benchmark/single-source/StaticArray.swift
+++ b/benchmark/single-source/StaticArray.swift
@@ -16,6 +16,11 @@
 
 import TestsUtils
 
+public let StaticArrayTest = BenchmarkInfo(
+  name: "StaticArray",
+  runFunction: run_StaticArray,
+  tags: [.validation, .api, .Array])
+
 protocol StaticArrayProtocol {
   associatedtype ElemTy
   init(_ defaultValue : ElemTy)
diff --git a/benchmark/single-source/StrComplexWalk.swift b/benchmark/single-source/StrComplexWalk.swift
index 4611346..db9f082 100644
--- a/benchmark/single-source/StrComplexWalk.swift
+++ b/benchmark/single-source/StrComplexWalk.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let StrComplexWalk = BenchmarkInfo(
+  name: "StrComplexWalk",
+  runFunction: run_StrComplexWalk,
+  tags: [.validation, .api, .String])
+
 @inline(never)
 public func run_StrComplexWalk(_ N: Int) {
   var s = "निरन्तरान्धकारिता-दिगन्तर-कन्दलदमन्द-सुधारस-बिन्दु-सान्द्रतर-घनाघन-वृन्द-सन्देहकर-स्यन्दमान-मकरन्द-बिन्दु-बन्धुरतर-माकन्द-तरु-कुल-तल्प-कल्प-मृदुल-सिकता-जाल-जटिल-मूल-तल-मरुवक-मिलदलघु-लघु-लय-कलित-रमणीय-पानीय-शालिका-बालिका-करार-विन्द-गलन्तिका-गलदेला-लवङ्ग-पाटल-घनसार-कस्तूरिकातिसौरभ-मेदुर-लघुतर-मधुर-शीतलतर-सलिलधारा-निराकरिष्णु-तदीय-विमल-विलोचन-मयूख-रेखापसारित-पिपासायास-पथिक-लोकान्"
diff --git a/benchmark/single-source/StrToInt.swift b/benchmark/single-source/StrToInt.swift
index 4258549..77cfa1c 100644
--- a/benchmark/single-source/StrToInt.swift
+++ b/benchmark/single-source/StrToInt.swift
@@ -14,6 +14,11 @@
 // It is reported to be very slow: <rdar://problem/17255477>
 import TestsUtils
 
+public let StrToInt = BenchmarkInfo(
+  name: "StrToInt",
+  runFunction: run_StrToInt,
+  tags: [.validation, .api, .String])
+
 @inline(never)
 public func run_StrToInt(_ N: Int) {
   // 64 numbers from -500_000 to 500_000 generated randomly
diff --git a/benchmark/single-source/StringBuilder.swift b/benchmark/single-source/StringBuilder.swift
index 3ea3c5d..72c6b7e 100644
--- a/benchmark/single-source/StringBuilder.swift
+++ b/benchmark/single-source/StringBuilder.swift
@@ -12,6 +12,13 @@
 
 import TestsUtils
 
+public let StringBuilder = [
+  BenchmarkInfo(name: "StringAdder", runFunction: run_StringAdder, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringBuilder", runFunction: run_StringBuilder, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringBuilderLong", runFunction: run_StringBuilderLong, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringUTF16Builder", runFunction: run_StringUTF16Builder, tags: [.validation, .api, .String]),
+]
+
 @inline(never)
 func buildString(_ i: String) -> String {
   var sb = i
diff --git a/benchmark/single-source/StringEdits.swift b/benchmark/single-source/StringEdits.swift
index 10b5419..23fc8bf 100644
--- a/benchmark/single-source/StringEdits.swift
+++ b/benchmark/single-source/StringEdits.swift
@@ -17,6 +17,11 @@
 import Darwin
 #endif
 
+public let StringEdits = BenchmarkInfo(
+  name: "StringEdits",
+  runFunction: run_StringEdits,
+  tags: [.validation, .api, .String])
+
 var editWords: [String] = [
   "woodshed",
   "lakism",
@@ -26,16 +31,13 @@
 let alphabet = "abcdefghijklmnopqrstuvwxyz"
 /// All edits that are one edit away from `word`
 func edits(_ word: String) -> Set<String> {
-  // create right/left splits as CharacterViews instead
-  let splits = word.characters.indices.map {
-    (word.characters[word.characters.startIndex..<$0],word.characters[$0..<word.characters.endIndex])
+  let splits = word.indices.map {
+    (String(word[..<$0]), String(word[$0...]))
   }
   
-  // though it should be, CharacterView isn't hashable
-  // so using an array for now, ignore that aspect...
-  var result: [String.CharacterView] = []
+  var result: Array<String> = []
   
-  for (left,right) in splits {
+  for (left, right) in splits {
     // drop a character
     result.append(left + right.dropFirst())
     
@@ -59,7 +61,7 @@
   }
   
   // have to map back to strings right at the end
-  return Set(result.lazy.map(String.init))
+  return Set(result)
 }
 
 @inline(never)
diff --git a/benchmark/single-source/StringEnum.swift b/benchmark/single-source/StringEnum.swift
index 74573b4..06031eb 100644
--- a/benchmark/single-source/StringEnum.swift
+++ b/benchmark/single-source/StringEnum.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let StringEnum = BenchmarkInfo(
+  name: "StringEnumRawValueInitialization",
+  runFunction: run_StringEnumRawValueInitialization,
+  tags: [.validation, .api, .String])
+
 enum TestEnum : String {
   case c1 = "Swift"
   case c2 = "is"
diff --git a/benchmark/single-source/StringInterpolation.swift b/benchmark/single-source/StringInterpolation.swift
index 337f43d..cc33905 100644
--- a/benchmark/single-source/StringInterpolation.swift
+++ b/benchmark/single-source/StringInterpolation.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let StringInterpolation = BenchmarkInfo(
+  name: "StringInterpolation",
+  runFunction: run_StringInterpolation,
+  tags: [.validation, .api, .String])
+
 class RefTypePrintable : CustomStringConvertible {
   var description: String {
     return "01234567890123456789012345678901234567890123456789"
diff --git a/benchmark/single-source/StringMatch.swift b/benchmark/single-source/StringMatch.swift
index 5afdf69..be30022 100644
--- a/benchmark/single-source/StringMatch.swift
+++ b/benchmark/single-source/StringMatch.swift
@@ -17,6 +17,11 @@
 import Darwin
 #endif
 
+public let StringMatch = BenchmarkInfo(
+  name: "StringMatch",
+  runFunction: run_StringMatch,
+  tags: [.validation, .api, .String])
+
 extension String {
   @inline(__always)
   func dropFirst(_ n: Int = 1) -> String {
diff --git a/benchmark/single-source/StringTests.swift b/benchmark/single-source/StringTests.swift
index 98e59aa..0ff145a 100644
--- a/benchmark/single-source/StringTests.swift
+++ b/benchmark/single-source/StringTests.swift
@@ -11,6 +11,14 @@
 //===----------------------------------------------------------------------===//
 import TestsUtils
 
+public let StringTests = [
+  BenchmarkInfo(name: "StringEqualPointerComparison", runFunction: run_StringEqualPointerComparison, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringHasPrefix", runFunction: run_StringHasPrefix, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringHasPrefixUnicode", runFunction: run_StringHasPrefixUnicode, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringHasSuffix", runFunction: run_StringHasSuffix, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringHasSuffixUnicode", runFunction: run_StringHasSuffixUnicode, tags: [.validation, .api, .String]),
+]
+
 // FIXME(string)
 public func run_StringHasPrefix(_ N: Int) {
 #if _runtime(_ObjC)
diff --git a/benchmark/single-source/StringWalk.swift b/benchmark/single-source/StringWalk.swift
index 1998b23..e5273a0 100644
--- a/benchmark/single-source/StringWalk.swift
+++ b/benchmark/single-source/StringWalk.swift
@@ -34,7 +34,7 @@
     count += 1
   }
 }
-@inline(never) func count_characters(_ s: String.CharacterView) {
+@inline(never) func count_characters(_ s: String) {
   for _ in s {
     count += 1
   }
@@ -47,7 +47,7 @@
   }
 }
 @inline(never) func count_characters_rev(
-  _ s: ReversedCollection<String.CharacterView>
+  _ s: ReversedCollection<String>
 ) {
   for _ in s {
     count += 1
@@ -89,6 +89,413 @@
 let charactersMultiplier = baseMultiplier / 5
 
 
+// An extended benchmark suite exercising finer-granularity behavior of our
+// Strings.
+public var StringWalk = [
+  BenchmarkInfo(
+    name: "StringWalk",
+    runFunction: run_StringWalk,
+    tags: [.validation, .api, .String]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_ascii_unicodeScalars",
+    runFunction: run_StringWalk_ascii_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_ascii_characters",
+    runFunction: run_StringWalk_ascii_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_ascii_unicodeScalars",
+    runFunction: run_CharIteration_ascii_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_ascii_unicodeScalars",
+    runFunction: run_CharIndexing_ascii_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_ascii_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_ascii_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_ascii_characters_Backwards",
+    runFunction: run_StringWalk_ascii_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_ascii_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_ascii_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_ascii_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_ascii_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_utf16_unicodeScalars",
+    runFunction: run_StringWalk_utf16_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_utf16_characters",
+    runFunction: run_StringWalk_utf16_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_utf16_unicodeScalars",
+    runFunction: run_CharIteration_utf16_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_utf16_unicodeScalars",
+    runFunction: run_CharIndexing_utf16_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_utf16_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_utf16_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_utf16_characters_Backwards",
+    runFunction: run_StringWalk_utf16_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_utf16_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_utf16_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_utf16_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_utf16_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_tweet_unicodeScalars",
+    runFunction: run_StringWalk_tweet_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_tweet_characters",
+    runFunction: run_StringWalk_tweet_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_tweet_unicodeScalars",
+    runFunction: run_CharIteration_tweet_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_tweet_unicodeScalars",
+    runFunction: run_CharIndexing_tweet_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_tweet_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_tweet_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_tweet_characters_Backwards",
+    runFunction: run_StringWalk_tweet_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_tweet_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_tweet_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_tweet_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_tweet_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_japanese_unicodeScalars",
+    runFunction: run_StringWalk_japanese_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_japanese_characters",
+    runFunction: run_StringWalk_japanese_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_japanese_unicodeScalars",
+    runFunction: run_CharIteration_japanese_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_japanese_unicodeScalars",
+    runFunction: run_CharIndexing_japanese_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_japanese_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_japanese_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_japanese_characters_Backwards",
+    runFunction: run_StringWalk_japanese_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_japanese_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_japanese_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_japanese_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_japanese_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_chinese_unicodeScalars",
+    runFunction: run_StringWalk_chinese_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_chinese_characters",
+    runFunction: run_StringWalk_chinese_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_chinese_unicodeScalars",
+    runFunction: run_CharIteration_chinese_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_chinese_unicodeScalars",
+    runFunction: run_CharIndexing_chinese_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_chinese_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_chinese_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_chinese_characters_Backwards",
+    runFunction: run_StringWalk_chinese_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_chinese_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_chinese_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_chinese_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_chinese_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_korean_unicodeScalars",
+    runFunction: run_StringWalk_korean_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_korean_characters",
+    runFunction: run_StringWalk_korean_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_korean_unicodeScalars",
+    runFunction: run_CharIteration_korean_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_korean_unicodeScalars",
+    runFunction: run_CharIndexing_korean_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_korean_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_korean_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_korean_characters_Backwards",
+    runFunction: run_StringWalk_korean_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_korean_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_korean_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_korean_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_korean_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_russian_unicodeScalars",
+    runFunction: run_StringWalk_russian_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_russian_characters",
+    runFunction: run_StringWalk_russian_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_russian_unicodeScalars",
+    runFunction: run_CharIteration_russian_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_russian_unicodeScalars",
+    runFunction: run_CharIndexing_russian_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_russian_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_russian_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_russian_characters_Backwards",
+    runFunction: run_StringWalk_russian_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_russian_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_russian_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_russian_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_russian_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuated_unicodeScalars",
+    runFunction: run_StringWalk_punctuated_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuated_characters",
+    runFunction: run_StringWalk_punctuated_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_punctuated_unicodeScalars",
+    runFunction: run_CharIteration_punctuated_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_punctuated_unicodeScalars",
+    runFunction: run_CharIndexing_punctuated_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuated_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_punctuated_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuated_characters_Backwards",
+    runFunction: run_StringWalk_punctuated_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_punctuated_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_punctuated_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_punctuated_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_punctuated_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuatedJapanese_unicodeScalars",
+    runFunction: run_StringWalk_punctuatedJapanese_unicodeScalars,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuatedJapanese_characters",
+    runFunction: run_StringWalk_punctuatedJapanese_characters,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_punctuatedJapanese_unicodeScalars",
+    runFunction: run_CharIteration_punctuatedJapanese_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_punctuatedJapanese_unicodeScalars",
+    runFunction: run_CharIndexing_punctuatedJapanese_unicodeScalars,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuatedJapanese_unicodeScalars_Backwards",
+    runFunction: run_StringWalk_punctuatedJapanese_unicodeScalars_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "StringWalk_punctuatedJapanese_characters_Backwards",
+    runFunction: run_StringWalk_punctuatedJapanese_characters_Backwards,
+    tags: [.api, .String, .skip]),
+
+
+  BenchmarkInfo(
+    name: "CharIteration_punctuatedJapanese_unicodeScalars_Backwards",
+    runFunction: run_CharIteration_punctuatedJapanese_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_punctuatedJapanese_unicodeScalars_Backwards",
+    runFunction: run_CharIndexing_punctuatedJapanese_unicodeScalars_Backwards,
+    tags: [.validation, .api, .String]),
+]
+
+
 @inline(never)
 public func run_StringWalk_ascii_unicodeScalars(_ N: Int) {
   for _ in 1...unicodeScalarsMultiplier*N {
@@ -104,25 +511,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_ascii_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(ascii.characters)
+    count_characters(ascii)
   }
 }
 
 @inline(never)
 public func run_StringWalk_ascii_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(ascii.characters.reversed())
+    count_characters_rev(ascii.reversed())
   }
 }
 
 
-
-
 let asciiCharacters = Array(ascii)
 
 @inline(never)
@@ -189,25 +592,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_utf16_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(utf16.characters)
+    count_characters(utf16)
   }
 }
 
 @inline(never)
 public func run_StringWalk_utf16_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(utf16.characters.reversed())
+    count_characters_rev(utf16.reversed())
   }
 }
 
 
-
-
 let utf16Characters = Array(utf16)
 
 @inline(never)
@@ -274,25 +673,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_tweet_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(tweet.characters)
+    count_characters(tweet)
   }
 }
 
 @inline(never)
 public func run_StringWalk_tweet_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(tweet.characters.reversed())
+    count_characters_rev(tweet.reversed())
   }
 }
 
 
-
-
 let tweetCharacters = Array(tweet)
 
 @inline(never)
@@ -359,25 +754,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_japanese_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(japanese.characters)
+    count_characters(japanese)
   }
 }
 
 @inline(never)
 public func run_StringWalk_japanese_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(japanese.characters.reversed())
+    count_characters_rev(japanese.reversed())
   }
 }
 
 
-
-
 let japaneseCharacters = Array(japanese)
 
 @inline(never)
@@ -444,25 +835,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_chinese_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(chinese.characters)
+    count_characters(chinese)
   }
 }
 
 @inline(never)
 public func run_StringWalk_chinese_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(chinese.characters.reversed())
+    count_characters_rev(chinese.reversed())
   }
 }
 
 
-
-
 let chineseCharacters = Array(chinese)
 
 @inline(never)
@@ -529,25 +916,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_korean_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(korean.characters)
+    count_characters(korean)
   }
 }
 
 @inline(never)
 public func run_StringWalk_korean_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(korean.characters.reversed())
+    count_characters_rev(korean.reversed())
   }
 }
 
 
-
-
 let koreanCharacters = Array(korean)
 
 @inline(never)
@@ -614,25 +997,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_russian_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(russian.characters)
+    count_characters(russian)
   }
 }
 
 @inline(never)
 public func run_StringWalk_russian_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(russian.characters.reversed())
+    count_characters_rev(russian.reversed())
   }
 }
 
 
-
-
 let russianCharacters = Array(russian)
 
 @inline(never)
@@ -699,25 +1078,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_punctuated_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(punctuated.characters)
+    count_characters(punctuated)
   }
 }
 
 @inline(never)
 public func run_StringWalk_punctuated_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(punctuated.characters.reversed())
+    count_characters_rev(punctuated.reversed())
   }
 }
 
 
-
-
 let punctuatedCharacters = Array(punctuated)
 
 @inline(never)
@@ -784,25 +1159,21 @@
 }
 
 
-
-
 @inline(never)
 public func run_StringWalk_punctuatedJapanese_characters(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters(punctuatedJapanese.characters)
+    count_characters(punctuatedJapanese)
   }
 }
 
 @inline(never)
 public func run_StringWalk_punctuatedJapanese_characters_Backwards(_ N: Int) {
   for _ in 1...charactersMultiplier*N {
-    count_characters_rev(punctuatedJapanese.characters.reversed())
+    count_characters_rev(punctuatedJapanese.reversed())
   }
 }
 
 
-
-
 let punctuatedJapaneseCharacters = Array(punctuatedJapanese)
 
 @inline(never)
diff --git a/benchmark/single-source/StringWalk.swift.gyb b/benchmark/single-source/StringWalk.swift.gyb
index d209427..230d667 100644
--- a/benchmark/single-source/StringWalk.swift.gyb
+++ b/benchmark/single-source/StringWalk.swift.gyb
@@ -35,7 +35,7 @@
     count += 1
   }
 }
-@inline(never) func count_characters(_ s: String.CharacterView) {
+@inline(never) func count_characters(_ s: String) {
   for _ in s {
     count += 1
   }
@@ -48,7 +48,7 @@
   }
 }
 @inline(never) func count_characters_rev(
-  _ s: ReversedCollection<String.CharacterView>
+  _ s: ReversedCollection<String>
 ) {
   for _ in s {
     count += 1
@@ -89,25 +89,59 @@
 let unicodeScalarsMultiplier = baseMultiplier
 let charactersMultiplier = baseMultiplier / 5
 
-% for Name in ["ascii", "utf16", "tweet", "japanese", "chinese", "korean", "russian", "punctuated", "punctuatedJapanese"]:
-%   for Kind in ["unicodeScalars", "characters"]:
+% Names = ["ascii", "utf16", "tweet", "japanese", "chinese", "korean", "russian", "punctuated", "punctuatedJapanese"]
+% Kinds = ["unicodeScalars", "characters"]
+% Directions = ["", "_Backwards"]
+
+// An extended benchmark suite exercising finer-granularity behavior of our
+// Strings.
+public var StringWalk = [
+  BenchmarkInfo(
+    name: "StringWalk",
+    runFunction: run_StringWalk,
+    tags: [.validation, .api, .String]),
+
+% for Name in Names:
+%   for Direction in Directions:
+%     for Kind in Kinds:
+
+  BenchmarkInfo(
+    name: "StringWalk_${Name}_${Kind}${Direction}",
+    runFunction: run_StringWalk_${Name}_${Kind}${Direction},
+    tags: [.api, .String, .skip]),
+
+%     end # Kinds
+
+  BenchmarkInfo(
+    name: "CharIteration_${Name}_unicodeScalars${Direction}",
+    runFunction: run_CharIteration_${Name}_unicodeScalars${Direction},
+    tags: [.validation, .api, .String]),
+
+  BenchmarkInfo(
+    name: "CharIndexing_${Name}_unicodeScalars${Direction}",
+    runFunction: run_CharIndexing_${Name}_unicodeScalars${Direction},
+    tags: [.validation, .api, .String]),
+%   end # Directions
+% end # Names
+]
+
+% for Name in Names:
+%   for (Kind, View) in zip(Kinds, [".unicodeScalars", ""]):
 
 @inline(never)
 public func run_StringWalk_${Name}_${Kind}(_ N: Int) {
   for _ in 1...${Kind}Multiplier*N {
-    count_${Kind}(${Name}.${Kind})
+    count_${Kind}(${Name}${View})
   }
 }
 
 @inline(never)
 public func run_StringWalk_${Name}_${Kind}_Backwards(_ N: Int) {
   for _ in 1...${Kind}Multiplier*N {
-    count_${Kind}_rev(${Name}.${Kind}.reversed())
+    count_${Kind}_rev(${Name}${View}.reversed())
   }
 }
 
-
-
 %   end
 
 let ${Name}Characters = Array(${Name})
diff --git a/benchmark/single-source/Substring.swift b/benchmark/single-source/Substring.swift
index b64715e..e3a6661 100644
--- a/benchmark/single-source/Substring.swift
+++ b/benchmark/single-source/Substring.swift
@@ -12,6 +12,22 @@
 
 import TestsUtils
 
+public let SubstringTest = [
+  BenchmarkInfo(name: "EqualStringSubstring", runFunction: run_EqualStringSubstring, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "EqualSubstringString", runFunction: run_EqualSubstringString, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "EqualSubstringSubstring", runFunction: run_EqualSubstringSubstring, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "EqualSubstringSubstringGenericEquatable", runFunction: run_EqualSubstringSubstringGenericEquatable, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "LessSubstringSubstring", runFunction: run_LessSubstringSubstring, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "LessSubstringSubstringGenericComparable", runFunction: run_LessSubstringSubstringGenericComparable, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringFromLongWholeSubstring", runFunction: run_StringFromLongWholeSubstring, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "StringFromLongWholeSubstringGeneric", runFunction: run_StringFromLongWholeSubstringGeneric, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "SubstringComparable", runFunction: run_SubstringComparable, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "SubstringEqualString", runFunction: run_SubstringEqualString, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "SubstringEquatable", runFunction: run_SubstringEquatable, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "SubstringFromLongString", runFunction: run_SubstringFromLongString, tags: [.validation, .api, .String]),
+  BenchmarkInfo(name: "SubstringFromLongStringGeneric", runFunction: run_SubstringFromLongStringGeneric, tags: [.validation, .api, .String]),
+]
+
 // A string that doesn't fit in small string storage and doesn't fit in Latin-1
 let longWide = "fὢasὢodὢijὢadὢolὢsjὢalὢsdὢjlὢasὢdfὢijὢliὢsdὢjøὢslὢdiὢalὢiὢ"
 
diff --git a/benchmark/single-source/Suffix.swift b/benchmark/single-source/Suffix.swift
index 4a0aaa1..d734c2a 100644
--- a/benchmark/single-source/Suffix.swift
+++ b/benchmark/single-source/Suffix.swift
@@ -22,6 +22,65 @@
 let suffixCount = 1024
 let sumCount = suffixCount * (2 * sequenceCount - suffixCount - 1) / 2
 
+public let Suffix = [
+  BenchmarkInfo(
+    name: "SuffixCountableRange",
+    runFunction: run_SuffixCountableRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixSequence",
+    runFunction: run_SuffixSequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnySequence",
+    runFunction: run_SuffixAnySequence,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnySeqCntRange",
+    runFunction: run_SuffixAnySeqCntRange,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnySeqCRangeIter",
+    runFunction: run_SuffixAnySeqCRangeIter,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnyCollection",
+    runFunction: run_SuffixAnyCollection,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixArray",
+    runFunction: run_SuffixArray,
+    tags: [.validation, .api, .Array]),
+  BenchmarkInfo(
+    name: "SuffixCountableRangeLazy",
+    runFunction: run_SuffixCountableRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixSequenceLazy",
+    runFunction: run_SuffixSequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnySequenceLazy",
+    runFunction: run_SuffixAnySequenceLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnySeqCntRangeLazy",
+    runFunction: run_SuffixAnySeqCntRangeLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnySeqCRangeIterLazy",
+    runFunction: run_SuffixAnySeqCRangeIterLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixAnyCollectionLazy",
+    runFunction: run_SuffixAnyCollectionLazy,
+    tags: [.validation, .api]),
+  BenchmarkInfo(
+    name: "SuffixArrayLazy",
+    runFunction: run_SuffixArrayLazy,
+    tags: [.validation, .api]),
+]
+
 @inline(never)
 public func run_SuffixCountableRange(_ N: Int) {
   let s = 0..<sequenceCount
diff --git a/benchmark/single-source/Suffix.swift.gyb b/benchmark/single-source/Suffix.swift.gyb
index fa68349..fa59451 100644
--- a/benchmark/single-source/Suffix.swift.gyb
+++ b/benchmark/single-source/Suffix.swift.gyb
@@ -41,6 +41,15 @@
 Sequences = Sequences + map(lazy, Sequences)
 }%
 
+public let Suffix = [
+% for (Name, Expr) in Sequences:
+  BenchmarkInfo(
+    name: "Suffix${Name}",
+    runFunction: run_Suffix${Name},
+    tags: [.validation, .api${', .Array' if Name == 'Array' else ''}]),
+% end
+]
+
 % for (Name, Expr) in Sequences:
 @inline(never)
 public func run_Suffix${Name}(_ N: Int) {
diff --git a/benchmark/single-source/SuperChars.swift b/benchmark/single-source/SuperChars.swift
index ae8918a..dc807ba 100644
--- a/benchmark/single-source/SuperChars.swift
+++ b/benchmark/single-source/SuperChars.swift
@@ -13,6 +13,11 @@
 // This test tests the performance of ASCII Character comparison.
 import TestsUtils
 
+public let SuperChars = BenchmarkInfo(
+  name: "SuperChars",
+  runFunction: run_SuperChars,
+  tags: [.validation, .api, .String])
+
 @inline(never)
 public func run_SuperChars(_ N: Int) {
   // Permute some characters.
diff --git a/benchmark/single-source/TwoSum.swift b/benchmark/single-source/TwoSum.swift
index 545a09a..17d4752 100644
--- a/benchmark/single-source/TwoSum.swift
+++ b/benchmark/single-source/TwoSum.swift
@@ -14,6 +14,11 @@
 // Given an array and a number C, find elements A and B such that A+B = C
 import TestsUtils
 
+public let TwoSum = BenchmarkInfo(
+  name: "TwoSum",
+  runFunction: run_TwoSum,
+  tags: [.validation, .api, .Dictionary, .Array, .algorithm])
+
 let array = [
   959,  81, 670, 727, 416, 171, 401, 398, 707, 596, 200,   9, 414,  98,  43,
   352, 752, 158, 593, 418, 240, 912, 542, 445, 429, 456, 993, 618,  52, 649,
diff --git a/benchmark/single-source/TypeFlood.swift b/benchmark/single-source/TypeFlood.swift
index 6b38220..57c9bfb 100644
--- a/benchmark/single-source/TypeFlood.swift
+++ b/benchmark/single-source/TypeFlood.swift
@@ -23,6 +23,12 @@
 
 
 import TestsUtils
+
+public let TypeFlood = BenchmarkInfo(
+  name: "TypeFlood",
+  runFunction: run_TypeFlood,
+  tags: [.validation, .metadata])
+
 protocol Pingable {}
 
 struct Some1<T> {
diff --git a/benchmark/single-source/UTF8Decode.swift b/benchmark/single-source/UTF8Decode.swift
index 09bef9b..56169ec 100644
--- a/benchmark/single-source/UTF8Decode.swift
+++ b/benchmark/single-source/UTF8Decode.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let UTF8Decode = BenchmarkInfo(
+  name: "UTF8Decode",
+  runFunction: run_UTF8Decode,
+  tags: [.validation, .api, .String])
+
 @inline(never)
 public func run_UTF8Decode(_ N: Int) {
   // 1-byte sequences
diff --git a/benchmark/single-source/Walsh.swift b/benchmark/single-source/Walsh.swift
index 125c905..9b43ea1 100644
--- a/benchmark/single-source/Walsh.swift
+++ b/benchmark/single-source/Walsh.swift
@@ -17,6 +17,11 @@
 import Darwin
 #endif
 
+public let Walsh = BenchmarkInfo(
+  name: "Walsh",
+  runFunction: run_Walsh,
+  tags: [.validation, .algorithm])
+
 func IsPowerOfTwo(_ x: Int) -> Bool { return (x & (x - 1)) == 0 }
 
 // Fast Walsh Hadamard Transform
diff --git a/benchmark/single-source/XorLoop.swift b/benchmark/single-source/XorLoop.swift
index 044614f..8bb9f40 100644
--- a/benchmark/single-source/XorLoop.swift
+++ b/benchmark/single-source/XorLoop.swift
@@ -12,6 +12,11 @@
 
 import TestsUtils
 
+public let XorLoop = BenchmarkInfo(
+  name: "XorLoop",
+  runFunction: run_XorLoop,
+  tags: [.validation])
+
 @inline(never)
 public func run_XorLoop(_ N: Int) {
   for _ in 1...5*N {
diff --git a/benchmark/utils/ArgParse.swift b/benchmark/utils/ArgParse.swift
index ebd3bb5..396c01b 100644
--- a/benchmark/utils/ArgParse.swift
+++ b/benchmark/utils/ArgParse.swift
@@ -46,7 +46,7 @@
   for arg in CommandLine.arguments[1..<CommandLine.arguments.count] {
     // If the argument doesn't match the optional argument pattern. Add
     // it to the positional argument list and continue...
-    if passThroughArgs || !arg.characters.starts(with: "-".characters) {
+    if passThroughArgs || !arg.starts(with: "-") {
       positionalArgs.append(arg)
       continue
     }
diff --git a/benchmark/utils/DriverUtils.swift b/benchmark/utils/DriverUtils.swift
index f464c6a..33c3230 100644
--- a/benchmark/utils/DriverUtils.swift
+++ b/benchmark/utils/DriverUtils.swift
@@ -107,9 +107,12 @@
   /// The filters applied to our test names.
   var filters = [String]()
 
-  /// The tag that we want to run
+  /// The tags that we want to run
   var tags = Set<BenchmarkCategory>()
 
+  /// Tests tagged with any of these will not be executed
+  var skipTags: Set<BenchmarkCategory> = [.unstable, .skip]
+
   /// The scalar multiple of the amount of times a test should be run. This
   /// enables one to cause tests to run for N iterations longer than they
   /// normally would. This is useful when one wishes for a test to run for a
@@ -127,14 +130,6 @@
   /// Is verbose output enabled?
   var verbose: Bool = false
 
-  /// Should we only run the "pre-commit" tests?
-  var onlyPrecommit: Bool = true
-
-  /// Temporary option to only run tests that have been registered with
-  /// BenchmarkInfo. This will go away as soon as the benchmarks have been
-  /// categorized.
-  var onlyRegistered: Bool = false
-
   /// After we run the tests, should the harness sleep to allow for utilities
   /// like leaks that require a PID to run on the test harness.
   var afterRunSleep: Int?
@@ -145,8 +140,8 @@
   mutating func processArguments() -> TestAction {
     let validOptions = [
       "--iter-scale", "--num-samples", "--num-iters",
-      "--verbose", "--delim", "--run-all", "--list", "--sleep",
-      "--registered", "--tags"
+      "--verbose", "--delim", "--list", "--sleep",
+      "--tags", "--skip-tags"
     ]
     let maybeBenchArgs: Arguments? = parseArgs(validOptions)
     if maybeBenchArgs == nil {
@@ -198,8 +193,23 @@
       }
     }
 
-    if let _ = benchArgs.optionalArgsMap["--run-all"] {
-      onlyPrecommit = false
+    if let x = benchArgs.optionalArgsMap["--skip-tags"] {
+      // if the --skip-tags parameter is specified, we need to ignore the
+      // default and start from a clean slate.
+      skipTags = []
+
+      // We support specifying multiple tags by splitting on comma, i.e.:
+      //
+      //  --skip-tags=array,set
+      //
+      // FIXME: If we used Error instead of .fail, then we could have a cleaner
+      // impl here using map on x and tags.formUnion.
+      for t in x.split(separator: ",") {
+        guard let cat = BenchmarkCategory(rawValue: String(t)) else {
+          return .fail("Unknown benchmark category: '\(t)'")
+        }
+        skipTags.insert(cat)
+      }
     }
 
     if let x = benchArgs.optionalArgsMap["--sleep"] {
@@ -217,72 +227,52 @@
       return .listTests
     }
 
-    if let _ = benchArgs.optionalArgsMap["--registered"] {
-      onlyRegistered = true
-    }
-
     return .run
   }
 
   mutating func findTestsToRun() {
     // Begin by creating a set of our non-legacy registeredBenchmarks
-    var allTests = Set<BenchmarkInfo>(registeredBenchmarks)
+    var allTests = Set(registeredBenchmarks)
 
-    // If we are supposed to only run registered tests there isn't anything
-    // further to do (in the future anyways).
-    if onlyRegistered {
-      // FIXME: for now unstable/extra benchmarks are not registered at all, but
-      // soon they will be handled with a default exclude list.
-      onlyPrecommit = false
-    } else {
-      // Merge legacy benchmark info into allTests. If we already have a
-      // registered benchmark info, formUnion leaves this alone. This allows for
-      // us to perform incremental work.
-      for testList in [precommitTests, otherTests, stringTests] {
-        allTests.formUnion(testList)
-      }
+    // Merge legacy benchmark info into allTests. If we already have a
+    // registered benchmark info, formUnion leaves this alone. This allows for
+    // us to perform incremental work.
+    for testList in [precommitTests, otherTests, stringTests] {
+      allTests.formUnion(testList)
     }
 
-    let benchmarkNameFilter: Set<String>? = {
-      if !filters.isEmpty {
-        return Set(filters)
-      }
-
-      if onlyPrecommit {
-        return Set(precommitTests.map { $0.name })
-      }
-
-      return nil
-    }()
+    let benchmarkNameFilter = Set(filters)
 
     // t is needed so we don't capture an ivar of a mutable inout self.
     let t = tags
-    var filteredTests = allTests.filter {
-      benchInfo in
+    let st = skipTags
+    let filteredTests = Array(allTests.filter { benchInfo in
       if !t.isSubset(of: benchInfo.tags) {
         return false
       }
 
+      if !st.isDisjoint(with: benchInfo.tags) {
+        return false
+      }
+
       // If the user did not specified a benchmark name filter and our tags are
       // a subset of the specified tags by the user, return true. We want to run
       // this test.
-      guard let benchFilter = benchmarkNameFilter else {
+      if benchmarkNameFilter.isEmpty {
         return true
       }
 
       // Otherwise, we need to check if our benchInfo's name is in the benchmark
       // name filter list. If it isn't, then we shouldn't process it.
-      return benchFilter.contains(benchInfo.name)
-    }.map { $0 }.sorted()
+      return benchmarkNameFilter.contains(benchInfo.name)
+    }).sorted()
 
     if (filteredTests.isEmpty) {
       return
     }
 
-    tests = zip(1...filteredTests.count, filteredTests).map {
-      t -> Test in
-      let (ordinal, benchInfo) = t
-      return Test(benchInfo: benchInfo, index: ordinal)
+    tests = filteredTests.enumerated().map {
+      Test(benchInfo: $0.element, index: $0.offset + 1)
     }
   }
 }
diff --git a/benchmark/utils/TestsUtils.swift b/benchmark/utils/TestsUtils.swift
index ddf9b8e..a4fe216 100644
--- a/benchmark/utils/TestsUtils.swift
+++ b/benchmark/utils/TestsUtils.swift
@@ -65,6 +65,9 @@
   // reimplementing or call into code paths that have known opportunities for
   // significant optimization.
   case cpubench
+
+  // Explicit skip marker
+  case skip
 }
 
 public struct BenchmarkInfo {
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index 6bab9bd..b8524f3 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -10,13 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-////////////////////////////////////////////////////////////////////////////////
-// WARNING: This file is manually generated from .gyb template and should not
-// be directly modified. Instead, make changes to main.swift.gyb and run
-// scripts/generate_harness/generate_harness.py to regenerate this file.
-////////////////////////////////////////////////////////////////////////////////
-
 // This is just a driver for performance overview tests.
+
 import TestsUtils
 import DriverUtils
 import Ackermann
@@ -96,6 +91,7 @@
 import RC4
 import RGBHistogram
 import RangeAssignment
+import RangeIteration
 import RecursiveOwnedParameter
 import ReduceInto
 import ReversedCollections
@@ -130,498 +126,118 @@
   registeredBenchmarks.append(bench)
 }
 
-registerBenchmark(AnyHashableWithAClass)
-registerBenchmark(ArraySetElement)
-registerBenchmark(ExclusivityGlobal)
-registerBenchmark(ExclusivityInMatSet)
-registerBenchmark(ExclusivityIndependent)
-registerBenchmark(LinkedList)
-registerBenchmark(ObjectAllocation)
-registerBenchmark(PolymorphicCalls)
-registerBenchmark(SevenBoom)
-
 @inline(__always)
-private func addTo(
-  _ testSuite: inout [BenchmarkInfo],
-  _ name: String,
-  _ function: @escaping (Int) -> (),
-  _ tags: [BenchmarkCategory] = []
-  ) {
-  testSuite.append(BenchmarkInfo(name: name, runFunction: function, tags: tags))
+private func registerBenchmark<
+  S : Sequence
+>(_ infos: S) where S.Element == BenchmarkInfo {
+  registeredBenchmarks.append(contentsOf: infos)
 }
 
-// The main test suite: precommit tests
-addTo(&precommitTests, "AngryPhonebook", run_AngryPhonebook, [.validation, .api, .String])
-addTo(&precommitTests, "AnyHashableWithAClass", run_AnyHashableWithAClass, [.validation, .abstraction, .runtime])
-addTo(&precommitTests, "Array2D", run_Array2D, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppend", run_ArrayAppend, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendArrayOfInt", run_ArrayAppendArrayOfInt, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendAscii", run_ArrayAppendAscii, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendFromGeneric", run_ArrayAppendFromGeneric, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendGenericStructs", run_ArrayAppendGenericStructs, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendLatin1", run_ArrayAppendLatin1, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendLazyMap", run_ArrayAppendLazyMap, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendOptionals", run_ArrayAppendOptionals, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendRepeatCol", run_ArrayAppendRepeatCol, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendReserved", run_ArrayAppendReserved, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendSequence", run_ArrayAppendSequence, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendStrings", run_ArrayAppendStrings, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendToFromGeneric", run_ArrayAppendToFromGeneric, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendToGeneric", run_ArrayAppendToGeneric, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayAppendUTF16", run_ArrayAppendUTF16, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayInClass", run_ArrayInClass, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayLiteral", run_ArrayLiteral, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayOfGenericPOD", run_ArrayOfGenericPOD, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayOfGenericRef", run_ArrayOfGenericRef, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayOfPOD", run_ArrayOfPOD, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayOfRef", run_ArrayOfRef, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayPlusEqualArrayOfInt", run_ArrayPlusEqualArrayOfInt, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayPlusEqualFiveElementCollection", run_ArrayPlusEqualFiveElementCollection, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayPlusEqualSingleElementCollection", run_ArrayPlusEqualSingleElementCollection, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayPlusEqualThreeElements", run_ArrayPlusEqualThreeElements, [.validation, .api, .Array])
-addTo(&precommitTests, "ArraySubscript", run_ArraySubscript, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayValueProp", run_ArrayValueProp, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayValueProp2", run_ArrayValueProp2, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayValueProp3", run_ArrayValueProp3, [.validation, .api, .Array])
-addTo(&precommitTests, "ArrayValueProp4", run_ArrayValueProp4, [.validation, .api, .Array])
-addTo(&precommitTests, "BitCount", run_BitCount, [.validation, .algorithm])
-addTo(&precommitTests, "ByteSwap", run_ByteSwap, [.validation, .algorithm])
-addTo(&precommitTests, "CStringLongAscii", run_CStringLongAscii, [.validation, .api, .String, .bridging])
-addTo(&precommitTests, "CStringLongNonAscii", run_CStringLongNonAscii, [.validation, .api, .String, .bridging])
-addTo(&precommitTests, "CStringShortAscii", run_CStringShortAscii, [.validation, .api, .String, .bridging])
-addTo(&precommitTests, "Calculator", run_Calculator, [.validation])
-addTo(&precommitTests, "CaptureProp", run_CaptureProp, [.validation, .api, .refcount])
-addTo(&precommitTests, "CharIndexing_ascii_unicodeScalars", run_CharIndexing_ascii_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_ascii_unicodeScalars_Backwards", run_CharIndexing_ascii_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_chinese_unicodeScalars", run_CharIndexing_chinese_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_chinese_unicodeScalars_Backwards", run_CharIndexing_chinese_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_japanese_unicodeScalars", run_CharIndexing_japanese_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_japanese_unicodeScalars_Backwards", run_CharIndexing_japanese_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_korean_unicodeScalars", run_CharIndexing_korean_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_korean_unicodeScalars_Backwards", run_CharIndexing_korean_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_punctuatedJapanese_unicodeScalars", run_CharIndexing_punctuatedJapanese_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_punctuatedJapanese_unicodeScalars_Backwards", run_CharIndexing_punctuatedJapanese_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_punctuated_unicodeScalars", run_CharIndexing_punctuated_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_punctuated_unicodeScalars_Backwards", run_CharIndexing_punctuated_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_russian_unicodeScalars", run_CharIndexing_russian_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_russian_unicodeScalars_Backwards", run_CharIndexing_russian_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_tweet_unicodeScalars", run_CharIndexing_tweet_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_tweet_unicodeScalars_Backwards", run_CharIndexing_tweet_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_utf16_unicodeScalars", run_CharIndexing_utf16_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIndexing_utf16_unicodeScalars_Backwards", run_CharIndexing_utf16_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_ascii_unicodeScalars", run_CharIteration_ascii_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_ascii_unicodeScalars_Backwards", run_CharIteration_ascii_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_chinese_unicodeScalars", run_CharIteration_chinese_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_chinese_unicodeScalars_Backwards", run_CharIteration_chinese_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_japanese_unicodeScalars", run_CharIteration_japanese_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_japanese_unicodeScalars_Backwards", run_CharIteration_japanese_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_korean_unicodeScalars", run_CharIteration_korean_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_korean_unicodeScalars_Backwards", run_CharIteration_korean_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_punctuatedJapanese_unicodeScalars", run_CharIteration_punctuatedJapanese_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_punctuatedJapanese_unicodeScalars_Backwards", run_CharIteration_punctuatedJapanese_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_punctuated_unicodeScalars", run_CharIteration_punctuated_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_punctuated_unicodeScalars_Backwards", run_CharIteration_punctuated_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_russian_unicodeScalars", run_CharIteration_russian_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_russian_unicodeScalars_Backwards", run_CharIteration_russian_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_tweet_unicodeScalars", run_CharIteration_tweet_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_tweet_unicodeScalars_Backwards", run_CharIteration_tweet_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_utf16_unicodeScalars", run_CharIteration_utf16_unicodeScalars, [.validation, .api, .String])
-addTo(&precommitTests, "CharIteration_utf16_unicodeScalars_Backwards", run_CharIteration_utf16_unicodeScalars_Backwards, [.validation, .api, .String])
-addTo(&precommitTests, "CharacterLiteralsLarge", run_CharacterLiteralsLarge, [.validation, .api, .String])
-addTo(&precommitTests, "CharacterLiteralsSmall", run_CharacterLiteralsSmall, [.validation, .api, .String])
-addTo(&precommitTests, "Chars", run_Chars, [.validation, .api, .String])
-addTo(&precommitTests, "ClassArrayGetter", run_ClassArrayGetter, [.validation, .api, .Array])
-addTo(&precommitTests, "DeadArray", run_DeadArray, [.regression])
-addTo(&precommitTests, "Dictionary", run_Dictionary, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "Dictionary2", run_Dictionary2, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "Dictionary2OfObjects", run_Dictionary2OfObjects, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "Dictionary3", run_Dictionary3, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "Dictionary3OfObjects", run_Dictionary3OfObjects, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionaryBridge", run_DictionaryBridge, [.validation, .api, .Dictionary, .bridging])
-addTo(&precommitTests, "DictionaryGroup", run_DictionaryGroup, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionaryGroupOfObjects", run_DictionaryGroupOfObjects, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionaryLiteral", run_DictionaryLiteral, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionaryOfObjects", run_DictionaryOfObjects, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionaryRemove", run_DictionaryRemove, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionaryRemoveOfObjects", run_DictionaryRemoveOfObjects, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionarySwap", run_DictionarySwap, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DictionarySwapOfObjects", run_DictionarySwapOfObjects, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "DropFirstAnyCollection", run_DropFirstAnyCollection, [.validation, .api])
-addTo(&precommitTests, "DropFirstAnyCollectionLazy", run_DropFirstAnyCollectionLazy, [.validation, .api])
-addTo(&precommitTests, "DropFirstAnySeqCRangeIter", run_DropFirstAnySeqCRangeIter, [.validation, .api])
-addTo(&precommitTests, "DropFirstAnySeqCRangeIterLazy", run_DropFirstAnySeqCRangeIterLazy, [.validation, .api])
-addTo(&precommitTests, "DropFirstAnySeqCntRange", run_DropFirstAnySeqCntRange, [.validation, .api])
-addTo(&precommitTests, "DropFirstAnySeqCntRangeLazy", run_DropFirstAnySeqCntRangeLazy, [.validation, .api])
-addTo(&precommitTests, "DropFirstAnySequence", run_DropFirstAnySequence, [.validation, .api])
-addTo(&precommitTests, "DropFirstAnySequenceLazy", run_DropFirstAnySequenceLazy, [.validation, .api])
-addTo(&precommitTests, "DropFirstArray", run_DropFirstArray, [.validation, .api, .Array])
-addTo(&precommitTests, "DropFirstArrayLazy", run_DropFirstArrayLazy, [.validation, .api, .Array])
-addTo(&precommitTests, "DropFirstCountableRange", run_DropFirstCountableRange, [.validation, .api])
-addTo(&precommitTests, "DropFirstCountableRangeLazy", run_DropFirstCountableRangeLazy, [.validation, .api])
-addTo(&precommitTests, "DropFirstSequence", run_DropFirstSequence, [.validation, .api])
-addTo(&precommitTests, "DropFirstSequenceLazy", run_DropFirstSequenceLazy, [.validation, .api])
-addTo(&precommitTests, "DropLastAnyCollection", run_DropLastAnyCollection, [.validation, .api])
-addTo(&precommitTests, "DropLastAnyCollectionLazy", run_DropLastAnyCollectionLazy, [.validation, .api])
-addTo(&precommitTests, "DropLastAnySeqCRangeIter", run_DropLastAnySeqCRangeIter, [.validation, .api])
-addTo(&precommitTests, "DropLastAnySeqCRangeIterLazy", run_DropLastAnySeqCRangeIterLazy, [.validation, .api])
-addTo(&precommitTests, "DropLastAnySeqCntRange", run_DropLastAnySeqCntRange, [.validation, .api])
-addTo(&precommitTests, "DropLastAnySeqCntRangeLazy", run_DropLastAnySeqCntRangeLazy, [.validation, .api])
-addTo(&precommitTests, "DropLastAnySequence", run_DropLastAnySequence, [.validation, .api])
-addTo(&precommitTests, "DropLastAnySequenceLazy", run_DropLastAnySequenceLazy, [.validation, .api])
-addTo(&precommitTests, "DropLastArray", run_DropLastArray, [.validation, .api, .Array])
-addTo(&precommitTests, "DropLastArrayLazy", run_DropLastArrayLazy, [.validation, .api, .Array])
-addTo(&precommitTests, "DropLastCountableRange", run_DropLastCountableRange, [.validation, .api])
-addTo(&precommitTests, "DropLastCountableRangeLazy", run_DropLastCountableRangeLazy, [.validation, .api])
-addTo(&precommitTests, "DropLastSequence", run_DropLastSequence, [.validation, .api])
-addTo(&precommitTests, "DropLastSequenceLazy", run_DropLastSequenceLazy, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnyCollection", run_DropWhileAnyCollection, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnyCollectionLazy", run_DropWhileAnyCollectionLazy, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnySeqCRangeIter", run_DropWhileAnySeqCRangeIter, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnySeqCRangeIterLazy", run_DropWhileAnySeqCRangeIterLazy, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnySeqCntRange", run_DropWhileAnySeqCntRange, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnySeqCntRangeLazy", run_DropWhileAnySeqCntRangeLazy, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnySequence", run_DropWhileAnySequence, [.validation, .api])
-addTo(&precommitTests, "DropWhileAnySequenceLazy", run_DropWhileAnySequenceLazy, [.validation, .api])
-addTo(&precommitTests, "DropWhileArray", run_DropWhileArray, [.validation, .api, .Array])
-addTo(&precommitTests, "DropWhileArrayLazy", run_DropWhileArrayLazy, [.validation, .api, .Array])
-addTo(&precommitTests, "DropWhileCountableRange", run_DropWhileCountableRange, [.validation, .api])
-addTo(&precommitTests, "DropWhileCountableRangeLazy", run_DropWhileCountableRangeLazy, [.validation, .api])
-addTo(&precommitTests, "DropWhileSequence", run_DropWhileSequence, [.validation, .api])
-addTo(&precommitTests, "DropWhileSequenceLazy", run_DropWhileSequenceLazy, [.validation, .api])
-addTo(&precommitTests, "EqualStringSubstring", run_EqualStringSubstring, [.validation, .api, .String])
-addTo(&precommitTests, "EqualSubstringString", run_EqualSubstringString, [.validation, .api, .String])
-addTo(&precommitTests, "EqualSubstringSubstring", run_EqualSubstringSubstring, [.validation, .api, .String])
-addTo(&precommitTests, "EqualSubstringSubstringGenericEquatable", run_EqualSubstringSubstringGenericEquatable, [.validation, .api, .String])
-addTo(&precommitTests, "ErrorHandling", run_ErrorHandling, [.validation, .exceptions])
-addTo(&precommitTests, "FilterEvenUsingReduce", run_FilterEvenUsingReduce, [.validation, .api])
-addTo(&precommitTests, "FilterEvenUsingReduceInto", run_FilterEvenUsingReduceInto, [.validation, .api])
-addTo(&precommitTests, "FrequenciesUsingReduce", run_FrequenciesUsingReduce, [.validation, .api])
-addTo(&precommitTests, "FrequenciesUsingReduceInto", run_FrequenciesUsingReduceInto, [.validation, .api])
-addTo(&precommitTests, "Hanoi", run_Hanoi, [.validation, .algorithm])
-addTo(&precommitTests, "HashTest", run_HashTest, [.validation, .algorithm])
-addTo(&precommitTests, "Histogram", run_Histogram, [.validation, .algorithm])
-addTo(&precommitTests, "Integrate", run_Integrate, [.validation, .algorithm])
-addTo(&precommitTests, "IterateData", run_IterateData, [.validation, .api])
-addTo(&precommitTests, "Join", run_Join, [.validation, .api, .String, .Array])
-addTo(&precommitTests, "LazilyFilteredArrays", run_LazilyFilteredArrays, [.validation, .api, .Array])
-addTo(&precommitTests, "LazilyFilteredRange", run_LazilyFilteredRange, [.validation, .api, .Array])
-addTo(&precommitTests, "LessSubstringSubstring", run_LessSubstringSubstring, [.validation, .api, .String])
-addTo(&precommitTests, "LessSubstringSubstringGenericComparable", run_LessSubstringSubstringGenericComparable, [.validation, .api, .String])
-addTo(&precommitTests, "LinkedList", run_LinkedList, [.validation])
-addTo(&precommitTests, "MapReduce", run_MapReduce, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceAnyCollection", run_MapReduceAnyCollection, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceAnyCollectionShort", run_MapReduceAnyCollectionShort, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceClass", run_MapReduceClass, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceClassShort", run_MapReduceClassShort, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceLazyCollection", run_MapReduceLazyCollection, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceLazyCollectionShort", run_MapReduceLazyCollectionShort, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceLazySequence", run_MapReduceLazySequence, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceSequence", run_MapReduceSequence, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceShort", run_MapReduceShort, [.validation, .algorithm])
-addTo(&precommitTests, "MapReduceShortString", run_MapReduceShortString, [.validation, .algorithm, .String])
-addTo(&precommitTests, "MapReduceString", run_MapReduceString, [.validation, .algorithm, .String])
-addTo(&precommitTests, "Memset", run_Memset, [.validation])
-addTo(&precommitTests, "MonteCarloE", run_MonteCarloE, [.validation, .algorithm])
-addTo(&precommitTests, "MonteCarloPi", run_MonteCarloPi, [.validation, .algorithm])
-addTo(&precommitTests, "NSDictionaryCastToSwift", run_NSDictionaryCastToSwift, [.validation, .api, .Dictionary, .bridging])
-addTo(&precommitTests, "NSError", run_NSError, [.validation, .exceptions, .bridging])
-addTo(&precommitTests, "NSStringConversion", run_NSStringConversion, [.validation, .api, .String, .bridging])
-addTo(&precommitTests, "NopDeinit", run_NopDeinit, [.regression])
-addTo(&precommitTests, "ObjectAllocation", run_ObjectAllocation, [.validation])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSArrayAnyObject", run_ObjectiveCBridgeFromNSArrayAnyObject, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSArrayAnyObjectForced", run_ObjectiveCBridgeFromNSArrayAnyObjectForced, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSArrayAnyObjectToString", run_ObjectiveCBridgeFromNSArrayAnyObjectToString, [.validation, .bridging, .String])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSArrayAnyObjectToStringForced", run_ObjectiveCBridgeFromNSArrayAnyObjectToStringForced, [.validation, .bridging, .String])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSDictionaryAnyObject", run_ObjectiveCBridgeFromNSDictionaryAnyObject, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSDictionaryAnyObjectForced", run_ObjectiveCBridgeFromNSDictionaryAnyObjectForced, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSDictionaryAnyObjectToString", run_ObjectiveCBridgeFromNSDictionaryAnyObjectToString, [.validation, .bridging, .String])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced", run_ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced, [.validation, .bridging, .String])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSSetAnyObject", run_ObjectiveCBridgeFromNSSetAnyObject, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSSetAnyObjectForced", run_ObjectiveCBridgeFromNSSetAnyObjectForced, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSSetAnyObjectToString", run_ObjectiveCBridgeFromNSSetAnyObjectToString, [.validation, .bridging, .String])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSSetAnyObjectToStringForced", run_ObjectiveCBridgeFromNSSetAnyObjectToStringForced, [.validation, .bridging, .String])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSString", run_ObjectiveCBridgeFromNSString, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeFromNSStringForced", run_ObjectiveCBridgeFromNSStringForced, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubDataAppend", run_ObjectiveCBridgeStubDataAppend, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubDateAccess", run_ObjectiveCBridgeStubDateAccess, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubDateMutation", run_ObjectiveCBridgeStubDateMutation, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubFromArrayOfNSString", run_ObjectiveCBridgeStubFromArrayOfNSString, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubFromNSDate", run_ObjectiveCBridgeStubFromNSDate, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubFromNSDateRef", run_ObjectiveCBridgeStubFromNSDateRef, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubFromNSString", run_ObjectiveCBridgeStubFromNSString, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubFromNSStringRef", run_ObjectiveCBridgeStubFromNSStringRef, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubNSDataAppend", run_ObjectiveCBridgeStubNSDataAppend, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubNSDateMutationRef", run_ObjectiveCBridgeStubNSDateMutationRef, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubNSDateRefAccess", run_ObjectiveCBridgeStubNSDateRefAccess, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubToArrayOfNSString", run_ObjectiveCBridgeStubToArrayOfNSString, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubToNSDate", run_ObjectiveCBridgeStubToNSDate, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubToNSDateRef", run_ObjectiveCBridgeStubToNSDateRef, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubToNSString", run_ObjectiveCBridgeStubToNSString, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubToNSStringRef", run_ObjectiveCBridgeStubToNSStringRef, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubURLAppendPath", run_ObjectiveCBridgeStubURLAppendPath, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeStubURLAppendPathRef", run_ObjectiveCBridgeStubURLAppendPathRef, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeToNSArray", run_ObjectiveCBridgeToNSArray, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeToNSDictionary", run_ObjectiveCBridgeToNSDictionary, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeToNSSet", run_ObjectiveCBridgeToNSSet, [.validation, .bridging])
-addTo(&precommitTests, "ObjectiveCBridgeToNSString", run_ObjectiveCBridgeToNSString, [.validation, .bridging])
-addTo(&precommitTests, "ObserverClosure", run_ObserverClosure, [.validation])
-addTo(&precommitTests, "ObserverForwarderStruct", run_ObserverForwarderStruct, [.validation])
-addTo(&precommitTests, "ObserverPartiallyAppliedMethod", run_ObserverPartiallyAppliedMethod, [.validation])
-addTo(&precommitTests, "ObserverUnappliedMethod", run_ObserverUnappliedMethod, [.validation])
-addTo(&precommitTests, "OpenClose", run_OpenClose, [.validation, .api, .String])
-addTo(&precommitTests, "Phonebook", run_Phonebook, [.validation, .api, .String])
-addTo(&precommitTests, "PolymorphicCalls", run_PolymorphicCalls, [.validation, .runtime, .abstraction])
-addTo(&precommitTests, "PopFrontArray", run_PopFrontArray, [.validation, .api, .Array])
-addTo(&precommitTests, "PopFrontArrayGeneric", run_PopFrontArrayGeneric, [.validation, .api, .Array])
-addTo(&precommitTests, "PopFrontUnsafePointer", run_PopFrontUnsafePointer, [.validation, .api])
-addTo(&precommitTests, "PrefixAnyCollection", run_PrefixAnyCollection, [.validation, .api])
-addTo(&precommitTests, "PrefixAnyCollectionLazy", run_PrefixAnyCollectionLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixAnySeqCRangeIter", run_PrefixAnySeqCRangeIter, [.validation, .api])
-addTo(&precommitTests, "PrefixAnySeqCRangeIterLazy", run_PrefixAnySeqCRangeIterLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixAnySeqCntRange", run_PrefixAnySeqCntRange, [.validation, .api])
-addTo(&precommitTests, "PrefixAnySeqCntRangeLazy", run_PrefixAnySeqCntRangeLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixAnySequence", run_PrefixAnySequence, [.validation, .api])
-addTo(&precommitTests, "PrefixAnySequenceLazy", run_PrefixAnySequenceLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixArray", run_PrefixArray, [.validation, .api, .Array])
-addTo(&precommitTests, "PrefixArrayLazy", run_PrefixArrayLazy, [.validation, .api, .Array])
-addTo(&precommitTests, "PrefixCountableRange", run_PrefixCountableRange, [.validation, .api])
-addTo(&precommitTests, "PrefixCountableRangeLazy", run_PrefixCountableRangeLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixSequence", run_PrefixSequence, [.validation, .api])
-addTo(&precommitTests, "PrefixSequenceLazy", run_PrefixSequenceLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnyCollection", run_PrefixWhileAnyCollection, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnyCollectionLazy", run_PrefixWhileAnyCollectionLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnySeqCRangeIter", run_PrefixWhileAnySeqCRangeIter, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnySeqCRangeIterLazy", run_PrefixWhileAnySeqCRangeIterLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnySeqCntRange", run_PrefixWhileAnySeqCntRange, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnySeqCntRangeLazy", run_PrefixWhileAnySeqCntRangeLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnySequence", run_PrefixWhileAnySequence, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileAnySequenceLazy", run_PrefixWhileAnySequenceLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileArray", run_PrefixWhileArray, [.validation, .api, .Array])
-addTo(&precommitTests, "PrefixWhileArrayLazy", run_PrefixWhileArrayLazy, [.validation, .api, .Array])
-addTo(&precommitTests, "PrefixWhileCountableRange", run_PrefixWhileCountableRange, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileCountableRangeLazy", run_PrefixWhileCountableRangeLazy, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileSequence", run_PrefixWhileSequence, [.validation, .api])
-addTo(&precommitTests, "PrefixWhileSequenceLazy", run_PrefixWhileSequenceLazy, [.validation, .api])
-addTo(&precommitTests, "Prims", run_Prims, [.validation, .algorithm])
-addTo(&precommitTests, "PrimsSplit", run_PrimsSplit, [.validation, .algorithm])
-addTo(&precommitTests, "ProtocolDispatch", run_ProtocolDispatch, [.validation, .abstraction])
-addTo(&precommitTests, "ProtocolDispatch2", run_ProtocolDispatch2, [.validation, .abstraction])
-addTo(&precommitTests, "RC4", run_RC4, [.validation, .algorithm])
-addTo(&precommitTests, "RGBHistogram", run_RGBHistogram, [.validation, .algorithm])
-addTo(&precommitTests, "RGBHistogramOfObjects", run_RGBHistogramOfObjects, [.validation, .algorithm])
-addTo(&precommitTests, "RangeAssignment", run_RangeAssignment, [.validation, .api])
-addTo(&precommitTests, "RecursiveOwnedParameter", run_RecursiveOwnedParameter, [.validation, .api, .Array, .refcount])
-addTo(&precommitTests, "ReversedArray", run_ReversedArray, [.validation, .api, .Array])
-addTo(&precommitTests, "ReversedBidirectional", run_ReversedBidirectional, [.validation, .api])
-addTo(&precommitTests, "ReversedDictionary", run_ReversedDictionary, [.validation, .api, .Dictionary])
-addTo(&precommitTests, "SetExclusiveOr", run_SetExclusiveOr, [.validation, .api, .Set])
-addTo(&precommitTests, "SetExclusiveOr_OfObjects", run_SetExclusiveOr_OfObjects, [.validation, .api, .Set])
-addTo(&precommitTests, "SetIntersect", run_SetIntersect, [.validation, .api, .Set])
-addTo(&precommitTests, "SetIntersect_OfObjects", run_SetIntersect_OfObjects, [.validation, .api, .Set])
-addTo(&precommitTests, "SetIsSubsetOf", run_SetIsSubsetOf, [.validation, .api, .Set])
-addTo(&precommitTests, "SetIsSubsetOf_OfObjects", run_SetIsSubsetOf_OfObjects, [.validation, .api, .Set])
-addTo(&precommitTests, "SetUnion", run_SetUnion, [.validation, .api, .Set])
-addTo(&precommitTests, "SetUnion_OfObjects", run_SetUnion_OfObjects, [.validation, .api, .Set])
-addTo(&precommitTests, "SevenBoom", run_SevenBoom, [.validation])
-addTo(&precommitTests, "Sim2DArray", run_Sim2DArray, [.validation, .api, .Array])
-addTo(&precommitTests, "SortLargeExistentials", run_SortLargeExistentials, [.validation, .api, .algorithm])
-addTo(&precommitTests, "SortLettersInPlace", run_SortLettersInPlace, [.validation, .api, .algorithm, .String])
-addTo(&precommitTests, "SortSortedStrings", run_SortSortedStrings, [.validation, .api, .algorithm, .String])
-addTo(&precommitTests, "SortStrings", run_SortStrings, [.validation, .api, .algorithm, .String])
-addTo(&precommitTests, "SortStringsUnicode", run_SortStringsUnicode, [.validation, .api, .algorithm, .String])
-addTo(&precommitTests, "StackPromo", run_StackPromo, [.regression])
-addTo(&precommitTests, "StaticArray", run_StaticArray, [.validation, .api, .Array])
-addTo(&precommitTests, "StrComplexWalk", run_StrComplexWalk, [.validation, .api, .String])
-addTo(&precommitTests, "StrToInt", run_StrToInt, [.validation, .api, .String])
-addTo(&precommitTests, "StringAdder", run_StringAdder, [.validation, .api, .String])
-addTo(&precommitTests, "StringBuilder", run_StringBuilder, [.validation, .api, .String])
-addTo(&precommitTests, "StringBuilderLong", run_StringBuilderLong, [.validation, .api, .String])
-addTo(&precommitTests, "StringEdits", run_StringEdits, [.validation, .api, .String])
-addTo(&precommitTests, "StringEnumRawValueInitialization", run_StringEnumRawValueInitialization, [.validation, .api, .String])
-addTo(&precommitTests, "StringEqualPointerComparison", run_StringEqualPointerComparison, [.validation, .api, .String])
-addTo(&precommitTests, "StringFromLongWholeSubstring", run_StringFromLongWholeSubstring, [.validation, .api, .String])
-addTo(&precommitTests, "StringFromLongWholeSubstringGeneric", run_StringFromLongWholeSubstringGeneric, [.validation, .api, .String])
-addTo(&precommitTests, "StringHasPrefix", run_StringHasPrefix, [.validation, .api, .String])
-addTo(&precommitTests, "StringHasPrefixUnicode", run_StringHasPrefixUnicode, [.validation, .api, .String])
-addTo(&precommitTests, "StringHasSuffix", run_StringHasSuffix, [.validation, .api, .String])
-addTo(&precommitTests, "StringHasSuffixUnicode", run_StringHasSuffixUnicode, [.validation, .api, .String])
-addTo(&precommitTests, "StringInterpolation", run_StringInterpolation, [.validation, .api, .String])
-addTo(&precommitTests, "StringMatch", run_StringMatch, [.validation, .api, .String])
-addTo(&precommitTests, "StringUTF16Builder", run_StringUTF16Builder, [.validation, .api, .String])
-addTo(&precommitTests, "StringWalk", run_StringWalk, [.validation, .api, .String])
-addTo(&precommitTests, "StringWithCString", run_StringWithCString, [.validation, .api, .String, .bridging])
-addTo(&precommitTests, "SubstringComparable", run_SubstringComparable, [.validation, .api, .String])
-addTo(&precommitTests, "SubstringEqualString", run_SubstringEqualString, [.validation, .api, .String])
-addTo(&precommitTests, "SubstringEquatable", run_SubstringEquatable, [.validation, .api, .String])
-addTo(&precommitTests, "SubstringFromLongString", run_SubstringFromLongString, [.validation, .api, .String])
-addTo(&precommitTests, "SubstringFromLongStringGeneric", run_SubstringFromLongStringGeneric, [.validation, .api, .String])
-addTo(&precommitTests, "SuffixAnyCollection", run_SuffixAnyCollection, [.validation, .api])
-addTo(&precommitTests, "SuffixAnyCollectionLazy", run_SuffixAnyCollectionLazy, [.validation, .api])
-addTo(&precommitTests, "SuffixAnySeqCRangeIter", run_SuffixAnySeqCRangeIter, [.validation, .api])
-addTo(&precommitTests, "SuffixAnySeqCRangeIterLazy", run_SuffixAnySeqCRangeIterLazy, [.validation, .api])
-addTo(&precommitTests, "SuffixAnySeqCntRange", run_SuffixAnySeqCntRange, [.validation, .api])
-addTo(&precommitTests, "SuffixAnySeqCntRangeLazy", run_SuffixAnySeqCntRangeLazy, [.validation, .api])
-addTo(&precommitTests, "SuffixAnySequence", run_SuffixAnySequence, [.validation, .api])
-addTo(&precommitTests, "SuffixAnySequenceLazy", run_SuffixAnySequenceLazy, [.validation, .api])
-addTo(&precommitTests, "SuffixArray", run_SuffixArray, [.validation, .api, .Array])
-addTo(&precommitTests, "SuffixArrayLazy", run_SuffixArrayLazy, [.validation, .api, .Array])
-addTo(&precommitTests, "SuffixCountableRange", run_SuffixCountableRange, [.validation, .api])
-addTo(&precommitTests, "SuffixCountableRangeLazy", run_SuffixCountableRangeLazy, [.validation, .api])
-addTo(&precommitTests, "SuffixSequence", run_SuffixSequence, [.validation, .api])
-addTo(&precommitTests, "SuffixSequenceLazy", run_SuffixSequenceLazy, [.validation, .api])
-addTo(&precommitTests, "SumUsingReduce", run_SumUsingReduce, [.validation, .api])
-addTo(&precommitTests, "SumUsingReduceInto", run_SumUsingReduceInto, [.validation, .api])
-addTo(&precommitTests, "SuperChars", run_SuperChars, [.validation, .api, .String])
-addTo(&precommitTests, "TwoSum", run_TwoSum, [.validation, .api, .Dictionary, .Array, .algorithm])
-addTo(&precommitTests, "TypeFlood", run_TypeFlood, [.validation, .metadata])
-addTo(&precommitTests, "UTF8Decode", run_UTF8Decode, [.validation, .api, .String])
-addTo(&precommitTests, "Walsh", run_Walsh, [.validation, .algorithm])
-addTo(&precommitTests, "XorLoop", run_XorLoop, [.validation])
-addTo(&precommitTests, "accessGlobal", run_accessGlobal, [.regression])
-addTo(&precommitTests, "accessInMatSet", run_accessInMatSet, [.regression])
-addTo(&precommitTests, "accessIndependent", run_accessIndependent, [.regression])
-
-// Other tests
-addTo(&otherTests, "Ackermann", run_Ackermann, [.unstable, .algorithm])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_ClassValueBuffer1", run_ExistentialTestArrayConditionalShift_ClassValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_ClassValueBuffer2", run_ExistentialTestArrayConditionalShift_ClassValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_ClassValueBuffer3", run_ExistentialTestArrayConditionalShift_ClassValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_ClassValueBuffer4", run_ExistentialTestArrayConditionalShift_ClassValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_IntValueBuffer0", run_ExistentialTestArrayConditionalShift_IntValueBuffer0, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_IntValueBuffer1", run_ExistentialTestArrayConditionalShift_IntValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_IntValueBuffer2", run_ExistentialTestArrayConditionalShift_IntValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_IntValueBuffer3", run_ExistentialTestArrayConditionalShift_IntValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayConditionalShift_IntValueBuffer4", run_ExistentialTestArrayConditionalShift_IntValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_ClassValueBuffer1", run_ExistentialTestArrayMutating_ClassValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_ClassValueBuffer2", run_ExistentialTestArrayMutating_ClassValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_ClassValueBuffer3", run_ExistentialTestArrayMutating_ClassValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_ClassValueBuffer4", run_ExistentialTestArrayMutating_ClassValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_IntValueBuffer0", run_ExistentialTestArrayMutating_IntValueBuffer0, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_IntValueBuffer1", run_ExistentialTestArrayMutating_IntValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_IntValueBuffer2", run_ExistentialTestArrayMutating_IntValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_IntValueBuffer3", run_ExistentialTestArrayMutating_IntValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayMutating_IntValueBuffer4", run_ExistentialTestArrayMutating_IntValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_ClassValueBuffer1", run_ExistentialTestArrayOneMethodCall_ClassValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_ClassValueBuffer2", run_ExistentialTestArrayOneMethodCall_ClassValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_ClassValueBuffer3", run_ExistentialTestArrayOneMethodCall_ClassValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_ClassValueBuffer4", run_ExistentialTestArrayOneMethodCall_ClassValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_IntValueBuffer0", run_ExistentialTestArrayOneMethodCall_IntValueBuffer0, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_IntValueBuffer1", run_ExistentialTestArrayOneMethodCall_IntValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_IntValueBuffer2", run_ExistentialTestArrayOneMethodCall_IntValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_IntValueBuffer3", run_ExistentialTestArrayOneMethodCall_IntValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayOneMethodCall_IntValueBuffer4", run_ExistentialTestArrayOneMethodCall_IntValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_ClassValueBuffer1", run_ExistentialTestArrayShift_ClassValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_ClassValueBuffer2", run_ExistentialTestArrayShift_ClassValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_ClassValueBuffer3", run_ExistentialTestArrayShift_ClassValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_ClassValueBuffer4", run_ExistentialTestArrayShift_ClassValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_IntValueBuffer0", run_ExistentialTestArrayShift_IntValueBuffer0, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_IntValueBuffer1", run_ExistentialTestArrayShift_IntValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_IntValueBuffer2", run_ExistentialTestArrayShift_IntValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_IntValueBuffer3", run_ExistentialTestArrayShift_IntValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayShift_IntValueBuffer4", run_ExistentialTestArrayShift_IntValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer1", run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer2", run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer3", run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_ClassValueBuffer4", run_ExistentialTestArrayTwoMethodCalls_ClassValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_IntValueBuffer0", run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer0, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_IntValueBuffer1", run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer1, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_IntValueBuffer2", run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer2, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_IntValueBuffer3", run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer3, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestArrayTwoMethodCalls_IntValueBuffer4", run_ExistentialTestArrayTwoMethodCalls_IntValueBuffer4, [.unstable, .api, .Array])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_ClassValueBuffer1", run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_ClassValueBuffer2", run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_ClassValueBuffer3", run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_ClassValueBuffer4", run_ExistentialTestMutatingAndNonMutating_ClassValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_IntValueBuffer0", run_ExistentialTestMutatingAndNonMutating_IntValueBuffer0, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_IntValueBuffer1", run_ExistentialTestMutatingAndNonMutating_IntValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_IntValueBuffer2", run_ExistentialTestMutatingAndNonMutating_IntValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_IntValueBuffer3", run_ExistentialTestMutatingAndNonMutating_IntValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestMutatingAndNonMutating_IntValueBuffer4", run_ExistentialTestMutatingAndNonMutating_IntValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_ClassValueBuffer1", run_ExistentialTestMutating_ClassValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_ClassValueBuffer2", run_ExistentialTestMutating_ClassValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_ClassValueBuffer3", run_ExistentialTestMutating_ClassValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_ClassValueBuffer4", run_ExistentialTestMutating_ClassValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_IntValueBuffer0", run_ExistentialTestMutating_IntValueBuffer0, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_IntValueBuffer1", run_ExistentialTestMutating_IntValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_IntValueBuffer2", run_ExistentialTestMutating_IntValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_IntValueBuffer3", run_ExistentialTestMutating_IntValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestMutating_IntValueBuffer4", run_ExistentialTestMutating_IntValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_ClassValueBuffer1", run_ExistentialTestOneMethodCall_ClassValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_ClassValueBuffer2", run_ExistentialTestOneMethodCall_ClassValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_ClassValueBuffer3", run_ExistentialTestOneMethodCall_ClassValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_ClassValueBuffer4", run_ExistentialTestOneMethodCall_ClassValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_IntValueBuffer0", run_ExistentialTestOneMethodCall_IntValueBuffer0, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_IntValueBuffer1", run_ExistentialTestOneMethodCall_IntValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_IntValueBuffer2", run_ExistentialTestOneMethodCall_IntValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_IntValueBuffer3", run_ExistentialTestOneMethodCall_IntValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestOneMethodCall_IntValueBuffer4", run_ExistentialTestOneMethodCall_IntValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer1", run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer2", run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer3", run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer4", run_ExistentialTestPassExistentialOneMethodCall_ClassValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer0", run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer0, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer1", run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer2", run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer3", run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialOneMethodCall_IntValueBuffer4", run_ExistentialTestPassExistentialOneMethodCall_IntValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer1", run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer2", run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer3", run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer4", run_ExistentialTestPassExistentialTwoMethodCalls_ClassValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer0", run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer0, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer1", run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer2", run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer3", run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer4", run_ExistentialTestPassExistentialTwoMethodCalls_IntValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_ClassValueBuffer1", run_ExistentialTestTwoMethodCalls_ClassValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_ClassValueBuffer2", run_ExistentialTestTwoMethodCalls_ClassValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_ClassValueBuffer3", run_ExistentialTestTwoMethodCalls_ClassValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_ClassValueBuffer4", run_ExistentialTestTwoMethodCalls_ClassValueBuffer4, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_IntValueBuffer0", run_ExistentialTestTwoMethodCalls_IntValueBuffer0, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_IntValueBuffer1", run_ExistentialTestTwoMethodCalls_IntValueBuffer1, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_IntValueBuffer2", run_ExistentialTestTwoMethodCalls_IntValueBuffer2, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_IntValueBuffer3", run_ExistentialTestTwoMethodCalls_IntValueBuffer3, [.unstable])
-addTo(&otherTests, "ExistentialTestTwoMethodCalls_IntValueBuffer4", run_ExistentialTestTwoMethodCalls_IntValueBuffer4, [.unstable])
-addTo(&otherTests, "Fibonacci", run_Fibonacci, [.unstable, .algorithm])
-addTo(&otherTests, "HashQuadratic", run_HashQuadratic, [.unstable, .api, .Dictionary])
-
-// String tests, an extended benchmark suite exercising finer-granularity
-// behavior of our Strings.
-addTo(&stringTests, "StringWalk_ascii_characters", run_StringWalk_ascii_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_ascii_characters_Backwards", run_StringWalk_ascii_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_ascii_unicodeScalars", run_StringWalk_ascii_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_ascii_unicodeScalars_Backwards", run_StringWalk_ascii_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_chinese_characters", run_StringWalk_chinese_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_chinese_characters_Backwards", run_StringWalk_chinese_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_chinese_unicodeScalars", run_StringWalk_chinese_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_chinese_unicodeScalars_Backwards", run_StringWalk_chinese_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_japanese_characters", run_StringWalk_japanese_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_japanese_characters_Backwards", run_StringWalk_japanese_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_japanese_unicodeScalars", run_StringWalk_japanese_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_japanese_unicodeScalars_Backwards", run_StringWalk_japanese_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_korean_characters", run_StringWalk_korean_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_korean_characters_Backwards", run_StringWalk_korean_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_korean_unicodeScalars", run_StringWalk_korean_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_korean_unicodeScalars_Backwards", run_StringWalk_korean_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuatedJapanese_characters", run_StringWalk_punctuatedJapanese_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuatedJapanese_characters_Backwards", run_StringWalk_punctuatedJapanese_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuatedJapanese_unicodeScalars", run_StringWalk_punctuatedJapanese_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuatedJapanese_unicodeScalars_Backwards", run_StringWalk_punctuatedJapanese_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuated_characters", run_StringWalk_punctuated_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuated_characters_Backwards", run_StringWalk_punctuated_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuated_unicodeScalars", run_StringWalk_punctuated_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_punctuated_unicodeScalars_Backwards", run_StringWalk_punctuated_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_russian_characters", run_StringWalk_russian_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_russian_characters_Backwards", run_StringWalk_russian_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_russian_unicodeScalars", run_StringWalk_russian_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_russian_unicodeScalars_Backwards", run_StringWalk_russian_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_tweet_characters", run_StringWalk_tweet_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_tweet_characters_Backwards", run_StringWalk_tweet_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_tweet_unicodeScalars", run_StringWalk_tweet_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_tweet_unicodeScalars_Backwards", run_StringWalk_tweet_unicodeScalars_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_utf16_characters", run_StringWalk_utf16_characters, [.api, .String])
-addTo(&stringTests, "StringWalk_utf16_characters_Backwards", run_StringWalk_utf16_characters_Backwards, [.api, .String])
-addTo(&stringTests, "StringWalk_utf16_unicodeScalars", run_StringWalk_utf16_unicodeScalars, [.api, .String])
-addTo(&stringTests, "StringWalk_utf16_unicodeScalars_Backwards", run_StringWalk_utf16_unicodeScalars_Backwards, [.api, .String])
+registerBenchmark(Ackermann)
+registerBenchmark(AngryPhonebook)
+registerBenchmark(AnyHashableWithAClass)
+registerBenchmark(Array2D)
+registerBenchmark(ArrayAppend)
+registerBenchmark(ArrayInClass)
+registerBenchmark(ArrayLiteral)
+registerBenchmark(ArrayOfGenericPOD)
+registerBenchmark(ArrayOfGenericRef)
+registerBenchmark(ArrayOfPOD)
+registerBenchmark(ArrayOfRef)
+registerBenchmark(ArraySetElement)
+registerBenchmark(ArraySubscript)
+registerBenchmark(BitCount)
+registerBenchmark(ByteSwap)
+registerBenchmark(CString)
+registerBenchmark(Calculator)
+registerBenchmark(CaptureProp)
+registerBenchmark(CharacterLiteralsLarge)
+registerBenchmark(CharacterLiteralsSmall)
+registerBenchmark(Chars)
+registerBenchmark(ClassArrayGetter)
+registerBenchmark(DeadArray)
+registerBenchmark(Dictionary)
+registerBenchmark(Dictionary2)
+registerBenchmark(Dictionary3)
+registerBenchmark(DictionaryBridge)
+registerBenchmark(DictionaryGroup)
+registerBenchmark(DictionaryLiteral)
+registerBenchmark(DictionaryRemove)
+registerBenchmark(DictionarySwap)
+registerBenchmark(DropFirst)
+registerBenchmark(DropLast)
+registerBenchmark(DropWhile)
+registerBenchmark(ErrorHandling)
+registerBenchmark(Exclusivity)
+registerBenchmark(ExistentialPerformance)
+registerBenchmark(Fibonacci)
+registerBenchmark(Hanoi)
+registerBenchmark(HashTest)
+registerBenchmark(HashQuadratic)
+registerBenchmark(Histogram)
+registerBenchmark(IntegrateTest)
+registerBenchmark(IterateData)
+registerBenchmark(Join)
+registerBenchmark(LazyFilter)
+registerBenchmark(LinkedList)
+registerBenchmark(MapReduce)
+registerBenchmark(Memset)
+registerBenchmark(MonteCarloE)
+registerBenchmark(MonteCarloPi)
+registerBenchmark(NSDictionaryCastToSwift)
+registerBenchmark(NSErrorTest)
+registerBenchmark(NSStringConversion)
+registerBenchmark(NopDeinit)
+registerBenchmark(ObjectAllocation)
+registerBenchmark(ObjectiveCBridging)
+registerBenchmark(ObjectiveCBridgingStubs)
+registerBenchmark(ObjectiveCNoBridgingStubs)
+registerBenchmark(ObserverClosure)
+registerBenchmark(ObserverForwarderStruct)
+registerBenchmark(ObserverPartiallyAppliedMethod)
+registerBenchmark(ObserverUnappliedMethod)
+registerBenchmark(OpenClose)
+registerBenchmark(Phonebook)
+registerBenchmark(PolymorphicCalls)
+registerBenchmark(PopFront)
+registerBenchmark(PopFrontArrayGeneric)
+registerBenchmark(Prefix)
+registerBenchmark(PrefixWhile)
+registerBenchmark(Prims)
+registerBenchmark(PrimsSplit)
+registerBenchmark(ProtocolDispatch)
+registerBenchmark(ProtocolDispatch2)
+registerBenchmark(RC4Test)
+registerBenchmark(RGBHistogram)
+registerBenchmark(RangeAssignment)
+registerBenchmark(RangeIteration)
+registerBenchmark(RecursiveOwnedParameter)
+registerBenchmark(ReduceInto)
+registerBenchmark(ReversedCollections)
+registerBenchmark(SetTests)
+registerBenchmark(SevenBoom)
+registerBenchmark(Sim2DArray)
+registerBenchmark(SortLargeExistentials)
+registerBenchmark(SortLettersInPlace)
+registerBenchmark(SortStrings)
+registerBenchmark(StackPromo)
+registerBenchmark(StaticArrayTest)
+registerBenchmark(StrComplexWalk)
+registerBenchmark(StrToInt)
+registerBenchmark(StringBuilder)
+registerBenchmark(StringEdits)
+registerBenchmark(StringEnum)
+registerBenchmark(StringInterpolation)
+registerBenchmark(StringMatch)
+registerBenchmark(StringTests)
+registerBenchmark(StringWalk)
+registerBenchmark(SubstringTest)
+registerBenchmark(Suffix)
+registerBenchmark(SuperChars)
+registerBenchmark(TwoSum)
+registerBenchmark(TypeFlood)
+registerBenchmark(UTF8Decode)
+registerBenchmark(Walsh)
+registerBenchmark(XorLoop)
 
 main()
diff --git a/cmake/modules/SwiftExternalBenchmarkBuild.cmake b/cmake/modules/SwiftExternalBenchmarkBuild.cmake
index 1d8614d..06e8eef 100644
--- a/cmake/modules/SwiftExternalBenchmarkBuild.cmake
+++ b/cmake/modules/SwiftExternalBenchmarkBuild.cmake
@@ -61,7 +61,7 @@
   set(stamp_dir ${SWIFT_BINARY_DIR}/external-benchmark/stamps)
   set(prefix_dir ${SWIFT_BINARY_DIR}/external-benchmark/prefix)
 
-  set(bench_targets Benchmark_O Benchmark_Onone Benchmark_Ounchecked)
+  set(bench_targets Benchmark_O Benchmark_Onone Benchmark_Osize)
   set(library_targets swift-benchmark-macosx-x86_64-external)
 
   set(all_stdlib_dependencies)
diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst
index 07de796..602d79f 100644
--- a/docs/Lexicon.rst
+++ b/docs/Lexicon.rst
@@ -344,12 +344,6 @@
     "Swift Intermediate Language". A high-level IR used by the Swift compiler
     for flow-sensitive diagnostics, optimization, and LLVM IR generation.
 
-  -sil-serialize-all
-    A mode where all functions in a library are made available for inlining by
-    any client, regardless of access control. Also called "magic performance
-    mode" as a reminder of how this drastically changes compilation. Not
-    guaranteed to work on arbitrary code.
-
   SR
     An issue reported on `bugs.swift.org <https://bugs.swift.org>`_. A
     backronym for "Swift Report"; really the name is derived from LLVM's
diff --git a/docs/SIL.rst b/docs/SIL.rst
index 0f11734..254abd9 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -1034,8 +1034,7 @@
   sil-vtable-entry ::= sil-decl-ref ':' sil-linkage? sil-function-name
 
 SIL represents dynamic dispatch for class methods using the `class_method`_,
-`super_method`_, `objc_method`_, `objc_super_method`_ and `dynamic_method`_
-instructions.
+`super_method`_, `objc_method`_, and `objc_super_method`_ instructions.
 
 The potential destinations for `class_method`_ and `super_method`_ are
 tracked in ``sil_vtable`` declarations for every class type. The declaration
@@ -2945,10 +2944,9 @@
 The ``class_method`` and ``super_method`` instructions must reference
 Swift native methods and always use vtable dispatch.
 
-The ``objc_method``, ``objc_super_method`` and ``dynamic_method``
-instructions must reference Objective-C methods (indicated by the
-``foreign`` marker on a method reference, as in
-``#NSObject.description!1.foreign``).
+The ``objc_method`` and ``objc_super_method`` instructions must reference
+Objective-C methods (indicated by the ``foreign`` marker on a method
+reference, as in ``#NSObject.description!1.foreign``).
 
 Note that ``objc_msgSend`` invocations can only be used as the callee
 of an ``apply`` instruction or ``partial_apply`` instruction. They cannot
@@ -3046,40 +3044,6 @@
 convention. If the referenced protocol is an ``@objc`` protocol, the
 resulting type has the ``objc`` calling convention.
 
-dynamic_method
-``````````````
-::
-
-  sil-instruction ::= 'dynamic_method' sil-method-attributes?
-                      sil-operand ',' sil-decl-ref ':' sil-type
-
-  %1 = dynamic_method %0 : $P, #X.method!1 : $@convention(thin) U -> V
-  // %0 must be of a protocol or protocol composition type $P,
-  // where $P contains the Swift.DynamicLookup protocol
-  // #X.method!1 must be a reference to an @objc method of any class
-  // or protocol type
-  //
-  // The "self" argument of the method type $@convention(thin) U -> V must be
-  //   AnyObject
-
-Looks up the implementation of an Objective-C method with the same
-selector as the named method for the dynamic type of the
-value inside an existential container. The "self" operand of the result
-function value is represented using an opaque type, the value for which must
-be projected out as a value of type ``AnyObject``.
-
-It is undefined behavior if the dynamic type of the operand does not
-have an implementation for the Objective-C method with the selector to
-which the ``dynamic_method`` instruction refers, or if that
-implementation has parameter or result types that are incompatible
-with the method referenced by ``dynamic_method``.
-This instruction should only be used in cases where its result will be
-immediately consumed by an operation that performs the selector check
-itself (e.g., an ``apply`` that lowers to ``objc_msgSend``).
-To query whether the operand has an implementation for the given
-method and safely handle the case where it does not, use
-`dynamic_method_br`_.
-
 Function Application
 ~~~~~~~~~~~~~~~~~~~~
 
diff --git a/include/swift/ABI/System.h b/include/swift/ABI/System.h
index ad3a986..47bd2e4 100644
--- a/include/swift/ABI/System.h
+++ b/include/swift/ABI/System.h
@@ -14,128 +14,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef SWIFT_ABI_SYSTEM_H
-#define SWIFT_ABI_SYSTEM_H
+#ifndef __SWIFT_ABI_SYSTEM_H__
+#define __SWIFT_ABI_SYSTEM_H__
 
-// In general, these macros are expected to expand to host-independent
-// integer constant expressions.  This allows the same data to feed
-// both the compiler and runtime implementation.
+#include "../../../stdlib/public/SwiftShims/System.h"
 
-/******************************* Default Rules ********************************/
-
-/// The least valid pointer value for an actual pointer (as opposed to
-/// Objective-C pointers, which may be tagged pointers and are covered
-/// separately).  Values up to this are "extra inhabitants" of the
-/// pointer representation, and payloaded enum types can take
-/// advantage of that as they see fit.
-///
-/// By default, we assume that there's at least an unmapped page at
-/// the bottom of the address space.  4K is a reasonably likely page
-/// size.
-///
-/// The minimum possible value for this macro is 1; we always assume
-/// that the null representation is available.
-#define SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER 4096
-
-/// The bitmask of spare bits in a function pointer.
-#define SWIFT_ABI_DEFAULT_FUNCTION_SPARE_BITS_MASK 0
-
-/// The bitmask of spare bits in a Swift heap object pointer.  A Swift
-/// heap object allocation will never set any of these bits.
-#define SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK 0
-
-/// The bitmask of reserved bits in an Objective-C object pointer.
-/// By default we assume the ObjC runtime doesn't use tagged pointers.
-#define SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK 0
-
-/// The number of low bits in an Objective-C object pointer that
-/// are reserved by the Objective-C runtime.
-#define SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS 0
-
-/// The ObjC runtime will not use pointer values for which
-/// ``pointer & SWIFT_ABI_XXX_OBJC_RESERVED_BITS_MASK == 0 && 
-/// pointer & SWIFT_ABI_XXX_SWIFT_SPARE_BITS_MASK != 0``.
-
-// Weak references use a marker to tell when they are controlled by
-// the ObjC runtime and when they are controlled by the Swift runtime.
-// Non-ObjC platforms don't use this marker.
-#define SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_MASK 0
-#define SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_VALUE 0
-
-/*********************************** i386 *************************************/
-
-// Heap objects are pointer-aligned, so the low two bits are unused.
-#define SWIFT_ABI_I386_SWIFT_SPARE_BITS_MASK 0x00000003U
-
-// ObjC weak reference discriminator is the LSB.
-#define SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_MASK  \
-  (SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK |          \
-   1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
-#define SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_VALUE \
-  (1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
-
-/*********************************** arm **************************************/
-
-// Heap objects are pointer-aligned, so the low two bits are unused.
-#define SWIFT_ABI_ARM_SWIFT_SPARE_BITS_MASK 0x00000003U
-
-// ObjC weak reference discriminator is the LSB.
-#define SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_MASK  \
-  (SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK |          \
-   1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
-#define SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_VALUE \
-  (1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
-
-/*********************************** x86-64 ***********************************/
-
-/// Darwin reserves the low 4GB of address space.
-#define SWIFT_ABI_DARWIN_X86_64_LEAST_VALID_POINTER (4ULL*1024*1024*1024)
-
-// Only the bottom 56 bits are used, and heap objects are eight-byte-aligned.
-#define SWIFT_ABI_X86_64_SWIFT_SPARE_BITS_MASK 0xFF00000000000007ULL
-
-// Objective-C reserves the high and low bits for tagged pointers.
-// Systems exist which use either bit.
-#define SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK 0x8000000000000001ULL
-#define SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS 1
-
-// ObjC weak reference discriminator is the two bits
-// reserved for ObjC tagged pointers plus one more low bit.
-#define SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_MASK  \
-  (SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK |          \
-   1<<SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS)
-#define SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_VALUE \
-  (1<<SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS)
-
-/*********************************** arm64 ************************************/
-
-/// Darwin reserves the low 4GB of address space.
-#define SWIFT_ABI_DARWIN_ARM64_LEAST_VALID_POINTER (4ULL*1024*1024*1024)
-
-// TBI guarantees the top byte of pointers is unused.
-// Heap objects are eight-byte aligned.
-#define SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK 0xFF00000000000007ULL
-
-// Objective-C reserves just the high bit for tagged pointers.
-#define SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK 0x8000000000000000ULL
-#define SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS 0
-
-// ObjC weak reference discriminator is the high bit
-// reserved for ObjC tagged pointers plus the LSB.
-#define SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_MASK  \
-  (SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK |          \
-   1<<SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS)
-#define SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_VALUE \
-  (1<<SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS)
-
-/*********************************** powerpc64 ********************************/
-
-// Heap objects are pointer-aligned, so the low three bits are unused.
-#define SWIFT_ABI_POWERPC64_SWIFT_SPARE_BITS_MASK 0x0000000000000007ULL
-
-/*********************************** s390x ************************************/
-
-// Top byte of pointers is unused, and heap objects are eight-byte aligned.
-#define SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK 0x0000000000000007ULL
-
-#endif /* SWIFT_ABI_SYSTEM_H */
+#endif // __SWIFT_ABI_SYSTEM_H__
diff --git a/include/swift/AST/AnyFunctionRef.h b/include/swift/AST/AnyFunctionRef.h
index 2d5e1fb..80d0fda 100644
--- a/include/swift/AST/AnyFunctionRef.h
+++ b/include/swift/AST/AnyFunctionRef.h
@@ -116,18 +116,9 @@
   /// known not to escape from that function.  In this case, captures can be
   /// more efficient.
   bool isKnownNoEscape() const {
-    if (auto afd = TheFunction.dyn_cast<AbstractFunctionDecl *>()) {
-      // As a hack, assume defer bodies are noescape.
-      if (auto fd = dyn_cast<FuncDecl>(afd))
-        return fd->isDeferBody();
-      return false;
-    }
-
-
-    auto *CE = TheFunction.get<AbstractClosureExpr *>();
-    if (!CE->getType() || CE->getType()->hasError())
-      return false;
-    return CE->getType()->castTo<FunctionType>()->isNoEscape();
+    if (hasType() && !getType()->hasError())
+      return getType()->castTo<AnyFunctionType>()->isNoEscape();
+    return false;
   }
 
   bool isObjC() const {
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 3f02471..02a99a5 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -562,8 +562,10 @@
   class AssociatedTypeDeclBitfields {
     friend class AssociatedTypeDecl;
     unsigned : NumTypeDeclBits;
+    unsigned ComputedOverridden : 1;
+    unsigned HasOverridden : 1;
   };
-  enum { NumAssociatedTypeDeclBits = NumTypeDeclBits };
+  enum { NumAssociatedTypeDeclBits = NumTypeDeclBits + 2 };
   static_assert(NumAssociatedTypeDeclBits <= 32, "fits in an unsigned");
 
   class ImportDeclBitfields {
@@ -2207,6 +2209,9 @@
     return result;
   }
 
+  /// Determine whether this Decl has either Private or FilePrivate access.
+  bool isOutermostPrivateOrFilePrivateScope() const;
+
   /// Returns the outermost DeclContext from which this declaration can be
   /// accessed, or null if the declaration is public.
   ///
@@ -2662,6 +2667,33 @@
   /// type; can only be called after the alias type has been resolved.
   void computeType();
 
+  /// Retrieve the associated type "anchor", which is the associated type
+  /// declaration that will be used to describe this associated type in the
+  /// ABI.
+  ///
+  /// The associated type "anchor" is an associated type that does not
+  /// override any other associated type. There may be several such associated
+  /// types; select one deterministically.
+  AssociatedTypeDecl *getAssociatedTypeAnchor() const;
+
+  /// Retrieve the (first) overridden associated type declaration, if any.
+  AssociatedTypeDecl *getOverriddenDecl() const;
+
+  /// Retrieve the set of associated types overridden by this associated
+  /// type.
+  ArrayRef<AssociatedTypeDecl *> getOverriddenDecls() const;
+
+  /// Whether the overridden declarations have already been computed.
+  bool overriddenDeclsComputed() const {
+    return AssociatedTypeDeclBits.ComputedOverridden;
+  }
+
+  /// Record the set of overridden declarations.
+  ///
+  /// \returns the array recorded in the AST.
+  ArrayRef<AssociatedTypeDecl *> setOverriddenDecls(
+                                   ArrayRef<AssociatedTypeDecl *> overridden);
+
   SourceLoc getStartLoc() const { return KeywordLoc; }
   SourceRange getSourceRange() const;
 
@@ -3552,6 +3584,11 @@
   /// Retrieve the set of protocols inherited from this protocol.
   llvm::TinyPtrVector<ProtocolDecl *> getInheritedProtocols() const;
 
+  /// Retrieve the set of AssociatedTypeDecl members of this protocol; this
+  /// saves loading the set of members in cases where there's no possibility of
+  /// a protocol having nested types (ObjC protocols).
+  llvm::TinyPtrVector<AssociatedTypeDecl *> getAssociatedTypeMembers() const;
+
   /// Walk all of the protocols inherited by this protocol, transitively,
   /// invoking the callback function for each protocol.
   ///
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index a107dec..cd65582 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1452,6 +1452,11 @@
       "method %0 in non-final class %1 must return `Self` to conform to "
       "protocol %2",
       (DeclName, Type, Type))
+ERROR(witness_requires_class_implementation,none,
+      "method %0 in non-final class %1 cannot be implemented in a "
+      "protocol extension because it returns `Self` and has associated type "
+      "requirements",
+      (DeclName, Type))
 ERROR(witness_not_accessible_proto,none,
       "%select{initializer %1|method %1|%select{|setter for }2property %1"
       "|subscript%select{| setter}2}0 must be declared "
@@ -3115,6 +3120,13 @@
       "'weak' variable should have optional type %0", (Type))
 ERROR(invalid_weak_let,none,
       "'weak' must be a mutable variable, because it may change at runtime", ())
+ERROR(ownership_invalid_in_protocols,none,
+      "'%select{strong|weak|unowned|unowned}0' cannot be applied to a property declaration in a protocol",
+      (/*Ownership*/unsigned))
+WARNING(ownership_invalid_in_protocols_compat_warning,none,
+      "'%select{strong|weak|unowned|unowned}0' should not be applied to a property declaration "
+      "in a protocol and will be disallowed in future versions",
+      (/*Ownership*/unsigned))
 
 // required
 ERROR(required_initializer_nonclass,none,
diff --git a/include/swift/AST/GenericEnvironment.h b/include/swift/AST/GenericEnvironment.h
index e2fe487..50b943b 100644
--- a/include/swift/AST/GenericEnvironment.h
+++ b/include/swift/AST/GenericEnvironment.h
@@ -37,37 +37,17 @@
 /// Describes the mapping between archetypes and interface types for the
 /// generic parameters of a DeclContext.
 class alignas(1 << DeclAlignInBits) GenericEnvironment final
-        : private llvm::TrailingObjects<GenericEnvironment, Type,
-                                        std::pair<ArchetypeType *,
-                                                  GenericTypeParamType *>> {
+        : private llvm::TrailingObjects<GenericEnvironment, Type> {
   GenericSignature *Signature = nullptr;
   GenericSignatureBuilder *Builder = nullptr;
   DeclContext *OwningDC = nullptr;
 
-  // The number of generic type parameter -> context type mappings we have
-  // recorded so far. This saturates at the number of generic type parameters,
-  // at which point the archetype-to-interface trailing array is sorted.
-  unsigned NumMappingsRecorded : 16;
-
-  // The number of archetype-to-interface type mappings. This is always <=
-  // \c NumMappingsRecorded.
-  unsigned NumArchetypeToInterfaceMappings : 16;
-
   friend TrailingObjects;
 
-  /// An entry in the array mapping from archetypes to their corresponding
-  /// generic type parameters.
-  typedef std::pair<ArchetypeType *, GenericTypeParamType *>
-                                                    ArchetypeToInterfaceMapping;
-
   size_t numTrailingObjects(OverloadToken<Type>) const {
     return Signature->getGenericParams().size();
   }
 
-  size_t numTrailingObjects(OverloadToken<ArchetypeToInterfaceMapping>) const {
-    return Signature->getGenericParams().size();
-  }
-
   /// Retrieve the array containing the context types associated with the
   /// generic parameters, stored in parallel with the generic parameters of the
   /// generic signature.
@@ -84,30 +64,6 @@
                           Signature->getGenericParams().size());
   }
 
-  /// Retrieve the active set of archetype-to-interface mappings.
-  ArrayRef<ArchetypeToInterfaceMapping>
-                                getActiveArchetypeToInterfaceMappings() const {
-    return { getTrailingObjects<ArchetypeToInterfaceMapping>(),
-             NumArchetypeToInterfaceMappings };
-  }
-
-  /// Retrieve the active set of archetype-to-interface mappings.
-  MutableArrayRef<ArchetypeToInterfaceMapping>
-                                      getActiveArchetypeToInterfaceMappings() {
-    return { getTrailingObjects<ArchetypeToInterfaceMapping>(),
-             NumArchetypeToInterfaceMappings };
-  }
-
-  /// Retrieve the buffer for the archetype-to-interface mappings.
-  ///
-  /// Only the first \c NumArchetypeToInterfaceMappings elements in the buffer
-  /// are valid.
-  MutableArrayRef<ArchetypeToInterfaceMapping>
-                                      getArchetypeToInterfaceMappingsBuffer() {
-    return { getTrailingObjects<ArchetypeToInterfaceMapping>(),
-             Signature->getGenericParams().size() };
-  }
-
   GenericEnvironment(GenericSignature *signature,
                      GenericSignatureBuilder *builder);
 
@@ -129,19 +85,6 @@
   };
   friend class QueryInterfaceTypeSubstitutions;
 
-  /// Query function suitable for use as a \c TypeSubstitutionFn that queries
-  /// the mapping of archetypes back to interface types.
-  class QueryArchetypeToInterfaceSubstitutions {
-    const GenericEnvironment *self;
-
-  public:
-    QueryArchetypeToInterfaceSubstitutions(const GenericEnvironment *self)
-      : self(self) { }
-
-    Type operator()(SubstitutableType *type) const;
-  };
-  friend class QueryArchetypeToInterfaceSubstitutions;
-
 public:
   GenericSignature *getGenericSignature() const {
     return Signature;
@@ -151,10 +94,6 @@
     return Signature->getGenericParams();
   }
 
-  /// Determine whether this generic environment contains the given
-  /// primary archetype.
-  bool containsPrimaryArchetype(ArchetypeType *archetype) const;
-
   /// Create a new, "incomplete" generic environment that will be populated
   /// by calls to \c addMapping().
   static
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index e55ee0b..5aa9dc6 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -1452,18 +1452,13 @@
   /// associated type.
   PotentialArchetype(PotentialArchetype *parent, Identifier name);
 
-  /// \brief Construct a new potential archetype for an associated type.
-  PotentialArchetype(PotentialArchetype *parent, AssociatedTypeDecl *assocType)
-    : parentOrBuilder(parent), identifier(assocType)
-  {
-    assert(parent != nullptr && "Not an associated type?");
-  }
-
   /// \brief Construct a new potential archetype for a concrete declaration.
   PotentialArchetype(PotentialArchetype *parent, TypeDecl *concreteDecl)
     : parentOrBuilder(parent), identifier(concreteDecl)
   {
-    assert(parent != nullptr && "Not an associated type?");
+    assert(parent != nullptr && "Not a nested type?");
+    assert(!isa<AssociatedTypeDecl>(concreteDecl) ||
+      cast<AssociatedTypeDecl>(concreteDecl)->getOverriddenDecls().empty());
   }
 
   /// \brief Construct a new potential archetype for a generic parameter.
diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h
index 72c6545..116afec 100644
--- a/include/swift/AST/Module.h
+++ b/include/swift/AST/Module.h
@@ -112,13 +112,7 @@
   /// Non-inlineable function bodies: resilient
   ///
   /// This is the behavior with -enable-resilience.
-  Resilient,
-
-  /// Public nominal types: fragile
-  /// Non-inlineable function bodies: fragile
-  ///
-  /// This is the behavior with -sil-serialize-all.
-  Fragile
+  Resilient
 };
 
 /// The minimum unit of compilation.
diff --git a/include/swift/AST/SILOptions.h b/include/swift/AST/SILOptions.h
index acefc7f..1831973 100644
--- a/include/swift/AST/SILOptions.h
+++ b/include/swift/AST/SILOptions.h
@@ -150,11 +150,6 @@
   /// \brief Enable large loadable types IRGen pass.
   bool EnableLargeLoadableTypes = true;
 
-  /// Enables the "fully fragile" resilience strategy.
-  ///
-  /// \see ResilienceStrategy::Fragile
-  bool SILSerializeAll = false;
-
   /// If set, SIL witness tables will be serialized.
   ///
   /// It is supposed to be used only for compiling overlays.
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index e4176cc..40a9610 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -3520,10 +3520,16 @@
 
   CanType getSelfInstanceType() const;
 
-  /// If this a @convention(witness_method) function with an abstract
-  /// self parameter, return the protocol constraint for the Self type.
+  /// If this is a @convention(witness_method) function with a protocol
+  /// constrained self parameter, return the protocol constraint for
+  /// the Self type.
   ProtocolDecl *getDefaultWitnessMethodProtocol(ModuleDecl &M) const;
 
+  /// If this is a @convention(witness_method) function with a class
+  /// constrained self parameter, return the class constraint for the
+  /// Self type.
+  ClassDecl *getWitnessMethodClass(ModuleDecl &M) const;
+
   ExtInfo getExtInfo() const { return ExtInfo(SILFunctionTypeBits.ExtInfo); }
 
   /// \brief Returns the language-level calling convention of the function.
@@ -4041,7 +4047,7 @@
 
   llvm::PointerUnion3<ArchetypeType *, TypeBase *,
                       GenericEnvironment *> ParentOrOpenedOrEnvironment;
-  llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName;
+  Type InterfaceType;
   MutableArrayRef<std::pair<Identifier, Type>> NestedTypes;
 
   void populateNestedTypes() const;
@@ -4053,7 +4059,7 @@
   /// The ConformsTo array will be copied into the ASTContext by this routine.
   static CanTypeWrapper<ArchetypeType>
                         getNew(const ASTContext &Ctx, ArchetypeType *Parent,
-                               AssociatedTypeDecl *AssocType,
+                               DependentMemberType *InterfaceType,
                                SmallVectorImpl<ProtocolDecl *> &ConformsTo,
                                Type Superclass, LayoutConstraint Layout);
 
@@ -4063,8 +4069,8 @@
   /// by this routine.
   static CanTypeWrapper<ArchetypeType>
                         getNew(const ASTContext &Ctx,
-                               GenericEnvironment *genericEnvironment,
-                               Identifier Name,
+                               GenericEnvironment *GenericEnv,
+                               GenericTypeParamType *InterfaceType,
                                SmallVectorImpl<ProtocolDecl *> &ConformsTo,
                                Type Superclass, LayoutConstraint Layout);
 
@@ -4108,15 +4114,17 @@
   /// Note: opened archetypes currently don't have generic environments.
   GenericEnvironment *getGenericEnvironment() const;
 
+  /// Retrieve the interface type of this associated type, which will either
+  /// be a GenericTypeParamType or a DependentMemberType.
+  Type getInterfaceType() const { return InterfaceType; }
+
   /// Retrieve the associated type to which this archetype (if it is a nested
   /// archetype) corresponds.
   ///
   /// This associated type will have the same name as the archetype and will
   /// be a member of one of the protocols to which the parent archetype
   /// conforms.
-  AssociatedTypeDecl *getAssocType() const {
-    return AssocTypeOrName.dyn_cast<AssociatedTypeDecl *>();
-  }
+  AssociatedTypeDecl *getAssocType() const;
 
   /// getConformsTo - Retrieve the set of protocols to which this substitutable
   /// type shall conform.
@@ -4224,7 +4232,7 @@
           const ASTContext &Ctx,
           llvm::PointerUnion<ArchetypeType *, GenericEnvironment *>
             ParentOrGenericEnv,
-          llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName,
+          Type InterfaceType,
           ArrayRef<ProtocolDecl *> ConformsTo,
           Type Superclass, LayoutConstraint Layout);
 
diff --git a/include/swift/AST/Witness.h b/include/swift/AST/Witness.h
index e81c5ea..02b4a1d 100644
--- a/include/swift/AST/Witness.h
+++ b/include/swift/AST/Witness.h
@@ -150,13 +150,6 @@
   /// Determines whether there is a witness at all.
   explicit operator bool() const { return !storage.isNull(); }
 
-  /// Implicit conversion to the \c ConcreteDeclRef, which is used by a
-  /// number of clients.
-  ///
-  /// FIXME: We probably want this to go away eventually, because clients using
-  /// it will all need to be cognizant of the synthetic environment.
-  operator ConcreteDeclRef() const { return getDeclRef(); }
-
   /// Determine whether this witness requires any substitutions.
   bool requiresSubstitution() const { return storage.is<StoredWitness *>(); }
 
diff --git a/include/swift/Driver/ToolChain.h b/include/swift/Driver/ToolChain.h
index 74c29a5..1b79835 100644
--- a/include/swift/Driver/ToolChain.h
+++ b/include/swift/Driver/ToolChain.h
@@ -167,6 +167,8 @@
                                     const OutputInfo &OI) const;
 
   /// Return the default language type to use for the given extension.
+  /// If the extension is empty or is otherwise not recognized, return
+  /// the invalid type \c TY_INVALID.
   virtual types::ID lookupTypeForExtension(StringRef Ext) const;
 
   /// Check whether a clang library with a given name exists.
diff --git a/include/swift/Driver/Types.def b/include/swift/Driver/Types.def
index 98cb9b3..14c69b4 100644
--- a/include/swift/Driver/Types.def
+++ b/include/swift/Driver/Types.def
@@ -60,10 +60,7 @@
 TYPE("imported-modules", ImportedModules,   "importedmodules", "")
 TYPE("tbd",             TBD,                "tbd",             "")
 TYPE("module-trace",    ModuleTrace,        "trace.json",      "")
-
-// BEGIN APPLE-ONLY OUTPUT TYPES
 TYPE("index-data",      IndexData,          "",                "")
-// END APPLE-ONLY OUTPUT TYPES
 
 // Misc types
 TYPE("pcm",             ClangModuleFile,    "pcm",             "")
diff --git a/include/swift/Driver/Types.h b/include/swift/Driver/Types.h
index 0110af0..c93ca97 100644
--- a/include/swift/Driver/Types.h
+++ b/include/swift/Driver/Types.h
@@ -36,6 +36,8 @@
   StringRef getTypeTempSuffix(ID Id);
 
   /// Lookup the type to use for the file extension \p Ext.
+  /// If the extension is empty or is otherwise not recognized, return
+  /// the invalid type \c TY_INVALID.
   ID lookupTypeForExtension(StringRef Ext);
 
   /// Lookup the type to use for the name \p Name.
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index 7d06a03..6631236 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -567,11 +567,6 @@
   ///
   bool isAvailableExternally(IRGenModule &IGM) const;
 
-  /// Returns true if this function or global variable may be inlined into
-  /// another module.
-  ///
-  bool isFragile(ForDefinition_t isDefinition) const;
-
   const ValueDecl *getDecl() const {
     assert(isDeclKind(getKind()));
     return reinterpret_cast<ValueDecl*>(Pointer);
@@ -686,7 +681,6 @@
   static LinkInfo get(const UniversalLinkageInfo &linkInfo,
                       StringRef name,
                       SILLinkage linkage,
-                      bool isFragile,
                       bool isSILOnly,
                       ForDefinition_t isDefinition,
                       bool isWeakImported);
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 5732bb8..441dfc3 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -372,9 +372,6 @@
 def sil_link_all : Flag<["-"], "sil-link-all">,
   HelpText<"Link all SIL functions">;
 
-def sil_serialize_all : Flag<["-"], "sil-serialize-all">,
-  HelpText<"Serialize all generated SIL">;
-
 def sil_serialize_witness_tables : Flag<["-"], "sil-serialize-witness-tables">,
   HelpText<"Serialize eligible SIL witness tables">;
 
diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h
index fe7ad64..c5aad6d 100644
--- a/include/swift/Remote/MetadataReader.h
+++ b/include/swift/Remote/MetadataReader.h
@@ -690,6 +690,8 @@
 
     switch (Meta->getKind()) {
     case MetadataKind::Class:
+      if (!cast<TargetClassMetadata<Runtime>>(Meta)->isTypeMetadata())
+        return BuiltType();
       return readNominalTypeFromMetadata(Meta, skipArtificialSubclasses);
     case MetadataKind::Struct:
       return readNominalTypeFromMetadata(Meta);
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index aab6283..8df1c4f 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -719,87 +719,7 @@
     using type = R;
   };
 }
-  
-namespace heap_object_abi {
-  
-// The extra inhabitants and spare bits of heap object pointers.
-// These must align with the values in IRGen's SwiftTargetInfo.cpp.
-#if defined(__x86_64__)
 
-# ifdef __APPLE__
-static const uintptr_t LeastValidPointerValue =
-  SWIFT_ABI_DARWIN_X86_64_LEAST_VALID_POINTER;
-# else
-static const uintptr_t LeastValidPointerValue =
-  SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER;
-# endif
-static const uintptr_t SwiftSpareBitsMask =
-  SWIFT_ABI_X86_64_SWIFT_SPARE_BITS_MASK;
-static const uintptr_t ObjCReservedBitsMask =
-  SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK;
-static const unsigned ObjCReservedLowBits =
-  SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS;
-
-#elif defined(__arm64__)
-
-# ifdef __APPLE__
-static const uintptr_t LeastValidPointerValue =
-  SWIFT_ABI_DARWIN_ARM64_LEAST_VALID_POINTER;
-# else
-static const uintptr_t LeastValidPointerValue =
-  SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER;
-# endif
-static const uintptr_t SwiftSpareBitsMask =
-  SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK;
-static const uintptr_t ObjCReservedBitsMask =
-  SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK;
-static const unsigned ObjCReservedLowBits =
-  SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS;
-
-#elif defined(__powerpc64__)
-
-static const uintptr_t LeastValidPointerValue =
-  SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER;
-static const uintptr_t SwiftSpareBitsMask =
-  SWIFT_ABI_POWERPC64_SWIFT_SPARE_BITS_MASK;
-static const uintptr_t ObjCReservedBitsMask =
-  SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK;
-static const unsigned ObjCReservedLowBits =
-  SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS;
-
-#elif defined(__s390x__)
-
-static const uintptr_t LeastValidPointerValue =
-  SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER;
-static const uintptr_t SwiftSpareBitsMask =
-  SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK;
-static const uintptr_t ObjCReservedBitsMask =
-  SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK;
-static const unsigned ObjCReservedLowBits =
-  SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS;
-
-#else
-
-static const uintptr_t LeastValidPointerValue =
-  SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER;
-static const uintptr_t SwiftSpareBitsMask =
-# if __i386__
-  SWIFT_ABI_I386_SWIFT_SPARE_BITS_MASK
-# elif __arm__
-  SWIFT_ABI_ARM_SWIFT_SPARE_BITS_MASK
-# else
-  SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK
-# endif
-  ;
-static const uintptr_t ObjCReservedBitsMask =
-  SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK;
-static const unsigned ObjCReservedLowBits =
-  SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS;
-
-#endif
-
-}
-  
 template <typename Runtime> struct TargetNominalTypeDescriptor;
 template <typename Runtime> struct TargetGenericMetadata;
 template <typename Runtime> struct TargetClassMetadata;
@@ -999,10 +919,6 @@
     swift_runtime_unreachable("Unhandled MetadataKind in switch.");
   }
 
-  /// Get the generic metadata pattern from which this generic type instance was
-  /// instantiated, or null if the type is not generic.
-  const TargetGenericMetadata<Runtime> *getGenericPattern() const;
-  
   /// Get the class object for this type if it has one, or return null if the
   /// type is not a class (or not a class with a class object).
   const TargetClassMetadata<Runtime> *getClassObject() const;
@@ -1287,9 +1203,7 @@
     } Enum;
   };
   
-  RelativeDirectPointerIntPair<TargetGenericMetadata<Runtime>,
-                               NominalTypeKind, /*Nullable*/ true>
-    GenericMetadataPatternAndKind;
+  NominalTypeKind Kind;
 
   using NonGenericMetadataAccessFunction = const Metadata *();
 
@@ -1304,19 +1218,12 @@
   TargetRelativeDirectPointer<Runtime, NonGenericMetadataAccessFunction,
                               /*Nullable*/ true> AccessFunction;
 
-  /// A pointer to the generic metadata pattern that is used to instantiate
-  /// instances of this type. Zero if the type is not generic.
-  TargetGenericMetadata<Runtime> *getGenericMetadataPattern() const {
-    return const_cast<TargetGenericMetadata<Runtime>*>(
-                                    GenericMetadataPatternAndKind.getPointer());
-  }
-
   NonGenericMetadataAccessFunction *getAccessFunction() const {
     return AccessFunction.get();
   }
 
   NominalTypeKind getKind() const {
-    return GenericMetadataPatternAndKind.getInt();
+    return Kind;
   }
 
   int32_t offsetToNameOffset() const {
diff --git a/include/swift/SIL/PatternMatch.h b/include/swift/SIL/PatternMatch.h
index 40479bd..57e8c8b 100644
--- a/include/swift/SIL/PatternMatch.h
+++ b/include/swift/SIL/PatternMatch.h
@@ -370,7 +370,6 @@
 UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCMethodInst)
 UNARY_OP_MATCH_WITH_ARG_MATCHER(SuperMethodInst)
 UNARY_OP_MATCH_WITH_ARG_MATCHER(ObjCSuperMethodInst)
-UNARY_OP_MATCH_WITH_ARG_MATCHER(DynamicMethodInst)
 UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialAddrInst)
 UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialRefInst)
 UNARY_OP_MATCH_WITH_ARG_MATCHER(OpenExistentialValueInst)
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index 12ecc81..52577e1 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -1198,8 +1198,9 @@
 
   ObjCMethodInst *createObjCMethod(SILLocation Loc, SILValue Operand,
                                    SILDeclRef Member, SILType MethodTy) {
-    return insert(new (getModule()) ObjCMethodInst(
-        getSILDebugLocation(Loc), Operand, Member, MethodTy));
+    return insert(ObjCMethodInst::create(
+        getSILDebugLocation(Loc), Operand, Member, MethodTy,
+        &getFunction(), OpenedArchetypes));
   }
 
   ObjCSuperMethodInst *createObjCSuperMethod(SILLocation Loc, SILValue Operand,
@@ -1217,13 +1218,6 @@
         &getFunction(), OpenedArchetypes, Volatile));
   }
 
-  DynamicMethodInst *createDynamicMethod(SILLocation Loc, SILValue Operand,
-                                         SILDeclRef Member, SILType MethodTy) {
-    return insert(DynamicMethodInst::create(
-        getSILDebugLocation(Loc), Operand, Member, MethodTy,
-        &getFunction(), OpenedArchetypes));
-  }
-
   OpenExistentialAddrInst *
   createOpenExistentialAddr(SILLocation Loc, SILValue Operand, SILType SelfTy,
                             OpenedExistentialAccess ForAccess) {
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 16b107a..3cd9967 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -1557,7 +1557,7 @@
     getBuilder().createObjCMethod(getOpLocation(Inst->getLoc()),
                                   getOpValue(Inst->getOperand()),
                                   Inst->getMember(),
-                                  Inst->getType()));
+                                  getOpType(Inst->getType())));
 }
 
 template<typename ImplClass>
@@ -1603,17 +1603,6 @@
 
 template<typename ImplClass>
 void
-SILCloner<ImplClass>::visitDynamicMethodInst(DynamicMethodInst *Inst) {
-  getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
-  doPostProcess(Inst,
-    getBuilder().createDynamicMethod(getOpLocation(Inst->getLoc()),
-                                     getOpValue(Inst->getOperand()),
-                                     Inst->getMember(),
-                                     getOpType(Inst->getType())));
-}
-
-template<typename ImplClass>
-void
 SILCloner<ImplClass>::visitOpenExistentialAddrInst(OpenExistentialAddrInst *Inst) {
   // Create a new archetype for this opened existential type.
   auto archetypeTy
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index f4b532b..3f5e6e7 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -4870,15 +4870,24 @@
 /// ObjCMethodInst - Given the address of a value of class type and a method
 /// constant, extracts the implementation of that method for the dynamic
 /// instance type of the class.
-class ObjCMethodInst
-    : public UnaryInstructionBase<SILInstructionKind::ObjCMethodInst,
-                                  MethodInst>
+class ObjCMethodInst final
+    : public UnaryInstructionWithTypeDependentOperandsBase<
+          SILInstructionKind::ObjCMethodInst,
+          ObjCMethodInst,
+          MethodInst>
 {
   friend SILBuilder;
 
   ObjCMethodInst(SILDebugLocation DebugLoc, SILValue Operand,
+                 ArrayRef<SILValue> TypeDependentOperands,
                  SILDeclRef Member, SILType Ty)
-      : UnaryInstructionBase(DebugLoc, Operand, Ty, Member) {}
+      : UnaryInstructionWithTypeDependentOperandsBase(DebugLoc, Operand,
+                               TypeDependentOperands, Ty, Member) {}
+
+  static ObjCMethodInst *
+  create(SILDebugLocation DebugLoc, SILValue Operand,
+         SILDeclRef Member, SILType Ty, SILFunction *F,
+         SILOpenedArchetypesState &OpenedArchetypes);
 };
 
 /// ObjCSuperMethodInst - Given the address of a value of class type and a method
@@ -4921,6 +4930,18 @@
                                            TypeDependentOperands);
   }
 
+  /// Create a witness method call of a protocol requirement, passing in a lookup
+  /// type and conformance.
+  ///
+  /// At runtime, the witness is looked up in the conformance of the lookup type
+  /// to the protocol.
+  ///
+  /// The lookup type is usually an archetype, but it will be concrete if the
+  /// witness_method instruction is inside a function body that was specialized.
+  ///
+  /// The conformance must exactly match the requirement; the caller must handle
+  /// the case where the requirement is defined in a base protocol that is
+  /// refined by the conforming protocol.
   static WitnessMethodInst *
   create(SILDebugLocation DebugLoc, CanType LookupType,
          ProtocolConformanceRef Conformance, SILDeclRef Member, SILType Ty,
@@ -4962,30 +4983,6 @@
   }
 };
 
-/// Given the address of a value of AnyObject protocol type and a method
-/// constant referring to some Objective-C method, performs dynamic method
-/// lookup to extract the implementation of that method. This method lookup
-/// can fail at run-time
-class DynamicMethodInst final
-  : public UnaryInstructionWithTypeDependentOperandsBase<
-                                   SILInstructionKind::DynamicMethodInst,
-                                   DynamicMethodInst,
-                                   MethodInst>
-{
-  friend SILBuilder;
-
-  DynamicMethodInst(SILDebugLocation DebugLoc, SILValue Operand,
-                    ArrayRef<SILValue> TypeDependentOperands,
-                    SILDeclRef Member, SILType Ty)
-      : UnaryInstructionWithTypeDependentOperandsBase(DebugLoc, Operand,
-                               TypeDependentOperands, Ty, Member) {}
-
-  static DynamicMethodInst *
-  create(SILDebugLocation DebugLoc, SILValue Operand,
-         SILDeclRef Member, SILType Ty, SILFunction *F,
-         SILOpenedArchetypesState &OpenedArchetypes);
-};
-
 /// Access allowed to the opened value by the open_existential_addr instruction.
 /// Allowing mutable access to the opened existential requires a boxed
 /// existential value's box to be unique.
diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h
index 1c68b4b..0d29a30 100644
--- a/include/swift/SIL/SILModule.h
+++ b/include/swift/SIL/SILModule.h
@@ -322,9 +322,6 @@
     return wholeModule;
   }
 
-  /// Returns true if everything in this SILModule is being serialized.
-  bool isWholeModuleSerialized() const { return Options.SILSerializeAll; }
-
   /// Returns true if it is the OnoneSupport module.
   bool isOnoneSupportModule() const;
 
diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def
index e2d0b04..8c9126c 100644
--- a/include/swift/SIL/SILNodes.def
+++ b/include/swift/SIL/SILNodes.def
@@ -255,9 +255,7 @@
                       MethodInst, None, DoesNotRelease)
     SINGLE_VALUE_INST(WitnessMethodInst, witness_method,
                       MethodInst, None, DoesNotRelease)
-    SINGLE_VALUE_INST(DynamicMethodInst, dynamic_method,
-                      MethodInst, None, DoesNotRelease)
-    SINGLE_VALUE_INST_RANGE(MethodInst, ClassMethodInst, DynamicMethodInst)
+    SINGLE_VALUE_INST_RANGE(MethodInst, ClassMethodInst, WitnessMethodInst)
 
   // Conversions
   ABSTRACT_SINGLE_VALUE_INST(ConversionInst, SingleValueInstruction)
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index cf4e11e..4101be6 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -54,7 +54,7 @@
 /// in source control, you should also update the comment to briefly
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
-const uint16_t VERSION_MINOR = 368; // Last change: objc_method, objc_super_method
+const uint16_t VERSION_MINOR = 369; // Last change: associated type overrides
 
 using DeclID = PointerEmbeddedInt<unsigned, 31>;
 using DeclIDField = BCFixed<31>;
@@ -815,10 +815,11 @@
 
   using AssociatedTypeDeclLayout = BCRecordLayout<
     ASSOCIATED_TYPE_DECL,
-    IdentifierIDField, // name
-    DeclContextIDField,// context decl
-    TypeIDField,       // default definition
-    BCFixed<1>         // implicit flag
+    IdentifierIDField,   // name
+    DeclContextIDField,  // context decl
+    TypeIDField,         // default definition
+    BCFixed<1>,          // implicit flag
+    BCArray<DeclIDField> // overridden associated types
   >;
 
   using StructLayout = BCRecordLayout<
diff --git a/include/swift/Syntax/Syntax.h b/include/swift/Syntax/Syntax.h
index e384a37..a251597 100644
--- a/include/swift/Syntax/Syntax.h
+++ b/include/swift/Syntax/Syntax.h
@@ -152,6 +152,9 @@
   /// Returns true if the node is "present" in the source.
   bool isPresent() const;
 
+
+  bool isToken() const;
+
   /// Print the syntax node with full fidelity to the given output stream.
   void print(llvm::raw_ostream &OS) const;
 
@@ -166,6 +169,10 @@
     return Root == Other.Root && Data == Other.Data;
   }
 
+  static bool classof(const Syntax *S) {
+    // Trivially true.
+    return true;
+  }
   // TODO: hasSameStructureAs ?
 };
 
diff --git a/include/swift/Syntax/SyntaxFactory.h.gyb b/include/swift/Syntax/SyntaxFactory.h.gyb
index 41e0be9..18a06e0 100644
--- a/include/swift/Syntax/SyntaxFactory.h.gyb
+++ b/include/swift/Syntax/SyntaxFactory.h.gyb
@@ -51,6 +51,9 @@
   static UnknownSyntax
   makeUnknownSyntax(llvm::ArrayRef<TokenSyntax> Tokens);
 
+  static Optional<Syntax>
+  createSyntax(SyntaxKind Kind, llvm::ArrayRef<Syntax> Elements);
+
 % for node in SYNTAX_NODES:
 %   if node.children:
 %     child_params = []
diff --git a/include/swift/Syntax/TokenSyntax.h b/include/swift/Syntax/TokenSyntax.h
index 73cc986..c36a08e 100644
--- a/include/swift/Syntax/TokenSyntax.h
+++ b/include/swift/Syntax/TokenSyntax.h
@@ -89,6 +89,10 @@
   StringRef getText() const {
     return getRawToken()->getText();
   }
+
+  static bool classof(const Syntax *S) {
+    return S->isToken();
+  }
 };
 
 } // end namespace syntax
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index dd159c0..c794667 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -278,6 +278,10 @@
   /// The existential signature <T : P> for each P.
   llvm::DenseMap<CanType, CanGenericSignature> ExistentialSignatures;
 
+  /// Overridden associated type declarations.
+  llvm::DenseMap<const AssociatedTypeDecl *, ArrayRef<AssociatedTypeDecl *>>
+    AssociatedTypeOverrides;
+
   /// \brief Structure that captures data that is segregated into different
   /// arenas.
   struct Arena {
@@ -1541,6 +1545,125 @@
   return env;
 }
 
+/// Minimize the set of overridden associated types, eliminating any
+/// associated types that are overridden by other associated types.
+static void minimizeOverriddenAssociatedTypes(
+                           SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) {
+  // Mark associated types that are "worse" than some other associated type,
+  // because they come from an inherited protocol.
+  bool anyWorse = false;
+  std::vector<bool> worseThanAny(assocTypes.size(), false);
+  for (unsigned i : indices(assocTypes)) {
+    auto proto1 = assocTypes[i]->getProtocol();
+    for (unsigned j : range(i + 1, assocTypes.size())) {
+      auto proto2 = assocTypes[j]->getProtocol();
+      if (proto1->inheritsFrom(proto2)) {
+        anyWorse = true;
+        worseThanAny[j] = true;
+      } else if (proto2->inheritsFrom(proto1)) {
+        anyWorse = true;
+        worseThanAny[i] = true;
+        break;
+      }
+    }
+  }
+
+  // If we didn't find any associated types that were "worse", we're done.
+  if (!anyWorse) return;
+
+  // Copy in the associated types that aren't worse than any other associated
+  // type.
+  unsigned nextIndex = 0;
+  for (unsigned i : indices(assocTypes)) {
+    if (worseThanAny[i]) continue;
+    assocTypes[nextIndex++] = assocTypes[i];
+  }
+
+  assocTypes.erase(assocTypes.begin() + nextIndex, assocTypes.end());
+}
+
+/// Sort associated types just based on the protocol.
+static int compareSimilarAssociatedTypes(AssociatedTypeDecl *const *lhs,
+                                         AssociatedTypeDecl *const *rhs) {
+  auto lhsProto = (*lhs)->getProtocol();
+  auto rhsProto = (*rhs)->getProtocol();
+  return ProtocolType::compareProtocols(&lhsProto, &rhsProto);
+}
+
+ArrayRef<AssociatedTypeDecl *> AssociatedTypeDecl::getOverriddenDecls() const {
+  // If we already computed the set of overridden associated types, return it.
+  if (AssociatedTypeDeclBits.ComputedOverridden) {
+    // We didn't override any associated types, so return the empty set.
+    if (!AssociatedTypeDeclBits.HasOverridden)
+      return { };
+
+    // Look up the overrides.
+    auto known = getASTContext().Impl.AssociatedTypeOverrides.find(this);
+    assert(known != getASTContext().Impl.AssociatedTypeOverrides.end());
+    return known->second;
+  }
+
+  // Find associated types with the given name in all of the inherited
+  // protocols.
+  SmallVector<AssociatedTypeDecl *, 4> inheritedAssociatedTypes;
+  auto proto = getProtocol();
+  proto->walkInheritedProtocols([&](ProtocolDecl *inheritedProto) {
+    if (proto == inheritedProto) return TypeWalker::Action::Continue;
+
+    // Objective-C protocols
+    if (inheritedProto->isObjC()) return TypeWalker::Action::Continue;
+
+    // Look for associated types with the same name.
+    bool foundAny = false;
+    for (auto member : inheritedProto->lookupDirect(
+                                              getFullName(),
+                                              /*ignoreNewExtensions=*/true)) {
+      if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
+        inheritedAssociatedTypes.push_back(assocType);
+        foundAny = true;
+      }
+    }
+
+    return foundAny ? TypeWalker::Action::SkipChildren
+                    : TypeWalker::Action::Continue;
+  });
+
+  // Minimize the set of inherited associated types, eliminating any that
+  // themselves are overridden.
+  minimizeOverriddenAssociatedTypes(inheritedAssociatedTypes);
+
+  // Sort the set of inherited associated types.
+  llvm::array_pod_sort(inheritedAssociatedTypes.begin(),
+                       inheritedAssociatedTypes.end(),
+                       compareSimilarAssociatedTypes);
+
+  return const_cast<AssociatedTypeDecl *>(this)
+    ->setOverriddenDecls(inheritedAssociatedTypes);
+}
+
+ArrayRef<AssociatedTypeDecl *> AssociatedTypeDecl::setOverriddenDecls(
+                                  ArrayRef<AssociatedTypeDecl *> overridden) {
+  assert(!AssociatedTypeDeclBits.ComputedOverridden &&
+         "Overridden decls already computed");
+  AssociatedTypeDeclBits.ComputedOverridden = true;
+
+  // If the set of overridden declarations is empty, note that.
+  if (overridden.empty()) {
+    AssociatedTypeDeclBits.HasOverridden = false;
+    return { };
+  }
+
+  // Record the overrides in the context.
+  auto &ctx = getASTContext();
+  AssociatedTypeDeclBits.HasOverridden = true;
+  auto overriddenCopy = ctx.AllocateCopy(overridden);
+  auto inserted =
+    ctx.Impl.AssociatedTypeOverrides.insert({this, overriddenCopy}).second;
+  (void)inserted;
+  assert(inserted && "Already recorded associated type overrides");
+  return overriddenCopy;
+}
+
 bool ASTContext::canImportModule(std::pair<Identifier, SourceLoc> ModulePath) {
   // If this module has already been successfully imported, it is importable.
   if (getLoadedModule(ModulePath) != nullptr)
@@ -4055,8 +4178,7 @@
 
   // Allocate and construct the new environment.
   unsigned numGenericParams = signature->getGenericParams().size();
-  size_t bytes = totalSizeToAlloc<Type, ArchetypeToInterfaceMapping>(
-                                           numGenericParams, numGenericParams);
+  size_t bytes = totalSizeToAlloc<Type>(numGenericParams);
   void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
   return new (mem) GenericEnvironment(signature, builder);
 }
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 295c39d..e0987bd 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -667,6 +667,15 @@
                    [&](const RequirementRepr &req) { req.print(OS); },
                    [&] { OS << ", "; });
       }
+      if (decl->overriddenDeclsComputed()) {
+        OS << " overridden=";
+        interleave(decl->getOverriddenDecls(),
+                   [&](AssociatedTypeDecl *overridden) {
+                     OS << overridden->getProtocol()->getName();
+                   }, [&]() {
+                     OS << ", ";
+                   });
+      }
 
       OS << ")";
     }
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 69341f0..3ed397c 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -533,25 +533,6 @@
   }
 }
 
-/// Returns true if one of the ancestor DeclContexts of \p D is either marked
-/// private or is a local context.
-static bool isInPrivateOrLocalContext(const ValueDecl *D) {
-  const DeclContext *DC = D->getDeclContext();
-  if (!DC->isTypeContext()) {
-    assert((DC->isModuleScopeContext() || DC->isLocalContext()) &&
-           "unexpected context kind");
-    return DC->isLocalContext();
-  }
-
-  auto *nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
-  if (nominal == nullptr)
-    return false;
-
-  if (nominal->getFormalAccess() <= AccessLevel::FilePrivate)
-    return true;
-  return isInPrivateOrLocalContext(nominal);
-}
-
 static bool getUnnamedParamIndex(const ParameterList *ParamList,
                                  const ParamDecl *D,
                                  unsigned &UnnamedIndex) {
@@ -593,11 +574,8 @@
 }
 
 static StringRef getPrivateDiscriminatorIfNecessary(const ValueDecl *decl) {
-  if (!decl->hasAccess() ||
-      decl->getFormalAccess() > AccessLevel::FilePrivate ||
-      isInPrivateOrLocalContext(decl)) {
+  if (!decl->isOutermostPrivateOrFilePrivateScope())
     return StringRef();
-  }
 
   // Mangle non-local private declarations with a textual discriminator
   // based on their enclosing file.
@@ -892,8 +870,7 @@
 
       // Find the archetype information.
       const DeclContext *DC = DeclCtx;
-      auto GTPT = GenericEnvironment::mapTypeOutOfContext(GenericEnv, archetype)
-                      ->castTo<GenericTypeParamType>();
+      auto GTPT = archetype->getInterfaceType()->castTo<GenericTypeParamType>();
 
       // The DWARF output created by Swift is intentionally flat,
       // therefore archetypes are emitted with their DeclContext if
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index f5d6f86..dc4cd51 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -170,11 +170,11 @@
     if (isLazy()) return true;
 
     if (auto genericEnv = storage.dyn_cast<GenericEnvironment *>())
-      return genericEnv->containsPrimaryArchetype(archetype);
+      return archetype->getGenericEnvironment() == genericEnv;
 
     if (auto dc = storage.dyn_cast<DeclContext *>()) {
       if (auto genericEnv = dc->getGenericEnvironmentOfContext())
-        return genericEnv->containsPrimaryArchetype(archetype);
+        return archetype->getGenericEnvironment() == genericEnv;
     }
 
     return false;
@@ -924,6 +924,8 @@
       verifyCheckedBase(S);
     }
     void verifyChecked(DeferStmt *S) {
+      auto FT = S->getTempDecl()->getInterfaceType()->castTo<AnyFunctionType>();
+      assert(FT->isNoEscape() && "Defer statements must not escape");
       verifyCheckedBase(S);
     }
 
diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp
index 063acbb..bf32c66 100644
--- a/lib/AST/ConformanceLookupTable.cpp
+++ b/lib/AST/ConformanceLookupTable.cpp
@@ -1131,7 +1131,7 @@
 
       auto normal = conf->getRootNormalConformance();
       normal->forEachValueWitness(resolver, [&](ValueDecl *req,
-                                              ConcreteDeclRef witness) {
+                                                Witness witness) {
         if (witness.getDecl() == member)
           reqs.push_back(req);
       });
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 0771a8a..2ea820d 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1433,6 +1433,34 @@
   llvm_unreachable("bad access semantics");
 }
 
+static bool hasPrivateOrFilePrivateFormalAccess(const ValueDecl *D) {
+  return D->hasAccess() && D->getFormalAccess() <= AccessLevel::FilePrivate;
+}
+
+/// Returns true if one of the ancestor DeclContexts of this ValueDecl is either
+/// marked private or fileprivate or is a local context.
+static bool isInPrivateOrLocalContext(const ValueDecl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  if (!DC->isTypeContext()) {
+    assert((DC->isModuleScopeContext() || DC->isLocalContext()) &&
+           "unexpected context kind");
+    return DC->isLocalContext();
+  }
+
+  auto *nominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
+  if (nominal == nullptr)
+    return false;
+
+  if (hasPrivateOrFilePrivateFormalAccess(nominal))
+    return true;
+  return isInPrivateOrLocalContext(nominal);
+}
+
+bool ValueDecl::isOutermostPrivateOrFilePrivateScope() const {
+  return hasPrivateOrFilePrivateFormalAccess(this) &&
+         !isInPrivateOrLocalContext(this);
+}
+
 bool AbstractStorageDecl::hasFixedLayout() const {
   // If we're in a nominal type, just query the type.
   auto *dc = getDeclContext();
@@ -1459,7 +1487,6 @@
   switch (getDeclContext()->getParentModule()->getResilienceStrategy()) {
   case ResilienceStrategy::Resilient:
     return false;
-  case ResilienceStrategy::Fragile:
   case ResilienceStrategy::Default:
     return true;
   }
@@ -1594,6 +1621,8 @@
     return sdd->getOverriddenDecl();
   if (auto cd = dyn_cast<ConstructorDecl>(this))
     return cd->getOverriddenDecl();
+  if (auto at = dyn_cast<AssociatedTypeDecl>(this))
+    return at->getOverriddenDecl();
   return nullptr;
 }
 
@@ -2217,7 +2246,6 @@
   switch (getParentModule()->getResilienceStrategy()) {
   case ResilienceStrategy::Resilient:
     return false;
-  case ResilienceStrategy::Fragile:
   case ResilienceStrategy::Default:
     return true;
   }
@@ -2582,7 +2610,11 @@
                                        TrailingWhereClause *trailingWhere)
     : AbstractTypeParamDecl(DeclKind::AssociatedType, dc, name, nameLoc),
       KeywordLoc(keywordLoc), DefaultDefinition(defaultDefinition),
-      TrailingWhere(trailingWhere) {}
+      TrailingWhere(trailingWhere) {
+
+  AssociatedTypeDeclBits.ComputedOverridden = false;
+  AssociatedTypeDeclBits.HasOverridden = false;
+}
 
 AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
                                        Identifier name, SourceLoc nameLoc,
@@ -2593,6 +2625,8 @@
       KeywordLoc(keywordLoc), TrailingWhere(trailingWhere),
       Resolver(definitionResolver), ResolverContextData(resolverData) {
   assert(Resolver && "missing resolver");
+  AssociatedTypeDeclBits.ComputedOverridden = false;
+  AssociatedTypeDeclBits.HasOverridden = false;
 }
 
 void AssociatedTypeDecl::computeType() {
@@ -2619,6 +2653,29 @@
   return SourceRange(KeywordLoc, endLoc);
 }
 
+AssociatedTypeDecl *AssociatedTypeDecl::getAssociatedTypeAnchor() const {
+  auto overridden = getOverriddenDecls();
+
+  // If this declaration does not override any other declarations, it's
+  // the anchor.
+  if (overridden.empty()) return const_cast<AssociatedTypeDecl *>(this);
+
+  // Find the best anchor among the anchors of the overridden decls.
+  AssociatedTypeDecl *bestAnchor = nullptr;
+  for (auto assocType : overridden) {
+    auto anchor = assocType->getAssociatedTypeAnchor();
+    if (!bestAnchor || compare(anchor, bestAnchor) < 0)
+      bestAnchor = anchor;
+  }
+
+  return bestAnchor;
+}
+
+AssociatedTypeDecl *AssociatedTypeDecl::getOverriddenDecl() const {
+  auto overridden = getOverriddenDecls();
+  return overridden.empty() ? nullptr : overridden.front();
+}
+
 EnumDecl::EnumDecl(SourceLoc EnumLoc,
                      Identifier Name, SourceLoc NameLoc,
                      MutableArrayRef<TypeLoc> Inherited,
@@ -3020,6 +3077,19 @@
   return result;
 }
 
+llvm::TinyPtrVector<AssociatedTypeDecl *>
+ProtocolDecl::getAssociatedTypeMembers() const {
+  llvm::TinyPtrVector<AssociatedTypeDecl *> result;
+  if (!isObjC()) {
+    for (auto member : getMembers()) {
+      if (auto ATD = dyn_cast<AssociatedTypeDecl>(member)) {
+        result.push_back(ATD);
+      }
+    }
+  }
+  return result;
+}
+
 bool ProtocolDecl::walkInheritedProtocols(
               llvm::function_ref<TypeWalker::Action(ProtocolDecl *)> fn) const {
   auto self = const_cast<ProtocolDecl *>(this);
@@ -4202,7 +4272,9 @@
 ParamDecl::ParamDecl(ParamDecl *PD, bool withTypes)
   : VarDecl(DeclKind::Param, /*IsStatic*/false, PD->getSpecifier(),
             /*IsCaptureList*/false, PD->getNameLoc(), PD->getName(),
-            PD->hasType() && withTypes? PD->getType() : Type(),
+            PD->hasType() && withTypes
+              ? PD->getType()->getInOutObjectType()
+              : Type(),
             PD->getDeclContext()),
     ArgumentName(PD->getArgumentName()),
     ArgumentNameLoc(PD->getArgumentNameLoc()),
@@ -4215,7 +4287,7 @@
     typeLoc.setType(Type());
 
   if (withTypes && PD->hasInterfaceType())
-    setInterfaceType(PD->getInterfaceType());
+    setInterfaceType(PD->getInterfaceType()->getInOutObjectType());
 }
 
 
diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp
index fe8d718..a5fdd3f 100644
--- a/lib/AST/GenericEnvironment.cpp
+++ b/lib/AST/GenericEnvironment.cpp
@@ -25,9 +25,6 @@
                                        GenericSignatureBuilder *builder)
   : Signature(signature), Builder(builder)
 {
-  NumMappingsRecorded = 0;
-  NumArchetypeToInterfaceMappings = 0;
-
   // Clear out the memory that holds the context types.
   std::uninitialized_fill(getContextTypes().begin(), getContextTypes().end(),
                           Type());
@@ -73,55 +70,6 @@
   // Add the mapping from the generic parameter to the context type.
   assert(getContextTypes()[index].isNull() && "Already recoded this mapping");
   getContextTypes()[index] = contextType;
-
-  // If we mapped the generic parameter to an archetype, add it to the
-  // reverse mapping.
-  if (auto *archetype = contextType->getAs<ArchetypeType>()) {
-    auto genericParam = genericParams[index];
-
-    // Check whether we've already recorded a generic parameter for this
-    // archetype. Note that we always perform a linear search, because we
-    // won't have sorted the list yet.
-    bool found = false;
-    for (auto &mapping : getActiveArchetypeToInterfaceMappings()) {
-      if (mapping.first != archetype) continue;
-
-      // Multiple generic parameters map to the same archetype. If the
-      // existing entry comes from a later generic parameter, replace it with
-      // the earlier generic parameter. This gives us a deterministic reverse
-      // mapping.
-      auto otherGP = mapping.second->castTo<GenericTypeParamType>();
-      if (GenericParamKey(genericParam) < GenericParamKey(otherGP))
-        mapping.second = genericParam;
-      found = true;
-      break;
-    }
-
-    // If we haven't recorded a generic parameter for this archetype, do so now.
-    if (!found) {
-      void *ptr = getArchetypeToInterfaceMappingsBuffer().data()
-                + NumArchetypeToInterfaceMappings;
-      new (ptr) ArchetypeToInterfaceMapping(archetype, genericParam);
-      ++NumArchetypeToInterfaceMappings;
-    }
-  }
-
-  // Note that we've recorded this mapping.
-  ++NumMappingsRecorded;
-
-  // If we've recorded all of the mappings, go ahead and sort the array of
-  // archetype-to-interface-type mappings.
-  if (NumMappingsRecorded == genericParams.size()) {
-    llvm::array_pod_sort(getActiveArchetypeToInterfaceMappings().begin(),
-                         getActiveArchetypeToInterfaceMappings().end(),
-                         [](const ArchetypeToInterfaceMapping *lhs,
-                            const ArchetypeToInterfaceMapping *rhs) -> int {
-                           std::less<ArchetypeType *> compare;
-                           if (compare(lhs->first, rhs->first)) return -1;
-                           if (compare(rhs->first, lhs->first)) return 1;
-                           return 0;
-                         });
-  }
 }
 
 Optional<Type> GenericEnvironment::getMappingIfPresent(
@@ -138,12 +86,6 @@
   return None;
 }
 
-bool GenericEnvironment::containsPrimaryArchetype(
-                                              ArchetypeType *archetype) const {
-  return static_cast<bool>(
-                       QueryArchetypeToInterfaceSubstitutions(this)(archetype));
-}
-
 Type GenericEnvironment::mapTypeIntoContext(GenericEnvironment *env,
                                             Type type) {
   assert(!type->hasArchetype() && "already have a contextual type");
@@ -166,7 +108,9 @@
 }
 
 Type GenericEnvironment::mapTypeOutOfContext(Type type) const {
-  type = type.subst(QueryArchetypeToInterfaceSubstitutions(this),
+  type = type.subst([&](SubstitutableType *t) -> Type {
+                      return cast<ArchetypeType>(t)->getInterfaceType();
+                    },
                     MakeAbstractConformanceForGenericType(),
                     SubstFlags::AllowLoweredTypes);
   assert(!type->hasArchetype() && "not fully substituted");
@@ -210,74 +154,6 @@
   return Type();
 }
 
-Type GenericEnvironment::QueryArchetypeToInterfaceSubstitutions::operator()(
-                                                SubstitutableType *type) const {
-  auto archetype = type->getAs<ArchetypeType>();
-  if (!archetype) return Type();
-
-  // Only top-level archetypes need to be substituted directly; nested
-  // archetypes will be handled via their root archetypes.
-  if (archetype->getParent()) return Type();
-
-  // If not all generic parameters have had their context types recorded,
-  // perform a linear search.
-  auto genericParams = self->Signature->getGenericParams();
-  unsigned numGenericParams = genericParams.size();
-  if (self->NumMappingsRecorded < numGenericParams) {
-    // Search through all of the active archetype-to-interface mappings.
-    for (auto &mapping : self->getActiveArchetypeToInterfaceMappings())
-      if (mapping.first == archetype) return mapping.second;
-
-    // We don't know if the archetype is from a different context or if we
-    // simply haven't recorded it yet. Spin through all of the generic
-    // parameters looking for one that provides this mapping.
-    for (auto gp : genericParams) {
-      // Map the generic parameter into our context. If we get back an
-      // archetype that matches, we're done.
-      auto gpArchetype = self->mapTypeIntoContext(gp)->getAs<ArchetypeType>();
-      if (gpArchetype == archetype) return gp;
-    }
-
-    // We have checked all of the generic parameters and not found anything;
-    // there is no substitution.
-    return Type();
-  }
-
-  // All generic parameters have ad their context types recorded, which means
-  // that the archetypes-to-interface-types array is sorted by address. Use a
-  // binary search.
-  struct MappingComparison {
-    bool operator()(const ArchetypeToInterfaceMapping &lhs,
-                    const ArchetypeType *rhs) const {
-      std::less<const ArchetypeType *> compare;
-
-      return compare(lhs.first, rhs);
-    }
-
-    bool operator()(const ArchetypeType *lhs,
-                    const ArchetypeToInterfaceMapping &rhs) const {
-      std::less<const ArchetypeType *> compare;
-
-      return compare(lhs, rhs.first);
-    }
-
-    bool operator()(const ArchetypeToInterfaceMapping &lhs,
-                    const ArchetypeToInterfaceMapping &rhs) const {
-      std::less<const ArchetypeType *> compare;
-
-      return compare(lhs.first, rhs.first);
-    }
-  } mappingComparison;
-
-  auto mappings = self->getActiveArchetypeToInterfaceMappings();
-  auto known = std::lower_bound(mappings.begin(), mappings.end(), archetype,
-                                mappingComparison);
-  if (known != mappings.end() && known->first == archetype)
-    return known->second;
-
-  return Type();
-}
-
 Type GenericEnvironment::mapTypeIntoContext(
                                 Type type,
                                 LookupConformanceFn lookupConformance) const {
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index f409963..ba903ae 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -1604,6 +1604,13 @@
                                               assocType2->getName().str()))
     return result;
 
+  // Prefer an associated type with no overrides (i.e., an anchor) to one
+  // that has overrides.
+  bool hasOverridden1 = !assocType1->getOverriddenDecls().empty();
+  bool hasOverridden2 = !assocType2->getOverriddenDecls().empty();
+  if (hasOverridden1 != hasOverridden2)
+    return hasOverridden1 ? +1 : -1;
+
   // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
   auto proto1 = assocType1->getProtocol();
   auto proto2 = assocType2->getProtocol();
@@ -1655,6 +1662,7 @@
 
   // Look for types with the given name in protocols that we know about.
   AssociatedTypeDecl *bestAssocType = nullptr;
+  llvm::SmallSetVector<AssociatedTypeDecl *, 4> assocTypeAnchors;
   SmallVector<TypeDecl *, 4> concreteDecls;
   for (const auto &conforms : conformsTo) {
     ProtocolDecl *proto = conforms.first;
@@ -1665,6 +1673,10 @@
       // If this is an associated type, record whether it is the best
       // associated type we've seen thus far.
       if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
+        // Retrieve the associated type anchor.
+        assocType = assocType->getAssociatedTypeAnchor();
+        assocTypeAnchors.insert(assocType);
+
         if (!bestAssocType ||
              compareAssociatedTypes(assocType, bestAssocType) < 0)
           bestAssocType = assocType;
@@ -1721,6 +1733,22 @@
     }
   }
 
+  // Infer same-type constraints among same-named associated type anchors.
+  if (assocTypeAnchors.size() > 1) {
+    auto &builder = *members.front()->getBuilder();
+    auto anchorType = getAnchor({ });
+    auto inferredSource = FloatingRequirementSource::forInferred(nullptr);
+    for (auto assocType : assocTypeAnchors) {
+      if (assocType == bestAssocType) continue;
+
+      builder.addRequirement(
+        Requirement(RequirementKind::SameType,
+                    DependentMemberType::get(anchorType, bestAssocType),
+                    DependentMemberType::get(anchorType, assocType)),
+        inferredSource, nullptr);
+    }
+  }
+
   // Form the new cache entry.
   CachedNestedType entry;
   entry.numConformancesPresent = conformsTo.size();
@@ -1730,6 +1758,8 @@
     entry.types.push_back(bestAssocType);
     entry.types.insert(entry.types.end(),
                        concreteDecls.begin(), concreteDecls.end());
+    assert(bestAssocType->getOverriddenDecls().empty() &&
+           "Lookup should never keep a non-anchor associated type");
   } else if (!concreteDecls.empty()) {
     // Find the best concrete type.
     auto bestConcreteTypeIter =
@@ -1856,7 +1886,8 @@
   ASTContext &ctx = builder.getASTContext();
   if (parentArchetype) {
     // Create a nested archetype.
-    archetype = ArchetypeType::getNew(ctx, parentArchetype, assocType, protos,
+    auto *depMemTy = anchor->castTo<DependentMemberType>();
+    archetype = ArchetypeType::getNew(ctx, parentArchetype, depMemTy, protos,
                                       superclass, layout);
 
     // Register this archetype with its parent.
@@ -1864,8 +1895,7 @@
   } else {
     // Create a top-level archetype.
     auto genericParam = anchor->castTo<GenericTypeParamType>();
-    Identifier name = genericParam->getName();
-    archetype = ArchetypeType::getNew(ctx, genericEnv, name, protos,
+    archetype = ArchetypeType::getNew(ctx, genericEnv, genericParam, protos,
                                       superclass, layout);
 
     // Register the archetype with the generic environment.
@@ -2187,28 +2217,17 @@
     superConformance->getTypeWitness(assocType, builder.getLazyResolver());
   if (!concreteType) return;
 
+  // We should only have interface types here.
+  assert(!superConformance->getType()->hasArchetype());
+  assert(!concreteType->hasArchetype());
+
   // Add the same-type constraint.
   auto nestedSource = superSource->viaParent(builder, assocType);
-  concreteType = superConformance->getDeclContext()
-      ->mapTypeOutOfContext(concreteType);
 
   builder.addSameTypeRequirement(nestedPA, concreteType, nestedSource,
         GenericSignatureBuilder::UnresolvedHandlingKind::GenerateConstraints);
 }
 
-/// Walk the members of a protocol.
-///
-/// This is essentially just a call to \c proto->getMembers(), except that
-/// for Objective-C-imported protocols we can simply return an empty declaration
-/// range because the generic signature builder only cares about nested types (which
-/// Objective-C protocols don't have).
-static DeclRange getProtocolMembers(ProtocolDecl *proto) {
-  if (proto->hasClangNode())
-    return DeclRange(DeclIterator(), DeclIterator());
-
-  return proto->getMembers();
-}
-
 bool PotentialArchetype::addConformance(ProtocolDecl *proto,
                                         const RequirementSource *source,
                                         GenericSignatureBuilder &builder) {
@@ -2563,6 +2582,11 @@
   if (!type) return nullptr;
 
   AssociatedTypeDecl *assocType = dyn_cast<AssociatedTypeDecl>(type);
+
+  // Always refer to the archetype anchor.
+  if (assocType)
+    assocType = assocType->getAssociatedTypeAnchor();
+
   TypeDecl *concreteDecl = assocType ? nullptr : type;
 
   // If we were asked for a complete, well-formed archetype, make sure we
@@ -2696,8 +2720,7 @@
   auto genericEnv = getGenericEnvironment();
   auto &builder = *genericEnv->getGenericSignatureBuilder();
 
-  Type interfaceType =
-    genericEnv->mapTypeOutOfContext(const_cast<ArchetypeType *>(this));
+  Type interfaceType = getInterfaceType();
   Type memberInterfaceType =
     DependentMemberType::get(interfaceType, nested.first);
   auto equivClass =
@@ -3149,7 +3172,7 @@
         [&](ProtocolDecl *inheritedProto) -> TypeWalker::Action {
       if (inheritedProto == proto) return TypeWalker::Action::Continue;
 
-      for (auto req : getProtocolMembers(inheritedProto)) {
+      for (auto req : inheritedProto->getMembers()) {
         if (auto typeReq = dyn_cast<TypeDecl>(req))
           inheritedTypeDecls[typeReq->getFullName()].push_back(typeReq);
       }
@@ -3248,7 +3271,7 @@
   };
 
   // Add requirements for each of the associated types.
-  for (auto Member : getProtocolMembers(proto)) {
+  for (auto Member : proto->getMembers()) {
     if (auto assocTypeDecl = dyn_cast<AssociatedTypeDecl>(Member)) {
       // Add requirements placed directly on this associated type.
       Type assocType = DependentMemberType::get(concreteSelf, assocTypeDecl);
@@ -3288,10 +3311,6 @@
         // If we have inherited associated type...
         if (auto inheritedAssocTypeDecl =
               dyn_cast<AssociatedTypeDecl>(inheritedType)) {
-          // Infer a same-type requirement among the same-named associated
-          // types.
-          addInferredSameTypeReq(assocTypeDecl, inheritedAssocTypeDecl);
-
           // Complain about the first redeclaration.
           if (shouldWarnAboutRedeclaration) {
             auto inheritedFromProto = inheritedAssocTypeDecl->getProtocol();
@@ -3477,9 +3496,7 @@
   auto updateSuperclassConformances = [&] {
     for (auto proto : T->getConformsTo()) {
       if (auto superSource = resolveSuperConformance(T, proto)) {
-        for (auto req : getProtocolMembers(proto)) {
-          auto assocType = dyn_cast<AssociatedTypeDecl>(req);
-          if (!assocType) continue;
+        for (auto assocType : proto->getAssociatedTypeMembers()) {
 
           const auto &nestedTypes = T->getNestedTypes();
           auto nested = nestedTypes.find(assocType->getName());
@@ -5486,53 +5503,6 @@
                          collapsedParents.end());
 }
 
-/// Check whether two potential archetypes "structurally" match, e.g.,
-/// the names match up to the root (which must match).
-static bool potentialArchetypesStructurallyMatch(PotentialArchetype *pa1,
-                                                 PotentialArchetype *pa2) {
-  auto parent1 = pa1->getParent();
-  auto parent2 = pa2->getParent();
-  if (!parent1 && !parent2)
-    return pa1->getGenericParamKey() == pa2->getGenericParamKey();
-
-  // Check for depth mismatch.
-  if (static_cast<bool>(parent1) != static_cast<bool>(parent2))
-    return false;
-
-  // Check names.
-  if (pa1->getNestedName() != pa2->getNestedName())
-    return false;
-
-  return potentialArchetypesStructurallyMatch(parent1, parent2);
-}
-
-/// Look for structurally-equivalent types within the given equivalence class,
-/// collapsing their components.
-static void collapseStructurallyEquivalentSameTypeComponents(
-              EquivalenceClass *equivClass,
-              llvm::SmallDenseMap<PotentialArchetype *, unsigned> &componentOf,
-              SmallVectorImpl<unsigned> &collapsedParents,
-              unsigned &remainingComponents) {
-  for (unsigned i : indices(equivClass->members)) {
-    auto pa1 = equivClass->members[i];
-    auto rep1 = findRepresentative(collapsedParents, componentOf[pa1]);
-    for (unsigned j : indices(equivClass->members).slice(i + 1)) {
-      auto pa2 = equivClass->members[j];
-      auto rep2 = findRepresentative(collapsedParents, componentOf[pa2]);
-      if (rep1 == rep2) continue;
-
-      auto depth = pa1->getNestingDepth();
-      if (depth < 2 || depth != pa2->getNestingDepth()) continue;
-
-      if (potentialArchetypesStructurallyMatch(pa1, pa2) &&
-          unionSets(collapsedParents, rep1, rep2)) {
-        --remainingComponents;
-        rep1 = findRepresentative(collapsedParents, componentOf[pa1]);
-      }
-    }
-  }
-}
-
 /// Collapse same-type components within an equivalence class, minimizing the
 /// number of requirements required to express the equivalence class.
 static void collapseSameTypeComponents(
@@ -5593,14 +5563,6 @@
       builder, equivClass, componentOf, collapsedParents, remainingComponents);
   }
 
-  if (remainingComponents > 1) {
-    // Collapse structurally-equivalent components.
-    collapseStructurallyEquivalentSameTypeComponents(equivClass,
-                                                     componentOf,
-                                                     collapsedParents,
-                                                     remainingComponents);
-  }
-
   // If needed, collapse the same-type components merged by a derived
   // nested-type-name-match edge.
   unsigned maxComponents = equivClass->derivedSameTypeComponents.size();
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index b301427..460cd11 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -106,9 +106,8 @@
         archetype->getParent() != nullptr)
       return Type();
 
-    auto *genericEnv = archetype->getGenericEnvironment();
     type = cast<GenericTypeParamType>(
-      genericEnv->mapTypeOutOfContext(archetype)->getCanonicalType());
+      archetype->getInterfaceType()->getCanonicalType());
   }
 
   // Find the index of the replacement type based on the generic parameter we
@@ -168,8 +167,7 @@
   // If we have an archetype, map out of the context so we can compute a
   // conformance access path.
   if (auto archetype = dyn_cast<ArchetypeType>(type)) {
-    auto *genericEnv = archetype->getGenericEnvironment();
-    type = genericEnv->mapTypeOutOfContext(type)->getCanonicalType();
+    type = archetype->getInterfaceType()->getCanonicalType();
   }
 
   // Error path: if we don't have a type parameter, there is no conformance.
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 903d770..da5f7a0 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1022,6 +1022,27 @@
   llvm::array_pod_sort(protocols.begin(), protocols.end(), compareProtocols);
 }
 
+static Type
+getCanonicalInputType(AnyFunctionType *funcType,
+                      llvm::function_ref<CanType(Type)> getCanonicalType) {
+  auto origInputType = funcType->getInput();
+  bool isParen = isa<ParenType>(origInputType.getPointer());
+  Type inputType = getCanonicalType(origInputType);
+
+  if (!isParen && AnyFunctionType::isCanonicalFunctionInputType(inputType))
+    return inputType;
+
+  auto flags = ParameterTypeFlags().withInOut(inputType->is<InOutType>());
+  if (auto *parenTy = dyn_cast<ParenType>(origInputType.getPointer()))
+    flags = flags.withShared(parenTy->getParameterFlags().isShared());
+
+  inputType = ParenType::get(inputType->getASTContext(),
+                             inputType->getInOutObjectType(), flags);
+  assert(AnyFunctionType::isCanonicalFunctionInputType(inputType));
+
+  return inputType;
+}
+
 /// getCanonicalType - Return the canonical version of this type, which has
 /// sugar from all levels stripped off.
 CanType TypeBase::getCanonicalType() {
@@ -1124,15 +1145,10 @@
     // Transform the input and result types.
     auto &ctx = function->getInput()->getASTContext();
     auto &mod = *ctx.TheBuiltinModule;
-    Type inputTy = function->getInput()->getCanonicalType(sig, mod);
-    if (!AnyFunctionType::isCanonicalFunctionInputType(inputTy)) {
-      auto flags = ParameterTypeFlags().withInOut(inputTy->is<InOutType>());
-      if (auto parenTy = dyn_cast<ParenType>(function->getInput().getPointer()))
-        flags = flags.withShared(parenTy->getParameterFlags().isShared());
-      inputTy = ParenType::get(ctx, inputTy->getInOutObjectType(), flags);
-    }
+    auto inputTy = getCanonicalInputType(function, [&](Type type) -> CanType {
+      return type->getCanonicalType(sig, mod);
+    });
     auto resultTy = function->getResult()->getCanonicalType(sig, mod);
-
     Result = GenericFunctionType::get(sig, inputTy, resultTy,
                                       function->getExtInfo());
     assert(Result->isCanonical());
@@ -1146,14 +1162,8 @@
 
   case TypeKind::Function: {
     FunctionType *FT = cast<FunctionType>(this);
-    Type In = FT->getInput()->getCanonicalType();
-    if (!AnyFunctionType::isCanonicalFunctionInputType(In)) {
-      auto flags = ParameterTypeFlags().withInOut(In->is<InOutType>());
-      if (auto parenTy = dyn_cast<ParenType>(FT->getInput().getPointer()))
-        flags = flags.withShared(parenTy->getParameterFlags().isShared());
-      In = ParenType::get(In->getASTContext(), In->getInOutObjectType(), flags);
-      assert(AnyFunctionType::isCanonicalFunctionInputType(In));
-    }
+    auto In = getCanonicalInputType(
+        FT, [](Type type) -> CanType { return type->getCanonicalType(); });
     Type Out = FT->getResult()->getCanonicalType();
     Result = FunctionType::get(In, Out, FT->getExtInfo());
     break;
@@ -2567,12 +2577,12 @@
 ArchetypeType::ArchetypeType(
   const ASTContext &Ctx,
   llvm::PointerUnion<ArchetypeType *, GenericEnvironment *> ParentOrGenericEnv,
-  llvm::PointerUnion<AssociatedTypeDecl *, Identifier> AssocTypeOrName,
+  Type InterfaceType,
   ArrayRef<ProtocolDecl *> ConformsTo,
   Type Superclass, LayoutConstraint Layout)
     : SubstitutableType(TypeKind::Archetype, &Ctx,
                         RecursiveTypeProperties::HasArchetype),
-      AssocTypeOrName(AssocTypeOrName) {
+      InterfaceType(InterfaceType) {
   // Record the parent/generic environment.
   if (auto parent = ParentOrGenericEnv.dyn_cast<ArchetypeType *>()) {
     ParentOrOpenedOrEnvironment = parent;
@@ -2634,7 +2644,7 @@
 CanArchetypeType ArchetypeType::getNew(
                                    const ASTContext &Ctx,
                                    ArchetypeType *Parent,
-                                   AssociatedTypeDecl *AssocType,
+                                   DependentMemberType *InterfaceType,
                                    SmallVectorImpl<ProtocolDecl *> &ConformsTo,
                                    Type Superclass,
                                    LayoutConstraint Layout) {
@@ -2650,18 +2660,18 @@
       alignof(ArchetypeType), arena);
 
   return CanArchetypeType(new (mem) ArchetypeType(
-      Ctx, Parent, AssocType, ConformsTo, Superclass, Layout));
+      Ctx, Parent, InterfaceType, ConformsTo, Superclass, Layout));
 }
 
 CanArchetypeType
 ArchetypeType::getNew(const ASTContext &Ctx,
-                      GenericEnvironment *genericEnvironment,
-                      Identifier Name,
+                      GenericEnvironment *GenericEnv,
+                      GenericTypeParamType *InterfaceType,
                       SmallVectorImpl<ProtocolDecl *> &ConformsTo,
                       Type Superclass,
                       LayoutConstraint Layout) {
   assert(!Superclass || Superclass->getClassOrBoundGenericClass());
-  assert(genericEnvironment && "missing generic environment for archetype");
+  assert(GenericEnv && "missing generic environment for archetype");
 
   // Gather the set of protocol declarations to which this archetype conforms.
   ProtocolType::canonicalizeProtocols(ConformsTo);
@@ -2673,7 +2683,7 @@
       alignof(ArchetypeType), arena);
 
   return CanArchetypeType(new (mem) ArchetypeType(
-      Ctx, genericEnvironment, Name, ConformsTo, Superclass, Layout));
+      Ctx, GenericEnv, InterfaceType, ConformsTo, Superclass, Layout));
 }
 
 bool ArchetypeType::requiresClass() const {
@@ -2817,11 +2827,17 @@
                 Archetype->getName().str().end());
 }
 
+AssociatedTypeDecl *ArchetypeType::getAssocType() const {
+  if (auto *depMemTy = InterfaceType->getAs<DependentMemberType>())
+    return depMemTy->getAssocType();
+  return nullptr;
+}
+
 Identifier ArchetypeType::getName() const {
   if (auto assocType = getAssocType())
     return assocType->getName();
 
-  return AssocTypeOrName.get<Identifier>();
+  return InterfaceType->castTo<GenericTypeParamType>()->getName();
 }
 
 std::string ArchetypeType::getFullName() const {
diff --git a/lib/Basic/Statistic.cpp b/lib/Basic/Statistic.cpp
index 00c7a55..765e9ed 100644
--- a/lib/Basic/Statistic.cpp
+++ b/lib/Basic/Statistic.cpp
@@ -361,8 +361,11 @@
 
   std::error_code EC;
   raw_fd_ostream ostream(StatsFilename, EC, fs::F_Append | fs::F_Text);
-  if (EC)
+  if (EC) {
+    llvm::errs() << "Error opening -stats-output-dir file '"
+                 << TraceFilename << "' for writing\n";
     return;
+  }
 
   // We change behavior here depending on whether -DLLVM_ENABLE_STATS and/or
   // assertions were on in this build; this is somewhat subtle, but turning on
@@ -387,8 +390,11 @@
   if (LastTracedFrontendCounters && SourceMgr) {
     std::error_code EC;
     raw_fd_ostream tstream(TraceFilename, EC, fs::F_Append | fs::F_Text);
-    if (EC)
+    if (EC) {
+      llvm::errs() << "Error opening -trace-stats-events file '"
+                   << TraceFilename << "' for writing\n";
       return;
+    }
     tstream << "Time,Live,IsEntry,EventName,CounterName,"
             << "CounterDelta,CounterValue,SourceRange\n";
     for (auto const &E : FrontendStatsEvents) {
diff --git a/lib/ClangImporter/ImportMacro.cpp b/lib/ClangImporter/ImportMacro.cpp
index 948d880..518aa99 100644
--- a/lib/ClangImporter/ImportMacro.cpp
+++ b/lib/ClangImporter/ImportMacro.cpp
@@ -650,8 +650,9 @@
       // If the macro is equal to an existing macro, map down to the same
       // declaration.
       if (macro->isIdenticalTo(*entry.first, clangPP, true)) {
-        known->second.push_back({macro, entry.second});
-        return entry.second;
+        ValueDecl *result = entry.second;
+        known->second.push_back({macro, result});
+        return result;
       }
     }
   }
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 265bbea..d920cec 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -926,9 +926,6 @@
 void Driver::buildInputs(const ToolChain &TC,
                          const DerivedArgList &Args,
                          InputFileList &Inputs) const {
-  types::ID InputType = types::TY_Nothing;
-  Arg *InputTypeArg = nullptr;
-
   llvm::StringMap<StringRef> SourceFileNames;
 
   for (Arg *A : Args) {
@@ -936,29 +933,19 @@
       StringRef Value = A->getValue();
       types::ID Ty = types::TY_INVALID;
 
-      if (InputType == types::TY_Nothing) {
-        // If there was an explicit arg for this, claim it.
-        if (InputTypeArg)
-          InputTypeArg->claim();
-
-        // stdin must be handled specially.
-        if (Value.equals("-")) {
-          // By default, treat stdin as Swift input.
-          // FIXME: should we limit this inference to specific modes?
-          Ty = types::TY_Swift;
-        } else {
-          // Otherwise lookup by extension.
-          Ty = TC.lookupTypeForExtension(llvm::sys::path::extension(Value));
-
-          if (Ty == types::TY_INVALID) {
-            // FIXME: should we adjust this inference in certain modes?
-            Ty = types::TY_Object;
-          }
-        }
+      // stdin must be handled specially.
+      if (Value.equals("-")) {
+        // By default, treat stdin as Swift input.
+        Ty = types::TY_Swift;
       } else {
-        assert(InputTypeArg && "InputType set w/o InputTypeArg");
-        InputTypeArg->claim();
-        Ty = InputType;
+        // Otherwise lookup by extension.
+        Ty = TC.lookupTypeForExtension(llvm::sys::path::extension(Value));
+
+        if (Ty == types::TY_INVALID) {
+          // By default, treat inputs with no extension, or with an
+          // extension that isn't recognized, as object files.
+          Ty = types::TY_Object;
+        }
       }
 
       if (checkInputExistence(*this, Args, Diags, Value))
@@ -973,8 +960,6 @@
         }
       }
     }
-
-    // FIXME: add -x support (or equivalent)
   }
 }
 
@@ -1158,12 +1143,10 @@
       OI.CompilerMode = OutputInfo::Mode::SingleCompile;
       break;
 
-    // BEGIN APPLE-ONLY OUTPUT ACTIONS
     case options::OPT_index_file:
       OI.CompilerMode = OutputInfo::Mode::SingleCompile;
       OI.CompilerOutputType = types::TY_IndexData;
       break;
-    // END APPLE-ONLY OUTPUT ACTIONS
 
     case options::OPT_update_code:
       OI.CompilerOutputType = types::TY_Remapping;
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 968bf8c..83bfba4 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -234,13 +234,9 @@
     case types::TY_ImportedModules:
       FrontendModeOption = "-emit-imported-modules";
       break;
-
-    // BEGIN APPLE-ONLY OUTPUT TYPES
     case types::TY_IndexData:
       FrontendModeOption = "-typecheck";
       break;
-    // END APPLE-ONLY OUTPUT TYPES
-
     case types::TY_Remapping:
       FrontendModeOption = "-update-code";
       break;
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 5eb4627..4d943e9 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1132,13 +1132,9 @@
   }
 #endif
 
-  Opts.EnableObjCInterop = Target.isOSDarwin();
-  if (auto A = Args.getLastArg(OPT_enable_objc_interop,
-                               OPT_disable_objc_interop)) {
-    Opts.EnableObjCInterop
-      = A->getOption().matches(OPT_enable_objc_interop);
-  }
-
+  Opts.EnableObjCInterop =
+      Args.hasFlag(OPT_enable_objc_interop, OPT_disable_objc_interop,
+                   Target.isOSDarwin());
   Opts.EnableSILOpaqueValues |= Args.hasArg(OPT_enable_sil_opaque_values);
 
   // Must be processed after any other language options that could affect
@@ -1373,7 +1369,6 @@
   if (Args.hasArg(OPT_sil_merge_partial_modules))
     Opts.MergePartialModules = true;
 
-  Opts.SILSerializeAll |= Args.hasArg(OPT_sil_serialize_all);
   Opts.SILSerializeWitnessTables |=
     Args.hasArg(OPT_sil_serialize_witness_tables);
   Opts.SILSerializeVTables |=
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index 2feb3e3..12454e2 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -258,8 +258,6 @@
 
     if (Invocation.getFrontendOptions().EnableResilience)
       MainModule->setResilienceStrategy(ResilienceStrategy::Resilient);
-    else if (Invocation.getSILOptions().SILSerializeAll)
-      MainModule->setResilienceStrategy(ResilienceStrategy::Fragile);
   }
   return MainModule;
 }
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index 3998777..ff2cffc 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -925,8 +925,6 @@
       serializationOpts.OutputPath = opts.ModuleOutputPath.c_str();
       serializationOpts.DocOutputPath = opts.ModuleDocOutputPath.c_str();
       serializationOpts.GroupInfoPath = opts.GroupInfoPath.c_str();
-      serializationOpts.SerializeAllSIL =
-          Invocation.getSILOptions().SILSerializeAll;
       if (opts.SerializeBridgingHeader)
         serializationOpts.ImportedHeader = opts.ImplicitObjCHeaderPath;
       serializationOpts.ModuleLinkName = opts.ModuleLinkName;
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index ee12bc8..88c0b7c 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -1521,7 +1521,7 @@
   case CodeCompletionLiteralKind::NilLiteral:
     return KnownProtocolKind::ExpressibleByNilLiteral;
   case CodeCompletionLiteralKind::StringLiteral:
-    return KnownProtocolKind::ExpressibleByStringLiteral;
+    return KnownProtocolKind::ExpressibleByUnicodeScalarLiteral;
   case CodeCompletionLiteralKind::Tuple:
     llvm_unreachable("no such protocol kind");
   }
diff --git a/lib/IRGen/GenArchetype.cpp b/lib/IRGen/GenArchetype.cpp
index a257fbb..a2ceaff 100644
--- a/lib/IRGen/GenArchetype.cpp
+++ b/lib/IRGen/GenArchetype.cpp
@@ -208,7 +208,7 @@
   // to this conformance from concrete sources.
 
   auto signature = environment->getGenericSignature()->getCanonicalSignature();
-  auto archetypeDepType = environment->mapTypeOutOfContext(archetype);
+  auto archetypeDepType = archetype->getInterfaceType();
 
   auto astPath = signature->getConformanceAccessPath(archetypeDepType, protocol,
                                                      *IGF.IGM.getSwiftModule());
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 4d13753..23fbb29 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -1314,44 +1314,11 @@
   llvm_unreachable("bad link entity kind");
 }
 
-bool LinkEntity::isFragile(ForDefinition_t isDefinition) const {
-  switch (getKind()) {
-    case Kind::SILFunction:
-      return getSILFunction()->isSerialized();
-      
-    case Kind::SILGlobalVariable:
-      return getSILGlobalVariable()->isSerialized();
-      
-    case Kind::ReflectionAssociatedTypeDescriptor:
-    case Kind::ReflectionSuperclassDescriptor:
-    case Kind::AssociatedTypeMetadataAccessFunction:
-    case Kind::AssociatedTypeWitnessTableAccessFunction:
-    case Kind::GenericProtocolWitnessTableCache:
-    case Kind::GenericProtocolWitnessTableInstantiationFunction:
-    case Kind::ObjCClassRef:
-      return false;
-
-    default:
-      break;
-  }
-  if (isProtocolConformanceKind(getKind())) {
-    auto conformance = getProtocolConformance();
-
-    auto conformanceModule = conformance->getDeclContext()->getParentModule();
-    auto isCompletelySerialized = conformanceModule->getResilienceStrategy() ==
-                                  ResilienceStrategy::Fragile;
-
-    // The conformance is fragile if it is in a -sil-serialize-all module.
-    return isCompletelySerialized;
-  }
-  return false;
-}
-
 static std::tuple<llvm::GlobalValue::LinkageTypes,
                   llvm::GlobalValue::VisibilityTypes,
                   llvm::GlobalValue::DLLStorageClassTypes>
 getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
-             bool isFragile, bool isSILOnly, ForDefinition_t isDefinition,
+             bool isSILOnly, ForDefinition_t isDefinition,
              bool isWeakImported) {
 #define RESULT(LINKAGE, VISIBILITY, DLL_STORAGE)                               \
   std::make_tuple(llvm::GlobalValue::LINKAGE##Linkage,                         \
@@ -1372,29 +1339,6 @@
       info.UseDLLStorage ? llvm::GlobalValue::DLLImportStorageClass
                          : llvm::GlobalValue::DefaultStorageClass;
 
-  if (isFragile) {
-    // Fragile functions/globals must be visible from outside, regardless of
-    // their access level. If a caller is also fragile and inlined into another
-    // module it must be able to access this (not-inlined) function/global.
-    switch (linkage) {
-    case SILLinkage::Hidden:
-    case SILLinkage::Private:
-      linkage = SILLinkage::Public;
-      break;
-
-    case SILLinkage::HiddenExternal:
-    case SILLinkage::PrivateExternal:
-      linkage = SILLinkage::PublicExternal;
-      break;
-
-    case SILLinkage::Public:
-    case SILLinkage::Shared:
-    case SILLinkage::PublicExternal:
-    case SILLinkage::SharedExternal:
-      break;
-    }
-  }
-
   switch (linkage) {
   case SILLinkage::Public:
     // Don't code-gen transparent functions. Internal linkage will enable llvm
@@ -1453,8 +1397,7 @@
     return std::make_tuple(isDefinition
                                ? llvm::GlobalValue::AvailableExternallyLinkage
                                : llvm::GlobalValue::ExternalLinkage,
-                           isFragile ? llvm::GlobalValue::DefaultVisibility
-                                     : llvm::GlobalValue::HiddenVisibility,
+                           llvm::GlobalValue::HiddenVisibility,
                            ImportedStorage);
 
   }
@@ -1472,7 +1415,7 @@
   UniversalLinkageInfo linkInfo(IGM);
   auto linkage =
       getIRLinkage(linkInfo, entity.getLinkage(ForDefinition),
-                   entity.isFragile(ForDefinition), entity.isSILOnly(),
+                   entity.isSILOnly(),
                    ForDefinition, entity.isWeakImported(IGM.getSwiftModule()));
   global->setLinkage(std::get<0>(linkage));
   global->setVisibility(std::get<1>(linkage));
@@ -1504,7 +1447,7 @@
 
   std::tie(result.Linkage, result.Visibility, result.DLLStorageClass) =
       getIRLinkage(linkInfo, entity.getLinkage(isDefinition),
-                   entity.isFragile(isDefinition), entity.isSILOnly(),
+                   entity.isSILOnly(),
                    isDefinition, entity.isWeakImported(swiftModule));
 
   result.ForDefinition = isDefinition;
@@ -1515,20 +1458,19 @@
 LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
                        StringRef name,
                        SILLinkage linkage,
-                       bool isFragile,
                        bool isSILOnly,
                        ForDefinition_t isDefinition,
                        bool isWeakImported) {
   LinkInfo result;
-  
+
   result.Name += name;
   std::tie(result.Linkage, result.Visibility, result.DLLStorageClass) =
-    getIRLinkage(linkInfo, linkage, isFragile, isSILOnly,
+    getIRLinkage(linkInfo, linkage, isSILOnly,
                  isDefinition, isWeakImported);
   result.ForDefinition = isDefinition;
   return result;
 }
-                       
+
 static bool isPointerTo(llvm::Type *ptrTy, llvm::Type *objTy) {
   return cast<llvm::PointerType>(ptrTy)->getElementType() == objTy;
 }
diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp
index 95c8d0f..868de2b 100644
--- a/lib/IRGen/GenKeyPath.cpp
+++ b/lib/IRGen/GenKeyPath.cpp
@@ -330,7 +330,6 @@
     
     auto linkInfo = LinkInfo::get(IGM, "swift_keyPathGenericWitnessTable",
                                   SILLinkage::PublicExternal,
-                                  /*fragile*/ false,
                                   /*sil only*/ false,
                                   NotForDefinition,
                                   /*weak imported*/ false);
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 028c94b..7107da2 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -2116,7 +2116,7 @@
     void layout() {
       asImpl().addName();
       asImpl().addKindDependentFields();
-      asImpl().addGenericMetadataPatternAndKind();
+      asImpl().addKind();
       asImpl().addAccessFunction();
       asImpl().addGenericParams();
     }
@@ -2130,19 +2130,9 @@
                                  /*willBeRelativelyAddressed*/ true));
     }
     
-    void addGenericMetadataPatternAndKind() {
-      NominalTypeDecl *ntd = asImpl().getTarget();
+    void addKind() {
       auto kind = asImpl().getKind();
-      if (!ntd->isGenericContext()) {
-        // There's no pattern to link.
-        B.addInt32(kind);
-        return;
-      }
-
-      B.addTaggedRelativeOffset(
-        IGM.RelativeAddressTy,
-        IGM.getAddrOfTypeMetadata(getAbstractType(), /*pattern*/ true),
-        kind);
+      B.addInt32(kind);
     }
 
     void addAccessFunction() {
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 3982e34..acd3610 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -314,18 +314,35 @@
                        selfTy);
 
   if (auto *proto = fnType->getDefaultWitnessMethodProtocol(M)) {
-    // The Self type is abstract, so we must pass in a witness table.
+    // The Self type is abstract, so we can fulfill its metadata from
+    // the Self metadata parameter.
     addSelfMetadataFulfillment(selfTy);
 
-    // Look at the witness table for the conformance.
+    // The witness table for the Self : P conformance can be
+    // fulfilled from the Self witness table parameter.
     Sources.emplace_back(MetadataSource::Kind::SelfWitnessTable,
                          MetadataSource::InvalidSourceIndex,
                          selfTy);
     addSelfWitnessTableFulfillment(selfTy, proto);
+  } else if (auto *classDecl = fnType->getWitnessMethodClass(M)) {
+    // The Self type is abstract, so we can fulfill its metadata from
+    // the Self metadata parameter.
+    addSelfMetadataFulfillment(selfTy);
+
+    // FIXME: We should fulfill the witness table too, but we don't
+    // have the original protocol anymore -- we should store it as part
+    // of the @convention(witness_method) bit in the SILFunctionType's
+    // ExtInfo
   } else {
     // If the Self type is concrete, we have a witness thunk with a
     // fully substituted Self type. The witness table parameter is not
     // used.
+    //
+    // FIXME: As above, we should fulfill the Self metadata and
+    // conformance from our two special paramaters here. However, the
+    // Self metadata will be inexact.
+    //
+    // For now, just fulfill the generic arguments of 'Self'.
     considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath());
   }
 }
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index b97df13..16182b2 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -15,11 +15,10 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "irgen"
-#include "swift/Subsystems.h"
+#include "IRGenModule.h"
 #include "swift/AST/DiagnosticsIRGen.h"
 #include "swift/AST/IRGenOptions.h"
 #include "swift/AST/LinkLibrary.h"
-#include "swift/SIL/SILModule.h"
 #include "swift/Basic/Defer.h"
 #include "swift/Basic/Dwarf.h"
 #include "swift/Basic/Platform.h"
@@ -29,44 +28,46 @@
 #include "swift/ClangImporter/ClangImporter.h"
 #include "swift/IRGen/IRGenPublic.h"
 #include "swift/IRGen/IRGenSILPasses.h"
-#include "swift/LLVMPasses/PassesFwd.h"
 #include "swift/LLVMPasses/Passes.h"
-#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/LLVMPasses/PassesFwd.h"
+#include "swift/SIL/SILModule.h"
 #include "swift/SILOptimizer/PassManager/PassManager.h"
 #include "swift/SILOptimizer/PassManager/PassPipeline.h"
+#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/Subsystems.h"
 #include "clang/Basic/TargetInfo.h"
-#include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
+#include "llvm/Bitcode/BitcodeWriterPass.h"
 #include "llvm/CodeGen/BasicTTIImpl.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ValueSymbolTable.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/Linker/Linker.h"
 #include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Mutex.h"
 #include "llvm/Support/MD5.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/TargetRegistry.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
-#include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
-#include "llvm/Object/ObjectFile.h"
-#include "IRGenModule.h"
 
 #include <thread>
 
@@ -74,6 +75,10 @@
 using namespace irgen;
 using namespace llvm;
 
+static cl::opt<bool> DisableObjCARCContract(
+    "disable-objc-arc-contract", cl::Hidden,
+    cl::desc("Disable running objc arc contract for testing purposes"));
+
 namespace {
 // We need this to access IRGenOptions from extension functions
 class PassManagerBuilderWrapper : public PassManagerBuilder {
@@ -446,6 +451,13 @@
 
   legacy::PassManager EmitPasses;
 
+  // Make sure we do ARC contraction under optimization.  We don't
+  // rely on any other LLVM ARC transformations, but we do need ARC
+  // contraction to add the objc_retainAutoreleasedReturnValue
+  // assembly markers and remove clang.arc.used.
+  if (Opts.Optimize && !DisableObjCARCContract)
+    EmitPasses.add(createObjCARCContractPass());
+
   // Set up the final emission passes.
   switch (Opts.OutputKind) {
   case IRGenOutputKind::Module:
@@ -466,13 +478,6 @@
     EmitPasses.add(createTargetTransformInfoWrapperPass(
         TargetMachine->getTargetIRAnalysis()));
 
-    // Make sure we do ARC contraction under optimization.  We don't
-    // rely on any other LLVM ARC transformations, but we do need ARC
-    // contraction to add the objc_retainAutoreleasedReturnValue
-    // assembly markers.
-    if (Opts.Optimize)
-      EmitPasses.add(createObjCARCContractPass());
-
     bool fail = TargetMachine->addPassesToEmitFile(EmitPasses, *RawOS,
                                                    FileType, !Opts.Verify);
     if (fail) {
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index d469b20..0c6b85b 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -1395,6 +1395,16 @@
     return nullptr;
   }
 
+  /// The private discriminator is represented as an inline namespace.
+  llvm::DIScope *getFilePrivateScope(llvm::DIScope *Parent, TypeDecl *Decl) {
+    // Retrieve the private discriminator.
+    auto *MSC = Decl->getDeclContext()->getModuleScopeContext();
+    auto *FU = cast<FileUnit>(MSC);
+    Identifier PD = FU->getDiscriminatorForPrivateValue(Decl);
+    bool ExportSymbols = true;
+    return DBuilder.createNameSpace(Parent, PD.str(), ExportSymbols);
+  }
+
   llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) {
     // Is this an empty type?
     if (DbgTy.isNull())
@@ -1438,6 +1448,13 @@
     }
     if (!Scope)
       Scope = getOrCreateContext(Context);
+
+    // Scope outermost fileprivate decls in an inline private discriminator
+    // namespace.
+    if (auto *Decl = DbgTy.getDecl())
+      if (Decl->isOutermostPrivateOrFilePrivateScope())
+        Scope = getFilePrivateScope(Scope, Decl);
+
     llvm::DIType *DITy = createType(DbgTy, MangledName, Scope, getFile(Scope));
 
     // Incrementally build the DIRefMap.
@@ -1518,9 +1535,9 @@
     CU_Nodes->addOperand(*CU);
 
   // Create a module for the current compile unit.
+  auto *MDecl = IGM.getSwiftModule();
   llvm::sys::path::remove_filename(AbsMainFile);
-  MainModule = getOrCreateModule(IGM.getSwiftModule(), TheCU, Opts.ModuleName,
-                                 AbsMainFile);
+  MainModule = getOrCreateModule(MDecl, TheCU, Opts.ModuleName, AbsMainFile);
   DBuilder.createImportedModule(MainFile, MainModule, MainFile, 0);
 
   // Macro definitions that were defined by the user with "-Xcc -D" on the
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 198c2e8..ef2efaf 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -895,7 +895,6 @@
   void visitObjCMethodInst(ObjCMethodInst *i);
   void visitObjCSuperMethodInst(ObjCSuperMethodInst *i);
   void visitWitnessMethodInst(WitnessMethodInst *i);
-  void visitDynamicMethodInst(DynamicMethodInst *i);
 
   void visitAllocValueBufferInst(AllocValueBufferInst *i);
   void visitProjectValueBufferInst(ProjectValueBufferInst *i);
@@ -5001,12 +5000,6 @@
   }
 }
 
-void IRGenSILFunction::visitDynamicMethodInst(DynamicMethodInst *i) {
-  assert(i->getMember().isForeign && "dynamic_method requires [objc] method");
-  setLoweredObjCMethod(i, i->getMember());
-  return;
-}
-
 void IRGenSILFunction::visitWitnessMethodInst(swift::WitnessMethodInst *i) {
   // For Objective-C classes we need to arrange for a msgSend
   // to happen when the method is called.
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 7bf8678..7e0480a 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -478,7 +478,6 @@
       case SILInstructionKind::SuperMethodInst:
       case SILInstructionKind::ObjCMethodInst:
       case SILInstructionKind::ObjCSuperMethodInst:
-      case SILInstructionKind::DynamicMethodInst:
       case SILInstructionKind::WitnessMethodInst: {
         // TODO Any more instructions to add here?
         auto *MI = dyn_cast<MethodInst>(currIns);
@@ -2037,14 +2036,6 @@
                                                  newSILType);
       break;
     }
-    case SILInstructionKind::DynamicMethodInst: {
-      auto *DMI = dyn_cast<DynamicMethodInst>(instr);
-      assert(DMI && "ValueKind is Witness Method but dyn_cast failed");
-      SILValue selfValue = instr->getOperand(0);
-      newInstr = methodBuilder.createDynamicMethod(loc, selfValue, member,
-                                                   newSILType);
-      break;
-    }
     case SILInstructionKind::WitnessMethodInst: {
       auto *WMI = dyn_cast<WitnessMethodInst>(instr);
       assert(!WMI->isVolatile());
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index 7712a4d..49ab85b 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -3784,8 +3784,7 @@
   case SILInstructionKind::ClassMethodInst:
   case SILInstructionKind::SuperMethodInst:
   case SILInstructionKind::ObjCMethodInst:
-  case SILInstructionKind::ObjCSuperMethodInst:
-  case SILInstructionKind::DynamicMethodInst: {
+  case SILInstructionKind::ObjCSuperMethodInst: {
     SILDeclRef Member;
     SILType MethodTy;
     SourceLoc TyLoc;
@@ -3816,9 +3815,6 @@
     case SILInstructionKind::ObjCSuperMethodInst:
       ResultVal = B.createObjCSuperMethod(InstLoc, Val, Member, MethodTy);
       break;
-    case SILInstructionKind::DynamicMethodInst:
-      ResultVal = B.createDynamicMethod(InstLoc, Val, Member, MethodTy);
-      break;
     }
     break;
   }
diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp
index fdc4ed2..37a74fb 100644
--- a/lib/PrintAsObjC/PrintAsObjC.cpp
+++ b/lib/PrintAsObjC/PrintAsObjC.cpp
@@ -604,6 +604,7 @@
     }
 
     bool skipAvailability = false;
+    bool makeNewUnavailable = false;
     // Swift designated initializers are Objective-C designated initializers.
     if (auto ctor = dyn_cast<ConstructorDecl>(AFD)) {
       if (ctor->hasStubImplementation()
@@ -612,6 +613,9 @@
         // required access
         os << " SWIFT_UNAVAILABLE";
         skipAvailability = true;
+        // If -init is unavailable, then +new should be, too:
+        const bool selectorIsInit = selector.getNumArgs() == 0 && selectorPieces.front().str() == "init";
+        makeNewUnavailable = selectorIsInit;
       } else if (ctor->isDesignatedInit() &&
           !isa<ProtocolDecl>(ctor->getDeclContext())) {
         os << " OBJC_DESIGNATED_INITIALIZER";
@@ -643,6 +647,10 @@
     }
 
     os << ";\n";
+
+    if (makeNewUnavailable) {
+        os << "+ (nonnull instancetype)new SWIFT_UNAVAILABLE;\n";
+    }
   }
 
   void printAbstractFunctionAsFunction(FuncDecl *FD) {
diff --git a/lib/SIL/SIL.cpp b/lib/SIL/SIL.cpp
index 090173b..97546d5 100644
--- a/lib/SIL/SIL.cpp
+++ b/lib/SIL/SIL.cpp
@@ -54,11 +54,6 @@
   case AccessLevel::Open:
     return FormalLinkage::PublicUnique;
   case AccessLevel::Internal:
-    // If we're serializing all function bodies, type metadata for internal
-    // types needs to be public too.
-    if (D->getDeclContext()->getParentModule()->getResilienceStrategy()
-        == ResilienceStrategy::Fragile)
-      return FormalLinkage::PublicUnique;
     return FormalLinkage::HiddenUnique;
   case AccessLevel::FilePrivate:
   case AccessLevel::Private:
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 1286792..19d3377 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -100,10 +100,10 @@
   assert(getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod);
   auto selfTy = getSelfInstanceType();
   if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
+    assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
     auto superclass = GenericSig->getSuperclassBound(paramTy, M);
     if (superclass)
       return nullptr;
-    assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
     auto protos = GenericSig->getConformsTo(paramTy, M);
     assert(protos.size() == 1);
     return protos[0];
@@ -112,6 +112,20 @@
   return nullptr;
 }
 
+ClassDecl *
+SILFunctionType::getWitnessMethodClass(ModuleDecl &M) const {
+  auto selfTy = getSelfInstanceType();
+  auto genericSig = getGenericSignature();
+  if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
+    assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
+    auto superclass = genericSig->getSuperclassBound(paramTy, M);
+    if (superclass)
+      return superclass->getClassOrBoundGenericClass();
+  }
+
+  return nullptr;
+}
+
 static CanType getKnownType(Optional<CanType> &cacheSlot, ASTContext &C,
                             StringRef moduleName, StringRef typeName) {
   if (!cacheSlot) {
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index b9b9d9b..2cf7f76 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -1592,18 +1592,6 @@
       DynamicMethodBranchInst(Loc, Operand, Member, HasMethodBB, NoMethodBB);
 }
 
-/// Create a witness method call of a protocol requirement, passing in a lookup
-/// type and conformance.
-///
-/// At runtime, the witness is looked up in the conformance of the lookup type
-/// to the protocol.
-///
-/// The lookup type is usually an archetype, but it will be concrete if the
-/// witness_method instruction is inside a function body that was specialized.
-///
-/// The conformance must exactly match the requirement; the caller must handle
-/// the case where the requirement is defined in a base protocol that is
-/// refined by the conforming protocol.
 WitnessMethodInst *
 WitnessMethodInst::create(SILDebugLocation Loc, CanType LookupType,
                           ProtocolConformanceRef Conformance, SILDeclRef Member,
@@ -1627,10 +1615,10 @@
                                           Ty, TypeDependentOperands, Volatile);
 }
 
-DynamicMethodInst *
-DynamicMethodInst::create(SILDebugLocation DebugLoc, SILValue Operand,
-                          SILDeclRef Member, SILType Ty, SILFunction *F,
-                          SILOpenedArchetypesState &OpenedArchetypes) {
+ObjCMethodInst *
+ObjCMethodInst::create(SILDebugLocation DebugLoc, SILValue Operand,
+                       SILDeclRef Member, SILType Ty, SILFunction *F,
+                       SILOpenedArchetypesState &OpenedArchetypes) {
   SILModule &Mod = F->getModule();
   SmallVector<SILValue, 8> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, *F,
@@ -1638,10 +1626,10 @@
 
   unsigned size =
       totalSizeToAlloc<swift::Operand>(1 + TypeDependentOperands.size());
-  void *Buffer = Mod.allocateInst(size, alignof(DynamicMethodInst));
-  return ::new (Buffer) DynamicMethodInst(DebugLoc, Operand,
-                                          TypeDependentOperands,
-                                          Member, Ty);
+  void *Buffer = Mod.allocateInst(size, alignof(ObjCMethodInst));
+  return ::new (Buffer) ObjCMethodInst(DebugLoc, Operand,
+                                       TypeDependentOperands,
+                                       Member, Ty);
 }
 
 InitExistentialAddrInst *InitExistentialAddrInst::create(
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index 78513dc..69d568c 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -609,7 +609,6 @@
 ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, ObjCSuperMethod)
 ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, BridgeObjectToWord)
 ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, CopyBlock)
-ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, DynamicMethod)
 ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, OpenExistentialBox)
 ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefTailAddr)
 ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefToRawPointer)
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 54e470a..b32c4e0 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -1631,12 +1631,6 @@
     }
     *this << " : " << WMI->getType();
   }
-  void visitDynamicMethodInst(DynamicMethodInst *DMI) {
-    printMethodInst(DMI, DMI->getOperand());
-    *this << " : " << DMI->getMember().getDecl()->getInterfaceType();
-    *this << ", ";
-    *this << DMI->getType();
-  }
   void visitOpenExistentialAddrInst(OpenExistentialAddrInst *OI) {
     if (OI->getAccessKind() == OpenedExistentialAccess::Immutable)
       *this << "immutable_access ";
@@ -2897,29 +2891,37 @@
     // Lazily initialize the instruction -> ID mapping.
     if (ValueToIDMap.empty())
       F->numberValues(ValueToIDMap);
-  } else {
-    setContext(BB);
-    // Lazily initialize the instruction -> ID mapping.
-    if (ValueToIDMap.empty()) {
-      unsigned idx = 0;
-      for (auto &I : *BB) {
-        // Give the instruction itself the next ID.
-        ValueToIDMap[&I] = idx;
+    ID R = {ID::SSAValue, ValueToIDMap[node]};
+    return R;
+  }
 
-        // If there are no results, make sure we don't reuse that ID.
-        auto results = I.getResults();
-        if (results.empty()) {
-          idx++;
+  setContext(BB);
 
-        // Otherwise, assign all of the results an index.  Note that
-        // we'll assign the same ID to both the instruction and the
-        // first result.
-        } else {
-          for (auto result : results) {
-            ValueToIDMap[result] = idx++;
-          }
-        }
-      }
+  // Check if we have initialized our ValueToIDMap yet. If we have, just use
+  // that.
+  if (!ValueToIDMap.empty()) {
+    ID R = {ID::SSAValue, ValueToIDMap[node]};
+    return R;
+  }
+
+  // Otherwise, initialize the instruction -> ID mapping cache.
+  unsigned idx = 0;
+  for (auto &I : *BB) {
+    // Give the instruction itself the next ID.
+    ValueToIDMap[&I] = idx;
+
+    // If there are no results, make sure we don't reuse that ID.
+    auto results = I.getResults();
+    if (results.empty()) {
+      idx++;
+      continue;
+    }
+
+    // Otherwise, assign all of the results an index.  Note that
+    // we'll assign the same ID to both the instruction and the
+    // first result.
+    for (auto result : results) {
+      ValueToIDMap[result] = idx++;
     }
   }
 
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index 4009f48..32b9826 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -69,7 +69,7 @@
   // Ok, we have a primary archetype, make sure it is in the nested generic
   // environment of our caller.
   if (auto *genericEnv = F->getGenericEnvironment())
-    if (genericEnv->containsPrimaryArchetype(A))
+    if (A->getGenericEnvironment() == genericEnv)
       return true;
 
   return false;
@@ -2194,26 +2194,6 @@
     return SILType::getPrimitiveObjectType(fnTy);
   }
   
-  void checkDynamicMethodInst(DynamicMethodInst *EMI) {
-    requireObjectType(SILFunctionType, EMI, "result of dynamic_method");
-    SILType operandType = EMI->getOperand()->getType();
-
-    require(EMI->getMember().getDecl()->isObjC(), "method must be @objc");
-    if (!EMI->getMember().getDecl()->isInstanceMember()) {
-      require(operandType.is<MetatypeType>(),
-              "operand must have metatype type");
-      require(operandType.castTo<MetatypeType>()
-                ->getInstanceType()->mayHaveSuperclass(),
-              "operand must have metatype of class or class-bounded type");
-    }
-    
-    require(getDynamicMethodType(operandType, EMI->getMember())
-              .getSwiftRValueType()
-              ->isBindableTo(EMI->getType().getSwiftRValueType()),
-            "result must be of the method's type");
-    verifyOpenedArchetype(EMI, EMI->getType().getSwiftRValueType());
-  }
-
   void checkClassMethodInst(ClassMethodInst *CMI) {
     auto member = CMI->getMember();
     auto overrideTy = TC.getConstantOverrideType(member);
@@ -2270,24 +2250,31 @@
 
   void checkObjCMethodInst(ObjCMethodInst *OMI) {
     auto member = OMI->getMember();
-    auto overrideTy = TC.getConstantOverrideType(member);
-    if (OMI->getModule().getStage() != SILStage::Lowered) {
-      requireSameType(
-          OMI->getType(), SILType::getPrimitiveObjectType(overrideTy),
-          "result type of objc_method must match abstracted type of method");
-    }
+    require(member.isForeign,
+            "native method cannot be dispatched via objc");
+
     auto methodType = requireObjectType(SILFunctionType, OMI,
                                         "result of objc_method");
     require(!methodType->getExtInfo().hasContext(),
             "result method must be of a context-free function type");
-    SILType operandType = OMI->getOperand()->getType();
-    require(operandType.isClassOrClassMetatype(),
-            "operand must be of a class type");
-    require(getMethodSelfType(methodType).isClassOrClassMetatype(),
-            "result must be a method of a class");
-    
-    require(member.isForeign,
-            "native method cannot be dispatched via objc");
+
+    auto methodSelfType = getMethodSelfType(methodType);
+    auto operandType = OMI->getOperand()->getType();
+
+    if (methodSelfType.isClassOrClassMetatype()) {
+      auto overrideTy = TC.getConstantOverrideType(member);
+      requireSameType(
+          OMI->getType(), SILType::getPrimitiveObjectType(overrideTy),
+          "result type of objc_method must match abstracted type of method");
+      require(operandType.isClassOrClassMetatype(),
+              "operand must be of a class type");
+    } else {
+      require(getDynamicMethodType(operandType, OMI->getMember())
+                .getSwiftRValueType()
+                ->isBindableTo(OMI->getType().getSwiftRValueType()),
+              "result must be of the method's type");
+      verifyOpenedArchetype(OMI, OMI->getType().getSwiftRValueType());
+    }
 
     // TODO: We should enforce that ObjC methods are dispatched on ObjC
     // metatypes, but IRGen appears not to care right now.
diff --git a/lib/SIL/ValueOwnershipKindClassifier.cpp b/lib/SIL/ValueOwnershipKindClassifier.cpp
index 5f0271d..ad55f91 100644
--- a/lib/SIL/ValueOwnershipKindClassifier.cpp
+++ b/lib/SIL/ValueOwnershipKindClassifier.cpp
@@ -63,7 +63,6 @@
 CONSTANT_OWNERSHIP_INST(Trivial, BridgeObjectToWord)
 CONSTANT_OWNERSHIP_INST(Trivial, ClassMethod)
 CONSTANT_OWNERSHIP_INST(Trivial, ObjCMethod)
-CONSTANT_OWNERSHIP_INST(Trivial, DynamicMethod)
 CONSTANT_OWNERSHIP_INST(Trivial, ExistentialMetatype)
 CONSTANT_OWNERSHIP_INST(Trivial, FloatLiteral)
 CONSTANT_OWNERSHIP_INST(Trivial, FunctionRef)
diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp
index aaa8b13..bb4e271 100644
--- a/lib/SILGen/SILGen.cpp
+++ b/lib/SILGen/SILGen.cpp
@@ -461,9 +461,6 @@
       if (isAvailableExternally(F->getLinkage())) {
         F->setLinkage(constant.getLinkage(ForDefinition));
       }
-      if (isMakeModuleFragile()) {
-        F->setSerialized(IsSerialized);
-      }
     }
     return F;
   }
@@ -523,13 +520,6 @@
 
   assert(F && "SILFunction should have been defined");
 
-  if (isMakeModuleFragile()) {
-    SILLinkage linkage = constant.getLinkage(forDefinition);
-    if (linkage != SILLinkage::PublicExternal) {
-      F->setSerialized(IsSerialized);
-    }
-  }
-
   emittedFunctions[constant] = F;
 
   // If we delayed emitting this function previously, we need it now.
@@ -994,9 +984,7 @@
       M.createFunction(SILLinkage::Private,
                        funcName, initSILType, nullptr,
                        SILLocation(binding), IsNotBare, IsNotTransparent,
-                       isMakeModuleFragile()
-                           ? IsSerialized
-                           : IsNotSerialized);
+                       IsNotSerialized);
   f->setDebugScope(new (M) SILDebugScope(RegularLocation(binding), f));
   SILGenFunction(*this, *f).emitLazyGlobalInitializer(binding, pbdEntry);
   f->verify();
diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h
index f6f5701..acf14b0 100644
--- a/lib/SILGen/SILGen.h
+++ b/lib/SILGen/SILGen.h
@@ -121,13 +121,9 @@
   NormalProtocolConformance *lastEmittedConformance = nullptr;
 
   SILFunction *emitTopLevelFunction(SILLocation Loc);
-  
+
   size_t anonymousSymbolCounter = 0;
-  
-  /// If true, all functions and globals are made fragile. Currently only used
-  /// for compiling the stdlib.
-  bool isMakeModuleFragile() const { return M.getOptions().SILSerializeAll; }
-  
+
   Optional<SILDeclRef> StringToNSStringFn;
   Optional<SILDeclRef> NSStringToStringFn;
   Optional<SILDeclRef> ArrayToNSArrayFn;
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 8805294..84ce113 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -250,19 +250,17 @@
     /// Enum case constructor call.
     EnumElement,
 
-    VirtualMethod_First,
-      /// A method call using class method dispatch.
-      ClassMethod = VirtualMethod_First,
-      /// A method call using super method dispatch.
-      SuperMethod,
-    VirtualMethod_Last = SuperMethod,
+    /// A method call using class method dispatch.
+    ClassMethod,
 
-    GenericMethod_First,
-      /// A method call using archetype dispatch.
-      WitnessMethod = GenericMethod_First,
-      /// A method call using dynamic lookup.
-      DynamicMethod,
-    GenericMethod_Last = DynamicMethod
+    /// A method call using super method dispatch.
+    SuperMethod,
+
+    /// A method call using protocol witness table dispatch.
+    WitnessMethod,
+
+    /// A method call using dynamic lookup.
+    DynamicMethod,
   };
 
   const Kind kind;
@@ -391,14 +389,11 @@
     return Callee(Kind::SuperMethod, SGF, std::move(selfValue), c,
                   ci.FormalPattern, ci.FormalType, subs, l);
   }
-  static Callee forArchetype(SILGenFunction &SGF,
-                             CanType protocolSelfType,
-                             SILDeclRef c,
-                             SubstitutionList subs,
-                             SILLocation l) {
-    auto *protocol = cast<ProtocolDecl>(c.getDecl()->getDeclContext());
-    c = c.asForeign(protocol->isObjC());
-
+  static Callee forWitnessMethod(SILGenFunction &SGF,
+                                 CanType protocolSelfType,
+                                 SILDeclRef c,
+                                 SubstitutionList subs,
+                                 SILLocation l) {
     auto &ci = SGF.getConstantInfo(c);
     return Callee(Kind::WitnessMethod, SGF, None, c, ci.FormalPattern,
                   ci.FormalType, subs, l);
@@ -642,7 +637,7 @@
       Scope S(SGF, Loc);
       ManagedValue self =
           SelfValue.getValue().borrow(SGF).getAsSingleValue(SGF);
-      SILValue fn = SGF.B.createDynamicMethod(
+      SILValue fn = SGF.B.createObjCMethod(
           Loc, self.getValue(), *constant,
           SILType::getPrimitiveObjectType(closureType));
       return ManagedValue::forUnmanaged(fn);
@@ -958,11 +953,13 @@
       }
     }
 
-    SILDeclRef constant = SILDeclRef(afd, kind);
+    SILDeclRef constant(afd, kind);
+    constant = constant.asForeign(afd->isObjC());
 
     // Prepare the callee.  This can modify both selfValue and subs.
-    Callee theCallee = Callee::forArchetype(SGF, selfValue.getSubstRValueType(),
-                                            constant, subs, e);
+    Callee theCallee = Callee::forWitnessMethod(
+        SGF, selfValue.getSubstRValueType(),
+        constant, subs, e);
     assumedPlusZeroSelf =
         selfValue.isRValue() &&
         selfValue.forceAndPeekRValue(SGF).peekIsPlusZeroRValueOrTrivial();
@@ -1403,47 +1400,35 @@
     auto subs = ctorRef->getDeclRef().getSubstitutions();
     ArgumentSource selfArgSource(arg, RValue(SGF, expr, selfFormalType, self));
 
+    SILDeclRef constant(ctorRef->getDecl(),
+                        useAllocatingCtor
+                         ? SILDeclRef::Kind::Allocator
+                         : SILDeclRef::Kind::Initializer);
+
+    constant = constant.asForeign(requiresForeignEntryPoint(ctorRef->getDecl()));
+
     // Determine the callee. For structs and enums, this is the allocating
     // constructor (because there is no initializing constructor). For protocol
     // default implementations, we also use the allocating constructor, because
     // that's the only thing that's witnessed. For classes,
     // this is the initializing constructor, to which we will dynamically
     // dispatch.
-    if (selfArgSource.getSubstRValueType()
-            ->getRValueInstanceType()
-            ->is<ArchetypeType>() &&
-        isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
+    if (isa<ProtocolDecl>(ctorRef->getDecl()->getDeclContext())) {
       // Look up the witness for the constructor.
-      auto constant = SILDeclRef(ctorRef->getDecl(),
-                             useAllocatingCtor
-                               ? SILDeclRef::Kind::Allocator
-                               : SILDeclRef::Kind::Initializer);
-      setCallee(Callee::forArchetype(SGF,
-                                     self.getType().getSwiftRValueType(),
-                                     constant, subs, expr));
+      setCallee(Callee::forWitnessMethod(
+          SGF, self.getType().getSwiftRValueType(),
+          constant, subs, expr));
     } else if (getMethodDispatch(ctorRef->getDecl())
                  == MethodDispatch::Class) {
       // Dynamic dispatch to the initializer.
       Scope S(SGF, expr);
       setCallee(Callee::forClassMethod(
           SGF, selfArgSource.delayedBorrow(SGF),
-          SILDeclRef(ctorRef->getDecl(),
-                     useAllocatingCtor ? SILDeclRef::Kind::Allocator
-                                       : SILDeclRef::Kind::Initializer)
-              .asForeign(requiresForeignEntryPoint(ctorRef->getDecl())),
-          subs, fn));
+          constant, subs, fn));
     } else {
       // Directly call the peer constructor.
       setCallee(
-        Callee::forDirect(
-          SGF,
-          SILDeclRef(ctorRef->getDecl(),
-                     useAllocatingCtor
-                       ? SILDeclRef::Kind::Allocator
-                     : SILDeclRef::Kind::Initializer)
-            .asForeign(requiresForeignEntryPoint(ctorRef->getDecl())),
-          subs,
-          fn));
+        Callee::forDirect(SGF, constant, subs, fn));
     }
 
     setSelfParam(std::move(selfArgSource), expr);
@@ -4797,9 +4782,9 @@
   // Form the callee.
   Optional<Callee> callee;
   if (isa<ProtocolDecl>(ctor->getDeclContext())) {
-    callee.emplace(Callee::forArchetype(SGF,
-                                        selfMetaVal.getType().getSwiftRValueType(),
-                                        initRef, subs, loc));
+    callee.emplace(Callee::forWitnessMethod(
+        SGF, selfMetaVal.getType().getSwiftRValueType(),
+        initRef, subs, loc));
   } else {
     callee.emplace(Callee::forDirect(SGF, initRef, subs, loc));
   }
@@ -5021,9 +5006,9 @@
     assert(!isDirectUse && "direct use of protocol accessor?");
     assert(!isSuper && "super call to protocol method?");
 
-    return Callee::forArchetype(SGF,
-                                selfValue.getSubstRValueType(),
-                                constant, subs, loc);
+    return Callee::forWitnessMethod(
+        SGF, selfValue.getSubstRValueType(),
+        constant, subs, loc);
   }
 
   bool isClassDispatch = false;
@@ -5278,6 +5263,10 @@
 
 static bool shouldReferenceForeignAccessor(AbstractStorageDecl *storage,
                                            bool isDirectUse) {
+  // Members of Objective-C protocols should be dynamically dispatched.
+  if (auto *protoDecl = dyn_cast<ProtocolDecl>(storage->getDeclContext()))
+    return protoDecl->isObjC();
+
   // C functions imported as members should be referenced as C functions.
   if (storage->getGetter()->isImportAsMember())
     return true;
diff --git a/lib/SILGen/SILGenGlobalVariable.cpp b/lib/SILGen/SILGenGlobalVariable.cpp
index fce4b4a..eb1f9ae 100644
--- a/lib/SILGen/SILGenGlobalVariable.cpp
+++ b/lib/SILGen/SILGenGlobalVariable.cpp
@@ -46,10 +46,7 @@
   SILLinkage link = getSILLinkage(getDeclLinkage(gDecl), forDef);
   SILType silTy = M.Types.getLoweredTypeOfGlobal(gDecl);
 
-  auto *silGlobal = SILGlobalVariable::create(M, link,
-                                              isMakeModuleFragile()
-                                                ? IsSerialized
-                                                : IsNotSerialized,
+  auto *silGlobal = SILGlobalVariable::create(M, link, IsNotSerialized,
                                               mangledName, silTy,
                                               None, gDecl);
   silGlobal->setDeclaration(!forDef);
@@ -223,9 +220,7 @@
   // TODO: include the module in the onceToken's name mangling.
   // Then we can make it fragile.
   auto onceToken = SILGlobalVariable::create(M, SILLinkage::Private,
-                                             isMakeModuleFragile()
-                                               ? IsSerialized
-                                               : IsNotSerialized,
+                                             IsNotSerialized,
                                              onceTokenBuffer, onceSILTy);
   onceToken->setDeclaration(false);
 
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index 936dafd..0e3e92c 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -374,11 +374,6 @@
 
     Serialized = IsNotSerialized;
 
-    // Serialize the witness table if we're serializing everything with
-    // -sil-serialize-all....
-    if (SGM.isMakeModuleFragile())
-      Serialized = IsSerialized;
-
     // ... or if the conformance itself thinks it should be.
     if (SILWitnessTable::conformanceIsSerialized(
             Conformance, SGM.M.getSwiftModule()->getResilienceStrategy(),
@@ -482,9 +477,7 @@
     if (witnessSerialized &&
         fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage)) {
       witnessLinkage = SILLinkage::Public;
-      witnessSerialized = (SGM.isMakeModuleFragile()
-                           ? IsSerialized
-                           : IsNotSerialized);
+      witnessSerialized = IsNotSerialized;
     } else {
       // This is the "real" rule; the above case should go away once we
       // figure out what's going on.
@@ -611,62 +604,30 @@
                                   Witness witness) {
   auto requirementInfo = Types.getConstantInfo(requirement);
 
-  GenericEnvironment *genericEnv = nullptr;
-
   // Work out the lowered function type of the SIL witness thunk.
   auto reqtOrigTy = cast<GenericFunctionType>(requirementInfo.LoweredType);
+
+  // Mapping from the requirement's generic signature to the witness
+  // thunk's generic signature.
+  auto reqtSubs = witness.getRequirementToSyntheticSubs();
+  auto reqtSubMap = reqtOrigTy->getGenericSignature()->getSubstitutionMap(reqtSubs);
+
+  // The generic environment for the witness thunk.
+  auto *genericEnv = witness.getSyntheticEnvironment();
+
+  // The type of the witness thunk.
+  auto input = reqtOrigTy->getInput().subst(reqtSubMap)->getCanonicalType();
+  auto result = reqtOrigTy->getResult().subst(reqtSubMap)->getCanonicalType();
+
   CanAnyFunctionType reqtSubstTy;
-  SubstitutionList witnessSubs;
-  if (witness.requiresSubstitution()) {
-    genericEnv = witness.getSyntheticEnvironment();
-    witnessSubs = witness.getSubstitutions();
-
-    auto reqtSubs = witness.getRequirementToSyntheticSubs();
-    auto reqtSubMap = reqtOrigTy->getGenericSignature()
-        ->getSubstitutionMap(reqtSubs);
-    auto input = reqtOrigTy->getInput().subst(reqtSubMap);
-    auto result = reqtOrigTy->getResult().subst(reqtSubMap);
-
-    if (genericEnv) {
-      auto *genericSig = genericEnv->getGenericSignature();
-      reqtSubstTy = cast<GenericFunctionType>(
-        GenericFunctionType::get(genericSig, input, result,
-                                 reqtOrigTy->getExtInfo())
-          ->getCanonicalType());
-    } else {
-      reqtSubstTy = cast<FunctionType>(
-        FunctionType::get(input, result,
-                          reqtOrigTy->getExtInfo())
-          ->getCanonicalType());
-    }
+  if (genericEnv) {
+    auto *genericSig = genericEnv->getGenericSignature();
+    reqtSubstTy = CanGenericFunctionType::get(
+        genericSig->getCanonicalSignature(),
+        input, result, reqtOrigTy->getExtInfo());
   } else {
-    genericEnv = witnessRef.getDecl()->getInnermostDeclContext()
-                   ->getGenericEnvironmentOfContext();
-
-    auto conformanceDC = conformance->getDeclContext();
-    Type concreteTy = conformanceDC->getSelfInterfaceType();
-
-    // FIXME: conformance substitutions should be in terms of interface types
-    auto specialized = conformance;
-    if (conformance->getGenericSignature()) {
-      ASTContext &ctx = getASTContext();
-
-      auto concreteSubs = concreteTy->getContextSubstitutionMap(
-          M.getSwiftModule(),
-          conformance->getDeclContext());
-      specialized = ctx.getSpecializedConformance(concreteTy, conformance,
-                                                  concreteSubs);
-    }
-
-    auto reqtSubs = SubstitutionMap::getProtocolSubstitutions(
-        conformance->getProtocol(),
-        concreteTy,
-        ProtocolConformanceRef(specialized));
-
-    auto input = reqtOrigTy->getInput().subst(reqtSubs)->getCanonicalType();
-    auto result = reqtOrigTy->getResult().subst(reqtSubs)->getCanonicalType();
-
-    reqtSubstTy = CanFunctionType::get(input, result, reqtOrigTy->getExtInfo());
+    reqtSubstTy = CanFunctionType::get(
+        input, result, reqtOrigTy->getExtInfo());
   }
 
   // Lower the witness thunk type with the requirement's abstraction level.
@@ -678,7 +639,7 @@
   Mangle::ASTMangler NewMangler;
   std::string nameBuffer = NewMangler.mangleWitnessThunk(conformance,
                                                          requirement.getDecl());
-  
+
   // If the thunked-to function is set to be always inlined, do the
   // same with the witness, on the theory that the user wants all
   // calls removed if possible, e.g. when we're able to devirtualize
@@ -705,21 +666,18 @@
 
   // If the witness is a free function, there is no Self type.
   if (!isFree) {
-    if (conformance) {
-      auto conformanceDC = conformance->getDeclContext();
-      selfInterfaceType =
-        conformanceDC->mapTypeOutOfContext(conformance->getType());
-    } else {
-      auto *proto = cast<ProtocolDecl>(requirement.getDecl()->getDeclContext());
-      selfInterfaceType = proto->getSelfInterfaceType();
-    }
-
+    auto *proto = cast<ProtocolDecl>(requirement.getDecl()->getDeclContext());
+    selfInterfaceType = proto->getSelfInterfaceType().subst(reqtSubMap);
     selfType = GenericEnvironment::mapTypeIntoContext(
         genericEnv, selfInterfaceType);
   }
 
   SILGenFunction SGF(*this, *f);
 
+  // Substitutions mapping the generic parameters of the witness to
+  // archetypes of the witness thunk generic environment.
+  auto witnessSubs = witness.getSubstitutions();
+
   // Open-code certain protocol witness "thunks".
   if (maybeOpenCodeProtocolWitness(SGF, conformance, linkage,
                                    selfInterfaceType, selfType, genericEnv,
diff --git a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp
index 0f116f1..1558aab 100644
--- a/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp
@@ -134,9 +134,22 @@
 
     TheCallees.getPointer()->push_back(WitnessFn);
 
-    // FIXME: For now, conservatively assume that unknown functions
-    //        can be called from any witness_method call site.
-    TheCallees.setInt(true);
+    // If we can't resolve the witness, conservatively assume it can call
+    // anything.
+    if (!Requirement.getDecl()->isProtocolRequirement() ||
+        !WT.getConformance()->hasWitness(Requirement.getDecl())) {
+      TheCallees.setInt(true);
+      continue;
+    }
+
+    auto Witness = WT.getConformance()->getWitness(Requirement.getDecl(),
+                                                   nullptr);
+    auto DeclRef = SILDeclRef(Witness.getDecl());
+
+    bool canCallUnknown = !calleesAreStaticallyKnowable(M, DeclRef);
+
+    if (canCallUnknown)
+      TheCallees.setInt(true);
   }
 }
 
@@ -221,7 +234,6 @@
     return getCalleeList(cast<ClassMethodInst>(Callee));
 
   case ValueKind::SuperMethodInst:
-  case ValueKind::DynamicMethodInst:
   case ValueKind::ObjCMethodInst:
   case ValueKind::ObjCSuperMethodInst:
     return CalleeList();
diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
index 6aa23ab..2e8c5e6 100644
--- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
@@ -70,7 +70,6 @@
   case SILNodeKind::SuperMethodInst:
   case SILNodeKind::ObjCMethodInst:
   case SILNodeKind::ObjCSuperMethodInst:
-  case SILNodeKind::DynamicMethodInst:
   case SILNodeKind::StringLiteralInst:
   case SILNodeKind::ThinToThickFunctionInst:
   case SILNodeKind::ThinFunctionToPointerInst:
diff --git a/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp b/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp
index cfbf2eb..97561a0 100644
--- a/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp
+++ b/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp
@@ -167,9 +167,9 @@
   return SILValue();
 }
 
-// Simplify
-//   %1 = unchecked_enum_data %0 : $Optional<C>, #Optional.Some!enumelt.1 // user: %27
-//   %2 = enum $Optional<C>, #Optional.Some!enumelt.1, %1 : $C // user: %28
+// Simplify:
+//   %1 = unchecked_enum_data %0 : $Optional<C>, #Optional.Some!enumelt.1
+//   %2 = enum $Optional<C>, #Optional.Some!enumelt.1, %1 : $C
 // to %0 since we are building the same enum.
 static SILValue simplifyEnumFromUncheckedEnumData(EnumInst *EI) {
   assert(EI->hasOperand() && "Expected an enum with an operand!");
diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp
index 3dde555..3a38963 100644
--- a/lib/SILOptimizer/Utils/Devirtualize.cpp
+++ b/lib/SILOptimizer/Utils/Devirtualize.cpp
@@ -712,7 +712,8 @@
 //===----------------------------------------------------------------------===//
 
 static SubstitutionMap
-getSubstitutionsForProtocolConformance(ProtocolConformanceRef CRef) {
+getSubstitutionsForProtocolConformance(ModuleDecl *M,
+                                       ProtocolConformanceRef CRef) {
   auto C = CRef.getConcrete();
 
   // Walk down to the base NormalProtocolConformance.
@@ -746,8 +747,7 @@
 
   if (Subs.empty()) {
     auto *DC = NormalC->getDeclContext();
-    return NormalC->getType()
-      ->getContextSubstitutionMap(DC->getParentModule(), DC);
+    return NormalC->getType()->getContextSubstitutionMap(M, DC);
   }
 
   return NormalC->getGenericSignature()->getSubstitutionMap(Subs);
@@ -764,17 +764,50 @@
 /// are written in terms of the requirement's generic signature need
 /// to be remapped to substitutions suitable for the witness signature.
 ///
+/// Supported remappings are:
+///
+/// - (Concrete witness thunk) Original substitutions:
+///   [Self := ConcreteType, R0 := X0, R1 := X1, ...]
+/// - Requirement generic signature:
+///   <Self : P, R0, R1, ...>
+/// - Witness thunk generic signature:
+///   <W0, W1, ...>
+/// - Remapped substitutions:
+///   [W0 := X0, W1 := X1, ...]
+///
+/// - (Class witness thunk) Original substitutions:
+///   [Self := C<A0, A1>, T0 := X0, T1 := X1, ...]
+/// - Requirement generic signature:
+///   <Self : P, R0, R1, ...>
+/// - Witness thunk generic signature:
+///   <Self : C<B0, B1>, B0, B1, W0, W1, ...>
+/// - Remapped substitutions:
+///   [Self := C<B0, B1>, B0 := A0, B1 := A1, W0 := X0, W1 := X1]
+///
+/// - (Default witness thunk) Original substitutions:
+///   [Self := ConcreteType, R0 := X0, R1 := X1, ...]
+/// - Requirement generic signature:
+///   <Self : P, R0, R1, ...>
+/// - Witness thunk generic signature:
+///   <Self : P, W0, W1, ...>
+/// - Remapped substitutions:
+///   [Self := ConcreteType, W0 := X0, W1 := X1, ...]
+///
 /// \param conformanceRef The (possibly-specialized) conformance
 /// \param requirementSig The generic signature of the requirement
 /// \param witnessThunkSig The generic signature of the witness method
 /// \param origSubs The substitutions from the call instruction
+/// \param isDefaultWitness True if this is a default witness method
+/// \param classWitness The ClassDecl if this is a class witness method
 static SubstitutionMap
 getWitnessMethodSubstitutions(
+    ModuleDecl *mod,
     ProtocolConformanceRef conformanceRef,
     GenericSignature *requirementSig,
     GenericSignature *witnessThunkSig,
     SubstitutionList origSubs,
-    bool isDefaultWitness) {
+    bool isDefaultWitness,
+    ClassDecl *classWitness) {
 
   if (witnessThunkSig == nullptr)
     return SubstitutionMap();
@@ -789,42 +822,67 @@
 
   // If `Self` maps to a bound generic type, this gives us the
   // substitutions for the concrete type's generic parameters.
-  auto baseSubMap = getSubstitutionsForProtocolConformance(conformanceRef);
+  auto baseSubMap = getSubstitutionsForProtocolConformance(mod, conformanceRef);
 
   unsigned baseDepth = 0;
   auto *rootConformance = conformance->getRootNormalConformance();
   if (auto *witnessSig = rootConformance->getGenericSignature())
     baseDepth = witnessSig->getGenericParams().back()->getDepth() + 1;
 
-  auto origDepth = 1;
+  // If the witness has a class-constrained 'Self' generic parameter,
+  // we have to build a new substitution map that shifts all generic
+  // parameters down by one.
+  if (classWitness != nullptr) {
+    auto *proto = conformance->getProtocol();
+    auto selfType = proto->getSelfInterfaceType();
+
+    auto selfSubMap = SubstitutionMap::getProtocolSubstitutions(
+        proto, selfType.subst(origSubMap), conformanceRef);
+    if (baseSubMap.empty()) {
+      assert(baseDepth == 0);
+      baseSubMap = selfSubMap;
+    } else {
+      baseSubMap = SubstitutionMap::combineSubstitutionMaps(
+          selfSubMap,
+          baseSubMap,
+          CombineSubstitutionMaps::AtDepth,
+          /*firstDepth=*/1,
+          /*secondDepth=*/0,
+          witnessThunkSig);
+    }
+    baseDepth += 1;
+  }
 
   return SubstitutionMap::combineSubstitutionMaps(
       baseSubMap,
       origSubMap,
       CombineSubstitutionMaps::AtDepth,
-      baseDepth,
-      origDepth,
+      /*firstDepth=*/baseDepth,
+      /*secondDepth=*/1,
       witnessThunkSig);
 }
 
 static SubstitutionMap
 getWitnessMethodSubstitutions(SILModule &Module, ApplySite AI, SILFunction *F,
                               ProtocolConformanceRef CRef) {
+  auto witnessFnTy = F->getLoweredFunctionType();
+  assert(witnessFnTy->getRepresentation() ==
+         SILFunctionTypeRepresentation::WitnessMethod);
+
   auto requirementSig = AI.getOrigCalleeType()->getGenericSignature();
-  auto witnessThunkSig = F->getLoweredFunctionType()->getGenericSignature();
+  auto witnessThunkSig = witnessFnTy->getGenericSignature();
 
   SubstitutionList origSubs = AI.getSubstitutions();
 
+  auto *mod = Module.getSwiftModule();
   bool isDefaultWitness =
-    F->getLoweredFunctionType()->getRepresentation()
-      == SILFunctionTypeRepresentation::WitnessMethod &&
-    F->getLoweredFunctionType()->getDefaultWitnessMethodProtocol(
-                                                     *Module.getSwiftModule())
-      == CRef.getRequirement();
+    (witnessFnTy->getDefaultWitnessMethodProtocol(*mod)
+      == CRef.getRequirement());
+  auto *classWitness = witnessFnTy->getWitnessMethodClass(*mod);
 
   return getWitnessMethodSubstitutions(
-      CRef, requirementSig, witnessThunkSig,
-      origSubs, isDefaultWitness);
+      mod, CRef, requirementSig, witnessThunkSig,
+      origSubs, isDefaultWitness, classWitness);
 }
 
 /// Generate a new apply of a function_ref to replace an apply of a
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index c815ac3..5740641 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -854,7 +854,7 @@
                                             GenericSignature *Sig,
                                             GenericEnvironment *Env) {
   auto Reqs = Sig->getRequirements();
-  auto CurrentGP = Env->mapTypeOutOfContext(Archetype)
+  auto CurrentGP = Archetype->getInterfaceType()
                        ->getCanonicalType()
                        ->getRootGenericParam();
   for (auto Req : Reqs) {
@@ -897,7 +897,7 @@
                                 GenericEnvironment *Env,
                                 SmallVectorImpl<Requirement> &CollectedReqs) {
   auto Reqs = Sig->getRequirements();
-  auto CurrentGP = Env->mapTypeOutOfContext(Archetype)
+  auto CurrentGP = Archetype->getInterfaceType()
                        ->getCanonicalType()
                        ->getRootGenericParam();
   CollectedReqs.clear();
@@ -1304,8 +1304,7 @@
 void FunctionSignaturePartialSpecializer::
     createGenericParamsForUsedCallerArchetypes() {
   for (auto CallerArchetype : UsedCallerArchetypes) {
-    auto CallerGenericParam =
-        CallerGenericEnv->mapTypeOutOfContext(CallerArchetype);
+    auto CallerGenericParam = CallerArchetype->getInterfaceType();
     assert(CallerGenericParam->is<GenericTypeParamType>());
 
     DEBUG(llvm::dbgs() << "\n\nChecking used caller archetype:\n";
diff --git a/lib/SILOptimizer/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp
index ebda886..6d897d4 100644
--- a/lib/SILOptimizer/Utils/SILInliner.cpp
+++ b/lib/SILOptimizer/Utils/SILInliner.cpp
@@ -384,7 +384,6 @@
   case SILInstructionKind::AutoreleaseValueInst:
   case SILInstructionKind::UnmanagedAutoreleaseValueInst:
   case SILInstructionKind::DynamicMethodBranchInst:
-  case SILInstructionKind::DynamicMethodInst:
   case SILInstructionKind::EnumInst:
   case SILInstructionKind::IndexAddrInst:
   case SILInstructionKind::TailAddrInst:
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index cb440be..bbae4f6 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -4071,9 +4071,14 @@
           
           auto dc = subscript->getInnermostDeclContext();
           SmallVector<Substitution, 4> subs;
+          SubstitutionMap subMap;
+          auto indexType = subscript->getIndicesInterfaceType();
+
           if (auto sig = dc->getGenericSignatureOfContext()) {
             // Compute substitutions to refer to the member.
             solution.computeSubstitutions(sig, locator, subs);
+            subMap = sig->getSubstitutionMap(subs);
+            indexType = indexType.subst(subMap);
           }
           
           auto resolvedTy = foundDecl->openedType->castTo<AnyFunctionType>()
@@ -4082,9 +4087,13 @@
           
           auto ref = ConcreteDeclRef(cs.getASTContext(), subscript, subs);
           
+          // Coerce the indices to the type the subscript expects.
+          auto indexExpr = coerceToType(origComponent.getIndexExpr(),
+                                        indexType,
+                                        locator);
+          
           component = KeyPathExpr::Component
-            ::forSubscriptWithPrebuiltIndexExpr(ref,
-                                            origComponent.getIndexExpr(),
+            ::forSubscriptWithPrebuiltIndexExpr(ref, indexExpr,
                                             origComponent.getSubscriptLabels(),
                                             resolvedTy,
                                             origComponent.getLoc(),
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index f1e0cd5..ca2c57d 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -1879,8 +1879,7 @@
     return false;
 
   auto getGenericTypeDecl = [&](ArchetypeType *archetype) -> ValueDecl * {
-    auto *env = archetype->getGenericEnvironment();
-    auto paramType = env->mapTypeOutOfContext(archetype);
+    auto paramType = archetype->getInterfaceType();
 
     if (auto *GTPT = paramType->getAs<GenericTypeParamType>())
       return GTPT->getDecl();
@@ -6121,8 +6120,7 @@
         return false;
 
       // Record substitution from generic parameter to the argument type.
-      substitutions[env->mapTypeOutOfContext(archetype)
-                        ->getCanonicalType()
+      substitutions[archetype->getInterfaceType()->getCanonicalType()
                         ->castTo<SubstitutableType>()] = argType;
     }
   }
@@ -8998,7 +8996,7 @@
   if (!genericEnv)
     return false;
 
-  return genericEnv->containsPrimaryArchetype(archetype);
+  return archetype->getGenericEnvironment() == genericEnv;
 }
 
 static void noteArchetypeSource(const TypeLoc &loc, ArchetypeType *archetype,
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 6487731..54a8af8 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1037,20 +1037,10 @@
   // Match up the call arguments to the parameters.
   MatchCallArgumentListener listener;
   SmallVector<ParamBinding, 4> parameterBindings;
-  if (constraints::matchCallArguments(type2, type1, defaultMap,
-                                      hasTrailingClosure,
-                                      /*allowFixes=*/false,
-                                      listener,
-                                      parameterBindings)) {
-    // FIXME: Sometimes we get asked to bind type variables to parameters.
-    // We should not be asked to bind type variables to parameters.
-    if (type2.size() == 1 && type2[0].getType()->isTypeVariableOrMember()) {
-      return matchTypes(argType, type2[0].getType(),
-                        ConstraintKind::BindParam,
-                        subflags, locator);
-    }
+  if (constraints::matchCallArguments(
+          type2, type1, defaultMap, hasTrailingClosure,
+          /*allowFixes=*/false, listener, parameterBindings))
     return SolutionKind::Error;
-  }
   
   // Compare each of the bound arguments for this parameter.
   for (unsigned paramIdx = 0, numParams = parameterBindings.size();
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 2055c66..b29d4f0 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -352,6 +352,14 @@
         failedConstraint = constraint;
       }
 
+      if (TC.getLangOpts().DebugConstraintSolver) {
+        auto &log = getASTContext().TypeCheckerDebug->getStream();
+        log.indent(solverState ? solverState->depth * 2 : 0)
+            << "(failed constraint ";
+        constraint->print(log, &getASTContext().SourceMgr);
+        log << ")\n";
+      }
+
       if (solverState)
         solverState->retireConstraint(constraint);
 
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 24c5854..261ada8 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -2075,7 +2075,7 @@
         classDecl->getGenericEnvironment());
 
     for (auto *decl : *bodyParams) {
-      auto paramTy = decl->getInterfaceType();
+      auto paramTy = decl->getInterfaceType()->getInOutObjectType();
 
       // Apply the superclass substitutions to produce a contextual
       // type in terms of the derived class archetypes.
@@ -2089,7 +2089,9 @@
   } else {
     for (auto *decl : *bodyParams) {
       if (!decl->hasType())
-        decl->setType(classDecl->mapTypeIntoContext(decl->getInterfaceType()));
+        decl->setType(
+          classDecl->mapTypeIntoContext(
+            decl->getInterfaceType()->getInOutObjectType()));
     }
   }
 
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index f3438d3..d7513ca 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -2006,6 +2006,10 @@
 }
 
 void TypeChecker::checkOwnershipAttr(VarDecl *var, OwnershipAttr *attr) {
+  // Don't check ownership attribute if the declaration is already marked invalid.
+  if (var->isInvalid())
+    return;
+
   Type type = var->getType();
   Type interfaceType = var->getInterfaceType();
 
@@ -2053,6 +2057,20 @@
 
     diagnose(var->getStartLoc(), D, (unsigned) ownershipKind, underlyingType);
     attr->setInvalid();
+  } else if (dyn_cast<ProtocolDecl>(var->getDeclContext())) {
+    // Ownership does not make sense in protocols.
+    if (Context.isSwiftVersionAtLeast(5))
+      diagnose(attr->getLocation(),
+        diag::ownership_invalid_in_protocols,
+        (unsigned) ownershipKind)
+        .fixItRemove(attr->getRange());
+    else
+      diagnose(attr->getLocation(),
+        diag::ownership_invalid_in_protocols_compat_warning,
+        (unsigned) ownershipKind)
+        .fixItRemove(attr->getRange());
+
+    attr->setInvalid();
   }
 
   if (attr->isInvalid())
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 4e3d9e1..c16b5e7 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -255,14 +255,12 @@
                          options, resolver);
   }
 
-  for (auto member : protocol->getMembers()) {
-    if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
-      if (auto whereClause = assocType->getTrailingWhereClause()) {
-        revertGenericRequirements(whereClause->getRequirements());
-        validateRequirements(whereClause->getWhereLoc(),
-                             whereClause->getRequirements(),
-                             protocol, options, resolver);
-      }
+  for (auto assocType : protocol->getAssociatedTypeMembers()) {
+    if (auto whereClause = assocType->getTrailingWhereClause()) {
+      revertGenericRequirements(whereClause->getRequirements());
+      validateRequirements(whereClause->getWhereLoc(),
+                           whereClause->getRequirements(),
+                           protocol, options, resolver);
     }
   }
 }
@@ -3251,10 +3249,7 @@
   // First, satisfy any associated type requirements.
   Substitution valueSub;
   AssociatedTypeDecl *valueReqt = nullptr;
-  for (auto requirementDecl : behaviorProto->getMembers()) {
-    auto assocTy = dyn_cast<AssociatedTypeDecl>(requirementDecl);
-    if (!assocTy)
-      continue;
+  for (auto assocTy : behaviorProto->getAssociatedTypeMembers()) {
   
     // Match a Value associated type requirement to the property type.
     if (assocTy->getName() != TC.Context.Id_Value) {
@@ -7711,10 +7706,8 @@
     // Record inherited protocols.
     resolveInheritedProtocols(proto);
 
-    for (auto member : proto->getMembers()) {
-      if (auto ATD = dyn_cast<AssociatedTypeDecl>(member)) {
-        validateDeclForNameLookup(ATD);
-      }
+    for (auto ATD : proto->getAssociatedTypeMembers()) {
+      validateDeclForNameLookup(ATD);
     }
 
     // Make sure the protocol is fully validated by the end of Sema.
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 7423c6c..21e9a12 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -873,8 +873,12 @@
 
     // 'throws' only applies to the innermost function.
     AnyFunctionType::ExtInfo info;
-    if (i == 0 && func->hasThrows())
-      info = info.withThrows();
+    if (i == 0) {
+      info = info.withThrows(func->hasThrows());
+      // Defer bodies must not escape.
+      if (auto fd = dyn_cast<FuncDecl>(func))
+        info = info.withNoEscape(fd->isDeferBody());
+    }
     
     assert(std::all_of(argTy.begin(), argTy.end(), [](const AnyFunctionType::Param &aty){
       return !aty.getType()->hasArchetype();
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 840ca2d..6bc8396 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -124,14 +124,18 @@
     /// \param conformanceDC The \c DeclContext to which the protocol
     /// conformance is ascribed, which provides additional constraints.
     ///
-    /// \param req The requirement for which we are creating a generic
-    /// environment.
+    /// \param reqSig The generic signature of the requirement for which we
+    /// are creating a generic environment.
+    ///
+    /// \param proto The protocol containing the requirement.
     ///
     /// \param conformance The protocol conformance, or null if there is no
     /// conformance (because we're finding default implementations).
     RequirementEnvironment(TypeChecker &tc,
                            DeclContext *conformanceDC,
-                           ValueDecl *req,
+                           GenericSignature *reqSig,
+                           ProtocolDecl *proto,
+                           ClassDecl *covariantSelf,
                            ProtocolConformance *conformance);
 
     /// Retrieve the synthetic generic environment.
@@ -195,7 +199,6 @@
     bool findBestWitness(ValueDecl *requirement,
                          bool *ignoringNames,
                          NormalProtocolConformance *conformance,
-                         const RequirementEnvironment &reqEnvironment,
                          SmallVectorImpl<RequirementMatch> &matches,
                          unsigned &numViable,
                          unsigned &bestIdx,
@@ -212,7 +215,7 @@
 
     RequirementCheck checkWitness(AccessScope requiredAccessScope,
                                   ValueDecl *requirement,
-                                  RequirementMatch match);
+                                  const RequirementMatch &match);
   };
 
   /// \brief The result of matching a particular declaration to a given
@@ -412,15 +415,18 @@
 
   /// \brief Describes a match between a requirement and a witness.
   struct RequirementMatch {
-    RequirementMatch(ValueDecl *witness, MatchKind kind)
-      : Witness(witness), Kind(kind), WitnessType() {
+    RequirementMatch(ValueDecl *witness, MatchKind kind,
+                     Optional<RequirementEnvironment> &&env = None)
+      : Witness(witness), Kind(kind), WitnessType(), ReqEnv(std::move(env)) {
       assert(!hasWitnessType() && "Should have witness type");
     }
 
     RequirementMatch(ValueDecl *witness, MatchKind kind,
                      Type witnessType,
+                     Optional<RequirementEnvironment> &&env = None,
                      ArrayRef<OptionalAdjustment> optionalAdjustments = {})
       : Witness(witness), Kind(kind), WitnessType(witnessType),
+        ReqEnv(std::move(env)),
         OptionalAdjustments(optionalAdjustments.begin(),
                             optionalAdjustments.end())
     {
@@ -437,6 +443,9 @@
     /// \brief The type of the witness when it is referenced.
     Type WitnessType;
 
+    /// \brief The requirement environment to use for the witness thunk.
+    Optional<RequirementEnvironment> ReqEnv;
+
     /// The set of optional adjustments performed on the witness.
     SmallVector<OptionalAdjustment, 2> OptionalAdjustments;
 
@@ -496,51 +505,15 @@
 
     SmallVector<Substitution, 2> WitnessSubstitutions;
 
-    swift::Witness getWitness(ASTContext &ctx,
-                              RequirementEnvironment &&reqEnvironment) const {
+    swift::Witness getWitness(ASTContext &ctx) const {
       SmallVector<Substitution, 2> syntheticSubs;
-      auto syntheticEnv = reqEnvironment.getSyntheticEnvironment();
-      reqEnvironment.getRequirementSignature()->getSubstitutions(
-          reqEnvironment.getRequirementToSyntheticMap(),
+      auto syntheticEnv = ReqEnv->getSyntheticEnvironment();
+      ReqEnv->getRequirementSignature()->getSubstitutions(
+          ReqEnv->getRequirementToSyntheticMap(),
           syntheticSubs);
       return swift::Witness(this->Witness, WitnessSubstitutions,
                             syntheticEnv, syntheticSubs);
     }
-
-    /// Classify the provided optionality issues for use in diagnostics.
-    /// FIXME: Enumify this
-    unsigned classifyOptionalityIssues(ValueDecl *requirement) const {
-      unsigned numParameterAdjustments = 0;
-      bool hasNonParameterAdjustment = false;
-      for (const auto &adjustment : OptionalAdjustments) {
-        if (adjustment.isParameterAdjustment())
-          ++numParameterAdjustments;
-        else
-          hasNonParameterAdjustment = true;
-      }
-
-      if (hasNonParameterAdjustment) {
-        // Both return and parameter adjustments.
-        if (numParameterAdjustments > 0)
-          return 4;
-
-        // The type of a variable.
-        if (isa<VarDecl>(requirement))
-          return 0;
-
-        // The result type of something.
-        return 1;
-      }
-
-      // Only parameter adjustments.
-      assert(numParameterAdjustments > 0 && "No adjustments?");
-      return numParameterAdjustments == 1 ? 2 : 3;
-    }
-
-    /// Add Fix-Its that correct the optionality in the witness.
-    void addOptionalityFixIts(const ASTContext &ctx,
-                              ValueDecl *witness, 
-                              InFlightDiagnostic &diag) const;
   };
 
   /// \brief Describes the suitability of the chosen witness for
@@ -949,7 +922,7 @@
     Optional<RequirementMatch> result;
     std::tie(result, reqType, witnessType) = setup();
     if (result) {
-      return *result;
+      return std::move(result.getValue());
     }
   }
 
@@ -977,7 +950,7 @@
 
       if (auto result = matchTypes(std::get<0>(types), 
                                    std::get<1>(types))) {
-        return *result;
+        return std::move(result.getValue());
       }
     }
 
@@ -1001,7 +974,10 @@
 
       if (reqParams[i].isShared() != witnessParams[i].isShared())
         return RequirementMatch(witness, MatchKind::TypeConflict, witnessType);
-      
+
+      if (reqParams[i].isInOut() != witnessParams[i].isInOut())
+        return RequirementMatch(witness, MatchKind::TypeConflict, witnessType);
+
       // Gross hack: strip a level of unchecked-optionality off both
       // sides when matching against a protocol imported from Objective-C.
       auto types = getTypesToCompare(req, reqParams[i].getType(),
@@ -1017,10 +993,8 @@
       // Check whether the parameter types match.
       if (auto result = matchTypes(std::get<0>(types), 
                                    std::get<1>(types))) {
-        return *result;
+        return std::move(result.getValue());
       }
-
-      // FIXME: Consider default arguments here?
     }
 
     // If the witness is 'throws', the requirement must be.
@@ -1041,7 +1015,7 @@
     }
 
     if (auto result = matchTypes(std::get<0>(types), std::get<1>(types))) {
-      return *result;
+      return std::move(result.getValue());
     }
   }
 
@@ -1052,61 +1026,99 @@
 RequirementEnvironment::RequirementEnvironment(
                                            TypeChecker &tc,
                                            DeclContext *conformanceDC,
-                                           ValueDecl *req,
-                                           ProtocolConformance *conformance) {
-
-  auto reqDC = req->getInnermostDeclContext();
-  reqSig = reqDC->getGenericSignatureOfContext();
-
+                                           GenericSignature *reqSig,
+                                           ProtocolDecl *proto,
+                                           ClassDecl *covariantSelf,
+                                           ProtocolConformance *conformance)
+    : reqSig(reqSig) {
   ASTContext &ctx = tc.Context;
-  auto proto = cast<ProtocolDecl>(req->getDeclContext());
+
+  auto concreteType = conformanceDC->getSelfInterfaceType();
+  auto *conformanceSig = conformanceDC->getGenericSignatureOfContext();
+
+  // Build a substitution map from the generic parameters of the conforming
+  // type to the synthetic environment.
+  //
+  // For structs, enums and protocols, this is a 1:1 mapping; for classes,
+  // we increase the depth of each generic parameter by 1 so that we can
+  // introduce a class-bound 'Self' parameter.
+  auto substConcreteType = concreteType;
+  SubstitutionMap conformanceToSyntheticEnvMap;
+  if (conformanceSig) {
+    conformanceToSyntheticEnvMap = conformanceSig->getSubstitutionMap(
+      [&](SubstitutableType *type) {
+        auto *genericParam = cast<GenericTypeParamType>(type);
+        if (covariantSelf) {
+          return GenericTypeParamType::get(
+              genericParam->getDepth() + 1,
+              genericParam->getIndex(),
+              ctx);
+        }
+
+        return GenericTypeParamType::get(
+            genericParam->getDepth(),
+            genericParam->getIndex(),
+            ctx);
+      },
+      MakeAbstractConformanceForGenericType());
+
+    substConcreteType = concreteType.subst(conformanceToSyntheticEnvMap);
+  }
+
+  // Calculate the depth at which the requirement's generic parameters
+  // appear in the synthetic signature.
+  unsigned depth = 0;
+  if (covariantSelf) {
+    depth++;
+  }
+  if (conformanceSig) {
+    depth += conformanceSig->getGenericParams().back()->getDepth() + 1;
+  }
 
   // Build a substitution map to replace the protocol's \c Self and the type
   // parameters of the requirement into a combined context that provides the
   // type parameters of the conformance context and the parameters of the
   // requirement.
   auto selfType = cast<GenericTypeParamType>(
-                            proto->getSelfInterfaceType()->getCanonicalType());
-
-  // Add the generic signature of the context of the conformance. This includes
-  // the generic parameters from the conforming type as well as any additional
-  // constraints that might occur on the extension that declares the
-  // conformance (i.e., if the conformance is conditional).
-  GenericSignature *conformanceSig;
-  unsigned depth = 0;
-  if ((conformanceSig = conformanceDC->getGenericSignatureOfContext())) {
-    // Use the canonical signature here.
-    conformanceSig = conformanceSig->getCanonicalSignature();
-    depth = conformanceSig->getGenericParams().back()->getDepth() + 1;
-  }
-
-  // Add the generic signature of the requirement, substituting our concrete
-  // type for 'Self'. We don't need the 'Self' requirement or parameter.
-  auto concreteType = conformanceDC->getSelfInterfaceType();
+      proto->getSelfInterfaceType()->getCanonicalType());
 
   reqToSyntheticEnvMap = reqSig->getSubstitutionMap(
-    [selfType, concreteType, depth, &ctx](SubstitutableType *type) -> Type {
-      if (type->isEqual(selfType))
-        return concreteType;
+    [selfType, substConcreteType, depth, covariantSelf, &ctx]
+    (SubstitutableType *type) -> Type {
+      // If the conforming type is a class, the protocol 'Self' maps to
+      // the class-constrained 'Self'. Otherwise, it maps to the concrete
+      // type.
+      if (type->isEqual(selfType)) {
+        if (covariantSelf)
+          return GenericTypeParamType::get(/*depth=*/0, /*index=*/0, ctx);
+        return substConcreteType;
+      }
+      // Other requirement generic parameters map 1:1 with their depth
+      // increased appropriately.
       auto *genericParam = cast<GenericTypeParamType>(type);
+      // In a protocol requirement, the only generic parameter at depth 0
+      // should be 'Self', and all others at depth 1. Anything else is
+      // invalid code.
       if (genericParam->getDepth() != 1)
         return Type();
       auto substGenericParam =
         GenericTypeParamType::get(depth, genericParam->getIndex(), ctx);
       return substGenericParam;
     },
-    [selfType, concreteType, conformance, conformanceDC, &ctx](
+    [selfType, substConcreteType, conformance, conformanceDC, &ctx](
         CanType type, Type replacement, ProtocolType *protoType)
           -> Optional<ProtocolConformanceRef> {
       auto proto = protoType->getDecl();
+
+      // The protocol 'Self' conforms concretely to the conforming type.
       if (type->isEqual(selfType)) {
         ProtocolConformance *specialized = conformance;
         if (conformance && conformance->getGenericSignature()) {
           auto concreteSubs =
-            concreteType->getContextSubstitutionMap(
+            substConcreteType->getContextSubstitutionMap(
               conformanceDC->getParentModule(), conformanceDC);
           specialized =
-            ctx.getSpecializedConformance(concreteType, conformance,
+            ctx.getSpecializedConformance(substConcreteType, conformance,
                                           concreteSubs);
         }
 
@@ -1114,12 +1126,15 @@
           return ProtocolConformanceRef(specialized);
       }
 
+      // All other generic parameters come from the requirement itself
+      // and conform abstractly.
       return ProtocolConformanceRef(proto);
     });
 
   // If the requirement itself is non-generic, the synthetic signature
   // is that of the conformance context.
-  if (reqSig->getGenericParams().size() == 1 &&
+  if (!covariantSelf &&
+      reqSig->getGenericParams().size() == 1 &&
       reqSig->getRequirements().size() == 1) {
     syntheticSignature = conformanceDC->getGenericSignatureOfContext();
     if (syntheticSignature) {
@@ -1139,11 +1154,40 @@
            ctx,
            TypeChecker::LookUpConformance(tc, conformanceDC));
 
-  if (conformanceSig) {
-    builder.addGenericSignature(conformanceSig);
+  auto source =
+    GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
+
+  // If the conforming type is a class, add a class-constrained 'Self'
+  // parameter.
+  if (covariantSelf) {
+    auto paramTy = GenericTypeParamType::get(/*depth=*/0, /*index=*/0, ctx);
+    builder.addGenericParameter(paramTy);
   }
 
-  // First, add the generic parameters from the requirement.
+  // Now, add all generic parameters from the conforming type.
+  if (conformanceSig) {
+    for (auto param : conformanceSig->getGenericParams()) {
+      builder.addGenericParameter(
+          Type(param).subst(conformanceToSyntheticEnvMap)
+              ->castTo<GenericTypeParamType>());
+    }
+  }
+
+  // Next, add requirements.
+  if (covariantSelf) {
+    auto paramTy = GenericTypeParamType::get(/*depth=*/0, /*index=*/0, ctx);
+    Requirement reqt(RequirementKind::Superclass, paramTy, substConcreteType);
+    builder.addRequirement(reqt, source, nullptr);
+  }
+
+  if (conformanceSig) {
+    for (auto &reqt : conformanceSig->getRequirements()) {
+      builder.addRequirement(reqt, source, nullptr,
+                             &conformanceToSyntheticEnvMap);
+    }
+  }
+
+  // Finally, add the generic parameters from the requirement.
   for (auto genericParam : reqSig->getGenericParams().slice(1)) {
     // The only depth that makes sense is depth == 1, the generic parameters
     // of the requirement itself. Anything else is from invalid code.
@@ -1162,10 +1206,15 @@
 
   // Next, add each of the requirements (mapped from the requirement's
   // interface types into the abstract type parameters).
-  auto source =
-    GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
   for (auto &req : reqSig->getRequirements()) {
-    builder.addRequirement(req, source, conformanceDC->getParentModule(),
+    // FIXME: This should not be necessary, since the constraint is redundant,
+    // but we need it to work around some crashes for now.
+    if (req.getKind() == RequirementKind::Conformance &&
+        req.getFirstType()->isEqual(selfType) &&
+        req.getSecondType()->isEqual(proto->getDeclaredType()))
+      continue;
+
+    builder.addRequirement(req, source, /*inferModule=*/nullptr,
                            &reqToSyntheticEnvMap);
   }
 
@@ -1184,8 +1233,7 @@
 matchWitness(TypeChecker &tc,
              ProtocolDecl *proto,
              ProtocolConformance *conformance,
-             DeclContext *dc, ValueDecl *req, ValueDecl *witness,
-             const RequirementEnvironment &reqEnvironment) {
+             DeclContext *dc, ValueDecl *req, ValueDecl *witness) {
   using namespace constraints;
 
   // Initialized by the setup operation.
@@ -1197,20 +1245,80 @@
   Type openedFullWitnessType;
   Type reqType, openedFullReqType;
 
+  auto *reqSig = req->getInnermostDeclContext()->getGenericSignatureOfContext();
+
+  ClassDecl *covariantSelf = nullptr;
+  if (witness->getDeclContext()->getAsProtocolExtensionContext()) {
+    if (auto *classDecl = dc->getAsClassOrClassExtensionContext()) {
+      if (!classDecl->isFinal()) {
+        // If the requirement's type does not involve any associated types,
+        // we use a class-constrained generic parameter as the 'Self' type
+        // in the witness thunk.
+        //
+        // This allows the following code to type check:
+        //
+        // protocol P {
+        //   func f() -> Self
+        // }
+        //
+        // extension P {
+        //   func f() { return self }
+        // }
+        //
+        // class C : P {}
+        //
+        // When we call (C() as P).f(), we want to pass the 'Self' type
+        // from the call site, not the static 'Self' type of the conformance.
+        //
+        // On the other hand, if the requirement's type contains associated
+        // types, we use the static 'Self' type, to preserve backward
+        // compatibility with code that uses this pattern:
+        //
+        // protocol P {
+        //   associatedtype T = Self
+        //   func f() -> T
+        // }
+        //
+        // extension P where Self.T == Self {
+        //   func f() -> Self { return self }
+        // }
+        //
+        // class C : P {}
+        //
+        // It would have been much nicer to just ban this completely if
+        // the class 'C' is not final, but there is a great deal of existing
+        // code out there that relies on this behavior, most commonly by
+        // defining a non-final class conforming to 'Collection' which uses
+        // the default witness for 'Collection.Iterator', which is defined
+        // as 'IndexingIterator<Self>'.
+        auto selfKind = proto->findProtocolSelfReferences(req,
+                                             /*allowCovariantParameters=*/false,
+                                             /*skipAssocTypes=*/false);
+        if (!selfKind.other) {
+          covariantSelf = classDecl;
+        }
+      }
+    }
+  }
+
+  Optional<RequirementEnvironment> reqEnvironment(
+      RequirementEnvironment(tc, dc, reqSig, proto, covariantSelf,
+                             conformance));
+
   // Set up the constraint system for matching.
   auto setup = [&]() -> std::tuple<Optional<RequirementMatch>, Type, Type> {
     // Construct a constraint system to use to solve the equality between
     // the required type and the witness type.
     cs.emplace(tc, dc, ConstraintSystemOptions());
 
-    auto reqGenericEnv = reqEnvironment.getSyntheticEnvironment();
-    auto &reqSubMap = reqEnvironment.getRequirementToSyntheticMap();
+    auto reqGenericEnv = reqEnvironment->getSyntheticEnvironment();
+    auto &reqSubMap = reqEnvironment->getRequirementToSyntheticMap();
 
     Type selfTy = proto->getSelfInterfaceType().subst(reqSubMap);
     if (reqGenericEnv)
       selfTy = reqGenericEnv->mapTypeIntoContext(selfTy);
 
-        // Open up the type of the requirement.
+    // Open up the type of the requirement.
     reqLocator = cs->getConstraintLocator(
                      static_cast<Expr *>(nullptr),
                      LocatorPathElt(ConstraintLocator::Requirement, req));
@@ -1295,6 +1403,7 @@
                               : anyRenaming ? MatchKind::RenamedMatch
                                             : MatchKind::ExactMatch,
                             witnessType,
+                            std::move(reqEnvironment),
                             optionalAdjustments);
 
     // Compute the set of substitutions we'll need for the witness.
@@ -1409,7 +1518,6 @@
                                ValueDecl *requirement,
                                bool *ignoringNames,
                                NormalProtocolConformance *conformance,
-                               const RequirementEnvironment &reqEnvironment,
                                SmallVectorImpl<RequirementMatch> &matches,
                                unsigned &numViable,
                                unsigned &bestIdx,
@@ -1474,7 +1582,7 @@
         TC.validateDecl(witness);
 
       auto match = matchWitness(TC, Proto, conformance, DC,
-                                requirement, witness, reqEnvironment);
+                                requirement, witness);
       if (match.isViable()) {
         ++numViable;
         bestIdx = matches.size();
@@ -1590,7 +1698,7 @@
 RequirementCheck WitnessChecker::
 checkWitness(AccessScope requiredAccessScope,
              ValueDecl *requirement,
-             RequirementMatch match) {
+             const RequirementMatch &match) {
   if (!match.OptionalAdjustments.empty())
     return CheckKind::OptionalityConflict;
 
@@ -1822,8 +1930,7 @@
     ArrayRef<AssociatedTypeDecl *> getReferencedAssociatedTypes(ValueDecl *req);
 
     /// Record a (non-type) witness for the given requirement.
-    void recordWitness(ValueDecl *requirement, const RequirementMatch &match,
-                       RequirementEnvironment &&reqEnvironment);
+    void recordWitness(ValueDecl *requirement, const RequirementMatch &match);
 
     /// Record that the given optional requirement has no witness.
     void recordOptionalWitness(ValueDecl *requirement);
@@ -1841,6 +1948,11 @@
     void recordTypeWitness(AssociatedTypeDecl *assocType, Type type,
                            TypeDecl *typeDecl, bool performRedeclarationCheck);
 
+    /// Enforce restrictions on non-final classes witnessing requirements
+    /// involving the protocol 'Self' type.
+    void checkNonFinalClassWitness(ValueDecl *requirement,
+                                   ValueDecl *witness);
+
     /// Resolve a (non-type) witness via name lookup.
     ResolveWitnessResult resolveWitnessViaLookup(ValueDecl *requirement);
 
@@ -2329,11 +2441,44 @@
   return SourceLoc();
 }
 
-void RequirementMatch::addOptionalityFixIts(
-      const ASTContext &ctx,
-       ValueDecl *witness, 
-       InFlightDiagnostic &diag) const {
-  for (const auto &adjustment : OptionalAdjustments) {
+/// Classify the provided optionality issues for use in diagnostics.
+/// FIXME: Enumify this
+static unsigned classifyOptionalityIssues(
+    const SmallVectorImpl<OptionalAdjustment> &adjustments,
+    ValueDecl *requirement) {
+  unsigned numParameterAdjustments = 0;
+  bool hasNonParameterAdjustment = false;
+  for (const auto &adjustment : adjustments) {
+    if (adjustment.isParameterAdjustment())
+      ++numParameterAdjustments;
+    else
+      hasNonParameterAdjustment = true;
+  }
+
+  if (hasNonParameterAdjustment) {
+    // Both return and parameter adjustments.
+    if (numParameterAdjustments > 0)
+      return 4;
+
+    // The type of a variable.
+    if (isa<VarDecl>(requirement))
+      return 0;
+
+    // The result type of something.
+    return 1;
+  }
+
+  // Only parameter adjustments.
+  assert(numParameterAdjustments > 0 && "No adjustments?");
+  return numParameterAdjustments == 1 ? 2 : 3;
+}
+
+static void addOptionalityFixIts(
+    const SmallVectorImpl<OptionalAdjustment> &adjustments,
+    const ASTContext &ctx,
+    ValueDecl *witness, 
+    InFlightDiagnostic &diag) {
+  for (const auto &adjustment : adjustments) {
     SourceLoc adjustmentLoc = adjustment.getOptionalityLoc(witness);
     if (adjustmentLoc.isInvalid())
       continue;
@@ -2368,12 +2513,10 @@
   // Form a string describing the associated type deductions.
   // FIXME: Determine which associated types matter, and only print those.
   llvm::SmallString<128> withAssocTypes;
-  for (auto member : conformance->getProtocol()->getMembers()) {
-    if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
-      if (conformance->usesDefaultDefinition(assocType)) {
-        Type witness = conformance->getTypeWitness(assocType, nullptr);
-        addAssocTypeDeductionString(withAssocTypes, assocType, witness);
-      }
+  for (auto assocType : conformance->getProtocol()->getAssociatedTypeMembers()) {
+    if (conformance->usesDefaultDefinition(assocType)) {
+      Type witness = conformance->getTypeWitness(assocType, nullptr);
+      addAssocTypeDeductionString(withAssocTypes, assocType, witness);
     }
   }
   if (!withAssocTypes.empty())
@@ -2424,12 +2567,15 @@
     break;
 
   case MatchKind::OptionalityConflict: {
+    auto &adjustments = match.OptionalAdjustments;
     auto diag = diags.diagnose(match.Witness, 
                                diag::protocol_witness_optionality_conflict,
-                               match.classifyOptionalityIssues(req),
+                               classifyOptionalityIssues(adjustments, req),
                                withAssocTypes);
-    match.addOptionalityFixIts(match.Witness->getASTContext(), match.Witness,
-                               diag);
+    addOptionalityFixIts(adjustments,
+                         match.Witness->getASTContext(),
+                         match.Witness,
+                         diag);
     break;
   }
 
@@ -2509,8 +2655,7 @@
 }
 
 void ConformanceChecker::recordWitness(ValueDecl *requirement,
-                                       const RequirementMatch &match,
-                                       RequirementEnvironment &&reqEnvironment){
+                                       const RequirementMatch &match) {
   // If we already recorded this witness, don't do so again.
   if (Conformance->hasWitness(requirement)) {
     assert(Conformance->getWitness(requirement, nullptr).getDecl() ==
@@ -2519,7 +2664,7 @@
   }
 
   // Record this witness in the conformance.
-  auto witness = match.getWitness(TC.Context, std::move(reqEnvironment));
+  auto witness = match.getWitness(TC.Context);
   Conformance->setWitness(requirement, witness);
 
   // Synthesize accessors for the protocol witness table to use.
@@ -2902,10 +3047,147 @@
   return None;
 }
 
+void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
+                                                   ValueDecl *witness) {
+  auto *classDecl = Adoptee->getClassOrBoundGenericClass();
+
+  // If we have an initializer requirement and the conforming type
+  // is a non-final class, the witness must be 'required'.
+  // We exempt Objective-C initializers from this requirement
+  // because there is no equivalent to 'required' in Objective-C.
+  if (auto ctor = dyn_cast<ConstructorDecl>(witness)) {
+    if (!ctor->isRequired() &&
+        !ctor->getDeclContext()->getAsProtocolOrProtocolExtensionContext() &&
+        !ctor->hasClangNode()) {
+      // FIXME: We're not recovering (in the AST), so the Fix-It
+      // should move.
+      diagnoseOrDefer(requirement, false,
+        [ctor, requirement](NormalProtocolConformance *conformance) {
+          bool inExtension = isa<ExtensionDecl>(ctor->getDeclContext());
+          auto &diags = ctor->getASTContext().Diags;
+          auto diag = diags.diagnose(ctor->getLoc(),
+                                     diag::witness_initializer_not_required,
+                                     requirement->getFullName(),
+                                     inExtension,
+                                     conformance->getType());
+          if (!ctor->isImplicit() && !inExtension)
+            diag.fixItInsert(ctor->getStartLoc(), "required ");
+        });
+    }
+  }
+
+  // Check whether this requirement uses Self in a way that might
+  // prevent conformance from succeeding.
+  auto selfKind = Proto->findProtocolSelfReferences(requirement,
+                                       /*allowCovariantParameters=*/false,
+                                       /*skipAssocTypes=*/true);
+
+  if (selfKind.other) {
+    // References to Self in a position where subclasses cannot do
+    // the right thing. Complain if the adoptee is a non-final
+    // class.
+    diagnoseOrDefer(requirement, false,
+      [witness, requirement](NormalProtocolConformance *conformance) {
+        auto proto = conformance->getProtocol();
+        auto &diags = proto->getASTContext().Diags;
+        diags.diagnose(witness->getLoc(), diag::witness_self_non_subtype,
+                       proto->getDeclaredType(), requirement->getFullName(),
+                       conformance->getType());
+      });
+  } else if (selfKind.result) {
+    // The reference to Self occurs in the result type. A non-final class
+    // can satisfy this requirement with a method that returns Self.
+
+    // If the function has a dynamic Self, it's okay.
+    if (auto func = dyn_cast<FuncDecl>(witness)) {
+      if (func->getDeclContext()->getAsClassOrClassExtensionContext() &&
+          !func->hasDynamicSelf()) {
+        diagnoseOrDefer(requirement, false,
+          [witness, requirement](NormalProtocolConformance *conformance) {
+            auto proto = conformance->getProtocol();
+            auto &diags = proto->getASTContext().Diags;
+            diags.diagnose(witness->getLoc(),
+                           diag::witness_requires_dynamic_self,
+                           requirement->getFullName(),
+                           conformance->getType(),
+                           proto->getDeclaredType());
+          });
+      }
+
+    // Constructors conceptually also have a dynamic Self
+    // return type, so they're okay.
+    } else if (!isa<ConstructorDecl>(witness)) {
+      diagnoseOrDefer(requirement, false,
+        [witness, requirement](NormalProtocolConformance *conformance) {
+          auto proto = conformance->getProtocol();
+          auto &diags = proto->getASTContext().Diags;
+          diags.diagnose(witness->getLoc(), diag::witness_self_non_subtype,
+                         proto->getDeclaredType(),
+                         requirement->getFullName(),
+                         conformance->getType());
+        });
+    }
+  } else if (selfKind.requirement) {
+    if (auto constraint = getAdopteeSelfSameTypeConstraint(classDecl,
+                                                           witness)) {
+      // A "Self ==" constraint works incorrectly with subclasses. Complain.
+      auto proto = Conformance->getProtocol();
+      auto &diags = proto->getASTContext().Diags;
+      diags.diagnose(witness->getLoc(),
+                     diag::witness_self_same_type,
+                     witness->getDescriptiveKind(),
+                     witness->getFullName(),
+                     Conformance->getType(),
+                     requirement->getDescriptiveKind(),
+                     requirement->getFullName(),
+                     proto->getDeclaredType());
+
+      if (auto requirementRepr = *constraint) {
+        diags.diagnose(requirementRepr->getEqualLoc(),
+                       diag::witness_self_weaken_same_type,
+                       requirementRepr->getFirstType(),
+                       requirementRepr->getSecondType())
+          .fixItReplace(requirementRepr->getEqualLoc(), ":");
+      }
+    }
+  }
+
+  // A non-final class can model a protocol requirement with a
+  // contravariant Self, because here the witness will always have
+  // a more general type than the requirement.
+
+  // If the witness is in a protocol extension, there's an additional
+  // constraint that either the requirement not produce 'Self' in a
+  // covariant position, or the type of the requirement does not involve
+  // associated types.
+  if (auto func = dyn_cast<FuncDecl>(witness)) {
+    if (func->getDeclContext()->getAsProtocolExtensionContext()) {
+      auto selfKindWithAssocTypes = Proto->findProtocolSelfReferences(
+          requirement,
+          /*allowCovariantParameters=*/false,
+          /*skipAssocTypes=*/false);
+      if (selfKindWithAssocTypes.other &&
+          selfKindWithAssocTypes.result) {
+        diagnoseOrDefer(requirement, false,
+          [witness, requirement](NormalProtocolConformance *conformance) {
+            auto proto = conformance->getProtocol();
+            auto &diags = proto->getASTContext().Diags;
+            diags.diagnose(witness->getLoc(),
+                           diag::witness_requires_class_implementation,
+                           requirement->getFullName(),
+                           conformance->getType());
+          });
+      }
+    }
+  }
+}
+
 ResolveWitnessResult
 ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
   assert(!isa<AssociatedTypeDecl>(requirement) && "Use resolveTypeWitnessVia*");
 
+  auto *nominal = Adoptee->getAnyNominal();
+
   // Resolve all associated types before trying to resolve this witness.
   resolveTypeWitnesses();
 
@@ -2919,23 +3201,21 @@
 
   // Determine whether we can derive a witness for this requirement.
   bool canDerive = false;
-  if (auto *nominal = Adoptee->getAnyNominal()) {
-    // Can a witness for this requirement be derived for this nominal type?
-    if (auto derivable = DerivedConformance::getDerivableRequirement(
-                           nominal,
-                           requirement)) {
-      if (derivable == requirement) {
-        // If it's the same requirement, we can derive it here.
-        canDerive = true;
-      } else {
-        // Otherwise, go satisfy the derivable requirement, which can introduce
-        // a member that could in turn satisfy *this* requirement.
-        auto derivableProto = cast<ProtocolDecl>(derivable->getDeclContext());
-        if (auto conformance =
-              TC.conformsToProtocol(Adoptee, derivableProto, DC, None)) {
-          if (conformance->isConcrete())
-            (void)conformance->getConcrete()->getWitnessDecl(derivable, &TC);
-        }
+  // Can a witness for this requirement be derived for this nominal type?
+  if (auto derivable = DerivedConformance::getDerivableRequirement(
+                         nominal,
+                         requirement)) {
+    if (derivable == requirement) {
+      // If it's the same requirement, we can derive it here.
+      canDerive = true;
+    } else {
+      // Otherwise, go satisfy the derivable requirement, which can introduce
+      // a member that could in turn satisfy *this* requirement.
+      auto derivableProto = cast<ProtocolDecl>(derivable->getDeclContext());
+      if (auto conformance =
+            TC.conformsToProtocol(Adoptee, derivableProto, DC, None)) {
+        if (conformance->isConcrete())
+          (void)conformance->getConcrete()->getWitnessDecl(derivable, &TC);
       }
     }
   }
@@ -2949,14 +3229,12 @@
   bool considerRenames =
     !canDerive && !requirement->getAttrs().hasAttribute<OptionalAttr>() &&
     !requirement->getAttrs().isUnavailable(TC.Context);
-  RequirementEnvironment reqEnvironment(TC, DC, requirement, Conformance);
   if (findBestWitness(requirement,
                       considerRenames ? &ignoringNames : nullptr,
                       Conformance,
-                      reqEnvironment,
                       /* out parameters: */
                       matches, numViable, bestIdx, doNotDiagnoseMatches)) {
-    auto &best = matches[bestIdx];
+    const auto &best = matches[bestIdx];
     auto witness = best.Witness;
 
     // If the name didn't actually line up, complain.
@@ -2984,8 +3262,7 @@
         });
     }
 
-    AccessScope nominalAccessScope =
-        Adoptee->getAnyNominal()->getFormalAccessScope(DC);
+    auto nominalAccessScope = nominal->getFormalAccessScope(DC);
     auto check = checkWitness(nominalAccessScope, requirement, best);
 
     switch (check.Kind) {
@@ -3053,28 +3330,31 @@
       break;
     }
 
-    case CheckKind::OptionalityConflict:
+    case CheckKind::OptionalityConflict: {
+      auto adjustments = best.OptionalAdjustments;
+
       diagnoseOrDefer(requirement, false,
-        [witness, best, requirement](NormalProtocolConformance *conformance) {
+        [witness, adjustments, requirement](NormalProtocolConformance *conformance) {
           auto proto = conformance->getProtocol();
           auto &ctx = witness->getASTContext();
           auto &diags = ctx.Diags;
           {
             auto diag = diags.diagnose(
                           witness,
-                          hasAnyError(best.OptionalAdjustments)
+                          hasAnyError(adjustments)
                             ? diag::err_protocol_witness_optionality
                             : diag::warn_protocol_witness_optionality,
-                          best.classifyOptionalityIssues(requirement),
+                          classifyOptionalityIssues(adjustments, requirement),
                           witness->getFullName(),
                           proto->getFullName());
-            best.addOptionalityFixIts(ctx, witness, diag);
+            addOptionalityFixIts(adjustments, ctx, witness, diag);
           }
 
           diags.diagnose(requirement, diag::protocol_requirement_here,
                          requirement->getFullName());
       });
       break;
+    }
 
     case CheckKind::ConstructorFailability:
       diagnoseOrDefer(requirement, false,
@@ -3111,116 +3391,14 @@
     }
     }
 
-    ClassDecl *classDecl = Adoptee->getClassOrBoundGenericClass();
-
-    if (classDecl && !classDecl->isFinal()) {
-      // If we have an initializer requirement and the conforming type
-      // is a non-final class, the witness must be 'required'.
-      // We exempt Objective-C initializers from this requirement
-      // because there is no equivalent to 'required' in Objective-C.
-      if (auto ctor = dyn_cast<ConstructorDecl>(best.Witness)) {
-        if (!ctor->isRequired() &&
-            !ctor->getDeclContext()->getAsProtocolOrProtocolExtensionContext() &&
-            !ctor->hasClangNode()) {
-          // FIXME: We're not recovering (in the AST), so the Fix-It
-          // should move.
-          diagnoseOrDefer(requirement, false,
-            [ctor, requirement](NormalProtocolConformance *conformance) {
-              bool inExtension = isa<ExtensionDecl>(ctor->getDeclContext());
-              auto &diags = ctor->getASTContext().Diags;
-              auto diag = diags.diagnose(ctor->getLoc(),
-                                         diag::witness_initializer_not_required,
-                                         requirement->getFullName(), 
-                                         inExtension,
-                                         conformance->getType());
-              if (!ctor->isImplicit() && !inExtension)
-                diag.fixItInsert(ctor->getStartLoc(), "required ");
-            });
-        }
+    if (auto *classDecl = Adoptee->getClassOrBoundGenericClass()) {
+      if (!classDecl->isFinal()) {
+        checkNonFinalClassWitness(requirement, witness);
       }
-
-      // Check whether this requirement uses Self in a way that might
-      // prevent conformance from succeeding.
-      auto selfKind = Proto->findProtocolSelfReferences(requirement,
-                                           /*allowCovariantParameters=*/false,
-                                           /*skipAssocTypes=*/true);
-
-      if (selfKind.other) {
-        // References to Self in a position where subclasses cannot do
-        // the right thing. Complain if the adoptee is a non-final
-        // class.
-        diagnoseOrDefer(requirement, false,
-          [witness, requirement](NormalProtocolConformance *conformance) {
-            auto proto = conformance->getProtocol();
-            auto &diags = proto->getASTContext().Diags;
-            diags.diagnose(witness->getLoc(), diag::witness_self_non_subtype,
-                           proto->getDeclaredType(), requirement->getFullName(),
-                           conformance->getType());
-          });
-      } else if (selfKind.result) {
-        // The reference to Self occurs in the result type. A non-final class 
-        // can satisfy this requirement with a method that returns Self.
-
-        // If the function has a dynamic Self, it's okay.
-        if (auto func = dyn_cast<FuncDecl>(best.Witness)) {
-          if (!func->hasDynamicSelf()) {
-            diagnoseOrDefer(requirement, false,
-              [witness, requirement](NormalProtocolConformance *conformance) {
-                auto proto = conformance->getProtocol();
-                auto &diags = proto->getASTContext().Diags;
-                diags.diagnose(witness->getLoc(),
-                               diag::witness_requires_dynamic_self,
-                               requirement->getFullName(),
-                               conformance->getType(),
-                               proto->getDeclaredType());
-              });
-          }
-
-        // Constructors conceptually also have a dynamic Self
-        // return type, so they're okay.
-        } else if (!isa<ConstructorDecl>(best.Witness)) {
-          diagnoseOrDefer(requirement, false,
-            [witness, requirement](NormalProtocolConformance *conformance) {
-              auto proto = conformance->getProtocol();
-              auto &diags = proto->getASTContext().Diags;
-              diags.diagnose(witness->getLoc(), diag::witness_self_non_subtype,
-                             proto->getDeclaredType(),
-                             requirement->getFullName(),
-                             conformance->getType());
-            });
-        }
-      } else if (selfKind.requirement) {
-        if (auto constraint = getAdopteeSelfSameTypeConstraint(classDecl,
-                                                               witness)) {
-          // A "Self ==" constraint works incorrectly with subclasses. Complain.
-          auto proto = Conformance->getProtocol();
-          auto &diags = proto->getASTContext().Diags;
-          diags.diagnose(witness->getLoc(),
-                         diag::witness_self_same_type,
-                         witness->getDescriptiveKind(),
-                         witness->getFullName(),
-                         Conformance->getType(),
-                         requirement->getDescriptiveKind(),
-                         requirement->getFullName(),
-                         proto->getDeclaredType());
-
-          if (auto requirementRepr = *constraint) {
-            diags.diagnose(requirementRepr->getEqualLoc(),
-                           diag::witness_self_weaken_same_type,
-                           requirementRepr->getFirstType(),
-                           requirementRepr->getSecondType())
-              .fixItReplace(requirementRepr->getEqualLoc(), ":");
-          }
-        }
-      }
-
-      // A non-final class can model a protocol requirement with a
-      // contravariant Self, because here the witness will always have
-      // a more general type than the requirement.
     }
 
     // Record the match.
-    recordWitness(requirement, best, std::move(reqEnvironment));
+    recordWitness(requirement, best);
     return ResolveWitnessResult::Success;
 
     // We have an ambiguity; diagnose it below.
@@ -3300,10 +3478,9 @@
 
   // Find the declaration that derives the protocol conformance.
   NominalTypeDecl *derivingTypeDecl = nullptr;
-  if (auto *nominal = Adoptee->getAnyNominal()) {
-    if (nominal->derivesProtocolConformance(Proto))
-      derivingTypeDecl = nominal;
-  }
+  auto *nominal = Adoptee->getAnyNominal();
+  if (nominal->derivesProtocolConformance(Proto))
+    derivingTypeDecl = nominal;
 
   if (!derivingTypeDecl) {
     return ResolveWitnessResult::Missing;
@@ -3315,11 +3492,9 @@
     return ResolveWitnessResult::ExplicitFailed;
 
   // Try to match the derived requirement.
-  RequirementEnvironment reqEnvironment(TC, DC, requirement, Conformance);
-  auto match = matchWitness(TC, Proto, Conformance, DC, requirement, derived,
-                            reqEnvironment);
+  auto match = matchWitness(TC, Proto, Conformance, DC, requirement, derived);
   if (match.isViable()) {
-    recordWitness(requirement, match, std::move(reqEnvironment));
+    recordWitness(requirement, match);
     return ResolveWitnessResult::Success;
   }
 
@@ -4274,11 +4449,7 @@
   Conformance->setState(ProtocolConformanceState::CheckingTypeWitnesses);
   SWIFT_DEFER { Conformance->setState(initialState); };
 
-  for (auto member : Proto->getMembers()) {
-    auto assocType = dyn_cast<AssociatedTypeDecl>(member);
-    if (!assocType)
-      continue;
-
+  for (auto assocType : Proto->getAssociatedTypeMembers()) {
     // If we already have a type witness, do nothing.
     if (Conformance->hasTypeWitness(assocType))
       continue;
@@ -4347,23 +4518,21 @@
     TypeSubstitutionMap substitutions;
     substitutions[Proto->mapTypeIntoContext(selfType)
         ->castTo<ArchetypeType>()] = Adoptee;
-    for (auto member : Proto->getMembers()) {
-      if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
-        auto archetype = Proto->mapTypeIntoContext(
-            assocType->getDeclaredInterfaceType())
-                ->getAs<ArchetypeType>();
-        if (!archetype)
-          continue;
-        if (Conformance->hasTypeWitness(assocType)) {
-          substitutions[archetype] =
-            Conformance->getTypeWitness(assocType, nullptr);
-        } else {
-          auto known = typeWitnesses.begin(assocType);
-          if (known != typeWitnesses.end())
-            substitutions[archetype] = known->first;
-          else
-            substitutions[archetype] = ErrorType::get(archetype);
-        }
+    for (auto assocType : Proto->getAssociatedTypeMembers()) {
+      auto archetype = Proto->mapTypeIntoContext(
+        assocType->getDeclaredInterfaceType())
+        ->getAs<ArchetypeType>();
+      if (!archetype)
+        continue;
+      if (Conformance->hasTypeWitness(assocType)) {
+        substitutions[archetype] =
+          Conformance->getTypeWitness(assocType, nullptr);
+      } else {
+        auto known = typeWitnesses.begin(assocType);
+        if (known != typeWitnesses.end())
+          substitutions[archetype] = known->first;
+        else
+          substitutions[archetype] = ErrorType::get(archetype);
       }
     }
 
@@ -4490,25 +4659,23 @@
   // substitution of type witness bindings into other type witness bindings.
   auto checkCurrentTypeWitnesses = [&]() -> bool {
     // Fold the dependent member types within this type.
-    for (auto member : Proto->getMembers()) {
-      if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
-        if (Conformance->hasTypeWitness(assocType))
-          continue;
+    for (auto assocType : Proto->getAssociatedTypeMembers()) {
+      if (Conformance->hasTypeWitness(assocType))
+        continue;
 
-        // If the type binding does not have a type parameter, there's nothing
-        // to do.
-        auto known = typeWitnesses.begin(assocType);
-        assert(known != typeWitnesses.end());
-        if (!known->first->hasTypeParameter() &&
-            !known->first->hasDependentMember())
-          continue;
+      // If the type binding does not have a type parameter, there's nothing
+      // to do.
+      auto known = typeWitnesses.begin(assocType);
+      assert(known != typeWitnesses.end());
+      if (!known->first->hasTypeParameter() &&
+          !known->first->hasDependentMember())
+        continue;
 
-        Type replaced = known->first.transform(foldDependentMemberTypes);
-        if (replaced.isNull())
-          return true;
-        
-        known->first = replaced;
-      }
+      Type replaced = known->first.transform(foldDependentMemberTypes);
+      if (replaced.isNull())
+        return true;
+
+      known->first = replaced;
     }
 
     // Check any same-type requirements in the protocol's requirement signature.
@@ -4605,6 +4772,24 @@
           continue;
         }
 
+        // If there is a generic parameter of the named type, use that.
+        if (auto gpList = DC->getGenericParamsOfContext()) {
+          GenericTypeParamDecl *foundGP = nullptr;
+          for (auto gp : *gpList) {
+            if (gp->getName() == assocType->getName()) {
+              foundGP = gp;
+              break;
+            }
+          }
+
+          if (foundGP) {
+            auto gpType = DC->mapTypeIntoContext(
+                            foundGP->getDeclaredInterfaceType());
+            typeWitnesses.insert(assocType, {gpType, reqDepth});
+            continue;
+          }
+        }
+
         // The solution is incomplete.
         recordMissing();
         return;
@@ -5467,14 +5652,13 @@
   // Note that we check the module name to smooth over the difference
   // between an imported Objective-C module and its overlay.
   if (Proto->isSpecificProtocol(KnownProtocolKind::ObjectiveCBridgeable)) {
-    if (auto nominal = Adoptee->getAnyNominal()) {
-      if (!TC.Context.isTypeBridgedInExternalModule(nominal)) {
-        if (nominal->getParentModule() != DC->getParentModule() &&
-            !isInOverlayModuleForImportedModule(DC, nominal)) {
-          auto nominalModule = nominal->getParentModule();
-          TC.diagnose(Loc, diag::nonlocal_bridged_to_objc, nominal->getName(),
-                      Proto->getName(), nominalModule->getName());
-        }
+    auto nominal = Adoptee->getAnyNominal();
+    if (!TC.Context.isTypeBridgedInExternalModule(nominal)) {
+      if (nominal->getParentModule() != DC->getParentModule() &&
+          !isInOverlayModuleForImportedModule(DC, nominal)) {
+        auto nominalModule = nominal->getParentModule();
+        TC.diagnose(Loc, diag::nonlocal_bridged_to_objc, nominal->getName(),
+                    Proto->getName(), nominalModule->getName());
       }
     }
   }
@@ -6179,9 +6363,8 @@
 
   // Describe why the witness didn't satisfy the requirement.
   auto dc = conformance->getDeclContext();
-  RequirementEnvironment reqEnvironment(tc, dc, req, conformance);
   auto match = matchWitness(tc, conformance->getProtocol(), conformance,
-                            dc, req, witness, reqEnvironment);
+                            dc, req, witness);
   if (match.Kind == MatchKind::ExactMatch &&
       req->isObjC() && !witness->isObjC()) {
     // Special case: note to add @objc.
@@ -6672,11 +6855,10 @@
         if (accessorKind != AccessorKind::NotAccessor)
           witnessToMatch = cast<FuncDecl>(witness)->getAccessorStorageDecl();
 
-        RequirementEnvironment reqEnvironment(*this, dc, req, *conformance);
         if (matchWitness(*this, proto, *conformance,
                          witnessToMatch->getDeclContext(), req,
-                         const_cast<ValueDecl *>(witnessToMatch),
-                         reqEnvironment).Kind == MatchKind::ExactMatch) {
+                         const_cast<ValueDecl *>(witnessToMatch))
+              .Kind == MatchKind::ExactMatch) {
           if (accessorKind != AccessorKind::NotAccessor) {
             auto *storageReq = dyn_cast<AbstractStorageDecl>(req);
             if (!storageReq)
@@ -6828,8 +7010,7 @@
       : WitnessChecker(tc, proto, proto->getDeclaredType(), proto) { }
 
     ResolveWitnessResult resolveWitnessViaLookup(ValueDecl *requirement);
-    void recordWitness(ValueDecl *requirement, const RequirementMatch &match,
-                       RequirementEnvironment &&reqEnvironment);
+    void recordWitness(ValueDecl *requirement, const RequirementMatch &match);
   };
 } // end anonymous namespace
 
@@ -6843,10 +7024,8 @@
   unsigned bestIdx = 0;
   bool doNotDiagnoseMatches = false;
 
-  RequirementEnvironment reqEnvironment(TC, DC, requirement,
-                                        /*conformance=*/nullptr);
   if (findBestWitness(
-                 requirement, nullptr, nullptr, reqEnvironment,
+                 requirement, nullptr, nullptr,
                  /* out parameters: */
                  matches, numViable, bestIdx, doNotDiagnoseMatches)) {
 
@@ -6859,7 +7038,7 @@
       return ResolveWitnessResult::ExplicitFailed;
 
     // Record the match.
-    recordWitness(requirement, best, std::move(reqEnvironment));
+    recordWitness(requirement, best);
     return ResolveWitnessResult::Success;
   }
 
@@ -6869,11 +7048,9 @@
 
 void DefaultWitnessChecker::recordWitness(
                                   ValueDecl *requirement,
-                                  const RequirementMatch &match,
-                                  RequirementEnvironment &&reqEnvironment) {
+                                  const RequirementMatch &match) {
   Proto->setDefaultWitness(requirement,
-                           match.getWitness(TC.Context,
-                                            std::move(reqEnvironment)));
+                           match.getWitness(TC.Context));
 
   // Synthesize accessors for the protocol witness table to use.
   if (auto storage = dyn_cast<AbstractStorageDecl>(match.Witness))
@@ -6951,9 +7128,8 @@
   // (because property behaviors rely on renaming).
   validateDecl(witness);
   auto dc = conformance->getDeclContext();
-  RequirementEnvironment reqEnvironment(*this, dc, req, conformance);
   auto match = matchWitness(*this, conformance->getProtocol(), conformance,
-                            dc, req, witness, reqEnvironment);
+                            dc, req, witness);
   if (match.Kind != MatchKind::ExactMatch &&
       match.Kind != MatchKind::RenamedMatch) {
     diagnose(witness, diag::property_behavior_conformance_broken,
@@ -6961,8 +7137,7 @@
     return;
   }
 
-  conformance->setWitness(req,
-                          match.getWitness(Context, std::move(reqEnvironment)));
+  conformance->setWitness(req, match.getWitness(Context));
 }
 
 Type TypeChecker::getWitnessType(Type type, ProtocolDecl *protocol,
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 408b293..0a263a3 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -612,7 +612,7 @@
                                 LookUpConformance(*this, dc),
                                 SubstFlags::UseErrorType);
 
-  if (isa<NominalTypeDecl>(decl)) {
+  if (isa<NominalTypeDecl>(decl) && resultType) {
     if (useObjectiveCBridgeableConformancesOfArgs(
           dc, resultType->castTo<BoundGenericType>(),
           unsatisfiedDependency))
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 4730baf..18a430d 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -2502,11 +2502,13 @@
     DeclContextID contextID;
     TypeID defaultDefinitionID;
     bool isImplicit;
+    ArrayRef<uint64_t> rawOverriddenIDs;
 
     decls_block::AssociatedTypeDeclLayout::readRecord(scratch, nameID,
                                                       contextID,
                                                       defaultDefinitionID,
-                                                      isImplicit);
+                                                      isImplicit,
+                                                      rawOverriddenIDs);
 
     auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
     if (declOrOffset.isComplete())
@@ -2533,6 +2535,17 @@
       assocType->setImplicit();
 
     assocType->setCheckedInheritanceClause();
+
+    // Overridden associated types.
+    SmallVector<AssociatedTypeDecl *, 2> overriddenAssocTypes;
+    for (auto overriddenID : rawOverriddenIDs) {
+      if (auto overriddenAssocType =
+              dyn_cast_or_null<AssociatedTypeDecl>(getDecl(overriddenID))) {
+        overriddenAssocTypes.push_back(overriddenAssocType);
+      }
+    }
+    (void)assocType->setOverriddenDecls(overriddenAssocTypes);
+
     break;
   }
 
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 7455367..7441149 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -1897,8 +1897,7 @@
   case SILInstructionKind::ClassMethodInst:
   case SILInstructionKind::SuperMethodInst:
   case SILInstructionKind::ObjCMethodInst:
-  case SILInstructionKind::ObjCSuperMethodInst:
-  case SILInstructionKind::DynamicMethodInst: {
+  case SILInstructionKind::ObjCSuperMethodInst: {
     // Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
     // type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel), and an operand.
     unsigned NextValueIndex = 0;
@@ -1932,11 +1931,6 @@
                     getLocalValue(ListOfValues[NextValueIndex], operandTy),
                     DRef, Ty);
       break;
-    case SILInstructionKind::DynamicMethodInst:
-      ResultVal = Builder.createDynamicMethod(Loc,
-                    getLocalValue(ListOfValues[NextValueIndex], operandTy),
-                    DRef, Ty);
-      break;
     }
     break;
   }
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 44c9f79..bb6ec14 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -1642,7 +1642,7 @@
   unsigned abbrCode = abbrCodes[DefaultWitnessTableLayout::Code];
   for (auto member : proto->getMembers()) {
     if (auto *value = dyn_cast<ValueDecl>(member)) {
-      ConcreteDeclRef witness = proto->getDefaultWitness(value);
+      auto witness = proto->getDefaultWitness(value);
       if (!witness)
         continue;
 
@@ -2720,6 +2720,10 @@
     verifyAttrSerializable(assocType);
 
     auto contextID = addDeclContextRef(assocType->getDeclContext());
+    SmallVector<DeclID, 4> overriddenAssocTypeIDs;
+    for (auto overridden : assocType->getOverriddenDecls()) {
+      overriddenAssocTypeIDs.push_back(addDeclRef(overridden));
+    }
 
     unsigned abbrCode = DeclTypeAbbrCodes[AssociatedTypeDeclLayout::Code];
     AssociatedTypeDeclLayout::emitRecord(
@@ -2727,7 +2731,8 @@
       addDeclBaseNameRef(assocType->getName()),
       contextID,
       addTypeRef(assocType->getDefaultDefinitionType()),
-      assocType->isImplicit());
+      assocType->isImplicit(),
+      overriddenAssocTypeIDs);
     break;
   }
 
@@ -3418,7 +3423,7 @@
     assert(env && "Primary archetype without generic environment?");
 
     GenericEnvironmentID envID = addGenericEnvironmentRef(env);
-    Type interfaceType = env->mapTypeOutOfContext(archetypeTy);
+    Type interfaceType = archetypeTy->getInterfaceType();
 
     unsigned abbrCode = DeclTypeAbbrCodes[ArchetypeTypeLayout::Code];
     ArchetypeTypeLayout::emitRecord(Out, ScratchRecord, abbrCode,
diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp
index 64c94f8..08c7717 100644
--- a/lib/Serialization/SerializeSIL.cpp
+++ b/lib/Serialization/SerializeSIL.cpp
@@ -1755,21 +1755,6 @@
         (unsigned)Ty.getCategory(), ListOfValues);
     break;
   }
-  case SILInstructionKind::DynamicMethodInst: {
-    // Format: a type, an operand and a SILDeclRef. Use SILOneTypeValuesLayout:
-    // type, Attr, SILDeclRef (DeclID, Kind, uncurryLevel),
-    // and an operand.
-    const DynamicMethodInst *DMI = cast<DynamicMethodInst>(&SI);
-    SILType Ty = DMI->getType();
-    SmallVector<ValueID, 9> ListOfValues;
-    handleMethodInst(DMI, DMI->getOperand(), ListOfValues);
-
-    SILOneTypeValuesLayout::emitRecord(Out, ScratchRecord,
-        SILAbbrCodes[SILOneTypeValuesLayout::Code], (unsigned)SI.getKind(),
-        S.addTypeRef(Ty.getSwiftRValueType()),
-        (unsigned)Ty.getCategory(), ListOfValues);
-    break;
-  }
   case SILInstructionKind::DynamicMethodBranchInst: {
     // Format: a typed value, a SILDeclRef, a BasicBlock ID for method,
     // a BasicBlock ID for no method. Use SILOneTypeValuesLayout.
@@ -2087,6 +2072,11 @@
 }
 
 void SILSerializer::writeSILVTable(const SILVTable &vt) {
+  // Do not emit vtables for non-public classes unless everything has to be
+  // serialized.
+  if (!ShouldSerializeAll &&
+      vt.getClass()->getEffectiveAccess() < swift::AccessLevel::Public)
+    return;
   VTableList[vt.getClass()->getName()] = NextVTableID++;
   VTableOffset.push_back(Out.GetCurrentBitNo());
   VTableLayout::emitRecord(Out, ScratchRecord, SILAbbrCodes[VTableLayout::Code],
@@ -2094,6 +2084,12 @@
 
   for (auto &entry : vt.getEntries()) {
     SmallVector<ValueID, 4> ListOfValues;
+    // Do not emit entries which are not public or serialized, unless everything
+    // has to be serialized.
+    if (!ShouldSerializeAll && entry.Implementation &&
+        !entry.Implementation->isPossiblyUsedExternally() &&
+        !entry.Implementation->isSerialized())
+      continue;
     handleSILDeclRef(S, entry.Method, ListOfValues);
     addReferencedSILFunction(entry.Implementation, true);
     // Each entry is a pair of SILDeclRef and SILFunction.
@@ -2298,7 +2294,8 @@
 
   // Write out fragile WitnessTables.
   for (const SILWitnessTable &wt : SILMod->getWitnessTables()) {
-    if ((ShouldSerializeAll || wt.isSerialized()) &&
+    if ((ShouldSerializeAll || SILMod->getOptions().SILSerializeWitnessTables ||
+         wt.isSerialized()) &&
         wt.getConformance()->getDeclContext()->isChildContextOf(assocDC))
       writeSILWitnessTable(wt);
   }
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index 09aa5f8..dfe6aa3 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -497,10 +497,6 @@
   if (isSIB()) {
     collectLinkLibrariesFromImports(callback);
   } else {
-    if (File.getAssociatedModule()->getResilienceStrategy()
-        == ResilienceStrategy::Fragile) {
-      collectLinkLibrariesFromImports(callback);
-    }
     File.collectLinkLibraries(callback);
   }
 }
diff --git a/lib/Syntax/Syntax.cpp b/lib/Syntax/Syntax.cpp
index 055b8ff..890754e 100644
--- a/lib/Syntax/Syntax.cpp
+++ b/lib/Syntax/Syntax.cpp
@@ -68,6 +68,11 @@
   return getRaw()->isMissing();
 }
 
+bool Syntax::isToken() const {
+  return getRaw()->isToken();
+}
+
+
 llvm::Optional<Syntax> Syntax::getParent() const {
   auto ParentData = getData().Parent;
   if (ParentData == nullptr) return llvm::None;
diff --git a/lib/Syntax/SyntaxFactory.cpp.gyb b/lib/Syntax/SyntaxFactory.cpp.gyb
index a76450a..d01d559 100644
--- a/lib/Syntax/SyntaxFactory.cpp.gyb
+++ b/lib/Syntax/SyntaxFactory.cpp.gyb
@@ -57,6 +57,109 @@
   return make<UnknownSyntax>(Raw);
 }
 
+Optional<Syntax>
+SyntaxFactory::createSyntax(SyntaxKind Kind, llvm::ArrayRef<Syntax> Elements) {
+  switch(Kind) {
+% for node in SYNTAX_NODES:
+  case SyntaxKind::${node.syntax_kind}: {
+% if node.children:
+%    child_count = len(node.children)
+    static std::pair<bool, std::function<bool(const Syntax&)>>
+      ChildrenConditions[${child_count}] = {
+%    for child in node.children:
+%       if child.is_optional:
+%         option = "true"
+%       else:
+%         option = "false"
+%       if child.token_choices:
+        {   ${option},
+            [](const Syntax &S) {
+              // check ${child.name}.
+              if (auto Tok = S.getAs<TokenSyntax>()) {
+                auto Kind = Tok->getTokenKind();
+%           tok_checks = []
+%           for choice in child.token_choices:
+%             tok_checks.append("Kind == tok::%s" % choice.kind)
+%           end
+%           all_checks = ' || '.join(tok_checks)
+                return ${all_checks};
+              }
+              return false;
+            }
+        },
+%       else:
+        {   ${option},
+            [](const Syntax &S) {
+              // check ${child.name}.
+              return S.getAs<${child.type_name}>().hasValue();
+            }
+        },
+%       end
+%    end
+    };
+    Optional<Syntax> Parameters[${child_count}];
+    unsigned CurCond = 0;
+    for (unsigned I = 0, N = Elements.size(); I < N; ) {
+      // We should use all elements.
+      if (CurCond == ${child_count}) {
+        return None;
+      }
+      if (ChildrenConditions[CurCond].second(Elements[I])) {
+        // we find a node that satisfies the condition.
+        Parameters[CurCond].emplace(Elements[I]);
+        CurCond ++;
+        I ++;
+      } else if (ChildrenConditions[CurCond].first) {
+        // If the unsatisfied condition is optional, move on to the next condition.
+        CurCond ++;
+      } else {
+        // Mandatory condition is not satisfied.
+        return None;
+      }
+    }
+    for (; CurCond < ${child_count}; CurCond ++) {
+      if (!ChildrenConditions[CurCond].first) {
+        // if the remaining condition is mandatory, we cannot create.
+        return None;
+      }
+    }
+    assert(CurCond == ${child_count});
+    return make${node.syntax_kind}(
+% params = []
+% for i, child in enumerate(node.children):
+%   child = node.children[i]
+%   if child.is_optional:
+%      params.append("/*Optional %s*/ Parameters[%s].hasValue() ?" \
+%       "(*Parameters[%s]).getAs<%s>().getValue() : (Optional<%s>) None" %
+%         (child.name, i, i, child.type_name, child.type_name))
+%   else:
+%      params.append("/*%s*/ (*Parameters[%s]).getAs<%s>().getValue()" %
+%        (child.name, i, child.type_name))
+%   end
+% end
+% child_parms = '\n, '.join(params)
+      ${child_parms}
+    );
+% elif node.is_syntax_collection():
+      std::vector<${node.collection_element_type}> Parts;
+      for (auto &E: Elements) {
+        if (auto P = E.getAs<${node.collection_element_type}>()) {
+          Parts.emplace_back(make<${node.collection_element_type}>(P->getRaw()));
+        } else {
+          return None;
+        }
+      }
+      return make${node.syntax_kind}(Parts);
+% else:
+    return None;
+% end
+   }
+% end
+  default:
+    return None;
+  }
+}
+
 % for node in SYNTAX_NODES:
 %   if node.children:
 %     child_params = []
@@ -110,7 +213,7 @@
   TokenSyntax
   SyntaxFactory::make${token.name}Keyword(const Trivia &LeadingTrivia,
                                           const Trivia &TrailingTrivia) {
-    return makeToken(tok::${token.kind}, "${token.text}", 
+    return makeToken(tok::${token.kind}, "${token.text}",
                      SourcePresence::Present,
                      LeadingTrivia, TrailingTrivia);
   }
@@ -168,7 +271,7 @@
     const Trivia &LeadingTrivia, const Trivia &TrailingTrivia) {
   return makeTypeIdentifier("Any", LeadingTrivia, TrailingTrivia);
 }
-  
+
 TypeIdentifierSyntax SyntaxFactory::makeSelfTypeIdentifier(
     const Trivia &LeadingTrivia, const Trivia &TrailingTrivia) {
   return makeTypeIdentifier("Self", LeadingTrivia, TrailingTrivia);
diff --git a/stdlib/private/StdlibCollectionUnittest/CMakeLists.txt b/stdlib/private/StdlibCollectionUnittest/CMakeLists.txt
index db93305..55686cf 100644
--- a/stdlib/private/StdlibCollectionUnittest/CMakeLists.txt
+++ b/stdlib/private/StdlibCollectionUnittest/CMakeLists.txt
@@ -1,6 +1,6 @@
 set(swift_stdlib_unittest_compile_flags)
 if(SWIFT_SERIALIZE_STDLIB_UNITTEST)
-  list(APPEND swift_stdlib_unittest_compile_flags "-Xfrontend" "-sil-serialize-all")
+  list(APPEND swift_stdlib_unittest_compile_flags "-Xfrontend" "-sil-serialize-witness-tables" "-Xfrontend" "-sil-serialize-vtables")
 endif()
 
 # TODO: support this on non-POSIX platforms.  It cannot be currently as it
diff --git a/stdlib/private/StdlibUnicodeUnittest/CMakeLists.txt b/stdlib/private/StdlibUnicodeUnittest/CMakeLists.txt
index a085944..4e30ef7 100644
--- a/stdlib/private/StdlibUnicodeUnittest/CMakeLists.txt
+++ b/stdlib/private/StdlibUnicodeUnittest/CMakeLists.txt
@@ -1,6 +1,6 @@
 set(swift_stdlib_unittest_compile_flags)
 if(SWIFT_SERIALIZE_STDLIB_UNITTEST)
-  list(APPEND swift_stdlib_unittest_compile_flags "-Xfrontend" "-sil-serialize-all")
+  list(APPEND swift_stdlib_unittest_compile_flags "-Xfrontend" "-sil-serialize-witness-tables" "-Xfrontend" "-sil-serialize-vtables")
 endif()
 
 # TODO: support this on non-POSIX platforms.  It cannot be currently as it
diff --git a/stdlib/private/StdlibUnittest/CMakeLists.txt b/stdlib/private/StdlibUnittest/CMakeLists.txt
index 4db41c5..64cf737 100644
--- a/stdlib/private/StdlibUnittest/CMakeLists.txt
+++ b/stdlib/private/StdlibUnittest/CMakeLists.txt
@@ -5,7 +5,7 @@
   list(APPEND swift_stdlib_unittest_compile_flags "-DSWIFT_RUNTIME_ENABLE_LEAK_CHECKER")
 endif()
 if(SWIFT_SERIALIZE_STDLIB_UNITTEST)
-  list(APPEND swift_stdlib_unittest_compile_flags "-Xfrontend" "-sil-serialize-all")
+  list(APPEND swift_stdlib_unittest_compile_flags "-Xfrontend" "-sil-serialize-witness-tables" "-Xfrontend" "-sil-serialize-vtables")
 endif()
 
 is_build_type_optimized("${SWIFT_STDLIB_BUILD_TYPE}" IS_BUILD_TYPE_OPTIMIZED)
diff --git a/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift b/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
index a0ed6c6..b1aee1b 100644
--- a/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
+++ b/stdlib/public/SwiftOnoneSupport/SwiftOnoneSupport.swift
@@ -151,7 +151,7 @@
     _createArrayUserWithoutSorting("a".utf8)
     _createArrayUserWithoutSorting("a".utf16)
     _createArrayUserWithoutSorting("a".unicodeScalars)
-    _createArrayUserWithoutSorting("a".characters)
+    _createArrayUserWithoutSorting("a")
   }
 
   // Force pre-specialization of Range<Int>
diff --git a/stdlib/public/SwiftShims/CMakeLists.txt b/stdlib/public/SwiftShims/CMakeLists.txt
index 032b677..c719ede 100644
--- a/stdlib/public/SwiftShims/CMakeLists.txt
+++ b/stdlib/public/SwiftShims/CMakeLists.txt
@@ -12,6 +12,7 @@
   SwiftStdbool.h
   SwiftStddef.h
   SwiftStdint.h
+  System.h
   UnicodeShims.h
   Visibility.h
 
diff --git a/stdlib/public/SwiftShims/HeapObject.h b/stdlib/public/SwiftShims/HeapObject.h
index 4c93a7e..29b78b9 100644
--- a/stdlib/public/SwiftShims/HeapObject.h
+++ b/stdlib/public/SwiftShims/HeapObject.h
@@ -13,6 +13,7 @@
 #define SWIFT_STDLIB_SHIMS_HEAPOBJECT_H
 
 #include "RefCount.h"
+#include "System.h"
 
 #define SWIFT_ABI_HEAP_OBJECT_HEADER_SIZE_64 16
 // TODO: Should be 8
@@ -53,7 +54,7 @@
     : metadata(newMetadata)
     , refCounts(InlineRefCounts::Initialized)
   { }
-#endif
+#endif // __cplusplus
 };
 
 #ifdef __cplusplus
@@ -88,6 +89,107 @@
               "HeapObject must be pointer-aligned");
 
 } // end namespace swift
+#endif // __cplusplus
+
+/// Global bit masks
+
+// TODO(<rdar://problem/34837179>): Convert each macro below to static consts
+// when static consts are visible to SIL.
+
+// The extra inhabitants and spare bits of heap object pointers.
+// These must align with the values in IRGen's SwiftTargetInfo.cpp.
+#if defined(__x86_64__)
+
+#ifdef __APPLE__
+#define _swift_abi_LeastValidPointerValue                                      \
+  (__swift_uintptr_t) SWIFT_ABI_DARWIN_X86_64_LEAST_VALID_POINTER
+#else
+#define _swift_abi_LeastValidPointerValue                                      \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER
+#endif
+#define _swift_abi_SwiftSpareBitsMask                                          \
+  (__swift_uintptr_t) SWIFT_ABI_X86_64_SWIFT_SPARE_BITS_MASK
+#define _swift_abi_ObjCReservedBitsMask                                        \
+  (__swift_uintptr_t) SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK
+#define _swift_abi_ObjCReservedLowBits                                         \
+  (unsigned) SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS
+
+#elif defined(__arm64__)
+
+#ifdef __APPLE__
+#define _swift_abi_LeastValidPointerValue                                      \
+  (__swift_uintptr_t) SWIFT_ABI_DARWIN_ARM64_LEAST_VALID_POINTER
+#else
+#define _swift_abi_LeastValidPointerValue                                      \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER
+#endif
+#define _swift_abi_SwiftSpareBitsMask                                          \
+  (__swift_uintptr_t) SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK
+#define _swift_abi_ObjCReservedBitsMask                                        \
+  (__swift_uintptr_t) SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK
+#define _swift_abi_ObjCReservedLowBits                                         \
+  (unsigned) SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS
+
+#elif defined(__powerpc64__)
+
+#define _swift_abi_LeastValidPointerValue                                      \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER
+#define _swift_abi_SwiftSpareBitsMask                                          \
+  (__swift_uintptr_t) SWIFT_ABI_POWERPC64_SWIFT_SPARE_BITS_MASK
+#define _swift_abi_ObjCReservedBitsMask                                        \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK
+#define _swift_abi_ObjCReservedLowBits                                         \
+  (unsigned) SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS
+
+#elif defined(__s390x__)
+
+#define _swift_abi_LeastValidPointerValue                                      \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER
+#define _swift_abi_SwiftSpareBitsMask                                          \
+  (__swift_uintptr_t) SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK
+#define _swift_abi_ObjCReservedBitsMask                                        \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK
+#define _swift_abi_ObjCReservedLowBits                                         \
+  (unsigned) SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS
+
+#else
+
+#define _swift_abi_LeastValidPointerValue                                      \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER
+
+#if __i386__
+#define _swift_abi_SwiftSpareBitsMask                                          \
+  (__swift_uintptr_t) SWIFT_ABI_I386_SWIFT_SPARE_BITS_MASK
+#elif __arm__
+#define _swift_abi_SwiftSpareBitsMask                                          \
+  (__swift_uintptr_t) SWIFT_ABI_ARM_SWIFT_SPARE_BITS_MASK
+#else
+#define _swift_abi_SwiftSpareBitsMask                                          \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK
 #endif
 
+#define _swift_abi_ObjCReservedBitsMask                                        \
+  (__swift_uintptr_t) SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK
+#define _swift_abi_ObjCReservedLowBits                                         \
+  (unsigned) SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS
 #endif
+
+/// Corresponding namespaced decls
+#ifdef __cplusplus
+namespace heap_object_abi {
+static const __swift_uintptr_t LeastValidPointerValue =
+    _swift_abi_LeastValidPointerValue;
+static const __swift_uintptr_t SwiftSpareBitsMask =
+    _swift_abi_SwiftSpareBitsMask;
+static const __swift_uintptr_t ObjCReservedBitsMask =
+    _swift_abi_ObjCReservedBitsMask;
+static const unsigned ObjCReservedLowBits = _swift_abi_ObjCReservedLowBits;
+} // heap_object_abi
+#endif // __cplusplus
+
+/// BridgeObject masks
+
+#define _swift_BridgeObject_TaggedPointerBits _swift_abi_ObjCReservedBitsMask
+
+
+#endif // SWIFT_STDLIB_SHIMS_HEAPOBJECT_H
diff --git a/stdlib/public/SwiftShims/System.h b/stdlib/public/SwiftShims/System.h
new file mode 100644
index 0000000..7e7275f
--- /dev/null
+++ b/stdlib/public/SwiftShims/System.h
@@ -0,0 +1,141 @@
+//===--- System.h - Swift ABI system-specific constants ---------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Here are some fun facts about the target platforms we support!
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_ABI_SYSTEM_H
+#define SWIFT_ABI_SYSTEM_H
+
+// In general, these macros are expected to expand to host-independent
+// integer constant expressions.  This allows the same data to feed
+// both the compiler and runtime implementation.
+
+/******************************* Default Rules ********************************/
+
+/// The least valid pointer value for an actual pointer (as opposed to
+/// Objective-C pointers, which may be tagged pointers and are covered
+/// separately).  Values up to this are "extra inhabitants" of the
+/// pointer representation, and payloaded enum types can take
+/// advantage of that as they see fit.
+///
+/// By default, we assume that there's at least an unmapped page at
+/// the bottom of the address space.  4K is a reasonably likely page
+/// size.
+///
+/// The minimum possible value for this macro is 1; we always assume
+/// that the null representation is available.
+#define SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER 4096
+
+/// The bitmask of spare bits in a function pointer.
+#define SWIFT_ABI_DEFAULT_FUNCTION_SPARE_BITS_MASK 0
+
+/// The bitmask of spare bits in a Swift heap object pointer.  A Swift
+/// heap object allocation will never set any of these bits.
+#define SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK 0
+
+/// The bitmask of reserved bits in an Objective-C object pointer.
+/// By default we assume the ObjC runtime doesn't use tagged pointers.
+#define SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK 0
+
+/// The number of low bits in an Objective-C object pointer that
+/// are reserved by the Objective-C runtime.
+#define SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS 0
+
+/// The ObjC runtime will not use pointer values for which
+/// ``pointer & SWIFT_ABI_XXX_OBJC_RESERVED_BITS_MASK == 0 && 
+/// pointer & SWIFT_ABI_XXX_SWIFT_SPARE_BITS_MASK != 0``.
+
+// Weak references use a marker to tell when they are controlled by
+// the ObjC runtime and when they are controlled by the Swift runtime.
+// Non-ObjC platforms don't use this marker.
+#define SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_MASK 0
+#define SWIFT_ABI_DEFAULT_OBJC_WEAK_REFERENCE_MARKER_VALUE 0
+
+/*********************************** i386 *************************************/
+
+// Heap objects are pointer-aligned, so the low two bits are unused.
+#define SWIFT_ABI_I386_SWIFT_SPARE_BITS_MASK 0x00000003U
+
+// ObjC weak reference discriminator is the LSB.
+#define SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_MASK  \
+  (SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK |          \
+   1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
+#define SWIFT_ABI_I386_OBJC_WEAK_REFERENCE_MARKER_VALUE \
+  (1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
+
+/*********************************** arm **************************************/
+
+// Heap objects are pointer-aligned, so the low two bits are unused.
+#define SWIFT_ABI_ARM_SWIFT_SPARE_BITS_MASK 0x00000003U
+
+// ObjC weak reference discriminator is the LSB.
+#define SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_MASK  \
+  (SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK |          \
+   1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
+#define SWIFT_ABI_ARM_OBJC_WEAK_REFERENCE_MARKER_VALUE \
+  (1<<SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS)
+
+/*********************************** x86-64 ***********************************/
+
+/// Darwin reserves the low 4GB of address space.
+#define SWIFT_ABI_DARWIN_X86_64_LEAST_VALID_POINTER 0x100000000ULL
+
+// Only the bottom 56 bits are used, and heap objects are eight-byte-aligned.
+#define SWIFT_ABI_X86_64_SWIFT_SPARE_BITS_MASK 0xFF00000000000007ULL
+
+// Objective-C reserves the high and low bits for tagged pointers.
+// Systems exist which use either bit.
+#define SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK 0x8000000000000001ULL
+#define SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS 1
+
+// ObjC weak reference discriminator is the two bits
+// reserved for ObjC tagged pointers plus one more low bit.
+#define SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_MASK  \
+  (SWIFT_ABI_X86_64_OBJC_RESERVED_BITS_MASK |          \
+   1<<SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS)
+#define SWIFT_ABI_X86_64_OBJC_WEAK_REFERENCE_MARKER_VALUE \
+  (1<<SWIFT_ABI_X86_64_OBJC_NUM_RESERVED_LOW_BITS)
+
+/*********************************** arm64 ************************************/
+
+/// Darwin reserves the low 4GB of address space.
+#define SWIFT_ABI_DARWIN_ARM64_LEAST_VALID_POINTER 0x100000000ULL
+
+// TBI guarantees the top byte of pointers is unused.
+// Heap objects are eight-byte aligned.
+#define SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK 0xFF00000000000007ULL
+
+// Objective-C reserves just the high bit for tagged pointers.
+#define SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK 0x8000000000000000ULL
+#define SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS 0
+
+// ObjC weak reference discriminator is the high bit
+// reserved for ObjC tagged pointers plus the LSB.
+#define SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_MASK  \
+  (SWIFT_ABI_ARM64_OBJC_RESERVED_BITS_MASK |          \
+   1<<SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS)
+#define SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_VALUE \
+  (1<<SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS)
+
+/*********************************** powerpc64 ********************************/
+
+// Heap objects are pointer-aligned, so the low three bits are unused.
+#define SWIFT_ABI_POWERPC64_SWIFT_SPARE_BITS_MASK 0x0000000000000007ULL
+
+/*********************************** s390x ************************************/
+
+// Top byte of pointers is unused, and heap objects are eight-byte aligned.
+#define SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK 0x0000000000000007ULL
+
+#endif /* SWIFT_ABI_SYSTEM_H */
diff --git a/stdlib/public/SwiftShims/module.modulemap b/stdlib/public/SwiftShims/module.modulemap
index 5b48587..4666fa4 100644
--- a/stdlib/public/SwiftShims/module.modulemap
+++ b/stdlib/public/SwiftShims/module.modulemap
@@ -12,6 +12,7 @@
   header "SwiftStdbool.h"
   header "SwiftStddef.h"
   header "SwiftStdint.h"
+  header "System.h"
   header "UnicodeShims.h"
   header "Visibility.h"
   export *
diff --git a/stdlib/public/core/Arrays.swift.gyb b/stdlib/public/core/Arrays.swift.gyb
index 93315e7..c9eeeee 100644
--- a/stdlib/public/core/Arrays.swift.gyb
+++ b/stdlib/public/core/Arrays.swift.gyb
@@ -1613,40 +1613,20 @@
 }
 
 extension ${Self} : CustomStringConvertible, CustomDebugStringConvertible {
-  internal func _makeDescription(isDebug: Bool) -> String {
-%   if Self != 'Array':
-    var result = isDebug ? "${Self}([" : "["
-%   else:
-    // Always show sugared representation for Arrays.
-    var result = "["
-%   end
-    var first = true
-    for item in self {
-      if first {
-        first = false
-      } else {
-        result += ", "
-      }
-      debugPrint(item, terminator: "", to: &result)
-    }
-%   if Self != 'Array':
-    result += isDebug ? "])" : "]"
-%   else:
-    // Always show sugared representation for Arrays.
-    result += "]"
-%   end
-    return result
-  }
-
   /// A textual representation of the array and its elements.
   public var description: String {
-    return _makeDescription(isDebug: false)
+    return _makeCollectionDescription(for: self, withTypeName: nil)
   }
 
   /// A textual representation of the array and its elements, suitable for
   /// debugging.
   public var debugDescription: String {
-    return _makeDescription(isDebug: true)
+%   if Self != 'Array':
+    return _makeCollectionDescription(for: self, withTypeName: "${Self}")
+%   else:
+    // Always show sugared representation for Arrays.
+    return _makeCollectionDescription(for: self, withTypeName: nil)
+%   end
   }
 }
 
@@ -1812,6 +1792,32 @@
 }
 %end
 
+// Utility method for collections that wish to implement CustomStringConvertible
+// and CustomDebugStringConvertible using a bracketed list of elements,
+// like an array.
+@_inlineable // FIXME(sil-serialize-all)
+@_versioned // FIXME(sil-serialize-all)
+internal func _makeCollectionDescription<C : Collection>
+  (for items: C, withTypeName type: String?) -> String {
+  var result = ""
+  if let type = type {
+    result += "\(type)(["
+  } else {
+    result += "["
+  }
+  var first = true
+  for item in items {
+    if first {
+      first = false
+    } else {
+      result += ", "
+    }
+    debugPrint(item, terminator: "", to: &result)
+  }
+  result += type != nil ? "])" : "]"
+  return result
+}
+
 @_versioned
 @_fixed_layout
 internal struct _InitializeMemoryFromCollection<
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index 1f43104..72e2592 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -348,111 +348,44 @@
 
 //===--- Builtin.BridgeObject ---------------------------------------------===//
 
-#if arch(i386) || arch(arm)
+// TODO(<rdar://problem/34837023>): Get rid of superfluous UInt constructor
+// calls
+
+@_inlineable // FIXME(sil-serialize-all)
+@_versioned
+internal var _objCTaggedPointerBits: UInt {
+  @inline(__always) get { return UInt(_swift_BridgeObject_TaggedPointerBits) }
+}
 @_inlineable // FIXME(sil-serialize-all)
 @_versioned
 internal var _objectPointerSpareBits: UInt {
-    @inline(__always) get { return 0x0000_0003 }
+    @inline(__always) get {
+      return UInt(_swift_abi_SwiftSpareBitsMask) & ~_objCTaggedPointerBits
+    }
 }
 @_inlineable // FIXME(sil-serialize-all)
 @_versioned
+internal var _objectPointerLowSpareBitShift: UInt {
+    @inline(__always) get {
+      _sanityCheck(_swift_abi_ObjCReservedLowBits < 2,
+        "num bits now differs from num-shift-amount, new platform?")
+      return UInt(_swift_abi_ObjCReservedLowBits)
+    }
+}
+
+#if arch(i386) || arch(arm) || arch(powerpc64) || arch(powerpc64le) || arch(
+  s390x)
+@_inlineable // FIXME(sil-serialize-all)
+@_versioned
 internal var _objectPointerIsObjCBit: UInt {
     @inline(__always) get { return 0x0000_0002 }
 }
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerLowSpareBitShift: UInt {
-    @inline(__always) get { return 0 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objCTaggedPointerBits: UInt {
-  @inline(__always) get { return 0 }
-}
-#elseif arch(x86_64)
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerSpareBits: UInt {
-  @inline(__always) get { return 0x7F00_0000_0000_0006 }
-}
+#else
 @_inlineable // FIXME(sil-serialize-all)
 @_versioned
 internal var _objectPointerIsObjCBit: UInt {
   @inline(__always) get { return 0x4000_0000_0000_0000 }
 }
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerLowSpareBitShift: UInt {
-  @inline(__always) get { return 1 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objCTaggedPointerBits: UInt {
-  @inline(__always) get { return 0x8000_0000_0000_0001 }
-}
-#elseif arch(arm64)
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerSpareBits: UInt {
-  @inline(__always) get { return 0x7F00_0000_0000_0007 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerIsObjCBit: UInt {
-  @inline(__always) get { return 0x4000_0000_0000_0000 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerLowSpareBitShift: UInt {
-    @inline(__always) get { return 0 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objCTaggedPointerBits: UInt {
-    @inline(__always) get { return 0x8000_0000_0000_0000 }
-}
-#elseif arch(powerpc64) || arch(powerpc64le)
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerSpareBits: UInt {
-  @inline(__always) get { return 0x0000_0000_0000_0007 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerIsObjCBit: UInt {
-  @inline(__always) get { return 0x0000_0000_0000_0002 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerLowSpareBitShift: UInt {
-    @inline(__always) get { return 0 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objCTaggedPointerBits: UInt {
-    @inline(__always) get { return 0 }
-}
-#elseif arch(s390x)
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerSpareBits: UInt {
-  @inline(__always) get { return 0x0000_0000_0000_0007 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerIsObjCBit: UInt {
-  @inline(__always) get { return 0x0000_0000_0000_0002 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objectPointerLowSpareBitShift: UInt {
-  @inline(__always) get { return 0 }
-}
-@_inlineable // FIXME(sil-serialize-all)
-@_versioned
-internal var _objCTaggedPointerBits: UInt {
-  @inline(__always) get { return 0 }
-}
 #endif
 
 /// Extract the raw bits of `x`.
diff --git a/stdlib/public/core/HashedCollections.swift.gyb b/stdlib/public/core/HashedCollections.swift.gyb
index a16f14c..36f88c8 100644
--- a/stdlib/public/core/HashedCollections.swift.gyb
+++ b/stdlib/public/core/HashedCollections.swift.gyb
@@ -1322,33 +1322,16 @@
 }
 
 extension Set : CustomStringConvertible, CustomDebugStringConvertible {
-  @_inlineable // FIXME(sil-serialize-all)
-  @_versioned // FIXME(sil-serialize-all)
-  internal func makeDescription(isDebug: Bool) -> String {
-    var result = isDebug ? "Set([" : "["
-    var first = true
-    for member in self {
-      if first {
-        first = false
-      } else {
-        result += ", "
-      }
-      debugPrint(member, terminator: "", to: &result)
-    }
-    result += isDebug ? "])" : "]"
-    return result
-  }
-
   /// A string that represents the contents of the set.
   @_inlineable // FIXME(sil-serialize-all)
   public var description: String {
-    return makeDescription(isDebug: false)
+    return _makeCollectionDescription(for: self, withTypeName: nil)
   }
 
   /// A string that represents the contents of the set, suitable for debugging.
   @_inlineable // FIXME(sil-serialize-all)
   public var debugDescription: String {
-    return makeDescription(isDebug: true)
+    return _makeCollectionDescription(for: self, withTypeName: "Set")
   }
 }
 
@@ -2554,7 +2537,9 @@
 
   /// A view of a dictionary's keys.
   @_fixed_layout // FIXME(sil-serialize-all)
-  public struct Keys : Collection, Equatable {
+  public struct Keys
+    : Collection, Equatable,
+      CustomStringConvertible, CustomDebugStringConvertible {
     public typealias Element = Key
 
     @_versioned // FIXME(sil-serialize-all)
@@ -2638,11 +2623,22 @@
 
       return true
     }
+
+    @_inlineable // FIXME(sil-serialize-all)
+    public var description: String {
+      return _makeCollectionDescription(for: self, withTypeName: nil)
+    }
+
+    @_inlineable // FIXME(sil-serialize-all)
+    public var debugDescription: String {
+      return _makeCollectionDescription(for: self, withTypeName: "Dictionary.Keys")
+    }
   }
 
   /// A view of a dictionary's values.
   @_fixed_layout // FIXME(sil-serialize-all)
-  public struct Values : MutableCollection {
+  public struct Values
+    : MutableCollection, CustomStringConvertible, CustomDebugStringConvertible {
     public typealias Element = Value
 
     @_versioned // FIXME(sil-serialize-all)
@@ -2699,6 +2695,16 @@
     public var isEmpty: Bool {
       return count == 0
     }
+
+    @_inlineable // FIXME(sil-serialize-all)
+    public var description: String {
+      return _makeCollectionDescription(for: self, withTypeName: nil)
+    }
+
+    @_inlineable // FIXME(sil-serialize-all)
+    public var debugDescription: String {
+      return _makeCollectionDescription(for: self, withTypeName: "Dictionary.Values")
+    }
   }
 }
 
diff --git a/stdlib/public/core/Indices.swift.gyb b/stdlib/public/core/Indices.swift.gyb
index e6ecc55..5d1b1dd 100644
--- a/stdlib/public/core/Indices.swift.gyb
+++ b/stdlib/public/core/Indices.swift.gyb
@@ -34,8 +34,8 @@
   Elements : ${collectionForTraversal(Traversal)}
 > : ${collectionForTraversal(Traversal)} {
 
-  // FIXME(compiler limitation): this typealias should be inferred.
   public typealias Index = Elements.Index
+  public typealias Indices = ${Self}<Elements>
 
   @_inlineable
   @_versioned
@@ -50,12 +50,12 @@
   }
 
   @_inlineable
-  public var startIndex: Elements.Index {
+  public var startIndex: Index {
     return _startIndex
   }
 
   @_inlineable
-  public var endIndex: Elements.Index {
+  public var endIndex: Index {
     return _endIndex
   }
 
@@ -65,7 +65,6 @@
     return i
   }
 
-  // FIXME(compiler limitation): this typealias should be inferred.
   public typealias SubSequence = ${Self}<Elements>
 
   @_inlineable
@@ -103,9 +102,6 @@
   }
 %     end
 
-  // FIXME(compiler limitation): this typealias should be inferred.
-  public typealias Indices = ${Self}<Elements>
-
   @_inlineable
   public var indices: Indices {
     return self
@@ -120,10 +116,7 @@
 }
 
 extension ${collectionForTraversal(Traversal)}
-%     if Traversal != 'RandomAccess':
-  where Indices == ${Self}<Self>
-%     end
-{
+where Indices == ${Self}<Self> {
   /// The indices that are valid for subscripting the collection, in ascending
   /// order.
   ///
diff --git a/stdlib/public/core/Slice.swift.gyb b/stdlib/public/core/Slice.swift.gyb
index c035bf9..77bc621 100644
--- a/stdlib/public/core/Slice.swift.gyb
+++ b/stdlib/public/core/Slice.swift.gyb
@@ -116,8 +116,7 @@
   : ${SelfProtocols} {
 
   public typealias Index = Base.Index
-  public typealias IndexDistance = Base.IndexDistance
-  public typealias Indices = ${Indices}<${Self}<Base>>
+  public typealias IndexDistance = Base.IndexDistance  
 
   public var _startIndex: Index
   public var _endIndex: Index
@@ -164,13 +163,10 @@
 %     end
   }
 
-  // FIXME(ABI)#67 (Associated Types with where clauses):
-  //
-  //   public typealias Indices = Base.Indices
-  //   public var indices: Indices { ... }
-  //
-  // We can't do it right now because we don't have enough
-  // constraints on the Base.Indices type in this context.
+  public typealias Indices = Base.Indices
+  public var indices: Indices { 
+    return _base.indices[_startIndex..<_endIndex]
+  }
 
   @_inlineable // FIXME(sil-serialize-all)
   public func index(after i: Index) -> Index {
diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp
index ce7f0fc..12536a0 100644
--- a/stdlib/public/runtime/Casting.cpp
+++ b/stdlib/public/runtime/Casting.cpp
@@ -100,6 +100,8 @@
 
   Demangle::DemangleOptions options;
   options.QualifyEntities = qualified;
+  if (!qualified)
+    options.ShowPrivateDiscriminators = false;
   result = Demangle::nodeToString(demangling, options);
 }
 
diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp
index 3863d0d..5a9bf87 100644
--- a/stdlib/public/runtime/Errors.cpp
+++ b/stdlib/public/runtime/Errors.cpp
@@ -332,7 +332,10 @@
   va_start(args, format);
 
   char *log;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
   swift_vasprintf(&log, format, args);
+#pragma GCC diagnostic pop
 
   swift_reportError(flags, log);
   abort();
@@ -346,7 +349,10 @@
   va_start(args, format);
 
   char *log;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
   swift_vasprintf(&log, format, args);
+#pragma GCC diagnostic pop
 
   reportNow(flags, log);
 
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 961a5e5..587a20a 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -1471,11 +1471,6 @@
   // even if Swift doesn't, because of SwiftObject.)
   rodata->InstanceStart = size;
 
-  auto genericPattern = self->getDescription()->getGenericMetadataPattern();
-  auto &allocator =
-    genericPattern ? unsafeGetInitializedCache(genericPattern).getAllocator()
-                   : getResilientMetadataAllocator();
-
   // Always clone the ivar descriptors.
   if (numFields) {
     const ClassIvarList *dependentIvars = rodata->IvarList;
@@ -1484,8 +1479,8 @@
 
     auto ivarListSize = sizeof(ClassIvarList) +
                         numFields * sizeof(ClassIvarEntry);
-    auto ivars = (ClassIvarList*) allocator.Allocate(ivarListSize,
-                                                     alignof(ClassIvarList));
+    auto ivars = (ClassIvarList*) getResilientMetadataAllocator()
+      .Allocate(ivarListSize, alignof(ClassIvarList));
     memcpy(ivars, dependentIvars, ivarListSize);
     rodata->IvarList = ivars;
 
@@ -2420,13 +2415,6 @@
 /*** Other metadata routines ***********************************************/
 /***************************************************************************/
 
-template<> const GenericMetadata *
-Metadata::getGenericPattern() const {
-  if (const auto *ntd = getNominalTypeDescriptor())
-    return ntd->getGenericMetadataPattern();
-  return nullptr;
-}
-
 template<> const ClassMetadata *
 Metadata::getClassObject() const {
   switch (getKind()) {
diff --git a/stdlib/public/stubs/Assert.cpp b/stdlib/public/stubs/Assert.cpp
index 3075386..124c580 100644
--- a/stdlib/public/stubs/Assert.cpp
+++ b/stdlib/public/stubs/Assert.cpp
@@ -27,7 +27,10 @@
   va_list args;
   va_start(args, fmt);
 #if defined(_WIN32)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
   int len = _vscprintf(fmt, args);
+#pragma GCC diagnostic pop
   if (len < 0) {
     va_end(args);
     return -1;
diff --git a/stdlib/public/stubs/CMakeLists.txt b/stdlib/public/stubs/CMakeLists.txt
index 4f96fd3..21062c1 100644
--- a/stdlib/public/stubs/CMakeLists.txt
+++ b/stdlib/public/stubs/CMakeLists.txt
@@ -11,6 +11,7 @@
     FoundationHelpers.mm
     OptionalBridgingHelper.mm
     Reflection.mm
+    SwiftNativeNSXXXBaseARC.m
     SwiftNativeNSXXXBase.mm.gyb)
 set(swift_stubs_unicode_normalization_sources
     UnicodeNormalization.cpp)
@@ -41,3 +42,7 @@
   LINK_FLAGS ${SWIFT_RUNTIME_CORE_LINK_FLAGS}
   INSTALL_IN_COMPONENT stdlib)
 
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+  set_property(SOURCE SwiftNativeNSXXXBaseARC.m APPEND_STRING PROPERTY COMPILE_FLAGS
+    "-fobjc-arc")
+endif()
diff --git a/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb b/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb
index ece3bbc..46551a5 100644
--- a/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb
+++ b/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb
@@ -144,25 +144,6 @@
 }
 
 SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-size_t
-swift_stdlib_NSStringHashValue(NSString *NS_RELEASES_ARGUMENT str,
-                               bool isASCII) {
-  size_t Result =
-      isASCII ? str.hash : str.decomposedStringWithCanonicalMapping.hash;
-
-  swift_unknownRelease(str);
-  return Result;
-}
-
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-size_t
-swift_stdlib_NSStringHashValuePointer(void *opaque, bool isASCII) {
-  NSString *str = (NSString *)opaque;
-  return isASCII ? str.hash : str.decomposedStringWithCanonicalMapping.hash;
-}
-
-
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
 bool swift_stdlib_NSStringHasPrefixNFD(NSString *theString,
                                        NSString *prefix) {
   auto Length = CFStringGetLength((__bridge CFStringRef)theString);
@@ -212,22 +193,6 @@
 }
 
 SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-NS_RETURNS_RETAINED NSString *
-swift_stdlib_NSStringLowercaseString(NSString *NS_RELEASES_ARGUMENT str) {
-  NSString *Result = objc_retain(str.lowercaseString);
-  swift_unknownRelease(str);
-  return Result;
-}
-
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
-NS_RETURNS_RETAINED NSString *
-swift_stdlib_NSStringUppercaseString(NSString *NS_RELEASES_ARGUMENT str) {
-  NSString *Result = objc_retain(str.uppercaseString);
-  swift_unknownRelease(str);
-  return Result;
-}
-
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
 void swift_stdlib_CFSetGetValues(NSSet *NS_RELEASES_ARGUMENT set,
                                             const void **values) {
   CFSetGetValues((__bridge CFSetRef)set, values);
diff --git a/stdlib/public/stubs/SwiftNativeNSXXXBaseARC.m b/stdlib/public/stubs/SwiftNativeNSXXXBaseARC.m
new file mode 100644
index 0000000..28ec1b8
--- /dev/null
+++ b/stdlib/public/stubs/SwiftNativeNSXXXBaseARC.m
@@ -0,0 +1,75 @@
+//===--- SwiftNativeNSXXXBaseARC.mm - Runtime stubs that require ARC ------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+#include "swift/Runtime/Config.h"
+
+#if SWIFT_OBJC_INTEROP
+
+#import <Foundation/Foundation.h>
+#import <CoreFoundation/CoreFoundation.h>
+#include <objc/NSObject.h>
+#include <objc/runtime.h>
+#include <objc/objc.h>
+
+// The following two routines need to be implemented in ARC because
+// decomposedStringWithCanonicalMapping returns its result autoreleased. And we
+// want ARC to insert 'objc_retainAutoreleasedReturnValue' and the necessary
+// markers for the hand-off to facilitate the remove from autorelease pool
+// optimization such that the object is not handed into the current autorelease
+// pool which might be scoped such that repeatedly placing objects into it
+// results in unbounded memory growth.
+
+// On i386 the remove from autorelease pool optimization is foiled by the
+// decomposedStringWithCanonicalMapping implementation. Instead, we use a local
+// autorelease pool to prevent leaking of the temporary object into the callers
+// autorelease pool.
+#if defined(__i386__)
+#define AUTORELEASEPOOL @autoreleasepool
+#else
+// On other platforms we rely on the remove from autorelease pool optimization.
+#define AUTORELEASEPOOL
+#endif
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+size_t swift_stdlib_NSStringHashValue(NSString *NS_RELEASES_ARGUMENT str,
+                                      bool isASCII) {
+  AUTORELEASEPOOL {
+    return isASCII ? str.hash : str.decomposedStringWithCanonicalMapping.hash;
+  }
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+size_t
+swift_stdlib_NSStringHashValuePointer(void *opaque, bool isASCII) {
+  NSString __unsafe_unretained *str =
+      (__bridge NSString __unsafe_unretained *)opaque;
+  AUTORELEASEPOOL {
+    return isASCII ? str.hash : str.decomposedStringWithCanonicalMapping.hash;
+  }
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+NS_RETURNS_RETAINED NSString *
+swift_stdlib_NSStringLowercaseString(NSString *NS_RELEASES_ARGUMENT str) {
+  AUTORELEASEPOOL {
+    return str.lowercaseString;
+  }
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
+NS_RETURNS_RETAINED NSString *
+swift_stdlib_NSStringUppercaseString(NSString *NS_RELEASES_ARGUMENT str) {
+  AUTORELEASEPOOL {
+    return str.uppercaseString;
+  }
+}
+
+#endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 851be89..b4c8bd9 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -46,7 +46,7 @@
       swift-api-digester swift-refactor)
   if(NOT SWIFT_BUILT_STANDALONE)
     list(APPEND deps_binaries FileCheck arcmt-test c-arcmt-test c-index-test
-         clang llc llvm-cov llvm-dwarfdump llvm-link llvm-as llvm-profdata not)
+         clang llc llvm-cov llvm-dwarfdump llvm-link llvm-as llvm-dis llvm-profdata not)
   endif()
   if(SWIFT_BUILD_SOURCEKIT)
     list(APPEND deps_binaries sourcekitd-test complete-test)
diff --git a/test/ClangImporter/objc_init.swift b/test/ClangImporter/objc_init.swift
index 13ea4c7..255c776 100644
--- a/test/ClangImporter/objc_init.swift
+++ b/test/ClangImporter/objc_init.swift
@@ -1,8 +1,6 @@
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -I %S/Inputs/custom-modules %s -verify
 
 // REQUIRES: objc_interop
-// REQUIRES: OS=macosx
-// FIXME: <rdar://problem/19452886> test/ClangModules/objc_init.swift should not require REQUIRES: OS=macosx
 
 import AppKit
 import objc_ext
@@ -59,7 +57,10 @@
 
 func createMyDocument3(_ url: NSURL) {
   var md = MyDocument3()
+#if os(macOS)
+  // Limit this particular test to macOS; it depends on availability.
   md = try! MyDocument3(contentsOf: url as URL, ofType:"")
+#endif
   _ = md
 }
 
diff --git a/test/Compatibility/ownership_protocol.swift b/test/Compatibility/ownership_protocol.swift
new file mode 100644
index 0000000..4fbfa6c
--- /dev/null
+++ b/test/Compatibility/ownership_protocol.swift
@@ -0,0 +1,12 @@
+// RUN: %target-typecheck-verify-swift -swift-version 4
+// Generate a swift 4 compatible warning if ownership is specified in a protocol
+
+class SomeClass {}
+
+protocol P {
+  weak var foo: SomeClass? { get set } // expected-warning {{'weak' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
+  unowned var foo2: SomeClass { get set } // expected-warning {{'unowned' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
+  weak var foo3: Int? { get set } // expected-error {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}}
+  unowned var foo4: Int { get set } // expected-error {{'unowned' may only be applied to class and class-bound protocol types, not 'Int'}}
+}
+
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index 4608c4d..ef609ad 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -97,7 +97,7 @@
 f8(3, f4) // expected-error {{in argument type '(Int) -> Int', 'Int' does not conform to expected type 'P2'}}
 typealias Tup = (Int, Double)
 func f9(_ x: Tup) -> Tup { return x }
-f8((1,2.0), f9) // expected-error {{in argument type '(Tup) -> Tup' (aka '(Int, Double) -> (Int, Double)'), 'Tup' (aka '(Int, Double)') does not conform to expected type 'P2'}}
+f8((1,2.0), f9) // expected-error {{in argument type '(Tup) -> Tup' (aka '((Int, Double)) -> (Int, Double)'), 'Tup' (aka '(Int, Double)') does not conform to expected type 'P2'}}
 
 // <rdar://problem/19658691> QoI: Incorrect diagnostic for calling nonexistent members on literals
 1.doesntExist(0)  // expected-error {{value of type 'Int' has no member 'doesntExist'}}
diff --git a/test/DebugInfo/PrivateDiscriminator.swift b/test/DebugInfo/PrivateDiscriminator.swift
index 1db03e1..c706f53 100644
--- a/test/DebugInfo/PrivateDiscriminator.swift
+++ b/test/DebugInfo/PrivateDiscriminator.swift
@@ -1,25 +1,57 @@
 // Private discriminators should only be emitted for multi-file projects.
 
-// RUN: %target-swift-frontend -emit-ir %s -g -o - | %FileCheck --check-prefix=SINGLE %s
+// RUN: %target-swift-frontend -emit-ir %s -g -o - \
+// RUN:   | %FileCheck --check-prefix=SINGLE %s
 // SINGLE-NOT: !DICompileUnit({{.*}}-private-discriminator
 
-// RUN: %target-swift-frontend %S/../Inputs/empty.swift -primary-file %s -emit-ir -g | %FileCheck %s
+// RUN: %target-swift-frontend %S/../Inputs/empty.swift -primary-file %s \
+// RUN:   -emit-ir -g | %FileCheck %s
 // CHECK: !DICompileUnit({{.*}}flags: {{[^,]*}}-private-discriminator [[DISCRIMINATOR:_[A-Z0-9]+]]
+// CHECK: ![[MOD:.*]] = !DIModule(scope: null,
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "InA",
+// CHECK-SAME:             scope: ![[A:[0-9]+]],
+// CHECK: ![[A]] = !DICompositeType(tag: DW_TAG_structure_type, name: "A",
+// CHECK-SAME:                      scope: ![[NS:[0-9]+]]
+// CHECK: !DINamespace(name: "[[DISCRIMINATOR]]",
+// CHECK-SAME:         scope: ![[OUTER:[0-9]+]], exportSymbols: true)
+// CHECK: ![[OUTER]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK-SAME:                          name: "Outer",
+// CHECK-SAME:                          scope: ![[MOD]],
 
 func markUsed<T>(_ t: T) {}
 
-private class A {
-  init(val : Int64) { member = val }
-  private let member : Int64
-  // CHECK: !DISubprogram(name: "getMember"
-  // CHECK-SAME:          linkageName: "{{[^"]*}}[[DISCRIMINATOR]]
-  // CHECK-SAME:          line: [[@LINE+2]]
-  // CHECK-SAME:          isLocal: true, isDefinition: true 
-  private func getMember() -> Int64 { return member }
-  func getVal() -> Int64 { return getMember() }  
+public class Outer {
+  fileprivate class A {
+    fileprivate struct InA {
+      let i : Int64
+      init(_ val : Int64) { i = val }
+    }
+    
+    init(val : Int64) { member = InA(val) }
+    fileprivate let member : InA
+    // CHECK: !DISubprogram(name: "getMember"
+    // CHECK-SAME:          linkageName: "{{[^"]*}}[[DISCRIMINATOR]]
+    // CHECK-SAME:          line: [[@LINE+2]]
+    // CHECK-SAME:          isLocal: true, isDefinition: true 
+    fileprivate func getMember() -> Int64 { return member.i }
+  }
 }
 
-func f() {
-  let a = A(val: 42)
-  markUsed(a.getVal())
+// CHECK: ![[G:[0-9]+]] = distinct !DISubprogram(name: "g",
+// CHECK-SAME:                                   scope: ![[MOD]]
+fileprivate func g() -> Int64 {
+  // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "InG",
+  // CHECK-SAME:             scope: ![[G]],
+  struct InG {
+    let i : Int64
+    init(_ val : Int64) { i = val }
+  }
+
+  return InG(42).i
+}
+
+// CHECK: distinct !DISubprogram(name: "f", {{.*}}, scope: ![[MOD]]
+public func f() {
+  let a = Outer.A(val: g())
+  markUsed(a)
 }
diff --git a/test/Driver/emit-sib-single-file.swift b/test/Driver/emit-sib-single-file.swift
index ad84496..7b7f8d9 100644
--- a/test/Driver/emit-sib-single-file.swift
+++ b/test/Driver/emit-sib-single-file.swift
@@ -18,6 +18,8 @@
 // CHECK: Hello World
 // CHECK: Hello Bob, today is Tuesday.
 
+@_inlineable
+@_versioned
 func greet(_ name: String, _ day: String) -> String {
   return "Hello \(name), today is \(day)."
 }
diff --git a/test/Generics/protocol_requirement_signatures.swift b/test/Generics/protocol_requirement_signatures.swift
index 1007e7b..676b1bf 100644
--- a/test/Generics/protocol_requirement_signatures.swift
+++ b/test/Generics/protocol_requirement_signatures.swift
@@ -33,16 +33,16 @@
 
 // inheritance without any new requirements
 // CHECK-LABEL: .Q3@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q1, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q1>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1>
 protocol Q3: Q1 {
     associatedtype X // expected-warning{{redeclaration of associated type 'X'}}
 }
 
 // inheritance adding a new conformance
 // CHECK-LABEL: .Q4@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q1, Self.X : P2, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1, τ_0_0.X : P2, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q1, Self.X : P2>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1, τ_0_0.X : P2>
 protocol Q4: Q1 {
     associatedtype X: P2 // expected-warning{{redeclaration of associated type 'X'}}
                    // expected-note@-1 2{{'X' declared here}}
@@ -56,8 +56,8 @@
 
 // multiple inheritance without any new requirements
 // CHECK-LABEL: .Q6@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4>
 protocol Q6: Q2, // expected-note{{conformance constraint 'Self.X': 'P1' implied here}}
              Q3, Q4 {
     associatedtype X: P1 // expected-warning{{redundant conformance constraint 'Self.X': 'P1'}}
@@ -66,8 +66,8 @@
 
 // multiple inheritance with a new conformance
 // CHECK-LABEL: .Q7@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4, Self.X : P3, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4, τ_0_0.X : P3, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4, Self.X : P3>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4, τ_0_0.X : P3>
 protocol Q7: Q2, Q3, Q4 {
     associatedtype X: P3 // expected-warning{{redeclaration of associated type 'X'}}
 }
diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift
index 1342d29..38fd692 100644
--- a/test/Generics/requirement_inference.swift
+++ b/test/Generics/requirement_inference.swift
@@ -158,7 +158,8 @@
 func sameTypeConcrete1<T : P9 & P10>(_: T) where T.A == X3, T.C == T.B, T.C == Int { }
 
 // CHECK-LABEL: sameTypeConcrete2@
-// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == τ_0_0.A, τ_0_0.B == X3, τ_0_0.C == X3>
+// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.B == X3, τ_0_0.C == X3>
+// FIXME: Should have τ_0_0.A == τ_0_0.A
 func sameTypeConcrete2<T : P9 & P10>(_: T) where T.B : X3, T.C == T.B, T.C == X3 { }
 // expected-warning@-1{{redundant superclass constraint 'T.B' : 'X3'}}
 // expected-note@-2{{same-type constraint 'T.C' == 'X3' written here}}
@@ -396,5 +397,5 @@
 protocol P31 { }
 
 // CHECK-LABEL: .sameTypeNameMatch1@
-// Generic signature: <T where T : P29, T : P30, T.X : P31, T.X == T.X>
+// CHECK: Generic signature: <T where T : P29, T : P30, T.X : P31, T.X == T.X>
 func sameTypeNameMatch1<T: P29 & P30>(_: T) where T.X: P31 { }
diff --git a/test/Generics/sr5726.swift b/test/Generics/sr5726.swift
new file mode 100644
index 0000000..70a04d5
--- /dev/null
+++ b/test/Generics/sr5726.swift
@@ -0,0 +1,16 @@
+// RUN: %target-typecheck-verify-swift
+
+// SR-5726
+protocol Foo
+{
+  associatedtype Bar
+  var bar: Bar { get }
+}
+
+extension Foo where Self: Collection, Bar: Collection, Self.SubSequence == Bar.SubSequence, Self.Index == Bar.Index
+{
+  subscript(_ bounds: Range<Index>) -> SubSequence
+  {
+    return bar[bounds]
+  }
+}
diff --git a/test/Generics/superclass_constraint.swift b/test/Generics/superclass_constraint.swift
index b27d7af..a54db73 100644
--- a/test/Generics/superclass_constraint.swift
+++ b/test/Generics/superclass_constraint.swift
@@ -164,3 +164,18 @@
 // CHECK: Generic signature: <T where T : P10, T.A : C10>
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0.A : C10>
 func testP10<T>(_: T) where T: P10, T.A: C10 { }
+
+// Nested types of generic class-constrained type parameters.
+protocol Tail {
+  associatedtype E
+}
+
+protocol Rump : Tail {
+  associatedtype E = Self
+}
+
+class Horse<T>: Rump { }
+
+func hasRedundantConformanceConstraint<X : Horse<T>, T>(_: X) where X : Rump {}
+// expected-warning@-1 {{redundant conformance constraint 'X': 'Rump'}}
+// expected-note@-2 {{conformance constraint 'X': 'Rump' implied here}}
diff --git a/test/IDE/complete_value_literals.swift b/test/IDE/complete_value_literals.swift
index 6f02d3e..d4363ea 100644
--- a/test/IDE/complete_value_literals.swift
+++ b/test/IDE/complete_value_literals.swift
@@ -14,6 +14,9 @@
 // RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=STRING_0 | %FileCheck %s -check-prefix=STRING_0
 // RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=STRING_1 | %FileCheck %s -check-prefix=STRING_1
 // RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=STRING_2 | %FileCheck %s -check-prefix=STRING_2
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=STRING_3 | %FileCheck %s -check-prefix=STRING_3
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=STRING_4 | %FileCheck %s -check-prefix=STRING_4
+// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=STRING_5 | %FileCheck %s -check-prefix=STRING_5
 // RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=ARRAY_0 | %FileCheck %s -check-prefix=ARRAY_0
 // RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=ARRAY_1 | %FileCheck %s -check-prefix=ARRAY_1
 // RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=ARRAY_2 | %FileCheck %s -check-prefix=ARRAY_2
@@ -62,6 +65,13 @@
   init(extendedGraphemeClusterLiteral value: String) {}
   init(stringLiteral value: String) {}
 }
+struct MyUnicodeScalar1: ExpressibleByUnicodeScalarLiteral {
+  init(unicodeScalarLiteral value: Character) {}
+}
+struct MyCharacter1: ExpressibleByExtendedGraphemeClusterLiteral {
+  init(unicodeScalarLiteral value: Character) {}
+  init(extendedGraphemeClusterLiteral value: String) {}
+}
 struct MyArray1<Element>: ExpressibleByArrayLiteral {
   init(arrayLiteral value: Element...) {}
 }
@@ -154,6 +164,19 @@
 }
 // STRING_2: Literal[String]/None/TypeRelation[Identical]: "{#(abc)#}"[#String#];
 
+func testString3() {
+  let x: MyUnicodeScalar1 = #^STRING_3^#
+}
+// STRING_3: Literal[String]/None/TypeRelation[Identical]: "{#(abc)#}"[#MyUnicodeScalar1#];
+func testString4() {
+  let x: MyCharacter1 = #^STRING_4^#
+}
+// STRING_4: Literal[String]/None/TypeRelation[Identical]: "{#(abc)#}"[#MyCharacter1#];
+func testString5() {
+  let x: Character = #^STRING_5^#
+}
+// STRING_5: Literal[String]/None/TypeRelation[Identical]: "{#(abc)#}"[#Character#];
+
 func testArray0() {
   let x: Int = #^ARRAY_0^#
 }
diff --git a/test/IRGen/Inputs/StaticInline.h b/test/IRGen/Inputs/StaticInline.h
index 165f5b3..d0a8bbb 100644
--- a/test/IRGen/Inputs/StaticInline.h
+++ b/test/IRGen/Inputs/StaticInline.h
@@ -3,3 +3,18 @@
 static inline NSString *staticInlineFun() {
   return [[NSLocale currentLocale] localeIdentifier];
 }
+
+static inline __attribute__((ns_returns_retained))
+NSURL *_Nullable test(NSFileManager *self_, NSURL *originalItemURL,
+                      NSURL *newItemURL, NSString *_Nullable backupItemName,
+                      NSFileManagerItemReplacementOptions options,
+                      NSError **_Nullable error) {
+  NSURL *result = nil;
+  BOOL success = [self_ replaceItemAtURL:originalItemURL
+                           withItemAtURL:newItemURL
+                          backupItemName:backupItemName
+                                 options:options
+                        resultingItemURL:&result
+                                   error:error];
+  return success ? result : nil;
+}
diff --git a/test/IRGen/associated_types.swift b/test/IRGen/associated_types.swift
index 62fb04d..7ddaf0e 100644
--- a/test/IRGen/associated_types.swift
+++ b/test/IRGen/associated_types.swift
@@ -66,11 +66,12 @@
 // information for archetypes from all paths to that archetype, not just
 // its parent relationships.
 
-func testFastRuncible<T: Runcible, U: FastRuncible where T.RuncerType == U.RuncerType>(_ t: T, u: U) {
+func testFastRuncible<T: Runcible, U: FastRuncible>(_ t: T, u: U)
+   where T.RuncerType == U.RuncerType {
   U.RuncerType.Runcee.accelerate()
 }
 
-// CHECK: define hidden swiftcc void @_T016associated_types16testFastRuncibleyx_q_1utAA0E0RzAA0dE0R_10RuncerTypeQy_AFRtzr0_lF(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %T, %swift.type* %U, i8** %T.Runcible, i8** %U.FastRuncible) #0 {
+// CHECK: define hidden swiftcc void @_T016associated_types16testFastRuncibleyx_q_1utAA0E0RzAA0dE0R_10RuncerTypeQy_AFRtzAF_6RunceeAA0F0PQZAF_AiA0dF0PRTzr0_lF(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %T, %swift.type* %U, i8** %T.Runcible, i8** %U.FastRuncible) #0 {
 //   1. Get the type metadata for U.RuncerType.Runcee.
 //     1a. Get the type metadata for U.RuncerType.
 //         Note that we actually look things up in T, which is going to prove unfortunate.
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index 62ab6c6..806d815 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -21,8 +21,8 @@
 // CHECK-SAME:   i32 15,
 // --       field names
 // CHECK-SAME:   [7 x i8]* [[ROOTGENERIC_FIELDS]]
-// --       generic metadata pattern
-// CHECK-SAME:   @_T015generic_classes11RootGenericCMP
+// --       kind 0 (class)
+// CHECK-SAME:   i32 0,
 // --       generic parameter vector offset
 // CHECK-SAME:   i32 10,
 // --       generic parameter count, primary count
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 1796e4b..4ff9186 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -19,8 +19,8 @@
 // CHECK-SAME:   i32 2,
 // --       field names
 // CHECK-SAME:   [3 x i8]* [[SINGLEDYNAMIC_FIELDS]]
-// --       generic metadata pattern, kind 1 (struct)
-// CHECK-SAME:   i32 add ({{.*}}@_T015generic_structs13SingleDynamicVMP{{.*}}, i32 1)
+// --       kind 1 (struct)
+// CHECK-SAME:   i32 1
 // --       generic parameter vector offset
 // CHECK-SAME:   i32 3,
 // --       generic parameter count, primary count
@@ -66,8 +66,8 @@
 // CHECK-SAME: i32 2,
 // --       field names
 // CHECK-SAME: [5 x i8]* [[DYNAMICWITHREQUIREMENTS_FIELDS]]
-// --       generic metadata pattern
-// CHECK-SAME: i32 add ({{.*}}@_T015generic_structs23DynamicWithRequirementsVMP{{.*}}, i32 1)
+// --       kind 1 (struct)
+// CHECK-SAME: i32 1,
 // --       generic parameter vector offset
 // CHECK-SAME: i32 4,
 // --       generic requirements count; generic arguments count
diff --git a/test/IRGen/objc_arc_contract.swift b/test/IRGen/objc_arc_contract.swift
new file mode 100644
index 0000000..6d70f88
--- /dev/null
+++ b/test/IRGen/objc_arc_contract.swift
@@ -0,0 +1,28 @@
+// Make sure that we run objc arc contract when emitting ir or bc with optimization enabled.
+
+// RUN: %empty-directory(%t)
+
+// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-ir -Xllvm -disable-objc-arc-contract -parse-as-library -O | %FileCheck --check-prefix=CHECK-WITHOUT-PASS %s
+// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-bc -Xllvm -disable-objc-arc-contract -parse-as-library -O -o %t/test1.bc && %llvm-dis -o - %t/test1.bc | %FileCheck --check-prefix=CHECK-WITHOUT-PASS %s
+
+// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-ir -parse-as-library -O | %FileCheck --check-prefix=CHECK-WITH-PASS %s
+// RUN: %target-swift-frontend -import-objc-header %S/Inputs/StaticInline.h %s -emit-bc -parse-as-library -O -o %t/test2.bc && %llvm-dis -o - %t/test2.bc | %FileCheck --check-prefix=CHECK-WITH-PASS %s
+
+
+// REQUIRES: objc_interop
+// REQUIRES: asserts
+
+// CHECK-WITHOUT-PASS: call void (...) @clang.arc.use
+// CHECK-WITH-PASS-NOT: call void (...) @clang.arc.use
+
+import Foundation
+
+@inline(never)
+public func foo() throws {
+  let x: FileManager! = nil
+  let y = URL(string: "http://swift.org")
+  let z: URL! = nil
+  let w: String = "foo"
+  var e: NSError? = nil
+  test(x, y, z, w, .usingNewMetadataOnly, &e)
+}
diff --git a/test/IRGen/sil_linkage.sil b/test/IRGen/sil_linkage.sil
index 2b5a586..b32a9ba 100644
--- a/test/IRGen/sil_linkage.sil
+++ b/test/IRGen/sil_linkage.sil
@@ -5,13 +5,13 @@
 // CHECK: define{{( protected)?}} swiftcc void @public_fragile_function_test() {{.*}} {
 // CHECK: define{{( protected)?}} internal swiftcc void @public_transparent_fragile_function_test() {{.*}} {
 // CHECK: define{{( protected)?}} swiftcc void @public_transparent_function_test() {{.*}} {
-// CHECK: define{{( protected)?}} swiftcc void @hidden_fragile_function_test() {{.*}} {
+// CHECK: define{{( hidden)?}} swiftcc void @hidden_fragile_function_test() {{.*}} {
 // CHECK: define linkonce_odr hidden swiftcc void @shared_fragile_function_test() {{.*}} {
-// CHECK: define{{( protected)?}} swiftcc void @private_fragile_function_test() {{.*}} {
+// CHECK: define{{( internal)?}} swiftcc void @private_fragile_function_test() {{.*}} {
 // CHECK: define available_externally swiftcc void @public_external_fragile_function_def_test() {{.*}} {
-// CHECK: define{{( protected)?}} available_externally swiftcc void @hidden_external_fragile_function_def_test() {{.*}} {
+// CHECK: define{{( protected)?}} available_externally{{ (hidden)?}} swiftcc void @hidden_external_fragile_function_def_test() {{.*}} {
 // CHECK: define linkonce_odr hidden swiftcc void @shared_external_fragile_function_def_test() {{.*}} {
-// CHECK: define{{( protected)?}} available_externally swiftcc void @private_external_fragile_function_def_test() {{.*}} {
+// CHECK: define{{( protected)?}} available_externally{{ (hidden)?}} swiftcc void @private_external_fragile_function_def_test() {{.*}} {
 // CHECK: define{{( protected)?}} swiftcc void @public_resilient_function_test() {{.*}} {
 // CHECK: define hidden swiftcc void @hidden_resilient_function_test() {{.*}} {
 // CHECK: define linkonce_odr hidden swiftcc void @shared_resilient_function_test() {{.*}} {
diff --git a/test/IRGen/sil_witness_tables_external_witnesstable.swift b/test/IRGen/sil_witness_tables_external_witnesstable.swift
index 3437d4f..33d737a 100644
--- a/test/IRGen/sil_witness_tables_external_witnesstable.swift
+++ b/test/IRGen/sil_witness_tables_external_witnesstable.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-module %S/Inputs/sil_witness_tables_external_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -sil-serialize-all -module-link-name swiftCore
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-module %S/Inputs/sil_witness_tables_external_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -sil-serialize-witness-tables -sil-serialize-vtables -module-link-name swiftCore
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %t -primary-file %s -emit-ir | %FileCheck %s
 
 import Swift
diff --git a/test/IRGen/witness_method.sil b/test/IRGen/witness_method.sil
index e36ff22..5724a12 100644
--- a/test/IRGen/witness_method.sil
+++ b/test/IRGen/witness_method.sil
@@ -100,3 +100,36 @@
   %z = apply %m<T>(%ret, %self) : $@convention(witness_method) <U: Strategy> (@in_guaranteed U) -> @out U.GrowthHack
   return %z : $()
 }
+
+// Class-constrained archetype witness method.
+struct ToVideo : Pivot {}
+
+class TPSReport<CoverSheet> : Strategy {
+  typealias GrowthHack = ToVideo
+
+  func disrupt() -> GrowthHack
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @classArchetypeWitnessMethod(%swift.type* %CoverSheet, %T14witness_method9TPSReportC** noalias nocapture swiftself dereferenceable({{4|8}}), %swift.type* %Self, i8** %SelfWitnessTable)
+
+sil @classArchetypeWitnessMethod : $@convention(witness_method) <T><CoverSheet where T : TPSReport<CoverSheet>> (@in_guaranteed T) -> () {
+entry(%self : $*T):
+  %z = tuple ()
+  return %z : $()
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @testClassArchetypeWitnessMethod(%T14witness_method7ToVideoV* noalias nocapture sret, %T14witness_method9TPSReportC** noalias nocapture dereferenceable({{4|8}}), %swift.type* %T, %swift.type* %CoverSheet)
+// CHECK: entry:
+// CHECK:  [[WITNESS_FN:%.*]] = load i8*, i8** getelementptr inbounds (i8*, i8** @_T014witness_method9TPSReportCyxGAA8StrategyAAlWP, i32 2)
+// CHECK:  [[WITNESS:%.*]] = bitcast i8* [[WITNESS_FN]] to void (%swift.opaque*, %swift.opaque*, %swift.type*, i8**)*
+// CHECK: call swiftcc void [[WITNESS]](%swift.opaque* noalias nocapture sret %4, %swift.opaque* noalias nocapture swiftself %5, %swift.type* %T, i8** @_T014witness_method9TPSReportCyxGAA8StrategyAAlWP)
+// CHECK: ret void
+
+sil @testClassArchetypeWitnessMethod : $@convention(thin) <T><CoverSheet where T : TPSReport<CoverSheet>> (@in_guaranteed T) -> (@out T.GrowthHack) {
+entry(%ret : $*T.GrowthHack, %self : $*T):
+  %m = witness_method $T, #Strategy.disrupt!1 : $@convention(witness_method) <U: Strategy> (@in_guaranteed U) -> @out U.GrowthHack
+  %z = apply %m<T>(%ret, %self) : $@convention(witness_method) <U: Strategy> (@in_guaranteed U) -> @out U.GrowthHack
+  return %z : $()
+}
+
+sil_vtable TPSReport {}
diff --git a/test/Interpreter/protocol_extensions.swift b/test/Interpreter/protocol_extensions.swift
index 500984c..9e2cb73 100644
--- a/test/Interpreter/protocol_extensions.swift
+++ b/test/Interpreter/protocol_extensions.swift
@@ -263,5 +263,68 @@
 sup = Sub.self
 _ = sup.init()
 
+// https://bugs.swift.org/browse/SR-617
+protocol SelfMetadataTest {
+  associatedtype T = Int
+
+  func staticTypeOfSelf() -> Any
+  func staticTypeOfSelfTakesT(_: T) -> Any
+  func staticTypeOfSelfCallsWitness() -> Any
+}
+
+extension SelfMetadataTest {
+  func staticTypeOfSelf() -> Any {
+    return Self.self
+  }
+
+  func staticTypeOfSelfTakesT(_: T) -> Any {
+    return Self.self
+  }
+
+  func staticTypeOfSelfNotAWitness() -> Any {
+    return Self.self
+  }
+
+  func staticTypeOfSelfCallsWitness() -> Any {
+    return staticTypeOfSelf()
+  }
+}
+
+class SelfMetadataBase : SelfMetadataTest {}
+
+class SelfMetadataDerived : SelfMetadataBase {}
+
+func testSelfMetadata<T : SelfMetadataTest>(_ x: T, _ t: T.T) {
+  print("testSelfMetadata()")
+  print(x.staticTypeOfSelf())
+  print(x.staticTypeOfSelfTakesT(t))
+  print(x.staticTypeOfSelfNotAWitness())
+  print(x.staticTypeOfSelfCallsWitness())
+}
+
+// CHECK: testSelfMetadata()
+// CHECK-NEXT: SelfMetadataBase
+// CHECK-NEXT: SelfMetadataBase
+// CHECK-NEXT: SelfMetadataBase
+// CHECK-NEXT: SelfMetadataBase
+testSelfMetadata(SelfMetadataBase(), 0)
+
+// CHECK: testSelfMetadata()
+// CHECK-NEXT: SelfMetadataBase
+// CHECK-NEXT: SelfMetadataBase
+// CHECK-NEXT: SelfMetadataBase
+// CHECK-NEXT: SelfMetadataBase
+testSelfMetadata(SelfMetadataDerived() as SelfMetadataBase, 0)
+
+// This is the interesting case -- make sure the static type of 'Self'
+// is correctly passed on from the call site to the extension method
+
+// CHECK: testSelfMetadata()
+// CHECK-NEXT: SelfMetadataDerived
+// CHECK-NEXT: SelfMetadataBase
+// CHECK-NEXT: SelfMetadataDerived
+// CHECK-NEXT: SelfMetadataDerived
+testSelfMetadata(SelfMetadataDerived(), 0)
+
 // CHECK: DONE
 print("DONE")
diff --git a/test/Misc/stats_dir.swift b/test/Misc/stats_dir.swift
index 4e0d87a..537081d 100644
--- a/test/Misc/stats_dir.swift
+++ b/test/Misc/stats_dir.swift
@@ -23,10 +23,14 @@
 // RUN: %FileCheck -input-file %t/driver.csv %s
 // RUN: %utils/process-stats-dir.py --compare-to-csv-baseline %t/driver.csv %t
 
+// RUN: %target-swiftc_driver -c -o %t/out.o -stats-output-dir %t/this/is/not/a/directory %s 2>&1 | %FileCheck -check-prefix=CHECK-NODIR %s
+
 // CHECK: {{"AST.NumSourceLines"	[1-9][0-9]*$}}
 // CHECK: {{"IRModule.NumIRFunctions"	[1-9][0-9]*$}}
 // CHECK: {{"LLVM.NumLLVMBytesOutput"	[1-9][0-9]*$}}
 
+// CHECK-NODIR: {{Error opening -stats-output-dir file}}
+
 public func foo() {
     print("hello")
 }
diff --git a/test/Misc/stats_dir_long_path_name.swift b/test/Misc/stats_dir_long_path_name.swift
new file mode 100644
index 0000000..c31f31b
--- /dev/null
+++ b/test/Misc/stats_dir_long_path_name.swift
@@ -0,0 +1,16 @@
+// REQUIRES: OS=macosx
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: mkdir -p %t/very-long-directory-name-that-contains-over-128-characters-which-is-not-enough-to-be-illegal-on-its-own-but-presents
+// RUN: cp %s %t/very-long-directory-name-that-contains-over-128-characters-which-is-not-enough-to-be-illegal-on-its-own-but-presents/a-problem-when-combined-with-other-long-path-elements-and-filenames-to-exceed-256-characters-combined-because-yay-arbitrary-limits-amirite.swift
+// RUN: touch %t/main.swift
+// RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t %t/main.swift %t/very-long-directory-name-that-contains-over-128-characters-which-is-not-enough-to-be-illegal-on-its-own-but-presents/a-problem-when-combined-with-other-long-path-elements-and-filenames-to-exceed-256-characters-combined-because-yay-arbitrary-limits-amirite.swift
+// RUN: %utils/process-stats-dir.py --set-csv-baseline %t/frontend.csv %t
+// RUN: %FileCheck -input-file %t/frontend.csv %s
+
+// CHECK: {{"AST.NumSourceLines"	[1-9][0-9]*$}}
+// CHECK: {{"IRModule.NumIRFunctions"	[1-9][0-9]*$}}
+// CHECK: {{"LLVM.NumLLVMBytesOutput"	[1-9][0-9]*$}}
+
+public func foo() {
+    print("hello")
+}
diff --git a/test/PrintAsObjC/availability.swift b/test/PrintAsObjC/availability.swift
index ae4e9d2..bf61fde 100644
--- a/test/PrintAsObjC/availability.swift
+++ b/test/PrintAsObjC/availability.swift
@@ -57,6 +57,7 @@
 
 // CHECK-LABEL: @interface AvailabilitySub
 // CHECK-NEXT: - (nonnull instancetype)init SWIFT_UNAVAILABLE;
+// CHECK-NEXT: + (nonnull instancetype)new SWIFT_UNAVAILABLE;
 // CHECK-NEXT: - (nonnull instancetype)initWithX:(NSInteger)_ SWIFT_UNAVAILABLE;
 // CHECK-NEXT: @end
 
diff --git a/test/PrintAsObjC/classes.swift b/test/PrintAsObjC/classes.swift
index ea24087..4dca51c 100644
--- a/test/PrintAsObjC/classes.swift
+++ b/test/PrintAsObjC/classes.swift
@@ -175,6 +175,15 @@
   @objc init(evenMoreFun: ()) { super.init() }
 }
 
+// CHECK-LABEL: @interface InheritedInitializersRequired
+// CHECK-NEXT: - (nonnull instancetype)initWithEvenMoreFun OBJC_DESIGNATED_INITIALIZER;
+// CHECK-NEXT: - (nonnull instancetype)init SWIFT_UNAVAILABLE;
+// CHECK-NEXT: + (nonnull instancetype)new SWIFT_UNAVAILABLE;
+// CHECK-NEXT: @end
+@objc class InheritedInitializersRequired : InheritedInitializers {
+  @objc required init(evenMoreFun: ()) { super.init() }
+}
+
 // NEGATIVE-NOT: NotObjC
 class NotObjC {}
 
diff --git a/test/PrintAsObjC/protocols.swift b/test/PrintAsObjC/protocols.swift
index 5b73cec..60642f9 100644
--- a/test/PrintAsObjC/protocols.swift
+++ b/test/PrintAsObjC/protocols.swift
@@ -55,6 +55,7 @@
 // CHECK-LABEL: @interface MyObject : NSObject <NSCoding, Fungible>
 // CHECK-NEXT: initWithCoder
 // CHECK-NEXT: init SWIFT_UNAVAILABLE
+// CHECK-NEXT: new SWIFT_UNAVAILABLE
 // CHECK-NEXT: @end
 // NEGATIVE-NOT: @protocol NSCoding
 class MyObject : NSObject, NSCoding, Fungible {
diff --git a/test/Prototypes/Algorithms.swift.gyb b/test/Prototypes/Algorithms.swift.gyb
index 8849f81..e8c2409 100644
--- a/test/Prototypes/Algorithms.swift.gyb
+++ b/test/Prototypes/Algorithms.swift.gyb
@@ -11,7 +11,7 @@
 //===----------------------------------------------------------------------===//
 // RUN: %empty-directory(%t)
 // RUN: %gyb -DWORD_BITS=%target-ptrsize %s -o %t/out.swift
-// RUN: %line-directive %t/out.swift -- %target-build-swift -parse-stdlib %t/out.swift -o %t/a.out -Onone
+// RUN: %line-directive %t/out.swift -- %target-build-swift -parse-stdlib %t/out.swift -o %t/a.out -Onone -swift-version 4
 // RUN: %line-directive %t/out.swift -- %target-run %t/a.out
 
 // REQUIRES: executable_test
@@ -34,7 +34,9 @@
 //===----------------------------------------------------------------------===//
 
 // In the stdlib, this would simply be MutableCollection
-public protocol MutableCollectionAlgorithms : MutableCollection {
+public protocol MutableCollectionAlgorithms : MutableCollection
+  where SubSequence : MutableCollectionAlgorithms
+{
   /// Rotates the elements of the collection so that the element
   /// at `middle` ends up first.
   ///
@@ -43,24 +45,40 @@
   /// - Complexity: O(*n*)
   @discardableResult
   mutating func rotate(shiftingToStart middle: Index) -> Index
-
-  /// Rotates the elements in `bounds` so that the element
-  /// at `middle` ends up first in `bounds`.
-  ///
-  /// - Returns: The new index of the element that was first
-  ///   pre-rotation.
-  /// - Complexity: O(*n*)
-  @discardableResult
-  mutating func rotateSubrange(
-    _ bounds: Range<Index>, shiftingToStart middle: Index
-  ) -> Index
 }
 
-// In the stdlib, this conformance wouldn't be needed
+// In the stdlib, these conformances wouldn't be needed
 extension Array : MutableCollectionAlgorithms {  }
+extension ArraySlice : MutableCollectionAlgorithms {  }
+
+% for Traversal in TRAVERSALS:
+%   for RangeReplaceable in [ False, True ]:
+%     Slice = sliceTypeName(traversal=Traversal, mutable=True, rangeReplaceable=RangeReplaceable)
+extension ${Slice} : MutableCollectionAlgorithms {  }
+%   end
+% end
 
 /// In the stdlib, this would simply be MutableCollection
 extension MutableCollectionAlgorithms {
+  /// Swaps the elements of the two given subranges, up to the upper bound of
+  /// the smaller subrange. The returned indices are the ends of the two ranges
+  /// that were actually swapped.
+  ///
+  ///     Input:
+  ///     [a b c d e f g h i j k l m n o p]
+  ///      ^^^^^^^         ^^^^^^^^^^^^^
+  ///      lhs             rhs
+  ///
+  ///     Output:
+  ///     [i j k l e f g h a b c d m n o p]
+  ///             ^               ^
+  ///             p               q
+  ///
+  /// - Precondition: !lhs.isEmpty && !rhs.isEmpty
+  /// - Postcondition: For returned indices `(p, q)`:
+  ///   - distance(from: lhs.lowerBound, to: p) ==
+  ///       distance(from: rhs.lowerBound, to: q)
+  ///   - p == lhs.upperBound || q == rhs.upperBound
   @inline(__always)
   internal mutating func _swapNonemptySubrangePrefixes(
     _ lhs: Range<Index>, _ rhs: Range<Index>
@@ -71,7 +89,7 @@
     var p = lhs.lowerBound
     var q = rhs.lowerBound
     repeat {
-      swap(&self[p], &self[q])
+      swapAt(p, q)
       formIndex(after: &p)
       formIndex(after: &q)
     }
@@ -79,15 +97,6 @@
     return (p, q)
   }
 
-  @inline(__always)
-  internal mutating func _swapSubrangePrefixes(
-    _ lhs: Range<Index>, with rhs: Range<Index>
-  ) -> (Index, Index) {
-    return lhs.isEmpty || rhs.isEmpty
-      ? (lhs.lowerBound, rhs.lowerBound)
-      : _swapNonemptySubrangePrefixes(lhs, rhs)
-  }
-
   /// Rotates the elements of the collection so that the element
   /// at `middle` ends up first.
   ///
@@ -96,29 +105,8 @@
   /// - Complexity: O(*n*)
   @discardableResult
   public mutating func rotate(shiftingToStart middle: Index) -> Index {
-    return rotateSubrange(startIndex..<endIndex, shiftingToStart: middle)
-  }
-
-  /// Rotates the elements in `bounds` so that the element
-  /// at `middle` ends up first.
-  ///
-  /// - Returns: The new index of the element that was first
-  ///   pre-rotation.
-  /// - Complexity: O(*n*)
-  @discardableResult
-  public mutating func rotateSubrange(
-    _ bounds: Range<Index>, shiftingToStart middle: Index
-  ) -> Index {
-    return _rotateSubrangeForward(bounds, shiftingToStart: middle)
-  }
-
-  // Broken out of the method above for testability purposes
-  @discardableResult
-  internal mutating func _rotateSubrangeForward(
-    _ bounds: Range<Index>, shiftingToStart middle: Index
-  ) -> Index {
-    var m = middle, s = bounds.lowerBound
-    let e = bounds.upperBound
+    var m = middle, s = startIndex
+    let e = endIndex
 
     // Handle the trivial cases
     if s == m { return e }
@@ -176,32 +164,21 @@
 
 extension MutableCollection where Self: BidirectionalCollection {
 
-  // This could be internal, but until we have pinned accessors for
-  // slices, every mutating algorithm needs a version that takes
-  // indices in order to get performance.
-
-  /// Reverses the elements in the given subrange in place.
+  /// Reverses the elements of the collection, moving from each end until
+  /// `limit` is reached from either direction. The returned indices are the
+  /// start and end of the range of unreversed elements.
   ///
-  ///     var characters: [Character] = ["^", "C", "a", "f", "é", "$""]
-  ///     let r = characters.index(after: characters.startIndex)
-  ///             ..< characters.index(before: characters.endIndex)
-  ///     characters.reverseSubrange(r)
-  ///     print(cafe.characters)
-  ///     // Prints "["^", "é", "f", "a", "C", "$"]
+  ///     Input:
+  ///     [a b c d e f g h i j k l m n o p]
+  ///             ^
+  ///           limit
+  ///     Output:
+  ///     [p o n m e f g h i j k l d c b a]
+  ///             ^               ^
+  ///             f               l
   ///
-  /// - Complexity: O(*n*), where *n* is the number of elements in the
-  ///   subrange.
-  public mutating func reverseSubrange(_ bounds: Range<Index>) {
-    if bounds.isEmpty { return }
-    var f = bounds.lowerBound
-    var l = index(before: bounds.upperBound)
-    while f < l {
-      swap(&self[f], &self[l])
-      formIndex(after: &f)
-      formIndex(before: &l)
-    }
-  }
-
+  /// - Postcondition: For returned indices `(f, l)`:
+  ///   `f == limit || l == limit`
   @inline(__always)
   @discardableResult
   internal mutating func _reverseUntil(_ limit: Index) -> (Index, Index) {
@@ -209,7 +186,7 @@
     var l = endIndex
     while f != limit && l != limit {
       formIndex(before: &l)
-      swap(&self[f], &self[l])
+      swapAt(f, l)
       formIndex(after: &f)
     }
     return (f, l)
@@ -233,11 +210,11 @@
     // locality properties than either of the other implementations.
     // Benchmarks should be performed for that algorithm too, just to
     // be sure.
-    reverseSubrange(startIndex..<middle)
-    reverseSubrange(middle..<endIndex)
+    self[..<middle].reverse()
+    self[middle...].reverse()
     let (p, q) = _reverseUntil(middle)
-    reverseSubrange(p..<q)
-    return middle == p  ? q : p
+    self[p..<q].reverse()
+    return middle == p ? q : p
   }
 }
 
@@ -252,21 +229,22 @@
   return m
 }
 
-extension MutableCollection where Self: RandomAccessCollection,
-  SubSequence: MutableCollection, SubSequence: RandomAccessCollection {
+extension MutableCollection where Self: RandomAccessCollection {
 
   /// Rotates elements through a cycle, using `sourceForIndex` to generate
   /// the source index for each movement.
   @inline(__always)
-  internal mutating func _rotateCycle(start: Index,
-    transform sourceForIndex: (Index) -> Index)
-  {
+  internal mutating func _rotateCycle(
+    start: Index,
+    sourceOffsetForIndex: (Index) -> IndexDistance
+  ) {
     let tmp = self[start]
-    var (i, j) = (start, sourceForIndex(start))
+    var i = start
+    var j = index(start, offsetBy: sourceOffsetForIndex(start))
     while j != start {
       self[i] = self[j]
       i = j
-      j = sourceForIndex(j)
+      j = index(j, offsetBy: sourceOffsetForIndex(j))
     }
     self[i] = tmp
   }
@@ -297,9 +275,9 @@
     let cycles = _gcd(numericCast(plus), -numericCast(minus))
 
     for cycle in 1...cycles {
-      _rotateCycle(start: index(startIndex, offsetBy: numericCast(cycle))) {
-        index($0, offsetBy: $0 < pivot ? plus : minus)
-      }
+      _rotateCycle(
+        start: index(startIndex, offsetBy: numericCast(cycle)),
+        sourceOffsetForIndex: { $0 < pivot ? plus : minus })
     }
     return pivot
   }
@@ -340,35 +318,33 @@
 
   internal let _position:
     _ConcatenatedCollectionIndexRepresentation<C1.Index, C2.Index>
-}
 
-public func < <C1: Collection, C2: Collection>(
-  lhs: ConcatenatedCollectionIndex<C1, C2>,
-  rhs: ConcatenatedCollectionIndex<C1, C2>
-) -> Bool {
-  switch (lhs._position, rhs._position) {
-  case (.first, .second):
-    return true
-  case (.second, .first):
-    return false
-  case let (.first(l), .first(r)):
-    return l < r
-  case let (.second(l), .second(r)):
-    return l < r
+  public static func < (
+    lhs: ConcatenatedCollectionIndex, rhs: ConcatenatedCollectionIndex
+  ) -> Bool {
+    switch (lhs._position, rhs._position) {
+    case (.first, .second):
+      return true
+    case (.second, .first):
+      return false
+    case let (.first(l), .first(r)):
+      return l < r
+    case let (.second(l), .second(r)):
+      return l < r
+    }
   }
-}
 
-public func == <C1: Collection, C2: Collection>(
-  lhs: ConcatenatedCollectionIndex<C1, C2>,
-  rhs: ConcatenatedCollectionIndex<C1, C2>
-) -> Bool {
-  switch (lhs._position, rhs._position) {
-  case let (.first(l), .first(r)):
-    return l == r
-  case let (.second(l), .second(r)):
-    return l == r
-  default:
-    return false
+  public static func == (
+    lhs: ConcatenatedCollectionIndex, rhs: ConcatenatedCollectionIndex
+  ) -> Bool {
+    switch (lhs._position, rhs._position) {
+    case let (.first(l), .first(r)):
+      return l == r
+    case let (.second(l), .second(r)):
+      return l == r
+    default:
+      return false
+    }
   }
 }
 
@@ -378,7 +354,7 @@
 
 /// A concatenation of two collections with the same element type.
 public struct ${Self}<C1 : ${Collection}, C2: ${Collection}>: ${Collection}
-  where C1.Iterator.Element == C2.Iterator.Element {
+  where C1.Element == C2.Element {
 
   init(_base1: C1, base2: C2) {
     self._base1 = _base1
@@ -399,7 +375,7 @@
     return ConcatenatedCollectionIndex(second: _base2.endIndex)
   }
 
-  public subscript(i: Index) -> C1.Iterator.Element {
+  public subscript(i: Index) -> C1.Element {
     switch i._position {
     case let .first(i):
       return _base1[i]
@@ -492,7 +468,7 @@
 func concatenate<
   C1 : ${Collection}, C2 : ${Collection}
 >(_ first: C1, _ second: C2) -> ${Self}<C1, C2>
-where C1.Iterator.Element == C2.Iterator.Element {
+where C1.Element == C2.Element {
   return ${Self}(_base1: first, base2: second)
 }
 
@@ -502,24 +478,21 @@
 //===----------------------------------------------------------------------===//
 
 /// A position in a rotated collection.
-public struct RotatedCollectionIndex<Base : Collection> : Comparable
-where Base.SubSequence: Collection {
+public struct RotatedCollectionIndex<Base : Collection> : Comparable {
   internal let _index:
     ConcatenatedCollectionIndex<Base.SubSequence, Base.SubSequence>
-}
 
-public func < <Base: Collection>(
-  lhs: RotatedCollectionIndex<Base>, rhs: RotatedCollectionIndex<Base>
-) -> Bool
-where Base.SubSequence: Collection {
-  return lhs._index < rhs._index
-}
+  public static func < (
+    lhs: RotatedCollectionIndex, rhs: RotatedCollectionIndex
+  ) -> Bool {
+    return lhs._index < rhs._index
+  }
 
-public func == <Base: Collection>(
-  lhs: RotatedCollectionIndex<Base>, rhs: RotatedCollectionIndex<Base>
-) -> Bool
-where Base.SubSequence: Collection {
-  return lhs._index == rhs._index
+  public static func == (
+    lhs: RotatedCollectionIndex, rhs: RotatedCollectionIndex
+  ) -> Bool {
+    return lhs._index == rhs._index
+  }
 }
 
 % for Traversal in TRAVERSALS:
@@ -529,13 +502,12 @@
 /// A rotated view onto a `${Collection}`.
 public struct ${Self}<
   Base : ${Collection}
-> : ${Collection}
-where Base.SubSequence: ${Collection} {
+> : ${Collection} {
   let _concatenation: Concatenated${Collection}<
     Base.SubSequence, Base.SubSequence>
 
   init(_base: Base, shiftingToStart i: Base.Index) {
-    _concatenation = concatenate(_base.suffix(from: i), _base.prefix(upTo: i))
+    _concatenation = concatenate(_base[i...], _base[..<i])
   }
 
   public typealias Index = RotatedCollectionIndex<Base>
@@ -548,7 +520,7 @@
     return RotatedCollectionIndex(_index: _concatenation.endIndex)
   }
 
-  public subscript(i: Index) -> Base.SubSequence.Iterator.Element {
+  public subscript(i: Index) -> Base.SubSequence.Element {
     return _concatenation[i._index]
   }
 
@@ -577,7 +549,7 @@
   }
 }
 
-extension ${Collection} where SubSequence: ${Collection} {
+extension ${Collection} {
   /// Returns a view of this collection with the elements reordered such the
   /// element at the given position ends up first.
   ///
@@ -604,66 +576,50 @@
 //===----------------------------------------------------------------------===//
 
 extension BidirectionalCollection
-  where Self : MutableCollectionAlgorithms,
-  SubSequence : BidirectionalCollection,
-  SubSequence.Index == Self.Index {
+  where Self : MutableCollectionAlgorithms {
 
   @discardableResult
   mutating func stablePartition(
-    choosingStartGroupBy p: (Iterator.Element) -> Bool
+    choosingStartGroupBy p: (Element) -> Bool
   ) -> Index {
-    return stablyPartitionSubrange(
-      startIndex..<endIndex,
+    return _stablePartition(
+      distance: distance(from: startIndex, to: endIndex),
       choosingStartGroupBy: p
     )
   }
 
-  mutating func stablyPartitionSubrange(
-    _ bounds: Range<Index>,
-    choosingStartGroupBy p: (Iterator.Element) -> Bool
-  ) -> Index {
-    return _stablyPartitionSubrange(
-      bounds,
-      distance: distance(from: bounds.lowerBound, to: bounds.upperBound),
-      choosingStartGroupBy: p
-    )
-  }
-
-  mutating func _stablyPartitionSubrange(
-    _ bounds: Range<Index>,
+  mutating func _stablePartition(
     distance n: IndexDistance,
-    choosingStartGroupBy p: (Iterator.Element) -> Bool
+    choosingStartGroupBy p: (Element) -> Bool
   ) -> Index {
     assert(n >= 0)
-    let (start, end) = (bounds.lowerBound, bounds.upperBound)
-    assert(n == distance(from: start, to: end))
-    if n == 0 { return start }
+    assert(n == distance(from: startIndex, to: endIndex))
+    if n == 0 { return startIndex }
     if n == 1 {
-      return p(self[start]) ? index(after: start) : start
+      return p(self[startIndex]) ? endIndex : startIndex
     }
 
-
     // divide and conquer.
     let d = n / numericCast(2)
-    let m = index(start, offsetBy: d)
+    let m = index(startIndex, offsetBy: d)
 
     // TTTTTTTTT s FFFFFFF m ?????????????
-    let s = _stablyPartitionSubrange(
-      start..<m, distance: d, choosingStartGroupBy: p)
+    let s = self[..<m]._stablePartition(
+      distance: numericCast(d), choosingStartGroupBy: p)
 
     // TTTTTTTTT s FFFFFFF m TTTTTTT e FFFFFFFF
-    let e = _stablyPartitionSubrange(
-      m..<end, distance: n - d, choosingStartGroupBy: p)
+    let e = self[m...]._stablePartition(
+      distance: numericCast(n - d), choosingStartGroupBy: p)
 
     // TTTTTTTTT s TTTTTTT m  FFFFFFF e FFFFFFFF
-    return self.rotateSubrange(s..<e, shiftingToStart: m)
+    return self[s..<e].rotate(shiftingToStart: m)
   }
 }
 
 extension Collection {
   func stablyPartitioned(
-    choosingStartGroupBy p: (Iterator.Element) -> Bool
-  ) -> [Iterator.Element] {
+    choosingStartGroupBy p: (Element) -> Bool
+  ) -> [Element] {
     var a = Array(self)
     a.stablePartition(choosingStartGroupBy: p)
     return a
@@ -671,46 +627,46 @@
 }
 
 extension LazyCollectionProtocol
-  where Iterator.Element == Elements.Iterator.Element {
+  where Element == Elements.Element {
   func stablyPartitioned(
-    choosingStartGroupBy p: (Iterator.Element) -> Bool
-  ) -> LazyCollection<[Iterator.Element]> {
+    choosingStartGroupBy p: (Element) -> Bool
+  ) -> LazyCollection<[Element]> {
     return elements.stablyPartitioned(choosingStartGroupBy: p).lazy
   }
 }
 
 extension Collection {
-    /// Returns the index of the first element in the collection
-    /// that matches the predicate.
-    ///
-    /// The collection must already be partitioned according to the
-    /// predicate, as if `self.partition(by: predicate)` had already
-    /// been called.
-    func partitionPoint(
-        where predicate: (Iterator.Element) throws -> Bool
-        ) rethrows -> Index {
-        var n = distance(from: startIndex, to: endIndex)
-        var r = startIndex..<endIndex
+  /// Returns the index of the first element in the collection
+  /// that matches the predicate.
+  ///
+  /// The collection must already be partitioned according to the
+  /// predicate, as if `self.partition(by: predicate)` had already
+  /// been called.
+  func partitionPoint(
+    where predicate: (Element) throws -> Bool
+  ) rethrows -> Index {
+    var n = distance(from: startIndex, to: endIndex)
+    var l = startIndex
 
-        while n > 0 {
-            let half = n / 2
-            let mid = index(r.lowerBound, offsetBy: half)
-            if try predicate(self[mid]) {
-                r = r.lowerBound..<mid
-                n = half
-            }
-            else {
-                r = index(after: mid)..<r.upperBound
-                n -= half + 1
-            }
-        }
-        return r.lowerBound
+    while n > 0 {
+      let half = n / 2
+      let mid = index(l, offsetBy: half)
+      if try predicate(self[mid]) {
+        n = half
+      } else {
+        l = index(after: mid)
+        n -= half + 1
+      }
     }
+    return l
+  }
 }
 
 //===--- Tests ------------------------------------------------------------===//
 //===----------------------------------------------------------------------===//
 
+func address<T>(_ p: UnsafePointer<T>) -> UInt { return UInt(bitPattern: p )}
+
 var suite = TestSuite("Algorithms")
 
 suite.test("reverseSubrange") {
@@ -718,15 +674,20 @@
     let a = Array(0..<l)
 
     for p in a.startIndex...a.endIndex {
-      let prefix = a.prefix(upTo: p)
+      let prefix = a[..<p]
       for q in p...l {
-        let suffix = a.suffix(from: q)
+        let suffix = a[q...]
+
         var b = a
-        b.reverseSubrange(p..<q)
+        b.reserveCapacity(b.count)  // guarantee unique storage
+        let id = address(b)
+
+        b[p..<q].reverse()
         expectEqual(
           b,
           Array([prefix, ArraySlice(a[p..<q].reversed()), suffix].joined()))
-        }
+        expectEqual(address(b), id)
+      }
     }
   }
 }
@@ -736,21 +697,20 @@
     let a = Array(0..<l)
 
     for p in a.startIndex...a.endIndex {
-      let prefix = a.prefix(upTo: p)
+      let prefix = a[..<p]
       for q in p...l {
-        let suffix = a.suffix(from: q)
+        let suffix = a[q...]
 
         for m in p...q {
           var b = a
-          let r0 = b._rotateSubrangeForward(p..<q, shiftingToStart: m)
+          b.reserveCapacity(b.count)  // guarantee unique storage
+          let id = address(b)
+
+          let r = b[p..<q].rotate(shiftingToStart: m)
           let rotated = Array([prefix, a[m..<q], a[p..<m], suffix].joined())
           expectEqual(b, rotated)
-          expectEqual(r0, a.index(p, offsetBy: a[m..<q].count))
-
-          b = a
-          let r1 = b.rotateSubrange(p..<q, shiftingToStart: m)
-          expectEqual(b, rotated)
-          expectEqual(r1, r0)
+          expectEqual(r, a.index(p, offsetBy: a[m..<q].count))
+          expectEqual(address(b), id)
         }
       }
       var b = a
@@ -765,21 +725,20 @@
     let a = Array(0..<l)
 
     for p in a.startIndex...a.endIndex {
-      let prefix = a.prefix(upTo: p)
+      let prefix = a[..<p]
       for q in p...l {
-        let suffix = a.suffix(from: q)
+        let suffix = a[q...]
 
         for m in p...q {
           var b = a
-          let r0 = b[p..<q].rotateRandomAccess(shiftingToStart: m)
+          b.reserveCapacity(b.count)  // guarantee unique storage
+          let id = address(b)
+
+          let r = b[p..<q].rotateRandomAccess(shiftingToStart: m)
           let rotated = Array([prefix, a[m..<q], a[p..<m], suffix].joined())
           expectEqual(b, rotated)
-          expectEqual(r0, a.index(p, offsetBy: a[m..<q].count))
-
-          b = a
-          let r1 = b[p..<q].rotateRandomAccess(shiftingToStart: m)
-          expectEqual(b, rotated)
-          expectEqual(r1, r0)
+          expectEqual(r, a.index(p, offsetBy: a[m..<q].count))
+          expectEqual(address(b), id)
         }
       }
       var b = a
@@ -805,18 +764,19 @@
 
   let h = "Hello, "
   let w = "world!"
-  let hw = concatenate(h.characters, w.characters)
+  let hw = concatenate(h, w)
   expectEqual("Hello, world!", String(hw))
 }
 
 suite.test("stablePartition") {
+  // FIXME: add test for stability
   for l in 0..<13 {
     let a = Array(0..<l)
 
     for p in a.startIndex...a.endIndex {
-      let prefix = a.prefix(upTo: p)
+      let prefix = a[..<p]
       for q in p...l {
-        let suffix = a.suffix(from: q)
+        let suffix = a[q...]
 
         let subrange = a[p..<q]
 
@@ -825,15 +785,19 @@
           let notf = { !f($0) }
 
           var b = a
-          var r = b.stablyPartitionSubrange(p..<q, choosingStartGroupBy: f)
-          expectEqual(b.prefix(upTo:p), prefix)
+          b.reserveCapacity(b.count)  // guarantee unique storage
+          let id = address(b)
+
+          var r = b[p..<q].stablePartition(choosingStartGroupBy: f)
+          expectEqual(b[..<p], prefix)
           expectEqual(b.suffix(from:q), suffix)
           expectEqual(b[p..<r], ArraySlice(subrange.filter(f)))
           expectEqual(b[r..<q], ArraySlice(subrange.filter(notf)))
+          expectEqual(address(b), id)
 
           b = a
-          r = b.stablyPartitionSubrange(p..<q, choosingStartGroupBy: notf)
-          expectEqual(b.prefix(upTo:p), prefix)
+          r = b[p..<q].stablePartition(choosingStartGroupBy: notf)
+          expectEqual(b[..<p], prefix)
           expectEqual(b.suffix(from:q), suffix)
           expectEqual(b[p..<r], ArraySlice(subrange.filter(notf)))
           expectEqual(b[r..<q], ArraySlice(subrange.filter(f)))
@@ -845,13 +809,13 @@
         let notf = { !f($0) }
         var b = a
         var r = b.stablePartition(choosingStartGroupBy: f)
-        expectEqual(b.prefix(upTo: r), ArraySlice(a.filter(f)))
-        expectEqual(b.suffix(from: r), ArraySlice(a.filter(notf)))
+        expectEqual(b[..<r], ArraySlice(a.filter(f)))
+        expectEqual(b[r...], ArraySlice(a.filter(notf)))
 
         b = a
         r = b.stablePartition(choosingStartGroupBy: notf)
-        expectEqual(b.prefix(upTo: r), ArraySlice(a.filter(notf)))
-        expectEqual(b.suffix(from: r), ArraySlice(a.filter(f)))
+        expectEqual(b[..<r], ArraySlice(a.filter(notf)))
+        expectEqual(b[r...], ArraySlice(a.filter(f)))
       }
     }
   }
diff --git a/test/SIL/Parser/undef.sil b/test/SIL/Parser/undef.sil
index d589c60..bc5c7ba 100644
--- a/test/SIL/Parser/undef.sil
+++ b/test/SIL/Parser/undef.sil
@@ -105,8 +105,8 @@
   class_method undef : $C, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
   // CHECK: super_method undef : $D, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
   super_method undef : $D, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
-  // CHECK: dynamic_method undef : $C, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
-  dynamic_method undef : $C, #C.fn!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
+  // CHECK: objc_method undef : $C, #C.fn!1.foreign : (C) -> () -> (), $@convention(objc_method) (C) -> ()
+  objc_method undef : $C, #C.fn!1.foreign : (C) -> () -> (), $@convention(objc_method) (C) -> ()
 
   // Function Application
 
diff --git a/test/SIL/Serialization/Inputs/def_generic.swift b/test/SIL/Serialization/Inputs/def_generic.swift
index c55dc44..1fd5815 100644
--- a/test/SIL/Serialization/Inputs/def_generic.swift
+++ b/test/SIL/Serialization/Inputs/def_generic.swift
@@ -1,6 +1,12 @@
-class A<T> {
+public class A<T> {
   typealias Element = T
+  @_versioned
+  @_inlineable
   func convertFromArrayLiteral(_ elements: Element...) -> A {
     return A()
   }
+
+  @_versioned
+  @_inlineable
+  init() {}
 }
diff --git a/test/SIL/Serialization/Inputs/def_generic_marker.swift b/test/SIL/Serialization/Inputs/def_generic_marker.swift
index 086523b..fd195dd 100644
--- a/test/SIL/Serialization/Inputs/def_generic_marker.swift
+++ b/test/SIL/Serialization/Inputs/def_generic_marker.swift
@@ -13,6 +13,7 @@
   > (_ seq: S)
 }
 
+@_inlineable
 public func test<
   EC1 : mmCollectionType,
   EC2 : mmCollectionType
diff --git a/test/SIL/Serialization/Inputs/function_param_convention_input.sil b/test/SIL/Serialization/Inputs/function_param_convention_input.sil
index e1943e3..68bf46f 100644
--- a/test/SIL/Serialization/Inputs/function_param_convention_input.sil
+++ b/test/SIL/Serialization/Inputs/function_param_convention_input.sil
@@ -3,7 +3,7 @@
 
 // Make sure that we can deserialize an apply with various parameter calling
 // conventions.
-sil @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X {
+sil [serialized] @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X {
 bb0(%0 : $*X, %1 : $*X, %2 : $*X, %3 : $*X, %4 : $X, %5 : $X, %6 : $X):
   %9999 = tuple()
   return %9999 : $()
diff --git a/test/SIL/Serialization/Inputs/nontransparent.swift b/test/SIL/Serialization/Inputs/nontransparent.swift
index b19debc..314e0de 100644
--- a/test/SIL/Serialization/Inputs/nontransparent.swift
+++ b/test/SIL/Serialization/Inputs/nontransparent.swift
@@ -6,21 +6,27 @@
 }
 
 public struct B {
+  @_inlineable
   public func amIConfused() {}
+  @_inlineable
+  public init() {}
 }
 
 public struct A {
   public var b : B
 
+  @_inlineable
   public init() {
     b = B()
   }
 
+  @_inlineable
   public func isBConfused() {
     b.amIConfused()
   }
 }
 
+@_inlineable
 public func doSomething() -> A {
   var a = A()
   return a
diff --git a/test/SIL/Serialization/Inputs/shared_function_serialization_input.swift b/test/SIL/Serialization/Inputs/shared_function_serialization_input.swift
index 0f3d42d..1a00437 100644
--- a/test/SIL/Serialization/Inputs/shared_function_serialization_input.swift
+++ b/test/SIL/Serialization/Inputs/shared_function_serialization_input.swift
@@ -1,11 +1,14 @@
 
 public struct X {
+  @_inlineable
   public init() { }
 }
 
+@_inlineable
 @inline(never)
 public func the_thing<T>(t t : T) { }
 
+@_inlineable
 @inline(never)
 public func the_thing_it_does(x x : X) {
   the_thing(t: x)
diff --git a/test/SIL/Serialization/Inputs/specializer_input.swift b/test/SIL/Serialization/Inputs/specializer_input.swift
index 29a1a60..c55d1a6 100644
--- a/test/SIL/Serialization/Inputs/specializer_input.swift
+++ b/test/SIL/Serialization/Inputs/specializer_input.swift
@@ -2,8 +2,10 @@
 public typealias Int = Builtin.Int32
 
 public struct Container<V> {
+  @_inlineable
   @inline(never)
   public func doSomething() {}
+  @_inlineable
   @inline(never)
   public init() {}
 }
diff --git a/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift b/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift
index c6f7e9f..2370e6b 100644
--- a/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift
+++ b/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift
@@ -7,12 +7,15 @@
 func unknown() -> ()
 
 public class Y : P {
+  @_inlineable
   public func doAnotherThing() {
     unknown()
   }
 
+  @_inlineable
   public func doSomething() {
     doAnotherThing()
   }
+  @_inlineable
   public init() {}
 }
diff --git a/test/SIL/Serialization/basic.sil b/test/SIL/Serialization/basic.sil
index 9ac3d90..53d4603 100644
--- a/test/SIL/Serialization/basic.sil
+++ b/test/SIL/Serialization/basic.sil
@@ -7,17 +7,17 @@
 
 import Builtin
 
-// CHECK-LABEL: sil @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+// CHECK-LABEL: sil [serialized] @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
 // CHECK: unchecked_ownership_conversion {{%.*}} : $Builtin.NativeObject, @guaranteed to @owned
-sil @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+sil [serialized] @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
 bb0(%0 : $Builtin.NativeObject):
   unchecked_ownership_conversion %0 : $Builtin.NativeObject, @guaranteed to @owned
   return undef : $()
 }
 
-// CHECK-LABEL: sil @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// CHECK-LABEL: sil [serialized] @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
 // CHECK: end_lifetime {{%.*}} : $Builtin.NativeObject
-sil @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+sil [serialized] @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
 bb0(%0 : $Builtin.NativeObject):
   end_lifetime %0 : $Builtin.NativeObject
   return undef : $()
diff --git a/test/SIL/Serialization/borrow.sil b/test/SIL/Serialization/borrow.sil
index 8c45976..150bd63 100644
--- a/test/SIL/Serialization/borrow.sil
+++ b/test/SIL/Serialization/borrow.sil
@@ -10,7 +10,7 @@
 import Builtin
 
 // We do not verify here, but just make sure that all of the combinations parse and print correctly.
-// CHECK-LABEL: sil @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
+// CHECK-LABEL: sil [serialized] @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
 // CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.NativeObject, [[ARG2:%[0-9]+]] : $Builtin.NativeObject):
 // CHECK: begin_borrow [[ARG2]]
 // CHECK: [[MEM:%.*]] = alloc_stack $Builtin.NativeObject
@@ -19,7 +19,7 @@
 // CHECK: end_borrow [[ARG2]] from [[ARG1]] : $Builtin.NativeObject, $*Builtin.NativeObject
 // CHECK: end_borrow [[ARG1]] from [[ARG1]] : $*Builtin.NativeObject, $*Builtin.NativeObject
 // CHECK: end_borrow [[ARG2]] from [[ARG2]] : $Builtin.NativeObject, $Builtin.NativeObject
-sil @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
+sil [serialized] @borrow_test : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
 bb0(%0 : $*Builtin.NativeObject, %1 : $Builtin.NativeObject):
   %2 = begin_borrow %1 : $Builtin.NativeObject
   end_borrow %2 from %1 : $Builtin.NativeObject, $Builtin.NativeObject
diff --git a/test/SIL/Serialization/borrow_argument.sil b/test/SIL/Serialization/borrow_argument.sil
index b134fa2..f880601 100644
--- a/test/SIL/Serialization/borrow_argument.sil
+++ b/test/SIL/Serialization/borrow_argument.sil
@@ -9,10 +9,10 @@
 
 import Builtin
 
-// CHECK-LABEL: sil @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+// CHECK-LABEL: sil [serialized] @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
 // CHECK: bb1([[PHIBBARG:%.*]] : @guaranteed $Builtin.NativeObject):
 // CHECK: end_borrow_argument [[PHIBBARG]] : $Builtin.NativeObject
-sil @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+sil [serialized] @borrow_argument_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
 bb0(%0 : @guaranteed $Builtin.NativeObject):
   br bb1(%0 : $Builtin.NativeObject)
 
diff --git a/test/SIL/Serialization/boxes.sil b/test/SIL/Serialization/boxes.sil
index 3a03fb7..db95f6a 100644
--- a/test/SIL/Serialization/boxes.sil
+++ b/test/SIL/Serialization/boxes.sil
@@ -16,8 +16,8 @@
 
 // TODO: Transform boxes by transforming their arguments, not as single-field,
 // so that they work as parameters in generic SIL functions.
-// CHECK-LABEL: sil hidden @box_type_parsing : $@convention(thin) (
-sil hidden @box_type_parsing : $@convention(thin) (
+// CHECK-LABEL: sil hidden [serialized] @box_type_parsing : $@convention(thin) (
+sil hidden [serialized] @box_type_parsing : $@convention(thin) (
   // CHECK: <τ_0_0> { var τ_0_0 } <F>,
   <B>{ var B }<F>,
   // CHECK: <τ_0_0 where τ_0_0 : P> { let τ_0_0 } <G>,
@@ -38,8 +38,8 @@
   unreachable
 }
 
-// CHECK-LABEL: sil hidden @box_type_parsing_in_generic_function : $@convention(thin) <F, G where G : P> (
-sil hidden @box_type_parsing_in_generic_function : $@convention(thin) <F, G: P> (
+// CHECK-LABEL: sil hidden [serialized] @box_type_parsing_in_generic_function : $@convention(thin) <F, G where G : P> (
+sil hidden [serialized] @box_type_parsing_in_generic_function : $@convention(thin) <F, G: P> (
   // CHECK: <τ_0_0> { var τ_0_0 } <F>,
   <B>{ var B }<F>,
   // CHECK: <τ_0_0 where τ_0_0 : P> { let τ_0_0 } <G>,
@@ -60,8 +60,8 @@
   unreachable
 }
 
-// CHECK-LABEL: sil hidden @same_generic_param_name_in_multiple_box_signatures : $@convention(thin) (
-sil hidden @same_generic_param_name_in_multiple_box_signatures : $@convention(thin) (
+// CHECK-LABEL: sil hidden [serialized] @same_generic_param_name_in_multiple_box_signatures : $@convention(thin) (
+sil hidden [serialized] @same_generic_param_name_in_multiple_box_signatures : $@convention(thin) (
   // CHECK: <τ_0_0> { var τ_0_0 } <Int>,
   <A> { var A } <Int>,
   // CHECK: <τ_0_0> { var τ_0_0 } <String>
@@ -72,8 +72,8 @@
   unreachable
 }
 
-// CHECK-LABEL: sil hidden @same_generic_param_name_in_outer_scope : $@convention(thin) <A> (
-sil hidden @same_generic_param_name_in_outer_scope : $@convention(thin) <A> (
+// CHECK-LABEL: sil hidden [serialized] @same_generic_param_name_in_outer_scope : $@convention(thin) <A> (
+sil hidden [serialized] @same_generic_param_name_in_outer_scope : $@convention(thin) <A> (
   // CHECK: <τ_0_0> { var τ_0_0 } <A>
   <A> { var A } <A>
 // CHECK: ) -> ()
@@ -82,20 +82,20 @@
   unreachable
 }
 
-// CHECK-LABEL: sil hidden @box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <τ_0_0> { let τ_0_0 } <Int>) -> ()
-sil hidden @box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <T> { let T } <Int>) -> () {
+// CHECK-LABEL: sil hidden [serialized] @box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <τ_0_0> { let τ_0_0 } <Int>) -> ()
+sil hidden [serialized ]@box_ownership : $@convention(thin) (@owned { var Int }, @guaranteed <T> { let T } <Int>) -> () {
 entry(%0 : ${ var Int }, %1 : $<T> { let T } <Int>):
   unreachable
 }
 
-// CHECK-LABEL: sil hidden @address_of_box
-sil hidden @address_of_box : $@convention(thin) (@in { var Int }, @in <T> { let T } <Int>) -> () {
+// CHECK-LABEL: sil hidden [serialized] @address_of_box
+sil hidden [serialized] @address_of_box : $@convention(thin) (@in { var Int }, @in <T> { let T } <Int>) -> () {
 // CHECK: %0 : $*{ var Int }, %1 : $*<τ_0_0> { let τ_0_0 } <Int>
 entry(%0 : $*{ var Int }, %1 : $*<T> { let T } <Int>):
   unreachable
 }
 
-sil @serialize_all : $@convention(thin) () -> () {
+sil [serialized] @serialize_all : $@convention(thin) () -> () {
 entry:
   %0 = function_ref @box_type_parsing : $@convention(thin) (<B>{ var B }<F>, <C: P>{ let C }<G>, <D: P>{ var D }<Q>, { let Int }, { var Int, let String }, {}, <X, Y, Z>{ var X, let Z }<Int, String, Optional<Double>>) -> ()
   %1 = function_ref @box_type_parsing_in_generic_function : $@convention(thin) <F, G: P> (<B>{ var B }<F>, <C: P>{ let C }<G>, <D: P>{ var D }<Q>, { let Int }, { var Int, let String }, {}, <X, Y, Z>{ var X, let Z }<Int, String, Optional<Double>>) -> ()
diff --git a/test/SIL/Serialization/copy_value_destroy_value.sil b/test/SIL/Serialization/copy_value_destroy_value.sil
index 0891225..0833b3b 100644
--- a/test/SIL/Serialization/copy_value_destroy_value.sil
+++ b/test/SIL/Serialization/copy_value_destroy_value.sil
@@ -10,24 +10,24 @@
 import Builtin
 
 
-// CHECK-LABEL: sil @test_copy_unowned_value : $@convention(thin) (@owned @sil_unowned Builtin.NativeObject) -> @owned Builtin.NativeObject {
+// CHECK-LABEL: sil [serialized] @test_copy_unowned_value : $@convention(thin) (@owned @sil_unowned Builtin.NativeObject) -> @owned Builtin.NativeObject {
 // CHECK: bb0([[T0:%[0-9]+]] : $@sil_unowned Builtin.NativeObject):
 // CHECK-NEXT: [[COPY_RESULT:%.*]] = copy_unowned_value [[T0]] : $@sil_unowned Builtin.NativeObject
 // CHECK-NEXT: destroy_value [[T0]] : $@sil_unowned Builtin.NativeObject
 // CHECK-NEXT: return [[COPY_RESULT]] : $Builtin.NativeObject
-sil @test_copy_unowned_value : $@convention(thin) (@owned @sil_unowned Builtin.NativeObject) -> @owned Builtin.NativeObject {
+sil [serialized] @test_copy_unowned_value : $@convention(thin) (@owned @sil_unowned Builtin.NativeObject) -> @owned Builtin.NativeObject {
 bb0(%0 : $@sil_unowned Builtin.NativeObject):
   %1 = copy_unowned_value %0 : $@sil_unowned Builtin.NativeObject
   destroy_value %0 : $@sil_unowned Builtin.NativeObject
   return %1 : $Builtin.NativeObject
 }
 
-// CHECK-LABEL: sil @test : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
+// CHECK-LABEL: sil [serialized] @test : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
 // CHECK: bb0([[ARG1:%[0-9]+]] : $Builtin.NativeObject):
 // CHECK: [[COPY_VALUE_RESULT:%[0-9]+]] = copy_value [[ARG1]] : $Builtin.NativeObject
 // CHECK: destroy_value [[ARG1]]
 // CHECK: return [[COPY_VALUE_RESULT]]
-sil @test : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
+sil [serialized] @test : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
 bb0(%0 : $Builtin.NativeObject):
   %1 = copy_value %0 : $Builtin.NativeObject
   destroy_value %0 : $Builtin.NativeObject
diff --git a/test/SIL/Serialization/deserialize_generic.sil b/test/SIL/Serialization/deserialize_generic.sil
index 9aacd80..45b841b 100644
--- a/test/SIL/Serialization/deserialize_generic.sil
+++ b/test/SIL/Serialization/deserialize_generic.sil
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -sil-serialize-all -o %t %S/Inputs/def_generic.swift
+// RUN: %target-swift-frontend -emit-module -sil-serialize-witness-tables -sil-serialize-vtables -o %t %S/Inputs/def_generic.swift
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -linker -I %t %s | %FileCheck %s
 
 // Make sure that SILFunctionType with GenericSignature can match up with
diff --git a/test/SIL/Serialization/deserialize_generic_marker.sil b/test/SIL/Serialization/deserialize_generic_marker.sil
index 0ae91fa..dfbcf0c 100644
--- a/test/SIL/Serialization/deserialize_generic_marker.sil
+++ b/test/SIL/Serialization/deserialize_generic_marker.sil
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -sil-serialize-all -o %t %S/Inputs/def_generic_marker.swift
+// RUN: %target-swift-frontend -emit-module -sil-serialize-witness-tables -sil-serialize-vtables -o %t %S/Inputs/def_generic_marker.swift
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -linker -I %t %s | %FileCheck %s
 
 // Make sure that SILFunctionType with GenericSignature can match up with
diff --git a/test/SIL/Serialization/function_param_convention.sil b/test/SIL/Serialization/function_param_convention.sil
index 90da2d9..9d6c7f7 100644
--- a/test/SIL/Serialization/function_param_convention.sil
+++ b/test/SIL/Serialization/function_param_convention.sil
@@ -1,12 +1,12 @@
 // 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 -sil-serialize-all -O
+// 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 -sil-serialize-witness-tables -sil-serialize-vtables -O
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -I %t -linker %s -o - | %FileCheck %s
 
 import Swift
 import FunctionInput
 
 // Make sure we can deserialize a SIL function with these various attributes.
-// CHECK: sil public_external @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X {
+// CHECK: sil public_external [serialized] @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X {
 
 sil @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X
 
diff --git a/test/SIL/Serialization/init_existential_inst_deserializes_witness_tables.swift b/test/SIL/Serialization/init_existential_inst_deserializes_witness_tables.swift
index 60dd798..0a98465 100644
--- a/test/SIL/Serialization/init_existential_inst_deserializes_witness_tables.swift
+++ b/test/SIL/Serialization/init_existential_inst_deserializes_witness_tables.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -sil-inline-threshold 0 %S/Inputs/init_existential_inst_deserializes_witness_tables_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift -sil-serialize-all -O
+// RUN: %target-swift-frontend -sil-inline-threshold 0 %S/Inputs/init_existential_inst_deserializes_witness_tables_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift -sil-serialize-witness-tables -O
 // RUN: %target-swift-frontend -I %t -O %s -emit-sil -o - | %FileCheck %s
 
 // CHECK: sil_witness_table public_external [serialized] X: P module Swift {
diff --git a/test/SIL/Serialization/keypath.sil b/test/SIL/Serialization/keypath.sil
index 53989c9..b38d742 100644
--- a/test/SIL/Serialization/keypath.sil
+++ b/test/SIL/Serialization/keypath.sil
@@ -41,8 +41,8 @@
   var z: C
 }
 
-// CHECK-LABEL: sil shared @stored_properties
-sil shared @stored_properties : $@convention(thin) () -> () {
+// CHECK-LABEL: sil shared [serialized] @stored_properties
+sil shared [serialized] @stored_properties : $@convention(thin) () -> () {
 entry:
   // CHECK: keypath $WritableKeyPath<S, Int>, (root $S; stored_property #S.x : $Int)
   %a = keypath $WritableKeyPath<S, Int>, (root $S; stored_property #S.x : $Int)
@@ -56,8 +56,8 @@
   return undef : $()
 }
 
-// CHECK-LABEL: sil shared @stored_properties_generic
-sil shared @stored_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> () {
+// CHECK-LABEL: sil shared [serialized] @stored_properties_generic
+sil shared [serialized] @stored_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> () {
 entry:
   // CHECK: keypath $WritableKeyPath<Gen<D, E, F>, D>, <τ_0_0, τ_0_1, τ_0_2 where {{.*}}> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; stored_property #Gen.x : $τ_0_0) <D, E, F>
   %a = keypath $WritableKeyPath<Gen<D,E,F>, D>, <G: P, H: Q, I: R> (root $Gen<G, H, I>; stored_property #Gen.x : $G) <D, E, F>
@@ -83,8 +83,8 @@
 sil @gen_subs_eq : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool
 sil @gen_subs_hash : $@convention(thin) <A: Hashable, B: Hashable, C: Hashable> (UnsafeRawPointer) -> Int
 
-// CHECK-LABEL: sil shared @computed_properties
-sil shared @computed_properties : $@convention(thin) () -> () {
+// CHECK-LABEL: sil shared [serialized] @computed_properties
+sil shared [serialized] @computed_properties : $@convention(thin) () -> () {
 entry:
   // CHECK: keypath $KeyPath<S, Int>, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in S) -> @out Int)
   %a = keypath $KeyPath<S, Int>, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in S) -> @out Int)
@@ -101,8 +101,8 @@
 sil @get_gen_a : $@convention(thin) <X1: P, Y1: Q, Z1: R> (@in Gen<X1, Y1, Z1>) -> @out X1
 sil @set_gen_a : $@convention(thin) <X2: P, Y2: Q, Z2: R> (@in X2, @in Gen<X2, Y2, Z2>) -> ()
 
-// CHECK-LABEL: sil shared @computed_properties_generic
-sil shared @computed_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> () {
+// CHECK-LABEL: sil shared [serialized] @computed_properties_generic
+sil shared [serialized] @computed_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> () {
 entry:
   // CHECK: keypath $KeyPath<Gen<D, E, F>, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in τ_0_0, @in Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) <D, E, F>
   %a = keypath $KeyPath<Gen<D, E, F>, D>, <G: P, H: Q, I: R> (root $Gen<G, H, I>; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <X3: P, Y3: Q, Z3: R> (@in Gen<X3, Y3, Z3>) -> @out X3, setter @set_gen_a : $@convention(thin) <X4: P, Y4: Q, Z4: R> (@in X4, @in Gen<X4, Y4, Z4>) -> ()) <D, E, F>
@@ -110,8 +110,8 @@
   return undef : $()
 }
 
-// CHECK-LABEL: sil shared @optional
-sil shared @optional : $@convention(thin) () -> () {
+// CHECK-LABEL: sil shared [serialized] @optional
+sil shared [serialized] @optional : $@convention(thin) () -> () {
 entry:
   // CHECK: keypath $KeyPath<Optional<Int>, Optional<Int>>, (root $Optional<Int>; optional_chain : $Int; optional_wrap : $Optional<Int>)
   %a = keypath $KeyPath<Optional<Int>, Optional<Int>>, (root $Optional<Int>; optional_chain : $Int; optional_wrap : $Optional<Int>)
@@ -121,8 +121,8 @@
   return undef : $()
 }
 
-// CHECK-LABEL: sil shared @indexes
-sil shared @indexes : $@convention(thin) (S, C) -> () {
+// CHECK-LABEL: sil shared [serialized] @indexes
+sil shared [serialized] @indexes : $@convention(thin) (S, C) -> () {
 // CHECK: bb0([[S:%.*]] : $S, [[C:%.*]] : $C):
 entry(%s : $S, %c : $C):
   // CHECK: keypath $KeyPath<S, Int>, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in Int, @in S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) ([[S]], [[C]])
@@ -140,7 +140,7 @@
   return undef : $()
 }
 
-sil @serialize_all : $@convention(thin) () -> () {
+sil [serialized] @serialize_all : $@convention(thin) () -> () {
 entry:
   %0 = function_ref @stored_properties : $@convention(thin) () -> ()
   %1 = function_ref @stored_properties_generic : $@convention(thin) <D: P, E: Q, F: R> () -> ()
diff --git a/test/SIL/Serialization/literals.sil b/test/SIL/Serialization/literals.sil
index 40ba997..9191fee 100644
--- a/test/SIL/Serialization/literals.sil
+++ b/test/SIL/Serialization/literals.sil
@@ -7,7 +7,7 @@
 
 sil_stage canonical
 
-sil @test : $@convention(thin) () -> () {
+sil [serialized] @test : $@convention(thin) () -> () {
 bb0:
 // CHECK: string_literal utf8 "\u{0B}"
   %1 = string_literal utf8 "\u{0B}"
diff --git a/test/SIL/Serialization/opaque_values_serialize.sil b/test/SIL/Serialization/opaque_values_serialize.sil
index bb7ea3a..ecb09fa 100644
--- a/test/SIL/Serialization/opaque_values_serialize.sil
+++ b/test/SIL/Serialization/opaque_values_serialize.sil
@@ -20,22 +20,22 @@
   init()
 }
 
-// CHECK-LABEL: sil @castOpaque : $@convention(thin) (Int) -> () {
+// CHECK-LABEL: sil [serialized] @castOpaque : $@convention(thin) (Int) -> () {
 // CHECK: bb0([[ARG:%.*]] : $Int):
 // CHECK:  unconditional_checked_cast_value [[ARG]] : $Int to $Foo
 // CHECK-LABEL: } // end sil function 'castOpaque'
-sil @castOpaque : $@convention(thin) (Int) -> () {
+sil [serialized] @castOpaque : $@convention(thin) (Int) -> () {
 bb0(%0 : $Int):
   %c = unconditional_checked_cast_value %0 : $Int to $Foo
   %t = tuple ()
   return %t : $()
 }
 
-// CHECK-LABEL: sil @condCastOpaque : $@convention(thin) (Int) -> () {
+// CHECK-LABEL: sil [serialized] @condCastOpaque : $@convention(thin) (Int) -> () {
 // CHECK: bb0([[ARG:%.*]] : $Int):
 // CHECK:  checked_cast_value_br [[ARG]] : $Int to $Int
 // CHECK-LABEL: } // end sil function 'condCastOpaque'
-sil @condCastOpaque : $@convention(thin) (Int) -> () {
+sil [serialized] @condCastOpaque : $@convention(thin) (Int) -> () {
 bb0(%0 : $Int):
   checked_cast_value_br %0 : $Int to $Int, bb2, bb1
 
@@ -50,12 +50,12 @@
   return %t : $()
 }
 
-// CHECK-LABEL: sil @initDeinitExistentialValue : $@convention(thin) <T> (@in T) -> () {
+// CHECK-LABEL: sil [serialized] @initDeinitExistentialValue : $@convention(thin) <T> (@in T) -> () {
 // CHECK: bb0([[ARG:%.*]] : $T):
 // CHECK:  [[IE:%.*]] = init_existential_value [[ARG]] : $T, $T, $Any
 // CHECK:  deinit_existential_value [[IE]] : $Any
 // CHECK-LABEL: } // end sil function 'initDeinitExistentialValue'
-sil @initDeinitExistentialValue : $@convention(thin) <T> (@in T) -> () {
+sil [serialized] @initDeinitExistentialValue : $@convention(thin) <T> (@in T) -> () {
 bb0(%0 : $T):
   %i = init_existential_value %0 : $T, $T, $Any
   deinit_existential_value %i : $Any
@@ -63,22 +63,22 @@
   return %t : $()
 }
 
-// CHECK-LABEL: sil @openExistentialBoxValue : $@convention(thin) (@in Error) -> () {
+// CHECK-LABEL: sil [serialized] @openExistentialBoxValue : $@convention(thin) (@in Error) -> () {
 // CHECK: bb0([[ARG:%.*]] : $Error):
 // CHECK:  open_existential_box_value [[ARG]] : $Error to $@opened({{.*}}) Error
 // CHECK-LABEL: } // end sil function 'openExistentialBoxValue'
-sil @openExistentialBoxValue : $@convention(thin) (@in Error) -> () {
+sil [serialized] @openExistentialBoxValue : $@convention(thin) (@in Error) -> () {
 bb0(%0 : $Error):
   %o = open_existential_box_value %0 : $Error to $@opened("2E9EACA6-FD59-11E6-B016-685B3593C495") Error
   %t = tuple ()
   return %t : $()
 }
 
-// CHECK-LABEL: sil @openExistentialValue : $@convention(thin) (@in Foo) -> () {
+// CHECK-LABEL: sil [serialized] @openExistentialValue : $@convention(thin) (@in Foo) -> () {
 // CHECK: bb0([[ARG:%.*]] : $Foo):
 // CHECK:  open_existential_value [[ARG]] : $Foo to $@opened({{.*}}) Foo
 // CHECK-LABEL: } // end sil function 'openExistentialValue'
-sil @openExistentialValue : $@convention(thin) (@in Foo) -> () {
+sil [serialized] @openExistentialValue : $@convention(thin) (@in Foo) -> () {
 bb0(%0 : $Foo):
   %o = open_existential_value %0 : $Foo to $@opened("2E9EACA6-FD59-11E6-B016-685B3593C496") Foo
   %t = tuple ()
@@ -88,8 +88,8 @@
 // Test @in/@out serialization.
 // ----
 
-// CHECK-LABEL: sil hidden @serialize_identity : $@convention(thin) <T> (@in T) -> @out T {
-sil hidden @serialize_identity : $@convention(thin) <T> (@in T) -> @out T {
+// CHECK-LABEL: sil hidden [serialized] @serialize_identity : $@convention(thin) <T> (@in T) -> @out T {
+sil hidden [serialized] @serialize_identity : $@convention(thin) <T> (@in T) -> @out T {
 // CHECK: bb0(%0 : $T):
 bb0(%0 : $T):
   // CHECK: return %0 : $T
@@ -102,8 +102,8 @@
 
 sil @doWithS : $@convention(method) (S) -> ()
 
-// CHECK-LABEL: sil hidden [transparent] [thunk] @serialize_mutating : $@convention(witness_method) (@in_guaranteed S) -> () {
-sil hidden [transparent] [thunk] @serialize_mutating : $@convention(witness_method) (@in_guaranteed S) -> () {
+// CHECK-LABEL: sil hidden [transparent] [serialized] [thunk] @serialize_mutating : $@convention(witness_method) (@in_guaranteed S) -> () {
+sil hidden [transparent] [serialized] [thunk] @serialize_mutating : $@convention(witness_method) (@in_guaranteed S) -> () {
 // CHECK: bb0(%0 : $S):
 bb0(%0 : $S):
   %f = function_ref @doWithS : $@convention(method) (S) -> ()
diff --git a/test/SIL/Serialization/ownership_qualified_memopts.sil b/test/SIL/Serialization/ownership_qualified_memopts.sil
index 5e7f446..67a5f4f 100644
--- a/test/SIL/Serialization/ownership_qualified_memopts.sil
+++ b/test/SIL/Serialization/ownership_qualified_memopts.sil
@@ -10,11 +10,11 @@
 import Builtin
 
 
-// CHECK-LABEL: sil @trivial : $@convention(thin) (@in Builtin.Int32, Builtin.Int32) -> () {
+// CHECK-LABEL: sil [serialized] @trivial : $@convention(thin) (@in Builtin.Int32, Builtin.Int32) -> () {
 // CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.Int32, [[ARG2:%[0-9]+]] : $Builtin.Int32):
 // CHECK: load [trivial] [[ARG1]] : $*Builtin.Int32
 // CHECK: store [[ARG2]] to [trivial] [[ARG1]] : $*Builtin.Int32
-sil @trivial : $@convention(thin) (@in Builtin.Int32, Builtin.Int32) -> () {
+sil [serialized] @trivial : $@convention(thin) (@in Builtin.Int32, Builtin.Int32) -> () {
 bb0(%0 : $*Builtin.Int32, %1 : $Builtin.Int32):
   load [trivial] %0 : $*Builtin.Int32
   store %1 to [trivial] %0 : $*Builtin.Int32
@@ -22,13 +22,13 @@
   return %2 : $()
 }
 
-// CHECK-LABEL: sil @non_trivial : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
+// CHECK-LABEL: sil [serialized] @non_trivial : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
 // CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.NativeObject, [[ARG2:%[0-9]+]] : $Builtin.NativeObject):
 // CHECK: load [take] [[ARG1]] : $*Builtin.NativeObject
 // CHECK: load [copy] [[ARG1]] : $*Builtin.NativeObject
 // CHECK: store [[ARG2]] to [init] [[ARG1]] : $*Builtin.NativeObject
 // CHECK: store [[ARG2]] to [assign] [[ARG1]] : $*Builtin.NativeObject
-sil @non_trivial : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
+sil [serialized] @non_trivial : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () {
 bb0(%0 : $*Builtin.NativeObject, %1 : $Builtin.NativeObject):
   load [take] %0 : $*Builtin.NativeObject
   load [copy] %0 : $*Builtin.NativeObject
diff --git a/test/SIL/Serialization/perf_inline_without_inline_all.swift b/test/SIL/Serialization/perf_inline_without_inline_all.swift
index d11e748..b2d516d 100644
--- a/test/SIL/Serialization/perf_inline_without_inline_all.swift
+++ b/test/SIL/Serialization/perf_inline_without_inline_all.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module %S/Inputs/nontransparent.swift -O -sil-serialize-all -parse-stdlib -parse-as-library -emit-module -o %t/Swift.swiftmodule -module-name=Swift -module-link-name swiftCore
+// RUN: %target-swift-frontend -emit-module %S/Inputs/nontransparent.swift -O -sil-serialize-witness-tables -sil-serialize-vtables -parse-stdlib -parse-as-library -emit-module -o %t/Swift.swiftmodule -module-name=Swift -module-link-name swiftCore
 // RUN: %target-swift-frontend %s -O -I %t -emit-sil -o - | %FileCheck %s
 
 import Swift
diff --git a/test/SIL/Serialization/projection_lowered_type_parse.sil b/test/SIL/Serialization/projection_lowered_type_parse.sil
index 5676871..c6d3cd5 100644
--- a/test/SIL/Serialization/projection_lowered_type_parse.sil
+++ b/test/SIL/Serialization/projection_lowered_type_parse.sil
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-module %s -module-name Swift -sil-serialize-all -module-link-name swiftCore -parse-as-library -parse-sil -parse-stdlib -o - | %target-sil-opt -assume-parsing-unqualified-ownership-sil -module-name=Swift
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-module %s -module-name Swift -sil-serialize-witness-tables -sil-serialize-vtables -module-link-name swiftCore -parse-as-library -parse-sil -parse-stdlib -o - | %target-sil-opt -assume-parsing-unqualified-ownership-sil -module-name=Swift
 
 struct A {
   var f : () -> ()
diff --git a/test/SIL/Serialization/public_external.sil b/test/SIL/Serialization/public_external.sil
index d20b528..8143158 100644
--- a/test/SIL/Serialization/public_external.sil
+++ b/test/SIL/Serialization/public_external.sil
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -Xllvm -sil-disable-pass="External Definition To Declaration" -parse-sil -emit-module -module-name Swift -module-link-name swiftCore -parse-stdlib -parse-as-library -sil-serialize-all -o - | %target-sil-opt -assume-parsing-unqualified-ownership-sil -module-name Swift -emit-sorted-sil | %FileCheck %s
+// RUN: %target-swift-frontend %s -Xllvm -sil-disable-pass="External Definition To Declaration" -parse-sil -emit-module -module-name Swift -module-link-name swiftCore -parse-stdlib -parse-as-library -sil-serialize-witness-tables -sil-serialize-vtables -o - | %target-sil-opt -assume-parsing-unqualified-ownership-sil -module-name Swift -emit-sorted-sil | %FileCheck %s
 
 sil_stage raw
 import Builtin
@@ -110,7 +110,7 @@
 
 // The body of this fragile function has to be emitted.
 // CHECK-LABEL: sil{{.*}}@use_external_functions : $@convention(thin) () -> () {
-sil @use_external_functions: $@convention(thin) () -> () {
+sil [serialized] @use_external_functions: $@convention(thin) () -> () {
   %0 = function_ref @public_external_fn : $@convention(thin) () -> ()
   %1 = apply %0 () : $@convention(thin) () -> ()
 
diff --git a/test/SIL/Serialization/semanticsattr.sil b/test/SIL/Serialization/semanticsattr.sil
index a4edaf2..b5b2ea2 100644
--- a/test/SIL/Serialization/semanticsattr.sil
+++ b/test/SIL/Serialization/semanticsattr.sil
@@ -10,16 +10,16 @@
 @_semantics("123") @_semantics("456")
 func semanticsFunction() -> Builtin.Int64
 
-// CHECK: sil [_semantics "789"] [_semantics "ABC"] @foo1 : $@convention(thin) () -> () {
-sil public [_semantics "789"] [_semantics "ABC"] @foo1 : $@convention(thin) () -> () {
+// CHECK: sil [serialized] [_semantics "789"] [_semantics "ABC"] @foo1 : $@convention(thin) () -> () {
+sil public [serialized] [_semantics "789"] [_semantics "ABC"] @foo1 : $@convention(thin) () -> () {
 bb0:
   return undef : $()
 }
 
 // Make sure that we can parse with multiple generics that are after the semantic attributes.
 //
-// CHECK: sil [_semantics "DEF"] [_semantics "GHI"] @foo2 : $@convention(thin) <T1, T2> () -> () {
-sil public [_semantics "DEF"] [_semantics "GHI"] @foo2 : $@convention(thin) <T1, T2> () -> () {
+// CHECK: sil [serialized] [_semantics "DEF"] [_semantics "GHI"] @foo2 : $@convention(thin) <T1, T2> () -> () {
+sil public [serialized] [_semantics "DEF"] [_semantics "GHI"] @foo2 : $@convention(thin) <T1, T2> () -> () {
 bb0:
   return undef : $()
 }
diff --git a/test/SIL/Serialization/shared_function_serialization.sil b/test/SIL/Serialization/shared_function_serialization.sil
index 5de0b23..5c873d8 100644
--- a/test/SIL/Serialization/shared_function_serialization.sil
+++ b/test/SIL/Serialization/shared_function_serialization.sil
@@ -1,5 +1,5 @@
 // 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 -sil-serialize-all -O
+// 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 -sil-serialize-witness-tables -sil-serialize-vtables -O
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -I %t -linker -inline %s -o - | %FileCheck %s
 
 // CHECK: sil private @top_level_code
diff --git a/test/SIL/Serialization/specializer_can_deserialize.swift b/test/SIL/Serialization/specializer_can_deserialize.swift
index 708bd61..44c79b4 100644
--- a/test/SIL/Serialization/specializer_can_deserialize.swift
+++ b/test/SIL/Serialization/specializer_can_deserialize.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module %S/Inputs/specializer_input.swift -O -sil-serialize-all -parse-stdlib -parse-as-library -emit-module -o %t/Swift.swiftmodule -module-name=Swift -module-link-name swiftCore 
+// RUN: %target-swift-frontend -emit-module %S/Inputs/specializer_input.swift -O -sil-serialize-witness-tables -sil-serialize-vtables -parse-stdlib -parse-as-library -emit-module -o %t/Swift.swiftmodule -module-name=Swift -module-link-name swiftCore 
 // RUN: %target-swift-frontend %s -O -I %t -emit-sil -o - | %FileCheck %s
 
 import Swift
diff --git a/test/SIL/Serialization/unmanaged.sil b/test/SIL/Serialization/unmanaged.sil
index 79cc3a2..ead2d22 100644
--- a/test/SIL/Serialization/unmanaged.sil
+++ b/test/SIL/Serialization/unmanaged.sil
@@ -10,13 +10,13 @@
 
 class C {}
 
-// CHECK-LABEL: sil @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
+// CHECK-LABEL: sil [serialized] @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
 // CHECK: bb0([[ARG:%.*]] : $@sil_unmanaged Optional<C>):
 // CHECK: [[REF:%.*]] = unmanaged_to_ref [[ARG]] : $@sil_unmanaged Optional<C> to $Optional<C>
 // CHECK: unmanaged_retain_value [[REF]]
 // CHECK: unmanaged_autorelease_value [[REF]]
 // CHECK: unmanaged_release_value [[REF]]
-sil @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
+sil [serialized] @retain_release : $@convention(thin) (@sil_unmanaged Optional<C>) -> () {
 bb0(%0 : $@sil_unmanaged Optional<C>):
   %1 = unmanaged_to_ref %0 : $@sil_unmanaged Optional<C> to $Optional<C>
   unmanaged_retain_value %1 : $Optional<C>
@@ -26,13 +26,13 @@
   return %9999 : $()
 }
 
-// CHECK-LABEL: sil @test : $@convention(thin) <U where U : AnyObject> (@inout Optional<U>) -> () {
+// CHECK-LABEL: sil [serialized] @test : $@convention(thin) <U where U : AnyObject> (@inout Optional<U>) -> () {
 // CHECK: bb0([[ARG:%.*]] : $*Optional<U>):
 // CHECK: [[LOADED_ARG:%.*]] = load [copy] [[ARG]]
 // CHECK: [[UNMANAGED_LOADED_ARG:%.*]] = ref_to_unmanaged [[LOADED_ARG]] : $Optional<U> to $@sil_unmanaged Optional<U>
 // CHECK: {{%.*}} = unmanaged_to_ref [[UNMANAGED_LOADED_ARG]] : $@sil_unmanaged Optional<U> to $Optional<U>
 // CHECK: destroy_value [[LOADED_ARG]]
-sil @test : $@convention(thin) <U where U : AnyObject> (@inout Optional<U>) -> () {
+sil [serialized] @test : $@convention(thin) <U where U : AnyObject> (@inout Optional<U>) -> () {
 bb0(%0 : $*Optional<U>):
   %1 = load [copy] %0 : $*Optional<U>
   %2 = ref_to_unmanaged %1 : $Optional<U> to $@sil_unmanaged Optional<U>
diff --git a/test/SIL/Serialization/visibility.sil b/test/SIL/Serialization/visibility.sil
index c31a381..0e56db2 100644
--- a/test/SIL/Serialization/visibility.sil
+++ b/test/SIL/Serialization/visibility.sil
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -Xllvm -sil-disable-pass="External Definition To Declaration" -parse-sil -sil-serialize-all -emit-module -o - -module-name Swift -module-link-name swiftCore -parse-as-library -parse-stdlib | %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=false -module-name Swift > %t.sil
+// RUN: %target-swift-frontend %s -Xllvm -sil-disable-pass="External Definition To Declaration" -parse-sil -sil-serialize-witness-tables -emit-module -o - -module-name Swift -module-link-name swiftCore -parse-as-library -parse-stdlib | %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=false -module-name Swift > %t.sil
 // RUN: %FileCheck %s < %t.sil
 // RUN: %FileCheck -check-prefix=NEG-CHECK %s < %t.sil
 
@@ -212,7 +212,7 @@
   return %8 : $()
 }
 
-sil @hidden_external_function_test_caller : $@convention(thin) () -> () {
+sil [serialized] @hidden_external_function_test_caller : $@convention(thin) () -> () {
   %0 = function_ref @hidden_external_function_test : $@convention(thin) () -> ()
   %1 = apply %0() : $@convention(thin) () -> ()
   %2 = tuple()
@@ -240,7 +240,7 @@
   return %8 : $()
 }
 
-sil @public_external_function_test_caller : $@convention(thin) () -> () {
+sil [serialized] @public_external_function_test_caller : $@convention(thin) () -> () {
   %0 = function_ref @public_external_function_test : $@convention(thin) () -> ()
   %1 = apply %0() : $@convention(thin) () -> ()
   %2 = tuple()
@@ -268,7 +268,7 @@
   return %8 : $()
 }
 
-sil @shared_external_function_test_caller : $@convention(thin) () -> () {
+sil [serialized] @shared_external_function_test_caller : $@convention(thin) () -> () {
   %0 = function_ref @shared_external_function_test : $@convention(thin) () -> ()
   %1 = apply %0() : $@convention(thin) () -> ()
   %2 = tuple()
diff --git a/test/SIL/Serialization/vtable.sil b/test/SIL/Serialization/vtable.sil
index fd5fcb3..06ec8bb 100644
--- a/test/SIL/Serialization/vtable.sil
+++ b/test/SIL/Serialization/vtable.sil
@@ -1,44 +1,44 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -parse-sil -emit-sib -parse-as-library -parse-stdlib -module-name vtable -o %t/vtable.sib %s
+// RUN: %target-swift-frontend -parse-sil -emit-sib -parse-as-library -sil-serialize-vtables -parse-stdlib -module-name vtable -o %t/vtable.sib %s
 // RUN: %target-sil-opt %t/vtable.sib -o - -emit-sorted-sil | %FileCheck %s
 
 sil_stage canonical
 
 import Builtin
 
-class Base {
+public class Base {
   func m1()
   func m2()
 }
 
-class Derived : Base {
+public class Derived : Base {
   override func m2()
   func m3()
 }
 
-sil hidden_external @_T01x4BaseC2m1yyF : $@convention(method) (@guaranteed Base) -> ()
+sil hidden_external [serialized] @_T01x4BaseC2m1yyF : $@convention(method) (@guaranteed Base) -> ()
 
-sil hidden_external @_T01x4BaseC2m2yyF : $@convention(method) (@guaranteed Base) -> ()
+sil hidden_external [serialized] @_T01x4BaseC2m2yyF : $@convention(method) (@guaranteed Base) -> ()
 
-sil hidden_external @_T01x4BaseCfd : $@convention(method) (@guaranteed Base) -> @owned Builtin.NativeObject
+sil hidden_external [serialized] @_T01x4BaseCfd : $@convention(method) (@guaranteed Base) -> @owned Builtin.NativeObject
 
-sil hidden_external @_T01x4BaseCfD : $@convention(method) (@owned Base) -> ()
+sil hidden_external [serialized] @_T01x4BaseCfD : $@convention(method) (@owned Base) -> ()
 
-sil hidden_external @_T01x4BaseCACycfC : $@convention(method) (@thick Base.Type) -> @owned Base
+sil hidden_external [serialized] @_T01x4BaseCACycfC : $@convention(method) (@thick Base.Type) -> @owned Base
 
-sil hidden_external @_T01x4BaseCACycfc : $@convention(method) (@owned Base) -> @owned Base
+sil hidden_external [serialized] @_T01x4BaseCACycfc : $@convention(method) (@owned Base) -> @owned Base
 
-sil hidden_external @_T01x7DerivedC2m2yyF : $@convention(method) (@guaranteed Derived) -> ()
+sil hidden_external [serialized] @_T01x7DerivedC2m2yyF : $@convention(method) (@guaranteed Derived) -> ()
 
-sil hidden_external @_T01x7DerivedC2m3yyF : $@convention(method) (@guaranteed Derived) -> ()
+sil hidden_external [serialized] @_T01x7DerivedC2m3yyF : $@convention(method) (@guaranteed Derived) -> ()
 
-sil hidden_external @_T01x7DerivedCfd : $@convention(method) (@guaranteed Derived) -> @owned Builtin.NativeObject
+sil hidden_external [serialized] @_T01x7DerivedCfd : $@convention(method) (@guaranteed Derived) -> @owned Builtin.NativeObject
 
-sil hidden_external @_T01x7DerivedCfD : $@convention(method) (@owned Derived) -> ()
+sil hidden_external [serialized] @_T01x7DerivedCfD : $@convention(method) (@owned Derived) -> ()
 
-sil hidden_external @_T01x7DerivedCACycfC : $@convention(method) (@thick Derived.Type) -> @owned Derived
+sil hidden_external [serialized] @_T01x7DerivedCACycfC : $@convention(method) (@thick Derived.Type) -> @owned Derived
 
-sil hidden_external @_T01x7DerivedCACycfc : $@convention(method) (@owned Derived) -> @owned Derived
+sil hidden_external [serialized] @_T01x7DerivedCACycfc : $@convention(method) (@owned Derived) -> @owned Derived
 
 sil_vtable Base {
   #Base.m1!1: (Base) -> () -> () : _T01x4BaseC2m1yyF
diff --git a/test/SIL/Serialization/vtable_deserialization.swift b/test/SIL/Serialization/vtable_deserialization.swift
index acae21f..5c21124 100644
--- a/test/SIL/Serialization/vtable_deserialization.swift
+++ b/test/SIL/Serialization/vtable_deserialization.swift
@@ -1,9 +1,11 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend %S/Inputs/vtable_deserialization_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift -sil-serialize-all
+// RUN: %target-swift-frontend %S/Inputs/vtable_deserialization_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift -sil-serialize-witness-tables -sil-serialize-vtables
 // RUN: %target-swift-frontend %s -emit-sil -O -I %t -o - | %FileCheck %s
 
 import Swift
 
+@_versioned
+@_inlineable
 func WhatShouldIDoImBored<T : P>(_ t : T) {
   t.doSomething()
 }
diff --git a/test/SIL/Serialization/witness_tables.sil b/test/SIL/Serialization/witness_tables.sil
index 285239c..83c2b7d 100644
--- a/test/SIL/Serialization/witness_tables.sil
+++ b/test/SIL/Serialization/witness_tables.sil
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -parse-as-library -sil-serialize-all -module-name witness_tables -emit-module -o - %s | %target-sil-opt -assume-parsing-unqualified-ownership-sil -module-name witness_tables | %FileCheck %s
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -parse-as-library -sil-serialize-witness-tables -module-name witness_tables -emit-module -o - %s | %target-sil-opt -assume-parsing-unqualified-ownership-sil -module-name witness_tables | %FileCheck %s
 
 protocol AssocReqt {
   func requiredMethod()
@@ -8,14 +8,14 @@
   func requiredMethod()
 }
 
-sil @_TFV14witness_tables15ConformingAssoc14requiredMethodfS0_FT_T_ : $@convention(method) (ConformingAssoc) -> () {
+sil [serialized] @_TFV14witness_tables15ConformingAssoc14requiredMethodfS0_FT_T_ : $@convention(method) (ConformingAssoc) -> () {
 bb0(%0 : $ConformingAssoc):
   debug_value %0 : $ConformingAssoc
   %2 = tuple ()
   return %2 : $()
 }
 
-sil @_TTWV14witness_tables15ConformingAssocS_9AssocReqtS_FS1_14requiredMethodU_fRQPS1_FT_T_ : $@convention(witness_method) (@inout ConformingAssoc) -> () {
+sil [serialized] @_TTWV14witness_tables15ConformingAssocS_9AssocReqtS_FS1_14requiredMethodU_fRQPS1_FT_T_ : $@convention(witness_method) (@inout ConformingAssoc) -> () {
 bb0(%0 : $*ConformingAssoc):
   %1 = load %0 : $*ConformingAssoc
   %2 = function_ref @_TFV14witness_tables15ConformingAssoc14requiredMethodfS0_FT_T_ : $@convention(method) (ConformingAssoc) -> ()
@@ -23,10 +23,10 @@
   return %3 : $()
 }
 
-// CHECK-LABEL: sil_witness_table ConformingAssoc: AssocReqt module witness_tables {
+// CHECK-LABEL: sil_witness_table [serialized] ConformingAssoc: AssocReqt module witness_tables {
 // CHECK: #AssocReqt.requiredMethod!1: {{.*}} : @_TTWV14witness_tables15ConformingAssocS_9AssocReqtS_FS1_14requiredMethodU_fRQPS1_FT_T_
 // CHECK: }
-sil_witness_table ConformingAssoc: AssocReqt module witness_tables {
+sil_witness_table [serialized] ConformingAssoc: AssocReqt module witness_tables {
   method #AssocReqt.requiredMethod!1: @_TTWV14witness_tables15ConformingAssocS_9AssocReqtS_FS1_14requiredMethodU_fRQPS1_FT_T_
 }
 
@@ -57,18 +57,18 @@
 }
 
 
-// CHECK-LABEL: sil_witness_table shared InheritedConformance: InheritedProtocol1 module
+// CHECK-LABEL: sil_witness_table shared [serialized] InheritedConformance: InheritedProtocol1 module
 // CHECK: base_protocol AnyProtocol: InheritedConformance: AnyProtocol module
 // CHECK: }
-sil_witness_table shared InheritedConformance: InheritedProtocol1 module witness_tables {
+sil_witness_table shared [serialized] InheritedConformance: InheritedProtocol1 module witness_tables {
   base_protocol AnyProtocol: InheritedConformance: AnyProtocol module witness_tables
 }
 
-// CHECK-LABEL: sil_witness_table shared InheritedConformance: AnyProtocol module
+// CHECK-LABEL: sil_witness_table shared [serialized] InheritedConformance: AnyProtocol module
 // CHECK: associated_type AssocType: SomeAssoc
 // CHECK: associated_type_protocol (AssocWithReqt: AssocReqt): ConformingAssoc: AssocReqt module
 // CHECK: }
-sil_witness_table shared InheritedConformance: AnyProtocol module witness_tables {
+sil_witness_table shared [serialized] InheritedConformance: AnyProtocol module witness_tables {
   associated_type AssocType: SomeAssoc
   associated_type_protocol (AssocWithReqt: AssocReqt): ConformingAssoc: AssocReqt module witness_tables
 }
@@ -89,10 +89,10 @@
 	func abc()
 }
 
-// CHECK-LABEL: sil_witness_table DeadMethodClass: Proto module witness_tables
+// CHECK-LABEL: sil_witness_table [serialized] DeadMethodClass: Proto module witness_tables
 // CHECK: method #Proto.abc!1: {{.*}} : nil
 // CHECK: }
-sil_witness_table DeadMethodClass: Proto module witness_tables {
+sil_witness_table [serialized] DeadMethodClass: Proto module witness_tables {
   method #Proto.abc!1: nil
 }
 
diff --git a/test/SILGen/Inputs/ModuleA.swift b/test/SILGen/Inputs/ModuleA.swift
index 0a1aa28..066e3dd 100644
--- a/test/SILGen/Inputs/ModuleA.swift
+++ b/test/SILGen/Inputs/ModuleA.swift
@@ -1,11 +1,14 @@
+@_versioned
+internal var gg = nonTrivialInit()
 
-private var gg = nonTrivialInit()
-
+@_inlineable
 public func get_gg_a() -> Int {
   return gg
 }
 
+@_inlineable
+@_versioned
 @inline(never)
-private func nonTrivialInit() -> Int {
+internal func nonTrivialInit() -> Int {
   return 27
 }
diff --git a/test/SILGen/Inputs/ModuleB.swift b/test/SILGen/Inputs/ModuleB.swift
index 7180344..79d456c 100644
--- a/test/SILGen/Inputs/ModuleB.swift
+++ b/test/SILGen/Inputs/ModuleB.swift
@@ -1,12 +1,14 @@
+@_versioned
+internal var gg = nonTrivialInit()
 
-
-private var gg = nonTrivialInit()
-
+@_inlineable
 public func get_gg_b() -> Int {
   return gg
 }
 
+@_versioned
+@_inlineable
 @inline(never)
-private func nonTrivialInit() -> Int {
+internal func nonTrivialInit() -> Int {
   return 28
 }
diff --git a/test/SILGen/Inputs/weak_other.swift b/test/SILGen/Inputs/weak_other.swift
index cc4132a..0e57c1c 100644
--- a/test/SILGen/Inputs/weak_other.swift
+++ b/test/SILGen/Inputs/weak_other.swift
@@ -11,7 +11,7 @@
 }
 
 public protocol Environment : class {
-  unowned var router: Router { get }
+  var router: Router { get }
 }
 
 open class UI {
diff --git a/test/SILGen/dynamic_lookup.swift b/test/SILGen/dynamic_lookup.swift
index b865738..978a27c 100644
--- a/test/SILGen/dynamic_lookup.swift
+++ b/test/SILGen/dynamic_lookup.swift
@@ -28,7 +28,7 @@
   // CHECK: [[OPENED_ARG:%[0-9]+]] = open_existential_ref [[BORROWED_ARG]] : $AnyObject to $@opened({{.*}}) AnyObject
   // CHECK: [[OPENED_ARG_COPY:%.*]] = copy_value [[OPENED_ARG]]
   // CHECK: [[BORROWED_OPENED_ARG_COPY:%.*]] = begin_borrow [[OPENED_ARG_COPY]]
-  // CHECK: [[METHOD:%[0-9]+]] = dynamic_method [[BORROWED_OPENED_ARG_COPY]] : $@opened({{.*}}) AnyObject, #X.f!1.foreign : (X) -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> ()
+  // CHECK: [[METHOD:%[0-9]+]] = objc_method [[BORROWED_OPENED_ARG_COPY]] : $@opened({{.*}}) AnyObject, #X.f!1.foreign : (X) -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> ()
   // CHECK: apply [[METHOD]]([[OPENED_ARG_COPY]]) : $@convention(objc_method) (@opened({{.*}}) AnyObject) -> ()
   // CHECK: destroy_value [[OPENED_ARG_COPY]]
   // CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]]
@@ -44,7 +44,7 @@
   // CHECK:   [[OPENED_ARG:%[0-9]+]] = open_existential_ref [[BORROWED_ARG]] : $AnyObject to $@opened({{.*}}) AnyObject
   // CHECK:   [[OPENED_ARG_COPY:%.*]] = copy_value [[OPENED_ARG]]
   // CHECK:   [[BORROWED_OPENED_ARG_COPY:%.*]] = begin_borrow [[OPENED_ARG_COPY]]
-  // CHECK:   [[METHOD:%[0-9]+]] = dynamic_method [[BORROWED_OPENED_ARG_COPY]] : $@opened({{.*}}) AnyObject, #P.g!1.foreign : <Self where Self : P> (Self) -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> ()
+  // CHECK:   [[METHOD:%[0-9]+]] = objc_method [[BORROWED_OPENED_ARG_COPY]] : $@opened({{.*}}) AnyObject, #P.g!1.foreign : <Self where Self : P> (Self) -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> ()
   // CHECK:   apply [[METHOD]]([[OPENED_ARG_COPY]]) : $@convention(objc_method) (@opened({{.*}}) AnyObject) -> ()
   // CHECK:   destroy_value [[OPENED_ARG_COPY]]
   // CHECK:   end_borrow [[BORROWED_ARG]] from [[ARG]]
@@ -68,7 +68,7 @@
   // CHECK: end_access [[READ]]
   // CHECK-NEXT: [[OBJMETA:%[0-9]+]] = existential_metatype $@thick AnyObject.Type, [[OBJCOPY]] : $AnyObject
   // CHECK-NEXT: [[OPENMETA:%[0-9]+]] = open_existential_metatype [[OBJMETA]] : $@thick AnyObject.Type to $@thick (@opened([[UUID:".*"]]) AnyObject).Type
-  // CHECK-NEXT: [[METHOD:%[0-9]+]] = dynamic_method [[OPENMETA]] : $@thick (@opened([[UUID]]) AnyObject).Type, #X.staticF!1.foreign : (X.Type) -> () -> (), $@convention(objc_method) (@thick (@opened([[UUID]]) AnyObject).Type) -> ()
+  // CHECK-NEXT: [[METHOD:%[0-9]+]] = objc_method [[OPENMETA]] : $@thick (@opened([[UUID]]) AnyObject).Type, #X.staticF!1.foreign : (X.Type) -> () -> (), $@convention(objc_method) (@thick (@opened([[UUID]]) AnyObject).Type) -> ()
   // CHECK: apply [[METHOD]]([[OPENMETA]]) : $@convention(objc_method) (@thick (@opened([[UUID]]) AnyObject).Type) -> ()
   // CHECK: destroy_value [[OBJBOX]]
   // CHECK: destroy_value [[ARG]]
diff --git a/test/SILGen/dynamic_lookup_throws.swift b/test/SILGen/dynamic_lookup_throws.swift
index 38d6100..af96fda 100644
--- a/test/SILGen/dynamic_lookup_throws.swift
+++ b/test/SILGen/dynamic_lookup_throws.swift
@@ -18,7 +18,7 @@
   // CHECK:   [[ANYOBJECT_REF:%.*]] = open_existential_ref [[BORROWED_ARG]] : $AnyObject to $@opened("[[OPENED:.*]]") AnyObject
   // CHECK:   [[ANYOBJECT_REF_COPY:%.*]] = copy_value [[ANYOBJECT_REF]]
   // CHECK:   [[BORROWED_ANYOBJECT_REF_COPY:%.*]] = begin_borrow [[ANYOBJECT_REF_COPY]]
-  // CHECK:   dynamic_method [[BORROWED_ANYOBJECT_REF_COPY]] : $@opened("[[OPENED]]") AnyObject, #Blub.blub!1.foreign : (Blub) -> () throws -> (), $@convention(objc_method) (Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, @opened("[[OPENED]]") AnyObject) -> ObjCBool
+  // CHECK:   objc_method [[BORROWED_ANYOBJECT_REF_COPY]] : $@opened("[[OPENED]]") AnyObject, #Blub.blub!1.foreign : (Blub) -> () throws -> (), $@convention(objc_method) (Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, @opened("[[OPENED]]") AnyObject) -> ObjCBool
   // CHECK:   cond_br {{%.*}}, bb1, bb2
 
   // CHECK: bb1
diff --git a/test/SILGen/fragile_globals.swift b/test/SILGen/fragile_globals.swift
index 3cdc72b..bb64dd4 100644
--- a/test/SILGen/fragile_globals.swift
+++ b/test/SILGen/fragile_globals.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-all -o %t %S/Inputs/ModuleA.swift
-// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-all -o %t %S/Inputs/ModuleB.swift
+// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-witness-tables -o %t %S/Inputs/ModuleA.swift
+// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-witness-tables -o %t %S/Inputs/ModuleB.swift
 // RUN: %target-swift-frontend -parse-as-library -I%t %s -Xllvm -sil-disable-pass="SIL Global Optimization" -O -emit-sil | %FileCheck %s
 
 import ModuleA
@@ -8,27 +8,23 @@
 
 var mygg = 29
 
-// Check if we have three tokens: 2 from the imported modules, one from mygg.
+// Check if we have one token: from mygg.
+// Initializers from other modules are never fragile.
 
-// CHECK: sil_global private{{.*}} @globalinit_[[T1:.*]]_token0
-// CHECK: sil_global private{{.*}} @globalinit_[[T2:.*]]_token0
 // CHECK: sil_global private{{.*}} @globalinit_[[T3:.*]]_token0
 
+//@_inlineable
 public func sum() -> Int {
   return mygg + get_gg_a() + get_gg_b()
 }
 
 // Check if all the addressors are inlined.
 
-// CHECK-LABEL: sil @_T015fragile_globals3sumSiyF
-// CHECK-DAG: global_addr @_T015fragile_globals4myggSiv
-// CHECK-DAG: global_addr @_T07ModuleA2gg33_{{.*}}
-// CHECK-DAG: global_addr @_T07ModuleA2gg33_{{.*}}
-// CHECK-DAG: global_addr @globalinit_[[T1]]_token0
-// CHECK-DAG: global_addr @globalinit_[[T2]]_token0
-// CHECK-DAG: global_addr @globalinit_[[T3]]_token0
+// CHECK-LABEL: sil {{.*}}@_T015fragile_globals3sumSiyF
+// CHECK-DAG: global_addr @globalinit_[[T1:.*]]_token0
 // CHECK-DAG: function_ref @globalinit_[[T1]]_func0
-// CHECK-DAG: function_ref @globalinit_[[T2]]_func0
-// CHECK-DAG: function_ref @globalinit_[[T3]]_func0
+// CHECK-DAG: global_addr @_T015fragile_globals4myggSivp
+// CHECK-DAG: function_ref @_T07ModuleA2ggSivau
+// CHECK-DAG: function_ref @_T07ModuleB2ggSivau
 // CHECK: return
 
diff --git a/test/SILGen/keypaths.swift b/test/SILGen/keypaths.swift
index 4f7247b..7142e6a 100644
--- a/test/SILGen/keypaths.swift
+++ b/test/SILGen/keypaths.swift
@@ -267,6 +267,13 @@
   _ = \IUOProperty.iuo!.x
 }
 
+class Bass: Hashable {
+  static func ==(_: Bass, _: Bass) -> Bool { return false }
+  var hashValue: Int { return 0 }
+}
+
+class Treble: Bass { }
+
 struct Subscripts<T> {
   subscript() -> T {
     get { fatalError() }
@@ -292,6 +299,10 @@
     get { fatalError() }
     set { fatalError() }
   }
+  subscript(bass: Bass) -> Bass {
+    get { return bass }
+    set { }
+  }
 }
 
 // CHECK-LABEL: sil hidden @{{.*}}10subscripts
@@ -321,4 +332,7 @@
   _ = \Subscripts<String>.[subGeneric: y]
 
   _ = \Subscripts<T>.[s, s].count
+
+  _ = \Subscripts<T>.[Bass()]
+  _ = \Subscripts<T>.[Treble()]
 }
diff --git a/test/SILGen/objc_imported_generic.swift b/test/SILGen/objc_imported_generic.swift
index 4b6ab73..2c3965c 100644
--- a/test/SILGen/objc_imported_generic.swift
+++ b/test/SILGen/objc_imported_generic.swift
@@ -18,7 +18,7 @@
 }
 
 // CHECK-LABEL: sil @_T021objc_imported_generic0C17MethodOnAnyObject{{[_0-9a-zA-Z]*}}F
-// CHECK:         dynamic_method {{%.*}} : $@opened([[TAG:.*]]) AnyObject, #GenericClass.thing!1.foreign : <T where T : AnyObject> (GenericClass<T>) -> () -> T?, $@convention(objc_method) @pseudogeneric (@opened([[TAG]]) AnyObject) -> @autoreleased Optional<AnyObject>
+// CHECK:         objc_method {{%.*}} : $@opened([[TAG:.*]]) AnyObject, #GenericClass.thing!1.foreign : <T where T : AnyObject> (GenericClass<T>) -> () -> T?, $@convention(objc_method) @pseudogeneric (@opened([[TAG]]) AnyObject) -> @autoreleased Optional<AnyObject>
 
 public func genericMethodOnAnyObjectChained(o: AnyObject, b: Bool) -> AnyObject? {
   return o.thing?()
diff --git a/test/SILGen/properties.swift b/test/SILGen/properties.swift
index 84df67b..1759495 100644
--- a/test/SILGen/properties.swift
+++ b/test/SILGen/properties.swift
@@ -850,7 +850,7 @@
 
 // <rdar://problem/16554876> property accessor synthesization of weak variables doesn't work
 protocol WeakPropertyProtocol {
- weak var maybePresent : Ref? { get set }
+ var maybePresent : Ref? { get set }
 }
 
 struct WeakPropertyStruct : WeakPropertyProtocol {
diff --git a/test/SILGen/protocol_extensions.swift b/test/SILGen/protocol_extensions.swift
index cdf5483..7f69e46 100644
--- a/test/SILGen/protocol_extensions.swift
+++ b/test/SILGen/protocol_extensions.swift
@@ -70,7 +70,7 @@
 
 //   (materializeForSet test from above)
 // CHECK-LABEL: sil private [transparent] [thunk] @_T019protocol_extensions1CCAA2P1A2aDPS2icimTW
-// CHECK: bb0(%0 : $Builtin.RawPointer, %1 : $*Builtin.UnsafeValueBuffer, %2 : $Int, %3 : $*C):
+// CHECK: bb0(%0 : $Builtin.RawPointer, %1 : $*Builtin.UnsafeValueBuffer, %2 : $Int, %3 : $*τ_0_0):
 // CHECK: function_ref @_T019protocol_extensions2P1PAAES2icig
 // CHECK: return
 
diff --git a/test/SILGen/witness_tables_serialized.swift b/test/SILGen/witness_tables_serialized.swift
index 3d06881..ba1261a 100644
--- a/test/SILGen/witness_tables_serialized.swift
+++ b/test/SILGen/witness_tables_serialized.swift
@@ -2,14 +2,17 @@
 
 public protocol PublicProtocol {}
 
+@_versioned
 internal protocol InternalProtocol {}
 
+@_fixed_layout
 public struct PublicStruct : PublicProtocol, InternalProtocol {}
 
+@_versioned
 internal struct InternalStruct : PublicProtocol, InternalProtocol {}
 
 // CHECK-LABEL: sil_witness_table [serialized] PublicStruct: PublicProtocol
-// CHECK-LABEL: sil_witness_table hidden PublicStruct: InternalProtocol
+// CHECK-LABEL: sil_witness_table [serialized] PublicStruct: InternalProtocol
 
-// CHECK-LABEL: sil_witness_table hidden InternalStruct: PublicProtocol
-// CHECK-LABEL: sil_witness_table hidden InternalStruct: InternalProtocol
+// CHECK-LABEL: sil_witness_table [serialized] InternalStruct: PublicProtocol
+// CHECK-LABEL: sil_witness_table [serialized] InternalStruct: InternalProtocol
diff --git a/test/SILGen/witnesses_class.swift b/test/SILGen/witnesses_class.swift
index 55dd943..4e37ce8 100644
--- a/test/SILGen/witnesses_class.swift
+++ b/test/SILGen/witnesses_class.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
+// RUN: %target-swift-frontend -enable-sil-ownership -emit-silgen %s | %FileCheck %s
 
 protocol Fooable: class {
   func foo()
@@ -24,8 +24,8 @@
   // CHECK:         class_method
 }
 
-// CHECK-LABEL: sil hidden @_T015witnesses_class3gen{{[_0-9a-zA-Z]*}}F
-// CHECK:         bb0([[SELF:%.*]] : $T)
+// CHECK-LABEL: sil hidden @_T015witnesses_class3genyxAA7FooableRzlF
+// CHECK:         bb0([[SELF:%.*]] : @owned $T)
 // CHECK:         [[METHOD:%.*]] = witness_method $T
 // CHECK-NOT:     copy_value [[SELF]]
 // CHECK:         [[BORROWED_SELF:%.*]] = begin_borrow [[SELF]]
@@ -40,7 +40,7 @@
 }
 
 // CHECK-LABEL: sil hidden @_T015witnesses_class2exyAA7Fooable_pF
-// CHECK: bb0([[SELF:%[0-0]+]] : $Fooable):
+// CHECK: bb0([[SELF:%[0-0]+]] : @owned $Fooable):
 // CHECK:         [[BORROWED_SELF:%.*]] = begin_borrow [[SELF]]
 // CHECK:         [[SELF_PROJ:%.*]] = open_existential_ref [[BORROWED_SELF]]
 // CHECK:         [[METHOD:%.*]] = witness_method $[[OPENED:@opened(.*) Fooable]],
@@ -53,3 +53,58 @@
 func ex(_ foo: Fooable) {
   foo.foo()
 }
+
+// Default implementations in a protocol extension
+protocol HasDefaults {
+  associatedtype T = Self
+
+  func hasDefault()
+
+  func hasDefaultTakesT(_: T)
+
+  func hasDefaultGeneric<U : Fooable>(_: U)
+
+  func hasDefaultGenericTakesT<U : Fooable>(_: T, _: U)
+}
+
+extension HasDefaults {
+  func hasDefault() {}
+
+  func hasDefaultTakesT(_: T) {}
+
+  func hasDefaultGeneric<U : Fooable>(_: U) {}
+
+  func hasDefaultGenericTakesT<U : Fooable>(_: T, _: U) {}
+}
+
+protocol Barable {}
+
+class UsesDefaults<X : Barable> : HasDefaults {}
+
+// Covariant Self:
+
+// CHECK-LABEL: sil private [transparent] [thunk] @_T015witnesses_class12UsesDefaultsCyxGAA03HasD0A2A7BarableRzlAaEP10hasDefaultyyFTW : $@convention(witness_method) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable> (@in_guaranteed τ_0_0) -> ()
+// CHECK: [[FN:%.*]] = function_ref @_T015witnesses_class11HasDefaultsPAAE10hasDefaultyyF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults> (@in_guaranteed τ_0_0) -> ()
+// CHECK: apply [[FN]]<τ_0_0>(
+// CHECK: return
+
+// Invariant Self, since type signature contains an associated type:
+
+// CHECK-LABEL: sil private [transparent] [thunk] @_T015witnesses_class12UsesDefaultsCyxGAA03HasD0A2A7BarableRzlAaEP16hasDefaultTakesTy1TQzFTW : $@convention(witness_method) <τ_0_0 where τ_0_0 : Barable> (@in UsesDefaults<τ_0_0>, @in_guaranteed UsesDefaults<τ_0_0>) -> ()
+// CHECK: [[FN:%.*]] = function_ref @_T015witnesses_class11HasDefaultsPAAE16hasDefaultTakesTy1TQzF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults> (@in τ_0_0.T, @in_guaranteed τ_0_0) -> ()
+// CHECK: apply [[FN]]<UsesDefaults<τ_0_0>>(
+// CHECK: return
+
+// Covariant Self:
+
+// CHECK-LABEL: sil private [transparent] [thunk] @_T015witnesses_class12UsesDefaultsCyxGAA03HasD0A2A7BarableRzlAaEP17hasDefaultGenericyqd__AA7FooableRd__lFTW : $@convention(witness_method) <τ_0_0><τ_1_0 where τ_0_0 : UsesDefaults<τ_1_0>, τ_1_0 : Barable><τ_2_0 where τ_2_0 : Fooable> (@owned τ_2_0, @in_guaranteed τ_0_0) -> ()
+// CHECK: [[FN:%.*]] = function_ref @_T015witnesses_class11HasDefaultsPAAE17hasDefaultGenericyqd__AA7FooableRd__lF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults><τ_1_0 where τ_1_0 : Fooable> (@owned τ_1_0, @in_guaranteed τ_0_0) -> ()
+// CHECK: apply [[FN]]<τ_0_0, τ_2_0>(
+// CHECK: return
+
+// Invariant Self, since type signature contains an associated type:
+
+// CHECK-LABEL: sil private [transparent] [thunk] @_T015witnesses_class12UsesDefaultsCyxGAA03HasD0A2A7BarableRzlAaEP23hasDefaultGenericTakesTy1TQz_qd__tAA7FooableRd__lFTW : $@convention(witness_method) <τ_0_0 where τ_0_0 : Barable><τ_1_0 where τ_1_0 : Fooable> (@in UsesDefaults<τ_0_0>, @owned τ_1_0, @in_guaranteed UsesDefaults<τ_0_0>) -> ()
+// CHECK: [[FN:%.*]] = function_ref @_T015witnesses_class11HasDefaultsPAAE23hasDefaultGenericTakesTy1TQz_qd__tAA7FooableRd__lF : $@convention(method) <τ_0_0 where τ_0_0 : HasDefaults><τ_1_0 where τ_1_0 : Fooable> (@in τ_0_0.T, @owned τ_1_0, @in_guaranteed τ_0_0) -> ()
+// CHECK: apply [[FN]]<UsesDefaults<τ_0_0>, τ_1_0>(
+// CHECK: return
diff --git a/test/SILOptimizer/Inputs/TestModule.swift b/test/SILOptimizer/Inputs/TestModule.swift
index 2104a06..5419671 100644
--- a/test/SILOptimizer/Inputs/TestModule.swift
+++ b/test/SILOptimizer/Inputs/TestModule.swift
@@ -5,6 +5,7 @@
 }
 
 public struct MyStruct : Proto {
+  @_versioned
   func confx() {
   }
 
diff --git a/test/SILOptimizer/basic-callee-printer.sil b/test/SILOptimizer/basic-callee-printer.sil
index f003316..48380b1 100644
--- a/test/SILOptimizer/basic-callee-printer.sil
+++ b/test/SILOptimizer/basic-callee-printer.sil
@@ -425,7 +425,7 @@
 // CHECK: Function call site:
 // CHECK:   %2 = witness_method $T, #private_proto_1.theMethod!1 : {{.*}} : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_1> (@in_guaranteed τ_0_0) -> (){{.*}} // user: %3
 // CHECK:   %3 = apply %2<T>(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_1> (@in_guaranteed τ_0_0) -> ()
-// CHECK: Incomplete callee list? : Yes
+// CHECK: Incomplete callee list? : No
 // CHECK: Known callees:
 // CHECK: private_proto_1_private_class_witness
 sil private @call_through_private_proto_1 : $@convention(thin) <T where T : private_proto_1> (@in T) -> () {
@@ -468,7 +468,8 @@
 // CHECK: Function call site:
 // CHECK:   %2 = witness_method $T, #private_proto_2.theMethod!1 : {{.*}} : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_2> (@in_guaranteed τ_0_0) -> (){{.*}} // user: %3
 // CHECK:   %3 = apply %2<T>(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_2> (@in_guaranteed τ_0_0) -> ()
-// CHECK: Incomplete callee list? : Yes
+// CHECK-WMO: Incomplete callee list? : No
+// CHECK-NOWMO: Incomplete callee list? : Yes
 // CHECK: Known callees:
 // CHECK: private_proto_2_internal_class_witness
 sil private @call_through_private_proto_2 : $@convention(thin) <T where T : private_proto_2> (@in T) -> () {
@@ -552,7 +553,7 @@
 // CHECK: Function call site:
 // CHECK:   %2 = witness_method $T, #private_proto_4.theMethod!1 : {{.*}} : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_4> (@in_guaranteed τ_0_0) -> (){{.*}} // user: %3
 // CHECK:   %3 = apply %2<T>(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_4> (@in_guaranteed τ_0_0) -> ()
-// CHECK: Incomplete callee list? : Yes
+// CHECK: Incomplete callee list? : No
 // CHECK: Known callees:
 // CHECK: private_proto_4_public_class_private_method_witness
 sil private @call_through_private_proto_4 : $@convention(thin) <T where T : private_proto_4> (@in T) -> () {
diff --git a/test/SILOptimizer/bug-reducer-tester-miscompile.sil b/test/SILOptimizer/bug-reducer-tester-miscompile.sil
index 3a20e98..9c61c9b 100644
--- a/test/SILOptimizer/bug-reducer-tester-miscompile.sil
+++ b/test/SILOptimizer/bug-reducer-tester-miscompile.sil
@@ -44,7 +44,7 @@
 
 sil @putchar : $@convention(c) (Builtin.Int64) -> ()
 
-sil @target_func : $@convention(thin) () -> () {
+sil [serialized] @target_func : $@convention(thin) () -> () {
 bb0:
   %0 = function_ref @putchar : $@convention(c) (Builtin.Int64) -> ()
   // "swift\n" in ASCII
@@ -64,7 +64,7 @@
   return %9999 : $()
 }
 
-sil @function_2 : $@convention(thin) () -> () {
+sil [serialized] @function_2 : $@convention(thin) () -> () {
 bb0:
   %0 = function_ref @target_func : $@convention(thin) () -> ()
   apply %0() : $@convention(thin) () -> ()
@@ -76,7 +76,7 @@
   return %9999 : $()
 }
 
-sil @function_3 : $@convention(thin) () -> () {
+sil [serialized] @function_3 : $@convention(thin) () -> () {
 bb0:
   // Make sure we only eliminate one.
   %0 = function_ref @target_func : $@convention(thin) () -> ()
diff --git a/test/SILOptimizer/bug-reducer-tester-runtime-crasher.sil b/test/SILOptimizer/bug-reducer-tester-runtime-crasher.sil
index 0fb01d7..e7d010e 100644
--- a/test/SILOptimizer/bug-reducer-tester-runtime-crasher.sil
+++ b/test/SILOptimizer/bug-reducer-tester-runtime-crasher.sil
@@ -41,7 +41,7 @@
 
 sil @putchar : $@convention(c) (Builtin.Int64) -> ()
 
-sil @target_func : $@convention(thin) () -> () {
+sil [serialized] @target_func : $@convention(thin) () -> () {
 bb0:
   %0 = function_ref @putchar : $@convention(c) (Builtin.Int64) -> ()
   // "swift\n" in ASCII
@@ -61,7 +61,7 @@
   return %9999 : $()
 }
 
-sil @function_2 : $@convention(thin) () -> () {
+sil [serialized] @function_2 : $@convention(thin) () -> () {
 bb0:
   %0 = function_ref @target_func : $@convention(thin) () -> ()
   apply %0() : $@convention(thin) () -> ()
@@ -73,7 +73,7 @@
   return %9999 : $()
 }
 
-sil @function_3 : $@convention(thin) () -> () {
+sil [serialized] @function_3 : $@convention(thin) () -> () {
 bb0:
   // Make sure we only eliminate one.
   %0 = function_ref @target_func : $@convention(thin) () -> ()
diff --git a/test/SILOptimizer/dead_inlined_func.swift b/test/SILOptimizer/dead_inlined_func.swift
index b1ef650..3fd99b7 100644
--- a/test/SILOptimizer/dead_inlined_func.swift
+++ b/test/SILOptimizer/dead_inlined_func.swift
@@ -1,5 +1,5 @@
 // RUN: %target-swift-frontend -O -g %s -emit-sil | %FileCheck %s -check-prefix=CHECK-SIL
-// RUN: %target-swift-frontend -O -g %s -sil-serialize-all -emit-ir | %FileCheck %s -check-prefix=CHECK-IR
+// RUN: %target-swift-frontend -O -g %s -sil-serialize-witness-tables -sil-serialize-vtables -emit-ir | %FileCheck %s -check-prefix=CHECK-IR
 
 // The dead inlined function should not be in the SIL
 // CHECK-SIL-NOT: sil {{.*}}to_be_inlined
diff --git a/test/SILOptimizer/dead_witness_module.swift b/test/SILOptimizer/dead_witness_module.swift
index e0796a7..8c6659d 100644
--- a/test/SILOptimizer/dead_witness_module.swift
+++ b/test/SILOptimizer/dead_witness_module.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -Onone -parse-stdlib -parse-as-library  -module-name TestModule -sil-serialize-all %S/Inputs/TestModule.swift -emit-module-path %t/TestModule.swiftmodule 
+// RUN: %target-swift-frontend -Onone -parse-stdlib -parse-as-library  -module-name TestModule -sil-serialize-witness-tables %S/Inputs/TestModule.swift -emit-module-path %t/TestModule.swiftmodule 
 // RUN: %target-swift-frontend -O %s -I %t -emit-sil | %FileCheck %s
 
 // DeadFunctionElimination may not remove a method from a witness table which
diff --git a/test/SILOptimizer/devirt_class_witness_method.sil b/test/SILOptimizer/devirt_class_witness_method.sil
new file mode 100644
index 0000000..83d1769
--- /dev/null
+++ b/test/SILOptimizer/devirt_class_witness_method.sil
@@ -0,0 +1,42 @@
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -devirtualizer -sil-combine -enable-resilience | tee /tmp/xxx | %FileCheck %s
+sil_stage canonical
+
+import Builtin
+
+protocol P {
+  func f()
+}
+
+extension P {
+  func f()
+}
+
+class C<T, U> : P {}
+
+sil hidden_external [transparent] [thunk] @witness_thunk : $@convention(witness_method) <τ_0_0><τ_1_0, τ_1_1 where τ_0_0 : C<τ_1_0, τ_1_1>> (@in_guaranteed τ_0_0) -> ()
+
+// CHECK-LABEL: sil hidden @caller : $@convention(thin) <T, U> (@owned C<T, U>) -> ()
+// CHECK: [[FN:%.*]] = function_ref @witness_thunk
+// CHECK: apply [[FN]]<C<T, U>, T, U>(
+// CHECK: return
+sil hidden @caller : $@convention(thin) <T, U> (@owned C<T, U>) -> () {
+bb0(%0 : $C<T, U>):
+  strong_retain %0 : $C<T, U>
+  %4 = alloc_stack $C<T, U>
+  store %0 to %4 : $*C<T, U>
+  %6 = witness_method $C<T, U>, #P.f!1 : <Self where Self : P> (Self) -> () -> () : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
+  %7 = apply %6<C<T, U>>(%4) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
+  dealloc_stack %4 : $*C<T, U>
+  strong_release %0 : $C<T, U>
+  %9 = tuple ()
+  return %9 : $()
+}
+
+sil_vtable C {}
+
+sil_witness_table hidden <T, U> C<T, U>: P module clsx {
+  method #P.f!1: <Self where Self : P> (Self) -> () -> () : @witness_thunk
+}
+
+sil_default_witness_table hidden P {
+}
diff --git a/test/SILOptimizer/linker.swift b/test/SILOptimizer/linker.swift
index 7959a07..45a1e1f 100644
--- a/test/SILOptimizer/linker.swift
+++ b/test/SILOptimizer/linker.swift
@@ -1,5 +1,5 @@
 // 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 -emit-module %S/Inputs/linker_pass_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -sil-serialize-witness-tables -sil-serialize-vtables -module-link-name swiftCore
 // RUN: %target-swift-frontend %s -O -I %t -sil-debug-serialization -o - -emit-sil | %FileCheck %s
 
 // CHECK: sil public_external [serialized] @_T0s11doSomethingyyF : $@convention(thin) () -> () {
diff --git a/test/SILOptimizer/mandatory_inlining_dynamic_method.swift b/test/SILOptimizer/mandatory_inlining_dynamic_method.swift
new file mode 100644
index 0000000..68cf0e8
--- /dev/null
+++ b/test/SILOptimizer/mandatory_inlining_dynamic_method.swift
@@ -0,0 +1,13 @@
+// RUN: %target-swift-frontend -enable-sil-ownership -sil-verify-all -emit-sil %s -o /dev/null -verify
+// REQUIRES: objc_interop
+
+import Foundation
+
+@_transparent public func a(_ condition: @autoclosure () -> Bool) {
+  _ = condition()
+}
+
+func callsA() {
+  let x = (2 as NSNumber) as AnyObject
+  a(x.isEqual(2))
+}
diff --git a/test/SILOptimizer/sil_witness_tables_external_witnesstable.swift b/test/SILOptimizer/sil_witness_tables_external_witnesstable.swift
index 9f765a4..5edd7c9 100644
--- a/test/SILOptimizer/sil_witness_tables_external_witnesstable.swift
+++ b/test/SILOptimizer/sil_witness_tables_external_witnesstable.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module %S/Inputs/sil_witness_tables_external_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -sil-serialize-all -module-link-name swiftCore
+// RUN: %target-swift-frontend -emit-module %S/Inputs/sil_witness_tables_external_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -sil-serialize-witness-tables -module-link-name swiftCore
 // RUN: %target-swift-frontend -O -I %t %s -emit-sil | %FileCheck %s
 
 import Swift
diff --git a/test/SILOptimizer/specialize_cg_update_crash.sil b/test/SILOptimizer/specialize_cg_update_crash.sil
index 830e845..a117b3a 100644
--- a/test/SILOptimizer/specialize_cg_update_crash.sil
+++ b/test/SILOptimizer/specialize_cg_update_crash.sil
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -parse-stdlib -parse-as-library  -module-name TestMod -sil-serialize-all %S/Inputs/TestMod.sil -emit-module-path %t/TestMod.swiftmodule
+// RUN: %target-swift-frontend -parse-stdlib -parse-as-library  -module-name TestMod -sil-serialize-witness-tables -sil-serialize-vtables %S/Inputs/TestMod.sil -emit-module-path %t/TestMod.swiftmodule
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -inline -I %t %s | %FileCheck %s
 
 // Test if the CG is updated correctly during specialization and
diff --git a/test/Serialization/Inputs/def_basic.sil b/test/Serialization/Inputs/def_basic.sil
index 4bd889a..a691df7 100644
--- a/test/Serialization/Inputs/def_basic.sil
+++ b/test/Serialization/Inputs/def_basic.sil
@@ -1221,18 +1221,18 @@
   return undef : $()
 }
 
-// CHECK-LABEL: sil {{.*}} [reabstraction_thunk] @a_reabstraction_thunk : $@convention(thin) () -> ()
+// CHECK-LABEL: sil {{.*}}[reabstraction_thunk] @a_reabstraction_thunk : $@convention(thin) () -> ()
 sil [reabstraction_thunk] @a_reabstraction_thunk : $@convention(thin) () -> () {
   %1 = tuple()
   return %1 : $()
 }
-// CHECK-LABEL: sil {{.*}} [thunk] @a_regular_thunk : $@convention(thin) () -> () {
-sil [thunk] @a_regular_thunk : $@convention(thin) () -> () {
+// CHECK-LABEL: sil {{.*}}[thunk] @a_regular_thunk : $@convention(thin) () -> () {
+sil [serialized] [thunk] @a_regular_thunk : $@convention(thin) () -> () {
   %1 = tuple()
   return %1 : $()
 }
 
-class Foo {
+public class Foo {
   subscript (x: Int, y: Int) -> Int32 { get set }
   var x: Int
   var y: Int
diff --git a/test/Serialization/Inputs/def_noinline.swift b/test/Serialization/Inputs/def_noinline.swift
index f60a561..f06796b 100644
--- a/test/Serialization/Inputs/def_noinline.swift
+++ b/test/Serialization/Inputs/def_noinline.swift
@@ -1,10 +1,13 @@
+@_inlineable
 @inline(never) public func testNoinline(x x: Bool) -> Bool {
   return x
 }
 
 public struct NoInlineInitStruct {
+  @_versioned
   var x: Bool
 
+  @_inlineable
   @inline(never)
   public init(x x2: Bool) {
     self.x = x2
diff --git a/test/Serialization/Inputs/def_transparent.swift b/test/Serialization/Inputs/def_transparent.swift
index 70111eb..c061dfa 100644
--- a/test/Serialization/Inputs/def_transparent.swift
+++ b/test/Serialization/Inputs/def_transparent.swift
@@ -11,13 +11,21 @@
 @_transparent public func standalone_function(x x: Int32, y: Int32) -> Int32 {
   return x
 }
+
+@_inlineable
 public func foo() -> Int32 { return 0 }
+@_inlineable
 public func runced() -> Bool { return true }
 
+@_inlineable
 public func a() {}
+@_inlineable
 public func b() {}
+@_inlineable
 public func c() {}
+@_inlineable
 public func d() {}
+@_inlineable
 public func e() {}
 
 @_transparent public func test_br() {
@@ -36,6 +44,7 @@
   case Right(String)
   case Both(Int32, String)
 }
+@_inlineable
 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 a0269db..28591c8 100644
--- a/test/Serialization/always_inline.swift
+++ b/test/Serialization/always_inline.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -sil-serialize-all -o %t %S/Inputs/def_always_inline.swift
+// RUN: %target-swift-frontend -emit-module -sil-serialize-witness-tables -sil-serialize-vtables -o %t %S/Inputs/def_always_inline.swift
 // RUN: llvm-bcanalyzer %t/def_always_inline.swiftmodule | %FileCheck %s
 // RUN: %target-swift-frontend -emit-silgen -sil-link-all -I %t %s | %FileCheck %s -check-prefix=SIL
 
diff --git a/test/Serialization/basic_sil.swift b/test/Serialization/basic_sil.swift
index 63743ea..d5abee1 100644
--- a/test/Serialization/basic_sil.swift
+++ b/test/Serialization/basic_sil.swift
@@ -1,10 +1,10 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-all -force-single-frontend-invocation -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil
+// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-witness-tables -Xfrontend -sil-serialize-vtables -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-silgen -Xfrontend -sil-link-all -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 -Xfrontend -sil-serialize-all -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil
+// RUN: %target-build-swift  -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -Xfrontend -sil-serialize-witness-tables -Xfrontend -sil-serialize-vtables -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil
 // RUN: %target-build-swift -emit-silgen -Xfrontend -sil-link-all -I %t %s | %FileCheck -check-prefix=CHECK_DECL %S/Inputs/def_basic.sil
 
 // This test currently is written such that no optimizations are assumed.
diff --git a/test/Serialization/basic_sil_objc.swift b/test/Serialization/basic_sil_objc.swift
index f54147c..3eeb900 100644
--- a/test/Serialization/basic_sil_objc.swift
+++ b/test/Serialization/basic_sil_objc.swift
@@ -1,5 +1,5 @@
 // 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 -Xfrontend -sil-serialize-all -force-single-frontend-invocation -o %t/def_basic_objc.swiftmodule %S/Inputs/def_basic_objc.sil
+// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -I %S/../Inputs/clang-importer-sdk/swift-modules -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-witness-tables -Xfrontend -sil-serialize-vtables -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-silgen -Xfrontend -sil-link-all -I %t %s | %FileCheck %S/Inputs/def_basic_objc.sil
 
diff --git a/test/Serialization/default-witness-table-deserialization.swift b/test/Serialization/default-witness-table-deserialization.swift
index 8f7757a..87d8484 100644
--- a/test/Serialization/default-witness-table-deserialization.swift
+++ b/test/Serialization/default-witness-table-deserialization.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend %s -module-name Test -sil-serialize-all -emit-module -emit-module-path - -o /dev/null | %target-sil-opt -enable-sil-verify-all -disable-sil-linking -module-name="Test" | %FileCheck %s
+// RUN: %target-swift-frontend %s -module-name Test -sil-serialize-witness-tables -sil-serialize-vtables -emit-module -emit-module-path - -o /dev/null | %target-sil-opt -enable-sil-verify-all -disable-sil-linking -module-name="Test" | %FileCheck %s
 
 // Check that default witness tables are properly deserialized.
 // rdar://problem/29173229
diff --git a/test/Serialization/duplicate_normalprotocolconformance.swift b/test/Serialization/duplicate_normalprotocolconformance.swift
index 1a33f32..752d0ad 100644
--- a/test/Serialization/duplicate_normalprotocolconformance.swift
+++ b/test/Serialization/duplicate_normalprotocolconformance.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend %S/Inputs/duplicate_normalprotocolconformance_input.swift -o %t/Swift.swiftmodule -sil-serialize-all -emit-module -parse-stdlib -parse-as-library -module-link-name swiftCore -module-name Swift
+// RUN: %target-swift-frontend %S/Inputs/duplicate_normalprotocolconformance_input.swift -o %t/Swift.swiftmodule -sil-serialize-witness-tables -sil-serialize-vtables -emit-module -parse-stdlib -parse-as-library -module-link-name swiftCore -module-name Swift
 // RUN: %target-swift-frontend -c %s -I %t -sil-link-all -o %t/out
 
 import Swift
diff --git a/test/Serialization/global_init.swift b/test/Serialization/global_init.swift
index 88f659f..18c8bbd 100644
--- a/test/Serialization/global_init.swift
+++ b/test/Serialization/global_init.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-all -o %t %s
+// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-witness-tables -o %t %s
 // RUN: llvm-bcanalyzer %t/global_init.swiftmodule | %FileCheck %s -check-prefix=BCANALYZER
 // RUN: %target-sil-opt -enable-sil-verify-all -disable-sil-linking %t/global_init.swiftmodule | %FileCheck %s
 
@@ -12,15 +12,19 @@
 // The only way to inspect the serialized module is sil-opt. The swift
 // driver will only output the SIL that it deserializes.
 
+@_versioned
 let MyConst = 42
+@_versioned
 var MyVar = 3
 
 // CHECK: let MyConst: Int
 // CHECK: var MyVar: Int
 
-// CHECK-DAG: sil hidden [serialized] [global_init] @_T011global_init7MyConstSivau : $@convention(thin) () -> Builtin.RawPointer
-// CHECK-DAG: sil hidden [serialized] [global_init] @_T011global_init5MyVarSivau : $@convention(thin) () -> Builtin.RawPointer
+// CHECK-DAG: sil [global_init] @_T011global_init7MyConstSivau : $@convention(thin) () -> Builtin.RawPointer
+// CHECK-DAG: sil [global_init] @_T011global_init5MyVarSivau : $@convention(thin) () -> Builtin.RawPointer
 
+@_inlineable
+@_versioned
 func getGlobals() -> Int {
   return MyVar + MyConst
 }
diff --git a/test/Serialization/noinline.swift b/test/Serialization/noinline.swift
index 46c448f..4510841 100644
--- a/test/Serialization/noinline.swift
+++ b/test/Serialization/noinline.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -sil-serialize-all -o %t %S/Inputs/def_noinline.swift
+// RUN: %target-swift-frontend -emit-module -sil-serialize-witness-tables -sil-serialize-vtables -o %t %S/Inputs/def_noinline.swift
 // RUN: llvm-bcanalyzer %t/def_noinline.swiftmodule | %FileCheck %s
 // RUN: %target-swift-frontend -emit-silgen -sil-link-all -I %t %s | %FileCheck %s -check-prefix=SIL
 
diff --git a/test/Serialization/resilience.swift b/test/Serialization/resilience.swift
index a668045..db5ec5e 100644
--- a/test/Serialization/resilience.swift
+++ b/test/Serialization/resilience.swift
@@ -11,7 +11,7 @@
 // RUN: llvm-bcanalyzer -dump %t/resilience.swiftmodule > %t/resilience2.dump.txt
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=RESILIENCE %s < %t/resilience2.dump.txt
 
-// RUN: %target-swift-frontend -emit-module -o %t -sil-serialize-all %s
+// RUN: %target-swift-frontend -emit-module -o %t -sil-serialize-witness-tables -sil-serialize-vtables %s
 // RUN: llvm-bcanalyzer -dump %t/resilience.swiftmodule > %t/resilience3.dump.txt
 // RUN: %FileCheck -check-prefix=CHECK -check-prefix=FRAGILE %s < %t/resilience3.dump.txt
 
@@ -19,7 +19,7 @@
 
 // CHECK: <MODULE_BLOCK {{.*}}>
 // RESILIENCE: <RESILIENCE_STRATEGY abbrevid={{[0-9]+}} op0=1/>
-// FRAGILE: <RESILIENCE_STRATEGY abbrevid={{[0-9]+}} op0=2/>
+// FRAGILE-NOT: <RESILIENCE_STRATEGY abbrevid={{[0-9]+}}
 // DEFAULT-NOT: RESILIENCE_STRATEGY
 
 // CHECK: </MODULE_BLOCK>
diff --git a/test/Serialization/serialize_attr.swift b/test/Serialization/serialize_attr.swift
index e1e8a73..41104f9 100644
--- a/test/Serialization/serialize_attr.swift
+++ b/test/Serialization/serialize_attr.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-all -o %t %s
+// RUN: %target-swift-frontend -emit-module -parse-as-library -sil-serialize-witness-tables -o %t %s
 // RUN: llvm-bcanalyzer %t/serialize_attr.swiftmodule | %FileCheck %s -check-prefix=BCANALYZER
 // RUN: %target-sil-opt -enable-sil-verify-all -disable-sil-linking %t/serialize_attr.swiftmodule | %FileCheck %s
 
@@ -9,6 +9,8 @@
 // -----------------------------------------------------------------------------
 
 //CHECK-DAG: @_semantics("crazy") func foo()
+@_inlineable
+@_versioned
 @_semantics("crazy") func foo() -> Int  { return 5}
 
 // @_specialize
@@ -17,24 +19,26 @@
 // These lines should be contiguous.
 // CHECK-DAG: @_specialize(exported: false, kind: full, where T == Int, U == Float)
 // CHECK-DAG: func specializeThis<T, U>(_ t: T, u: U)
+@_inlineable
+@_versioned
 @_specialize(where T == Int, U == Float)
 func specializeThis<T, U>(_ t: T, u: U) {}
 
-protocol PP {
+public protocol PP {
   associatedtype PElt
 }
-protocol QQ {
+public protocol QQ {
   associatedtype QElt
 }
 
-struct RR : PP {
-  typealias PElt = Float
+public struct RR : PP {
+  public typealias PElt = Float
 }
-struct SS : QQ {
-  typealias QElt = Int
+public struct SS : QQ {
+  public typealias QElt = Int
 }
 
-struct GG<T : PP> {}
+public struct GG<T : PP> {}
 
 // These three lines should be contiguous, however, there is no way to
 // sequence FileCheck directives while using CHECK-DAG as the outer
@@ -43,7 +47,9 @@
 // CHECK-DAG: class CC<T> where T : PP {
 // CHECK-DAG: @_specialize(exported: false, kind: full, where T == RR, U == SS)
 // CHECK-DAG: @inline(never) func foo<U>(_ u: U, g: GG<T>) -> (U, GG<T>) where U : QQ
-class CC<T : PP> {
+public class CC<T : PP> {
+  @_inlineable
+  @_versioned
   @inline(never)
   @_specialize(where T==RR, U==SS)
   func foo<U : QQ>(_ u: U, g: GG<T>) -> (U, GG<T>) {
@@ -51,6 +57,6 @@
   }
 }
 
-// CHECK-DAG: sil hidden [serialized] [_specialize exported: false, kind: full, where T == Int, U == Float] @_T014serialize_attr14specializeThisyx_q_1utr0_lF : $@convention(thin) <T, U> (@in T, @in U) -> () {
+// CHECK-DAG: sil [serialized] [_specialize exported: false, kind: full, where T == Int, U == Float] @_T014serialize_attr14specializeThisyx_q_1utr0_lF : $@convention(thin) <T, U> (@in T, @in U) -> () {
 
-// CHECK-DAG: sil hidden [serialized] [noinline] [_specialize exported: false, kind: full, where T == RR, U == SS] @_T014serialize_attr2CCC3fooqd___AA2GGVyxGtqd___AG1gtAA2QQRd__lF : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
+// CHECK-DAG: sil [serialized] [noinline] [_specialize exported: false, kind: full, where T == RR, U == SS] @_T014serialize_attr2CCC3fooqd___AA2GGVyxGtqd___AG1gtAA2QQRd__lF : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
diff --git a/test/Serialization/sil-serialize-all-with-cross-module-conformance.swift b/test/Serialization/sil-serialize-all-with-cross-module-conformance.swift
index 38d19ca..2b23d86 100644
--- a/test/Serialization/sil-serialize-all-with-cross-module-conformance.swift
+++ b/test/Serialization/sil-serialize-all-with-cross-module-conformance.swift
@@ -1,6 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -parse-as-library -module-name ProtoModule -o %t/ProtoModule.swiftmodule %s -DPROTO
-// RUN: %target-swift-frontend -emit-module -parse-as-library -module-name ModelModule -o %t/ModelModule.swiftmodule %s -DMODEL -I %t -sil-serialize-all
+// RUN: %target-swift-frontend -emit-module -parse-as-library -module-name ModelModule -o %t/ModelModule.swiftmodule %s -DMODEL -I %t -sil-serialize-witness-tables -sil-serialize-vtables
 // RUN: %target-swift-frontend -emit-sil -O -sil-verify-all -o /dev/null %s -DUSE -I %t
 
 #if PROTO
diff --git a/test/Serialization/sil_box_types.sil b/test/Serialization/sil_box_types.sil
index 9c68bf2..7957368 100644
--- a/test/Serialization/sil_box_types.sil
+++ b/test/Serialization/sil_box_types.sil
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: mkdir %t
-// RUN: %target-build-swift -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-all -force-single-frontend-invocation -o %t/sil_box_types.swiftmodule %s
+// RUN: %target-build-swift -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-witness-tables -Xfrontend -sil-serialize-vtables -force-single-frontend-invocation -o %t/sil_box_types.swiftmodule %s
 // RUN: %target-build-swift -emit-sil -Xfrontend -sil-link-all -I %t %s | %FileCheck %s
 
 import Builtin
diff --git a/test/Serialization/sil_partial_apply_ownership.sil b/test/Serialization/sil_partial_apply_ownership.sil
index 194eced..7356e33 100644
--- a/test/Serialization/sil_partial_apply_ownership.sil
+++ b/test/Serialization/sil_partial_apply_ownership.sil
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: mkdir %t
-// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-all -force-single-frontend-invocation -o %t/sil_partial_apply_ownership.swiftmodule %s
+// RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-witness-tables -Xfrontend -sil-serialize-vtables -force-single-frontend-invocation -o %t/sil_partial_apply_ownership.swiftmodule %s
 // RUN: %target-build-swift -Xfrontend -assume-parsing-unqualified-ownership-sil -emit-sil -Xfrontend -sil-link-all -I %t %s | %FileCheck %s
 
 import Builtin
diff --git a/test/Serialization/transparent.swift b/test/Serialization/transparent.swift
index 73e90d6..aab86af 100644
--- a/test/Serialization/transparent.swift
+++ b/test/Serialization/transparent.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -sil-serialize-all -o %t %S/Inputs/def_transparent.swift
+// RUN: %target-swift-frontend -emit-module -sil-serialize-witness-tables -sil-serialize-vtables -o %t %S/Inputs/def_transparent.swift
 // RUN: llvm-bcanalyzer %t/def_transparent.swiftmodule | %FileCheck %s
 // RUN: %target-swift-frontend -emit-silgen -sil-link-all -I %t %s | %FileCheck %s -check-prefix=SIL
 
diff --git a/test/Serialization/vtable-function-deserialization.swift b/test/Serialization/vtable-function-deserialization.swift
index ffe3c34..e89d042 100644
--- a/test/Serialization/vtable-function-deserialization.swift
+++ b/test/Serialization/vtable-function-deserialization.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -o Swift.swiftmodule -O -sil-inline-threshold 0 -module-name Swift -module-link-name swiftCore -parse-as-library -parse-stdlib -emit-module -sil-serialize-all %S/Inputs/vtable-function-deserialization-input.swift -o %t/Swift.swiftmodule
+// RUN: %target-swift-frontend -emit-module -o Swift.swiftmodule -O -sil-inline-threshold 0 -module-name Swift -module-link-name swiftCore -parse-as-library -parse-stdlib -emit-module -sil-serialize-witness-tables -sil-serialize-vtables %S/Inputs/vtable-function-deserialization-input.swift -o %t/Swift.swiftmodule
 // RUN: %target-swift-frontend -I %t %s -emit-sil -o - -O -sil-link-all
 
 import Swift
diff --git a/test/Serialization/witnesstable-function-deserialization.swift b/test/Serialization/witnesstable-function-deserialization.swift
index a1a9f22..b84b26e 100644
--- a/test/Serialization/witnesstable-function-deserialization.swift
+++ b/test/Serialization/witnesstable-function-deserialization.swift
@@ -1,5 +1,5 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend -emit-module -O -module-name Swift -module-link-name swiftCore -parse-as-library -parse-stdlib -emit-module -sil-serialize-all %S/Inputs/witnesstable-function-deserialization-input.swift -o %t/Swift.swiftmodule -sil-inline-threshold 10
+// RUN: %target-swift-frontend -emit-module -O -module-name Swift -module-link-name swiftCore -parse-as-library -parse-stdlib -emit-module -sil-serialize-witness-tables -sil-serialize-vtables %S/Inputs/witnesstable-function-deserialization-input.swift -o %t/Swift.swiftmodule -sil-inline-threshold 10
 // RUN: %target-swift-frontend -I %t %s -emit-sil -o - -O -sil-link-all
 
 import Swift
diff --git a/test/SourceKit/CodeFormat/indent-implicit-getter.swift b/test/SourceKit/CodeFormat/indent-implicit-getter.swift
index 548febf..0154011 100644
--- a/test/SourceKit/CodeFormat/indent-implicit-getter.swift
+++ b/test/SourceKit/CodeFormat/indent-implicit-getter.swift
@@ -24,7 +24,6 @@
   return 1
   }
 }
-// REQUIRES: disabled
 // FIXME: may be crashing non-deterministically
 
 // RUN: %sourcekitd-test -req=format -line=1 -length=1 %s >%t.response
diff --git a/test/SourceKit/CursorInfo/cursor_overrides.swift b/test/SourceKit/CursorInfo/cursor_overrides.swift
index a302b79..1e6415a 100644
--- a/test/SourceKit/CursorInfo/cursor_overrides.swift
+++ b/test/SourceKit/CursorInfo/cursor_overrides.swift
@@ -16,6 +16,15 @@
   x.meth()
 }
 
+public protocol WithAssocType {
+  /// Some kind of associated type
+  associatedtype AssocType
+}
+
+public protocol WithInheritedAssocType : WithAssocType {
+  associatedtype AssocType = Int
+}
+
 // REQUIRES: objc_interop
 // RUN: %sourcekitd-test -req=cursor -pos=16:7 %s -- -embed-bitcode -I %S/Inputs/cursor-overrides %mcp_opt %s | %FileCheck -check-prefix=CHECK1 %s
 // CHECK1: source.lang.swift.ref.function.method.instance (12:8-12:14)
@@ -28,3 +37,9 @@
 // CHECK1-NEXT: c:objc(cs)B1(im)meth
 // CHECK1-NEXT: c:objc(pl)P1(im)meth
 // CHECK1-NEXT: OVERRIDES END
+
+// RUN: %sourcekitd-test -req=cursor -pos=25:20 %s -- -embed-bitcode -I %S/Inputs/cursor-overrides %mcp_opt %s | %FileCheck -check-prefix=CHECK2 %s
+// CHECK2: s:16cursor_overrides22WithInheritedAssocTypeP0eF0
+// CHECK2: OVERRIDES BEGIN
+// CHECK2-NEXT: s:16cursor_overrides13WithAssocTypeP0dE0
+// CHECK2-NEXT: OVERRIDES END
diff --git a/test/SourceKit/InterfaceGen/gen_swift_module.swift b/test/SourceKit/InterfaceGen/gen_swift_module.swift
index 7df6ce9..33c4418 100644
--- a/test/SourceKit/InterfaceGen/gen_swift_module.swift
+++ b/test/SourceKit/InterfaceGen/gen_swift_module.swift
@@ -15,12 +15,12 @@
 
 // RUN: %swift -emit-module -o %t.mod/swift_mod_syn.swiftmodule %S/Inputs/swift_mod_syn.swift -parse-as-library
 // RUN: %sourcekitd-test -req=interface-gen-open -module swift_mod_syn -- -I %t.mod == -req=cursor -pos=4:7 %s -- %s -I %t.mod | %FileCheck -check-prefix=SYNTHESIZED-USR1 %s
-// SYNTHESIZED-USR1: s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa
+// SYNTHESIZED-USR1: s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa
 
 // RUN: %sourcekitd-test -req=interface-gen-open -module Swift -synthesized-extension \
-// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa" | %FileCheck -check-prefix=SYNTHESIZED-USR2 %s
+// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa" | %FileCheck -check-prefix=SYNTHESIZED-USR2 %s
 // SYNTHESIZED-USR2-NOT: USR NOT FOUND
 
 // RUN: %sourcekitd-test -req=interface-gen-open -module Swift \
-// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa::SYNTHESIZED::USRDOESNOTEXIST" | %FileCheck -check-prefix=SYNTHESIZED-USR3 %s
+// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa::SYNTHESIZED::USRDOESNOTEXIST" | %FileCheck -check-prefix=SYNTHESIZED-USR3 %s
 // SYNTHESIZED-USR3-NOT: USR NOT FOUND
diff --git a/test/SourceKit/Misc/stats.swift b/test/SourceKit/Misc/stats.swift
new file mode 100644
index 0000000..32c7fff
--- /dev/null
+++ b/test/SourceKit/Misc/stats.swift
@@ -0,0 +1,57 @@
+func foo() {}
+
+// RUN: %sourcekitd-test -req=syntax-map %s == -req=stats | %FileCheck %s -check-prefix=SYNTAX_1
+
+// SYNTAX_1: 2 {{.*}} source.statistic.num-requests
+// SYNTAX_1: 0 {{.*}} source.statistic.num-semantic-requests
+// SYNTAX_1: 0 {{.*}} source.statistic.num-ast-builds
+// SYNTAX_1: 1 {{.*}} source.statistic.num-open-documents
+// SYNTAX_1: 1 {{.*}} source.statistic.max-open-documents
+
+// RUN: %sourcekitd-test -req=syntax-map %s == -req=close %s == -req=stats | %FileCheck %s -check-prefix=SYNTAX_2
+
+// SYNTAX_2: 3 {{.*}} source.statistic.num-requests
+// SYNTAX_2: 0 {{.*}} source.statistic.num-semantic-requests
+// SYNTAX_2: 0 {{.*}} source.statistic.num-ast-builds
+// SYNTAX_2: 0 {{.*}} source.statistic.num-open-documents
+// SYNTAX_2: 1 {{.*}} source.statistic.max-open-documents
+
+// RUN: %sourcekitd-test -req=sema %s -- %s == -req=stats | %FileCheck %s -check-prefix=SEMA_1
+
+// SEMA_1: 3 {{.*}} source.statistic.num-requests
+// SEMA_1: 0 {{.*}} source.statistic.num-semantic-requests
+// SEMA_1: 1 {{.*}} source.statistic.num-ast-builds
+// SEMA_1: 1 {{.*}} source.statistic.num-asts-in-memory
+// SEMA_1: 1 {{.*}} source.statistic.max-asts-in-memory
+// SEMA_1: 0 {{.*}} source.statistic.num-ast-cache-hits
+// SEMA_1: 0 {{.*}} source.statistic.num-ast-snaphost-uses
+
+// RUN: %sourcekitd-test -req=sema %s -- %s == -req=edit -pos=1:1 -replace=" " %s == -req=stats | %FileCheck %s -check-prefix=SEMA_2
+
+// SEMA_2: 5 {{.*}} source.statistic.num-requests
+// SEMA_2: 0 {{.*}} source.statistic.num-semantic-requests
+// SEMA_2: 2 {{.*}} source.statistic.num-ast-builds
+// SEMA_2: 1 {{.*}} source.statistic.num-asts-in-memory
+// SEMA_2: 2 {{.*}} source.statistic.max-asts-in-memory
+// SEMA_2: 0 {{.*}} source.statistic.num-ast-cache-hits
+// SEMA_2: 0 {{.*}} source.statistic.num-ast-snaphost-uses
+
+// RUN: %sourcekitd-test -req=sema %s -- %s == -req=cursor -pos=1:6 %s -- %s == -req=stats | %FileCheck %s -check-prefix=SEMA_3
+
+// SEMA_3: 4 {{.*}} source.statistic.num-requests
+// SEMA_3: 1 {{.*}} source.statistic.num-semantic-requests
+// SEMA_3: 1 {{.*}} source.statistic.num-ast-builds
+// SEMA_3: 1 {{.*}} source.statistic.num-asts-in-memory
+// SEMA_3: 1 {{.*}} source.statistic.max-asts-in-memory
+// SEMA_3: 0 {{.*}} source.statistic.num-ast-cache-hits
+// SEMA_3: 1 {{.*}} source.statistic.num-ast-snaphost-uses
+
+// RUN: %sourcekitd-test -req=sema %s -- %s == -req=related-idents -pos=1:6 %s -- %s == -req=stats | %FileCheck %s -check-prefix=SEMA_4
+
+// SEMA_4: 4 {{.*}} source.statistic.num-requests
+// SEMA_4: 1 {{.*}} source.statistic.num-semantic-requests
+// SEMA_4: 1 {{.*}} source.statistic.num-ast-builds
+// SEMA_4: 1 {{.*}} source.statistic.num-asts-in-memory
+// SEMA_4: 1 {{.*}} source.statistic.max-asts-in-memory
+// SEMA_4: 1 {{.*}} source.statistic.num-ast-cache-hits
+// SEMA_4: 0 {{.*}} source.statistic.num-ast-snaphost-uses
diff --git a/test/SwiftSyntax/LazyCaching.swift b/test/SwiftSyntax/LazyCaching.swift
index 1970935..753fca4 100644
--- a/test/SwiftSyntax/LazyCaching.swift
+++ b/test/SwiftSyntax/LazyCaching.swift
@@ -1,6 +1,7 @@
 // RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 // REQUIRES: OS=macosx
+// REQUIRES: sdk_overlay
 
 import StdlibUnittest
 import Foundation
diff --git a/test/SwiftSyntax/ParseFile.swift b/test/SwiftSyntax/ParseFile.swift
index 8d9a2b9..5909862 100644
--- a/test/SwiftSyntax/ParseFile.swift
+++ b/test/SwiftSyntax/ParseFile.swift
@@ -1,6 +1,7 @@
 // RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 // REQUIRES: OS=macosx
+// REQUIRES: sdk_overlay
 
 import Foundation
 import StdlibUnittest
diff --git a/test/SwiftSyntax/SyntaxFactory.swift b/test/SwiftSyntax/SyntaxFactory.swift
index 6686c57..f94d86a 100644
--- a/test/SwiftSyntax/SyntaxFactory.swift
+++ b/test/SwiftSyntax/SyntaxFactory.swift
@@ -1,6 +1,7 @@
 // RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 // REQUIRES: OS=macosx
+// REQUIRES: sdk_overlay
 
 import Foundation
 import StdlibUnittest
diff --git a/test/decl/inherit/initializer.swift b/test/decl/inherit/initializer.swift
index 7ceacd6..86cf550 100644
--- a/test/decl/inherit/initializer.swift
+++ b/test/decl/inherit/initializer.swift
@@ -150,3 +150,59 @@
 
   _ = B(t: t)
 }
+
+// rdar://problem/34789779
+public class Node {
+  var data : Data
+
+  public struct Data {
+    var index: Int32 = 0// for helpers
+  }
+
+ init(data: inout Data/*, context: Context*/) {
+   self.data = data
+ }
+
+ public required init(node: Node) {
+   data = node.data
+ }
+}
+
+class SubNode : Node {
+  var a: Int
+
+  required init(node: Node) {
+    a = 1
+    super.init(node: node)
+  }
+
+  init(data: inout Data, additionalParam: Int) {
+    a = additionalParam
+    super.init(data: &data)
+  }
+}
+
+class GenericSubNode<T> : SubNode {
+  required init(node: Node) {
+    super.init(node: node)
+  }
+
+  init(data: inout Data, value: T) {
+    super.init(data: &data, additionalParam: 1)
+  }
+}
+
+protocol HasValue {
+  associatedtype Value
+  func getValue() -> Value
+}
+
+class GenericWrapperNode<T : HasValue> : GenericSubNode<T.Value> {
+  required init(node: Node) {
+    super.init(node: node)
+  }
+
+  init(data: inout Data, otherValue: T) {
+    super.init(data: &data, value: otherValue.getValue())
+  }
+}
diff --git a/test/decl/protocol/associated_type_overrides.swift b/test/decl/protocol/associated_type_overrides.swift
new file mode 100644
index 0000000..99e8eaf
--- /dev/null
+++ b/test/decl/protocol/associated_type_overrides.swift
@@ -0,0 +1,28 @@
+// RUN: %target-swift-frontend -typecheck -dump-ast %s 2>&1 | %FileCheck %s
+
+protocol P1 {
+  associatedtype A
+}
+
+// CHECK-LABEL: protocol "P2"
+// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P1))
+protocol P2 : P1 {
+  associatedtype A
+}
+
+protocol P3 {
+  associatedtype A
+}
+
+// CHECK-LABEL: protocol "P4"
+// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P2, P3))
+protocol P4 : P2, P3 {
+  associatedtype A
+}
+
+// CHECK-LABEL: protocol "P5"
+// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P4))
+protocol P5 : P4, P2 {
+  associatedtype A
+}
+
diff --git a/test/decl/protocol/conforms/self.swift b/test/decl/protocol/conforms/self.swift
new file mode 100644
index 0000000..6b2a7e9
--- /dev/null
+++ b/test/decl/protocol/conforms/self.swift
@@ -0,0 +1,37 @@
+// RUN: %target-typecheck-verify-swift
+
+protocol P {
+  associatedtype T = Int
+
+  func hasDefault()
+  func returnsSelf() -> Self
+  func hasDefaultTakesT(_: T)
+  func returnsSelfTakesT(_: T) -> Self
+}
+
+extension P {
+  func hasDefault() {}
+
+  func returnsSelf() -> Self {
+    return self
+  }
+
+  func hasDefaultTakesT(_: T) {}
+
+  func returnsSelfTakesT(_: T) -> Self { // expected-error {{method 'returnsSelfTakesT' in non-final class 'Class' cannot be implemented in a protocol extension because it returns `Self` and has associated type requirements}}
+    return self
+  }
+}
+
+// This fails
+class Class : P {}
+
+// This succeeds, because the class is final
+final class FinalClass : P {}
+
+// This succeeds, because we're not using the default implementation
+class NonFinalClass : P {
+  func returnsSelfTakesT(_: T) -> Self {
+    return self
+  }
+}
diff --git a/test/decl/protocol/ownership_protocol.swift b/test/decl/protocol/ownership_protocol.swift
new file mode 100644
index 0000000..b998a81
--- /dev/null
+++ b/test/decl/protocol/ownership_protocol.swift
@@ -0,0 +1,29 @@
+// RUN: %target-typecheck-verify-swift -swift-version 5
+
+class SomeClass {}
+
+protocol P {
+  weak var foo: SomeClass? { get set } // expected-error {{'weak' cannot be applied to a property declaration in a protocol}}
+  unowned var foo2: SomeClass { get set } // expected-error {{'unowned' cannot be applied to a property declaration in a protocol}}
+  weak var foo3: Int? { get set } // expected-error {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}}
+  unowned var foo4: Int { get set } // expected-error {{'unowned' may only be applied to class and class-bound protocol types, not 'Int'}}
+  var foo9: SomeClass? { get }
+}
+
+extension P {
+  weak var foo5: SomeClass? // expected-error {{extensions must not contain stored properties}}
+  unowned var foo6: SomeClass // expected-error {{extensions must not contain stored properties}}
+  
+  weak var foo7: SomeClass? { // Okay
+    return SomeClass()
+  }
+
+  unowned var foo8: SomeClass { // Okay
+    return SomeClass()
+  }
+
+  weak var foo9: SomeClass? { // Okay
+    return nil
+  }
+}
+
diff --git a/test/decl/protocol/req/associated_type_inference.swift b/test/decl/protocol/req/associated_type_inference.swift
index 7d94310..5885342 100644
--- a/test/decl/protocol/req/associated_type_inference.swift
+++ b/test/decl/protocol/req/associated_type_inference.swift
@@ -195,9 +195,9 @@
     func then(_ success: (_: T) -> T) -> Self
 }
 
-public class CorePromise<T> : Thenable { // expected-error{{type 'CorePromise<T>' does not conform to protocol 'Thenable'}}
-    public func then(_ success: @escaping (_ t: T, _: CorePromise<T>) -> T) -> Self {
-        return self.then() { (t: T) -> T in
+public class CorePromise<U> : Thenable { // expected-error{{type 'CorePromise<U>' does not conform to protocol 'Thenable'}}
+    public func then(_ success: @escaping (_ t: U, _: CorePromise<U>) -> U) -> Self {
+        return self.then() { (t: U) -> U in // expected-error{{contextual closure type '(U, CorePromise<U>) -> U' expects 2 arguments, but 1 was used in closure body}}
             return success(t: t, self)
         }
     }
@@ -380,3 +380,23 @@
 struct Int8Vector : Vector {
   func process(elements: [Int8]) { }
 }
+
+// SR-4486
+protocol P13 {
+  associatedtype Arg // expected-note{{protocol requires nested type 'Arg'; do you want to add it?}}
+  func foo(arg: Arg)
+}
+
+struct S13 : P13 { // expected-error{{type 'S13' does not conform to protocol 'P13'}}
+  func foo(arg: inout Int) {}
+}
+
+// "Infer" associated type from generic parameter.
+protocol P14 {
+  associatedtype Value
+}
+
+struct P14a<Value>: P14 { }
+
+struct P14b<Value> { }
+extension P14b: P14 { }
diff --git a/test/expr/unary/keypath/keypath.swift b/test/expr/unary/keypath/keypath.swift
index 3b7f36c..0077db8 100644
--- a/test/expr/unary/keypath/keypath.swift
+++ b/test/expr/unary/keypath/keypath.swift
@@ -417,6 +417,23 @@
   _ = \X.Type.b // expected-error{{cannot refer to static member}}
 }
 
+class Bass: Hashable {
+  static func ==(_: Bass, _: Bass) -> Bool { return false }
+  var hashValue: Int { return 0 }
+}
+
+class Treble: Bass { }
+
+struct BassSubscript {
+  subscript(_: Bass) -> Int { fatalError() }
+  subscript(_: @autoclosure () -> String) -> Int { fatalError() }
+}
+
+func testImplicitConversionInSubscriptIndex() {
+  _ = \BassSubscript.[Treble()]
+  _ = \BassSubscript.["hello"] // expected-error{{must be Hashable}}
+}
+
 func testSyntaxErrors() { // expected-note{{}}
   _ = \.  ; // expected-error{{expected member name following '.'}}
   _ = \.a ;
diff --git a/test/lit.cfg b/test/lit.cfg
index 33dda81..c01f7b6 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -262,6 +262,7 @@
 config.llvm_cov = inferSwiftBinary('llvm-cov')
 config.filecheck = inferSwiftBinary('FileCheck')
 config.llvm_dwarfdump = inferSwiftBinary('llvm-dwarfdump')
+config.llvm_dis = inferSwiftBinary('llvm-dis')
 config.sourcekitd_test = inferSwiftBinary('sourcekitd-test')
 config.complete_test = inferSwiftBinary('complete-test')
 config.swift_api_digester = inferSwiftBinary('swift-api-digester')
@@ -295,6 +296,8 @@
 sdk_overlay_dir_opt = ""
 test_sdk_overlay_dir = lit_config.params.get('test_sdk_overlay_dir', None)
 if test_sdk_overlay_dir is not None:
+    config.available_features.add('sdk_overlay')
+
     sdk_overlay_dir_opt = ("-I %s" % os.path.join(test_sdk_overlay_dir, run_cpu))
     sdk_overlay_link_path_dir = os.path.join(test_sdk_overlay_dir, run_cpu)
     sdk_overlay_link_path = ("-L %s" % sdk_overlay_link_path_dir)
@@ -352,6 +355,7 @@
 config.substitutions.append( ('%llvm-link', config.llvm_link) )
 config.substitutions.append( ('%swift-llvm-opt', config.swift_llvm_opt) )
 config.substitutions.append( ('%llvm-dwarfdump', config.llvm_dwarfdump) )
+config.substitutions.append( ('%llvm-dis', config.llvm_dis) )
 
 # This must come after all substitutions containing "%swift".
 config.substitutions.append(
@@ -424,6 +428,7 @@
 disallow('clang')
 disallow('FileCheck')
 disallow('llvm-dwarfdump')
+disallow('llvm-dis')
 
 config.substitutions.insert(0,
     ('%p',
diff --git a/test/sil-func-extractor/basic.sil b/test/sil-func-extractor/basic.sil
index f4aaf96..39ba357 100644
--- a/test/sil-func-extractor/basic.sil
+++ b/test/sil-func-extractor/basic.sil
@@ -14,11 +14,11 @@
 // CHECK-NOT: sil @makesInt : $@convention(thin) () -> Int64
 sil @makesInt : $@convention(thin) () -> Int64
 
-// CHECK-LABEL: sil @use_before_init : $@convention(thin) () -> Int64 {
+// CHECK-LABEL: sil [serialized] @use_before_init : $@convention(thin) () -> Int64 {
 // CHECK: bb0:
 // CHECK: return
 // CHECK: }
-sil @use_before_init : $@convention(thin) () -> Int64 {
+sil [serialized] @use_before_init : $@convention(thin) () -> Int64 {
 bb0:
   %1 = alloc_box $<τ_0_0> { var τ_0_0 } <Int64>
   %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <Int64>, 0
diff --git a/test/sil-func-extractor/basic.swift b/test/sil-func-extractor/basic.swift
index cdf1e69..b04a786 100644
--- a/test/sil-func-extractor/basic.swift
+++ b/test/sil-func-extractor/basic.swift
@@ -17,7 +17,7 @@
 // EXTRACT-FOO-NOT: sil hidden @_T05basic7VehicleCACSi1n_tcfc : $@convention(method) (Int, @guaranteed Vehicle) -> @owned Vehicle {
 // EXTRACT-FOO-NOT: sil hidden @_T05basic7VehicleC3nowSiyF : $@convention(method) (@guaranteed Vehicle) -> Int {
 
-// EXTRACT-FOO-LABEL: sil hidden @_T05basic3fooSiyF : $@convention(thin) () -> Int {
+// EXTRACT-FOO-LABEL: sil [serialized] @_T05basic3fooSiyF : $@convention(thin) () -> Int {
 // EXTRACT-FOO:       bb0:
 // EXTRACT-FOO-NEXT:    %0 = integer_literal
 // EXTRACT-FOO:         %[[POS:.*]] = struct $Int
@@ -28,7 +28,7 @@
 // EXTRACT-TEST-NOT: sil hidden @_T05basic7VehicleCACSi1n_tcfc : $@convention(method) (Int, @guaranteed Vehicle) -> @owned Vehicle {
 // EXTRACT-TEST-NOT: sil hidden @_T05basic7VehicleC3nowSiyF : $@convention(method) (@guaranteed Vehicle) -> Int {
 
-// EXTRACT-TEST-LABEL:  sil hidden @_T05basic1XV4testyyF : $@convention(method) (X) -> () {
+// EXTRACT-TEST-LABEL:  sil [serialized] @_T05basic1XV4testyyF : $@convention(method) (X) -> () {
 // EXTRACT-TEST:        bb0(%0 : $X):
 // EXTRACT-TEST-NEXT:     function_ref
 // EXTRACT-TEST-NEXT:     function_ref @_T05basic3fooSiyF : $@convention(thin) () -> Int
@@ -37,11 +37,11 @@
 // EXTRACT-TEST-NEXT:     return
 
 
-// EXTRACT-INIT-NOT: sil hidden @_T05basic3fooSiyF : $@convention(thin) () -> Int {
-// EXTRACT-INIT-NOT: sil hidden @_T05basic1XV4testyyF : $@convention(method) (X) -> () {
-// EXTRACT-INIT-NOT: sil hidden @_T05basic7VehicleC3nowSiyF : $@convention(method) (@owned Vehicle) -> Int {
+// EXTRACT-INIT-NOT: sil [serialized] @_T05basic3fooSiyF : $@convention(thin) () -> Int {
+// EXTRACT-INIT-NOT: sil [serialized] @_T05basic1XV4testyyF : $@convention(method) (X) -> () {
+// EXTRACT-INIT-NOT: sil [serialized] @_T05basic7VehicleC3nowSiyF : $@convention(method) (@owned Vehicle) -> Int {
 
-// EXTRACT-INIT-LABEL:   sil hidden @_T05basic7VehicleCACSi1n_tcfc : $@convention(method) (Int, @owned Vehicle) -> @owned Vehicle {
+// EXTRACT-INIT-LABEL:   sil [serialized] @_T05basic7VehicleCACSi1n_tcfc : $@convention(method) (Int, @owned Vehicle) -> @owned Vehicle {
 // EXTRACT-INIT:         bb0
 // EXTRACT-INIT-NEXT:      ref_element_addr
 // EXTRACT-INIT-NEXT:      begin_access [modify] [dynamic]
@@ -50,11 +50,11 @@
 // EXTRACT-INIT-NEXT:      return
 
 
-// EXTRACT-NOW-NOT: sil hidden @_T05basic3fooSiyF : $@convention(thin) () -> Int {
-// EXTRACT-NOW-NOT: sil hidden @_T05basic1XV4testyyF : $@convention(method) (X) -> () {
-// EXTRACT-NOW-NOT: sil hidden @_T05basic7VehicleCACSi1n_tcfc : $@convention(method) (Int, @guaranteed Vehicle) -> @owned Vehicle {
+// EXTRACT-NOW-NOT: sil [serialized] @_T05basic3fooSiyF : $@convention(thin) () -> Int {
+// EXTRACT-NOW-NOT: sil [serialized] @_T05basic1XV4testyyF : $@convention(method) (X) -> () {
+// EXTRACT-NOW-NOT: sil [serialized] @_T05basic7VehicleCACSi1n_tcfc : $@convention(method) (Int, @guaranteed Vehicle) -> @owned Vehicle {
 
-// EXTRACT-NOW-LABEL:   sil hidden @_T05basic7VehicleC3nowSiyF : $@convention(method) (@guaranteed Vehicle) -> Int {
+// EXTRACT-NOW-LABEL:   sil [serialized] @_T05basic7VehicleC3nowSiyF : $@convention(method) (@guaranteed Vehicle) -> Int {
 // EXTRACT-NOW:         bb0
 // EXTRACT-NOW:           ref_element_addr
 // EXTRACT-NOW-NEXT:      begin_access [read] [dynamic]
@@ -62,25 +62,34 @@
 // EXTRACT-NOW-NEXT:      end_access
 // EXTRACT-NOW-NEXT:      return
 
-struct X {
+public struct X {
+  @_versioned
+  @_inlineable
   func test() {
     foo()
   }
 }
 
-class Vehicle {
+public class Vehicle {
+    @_versioned
     var numOfWheels: Int
 
+    @_versioned
+    @_inlineable
     init(n: Int) {
       numOfWheels = n
     }
 
+    @_versioned
+    @_inlineable
     func now() -> Int {
         return numOfWheels
     }
 }
 
 @discardableResult
+@_versioned
+@_inlineable
 func foo() -> Int {
   return 7
 }
diff --git a/test/sil-func-extractor/load-serialized-sil.swift b/test/sil-func-extractor/load-serialized-sil.swift
index 28dbbac..52c1eda 100644
--- a/test/sil-func-extractor/load-serialized-sil.swift
+++ b/test/sil-func-extractor/load-serialized-sil.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -primary-file %s -module-name Swift -g -sil-serialize-all -module-link-name swiftCore -O -parse-as-library -parse-stdlib -emit-module -emit-module-path - -o /dev/null | %target-sil-func-extractor -module-name="Swift" -func="_T0s1XV4testyyF" | %FileCheck %s
+// RUN: %target-swift-frontend -primary-file %s -module-name Swift -g -sil-serialize-witness-tables -sil-serialize-vtables -module-link-name swiftCore -O -parse-as-library -parse-stdlib -emit-module -emit-module-path - -o /dev/null | %target-sil-func-extractor -module-name="Swift" -func="_T0s1XV4testyyF" | %FileCheck %s
 // RUN: %target-swift-frontend -primary-file %s -module-name Swift -g -O -parse-as-library -parse-stdlib -emit-sib -o - | %target-sil-func-extractor -module-name="Swift" -func="_T0s1XV4testyyF" | %FileCheck %s -check-prefix=SIB-CHECK
 
 // CHECK: import Builtin
@@ -7,13 +7,14 @@
 // CHECK: func unknown()
 
 // CHECK: struct X {
-// CHECK-NEXT:  func test()
+// CHECK-NEXT:  @_versioned
+// CHECK-NEXT:  @_inlineable func test()
 // CHECK-NEXT:  init
 // CHECK-NEXT: }
 
 // CHECK: sil @unknown : $@convention(thin) () -> ()
 
-// CHECK-LABEL: sil hidden [serialized] @_T0s1XV4testyyF : $@convention(method) (X) -> ()
+// CHECK-LABEL: sil [serialized] @_T0s1XV4testyyF : $@convention(method) (X) -> ()
 // CHECK: bb0
 // CHECK-NEXT: function_ref
 // CHECK-NEXT: function_ref @unknown : $@convention(thin) () -> ()
@@ -30,13 +31,14 @@
 // SIB-CHECK: func unknown()
 
 // SIB-CHECK: struct X {
-// SIB-CHECK-NEXT:  func test()
+// SIB-CHECK-NEXT:  @_versioned
+// SIB-CHECK-NEXT:  @_inlineable func test()
 // SIB-CHECK-NEXT:  init
 // SIB-CHECK-NEXT: }
 
 // SIB-CHECK: sil @unknown : $@convention(thin) () -> ()
 
-// SIB-CHECK-LABEL: sil hidden @_T0s1XV4testyyF : $@convention(method) (X) -> ()
+// SIB-CHECK-LABEL: sil [serialized] @_T0s1XV4testyyF : $@convention(method) (X) -> ()
 // SIB-CHECK: bb0
 // SIB-CHECK-NEXT: function_ref
 // SIB-CHECK-NEXT: function_ref @unknown : $@convention(thin) () -> ()
@@ -49,7 +51,9 @@
 @_silgen_name("unknown")
 public func unknown() -> ()
 
-struct X {
+public struct X {
+  @_versioned
+  @_inlineable
   func test() {
     unknown()
   }
diff --git a/test/sil-nm/basic.sil b/test/sil-nm/basic.sil
index 5464b2d..77fdabe 100644
--- a/test/sil-nm/basic.sil
+++ b/test/sil-nm/basic.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-nm -assume-parsing-unqualified-ownership-sil %s | %FileCheck %s
+// RUN: %target-sil-nm -assume-parsing-unqualified-ownership-sil %s | %FileCheck -check-prefix=SIL-NM -check-prefix=CHECK %s
 // RUN: %target-sil-nm -demangle -assume-parsing-unqualified-ownership-sil %s | %FileCheck -check-prefix=DEMANGLE %s
 // RUN: rm -rfv %t
 // RUN: mkdir %t
@@ -22,28 +22,28 @@
 }
 
 // CHECK: F c_deinit
-sil @c_deinit : $@convention(method) (@owned C) -> () {
+sil [serialized] @c_deinit : $@convention(method) (@owned C) -> () {
 bb0(%0 : $C):
   %1 = tuple()
   return %1 : $()
 }
 
 // CHECK: F defaultA
-sil @defaultA : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> () {
+sil [serialized] @defaultA : $@convention(witness_method) <Self where Self : ResilientProtocol> (@in_guaranteed Self) -> () {
 bb0(%0 : $*Self):
   %result = tuple ()
   return %result : $()
 }
 
 // CHECK: F f1
-sil @f1 : $@convention(thin) () -> () {
+sil [serialized] @f1 : $@convention(thin) () -> () {
 bb0:
   %0 = tuple()
   return %0 : $()
 }
 
 // CHECK: F globalinit
-sil @globalinit : $@convention(thin) () -> () {
+sil [serialized] @globalinit : $@convention(thin) () -> () {
 bb0:
   %0 = tuple()
   return %0 : $()
@@ -54,11 +54,13 @@
 
 // CHECK: W _T04main23ConformingGenericStructVyxGAA17ResilientProtocolAAlWP
 // DEMANGLE: W protocol witness table for <A> main.ConformingGenericStruct<A> : main.ResilientProtocol in main
-sil_witness_table <T> ConformingGenericStruct<T> : ResilientProtocol module protocol_resilience {
+sil_witness_table [serialized] <T> ConformingGenericStruct<T> : ResilientProtocol module protocol_resilience {
   method #ResilientProtocol.defaultA!1: @defaultA
 }
 
-// CHECK: V C
+// vtables cannot be serialized from SIL.
+// Only the frontend has the -Xfrontend -sil-serialize-vtables option. 
+// SIL-NM: V C
 sil_vtable C {
   #C.deinit!deallocator: c_deinit
 }
diff --git a/test/sil-opt/sil-opt.swift b/test/sil-opt/sil-opt.swift
index c90c52f..4171261 100644
--- a/test/sil-opt/sil-opt.swift
+++ b/test/sil-opt/sil-opt.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -primary-file %s -module-name Swift -g -sil-serialize-all -module-link-name swiftCore -O -parse-as-library -parse-stdlib -emit-module -emit-module-path - -o /dev/null | %target-sil-opt -enable-sil-verify-all -module-name="Swift" | %FileCheck %s
+// RUN: %target-swift-frontend -primary-file %s -module-name Swift -g -sil-serialize-witness-tables -module-link-name swiftCore -O -parse-as-library -parse-stdlib -emit-module -emit-module-path - -o /dev/null | %target-sil-opt -enable-sil-verify-all -module-name="Swift" | %FileCheck %s
 // RUN: %target-swift-frontend -primary-file %s -module-name Swift -g -O -parse-as-library -parse-stdlib -emit-sib -o - | %target-sil-opt -enable-sil-verify-all -module-name="Swift" | %FileCheck %s -check-prefix=SIB-CHECK
 
 // CHECK: import Builtin
@@ -7,13 +7,13 @@
 // CHECK: func unknown()
 
 // CHECK: struct X {
-// CHECK-NEXT:  func test()
-// CHECK-NEXT:  init
+// CHECK-NEXT:  @_inlineable func test()
+// CHECK-NEXT:  @_inlineable init
 // CHECK-NEXT: }
 
 // CHECK: sil @unknown : $@convention(thin) () -> ()
 
-// CHECK-LABEL: sil hidden [serialized] @_T0s1XV4testyyF : $@convention(method) (X) -> ()
+// CHECK-LABEL: sil [serialized] @_T0s1XV4testyyF : $@convention(method) (X) -> ()
 // CHECK: bb0
 // CHECK-NEXT: function_ref
 // CHECK-NEXT: function_ref @unknown : $@convention(thin) () -> ()
@@ -21,7 +21,7 @@
 // CHECK-NEXT: tuple
 // CHECK-NEXT: return
 
-// CHECK-LABEL: sil hidden [serialized] @_T0s1XVABycfC : $@convention(method) (@thin X.Type) -> X
+// CHECK-LABEL: sil [serialized] @_T0s1XVABycfC : $@convention(method) (@thin X.Type) -> X
 // CHECK: bb0
 // CHECK-NEXT: struct $X ()
 // CHECK-NEXT: return
@@ -39,7 +39,7 @@
 
 // SIB-CHECK: sil @unknown : $@convention(thin) () -> ()
 
-// SIB-CHECK-LABEL: sil hidden @_T0s1XV4testyyF : $@convention(method) (X) -> ()
+// SIB-CHECK-LABEL: sil [serialized] @_T0s1XV4testyyF : $@convention(method) (X) -> ()
 // SIB-CHECK: bb0
 // SIB-CHECK-NEXT: function_ref
 // SIB-CHECK-NEXT: function_ref @unknown : $@convention(thin) () -> ()
@@ -47,7 +47,7 @@
 // SIB-CHECK-NEXT: tuple
 // SIB-CHECK-NEXT: return
 
-// SIB-CHECK-LABEL: sil hidden @_T0s1XVABycfC : $@convention(method) (@thin X.Type) -> X
+// SIB-CHECK-LABEL: sil [serialized] @_T0s1XVABycfC : $@convention(method) (@thin X.Type) -> X
 // SIB-CHECK: bb0
 // SIB-CHECK-NEXT: struct $X ()
 // SIB-CHECK-NEXT: return
@@ -55,8 +55,13 @@
 @_silgen_name("unknown")
 public func unknown() -> ()
 
-struct X {
-  func test() {
+// FIXME: Why does it need to be public?
+public struct X {
+  @_inlineable
+  public func test() {
     unknown()
   }
+
+  @_inlineable
+  public init() {}
 }
diff --git a/test/stdlib/Dispatch.swift b/test/stdlib/Dispatch.swift
index b3ff86f..a360372 100644
--- a/test/stdlib/Dispatch.swift
+++ b/test/stdlib/Dispatch.swift
@@ -10,7 +10,7 @@
 // REQUIRES: objc_interop
 
 // FIXME: rdar://34751238 DispatchTime.addSubtract test traps
-// XFAIL: CPU=armv7 || CPU=armv7k
+// XFAIL: CPU=armv7 || CPU=armv7k || CPU=armv7s || CPU=arm64
 
 
 import Dispatch
diff --git a/test/stdlib/StringCompatibilityDiagnostics.swift b/test/stdlib/StringCompatibilityDiagnostics.swift
index a26d6e0..352c6f1 100644
--- a/test/stdlib/StringCompatibilityDiagnostics.swift
+++ b/test/stdlib/StringCompatibilityDiagnostics.swift
@@ -1,4 +1,4 @@
-// RUN: %swift -typecheck -swift-version 4 %s -verify
+// RUN: %target-swift-frontend -typecheck -swift-version 4 %s -verify
 
 func testPopFirst() {
   var str = "abc"
diff --git a/test/stdlib/StringCompatibilityDiagnostics3.swift b/test/stdlib/StringCompatibilityDiagnostics3.swift
index 325b97f..c9358ac 100644
--- a/test/stdlib/StringCompatibilityDiagnostics3.swift
+++ b/test/stdlib/StringCompatibilityDiagnostics3.swift
@@ -1,4 +1,4 @@
-// RUN: %swift -typecheck -swift-version 3 %s -verify
+// RUN: %target-swift-frontend -typecheck -swift-version 3 %s -verify
 
 func testPopFirst() {
   var str = "abc"
diff --git a/test/stdlib/StringCompatibilityDiagnostics4.swift b/test/stdlib/StringCompatibilityDiagnostics4.swift
index 13cf2a9..b5fb753 100644
--- a/test/stdlib/StringCompatibilityDiagnostics4.swift
+++ b/test/stdlib/StringCompatibilityDiagnostics4.swift
@@ -1,4 +1,4 @@
-// RUN: %swift -typecheck -swift-version 4 %s -verify
+// RUN: %target-swift-frontend -typecheck -swift-version 4 %s -verify
 
 func testPopFirst() {
   var str = "abc"
diff --git a/test/stdlib/StringDescribing.swift b/test/stdlib/StringDescribing.swift
new file mode 100644
index 0000000..f9b9082
--- /dev/null
+++ b/test/stdlib/StringDescribing.swift
@@ -0,0 +1,21 @@
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+
+private class Foo {}
+class Bar {}
+
+var StringDescribingTestSuite = TestSuite("StringDescribing")
+
+StringDescribingTestSuite.test("String(describing:) shouldn't include extra stuff if the class is private") {
+  expectEqual(String(describing: Foo.self), "Foo")
+  expectEqual(String(describing: Bar.self), "Bar")
+}
+
+StringDescribingTestSuite.test("String(reflecting:) should include extra stuff if the class is private") {
+  expectEqual(String(reflecting: Bar.self), "main.Bar")
+  expectEqual(String(reflecting: Foo.self), "main.(Foo in _AE29BC3E71CF180B9604AA0071CCE6E8)")
+}
+
+runAllTests()
diff --git a/test/stdlib/StringMemoryTest.swift b/test/stdlib/StringMemoryTest.swift
new file mode 100644
index 0000000..68a5d24
--- /dev/null
+++ b/test/stdlib/StringMemoryTest.swift
@@ -0,0 +1,63 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -O %s -o %t/StringMemoryTest
+// RUN: %target-run %t/StringMemoryTest | %FileCheck %s
+
+// REQUIRES: optimized_stdlib
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+
+import Foundation
+
+let str = "abcdefg\u{A758}hijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\u{A759}"
+let str2 = "abcdefg\u{A759}hijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\u{A758}"
+
+@inline(never)
+func lookup(_ str: String, _ dict: [String: Int]) -> Bool {
+  if let _ = dict[str] {
+    return true
+  }
+  return false
+}
+
+@inline(never)
+func uppercase(_ str: String) -> String {
+      return str.uppercased()
+}
+
+@inline(never)
+func lowercase(_ str: String) -> String {
+      return str.lowercased()
+}
+
+/// Make sure the hash function does not leak.
+
+let dict = [ "foo" : 1]
+for _ in 0 ..< 10_000_000 {
+  if lookup("\u{1F1E7}\u{1F1E7}", dict) {
+    print("Found?!")
+  }
+  if uppercase(str) == "A" {
+    print("Found?!")
+  }
+  if lowercase(str2) == "A" {
+    print("Found?!")
+  }
+}
+
+// CHECK-NOT: Found?!
+// CHECK: Not found
+
+print("Not found")
+
+var usage = rusage()
+getrusage(RUSAGE_SELF, &usage)
+
+// CHECK: success
+// CHECK-NOT: failure
+
+// We should not need 50MB for this.
+if usage.ru_maxrss > 50 * 1024 * 1024 {
+  print("failure - should not need 50MB!")
+} else {
+  print("success")
+}
diff --git a/test/stdlib/WeakMirror.swift b/test/stdlib/WeakMirror.swift
index 252e299..a9f1d8b 100644
--- a/test/stdlib/WeakMirror.swift
+++ b/test/stdlib/WeakMirror.swift
@@ -103,7 +103,7 @@
 import Foundation
 
 @objc protocol ObjCClassExistential : class {
-  weak var weakProperty: AnyObject? { get set }
+  var weakProperty: AnyObject? { get set }
   var x: Int { get }
 }
 
diff --git a/test/stdlib/runtime_autorelease_optimization.txt b/test/stdlib/runtime_autorelease_optimization.txt
new file mode 100644
index 0000000..7b10575
--- /dev/null
+++ b/test/stdlib/runtime_autorelease_optimization.txt
@@ -0,0 +1,101 @@
+// REQUIRES: objc_interop
+// RUN: otool -tvV %platform-module-dir/libswiftCore.dylib | %FileCheck %s --check-prefix=CHECK-%target-cpu
+
+// Verify the autorelease return optimization sequence.
+
+/// Test x86-64:
+
+// CHECK-x86_64-LABEL: _swift_stdlib_NSStringHashValue:
+// CHECK-x86_64-NOT: ret
+// CHECK-x86_64: movq    {{.*}}(%rip), %rsi ## Objc selector ref: decomposedStringWithCanonicalMapping
+// CHECK-x86_64: movq    {{.*}}(%rip), [[MSG:%.*]] ## Objc message: -[%rdi decomposedStringWithCanonicalMapping]
+// CHECK-x86_64: callq   *[[MSG]]
+// CHECK-x86_64: movq    %rax, %rdi
+// CHECK-x86_64: callq   {{.*}} ## symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-x86_64: ret
+
+
+// CHECK-x86_64-LABEL: _swift_stdlib_NSStringHashValuePointer:
+// CHECK-x86_64-NOT: ret
+// CHECK-x86_64: movq    {{.*}}(%rip), %rsi ## Objc selector ref: decomposedStringWithCanonicalMapping
+// CHECK-x86_64: movq    {{.*}}(%rip), [[MSG:%.*]] ## Objc message: -[%rdi decomposedStringWithCanonicalMapping]
+// CHECK-x86_64: callq   *[[MSG]]
+// CHECK-x86_64: movq    %rax, %rdi
+// CHECK-x86_64: callq   {{.*}} ## symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-x86_64: ret
+
+/// Test i386:
+
+// CHECK-i386-LABEL: _swift_stdlib_NSStringHashValue:
+// CHECK-i386-NOT: ret
+// CHECK-i386: calll   {{.*}} ## symbol stub for: _objc_msgSend
+// CHECK-i386: movl    %ebp, %ebp
+// CHECK-i386: calll   {{.*}} ## symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-i386: ret
+// CHECK-i386-LABEL: _swift_stdlib_NSStringHashValuePointer:
+// CHECK-i386-NOT: ret
+// CHECK-i386: calll   {{.*}} ## symbol stub for: _objc_msgSend
+// CHECK-i386: movl    %ebp, %ebp
+// CHECK-i386: calll   {{.*}} ## symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-i386: ret
+
+/// Test armv7:
+
+// CHECK-armv7-LABEL: _swift_stdlib_NSStringHashValue:
+// CHECK-armv7-NOT: pop {{.*}}pc{{.*}}
+// CHECK-armv7: blx     {{.*}} @ symbol stub for: _objc_msgSend
+// CHECK-armv7: mov     r7, r7
+// CHECK-armv7: blx     {{.*}} @ symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-armv7: pop {{.*}}pc{{.*}}
+// CHECK-armv7-LABEL: _swift_stdlib_NSStringHashValuePointer:
+// CHECK-armv7-NOT: pop {{.*}}pc{{.*}}
+// CHECK-armv7: blx     {{.*}} @ symbol stub for: _objc_msgSend
+// CHECK-armv7: mov     r7, r7
+// CHECK-armv7: blx     {{.*}} @ symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-armv7: pop {{.*}}pc{{.*}}
+
+/// Test armv7s:
+
+// CHECK-armv7s-LABEL: _swift_stdlib_NSStringHashValue:
+// CHECK-armv7s-NOT: pop {{.*}}pc{{.*}}
+// CHECK-armv7s: blx     {{.*}} @ symbol stub for: _objc_msgSend
+// CHECK-armv7s: mov     r7, r7
+// CHECK-armv7s: blx     {{.*}} @ symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-armv7s: pop {{.*}}pc{{.*}}
+// CHECK-armv7s-LABEL: _swift_stdlib_NSStringHashValuePointer:
+// CHECK-armv7s-NOT: pop {{.*}}pc{{.*}}
+// CHECK-armv7s: blx     {{.*}} @ symbol stub for: _objc_msgSend
+// CHECK-armv7s: mov     r7, r7
+// CHECK-armv7s: blx     {{.*}} @ symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-armv7s: pop {{.*}}pc{{.*}}
+
+
+/// Test armv7k:
+
+// CHECK-armv7k-LABEL: _swift_stdlib_NSStringHashValue:
+// CHECK-armv7k-NOT: pop {{.*}}pc{{.*}}
+// CHECK-armv7k: blx     {{.*}} @ symbol stub for: _objc_msgSend
+// CHECK-armv7k: mov     r7, r7
+// CHECK-armv7k: blx     {{.*}} @ symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-armv7k: pop {{.*}}pc{{.*}}
+// CHECK-armv7k-LABEL: _swift_stdlib_NSStringHashValuePointer:
+// CHECK-armv7k-NOT: pop {{.*}}pc{{.*}}
+// CHECK-armv7k: blx     {{.*}} @ symbol stub for: _objc_msgSend
+// CHECK-armv7k: mov     r7, r7
+// CHECK-armv7k: blx     {{.*}} @ symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-armv7k: pop {{.*}}pc{{.*}}
+
+/// Test arm64:
+
+// CHECK-arm64-LABEL: _swift_stdlib_NSStringHashValue:
+// CHECK-arm64-NOT: ret
+// CHECK-arm64: bl      {{.*}} ; Objc message: -[x0 decomposedStringWithCanonicalMapping]
+// CHECK-arm64: mov      x29, x29
+// CHECK-arm64: bl      {{.*}} ; symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-arm64: ret
+// CHECK-arm64-LABEL: _swift_stdlib_NSStringHashValuePointer:
+// CHECK-arm64-NOT: ret
+// CHECK-arm64: bl      {{.*}} ; Objc message: -[x0 decomposedStringWithCanonicalMapping]
+// CHECK-arm64: mov      x29, x29
+// CHECK-arm64: bl      {{.*}} ; symbol stub for: _objc_retainAutoreleasedReturnValue
+// CHECK-arm64: ret
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 2c0677c..055dc27 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -22,7 +22,10 @@
   # Only build Darwin-specific tools when deploying to OS X.
   add_swift_tool_subdirectory(swift-stdlib-tool)
 
-  if(SWIFT_BUILD_STDLIB)
+  # SwiftSyntax depends on both the standard library (because it's a
+  # Swift module), and the SDK overlays (because it depends on Foundation).
+  # Ensure we only build SwiftSyntax when we're building both.
+  if(SWIFT_BUILD_STDLIB AND SWIFT_BUILD_SDK_OVERLAY)
     add_subdirectory(SwiftSyntax)
   endif()
 endif()
diff --git a/tools/SourceKit/CMakeLists.txt b/tools/SourceKit/CMakeLists.txt
index 9ac9b80..8b37b55 100644
--- a/tools/SourceKit/CMakeLists.txt
+++ b/tools/SourceKit/CMakeLists.txt
@@ -98,25 +98,54 @@
                         CMAKE_ARGS
                           -DCMAKE_C_COMPILER=${PATH_TO_CLANG_BUILD}/bin/clang
                           -DCMAKE_CXX_COMPILER=${PATH_TO_CLANG_BUILD}/bin/clang++
+                          -DCMAKE_SWIFT_COMPILER=$<TARGET_FILE:swift>c
                           -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+                          -DENABLE_SWIFT=YES
                         BUILD_BYPRODUCTS
-                          ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/${CMAKE_SHARED_LIBRARY_PREFIX}dispatch${CMAKE_SHARED_LIBRARY_SUFFIX})
+                          ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/${CMAKE_SHARED_LIBRARY_PREFIX}dispatch${CMAKE_SHARED_LIBRARY_SUFFIX}
+                          ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/${CMAKE_STATIC_LIBRARY_PREFIX}BlocksRuntime${CMAKE_STATIC_LIBRARY_SUFFIX}
+                        STEP_TARGETS
+                          configure
+                        BUILD_ALWAYS
+                          1)
 
+    # CMake does not like the addition of INTERFACE_INCLUDE_DIRECTORIES without
+    # the directory existing.  Just create the location which will be populated
+    # during the installation.
+    ExternalProject_Get_Property(libdispatch install_dir)
+    file(MAKE_DIRECTORY ${install_dir}/include)
+
+    # TODO(compnerd) this should be taken care of by the
+    # INTERFACE_INCLUDE_DIRECTORIES below
     include_directories(AFTER
-                          ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}/src/BlocksRuntime)
-    link_directories(${SWIFT_PATH_TO_LIBDISPATCH_BUILD})
+                          ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}/src/BlocksRuntime
+                          ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE})
+    add_dependencies(libdispatch
+                       swift
+                       swiftCore-${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}-${SWIFT_HOST_VARIANT_ARCH}
+                       swiftSwiftOnoneSupport-${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}-${SWIFT_HOST_VARIANT_ARCH}
+                       swiftCore-swiftmodule-${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}-${SWIFT_HOST_VARIANT_ARCH}
+                       swiftSwiftOnoneSupport-swiftmodule-${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}-${SWIFT_HOST_VARIANT_ARCH})
   endif()
 
-  include_directories(AFTER ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE})
-
-  add_library(dispatch UNKNOWN IMPORTED)
+  ExternalProject_Get_Property(libdispatch install_dir)
+  add_library(dispatch SHARED IMPORTED)
   set_target_properties(dispatch
                         PROPERTIES
-                          IMPORTED_LOCATION ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/${CMAKE_SHARED_LIBRARY_PREFIX}dispatch${CMAKE_SHARED_LIBRARY_SUFFIX})
+                          IMPORTED_LOCATION
+                            ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/src/${CMAKE_SHARED_LIBRARY_PREFIX}dispatch${CMAKE_SHARED_LIBRARY_SUFFIX}
+                          INTERFACE_INCLUDE_DIRECTORIES
+                            ${install_dir}/include
+                          IMPORTED_LINK_INTERFACE_LIBRARIES
+                            swiftCore-${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}-${SWIFT_HOST_VARIANT_ARCH})
 
-  add_library(swiftCore SHARED IMPORTED)
-  set_target_properties(swiftCore PROPERTIES
-                        IMPORTED_LOCATION ${SOURCEKIT_BINARY_DIR}/lib/swift/linux/libswiftCore.so)
+  add_library(BlocksRuntime STATIC IMPORTED)
+  set_target_properties(BlocksRuntime
+                        PROPERTIES
+                          IMPORTED_LOCATION
+                            ${SWIFT_PATH_TO_LIBDISPATCH_BUILD}/${CMAKE_STATIC_LIBRARY_PREFIX}BlocksRuntime${CMAKE_STATIC_LIBRARY_SUFFIX}
+                          INTERFACE_INCLUDE_DIRECTORIES
+                            ${SWIFT_PATH_TO_LIBDISPATCH_SOURCE}/src/BlocksRuntime)
 
   set(SOURCEKIT_NEED_EXPLICIT_LIBDISPATCH TRUE)
 endif()
diff --git a/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake b/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
index 0a42829..441c019 100644
--- a/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
+++ b/tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
@@ -67,8 +67,18 @@
     RESULT_VAR_NAME link_flags)
 
   if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+    # TODO(compnerd) this should really use target_compile_options but the use
+    # of keyword and non-keyword flags prevents this
     list(APPEND c_compile_flags "-fblocks")
+    # TODO(compnerd) this should really use target_link_libraries but the use of
+    # explicit_llvm_config using target_link_libraries without keywords on
+    # executables causes conflicts here
+    list(APPEND link_flags "-L${SWIFT_PATH_TO_LIBDISPATCH_BUILD}")
     list(APPEND link_flags "-lBlocksRuntime")
+    # NOTE(compnerd) since we do not use target_link_libraries, we do not get
+    # the implicit dependency tracking.  Add an explicit dependency until we can
+    # use target_link_libraries.
+    add_dependencies(${target} BlocksRuntime)
   endif()
 
   # Convert variables to space-separated strings.
diff --git a/tools/SourceKit/include/SourceKit/Core/LangSupport.h b/tools/SourceKit/include/SourceKit/Core/LangSupport.h
index 7cb7f86..117fc80 100644
--- a/tools/SourceKit/include/SourceKit/Core/LangSupport.h
+++ b/tools/SourceKit/include/SourceKit/Core/LangSupport.h
@@ -251,6 +251,9 @@
   virtual bool valueForOption(UIdent Key, StringRef &Val) = 0;
 };
 
+struct Statistic;
+typedef std::function<void(ArrayRef<Statistic *> stats)> StatisticsReceiver;
+
 struct RefactoringInfo {
   UIdent Kind;
   StringRef KindName;
@@ -626,6 +629,8 @@
                           StringRef ModuleName,
                           ArrayRef<const char *> Args,
                           DocInfoConsumer &Consumer) = 0;
+
+  virtual void getStatistics(StatisticsReceiver) = 0;
 };
 
 } // namespace SourceKit
diff --git a/tools/SourceKit/include/SourceKit/Core/ProtocolUIDs.def b/tools/SourceKit/include/SourceKit/Core/ProtocolUIDs.def
index b332d41..2efa730 100644
--- a/tools/SourceKit/include/SourceKit/Core/ProtocolUIDs.def
+++ b/tools/SourceKit/include/SourceKit/Core/ProtocolUIDs.def
@@ -107,6 +107,7 @@
 KEY(LocalizationKey, "key.localization_key")
 KEY(IsZeroArgSelector, "key.is_zero_arg_selector")
 KEY(SwiftVersion, "key.swift_version")
+KEY(Value, "key.value")
 
 KEY(EnableDiagnostics, "key.enablediagnostics")
 KEY(GroupName, "key.groupname")
@@ -181,6 +182,7 @@
 REQUEST(ModuleGroups, "source.request.module.groups")
 REQUEST(NameTranslation, "source.request.name.translation")
 REQUEST(MarkupToXML, "source.request.convert.markup.xml")
+REQUEST(Statistics, "source.request.statistics")
 
 REQUEST(SyntacticRename, "source.request.syntacticrename")
 REQUEST(FindRenameRanges, "source.request.find-syntactic-rename-ranges")
@@ -340,6 +342,9 @@
 KIND(Call, "source.syntacticrename.call")
 KIND(Unknown, "source.syntacticrename.unknown")
 
+KIND(StatNumRequests, "source.statistic.num-requests")
+KIND(StatNumSemaRequests, "source.statistic.num-semantic-requests")
+
 #undef KIND
 #undef REQUEST
 #undef KEY
diff --git a/tools/SourceKit/include/SourceKit/Support/Statistic.h b/tools/SourceKit/include/SourceKit/Support/Statistic.h
new file mode 100644
index 0000000..8f62f55
--- /dev/null
+++ b/tools/SourceKit/include/SourceKit/Support/Statistic.h
@@ -0,0 +1,48 @@
+//===--- Statistic.h - ------------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SOURCEKIT_SUPPORT_STATISTIC_H
+#define LLVM_SOURCEKIT_SUPPORT_STATISTIC_H
+
+#include "SourceKit/Support/UIdent.h"
+#include <atomic>
+#include <string>
+
+namespace SourceKit {
+
+struct Statistic {
+  const UIdent name;
+  const std::string description;
+  std::atomic<int64_t> value = {0};
+
+  Statistic(UIdent name, std::string description)
+      : name(name), description(std::move(description)) {}
+
+  int64_t operator++() {
+    return 1 + value.fetch_add(1, std::memory_order_relaxed);
+  }
+  int64_t operator--() {
+    return value.fetch_sub(1, std::memory_order_relaxed) - 1;
+  }
+
+  void updateMax(int64_t newValue) {
+    int64_t prev = value.load(std::memory_order_relaxed);
+    // Note: compare_exchange_weak updates 'prev' if it fails.
+    while (newValue > prev && !value.compare_exchange_weak(
+                                  prev, newValue, std::memory_order_relaxed)) {
+    }
+  }
+};
+
+} // namespace SourceKit
+
+#endif // LLVM_SOURCEKIT_SUPPORT_STATISTIC_H
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
index b082757..9597a5f 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
@@ -158,13 +158,15 @@
 namespace SourceKit {
   struct ASTUnit::Implementation {
     const uint64_t Generation;
+    SwiftStatistics &Stats;
     SmallVector<ImmutableTextSnapshotRef, 4> Snapshots;
     EditorDiagConsumer CollectDiagConsumer;
     CompilerInstance CompInst;
     OwnedResolver TypeResolver{ nullptr, nullptr };
     WorkQueue Queue{ WorkQueue::Dequeuing::Serial, "sourcekit.swift.ConsumeAST" };
 
-    Implementation(uint64_t Generation) : Generation(Generation) {}
+    Implementation(uint64_t Generation, SwiftStatistics &Statistics)
+        : Generation(Generation), Stats(Statistics) {}
 
     void consumeAsync(SwiftASTConsumerRef ASTConsumer, ASTUnitRef ASTRef);
   };
@@ -185,10 +187,14 @@
     });
   }
 
-  ASTUnit::ASTUnit(uint64_t Generation) : Impl(*new Implementation(Generation)) {
+  ASTUnit::ASTUnit(uint64_t Generation, SwiftStatistics &Stats)
+      : Impl(*new Implementation(Generation, Stats)) {
+    auto numASTs = ++Stats.numASTsInMem;
+    Stats.maxASTsInMem.updateMax(numASTs);
   }
 
   ASTUnit::~ASTUnit() {
+    --Impl.Stats.numASTsInMem;
     delete &Impl;
   }
 
@@ -307,10 +313,12 @@
 
 struct SwiftASTManager::Implementation {
   explicit Implementation(SwiftLangSupport &LangSupport)
-    : EditorDocs(LangSupport.getEditorDocuments()),
-      RuntimeResourcePath(LangSupport.getRuntimeResourcePath()) { }
+      : EditorDocs(LangSupport.getEditorDocuments()),
+        Stats(LangSupport.getStatistics()),
+        RuntimeResourcePath(LangSupport.getRuntimeResourcePath()) {}
 
   SwiftEditorDocumentFileMap &EditorDocs;
+  SwiftStatistics &Stats;
   std::string RuntimeResourcePath;
   SourceManager SourceMgr;
   Cache<ASTKey, ASTProducerRef> ASTCache{ "sourcekit.swift.ASTCache" };
@@ -488,6 +496,7 @@
 
   if (ASTUnitRef Unit = Producer->getExistingAST()) {
     if (ASTConsumer->canUseASTWithSnapshots(Unit->getSnapshots())) {
+      ++Impl.Stats.numASTsUsedWithSnaphots;
       Unit->Impl.consumeAsync(std::move(ASTConsumer), Unit);
       return;
     }
@@ -616,6 +625,8 @@
       ASTProducerRef ThisProducer = this;
       MgrImpl.ASTCache.set(InvokRef->Impl.Key, ThisProducer);
     }
+  } else {
+    ++MgrImpl.Stats.numASTCacheHits;
   }
 
   return AST;
@@ -732,6 +743,8 @@
 ASTUnitRef ASTProducer::createASTUnit(SwiftASTManager::Implementation &MgrImpl,
                                       ArrayRef<ImmutableTextSnapshotRef> Snapshots,
                                       std::string &Error) {
+  ++MgrImpl.Stats.numASTBuilds;
+
   Stamps.clear();
   DependencyStamps.clear();
 
@@ -770,7 +783,7 @@
     TraceInfo.Args.Args = Opts.Args;
   }
 
-  ASTUnitRef ASTRef = new ASTUnit(++ASTUnitGeneration);
+  ASTUnitRef ASTRef = new ASTUnit(++ASTUnitGeneration, MgrImpl.Stats);
   for (auto &Content : Contents) {
     if (Content.Snapshot)
       ASTRef->Impl.Snapshots.push_back(Content.Snapshot);
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h
index e6b4cee..a47c975 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h
+++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h
@@ -40,6 +40,7 @@
   class SwiftEditorDocumentFileMap;
   class SwiftLangSupport;
   class SwiftInvocation;
+  struct SwiftStatistics;
   typedef RefPtr<SwiftInvocation> SwiftInvocationRef;
   class EditorDiagConsumer;
 
@@ -48,7 +49,7 @@
   struct Implementation;
   Implementation &Impl;
 
-  explicit ASTUnit(uint64_t Generation);
+  explicit ASTUnit(uint64_t Generation, SwiftStatistics &Statistics);
   ~ASTUnit();
 
   swift::CompilerInstance &getCompilerInstance() const;
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
index 7414626..b42e0ef 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
@@ -2073,6 +2073,8 @@
       LOG_WARN_FUNC("Document already exists in editorOpen(..): " << Name);
       Snapshot = nullptr;
     }
+    auto numOpen = ++Stats.numOpenDocs;
+    Stats.maxOpenDocs.updateMax(numOpen);
   }
 
   if (!Snapshot) {
@@ -2095,8 +2097,12 @@
 
 void SwiftLangSupport::editorClose(StringRef Name, bool RemoveCache) {
   auto Removed = EditorDocuments.remove(Name);
-  if (!Removed)
+  if (Removed) {
+    --Stats.numOpenDocs;
+  } else {
     IFaceGenContexts.remove(Name);
+  }
+
   if (Removed && RemoveCache)
     Removed->removeCachedAST();
   // FIXME: Report error if Name did not apply to anything ?
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
index dfb75c6..f4afeb8 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
@@ -715,6 +715,14 @@
 #endif
 }
 
+void SwiftLangSupport::getStatistics(StatisticsReceiver receiver) {
+  std::vector<Statistic *> stats = {
+#define SWIFT_STATISTIC(VAR, UID, DESC) &Stats.VAR,
+#include "SwiftStatistics.def"
+  };
+  receiver(stats);
+}
+
 CloseClangModuleFiles::~CloseClangModuleFiles() {
   clang::Preprocessor &PP = loader.getClangPreprocessor();
   clang::ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
index 4e837c1..8b2bc5a 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h
@@ -17,6 +17,7 @@
 #include "SwiftInterfaceGenContext.h"
 #include "SourceKit/Core/LangSupport.h"
 #include "SourceKit/Support/Concurrency.h"
+#include "SourceKit/Support/Statistic.h"
 #include "SourceKit/Support/ThreadSafeRefCntPtr.h"
 #include "SourceKit/Support/Tracing.h"
 #include "swift/Basic/ThreadSafeRefCounted.h"
@@ -250,6 +251,12 @@
                         const swift::DiagnosticInfo &Info) override;
 };
 
+struct SwiftStatistics {
+#define SWIFT_STATISTIC(VAR, UID, DESC)                                        \
+  Statistic VAR{UIdent{"source.statistic." #UID}, DESC};
+#include "SwiftStatistics.def"
+};
+
 class SwiftLangSupport : public LangSupport {
   SourceKit::Context &SKCtx;
   std::string RuntimeResourcePath;
@@ -260,6 +267,7 @@
   ThreadSafeRefCntPtr<SwiftPopularAPI> PopularAPI;
   CodeCompletion::SessionCacheMap CCSessions;
   ThreadSafeRefCntPtr<SwiftCustomCompletions> CustomCompletions;
+  SwiftStatistics Stats;
 
 public:
   explicit SwiftLangSupport(SourceKit::Context &SKCtx);
@@ -277,6 +285,8 @@
     return CCCache;
   }
 
+  SwiftStatistics &getStatistics() { return Stats; }
+
   static SourceKit::UIdent getUIDForDecl(const swift::Decl *D,
                                          bool IsRef = false);
   static SourceKit::UIdent getUIDForExtensionOfDecl(const swift::Decl *D);
@@ -492,6 +502,8 @@
   void findModuleGroups(StringRef ModuleName, ArrayRef<const char *> Args,
                std::function<void(ArrayRef<StringRef>, StringRef Error)> Receiver) override;
 
+  void getStatistics(StatisticsReceiver) override;
+
 private:
   swift::SourceFile *getSyntacticSourceFile(llvm::MemoryBuffer *InputBuf,
                                             ArrayRef<const char *> Args,
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftStatistics.def b/tools/SourceKit/lib/SwiftLang/SwiftStatistics.def
new file mode 100644
index 0000000..8bc2b45
--- /dev/null
+++ b/tools/SourceKit/lib/SwiftLang/SwiftStatistics.def
@@ -0,0 +1,28 @@
+//===--- SwiftStatistics.def - ----------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_STATISTIC
+#error "must define SWIFT_STATISTIC to use"
+#endif
+
+/// SWIFT_STATISTIC(VAR_NAME, UNIQUE_ID, DESCRIPTION)
+
+SWIFT_STATISTIC(numASTBuilds, num-ast-builds, "# of ASTs built or rebuilt")
+SWIFT_STATISTIC(numASTsInMem, num-asts-in-memory, "# of ASTs currently in memory")
+SWIFT_STATISTIC(maxASTsInMem, max-asts-in-memory, "maximum # of ASTs ever in memory at once")
+SWIFT_STATISTIC(numASTCacheHits, num-ast-cache-hits, "# of ASTs found in the cache without rebuilding")
+SWIFT_STATISTIC(numASTsUsedWithSnaphots, num-ast-snaphost-uses, "# of ASTs used with snaphots without rebuilding")
+
+SWIFT_STATISTIC(numOpenDocs, num-open-documents, "# of editor documents currently open")
+SWIFT_STATISTIC(maxOpenDocs, max-open-documents, "maximum # of editor documents ever open at once")
+
+#undef SWIFT_STATISTIC
diff --git a/tools/SourceKit/tools/complete-test/CMakeLists.txt b/tools/SourceKit/tools/complete-test/CMakeLists.txt
index e67b69e..110192c 100644
--- a/tools/SourceKit/tools/complete-test/CMakeLists.txt
+++ b/tools/SourceKit/tools/complete-test/CMakeLists.txt
@@ -5,7 +5,7 @@
 endif()
 
 if(SOURCEKIT_NEED_EXPLICIT_LIBDISPATCH)
-  set(SOURCEKITD_TEST_LINK_LIBS ${SOURCEKITD_TEST_LINK_LIBS} dispatch swiftCore)
+  set(SOURCEKITD_TEST_LINK_LIBS ${SOURCEKITD_TEST_LINK_LIBS} dispatch)
 endif()
 
 add_sourcekit_executable(complete-test
diff --git a/tools/SourceKit/tools/sourcekitd-repl/CMakeLists.txt b/tools/SourceKit/tools/sourcekitd-repl/CMakeLists.txt
index 0cc215f..0924db9 100644
--- a/tools/SourceKit/tools/sourcekitd-repl/CMakeLists.txt
+++ b/tools/SourceKit/tools/sourcekitd-repl/CMakeLists.txt
@@ -9,7 +9,7 @@
   endif()
 
   if(SOURCEKIT_NEED_EXPLICIT_LIBDISPATCH)
-    set(SOURCEKITD_REPL_LINK_LIBS ${SOURCEKITD_REPL_LINK_LIBS} dispatch swiftCore)
+    set(SOURCEKITD_REPL_LINK_LIBS ${SOURCEKITD_REPL_LINK_LIBS} dispatch)
   endif()
 
   add_sourcekit_executable(sourcekitd-repl
diff --git a/tools/SourceKit/tools/sourcekitd-test/CMakeLists.txt b/tools/SourceKit/tools/sourcekitd-test/CMakeLists.txt
index 1a409ef..fb739cc 100644
--- a/tools/SourceKit/tools/sourcekitd-test/CMakeLists.txt
+++ b/tools/SourceKit/tools/sourcekitd-test/CMakeLists.txt
@@ -9,7 +9,7 @@
 endif()
 
 if(SOURCEKIT_NEED_EXPLICIT_LIBDISPATCH)
-  set(SOURCEKITD_TEST_LINK_LIBS ${SOURCEKITD_TEST_LINK_LIBS} dispatch swiftCore)
+  set(SOURCEKITD_TEST_LINK_LIBS ${SOURCEKITD_TEST_LINK_LIBS} dispatch)
 endif()
 
 add_sourcekit_executable(sourcekitd-test
diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
index 07a1f7c..4f77007 100644
--- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp
@@ -127,6 +127,7 @@
         .Case("find-usr", SourceKitRequest::FindUSR)
         .Case("find-interface", SourceKitRequest::FindInterfaceDoc)
         .Case("open", SourceKitRequest::Open)
+        .Case("close", SourceKitRequest::Close)
         .Case("edit", SourceKitRequest::Edit)
         .Case("print-annotations", SourceKitRequest::PrintAnnotations)
         .Case("print-diags", SourceKitRequest::PrintDiags)
@@ -145,6 +146,7 @@
         .Case("expand-default", SourceKitRequest::ExpandDefault)
         .Case("localize-string", SourceKitRequest::LocalizeString)
         .Case("markup-xml", SourceKitRequest::MarkupToXML)
+        .Case("stats", SourceKitRequest::Statistics)
         .Default(SourceKitRequest::None);
 
       if (Request == SourceKitRequest::None) {
@@ -153,8 +155,8 @@
                "complete.update/complete.cache.ondisk/complete.cache.setpopularapi/"
                "cursor/related-idents/syntax-map/structure/format/expand-placeholder/"
                "doc-info/sema/interface-gen/interface-gen-openfind-usr/find-interface/"
-               "open/edit/print-annotations/print-diags/extract-comment/module-groups/"
-               "range/syntactic-rename/find-rename-ranges/translate/markup-xml\n";
+               "open/close/edit/print-annotations/print-diags/extract-comment/module-groups/"
+               "range/syntactic-rename/find-rename-ranges/translate/markup-xml/stats\n";
         return true;
       }
       break;
diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
index 0464d8da..3d3d05b 100644
--- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
+++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h
@@ -45,6 +45,7 @@
   FindUSR,
   FindInterfaceDoc,
   Open,
+  Close,
   Edit,
   PrintAnnotations,
   PrintDiags,
@@ -55,6 +56,7 @@
   FindLocalRenameRanges,
   NameTranslation,
   MarkupToXML,
+  Statistics,
 #define SEMANTIC_REFACTORING(KIND, NAME, ID) KIND,
 #include "swift/IDE/RefactoringKinds.def"
 };
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index 47ce8a1..5c1568a 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -71,6 +71,7 @@
 static void prepareMangleRequest(sourcekitd_object_t Req,
                                  const TestOptions &Opts);
 static void printMangleResults(sourcekitd_variant_t Info, raw_ostream &OS);
+static void printStatistics(sourcekitd_variant_t Info, raw_ostream &OS);
 
 static unsigned resolveFromLineCol(unsigned Line, unsigned Col,
                                    StringRef Filename);
@@ -569,6 +570,11 @@
     sourcekitd_request_dictionary_set_string(Req, KeyName, SourceFile.c_str());
     break;
 
+  case SourceKitRequest::Close:
+    sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestEditorClose);
+    sourcekitd_request_dictionary_set_string(Req, KeyName, SourceFile.c_str());
+    break;
+
   case SourceKitRequest::Edit:
     sourcekitd_request_dictionary_set_uid(Req, KeyRequest,
                                           RequestEditorReplaceText);
@@ -662,7 +668,7 @@
     break;
 
   case SourceKitRequest::SyntacticRename:
-  case SourceKitRequest::FindRenameRanges:
+  case SourceKitRequest::FindRenameRanges: {
     if (Opts.Request == SourceKitRequest::SyntacticRename) {
       sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestSyntacticRename);
     } else {
@@ -684,6 +690,10 @@
     sourcekitd_request_dictionary_set_value(Req, KeyRenameLocations, RenameSpec);
     break;
   }
+  case SourceKitRequest::Statistics:
+    sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestStatistics);
+    break;
+  }
 
   if (!SourceFile.empty()) {
     if (Opts.PassAsSourceText) {
@@ -803,6 +813,7 @@
       break;
 
     case SourceKitRequest::ProtocolVersion:
+    case SourceKitRequest::Close:
     case SourceKitRequest::Index:
     case SourceKitRequest::CodeComplete:
     case SourceKitRequest::CodeCompleteOpen:
@@ -945,6 +956,8 @@
       case SourceKitRequest::FindLocalRenameRanges:
         printRenameRanges(Info, llvm::outs());
         break;
+      case SourceKitRequest::Statistics:
+        printStatistics(Info, llvm::outs());
     }
   }
 
@@ -1636,6 +1649,18 @@
   OS << "END MANGLE\n";
 }
 
+static void printStatistics(sourcekitd_variant_t Info, raw_ostream &OS) {
+  sourcekitd_variant_t results =
+    sourcekitd_variant_dictionary_get_value(Info, KeyResults);
+  sourcekitd_variant_array_apply(results, ^bool(size_t index, sourcekitd_variant_t value) {
+    auto uid = sourcekitd_variant_dictionary_get_uid(value, KeyKind);
+    auto desc = sourcekitd_variant_dictionary_get_string(value, KeyDescription);
+    auto statValue = sourcekitd_variant_dictionary_get_int64(value, KeyValue);
+    OS << statValue << "\t" << desc << "\t- " << sourcekitd_uid_get_string_ptr(uid) << "\n";
+    return true;
+  });
+}
+
 static void initializeRewriteBuffer(StringRef Input,
                                     clang::RewriteBuffer &RewriteBuf) {
   RewriteBuf.Initialize(Input);
diff --git a/tools/SourceKit/tools/sourcekitd/bin/InProc/CMakeLists.txt b/tools/SourceKit/tools/sourcekitd/bin/InProc/CMakeLists.txt
index 0e2e7cd..e3a9d07 100644
--- a/tools/SourceKit/tools/sourcekitd/bin/InProc/CMakeLists.txt
+++ b/tools/SourceKit/tools/sourcekitd/bin/InProc/CMakeLists.txt
@@ -42,10 +42,6 @@
   )
 endif()
 
-if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
-  target_link_libraries(sourcekitdInProc PUBLIC BlocksRuntime)
-endif()
-
 if (SOURCEKIT_BUILT_STANDALONE)
   # Create the symlinks necessary to find the swift runtime.
   add_custom_command(TARGET sourcekitdInProc PRE_BUILD
diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
index f20d429..35514ef 100644
--- a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
+++ b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
@@ -21,6 +21,7 @@
 #include "SourceKit/Core/NotificationCenter.h"
 #include "SourceKit/Support/Concurrency.h"
 #include "SourceKit/Support/Logging.h"
+#include "SourceKit/Support/Statistic.h"
 #include "SourceKit/Support/UIdent.h"
 #include "SourceKit/SwiftLang/Factory.h"
 
@@ -294,6 +295,11 @@
                       ArrayRef<const char *> Args);
 
 void handleRequestImpl(sourcekitd_object_t ReqObj, ResponseReceiver Rec) {
+  // NOTE: if we had a connection context, these stats should move into it.
+  static Statistic numRequests(UIdentFromSKDUID(KindStatNumRequests), "# of requests (total)");
+  static Statistic numSemaRequests(UIdentFromSKDUID(KindStatNumSemaRequests), "# of semantic requests");
+  ++numRequests;
+
   RequestDict Req(ReqObj);
   sourcekitd_uid_t ReqUID = Req.getUID(KeyRequest);
   if (!ReqUID)
@@ -660,6 +666,27 @@
     return Rec(ResponseBuilder().createResponse());
   }
 
+  if (ReqUID == RequestStatistics) {
+    LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
+    Lang.getStatistics([Rec](ArrayRef<Statistic *> stats) {
+      ResponseBuilder builder;
+      auto results = builder.getDictionary().setArray(KeyResults);
+      auto addStat = [&results](Statistic *stat) {
+        auto dict = results.appendDictionary();
+        dict.set(KeyKind, stat->name);
+        dict.set(KeyDescription, stat->description);
+        dict.set(KeyValue, stat->value);
+      };
+
+      addStat(&numRequests);
+      addStat(&numSemaRequests);
+      std::for_each(stats.begin(), stats.end(), addStat);
+
+      Rec(builder.createResponse());
+    });
+    return;
+  }
+
   if (!SourceFile.hasValue() && !SourceText.hasValue() &&
       ReqUID != RequestCodeCompleteUpdate)
     return Rec(createErrorRequestInvalid(
@@ -673,6 +700,7 @@
   static WorkQueue SemaQueue{ WorkQueue::Dequeuing::Concurrent,
                               "sourcekit.request.semantic" };
   sourcekitd_request_retain(ReqObj);
+  ++numSemaRequests;
   SemaQueue.dispatch(
     [ReqObj, Rec, ReqUID, SourceFile, SourceText, Args] {
       RequestDict Req(ReqObj);
diff --git a/utils/swift-project-settings.el b/utils/swift-project-settings.el
index 79ecb57..b7d8957 100644
--- a/utils/swift-project-settings.el
+++ b/utils/swift-project-settings.el
@@ -369,7 +369,7 @@
 
 (defconst swift-project-stdlib-aux-swiftc-args
   (append swift-project-single-frontend-swiftc-args
-          (list "-Xfrontend" "-sil-serialize-all" "-parse-stdlib"))
+          (list "-Xfrontend" "-sil-serialize-witness-tables" "-sil-serialize-vtables" "-parse-stdlib"))
   "swiftc arguments for library components that are compiled as
   though they are part of the standard library even though
   they're not strictly in that binary."  )
diff --git a/utils/vim/syntax/sil.vim b/utils/vim/syntax/sil.vim
index 76e3918..91428e2 100644
--- a/utils/vim/syntax/sil.vim
+++ b/utils/vim/syntax/sil.vim
@@ -30,7 +30,7 @@
 syn keyword swiftKeyword load load_unowned store assign mark_uninitialized mark_function_escape copy_addr destroy_addr index_addr index_raw_pointer bind_memory to skipwhite
 syn keyword swiftKeyword strong_retain strong_release strong_retain_unowned ref_to_unowned unowned_to_ref unowned_retain unowned_release load_weak store_unowned store_weak fix_lifetime autorelease_value set_deallocating is_unique is_unique_or_pinned strong_pin strong_unpin skipwhite
 syn keyword swiftKeyword function_ref integer_literal float_literal string_literal const_string_literal global_addr skipwhite
-syn keyword swiftKeyword class_method super_method witness_method dynamic_method skipwhite
+syn keyword swiftKeyword class_method super_method witness_method objc_method objc_super_method skipwhite
 syn keyword swiftKeyword partial_apply builtin skipwhite
 syn keyword swiftApplyKeyword apply try_apply skipwhite
 syn keyword swiftKeyword metatype value_metatype existential_metatype skipwhite
diff --git a/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/A.h b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/A.h
new file mode 100644
index 0000000..0bb842b
--- /dev/null
+++ b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/A.h
@@ -0,0 +1 @@
+#define REDEFINED 1
\ No newline at end of file
diff --git a/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/B.h b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/B.h
new file mode 100644
index 0000000..0bb842b
--- /dev/null
+++ b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/B.h
@@ -0,0 +1 @@
+#define REDEFINED 1
\ No newline at end of file
diff --git a/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/C.h b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/C.h
new file mode 100644
index 0000000..0bb842b
--- /dev/null
+++ b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/C.h
@@ -0,0 +1 @@
+#define REDEFINED 1
\ No newline at end of file
diff --git a/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/D.h b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/D.h
new file mode 100644
index 0000000..0bb842b
--- /dev/null
+++ b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/D.h
@@ -0,0 +1 @@
+#define REDEFINED 1
\ No newline at end of file
diff --git a/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/E.h b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/E.h
new file mode 100644
index 0000000..0bb842b
--- /dev/null
+++ b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/E.h
@@ -0,0 +1 @@
+#define REDEFINED 1
\ No newline at end of file
diff --git a/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/F.h b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/F.h
new file mode 100644
index 0000000..0bb842b
--- /dev/null
+++ b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/F.h
@@ -0,0 +1 @@
+#define REDEFINED 1
\ No newline at end of file
diff --git a/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/module.modulemap b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/module.modulemap
new file mode 100644
index 0000000..eecdbb2
--- /dev/null
+++ b/validation-test/ClangImporter/Inputs/macros-repeatedly-redefined/module.modulemap
@@ -0,0 +1,6 @@
+module A { header "A.h" }
+module B { header "B.h" }
+module C { header "C.h" }
+module D { header "D.h" }
+module E { header "E.h" }
+module F { header "F.h" }
diff --git a/validation-test/ClangImporter/macros-repeatedly-redefined.swift b/validation-test/ClangImporter/macros-repeatedly-redefined.swift
new file mode 100644
index 0000000..00dc28f
--- /dev/null
+++ b/validation-test/ClangImporter/macros-repeatedly-redefined.swift
@@ -0,0 +1,13 @@
+// RUN: %target-swift-frontend -sdk "" -I %S/Inputs/macros-repeatedly-redefined -typecheck %s -verify
+
+// This used to result in a use-after-free because the SmallVector holding the
+// macros was reallocated.
+import A
+import B
+import C
+import D
+import E
+import F
+
+_ = REDEFINED // no-warning
+_ = x // expected-error {{use of unresolved identifier 'x'}}
diff --git a/validation-test/SIL/Inputs/gen_parse_stdlib_tests.sh b/validation-test/SIL/Inputs/gen_parse_stdlib_tests.sh
index 351b753..6db4953 100755
--- a/validation-test/SIL/Inputs/gen_parse_stdlib_tests.sh
+++ b/validation-test/SIL/Inputs/gen_parse_stdlib_tests.sh
@@ -19,8 +19,8 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
 __EOF__
 
 done
diff --git a/validation-test/SIL/parse_stdlib_0.sil b/validation-test/SIL/parse_stdlib_0.sil
index 8dd0386..4979ca4 100644
--- a/validation-test/SIL/parse_stdlib_0.sil
+++ b/validation-test/SIL/parse_stdlib_0.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_1.sil b/validation-test/SIL/parse_stdlib_1.sil
index 891f74a..b984174 100644
--- a/validation-test/SIL/parse_stdlib_1.sil
+++ b/validation-test/SIL/parse_stdlib_1.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_10.sil b/validation-test/SIL/parse_stdlib_10.sil
index 1233d3c..8af2857 100644
--- a/validation-test/SIL/parse_stdlib_10.sil
+++ b/validation-test/SIL/parse_stdlib_10.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_11.sil b/validation-test/SIL/parse_stdlib_11.sil
index 6c69e51..8c62fd5 100644
--- a/validation-test/SIL/parse_stdlib_11.sil
+++ b/validation-test/SIL/parse_stdlib_11.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_12.sil b/validation-test/SIL/parse_stdlib_12.sil
index d35ec3c..d517ea2 100644
--- a/validation-test/SIL/parse_stdlib_12.sil
+++ b/validation-test/SIL/parse_stdlib_12.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_13.sil b/validation-test/SIL/parse_stdlib_13.sil
index ba53d48..cbe459e 100644
--- a/validation-test/SIL/parse_stdlib_13.sil
+++ b/validation-test/SIL/parse_stdlib_13.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_14.sil b/validation-test/SIL/parse_stdlib_14.sil
index 9573614..bc4c42a 100644
--- a/validation-test/SIL/parse_stdlib_14.sil
+++ b/validation-test/SIL/parse_stdlib_14.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_15.sil b/validation-test/SIL/parse_stdlib_15.sil
index b82685a..762e915 100644
--- a/validation-test/SIL/parse_stdlib_15.sil
+++ b/validation-test/SIL/parse_stdlib_15.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_16.sil b/validation-test/SIL/parse_stdlib_16.sil
index fe32687..0268bee 100644
--- a/validation-test/SIL/parse_stdlib_16.sil
+++ b/validation-test/SIL/parse_stdlib_16.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_2.sil b/validation-test/SIL/parse_stdlib_2.sil
index 52ab68e..cb4a5d1 100644
--- a/validation-test/SIL/parse_stdlib_2.sil
+++ b/validation-test/SIL/parse_stdlib_2.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_3.sil b/validation-test/SIL/parse_stdlib_3.sil
index be8278e..80da211 100644
--- a/validation-test/SIL/parse_stdlib_3.sil
+++ b/validation-test/SIL/parse_stdlib_3.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_4.sil b/validation-test/SIL/parse_stdlib_4.sil
index 01acaaf..4ba5869 100644
--- a/validation-test/SIL/parse_stdlib_4.sil
+++ b/validation-test/SIL/parse_stdlib_4.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_5.sil b/validation-test/SIL/parse_stdlib_5.sil
index 58de6b6..7e2adc0 100644
--- a/validation-test/SIL/parse_stdlib_5.sil
+++ b/validation-test/SIL/parse_stdlib_5.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_6.sil b/validation-test/SIL/parse_stdlib_6.sil
index 5b3ced2..dcc42f8 100644
--- a/validation-test/SIL/parse_stdlib_6.sil
+++ b/validation-test/SIL/parse_stdlib_6.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_7.sil b/validation-test/SIL/parse_stdlib_7.sil
index 4d759bd..eea810c 100644
--- a/validation-test/SIL/parse_stdlib_7.sil
+++ b/validation-test/SIL/parse_stdlib_7.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_8.sil b/validation-test/SIL/parse_stdlib_8.sil
index 1dab138..fb7e59b 100644
--- a/validation-test/SIL/parse_stdlib_8.sil
+++ b/validation-test/SIL/parse_stdlib_8.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/SIL/parse_stdlib_9.sil b/validation-test/SIL/parse_stdlib_9.sil
index cbca5e6..57cb8d0 100644
--- a/validation-test/SIL/parse_stdlib_9.sil
+++ b/validation-test/SIL/parse_stdlib_9.sil
@@ -11,5 +11,5 @@
 // REQUIRES: long_test
 // REQUIRES: nonexecutable_test
 
-// FIXME: Re-enable on Linux when we're no long running out of memory.
-// REQUIRES: OS=macosx
+// FIXME: Re-enable when we're no longer running out of memory.
+// REQUIRES: rdar34771322
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
similarity index 89%
rename from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
rename to validation-test/compiler_crashers/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
index 3902655..b57ef5e 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not %target-swift-frontend %s -emit-ir
+// RUN: not --crash %target-swift-frontend %s -emit-ir
 class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
similarity index 68%
copy from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
copy to validation-test/compiler_crashers/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
index 3902655..ece7287 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28850-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-220.swift
@@ -5,6 +5,5 @@
 // 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 %target-swift-frontend %s -emit-ir
-class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol P{class a{protocol a:P{func a:a.a{}typealias a
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
similarity index 72%
copy from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
copy to validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
index 3902655..0e26155 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not %target-swift-frontend %s -emit-ir
-class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+protocol A:a{{}typealias a=a{}func a{}typealias a}class a:A{func a
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28852-swift-genericsignaturebuilder-addrequirement-swift-requirementrepr-const-swift-g.swift
similarity index 68%
copy from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
copy to validation-test/compiler_crashers/28852-swift-genericsignaturebuilder-addrequirement-swift-requirementrepr-const-swift-g.swift
index 3902655..3cacc3c 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28852-swift-genericsignaturebuilder-addrequirement-swift-requirementrepr-const-swift-g.swift
@@ -5,6 +5,8 @@
 // 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 %target-swift-frontend %s -emit-ir
-class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+extension P{}
+protocol P{{}typealias e:A
+protocol A{{}typealias e where f=a
+{}class a
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28853-result-second.swift
similarity index 71%
copy from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
copy to validation-test/compiler_crashers/28853-result-second.swift
index 3902655..b0acfc3 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28853-result-second.swift
@@ -6,5 +6,11 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not %target-swift-frontend %s -emit-ir
-class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+func a<a{
+extension{{}
+{
+}
+class a<a{
+class a{protocol
+protocol{protocol A typealias e:A
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28854-known-typewitnesses-end-didnt-resolve-witness.swift
similarity index 72%
copy from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
copy to validation-test/compiler_crashers/28854-known-typewitnesses-end-didnt-resolve-witness.swift
index 3902655..e2bee9f 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28854-known-typewitnesses-end-didnt-resolve-witness.swift
@@ -6,5 +6,8 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not %target-swift-frontend %s -emit-ir
-class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+@objc protocol A
+{
+typealias a
+protocol P{{}class a:A{typealias e:a
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28855-swift-genericsignaturebuilder-addrequirement-swift-requirementrepr-const-swift-g.swift
similarity index 68%
copy from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
copy to validation-test/compiler_crashers/28855-swift-genericsignaturebuilder-addrequirement-swift-requirementrepr-const-swift-g.swift
index 3902655..e52c0d7 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28855-swift-genericsignaturebuilder-addrequirement-swift-requirementrepr-const-swift-g.swift
@@ -5,6 +5,5 @@
 // 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 %target-swift-frontend %s -emit-ir
-class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+@objc protocol P{typealias e where f=a
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28856-typevariables-impl-getgraphindex-typevar-type-variable-mismatch.swift
similarity index 72%
copy from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
copy to validation-test/compiler_crashers/28856-typevariables-impl-getgraphindex-typevar-type-variable-mismatch.swift
index 3902655..ffe21dc 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28856-typevariables-impl-getgraphindex-typevar-type-variable-mismatch.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not %target-swift-frontend %s -emit-ir
-class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection
+// RUN: not --crash %target-swift-frontend %s -emit-ir
+{[Int?as?ManagedBuffer}{
diff --git a/validation-test/compiler_crashers_2/0127-sr5546.swift b/validation-test/compiler_crashers_2/0127-sr5546.swift
new file mode 100644
index 0000000..a6f77b5
--- /dev/null
+++ b/validation-test/compiler_crashers_2/0127-sr5546.swift
@@ -0,0 +1,38 @@
+// RUN: not --crash %target-swift-frontend %s -typecheck
+// REQUIRES: asserts
+
+public struct Foo<A, B, C> {}
+
+public protocol P {
+    associatedtype PA
+    associatedtype PB = Never
+    associatedtype PC = Never
+
+    typealias Context = Foo<PA, PB, PC>
+
+    func f1(_ x: Context, _ y: PA)
+    func f2(_ x: Context, _ y: PB)
+    func f3(_ x: Context, _ y: PC)
+    func f4(_ x: Context)
+}
+
+public extension P {
+    public func f1(_ x: Context, _ y: PA) {
+    }
+    public func f2(_ x: Context, _ y: PB) {
+    }
+    public func f3(_ x: Context, _ y: PC) {
+    }
+    public func f4(_ x: Context) {
+    }
+}
+
+public struct S: P {
+    public typealias PA = String
+    public typealias PB = Int
+
+    public func f1(_ x: Context, _ y: PA) {
+    }
+    public func f2(_ x: Context, _ y: PB) {
+    }
+}
diff --git a/validation-test/compiler_crashers_2_fixed/0126-sr5905.swift b/validation-test/compiler_crashers_2_fixed/0126-sr5905.swift
new file mode 100644
index 0000000..6d1a145
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0126-sr5905.swift
@@ -0,0 +1,28 @@
+// RUN: not %target-swift-frontend %s -typecheck
+protocol VectorIndex {
+    associatedtype Vector8 : Vector where Vector8.Index == Self, Vector8.Element == UInt8
+}
+enum VectorIndex1 : VectorIndex {
+    case i0
+    typealias Vector8 = Vector1<UInt8>
+}
+protocol Vector {
+    associatedtype Index: VectorIndex
+    associatedtype Element
+    init(elementForIndex: (Index) -> Element)
+    subscript(index: Index) -> Element { get set }
+}
+struct Vector1<Element> : Vector {
+    //typealias Index = VectorIndex1 // Uncomment this line to workaround bug.
+    var e0: Element
+    init(elementForIndex: (VectorIndex1) -> Element) {
+        e0 = elementForIndex(.i0)
+    }
+    subscript(index: Index) -> Element {
+        get { return e0 }
+        set { e0 = newValue }
+    }
+}
+extension Vector where Index == VectorIndex1 {
+    init(_ e0: Element) { fatalError() }
+}
diff --git a/validation-test/compiler_crashers_fixed/26725-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift b/validation-test/compiler_crashers_fixed/26725-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift
index eb072e2..ec99b6a 100644
--- a/validation-test/compiler_crashers_fixed/26725-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift
+++ b/validation-test/compiler_crashers_fixed/26725-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift
@@ -6,6 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // RUN: not %target-swift-frontend %s -typecheck
-// This test fails in the AST verifier, which can be turned off.
-// REQUIRES: swift_ast_verifier
+// REQUIRES: asserts
 class a<T where g:d{class A{class A<T>:A{init(){T{
diff --git a/validation-test/stdlib/Slice.swift.gyb b/validation-test/stdlib/Slice.swift.gyb
index 8fda74a..fe33c9b 100644
--- a/validation-test/stdlib/Slice.swift.gyb
+++ b/validation-test/stdlib/Slice.swift.gyb
@@ -62,7 +62,7 @@
       subSequenceType: CollectionSlice.self,
       indexType: MinimalIndex.self,
       indexDistanceType: Int.self,
-      indicesType: ${defaultIndicesForTraversal(Traversal)}<CollectionSlice>.self)
+      indicesType: Collection.Indices.self)
   }
 
   func checkStaticTypealiases1<Base : Collection>(_: Base) {