Merge pull request #12121 from aschwaighofer/fix_dom_tree_array_specialization

Fix dominator tree update in array specialization
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 22fb3fb..8acdac1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,7 +66,11 @@
 endif()
 
 option(SWIFT_BUILD_PERF_TESTSUITE
-    "Create targets for swift performance benchmarks."
+    "Create in-tree targets for building swift performance benchmarks."
+    FALSE)
+
+option(SWIFT_BUILD_EXTERNAL_PERF_TESTSUITE
+    "Create out-of-tree targets for building swift performance benchmarks."
     FALSE)
 
 option(SWIFT_INCLUDE_TESTS "Create targets for building/running tests." TRUE)
@@ -882,9 +886,16 @@
   add_subdirectory(tools/swift-reflection-test)
 endif()
 
-if(SWIFT_BUILD_PERF_TESTSUITE AND "${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
-  add_subdirectory(benchmark)
+if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+  if(SWIFT_BUILD_PERF_TESTSUITE)
+    add_subdirectory(benchmark)
+  endif()
+  if(SWIFT_BUILD_EXTERNAL_PERF_TESTSUITE)
+    include(SwiftExternalBenchmarkBuild)
+    add_external_benchmark_suite()
+  endif()
 endif()
+
 if(SWIFT_INCLUDE_TESTS)
   add_subdirectory(test)
   add_subdirectory(unittests)
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 8012413..fe92ab2 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -125,9 +125,16 @@
     single-source/XorLoop
 )
 
-set(SWIFT_MULTISOURCE_BENCHES
+set(SWIFT_MULTISOURCE_SWIFT3_BENCHES
+  multi-source/PrimsSplit
 )
 
+set(PrimsSplit_sources
+    multi-source/PrimsSplit/Prims.swift
+    multi-source/PrimsSplit/main.swift)
+
+set(SWIFT_MULTISOURCE_SWIFT4_BENCHES
+)
 
 set(BENCH_DRIVER_LIBRARY_FLAGS)
 if (SWIFT_RUNTIME_ENABLE_LEAK_CHECKER)
@@ -231,6 +238,7 @@
 
 message("--")
 message("-- Swift Benchmark Suite:")
+message("--   SWIFT_BENCHMARK_BUILT_STANDALONE = ${SWIFT_BENCHMARK_BUILT_STANDALONE}")
 message("--   SWIFT_EXEC = ${SWIFT_EXEC}")
 message("--   SWIFT_LIBRARY_PATH = ${SWIFT_LIBRARY_PATH}")
 message("--   CLANG_EXEC = ${CLANG_EXEC}")
diff --git a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
index 3a00b46..e56b583 100644
--- a/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
+++ b/benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
@@ -73,6 +73,104 @@
   endif()
 endfunction()
 
+function(_construct_sources_for_multibench sources_out objfile_out)
+  cmake_parse_arguments(SOURCEJSONLIST "" "" "SOURCES" ${ARGN})
+
+  set(sources)
+  set(objfiles)
+
+  foreach(source ${SOURCEJSONLIST_SOURCES})
+    list(APPEND sources "${srcdir}/${source}")
+
+    get_filename_component(basename "${source}" NAME_WE)
+    set(objfile "${objdir}/${module_name}/${basename}.o")
+
+    string(CONCAT json "${json}"
+      "  \"${srcdir}/${source}\": { \"object\": \"${objfile}\" },\n")
+
+    list(APPEND objfiles "${objfile}")
+  endforeach()
+  string(CONCAT json "${json}" "}")
+  file(WRITE "${objdir}/${module_name}/outputmap.json" ${json})
+  set(${sources_out} ${sources} PARENT_SCOPE)
+  set(${objfile_out} ${objfiles} PARENT_SCOPE)
+endfunction()
+
+# Regular whole-module-compilation: only a single object file is
+# generated.
+function (add_swift_multisource_wmo_benchmark_library objfile_out)
+  cmake_parse_arguments(BENCHLIB "" "MODULE_PATH;SOURCE_DIR;OBJECT_DIR" "SOURCES;LIBRARY_FLAGS;DEPENDS" ${ARGN})
+
+  precondition(BENCHLIB_MODULE_PATH)
+  precondition(BENCHLIB_SOURCE_DIR)
+  precondition(BENCHLIB_OBJECT_DIR)
+  precondition(BENCHLIB_SOURCES)
+
+  set(module_name_path "${BENCHLIB_MODULE_PATH}")
+  get_filename_component(module_name "${module_name_path}" NAME)
+  set(srcdir "${BENCHLIB_SOURCE_DIR}")
+  set(objdir "${BENCHLIB_OBJECT_DIR}")
+
+  set(objfile "${objdir}/${module_name}.o")
+
+  set(sources)
+  foreach(source ${BENCHLIB_SOURCES})
+    list(APPEND sources "${srcdir}/${source}")
+  endforeach()
+
+  add_custom_command(
+    OUTPUT "${objfile}"
+    DEPENDS
+      ${sources} ${BENCHLIB_DEPENDS}
+    COMMAND "${SWIFT_EXEC}"
+      ${BENCHLIB_LIBRARY_FLAGS}
+      "-parse-as-library"
+      "-emit-module" "-module-name" "${module_name}"
+      "-I" "${objdir}"
+      "-o" "${objfile}"
+      ${sources})
+
+  set(${objfile_out} "${objfile}" PARENT_SCOPE)
+endfunction()
+
+function(add_swift_multisource_nonwmo_benchmark_library objfiles_out)
+  cmake_parse_arguments(BENCHLIB "" "MODULE_PATH;SOURCE_DIR;OBJECT_DIR" "SOURCES;LIBRARY_FLAGS;DEPENDS" ${ARGN})
+
+  precondition(BENCHLIB_MODULE_PATH)
+  precondition(BENCHLIB_SOURCE_DIR)
+  precondition(BENCHLIB_OBJECT_DIR)
+  precondition(BENCHLIB_SOURCES)
+
+  set(module_name_path "${BENCHLIB_MODULE_PATH}")
+  get_filename_component(module_name "${module_name_path}" NAME)
+  set(srcdir "${BENCHLIB_SOURCE_DIR}")
+  set(objdir "${BENCHLIB_OBJECT_DIR}")
+
+  set(objfile "${objdir}/${module_name}.o")
+
+  # No whole-module-compilation or multi-threaded compilation.
+  # There is an output object file for each input file. We have to write
+  # an output-map-file to specify the output object file names.
+  set(sources)
+  set(objfiles)
+  _construct_sources_for_multibench(sources objfiles
+    SOURCES ${BENCHLIB_SOURCES})
+
+  add_custom_command(
+    OUTPUT ${objfiles}
+    DEPENDS ${sources} ${BENCHLIB_DEPENDS}
+    COMMAND "${SWIFT_EXEC}"
+      ${BENCHLIB_LIBRARY_FLAGS}
+      "-parse-as-library"
+      "-emit-module-path" "${objdir}/${module_name}.swiftmodule"
+      "-module-name" "${module_name}"
+      "-I" "${objdir}"
+      "-output-file-map" "${objdir}/${module_name}/outputmap.json"
+      ${sources})
+
+  set(${objfiles_out} ${objfiles} PARENT_SCOPE)
+endfunction()
+
 function (swift_benchmark_compile_archopts)
   cmake_parse_arguments(BENCH_COMPILE_ARCHOPTS "" "PLATFORM;ARCH;OPT" "" ${ARGN})
   set(sdk ${${BENCH_COMPILE_ARCHOPTS_PLATFORM}_sdk})
@@ -95,7 +193,6 @@
   set(bench_flags "${${benchvar}}")
 
   set(common_options
-      "-swift-version" "3" # FIXME: Force Swift 3 version compatibility.
       "-c"
       "-sdk" "${sdk}"
       "-target" "${target}"
@@ -103,6 +200,8 @@
       "-${BENCH_COMPILE_ARCHOPTS_OPT}"
       "-no-link-objc-runtime"
       "-I" "${srcdir}/utils/ObjectiveCTests")
+  set(common_swift3_options ${common_options} "-swift-version" "3")
+  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
@@ -128,7 +227,7 @@
       SOURCE_DIR "${srcdir}"
       OBJECT_DIR "${objdir}"
       SOURCES ${sources}
-      LIBRARY_FLAGS ${common_options})
+      LIBRARY_FLAGS ${common_swift3_options})
     precondition(objfile_out)
     list(APPEND bench_library_objects "${objfile_out}")
     if (SWIFT_BENCHMARK_EMIT_SIB)
@@ -197,7 +296,7 @@
             ${stdlib_dependencies} ${bench_library_objects}
             "${srcdir}/${module_name_path}.swift"
           COMMAND "${SWIFT_EXEC}"
-          ${common_options}
+          ${common_swift3_options}
           ${extra_options}
           "-parse-as-library"
           ${bench_flags}
@@ -215,7 +314,7 @@
               ${stdlib_dependencies} ${bench_library_sibfiles}
               "${srcdir}/${module_name_path}.swift"
             COMMAND "${SWIFT_EXEC}"
-            ${common_options}
+            ${common_swift3_options}
             "-parse-as-library"
             ${bench_flags}
             "-module-name" "${module_name}"
@@ -227,67 +326,61 @@
     endif()
   endforeach()
 
-  foreach(module_name_path ${SWIFT_MULTISOURCE_BENCHES})
+  foreach(module_name_path ${SWIFT_MULTISOURCE_SWIFT3_BENCHES})
     get_filename_component(module_name "${module_name_path}" NAME)
 
     if ("${bench_flags}" MATCHES "-whole-module.*" AND
         NOT "${bench_flags}" MATCHES "-num-threads.*")
-      # Regular whole-module-compilation: only a single object file is
-      # generated.
-      set(objfile "${objdir}/${module_name}.o")
-      list(APPEND SWIFT_BENCH_OBJFILES "${objfile}")
-      set(sources)
-      foreach(source ${${module_name}_sources})
-        list(APPEND sources "${srcdir}/${source}")
-      endforeach()
-      add_custom_command(
-          OUTPUT "${objfile}"
-          DEPENDS
-            ${stdlib_dependencies} ${bench_library_objects} ${sources}
-          COMMAND "${SWIFT_EXEC}"
-          ${common_options}
-          ${bench_flags}
-          "-parse-as-library"
-          "-emit-module" "-module-name" "${module_name}"
-          "-I" "${objdir}"
-          "-o" "${objfile}"
-          ${sources})
+      set(objfile_out)
+      add_swift_multisource_wmo_benchmark_library(objfile_out
+        MODULE_PATH "${module_name_path}"
+        SOURCE_DIR "${srcdir}"
+        OBJECT_DIR "${objdir}"
+        SOURCES ${${module_name}_sources}
+        LIBRARY_FLAGS ${common_swift3_options} ${bench_flags}
+        DEPENDS ${bench_library_objects} ${stdlib_dependencies})
+      precondition(objfile_out)
+      list(APPEND SWIFT_BENCH_OBJFILES "${objfile_out}")
     else()
+      set(objfiles_out)
+      add_swift_multisource_nonwmo_benchmark_library(objfiles_out
+        MODULE_PATH "${module_name_path}"
+        SOURCE_DIR "${srcdir}"
+        OBJECT_DIR "${objdir}"
+        SOURCES ${${module_name}_sources}
+        LIBRARY_FLAGS ${common_swift3_options} ${bench_flags}
+        DEPENDS ${bench_library_objects} ${stdlib_dependencies})
+      precondition(objfiles_out)
+      list(APPEND SWIFT_BENCH_OBJFILES ${objfiles_out})
+    endif()
+  endforeach()
 
-      # No whole-module-compilation or multi-threaded compilation.
-      # There is an output object file for each input file. We have to write
-      # an output-map-file to specify the output object file names.
-      set(sources)
-      set(objfiles)
-      set(json "{\n")
-      foreach(source ${${module_name}_sources})
-          list(APPEND sources "${srcdir}/${source}")
+  foreach(module_name_path ${SWIFT_MULTISOURCE_SWIFT4_BENCHES})
+    get_filename_component(module_name "${module_name_path}" NAME)
 
-          get_filename_component(basename "${source}" NAME_WE)
-          set(objfile "${objdir}/${module_name}/${basename}.o")
-
-              string(CONCAT json "${json}"
-    "  \"${srcdir}/${source}\": { \"object\": \"${objfile}\" },\n")
-
-          list(APPEND objfiles "${objfile}")
-          list(APPEND SWIFT_BENCH_OBJFILES "${objfile}")
-      endforeach()
-      string(CONCAT json "${json}" "}")
-      file(WRITE "${objdir}/${module_name}/outputmap.json" ${json})
-
-      add_custom_command(
-          OUTPUT ${objfiles}
-          DEPENDS
-            ${stdlib_dependencies} ${bench_library_objects} ${sources}
-          COMMAND "${SWIFT_EXEC}"
-          ${common_options}
-          ${bench_flags}
-          "-parse-as-library"
-          "-emit-module-path" "${objdir}/${module_name}.swiftmodule"
-          "-module-name" "${module_name}"
-          "-I" "${objdir}"
-          "-output-file-map" "${objdir}/${module_name}/outputmap.json"
-          ${sources})
+    if ("${bench_flags}" MATCHES "-whole-module.*" AND
+        NOT "${bench_flags}" MATCHES "-num-threads.*")
+      set(objfile_out)
+      add_swift_multisource_wmo_benchmark_library(objfile_out
+        MODULE_PATH "${module_name_path}"
+        SOURCE_DIR "${srcdir}"
+        OBJECT_DIR "${objdir}"
+        SOURCES ${${module_name}_sources}
+        LIBRARY_FLAGS ${common_swift4_options} ${bench_flags}
+        DEPENDS ${bench_library_objects} ${stdlib_dependencies})
+      precondition(objfile_out)
+      list(APPEND SWIFT_BENCH_OBJFILES "${objfile_out}")
+    else()
+      set(objfiles_out)
+      add_swift_multisource_nonwmo_benchmark_library(objfiles_out
+        MODULE_PATH "${module_name_path}"
+        SOURCE_DIR "${srcdir}"
+        OBJECT_DIR "${objdir}"
+        SOURCES ${${module_name}_sources}
+        LIBRARY_FLAGS ${common_swift4_options} ${bench_flags}
+        DEPENDS ${bench_library_objects} ${stdlib_dependencies})
+      precondition(objfiles_out)
+      list(APPEND SWIFT_BENCH_OBJFILES ${objfiles_out})
     endif()
   endforeach()
 
@@ -301,7 +394,7 @@
         ${bench_library_sibfiles} ${bench_driver_sibfiles}
         ${SWIFT_BENCH_SIBFILES} "${source}"
       COMMAND "${SWIFT_EXEC}"
-      ${common_options}
+      ${common_swift3_options}
       "-force-single-frontend-invocation"
       "-emit-module" "-module-name" "${module_name}"
       "-I" "${objdir}"
@@ -395,7 +488,16 @@
       list(APPEND platform_executables ${new_output_exec})
     endforeach()
 
-    set(executable_target "swift-benchmark-${SWIFT_BENCHMARK_COMPILE_PLATFORM}-${arch}")
+    # If we are building standalone, we add the -external suffix to all of our
+    # cmake target names. This enables the main swift build to simple create
+    # -external targets and forward them via AddExternalProject to the
+    # standalone benchmark project. The reason why this is necessary is that we
+    # want to be able to support in-tree and out-of-tree benchmark builds at the
+    # same time implying that we need some sort of way to distinguish the
+    # in-tree (which don't have the suffix) from the out of tree target (which
+    # do).
+    translate_flag(SWIFT_BENCHMARK_BUILT_STANDALONE "-external" external)
+    set(executable_target "swift-benchmark-${SWIFT_BENCHMARK_COMPILE_PLATFORM}-${arch}${external}")
 
     add_custom_target("${executable_target}"
         DEPENDS ${platform_executables})
diff --git a/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake b/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake
index 4806892..9c5e6a0 100644
--- a/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake
+++ b/benchmark/cmake/modules/SwiftBenchmarkUtils.cmake
@@ -27,3 +27,19 @@
     endif()
   endif()
 endfunction()
+
+# Translate a yes/no variable to the presence of a given string in a
+# variable.
+#
+# Usage:
+#   translate_flag(is_set flag_name var_name)
+#
+# If is_set is true, sets ${var_name} to ${flag_name}. Otherwise,
+# unsets ${var_name}.
+function(translate_flag is_set flag_name var_name)
+  if(${is_set})
+    set("${var_name}" "${flag_name}" PARENT_SCOPE)
+  else()
+    set("${var_name}" "" PARENT_SCOPE)
+  endif()
+endfunction()
diff --git a/benchmark/multi-source/PrimsSplit/Prims.swift b/benchmark/multi-source/PrimsSplit/Prims.swift
new file mode 100644
index 0000000..57d1f6d
--- /dev/null
+++ b/benchmark/multi-source/PrimsSplit/Prims.swift
@@ -0,0 +1,214 @@
+//===--- Prims.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
+//
+//===----------------------------------------------------------------------===//
+
+// The test implements Prim's algorithm for minimum spanning tree building.
+// http://en.wikipedia.org/wiki/Prim%27s_algorithm
+
+// This class implements array-based heap (priority queue).
+// It is used to store edges from nodes in spanning tree to nodes outside of it.
+// We are interested only in the edges with the smallest costs, so if there are
+// several edges pointing to the same node, we keep only one from them. Thus,
+// it is enough to record this node instead.
+// We maintain a map (node index in graph)->(node index in heap) to be able to
+// update the heap fast when we add a new node to the tree.
+import TestsUtils
+
+class PriorityQueue {
+  final var heap: Array<EdgeCost>
+  final var graphIndexToHeapIndexMap: Array<Int?>
+
+  // Create heap for graph with NUM nodes.
+  init(Num: Int) {
+    heap = Array<EdgeCost>()
+    graphIndexToHeapIndexMap = Array<Int?>(repeating:nil, count: Num)
+  }
+
+  func isEmpty() -> Bool {
+    return heap.isEmpty
+  }
+
+  // Insert element N to heap, maintaining the heap property.
+  func insert(_ n: EdgeCost) {
+    let ind: Int = heap.count
+    heap.append(n)
+    graphIndexToHeapIndexMap[n.to] = heap.count - 1
+    bubbleUp(ind)
+  }
+
+  // Insert element N if in's not in the heap, or update its cost if the new
+  // value is less than the existing one.
+  func insertOrUpdate(_ n: EdgeCost) {
+    let id = n.to
+    let c  = n.cost
+    if let ind = graphIndexToHeapIndexMap[id] {
+      if heap[ind].cost <= c {
+        // We don't need an edge with a bigger cost
+        return
+      }
+      heap[ind].cost = c
+      heap[ind].from = n.from
+      bubbleUp(ind)
+    } else {
+      insert(n)
+    }
+  }
+
+  // Restore heap property by moving element at index IND up.
+  // This is needed after insertion, and after decreasing an element's cost.
+  func bubbleUp(_ ind: Int) {
+    var ind = ind
+    let c = heap[ind].cost
+    while (ind != 0) {
+      let p = getParentIndex(ind)
+      if heap[p].cost > c {
+        Swap(p, with: ind)
+        ind = p
+      } else {
+        break
+      }
+    }
+  }
+
+  // Pop minimum element from heap and restore the heap property after that.
+  func pop() -> EdgeCost? {
+    if (heap.isEmpty) {
+      return nil
+    }
+    Swap(0, with:heap.count-1)
+    let r = heap.removeLast()
+    graphIndexToHeapIndexMap[r.to] = nil
+    bubbleDown(0)
+    return r
+  }
+
+  // Restore heap property by moving element at index IND down.
+  // This is needed after removing an element, and after increasing an
+  // element's cost.
+  func bubbleDown(_ ind: Int) {
+    var ind = ind
+    let n = heap.count
+    while (ind < n) {
+      let l = getLeftChildIndex(ind)
+      let r = getRightChildIndex(ind)
+      if (l >= n) {
+        break
+      }
+      var min: Int
+      if (r < n && heap[r].cost < heap[l].cost) {
+        min = r
+      } else {
+        min = l
+      }
+      if (heap[ind].cost <= heap[min].cost) {
+        break
+      }
+      Swap(ind, with: min)
+      ind = min
+    }
+  }
+
+  // Swaps elements I and J in the heap and correspondingly updates
+  // graphIndexToHeapIndexMap.
+  func Swap(_ i: Int, with j : Int) {
+    if (i == j) {
+      return
+    }
+    (heap[i], heap[j]) = (heap[j], heap[i])
+    let (I, J) = (heap[i].to, heap[j].to)
+    (graphIndexToHeapIndexMap[I], graphIndexToHeapIndexMap[J]) =
+    (graphIndexToHeapIndexMap[J], graphIndexToHeapIndexMap[I])
+  }
+
+  // Dumps the heap.
+  func dump() {
+    print("QUEUE")
+    for nodeCost in heap {
+      let to: Int = nodeCost.to
+      let from: Int = nodeCost.from
+      let cost: Double = nodeCost.cost
+      print("(\(from)->\(to), \(cost))")
+    }
+  }
+
+  func getLeftChildIndex(_ index : Int) -> Int {
+    return index*2 + 1
+  }
+  func getRightChildIndex(_ index : Int) -> Int {
+    return (index + 1)*2
+  }
+  func getParentIndex(_ childIndex : Int) -> Int {
+    return (childIndex - 1)/2
+  }
+}
+
+struct GraphNode {
+  var id: Int
+  var adjList: Array<Int>
+
+  init(i : Int) {
+    id = i
+    adjList = Array<Int>()
+  }
+}
+
+struct EdgeCost {
+  var to: Int
+  var cost: Double
+  var from: Int
+}
+
+struct Edge : Equatable {
+  var start: Int
+  var end: Int
+}
+
+func ==(lhs: Edge, rhs: Edge) -> Bool {
+  return lhs.start == rhs.start && lhs.end == rhs.end
+}
+
+extension Edge : Hashable {
+  var hashValue: Int {
+    get {
+      return start.hashValue ^ end.hashValue
+    }
+  }
+}
+
+func Prims(_ graph : Array<GraphNode>, _ fun : (Int, Int) -> Double) -> Array<Int?> {
+  var treeEdges = Array<Int?>(repeating:nil, count:graph.count)
+
+  let queue = PriorityQueue(Num:graph.count)
+  // Make the minimum spanning tree root its own parent for simplicity.
+  queue.insert(EdgeCost(to: 0, cost: 0.0, from: 0))
+
+  // Take an element with the smallest cost from the queue and add its
+  // neighbors to the queue if their cost was updated
+  while !queue.isEmpty() {
+    // Add an edge with minimum cost to the spanning tree
+    let e = queue.pop()!
+    let newnode = e.to
+    // Add record about the edge newnode->e.from to treeEdges
+    treeEdges[newnode] = e.from
+
+    // Check all adjacent nodes and add edges, ending outside the tree, to the
+    // queue. If the queue already contains an edge to an adjacent node, we
+    // replace existing one with the new one in case the new one costs less.
+    for adjNodeIndex in graph[newnode].adjList {
+      if treeEdges[adjNodeIndex] != nil {
+        continue
+      }
+      let newcost = fun(newnode, graph[adjNodeIndex].id)
+      queue.insertOrUpdate(EdgeCost(to: adjNodeIndex, cost: newcost, from: newnode))
+    }
+  }
+  return treeEdges
+}
diff --git a/benchmark/multi-source/PrimsSplit/README.md b/benchmark/multi-source/PrimsSplit/README.md
new file mode 100644
index 0000000..9987e9c
--- /dev/null
+++ b/benchmark/multi-source/PrimsSplit/README.md
@@ -0,0 +1,4 @@
+
+This test is just a split version of Prims.swift. The reason why this is here is
+to provide at least 1 multi-source benchmark for the purpose of validating that
+the multi-source benchmarks can build successfully.
diff --git a/benchmark/multi-source/PrimsSplit/main.swift b/benchmark/multi-source/PrimsSplit/main.swift
new file mode 100644
index 0000000..0609e92
--- /dev/null
+++ b/benchmark/multi-source/PrimsSplit/main.swift
@@ -0,0 +1,555 @@
+//===--- main.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
+
+@inline(never)
+public func run_PrimsSplit(_ N: Int) {
+  for _ in 1...5*N {
+    let nodes : [Int] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+      13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
+      29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+      45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+      61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+      77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
+      93, 94, 95, 96, 97, 98, 99 ]
+
+    // Prim's algorithm is designed for undirected graphs.
+    // Due to that, in our set all the edges are paired, i.e. for any
+    // edge (start, end, C) there is also an edge (end, start, C).
+    let edges : [(Int, Int, Double)] = [
+      (26, 47, 921),
+      (20, 25, 971),
+      (92, 59, 250),
+      (33, 55, 1391),
+      (78, 39, 313),
+      (7, 25, 637),
+      (18, 19, 1817),
+      (33, 41, 993),
+      (64, 41, 926),
+      (88, 86, 574),
+      (93, 15, 1462),
+      (86, 33, 1649),
+      (37, 35, 841),
+      (98, 51, 1160),
+      (15, 30, 1125),
+      (65, 78, 1052),
+      (58, 12, 1273),
+      (12, 17, 285),
+      (45, 61, 1608),
+      (75, 53, 545),
+      (99, 48, 410),
+      (97, 0, 1303),
+      (48, 17, 1807),
+      (1, 54, 1491),
+      (15, 34, 807),
+      (94, 98, 646),
+      (12, 69, 136),
+      (65, 11, 983),
+      (63, 83, 1604),
+      (78, 89, 1828),
+      (61, 63, 845),
+      (18, 36, 1626),
+      (68, 52, 1324),
+      (14, 50, 690),
+      (3, 11, 943),
+      (21, 68, 914),
+      (19, 44, 1762),
+      (85, 80, 270),
+      (59, 92, 250),
+      (86, 84, 1431),
+      (19, 18, 1817),
+      (52, 68, 1324),
+      (16, 29, 1108),
+      (36, 80, 395),
+      (67, 18, 803),
+      (63, 88, 1717),
+      (68, 21, 914),
+      (75, 82, 306),
+      (49, 82, 1292),
+      (73, 45, 1876),
+      (89, 82, 409),
+      (45, 47, 272),
+      (22, 83, 597),
+      (61, 12, 1791),
+      (44, 68, 1229),
+      (50, 51, 917),
+      (14, 53, 355),
+      (77, 41, 138),
+      (54, 21, 1870),
+      (93, 70, 1582),
+      (76, 2, 1658),
+      (83, 73, 1162),
+      (6, 1, 482),
+      (11, 65, 983),
+      (81, 90, 1024),
+      (19, 1, 970),
+      (8, 58, 1131),
+      (60, 42, 477),
+      (86, 29, 258),
+      (69, 59, 903),
+      (34, 15, 807),
+      (37, 2, 1451),
+      (7, 73, 754),
+      (47, 86, 184),
+      (67, 17, 449),
+      (18, 67, 803),
+      (25, 4, 595),
+      (3, 31, 1337),
+      (64, 31, 1928),
+      (9, 43, 237),
+      (83, 63, 1604),
+      (47, 45, 272),
+      (86, 88, 574),
+      (87, 74, 934),
+      (98, 94, 646),
+      (20, 1, 642),
+      (26, 92, 1344),
+      (18, 17, 565),
+      (47, 11, 595),
+      (10, 59, 1558),
+      (2, 76, 1658),
+      (77, 74, 1277),
+      (42, 60, 477),
+      (80, 36, 395),
+      (35, 23, 589),
+      (50, 37, 203),
+      (6, 96, 481),
+      (78, 65, 1052),
+      (1, 52, 127),
+      (65, 23, 1932),
+      (46, 51, 213),
+      (59, 89, 89),
+      (15, 93, 1462),
+      (69, 3, 1305),
+      (17, 37, 1177),
+      (30, 3, 193),
+      (9, 15, 818),
+      (75, 95, 977),
+      (86, 47, 184),
+      (10, 12, 1736),
+      (80, 27, 1010),
+      (12, 10, 1736),
+      (86, 1, 1958),
+      (60, 12, 1240),
+      (43, 71, 683),
+      (91, 65, 1519),
+      (33, 86, 1649),
+      (62, 26, 1773),
+      (1, 13, 1187),
+      (2, 10, 1018),
+      (91, 29, 351),
+      (69, 12, 136),
+      (43, 9, 237),
+      (29, 86, 258),
+      (17, 48, 1807),
+      (31, 64, 1928),
+      (68, 61, 1936),
+      (76, 38, 1724),
+      (1, 6, 482),
+      (53, 14, 355),
+      (51, 50, 917),
+      (54, 13, 815),
+      (19, 29, 883),
+      (35, 87, 974),
+      (70, 96, 511),
+      (23, 35, 589),
+      (39, 69, 1588),
+      (93, 73, 1093),
+      (13, 73, 435),
+      (5, 60, 1619),
+      (42, 41, 1523),
+      (66, 58, 1596),
+      (1, 67, 431),
+      (17, 67, 449),
+      (30, 95, 906),
+      (71, 43, 683),
+      (5, 87, 190),
+      (12, 78, 891),
+      (30, 97, 402),
+      (28, 17, 1131),
+      (7, 97, 1356),
+      (58, 66, 1596),
+      (20, 37, 1294),
+      (73, 76, 514),
+      (54, 8, 613),
+      (68, 35, 1252),
+      (92, 32, 701),
+      (3, 90, 652),
+      (99, 46, 1576),
+      (13, 54, 815),
+      (20, 87, 1390),
+      (36, 18, 1626),
+      (51, 26, 1146),
+      (2, 23, 581),
+      (29, 7, 1558),
+      (88, 59, 173),
+      (17, 1, 1071),
+      (37, 49, 1011),
+      (18, 6, 696),
+      (88, 33, 225),
+      (58, 38, 802),
+      (87, 50, 1744),
+      (29, 91, 351),
+      (6, 71, 1053),
+      (45, 24, 1720),
+      (65, 91, 1519),
+      (37, 50, 203),
+      (11, 3, 943),
+      (72, 65, 1330),
+      (45, 50, 339),
+      (25, 20, 971),
+      (15, 9, 818),
+      (14, 54, 1353),
+      (69, 95, 393),
+      (8, 66, 1213),
+      (52, 2, 1608),
+      (50, 14, 690),
+      (50, 45, 339),
+      (1, 37, 1273),
+      (45, 93, 1650),
+      (39, 78, 313),
+      (1, 86, 1958),
+      (17, 28, 1131),
+      (35, 33, 1667),
+      (23, 2, 581),
+      (51, 66, 245),
+      (17, 54, 924),
+      (41, 49, 1629),
+      (60, 5, 1619),
+      (56, 93, 1110),
+      (96, 13, 461),
+      (25, 7, 637),
+      (11, 69, 370),
+      (90, 3, 652),
+      (39, 71, 1485),
+      (65, 51, 1529),
+      (20, 6, 1414),
+      (80, 85, 270),
+      (73, 83, 1162),
+      (0, 97, 1303),
+      (13, 33, 826),
+      (29, 71, 1788),
+      (33, 12, 461),
+      (12, 58, 1273),
+      (69, 39, 1588),
+      (67, 75, 1504),
+      (87, 20, 1390),
+      (88, 97, 526),
+      (33, 88, 225),
+      (95, 69, 393),
+      (2, 52, 1608),
+      (5, 25, 719),
+      (34, 78, 510),
+      (53, 99, 1074),
+      (33, 35, 1667),
+      (57, 30, 361),
+      (87, 58, 1574),
+      (13, 90, 1030),
+      (79, 74, 91),
+      (4, 86, 1107),
+      (64, 94, 1609),
+      (11, 12, 167),
+      (30, 45, 272),
+      (47, 91, 561),
+      (37, 17, 1177),
+      (77, 49, 883),
+      (88, 23, 1747),
+      (70, 80, 995),
+      (62, 77, 907),
+      (18, 4, 371),
+      (73, 93, 1093),
+      (11, 47, 595),
+      (44, 23, 1990),
+      (20, 0, 512),
+      (3, 69, 1305),
+      (82, 3, 1815),
+      (20, 88, 368),
+      (44, 45, 364),
+      (26, 51, 1146),
+      (7, 65, 349),
+      (71, 39, 1485),
+      (56, 88, 1954),
+      (94, 69, 1397),
+      (12, 28, 544),
+      (95, 75, 977),
+      (32, 90, 789),
+      (53, 1, 772),
+      (54, 14, 1353),
+      (49, 77, 883),
+      (92, 26, 1344),
+      (17, 18, 565),
+      (97, 88, 526),
+      (48, 80, 1203),
+      (90, 32, 789),
+      (71, 6, 1053),
+      (87, 35, 974),
+      (55, 90, 1808),
+      (12, 61, 1791),
+      (1, 96, 328),
+      (63, 10, 1681),
+      (76, 34, 871),
+      (41, 64, 926),
+      (42, 97, 482),
+      (25, 5, 719),
+      (23, 65, 1932),
+      (54, 1, 1491),
+      (28, 12, 544),
+      (89, 10, 108),
+      (27, 33, 143),
+      (67, 1, 431),
+      (32, 45, 52),
+      (79, 33, 1871),
+      (6, 55, 717),
+      (10, 58, 459),
+      (67, 39, 393),
+      (10, 4, 1808),
+      (96, 6, 481),
+      (1, 19, 970),
+      (97, 7, 1356),
+      (29, 16, 1108),
+      (1, 53, 772),
+      (30, 15, 1125),
+      (4, 6, 634),
+      (6, 20, 1414),
+      (88, 56, 1954),
+      (87, 64, 1950),
+      (34, 76, 871),
+      (17, 12, 285),
+      (55, 59, 321),
+      (61, 68, 1936),
+      (50, 87, 1744),
+      (84, 44, 952),
+      (41, 33, 993),
+      (59, 18, 1352),
+      (33, 27, 143),
+      (38, 32, 1210),
+      (55, 70, 1264),
+      (38, 58, 802),
+      (1, 20, 642),
+      (73, 13, 435),
+      (80, 48, 1203),
+      (94, 64, 1609),
+      (38, 28, 414),
+      (73, 23, 1113),
+      (78, 12, 891),
+      (26, 62, 1773),
+      (87, 43, 579),
+      (53, 6, 95),
+      (59, 95, 285),
+      (88, 63, 1717),
+      (17, 5, 633),
+      (66, 8, 1213),
+      (41, 42, 1523),
+      (83, 22, 597),
+      (95, 30, 906),
+      (51, 65, 1529),
+      (17, 49, 1727),
+      (64, 87, 1950),
+      (86, 4, 1107),
+      (37, 98, 1102),
+      (32, 92, 701),
+      (60, 94, 198),
+      (73, 98, 1749),
+      (4, 18, 371),
+      (96, 70, 511),
+      (7, 29, 1558),
+      (35, 37, 841),
+      (27, 64, 384),
+      (12, 33, 461),
+      (36, 38, 529),
+      (69, 16, 1183),
+      (91, 47, 561),
+      (85, 29, 1676),
+      (3, 82, 1815),
+      (69, 58, 1579),
+      (93, 45, 1650),
+      (97, 42, 482),
+      (37, 1, 1273),
+      (61, 4, 543),
+      (96, 1, 328),
+      (26, 0, 1993),
+      (70, 64, 878),
+      (3, 30, 193),
+      (58, 69, 1579),
+      (4, 25, 595),
+      (31, 3, 1337),
+      (55, 6, 717),
+      (39, 67, 393),
+      (78, 34, 510),
+      (75, 67, 1504),
+      (6, 53, 95),
+      (51, 79, 175),
+      (28, 91, 1040),
+      (89, 78, 1828),
+      (74, 93, 1587),
+      (45, 32, 52),
+      (10, 2, 1018),
+      (49, 37, 1011),
+      (63, 61, 845),
+      (0, 20, 512),
+      (1, 17, 1071),
+      (99, 53, 1074),
+      (37, 20, 1294),
+      (10, 89, 108),
+      (33, 92, 946),
+      (23, 73, 1113),
+      (23, 88, 1747),
+      (49, 17, 1727),
+      (88, 20, 368),
+      (21, 54, 1870),
+      (70, 93, 1582),
+      (59, 88, 173),
+      (32, 38, 1210),
+      (89, 59, 89),
+      (23, 44, 1990),
+      (38, 76, 1724),
+      (30, 57, 361),
+      (94, 60, 198),
+      (59, 10, 1558),
+      (55, 64, 1996),
+      (12, 11, 167),
+      (36, 24, 1801),
+      (97, 30, 402),
+      (52, 1, 127),
+      (58, 87, 1574),
+      (54, 17, 924),
+      (93, 74, 1587),
+      (24, 36, 1801),
+      (2, 37, 1451),
+      (91, 28, 1040),
+      (59, 55, 321),
+      (69, 11, 370),
+      (8, 54, 613),
+      (29, 85, 1676),
+      (44, 19, 1762),
+      (74, 79, 91),
+      (93, 56, 1110),
+      (58, 10, 459),
+      (41, 50, 1559),
+      (66, 51, 245),
+      (80, 19, 1838),
+      (33, 79, 1871),
+      (76, 73, 514),
+      (98, 37, 1102),
+      (45, 44, 364),
+      (16, 69, 1183),
+      (49, 41, 1629),
+      (19, 80, 1838),
+      (71, 57, 500),
+      (6, 4, 634),
+      (64, 27, 384),
+      (84, 86, 1431),
+      (5, 17, 633),
+      (96, 88, 334),
+      (87, 5, 190),
+      (70, 21, 1619),
+      (55, 33, 1391),
+      (10, 63, 1681),
+      (11, 62, 1339),
+      (33, 13, 826),
+      (64, 70, 878),
+      (65, 72, 1330),
+      (70, 55, 1264),
+      (64, 55, 1996),
+      (50, 41, 1559),
+      (46, 99, 1576),
+      (88, 96, 334),
+      (51, 20, 868),
+      (73, 7, 754),
+      (80, 70, 995),
+      (44, 84, 952),
+      (29, 19, 883),
+      (59, 69, 903),
+      (57, 53, 1575),
+      (90, 13, 1030),
+      (28, 38, 414),
+      (12, 60, 1240),
+      (85, 58, 573),
+      (90, 55, 1808),
+      (4, 10, 1808),
+      (68, 44, 1229),
+      (92, 33, 946),
+      (90, 81, 1024),
+      (53, 75, 545),
+      (45, 30, 272),
+      (41, 77, 138),
+      (21, 70, 1619),
+      (45, 73, 1876),
+      (35, 68, 1252),
+      (13, 96, 461),
+      (53, 57, 1575),
+      (82, 89, 409),
+      (28, 61, 449),
+      (58, 61, 78),
+      (27, 80, 1010),
+      (61, 58, 78),
+      (38, 36, 529),
+      (80, 30, 397),
+      (18, 59, 1352),
+      (62, 11, 1339),
+      (95, 59, 285),
+      (51, 98, 1160),
+      (6, 18, 696),
+      (30, 80, 397),
+      (69, 94, 1397),
+      (58, 85, 573),
+      (48, 99, 410),
+      (51, 46, 213),
+      (57, 71, 500),
+      (91, 30, 104),
+      (65, 7, 349),
+      (79, 51, 175),
+      (47, 26, 921),
+      (4, 61, 543),
+      (98, 73, 1749),
+      (74, 77, 1277),
+      (61, 28, 449),
+      (58, 8, 1131),
+      (61, 45, 1608),
+      (74, 87, 934),
+      (71, 29, 1788),
+      (30, 91, 104),
+      (13, 1, 1187),
+      (0, 26, 1993),
+      (82, 49, 1292),
+      (43, 87, 579),
+      (24, 45, 1720),
+      (20, 51, 868),
+      (77, 62, 907),
+      (82, 75, 306),
+    ]
+
+    // Prepare graph and edge->cost map
+    var graph = Array<GraphNode>()
+    for n in nodes {
+      graph.append(GraphNode(i: n))
+    }
+    var map = Dictionary<Edge, Double>()
+    for tup in edges {
+      map[Edge(start: tup.0, end: tup.1)] = tup.2
+      graph[tup.0].adjList.append(tup.1)
+    }
+
+    // Find spanning tree
+    let treeEdges = Prims(graph, { (start: Int, end: Int) in
+        return map[Edge(start: start, end: end)]!
+    })
+
+    // Compute its cost in order to check results
+    var cost = 0.0
+    for i in 1..<treeEdges.count {
+      if let n = treeEdges[i] { cost += map[Edge(start: n, end: i)]! }
+    }
+    CheckResults(Int(cost) == 49324)
+  }
+}
diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift
index 88b7326..eec59ec 100644
--- a/benchmark/utils/main.swift
+++ b/benchmark/utils/main.swift
@@ -90,6 +90,7 @@
 import Prefix
 import PrefixWhile
 import Prims
+import PrimsSplit
 import ProtocolDispatch
 import ProtocolDispatch2
 import RC4
@@ -402,6 +403,7 @@
 addTo(&precommitTests, "PrefixWhileSequence", run_PrefixWhileSequence, [.validation, .api, .abstraction])
 addTo(&precommitTests, "PrefixWhileSequenceLazy", run_PrefixWhileSequenceLazy, [.validation, .api, .abstraction])
 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])
diff --git a/cmake/modules/SwiftExternalBenchmarkBuild.cmake b/cmake/modules/SwiftExternalBenchmarkBuild.cmake
new file mode 100644
index 0000000..64db306
--- /dev/null
+++ b/cmake/modules/SwiftExternalBenchmarkBuild.cmake
@@ -0,0 +1,89 @@
+
+include(CMakeParseArguments)
+include(LLVMExternalProjectUtils)
+include(SwiftUtils)
+
+# This is the name of the target on the parent cmake side that is associated
+# with an external project target.
+#
+# If LLVMExternalProjectUtils refactors its external target code, so we can
+# easily add individual forwarded targets with different dependencies, this can
+# be removed.
+function(compute_external_target_name target_name_out target)
+  string(REPLACE ":" ";" target_list ${target})
+  list(GET target_list 0 target)
+  list(LENGTH target_list target_list_len)
+  if(${target_list_len} GREATER 1)
+    list(GET target_list 1 target_name)
+  else()
+    set(target_name "${target}")
+  endif()
+
+  set(${target_name_out} "${target_name}" PARENT_SCOPE)
+endfunction()
+
+function(compute_stdlib_dependencies stdlib_dependencies_out platform)
+  foreach(stdlib_dependency ${UNIVERSAL_LIBRARY_NAMES_${platform}})
+    string(FIND "${stdlib_dependency}" "Unittest" find_output)
+    if("${find_output}" STREQUAL "-1")
+      list(APPEND stdlib_dependencies "${stdlib_dependency}")
+    endif()
+  endforeach()
+  set(${stdlib_dependencies_out} "${stdlib_dependencies}" PARENT_SCOPE)
+endfunction()
+
+set(ONLY_PLATFORMS "macosx" "iphoneos" "appletvos" "watchos")
+
+function (get_platform_from_target target_platform_out target)
+  foreach (platform ${ONLY_PLATFORMS})
+    string(FIND "${target}" "${platform}" FOUND_TARGET_PLATFORM)
+    if (NOT FOUND_TARGET_PLATFORM)
+      continue()
+    endif()
+
+    set(${target_platform_out} "${platform}" PARENT_SCOPE)
+    break()
+  endforeach()
+endfunction()
+
+function (compute_target_stdlib_dependencies dependencies_out target)
+  get_platform_from_target(target_platform ${target})
+  precondition(target_platform
+    MESSAGE "Failed to find a platform for ${target_platform}")
+  compute_stdlib_dependencies(stdlib_dependencies ${target_platform})
+  set(${dependencies_out} ${stdlib_dependencies} PARENT_SCOPE)
+endfunction()
+
+function (add_external_benchmark_suite)
+  set(name swift-benchmark)
+  set(src_dir ${SWIFT_SOURCE_DIR}/benchmark)
+  set(bin_dir ${SWIFT_BINARY_DIR}/external-benchmark/binary)
+  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(library_targets swift-benchmark-macosx-x86_64-external)
+
+  set(all_stdlib_dependencies)
+  foreach (target ${library_targets})
+    compute_target_stdlib_dependencies(stdlib_dependencies ${target})
+    precondition(stdlib_dependencies)
+    # Add dependencies from all of our stdlib dependencies to
+    # swift-bench-configure. This will ensure the stdlib is ready to be poked at
+    # in the configure script if we ever want to do so.
+    list(APPEND all_stdlib_dependencies ${stdlib_dependencies})
+  endforeach()
+
+  llvm_ExternalProject_add(swift-bench ${src_dir}
+    SOURCE_DIR ${src_dir}
+    EXCLUDE_FROM_ALL
+    DEPENDS swift ${all_stdlib_dependencies}
+    EXTRA_TARGETS ${bench_targets} ${library_targets}
+    CMAKE_ARGS
+      -DSWIFT_EXEC=${SWIFT_BINARY_DIR}/bin/swiftc
+      -DSWIFT_LIBRARY_PATH=${SWIFT_BINARY_DIR}/lib/swift
+      -DCMAKE_C_COMPILER=${PATH_TO_CLANG_BUILD}/bin/clang
+      -DCMAKE_CXX_COMPILER=${PATH_TO_CLANG_BUILD}/bin/clang++
+    PASSTHROUGH_PREFIXES SWIFT_BENCHMARK
+    )
+endfunction()
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index 1d53b34..0259ba7 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -305,11 +305,9 @@
 
 /// Flags in a generic nominal type descriptor.
 class GenericParameterDescriptorFlags {
-  typedef uint32_t int_type;
+  typedef uint16_t int_type;
   enum : int_type {
-    HasParent        = 0x01,
-    HasGenericParent = 0x02,
-    HasVTable        = 0x04,
+    HasVTable        = 0x0004,
   };
   int_type Data;
   
@@ -317,38 +315,11 @@
 public:
   constexpr GenericParameterDescriptorFlags() : Data(0) {}
 
-  constexpr GenericParameterDescriptorFlags withHasParent(bool b) const {
-    return GenericParameterDescriptorFlags(b ? (Data | HasParent)
-                                             : (Data & ~HasParent));
-  }
-
-  constexpr GenericParameterDescriptorFlags withHasGenericParent(bool b) const {
-    return GenericParameterDescriptorFlags(b ? (Data | HasGenericParent)
-                                             : (Data & ~HasGenericParent));
-  }
-
   constexpr GenericParameterDescriptorFlags withHasVTable(bool b) const {
     return GenericParameterDescriptorFlags(b ? (Data | HasVTable)
                                              : (Data & ~HasVTable));
   }
 
-  /// Does this type have a lexical parent type?
-  ///
-  /// For class metadata, if this is true, the storage for the parent type
-  /// appears immediately prior to the first generic argument.  Other
-  /// metadata always have a slot for their parent type.
-  bool hasParent() const {
-    return Data & HasParent;
-  }
-
-  /// Given that this type has a parent type, is that type generic?  If so,
-  /// it forms part of the key distinguishing this metadata from other
-  /// metadata, and the parent metadata will be the first argument to
-  /// the generic metadata access function.
-  bool hasGenericParent() const {
-    return Data & HasGenericParent;
-  }
-
   /// If this type is a class, does it have a vtable?  If so, the number
   /// of vtable entries immediately follows the generic requirement
   /// descriptor.
diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def
index 359a7bd..19937a3 100644
--- a/include/swift/AST/Attr.def
+++ b/include/swift/AST/Attr.def
@@ -259,8 +259,8 @@
 // FIXME: Replace with improved @available attribute.
 SIMPLE_DECL_ATTR(_versioned, Versioned,
                  OnFunc | OnVar | OnSubscript | OnConstructor |
-                 OnStruct | OnEnum | OnClass | OnProtocol |
-                 LongAttribute | UserInaccessible,
+                 OnDestructor | OnStruct | OnEnum | OnClass |
+                 OnProtocol | LongAttribute | UserInaccessible,
                  64)
 
 SIMPLE_DECL_ATTR(discardableResult, DiscardableResult,
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index 8eecc19..ddf8ebe 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -215,15 +215,6 @@
     /// a superclass requirement.
     bool isConformanceSatisfiedBySuperclass(ProtocolDecl *proto) const;
 
-    /// Lookup a nested type with the given name within this equivalence
-    /// class.
-    ///
-    /// \param otherConcreteTypes If non-null, will be filled in the all of the
-    /// concrete types we found (other than the result) with the same name.
-    TypeDecl *lookupNestedType(
-                   Identifier name,
-                   SmallVectorImpl<TypeDecl *> *otherConcreteTypes = nullptr);
-
     /// Dump a debugging representation of this equivalence class.
     void dump(llvm::raw_ostream &out) const;
 
@@ -241,17 +232,6 @@
       /// anchor was cached.
       unsigned numMembers;
     } archetypeAnchorCache;
-
-    /// Describes a cached nested type.
-    struct CachedNestedType {
-      unsigned numConformancesPresent;
-      CanType superclassPresent;
-      llvm::TinyPtrVector<TypeDecl *> types;
-    };
-
-    /// Cached nested-type information, which contains the best declaration
-    /// for a given name.
-    llvm::SmallDenseMap<Identifier, CachedNestedType> nestedTypeNameCache;
   };
 
   friend class RequirementSource;
@@ -542,6 +522,9 @@
   /// \brief Add all of a generic signature's parameters and requirements.
   void addGenericSignature(GenericSignature *sig);
 
+  /// \brief Build the generic signature.
+  GenericSignature *getGenericSignature();
+
   /// Infer requirements from the given type, recursively.
   ///
   /// This routine infers requirements from a type that occurs within the
@@ -575,13 +558,11 @@
   /// \brief Finalize the set of requirements and compute the generic
   /// signature.
   ///
-  /// After this point, one cannot introduce new requirements, and the
-  /// generic signature builder no longer has valid state.
+  /// After this point, one cannot introduce new requirements.
   GenericSignature *computeGenericSignature(
                       SourceLoc loc,
-                      bool allowConcreteGenericParams = false) &&;
+                      bool allowConcreteGenericParams = false);
 
-private:
   /// Finalize the set of requirements, performing any remaining checking
   /// required before generating archetypes.
   ///
@@ -591,7 +572,6 @@
                 ArrayRef<GenericTypeParamType *> genericParams,
                 bool allowConcreteGenericParams=false);
 
-public:
   /// Process any delayed requirements that can be handled now.
   void processDelayedRequirements();
 
@@ -1510,12 +1490,6 @@
     return parentOrBuilder.dyn_cast<PotentialArchetype *>();
   }
 
-  /// Retrieve the type declaration to which this nested type was resolved.
-  TypeDecl *getResolvedType() const {
-    assert(getParent() && "Not an associated type");
-    return identifier.assocTypeOrConcrete;
-  }
-
   /// Retrieve the associated type to which this potential archetype
   /// has been resolved.
   AssociatedTypeDecl *getResolvedAssociatedType() const {
@@ -1658,8 +1632,13 @@
                                     ArchetypeResolutionKind kind,
                                     GenericSignatureBuilder &builder);
 
-  /// \brief Retrieve (or create) a nested type with a known type.
-  PotentialArchetype *getNestedType(TypeDecl *type,
+  /// \brief Retrieve (or create) a nested type with a known associated type.
+  PotentialArchetype *getNestedType(AssociatedTypeDecl *assocType,
+                                    GenericSignatureBuilder &builder);
+
+  /// \brief Retrieve (or create) a nested type with a known concrete type
+  /// declaration.
+  PotentialArchetype *getNestedType(TypeDecl *concreteDecl,
                                     GenericSignatureBuilder &builder);
 
   /// \brief Retrieve (or create) a nested type that is the current best
@@ -1679,8 +1658,8 @@
   /// type or typealias of the given protocol, unless the \c kind implies that
   /// a potential archetype should not be created if it's missing.
   PotentialArchetype *updateNestedTypeForConformance(
-                        TypeDecl *type,
-                        ArchetypeResolutionKind kind);
+                      PointerUnion<AssociatedTypeDecl *, TypeDecl *> type,
+                      ArchetypeResolutionKind kind);
 
   /// Update the named nested type when we know this type conforms to the given
   /// protocol.
diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h
index 453fab4..f0408a7 100644
--- a/include/swift/AST/Type.h
+++ b/include/swift/AST/Type.h
@@ -356,11 +356,11 @@
   /// join of D and A (or D and B, or D and C) because there is no common
   /// superclass. One would have to jump to an existential (e.g., \c AnyObject)
   /// to find a common type.
-  /// 
-  /// \returns the join of the two types, if there is a concrete type that can
-  /// express the join, or a null type if the only join would be a more-general
-  /// existential type (e.g., \c Any).
-  static Type join(Type type1, Type type2);
+  ///
+  /// \returns the join of the two types, if there is a concrete type
+  /// that can express the join, or Any if the only join would be a
+  /// more-general existential type
+  static Type join(Type first, Type second);
 
 private:
   // Direct comparison is disabled for types, because they may not be canonical.
diff --git a/include/swift/Reflection/MetadataSource.h b/include/swift/Reflection/MetadataSource.h
index 7b234b0..5fa9706 100644
--- a/include/swift/Reflection/MetadataSource.h
+++ b/include/swift/Reflection/MetadataSource.h
@@ -147,25 +147,6 @@
   }
 
   template <typename Allocator>
-  static const MetadataSource*
-  decodeParent(Allocator &A,
-               std::string::const_iterator &it,
-               const std::string::const_iterator &end) {
-    if (it == end || *it != 'P')
-      return nullptr;
-
-    ++it;
-    auto Child = decode(A, it, end);
-    if (!Child)
-      return nullptr;
-
-    if (it == end || *it != '_')
-      return nullptr;
-
-    return A.createParent(Child);
-  }
-
-  template <typename Allocator>
   static const MetadataSource *decode(Allocator &A,
                                       std::string::const_iterator &it,
                                       const std::string::const_iterator &end) {
@@ -180,8 +161,6 @@
         return decodeMetadataCapture(A, it, end);
       case 'G':
         return decodeGenericArgument(A, it, end);
-      case 'P':
-        return decodeParent(A, it, end);
       case 'S':
         ++it;
         return A.createSelf();
@@ -318,29 +297,6 @@
   }
 };
 
-/// Metadata gotten through the parent of a nominal type's metadata.
-class ParentMetadataSource final : public MetadataSource {
-  const MetadataSource *Child;
-public:
-  ParentMetadataSource(const MetadataSource *Child)
-    : MetadataSource(MetadataSourceKind::Parent),
-      Child(Child) {}
-
-  template <typename Allocator>
-  static const ParentMetadataSource*
-  create(Allocator &A, const MetadataSource *Child) {
-    return A.template make_source<ParentMetadataSource>(Child);
-  }
-
-  const MetadataSource *getChild() const {
-    return Child;
-  }
-
-  static bool classof(const MetadataSource *MS) {
-    return MS->getKind() == MetadataSourceKind::Parent;
-  }
-};
-
 /// A source of metadata from the Self metadata parameter passed via
 /// a witness_method convention function.
 class SelfMetadataSource final : public MetadataSource {
diff --git a/include/swift/Reflection/MetadataSourceBuilder.h b/include/swift/Reflection/MetadataSourceBuilder.h
index 2df9d85..3117b10 100644
--- a/include/swift/Reflection/MetadataSourceBuilder.h
+++ b/include/swift/Reflection/MetadataSourceBuilder.h
@@ -59,11 +59,6 @@
     return ClosureBindingMetadataSource::create(*this, Index);
   }
 
-  const ParentMetadataSource *
-  createParent(const MetadataSource *Child) {
-    return ParentMetadataSource::create(*this, Child);
-  }
-
   const SelfMetadataSource *
   createSelf() {
     return SelfMetadataSource::create(*this);
diff --git a/include/swift/Reflection/MetadataSources.def b/include/swift/Reflection/MetadataSources.def
index 60fe4ef..b4dfe28 100644
--- a/include/swift/Reflection/MetadataSources.def
+++ b/include/swift/Reflection/MetadataSources.def
@@ -20,6 +20,5 @@
 METADATA_SOURCE(ReferenceCapture, MetadataSource)
 METADATA_SOURCE(MetadataCapture, MetadataSource)
 METADATA_SOURCE(GenericArgument, MetadataSource)
-METADATA_SOURCE(Parent, MetadataSource)
 METADATA_SOURCE(Self, MetadataSource)
 METADATA_SOURCE(SelfWitnessTable, MetadataSource)
diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h
index bc7a5c3..920c1d2 100644
--- a/include/swift/Reflection/ReflectionContext.h
+++ b/include/swift/Reflection/ReflectionContext.h
@@ -50,7 +50,6 @@
   using super::getBuilder;
   using super::readIsaMask;
   using super::readTypeFromMetadata;
-  using super::readParentFromMetadata;
   using super::readGenericArgFromMetadata;
   using super::readMetadataFromInstance;
   using typename super::StoredPointer;
@@ -460,10 +459,6 @@
       auto Base = cast<GenericArgumentMetadataSource>(MS)->getSource();
       return isMetadataSourceReady(Base, Builder);
     }
-    case MetadataSourceKind::Parent: {
-      auto Base = cast<ParentMetadataSource>(MS)->getChild();
-      return isMetadataSourceReady(Base, Builder);
-    }
     case MetadataSourceKind::Self:
     case MetadataSourceKind::SelfWitnessTable:
       return true;
@@ -548,19 +543,6 @@
 
       return Arg;
     }
-    case MetadataSourceKind::Parent: {
-      auto Base = readMetadataSource(Context,
-          cast<ParentMetadataSource>(MS)->getChild(),
-          Builder);
-      if (!Base.first)
-        break;
-
-      auto Parent = readParentFromMetadata(Base.second);
-      if (!Parent.first)
-        break;
-
-      return Parent;
-    }
     case MetadataSourceKind::Self:
     case MetadataSourceKind::SelfWitnessTable:
       break;
diff --git a/include/swift/Reflection/TypeRefBuilder.h b/include/swift/Reflection/TypeRefBuilder.h
index 2be00c3..b339432 100644
--- a/include/swift/Reflection/TypeRefBuilder.h
+++ b/include/swift/Reflection/TypeRefBuilder.h
@@ -178,6 +178,11 @@
   }
 
   const NominalTypeRef *createNominalType(
+                                    const Optional<std::string> &mangledName) {
+    return NominalTypeRef::create(*this, *mangledName, nullptr);
+  }
+
+  const NominalTypeRef *createNominalType(
                                     const Optional<std::string> &mangledName,
                                     const TypeRef *parent) {
     return NominalTypeRef::create(*this, *mangledName, parent);
@@ -185,6 +190,12 @@
 
   const BoundGenericTypeRef *
   createBoundGenericType(const Optional<std::string> &mangledName,
+                         const std::vector<const TypeRef *> &args) {
+    return BoundGenericTypeRef::create(*this, *mangledName, args, nullptr);
+  }
+
+  const BoundGenericTypeRef *
+  createBoundGenericType(const Optional<std::string> &mangledName,
                          const std::vector<const TypeRef *> &args,
                          const TypeRef *parent) {
     return BoundGenericTypeRef::create(*this, *mangledName, args, parent);
diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h
index 396e964..d26bc9f 100644
--- a/include/swift/Remote/MetadataReader.h
+++ b/include/swift/Remote/MetadataReader.h
@@ -934,33 +934,6 @@
     swift_runtime_unreachable("Unhandled IsaEncodingKind in switch.");
   }
 
-  /// Read the parent type metadata from a nested nominal type metadata.
-  std::pair<bool, StoredPointer>
-  readParentFromMetadata(StoredPointer metadata) {
-    auto Meta = readMetadata(metadata);
-    if (!Meta)
-      return std::make_pair(false, 0);
-
-    auto descriptorAddress = readAddressOfNominalTypeDescriptor(Meta);
-    if (!descriptorAddress)
-      return std::make_pair(false, 0);
-
-    // Read the nominal type descriptor.
-    auto descriptor = readNominalTypeDescriptor(descriptorAddress);
-    if (!descriptor)
-      return std::make_pair(false, 0);
-
-    // Read the parent type if the type has one.
-    if (descriptor->GenericParams.Flags.hasParent()) {
-      StoredPointer parentAddress = getNominalParent(Meta, descriptor);
-      if (!parentAddress)
-        return std::make_pair(false, 0);
-      return std::make_pair(true, parentAddress);
-    }
-
-    return std::make_pair(false, 0);
-  }
-
   /// Read a single generic type argument from a bound generic type
   /// metadata.
   std::pair<bool, StoredPointer>
@@ -1308,32 +1281,6 @@
     return OwnedProtocolDescriptorRef(Casted);
   }
 
-  StoredPointer getNominalParent(MetadataRef metadata,
-                                 NominalTypeDescriptorRef descriptor) {
-    // If this is metadata for some sort of value type, the parent type
-    // is at a fixed offset.
-    if (auto valueMetadata = dyn_cast<TargetValueMetadata<Runtime>>(metadata)) {
-      return valueMetadata->Parent;
-    }
-
-    // If this is metadata for a class type, the parent type for the
-    // most-derived class is at an offset stored in the most-derived
-    // nominal type descriptor.
-    if (auto classMetadata = dyn_cast<TargetClassMetadata<Runtime>>(metadata)) {
-      // If it does, it's immediately before the generic parameters.
-      auto offsetToParent
-        = sizeof(StoredPointer) * (descriptor->GenericParams.Offset - 1);
-      RemoteAddress addressOfParent(metadata.getAddress() + offsetToParent);
-      StoredPointer parentAddress;
-      if (!Reader->readInteger(addressOfParent, &parentAddress))
-        return StoredPointer();
-      return parentAddress;
-    }
-
-    // Otherwise, we don't know how to access its parent.  This is a failure.
-    return StoredPointer();
-  }
-
   std::vector<BuiltType>
   getGenericSubst(MetadataRef metadata, NominalTypeDescriptorRef descriptor) {
     std::vector<BuiltType> substitutions;
@@ -1387,23 +1334,13 @@
     if (!typeDecl)
       return BuiltType();
 
-    // Read the parent type if the type has one.
-    BuiltType parent = BuiltType();
-    if (descriptor->GenericParams.Flags.hasParent()) {
-      StoredPointer parentAddress = getNominalParent(metadata, descriptor);
-      if (!parentAddress)
-        return BuiltType();
-      parent = readTypeFromMetadata(parentAddress);
-      if (!parent) return BuiltType();
-    }
-
     BuiltType nominal;
     if (descriptor->GenericParams.NumPrimaryParams) {
       auto args = getGenericSubst(metadata, descriptor);
       if (args.empty()) return BuiltType();
-      nominal = Builder.createBoundGenericType(typeDecl, args, parent);
+      nominal = Builder.createBoundGenericType(typeDecl, args);
     } else {
-      nominal = Builder.createNominalType(typeDecl, parent);
+      nominal = Builder.createNominalType(typeDecl);
     }
     if (!nominal) return BuiltType();
 
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index 87ccf64..5207f0c 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -1102,6 +1102,13 @@
 };
 using HeapMetadata = TargetHeapMetadata<InProcess>;
 
+struct GenericContextDescriptor {
+  /// The number of primary type parameters. This is always less than or equal
+  /// to NumGenericRequirements; it counts only the type parameters
+  /// and not any required witness tables.
+  uint32_t NumPrimaryParams;
+};
+
 /// Header for a generic parameter descriptor. This is a variable-sized
 /// structure that describes how to find and parse a generic parameter vector
 /// within the type metadata for an instance of a nominal type.
@@ -1109,8 +1116,7 @@
   /// The offset to the first generic argument from the start of
   /// metadata record.
   ///
-  /// This is meaningful if either NumGenericRequirements is nonzero or
-  /// (for classes) if Flags.hasParent() is true.
+  /// This is meaningful if NumGenericRequirements is nonzero.
   uint32_t Offset;
 
   /// The amount of generic requirement data in the metadata record, in
@@ -1126,6 +1132,10 @@
   /// and not any required witness tables.
   uint32_t NumPrimaryParams;
 
+  /// The number of types that this type is nested inside of, including itself
+  /// (so this value is at least 1).
+  uint16_t NestingDepth;
+
   /// Flags for this generic parameter descriptor.
   GenericParameterDescriptorFlags Flags;
 
@@ -1135,7 +1145,12 @@
 
   /// True if the nominal type is generic in any way.
   bool isGeneric() const {
-    return hasGenericRequirements() || Flags.hasGenericParent();
+    return hasGenericRequirements();
+  }
+
+  GenericContextDescriptor getContext(unsigned depth) const {
+    assert(depth < NestingDepth);
+    return ((const GenericContextDescriptor *)(this + 1))[depth];
   }
 
   // TODO: add meaningful descriptions of the generic requirements.
@@ -1316,12 +1331,13 @@
         !GenericParams.Flags.hasVTable())
       return nullptr;
 
-    auto asWords = reinterpret_cast<const void * const*>(this + 1);
+    auto asWords = reinterpret_cast<const uint32_t *>(this + 1);
 
     // TODO: Once we emit reflective descriptions of generic requirements,
     // skip the right number of words here.
 
-    return reinterpret_cast<const VTableDescriptor *>(asWords);
+    return reinterpret_cast<const VTableDescriptor *>(asWords
+        + GenericParams.NestingDepth);
   }
 
   /// The generic parameter descriptor header. This describes how to find and
@@ -1567,17 +1583,6 @@
     return getter(this);
   }
 
-  /// Return the parent type for a given level in the class hierarchy, or
-  /// null if that level does not have a parent type.
-  const TargetMetadata<Runtime> *
-  getParentType(const TargetNominalTypeDescriptor<Runtime> *theClass) const {
-    if (!theClass->GenericParams.Flags.hasParent())
-      return nullptr;
-
-    auto metadataAsWords = reinterpret_cast<const Metadata * const *>(this);
-    return metadataAsWords[theClass->GenericParams.Offset - 1];
-  }
-
   StoredPointer offsetToDescriptorOffset() const {
     return offsetof(TargetClassMetadata<Runtime>, Description);
   }
@@ -1745,22 +1750,15 @@
   using StoredPointer = typename Runtime::StoredPointer;
   TargetValueMetadata(MetadataKind Kind,
     ConstTargetMetadataPointer<Runtime, TargetNominalTypeDescriptor>
-                      description,
-    ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> parent)
+                      description)
     : TargetMetadata<Runtime>(Kind),
-      Description(description),
-      Parent(parent)
+      Description(description)
   {}
 
   /// An out-of-line description of the type.
   ConstTargetFarRelativeDirectPointer<Runtime, TargetNominalTypeDescriptor>
   Description;
 
-  /// The parent type of this member type, or null if this is not a
-  /// member type.  It's acceptable to make this a direct pointer because
-  /// parent types are relatively uncommon.
-  TargetPointer<Runtime, const TargetMetadata<Runtime>> Parent;
-
   static bool classof(const TargetMetadata<Runtime> *metadata) {
     return metadata->getKind() == MetadataKind::Struct
       || metadata->getKind() == MetadataKind::Enum
@@ -1785,11 +1783,6 @@
   StoredPointer offsetToDescriptorOffset() const {
     return offsetof(TargetValueMetadata<Runtime>, Description);
   }
-
-  StoredPointer offsetToParentOffset() const {
-    return offsetof(TargetValueMetadata<Runtime>, Parent);
-  }
-  
 };
 using ValueMetadata = TargetValueMetadata<InProcess>;
 
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 5fea838..d716522 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -524,6 +524,8 @@
   // Redeclare because lldb currently doesn't know about using-declarations
   void dump() const;
 
+  void operator delete(void *Ptr, size_t) SWIFT_DELETE_OPERATOR_DELETED
+
   ValueKind getValueKind() const {
     return ValueBase::getKind();
   }
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 5bb5519..7917da8 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4591,7 +4591,7 @@
     GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
   builder.addRequirement(requirement, source, nullptr);
 
-  CanGenericSignature genericSig(std::move(builder).computeGenericSignature(SourceLoc()));
+  CanGenericSignature genericSig(builder.computeGenericSignature(SourceLoc()));
 
   auto result = Impl.ExistentialSignatures.insert(
     std::make_pair(existential, genericSig));
diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp
index f9af2d2..a7c473a 100644
--- a/lib/AST/Builtins.cpp
+++ b/lib/AST/Builtins.cpp
@@ -491,8 +491,7 @@
         Builder.addGenericParameter(gp);
       }
 
-      auto GenericSig =
-        std::move(Builder).computeGenericSignature(SourceLoc());
+      auto GenericSig = Builder.computeGenericSignature(SourceLoc());
       GenericEnv = GenericSig->createGenericEnvironment(*ctx.TheBuiltinModule);
     }
 
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index e7e7f55..bcb698a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3419,8 +3419,7 @@
          nullptr);
 
   // Compute and record the signature.
-  auto requirementSig =
-    std::move(builder).computeGenericSignature(SourceLoc());
+  auto requirementSig = builder.computeGenericSignature(SourceLoc());
   RequirementSignature = requirementSig->getRequirements().data();
   assert(RequirementSignature != nullptr);
   NumRequirementsInSignature = requirementSig->getRequirements().size();
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 32f8d63..f0b85ea 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -76,10 +76,6 @@
           "# of hits in the archetype anchor cache");
 STATISTIC(NumArchetypeAnchorCacheMisses,
           "# of misses in the archetype anchor cache");
-STATISTIC(NumNestedTypeCacheHits,
-         "# of hits in the equivalence class nested type cache");
-STATISTIC(NumNestedTypeCacheMisses,
-         "# of misses in the equivalence class nested type cache");
 STATISTIC(NumProcessDelayedRequirements,
           "# of times we process delayed requirements");
 STATISTIC(NumProcessDelayedRequirementsUnchanged,
@@ -1558,159 +1554,6 @@
   return false;
 }
 
-/// Compare two associated types.
-static int compareAssociatedTypes(AssociatedTypeDecl *assocType1,
-                                  AssociatedTypeDecl *assocType2) {
-  // - by name.
-  if (int result = assocType1->getName().str().compare(
-                                              assocType2->getName().str()))
-    return result;
-
-  // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
-  auto proto1 = assocType1->getProtocol();
-  auto proto2 = assocType2->getProtocol();
-  if (int compareProtocols = ProtocolType::compareProtocols(&proto1, &proto2))
-    return compareProtocols;
-
-  // Error case: if we have two associated types with the same name in the
-  // same protocol, just tie-break based on address.
-  if (assocType1 != assocType2)
-    return assocType1 < assocType2 ? -1 : +1;
-
-  return 0;
-}
-
-TypeDecl *EquivalenceClass::lookupNestedType(
-                             Identifier name,
-                             SmallVectorImpl<TypeDecl *> *otherConcreteTypes) {
-  // Populates the result structures from the given cache entry.
-  auto populateResult = [&](const CachedNestedType &cache) -> TypeDecl * {
-    if (otherConcreteTypes)
-      otherConcreteTypes->clear();
-
-    // If there aren't any types in the cache, we're done.
-    if (cache.types.empty()) return nullptr;
-
-    // The first type in the cache is always the final result.
-    // Collect the rest in the concrete-declarations list, if needed.
-    if (otherConcreteTypes) {
-      for (auto type : ArrayRef<TypeDecl *>(cache.types).slice(1)) {
-        otherConcreteTypes->push_back(type);
-      }
-    }
-
-    return cache.types.front();
-  };
-
-  // If we have a cached value that is up-to-date, use that.
-  auto cached = nestedTypeNameCache.find(name);
-  if (cached != nestedTypeNameCache.end() &&
-      cached->second.numConformancesPresent == conformsTo.size() &&
-      (!superclass ||
-       cached->second.superclassPresent == superclass->getCanonicalType())) {
-    ++NumNestedTypeCacheHits;
-    return populateResult(cached->second);
-  }
-
-  // Cache miss; go compute the result.
-  ++NumNestedTypeCacheMisses;
-
-  // Look for types with the given name in protocols that we know about.
-  AssociatedTypeDecl *bestAssocType = nullptr;
-  SmallVector<TypeDecl *, 4> concreteDecls;
-  for (const auto &conforms : conformsTo) {
-    ProtocolDecl *proto = conforms.first;
-
-    // Look for an associated type and/or concrete type with this name.
-    for (auto member : proto->lookupDirect(name,
-                                           /*ignoreNewExtensions=*/true)) {
-      // 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)) {
-        if (!bestAssocType ||
-             compareAssociatedTypes(assocType, bestAssocType) < 0)
-          bestAssocType = assocType;
-
-        continue;
-      }
-
-      // If this is another type declaration, determine whether we should
-      // record it.
-      if (auto type = dyn_cast<TypeDecl>(member)) {
-        // FIXME: Filter out type declarations that aren't in the same
-        // module as the protocol itself. This is an unprincipled hack, but
-        // provides consistent lookup semantics for the generic signature
-        // builder in all contents.
-        if (type->getDeclContext()->getParentModule()
-              != proto->getParentModule())
-          continue;
-
-        // Resolve the signature of this type.
-        if (!type->hasInterfaceType()) {
-          type->getASTContext().getLazyResolver()->resolveDeclSignature(type);
-          if (!type->hasInterfaceType())
-            continue;
-        }
-
-        concreteDecls.push_back(type);
-        continue;
-      }
-    }
-  }
-
-  // If we haven't found anything yet but have a superclass, look for a type
-  // in the superclass.
-  // FIXME: Shouldn't we always look in the superclass?
-  if (!bestAssocType && concreteDecls.empty() && superclass) {
-    if (auto classDecl = superclass->getClassOrBoundGenericClass()) {
-      SmallVector<ValueDecl *, 2> superclassMembers;
-      classDecl->getParentModule()->lookupQualified(
-          superclass, name,
-          NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers, nullptr,
-          superclassMembers);
-      for (auto member : superclassMembers) {
-        if (auto type = dyn_cast<TypeDecl>(member)) {
-          // Resolve the signature of this type.
-          if (!type->hasInterfaceType()) {
-            type->getASTContext().getLazyResolver()->resolveDeclSignature(type);
-            if (!type->hasInterfaceType())
-              continue;
-          }
-
-          concreteDecls.push_back(type);
-        }
-      }
-    }
-  }
-
-  // Form the new cache entry.
-  CachedNestedType entry;
-  entry.numConformancesPresent = conformsTo.size();
-  entry.superclassPresent =
-    superclass ? superclass->getCanonicalType() : CanType();
-  if (bestAssocType) {
-    entry.types.push_back(bestAssocType);
-    entry.types.insert(entry.types.end(),
-                       concreteDecls.begin(), concreteDecls.end());
-  } else if (!concreteDecls.empty()) {
-    // Find the best concrete type.
-    auto bestConcreteTypeIter =
-      std::min_element(concreteDecls.begin(), concreteDecls.end(),
-                       [](TypeDecl *type1, TypeDecl *type2) {
-                         return TypeDecl::compare(type1, type2) < 0;
-                       });
-
-    // Put the best concrete type first; the rest will follow.
-    entry.types.push_back(*bestConcreteTypeIter);
-    entry.types.insert(entry.types.end(),
-                       concreteDecls.begin(), bestConcreteTypeIter);
-    entry.types.insert(entry.types.end(),
-                       bestConcreteTypeIter + 1, concreteDecls.end());
-  }
-
-  return populateResult((nestedTypeNameCache[name] = std::move(entry)));
-}
-
 void EquivalenceClass::dump(llvm::raw_ostream &out) const {
   out << "Equivalence class represented by "
     << members.front()->getRepresentative()->getDebugName() << ":\n";
@@ -2118,6 +1961,28 @@
   return result;
 }
 
+/// Compare two associated types.
+static int compareAssociatedTypes(AssociatedTypeDecl *assocType1,
+                                  AssociatedTypeDecl *assocType2) {
+  // - by name.
+  if (int result = assocType1->getName().str().compare(
+                                              assocType2->getName().str()))
+    return result;
+
+  // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
+  auto proto1 = assocType1->getProtocol();
+  auto proto2 = assocType2->getProtocol();
+  if (int compareProtocols = ProtocolType::compareProtocols(&proto1, &proto2))
+    return compareProtocols;
+
+  // Error case: if we have two associated types with the same name in the
+  // same protocol, just tie-break based on address.
+  if (assocType1 != assocType2)
+    return assocType1 < assocType2 ? -1 : +1;
+
+  return 0;
+}
+
 /// Whether there are any concrete type declarations in the potential archetype.
 static bool hasConcreteDecls(const PotentialArchetype *pa) {
   auto parent = pa->getParent();
@@ -2345,9 +2210,16 @@
 }
 
 PotentialArchetype *PotentialArchetype::getNestedType(
-                                            TypeDecl *type,
+                                            AssociatedTypeDecl *assocType,
                                             GenericSignatureBuilder &builder) {
-  return updateNestedTypeForConformance(type,
+  return updateNestedTypeForConformance(assocType,
+                                        ArchetypeResolutionKind::WellFormed);
+}
+
+PotentialArchetype *PotentialArchetype::getNestedType(
+                                            TypeDecl *getConcreteTypeDecl,
+                                            GenericSignatureBuilder &builder) {
+  return updateNestedTypeForConformance(getConcreteTypeDecl,
                                         ArchetypeResolutionKind::WellFormed);
 }
 
@@ -2355,21 +2227,94 @@
                                            Identifier name,
                                            GenericSignatureBuilder &builder,
                                            ArchetypeResolutionKind kind) {
+  // Look for the best associated type or concrete type within the protocols
+  // we know about.
+  AssociatedTypeDecl *bestAssocType = nullptr;
+  TypeDecl *bestConcreteDecl = nullptr;
   SmallVector<TypeDecl *, 4> concreteDecls;
-  auto bestType =
-    getOrCreateEquivalenceClass()->lookupNestedType(name, &concreteDecls);
+  auto rep = getRepresentative();
+  for (auto proto : rep->getConformsTo()) {
+    // Look for an associated type and/or concrete type with this name.
+    AssociatedTypeDecl *assocType = nullptr;
+    TypeDecl *concreteDecl = nullptr;
+    for (auto member : proto->lookupDirect(name,
+                                           /*ignoreNewExtensions=*/true)) {
+      if (!assocType)
+        assocType = dyn_cast<AssociatedTypeDecl>(member);
 
-  // We didn't find any type with this name.
-  if (!bestType) return nullptr;
+      // FIXME: Filter out type declarations that aren't in the protocol itself?
+      if (!concreteDecl && !isa<AssociatedTypeDecl>(member)) {
+        if (!member->hasInterfaceType())
+          builder.getLazyResolver()->resolveDeclSignature(member);
+        if (member->hasInterfaceType())
+          concreteDecl = dyn_cast<TypeDecl>(member);
+      }
+    }
 
-  // Resolve the nested type.
-  auto resultPA = updateNestedTypeForConformance(bestType, kind);
+    if (assocType &&
+        (!bestAssocType ||
+         compareAssociatedTypes(assocType, bestAssocType) < 0))
+      bestAssocType = assocType;
+
+    if (concreteDecl) {
+      // Record every concrete type.
+      concreteDecls.push_back(concreteDecl);
+
+      // Track the best concrete type.
+      if (!bestConcreteDecl ||
+          TypeDecl::compare(concreteDecl, bestConcreteDecl) < 0)
+        bestConcreteDecl = concreteDecl;
+    }
+  }
+
+  // If we found an associated type, use it.
+  PotentialArchetype *resultPA = nullptr;
+  if (bestAssocType) {
+    resultPA = updateNestedTypeForConformance(bestAssocType, kind);
+  }
+
+  // If we have an associated type, drop any concrete decls that aren't in
+  // the same module as the protocol.
+  // FIXME: This is an unprincipled hack for an unprincipled feature.
+  concreteDecls.erase(
+    std::remove_if(concreteDecls.begin(), concreteDecls.end(),
+                   [&](TypeDecl *concreteDecl) {
+      return concreteDecl->getDeclContext()->getParentModule() !=
+        concreteDecl->getDeclContext()
+          ->getAsNominalTypeOrNominalTypeExtensionContext()->getParentModule();
+    }),
+    concreteDecls.end());
+
+  // If we haven't found anything yet but have a superclass, look for a type
+  // in the superclass.
+  if (!resultPA && concreteDecls.empty()) {
+    if (auto superclass = getSuperclass()) {
+      if (auto classDecl = superclass->getClassOrBoundGenericClass()) {
+        SmallVector<ValueDecl *, 2> superclassMembers;
+        classDecl->getParentModule()->lookupQualified(superclass, name, NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers, nullptr,
+            superclassMembers);
+        for (auto member : superclassMembers) {
+          if (auto concreteDecl = dyn_cast<TypeDecl>(member)) {
+            // Track the best concrete type.
+            if (!bestConcreteDecl ||
+                TypeDecl::compare(concreteDecl, bestConcreteDecl) < 0)
+              bestConcreteDecl = concreteDecl;
+
+            concreteDecls.push_back(concreteDecl);
+          }
+        }
+      }
+    }
+  }
 
   // Update for all of the concrete decls with this name, which will introduce
   // various same-type constraints.
   for (auto concreteDecl : concreteDecls) {
-    (void)updateNestedTypeForConformance(concreteDecl,
-                                         ArchetypeResolutionKind::WellFormed);
+    auto concreteDeclPA = updateNestedTypeForConformance(
+                                      concreteDecl,
+                                      ArchetypeResolutionKind::WellFormed);
+    if (!resultPA && concreteDecl == bestConcreteDecl)
+      resultPA = concreteDeclPA;
   }
 
   return resultPA;
@@ -2380,22 +2325,43 @@
                                                  Identifier name,
                                                  ProtocolDecl *proto,
                                                  ArchetypeResolutionKind kind) {
-  // Lookup the best type for this name.
-  auto bestType =
-    getOrCreateEquivalenceClass()->lookupNestedType(name, nullptr);
-  if (!bestType) return nullptr;
+  /// Determine whether there is an associated type or concrete type with this
+  /// name in this protocol. If not, there's nothing to do.
+  AssociatedTypeDecl *assocType = nullptr;
+  TypeDecl *concreteDecl = nullptr;
+  for (auto member : proto->lookupDirect(name, /*ignoreNewExtensions=*/true)) {
+    if (!assocType)
+      assocType = dyn_cast<AssociatedTypeDecl>(member);
 
-  // Form the potential archetype.
-  return updateNestedTypeForConformance(bestType, kind);
+    // FIXME: Filter out concrete types that aren't in the protocol itself?
+    if (!concreteDecl && !isa<AssociatedTypeDecl>(member)) {
+      if (!member->hasInterfaceType())
+        proto->getASTContext().getLazyResolver()->resolveDeclSignature(member);
+      if (member->hasInterfaceType())
+        concreteDecl = dyn_cast<TypeDecl>(member);
+    }
+  }
+
+  // There is no associated type or concrete type with this name in this
+  // protocol
+  if (!assocType && !concreteDecl)
+    return nullptr;
+
+  // If we had both an associated type and a concrete type, ignore the latter.
+  // This is for ill-formed code.
+  if (assocType)
+    return updateNestedTypeForConformance(assocType, kind);
+
+  return updateNestedTypeForConformance(concreteDecl, kind);
 }
 
 PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
-                                              TypeDecl *type,
-                                              ArchetypeResolutionKind kind) {
-  if (!type) return nullptr;
-
-  AssociatedTypeDecl *assocType = dyn_cast<AssociatedTypeDecl>(type);
-  TypeDecl *concreteDecl = assocType ? nullptr : type;
+                      PointerUnion<AssociatedTypeDecl *, TypeDecl *> type,
+                      ArchetypeResolutionKind kind) {
+  auto *assocType = type.dyn_cast<AssociatedTypeDecl *>();
+  auto *concreteDecl = type.dyn_cast<TypeDecl *>();
+  if (!assocType && !concreteDecl)
+    return nullptr;
 
   // If we were asked for a complete, well-formed archetype, make sure we
   // process delayed requirements if anything changed.
@@ -3667,8 +3633,13 @@
   auto parentRepPA = parentPA->getRepresentative();
   if (parentPA == parentRepPA) return;
 
-  PotentialArchetype *existingPA =
-    parentRepPA->getNestedType(nestedPA->getResolvedType(), *this);
+  PotentialArchetype *existingPA;
+  if (auto assocType = nestedPA->getResolvedAssociatedType()) {
+    existingPA = parentRepPA->getNestedType(assocType, *this);
+  } else {
+    existingPA = parentRepPA->getNestedType(nestedPA->getConcreteTypeDecl(),
+                                            *this);
+  }
 
   auto sameNamedSource =
     FloatingRequirementSource::forNestedTypeNameMatch(
@@ -3922,10 +3893,8 @@
                                  UnresolvedHandlingKind unresolvedHandling) {
   return addSameTypeRequirement(paOrT1, paOrT2, source, unresolvedHandling,
                                 [&](Type type1, Type type2) {
-      if (source.getLoc().isValid()) {
-        Diags.diagnose(source.getLoc(), diag::requires_same_concrete_type,
-                       type1, type2);
-      }
+      Diags.diagnose(source.getLoc(), diag::requires_same_concrete_type,
+                     type1, type2);
     });
 }
 
@@ -4201,10 +4170,9 @@
         firstType, secondType, source,
         UnresolvedHandlingKind::GenerateConstraints,
         [&](Type type1, Type type2) {
-          if (source.getLoc().isValid()) {
+          if (source.getLoc().isValid())
             Diags.diagnose(source.getLoc(), diag::requires_same_concrete_type,
                            type1, type2);
-          }
         });
   }
   }
@@ -6325,23 +6293,21 @@
   });
 }
 
-GenericSignature *GenericSignatureBuilder::computeGenericSignature(
-                                          SourceLoc loc,
-                                          bool allowConcreteGenericParams) && {
-  // Finalize the builder, producing any necessary diagnostics.
-  finalize(loc, Impl->GenericParams, allowConcreteGenericParams);
+GenericSignature *GenericSignatureBuilder::getGenericSignature() {
+  assert(Impl->finalized && "Must finalize builder first");
 
   // Collect the requirements placed on the generic parameter types.
   SmallVector<Requirement, 4> requirements;
   collectRequirements(*this, Impl->GenericParams, requirements);
 
-  // Form the generic signature.
   auto sig = GenericSignature::get(Impl->GenericParams, requirements);
-
-  // Wipe out the internal state, ensuring that nobody uses this builder for
-  // anything more.
-  Impl.reset();
-
   return sig;
 }
 
+GenericSignature *GenericSignatureBuilder::computeGenericSignature(
+                                          SourceLoc loc,
+                                          bool allowConcreteGenericParams) {
+  finalize(loc, Impl->GenericParams, allowConcreteGenericParams);
+  return getGenericSignature();
+}
+
diff --git a/lib/AST/TypeJoinMeet.cpp b/lib/AST/TypeJoinMeet.cpp
index 3620c4a..ac5284a 100644
--- a/lib/AST/TypeJoinMeet.cpp
+++ b/lib/AST/TypeJoinMeet.cpp
@@ -15,9 +15,9 @@
 //
 //===----------------------------------------------------------------------===//
 #include "swift/AST/ASTContext.h"
+#include "swift/AST/CanTypeVisitor.h"
 #include "swift/AST/Decl.h"
 #include "swift/AST/Type.h"
-#include "swift/AST/TypeVisitor.h"
 #include "swift/AST/Types.h"
 #include "llvm/ADT/SmallPtrSet.h"
 using namespace swift;
@@ -26,43 +26,33 @@
 // used for optimizing away extra exploratory work in the constraint
 // solver. It should eventually encompass all of the subtyping rules
 // of the language.
-struct TypeJoin : TypeVisitor<TypeJoin, Type> {
-  Type First;
+struct TypeJoin : CanTypeVisitor<TypeJoin, CanType> {
+  CanType First;
 
-  TypeJoin(Type First) : First(First) {
+  TypeJoin(CanType First) : First(First) {
     assert(First && "Unexpected null type!");
   }
 
-  static Type getSuperclassJoin(Type first, Type second);
+  static CanType getSuperclassJoin(CanType first, CanType second);
 
-  Type visitClassType(Type second);
-  Type visitBoundGenericClassType(Type second);
-  Type visitArchetypeType(Type second);
-  Type visitDynamicSelfType(Type second);
-  Type visitMetatypeType(Type second);
-  Type visitExistentialMetatypeType(Type second);
-  Type visitBoundGenericEnumType(Type second);
+  CanType visitClassType(CanType second);
+  CanType visitBoundGenericClassType(CanType second);
+  CanType visitArchetypeType(CanType second);
+  CanType visitDynamicSelfType(CanType second);
+  CanType visitMetatypeType(CanType second);
+  CanType visitExistentialMetatypeType(CanType second);
+  CanType visitBoundGenericEnumType(CanType second);
 
-  Type visitOptionalType(Type second);
+  CanType visitOptionalType(CanType second);
 
-  Type visitType(Type second) {
+  CanType visitType(CanType second) {
     // FIXME: Implement all the visitors.
     //    llvm_unreachable("Unimplemented type visitor!");
     return First->getASTContext().TheAnyType;
   }
 
 public:
-  static Type join(Type first, Type second) {
-    if (!first || !second) {
-      if (first)
-        return ErrorType::get(first->getASTContext());
-
-      if (second)
-        return ErrorType::get(second->getASTContext());
-
-      return Type();
-    }
-
+  static CanType join(CanType first, CanType second) {
     assert(!first->hasTypeVariable() && !second->hasTypeVariable() &&
            "Cannot compute join of types involving type variables");
 
@@ -72,7 +62,7 @@
            "Expected simple type!");
 
     // If the types are equivalent, the join is obvious.
-    if (first->isEqual(second))
+    if (first == second)
       return first;
 
     // Until we handle all the combinations of joins, we need to make
@@ -85,23 +75,19 @@
   }
 };
 
-Type TypeJoin::getSuperclassJoin(Type first, Type second) {
-  if (!first || !second)
-    return TypeJoin::join(first, second);
-
+CanType TypeJoin::getSuperclassJoin(CanType first, CanType second) {
   if (!first->mayHaveSuperclass() || !second->mayHaveSuperclass())
     return first->getASTContext().TheAnyType;
 
   /// Walk the superclasses of `first` looking for `second`. Record them
   /// for our second step.
   llvm::SmallPtrSet<CanType, 8> superclassesOfFirst;
-  CanType canSecond = second->getCanonicalType();
   for (Type super = first; super; super = super->getSuperclass()) {
-    CanType canSuper = super->getCanonicalType();
+    auto canSuper = super->getCanonicalType();
 
     // If we have found the second type, we're done.
-    if (canSuper == canSecond)
-      return super;
+    if (canSuper == second)
+      return canSuper;
 
     superclassesOfFirst.insert(canSuper);
   }
@@ -109,94 +95,104 @@
   // Look through the superclasses of second to determine if any were also
   // superclasses of first.
   for (Type super = second; super; super = super->getSuperclass()) {
-    CanType canSuper = super->getCanonicalType();
+    auto canSuper = super->getCanonicalType();
 
     // If we found the first type, we're done.
     if (superclassesOfFirst.count(canSuper))
-      return super;
+      return canSuper;
   }
 
   // There is no common superclass; we're done.
   return first->getASTContext().TheAnyType;
 }
 
-Type TypeJoin::visitClassType(Type second) {
+CanType TypeJoin::visitClassType(CanType second) {
   return getSuperclassJoin(First, second);
 }
 
-Type TypeJoin::visitBoundGenericClassType(Type second) {
+CanType TypeJoin::visitBoundGenericClassType(CanType second) {
   return getSuperclassJoin(First, second);
 }
 
-Type TypeJoin::visitArchetypeType(Type second) {
+CanType TypeJoin::visitArchetypeType(CanType second) {
   return getSuperclassJoin(First, second);
 }
 
-Type TypeJoin::visitDynamicSelfType(Type second) {
+CanType TypeJoin::visitDynamicSelfType(CanType second) {
   return getSuperclassJoin(First, second);
 }
 
-Type TypeJoin::visitMetatypeType(Type second) {
+CanType TypeJoin::visitMetatypeType(CanType second) {
   if (First->getKind() != second->getKind())
     return First->getASTContext().TheAnyType;
 
-  auto firstInstance = First->castTo<AnyMetatypeType>()->getInstanceType();
-  auto secondInstance = second->castTo<AnyMetatypeType>()->getInstanceType();
+  auto firstInstance =
+      First->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
+  auto secondInstance =
+      second->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
 
   auto joinInstance = join(firstInstance, secondInstance);
 
   if (!joinInstance)
     return First->getASTContext().TheAnyType;
 
-  return MetatypeType::get(joinInstance);
+  return MetatypeType::get(joinInstance)->getCanonicalType();
 }
 
-Type TypeJoin::visitExistentialMetatypeType(Type second) {
+CanType TypeJoin::visitExistentialMetatypeType(CanType second) {
   if (First->getKind() != second->getKind())
     return First->getASTContext().TheAnyType;
 
-  auto firstInstance = First->castTo<AnyMetatypeType>()->getInstanceType();
-  auto secondInstance = second->castTo<AnyMetatypeType>()->getInstanceType();
+  auto firstInstance =
+      First->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
+  auto secondInstance =
+      second->castTo<AnyMetatypeType>()->getInstanceType()->getCanonicalType();
 
   auto joinInstance = join(firstInstance, secondInstance);
 
   if (!joinInstance)
     return First->getASTContext().TheAnyType;
 
-  return ExistentialMetatypeType::get(joinInstance);
+  return ExistentialMetatypeType::get(joinInstance)->getCanonicalType();
 }
 
-Type TypeJoin::visitBoundGenericEnumType(Type second) {
+CanType TypeJoin::visitBoundGenericEnumType(CanType second) {
   if (First->getKind() != second->getKind())
     return First->getASTContext().TheAnyType;
 
   OptionalTypeKind otk1, otk2;
-  Type objectType1 = First->getAnyOptionalObjectType(otk1);
-  Type objectType2 = second->getAnyOptionalObjectType(otk2);
+  auto firstObject = First->getAnyOptionalObjectType(otk1);
+  auto secondObject = second->getAnyOptionalObjectType(otk2);
   if (otk1 == OTK_Optional || otk2 == OTK_Optional) {
+    auto canFirst = firstObject->getCanonicalType();
+    auto canSecond = secondObject->getCanonicalType();
+
     // Compute the join of the unwrapped type. If there is none, we're done.
-    Type unwrappedJoin = join(objectType1 ? objectType1 : First,
-                              objectType2 ? objectType2 : second);
+    auto unwrappedJoin =
+        join(canFirst ? canFirst : First, canSecond ? canSecond : second);
     // FIXME: More general joins of enums need to be handled.
     if (!unwrappedJoin)
       return First->getASTContext().TheAnyType;
 
-    return OptionalType::get(unwrappedJoin);
+    return OptionalType::get(unwrappedJoin)->getCanonicalType();
   }
 
   // FIXME: More general joins of enums need to be handled.
   return First->getASTContext().TheAnyType;
 }
 
-Type TypeJoin::visitOptionalType(Type second) {
-  auto canFirst = First->getCanonicalType();
-  auto canSecond = second->getCanonicalType();
+Type Type::join(Type first, Type second) {
+  assert(first && second && "Unexpected null type!");
 
-  return TypeJoin::join(canFirst, canSecond);
-}
+  if (!first || !second) {
+    if (first)
+      return Type(ErrorType::get(first->getASTContext()));
 
-Type Type::join(Type type1, Type type2) {
-  assert(type1 && type2 && "Unexpected null type!");
+    if (second)
+      return Type(ErrorType::get(second->getASTContext()));
 
-  return TypeJoin::join(type1, type2);
+    return Type();
+  }
+
+  return TypeJoin::join(first->getCanonicalType(), second->getCanonicalType());
 }
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 66a8338..16f22e8 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -7654,7 +7654,7 @@
     (void) result;
   }
 
-  return std::move(builder).computeGenericSignature(SourceLoc());
+  return builder.computeGenericSignature(SourceLoc());
 }
 
 // Calculate the generic environment from an imported generic param list.
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index f6bba17..c9e3c12 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -619,21 +619,17 @@
 class TokenBasedRefactoringAction : public RefactoringAction {
 protected:
   ResolvedCursorInfo CursorInfo;
-  bool CanProceed;
 public:
   TokenBasedRefactoringAction(ModuleDecl *MD, RefactoringOptions &Opts,
                               SourceEditConsumer &EditConsumer,
                               DiagnosticConsumer &DiagConsumer) :
   RefactoringAction(MD, Opts, EditConsumer, DiagConsumer) {
     // We can only proceed with valid location and source file.
-    CanProceed = StartLoc.isValid() && TheFile;
-    if (!CanProceed)
-      return;
-
-    // Resolve the sema token and save it for later use.
-    CursorInfoResolver Resolver(*TheFile);
-    CursorInfo = Resolver.resolve(StartLoc);
-    CanProceed = CursorInfo.isValid();
+    if (StartLoc.isValid() && TheFile) {
+      // Resolve the sema token and save it for later use.
+      CursorInfoResolver Resolver(*TheFile);
+      CursorInfo = Resolver.resolve(StartLoc);
+    }
   }
 };
 
@@ -644,8 +640,11 @@
                           SourceEditConsumer &EditConsumer,                   \
                           DiagnosticConsumer &DiagConsumer) :                 \
     TokenBasedRefactoringAction(MD, Opts, EditConsumer, DiagConsumer) {}      \
-  static bool isApplicable(ResolvedCursorInfo Tok);                           \
   bool performChange() override;                                              \
+  static bool isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag);   \
+  bool isApplicable() {                                                       \
+    return RefactoringAction##KIND::isApplicable(CursorInfo, DiagEngine) ;    \
+  }                                                                           \
 };
 #include "swift/IDE/RefactoringKinds.def"
 
@@ -671,10 +670,14 @@
     RangeBasedRefactoringAction(MD, Opts, EditConsumer, DiagConsumer) {}      \
   bool performChange() override;                                              \
   static bool isApplicable(ResolvedRangeInfo Info, DiagnosticEngine &Diag);   \
+  bool isApplicable() {                                                       \
+    return RefactoringAction##KIND::isApplicable(RangeInfo, DiagEngine) ;     \
+  }                                                                           \
 };
 #include "swift/IDE/RefactoringKinds.def"
 
-bool RefactoringActionLocalRename::isApplicable(ResolvedCursorInfo CursorInfo) {
+bool RefactoringActionLocalRename::
+isApplicable(ResolvedCursorInfo CursorInfo, DiagnosticEngine &Diag) {
   if (CursorInfo.Kind != CursorInfoKind::ValueRef)
     return false;
   auto RenameOp = getAvailableRenameForDecl(CursorInfo.ValueD);
@@ -1036,8 +1039,6 @@
 }
 
 bool RefactoringActionExtractFunction::performChange() {
-  if (!isApplicable(RangeInfo, DiagEngine))
-    return true;
   // Check if the new name is ok.
   if (!Lexer::isIdentifier(PreferredName)) {
     DiagEngine.diagnose(SourceLoc(), diag::invalid_name, PreferredName);
@@ -1420,8 +1421,6 @@
 }
 
 bool RefactoringActionExtractExpr::performChange() {
-  if (!isApplicable(RangeInfo, DiagEngine))
-    return true;
   return RefactoringActionExtractExprBase(TheFile, RangeInfo,
                                           DiagEngine, false, PreferredName,
                                           EditConsumer).performChange();
@@ -1442,8 +1441,6 @@
   }
 }
 bool RefactoringActionExtractRepeatedExpr::performChange() {
-  if (!isApplicable(RangeInfo, DiagEngine))
-    return true;
   return RefactoringActionExtractExprBase(TheFile, RangeInfo,
                                           DiagEngine, true, PreferredName,
                                           EditConsumer).performChange();
@@ -1523,7 +1520,8 @@
   return Walker.IfInfo;
 }
 
-bool RefactoringActionCollapseNestedIfExpr::isApplicable(ResolvedCursorInfo Tok) {
+bool RefactoringActionCollapseNestedIfExpr::
+isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag) {
   return findCollapseNestedIfTarget(Tok).isValid();
 }
 
@@ -1752,22 +1750,17 @@
   return NonWitnessedReqs;
 }
 
-bool RefactoringActionFillProtocolStub::isApplicable(ResolvedCursorInfo Tok) {
+bool RefactoringActionFillProtocolStub::
+isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag) {
   return FillProtocolStubContext::getContextFromCursorInfo(Tok).canProceed();
 };
 
 bool RefactoringActionFillProtocolStub::performChange() {
-  // If the base class says no proceeding, respect it.
-  if (!CanProceed)
-    return true;
-
   // Get the filling protocol context from the input token.
   FillProtocolStubContext Context = FillProtocolStubContext::
-  getContextFromCursorInfo(CursorInfo);
+    getContextFromCursorInfo(CursorInfo);
 
-  // If the filling context disallows continue, abort.
-  if (!Context.canProceed())
-    return true;
+  assert(Context.canProceed());
   assert(!Context.getFillingContents().empty());
   assert(Context.getFillingContext());
   llvm::SmallString<128> Text;
@@ -1807,21 +1800,22 @@
   return collectAvailableRefactorings(SF, Tok, Scratch, /*Exclude rename*/false);
 }
 
-bool RefactoringActionExpandDefault::isApplicable(ResolvedCursorInfo CursorInfo) {
+bool RefactoringActionExpandDefault::
+isApplicable(ResolvedCursorInfo CursorInfo, DiagnosticEngine &Diag) {
+  auto Exit = [&](bool Applicable) {
+    if (!Applicable)
+      Diag.diagnose(SourceLoc(), diag::invalid_default_location);
+    return Applicable;
+  };
   if (CursorInfo.Kind != CursorInfoKind::StmtStart)
-    return false;
+    return Exit(false);
   if (auto *CS = dyn_cast<CaseStmt>(CursorInfo.TrailingStmt)) {
-    return CS->isDefault();
+    return Exit(CS->isDefault());
   }
-  return false;
+  return Exit(false);
 }
 
 bool RefactoringActionExpandDefault::performChange() {
-  if (!isApplicable(CursorInfo)) {
-    DiagEngine.diagnose(SourceLoc(), diag::invalid_default_location);
-    return true;
-  }
-
   // Try to find the switch statement enclosing the default statement.
   auto *CS = static_cast<CaseStmt*>(CursorInfo.TrailingStmt);
   auto IsSwitch = [](ASTNode Node) {
@@ -1911,7 +1905,8 @@
   return Walker.Target;
 }
 
-bool RefactoringActionLocalizeString::isApplicable(ResolvedCursorInfo Tok) {
+bool RefactoringActionLocalizeString::
+isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag) {
   return findLocalizeTarget(Tok);
 }
 
@@ -1954,7 +1949,8 @@
   return ConvertToCharRange(TargetNode.getSourceRange());
 }
 
-bool RefactoringActionConvertToDoCatch::isApplicable(ResolvedCursorInfo Tok) {
+bool RefactoringActionConvertToDoCatch::
+isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag) {
   if (!Tok.TrailingExpr)
     return false;
   return isa<ForceTryExpr>(Tok.TrailingExpr);
@@ -1962,8 +1958,7 @@
 
 bool RefactoringActionConvertToDoCatch::performChange() {
   auto *TryExpr = dyn_cast<ForceTryExpr>(CursorInfo.TrailingExpr);
-  if (!TryExpr)
-    return true;
+  assert(TryExpr);
   auto Range = findSourceRangeToWrapInCatch(CursorInfo, TheFile, SM);
   if (!Range.isValid())
     return true;
@@ -2042,7 +2037,7 @@
 }
 
 bool RefactoringActionSimplifyNumberLiteral::
-isApplicable(ResolvedCursorInfo Tok) {
+isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag) {
   if (auto *Literal = getTrailingNumberLiteral(Tok)) {
     llvm::SmallString<64> Buffer;
     llvm::raw_svector_ostream OS(Buffer);
@@ -2257,8 +2252,9 @@
       AllKinds.push_back(RenameOp.getValue());
     }
   }
+  DiagnosticEngine DiagEngine(SF->getASTContext().SourceMgr);
 #define CURSOR_REFACTORING(KIND, NAME, ID)                                     \
-  if (RefactoringAction##KIND::isApplicable(CursorInfo))                       \
+  if (RefactoringAction##KIND::isApplicable(CursorInfo, DiagEngine))           \
     AllKinds.push_back(RefactoringKind::KIND);
 #include "swift/IDE/RefactoringKinds.def"
 
@@ -2323,8 +2319,13 @@
 
   switch (Opts.Kind) {
 #define SEMANTIC_REFACTORING(KIND, NAME, ID)                                   \
-    case RefactoringKind::KIND: return RefactoringAction##KIND(M, Opts,        \
-      EditConsumer, DiagConsumer).performChange();
+case RefactoringKind::KIND: {                                                  \
+      RefactoringAction##KIND Action(M, Opts, EditConsumer, DiagConsumer);     \
+      if (RefactoringKind::KIND == RefactoringKind::LocalRename ||             \
+          Action.isApplicable())                                               \
+        return Action.performChange();                                         \
+      return true;                                                             \
+  }
 #include "swift/IDE/RefactoringKinds.def"
     case RefactoringKind::GlobalRename:
     case RefactoringKind::FindGlobalRenameRanges:
diff --git a/lib/IRGen/ClassMetadataVisitor.h b/lib/IRGen/ClassMetadataVisitor.h
index 7d70d2b..a6faa37 100644
--- a/lib/IRGen/ClassMetadataVisitor.h
+++ b/lib/IRGen/ClassMetadataVisitor.h
@@ -105,11 +105,6 @@
       }
     }
 
-    // Add a reference to the parent class, if applicable.
-    if (theClass->getDeclContext()->isTypeContext()) {
-      asImpl().addParentMetadataRef(theClass, type);
-    }
-
     // Add space for the generic parameters, if applicable.
     // Note that we only add references for the immediate parameters;
     // parameters for the parent context are handled by the parent.
@@ -161,7 +156,6 @@
   void addIVarDestroyer() { addPointer(); }
   void addValueWitnessTable() { addPointer(); }
   void addDestructorFunction() { addPointer(); }
-  void addParentMetadataRef(ClassDecl *forClass, Type classType) {addPointer();}
   void addSuperClass() { addPointer(); }
   void addClassFlags() { addInt32(); }
   void addInstanceAddressPoint() { addInt32(); }
diff --git a/lib/IRGen/EnumMetadataVisitor.h b/lib/IRGen/EnumMetadataVisitor.h
index 917c6ca..bc8334a 100644
--- a/lib/IRGen/EnumMetadataVisitor.h
+++ b/lib/IRGen/EnumMetadataVisitor.h
@@ -49,7 +49,6 @@
 
     // EnumMetadata header.
     asImpl().addNominalTypeDescriptor();
-    asImpl().addParentMetadataRef();
 
     // If changing this layout, you must update the magic number in
     // emitParentMetadataRef.
@@ -83,7 +82,6 @@
   void addMetadataFlags() { addPointer(); }
   void addValueWitnessTable() { addPointer(); }
   void addNominalTypeDescriptor() { addPointer(); }
-  void addParentMetadataRef() { addPointer(); }
   void addGenericArgument(CanType argument) { addPointer(); }
   void addGenericWitnessTable(CanType argument, ProtocolConformanceRef conf) {
     addPointer();
diff --git a/lib/IRGen/Fulfillment.cpp b/lib/IRGen/Fulfillment.cpp
index 449acb8..739b4f5 100644
--- a/lib/IRGen/Fulfillment.cpp
+++ b/lib/IRGen/Fulfillment.cpp
@@ -70,12 +70,12 @@
   case TypeKind::Tuple:
     return cast<TupleType>(type)->getNumElements() == 0;
 
-  // Nominal types might have parents.
+  // Nominal types might have generic parents.
   case TypeKind::Class:
   case TypeKind::Enum:
   case TypeKind::Protocol:
   case TypeKind::Struct:
-    return !cast<NominalType>(type)->getParent();
+    return !cast<NominalType>(type)->getDecl()->isGenericContext();
 
   // Bound generic types have type arguments.
   case TypeKind::BoundGenericClass:
@@ -125,14 +125,17 @@
     return hadFulfillment;
   }
 
+  if (keys.isInterestingType(type)) {
+    if (auto superclassTy = keys.getSuperclassBound(type)) {
+      return searchNominalTypeMetadata(IGM, superclassTy, source,
+                                       std::move(path), keys);
+    }
+  }
+
   // Inexact metadata will be a problem if we ever try to use this
   // to remember that we already have the metadata for something.
-  if (auto nomTy = dyn_cast<NominalType>(type)) {
-    return searchNominalTypeMetadata(IGM, nomTy, source, std::move(path), keys);
-  }
-  if (auto boundTy = dyn_cast<BoundGenericType>(type)) {
-    return searchBoundGenericTypeMetadata(IGM, boundTy, source,
-                                          std::move(path), keys);
+  if (isa<NominalType>(type) || isa<BoundGenericType>(type)) {
+    return searchNominalTypeMetadata(IGM, type, source, std::move(path), keys);
   }
 
   // TODO: tuples
@@ -203,47 +206,27 @@
 }
 
 
-bool FulfillmentMap::searchParentTypeMetadata(IRGenModule &IGM,
-                                              NominalTypeDecl *decl,
-                                              CanType parent,
-                                              unsigned source,
-                                              MetadataPath &&path,
-                                        const InterestingKeysCallback &keys) {
-  // We might not have a parent type.
-  if (!parent) return false;
-
-  // If we do, it has to be nominal one way or another.
-  path.addNominalParentComponent();
-  return searchTypeMetadata(IGM, parent, IsExact, source, std::move(path),keys);
-}
-
 bool FulfillmentMap::searchNominalTypeMetadata(IRGenModule &IGM,
-                                               CanNominalType type,
+                                               CanType type,
                                                unsigned source,
                                                MetadataPath &&path,
                                          const InterestingKeysCallback &keys) {
-  // Nominal types add no generic arguments themselves, but they
-  // may have the arguments of their parents.
-  return searchParentTypeMetadata(IGM, type->getDecl(), type.getParent(),
-                                  source, std::move(path), keys);
-}
-
-bool FulfillmentMap::searchBoundGenericTypeMetadata(IRGenModule &IGM,
-                                                    CanBoundGenericType type,
-                                                    unsigned source,
-                                                    MetadataPath &&path,
-                                         const InterestingKeysCallback &keys) {
   // Objective-C generics don't preserve their generic parameters at runtime,
   // so they aren't able to fulfill type metadata requirements.
-  if (type->getDecl()->hasClangNode()) {
+  if (type.getAnyNominal()->hasClangNode()) {
     return false;
   }
   
+  auto *nominal = type.getAnyNominal();
+  if (!nominal->isGenericContext() || isa<ProtocolDecl>(nominal)) {
+    return false;
+  }
+
   bool hadFulfillment = false;
 
-  GenericTypeRequirements requirements(IGM, type->getDecl());
+  GenericTypeRequirements requirements(IGM, nominal);
   requirements.enumerateFulfillments(
-      IGM, type->getContextSubstitutionMap(IGM.getSwiftModule(), type->getDecl()),
+      IGM, type->getContextSubstitutionMap(IGM.getSwiftModule(), nominal),
       [&](unsigned reqtIndex, CanType arg,
           Optional<ProtocolConformanceRef> conf) {
     // Skip uninteresting type arguments.
@@ -289,11 +272,6 @@
                          std::move(argPath), keys, interestingConformances);
   });
 
-  // Also match against the parent.  The polymorphic type
-  // will start with any arguments from the parent.
-  hadFulfillment |= searchParentTypeMetadata(IGM, type->getDecl(),
-                                             type.getParent(),
-                                             source, std::move(path), keys);
   return hadFulfillment;
 }
 
@@ -318,21 +296,6 @@
   }
 }
 
-bool FulfillmentMap::Everything::isInterestingType(CanType type) const {
-  return true;
-}
-bool FulfillmentMap::Everything::hasInterestingType(CanType type) const {
-  return true;
-}
-bool FulfillmentMap::Everything
-                   ::hasLimitedInterestingConformances(CanType type) const {
-  return false;
-}
-GenericSignature::ConformsToArray
-FulfillmentMap::Everything::getInterestingConformances(CanType type) const{
-  return {};
-}
-
 void FulfillmentMap::dump() const {
   auto &out = llvm::errs();
   for (auto &entry : Fulfillments) {
diff --git a/lib/IRGen/Fulfillment.h b/lib/IRGen/Fulfillment.h
index 82b66ba..65737b6 100644
--- a/lib/IRGen/Fulfillment.h
+++ b/lib/IRGen/Fulfillment.h
@@ -66,17 +66,10 @@
     virtual GenericSignature::ConformsToArray
       getInterestingConformances(CanType type) const = 0;
 
-    virtual ~InterestingKeysCallback() = default;
-  };
+    /// Return the limited interesting conformances for an interesting type.
+    virtual CanType getSuperclassBound(CanType type) const = 0;
 
-  /// An implementation of InterestingKeysCallback that returns everything
-  /// fulfillable.
-  struct Everything : InterestingKeysCallback {
-    bool isInterestingType(CanType type) const override;
-    bool hasInterestingType(CanType type) const override;
-    bool hasLimitedInterestingConformances(CanType type) const override;
-    GenericSignature::ConformsToArray
-      getInterestingConformances(CanType type) const override;
+    virtual ~InterestingKeysCallback() = default;
   };
 
   FulfillmentMap() = default;
@@ -140,19 +133,10 @@
   }
 
 private:
-  bool searchParentTypeMetadata(IRGenModule &IGM, NominalTypeDecl *typeDecl,
-                                CanType parent,
-                                unsigned source, MetadataPath &&path,
-                                const InterestingKeysCallback &keys);
-
-  bool searchNominalTypeMetadata(IRGenModule &IGM, CanNominalType type,
+  bool searchNominalTypeMetadata(IRGenModule &IGM, CanType type,
                                  unsigned source, MetadataPath &&path,
                                  const InterestingKeysCallback &keys);
 
-  bool searchBoundGenericTypeMetadata(IRGenModule &IGM, CanBoundGenericType type,
-                                      unsigned source, MetadataPath &&path,
-                                      const InterestingKeysCallback &keys);
-
   /// Search the given witness table for useful fulfillments.
   ///
   /// \return true if any fulfillments were added by this search.
@@ -168,5 +152,3 @@
 }
 
 #endif
-
-
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index c2bea3e..fdd329d 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2561,8 +2561,9 @@
                                            NominalTypeDecl *nominal,
                                            ArrayRef<llvm::Type *> genericArgs,
                                            ForDefinition_t forDefinition) {
-  assert(!genericArgs.empty());
   assert(nominal->isGenericContext());
+  assert(!genericArgs.empty() ||
+         nominal->getGenericSignature()->areAllParamsConcrete());
   IRGen.addLazyTypeMetadata(nominal);
 
   auto type = nominal->getDeclaredType()->getCanonicalType();
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index c9dc1ca..2219b15 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -142,8 +142,7 @@
     static unsigned getNumGenericArguments(IRGenModule &IGM,
                                            NominalTypeDecl *nominal) {
       GenericTypeRequirements requirements(IGM, nominal);
-      return unsigned(requirements.hasParentType())
-               + requirements.getNumTypeRequirements();
+      return requirements.getNumTypeRequirements();
     }
 
     void collectTypes(IRGenModule &IGM, NominalTypeDecl *nominal) {
@@ -153,10 +152,6 @@
 
     void collectTypes(IRGenModule &IGM,
                       const GenericTypeRequirements &requirements) {
-      if (requirements.hasParentType()) {
-        Types.push_back(IGM.TypeMetadataPtrTy);
-      }
-
       for (auto &requirement : requirements.getRequirements()) {
         if (requirement.Protocol) {
           Types.push_back(IGM.WitnessTablePtrTy);
@@ -181,10 +176,6 @@
 
       GenericTypeRequirements requirements(IGF.IGM, decl);
 
-      if (requirements.hasParentType()) {
-        Values.push_back(IGF.emitTypeMetadataRef(parentType));
-      }
-
       auto subs =
         type->getContextSubstitutionMap(IGF.IGM.getSwiftModule(), decl);
       requirements.enumerateFulfillments(IGF.IGM, subs,
@@ -217,14 +208,6 @@
              ->getCanonicalType();
   };
 
-  // If we have a parent type, it's the first parameter.
-  if (requirements.hasParentType()) {
-    auto parentType = getInContext(requirements.getParentType());
-    llvm::Value *parentMetadata = IGF.Builder.CreateLoad(array);
-    array = IGF.Builder.CreateConstArrayGEP(array, 1, IGF.IGM.getPointerSize());
-    IGF.bindLocalTypeDataFromTypeMetadata(parentType, IsExact, parentMetadata);
-  }
-
   // Okay, bind everything else from the context.
   requirements.bindFromBuffer(IGF, array, getInContext);
 }
@@ -372,7 +355,9 @@
   // Grab the substitutions.
   GenericArguments genericArgs;
   genericArgs.collect(IGF, theType);
-  assert(genericArgs.Values.size() > 0 && "no generic args?!");
+  assert((genericArgs.Values.size() > 0 ||
+          theDecl->getGenericSignature()->areAllParamsConcrete())
+         && "no generic args?!");
 
   // Call the generic metadata accessor function.
   llvm::Function *accessor =
@@ -1147,7 +1132,9 @@
   for (auto &arg : IGF.CurFn->args())
     genericArgs.Values.push_back(&arg);
   assert(genericArgs.Values.size() == genericArgs.Types.size());
-  assert(genericArgs.Values.size() > 0 && "no generic args?!");
+  assert((genericArgs.Values.size() > 0 ||
+          nominal->getGenericSignature()->areAllParamsConcrete())
+         && "no generic args?!");
 
   // Slam that information directly into the generic arguments buffer.
   auto argsBufferTy =
@@ -2184,23 +2171,58 @@
 
       // GenericParameterDescriptorFlags Flags;
       GenericParameterDescriptorFlags flags;
-      if (ntd->getDeclContext()->isTypeContext())
-        flags = flags.withHasParent(true);
-      if (requirements.hasParentType())
-        flags = flags.withHasGenericParent(true);
       if (auto *cd = dyn_cast<ClassDecl>(ntd)) {
         auto &layout = IGM.getMetadataLayout(cd);
         if (layout.getVTableSize() > 0)
           flags = flags.withHasVTable(true);
       }
-      B.addInt32(flags.getIntValue());
+
+      // Calculate the number of generic parameters at each nesting depth.
+      unsigned totalGenericParams = 0;
+      SmallVector<unsigned, 2> numPrimaryParams;
+      for (auto *outer = ntd; outer != nullptr;
+           outer = outer->getDeclContext()
+               ->getAsNominalTypeOrNominalTypeExtensionContext()) {
+        unsigned genericParamsAtDepth = 0;
+        if (auto *genericParams = outer->getGenericParams()) {
+          for (auto *paramDecl : *genericParams) {
+            auto contextTy = ntd->mapTypeIntoContext(
+                paramDecl->getDeclaredInterfaceType());
+            // Skip parameters which have been made concrete, because they do
+            // not appear in type metadata.
+            //
+            // FIXME: We should emit information about same-type constraints
+            // as well as conformance constraints, so that clients can
+            // reconstruct the full generic signature of the type, including
+            // fully-concrete parameters.
+            if (contextTy->is<ArchetypeType>()) {
+              totalGenericParams++;
+              genericParamsAtDepth++;
+            }
+          }
+        }
+        numPrimaryParams.push_back(genericParamsAtDepth);
+      }
+
+      // This assertion will fail once we have generic types nested
+      // inside generic functions or other local generic contexts.
+      assert(totalGenericParams == requirements.getNumTypeRequirements());
+
+      // Emit the nesting depth.
+      B.addInt16(numPrimaryParams.size());
+
+      // Emit the flags.
+      B.addInt16(flags.getIntValue());
+
+      // Emit the number of generic parameters at each nesting depth.
+      std::reverse(numPrimaryParams.begin(), numPrimaryParams.end());
+      for (auto count : numPrimaryParams)
+        B.addInt32(count);
 
       // TODO: provide reflective descriptions of the type and
       // conformance requirements stored here.
-
-      // };
     }
-    
+
     llvm::Constant *emit() {
       asImpl().layout();
 
@@ -3487,7 +3509,6 @@
     using super = ClassMetadataBuilderBase<ClassMetadataBuilder>;
 
     bool HasUnfilledSuperclass = false;
-    bool HasUnfilledParent = false;
 
     Size AddressPoint;
 
@@ -3534,22 +3555,6 @@
       }
     }
 
-    void addParentMetadataRef(ClassDecl *forClass, Type classType) {
-      CanType parentType = classType->getCanonicalType().getNominalParent();
-
-      if (auto metadata =
-            tryEmitConstantTypeMetadataRef(IGM, parentType,
-                                           SymbolReferenceKind::Absolute)) {
-        B.add(metadata.getValue());
-      } else {
-        // Leave a null pointer placeholder to be filled by in-place
-        // initialization.
-        B.addNullPointer(IGM.TypeMetadataPtrTy);
-        if (forClass == Target)
-          HasUnfilledParent = true;
-      }
-    }
-
     bool canBeConstant() {
       // TODO: the metadata global can actually be constant in a very
       // special case: it's not a pattern, ObjC interoperation isn't
@@ -3566,7 +3571,7 @@
       [&](IRGenFunction &IGF, llvm::Constant *cacheVar) -> llvm::Value* {
         // There's an interesting special case where we can do the
         // initialization idempotently and thus avoid the need for a lock.
-        if (!HasUnfilledSuperclass && !HasUnfilledParent &&
+        if (!HasUnfilledSuperclass &&
             isFinishInitializationIdempotent()) {
           auto type = Target->getDeclaredType()->getCanonicalType();
           auto metadata =
@@ -3604,18 +3609,6 @@
         IGF.Builder.CreateStore(superclassMetadata, superField);
       }
 
-      // Initialize the class's own parent pointer if it has one and it
-      // wasn't emitted as a constant.
-      if (HasUnfilledParent) {
-        auto parentType = type.getParent();
-        assert(parentType);
-        llvm::Value *parentMetadata = IGF.emitTypeMetadataRef(parentType);
-
-        auto parentSlot =
-          emitAddressOfParentMetadataSlot(IGF, metadata, type->getDecl());
-        IGF.Builder.CreateStore(parentMetadata, parentSlot);
-      }
-
       metadata = emitFinishInitializationOfClassMetadata(IGF, metadata);
 
       return metadata;
@@ -3647,12 +3640,6 @@
       HasDependentMetadata = true;
     }
 
-    void addParentMetadataRef(ClassDecl *forClass, Type classType) {
-      CanType parentType = classType->getCanonicalType().getNominalParent();
-      this->addFillOp(parentType, None, /*relative*/ false);
-      B.addNullPointer(IGM.TypeMetadataPtrTy);
-    }
-
     void addSuperClass() {
       // Filled in by the runtime.
       B.addNullPointer(IGM.TypeMetadataPtrTy);
@@ -4362,71 +4349,13 @@
 // Value types (structs and enums)
 //===----------------------------------------------------------------------===//
 
-namespace {
-  template <class Impl, class Base>
-  class ValueTypeMetadataBuilderBase : public Base {
-    using super = Base;
-
-  protected:
-    using super::asImpl;
-    using super::IGM;
-    using super::Target;
-    ConstantStructBuilder &B;
-
-    template <class DeclTy>
-    ValueTypeMetadataBuilderBase(IRGenModule &IGM, DeclTy *theDecl,
-                                 ConstantStructBuilder &B)
-      : super(IGM, theDecl), B(B) {}
-
-    CanType getParentType() const {
-      Type type = Target->getDeclaredTypeInContext();
-      Type parentType = type->getNominalParent();
-      if (parentType)
-        return parentType->getCanonicalType();
-      return CanType();
-    }
-
-  public:
-    void addParentMetadataRef() {
-      llvm::Constant *parentMetadata = nullptr;
-      if (auto parentType = getParentType()) {
-        parentMetadata =
-          tryEmitConstantTypeMetadataRef(IGM, parentType,
-                                         SymbolReferenceKind::Absolute)
-            .getDirectValue();
-        if (!parentMetadata) {
-          asImpl().flagUnfilledParent();
-        }
-      }
-
-      if (!parentMetadata)
-        parentMetadata = llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy);
-      B.add(parentMetadata);
-    }
-  };
-} // end anonymous namespace
-
 static llvm::Value *
 emitInPlaceValueTypeMetadataInitialization(IRGenFunction &IGF,
                                            CanNominalType type,
-                                           llvm::Value *metadata,
-                                           bool hasUnfilledParent) {
+                                           llvm::Value *metadata) {
   // All the value types are basically similar.
   assert(isa<StructType>(type) || isa<EnumType>(type));
 
-  // Initialize the parent-metadata field if it wasn't done statically.
-  if (hasUnfilledParent) {
-    CanType parentType = type.getParent();
-    assert(parentType);
-
-    // Value types hold the parent metadata as a far relative
-    // indirectable pointer.
-    llvm::Value *parentMetadata = IGF.emitTypeMetadataRef(parentType);
-    Address addr =
-      emitAddressOfParentMetadataSlot(IGF, metadata, type->getDecl());
-    IGF.Builder.CreateStore(parentMetadata, addr);
-  }
-
   // Set up the value witness table if it's dependent.
   SILType loweredType = IGF.IGM.getLoweredType(AbstractionPattern(type), type);
   auto &ti = IGF.IGM.getTypeInfo(loweredType);
@@ -4445,8 +4374,7 @@
 /// Create an access function for the type metadata of the given
 /// non-generic nominal type.
 static void createInPlaceValueTypeMetadataAccessFunction(IRGenModule &IGM,
-                                                      NominalTypeDecl *typeDecl,
-                                                      bool hasUnfilledParent) {
+                                                      NominalTypeDecl *typeDecl) {
   assert(!typeDecl->isGenericContext());
   auto type =
     cast<NominalType>(typeDecl->getDeclaredType()->getCanonicalType());
@@ -4456,8 +4384,7 @@
                                            llvm::Constant *cacheVariable) {
     return emitInPlaceTypeMetadataAccessFunctionBody(IGF, type, cacheVariable,
       [&](IRGenFunction &IGF, llvm::Value *metadata) {
-        return emitInPlaceValueTypeMetadataInitialization(IGF, type, metadata,
-                                                          hasUnfilledParent);
+        return emitInPlaceValueTypeMetadataInitialization(IGF, type, metadata);
       });
   });
 }
@@ -4469,19 +4396,18 @@
 namespace {
   /// An adapter for laying out struct metadata.
   template <class Impl>
-  class StructMetadataBuilderBase
-         : public ValueTypeMetadataBuilderBase<Impl,StructMetadataVisitor<Impl>>{
-    using super = ValueTypeMetadataBuilderBase<Impl,StructMetadataVisitor<Impl>>;
+  class StructMetadataBuilderBase : public StructMetadataVisitor<Impl> {
+    using super = StructMetadataVisitor<Impl>;
 
   protected:
+    ConstantStructBuilder &B;
     using super::IGM;
     using super::Target;
     using super::asImpl;
-    using super::B;
 
     StructMetadataBuilderBase(IRGenModule &IGM, StructDecl *theStruct,
                               ConstantStructBuilder &B)
-      : super(IGM, theStruct, B) {
+      : super(IGM, theStruct), B(B) {
     }
 
   public:
@@ -4525,23 +4451,18 @@
   class StructMetadataBuilder :
     public StructMetadataBuilderBase<StructMetadataBuilder> {
 
-    bool HasUnfilledParent = false;
     bool HasUnfilledFieldOffset = false;
   public:
     StructMetadataBuilder(IRGenModule &IGM, StructDecl *theStruct,
                           ConstantStructBuilder &B)
       : StructMetadataBuilderBase(IGM, theStruct, B) {}
 
-    void flagUnfilledParent() {
-      HasUnfilledParent = true;
-    }
-
     void flagUnfilledFieldOffset() {
       HasUnfilledFieldOffset = true;
     }
 
     bool canBeConstant() {
-      return !HasUnfilledParent && !HasUnfilledFieldOffset;
+      return !HasUnfilledFieldOffset;
     }
 
     void addValueWitnessTable() {
@@ -4550,8 +4471,7 @@
     }
 
     void createMetadataAccessFunction() {
-      createInPlaceValueTypeMetadataAccessFunction(IGM, Target,
-                                                   HasUnfilledParent);
+      createInPlaceValueTypeMetadataAccessFunction(IGM, Target);
     }
   };
   
@@ -4591,15 +4511,6 @@
                                     {metadataPattern, arguments});
     }
 
-    void addParentMetadataRef() {
-      // Override to always use a fill op instead of a relocation.
-      if (CanType parentType = getParentType()) {
-        addFillOp(parentType, None, /*relative*/ false);
-      }
-
-      B.addInt(IGM.IntPtrTy, 0);
-    }
-
     void flagUnfilledFieldOffset() {
       // We just assume this might happen.
     }
@@ -4665,19 +4576,18 @@
 namespace {
 
 template<class Impl>
-class EnumMetadataBuilderBase
-       : public ValueTypeMetadataBuilderBase<Impl, EnumMetadataVisitor<Impl>> {
-  using super = ValueTypeMetadataBuilderBase<Impl, EnumMetadataVisitor<Impl>>;
+class EnumMetadataBuilderBase : public EnumMetadataVisitor<Impl> {
+  using super = EnumMetadataVisitor<Impl>;
 
 protected:
+  ConstantStructBuilder &B;
   using super::IGM;
   using super::Target;
-  using super::B;
 
 public:
   EnumMetadataBuilderBase(IRGenModule &IGM, EnumDecl *theEnum,
                           ConstantStructBuilder &B)
-  : super(IGM, theEnum, B) {
+  : super(IGM, theEnum), B(B) {
   }
   
   void addMetadataFlags() {
@@ -4705,7 +4615,6 @@
   
 class EnumMetadataBuilder
   : public EnumMetadataBuilderBase<EnumMetadataBuilder> {
-  bool HasUnfilledParent = false;
   bool HasUnfilledPayloadSize = false;
 
 public:
@@ -4733,17 +4642,12 @@
     B.addInt(IGM.IntPtrTy, strategy.getPayloadSizeForMetadata());
   }
 
-  void flagUnfilledParent() {
-    HasUnfilledParent = true;
-  }
-
   bool canBeConstant() {
-    return !HasUnfilledParent && !HasUnfilledPayloadSize;
+    return !HasUnfilledPayloadSize;
   }
 
   void createMetadataAccessFunction() {
-    createInPlaceValueTypeMetadataAccessFunction(IGM, Target,
-                                                 HasUnfilledParent);
+    createInPlaceValueTypeMetadataAccessFunction(IGM, Target);
   }
 };
   
@@ -4763,15 +4667,6 @@
                                   {metadataPattern, arguments});
   }
 
-  void addParentMetadataRef() {
-    // Override to always use a fill op instead of a relocation.
-    if (CanType parentType = getParentType()) {
-      addFillOp(parentType, None, /*relative*/ false);
-    }
-
-    B.addInt(IGM.IntPtrTy, 0);
-  }
-  
   void addValueWitnessTable() {
     B.add(getValueWitnessTableForGenericValueType(IGM, Target,
                                                   HasDependentVWT));
@@ -4905,14 +4800,6 @@
 
     Size AddressPoint = Size::invalid();
 
-    bool computeUnfilledParent() {
-      if (auto parentType = asImpl().getTargetType().getNominalParent()) {
-        return !tryEmitConstantTypeMetadataRef(IGM, parentType,
-                                               SymbolReferenceKind::Absolute);
-      }
-      return false;
-    }
-
   public:
     void layout() {
       if (asImpl().requiresInitializationFunction())
@@ -5027,41 +4914,25 @@
     public ForeignMetadataBuilderBase<ForeignStructMetadataBuilder,
                       StructMetadataBuilderBase<ForeignStructMetadataBuilder>>
   {
-    bool HasUnfilledParent = false;
   public:
     ForeignStructMetadataBuilder(IRGenModule &IGM, StructDecl *target,
                                  ConstantStructBuilder &builder)
-        : ForeignMetadataBuilderBase(IGM, target, builder) {
-      HasUnfilledParent = computeUnfilledParent();
-    }
+        : ForeignMetadataBuilderBase(IGM, target, builder) {}
     
     CanType getTargetType() const {
       return Target->getDeclaredType()->getCanonicalType();
     }
 
     bool requiresInitializationFunction() const {
-      return HasUnfilledParent;
+      return false;
     }
-    void emitInitialization(IRGenFunction &IGF, llvm::Value *metadata) {
-      if (HasUnfilledParent) {
-        auto parentType = getTargetType().getNominalParent();
-        auto parentMetadata = IGF.emitTypeMetadataRef(parentType);
-
-        Address slot =
-          emitAddressOfParentMetadataSlot(IGF, metadata, this->Target);
-        IGF.Builder.CreateStore(parentMetadata, slot);
-      }
-    }
+    void emitInitialization(IRGenFunction &IGF, llvm::Value *metadata) {}
 
     void addValueWitnessTable() {
       auto type = this->Target->getDeclaredType()->getCanonicalType();
       B.add(emitValueWitnessTable(IGM, type));
     }
 
-    void flagUnfilledParent() {
-      assert(HasUnfilledParent);
-    }
-
     void flagUnfilledFieldOffset() {
       llvm_unreachable("foreign type with non-fixed layout?");
     }
@@ -5072,31 +4943,19 @@
     public ForeignMetadataBuilderBase<ForeignEnumMetadataBuilder,
                       EnumMetadataBuilderBase<ForeignEnumMetadataBuilder>>
   {
-    bool HasUnfilledParent = false;
   public:
     ForeignEnumMetadataBuilder(IRGenModule &IGM, EnumDecl *target,
                                ConstantStructBuilder &builder)
-      : ForeignMetadataBuilderBase(IGM, target, builder) {
-      HasUnfilledParent = computeUnfilledParent();
-    }
+      : ForeignMetadataBuilderBase(IGM, target, builder) {}
     
     CanType getTargetType() const {
       return Target->getDeclaredType()->getCanonicalType();
     }
 
     bool requiresInitializationFunction() const {
-      return HasUnfilledParent;
+      return false;
     }
-    void emitInitialization(IRGenFunction &IGF, llvm::Value *metadata) {
-      if (HasUnfilledParent) {
-        auto parentType = getTargetType().getNominalParent();
-        auto parentMetadata = IGF.emitTypeMetadataRef(parentType);
-
-        Address slot =
-          emitAddressOfParentMetadataSlot(IGF, metadata, this->Target);
-        IGF.Builder.CreateStore(parentMetadata, slot);
-      }
-    }
+    void emitInitialization(IRGenFunction &IGF, llvm::Value *metadata) {}
 
     void addValueWitnessTable() {
       auto type = this->Target->getDeclaredType()->getCanonicalType();
@@ -5106,10 +4965,6 @@
     void addPayloadSize() const {
       llvm_unreachable("nongeneric enums shouldn't need payload size in metadata");
     }
-
-    void flagUnfilledParent() {
-      assert(HasUnfilledParent);
-    }
   };
 } // end anonymous namespace
 
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 7ddf897..3982e34 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -95,6 +95,12 @@
     return Generics->getConformsTo(t, M);
   }
 
+  CanType getSuperclassBound(Type t) {
+    if (auto superclassTy = Generics->getSuperclassBound(t, M))
+      return superclassTy->getCanonicalType();
+    return CanType();
+  }
+
 public:
   PolymorphicConvention(IRGenModule &IGM, CanSILFunctionType fnType);
 
@@ -291,6 +297,9 @@
     getInterestingConformances(CanType type) const override {
       return Self.getConformsTo(type);
     }
+    CanType getSuperclassBound(CanType type) const override {
+      return Self.getSuperclassBound(type);
+    }
   } callbacks(*this);
   return Fulfillments.searchTypeMetadata(IGM, type, isExact, sourceIndex,
                                          std::move(path), callbacks);
@@ -367,6 +376,15 @@
         return;
       }
 
+      if (isa<GenericTypeParamType>(type)) {
+        if (auto superclassTy = getSuperclassBound(type)) {
+          considerNewTypeSource(MetadataSource::Kind::ClassPointer,
+                                paramIndex, superclassTy, IsInexact);
+          return;
+
+        }
+      }
+
       // Thick metatypes are sources of metadata.
       if (auto metatypeTy = dyn_cast<MetatypeType>(type)) {
         if (metatypeTy->getRepresentation() != MetatypeRepresentation::Thick)
@@ -1284,6 +1302,11 @@
           getInterestingConformances(CanType type) const override {
             llvm_unreachable("no limits");
           }
+          CanType getSuperclassBound(CanType type) const override {
+            if (auto superclassTy = cast<ArchetypeType>(type)->getSuperclass())
+              return superclassTy->getCanonicalType();
+            return CanType();
+          }
         } callback;
         Fulfillments->searchTypeMetadata(IGM, ConcreteType, IsExact,
                                          /*sourceIndex*/ 0, MetadataPath(),
@@ -2023,15 +2046,17 @@
   case Component::Kind::NominalTypeArgument:
   case Component::Kind::NominalTypeArgumentConformance: {
     assert(sourceKey.Kind == LocalTypeDataKind::forTypeMetadata());
-    auto generic = cast<BoundGenericType>(sourceKey.Type);
+    auto type = sourceKey.Type;
+    if (auto archetypeTy = dyn_cast<ArchetypeType>(type))
+      type = archetypeTy->getSuperclass()->getCanonicalType();
+    auto *nominal = type.getAnyNominal();
     auto reqtIndex = component.getPrimaryIndex();
 
-    GenericTypeRequirements requirements(IGF.IGM, generic->getDecl());
+    GenericTypeRequirements requirements(IGF.IGM, nominal);
     auto &requirement = requirements.getRequirements()[reqtIndex];
 
     auto module = IGF.getSwiftModule();
-    auto subs = generic->getContextSubstitutionMap(module,
-                                                   generic->getDecl());
+    auto subs = sourceKey.Type->getContextSubstitutionMap(module, nominal);
     auto sub = requirement.TypeParameter.subst(subs)->getCanonicalType();
 
     // In either case, we need to change the type.
@@ -2041,7 +2066,7 @@
     if (component.getKind() == Component::Kind::NominalTypeArgument) {
       assert(!requirement.Protocol && "index mismatch!");
       if (source) {
-        source = emitArgumentMetadataRef(IGF, generic->getDecl(),
+        source = emitArgumentMetadataRef(IGF, nominal,
                                          requirements, reqtIndex, source);
         setTypeMetadataName(IGF.IGM, source, sourceKey.Type);
       }
@@ -2057,7 +2082,7 @@
 
       if (source) {
         auto protocol = conformance.getRequirement();
-        source = emitArgumentWitnessTableRef(IGF, generic->getDecl(),
+        source = emitArgumentWitnessTableRef(IGF, nominal,
                                              requirements, reqtIndex, source);
         setProtocolWitnessTableName(IGF.IGM, source, sourceKey.Type, protocol);
       }
@@ -2066,25 +2091,6 @@
     return source;
   }
 
-  case Component::Kind::NominalParent: {
-    assert(sourceKey.Kind == LocalTypeDataKind::forTypeMetadata());
-    NominalTypeDecl *nominalDecl;
-    if (auto nominal = dyn_cast<NominalType>(sourceKey.Type)) {
-      nominalDecl = nominal->getDecl();
-      sourceKey.Type = nominal.getParent();
-    } else {
-      auto generic = cast<BoundGenericType>(sourceKey.Type);
-      nominalDecl = generic->getDecl();
-      sourceKey.Type = generic.getParent();
-    }
-
-    if (source) {
-      source = emitParentMetadataRef(IGF, nominalDecl, source);
-      setTypeMetadataName(IGF.IGM, source, sourceKey.Type);
-    }
-    return source;
-  }
-
   case Component::Kind::OutOfLineBaseProtocol: {
     auto conformance = sourceKey.Kind.getProtocolConformance();
     auto protocol = conformance.getRequirement();
@@ -2184,9 +2190,6 @@
       out << "nominal_type_argument_conformance["
           << component.getPrimaryIndex() << "]";
       break;
-    case Component::Kind::NominalParent:
-      out << "nominal_parent";
-      break;
     case Component::Kind::Impossible:
       out << "impossible";
       break;
@@ -2573,28 +2576,9 @@
   // Construct a representative function type.
   auto generics = ncGenerics->getCanonicalSignature();
   CanSILFunctionType fnType = [&]() -> CanSILFunctionType {
-    CanType type = typeDecl->getDeclaredInterfaceType()->getCanonicalType();
-    if (auto nominal = dyn_cast<NominalType>(type)) {
-      ParentType = nominal.getParent();
-    } else {
-      ParentType = cast<BoundGenericType>(type).getParent();
-    }
-
-    // Ignore the existence of the parent type if it has no type parameters.
-    if (ParentType && !ParentType->hasTypeParameter())
-      ParentType = CanType();
-
-    SmallVector<SILParameterInfo, 1> params;
-    if (ParentType) {
-      auto parentMetatype =
-        CanMetatypeType::get(ParentType, MetatypeRepresentation::Thick);
-      params.push_back(SILParameterInfo(parentMetatype,
-                                        ParameterConvention::Direct_Unowned));
-    }
-
     return SILFunctionType::get(generics, SILFunctionType::ExtInfo(),
                                 /*callee*/ ParameterConvention::Direct_Unowned,
-                                params, /*results*/ {}, /*error*/ None,
+                                /*params*/ {}, /*results*/ {}, /*error*/ None,
                                 IGM.Context);
   }();
 
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index 98ece80..f282d27 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -71,12 +71,6 @@
     OS << '_';
   }
 
-  void visitParentMetadataSource(const ParentMetadataSource *P) {
-    OS << 'P';
-    visit(P->getChild());
-    OS << '_';
-  }
-
   void visitSelfMetadataSource(const SelfMetadataSource *S) {
     OS << 'S';
   }
@@ -158,13 +152,6 @@
   }
 
   void
-  visitParentMetadataSource(const ParentMetadataSource *P) {
-    printHeader("parent-of");
-    printRec(P->getChild());
-    closeForm();
-  }
-
-  void
   visitSelfMetadataSource(const SelfMetadataSource *S) {
     printHeader("self");
     closeForm();
diff --git a/lib/IRGen/GenericRequirement.h b/lib/IRGen/GenericRequirement.h
index 9839224..48cdccd 100644
--- a/lib/IRGen/GenericRequirement.h
+++ b/lib/IRGen/GenericRequirement.h
@@ -97,7 +97,6 @@
 /// anything fulfillable from its parent type metadata).
 class GenericTypeRequirements {
   NominalTypeDecl *TheDecl;
-  CanType ParentType;
   llvm::SmallVector<GenericRequirement, 4> Requirements;
 
 public:
@@ -108,15 +107,6 @@
     return Requirements;
   }
 
-  /// Does this generic type have 
-  bool hasParentType() const {
-    return bool(ParentType);
-  }
-
-  CanType getParentType() const {
-    return ParentType;
-  }
-
   /// Return the number of entries required in order to store this data.
   unsigned getStorageSizeInWords() const {
     return Requirements.size();
diff --git a/lib/IRGen/LocalTypeData.cpp b/lib/IRGen/LocalTypeData.cpp
index 3deddfb..fe2fc05 100644
--- a/lib/IRGen/LocalTypeData.cpp
+++ b/lib/IRGen/LocalTypeData.cpp
@@ -254,12 +254,34 @@
                                                     CanType type,
                                                     IsExact_t isExact,
                                                     llvm::Value *metadata) {
+  struct Callback : FulfillmentMap::InterestingKeysCallback {
+    bool isInterestingType(CanType type) const override {
+      return true;
+    }
+    bool hasInterestingType(CanType type) const override {
+      return true;
+    }
+    bool hasLimitedInterestingConformances(CanType type) const override {
+      return false;
+    }
+    GenericSignature::ConformsToArray
+    getInterestingConformances(CanType type) const override {
+      llvm_unreachable("no limits");
+    }
+    CanType getSuperclassBound(CanType type) const override {
+      if (auto arch = dyn_cast<ArchetypeType>(type))
+        if (auto superclassTy = arch->getSuperclass())
+          return superclassTy->getCanonicalType();
+      return CanType();
+    }
+  } callbacks;
+
   // Look for anything at all that's fulfilled by this.  If we don't find
   // anything, stop.
   FulfillmentMap fulfillments;
   if (!fulfillments.searchTypeMetadata(IGF.IGM, type, isExact,
                                        /*source*/ 0, MetadataPath(),
-                                       FulfillmentMap::Everything())) {
+                                       callbacks)) {
     return;
   }
 
diff --git a/lib/IRGen/MetadataLayout.cpp b/lib/IRGen/MetadataLayout.cpp
index 8fde127..fcda034 100644
--- a/lib/IRGen/MetadataLayout.cpp
+++ b/lib/IRGen/MetadataLayout.cpp
@@ -126,12 +126,6 @@
 
 /******************************* NOMINAL TYPES ********************************/
 
-Offset NominalMetadataLayout::getParentOffset(IRGenFunction &IGF) const {
-  assert(Parent.isValid());
-  assert(Parent.isStatic() && "resilient metadata layout unsupported!");
-  return Offset(Parent.getStaticOffset());
-}
-
 Size
 NominalMetadataLayout::getStaticGenericRequirementsOffset() const {
   assert(GenericRequirements.isValid());
@@ -146,24 +140,6 @@
   return Offset(GenericRequirements.getStaticOffset());
 }
 
-/// Given a reference to some metadata, derive a reference to the
-/// type's parent type.
-llvm::Value *irgen::emitParentMetadataRef(IRGenFunction &IGF,
-                                          NominalTypeDecl *decl,
-                                          llvm::Value *metadata) {
-  auto slot = emitAddressOfParentMetadataSlot(IGF, metadata, decl);
-  return IGF.emitInvariantLoad(slot);
-}
-
-Address irgen::emitAddressOfParentMetadataSlot(IRGenFunction &IGF,
-                                               llvm::Value *metadata,
-                                               NominalTypeDecl *decl) {
-  auto offset = IGF.IGM.getMetadataLayout(decl).getParentOffset(IGF);
-  return IGF.emitAddressAtOffset(metadata, offset,
-                                 IGF.IGM.TypeMetadataPtrTy,
-                                 IGF.IGM.getPointerAlignment());
-}
-
 static llvm::Value *emitLoadOfGenericRequirement(IRGenFunction &IGF,
                                                  llvm::Value *metadata,
                                                  NominalTypeDecl *decl,
@@ -246,12 +222,6 @@
       super::addInstanceAlignMask();
     }
 
-    void addParentMetadataRef(ClassDecl *forClass, Type classType) {
-      if (forClass == Target)
-        Layout.Parent = getNextOffset();
-      super::addParentMetadataRef(forClass, classType);
-    }
-
     void noteStartOfGenericRequirements(ClassDecl *forClass) {
       if (forClass == Target)
         Layout.GenericRequirements = getNextOffset();
@@ -404,11 +374,6 @@
       super::addPayloadSize();
     }
 
-    void addParentMetadataRef() {
-      Layout.Parent = getNextOffset();
-      super::addParentMetadataRef();
-    }
-
     void noteStartOfGenericRequirements() {
       Layout.GenericRequirements = getNextOffset();
       super::noteStartOfGenericRequirements();
@@ -441,11 +406,6 @@
     Scanner(IRGenModule &IGM, StructDecl *decl, StructMetadataLayout &layout)
       : super(IGM, decl), Layout(layout) {}
 
-    void addParentMetadataRef() {
-      Layout.Parent = getNextOffset();
-      super::addParentMetadataRef();
-    }
-
     void noteStartOfGenericRequirements() {
       Layout.GenericRequirements = getNextOffset();
       super::noteStartOfGenericRequirements();
diff --git a/lib/IRGen/MetadataLayout.h b/lib/IRGen/MetadataLayout.h
index 1c817ad..42ec292 100644
--- a/lib/IRGen/MetadataLayout.h
+++ b/lib/IRGen/MetadataLayout.h
@@ -120,7 +120,6 @@
 class NominalMetadataLayout : public MetadataLayout {
 protected:
   StoredOffset GenericRequirements;
-  StoredOffset Parent;
 
   NominalMetadataLayout(Kind kind) : MetadataLayout(kind) {}
 
@@ -134,8 +133,6 @@
 
   Offset getGenericRequirementsOffset(IRGenFunction &IGF) const;
 
-  Offset getParentOffset(IRGenFunction &IGF) const;
-
   static bool classof(const MetadataLayout *layout) {
     return true; // No non-nominal metadata for now.
   }
@@ -287,11 +284,6 @@
   }
 };
 
-/// Emit the address of the 'parent' slot in the given nominal-type metadata.
-Address emitAddressOfParentMetadataSlot(IRGenFunction &IGF,
-                                        llvm::Value *metadata,
-                                        NominalTypeDecl *decl);
-
 /// Emit the address of the field-offset slot in the given class metadata.
 Address emitAddressOfClassFieldOffset(IRGenFunction &IGF,
                                       llvm::Value *metadata,
diff --git a/lib/IRGen/MetadataPath.h b/lib/IRGen/MetadataPath.h
index 001cae0..0dd1566 100644
--- a/lib/IRGen/MetadataPath.h
+++ b/lib/IRGen/MetadataPath.h
@@ -61,9 +61,6 @@
 
       // Everything past this point has no index.
 
-      /// The parent metadata of a nominal type.
-      NominalParent,
-
       /// An impossible path.
       Impossible,
     };
@@ -102,7 +99,6 @@
       case Kind::OutOfLineBaseProtocol:
       case Kind::NominalTypeArgumentConformance:
       case Kind::NominalTypeArgument:
-      case Kind::NominalParent:
         return OperationCost::Load;
 
       case Kind::AssociatedConformance:
@@ -144,11 +140,6 @@
     Path.push_back(Component(Component::Kind::Impossible));
   }
 
-  /// Add a step to this path which gets the parent metadata.
-  void addNominalParentComponent() {
-    Path.push_back(Component(Component::Kind::NominalParent));
-  }
-
   /// Add a step to this path which gets the type metadata stored at
   /// requirement index n in a generic type metadata.
   void addNominalTypeArgumentComponent(unsigned index) {
@@ -208,9 +199,6 @@
 
     for (auto C : Path) {
       switch (C.getKind()) {
-      case Component::Kind::NominalParent:
-        Root = A.createParent(Root);
-        continue;
       case Component::Kind::NominalTypeArgument:
         Root = A.createGenericArgument(C.getPrimaryIndex(), Root);
         continue;
diff --git a/lib/IRGen/NominalMetadataVisitor.h b/lib/IRGen/NominalMetadataVisitor.h
index 214032f..3944a4e 100644
--- a/lib/IRGen/NominalMetadataVisitor.h
+++ b/lib/IRGen/NominalMetadataVisitor.h
@@ -67,8 +67,7 @@
     GenericTypeRequirements requirements(IGM, typeDecl);
     if (requirements.empty()) return;
 
-    auto subs = type->castTo<BoundGenericType>()
-                    ->getContextSubstitutionMap(IGM.getSwiftModule(),
+    auto subs = type->getContextSubstitutionMap(IGM.getSwiftModule(),
                                                 typeDecl);
     requirements.enumerateFulfillments(IGM, subs,
                     [&](unsigned reqtIndex, CanType argType,
diff --git a/lib/IRGen/StructMetadataVisitor.h b/lib/IRGen/StructMetadataVisitor.h
index 3910b75..17dc558 100644
--- a/lib/IRGen/StructMetadataVisitor.h
+++ b/lib/IRGen/StructMetadataVisitor.h
@@ -47,7 +47,6 @@
 
     // StructMetadata header.
     asImpl().addNominalTypeDescriptor();
-    asImpl().addParentMetadataRef();
 
     // If changing this layout, you must update the magic number in
     // emitParentMetadataRef.
@@ -80,7 +79,6 @@
   void addMetadataFlags() { addPointer(); }
   void addValueWitnessTable() { addPointer(); }
   void addNominalTypeDescriptor() { addPointer(); }
-  void addParentMetadataRef() { addPointer(); }
   void addFieldOffset(VarDecl*) { addPointer(); }
   void addGenericArgument(CanType argument) { addPointer(); }
   void addGenericWitnessTable(CanType argument, ProtocolConformanceRef conf) {
diff --git a/lib/RemoteAST/RemoteAST.cpp b/lib/RemoteAST/RemoteAST.cpp
index 508f84d..7501eee 100644
--- a/lib/RemoteAST/RemoteAST.cpp
+++ b/lib/RemoteAST/RemoteAST.cpp
@@ -21,6 +21,7 @@
 #include "swift/AST/Decl.h"
 #include "swift/AST/Module.h"
 #include "swift/AST/NameLookup.h"
+#include "swift/AST/SubstitutionMap.h"
 #include "swift/AST/Types.h"
 #include "swift/AST/TypeRepr.h"
 #include "swift/Basic/Mangler.h"
@@ -133,6 +134,14 @@
 
   NominalTypeDecl *createNominalTypeDecl(const Demangle::NodePointer &node);
 
+  Type createNominalType(NominalTypeDecl *decl) {
+    // If the declaration is generic, fail.
+    if (decl->isGenericContext())
+      return Type();
+
+    return decl->getDeclaredType();
+  }
+
   Type createNominalType(NominalTypeDecl *decl, Type parent) {
     // If the declaration is generic, fail.
     if (decl->getGenericParams())
@@ -145,6 +154,36 @@
     return NominalType::get(decl, parent, Ctx);
   }
 
+  Type createBoundGenericType(NominalTypeDecl *decl, ArrayRef<Type> args) {
+    // If the declaration isn't generic, fail.
+    if (!decl->isGenericContext())
+      return Type();
+
+    // Build a SubstitutionMap.
+    auto *genericSig = decl->getGenericSignature();
+    auto genericParams = genericSig->getSubstitutableParams();
+    if (genericParams.size() != args.size())
+      return Type();
+
+    auto subMap = genericSig->getSubstitutionMap(
+        [&](SubstitutableType *t) -> Type {
+          for (unsigned i = 0, e = genericParams.size(); i < e; ++i) {
+            if (t->isEqual(genericParams[i]))
+              return args[i];
+          }
+          return Type();
+        },
+        // FIXME: Wrong module
+        LookUpConformanceInModule(decl->getParentModule()));
+
+    auto origType = decl->getDeclaredInterfaceType();
+
+    // FIXME: We're not checking that the type satisfies the generic
+    // requirements of the signature here.
+    auto substType = origType.subst(subMap);
+    return substType;
+  }
+
   Type createBoundGenericType(NominalTypeDecl *decl, ArrayRef<Type> args,
                               Type parent) {
     // If the declaration isn't generic, fail.
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index 6916902..06d7bff 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -416,6 +416,12 @@
          I->getNumTypeDependentOperands() == 0) {
     // All the open instructions are single-value instructions.
     auto SVI = dyn_cast<SingleValueInstruction>(I->getOperand(0));
+    // Within SimplifyCFG this function may be called for an instruction
+    // within unreachable code. And within an unreachable block it can happen
+    // that defs do not dominate uses (because there is no dominance defined).
+    // To avoid the infinite loop when following the chain of instructions via
+    // their operands, bail if the operand is not an instruction or this
+    // instruction was seen already.
     if (!SVI || !Visited.insert(SVI).second)
       return;
     // If it is a definition of an opened archetype,
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 4a51087..dbb400d 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -100,6 +100,9 @@
   assert(getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod);
   auto selfTy = getSelfInstanceType();
   if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
+    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);
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 9871d2f..829c219 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -2695,7 +2695,7 @@
   builder.addRequirement(newRequirement, source, nullptr);
 
   GenericSignature *genericSig =
-    std::move(builder).computeGenericSignature(SourceLoc(),
+    builder.computeGenericSignature(SourceLoc(),
                                     /*allowConcreteGenericParams=*/true);
   genericEnv = genericSig->createGenericEnvironment(*mod);
 
diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp
index cf413e4..736ca54 100644
--- a/lib/SILOptimizer/PassManager/PassManager.cpp
+++ b/lib/SILOptimizer/PassManager/PassManager.cpp
@@ -291,12 +291,12 @@
 
   assert(analysesUnlocked() && "Expected all analyses to be unlocked!");
 
-  PrettyStackTraceSILFunctionTransform X(SFT, NumPassesRun);
-  DebugPrintEnabler DebugPrint(NumPassesRun);
-
   SFT->injectPassManager(this);
   SFT->injectFunction(F);
 
+  PrettyStackTraceSILFunctionTransform X(SFT, NumPassesRun);
+  DebugPrintEnabler DebugPrint(NumPassesRun);
+
   // If nothing changed since the last run of this pass, we can skip this
   // pass.
   CompletedPasses &completedPasses = CompletedPassesMap[F];
@@ -440,12 +440,12 @@
 
   const SILOptions &Options = getOptions();
 
-  PrettyStackTraceSILModuleTransform X(SMT, NumPassesRun);
-  DebugPrintEnabler DebugPrint(NumPassesRun);
-
   SMT->injectPassManager(this);
   SMT->injectModule(Mod);
 
+  PrettyStackTraceSILModuleTransform X(SMT, NumPassesRun);
+  DebugPrintEnabler DebugPrint(NumPassesRun);
+
   updateSILModuleStatsBeforeTransform(*Mod, SMT, *this, NumPassesRun);
 
   CurrentPassHasInvalidated = false;
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index b2fa942..d841f25 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -800,7 +800,7 @@
   }
 
   auto NewGenSig =
-    std::move(Builder).computeGenericSignature(SourceLoc(),
+    Builder.computeGenericSignature(SourceLoc(),
                                    /*allowConcreteGenericParams=*/true);
   auto NewGenEnv = NewGenSig->createGenericEnvironment(*M.getSwiftModule());
   return { NewGenEnv, NewGenSig };
@@ -1490,7 +1490,7 @@
 
   // Finalize the archetype builder.
   auto GenSig =
-      std::move(Builder).computeGenericSignature(SourceLoc(),
+      Builder.computeGenericSignature(SourceLoc(),
                                       /*allowConcreteGenericParams=*/true);
   auto GenEnv = GenSig->createGenericEnvironment(*M.getSwiftModule());
   return { GenEnv, GenSig };
diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp
index a175413..c6aa9fa 100644
--- a/lib/Sema/CSBindings.cpp
+++ b/lib/Sema/CSBindings.cpp
@@ -123,6 +123,40 @@
   llvm_unreachable("Unhandled ConstraintKind in switch.");
 }
 
+void ConstraintSystem::PotentialBindings::addPotentialBinding(
+    PotentialBinding binding, bool allowJoinMeet) {
+  assert(!binding.BindingType->is<ErrorType>());
+
+  // If this is a non-defaulted supertype binding,
+  // check whether we can combine it with another
+  // supertype binding by computing the 'join' of the types.
+  if (binding.Kind == AllowedBindingKind::Supertypes &&
+      !binding.BindingType->hasTypeVariable() && !binding.DefaultedProtocol &&
+      !binding.isDefaultableBinding() && allowJoinMeet) {
+    if (lastSupertypeIndex) {
+      // Can we compute a join?
+      auto &lastBinding = Bindings[*lastSupertypeIndex];
+      auto lastType = lastBinding.BindingType->getWithoutSpecifierType();
+      auto bindingType = binding.BindingType->getWithoutSpecifierType();
+      auto join = Type::join(lastType, bindingType);
+      if (join) {
+        auto anyType = join->getASTContext().TheAnyType;
+        if (!join->isEqual(anyType) || lastType->isEqual(anyType) ||
+            bindingType->isEqual(anyType)) {
+          // Replace the last supertype binding with the join. We're done.
+          lastBinding.BindingType = join;
+          return;
+        }
+      }
+    }
+
+    // Record this as the most recent supertype index.
+    lastSupertypeIndex = Bindings.size();
+  }
+
+  Bindings.push_back(std::move(binding));
+}
+
 /// \brief Retrieve the set of potential type bindings for the given
 /// representative type variable, along with flags indicating whether
 /// those types should be opened.
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index bea32ae..d2b84a8 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -3289,18 +3289,42 @@
           patternElt.first->setType(patternElt.second);
       
       for (auto paramDeclElt : ParamDeclTypes)
-        if (!paramDeclElt.first->hasType())
-          paramDeclElt.first->setType(paramDeclElt.second);
+        if (!paramDeclElt.first->hasType()) {
+          paramDeclElt.first->setType(getParamBaseType(paramDeclElt));
+        }
 
       for (auto paramDeclIfaceElt : ParamDeclInterfaceTypes)
-        if (!paramDeclIfaceElt.first->hasInterfaceType())
-          paramDeclIfaceElt.first->setInterfaceType(paramDeclIfaceElt.second);
+        if (!paramDeclIfaceElt.first->hasInterfaceType()) {
+          paramDeclIfaceElt.first->setInterfaceType(
+              getParamBaseType(paramDeclIfaceElt));
+        }
 
       if (!PossiblyInvalidDecls.empty())
         for (auto D : PossiblyInvalidDecls)
           if (D->hasInterfaceType())
             D->setInvalid(D->getInterfaceType()->hasError());
     }
+
+  private:
+    static Type getParamBaseType(std::pair<ParamDecl *, Type> &storedParam) {
+      ParamDecl *param;
+      Type storedType;
+
+      std::tie(param, storedType) = storedParam;
+
+      // FIXME: We are currently in process of removing `InOutType`
+      //        so `VarDecl::get{Interface}Type` is going to wrap base
+      //        type into `InOutType` if its flag indicates that it's
+      //        an `inout` parameter declaration. But such type can't
+      //        be restored directly using `VarDecl::set{Interface}Type`
+      //        caller needs additional logic to extract base type.
+      if (auto *IOT = storedType->getAs<InOutType>()) {
+        assert(param->isInOut());
+        return IOT->getObjectType();
+      }
+
+      return storedType;
+    }
   };
 } // end anonymous namespace
 
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 727f365..24c5854 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -2118,6 +2118,12 @@
     ctor->getAttrs().add(clonedAttr);
   }
 
+  // Inherit the @_inlineable attribute.
+  if (superclassCtor->getAttrs().hasAttribute<InlineableAttr>()) {
+    auto *clonedAttr = new (ctx) InlineableAttr(/*implicit=*/true);
+    ctor->getAttrs().add(clonedAttr);
+  }
+
   // Make sure the constructor is only as available as its superclass's
   // constructor.
   AvailabilityInference::applyInferredAvailableAttrs(ctor, superclassCtor, ctx);
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index c106aa4..a5cae21 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -2629,39 +2629,7 @@
     /// \brief Add a potential binding to the list of bindings,
     /// coalescing supertype bounds when we are able to compute the meet.
     void addPotentialBinding(PotentialBinding binding,
-                             bool allowJoinMeet = true) {
-      assert(!binding.BindingType->is<ErrorType>());
-
-      // If this is a non-defaulted supertype binding,
-      // check whether we can combine it with another
-      // supertype binding by computing the 'join' of the types.
-      if (binding.Kind == AllowedBindingKind::Supertypes &&
-          !binding.BindingType->hasTypeVariable() &&
-          !binding.DefaultedProtocol && !binding.isDefaultableBinding() &&
-          allowJoinMeet) {
-        if (lastSupertypeIndex) {
-          // Can we compute a join?
-          auto &lastBinding = Bindings[*lastSupertypeIndex];
-          auto lastType = lastBinding.BindingType->getWithoutSpecifierType();
-          auto bindingType = binding.BindingType->getWithoutSpecifierType();
-          auto join = Type::join(lastType, bindingType);
-          if (join) {
-            auto anyType = join->getASTContext().TheAnyType;
-            if (!join->isEqual(anyType) || lastType->isEqual(anyType) ||
-                bindingType->isEqual(anyType)) {
-              // Replace the last supertype binding with the join. We're done.
-              lastBinding.BindingType = join;
-              return;
-            }
-          }
-        }
-
-        // Record this as the most recent supertype index.
-        lastSupertypeIndex = Bindings.size();
-      }
-
-      Bindings.push_back(std::move(binding));
-    }
+                             bool allowJoinMeet = true);
 
     void dump(llvm::raw_ostream &out,
               unsigned indent = 0) const LLVM_ATTRIBUTE_USED {
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index 072e9ae..63d7375 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -1851,8 +1851,7 @@
     Builder.addRequirement(&req, DC->getParentModule());
 
   // Check the result.
-  (void)std::move(Builder).computeGenericSignature(
-                                        attr->getLocation(),
+  (void)Builder.computeGenericSignature(attr->getLocation(),
                                         /*allowConcreteGenericParams=*/true);
 }
 
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index a9db914..e85686f 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -7117,8 +7117,11 @@
   }
 
   void visitDestructorDecl(DestructorDecl *DD) {
-    if (DD->isInvalid()) {
+    auto enclosingClass = dyn_cast<ClassDecl>(DD->getDeclContext());
+    if (DD->isInvalid() ||
+        enclosingClass == nullptr) {
       DD->setInterfaceType(ErrorType::get(TC.Context));
+      DD->setInvalid();
       return;
     }
 
@@ -7140,10 +7143,13 @@
 
     TC.checkDeclAttributesEarly(DD);
     if (!DD->hasAccess()) {
-      auto enclosingClass = cast<ClassDecl>(DD->getParent());
       DD->setAccess(enclosingClass->getFormalAccess());
     }
 
+    if (enclosingClass->getAttrs().hasAttribute<VersionedAttr>()) {
+      DD->getAttrs().add(new (TC.Context) VersionedAttr(/*implicit=*/true));
+    }
+
     configureImplicitSelf(TC, DD);
 
     if (DD->getDeclContext()->getGenericSignatureOfContext()) {
@@ -7664,25 +7670,13 @@
 
     break;
   }
-      
-  case DeclKind::Func: {
-    typeCheckDecl(D, true);
-    break;
-  }
 
+  case DeclKind::Func:
   case DeclKind::Subscript:
   case DeclKind::Constructor:
-    typeCheckDecl(D, true);
-    break;
-
   case DeclKind::Destructor:
   case DeclKind::EnumElement: {
-    if (auto container = dyn_cast<NominalTypeDecl>(D->getDeclContext())) {
-      validateDecl(container);
-      typeCheckDecl(D, true);
-    } else {
-      D->setInterfaceType(ErrorType::get(Context));
-    }
+    typeCheckDecl(D, true);
     break;
   }
   }
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index 25b90cd..949f618 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -136,19 +136,20 @@
                                     DeclContext *DC,
                                     SourceRange baseRange,
                                     ComponentIdentTypeRepr *ref) {
-  auto baseEquivClass =
-    builder.resolveEquivalenceClass(
-                                baseTy,
-                                ArchetypeResolutionKind::CompleteWellFormed);
-  assert(baseEquivClass && "Unknown base type?");
+  // Resolve the base to a potential archetype.
+  auto basePA =
+    builder.resolveArchetype(baseTy,
+                             ArchetypeResolutionKind::CompleteWellFormed);
+  assert(basePA && "Missing potential archetype for base");
 
-  // Look for a nested type with the given name.
-  if (auto nestedType =
-          baseEquivClass->lookupNestedType(ref->getIdentifier())) {
-    // Record the type we found.
-    ref->setValue(nestedType, nullptr);
-  } else {
-    // Resolve the base to a potential archetype.
+  // Retrieve the potential archetype for the nested type.
+  auto nestedPA =
+    basePA->getNestedType(ref->getIdentifier(),
+                          ArchetypeResolutionKind::CompleteWellFormed,
+                          builder);
+
+  // If there was no such nested type, produce an error.
+  if (!nestedPA) {
     // Perform typo correction.
     LookupResult corrections;
     tc.performTypoCorrection(DC, DeclRefKind::Ordinary,
@@ -188,6 +189,11 @@
     // Correct to the single type result.
     ref->overwriteIdentifier(singleType->getBaseName().getIdentifier());
     ref->setValue(singleType, nullptr);
+  } else if (auto assocType = nestedPA->getResolvedAssociatedType()) {
+    ref->setValue(assocType, nullptr);
+  } else {
+    assert(nestedPA->getConcreteTypeDecl());
+    ref->setValue(nestedPA->getConcreteTypeDecl(), nullptr);
   }
 
   // If the nested type has been resolved to an associated type, use it.
@@ -211,7 +217,7 @@
       return concrete->getDeclaredInterfaceType().subst(subMap);
     }
 
-    if (auto superclass = baseEquivClass->superclass) {
+    if (auto superclass = basePA->getSuperclass()) {
       return superclass->getTypeOfMember(
                                        DC->getParentModule(), concrete,
                                        concrete->getDeclaredInterfaceType());
@@ -746,6 +752,13 @@
   if (auto gp = func->getGenericParams()) {
     prepareGenericParamList(gp, func);
 
+    // Collect the generic parameters.
+    SmallVector<GenericTypeParamType *, 4> allGenericParams;
+    if (auto parentSig = func->getDeclContext()->getGenericSignatureOfContext())
+      allGenericParams.append(parentSig->getGenericParams().begin(),
+                              parentSig->getGenericParams().end());
+    addGenericParamTypes(gp, allGenericParams);
+
     // Create the generic signature builder.
     GenericSignatureBuilder builder(Context, LookUpConformance(*this, func));
 
@@ -755,9 +768,8 @@
     if (checkGenericFuncSignature(*this, &builder, func, dependentResolver))
       invalid = true;
 
-    // The generic function signature is complete and well-formed. Determine
-    // the type of the generic function.
-    sig = std::move(builder).computeGenericSignature(func->getLoc());
+    // Finalize the generic requirements.
+    (void)builder.finalize(func->getLoc(), allGenericParams);
 
     // The generic signature builder now has all of the requirements, although
     // there might still be errors that have not yet been diagnosed. Revert the
@@ -766,10 +778,16 @@
     if (gp)
       revertGenericParamList(gp);
 
-    // Debugging of the generic signature.
+    // The generic function signature is complete and well-formed. Determine
+    // the type of the generic function.
+    sig = builder.getGenericSignature();
+
+    // Debugging of the generic signature builder and generic signature
+    // generation.
     if (Context.LangOpts.DebugGenericSignatures) {
       func->dumpRef(llvm::errs());
       llvm::errs() << "\n";
+      builder.dump(llvm::errs());
       llvm::errs() << "Generic signature: ";
       sig->print(llvm::errs());
       llvm::errs() << "\n";
@@ -969,9 +987,15 @@
   if (auto *gp = subscript->getGenericParams()) {
     prepareGenericParamList(gp, subscript);
 
+    // Collect the generic parameters.
+    SmallVector<GenericTypeParamType *, 4> allGenericParams;
+    if (auto parentSig = subscript->getDeclContext()->getGenericSignatureOfContext())
+      allGenericParams.append(parentSig->getGenericParams().begin(),
+                              parentSig->getGenericParams().end());
+    addGenericParamTypes(gp, allGenericParams);
+
     // Create the generic signature builder.
-    GenericSignatureBuilder builder(Context,
-                                    LookUpConformance(*this, subscript));
+    GenericSignatureBuilder builder(Context, LookUpConformance(*this, subscript));
 
     // Type check the function declaration, treating all generic type
     // parameters as dependent, unresolved.
@@ -980,9 +1004,8 @@
                                        dependentResolver))
       invalid = true;
 
-    // The generic subscript signature is complete and well-formed. Determine
-    // the type of the generic subscript.
-    sig = std::move(builder).computeGenericSignature(subscript->getLoc());
+    // Finalize the generic requirements.
+    (void)builder.finalize(subscript->getLoc(), allGenericParams);
 
     // The generic signature builder now has all of the requirements, although
     // there might still be errors that have not yet been diagnosed. Revert the
@@ -990,10 +1013,16 @@
     revertGenericSubscriptSignature(subscript);
     revertGenericParamList(gp);
 
-    // Debugging of generic signature generation.
+    // The generic subscript signature is complete and well-formed. Determine
+    // the type of the generic subscript.
+    sig = builder.getGenericSignature();
+
+    // Debugging of the generic signature builder and generic signature
+    // generation.
     if (Context.LangOpts.DebugGenericSignatures) {
       subscript->dumpRef(llvm::errs());
       llvm::errs() << "\n";
+      builder.dump(llvm::errs());
       llvm::errs() << "Generic signature: ";
       sig->print(llvm::errs());
       llvm::errs() << "\n";
@@ -1119,10 +1148,10 @@
     /// Perform any necessary requirement inference.
     inferRequirements(builder);
 
-    // Record the generic type parameter types and the requirements.
-    sig = std::move(builder).computeGenericSignature(
-                                         genericParams->getSourceRange().Start,
-                                         allowConcreteGenericParams);
+    // Finalize the generic requirements.
+    (void)builder.finalize(genericParams->getSourceRange().Start,
+                           allGenericParams,
+                           allowConcreteGenericParams);
 
     // The generic signature builder now has all of the requirements, although
     // there might still be errors that have not yet been diagnosed. Revert the
@@ -1136,11 +1165,15 @@
       revertGenericParamList(genericParams);
     }
 
+    // Record the generic type parameter types and the requirements.
+    sig = builder.getGenericSignature();
+
     // Debugging of the generic signature builder and generic signature
     // generation.
     if (Context.LangOpts.DebugGenericSignatures) {
       dc->printContext(llvm::errs());
       llvm::errs() << "\n";
+      builder.dump(llvm::errs());
       llvm::errs() << "Generic signature: ";
       sig->print(llvm::errs());
       llvm::errs() << "\n";
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 686557d..d730a4a 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1156,8 +1156,7 @@
   // Produce the generic signature and environment.
   // FIXME: Pass in a source location for the conformance, perhaps? It seems
   // like this could fail.
-  syntheticSignature =
-    std::move(builder).computeGenericSignature(SourceLoc());
+  syntheticSignature = builder.computeGenericSignature(SourceLoc());
   syntheticEnvironment = syntheticSignature->createGenericEnvironment(
                                              *conformanceDC->getParentModule());
 }
diff --git a/stdlib/public/Reflection/MetadataSource.cpp b/stdlib/public/Reflection/MetadataSource.cpp
index 59c989c..7278c53 100644
--- a/stdlib/public/Reflection/MetadataSource.cpp
+++ b/stdlib/public/Reflection/MetadataSource.cpp
@@ -87,13 +87,6 @@
     closeForm();
   }
 
-  void
-  visitParentMetadataSource(const ParentMetadataSource *P) {
-    printHeader("parent_of");
-    printRec(P->getChild());
-    closeForm();
-  }
-
   void visitSelfMetadataSource(const SelfMetadataSource *S) {
     printHeader("self");
     closeForm();
diff --git a/stdlib/public/core/Equatable.swift b/stdlib/public/core/Equatable.swift
index a72e3a2..a00c38d 100644
--- a/stdlib/public/core/Equatable.swift
+++ b/stdlib/public/core/Equatable.swift
@@ -236,10 +236,7 @@
 public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool {
   switch (lhs, rhs) {
   case let (l?, r?):
-    return Bool(Builtin.cmp_eq_RawPointer(
-        Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(l)),
-        Builtin.bridgeToRawPointer(Builtin.castToUnknownObject(r))
-      ))
+    return ObjectIdentifier(l) == ObjectIdentifier(r)
   case (nil, nil):
     return true
   default:
diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift
index b521f81..5a2adb8 100644
--- a/stdlib/public/core/VarArgs.swift
+++ b/stdlib/public/core/VarArgs.swift
@@ -168,6 +168,12 @@
   }
 }
 
+extension Bool : CVarArg {
+  public var _cVarArgEncoding: [Int] {
+    return _encodeBitsAsWords(Int32(self ? 1:0))
+  }
+}
+
 extension Int64 : CVarArg, _CVarArgAligned {
   /// Transform `self` into a series of machine words that can be
   /// appropriately interpreted by C varargs.
diff --git a/stdlib/public/runtime/Demangle.cpp b/stdlib/public/runtime/Demangle.cpp
index d36c04f..423b096 100644
--- a/stdlib/public/runtime/Demangle.cpp
+++ b/stdlib/public/runtime/Demangle.cpp
@@ -30,13 +30,107 @@
 swift::_swift_buildDemanglingForMetadata(const Metadata *type,
                                          Demangle::Demangler &Dem);
 
+static Demangle::NodePointer
+_applyGenericArguments(const Metadata * const *genericArgs,
+                       const NominalTypeDescriptor *description,
+                       Demangle::NodePointer node, unsigned depth,
+                       Demangle::Demangler &Dem) {
+  assert(depth > 0);
+
+  auto typeNode = node;
+  if (typeNode->getKind() == Node::Kind::Type)
+    typeNode = typeNode->getChild(0);
+
+  auto parentNode = typeNode->getChild(0);
+
+  // It might be more accurate to keep this sugar, but the old version
+  // of this function dropped it, and I want to keep things compatible.
+  if (parentNode->getKind() == Node::Kind::Extension) {
+    parentNode = parentNode->getChild(1);
+  }
+
+  switch (parentNode->getKind()) {
+  case Node::Kind::Class:
+  case Node::Kind::Structure:
+  case Node::Kind::Enum: {
+    // The parent type is a nominal type which may have its own generic
+    // arguments.
+    auto newParentNode = _applyGenericArguments(genericArgs, description,
+                                                parentNode, depth - 1,
+                                                Dem);
+    if (newParentNode == nullptr)
+      return nullptr;
+
+    auto newTypeNode = Dem.createNode(typeNode->getKind());
+    newTypeNode->addChild(newParentNode, Dem);
+    newTypeNode->addChild(typeNode->getChild(1), Dem);
+
+    typeNode = newTypeNode;
+    break;
+  }
+  default:
+    // Parent is a local context or module. Leave it as-is, and just apply
+    // generic arguments below.
+    break;
+  }
+
+  // See if we have any generic arguments at this depth.
+  unsigned numArgumentsAtDepth =
+      description->GenericParams.getContext(depth - 1).NumPrimaryParams;
+  if (numArgumentsAtDepth == 0) {
+    // No arguments here, just return the original node (except we may have
+    // replaced its parent type above).
+    return typeNode;
+  }
+
+  // Ok, we have generic arguments. Figure out where the arguments for this
+  // depth begin in the generic type metadata.
+  unsigned firstArgumentAtDepth = 0;
+  for (unsigned i = 0; i < depth - 1; i++) {
+    firstArgumentAtDepth +=
+        description->GenericParams.getContext(i).NumPrimaryParams;
+  }
+
+  // Demangle them.
+  auto typeParams = Dem.createNode(Node::Kind::TypeList);
+  for (unsigned i = firstArgumentAtDepth,
+                e = firstArgumentAtDepth + numArgumentsAtDepth;
+                i < e; ++i) {
+    auto demangling = _swift_buildDemanglingForMetadata(genericArgs[i], Dem);
+    if (demangling == nullptr)
+      return nullptr;
+    typeParams->addChild(demangling, Dem);
+  }
+
+  Node::Kind boundGenericKind;
+  switch (typeNode->getKind()) {
+  case Node::Kind::Class:
+    boundGenericKind = Node::Kind::BoundGenericClass;
+    break;
+  case Node::Kind::Structure:
+    boundGenericKind = Node::Kind::BoundGenericStructure;
+    break;
+  case Node::Kind::Enum:
+    boundGenericKind = Node::Kind::BoundGenericEnum;
+    break;
+  default:
+    return nullptr;
+  }
+
+  auto newNode = Dem.createNode(Node::Kind::Type);
+  newNode->addChild(typeNode, Dem);
+
+  auto genericNode = Dem.createNode(boundGenericKind);
+  genericNode->addChild(newNode, Dem);
+  genericNode->addChild(typeParams, Dem);
+  return genericNode;
+}
+
 // Build a demangled type tree for a nominal type.
 static Demangle::NodePointer
 _buildDemanglingForNominalType(const Metadata *type, Demangle::Demangler &Dem) {
   using namespace Demangle;
 
-  const Metadata *parent;
-  Node::Kind boundGenericKind;
   const NominalTypeDescriptor *description;
 
   // Demangle the parent type, if any.
@@ -48,23 +142,17 @@
     while (classType->isTypeMetadata() && classType->isArtificialSubclass())
       classType = classType->SuperClass;
 #endif
-    parent = classType->getParentType(classType->getDescription());
-    boundGenericKind = Node::Kind::BoundGenericClass;
     description = classType->getDescription();
     break;
   }
   case MetadataKind::Enum:
   case MetadataKind::Optional: {
     auto enumType = static_cast<const EnumMetadata *>(type);
-    parent = enumType->Parent;
-    boundGenericKind = Node::Kind::BoundGenericEnum;
     description = enumType->Description;
     break;
   }
   case MetadataKind::Struct: {
     auto structType = static_cast<const StructMetadata *>(type);
-    parent = structType->Parent;
-    boundGenericKind = Node::Kind::BoundGenericStructure;
     description = structType->Description;
     break;
   }
@@ -76,42 +164,13 @@
   auto node = Dem.demangleType(StringRef(description->Name));
   assert(node->getKind() == Node::Kind::Type);
 
-  // Demangle the parent.
-  if (parent) {
-    auto parentNode = _swift_buildDemanglingForMetadata(parent, Dem);
-    if (parentNode->getKind() == Node::Kind::Type)
-      parentNode = parentNode->getChild(0);
+  auto typeBytes = reinterpret_cast<const char *>(type);
+  auto genericArgs = reinterpret_cast<const Metadata * const *>(
+               typeBytes + sizeof(void*) * description->GenericParams.Offset);
 
-    auto typeNode = node->getChild(0);
-    auto newTypeNode = Dem.createNode(typeNode->getKind());
-    newTypeNode->addChild(parentNode, Dem);
-    newTypeNode->addChild(typeNode->getChild(1), Dem);
-
-    auto newNode = Dem.createNode(Node::Kind::Type);
-    newNode->addChild(newTypeNode, Dem);
-    node = newNode;
-  }
-
-  // If generic, demangle the type parameters.
-  if (description->GenericParams.NumPrimaryParams > 0) {
-    auto typeParams = Dem.createNode(Node::Kind::TypeList);
-    auto typeBytes = reinterpret_cast<const char *>(type);
-    auto genericParam = reinterpret_cast<const Metadata * const *>(
-                 typeBytes + sizeof(void*) * description->GenericParams.Offset);
-    for (unsigned i = 0, e = description->GenericParams.NumPrimaryParams;
-         i < e; ++i, ++genericParam) {
-      auto demangling = _swift_buildDemanglingForMetadata(*genericParam, Dem);
-      if (demangling == nullptr)
-        return nullptr;
-      typeParams->addChild(demangling, Dem);
-    }
-
-    auto genericNode = Dem.createNode(boundGenericKind);
-    genericNode->addChild(node, Dem);
-    genericNode->addChild(typeParams, Dem);
-    return genericNode;
-  }
-  return node;
+  return _applyGenericArguments(genericArgs, description, node,
+                                description->GenericParams.NestingDepth,
+                                Dem);
 }
 
 // Build a demangled type tree for a type.
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index d5875ac..fbfad19 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -221,8 +221,7 @@
     pattern->AddressPoint;
   auto patternMetadata = reinterpret_cast<const ValueMetadata*>(patternBytes);
   metadata->Description = patternMetadata->Description.get();
-  metadata->Parent = patternMetadata->Parent;
-  
+
   return metadata;
 }
 
@@ -1329,13 +1328,6 @@
     auto &description = ancestor->getDescription();
     auto &genericParams = description->GenericParams;
 
-    // Copy the parent type.
-    if (genericParams.Flags.hasParent()) {
-      memcpy(classWords + genericParams.Offset - 1,
-             superWords + genericParams.Offset - 1,
-             sizeof(uintptr_t));
-    }
-
     // Copy the generic requirements.
     if (genericParams.hasGenericRequirements()) {
       unsigned numParamWords = genericParams.NumGenericRequirements;
diff --git a/test/Generics/associated_type_typo.swift b/test/Generics/associated_type_typo.swift
index 4ac5b86..f023418 100644
--- a/test/Generics/associated_type_typo.swift
+++ b/test/Generics/associated_type_typo.swift
@@ -34,6 +34,13 @@
 // expected-error@+1{{'T' does not have a member type named 'Assocp2'; did you mean 'AssocP2'?}}{{39-46=AssocP2}}
 func typoAssoc4<T : P2>(_: T) where T.Assocp2.assoc : P3 {}
 
+
+// CHECK-GENERIC-LABEL: .typoAssoc4@
+// CHECK-GENERIC-NEXT: Requirements:
+// CHECK-GENERIC-NEXT:   τ_0_0 : P2 [τ_0_0: Explicit @ {{.*}}:21]
+// CHECK-GENERIC-NEXT:   τ_0_0[.P2].AssocP2 : P1 [τ_0_0: Explicit @ {{.*}}:21 -> Protocol requirement (via Self.AssocP2 in P2)
+// CHECK-GENERIC-NEXT: Potential archetypes
+
 // <rdar://problem/19620340>
 
 func typoFunc1<T : P1>(x: TypoType) { // expected-error{{use of undeclared type 'TypoType'}}
diff --git a/test/Generics/protocol_type_aliases.swift b/test/Generics/protocol_type_aliases.swift
index 9c083d4..afb2661 100644
--- a/test/Generics/protocol_type_aliases.swift
+++ b/test/Generics/protocol_type_aliases.swift
@@ -14,6 +14,10 @@
 }
 
 // CHECK-LABEL: .requirementOnNestedTypeAlias@
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : Q [τ_0_0: Explicit @ 22:51]
+// CHECK-NEXT:   τ_0_0[.Q].B : P [τ_0_0: Explicit @ 22:51 -> Protocol requirement (via Self.B in Q)
+// CHECK-NEXT:   τ_0_0[.Q].B[.P].A == Int [τ_0_0[.Q].B[.P].X: Explicit @ 22:62]
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Q, τ_0_0.B.A == Int>
 func requirementOnNestedTypeAlias<T>(_: T) where T: Q, T.B.X == Int {}
 
@@ -29,10 +33,20 @@
 }
 
 // CHECK-LABEL: .requirementOnConcreteNestedTypeAlias@
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : Q2 [τ_0_0: Explicit @ 42:59]
+// CHECK-NEXT:   τ_0_0[.Q2].B : P2 [τ_0_0: Explicit @ 42:59 -> Protocol requirement (via Self.B in Q2)
+// CHECK-NEXT:   τ_0_0[.Q2].C == S<T.B.A> [τ_0_0[.Q2].C: Explicit]
+// CHECK-NEXT:   τ_0_0[.Q2].B[.P2].X == S<T.B.A> [τ_0_0[.Q2].B[.P2].X: Concrete type binding]
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0.C == S<τ_0_0.B.A>>
 func requirementOnConcreteNestedTypeAlias<T>(_: T) where T: Q2, T.C == T.B.X {}
 
 // CHECK-LABEL: .concreteRequirementOnConcreteNestedTypeAlias@
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : Q2 [τ_0_0: Explicit @ 51:67]
+// CHECK-NEXT:   τ_0_0[.Q2].B : P2 [τ_0_0: Explicit @ 51:67 -> Protocol requirement (via Self.B in Q2)
+// CHECK-NEXT:   τ_0_0[.Q2].C == τ_0_0[.Q2].B[.P2].A [τ_0_0[.Q2].C: Explicit]
+// CHECK-NEXT:   τ_0_0[.Q2].B[.P2].X == S<T.B.A> [τ_0_0[.Q2].B[.P2].X: Concrete type binding]
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0.C == τ_0_0.B.A>
 func concreteRequirementOnConcreteNestedTypeAlias<T>(_: T) where T: Q2, S<T.C> == T.B.X {}
 
diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift
index 391c9b4..ac124ae 100644
--- a/test/Generics/requirement_inference.swift
+++ b/test/Generics/requirement_inference.swift
@@ -72,14 +72,16 @@
 struct V<T : Canidae> {}
 
 // CHECK-LABEL: .inferSuperclassRequirement1@
-// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Canidae>
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : Canidae
 func inferSuperclassRequirement1<T : Carnivora>(
 	_ v: V<T>) {}
 // expected-warning@-2{{redundant superclass constraint 'T' : 'Carnivora'}}
 // expected-note@-2{{superclass constraint 'T' : 'Canidae' inferred from type here}}
 
 // CHECK-LABEL: .inferSuperclassRequirement2@
-// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : Canidae>
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : Canidae
 func inferSuperclassRequirement2<T : Canidae>(_ v: U<T>) {}
 
 // ----------------------------------------------------------------------------
@@ -108,17 +110,33 @@
 
 struct Model_P3_P4_Eq<T : P3, U : P4> where T.P3Assoc == U.P4Assoc {}
 
-func inferSameType1<T, U>(_ x: Model_P3_P4_Eq<T, U>) {
-  let u: U.P4Assoc? = nil
-  let _: T.P3Assoc? = u!
-}
+// CHECK-LABEL: .inferSameType1@
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : P3 [τ_0_0: Inferred @ {{.*}}:32]
+// CHECK-NEXT:   τ_0_1 : P4 [τ_0_1: Inferred @ {{.*}}:32]
+// CHECK-NEXT:   τ_0_0[.P3].P3Assoc : P1 [τ_0_1: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P4Assoc in P4)
+// CHECK-NEXT:   τ_0_0[.P3].P3Assoc : P2 [τ_0_0: Inferred @ {{.*}}:32 -> Protocol requirement (via Self.P3Assoc in P3)
+// FIXME: τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [τ_0_0: Inferred]
+func inferSameType1<T, U>(_ x: Model_P3_P4_Eq<T, U>) { }
 
+// CHECK-LABEL: .inferSameType2@
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : P3 [τ_0_0: Explicit @ {{.*}}:25]
+// CHECK-NEXT:   τ_0_1 : P4 [τ_0_1: Explicit @ {{.*}}:33]
+// CHECK-NEXT:   τ_0_0[.P3].P3Assoc : P1 [τ_0_1: Explicit @ {{.*}}:33 -> Protocol requirement (via Self.P4Assoc in P4)
+// CHECK-NEXT:   τ_0_0[.P3].P3Assoc : P2 [τ_0_0: Explicit @ {{.*}}:25 -> Protocol requirement (via Self.P3Assoc in P3)
+// CHECK-NEXT:   τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [τ_0_0[.P3].P3Assoc: Explicit]
 func inferSameType2<T : P3, U : P4>(_: T, _: U) where U.P4Assoc : P2, T.P3Assoc == U.P4Assoc {}
 // expected-warning@-1{{redundant conformance constraint 'T.P3Assoc': 'P2'}}
 // expected-note@-2{{conformance constraint 'T.P3Assoc': 'P2' implied here}}
 
-func inferSameType3<T : PCommonAssoc1>(_: T) where T.CommonAssoc : P1, T : PCommonAssoc2 {
-}
+// CHECK-LABEL: .inferSameType3@
+// CHECK-NEXT: Requirements:
+// CHECK-NEXT:   τ_0_0 : PCommonAssoc1 [τ_0_0: Explicit @ {{.*}}:25]
+// CHECK-NEXT:   τ_0_0 : PCommonAssoc2 [τ_0_0: Explicit @ {{.*}}:74]
+// CHECK-NEXT:   τ_0_0[.PCommonAssoc1].CommonAssoc : P1 [τ_0_0[.PCommonAssoc1].CommonAssoc: Explicit @ {{.*}}:66]
+// CHECK-NEXT: Potential archetypes
+func inferSameType3<T : PCommonAssoc1>(_: T) where T.CommonAssoc : P1, T : PCommonAssoc2 {}
 
 protocol P5 {
   associatedtype Element
diff --git a/test/Generics/superclass_constraint.swift b/test/Generics/superclass_constraint.swift
index b27d7af..d02efc5 100644
--- a/test/Generics/superclass_constraint.swift
+++ b/test/Generics/superclass_constraint.swift
@@ -67,6 +67,10 @@
 }
 
 // CHECK: superclassConformance1
+// CHECK: Requirements:
+// CHECK-NEXT: τ_0_0 : C [τ_0_0: Explicit @ {{.*}}:11]
+// CHECK-NEXT: τ_0_0 : _NativeClass [τ_0_0: Explicit @ {{.*}}:11 -> Derived]
+// CHECK-NEXT: τ_0_0 : P3 [τ_0_0: Explicit @ {{.*}}:11 -> Superclass (C: P3)]
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : C>
 func superclassConformance1<T>(t: T)
   where T : C, // expected-note{{conformance constraint 'T': 'P3' implied here}}
@@ -75,6 +79,10 @@
 
 
 // CHECK: superclassConformance2
+// CHECK: Requirements:
+// CHECK-NEXT: τ_0_0 : C [τ_0_0: Explicit @ {{.*}}:11]
+// CHECK-NEXT: τ_0_0 : _NativeClass [τ_0_0: Explicit @ {{.*}}:11 -> Derived]
+// CHECK-NEXT: τ_0_0 : P3 [τ_0_0: Explicit @ {{.*}}:11 -> Superclass (C: P3)]
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : C>
 func superclassConformance2<T>(t: T)
   where T : C, // expected-note{{conformance constraint 'T': 'P3' implied here}}
@@ -85,6 +93,10 @@
 class C2 : C, P4 { }
 
 // CHECK: superclassConformance3
+// CHECK: Requirements:
+// CHECK-NEXT: τ_0_0 : C2 [τ_0_0: Explicit @ {{.*}}:61]
+// CHECK-NEXT: τ_0_0 : _NativeClass [τ_0_0: Explicit @ {{.*}}:46 -> Derived]
+// CHECK-NEXT: τ_0_0 : P4 [τ_0_0: Explicit @ {{.*}}:61 -> Superclass (C2: P4)]
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : C2>
 func superclassConformance3<T>(t: T) where T : C, T : P4, T : C2 {}
 // expected-warning@-1{{redundant superclass constraint 'T' : 'C'}}
diff --git a/test/IRGen/associated_type_witness.swift b/test/IRGen/associated_type_witness.swift
index 47e64cf..5b1f25e 100644
--- a/test/IRGen/associated_type_witness.swift
+++ b/test/IRGen/associated_type_witness.swift
@@ -51,21 +51,21 @@
 //   Associated type metadata access function for Fulfilled.Assoc.
 // CHECK-LABEL:  define internal %swift.type* @_T023associated_type_witness9FulfilledVyxGAA8AssockedA2A1PRzAA1QRzl5AssocWt(%swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
 // CHECK:         [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to %swift.type**
-// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3
+// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 2
 // CHECK-NEXT:    [[T2:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
 // CHECK-NEXT:    ret %swift.type* [[T2]]
 
 //   Associated type witness table access function for Fulfilled.Assoc : P.
 // CHECK-LABEL:  define internal i8** @_T023associated_type_witness9FulfilledVyxGAA8AssockedA2A1PRzAA1QRzl5AssocAaFPWT(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
 // CHECK:         [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to i8***
-// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 4
+// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 3
 // CHECK-NEXT:    [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
 // CHECK-NEXT:    ret i8** [[T2]]
 
 //   Associated type witness table access function for Fulfilled.Assoc : Q.
 // CHECK-LABEL:  define internal i8** @_T023associated_type_witness9FulfilledVyxGAA8AssockedA2A1PRzAA1QRzl5AssocAaGPWT(%swift.type* %"Fulfilled<T>.Assoc", %swift.type* %"Fulfilled<T>", i8** %"Fulfilled<T>.Assocked")
 // CHECK:         [[T0:%.*]] = bitcast %swift.type* %"Fulfilled<T>" to i8***
-// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 5
+// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 4
 // CHECK-NEXT:    [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load
 // CHECK-NEXT:    ret i8** [[T2]]
 
@@ -108,10 +108,10 @@
 // CHECK-NEXT:     ret %swift.type* [[T0]]
 // CHECK:        fetch:
 // CHECK-NEXT:    [[T0:%.*]] = bitcast %swift.type* %"Computed<T, U>" to %swift.type**
-// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3
+// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 2
 // CHECK-NEXT:    [[T:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
 // CHECK:         [[T0:%.*]] = bitcast %swift.type* %"Computed<T, U>" to %swift.type**
-// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 4
+// CHECK-NEXT:    [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3
 // CHECK-NEXT:    [[U:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load
 // CHECK-NEXT:    [[FETCH_RESULT]] = call %swift.type* @_T023associated_type_witness4PairVMa(%swift.type* [[T]], %swift.type* [[U]])
 // CHECK-NEXT:    store atomic %swift.type* [[FETCH_RESULT]], %swift.type** [[CACHE]] release, align 8
diff --git a/test/IRGen/class_bounded_generics.swift b/test/IRGen/class_bounded_generics.swift
index 184f8ae..573a13b 100644
--- a/test/IRGen/class_bounded_generics.swift
+++ b/test/IRGen/class_bounded_generics.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-ir -primary-file %s -disable-objc-attr-requires-foundation-module | %FileCheck %s
+// RUN: %target-swift-frontend -emit-ir -primary-file %s -disable-objc-attr-requires-foundation-module | %FileCheck %s
 
 // REQUIRES: CPU=x86_64
 // XFAIL: linux
@@ -9,7 +9,7 @@
 protocol ClassBound2 : class {
   func classBoundMethod2()
 }
-protocol ClassBoundBinary : class, ClassBound {
+protocol ClassBoundBinary : ClassBound {
   func classBoundBinaryMethod(_ x: Self)
 }
 @objc protocol ObjCClassBound {
@@ -214,7 +214,7 @@
 }
 
 // CHECK-LABEL: define hidden swiftcc { i64, %objc_object*, i64 } @_T022class_bounded_generics0A28_generic_field_struct_fields{{[_0-9a-zA-Z]*}}F(i64, %objc_object*, i64, %swift.type* %T, i8** %T.ClassBound)
-func class_generic_field_struct_fields<T : ClassBound>
+func class_generic_field_struct_fields<T>
 (_ x:ClassGenericFieldStruct<T>) -> (Int, T, Int) {
   return (x.x, x.y, x.z)
 }
@@ -226,7 +226,7 @@
 }
 
 // CHECK-LABEL: define hidden swiftcc { i64, %objc_object*, i64 } @_T022class_bounded_generics0a15_generic_field_A7_fields{{[_0-9a-zA-Z]*}}F(%T22class_bounded_generics017ClassGenericFieldD0C*)
-func class_generic_field_class_fields<T : ClassBound>
+func class_generic_field_class_fields<T>
 (_ x:ClassGenericFieldClass<T>) -> (Int, T, Int) {
   return (x.x, x.y, x.z)
   // CHECK: getelementptr inbounds %T22class_bounded_generics017ClassGenericFieldD0C, %T22class_bounded_generics017ClassGenericFieldD0C* %0, i32 0, i32 1
@@ -273,3 +273,36 @@
     s = S.init()
   }
 }
+
+// CHECK-LABEL: define hidden swiftcc void @_T022class_bounded_generics14takes_metatypeyxmlF(%swift.type*, %swift.type* %T)
+func takes_metatype<T>(_: T.Type) {}
+
+// CHECK-LABEL: define hidden swiftcc void @_T022class_bounded_generics023archetype_with_generic_A11_constraintyx1t_tAA1ACyq_GRbzr0_lF(%T22class_bounded_generics1AC.2*, %swift.type* %T)
+// CHECK:      [[ISA_ADDR:%.*]] = bitcast %T22class_bounded_generics1AC.2* %0 to %swift.type**
+// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
+// CHECK-NEXT: call swiftcc void @_T022class_bounded_generics14takes_metatypeyxmlF(%swift.type* %T, %swift.type* %T)
+// CHECK-NEXT: [[ISA_PTR:%.*]] = bitcast %swift.type* [[ISA]] to %swift.type**
+// CHECK-NEXT: [[U_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[ISA_PTR]], i64 10
+// CHECK-NEXT: [[U:%.*]] = load %swift.type*, %swift.type** [[U_ADDR]]
+// CHECK-NEXT: call swiftcc void @_T022class_bounded_generics14takes_metatypeyxmlF(%swift.type* %U, %swift.type* %U)
+// CHECK:      ret void
+
+func archetype_with_generic_class_constraint<T, U>(t: T) where T : A<U> {
+  takes_metatype(T.self)
+  takes_metatype(U.self)
+}
+
+// CHECK-LABEL: define hidden swiftcc void @_T022class_bounded_generics029calls_archetype_with_generic_A11_constraintyAA1ACyxG1a_tlF(%T22class_bounded_generics1AC*) #0 {
+// CHECK:      [[ISA_ADDR:%.*]] = getelementptr inbounds %T22class_bounded_generics1AC, %T22class_bounded_generics1AC* %0, i32 0, i32 0, i32 0
+// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
+// CHECK:      [[SELF:%.*]] = bitcast %T22class_bounded_generics1AC* %0 to %T22class_bounded_generics1AC.2*
+// CHECK-NEXT: [[ISA_PTR:%.*]] = bitcast %swift.type* [[ISA]] to %swift.type**
+// CHECK-NEXT: [[T_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[ISA_PTR]], i64 10
+// CHECK-NEXT: [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
+// CHECK-NEXT: [[A_OF_T:%.*]] = call %swift.type* @_T022class_bounded_generics1ACMa(%swift.type* [[T]])
+// CHECK-NEXT: call swiftcc void @_T022class_bounded_generics023archetype_with_generic_A11_constraintyx1t_tAA1ACyq_GRbzr0_lF(%T22class_bounded_generics1AC.2* [[SELF]], %swift.type* [[A_OF_T]])
+// CHECK:      ret void
+
+func calls_archetype_with_generic_class_constraint<T>(a: A<T>) {
+  archetype_with_generic_class_constraint(t: a)
+}
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index 6985832..e6d1f54 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -107,75 +107,86 @@
 // CHECK: [[DYNAMICSINGLETON_FIELD_NAMES:@.*]] = private constant [7 x i8] c"value\00\00"
 // CHECK: [[DYNAMICSINGLETON_NAME:@.*]] = private constant [25 x i8] c"4enum16DynamicSingletonO\00"
 // CHECK: @_T04enum16DynamicSingletonOMn = hidden constant <{ {{.*}} i32 }> <{
-// CHECK:   [25 x i8]* [[DYNAMICSINGLETON_NAME]]
+// CHECK-SAME:   [25 x i8]* [[DYNAMICSINGLETON_NAME]]
 // --       One payload
-// CHECK:   i32 1,
+// CHECK-SAME:   i32 1,
 // --       No empty cases
-// CHECK:   i32 0,
+// CHECK-SAME:   i32 0,
 // --       Case names
-// CHECK:   [[DYNAMICSINGLETON_FIELD_NAMES]]
+// CHECK-SAME:   [[DYNAMICSINGLETON_FIELD_NAMES]]
 // --       Case type accessor
-// CHECK:   @get_field_types_DynamicSingleton
+// CHECK-SAME:   @get_field_types_DynamicSingleton
 // --       generic parameter vector offset
-// CHECK:   i32 3,
+// CHECK-SAME:   i32 2,
 // --       generic parameter vector length; witness table counts
-// CHECK:   i32 1, i32 0
-// CHECK: }>
+// CHECK-SAME:   i32 1, i32 1
+// --       nesting depth
+// CHECK-SAME:   i16 1
+// --       flags
+// CHECK-SAME:   i16 0
+// --       generic parameters at depth 0
+// CHECK-SAME:   i32 1
+// CHECK-SAME: }>
 
 // CHECK: @_T04enum16DynamicSingletonOMP = internal global <{ {{.*}}, [16 x i8*] }> <{
-// CHECK:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_DynamicSingleton
-// CHECK:   @_T04enum16DynamicSingletonOMn
-// CHECK:   i8* null
-// CHECK:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum16DynamicSingletonOwxs to i8*)
-// CHECK:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum16DynamicSingletonOwxg to i8*)
+// CHECK-SAME:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_DynamicSingleton
+// CHECK-SAME:   @_T04enum16DynamicSingletonOMn
+// CHECK-SAME:   i8* null
+// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum16DynamicSingletonOwxs to i8*)
+// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum16DynamicSingletonOwxg to i8*)
 
 // -- No-payload enums have extra inhabitants in
 //    their value witness table.
 // CHECK: @_T04enum10NoPayloadsOWV = internal constant [16 x i8*] [
 // -- ...
 // -- size
-// CHECK:   i8* inttoptr ([[WORD:i32|i64]] 1 to i8*),
+// CHECK-SAME:   i8* inttoptr ([[WORD:i32|i64]] 1 to i8*),
 // -- flags                 0x24_0000 - alignment 1, has extra inhabitants and enum witnesses
-// CHECK:   i8* inttoptr ([[WORD]] 2359296 to i8*),
+// CHECK-SAME:   i8* inttoptr ([[WORD]] 2359296 to i8*),
 // -- stride
-// CHECK:   i8* inttoptr ([[WORD]] 1 to i8*),
+// CHECK-SAME:   i8* inttoptr ([[WORD]] 1 to i8*),
 // -- num extra inhabitants (256 - 3 valid states)
-// CHECK:   i8* inttoptr ([[WORD]] 253 to i8*)
+// CHECK-SAME:   i8* inttoptr ([[WORD]] 253 to i8*)
 // -- storeExtraInhabitant
-// CHECK:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum10NoPayloadsOwxs to i8*)
+// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum10NoPayloadsOwxs to i8*)
 // -- getExtraInhabitantIndex
-// CHECK:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum10NoPayloadsOwxg to i8*)
-// CHECK: ]
+// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum10NoPayloadsOwxg to i8*)
+// CHECK-SAME: ]
 
 // -- Single-payload enums take unused extra inhabitants from their payload
 //    as their own.
 // CHECK: @_T04enum19SinglePayloadNestedOWV = internal constant [16 x i8*] [
 // -- ...
 // -- size
-// CHECK:   i8* inttoptr ([[WORD]] 1 to i8*),
+// CHECK-SAME:   i8* inttoptr ([[WORD]] 1 to i8*),
 // -- flags                 0x4_0000 - alignment 1, has extra inhabitants
-// CHECK:   i8* inttoptr ([[WORD]] 2359296 to i8*),
+// CHECK-SAME:   i8* inttoptr ([[WORD]] 2359296 to i8*),
 // -- stride
-// CHECK:   i8* inttoptr ([[WORD]] 1 to i8*),
+// CHECK-SAME:   i8* inttoptr ([[WORD]] 1 to i8*),
 // -- num extra inhabitants (253 from payload - 3 empty cases)
-// CHECK:   i8* inttoptr ([[WORD]] 250 to i8*)
+// CHECK-SAME:   i8* inttoptr ([[WORD]] 250 to i8*)
 // -- storeExtraInhabitant
-// CHECK:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum19SinglePayloadNestedOwxs to i8*)
+// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum19SinglePayloadNestedOwxs to i8*)
 // -- getExtraInhabitantIndex
-// CHECK:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum19SinglePayloadNestedOwxg to i8*)
-// CHECK: ]
+// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum19SinglePayloadNestedOwxg to i8*)
+// CHECK-SAME: ]
 
 
 // CHECK: @_T04enum20DynamicSinglePayloadOMP = internal global <{ {{.*}}, [16 x i8*] }> <{
-// CHECK:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_DynamicSinglePayload
-// CHECK:   i8* null
-// CHECK:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum20DynamicSinglePayloadOwxs to i8*)
-// CHECK:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum20DynamicSinglePayloadOwxg to i8*)
+// CHECK-SAME:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_DynamicSinglePayload
+// CHECK-SAME:   i8* null
+// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T04enum20DynamicSinglePayloadOwxs to i8*)
+// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T04enum20DynamicSinglePayloadOwxg to i8*)
 
 // CHECK: @_T04enum18MultiPayloadNestedOWV = internal constant [16 x i8*] [
-// CHECK:   i8* inttoptr ([[WORD]] 9 to i8*),
-// CHECK:   i8* inttoptr ([[WORD]] 16 to i8*)
-// CHECK: ]
+// -- size
+// CHECK-32-SAME:   i8* inttoptr ([[WORD]] 5 to i8*),
+// CHECK-64-SAME:   i8* inttoptr ([[WORD]] 9 to i8*),
+// -- flags                 0x250003 - alignment 4
+// CHECK-32-SAME:   i8* inttoptr ([[WORD]] {{2424835|2097155}} to i8*)
+// -- flags                 0x200007 - alignment 8
+// CHECK-64-SAME:   i8* inttoptr ([[WORD]] 2097159 to i8*)
+// CHECK-SAME: ]
 
 enum Empty {}
 
@@ -2660,10 +2671,10 @@
 // CHECK:   [[T:%T]] = load %swift.type*, %swift.type** [[T0]],
 // CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_pattern* %0, i8** %1)
 // CHECK:   [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
-// CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 3
+// CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 2
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* [[T]] to i8*
 // CHECK:   store i8* [[T0]], i8** [[T1]]
-// CHECK:   [[VWT:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 5
+// CHECK:   [[VWT:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 4
 // CHECK:   [[T0:%.*]] = bitcast i8** [[VWT]] to i8*
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -1
 // CHECK:   store i8* [[T0]], i8** [[T1]]
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index e58ee04..f2f4ece 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -254,7 +254,7 @@
 
 // CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @_T014resilient_enum32ResilientMultiPayloadGenericEnumO0B11_resilienceE16getTypeParameterxmyF(%swift.type* %"ResilientMultiPayloadGenericEnum<T>", %swift.opaque* noalias nocapture swiftself)
 // CHECK: [[METADATA:%.*]] = bitcast %swift.type* %"ResilientMultiPayloadGenericEnum<T>" to %swift.type**
-// CHECK-NEXT: [[T_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[METADATA]], [[INT]] 3
+// CHECK-NEXT: [[T_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[METADATA]], [[INT]] 2
 // CHECK-NEXT: [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
   public func getTypeParameter() -> T.Type {
     return T.self
diff --git a/test/IRGen/enum_value_semantics.sil b/test/IRGen/enum_value_semantics.sil
index 734169d..1f1800c 100644
--- a/test/IRGen/enum_value_semantics.sil
+++ b/test/IRGen/enum_value_semantics.sil
@@ -119,7 +119,6 @@
 // CHECK-SAME:   i8** getelementptr inbounds ([16 x i8*], [16 x i8*]* @_T020enum_value_semantics20SinglePayloadTrivialOWV, i32 0, i32 0),
 // CHECK-SAME:   i64 2,
 // CHECK-SAME:   {{.*}}* @_T020enum_value_semantics20SinglePayloadTrivialOMn
-// CHECK-SAME:   %swift.type* null
 // CHECK-SAME: }>
 
 
@@ -150,13 +149,12 @@
 // CHECK-SAME:   i8** getelementptr inbounds ([16 x i8*], [16 x i8*]* @_T020enum_value_semantics23SinglePayloadNontrivialOWV, i32 0, i32 0),
 // CHECK-SAME:   i64 2,
 // CHECK-SAME:   {{.*}}* @_T020enum_value_semantics23SinglePayloadNontrivialOMn
-// CHECK-SAME:   %swift.type* null
 // CHECK-SAME: }>
 
 
 // CHECK-LABEL: @_T020enum_value_semantics18GenericFixedLayoutOMP = internal global <{{[{].*\* [}]}}> <{
 // CHECK:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_GenericFixedLayout
-// CHECK:   i32 48, i16 1, i16 8,
+// CHECK:   i32 40, i16 1, i16 8,
 // CHECK:   [16 x i8*] zeroinitializer,
 // CHECK:   i8** getelementptr inbounds ([16 x i8*], [16 x i8*]* @_T020enum_value_semantics18GenericFixedLayoutOWV, i32 0, i32 0),
 // CHECK:   i64 2,
diff --git a/test/IRGen/field_type_vectors.sil b/test/IRGen/field_type_vectors.sil
index 9908a8c..e526e07 100644
--- a/test/IRGen/field_type_vectors.sil
+++ b/test/IRGen/field_type_vectors.sil
@@ -13,9 +13,9 @@
 // CHECK-LABEL: @_T018field_type_vectors3BarVMn = hidden constant
 // CHECK:         %swift.type** (%swift.type*)* [[BAR_TYPES_ACCESSOR:@[A-Za-z0-9_]*]]
 // CHECK-LABEL: @_T018field_type_vectors3BarVMP = internal global
-// -- There should be 5 words between the address point and the field type
+// -- There should be 4 words between the address point and the field type
 //    vector slot, with type %swift.type**
-// CHECK:         i64, i64, i64, i64, %swift.type*, %swift.type**
+// CHECK:         i64, i64, i64, %swift.type*, %swift.type**
 struct Bar<T> {
   var y: Int
 }
@@ -23,9 +23,9 @@
 // CHECK-LABEL: @_T018field_type_vectors3BasVMn = hidden constant
 // CHECK:         %swift.type** (%swift.type*)* [[BAS_TYPES_ACCESSOR:@[A-Za-z0-9_]*]]
 // CHECK-LABEL: @_T018field_type_vectors3BasVMP = internal global
-// -- There should be 7 words between the address point and the field type
+// -- There should be 6 words between the address point and the field type
 //    vector slot, with type %swift.type**
-// CHECK:         i64, i64, i64, i64, i64, %swift.type*, %swift.type*, %swift.type**
+// CHECK:          i64, i64, i64, %swift.type*, %swift.type*, %swift.type**
 struct Bas<T, U> {
   var foo: Foo
   var bar: Bar<T>
@@ -83,8 +83,8 @@
 
 // CHECK: define{{( protected)?}} private %swift.type** [[BAR_TYPES_ACCESSOR]](%swift.type* %"Bar<T>")
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* %"Bar<T>" to %swift.type***
-// -- 5 words between the address point and the slot
-// CHECK:   [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 5
+// -- 4 words between the address point and the slot
+// CHECK:   [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 4
 // CHECK:   load %swift.type**, %swift.type*** [[SLOT]], align 8
 // CHECK:   br
 // CHECK-NOT: load %swift.type*,
@@ -93,8 +93,8 @@
 
 // CHECK: define{{( protected)?}} private %swift.type** [[BAS_TYPES_ACCESSOR]](%swift.type* %"Bas<T, U>")
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* %"Bas<T, U>" to %swift.type***
-// -- 7 words between the address point and the slot
-// CHECK:   [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 7
+// -- 6 words between the address point and the slot
+// CHECK:   [[SLOT:%.*]] = getelementptr inbounds %swift.type**, %swift.type*** [[T0]], i32 6
 // CHECK:   load %swift.type**, %swift.type*** [[SLOT]], align 8
 // CHECK:   br
 // CHECK:   store {{.*}} @_T018field_type_vectors3FooVMf
diff --git a/test/IRGen/foreign_types.sil b/test/IRGen/foreign_types.sil
index b52ce5b..ac6281d 100644
--- a/test/IRGen/foreign_types.sil
+++ b/test/IRGen/foreign_types.sil
@@ -4,14 +4,12 @@
 import c_layout
 
 // CHECK-LABEL: @_T0SC14HasNestedUnionV18__Unnamed_struct_sVN = linkonce_odr hidden global
-// CHECK-SAME:  void (%swift.type*)* @initialize_metadata___Unnamed_struct_s,
 // CHECK-SAME:  i8* getelementptr inbounds
 // CHECK-SAME:  %swift.type* null,
-// CHECK-SAME:  [[INT:i[0-9]+]] 1,
+// CHECK-SAME:  [[INT:i[0-9]+]] 0,
 // CHECK-SAME:  @_T0SC14HasNestedUnionV18__Unnamed_struct_sVWV
 // CHECK-SAME:  [[INT]] 1,
 // CHECK-SAME:  [[INT]] sub ({{.*}}),
-// CHECK-SAME:  %swift.type* null,
 // CHECK-SAME:  [[INT]] 0,
 // CHECK-SAME:  [[INT]] 4 }
 
@@ -22,10 +20,3 @@
   %ret = tuple ()
   return %ret : $()
 }
-
-// CHECK-LABEL: define private void @initialize_metadata___Unnamed_struct_s
-// CHECK:       [[PARENT:%.*]] = call %swift.type* @_T0SC14HasNestedUnionVMa()
-// CHECK-NEXT:  [[T0:%.]] = bitcast %swift.type* %0 to %swift.type**
-// CHECK-NEXT:  [[T1:%.]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], [[INT]] 2
-// CHECK-NEXT:  store %swift.type* [[PARENT]], %swift.type** [[T1]],
-// CHECK-NEXT:  ret void
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index e3f4c6f..62ab6c6 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -27,8 +27,12 @@
 // CHECK-SAME:   i32 10,
 // --       generic parameter count, primary count
 // CHECK-SAME:   i32 1, i32 1,
+// --       nesting depth
+// CHECK-SAME:   i16 1,
 // --       flags -- has vtable
-// CHECK-SAME:   i32 4,
+// CHECK-SAME:   i16 4,
+// --       generic parameters at depth 0
+// CHECK-SAME:   i32 1,
 // --       vtable offset
 // CHECK-SAME:   i32 11,
 // --       vtable size
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 4d3ee50..1796e4b 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -12,39 +12,45 @@
 // CHECK: [[SINGLEDYNAMIC_FIELDS:@.*]] = private constant [3 x i8] c"x\00\00"
 // CHECK: @_T015generic_structs13SingleDynamicVMn = hidden constant <{ {{.*}} i32 }> <{
 // --       name
-// CHECK:   [34 x i8]* [[SINGLEDYNAMIC_NAME]]
+// CHECK-SAME:   [34 x i8]* [[SINGLEDYNAMIC_NAME]]
 // --       field count
-// CHECK:   i32 1,
+// CHECK-SAME:   i32 1,
 // --       field offset vector offset
-// CHECK:   i32 3,
+// CHECK-SAME:   i32 2,
 // --       field names
-// CHECK:   [3 x i8]* [[SINGLEDYNAMIC_FIELDS]]
+// CHECK-SAME:   [3 x i8]* [[SINGLEDYNAMIC_FIELDS]]
 // --       generic metadata pattern, kind 1 (struct)
-// CHECK:   i32 add ({{.*}}@_T015generic_structs13SingleDynamicVMP{{.*}}, i32 1)
+// CHECK-SAME:   i32 add ({{.*}}@_T015generic_structs13SingleDynamicVMP{{.*}}, i32 1)
 // --       generic parameter vector offset
-// CHECK:   i32 4,
-// --       generic parameter count, primary counts; generic parameter witness counts
-// CHECK:   i32 1, i32 1, i32 0
-// CHECK: }>
+// CHECK-SAME:   i32 3,
+// --       generic parameter count, primary count
+// CHECK-SAME:   i32 1, i32 1
+// --       nesting depth
+// CHECK-SAME: i16 1,
+// --       flags
+// CHECK-SAME: i16 0,
+// --       generic parameters at depth 0
+// CHECK-SAME: i32 1
+// CHECK-SAME: }>
 // CHECK: @_T015generic_structs13SingleDynamicVMP = internal global <{ {{.*}} }> <{
 // -- template header
-// CHECK:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_SingleDynamic,
-// CHECK:   i32 160, i16 1, i16 8, [{{[0-9]+}} x i8*] zeroinitializer,
+// CHECK-SAME:   %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_SingleDynamic,
+// CHECK-SAME:   i32 152, i16 1, i16 8, [{{[0-9]+}} x i8*] zeroinitializer,
 // -- placeholder for vwtable pointer
-// CHECK:   i8* null,
+// CHECK-SAME:   i8* null,
 // -- address point
-// CHECK:   i64 1, {{.*}}* @_T015generic_structs13SingleDynamicVMn
+// CHECK-SAME:   i64 1, {{.*}}* @_T015generic_structs13SingleDynamicVMn
 // -- field offset vector; generic parameter vector
-// CHECK:   i64 0, %swift.type* null,
+// CHECK-SAME:   i64 0, %swift.type* null,
 // -- tail-allocated vwtable pattern
-// CHECK:   i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @_T015generic_structs13SingleDynamicVwCP to i8*),
+// CHECK-SAME:   i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @_T015generic_structs13SingleDynamicVwCP to i8*),
 // -- ...
 // -- placeholder for size, flags, stride
-// CHECK:   i8* null, i8* null, i8* null
+// CHECK-SAME:   i8* null, i8* null, i8* null
 // -- extra inhabitants
-// CHECK:   i8* null,
-// CHECK:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T015generic_structs13SingleDynamicVwxs to i8*),
-// CHECK:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T015generic_structs13SingleDynamicVwxg to i8*)] }>
+// CHECK-SAME:   i8* null,
+// CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_T015generic_structs13SingleDynamicVwxs to i8*),
+// CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_T015generic_structs13SingleDynamicVwxg to i8*)] }>
 // CHECK-NOT: @_T015generic_structs13SingleDynamicVWV
 
 // -- Nominal type descriptor for generic struct with protocol requirements
@@ -57,15 +63,21 @@
 // --       field count
 // CHECK-SAME: i32 2,
 // --       field offset vector offset
-// CHECK-SAME: i32 3,
+// CHECK-SAME: i32 2,
 // --       field names
 // CHECK-SAME: [5 x i8]* [[DYNAMICWITHREQUIREMENTS_FIELDS]]
 // --       generic metadata pattern
 // CHECK-SAME: i32 add ({{.*}}@_T015generic_structs23DynamicWithRequirementsVMP{{.*}}, i32 1)
 // --       generic parameter vector offset
-// CHECK-SAME: i32 5,
-// --       generic requirements count; generic arguments count; flags; generic parameter witness counts
-// CHECK-SAME: i32 4, i32 2, i32 0
+// CHECK-SAME: i32 4,
+// --       generic requirements count; generic arguments count
+// CHECK-SAME: i32 4, i32 2
+// --       nesting depth
+// CHECK-SAME: i16 1,
+// --       flags
+// CHECK-SAME: i16 0,
+// --       generic parameters at depth 0
+// CHECK-SAME: i32 2
 // CHECK-SAME: }>
 
 // CHECK: @_T015generic_structs23DynamicWithRequirementsVMP = internal global <{ {{.*}} }> <{
@@ -75,14 +87,14 @@
 
 // -- Fixed-layout struct metadata contains fixed field offsets
 // CHECK: @_T015generic_structs6IntishVMf = internal constant <{ {{.*}} i64 }> <{
-// CHECK:   i64 0
-// CHECK: }>
+// CHECK-SAME:   i64 0
+// CHECK-SAME: }>
 // CHECK: @_T015generic_structs7CharethVMf = internal constant <{ {{.*}} i64 }> <{
-// CHECK:   i64 0
-// CHECK: }>
+// CHECK-SAME:   i64 0
+// CHECK-SAME: }>
 // CHECK: @_T015generic_structs8StringlyVMf = internal constant <{ {{.*}} i64, i64, i64 }> <{
-// CHECK:   i64 0, i64 8, i64 16
-// CHECK: }>
+// CHECK-SAME:   i64 0, i64 8, i64 16
+// CHECK-SAME: }>
 
 struct SingleDynamic<T> {
   var x : T
@@ -134,7 +146,7 @@
   %a = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.a2
 
   // CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i64*
-  // CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i64, i64* [[METADATA]], i64 3
+  // CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i64, i64* [[METADATA]], i64 2
   // CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[FIELD_OFFSET_VECTOR]], i32 2
   // CHECK: [[FIELD_OFFSET:%.*]] = load i64, i64* [[FIELD_OFFSET_ADDR]], align 8
   // CHECK: [[BYTES:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0 to i8*
@@ -143,7 +155,7 @@
   %b = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.b
 
   // CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i64*
-  // CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i64, i64* [[METADATA]], i64 3
+  // CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i64, i64* [[METADATA]], i64 2
   // CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[FIELD_OFFSET_VECTOR]], i32 3
   // CHECK: [[FIELD_OFFSET:%.*]] = load i64, i64* [[FIELD_OFFSET_ADDR]], align 8
   // CHECK: [[BYTES:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0 to i8*
@@ -153,7 +165,7 @@
   %c = struct_element_addr %5 : $*SingleDynamic<B>, #SingleDynamic.x
 
   // CHECK: [[METADATA:%.*]] = bitcast %swift.type* {{%.*}} to i64*
-  // CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i64, i64* [[METADATA]], i64 3
+  // CHECK: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds i64, i64* [[METADATA]], i64 2
   // CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[FIELD_OFFSET_VECTOR]], i32 4
   // CHECK: [[FIELD_OFFSET:%.*]] = load i64, i64* [[FIELD_OFFSET_ADDR]], align 8
   // CHECK: [[BYTES:%.*]] = bitcast %T15generic_structs14ComplexDynamicV* %0 to i8*
@@ -204,17 +216,17 @@
 // CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericValueMetadata(%swift.type_pattern* %0, i8** %1)
 // CHECK:   [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
 //   Fill type argument.
-// CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 4
+// CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 3
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* %T to i8*
 // CHECK:   store i8* [[T0]], i8** [[T1]], align 8
 //   Fill vwtable reference.
-// CHECK:   [[VWTABLE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 6
+// CHECK:   [[VWTABLE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 5
 // CHECK:   [[VWTABLE_VAL:%.*]] = bitcast i8** [[VWTABLE_ADDR]] to i8*
 // CHECK:   [[VWTABLE_SLOT_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 -1
 // CHECK:   store i8* [[VWTABLE_VAL]], i8** [[VWTABLE_SLOT_ADDR]], align 8
 //   Lay out fields.
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i64*
-// CHECK:   [[T1:%.*]] = getelementptr inbounds i64, i64* [[T0]], i64 3
+// CHECK:   [[T1:%.*]] = getelementptr inbounds i64, i64* [[T0]], i64 2
 // CHECK:   [[T2:%.*]] = getelementptr inbounds i8**, i8*** [[TYPES:%.*]], i32 0
 // CHECK:   call void @swift_initStructMetadata_UniversalStrategy(i64 1, i8*** [[TYPES]], i64* [[T1]], i8** [[VWTABLE_ADDR]])
 // CHECK:   ret %swift.type* [[METADATA]]
diff --git a/test/IRGen/generic_vtable.swift b/test/IRGen/generic_vtable.swift
index 00c3cb8..bbba876 100644
--- a/test/IRGen/generic_vtable.swift
+++ b/test/IRGen/generic_vtable.swift
@@ -21,8 +21,12 @@
 //// Nominal type descriptor for 'Base' does not have any method descriptors.
 
 // CHECK-LABEL: @_T014generic_vtable4BaseCMn = {{(protected )?}}constant
+// -- nesting depth
+// CHECK-SAME: i16 1,
 // -- flags: has vtable
-// CHECK-SAME: i32 4,
+// CHECK-SAME: i16 4,
+// -- generic parameters at depth 0
+// CHECK-SAME: i32 0,
 // -- vtable offset
 // CHECK-SAME: i32 10,
 // -- vtable size
@@ -46,8 +50,12 @@
 //// Nominal type descriptor for 'Derived' has method descriptors.
 
 // CHECK-LABEL: @_T014generic_vtable7DerivedCMn = {{(protected )?}}constant
+// -- nesting depth
+// CHECK-SAME: i16 1,
 // -- flags: has vtable
-// CHECK-SAME: i32 4,
+// CHECK-SAME: i16 4,
+// -- generic parameters at depth 0
+// CHECK-SAME: i32 1,
 // -- vtable offset
 // CHECK-SAME: i32 14,
 // -- vtable size
@@ -76,8 +84,12 @@
 //// Nominal type descriptor for 'Concrete' has method descriptors.
 
 // CHECK-LABEL: @_T014generic_vtable8ConcreteCMn = {{(protected )?}}constant
+// -- nesting depth
+// CHECK-SAME: i16 1,
 // -- flags: has vtable
-// CHECK-SAME: i32 4,
+// CHECK-SAME: i16 4,
+// -- generic parameters at depth 0
+// CHECK-SAME: i32 0,
 // -- vtable offset
 // CHECK-SAME: i32 15,
 // -- vtable size
diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil
index b7dbb0e..8e5d64e 100644
--- a/test/IRGen/keypaths.sil
+++ b/test/IRGen/keypaths.sil
@@ -200,8 +200,8 @@
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 //             -- struct with runtime-resolved offset
 // CHECK-SAME: <i32 0x1ffffffe>,
-// CHECK-32-SAME: i32 12 }>
-// CHECK-64-SAME: i32 24 }>
+// CHECK-32-SAME: i32 8 }>
+// CHECK-64-SAME: i32 16 }>
 
 // -- %j: Gen<A>.y
 // CHECK: [[KP_J:@keypath.*]] = private global <{ {{.*}} }> <{
@@ -213,8 +213,8 @@
 // CHECK-64-SAME: [4 x i8] zeroinitializer,
 //             -- struct with runtime-resolved offset
 // CHECK-SAME: <i32 0x1ffffffe>,
-// CHECK-32-SAME: i32 16 }>
-// CHECK-64-SAME: i32 32 }>
+// CHECK-32-SAME: i32 12 }>
+// CHECK-64-SAME: i32 24 }>
 
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @stored_property_fixed_offsets()
 sil @stored_property_fixed_offsets : $@convention(thin) () -> () {
diff --git a/test/IRGen/nested_generics.swift b/test/IRGen/nested_generics.swift
new file mode 100644
index 0000000..13bf3e3
--- /dev/null
+++ b/test/IRGen/nested_generics.swift
@@ -0,0 +1,81 @@
+// RUN: %target-swift-frontend %s -emit-ir | %FileCheck %s --check-prefix=CHECK
+
+// REQUIRES: CPU=x86_64
+
+func blah<T>(_: T.Type) {}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @_T015nested_generics13makeAMetadatayyF()
+public func makeAMetadata() {
+  blah(OuterGenericStruct<Int>.InnerGenericStruct<String>.self)
+  blah(OuterGenericStruct<Int>.InnerConcreteStruct.self)
+
+  blah(OuterGenericClass<Int>.InnerGenericClass<String>.self)
+  blah(OuterGenericClass<Int>.InnerConcreteClass.self)
+}
+
+// Type constructor for OuterGenericStruct<Int>.InnerGenericStruct<String>
+// CHECK-LABEL: define linkonce_odr hidden %swift.type* @_T015nested_generics18OuterGenericStructV05InnerdE0VySi_SSGMa()
+// CHECK: call %swift.type* @_T015nested_generics18OuterGenericStructV05InnerdE0VMa(%swift.type* @_T0SiN, %swift.type* @_T0SSN)
+// CHECK: ret %swift.type
+
+// Type constructor for OuterGenericStruct<T>.InnerGenericStruct<U>
+// CHECK-LABEL: define{{( protected)?}} %swift.type* @_T015nested_generics18OuterGenericStructV05InnerdE0VMa(%swift.type*, %swift.type*)
+
+// Type constructor for OuterGenericStruct<Int>.InnerConcreteStruct
+// CHECK-LABEL: define linkonce_odr hidden %swift.type* @_T015nested_generics18OuterGenericStructV013InnerConcreteE0VySi_GMa()
+// CHECK: call %swift.type* @_T015nested_generics18OuterGenericStructV013InnerConcreteE0VMa(%swift.type* @_T0SiN)
+// CHECK: ret %swift.type
+
+// Type constructor for OuterGenericStruct<T>.InnerConcreteStruct
+// CHECK-LABEL: define{{( protected)?}} %swift.type* @_T015nested_generics18OuterGenericStructV013InnerConcreteE0VMa(%swift.type*)
+
+public struct OuterGenericStruct<T> {
+  public struct InnerGenericStruct<U> {
+    public func method() {
+      blah(T.self)
+      blah(U.self)
+    }
+  }
+
+  public struct InnerConcreteStruct {
+    public func method() {
+      blah(T.self)
+    }
+  }
+}
+
+// Type constructor for OuterGenericClass<Int>.InnerGenericClass<String>
+// CHECK-LABEL: define linkonce_odr hidden %swift.type* @_T015nested_generics17OuterGenericClassC05InnerdE0CySi_SSGMa()
+// CHECK: call %swift.type* @_T015nested_generics17OuterGenericClassC05InnerdE0CMa(%swift.type* @_T0SiN, %swift.type* @_T0SSN)
+
+// Type constructor for OuterGenericClass<T>.InnerGenericClass<U>
+// CHECK-LABEL: define{{( protected)?}} %swift.type* @_T015nested_generics17OuterGenericClassC05InnerdE0CMa(%swift.type*, %swift.type*)
+
+// Type constructor for OuterGenericClass<Int>.InnerConcreteClass
+// CHECK-LABEL: define linkonce_odr hidden %swift.type* @_T015nested_generics17OuterGenericClassC013InnerConcreteE0CySi_GMa()
+// CHECK: call %swift.type* @_T015nested_generics17OuterGenericClassC013InnerConcreteE0CMa(%swift.type* @_T0SiN)
+// CHECK: ret %swift.type
+
+// Type constructor for OuterGenericClass<T>.InnerConcreteClass
+// CHECK-LABEL: define{{( protected)?}} %swift.type* @_T015nested_generics17OuterGenericClassC013InnerConcreteE0CMa(%swift.type*)
+
+// Type constructor for OuterGenericStruct<T>
+// CHECK-LABEL: define{{( protected)?}} %swift.type* @_T015nested_generics18OuterGenericStructVMa(%swift.type*)
+
+// Type constructor for OuterGenericClass<T>
+// CHECK-LABEL: define{{( protected)?}} %swift.type* @_T015nested_generics17OuterGenericClassCMa(%swift.type*)
+
+public class OuterGenericClass<T> {
+  public class InnerGenericClass<U> {
+    public func method() {
+      blah(T.self)
+      blah(U.self)
+    }
+  }
+
+  public class InnerConcreteClass {
+    public func method() {
+      blah(T.self)
+    }
+  }
+}
diff --git a/test/IRGen/nested_types.sil b/test/IRGen/nested_types.sil
index 274a98b..f27fa25 100644
--- a/test/IRGen/nested_types.sil
+++ b/test/IRGen/nested_types.sil
@@ -32,7 +32,5 @@
 // CHECK-NEXT: ret %swift.type* [[T4]]
 
 // CHECK-LABEL: define private void @initialize_metadata_Inner
-// CHECK:      [[T0:%.*]] = call %swift.type* @_T012nested_types5OuterCMa()
-// CHECK-NEXT: store %swift.type* [[T0]], %swift.type** getelementptr inbounds (%swift.type*, %swift.type** bitcast ({{.*}} @_T012nested_types5OuterC5InnerVMf{{.*}}, [[INT:i[0-9]+]] 2), align
-// CHECK-NEXT: store atomic %swift.type* bitcast ({{.*}} @_T012nested_types5OuterC5InnerVMf{{.*}} to %swift.type*), %swift.type** @_T012nested_types5OuterC5InnerVML release, align
+// CHECK:      store atomic %swift.type* bitcast ({{.*}} @_T012nested_types5OuterC5InnerVMf{{.*}} to %swift.type*), %swift.type** @_T012nested_types5OuterC5InnerVML release, align
 // CHECK-NEXT: ret void
diff --git a/test/IRGen/struct_resilience.swift b/test/IRGen/struct_resilience.swift
index 7458d97..eed6368 100644
--- a/test/IRGen/struct_resilience.swift
+++ b/test/IRGen/struct_resilience.swift
@@ -59,7 +59,7 @@
 
 // CHECK: [[METADATA:%.*]] = call %swift.type* @_T016resilient_struct9RectangleVMa()
 // CHECK-NEXT: [[METADATA_ADDR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]*
-// CHECK-NEXT: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 3
+// CHECK-NEXT: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 2
 // CHECK-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[FIELD_OFFSET_VECTOR]], i32 2
 // CHECK-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]]
 // CHECK-NEXT: [[STRUCT_ADDR:%.*]] = bitcast %T16resilient_struct9RectangleV* %0 to i8*
@@ -116,7 +116,7 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc {{i32|i64}} @_T017struct_resilience26StructWithResilientStorageV1nSivg(%T17struct_resilience26StructWithResilientStorageV* {{.*}})
 // CHECK: [[METADATA:%.*]] = call %swift.type* @_T017struct_resilience26StructWithResilientStorageVMa()
 // CHECK-NEXT: [[METADATA_ADDR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]*
-// CHECK-NEXT: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 3
+// CHECK-NEXT: [[FIELD_OFFSET_VECTOR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 2
 // CHECK-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[FIELD_OFFSET_VECTOR]], i32 2
 // CHECK-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]]
 // CHECK-NEXT: [[STRUCT_ADDR:%.*]] = bitcast %T17struct_resilience26StructWithResilientStorageV* %0 to i8*
diff --git a/test/SILGen/inlineable_attribute.swift b/test/SILGen/inlineable_attribute.swift
index e747462..9150d51 100644
--- a/test/SILGen/inlineable_attribute.swift
+++ b/test/SILGen/inlineable_attribute.swift
@@ -74,3 +74,20 @@
 @_inlineable public func talkAboutAHorse(h: Horse) {
   _ = h.gallop
 }
+
+@_versioned class Base {
+  @_versioned
+  @_inlineable
+  init(horse: Horse) {}
+}
+
+// CHECK-LABEL: sil [serialized] @_T020inlineable_attribute7DerivedCfd : $@convention(method) (@guaranteed Derived) -> @owned Builtin.NativeObject
+// CHECK-LABEL: sil [serialized] @_T020inlineable_attribute7DerivedCfD : $@convention(method) (@owned Derived) -> ()
+
+// Make sure the synthesized delegating initializer is inlineable also
+
+// CHECK-LABEL: sil [serialized] @_T020inlineable_attribute7DerivedCAcA5HorseC5horse_tcfc : $@convention(method) (@owned Horse, @owned Derived) -> @owned Derived
+@_versioned class Derived : Base {
+  // Allow @_inlineable deinits
+  @_inlineable deinit {}
+}
diff --git a/test/SILGen/versioned_attribute.swift b/test/SILGen/versioned_attribute.swift
new file mode 100644
index 0000000..5a01525
--- /dev/null
+++ b/test/SILGen/versioned_attribute.swift
@@ -0,0 +1,17 @@
+// RUN: %target-swift-frontend -emit-silgen -enable-sil-ownership -emit-verbose-sil %s | %FileCheck %s
+
+@_versioned class Horse {
+  var mouth: AnyObject?
+}
+
+@_versioned class GiftHorse {
+  var mouth: AnyObject?
+
+  deinit {}
+}
+
+// CHECK-LABEL: sil @_T019versioned_attribute5HorseCfd : $@convention(method) (@guaranteed Horse) -> @owned Builtin.NativeObject
+// CHECK-LABEL: sil @_T019versioned_attribute5HorseCfD : $@convention(method) (@owned Horse) -> ()
+
+// CHEKC-LABEL: sil @_T019versioned_attribute9GiftHorseCfd : $@convention(method) (@guaranteed GiftHorse) -> @owned Builtin.NativeObject
+// CHECK-LABEL: sil @_T019versioned_attribute9GiftHorseCfD : $@convention(method) (@owned GiftHorse) -> ()
diff --git a/test/decl/protocol/recursive_requirement.swift b/test/decl/protocol/recursive_requirement.swift
index 30cd1a0..736d2af 100644
--- a/test/decl/protocol/recursive_requirement.swift
+++ b/test/decl/protocol/recursive_requirement.swift
@@ -76,14 +76,13 @@
   associatedtype Delta: Alpha
 }
 
-// FIXME: Redundancy diagnostics are an indication that we're getting
-// the minimization wrong. The errors prove it :D
+// FIXME: Redundancy diagnostics are odd here.
 struct Epsilon<T: Alpha, // expected-note{{conformance constraint 'U': 'Gamma' implied here}}
 // expected-warning@-1{{redundant conformance constraint 'T': 'Alpha'}}
                U: Gamma> // expected-warning{{redundant conformance constraint 'U': 'Gamma'}}
 // expected-note@-1{{conformance constraint 'T': 'Alpha' implied here}}
-  where T.Beta == U, // expected-error{{'Beta' is not a member type of 'T'}}
-        U.Delta == T {} // expected-error{{'Delta' is not a member type of 'U'}}
+  where T.Beta == U,
+        U.Delta == T {}
 
 // -----
 
diff --git a/test/stdlib/Inputs/VariadicBool/module.map b/test/stdlib/Inputs/VariadicBool/module.map
new file mode 100644
index 0000000..fa0bef5
--- /dev/null
+++ b/test/stdlib/Inputs/VariadicBool/module.map
@@ -0,0 +1,3 @@
+module VariadicBool {
+  header "variadicBool.h"
+}
diff --git a/test/stdlib/Inputs/VariadicBool/variadicBool.c b/test/stdlib/Inputs/VariadicBool/variadicBool.c
new file mode 100644
index 0000000..95aa6b4
--- /dev/null
+++ b/test/stdlib/Inputs/VariadicBool/variadicBool.c
@@ -0,0 +1,16 @@
+#include "variadicBool.h"
+
+int numberOfTrues(int count, va_list arguments) {  
+  int i, total;
+  total = 0;
+  
+  for(i = 0; i < count; i++) {
+    //we're passing int here because passing bool is actually incorrect since 
+    //bool is actually promoted to int in C
+    if(va_arg(arguments, int) == true) {
+      total += 1;
+    }
+  }
+  
+  return total;
+}
\ No newline at end of file
diff --git a/test/stdlib/Inputs/VariadicBool/variadicBool.h b/test/stdlib/Inputs/VariadicBool/variadicBool.h
new file mode 100644
index 0000000..7980068
--- /dev/null
+++ b/test/stdlib/Inputs/VariadicBool/variadicBool.h
@@ -0,0 +1,5 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+extern int numberOfTrues(int count, va_list arguments);
\ No newline at end of file
diff --git a/test/stdlib/TypeName.swift b/test/stdlib/TypeName.swift
index dfb93e4..496bd71 100644
--- a/test/stdlib/TypeName.swift
+++ b/test/stdlib/TypeName.swift
@@ -185,4 +185,28 @@
               _typeName(SomeOuterGenericClass<String>.SomeInnerGenericStruct<Int>.self));
 }
 
+extension SomeOuterGenericClass {
+  struct OtherInnerStruct {}
+  struct OtherInnerGenericStruct<U> {}
+}
+
+TypeNameTests.test("NestedInExtension") {
+  expectEqual("main.SomeOuterGenericClass<Swift.Int>.OtherInnerStruct",
+              _typeName(SomeOuterGenericClass<Int>.OtherInnerStruct.self));
+  expectEqual("main.SomeOuterGenericClass<Swift.Int>.OtherInnerGenericStruct<Swift.String>",
+              _typeName(SomeOuterGenericClass<Int>.OtherInnerGenericStruct<String>.self));
+}
+
+extension SomeOuterGenericClass where T == Int {
+  struct AnotherInnerStruct {}
+  struct AnotherInnerGenericStruct<U> {}
+}
+
+TypeNameTests.test("NestedInConstrainedExtension") {
+  expectEqual("main.SomeOuterGenericClass.AnotherInnerStruct",
+              _typeName(SomeOuterGenericClass<Int>.AnotherInnerStruct.self));
+  expectEqual("main.SomeOuterGenericClass.AnotherInnerGenericStruct<Swift.String>",
+              _typeName(SomeOuterGenericClass<Int>.AnotherInnerGenericStruct<String>.self));
+}
+
 runAllTests()
diff --git a/unittests/runtime/Metadata.cpp b/unittests/runtime/Metadata.cpp
index d53b6dc..97679b1 100644
--- a/unittests/runtime/Metadata.cpp
+++ b/unittests/runtime/Metadata.cpp
@@ -182,7 +182,7 @@
       metadataWords[2] = argsWords[0];
       return metadata;
     },
-    3 * sizeof(void*), // metadata size
+    2 * sizeof(void*), // metadata size
     1, // num arguments
     0, // address point
     {} // private data
@@ -191,8 +191,7 @@
   // Fields
   {
     MetadataKind::Struct,
-    reinterpret_cast<const NominalTypeDescriptor*>(&Global1),
-    nullptr
+    reinterpret_cast<const NominalTypeDescriptor*>(&Global1)
   }
 };
 
diff --git a/utils/build-script b/utils/build-script
index c377d7f..7313862 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -127,7 +127,11 @@
             test = (
                 deployment_platform not in invocation.platforms_to_skip_test)
             test_host_only = None
-            build_benchmark = build and deployment_target.supports_benchmark
+            dt_supports_benchmark = deployment_target.supports_benchmark
+            build_benchmarks = build and dt_supports_benchmark
+            build_external_benchmarks = all([build, dt_supports_benchmark,
+                                             args.build_external_benchmarks])
+
             # FIXME: Note, `build-script-impl` computed a property here
             # w.r.t. testing, but it was actually unused.
 
@@ -161,13 +165,20 @@
                 else:
                     self.swift_stdlib_build_targets.append(
                         "swift-test-stdlib-" + name)
-            if build_benchmark:
+            if build_benchmarks:
                 self.swift_benchmark_build_targets.append(
                     "swift-benchmark-" + name)
                 # FIXME: This probably should respect `args.benchmark`, but
                 # a typo in build-script-impl meant we always would do this.
                 self.swift_benchmark_run_targets.append(
                     "check-swift-benchmark-" + name)
+
+            if build_external_benchmarks:
+                # Add support for the external benchmarks.
+                self.swift_benchmark_build_targets.append(
+                    "swift-benchmark-{}-external".format(name))
+                self.swift_benchmark_run_targets.append(
+                    "check-swift-benchmark-{}-external".format(name))
             if test:
                 if test_host_only:
                     suffix = "-non-executable"
@@ -506,6 +517,9 @@
                           "--skip-build-swift"]
         if not args.build_benchmarks:
             impl_args += ["--skip-build-benchmarks"]
+        # Currently we do not build external benchmarks by default.
+        if args.build_external_benchmarks:
+            impl_args += ["--skip-build-external-benchmarks=0"]
         if not args.build_foundation:
             impl_args += ["--skip-build-foundation"]
         if not args.build_xctest:
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 0de5738..5a65bba 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -126,6 +126,7 @@
     skip-build-libdispatch      ""               "set to skip building libdispatch"
     skip-build-libicu           ""               "set to skip building libicu"
     skip-build-benchmarks       ""               "set to skip building Swift Benchmark Suite"
+    skip-build-external-benchmarks "1"            "set to skip building the external Swift Benchmark Suite. (skipped by default)"
     skip-build-playgroundlogger ""               "set to skip building PlaygroundLogger"
     skip-build-playgroundsupport ""              "set to skip building PlaygroundSupport"
     skip-test-cmark             ""               "set to skip testing CommonMark"
@@ -1324,6 +1325,7 @@
         local test_this_target=1
         local test_host_only=
         local build_benchmark_this_target=
+        local build_external_benchmark_this_target=
         local test_benchmark_this_target=
 
         case ${stdlib_deployment_target} in
@@ -1352,6 +1354,7 @@
                 build_for_this_target=$(not ${SKIP_BUILD_OSX})
                 test_this_target=$(not ${SKIP_TEST_OSX})
                 build_benchmark_this_target=$(not ${SKIP_BUILD_OSX})
+                build_external_benchmark_this_target=$(not ${SKIP_BUILD_OSX})
                 test_benchmark_this_target=$(not ${SKIP_BUILD_OSX})
                 ;;
             iphoneos-*)
@@ -1363,10 +1366,12 @@
                     test_this_target=
                 fi
                 build_benchmark_this_target=$(not ${SKIP_BUILD_IOS_DEVICE})
+                build_external_benchmark_this_target=$(not ${SKIP_BUILD_IOS_DEVICE})
 
                 # Never build iOS armv7s benchmarks.
                 if [[ "${stdlib_deployment_target}" == "iphoneos-armv7s" ]]; then
                     build_benchmark_this_target=
+                    build_external_benchmark_this_target=
                 fi
                 ;;
             iphonesimulator-x86_64)
@@ -1391,6 +1396,7 @@
                     test_this_target=
                 fi
                 build_benchmark_this_target=$(not ${SKIP_BUILD_TVOS_DEVICE})
+                build_external_benchmark_this_target=$(not ${SKIP_BUILD_TVOS_DEVICE})
                 ;;
             appletvsimulator-*)
                 swift_sdk="TVOS_SIMULATOR"
@@ -1406,6 +1412,7 @@
                     test_this_target=
                 fi
                 build_benchmark_this_target=$(not ${SKIP_BUILD_WATCHOS_DEVICE})
+                build_external_benchmark_this_target=$(not ${SKIP_BUILD_WATCHOS_DEVICE})
                 ;;
             watchsimulator-*)
                 swift_sdk="WATCHOS_SIMULATOR"
@@ -1443,6 +1450,16 @@
               SWIFT_RUN_BENCHMARK_TARGETS+=("check-swift-benchmark-${stdlib_deployment_target}")
             fi
         fi
+
+        if [[ "$(true_false ${SKIP_BUILD_EXTERNAL_BENCHMARKS})" == "FALSE"  ]] &&
+           [[ "${build_external_benchmark_this_target}" ]] &&
+           [[ "${is_in_build_list}" ]] ; then
+            SWIFT_BENCHMARK_TARGETS+=("swift-benchmark-${stdlib_deployment_target}-external")
+            if [[ $(not ${SKIP_TEST_BENCHMARK}) ]] ; then
+                SWIFT_RUN_BENCHMARK_TARGETS+=("check-swift-benchmark-${stdlib_deployment_target}-external")
+            fi
+        fi
+
         if [[ "${test_this_target}" ]] && [[ "${is_in_build_list}" ]]; then
             test_target_suffix=""
             if [[ -n "${test_host_only}" ]] ; then
@@ -2098,13 +2115,16 @@
 
                     # Don't build benchmarks and tests when building cross compiler.
                     build_perf_testsuite_this_time=false
+                    build_external_perf_testsuite_this_time=false
                     build_tests_this_time=false
 
                     native_llvm_tools_path="$(build_directory "${LOCAL_HOST}" llvm)/bin"
                     native_clang_tools_path="$(build_directory "${LOCAL_HOST}" llvm)/bin"
                     native_swift_tools_path="$(build_directory "${LOCAL_HOST}" swift)/bin"
                 else
+                    # FIXME: Why is the next line not using false_true?
                     build_perf_testsuite_this_time=$(true_false "$(not ${SKIP_BUILD_BENCHMARKS})")
+                    build_external_perf_testsuite_this_time=$(false_true "${SKIP_BUILD_EXTERNAL_BENCHMARKS}")
                     build_tests_this_time=${SWIFT_INCLUDE_TESTS}
                 fi
 
@@ -2162,6 +2182,7 @@
                     -DSWIFT_BUILD_DYNAMIC_SDK_OVERLAY:BOOL=$(true_false "${BUILD_SWIFT_DYNAMIC_SDK_OVERLAY}")
                     -DSWIFT_BUILD_STATIC_SDK_OVERLAY:BOOL=$(true_false "${BUILD_SWIFT_STATIC_SDK_OVERLAY}")
                     -DSWIFT_BUILD_PERF_TESTSUITE:BOOL=$(true_false "${build_perf_testsuite_this_time}")
+                    -DSWIFT_BUILD_EXTERNAL_PERF_TESTSUITE:BOOL=$(true_false "${build_external_perf_testsuite_this_time}")
                     -DSWIFT_BUILD_EXAMPLES:BOOL=$(true_false "${BUILD_SWIFT_EXAMPLES}")
                     -DSWIFT_INCLUDE_TESTS:BOOL=$(true_false "${build_tests_this_time}")
                     -DSWIFT_INSTALL_COMPONENTS:STRING="${SWIFT_INSTALL_COMPONENTS}"
diff --git a/utils/build_swift/driver_arguments.py b/utils/build_swift/driver_arguments.py
index d7c43d5..7b6e8ef 100644
--- a/utils/build_swift/driver_arguments.py
+++ b/utils/build_swift/driver_arguments.py
@@ -153,6 +153,7 @@
         args.build_watchos = False
         args.build_android = False
         args.build_benchmarks = False
+        args.build_external_benchmarks = False
         args.build_lldb = False
         args.build_llbuild = False
         args.build_swiftpm = False
@@ -771,6 +772,12 @@
         action=arguments.action.optional_false,
         help="skip building Swift Benchmark Suite")
 
+    run_build_group.add_argument(
+        "--build-external-benchmarks",
+        dest='build_external_benchmarks',
+        action=arguments.action.optional_true,
+        help="skip building Swift Benchmark Suite")
+
     skip_test_group = parser.add_argument_group(
         title="Skip testing specified targets")
     skip_test_group.add_argument(
diff --git a/validation-test/compiler_crashers_fixed/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift b/validation-test/compiler_crashers/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift
similarity index 88%
rename from validation-test/compiler_crashers_fixed/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift
rename to validation-test/compiler_crashers/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift
index 02b9326..1c78fe4 100644
--- a/validation-test/compiler_crashers_fixed/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift
+++ b/validation-test/compiler_crashers/28816-unreachable-executed-at-swift-lib-sema-typecheckgeneric-cpp-214.swift
@@ -5,6 +5,6 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not %target-swift-frontend %s -emit-ir
+// RUN: not --crash %target-swift-frontend %s -emit-ir
 protocol b{{}{}class a{{}class A}{}typealias a
 init(t:Self.a.a.a
diff --git a/validation-test/compiler_crashers_2_fixed/0119-rdar33613329.swift b/validation-test/compiler_crashers_2_fixed/0119-rdar33613329.swift
new file mode 100644
index 0000000..1d251d6
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0119-rdar33613329.swift
@@ -0,0 +1,45 @@
+// RUN: %target-typecheck-verify-swift %s
+
+precedencegroup BindingPrecedence {
+  higherThan: DefaultPrecedence
+}
+
+infix operator ~>
+infix operator ≈> : BindingPrecedence
+
+struct M<L : P, R> {
+  let f: L
+  let b: (inout L.B) -> R
+
+  init(f: L, b: @escaping (inout L.B) -> R) {
+    self.f = f
+    self.b = b
+  }
+}
+
+protocol P {
+  associatedtype A
+  associatedtype B
+
+  func `in`<R>(_ a: inout A, apply body: (inout B) -> R) -> R
+
+  static func ~> (_: A, _: Self) -> B
+}
+
+extension P {
+  static func ≈> <R>(f: Self,  b: @escaping (inout B) -> R) -> M<Self, R> {}
+}
+
+extension WritableKeyPath : P {
+  typealias A = Root
+  typealias B = Value
+
+  func `in`<R>(_ a: inout A, apply body: (inout B) -> R) -> R {}
+
+  static func ~> (a: A, path: WritableKeyPath) -> B {}
+}
+
+struct X { var y: Int = 0 }
+var x = X()
+x ~> \X.y ≈> { a in a += 1; return 3 }
+// expected-error@-1 {{cannot convert call result type 'M<WritableKeyPath<X, Int>, _>' to expected type 'WritableKeyPath<_, _>'}}
diff --git a/validation-test/execution/crashers/rdar18157434.swift b/validation-test/execution/crashers_fixed/rdar33767511.swift
similarity index 90%
rename from validation-test/execution/crashers/rdar18157434.swift
rename to validation-test/execution/crashers_fixed/rdar33767511.swift
index 5d0bfd8..825e4b1 100644
--- a/validation-test/execution/crashers/rdar18157434.swift
+++ b/validation-test/execution/crashers_fixed/rdar33767511.swift
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t
 // RUN: mkdir -p %t
 // RUN: %target-build-swift %s -o %t/a.out
-// RUN: not --crash %target-run %t/a.out
+// RUN: %target-run %t/a.out
 
 // REQUIRES: executable_test
 // REQUIRES: OS=macosx
diff --git a/validation-test/stdlib/Bool.swift b/validation-test/stdlib/Bool.swift
new file mode 100644
index 0000000..758f155
--- /dev/null
+++ b/validation-test/stdlib/Bool.swift
@@ -0,0 +1,44 @@
+// RUN: mkdir -p %t
+// RUN: %target-clang -x c %S/Inputs/VariadicBool/variadicBool.c -c -o %t/variadicBool.o
+// RUN: %target-build-swift -I %S/Inputs/VariadicBool/ %t/variadicBool.o %s -o %t/a.out
+// RUN: %target-run %t/a.out
+// REQUIRES: executable_test
+
+
+import Swift
+import StdlibUnittest
+import StdlibCollectionUnittest
+import VariadicBool
+
+func countTrues(_ count: Int, _ bools: CVarArg...) -> Int {
+  return Int(withVaList(bools) { numberOfTrues(Int32(count), $0) })
+}
+
+var BoolTestSuite = TestSuite("Bool")
+
+BoolTestSuite.test("AllTrues") {
+  let result = countTrues(2, true, true)
+  expectEqual(2, result)
+}
+
+BoolTestSuite.test("HalfAndHalf") {
+  let result = countTrues(4, true, true, false, false)
+  expectEqual(2, result)
+}
+
+BoolTestSuite.test("AllFalse") {
+  let result = countTrues(2, false, false)
+  expectEqual(0, result)
+}
+
+BoolTestSuite.test("Interleaved") {
+  let result = countTrues(7, false, true, false, true, false, true, false)
+  expectEqual(3, result)
+}
+
+BoolTestSuite.test("FalsePositive") {
+  let result = countTrues(7, false, true, false, true, false, true, false)
+  expectNotEqual(30, result)
+}
+
+runAllTests()
\ No newline at end of file
diff --git a/validation-test/stdlib/BoolDiagnostics.swift b/validation-test/stdlib/BoolDiagnostics.swift
new file mode 100644
index 0000000..95eee5e
--- /dev/null
+++ b/validation-test/stdlib/BoolDiagnostics.swift
@@ -0,0 +1,7 @@
+// RUN: %target-swift-frontend -typecheck -verify %s
+
+func CVarArgs_withBool() {
+  func varArgFunc(_ x: Bool, _ args: CVarArg...) { }
+  let x = false
+  varArgFunc(x, x)
+}