Merge pull request #21902 from compnerd/interpreter-tests

test: port most of the interpreter tests to Windows
diff --git a/benchmark/scripts/test_Benchmark_Driver.py b/benchmark/scripts/test_Benchmark_Driver.py
index 51cc95b..8a75d3a 100644
--- a/benchmark/scripts/test_Benchmark_Driver.py
+++ b/benchmark/scripts/test_Benchmark_Driver.py
@@ -57,13 +57,13 @@
 
     def test_run_benchmarks_by_name_or_ordinal(self):
         benchmarks = ['AngryPhonebook', '42']
-        self.assertEquals(
+        self.assertEqual(
             parse_args(['run'] + benchmarks).benchmarks, benchmarks)
 
     def test_run_benchmarks_matching_pattern(self):
         regexes = ['Prefix', '.*Suffix.*']
         filters = ['-f', regexes[0], '-f', regexes[1]]
-        self.assertEquals(parse_args(['run'] + filters).filters, regexes)
+        self.assertEqual(parse_args(['run'] + filters).filters, regexes)
 
     def test_run_benchmarks_and_filters_are_exclusive(self):
         with captured_output() as (_, err):
@@ -76,17 +76,17 @@
 
     def test_tests_location(self):
         here = os.path.dirname(os.path.abspath(__file__))
-        self.assertEquals(parse_args(['run']).tests, here)
+        self.assertEqual(parse_args(['run']).tests, here)
         tests = '/benchmarks/are/here'
-        self.assertEquals(parse_args(['run', '-t', tests]).tests, tests)
+        self.assertEqual(parse_args(['run', '-t', tests]).tests, tests)
 
     def test_optimization_argument(self):
-        self.assertEquals(parse_args(['run']).optimization, 'O')
-        self.assertEquals(
+        self.assertEqual(parse_args(['run']).optimization, 'O')
+        self.assertEqual(
             parse_args(['run', '-o', 'O']).optimization, 'O')
-        self.assertEquals(
+        self.assertEqual(
             parse_args(['run', '-o', 'Onone']).optimization, 'Onone')
-        self.assertEquals(
+        self.assertEqual(
             parse_args(['run', '-o', 'Osize']).optimization, 'Osize')
 
         with captured_output() as (_, err):
@@ -99,9 +99,9 @@
             err.getvalue())
 
     def test_independent_samples(self):
-        self.assertEquals(parse_args(['run']).independent_samples, 1)
-        self.assertEquals(parse_args(['run', '-i', '3']).independent_samples,
-                          3)
+        self.assertEqual(parse_args(['run']).independent_samples, 1)
+        self.assertEqual(parse_args(['run', '-i', '3']).independent_samples,
+                         3)
         with captured_output() as (out, err):
             self.assertRaises(SystemExit,
                               parse_args, ['run', '-i', '-3'])
@@ -112,7 +112,7 @@
 
     def test_output_dir(self):
         self.assertIsNone(parse_args(['run']).output_dir)
-        self.assertEquals(
+        self.assertEqual(
             parse_args(['run', '--output-dir', '/log']).output_dir, '/log')
 
     def test_check_supports_vebose_output(self):
@@ -169,12 +169,12 @@
         self.subprocess_mock = SubprocessMock()
 
     def test_test_harness(self):
-        self.assertEquals(
+        self.assertEqual(
             BenchmarkDriver(self.args, tests=['ignored']).test_harness,
             '/benchmarks/Benchmark_O')
         self.args.tests = '/path'
         self.args.optimization = 'Suffix'
-        self.assertEquals(
+        self.assertEqual(
             BenchmarkDriver(self.args, tests=['ignored']).test_harness,
             '/path/Benchmark_Suffix')
 
@@ -185,10 +185,10 @@
         driver = BenchmarkDriver(
             self.args, _subprocess=self.subprocess_mock)
         self.subprocess_mock.assert_called_all_expected()
-        self.assertEquals(driver.tests,
-                          ['Benchmark1', 'Benchmark2'])
-        self.assertEquals(driver.all_tests,
-                          ['Benchmark1', 'Benchmark2'])
+        self.assertEqual(driver.tests,
+                         ['Benchmark1', 'Benchmark2'])
+        self.assertEqual(driver.all_tests,
+                         ['Benchmark1', 'Benchmark2'])
         self.assertEquals(driver.test_number['Benchmark1'], "1")
         self.assertEquals(driver.test_number['Benchmark2'], "2")
 
@@ -207,9 +207,9 @@
         driver = BenchmarkDriver(
             self.args, _subprocess=self.subprocess_mock)
         self.subprocess_mock.assert_called_all_expected()
-        self.assertEquals(driver.tests, ['Benchmark1', 'Benchmark3'])
-        self.assertEquals(driver.all_tests,
-                          ['Benchmark1', 'Benchmark2', 'Benchmark3'])
+        self.assertEqual(driver.tests, ['Benchmark1', 'Benchmark3'])
+        self.assertEqual(driver.all_tests,
+                         ['Benchmark1', 'Benchmark2', 'Benchmark3'])
 
     def test_filters_benchmarks_by_pattern(self):
         self.args.filters = '-f .+3'.split()
@@ -217,9 +217,9 @@
         driver = BenchmarkDriver(
             self.args, _subprocess=self.subprocess_mock)
         self.subprocess_mock.assert_called_all_expected()
-        self.assertEquals(driver.tests, ['Benchmark3'])
-        self.assertEquals(driver.all_tests,
-                          ['Benchmark1', 'Benchmark2', 'Benchmark3'])
+        self.assertEqual(driver.tests, ['Benchmark3'])
+        self.assertEqual(driver.all_tests,
+                         ['Benchmark1', 'Benchmark2', 'Benchmark3'])
 
     def test_log_file(self):
         """When swift-repo is set, log is tied to Git branch and revision."""
@@ -230,8 +230,8 @@
         driver = BenchmarkDriver(
             Stub(output_dir='/path', tests='/bin/', optimization='Suffix',
                  swift_repo=None,), tests=['ignored'])
-        self.assertEquals(driver.log_file,
-                          '/path/Benchmark_Suffix-' + now + '.log')
+        self.assertEqual(driver.log_file,
+                         '/path/Benchmark_Suffix-' + now + '.log')
 
         r = '/repo/'
         subprocess_mock = SubprocessMock(responses=[
@@ -243,8 +243,8 @@
         driver = BenchmarkDriver(
             Stub(output_dir='/log/', tests='', optimization='S', swift_repo=r),
             tests=['ignored'], _subprocess=subprocess_mock)
-        self.assertEquals(driver.log_file,
-                          '/log/branch/Benchmark_S-' + now + '-short_hash.log')
+        self.assertEqual(driver.log_file,
+                         '/log/branch/Benchmark_S-' + now + '-short_hash.log')
         subprocess_mock.assert_called_all_expected()
 
 
@@ -332,14 +332,14 @@
         """Extract up to 20 measurements from an independent run."""
         self.driver.args.independent_samples = 3
         r = self.driver.run_independent_samples('b1')
-        self.assertEquals(self.subprocess_mock.calls.count(
+        self.assertEqual(self.subprocess_mock.calls.count(
             ('/benchmarks/Benchmark_O', 'b1', '--num-iters=1', '--memory',
              '--quantile=20', '--delta')), 3)
-        self.assertEquals(r.num_samples, 3)  # results are merged
+        self.assertEqual(r.num_samples, 3)  # results are merged
 
     def test_run_and_log(self):
         def mock_run(test):
-            self.assertEquals(test, 'b1')
+            self.assertEqual(test, 'b1')
             return PerformanceTestResult(
                 '3,b1,5,101,1,1,1,1,888'.split(','),
                 quantiles=True, delta=True, memory=True)
@@ -352,8 +352,8 @@
         header = '#,TEST,SAMPLES,MIN(μs),Q1(μs),MEDIAN(μs),Q3(μs),MAX(μs),' +\
             'MAX_RSS(B)\n'
         csv_log = '3,b1,5,101,102,103,104,105,888\n'
-        self.assertEquals(log, None)
-        self.assertEquals(
+        self.assertEqual(log, None)
+        self.assertEqual(
             out.getvalue(),
             header +
             csv_log +
@@ -363,8 +363,8 @@
         with captured_output() as (out, _):
             log = driver.run_and_log(csv_console=False)
 
-        self.assertEquals(log, header + csv_log)
-        self.assertEquals(
+        self.assertEqual(log, header + csv_log)
+        self.assertEqual(
             out.getvalue(),
             '  # TEST                      SAMPLES MIN(μs) Q1(μs)' +
             ' MEDIAN(μs) Q3(μs) MAX(μs) MAX_RSS(B)\n' +
@@ -376,11 +376,11 @@
     def test_log_results(self):
         """Create log directory if it doesn't exist and write the log file."""
         def assert_log_written(out, log_file, content):
-            self.assertEquals(out.getvalue(),
-                              'Logging results to: ' + log_file + '\n')
+            self.assertEqual(out.getvalue(),
+                             'Logging results to: ' + log_file + '\n')
             with open(log_file, 'rU') as f:
                 text = f.read()
-            self.assertEquals(text, "formatted output")
+            self.assertEqual(text, "formatted output")
 
         try:
             import tempfile  # setUp
@@ -408,7 +408,7 @@
     def test_deterministing_hashing(self):
         cmd = ['printenv', 'SWIFT_DETERMINISTIC_HASHING']
         driver = BenchmarkDriver(['no args'], tests=['ignored'])
-        self.assertEquals(driver._invoke(cmd).strip(), '1')
+        self.assertEqual(driver._invoke(cmd).strip(), '1')
 
 
 class BenchmarkDriverMock(Mock):
@@ -437,7 +437,7 @@
             'name': 'Base.category', 'level': logging.DEBUG,
             'levelname': 'DEBUG', 'msg': 'Hi!'})
         f = LoggingReportFormatter()
-        self.assertEquals(f.format(lr), 'DEBUG category: Hi!')
+        self.assertEqual(f.format(lr), 'DEBUG category: Hi!')
 
     def test_colored_log_format(self):
         def record(level, level_name):
@@ -445,23 +445,23 @@
                 'name': 'Base.category', 'levelno': level,
                 'levelname': level_name, 'msg': 'Hi!'})
         f = LoggingReportFormatter(use_color=True)
-        self.assertEquals(f.format(record(logging.DEBUG, 'DEBUG')),
-                          '\x1b[1;39mcategory: Hi!\x1b[1;0m')
-        self.assertEquals(f.format(record(logging.INFO, 'INFO')),
-                          '\x1b[1;32mcategory: Hi!\x1b[1;0m')
-        self.assertEquals(f.format(record(logging.WARNING, 'WARNING')),
-                          '\x1b[1;33mcategory: Hi!\x1b[1;0m')
-        self.assertEquals(f.format(record(logging.ERROR, 'ERROR')),
-                          '\x1b[1;31mcategory: Hi!\x1b[1;0m')
-        self.assertEquals(f.format(record(logging.CRITICAL, 'CRITICAL')),
-                          '\x1b[1;35mcategory: Hi!\x1b[1;0m')
+        self.assertEqual(f.format(record(logging.DEBUG, 'DEBUG')),
+                         '\x1b[1;39mcategory: Hi!\x1b[1;0m')
+        self.assertEqual(f.format(record(logging.INFO, 'INFO')),
+                         '\x1b[1;32mcategory: Hi!\x1b[1;0m')
+        self.assertEqual(f.format(record(logging.WARNING, 'WARNING')),
+                         '\x1b[1;33mcategory: Hi!\x1b[1;0m')
+        self.assertEqual(f.format(record(logging.ERROR, 'ERROR')),
+                         '\x1b[1;31mcategory: Hi!\x1b[1;0m')
+        self.assertEqual(f.format(record(logging.CRITICAL, 'CRITICAL')),
+                         '\x1b[1;35mcategory: Hi!\x1b[1;0m')
 
     def test_no_prefix_for_base_logging(self):
         lr = logging.makeLogRecord({
             'name': 'Base', 'level': logging.INFO,
             'levelname': 'INFO', 'msg': 'Hi!'})
         f = LoggingReportFormatter()
-        self.assertEquals(f.format(lr), 'INFO Hi!')
+        self.assertEqual(f.format(lr), 'INFO Hi!')
 
 
 class TestMarkdownReportHandler(unittest.TestCase):
@@ -481,7 +481,7 @@
             'levelno': level, 'msg': msg})
 
     def test_init_writes_table_header(self):
-        self.assertEquals(self.handler.level, logging.INFO)
+        self.assertEqual(self.handler.level, logging.INFO)
         self.assert_contains(['Benchmark Check Report\n', '---|---'])
 
     def test_close_writes_final_newlines(self):
@@ -552,7 +552,7 @@
         with captured_output() as (out, _):
             BenchmarkDoctor(self.args, driver)
         self.assert_contains(['Checking tests: B1, B2'], self.logs['debug'])
-        self.assertEquals(out.getvalue(), '')
+        self.assertEqual(out.getvalue(), '')
 
     def test_supports_verbose_output(self):
         driver = BenchmarkDriverMock(tests=['B1', 'B2'])
@@ -607,7 +607,7 @@
              'B1 O i1a', 'B1 O i1b', 'B1 O i1c', 'B1 O i1d', 'B1 O i1e',
              'B1 O i2a', 'B1 O i2b', 'B1 O i2c', 'B1 O i2d', 'B1 O i2e'],
             measurements.keys())
-        self.assertEquals(measurements['name'], 'B1')
+        self.assertEqual(measurements['name'], 'B1')
         self.assert_contains(
             ['Calibrating num-samples for B1:',
              'Runtime 300 μs yields 4096 adjusted samples per second.',
diff --git a/benchmark/scripts/test_compare_perf_tests.py b/benchmark/scripts/test_compare_perf_tests.py
index 04af04c..6ac0a33 100644
--- a/benchmark/scripts/test_compare_perf_tests.py
+++ b/benchmark/scripts/test_compare_perf_tests.py
@@ -35,15 +35,15 @@
 class TestSample(unittest.TestCase):
     def test_has_named_fields(self):
         s = Sample(1, 2, 3)
-        self.assertEquals(s.i, 1)
-        self.assertEquals(s.num_iters, 2)
-        self.assertEquals(s.runtime, 3)
+        self.assertEqual(s.i, 1)
+        self.assertEqual(s.num_iters, 2)
+        self.assertEqual(s.runtime, 3)
 
     def test_is_iterable(self):
         s = Sample(1, 2, 3)
-        self.assertEquals(s[0], 1)
-        self.assertEquals(s[1], 2)
-        self.assertEquals(s[2], 3)
+        self.assertEqual(s[0], 1)
+        self.assertEqual(s[1], 2)
+        self.assertEqual(s[2], 3)
 
 
 class TestPerformanceTestSamples(unittest.TestCase):
@@ -52,34 +52,34 @@
         self.samples.add(Sample(7, 42, 1000))
 
     def test_has_name(self):
-        self.assertEquals(self.samples.name, 'B1')
+        self.assertEqual(self.samples.name, 'B1')
 
     def test_stores_samples(self):
-        self.assertEquals(self.samples.count, 1)
+        self.assertEqual(self.samples.count, 1)
         s = self.samples.samples[0]
         self.assertTrue(isinstance(s, Sample))
-        self.assertEquals(s.i, 7)
-        self.assertEquals(s.num_iters, 42)
-        self.assertEquals(s.runtime, 1000)
+        self.assertEqual(s.i, 7)
+        self.assertEqual(s.num_iters, 42)
+        self.assertEqual(s.runtime, 1000)
 
     def test_quantile(self):
-        self.assertEquals(self.samples.quantile(1), 1000)
-        self.assertEquals(self.samples.quantile(0), 1000)
+        self.assertEqual(self.samples.quantile(1), 1000)
+        self.assertEqual(self.samples.quantile(0), 1000)
         self.samples.add(Sample(2, 1, 1100))
-        self.assertEquals(self.samples.quantile(0), 1000)
-        self.assertEquals(self.samples.quantile(1), 1100)
+        self.assertEqual(self.samples.quantile(0), 1000)
+        self.assertEqual(self.samples.quantile(1), 1100)
         self.samples.add(Sample(3, 1, 1050))
-        self.assertEquals(self.samples.quantile(0), 1000)
-        self.assertEquals(self.samples.quantile(.5), 1050)
-        self.assertEquals(self.samples.quantile(1), 1100)
+        self.assertEqual(self.samples.quantile(0), 1000)
+        self.assertEqual(self.samples.quantile(.5), 1050)
+        self.assertEqual(self.samples.quantile(1), 1100)
 
     def assertEqualFiveNumberSummary(self, ss, expected_fns):
         e_min, e_q1, e_median, e_q3, e_max = expected_fns
-        self.assertEquals(ss.min, e_min)
-        self.assertEquals(ss.q1, e_q1)
-        self.assertEquals(ss.median, e_median)
-        self.assertEquals(ss.q3, e_q3)
-        self.assertEquals(ss.max, e_max)
+        self.assertEqual(ss.min, e_min)
+        self.assertEqual(ss.q1, e_q1)
+        self.assertEqual(ss.median, e_median)
+        self.assertEqual(ss.q3, e_q3)
+        self.assertEqual(ss.max, e_max)
 
     def test_computes_five_number_summary(self):
         self.assertEqualFiveNumberSummary(
@@ -98,38 +98,38 @@
             self.samples, (1000, 1025, 1050, 1075, 1100))
 
     def test_computes_inter_quartile_range(self):
-        self.assertEquals(self.samples.iqr, 0)
+        self.assertEqual(self.samples.iqr, 0)
         self.samples.add(Sample(2, 1, 1025))
         self.samples.add(Sample(3, 1, 1050))
         self.samples.add(Sample(4, 1, 1075))
         self.samples.add(Sample(5, 1, 1100))
-        self.assertEquals(self.samples.iqr, 50)
+        self.assertEqual(self.samples.iqr, 50)
 
-    def assertEqualStats(self, stats, expected_stats):
+    def assertEqualtats(self, stats, expected_stats):
         for actual, expected in zip(stats, expected_stats):
             self.assertAlmostEquals(actual, expected, places=2)
 
     def test_computes_mean_sd_cv(self):
         ss = self.samples
-        self.assertEqualStats(
+        self.assertEqualtats(
             (ss.mean, ss.sd, ss.cv), (1000.0, 0.0, 0.0))
         self.samples.add(Sample(2, 1, 1100))
-        self.assertEqualStats(
+        self.assertEqualtats(
             (ss.mean, ss.sd, ss.cv), (1050.0, 70.71, 6.7 / 100))
 
     def test_computes_range_spread(self):
         ss = self.samples
-        self.assertEqualStats(
+        self.assertEqualtats(
             (ss.range, ss.spread), (0, 0))
         self.samples.add(Sample(2, 1, 1100))
-        self.assertEqualStats(
+        self.assertEqualtats(
             (ss.range, ss.spread), (100, 10.0 / 100))
 
     def test_init_with_samples(self):
         self.samples = PerformanceTestSamples(
             'B2', [Sample(0, 1, 1000), Sample(1, 1, 1100)])
-        self.assertEquals(self.samples.count, 2)
-        self.assertEqualStats(
+        self.assertEqual(self.samples.count, 2)
+        self.assertEqualtats(
             (self.samples.mean, self.samples.sd,
              self.samples.range, self.samples.spread),
             (1050.0, 70.71, 100, 9.52 / 100))
@@ -138,7 +138,7 @@
         # guard against dividing by 0
         self.samples = PerformanceTestSamples('Zero')
         self.samples.add(Sample(0, 1, 0))
-        self.assertEqualStats(
+        self.assertEqualtats(
             (self.samples.mean, self.samples.sd, self.samples.cv,
              self.samples.range, self.samples.spread),
             (0, 0, 0.0, 0, 0.0))
@@ -149,17 +149,17 @@
               '5 1 1000, 6 1 1025, 7 1 1050, 8 1 1075, 9 1 1100, '
               '10 1 1050, 11 1 949, 12 1 1151'.split(',')]
         self.samples = PerformanceTestSamples('Outliers', ss)
-        self.assertEquals(self.samples.count, 13)
-        self.assertEqualStats(
+        self.assertEqual(self.samples.count, 13)
+        self.assertEqualtats(
             (self.samples.mean, self.samples.sd), (1050, 52.36))
 
         self.samples.exclude_outliers()
 
-        self.assertEquals(self.samples.count, 11)
-        self.assertEquals(self.samples.outliers, ss[11:])
+        self.assertEqual(self.samples.count, 11)
+        self.assertEqual(self.samples.outliers, ss[11:])
         self.assertEqualFiveNumberSummary(
             self.samples, (1000, 1025, 1050, 1075, 1100))
-        self.assertEqualStats(
+        self.assertEqualtats(
             (self.samples.mean, self.samples.sd), (1050, 35.36))
 
     def test_excludes_outliers_zero_IQR(self):
@@ -168,12 +168,12 @@
         self.samples.add(Sample(1, 2, 18))
         self.samples.add(Sample(2, 2, 18))
         self.samples.add(Sample(3, 2, 18))
-        self.assertEquals(self.samples.iqr, 0)
+        self.assertEqual(self.samples.iqr, 0)
 
         self.samples.exclude_outliers()
 
-        self.assertEquals(self.samples.count, 3)
-        self.assertEqualStats(
+        self.assertEqual(self.samples.count, 3)
+        self.assertEqualtats(
             (self.samples.min, self.samples.max), (18, 18))
 
     def test_excludes_outliers_top_only(self):
@@ -181,61 +181,61 @@
               '0 1 1, 1 1 2, 2 1 2, 3 1 2, 4 1 3'.split(',')]
         self.samples = PerformanceTestSamples('Top', ss)
         self.assertEqualFiveNumberSummary(self.samples, (1, 2, 2, 2, 3))
-        self.assertEquals(self.samples.iqr, 0)
+        self.assertEqual(self.samples.iqr, 0)
 
         self.samples.exclude_outliers(top_only=True)
 
-        self.assertEquals(self.samples.count, 4)
-        self.assertEqualStats((self.samples.min, self.samples.max), (1, 2))
+        self.assertEqual(self.samples.count, 4)
+        self.assertEqualtats((self.samples.min, self.samples.max), (1, 2))
 
 
 class TestPerformanceTestResult(unittest.TestCase):
     def test_init(self):
         log_line = '1,AngryPhonebook,20,10664,12933,11035,576,10884'
         r = PerformanceTestResult(log_line.split(','))
-        self.assertEquals(r.test_num, '1')
-        self.assertEquals(r.name, 'AngryPhonebook')
-        self.assertEquals(
+        self.assertEqual(r.test_num, '1')
+        self.assertEqual(r.name, 'AngryPhonebook')
+        self.assertEqual(
             (r.num_samples, r.min, r.max, r.mean, r.sd, r.median),
             (20, 10664, 12933, 11035, 576, 10884))
-        self.assertEquals(r.samples, None)
+        self.assertEqual(r.samples, None)
 
         log_line = '1,AngryPhonebook,1,12045,12045,12045,0,12045,10510336'
         r = PerformanceTestResult(log_line.split(','))
-        self.assertEquals(r.max_rss, 10510336)
+        self.assertEqual(r.max_rss, 10510336)
 
     def test_init_quantiles(self):
         # #,TEST,SAMPLES,MIN(μs),MEDIAN(μs),MAX(μs)
         log = '1,Ackermann,3,54383,54512,54601'
         r = PerformanceTestResult(log.split(','), quantiles=True)
-        self.assertEquals(r.test_num, '1')
-        self.assertEquals(r.name, 'Ackermann')
-        self.assertEquals((r.num_samples, r.min, r.median, r.max),
-                          (3, 54383, 54512, 54601))
+        self.assertEqual(r.test_num, '1')
+        self.assertEqual(r.name, 'Ackermann')
+        self.assertEqual((r.num_samples, r.min, r.median, r.max),
+                         (3, 54383, 54512, 54601))
         self.assertAlmostEquals(r.mean, 54498.67, places=2)
         self.assertAlmostEquals(r.sd, 109.61, places=2)
-        self.assertEquals(r.samples.count, 3)
-        self.assertEquals(r.samples.num_samples, 3)
-        self.assertEquals([s.runtime for s in r.samples.all_samples],
-                          [54383, 54512, 54601])
+        self.assertEqual(r.samples.count, 3)
+        self.assertEqual(r.samples.num_samples, 3)
+        self.assertEqual([s.runtime for s in r.samples.all_samples],
+                         [54383, 54512, 54601])
 
         # #,TEST,SAMPLES,MIN(μs),MEDIAN(μs),MAX(μs),MAX_RSS(B)
         log = '1,Ackermann,3,54529,54760,55807,266240'
         r = PerformanceTestResult(log.split(','), quantiles=True, memory=True)
-        self.assertEquals((r.samples.count, r.max_rss), (3, 266240))
+        self.assertEqual((r.samples.count, r.max_rss), (3, 266240))
         # #,TEST,SAMPLES,MIN(μs),Q1(μs),Q2(μs),Q3(μs),MAX(μs)
         log = '1,Ackermann,5,54570,54593,54644,57212,58304'
         r = PerformanceTestResult(log.split(','), quantiles=True, memory=False)
-        self.assertEquals((r.num_samples, r.min, r.median, r.max),
-                          (5, 54570, 54644, 58304))
-        self.assertEquals((r.samples.q1, r.samples.q3), (54593, 57212))
-        self.assertEquals(r.samples.count, 5)
+        self.assertEqual((r.num_samples, r.min, r.median, r.max),
+                         (5, 54570, 54644, 58304))
+        self.assertEqual((r.samples.q1, r.samples.q3), (54593, 57212))
+        self.assertEqual(r.samples.count, 5)
         # #,TEST,SAMPLES,MIN(μs),Q1(μs),Q2(μs),Q3(μs),MAX(μs),MAX_RSS(B)
         log = '1,Ackermann,5,54686,54731,54774,55030,63466,270336'
         r = PerformanceTestResult(log.split(','), quantiles=True, memory=True)
-        self.assertEquals(r.samples.num_samples, 5)
-        self.assertEquals(r.samples.count, 4)  # outlier was excluded
-        self.assertEquals(r.max_rss, 270336)
+        self.assertEqual(r.samples.num_samples, 5)
+        self.assertEqual(r.samples.count, 4)  # outlier was excluded
+        self.assertEqual(r.max_rss, 270336)
 
     def test_init_delta_quantiles(self):
         # #,TEST,SAMPLES,MIN(μs),𝚫MEDIAN,𝚫MAX
@@ -243,10 +243,10 @@
         # the difference is 0, which is ommited -- only separator remains
         log = '202,DropWhileArray,2,265,,22'
         r = PerformanceTestResult(log.split(','), quantiles=True, delta=True)
-        self.assertEquals((r.num_samples, r.min, r.median, r.max),
-                          (2, 265, 265, 287))
-        self.assertEquals(r.samples.count, 2)
-        self.assertEquals(r.samples.num_samples, 2)
+        self.assertEqual((r.num_samples, r.min, r.median, r.max),
+                         (2, 265, 265, 287))
+        self.assertEqual(r.samples.count, 2)
+        self.assertEqual(r.samples.num_samples, 2)
 
     def test_init_oversampled_quantiles(self):
         """When num_samples is < quantile + 1, some of the measurements are
@@ -265,9 +265,9 @@
             num_samples = deq.count('1')
             r = PerformanceTestResult(['0', 'B', str(num_samples)] + deq,
                                       quantiles=True, delta=True)
-            self.assertEquals(r.samples.num_samples, num_samples)
-            self.assertEquals([s.runtime for s in r.samples.all_samples],
-                              range(1, num_samples + 1))
+            self.assertEqual(r.samples.num_samples, num_samples)
+            self.assertEqual([s.runtime for s in r.samples.all_samples],
+                             range(1, num_samples + 1))
 
         delta_encoded_quantiles = """
 1,,
@@ -311,7 +311,7 @@
     def test_repr(self):
         log_line = '1,AngryPhonebook,20,10664,12933,11035,576,10884'
         r = PerformanceTestResult(log_line.split(','))
-        self.assertEquals(
+        self.assertEqual(
             str(r),
             '<PerformanceTestResult name:\'AngryPhonebook\' samples:20 '
             'min:10664 max:12933 mean:11035 sd:576 median:10884>'
@@ -333,17 +333,17 @@
                     r.sd, r.median, r.max_rss, r.setup)
 
         r = results[0]
-        self.assertEquals(as_tuple(r),
-                          (1, 12045, 12045, 12045, 0, 12045, None, None))
+        self.assertEqual(as_tuple(r),
+                         (1, 12045, 12045, 12045, 0, 12045, None, None))
         r.merge(results[1])
-        self.assertEquals(as_tuple(r),  # drops SD and median, +max_rss
-                          (2, 12045, 12325, 12185, None, None, 10510336, None))
+        self.assertEqual(as_tuple(r),  # drops SD and median, +max_rss
+                         (2, 12045, 12325, 12185, None, None, 10510336, None))
         r.merge(results[2])
-        self.assertEquals(as_tuple(r),  # picks smaller of the MAX_RSS, +setup
-                          (3, 11616, 12325, 11995.33, None, None, 10502144, 9))
+        self.assertEqual(as_tuple(r),  # picks smaller of the MAX_RSS, +setup
+                         (3, 11616, 12325, 11995.33, None, None, 10502144, 9))
         r.merge(results[3])
-        self.assertEquals(as_tuple(r),  # picks smaller of the setup values
-                          (4, 11616, 12325, 12064, None, None, 10498048, 7))
+        self.assertEqual(as_tuple(r),  # picks smaller of the setup values
+                         (4, 11616, 12325, 12064, None, None, 10498048, 7))
 
 
 class TestResultComparison(unittest.TestCase):
@@ -359,14 +359,14 @@
 
     def test_init(self):
         rc = ResultComparison(self.r1, self.r2)
-        self.assertEquals(rc.name, 'AngryPhonebook')
+        self.assertEqual(rc.name, 'AngryPhonebook')
         self.assertAlmostEquals(rc.ratio, 12325.0 / 11616.0)
         self.assertAlmostEquals(rc.delta, (((11616.0 / 12325.0) - 1) * 100),
                                 places=3)
         # handle test results that sometimes change to zero, when compiler
         # optimizes out the body of the incorrectly written test
         rc = ResultComparison(self.r0, self.r0)
-        self.assertEquals(rc.name, 'GlobalClass')
+        self.assertEqual(rc.name, 'GlobalClass')
         self.assertAlmostEquals(rc.ratio, 1)
         self.assertAlmostEquals(rc.delta, 0, places=3)
         rc = ResultComparison(self.r0, self.r01)
@@ -452,14 +452,14 @@
         parser = LogParser()
         results = parser.parse_results(log.splitlines())
         self.assertTrue(isinstance(results[0], PerformanceTestResult))
-        self.assertEquals(results[0].name, 'BitCount')
+        self.assertEqual(results[0].name, 'BitCount')
 
     def test_parse_results_tab_delimited(self):
         log = '34\tBitCount\t20\t3\t4\t4\t0\t4'
         parser = LogParser()
         results = parser.parse_results(log.splitlines())
         self.assertTrue(isinstance(results[0], PerformanceTestResult))
-        self.assertEquals(results[0].name, 'BitCount')
+        self.assertEqual(results[0].name, 'BitCount')
 
     def test_parse_results_formatted_text(self):
         """Parse format that Benchmark_Driver prints to console"""
@@ -473,32 +473,32 @@
         results = parser.parse_results(log.splitlines()[1:])  # without 1st \n
         self.assertTrue(isinstance(results[0], PerformanceTestResult))
         r = results[0]
-        self.assertEquals(r.name, 'Array2D')
-        self.assertEquals(r.max_rss, 20915200)
+        self.assertEqual(r.name, 'Array2D')
+        self.assertEqual(r.max_rss, 20915200)
 
     def test_parse_quantiles(self):
         """Gathers samples from reported quantiles. Handles optional memory."""
         r = LogParser.results_from_string(
             """#,TEST,SAMPLES,MIN(μs),MEDIAN(μs),MAX(μs)
 1,Ackermann,3,54383,54512,54601""")['Ackermann']
-        self.assertEquals([s.runtime for s in r.samples.all_samples],
-                          [54383, 54512, 54601])
+        self.assertEqual([s.runtime for s in r.samples.all_samples],
+                         [54383, 54512, 54601])
         r = LogParser.results_from_string(
             """#,TEST,SAMPLES,MIN(μs),MEDIAN(μs),MAX(μs),MAX_RSS(B)
 1,Ackermann,3,54529,54760,55807,266240""")['Ackermann']
-        self.assertEquals([s.runtime for s in r.samples.all_samples],
-                          [54529, 54760, 55807])
-        self.assertEquals(r.max_rss, 266240)
+        self.assertEqual([s.runtime for s in r.samples.all_samples],
+                         [54529, 54760, 55807])
+        self.assertEqual(r.max_rss, 266240)
 
     def test_parse_delta_quantiles(self):
         r = LogParser.results_from_string(  # 2-quantile aka. median
             '#,TEST,SAMPLES,MIN(μs),𝚫MEDIAN,𝚫MAX\n0,B,1,101,,')['B']
-        self.assertEquals(
+        self.assertEqual(
             (r.num_samples, r.min, r.median, r.max, r.samples.count),
             (1, 101, 101, 101, 1))
         r = LogParser.results_from_string(
             '#,TEST,SAMPLES,MIN(μs),𝚫MEDIAN,𝚫MAX\n0,B,2,101,,1')['B']
-        self.assertEquals(
+        self.assertEqual(
             (r.num_samples, r.min, r.median, r.max, r.samples.count),
             (2, 101, 101, 102, 2))
         r = LogParser.results_from_string(  # 20-quantiles aka. ventiles
@@ -506,7 +506,7 @@
             '𝚫V9,𝚫VA,𝚫VB,𝚫VC,𝚫VD,𝚫VE,𝚫VF,𝚫VG,𝚫VH,𝚫VI,𝚫VJ,𝚫MAX\n' +
             '202,DropWhileArray,200,214,,,,,,,,,,,,1,,,,,,2,16,464'
         )['DropWhileArray']
-        self.assertEquals(
+        self.assertEqual(
             (r.num_samples, r.min, r.max, r.samples.count),
             # last 3 ventiles were outliers and were excluded from the sample
             (200, 214, 215, 18))
@@ -538,28 +538,28 @@
         results = parser.parse_results(verbose_log.split('\n'))
 
         r = results[0]
-        self.assertEquals(
+        self.assertEqual(
             (r.name, r.min, r.max, int(r.mean), int(r.sd), r.median),
             ('AngryPhonebook', 11467, 13898, 12392, 1315, 11812)
         )
-        self.assertEquals(r.num_samples, r.samples.num_samples)
-        self.assertEquals(results[0].samples.all_samples,
-                          [(0, 78, 11812), (1, 90, 13898), (2, 90, 11467)])
-        self.assertEquals(r.yields, None)
+        self.assertEqual(r.num_samples, r.samples.num_samples)
+        self.assertEqual(results[0].samples.all_samples,
+                         [(0, 78, 11812), (1, 90, 13898), (2, 90, 11467)])
+        self.assertEqual(r.yields, None)
 
         r = results[1]
-        self.assertEquals(
+        self.assertEqual(
             (r.name, r.min, r.max, int(r.mean), int(r.sd), r.median),
             ('Array2D', 369900, 381039, 373994, 6127, 371043)
         )
-        self.assertEquals(r.setup, 14444)
-        self.assertEquals(r.num_samples, r.samples.num_samples)
-        self.assertEquals(results[1].samples.all_samples,
-                          [(0, 1, 369900), (1, 1, 381039), (2, 1, 371043)])
+        self.assertEqual(r.setup, 14444)
+        self.assertEqual(r.num_samples, r.samples.num_samples)
+        self.assertEqual(results[1].samples.all_samples,
+                         [(0, 1, 369900), (1, 1, 381039), (2, 1, 371043)])
         yielded = r.yields[0]
-        self.assertEquals(yielded.before_sample, 1)
-        self.assertEquals(yielded.after, 369918)
-        self.assertEquals(r.yields, [(1, 369918), (2, 381039)])
+        self.assertEqual(yielded.before_sample, 1)
+        self.assertEqual(yielded.after, 369918)
+        self.assertEqual(r.yields, [(1, 369918), (2, 381039)])
 
     def test_parse_environment_verbose(self):
         """Parse stats about environment in verbose mode."""
@@ -572,21 +572,21 @@
         results = parser.parse_results(verbose_log.split('\n'))
 
         r = results[0]
-        self.assertEquals(r.max_rss, 32768)
-        self.assertEquals(r.mem_pages, 8)
-        self.assertEquals(r.voluntary_cs, 1)
-        self.assertEquals(r.involuntary_cs, 1109)
+        self.assertEqual(r.max_rss, 32768)
+        self.assertEqual(r.mem_pages, 8)
+        self.assertEqual(r.voluntary_cs, 1)
+        self.assertEqual(r.involuntary_cs, 1109)
 
     def test_results_from_merge(self):
         """Parsing concatenated log merges same PerformanceTestResults"""
         concatenated_logs = """4,ArrayAppend,20,23641,29000,24990,0,24990
 4,ArrayAppend,1,20000,20000,20000,0,20000"""
         results = LogParser.results_from_string(concatenated_logs)
-        self.assertEquals(results.keys(), ['ArrayAppend'])
+        self.assertEqual(results.keys(), ['ArrayAppend'])
         result = results['ArrayAppend']
         self.assertTrue(isinstance(result, PerformanceTestResult))
-        self.assertEquals(result.min, 20000)
-        self.assertEquals(result.max, 29000)
+        self.assertEqual(result.min, 20000)
+        self.assertEqual(result.max, 29000)
 
     def test_results_from_merge_verbose(self):
         """Parsing verbose log  merges all PerformanceTestSamples.
@@ -604,18 +604,18 @@
     Sample 3,364245
 3,Array2D,4,363094,376131,368159,5931,369169"""
         results = LogParser.results_from_string(concatenated_logs)
-        self.assertEquals(results.keys(), ['Array2D'])
+        self.assertEqual(results.keys(), ['Array2D'])
         result = results['Array2D']
         self.assertTrue(isinstance(result, PerformanceTestResult))
-        self.assertEquals(result.min, 350815)
-        self.assertEquals(result.max, 376131)
-        self.assertEquals(result.median, 358817)
+        self.assertEqual(result.min, 350815)
+        self.assertEqual(result.max, 376131)
+        self.assertEqual(result.median, 358817)
         self.assertAlmostEquals(result.sd, 8443.37, places=2)
         self.assertAlmostEquals(result.mean, 361463.25, places=2)
-        self.assertEquals(result.num_samples, 8)
+        self.assertEqual(result.num_samples, 8)
         samples = result.samples
         self.assertTrue(isinstance(samples, PerformanceTestSamples))
-        self.assertEquals(samples.count, 8)
+        self.assertEqual(samples.count, 8)
 
     def test_excludes_outliers_from_samples(self):
         verbose_log = """Running DropFirstAnySeqCntRangeLazy for 10 samples.
@@ -643,9 +643,9 @@
 """
         parser = LogParser()
         result = parser.parse_results(verbose_log.split('\n'))[0]
-        self.assertEquals(result.num_samples, 10)
-        self.assertEquals(result.samples.count, 8)
-        self.assertEquals(len(result.samples.outliers), 2)
+        self.assertEqual(result.num_samples, 10)
+        self.assertEqual(result.samples.count, 8)
+        self.assertEqual(len(result.samples.outliers), 2)
 
 
 class TestTestComparator(OldAndNewLog):
@@ -654,27 +654,27 @@
             return [t.name for t in tests]
 
         tc = TestComparator(self.old_results, self.new_results, 0.05)
-        self.assertEquals(names(tc.unchanged), ['AngryPhonebook', 'Array2D'])
-        self.assertEquals(names(tc.increased), ['ByteSwap', 'ArrayAppend'])
-        self.assertEquals(names(tc.decreased), ['BitCount'])
-        self.assertEquals(names(tc.added), ['TwoSum'])
-        self.assertEquals(names(tc.removed), ['AnyHashableWithAClass'])
+        self.assertEqual(names(tc.unchanged), ['AngryPhonebook', 'Array2D'])
+        self.assertEqual(names(tc.increased), ['ByteSwap', 'ArrayAppend'])
+        self.assertEqual(names(tc.decreased), ['BitCount'])
+        self.assertEqual(names(tc.added), ['TwoSum'])
+        self.assertEqual(names(tc.removed), ['AnyHashableWithAClass'])
         # other way around
         tc = TestComparator(self.new_results, self.old_results, 0.05)
-        self.assertEquals(names(tc.unchanged), ['AngryPhonebook', 'Array2D'])
-        self.assertEquals(names(tc.increased), ['BitCount'])
-        self.assertEquals(names(tc.decreased), ['ByteSwap', 'ArrayAppend'])
-        self.assertEquals(names(tc.added), ['AnyHashableWithAClass'])
-        self.assertEquals(names(tc.removed), ['TwoSum'])
+        self.assertEqual(names(tc.unchanged), ['AngryPhonebook', 'Array2D'])
+        self.assertEqual(names(tc.increased), ['BitCount'])
+        self.assertEqual(names(tc.decreased), ['ByteSwap', 'ArrayAppend'])
+        self.assertEqual(names(tc.added), ['AnyHashableWithAClass'])
+        self.assertEqual(names(tc.removed), ['TwoSum'])
         # delta_threshold determines the sorting into change groups;
         # report only change above 100% (ByteSwap's runtime went to 0):
         tc = TestComparator(self.old_results, self.new_results, 1)
-        self.assertEquals(
+        self.assertEqual(
             names(tc.unchanged),
             ['AngryPhonebook', 'Array2D', 'ArrayAppend', 'BitCount']
         )
-        self.assertEquals(names(tc.increased), ['ByteSwap'])
-        self.assertEquals(tc.decreased, [])
+        self.assertEqual(names(tc.increased), ['ByteSwap'])
+        self.assertEqual(tc.decreased, [])
 
 
 class TestReportFormatter(OldAndNewLog):
@@ -696,12 +696,12 @@
         self.assert_report_contains(texts, self.html)
 
     def test_values(self):
-        self.assertEquals(
+        self.assertEqual(
             ReportFormatter.values(PerformanceTestResult(
                 '1,AngryPhonebook,20,10664,12933,11035,576,10884'.split(','))),
             ('AngryPhonebook', '10664', '12933', '11035', '—')
         )
-        self.assertEquals(
+        self.assertEqual(
             ReportFormatter.values(PerformanceTestResult(
                 '1,AngryPhonebook,1,12045,12045,12045,0,12045,10510336'
                 .split(','))),
@@ -712,16 +712,16 @@
             '1,AngryPhonebook,1,12325,12325,12325,0,12325,10510336'.split(','))
         r2 = PerformanceTestResult(
             '1,AngryPhonebook,1,11616,11616,11616,0,11616,10502144'.split(','))
-        self.assertEquals(
+        self.assertEqual(
             ReportFormatter.values(ResultComparison(r1, r2)),
             ('AngryPhonebook', '12325', '11616', '-5.8%', '1.06x')
         )
-        self.assertEquals(
+        self.assertEqual(
             ReportFormatter.values(ResultComparison(r2, r1)),
             ('AngryPhonebook', '11616', '12325', '+6.1%', '0.94x')
         )
         r2.max = r1.min + 1
-        self.assertEquals(
+        self.assertEqual(
             ReportFormatter.values(ResultComparison(r1, r2))[4],
             '1.06x (?)'  # is_dubious
         )
@@ -742,12 +742,12 @@
         PerformanceTestResults.
         """
         performance_test_result = self.tc.added[0]
-        self.assertEquals(
+        self.assertEqual(
             ReportFormatter.header_for(performance_test_result),
             ('TEST', 'MIN', 'MAX', 'MEAN', 'MAX_RSS')
         )
         comparison_result = self.tc.increased[0]
-        self.assertEquals(
+        self.assertEqual(
             ReportFormatter.header_for(comparison_result),
             ('TEST', 'OLD', 'NEW', 'DELTA', 'RATIO')
         )
@@ -859,17 +859,17 @@
         self.assertIn('usage: compare_perf_tests.py', err.getvalue())
 
         args = parse_args(self.required)
-        self.assertEquals(args.old_file, 'old.log')
-        self.assertEquals(args.new_file, 'new.log')
+        self.assertEqual(args.old_file, 'old.log')
+        self.assertEqual(args.new_file, 'new.log')
 
     def test_format_argument(self):
-        self.assertEquals(parse_args(self.required).format, 'markdown')
-        self.assertEquals(
+        self.assertEqual(parse_args(self.required).format, 'markdown')
+        self.assertEqual(
             parse_args(self.required + ['--format', 'markdown']).format,
             'markdown')
-        self.assertEquals(
+        self.assertEqual(
             parse_args(self.required + ['--format', 'git']).format, 'git')
-        self.assertEquals(
+        self.assertEqual(
             parse_args(self.required + ['--format', 'html']).format, 'html')
 
         with captured_output() as (_, err):
@@ -882,14 +882,14 @@
     def test_delta_threshold_argument(self):
         # default value
         args = parse_args(self.required)
-        self.assertEquals(args.delta_threshold, 0.05)
+        self.assertEqual(args.delta_threshold, 0.05)
         # float parsing
         args = parse_args(self.required + ['--delta-threshold', '0.1'])
-        self.assertEquals(args.delta_threshold, 0.1)
+        self.assertEqual(args.delta_threshold, 0.1)
         args = parse_args(self.required + ['--delta-threshold', '1'])
-        self.assertEquals(args.delta_threshold, 1.0)
+        self.assertEqual(args.delta_threshold, 1.0)
         args = parse_args(self.required + ['--delta-threshold', '.2'])
-        self.assertEquals(args.delta_threshold, 0.2)
+        self.assertEqual(args.delta_threshold, 0.2)
 
         with captured_output() as (_, err):
             self.assertRaises(SystemExit, parse_args,
@@ -899,10 +899,10 @@
                       err.getvalue())
 
     def test_output_argument(self):
-        self.assertEquals(parse_args(self.required).output, None)
-        self.assertEquals(parse_args(self.required +
-                                     ['--output', 'report.log']).output,
-                          'report.log')
+        self.assertEqual(parse_args(self.required).output, None)
+        self.assertEqual(parse_args(self.required +
+                                    ['--output', 'report.log']).output,
+                         'report.log')
 
     def test_changes_only_argument(self):
         self.assertFalse(parse_args(self.required).changes_only)
@@ -962,7 +962,7 @@
         """Writes Markdown formatted report to stdout and `--output` file."""
         report_out, report_file = (
             self.execute_main_with_format('markdown', test_output=True))
-        self.assertEquals(report_out, report_file)
+        self.assertEqual(report_out, report_file)
         self.assert_report_contains(self.markdown, report_file)
 
     def test_git(self):
@@ -974,7 +974,7 @@
         """Writes Git formatted report to stdout and `--output` file."""
         report_out, report_file = (
             self.execute_main_with_format('git', test_output=True))
-        self.assertEquals(report_out, report_file)
+        self.assertEqual(report_out, report_file)
         self.assert_report_contains(self.git, report_file)
 
     def test_html(self):
@@ -986,7 +986,7 @@
         """Writes HTML formatted report to stdout and `--output` file."""
         report_out, report_file = (
             self.execute_main_with_format('html', test_output=True))
-        self.assertEquals(report_out, report_file)
+        self.assertEqual(report_out, report_file)
         self.assert_report_contains(self.html, report_file)
 
 
diff --git a/benchmark/single-source/Codable.swift b/benchmark/single-source/Codable.swift
index b0c451a..1729a7a 100644
--- a/benchmark/single-source/Codable.swift
+++ b/benchmark/single-source/Codable.swift
@@ -107,17 +107,33 @@
   JSONTester = CodablePerfTester(encoder: JSONEncoder(), decoder: JSONDecoder())
 }
 
+#if !_runtime(_ObjC)
+// If we do not have an objc-runtime, then we do not have a definition for
+// autoreleasepool. Add in our own fake autoclosure for it that is inline
+// always. That should be able to be eaten through by the optimizer no problem.
+@inline(__always)
+public func autoreleasepool<Result>(
+  invoking body: () throws -> Result
+) rethrows -> Result {
+  return try body()
+}
+#endif
+
 @inline(never)
 public func run_JSONPerfEncode(_ N: Int) {
-  for _ in 0 ..< N {
-    JSONTester.encode()
+  autoreleasepool {
+    for _ in 0 ..< N {
+      JSONTester.encode()
+    }
   }
 }
 
 @inline(never)
 public func run_JSONPerfDecode(_ N: Int) {
-  for _ in 0 ..< N {
-    JSONTester.decode()
+  autoreleasepool {
+    for _ in 0 ..< N {
+      JSONTester.decode()
+    }
   }
 }
 
@@ -131,15 +147,19 @@
 
 @inline(never)
 public func run_PlistPerfEncode(_ N: Int) {
-  for _ in 0 ..< N {
-    plistTester.encode()
+  autoreleasepool {
+    for _ in 0 ..< N {
+      plistTester.encode()
+    }
   }
 }
 
 @inline(never)
 public func run_PlistPerfDecode(_ N: Int) {
-  for _ in 0 ..< N {
-    plistTester.decode()
+  autoreleasepool {
+    for _ in 0 ..< N {
+      plistTester.decode()
+    }
   }
 }
 
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 8e51106..f3e9d2b 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -755,9 +755,10 @@
     endif()
   endif()
 
-  if (SWIFT_COMPILER_VERSION)
-    if(${SWIFTLIB_SINGLE_SDK} IN_LIST SWIFT_APPLE_PLATFORMS)
-      list(APPEND SWIFTLIB_SINGLE_LINK_FLAGS "-Xlinker" "-current_version" "-Xlinker" "${SWIFT_COMPILER_VERSION}" "-Xlinker" "-compatibility_version" "-Xlinker" "1")
+  if(${SWIFTLIB_SINGLE_SDK} IN_LIST SWIFT_APPLE_PLATFORMS)
+    list(APPEND SWIFTLIB_SINGLE_LINK_FLAGS "-Xlinker" "-compatibility_version" "-Xlinker" "1")
+    if (SWIFT_COMPILER_VERSION)
+      list(APPEND SWIFTLIB_SINGLE_LINK_FLAGS "-Xlinker" "-current_version" "-Xlinker" "${SWIFT_COMPILER_VERSION}" )
     endif()
   endif()
 
@@ -1848,12 +1849,6 @@
         set(swiftlib_swift_compile_private_frameworks_flag "-Fsystem" "${SWIFT_SDK_${sdk}_ARCH_${arch}_PATH}/System/Library/PrivateFrameworks/")
       endif()
 
-      if("${sdk}" STREQUAL WINDOWS)
-        if(arch STREQUAL x86_64)
-          set(swiftlib_swift_compile_flags_arch -Xcc -D_AMD64_)
-        endif()
-      endif()
-
       # Add this library variant.
       _add_swift_library_single(
         ${VARIANT_NAME}
@@ -2200,83 +2195,6 @@
       PROPERTIES FOLDER "Swift executables")
 endfunction()
 
-# Add an executable for the host machine.
-#
-# Usage:
-#   add_swift_executable(name
-#     [DEPENDS dep1 ...]
-#     [LLVM_COMPONENT_DEPENDS comp1 ...]
-#     [FILE_DEPENDS target1 ...]
-#     [LINK_LIBRARIES target1 ...]
-#     [EXCLUDE_FROM_ALL]
-#     [DONT_STRIP_NON_MAIN_SYMBOLS]
-#     [DISABLE_ASLR]
-#     source1 [source2 source3 ...])
-#
-#   name
-#     Name of the executable (e.g., swift).
-#
-#   LIBRARIES
-#     Libraries this executable depends on, without variant suffixes.
-#
-#   LLVM_COMPONENT_DEPENDS
-#     LLVM components this executable depends on.
-#
-#   FILE_DEPENDS
-#     Additional files this executable depends on.
-#
-#   LINK_LIBRARIES
-#     Libraries to link with.
-#
-#   EXCLUDE_FROM_ALL
-#     Whether to exclude this executable from the ALL_BUILD target.
-#
-#   DONT_STRIP_NON_MAIN_SYMBOLS
-#     Should we not strip non main symbols.
-#
-#   DISABLE_ASLR
-#     Should we compile with -Wl,-no_pie so that ASLR is disabled?
-#
-#   source1 ...
-#     Sources to add into this executable.
-#
-# Note:
-#   Host executables are not given a variant suffix. To build an executable for
-#   each SDK and ARCH variant, use add_swift_target_executable.
-function(add_swift_executable name)
-  # Parse the arguments we were given.
-  cmake_parse_arguments(SWIFTEXE
-    "EXCLUDE_FROM_ALL;DONT_STRIP_NON_MAIN_SYMBOLS;DISABLE_ASLR"
-    ""
-    "DEPENDS;LLVM_COMPONENT_DEPENDS;LINK_LIBRARIES;COMPILE_FLAGS"
-    ${ARGN})
-
-  translate_flag(${SWIFTEXE_EXCLUDE_FROM_ALL}
-      "EXCLUDE_FROM_ALL"
-      SWIFTEXE_EXCLUDE_FROM_ALL_FLAG)
-  translate_flag(${SWIFTEXE_DONT_STRIP_NON_MAIN_SYMBOLS}
-      "DONT_STRIP_NON_MAIN_SYMBOLS"
-      SWIFTEXE_DONT_STRIP_NON_MAIN_SYMBOLS_FLAG)
-  translate_flag(${SWIFTEXE_DISABLE_ASLR}
-      "DISABLE_ASLR"
-      SWIFTEXE_DISABLE_ASLR_FLAG)
-
-  set(SWIFTEXE_SOURCES ${SWIFTEXE_UNPARSED_ARGUMENTS})
-
-  _add_swift_executable_single(
-      ${name}
-      ${SWIFTEXE_SOURCES}
-      DEPENDS ${SWIFTEXE_DEPENDS}
-      LLVM_COMPONENT_DEPENDS ${SWIFTEXE_LLVM_COMPONENT_DEPENDS}
-      LINK_LIBRARIES ${SWIFTEXE_LINK_LIBRARIES}
-      SDK ${SWIFT_HOST_VARIANT_SDK}
-      ARCHITECTURE ${SWIFT_HOST_VARIANT_ARCH}
-      COMPILE_FLAGS ${SWIFTEXE_COMPILE_FLAGS}
-      ${SWIFTEXE_EXCLUDE_FROM_ALL_FLAG}
-      ${SWIFTEXE_DONT_STRIP_NON_MAIN_SYMBOLS_FLAG}
-      ${SWIFTEXE_DISABLE_ASLR_FLAG})
-endfunction()
-
 macro(add_swift_tool_subdirectory name)
   add_llvm_subdirectory(SWIFT TOOL ${name})
 endmacro()
@@ -2300,7 +2218,9 @@
                MESSAGE "Swift Component is required to add a host tool")
 
   # Create the executable rule.
-  add_swift_executable(${executable}
+  _add_swift_executable_single(${executable}
+    SDK ${SWIFT_HOST_VARIANT_SDK}
+    ARCHITECTURE ${SWIFT_HOST_VARIANT_ARCH}
     ${ASHT_UNPARSED_ARGUMENTS})
 
   swift_install_in_component(${ASHT_SWIFT_COMPONENT}
diff --git a/cmake/modules/StandaloneOverlay.cmake b/cmake/modules/StandaloneOverlay.cmake
index 98f55ef..a4cd97e 100644
--- a/cmake/modules/StandaloneOverlay.cmake
+++ b/cmake/modules/StandaloneOverlay.cmake
@@ -19,6 +19,7 @@
 set(SWIFT_DARWIN_DEPLOYMENT_VERSION_IOS "7.0" CACHE STRING "")
 set(SWIFT_DARWIN_DEPLOYMENT_VERSION_TVOS "9.0" CACHE STRING "")
 set(SWIFT_DARWIN_DEPLOYMENT_VERSION_WATCHOS "2.0" CACHE STRING "")
+set(SWIFT_ENABLE_PARSEABLE_MODULE_INTERFACES TRUE)
 
 set(SWIFT_SOURCE_DIR "${SWIFT_SOURCE_ROOT}/src/swift" CACHE PATH "")
 set(SWIFT_PATH_TO_LLVM_SOURCE "${SWIFT_SOURCE_ROOT}/src/llvm" CACHE PATH "")
@@ -61,6 +62,7 @@
 # Some overlays include the runtime's headers,
 # and some of those headers are generated at build time.
 add_subdirectory("${SWIFT_SOURCE_DIR}/include" "swift/include")
+add_subdirectory("${SWIFT_SOURCE_DIR}/apinotes" "swift/apinotes")
 
 # Without this line, installing components is broken. This needs refactoring.
 swift_configure_components()
diff --git a/cmake/modules/SwiftComponents.cmake b/cmake/modules/SwiftComponents.cmake
index ada4a1a..725c685 100644
--- a/cmake/modules/SwiftComponents.cmake
+++ b/cmake/modules/SwiftComponents.cmake
@@ -67,10 +67,25 @@
 set(_SWIFT_DEFINED_COMPONENTS
   "autolink-driver;compiler;clang-builtin-headers;clang-resource-dir-symlink;clang-builtin-headers-in-clang-resource-dir;stdlib;stdlib-experimental;sdk-overlay;parser-lib;editor-integration;tools;testsuite-tools;toolchain-dev-tools;dev;license;sourcekit-xpc-service;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers")
 
+# The default install components include all of the defined components, except
+# for the following exceptions.
+set(_SWIFT_DEFAULT_COMPONENTS "${_SWIFT_DEFINED_COMPONENTS}")
+# 'dev' takes up a lot of disk space and isn't part of a normal toolchain.
+list(REMOVE_ITEM _SWIFT_DEFAULT_COMPONENTS "dev")
+# These clang header options conflict with 'clang-builtin-headers'.
+list(REMOVE_ITEM _SWIFT_DEFAULT_COMPONENTS "clang-resource-dir-symlink")
+list(REMOVE_ITEM _SWIFT_DEFAULT_COMPONENTS "clang-builtin-headers-in-clang-resource-dir")
+# The sourcekit install variants are currently mutually exclusive.
+if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+  list(REMOVE_ITEM _SWIFT_DEFAULT_COMPONENTS "sourcekit-inproc")
+else()
+  list(REMOVE_ITEM _SWIFT_DEFAULT_COMPONENTS "sourcekit-xpc-service")
+endif()
+
 macro(swift_configure_components)
   # Set the SWIFT_INSTALL_COMPONENTS variable to the default value if it is not passed in via -D
-  set(SWIFT_INSTALL_COMPONENTS "${_SWIFT_DEFINED_COMPONENTS}" CACHE STRING
-    "A semicolon-separated list of components to install ${_SWIFT_DEFINED_COMPONENTS}")
+  set(SWIFT_INSTALL_COMPONENTS "${_SWIFT_DEFAULT_COMPONENTS}" CACHE STRING
+    "A semicolon-separated list of components to install from the set ${_SWIFT_DEFINED_COMPONENTS}")
 
   foreach(component ${_SWIFT_DEFINED_COMPONENTS})
     string(TOUPPER "${component}" var_name_piece)
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 34bef31..86870dd 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _ABI:
 
 .. highlight:: none
diff --git a/docs/ABI/TypeLayout.rst b/docs/ABI/TypeLayout.rst
index 7f5569c..4d6feb3 100644
--- a/docs/ABI/TypeLayout.rst
+++ b/docs/ABI/TypeLayout.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _ABI:
 
 .. highlight:: none
diff --git a/docs/ABI/TypeMetadata.rst b/docs/ABI/TypeMetadata.rst
index 4091108..350945a 100644
--- a/docs/ABI/TypeMetadata.rst
+++ b/docs/ABI/TypeMetadata.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _ABI:
 
 .. highlight:: none
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 75fc706..a0f36cb 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -24,112 +24,6 @@
   message(WARNING "Unable to find sphinx-build program. Not building docs")
 endif()
 
-## Example testing
-
-find_program(LITRE_EXECUTABLE
-  NAMES litre
-  DOC "LitRe literate programming tool for docutils")
-
-find_program(SPHINX_EXECUTABLE
-  NAMES sphinx-build
-  HINTS $ENV{SPHINX_DIR}
-  PATH_SUFFIXES bin
-  DOC "Sphinx documentation generator")
-
-if(LITRE_EXECUTABLE)
-  # Find all the .rst files
-  file(GLOB_RECURSE rst_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.rst)
-  set(subdir_CMakeLists)
-
-  foreach(rst ${rst_files})
-    # Prepare a testing directory containing a CMakeLists.txt
-    # and example files extracted from the .rst
-    set(test_dir "litre-tests/${rst}.litre-tests")
-
-    add_custom_command(
-      OUTPUT
-        ${test_dir}/CMakeLists.txt
-      COMMAND
-        ${LITRE_EXECUTABLE}
-        --default_compiler=${CMAKE_BINARY_DIR}/bin/swift
-        "--dump_dir=${test_dir}"
-        --traceback
-        --report=severe  # suppress most .rst errors.  We have lots of them.
-        ${CMAKE_CURRENT_SOURCE_DIR}/${rst}
-      DEPENDS
-        ${CMAKE_CURRENT_SOURCE_DIR}/${rst}
-      COMMENT
-        "Generating/Updating LitRe tests for ${rst}"
-      VERBATIM
-      )
-
-    list(APPEND subdir_CMakeLists ${test_dir}/CMakeLists.txt)
-  endforeach()
-
-  # Create a top-level CMakeLists.txt in a temporary file
-  add_custom_command(
-    OUTPUT
-      litre-top-CMakeLists.cmake
-    COMMAND
-      ${CMAKE_COMMAND} -DOUTPUT=litre-top-CMakeLists.cmake
-                      -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-          -P ${CMAKE_CURRENT_SOURCE_DIR}/GenerateTopLevelLitreCMakeLists.cmake
-          ${rst_files}
-    DEPENDS
-      ${rst_files}
-    COMMENT
-      "Generating top-level LitRe CMakeLists.txt content"
-    VERBATIM
-    )
-
-  # Only update the real top-level CMakeLists.txt if something changed
-  add_custom_command(
-    OUTPUT
-      "litre-tests/CMakeLists.txt"
-    COMMAND
-      "${CMAKE_COMMAND}" "-E" "copy_if_different"
-      "litre-top-CMakeLists.cmake" "litre-tests/CMakeLists.txt"
-    DEPENDS
-      "litre-top-CMakeLists.cmake"
-    COMMENT
-      "Updating top-level LitRe CMakeLists.txt"
-    VERBATIM)
-
-  # Create a build directory
-  add_custom_command(
-    OUTPUT "litre-tests/build"
-    COMMAND "${CMAKE_COMMAND}" "-E" "make_directory" "litre-tests/build")
-
-  # Run CMake itself to configure/build the tests
-  add_custom_command(
-    OUTPUT
-      litre-tests/results
-    COMMAND
-      ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" "${CMAKE_CURRENT_BINARY_DIR}/litre-tests"
-    COMMAND
-      ${CMAKE_COMMAND} --build .
-    COMMAND
-      ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/litre-tests/results"
-    WORKING_DIRECTORY
-      litre-tests/build
-    DEPENDS
-      ${CMAKE_BINARY_DIR}/bin/swift
-      litre-tests/CMakeLists.txt litre-tests/build ${subdir_CMakeLists}
-    COMMENT
-      "Running LitRe tests"
-    VERBATIM
-      )
-
-  # Add a target so these tests show up in the Xcode project.
-  add_custom_target(
-    LiterateTests SOURCES ${rst_files}
-    DEPENDS litre-tests/results
-    )
-  set_target_properties(LiterateTests PROPERTIES FOLDER "Tests")
-else()
-  message(WARNING "LitRe not found; code examples won't be tested.")
-endif()
-
 if (LLVM_ENABLE_DOXYGEN)
 if (DOXYGEN_FOUND)
   set(abs_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md
index 1963b1e..e95bc56 100644
--- a/docs/ContinuousIntegration.md
+++ b/docs/ContinuousIntegration.md
@@ -10,6 +10,7 @@
     - [Validation Testing](#validation-testing)
     - [Linting](#linting)
     - [Source Compatibility Testing](#source-compatibility-testing)
+    - [Sourcekit Stress Testing](#sourcekit-stress-testing)
     - [Specific Preset Testing](#specific-preset-testing)
     - [Build Swift Toolchain](#build-swift-toolchain)
     - [Testing Compiler Performance](#testing-compiler-performance)
@@ -139,6 +140,12 @@
 macOS platform | @swift-ci Please Test Source Compatibility Release | Swift Source Compatibility Suite on macOS Platform (Release)
 macOS platform | @swift-ci Please Test Source Compatibility Debug | Swift Source Compatibility Suite on macOS Platform (Debug)
 
+### Sourcekit Stress Testing
+
+Platform       | Comment | Check Status
+------------   | ------- | ------------
+macOS platform | @swift-ci Please Sourcekit Stress test | Swift Sourcekit Stress Tester on macOS Platform
+
 ### Specific Preset Testing
 
 Platform       | Comment | Check Status
diff --git a/docs/DependencyAnalysis.rst b/docs/DependencyAnalysis.rst
index 91a1a97..e7a1a36 100644
--- a/docs/DependencyAnalysis.rst
+++ b/docs/DependencyAnalysis.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 ===================
 Dependency Analysis
 ===================
diff --git a/docs/GenerateTopLevelLitreCMakeLists.cmake b/docs/GenerateTopLevelLitreCMakeLists.cmake
deleted file mode 100644
index 16fa3af..0000000
--- a/docs/GenerateTopLevelLitreCMakeLists.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-set(rst_files)
-foreach(i RANGE 5 ${CMAKE_ARGC})
-  list(APPEND rst_files ${CMAKE_ARGV${i}})
-endforeach()
-configure_file(${SOURCE_DIR}/LitReTemplate.cmake ${OUTPUT} @ONLY)
diff --git a/docs/Lexicon.rst b/docs/Lexicon.rst
index b15fab8..8d0a76c 100644
--- a/docs/Lexicon.rst
+++ b/docs/Lexicon.rst
@@ -3,8 +3,6 @@
 .. title:: Lexicon
 .. default-role:: term
 
-.. @raise litre.TestsAreMissing
-
 This file defines several terms used by the Swift compiler and standard library
 source code, tests, and commit messages. See also the `LLVM lexicon`_.
 
diff --git a/docs/Literals.rst b/docs/Literals.rst
index c7fde55..f6d4396 100644
--- a/docs/Literals.rst
+++ b/docs/Literals.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 Literals
 ========
 
diff --git a/docs/LitreTemplate.cmake b/docs/LitreTemplate.cmake
deleted file mode 100644
index 3bfbb7165..0000000
--- a/docs/LitreTemplate.cmake
+++ /dev/null
@@ -1,18 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-find_program(LITRE_EXECUTABLE
-  NAMES litre
-  DOC "LitRe literate programming tool for docutils")
-
-# Make the LitreTesting cmake module available
-execute_process(
-  COMMAND ${LITRE_EXECUTABLE} --cmake_module_path
-  OUTPUT_VARIABLE litre_cmake_module_path
-  OUTPUT_STRIP_TRAILING_WHITESPACE
-  )
-
-list(APPEND CMAKE_MODULE_PATH ${litre_cmake_module_path})
-set(rst_files "@rst_files@")
-foreach(rst ${rst_files})
-  add_subdirectory("${rst}.litre-tests")
-endforeach()
diff --git a/docs/LogicalObjects.rst b/docs/LogicalObjects.rst
index a5fef5d..6e32da0 100644
--- a/docs/LogicalObjects.rst
+++ b/docs/LogicalObjects.rst
@@ -1,5 +1,3 @@
-.. @raise litre.TestsAreMissing
-
 Logical Objects
 ===============
 
diff --git a/docs/Modules.rst b/docs/Modules.rst
index 16dfc4f..fbea23d 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. default-role:: term
 .. title:: Modules User Model
 
diff --git a/docs/OptimizationTips.rst b/docs/OptimizationTips.rst
index 9a6312c..f00de1f 100644
--- a/docs/OptimizationTips.rst
+++ b/docs/OptimizationTips.rst
@@ -161,7 +161,7 @@
   func usingE(_ e: E) {
     e.doSomething() // There is no sub class in the file that declares this class.
                     // The compiler can remove virtual calls to doSomething()
-                    // and directly call A's doSomething method.
+                    // and directly call E's doSomething method.
   }
 
   func usingF(_ f: F) -> Int {
diff --git a/docs/PatternMatching.rst b/docs/PatternMatching.rst
index f26d7e8..0968bfa 100644
--- a/docs/PatternMatching.rst
+++ b/docs/PatternMatching.rst
@@ -1,4 +1,3 @@
-.. @raise litre.TestsAreMissing
 .. _PatternMatching:
 
 Pattern Matching
diff --git a/docs/SIL.rst b/docs/SIL.rst
index 699e9f3..1e5b781 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -1,4 +1,3 @@
-.. @raise litre.TestsAreMissing
 .. highlight:: none
 
 Swift Intermediate Language (SIL)
@@ -2828,6 +2827,13 @@
 ``$Optional<T>``, except that it is ``null`` if the heap object has begun
 deallocation.
 
+If ``[take]`` is specified then the underlying weak reference is invalidated
+implying that the weak reference count of the loaded value is decremented. If
+``[take]`` is not specified then the underlying weak reference count is not
+affected by this operation (i.e. it is a +0 weak ref count operation). In either
+case, the strong reference count will be incremented before any changes to the
+weak reference count.
+
 This operation must be atomic with respect to the final ``strong_release`` on
 the operand heap object.  It need not be atomic with respect to ``store_weak``
 operations on the same address.
@@ -2846,7 +2852,13 @@
 
 If ``[initialization]`` is given, the weak reference must currently either be
 uninitialized or destroyed.  If it is not given, the weak reference must
-currently be initialized.
+currently be initialized. After the evaluation:
+
+* The value that was originally referenced by the weak reference will have
+  its weak reference count decremented by 1.
+* If the optionally typed operand is non-nil, the strong reference wrapped in
+  the optional has its weak reference count incremented by 1. In contrast, the reference's
+  strong reference count is not touched.
 
 This operation must be atomic with respect to the final ``strong_release`` on
 the operand (source) heap object.  It need not be atomic with respect to
@@ -3348,11 +3360,12 @@
 `````````````
 ::
 
-  sil-instruction ::= 'partial_apply' callee-ownership-attr? sil-value
+  sil-instruction ::= 'partial_apply' callee-ownership-attr? on-stack-attr? sil-value
                         sil-apply-substitution-list?
                         '(' (sil-value (',' sil-value)*)? ')'
                         ':' sil-type
   callee-ownership-attr ::= '[callee_guaranteed]'
+  on-stack-attr ::= '[on_stack]'
 
   %c = partial_apply %0(%1, %2, ...) : $(Z..., A, B, ...) -> R
   // Note that the type of the callee '%0' is specified *after* the arguments
@@ -3370,12 +3383,18 @@
 Creates a closure by partially applying the function ``%0`` to a partial
 sequence of its arguments. In the instruction syntax, the type of the callee is
 specified after the argument list; the types of the argument and of the defined
-value are derived from the function type of the callee. The closure context will
-be allocated with retain count 1 and initialized to contain the values ``%1``,
+value are derived from the function type of the callee. If the ``partial_apply``
+has an escaping function type (not ``[on_stack]``) the closure context will be
+allocated with retain count 1 and initialized to contain the values ``%1``,
 ``%2``, etc.  The closed-over values will not be retained; that must be done
-separately before the ``partial_apply``. The closure does however take
-ownership of the partially applied arguments; when the closure reference
-count reaches zero, the contained values will be destroyed.
+separately before the ``partial_apply``. The closure does however take ownership
+of the partially applied arguments; when the closure reference count reaches
+zero, the contained values will be destroyed. If the ``partial_apply`` has a
+``@noescape`` function type (``partial_apply [on_stack]``) the closure context
+is allocated on the stack and intialized to contain the closed-over values. The
+closed-over values are not retained, lifetime of the closed-over values must be
+managed separately. The lifetime of the stack context of a ``partial_apply
+[stack]`` must be terminated with a ``dealloc_stack``.
 
 If the callee is generic, all of its generic parameters must be bound by the
 given substitution list. The arguments are given with these generic
diff --git a/docs/SequencesAndCollections.rst b/docs/SequencesAndCollections.rst
index e0010c9..2eef944 100644
--- a/docs/SequencesAndCollections.rst
+++ b/docs/SequencesAndCollections.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. default-role:: code
 
 ====================================
diff --git a/docs/StdlibRationales.rst b/docs/StdlibRationales.rst
index 097dc8a..3b8503b 100644
--- a/docs/StdlibRationales.rst
+++ b/docs/StdlibRationales.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 =================================================
 Rationales for the Swift standard library designs
 =================================================
diff --git a/docs/StoredAndComputedVariables.rst b/docs/StoredAndComputedVariables.rst
index 3d8c196..22dd625 100644
--- a/docs/StoredAndComputedVariables.rst
+++ b/docs/StoredAndComputedVariables.rst
@@ -1,5 +1,3 @@
-.. @raise litre.TestsAreMissing
-
 =============================
 Stored and Computed Variables
 =============================
diff --git a/docs/StringDesign.rst b/docs/StringDesign.rst
index d8973bc..26c0c8f 100644
--- a/docs/StringDesign.rst
+++ b/docs/StringDesign.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 .. raw:: html
 
     <style>
diff --git a/docs/TypeChecker.rst b/docs/TypeChecker.rst
index 6aece99..d383781 100644
--- a/docs/TypeChecker.rst
+++ b/docs/TypeChecker.rst
@@ -1,5 +1,3 @@
-.. @raise litre.TestsAreMissing
-
 Type Checker Design and Implementation
 ========================================
 
diff --git a/docs/WindowsBuild.md b/docs/WindowsBuild.md
index 4673177..ecdd101 100644
--- a/docs/WindowsBuild.md
+++ b/docs/WindowsBuild.md
@@ -103,7 +103,7 @@
 cmake -G Ninja^
   -DCMAKE_BUILD_TYPE=Debug^
   -DCMAKE_C_COMPILER=cl^
-  -DCMAKE_CXX_COMPIELR=cl^
+  -DCMAKE_CXX_COMPILER=cl^
   S:\cmark
 popd
 cmake --build "S:\build\Ninja-DebugAssert\cmark-windows-amd64"
@@ -133,7 +133,7 @@
 - Update your path to include the LLVM tools.
 
 ```cmd
-set PATH=%PATH%;S:\build\Ninja-DebugAssert\llvm-windows-amd64\bin
+set PATH=S:\build\Ninja-DebugAssert\llvm-windows-amd64\bin;%PATH%
 ```
 
 ### 7. Build Swift
diff --git a/docs/archive/LangRefNew.rst b/docs/archive/LangRefNew.rst
index d14ec79..131d3ce 100644
--- a/docs/archive/LangRefNew.rst
+++ b/docs/archive/LangRefNew.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 ===============================
 Swift Language Reference Manual
 ===============================
diff --git a/docs/archive/NamespaceLevelVarsAndTopLevelCode.rst b/docs/archive/NamespaceLevelVarsAndTopLevelCode.rst
index 5e9fe71..18aad26 100644
--- a/docs/archive/NamespaceLevelVarsAndTopLevelCode.rst
+++ b/docs/archive/NamespaceLevelVarsAndTopLevelCode.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 .. warning:: This document was used in planning Swift 1.0; it has not been kept
   up to date and does not describe the current or planned behavior of Swift.
 
diff --git a/docs/archive/Objective-CInteroperability.rst b/docs/archive/Objective-CInteroperability.rst
index 2ad9689..4e121be 100644
--- a/docs/archive/Objective-CInteroperability.rst
+++ b/docs/archive/Objective-CInteroperability.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 ============================
 Objective-C Interoperability
 ============================
diff --git a/docs/archive/Resilience.rst b/docs/archive/Resilience.rst
index a65079f..64b32f8 100644
--- a/docs/archive/Resilience.rst
+++ b/docs/archive/Resilience.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _Resilience:
 
 Resilience
diff --git a/docs/contents.rst b/docs/contents.rst
index 8d2e9ee..1a57554 100644
--- a/docs/contents.rst
+++ b/docs/contents.rst
@@ -1,4 +1,3 @@
-.. @raise litre.TestsAreMissing
 .. _contents:
 
 Contents
diff --git a/docs/proposals/Concurrency.rst b/docs/proposals/Concurrency.rst
index 0e34b05..dfff719 100644
--- a/docs/proposals/Concurrency.rst
+++ b/docs/proposals/Concurrency.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. ConcurrencyModel:
 
 *Note*: This document is **not an accepted Swift proposal**. It does not describe Swift's concurrency mechanisms as they currently exist, nor is it a roadmap for the addition of concurrency mechanisms in future versions of Swift.
diff --git a/docs/proposals/DeclarationTypeChecker.rst b/docs/proposals/DeclarationTypeChecker.rst
index 5d3d395..711c0f6 100644
--- a/docs/proposals/DeclarationTypeChecker.rst
+++ b/docs/proposals/DeclarationTypeChecker.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 Declaration Type Checker
 ========================
 
diff --git a/docs/proposals/Inplace.rst b/docs/proposals/Inplace.rst
index c571b73..f14e0d1 100644
--- a/docs/proposals/Inplace.rst
+++ b/docs/proposals/Inplace.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 =====================
  In-Place Operations
 =====================
diff --git a/docs/proposals/TypeState.rst b/docs/proposals/TypeState.rst
index a09700d..e4b94d9 100644
--- a/docs/proposals/TypeState.rst
+++ b/docs/proposals/TypeState.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 General Type State Notes
 ========================
 
diff --git a/docs/proposals/ValueSemantics.rst b/docs/proposals/ValueSemantics.rst
index 72d514f..04ce7fc 100644
--- a/docs/proposals/ValueSemantics.rst
+++ b/docs/proposals/ValueSemantics.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _ValueSemantics:
 
 ==========================
diff --git a/docs/proposals/archive/MemoryAndConcurrencyModel.rst b/docs/proposals/archive/MemoryAndConcurrencyModel.rst
index 3f1fcff..6e35b3f 100644
--- a/docs/proposals/archive/MemoryAndConcurrencyModel.rst
+++ b/docs/proposals/archive/MemoryAndConcurrencyModel.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _MemoryAndConcurrencyModel:
 
 Swift Memory and Concurrency Model
diff --git a/docs/proposals/archive/ProgramStructureAndCompilationModel.rst b/docs/proposals/archive/ProgramStructureAndCompilationModel.rst
index e6219ea..49d6cd9 100644
--- a/docs/proposals/archive/ProgramStructureAndCompilationModel.rst
+++ b/docs/proposals/archive/ProgramStructureAndCompilationModel.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _ProgramStructureAndCompilationModel:
 
 .. highlight:: none
diff --git a/docs/proposals/rejected/Clonable.rst b/docs/proposals/rejected/Clonable.rst
index 2dfaf9e..b67b05b 100644
--- a/docs/proposals/rejected/Clonable.rst
+++ b/docs/proposals/rejected/Clonable.rst
@@ -1,7 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
-
 ==========
  Clonable
 ==========
diff --git a/docs/proposals/valref.rst b/docs/proposals/valref.rst
index b373097..c1d8623 100644
--- a/docs/proposals/valref.rst
+++ b/docs/proposals/valref.rst
@@ -1,6 +1,5 @@
 :orphan:
 
-.. @raise litre.TestsAreMissing
 .. _valref:
 
 =======================
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index fee647c..52795bb 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -493,7 +493,7 @@
     HasLazyConformances : 1
   );
 
-  SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+2+8+16,
+  SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+2+1+8+16,
     /// Whether the \c RequiresClass bit is valid.
     RequiresClassValid : 1,
 
@@ -519,6 +519,9 @@
     /// The stage of the circularity check for this protocol.
     Circularity : 2,
 
+    /// Whether we've computed the inherited protocols list yet.
+    InheritedProtocolsValid : 1,
+
     : NumPadBits,
 
     /// If this is a compiler-known protocol, this will be a KnownProtocolKind
@@ -3562,11 +3565,16 @@
   void createObjCMethodLookup();
 
   struct {
+    /// The superclass decl and a bit to indicate whether the
+    /// superclass was computed yet or not.
+    llvm::PointerIntPair<ClassDecl *, 1, bool> SuperclassDecl;
+
     /// The superclass type and a bit to indicate whether the
     /// superclass was computed yet or not.
-    llvm::PointerIntPair<Type, 1, bool> Superclass;
+    llvm::PointerIntPair<Type, 1, bool> SuperclassType;
   } LazySemanticInfo;
 
+  friend class SuperclassDeclRequest;
   friend class SuperclassTypeRequest;
   friend class TypeChecker;
 
@@ -3888,6 +3896,18 @@
 class ProtocolDecl final : public NominalTypeDecl {
   SourceLoc ProtocolLoc;
 
+  ArrayRef<ProtocolDecl *> InheritedProtocols;
+
+  struct {
+    /// The superclass decl and a bit to indicate whether the
+    /// superclass was computed yet or not.
+    llvm::PointerIntPair<ClassDecl *, 1, bool> SuperclassDecl;
+
+    /// The superclass type and a bit to indicate whether the
+    /// superclass was computed yet or not.
+    llvm::PointerIntPair<Type, 1, bool> SuperclassType;
+  } LazySemanticInfo;
+
   /// The generic signature representing exactly the new requirements introduced
   /// by this protocol.
   const Requirement *RequirementSignature = nullptr;
@@ -3898,12 +3918,9 @@
 
   bool existentialTypeSupportedSlow(LazyResolver *resolver);
 
-  struct {
-    /// The superclass type and a bit to indicate whether the
-    /// superclass was computed yet or not.
-    llvm::PointerIntPair<Type, 1, bool> Superclass;
-  } LazySemanticInfo;
+  ArrayRef<ProtocolDecl *> getInheritedProtocolsSlow();
 
+  friend class SuperclassDeclRequest;
   friend class SuperclassTypeRequest;
   friend class TypeChecker;
 
@@ -3915,7 +3932,12 @@
   using Decl::getASTContext;
 
   /// Retrieve the set of protocols inherited from this protocol.
-  llvm::TinyPtrVector<ProtocolDecl *> getInheritedProtocols() const;
+  ArrayRef<ProtocolDecl *> getInheritedProtocols() const {
+    if (Bits.ProtocolDecl.InheritedProtocolsValid)
+      return InheritedProtocols;
+
+    return const_cast<ProtocolDecl *>(this)->getInheritedProtocolsSlow();
+  }
 
   /// Determine whether this protocol has a superclass.
   bool hasSuperclass() const { return (bool)getSuperclassDecl(); }
@@ -5875,7 +5897,7 @@
 /// enum. EnumElementDecls are represented in the AST as members of their
 /// parent EnumDecl, although syntactically they are subordinate to the
 /// EnumCaseDecl.
-class EnumElementDecl : public ValueDecl {
+class EnumElementDecl : public DeclContext, public ValueDecl {
   /// This is the type specified with the enum element, for
   /// example 'Int' in 'case Y(Int)'.  This is null if there is no type
   /// associated with this element, as in 'case Z' or in all elements of enum
@@ -5895,7 +5917,8 @@
                   SourceLoc EqualsLoc,
                   LiteralExpr *RawValueExpr,
                   DeclContext *DC)
-  : ValueDecl(DeclKind::EnumElement, DC, Name, IdentifierLoc),
+  : DeclContext(DeclContextKind::EnumElementDecl, DC),
+    ValueDecl(DeclKind::EnumElement, DC, Name, IdentifierLoc),
     Params(Params),
     EqualsLoc(EqualsLoc),
     RawValueExpr(RawValueExpr)
@@ -5963,14 +5986,23 @@
     return getParameterList() != nullptr;
   }
 
-  static bool classof(const Decl *D) {
-    return D->getKind() == DeclKind::EnumElement;
-  }
-
   /// True if the case is marked 'indirect'.
   bool isIndirect() const {
     return getAttrs().hasAttribute<IndirectAttr>();
   }
+
+  static bool classof(const Decl *D) {
+    return D->getKind() == DeclKind::EnumElement;
+  }
+
+  static bool classof(const DeclContext *DC) {
+    if (auto D = DC->getAsDecl())
+      return classof(D);
+    return false;
+  }
+
+  using DeclContext::operator new;
+  using Decl::getASTContext;
 };
   
 inline SourceRange EnumCaseDecl::getSourceRange() const {
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index 14497b9..ddfbbb9 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -78,6 +78,7 @@
   Initializer,
   TopLevelCodeDecl,
   SubscriptDecl,
+  EnumElementDecl,
   AbstractFunctionDecl,
   SerializedLocal,
   Last_LocalDeclContextKind = SerializedLocal,
@@ -230,6 +231,7 @@
     case DeclContextKind::TopLevelCodeDecl:
     case DeclContextKind::AbstractFunctionDecl:
     case DeclContextKind::SubscriptDecl:
+    case DeclContextKind::EnumElementDecl:
     case DeclContextKind::GenericTypeDecl:
     case DeclContextKind::ExtensionDecl:
       return ASTHierarchy::Decl;
diff --git a/include/swift/AST/DeclNodes.def b/include/swift/AST/DeclNodes.def
index eca225a..5aeef91 100644
--- a/include/swift/AST/DeclNodes.def
+++ b/include/swift/AST/DeclNodes.def
@@ -171,7 +171,7 @@
     ABSTRACT_FUNCTION_DECL(Func, AbstractFunctionDecl)
       ABSTRACT_FUNCTION_DECL(Accessor, FuncDecl)
     DECL_RANGE(AbstractFunction, Constructor, Accessor)
-  VALUE_DECL(EnumElement, ValueDecl)
+  CONTEXT_VALUE_DECL(EnumElement, ValueDecl)
   DECL_RANGE(Value, Enum, EnumElement)
 
 ITERABLE_GENERIC_DECL(Extension, Decl)
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index f9c4321..96fe433 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -3172,6 +3172,12 @@
 ERROR(continue_not_in_this_stmt,none,
       "'continue' cannot be used with %0 statements", (StringRef))
 
+ERROR(unresolved_label,none,
+      "use of unresolved label %0", (Identifier))
+ERROR(unresolved_label_corrected,none,
+      "use of unresolved label %0; did you mean %1?",
+      (Identifier, Identifier))
+
 // Switch Stmt
 ERROR(no_match_operator,none,
       "no binary '~=' operator available for 'switch' statement", ())
diff --git a/include/swift/AST/NameLookupRequests.h b/include/swift/AST/NameLookupRequests.h
index 7f73230..5f7177a 100644
--- a/include/swift/AST/NameLookupRequests.h
+++ b/include/swift/AST/NameLookupRequests.h
@@ -133,7 +133,7 @@
 /// Request the superclass declaration for the given class.
 class SuperclassDeclRequest :
     public SimpleRequest<SuperclassDeclRequest,
-                         CacheKind::Uncached, // FIXME: Cache these
+                         CacheKind::SeparatelyCached,
                          ClassDecl *,
                          NominalTypeDecl *> {
 public:
@@ -149,6 +149,8 @@
 public:
   // Caching
   bool isCached() const { return true; }
+  Optional<ClassDecl *> getCachedResult() const;
+  void cacheResult(ClassDecl *value) const;
 
   // Cycle handling
   void diagnoseCycle(DiagnosticEngine &diags) const;
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index 0e4e5e6..b0565c7 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -3208,6 +3208,8 @@
     return cast<GenericFunctionType>(fnType->getCanonicalType());
   }
 
+  CanFunctionType substGenericArgs(SubstitutionMap subs) const;
+
   CanGenericSignature getGenericSignature() const {
     return CanGenericSignature(getPointer()->getGenericSignature());
   }
diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h
index ccabc6f..d84f82c 100644
--- a/include/swift/Frontend/Frontend.h
+++ b/include/swift/Frontend/Frontend.h
@@ -614,8 +614,7 @@
 
 private:
   void createREPLFile(const ImplicitImports &implicitImports);
-  std::unique_ptr<DelayedParsingCallbacks>
-  computeDelayedParsingCallback(bool isPrimary);
+  std::unique_ptr<DelayedParsingCallbacks> computeDelayedParsingCallback();
 
   void addMainFileToModule(const ImplicitImports &implicitImports);
 
@@ -626,15 +625,13 @@
   void parseLibraryFile(unsigned BufferID,
                         const ImplicitImports &implicitImports,
                         PersistentParserState &PersistentState,
-                        DelayedParsingCallbacks *PrimaryDelayedCB,
-                        DelayedParsingCallbacks *SecondaryDelayedCB);
+                        DelayedParsingCallbacks *DelayedCB);
 
   /// Return true if had load error
   bool
   parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports,
                                      PersistentParserState &PersistentState,
-                                     DelayedParsingCallbacks *PrimaryDelayedCB,
-                                     DelayedParsingCallbacks *SecondaryDelayedCB);
+                                     DelayedParsingCallbacks *DelayedCB);
 
   OptionSet<TypeCheckingFlags> computeTypeCheckingOptions();
 
diff --git a/include/swift/Parse/DelayedParsingCallbacks.h b/include/swift/Parse/DelayedParsingCallbacks.h
index b8dfc04..7359dcb 100644
--- a/include/swift/Parse/DelayedParsingCallbacks.h
+++ b/include/swift/Parse/DelayedParsingCallbacks.h
@@ -35,15 +35,6 @@
                                               SourceRange BodyRange) = 0;
 };
 
-class AlwaysDelayedCallbacks : public DelayedParsingCallbacks {
-  bool shouldDelayFunctionBodyParsing(Parser &TheParser,
-                                      AbstractFunctionDecl *AFD,
-                                      const DeclAttributes &Attrs,
-                                      SourceRange BodyRange) override {
-    return true;
-  }
-};
-
 /// Implementation of callbacks that guide the parser in delayed
 /// parsing for code completion.
 class CodeCompleteDelayedCallbacks : public DelayedParsingCallbacks {
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index 5cf9b20..cbe82c8 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -22,8 +22,7 @@
 #include "swift/Basic/SourceManager.h"
 #include "swift/Parse/LexerState.h"
 #include "swift/Parse/Token.h"
-#include "swift/Syntax/References.h"
-#include "swift/Syntax/Trivia.h"
+#include "swift/Parse/ParsedTrivia.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/SaveAndRestore.h"
 
@@ -118,13 +117,13 @@
   ///
   /// This is only preserved if this Lexer was constructed with
   /// `TriviaRetentionMode::WithTrivia`.
-  syntax::Trivia LeadingTrivia;
+  ParsedTrivia LeadingTrivia;
 
   /// The current trailing trivia for the next token.
   ///
   /// This is only preserved if this Lexer was constructed with
   /// `TriviaRetentionMode::WithTrivia`.
-  syntax::Trivia TrailingTrivia;
+  ParsedTrivia TrailingTrivia;
   
   Lexer(const Lexer&) = delete;
   void operator=(const Lexer&) = delete;
@@ -185,8 +184,8 @@
 
   /// Lex a token. If \c TriviaRetentionMode is \c WithTrivia, passed pointers
   /// to trivias are populated.
-  void lex(Token &Result, syntax::Trivia &LeadingTriviaResult,
-           syntax::Trivia &TrailingTriviaResult) {
+  void lex(Token &Result, ParsedTrivia &LeadingTriviaResult,
+           ParsedTrivia &TrailingTriviaResult) {
     Result = NextToken;
     if (TriviaRetention == TriviaRetentionMode::WithTrivia) {
       LeadingTriviaResult = {LeadingTrivia};
@@ -197,7 +196,7 @@
   }
 
   void lex(Token &Result) {
-    syntax::Trivia LeadingTrivia, TrailingTrivia;
+    ParsedTrivia LeadingTrivia, TrailingTrivia;
     lex(Result, LeadingTrivia, TrailingTrivia);
   }
 
@@ -229,7 +228,7 @@
   /// After restoring the state, lexer will return this token and continue from
   /// there.
   State getStateForBeginningOfToken(const Token &Tok,
-                                    const syntax::Trivia &LeadingTrivia = {}) const {
+                                    const ParsedTrivia &LeadingTrivia = {}) const {
 
     // If the token has a comment attached to it, rewind to before the comment,
     // not just the start of the token.  This ensures that we will re-lex and
@@ -529,7 +528,7 @@
   void lexOperatorIdentifier();
   void lexHexNumber();
   void lexNumber();
-  void lexTrivia(syntax::Trivia &T, bool IsForTrailingTrivia);
+  void lexTrivia(ParsedTrivia &T, bool IsForTrailingTrivia);
   static unsigned lexUnicodeEscape(const char *&CurPtr, Lexer *Diags);
 
   unsigned lexCharacter(const char *&CurPtr, char StopQuote,
diff --git a/include/swift/Parse/LexerState.h b/include/swift/Parse/LexerState.h
index 5ce65d3..f400cfe 100644
--- a/include/swift/Parse/LexerState.h
+++ b/include/swift/Parse/LexerState.h
@@ -19,7 +19,7 @@
 
 #include "llvm/ADT/Optional.h"
 #include "swift/Basic/SourceLoc.h"
-#include "swift/Syntax/Trivia.h"
+#include "swift/Parse/ParsedTrivia.h"
 
 namespace swift {
 class Lexer;
@@ -39,7 +39,7 @@
 private:
   explicit LexerState(SourceLoc Loc) : Loc(Loc) {}
   SourceLoc Loc;
-  llvm::Optional<syntax::Trivia> LeadingTrivia;
+  llvm::Optional<ParsedTrivia> LeadingTrivia;
   friend class Lexer;
 };
 
diff --git a/include/swift/Parse/ParsedRawSyntaxNode.h b/include/swift/Parse/ParsedRawSyntaxNode.h
index e415789..a43639c 100644
--- a/include/swift/Parse/ParsedRawSyntaxNode.h
+++ b/include/swift/Parse/ParsedRawSyntaxNode.h
@@ -14,14 +14,15 @@
 #define SWIFT_PARSE_PARSEDRAWSYNTAXNODE_H
 
 #include "swift/Basic/SourceLoc.h"
+#include "swift/Parse/ParsedTrivia.h"
 #include "swift/Parse/Token.h"
 #include "swift/Syntax/SyntaxKind.h"
-#include "swift/Syntax/Trivia.h"
 #include <vector>
 
 namespace swift {
 
 typedef void *OpaqueSyntaxNode;
+class SyntaxParsingContext;
 
 /// Represents a raw syntax node formed by the parser.
 ///
@@ -50,12 +51,14 @@
     CharSourceRange Range;
   };
   struct DeferredLayoutNode {
-    std::vector<ParsedRawSyntaxNode> Children;
+    ArrayRef<ParsedRawSyntaxNode> Children;
   };
   struct DeferredTokenNode {
-    Token Tok;
-    syntax::Trivia LeadingTrivia;
-    syntax::Trivia TrailingTrivia;
+    const ParsedTriviaPiece *TriviaPieces;
+    SourceLoc TokLoc;
+    unsigned TokLength;
+    uint16_t NumLeadingTrivia;
+    uint16_t NumTrailingTrivia;
   };
 
   union {
@@ -77,16 +80,22 @@
     assert(getKind() == k && "Syntax kind with too large value!");
   }
 
-  ParsedRawSyntaxNode(Token tok,
-                      syntax::Trivia leadingTrivia,
-                      syntax::Trivia trailingTrivia)
-    : DeferredToken{std::move(tok),
-                    std::move(leadingTrivia),
-                    std::move(trailingTrivia)},
+  ParsedRawSyntaxNode(tok tokKind, SourceLoc tokLoc, unsigned tokLength,
+                      const ParsedTriviaPiece *triviaPieces,
+                      unsigned numLeadingTrivia,
+                      unsigned numTrailingTrivia)
+    : DeferredToken{triviaPieces,
+                    tokLoc, tokLength,
+                    uint16_t(numLeadingTrivia),
+                    uint16_t(numTrailingTrivia)},
       SynKind(uint16_t(syntax::SyntaxKind::Token)),
-      TokKind(uint16_t(tok.getKind())),
+      TokKind(uint16_t(tokKind)),
       DK(DataKind::DeferredToken) {
-    assert(getTokenKind() == tok.getKind() && "Token kind is too large value!");
+    assert(getTokenKind() == tokKind && "Token kind is too large value!");
+    assert(DeferredToken.NumLeadingTrivia == numLeadingTrivia &&
+           "numLeadingTrivia is too large value!");
+    assert(DeferredToken.NumTrailingTrivia == numTrailingTrivia &&
+           "numLeadingTrivia is too large value!");
   }
 
 public:
@@ -106,63 +115,6 @@
     assert(getTokenKind() == tokKind && "Token kind with too large value!");
   }
 
-  ParsedRawSyntaxNode(const ParsedRawSyntaxNode &other) {
-    switch (other.DK) {
-    case DataKind::Null:
-      break;
-    case DataKind::Recorded:
-      new(&this->RecordedData)RecordedSyntaxNode(other.RecordedData);
-      break;
-    case DataKind::DeferredLayout:
-      new(&this->DeferredLayout)DeferredLayoutNode(other.DeferredLayout);
-      break;
-    case DataKind::DeferredToken:
-      new(&this->DeferredToken)DeferredTokenNode(other.DeferredToken);
-      break;
-    }
-    this->SynKind = other.SynKind;
-    this->TokKind = other.TokKind;
-    this->DK = other.DK;
-  }
-
-  ParsedRawSyntaxNode(ParsedRawSyntaxNode &&other) {
-    switch (other.DK) {
-    case DataKind::Null:
-      break;
-    case DataKind::Recorded:
-      new(&this->RecordedData)RecordedSyntaxNode(
-          std::move(other.RecordedData));
-      break;
-    case DataKind::DeferredLayout:
-      new(&this->DeferredLayout)DeferredLayoutNode(
-          std::move(other.DeferredLayout));
-      break;
-    case DataKind::DeferredToken:
-      new(&this->DeferredToken)DeferredTokenNode(
-          std::move(other.DeferredToken));
-      break;
-    }
-    this->SynKind = other.SynKind;
-    this->TokKind = other.TokKind;
-    this->DK = other.DK;
-  }
-
-  ~ParsedRawSyntaxNode() {
-    releaseMemory();
-  }
-
-  ParsedRawSyntaxNode &operator=(const ParsedRawSyntaxNode &other) {
-    releaseMemory();
-    new (this)ParsedRawSyntaxNode(other);
-    return *this;
-  }
-
-  ParsedRawSyntaxNode &operator=(ParsedRawSyntaxNode &&other) {
-    releaseMemory();
-    new (this)ParsedRawSyntaxNode(std::move(other));
-    return *this;
-  }
-
   syntax::SyntaxKind getKind() const { return syntax::SyntaxKind(SynKind); }
   tok getTokenKind() const { return tok(TokKind); }
 
@@ -201,44 +153,44 @@
     assert(DK == DataKind::DeferredLayout);
     return DeferredLayout.Children;
   }
-  void addDeferredChild(ParsedRawSyntaxNode subnode) {
-    assert(DK == DataKind::DeferredLayout);
-    DeferredLayout.Children.push_back(std::move(subnode));
-  }
 
   // Deferred Token Data =====================================================//
 
-  const Token &getToken() const {
+  CharSourceRange getDeferredTokenRangeWithoutBackticks() const {
     assert(DK == DataKind::DeferredToken);
-    return DeferredToken.Tok;
+    return CharSourceRange{DeferredToken.TokLoc, DeferredToken.TokLength};
   }
-  const syntax::Trivia &getLeadingTrivia() const {
+  ArrayRef<ParsedTriviaPiece> getDeferredLeadingTriviaPieces() const {
     assert(DK == DataKind::DeferredToken);
-    return DeferredToken.LeadingTrivia;
+    return ArrayRef<ParsedTriviaPiece>(DeferredToken.TriviaPieces,
+                                       DeferredToken.NumLeadingTrivia);
   }
-  const syntax::Trivia &getTrailingTrivia() const {
+  ArrayRef<ParsedTriviaPiece> getDeferredTrailingTriviaPieces() const {
     assert(DK == DataKind::DeferredToken);
-    return DeferredToken.TrailingTrivia;
+    return ArrayRef<ParsedTriviaPiece>(
+      DeferredToken.TriviaPieces + DeferredToken.NumLeadingTrivia,
+      DeferredToken.NumTrailingTrivia);
   }
 
   //==========================================================================//
 
   /// Form a deferred syntax layout node.
   static ParsedRawSyntaxNode makeDeferred(syntax::SyntaxKind k,
-                        ArrayRef<ParsedRawSyntaxNode> deferredNodes) {
-    return ParsedRawSyntaxNode{k, deferredNodes};
-  }
+                        ArrayRef<ParsedRawSyntaxNode> deferredNodes,
+                                          SyntaxParsingContext &ctx);
 
   /// Form a deferred token node.
   static ParsedRawSyntaxNode makeDeferred(Token tok,
-                                          syntax::Trivia leadingTrivia,
-                                          syntax::Trivia trailingTrivia) {
-    return ParsedRawSyntaxNode{std::move(tok), std::move(leadingTrivia),
-        std::move(trailingTrivia)};
-  }
+                                          const ParsedTrivia &leadingTrivia,
+                                          const ParsedTrivia &trailingTrivia,
+                                          SyntaxParsingContext &ctx);
 
   /// Form a deferred missing token node.
-  static ParsedRawSyntaxNode makeDeferredMissing(tok tokKind, SourceLoc loc);
+  static ParsedRawSyntaxNode makeDeferredMissing(tok tokKind, SourceLoc loc) {
+    auto raw = ParsedRawSyntaxNode(tokKind, loc, 0, nullptr, 0, 0);
+    raw.IsMissing = true;
+    return raw;
+  }
 
   /// Dump this piece of syntax recursively for debugging or testing.
   LLVM_ATTRIBUTE_DEPRECATED(
@@ -251,20 +203,6 @@
   static ParsedRawSyntaxNode null() {
     return ParsedRawSyntaxNode{};
   }
-
-private:
-  void releaseMemory() {
-    switch (DK) {
-    case DataKind::Null:
-      break;
-    case DataKind::Recorded:
-      RecordedData.~RecordedSyntaxNode(); break;
-    case DataKind::DeferredLayout:
-      DeferredLayout.~DeferredLayoutNode(); break;
-    case DataKind::DeferredToken:
-      DeferredToken.~DeferredTokenNode(); break;
-    }
-  }
 };
 
 } // end namespace swift
diff --git a/include/swift/Parse/ParsedRawSyntaxRecorder.h b/include/swift/Parse/ParsedRawSyntaxRecorder.h
index f43375e..9ab897b 100644
--- a/include/swift/Parse/ParsedRawSyntaxRecorder.h
+++ b/include/swift/Parse/ParsedRawSyntaxRecorder.h
@@ -24,7 +24,10 @@
 
 namespace swift {
 
+class CharSourceRange;
 class ParsedRawSyntaxNode;
+struct ParsedTrivia;
+class ParsedTriviaPiece;
 class SyntaxParseActions;
 class SourceLoc;
 class Token;
@@ -32,7 +35,6 @@
 
 namespace syntax {
   enum class SyntaxKind;
-  struct Trivia;
 }
 
 class ParsedRawSyntaxRecorder {
@@ -43,8 +45,12 @@
     : SPActions(std::move(spActions)) {}
 
   ParsedRawSyntaxNode recordToken(const Token &tok,
-                                  const syntax::Trivia &leadingTrivia,
-                                  const syntax::Trivia &trailingTrivia);
+                                  const ParsedTrivia &leadingTrivia,
+                                  const ParsedTrivia &trailingTrivia);
+
+  ParsedRawSyntaxNode recordToken(tok tokenKind, CharSourceRange tokenRange,
+                                  ArrayRef<ParsedTriviaPiece> leadingTrivia,
+                                  ArrayRef<ParsedTriviaPiece> trailingTrivia);
 
   /// Record a missing token. \p loc can be invalid or an approximate location
   /// of where the token would be if not missing.
diff --git a/include/swift/Parse/ParsedSyntaxBuilders.h.gyb b/include/swift/Parse/ParsedSyntaxBuilders.h.gyb
index 7a64c73..95d1f4e 100644
--- a/include/swift/Parse/ParsedSyntaxBuilders.h.gyb
+++ b/include/swift/Parse/ParsedSyntaxBuilders.h.gyb
@@ -34,17 +34,20 @@
 %   if node.is_buildable():
 %     child_count = len(node.children)
 class Parsed${node.name}Builder {
-  ParsedRawSyntaxRecorder &Rec;
-  bool IsBacktracking;
-  ParsedRawSyntaxNode Layout[${child_count}] = {
+  SyntaxParsingContext &SPCtx;
+  ParsedRawSyntaxNode Layout[${child_count}];
 %     for child in node.children:
-    ParsedRawSyntaxNode::null(),
+%       child_node = NODE_MAP.get(child.syntax_kind)
+%       if child_node and child_node.is_syntax_collection():
+%         child_elt = child_node.collection_element_name
+%         child_elt_type = child_node.collection_element_type
+  SmallVector<ParsedRawSyntaxNode, 8> ${child_elt}Nodes;
+%       end
 %     end
-  };
 
 public:
   explicit Parsed${node.name}Builder(SyntaxParsingContext &SPCtx)
-    : Rec(SPCtx.getRecorder()), IsBacktracking(SPCtx.isBacktracking()) {}
+    : SPCtx(SPCtx) {}
 
 %     for child in node.children:
   Parsed${node.name}Builder &use${child.name}(Parsed${child.type_name} ${child.name});
@@ -61,7 +64,7 @@
 
 private:
   Parsed${node.name} record();
-  void finishLayout();
+  void finishLayout(bool deferred);
 };
 
 %   end
diff --git a/include/swift/Parse/ParsedSyntaxRecorder.h.gyb b/include/swift/Parse/ParsedSyntaxRecorder.h.gyb
index da0734a..631bce6 100644
--- a/include/swift/Parse/ParsedSyntaxRecorder.h.gyb
+++ b/include/swift/Parse/ParsedSyntaxRecorder.h.gyb
@@ -46,7 +46,8 @@
   static Parsed${node.name} record${node.syntax_kind}(${child_params},
                                               ParsedRawSyntaxRecorder &rec);
 public:
-  static Parsed${node.name} defer${node.syntax_kind}(${child_params});
+  static Parsed${node.name} defer${node.syntax_kind}(${child_params},
+                                              SyntaxParsingContext &SPCtx);
   static Parsed${node.name} make${node.syntax_kind}(${child_params},
                                               SyntaxParsingContext &SPCtx);
 %   elif node.is_syntax_collection():
@@ -57,7 +58,8 @@
 
 public:
   static Parsed${node.name} defer${node.syntax_kind}(
-      ArrayRef<Parsed${node.collection_element_type}> elts);
+      ArrayRef<Parsed${node.collection_element_type}> elts,
+      SyntaxParsingContext &SPCtx);
   static Parsed${node.name} make${node.syntax_kind}(
       ArrayRef<Parsed${node.collection_element_type}> elts,
       SyntaxParsingContext &SPCtx);
diff --git a/include/swift/Parse/ParsedTrivia.h b/include/swift/Parse/ParsedTrivia.h
new file mode 100644
index 0000000..8bf9e9f
--- /dev/null
+++ b/include/swift/Parse/ParsedTrivia.h
@@ -0,0 +1,136 @@
+//===--- ParsedTrivia.h - ParsedTrivia API ----------------------*- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_PARSE_PARSEDTRIVIA_H
+#define SWIFT_PARSE_PARSEDTRIVIA_H
+
+#include "swift/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace swift {
+  class SourceLoc;
+  class SourceManager;
+
+namespace syntax {
+  enum class TriviaKind;
+  struct Trivia;
+}
+
+class ParsedTriviaPiece {
+  syntax::TriviaKind Kind;
+  unsigned Length;
+
+public:
+  ParsedTriviaPiece(syntax::TriviaKind kind, unsigned length)
+      : Kind(kind), Length(length) {}
+
+  syntax::TriviaKind getKind() const { return Kind; }
+
+  /// Return the text of the trivia.
+  unsigned getLength() const { return Length; }
+
+  void extendLength(unsigned len) {
+    Length += len;
+  }
+
+  static size_t getTotalLength(ArrayRef<ParsedTriviaPiece> pieces) {
+    size_t Len = 0;
+    for (auto &p : pieces)
+      Len += p.getLength();
+    return Len;
+  }
+
+  bool operator==(const ParsedTriviaPiece &Other) const {
+    return Kind == Other.Kind && Length == Other.Length;
+  }
+
+  bool operator!=(const ParsedTriviaPiece &Other) const {
+    return !(*this == Other);
+  }
+
+  static syntax::Trivia
+  convertToSyntaxTrivia(ArrayRef<ParsedTriviaPiece> pieces, SourceLoc loc,
+                        const SourceManager &SM, unsigned bufferID);
+};
+
+using ParsedTriviaList = SmallVector<ParsedTriviaPiece, 3>;
+
+struct ParsedTrivia {
+  ParsedTriviaList Pieces;
+
+  /// Get the begin iterator of the pieces.
+  ParsedTriviaList::const_iterator begin() const {
+    return Pieces.begin();
+  }
+
+  /// Get the end iterator of the pieces.
+  ParsedTriviaList::const_iterator end() const {
+    return Pieces.end();
+  }
+
+  /// Clear pieces.
+  void clear() {
+    Pieces.clear();
+  }
+
+  /// Returns true if there are no pieces in this Trivia collection.
+  bool empty() const {
+    return Pieces.empty();
+  }
+
+  /// Return the number of pieces in this Trivia collection.
+  size_t size() const {
+    return Pieces.size();
+  }
+
+  size_t getLength() const {
+    return ParsedTriviaPiece::getTotalLength(Pieces);
+  }
+
+  void push_back(syntax::TriviaKind kind, unsigned length) {
+    Pieces.emplace_back(kind, length);
+  }
+
+  void appendOrSquash(syntax::TriviaKind kind, unsigned length) {
+    if (empty() || Pieces.back().getKind() != kind) {
+      push_back(kind, length);
+    } else {
+      Pieces.back().extendLength(length);
+    }
+  }
+
+  bool operator==(const ParsedTrivia &Other) const {
+    if (Pieces.size() != Other.size()) {
+      return false;
+    }
+
+    for (size_t i = 0; i < Pieces.size(); ++i) {
+      if (Pieces[i] != Other.Pieces[i]) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  bool operator!=(const ParsedTrivia &Other) const {
+    return !(*this == Other);
+  }
+
+  syntax::Trivia convertToSyntaxTrivia(SourceLoc loc, const SourceManager &SM,
+                                       unsigned bufferID) const;
+};
+
+} // end namespace swift
+
+#endif
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 4bd61f3..bff4bc7 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -33,6 +33,7 @@
 #include "swift/Parse/ParserResult.h"
 #include "swift/Parse/SyntaxParserResult.h"
 #include "swift/Parse/SyntaxParsingContext.h"
+#include "swift/Syntax/References.h"
 #include "swift/Config.h"
 #include "llvm/ADT/SetVector.h"
 
@@ -164,7 +165,9 @@
 
   DelayedParsingCallbacks *DelayedParseCB = nullptr;
 
-  bool isDelayedParsingEnabled() const { return DelayedParseCB != nullptr; }
+  bool isDelayedParsingEnabled() const {
+    return DelayBodyParsing || DelayedParseCB != nullptr;
+  }
 
   void setDelayedParsingCallbacks(DelayedParsingCallbacks *DelayedParseCB) {
     this->DelayedParseCB = DelayedParseCB;
@@ -200,14 +203,21 @@
 
   /// leading trivias for \c Tok.
   /// Always empty if !SF.shouldBuildSyntaxTree().
-  syntax::Trivia LeadingTrivia;
+  ParsedTrivia LeadingTrivia;
 
   /// trailing trivias for \c Tok.
   /// Always empty if !SF.shouldBuildSyntaxTree().
-  syntax::Trivia TrailingTrivia;
+  ParsedTrivia TrailingTrivia;
 
-  /// Whether we should disable delayed parsing.
-  bool DisableDelayedParsing;
+  /// Whether we should delay parsing nominal type and extension bodies,
+  /// and skip function bodies.
+  ///
+  /// This is false in primary files, since we want to type check all
+  /// declarations and function bodies.
+  ///
+  /// This is true for non-primary files, where declarations only need to be
+  /// lazily parsed and type checked.
+  bool DelayBodyParsing;
 
   /// The receiver to collect all consumed tokens.
   ConsumeTokenReceiver *TokReceiver;
@@ -356,16 +366,16 @@
          SILParserTUStateBase *SIL,
          PersistentParserState *PersistentState,
          std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
-         bool DisableDelayedParsing = false);
+         bool DelayBodyParsing = true);
   Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
          PersistentParserState *PersistentState = nullptr,
          std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
-         bool DisableDelayedParsing = false);
+         bool DelayBodyParsing = true);
   Parser(std::unique_ptr<Lexer> Lex, SourceFile &SF,
          SILParserTUStateBase *SIL = nullptr,
          PersistentParserState *PersistentState = nullptr,
          std::shared_ptr<SyntaxParseActions> SPActions = nullptr,
-         bool DisableDelayedParsing = false);
+         bool DelayBodyParsing = true);
   ~Parser();
 
   bool isInSILMode() const { return SIL != nullptr; }
@@ -636,6 +646,9 @@
 
   /// Add the given Decl to the current scope.
   void addToScope(ValueDecl *D) {
+    if (Context.LangOpts.EnableASTScopeLookup)
+      return;
+
     getScopeInfo().addToScope(D, *this);
   }
 
@@ -794,6 +807,13 @@
 
   void parseDeclListDelayed(IterableDeclContext *IDC);
 
+  bool canDelayMemberDeclParsing();
+
+  bool delayParsingDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
+                            SourceLoc PosBeforeLB,
+                            ParseDeclOptions Options,
+                            IterableDeclContext *IDC);
+
   ParserResult<TypeDecl> parseDeclTypeAlias(ParseDeclOptions Flags,
                                             DeclAttributes &Attributes);
 
@@ -890,7 +910,7 @@
                              llvm::function_ref<void(Decl*)> handler);
   bool parseDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
                      Diag<> ErrorDiag, ParseDeclOptions Options,
-                     llvm::function_ref<void(Decl*)> handler);
+                     IterableDeclContext *IDC);
   ParserResult<ExtensionDecl> parseDeclExtension(ParseDeclOptions Flags,
                                                  DeclAttributes &Attributes);
   ParserResult<EnumDecl> parseDeclEnum(ParseDeclOptions Flags,
@@ -1424,8 +1444,6 @@
   parsePlatformVersionConstraintSpec();
   ParserResult<PlatformAgnosticVersionConstraintAvailabilitySpec>
   parsePlatformAgnosticVersionConstraintSpec();
-
-  bool canDelayMemberDeclParsing();
 };
 
 /// Describes a parsed declaration name.
diff --git a/include/swift/Parse/SyntaxParseActions.h b/include/swift/Parse/SyntaxParseActions.h
index 9bcd27c..1c12fa0 100644
--- a/include/swift/Parse/SyntaxParseActions.h
+++ b/include/swift/Parse/SyntaxParseActions.h
@@ -23,13 +23,12 @@
 namespace swift {
 
 class CharSourceRange;
+class ParsedTriviaPiece;
 class SourceLoc;
-class Token;
 enum class tok;
 
 namespace syntax {
   enum class SyntaxKind;
-  struct Trivia;
 }
 
 typedef void *OpaqueSyntaxNode;
@@ -40,10 +39,10 @@
 public:
   virtual ~SyntaxParseActions() = default;
 
-  virtual OpaqueSyntaxNode recordToken(const Token &tok,
-                                       const syntax::Trivia &leadingTrivia,
-                                       const syntax::Trivia &trailingTrivia,
-                                       CharSourceRange range) = 0;
+  virtual OpaqueSyntaxNode recordToken(tok tokenKind,
+                                    ArrayRef<ParsedTriviaPiece> leadingTrivia,
+                                    ArrayRef<ParsedTriviaPiece> trailingTrivia,
+                                    CharSourceRange range) = 0;
 
   /// Record a missing token. \c loc can be invalid or an approximate location
   /// of where the token would be if not missing.
diff --git a/include/swift/Parse/SyntaxParsingContext.h b/include/swift/Parse/SyntaxParsingContext.h
index 527ea3e..4dfeacb 100644
--- a/include/swift/Parse/SyntaxParsingContext.h
+++ b/include/swift/Parse/SyntaxParsingContext.h
@@ -24,6 +24,7 @@
 
 class ParsedSyntax;
 class ParsedTokenSyntax;
+struct ParsedTrivia;
 class SourceFile;
 enum class tok;
 class Token;
@@ -93,6 +94,8 @@
 
     ParsedRawSyntaxRecorder Recorder;
 
+    llvm::BumpPtrAllocator ScratchAlloc;
+
     RootContextData(SourceFile &SF, DiagnosticEngine &Diags,
                     SourceManager &SourceMgr, unsigned BufferID,
                     std::shared_ptr<SyntaxParseActions> spActions)
@@ -241,12 +244,16 @@
 
   ParsedRawSyntaxRecorder &getRecorder() { return getRootData()->Recorder; }
 
+  llvm::BumpPtrAllocator &getScratchAlloc() {
+    return getRootData()->ScratchAlloc;
+  }
+
   /// Add RawSyntax to the parts.
   void addRawSyntax(ParsedRawSyntaxNode Raw);
 
   /// Add Token with Trivia to the parts.
-  void addToken(Token &Tok, Trivia &LeadingTrivia,
-                Trivia &TrailingTrivia);
+  void addToken(Token &Tok, const ParsedTrivia &LeadingTrivia,
+                const ParsedTrivia &TrailingTrivia);
 
   /// Add Syntax to the parts.
   void addSyntax(ParsedSyntax Node);
diff --git a/include/swift/Parse/Token.h b/include/swift/Parse/Token.h
index c13f585..d607ad3 100644
--- a/include/swift/Parse/Token.h
+++ b/include/swift/Parse/Token.h
@@ -248,6 +248,17 @@
     return CharSourceRange(getLoc(), getLength());
   }
 
+  CharSourceRange getRangeWithoutBackticks() const {
+    SourceLoc TokLoc = getLoc();
+    unsigned TokLength = getLength();
+    if (isEscapedIdentifier()) {
+      // Adjust to account for the backticks.
+      TokLoc = TokLoc.getAdvancedLoc(1);
+      TokLength -= 2;
+    }
+    return CharSourceRange(TokLoc, TokLength);
+  }
+
   bool hasComment() const {
     return CommentLength != 0;
   }
diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h
index 216d45e..5bb0bf7 100644
--- a/include/swift/SIL/SILBuilder.h
+++ b/include/swift/SIL/SILBuilder.h
@@ -327,10 +327,12 @@
   // Type remapping
   //===--------------------------------------------------------------------===//
 
-  static SILType getPartialApplyResultType(SILType Ty, unsigned ArgCount,
-                                         SILModule &M,
-                                         SubstitutionMap subs,
-                                         ParameterConvention calleeConvention);
+  static SILType
+  getPartialApplyResultType(SILType Ty, unsigned ArgCount, SILModule &M,
+                            SubstitutionMap subs,
+                            ParameterConvention calleeConvention,
+                            PartialApplyInst::OnStackKind onStack =
+                                PartialApplyInst::OnStackKind::NotOnStack);
 
   //===--------------------------------------------------------------------===//
   // CFG Manipulation
@@ -476,10 +478,12 @@
   PartialApplyInst *createPartialApply(
       SILLocation Loc, SILValue Fn, SubstitutionMap Subs,
       ArrayRef<SILValue> Args, ParameterConvention CalleeConvention,
+      PartialApplyInst::OnStackKind OnStack =
+          PartialApplyInst::OnStackKind::NotOnStack,
       const GenericSpecializationInformation *SpecializationInfo = nullptr) {
     return insert(PartialApplyInst::create(
         getSILDebugLocation(Loc), Fn, Args, Subs, CalleeConvention, *F,
-        C.OpenedArchetypes, SpecializationInfo));
+        C.OpenedArchetypes, SpecializationInfo, OnStack));
   }
 
   BeginApplyInst *createBeginApply(
diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h
index 47f2e6c..0b22037 100644
--- a/include/swift/SIL/SILCloner.h
+++ b/include/swift/SIL/SILCloner.h
@@ -878,6 +878,7 @@
                 getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()),
                 getOpSubstitutionMap(Inst->getSubstitutionMap()), Args,
                 Inst->getType().getAs<SILFunctionType>()->getCalleeConvention(),
+                Inst->isOnStack(),
                 GenericSpecializationInformation::create(Inst, getBuilder())));
 }
 
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index 1899b00..7402e77 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -2072,6 +2072,12 @@
       public llvm::TrailingObjects<PartialApplyInst, Operand> {
   friend SILBuilder;
 
+public:
+  enum OnStackKind {
+    NotOnStack, OnStack
+  };
+
+private:
   PartialApplyInst(SILDebugLocation DebugLoc, SILValue Callee,
                    SILType SubstCalleeType,
                    SubstitutionMap Substitutions,
@@ -2084,7 +2090,8 @@
   create(SILDebugLocation DebugLoc, SILValue Callee, ArrayRef<SILValue> Args,
          SubstitutionMap Substitutions, ParameterConvention CalleeConvention,
          SILFunction &F, SILOpenedArchetypesState &OpenedArchetypes,
-         const GenericSpecializationInformation *SpecializationInfo);
+         const GenericSpecializationInformation *SpecializationInfo,
+         OnStackKind onStack);
 
 public:
   /// Return the result function type of this partial apply.
@@ -2094,6 +2101,10 @@
   bool hasCalleeGuaranteedContext() const {
     return getType().castTo<SILFunctionType>()->isCalleeGuaranteed();
   }
+
+  OnStackKind isOnStack() const {
+    return getFunctionType()->isNoEscape() ? OnStack : NotOnStack;
+  }
 };
 
 class BeginApplyInst;
diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h
index 13ef594..738b7fb 100644
--- a/include/swift/SIL/TypeSubstCloner.h
+++ b/include/swift/SIL/TypeSubstCloner.h
@@ -215,8 +215,8 @@
     PartialApplyInst *N = getBuilder().createPartialApply(
         getOpLocation(Inst->getLoc()), Helper.getCallee(),
         Helper.getSubstitutions(), Helper.getArguments(), ParamConvention,
-        GenericSpecializationInformation::create(
-          Inst, getBuilder()));
+        Inst->isOnStack(),
+        GenericSpecializationInformation::create(Inst, getBuilder()));
     recordClonedInstruction(Inst, N);
   }
 
diff --git a/include/swift/SILOptimizer/PassManager/Passes.def b/include/swift/SILOptimizer/PassManager/Passes.def
index f14f51d..6ff5215 100644
--- a/include/swift/SILOptimizer/PassManager/Passes.def
+++ b/include/swift/SILOptimizer/PassManager/Passes.def
@@ -232,8 +232,10 @@
      "Performance Function Inlining")
 PASS(PerformanceConstantPropagation, "performance-constant-propagation",
      "Constant Propagation for Performance without Diagnostics")
-PASS(PredictableMemoryOptimizations, "predictable-memopt",
-     "Predictable Memory Optimization for Diagnostics")
+PASS(PredictableMemoryAccessOptimizations, "predictable-memaccess-opts",
+     "Predictable Memory Access Optimizations for Diagnostics")
+PASS(PredictableDeadAllocationElimination, "predictable-deadalloc-elim",
+     "Eliminate dead temporary allocations after diagnostics")
 PASS(ReleaseDevirtualizer, "release-devirtualizer",
      "SIL release Devirtualization")
 PASS(RetainSinking, "retain-sinking",
diff --git a/include/swift/SILOptimizer/Utils/Local.h b/include/swift/SILOptimizer/Utils/Local.h
index 7548c4a..34ef9fb 100644
--- a/include/swift/SILOptimizer/Utils/Local.h
+++ b/include/swift/SILOptimizer/Utils/Local.h
@@ -212,6 +212,12 @@
     SILBuilder &Builder, SILLocation Loc, SILValue Arg, SILParameterInfo PInfo,
     InstModCallbacks Callbacks = InstModCallbacks());
 
+/// Insert destroys of captured arguments of partial_apply [stack].
+void insertDestroyOfCapturedArguments(
+    PartialApplyInst *PAI, SILBuilder &B,
+    llvm::function_ref<bool(SILValue)> shouldInsertDestroy =
+        [](SILValue arg) -> bool { return true; });
+
 /// This computes the lifetime of a single SILValue.
 ///
 /// This does not compute a set of jointly postdominating use points. Instead it
diff --git a/include/swift/SILOptimizer/Utils/StackNesting.h b/include/swift/SILOptimizer/Utils/StackNesting.h
index 988b3a5..8f71334 100644
--- a/include/swift/SILOptimizer/Utils/StackNesting.h
+++ b/include/swift/SILOptimizer/Utils/StackNesting.h
@@ -98,10 +98,10 @@
   ///
   /// Each stack location is allocated by a single allocation instruction.
   struct StackLoc {
-    StackLoc(AllocationInst *Alloc) : Alloc(Alloc) { }
+    StackLoc(SingleValueInstruction *Alloc) : Alloc(Alloc) { }
 
     /// Back-link to the allocation instruction.
-    AllocationInst *Alloc;
+    SingleValueInstruction *Alloc;
 
     /// Bit-set which represents all alive locations at this allocation.
     /// It obviously includes this location itself. And it includes all "outer"
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index 6c48b5f..6373887 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -52,7 +52,7 @@
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
 /// Don't worry about adhering to the 80-column limit for this line.
-const uint16_t SWIFTMODULE_VERSION_MINOR = 471; // Last change: Add @available(_PackageDescription..)
+const uint16_t SWIFTMODULE_VERSION_MINOR = 472; // Last change: partial_apply [stack]
 
 using DeclIDField = BCFixed<31>;
 
diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h
index 0d1323f..673e8e6 100644
--- a/include/swift/Subsystems.h
+++ b/include/swift/Subsystems.h
@@ -122,7 +122,7 @@
                            SILParserState *SIL = nullptr,
                            PersistentParserState *PersistentState = nullptr,
                            DelayedParsingCallbacks *DelayedParseCB = nullptr,
-                           bool DisableDelayedParsing = false);
+                           bool DelayBodyParsing = true);
 
   /// Parse a single buffer into the given source file, until the full source
   /// contents are parsed.
@@ -131,7 +131,7 @@
   bool parseIntoSourceFileFull(SourceFile &SF, unsigned BufferID,
                              PersistentParserState *PersistentState = nullptr,
                              DelayedParsingCallbacks *DelayedParseCB = nullptr,
-                               bool DisableDelayedParsing = false);
+                               bool DelayBodyParsing = true);
 
   /// Finish the parsing by going over the nodes that were delayed
   /// during the first parsing pass.
diff --git a/include/swift/Syntax/Trivia.h.gyb b/include/swift/Syntax/Trivia.h.gyb
index 622c09a..0f8994c 100644
--- a/include/swift/Syntax/Trivia.h.gyb
+++ b/include/swift/Syntax/Trivia.h.gyb
@@ -109,6 +109,8 @@
 % end
 };
 
+bool isCommentTriviaKind(TriviaKind kind);
+
 /// A contiguous stretch of a single kind of trivia. The constituent part of
 /// a `Trivia` collection.
 ///
@@ -150,6 +152,8 @@
 % end
 % end
 
+  static TriviaPiece fromText(TriviaKind kind, StringRef text);
+
   /// Return kind of the trivia.
   TriviaKind getKind() const { return Kind; }
 
@@ -174,7 +178,9 @@
     llvm_unreachable("unhandled kind");
   }
 
-  bool isComment() const;
+  bool isComment() const {
+    return isCommentTriviaKind(getKind());
+  }
 
   void accumulateAbsolutePosition(AbsolutePosition &Pos) const;
   
diff --git a/include/swift/SyntaxParse/SyntaxTreeCreator.h b/include/swift/SyntaxParse/SyntaxTreeCreator.h
index c8ad55e..3ed4496 100644
--- a/include/swift/SyntaxParse/SyntaxTreeCreator.h
+++ b/include/swift/SyntaxParse/SyntaxTreeCreator.h
@@ -18,6 +18,7 @@
 
 namespace swift {
   class RawSyntaxTokenCache;
+  class SourceManager;
   class SyntaxParsingCache;
   class SourceFile;
 
@@ -32,6 +33,8 @@
 /// It also handles caching re-usable RawSyntax objects and skipping parsed
 /// nodes via consulting a \c SyntaxParsingCache.
 class SyntaxTreeCreator: public SyntaxParseActions {
+  SourceManager &SM;
+  unsigned BufferID;
   RC<syntax::SyntaxArena> Arena;
 
   /// A cache of nodes that can be reused when creating the current syntax
@@ -43,16 +46,17 @@
   std::unique_ptr<RawSyntaxTokenCache> TokenCache;
 
 public:
-  SyntaxTreeCreator(SyntaxParsingCache *syntaxCache,
+  SyntaxTreeCreator(SourceManager &SM, unsigned bufferID,
+                    SyntaxParsingCache *syntaxCache,
                     RC<syntax::SyntaxArena> arena);
   ~SyntaxTreeCreator();
 
   void acceptSyntaxRoot(OpaqueSyntaxNode root, SourceFile &SF);
 
 private:
-  OpaqueSyntaxNode recordToken(const Token &tok,
-                               const syntax::Trivia &leadingTrivia,
-                               const syntax::Trivia &trailingTrivia,
+  OpaqueSyntaxNode recordToken(tok tokenKind,
+                               ArrayRef<ParsedTriviaPiece> leadingTrivia,
+                               ArrayRef<ParsedTriviaPiece> trailingTrivia,
                                CharSourceRange range) override;
 
   OpaqueSyntaxNode recordMissingToken(tok tokenKind, SourceLoc loc) override;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 8231708..9dfddd5 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -42,6 +42,7 @@
 #include "swift/Basic/Statistic.h"
 #include "swift/Basic/StringExtras.h"
 #include "swift/Parse/Lexer.h" // bad dependency
+#include "swift/Syntax/References.h"
 #include "swift/Syntax/SyntaxArena.h"
 #include "swift/Strings.h"
 #include "swift/Subsystems.h"
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 99b58cc..772d879 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -1331,6 +1331,10 @@
   case DeclContextKind::SubscriptDecl:
     printName(os, cast<SubscriptDecl>(dc)->getFullName());
     break;
+
+  case DeclContextKind::EnumElementDecl:
+    printName(os, cast<EnumElementDecl>(dc)->getFullName());
+    break;
   }
 }
 
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 76faaf8..71d351e 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -1508,6 +1508,11 @@
     return appendEntity(fn);
   }
 
+  case DeclContextKind::EnumElementDecl: {
+    auto eed = cast<EnumElementDecl>(ctx);
+    return appendEntity(eed);
+  }
+
   case DeclContextKind::SubscriptDecl:
     // FIXME: We may need to do something here if subscripts contain any symbols
     // exposed with linkage names, or if/when they get generic parameters.
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 1b84fd6..26b4b24 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -750,6 +750,7 @@
     FUNCTION_LIKE(ConstructorDecl)
     FUNCTION_LIKE(DestructorDecl)
     FUNCTION_LIKE(FuncDecl)
+    FUNCTION_LIKE(EnumElementDecl)
     SCOPE_LIKE(NominalTypeDecl)
     SCOPE_LIKE(ExtensionDecl)
 
diff --git a/lib/AST/AccessRequests.cpp b/lib/AST/AccessRequests.cpp
index 198baba..19640fb 100644
--- a/lib/AST/AccessRequests.cpp
+++ b/lib/AST/AccessRequests.cpp
@@ -105,6 +105,7 @@
   case DeclContextKind::Initializer:
   case DeclContextKind::AbstractFunctionDecl:
   case DeclContextKind::SubscriptDecl:
+  case DeclContextKind::EnumElementDecl:
     return AccessLevel::Private;
   case DeclContextKind::Module:
   case DeclContextKind::FileUnit:
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 8a30842..a33bddc 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3547,7 +3547,6 @@
   // Create an empty body for the destructor.
   DD->setBody(BraceStmt::create(ctx, getLoc(), { }, getLoc(), true));
   addMember(DD);
-  setHasDestructor();
 
   // Propagate access control and versioned-ness.
   DD->copyFormalAccessFrom(this, /*sourceIsParentContext*/true);
@@ -3910,16 +3909,19 @@
   Bits.ProtocolDecl.ExistentialConformsToSelf = false;
   Bits.ProtocolDecl.Circularity
     = static_cast<unsigned>(CircularityCheck::Unchecked);
+  Bits.ProtocolDecl.InheritedProtocolsValid = 0;
   Bits.ProtocolDecl.NumRequirementsInSignature = 0;
   Bits.ProtocolDecl.HasMissingRequirements = false;
   Bits.ProtocolDecl.KnownProtocol = 0;
-  setTrailingWhereClause(TrailingWhere);
+    setTrailingWhereClause(TrailingWhere);
 }
 
-llvm::TinyPtrVector<ProtocolDecl *>
-ProtocolDecl::getInheritedProtocols() const {
-  llvm::TinyPtrVector<ProtocolDecl *> result;
-  SmallPtrSet<const ProtocolDecl *, 4> known;
+ArrayRef<ProtocolDecl *>
+ProtocolDecl::getInheritedProtocolsSlow() {
+  Bits.ProtocolDecl.InheritedProtocolsValid = true;
+
+  llvm::SmallVector<ProtocolDecl *, 2> result;
+  SmallPtrSet<const ProtocolDecl *, 2> known;
   known.insert(this);
   bool anyObject = false;
   for (const auto found :
@@ -3931,7 +3933,9 @@
     }
   }
 
-  return result;
+  auto &ctx = getASTContext();
+  InheritedProtocols = ctx.AllocateCopy(result);
+  return InheritedProtocols;
 }
 
 llvm::TinyPtrVector<AssociatedTypeDecl *>
@@ -3973,7 +3977,10 @@
 void ProtocolDecl::setSuperclass(Type superclass) {
   assert((!superclass || !superclass->hasArchetype())
          && "superclass must be interface type");
-  LazySemanticInfo.Superclass.setPointerAndInt(superclass, true);
+  LazySemanticInfo.SuperclassType.setPointerAndInt(superclass, true);
+  LazySemanticInfo.SuperclassDecl.setPointerAndInt(
+    superclass ? superclass->getClassOrBoundGenericClass() : nullptr,
+    true);
 }
 
 bool ProtocolDecl::walkInheritedProtocols(
@@ -6478,7 +6485,10 @@
 void ClassDecl::setSuperclass(Type superclass) {
   assert((!superclass || !superclass->hasArchetype())
          && "superclass must be interface type");
-  LazySemanticInfo.Superclass.setPointerAndInt(superclass, true);
+  LazySemanticInfo.SuperclassType.setPointerAndInt(superclass, true);
+  LazySemanticInfo.SuperclassDecl.setPointerAndInt(
+    superclass ? superclass->getClassOrBoundGenericClass() : nullptr,
+    true);
 }
 
 ClangNode Decl::getClangNodeImpl() const {
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 4694e95..1c4d610 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -405,6 +405,9 @@
   case DeclContextKind::SubscriptDecl:
     break;
 
+  case DeclContextKind::EnumElementDecl:
+    break;
+
   case DeclContextKind::Module:
   case DeclContextKind::FileUnit:
     return true;
@@ -461,6 +464,8 @@
     return cast<AbstractFunctionDecl>(this)->walk(Walker);
   case DeclContextKind::SubscriptDecl:
     return cast<SubscriptDecl>(this)->walk(Walker);
+  case DeclContextKind::EnumElementDecl:
+    return cast<EnumElementDecl>(this)->walk(Walker);
   case DeclContextKind::SerializedLocal:
     llvm_unreachable("walk is unimplemented for deserialized contexts");
   case DeclContextKind::Initializer:
@@ -547,6 +552,7 @@
     Kind = "AbstractFunctionDecl";
     break;
   case DeclContextKind::SubscriptDecl:    Kind = "SubscriptDecl"; break;
+  case DeclContextKind::EnumElementDecl:  Kind = "EnumElementDecl"; break;
   }
   OS.indent(Depth*2 + indent) << (void*)this << " " << Kind;
 
@@ -601,6 +607,15 @@
       OS << " : (no type set)";
     break;
   }
+  case DeclContextKind::EnumElementDecl: {
+    auto *EED = cast<EnumElementDecl>(this);
+    OS << " name=" << EED->getBaseName();
+    if (EED->hasInterfaceType())
+      OS << " : " << EED->getInterfaceType();
+    else
+      OS << " : (no type set)";
+    break;
+  }
   case DeclContextKind::Initializer:
     switch (cast<Initializer>(this)->getInitializerKind()) {
     case InitializerKind::PatternBinding: {
@@ -920,6 +935,8 @@
       return DeclContextKind::TopLevelCodeDecl;
     case DeclKind::Subscript:
       return DeclContextKind::SubscriptDecl;
+    case DeclKind::EnumElement:
+      return DeclContextKind::EnumElementDecl;
     case DeclKind::Extension:
       return DeclContextKind::ExtensionDecl;
     default:
diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp
index ea80bc4..6fb8d11 100644
--- a/lib/AST/DiagnosticEngine.cpp
+++ b/lib/AST/DiagnosticEngine.cpp
@@ -767,6 +767,7 @@
             case DeclContextKind::AbstractClosureExpr:
             case DeclContextKind::AbstractFunctionDecl:
             case DeclContextKind::SubscriptDecl:
+            case DeclContextKind::EnumElementDecl:
               break;
             }
 
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index f3ca6bc..220c8d4 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -594,6 +594,14 @@
   auto *extDecl = decl.dyn_cast<ExtensionDecl *>();
 
   DeclContext *dc = protoDecl ? (DeclContext *)protoDecl : (DeclContext *)extDecl;
+
+  // A protocol or extension 'where' clause can reference associated types of
+  // the protocol itself, so we have to start unqualified lookup from 'dc'.
+  //
+  // However, the right hand side of a 'Self' conformance constraint must be
+  // resolved before unqualified lookup into 'dc' can work, so we make an
+  // exception here and begin lookup from the parent context instead.
+  auto *lookupDC = dc->getParent();
   auto requirements = protoDecl ? protoDecl->getTrailingWhereClause()
                                 : extDecl->getTrailingWhereClause();
 
@@ -623,7 +631,7 @@
     // Resolve the right-hand side.
     DirectlyReferencedTypeDecls rhsDecls;
     if (auto typeRepr = req.getConstraintRepr()) {
-      rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc);
+      rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, lookupDC);
     } else if (Type type = req.getConstraint()) {
       rhsDecls = directReferencesForType(type);
     }
@@ -1437,6 +1445,11 @@
 }
 
 void NominalTypeDecl::addedMember(Decl *member) {
+  // Remember if we added a destructor.
+  if (auto *CD = dyn_cast<ClassDecl>(this))
+    if (isa<DestructorDecl>(member))
+      CD->setHasDestructor();
+
   // If we have a lookup table, add the new member to it.
   if (LookupTable.getPointer()) {
     LookupTable.getPointer()->addMember(member);
diff --git a/lib/AST/NameLookupRequests.cpp b/lib/AST/NameLookupRequests.cpp
index 245e6ca..0a82db6 100644
--- a/lib/AST/NameLookupRequests.cpp
+++ b/lib/AST/NameLookupRequests.cpp
@@ -74,6 +74,30 @@
 //----------------------------------------------------------------------------//
 // Superclass declaration computation.
 //----------------------------------------------------------------------------//
+Optional<ClassDecl *> SuperclassDeclRequest::getCachedResult() const {
+  auto nominalDecl = std::get<0>(getStorage());
+
+  if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
+    if (classDecl->LazySemanticInfo.SuperclassDecl.getInt())
+      return classDecl->LazySemanticInfo.SuperclassDecl.getPointer();
+
+  if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
+    if (protocolDecl->LazySemanticInfo.SuperclassDecl.getInt())
+      return protocolDecl->LazySemanticInfo.SuperclassDecl.getPointer();
+
+  return None;
+}
+
+void SuperclassDeclRequest::cacheResult(ClassDecl *value) const {
+  auto nominalDecl = std::get<0>(getStorage());
+
+  if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
+    classDecl->LazySemanticInfo.SuperclassDecl.setPointerAndInt(value, true);
+
+  if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
+    protocolDecl->LazySemanticInfo.SuperclassDecl.setPointerAndInt(value, true);
+}
+
 void SuperclassDeclRequest::diagnoseCycle(DiagnosticEngine &diags) const {
   // FIXME: Improve this diagnostic.
   auto subjectDecl = std::get<0>(getStorage());
@@ -87,7 +111,7 @@
 }
 
 //----------------------------------------------------------------------------//
-// Superclass declaration computation.
+// Extended nominal computation.
 //----------------------------------------------------------------------------//
 Optional<NominalTypeDecl *> ExtendedNominalRequest::getCachedResult() const {
   // Note: if we fail to compute any nominal declaration, it's considered
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 6f250bc..163b560 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2683,6 +2683,12 @@
                            substFn->getResult(), getExtInfo());
 }
 
+CanFunctionType
+CanGenericFunctionType::substGenericArgs(SubstitutionMap subs) const {
+  return cast<FunctionType>(
+           getPointer()->substGenericArgs(subs)->getCanonicalType());
+}
+
 static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
                                  Type origBase,
                                  Type substBase,
diff --git a/lib/AST/TypeCheckRequests.cpp b/lib/AST/TypeCheckRequests.cpp
index 442adcb..466ff7c 100644
--- a/lib/AST/TypeCheckRequests.cpp
+++ b/lib/AST/TypeCheckRequests.cpp
@@ -125,12 +125,12 @@
   auto nominalDecl = std::get<0>(getStorage());
 
   if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
-    if (classDecl->LazySemanticInfo.Superclass.getInt())
-      return classDecl->LazySemanticInfo.Superclass.getPointer();
+    if (classDecl->LazySemanticInfo.SuperclassType.getInt())
+      return classDecl->LazySemanticInfo.SuperclassType.getPointer();
 
   if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
-    if (protocolDecl->LazySemanticInfo.Superclass.getInt())
-      return protocolDecl->LazySemanticInfo.Superclass.getPointer();
+    if (protocolDecl->LazySemanticInfo.SuperclassType.getInt())
+      return protocolDecl->LazySemanticInfo.SuperclassType.getPointer();
 
   return None;
 }
@@ -139,10 +139,10 @@
   auto nominalDecl = std::get<0>(getStorage());
 
   if (auto *classDecl = dyn_cast<ClassDecl>(nominalDecl))
-    classDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
+    classDecl->LazySemanticInfo.SuperclassType.setPointerAndInt(value, true);
 
   if (auto *protocolDecl = dyn_cast<ProtocolDecl>(nominalDecl))
-    protocolDecl->LazySemanticInfo.Superclass.setPointerAndInt(value, true);
+    protocolDecl->LazySemanticInfo.SuperclassType.setPointerAndInt(value, true);
 }
 
 //----------------------------------------------------------------------------//
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 250ce99..bd3ae67 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -1165,6 +1165,14 @@
   if (!DummyIncludeBuffer.isValid()) {
     clang::SourceLocation includeLoc =
         srcMgr.getLocForStartOfFile(srcMgr.getMainFileID());
+    // Picking the beginning of the main FileID as include location is also what
+    // the clang PCH mechanism is doing (see
+    // clang::ASTReader::getImportLocation()). Choose the next source location
+    // here to avoid having the exact same import location as the clang PCH.
+    // Otherwise, if we are using a PCH for bridging header, we'll have
+    // problems with source order comparisons of clang source locations not
+    // being deterministic.
+    includeLoc = includeLoc.getLocWithOffset(1);
     DummyIncludeBuffer = srcMgr.createFileID(
         llvm::make_unique<ZeroFilledMemoryBuffer>(
           256*1024, StringRef(moduleImportBufferName)),
@@ -1344,7 +1352,12 @@
     return true;
   }
 
-  llvm::SmallString<128> importLine{"#import \""};
+  llvm::SmallString<128> importLine;
+  if (Impl.SwiftContext.LangOpts.EnableObjCInterop)
+    importLine = "#import \"";
+  else
+    importLine = "#include \"";
+
   importLine += header;
   importLine += "\"\n";
 
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index 3c2bb2b..5566c6d 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -735,12 +735,10 @@
 }
 
 std::unique_ptr<DelayedParsingCallbacks>
-CompilerInstance::computeDelayedParsingCallback(bool isPrimary) {
+CompilerInstance::computeDelayedParsingCallback() {
   if (Invocation.isCodeCompletion())
     return llvm::make_unique<CodeCompleteDelayedCallbacks>(
         SourceMgr.getCodeCompletionLoc());
-  if (!isPrimary)
-    return llvm::make_unique<AlwaysDelayedCallbacks>();
   return nullptr;
 }
 
@@ -754,22 +752,13 @@
 void CompilerInstance::parseAndCheckTypesUpTo(
     const ImplicitImports &implicitImports, SourceFile::ASTStage_t limitStage) {
   FrontendStatsTracer tracer(Context->Stats, "parse-and-check-types");
-  // Delayed parsing callback for the primary file, or all files
-  // in non-WMO mode.
-  std::unique_ptr<DelayedParsingCallbacks> PrimaryDelayedCB{
-      computeDelayedParsingCallback(true)};
-
-  // Delayed parsing callback for non-primary files. Not used in
-  // WMO mode.
-  std::unique_ptr<DelayedParsingCallbacks> SecondaryDelayedCB{
-      computeDelayedParsingCallback(false)};
+  std::unique_ptr<DelayedParsingCallbacks> DelayedCB{
+      computeDelayedParsingCallback()};
 
   PersistentParserState PersistentState(getASTContext());
 
   bool hadLoadError = parsePartialModulesAndLibraryFiles(
-      implicitImports, PersistentState,
-      PrimaryDelayedCB.get(),
-      SecondaryDelayedCB.get());
+      implicitImports, PersistentState, DelayedCB.get());
   if (Invocation.isCodeCompletion()) {
     // When we are doing code completion, make sure to emit at least one
     // diagnostic, so that ASTContext is marked as erroneous.  In this case
@@ -788,7 +777,7 @@
   // interwined.
   if (MainBufferID != NO_SUCH_BUFFER) {
     parseAndTypeCheckMainFileUpTo(limitStage, PersistentState,
-                                  PrimaryDelayedCB.get(), TypeCheckOptions);
+                                  DelayedCB.get(), TypeCheckOptions);
   }
 
   assert(llvm::all_of(MainModule->getFiles(), [](const FileUnit *File) -> bool {
@@ -829,8 +818,7 @@
 void CompilerInstance::parseLibraryFile(
     unsigned BufferID, const ImplicitImports &implicitImports,
     PersistentParserState &PersistentState,
-    DelayedParsingCallbacks *PrimaryDelayedCB,
-    DelayedParsingCallbacks *SecondaryDelayedCB) {
+    DelayedParsingCallbacks *DelayedCB) {
   FrontendStatsTracer tracer(Context->Stats, "parse-library-file");
 
   auto *NextInput = createSourceFileForMainModule(
@@ -838,7 +826,6 @@
   addAdditionalInitialImportsTo(NextInput, implicitImports);
 
   auto IsPrimary = isWholeModuleCompilation() || isPrimaryInput(BufferID);
-  auto *DelayedCB = IsPrimary ? PrimaryDelayedCB : SecondaryDelayedCB;
 
   auto &Diags = NextInput->getASTContext().Diags;
   auto DidSuppressWarnings = Diags.getSuppressWarnings();
@@ -849,7 +836,7 @@
     // Parser may stop at some erroneous constructions like #else, #endif
     // or '}' in some cases, continue parsing until we are done
     parseIntoSourceFile(*NextInput, BufferID, &Done, nullptr, &PersistentState,
-                        DelayedCB);
+                        DelayedCB, /*DelayedBodyParsing=*/!IsPrimary);
   } while (!Done);
 
   Diags.setSuppressWarnings(DidSuppressWarnings);
@@ -878,8 +865,7 @@
 bool CompilerInstance::parsePartialModulesAndLibraryFiles(
     const ImplicitImports &implicitImports,
     PersistentParserState &PersistentState,
-    DelayedParsingCallbacks *PrimaryDelayedCB,
-    DelayedParsingCallbacks *SecondaryDelayedCB) {
+    DelayedParsingCallbacks *DelayedCB) {
   FrontendStatsTracer tracer(Context->Stats,
                              "parse-partial-modules-and-library-files");
   bool hadLoadError = false;
@@ -894,8 +880,7 @@
   // Then parse all the library files.
   for (auto BufferID : InputSourceCodeBufferIDs) {
     if (BufferID != MainBufferID) {
-      parseLibraryFile(BufferID, implicitImports, PersistentState,
-                       PrimaryDelayedCB, SecondaryDelayedCB);
+      parseLibraryFile(BufferID, implicitImports, PersistentState, DelayedCB);
     }
   }
   return hadLoadError;
@@ -928,7 +913,7 @@
     // with 'sil' definitions.
     parseIntoSourceFile(MainFile, MainFile.getBufferID().getValue(), &Done,
                         TheSILModule ? &SILContext : nullptr, &PersistentState,
-                        DelayedParseCB);
+                        DelayedParseCB, /*DelayedBodyParsing=*/false);
 
     if (mainIsPrimary && (Done || CurTUElem < MainFile.Decls.size())) {
       switch (LimitStage) {
@@ -1055,11 +1040,14 @@
     if (BufferID == MainBufferID)
       continue;
 
+    auto IsPrimary = isWholeModuleCompilation() || isPrimaryInput(BufferID);
+
     SourceFile *NextInput = createSourceFileForMainModule(
         SourceFileKind::Library, SourceFile::ImplicitModuleImportKind::None,
         BufferID);
 
-    parseIntoSourceFileFull(*NextInput, BufferID, &PersistentState);
+    parseIntoSourceFileFull(*NextInput, BufferID, &PersistentState,
+                            nullptr, /*DelayBodyParsing=*/!IsPrimary);
   }
 
   // Now parse the main file.
@@ -1069,7 +1057,8 @@
     MainFile.SyntaxParsingCache = Invocation.getMainFileSyntaxParsingCache();
 
     parseIntoSourceFileFull(MainFile, MainFile.getBufferID().getValue(),
-                            &PersistentState);
+                            &PersistentState, nullptr,
+                            /*DelayBodyParsing=*/false);
   }
 
   assert(Context->LoadedModules.size() == 1 &&
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index e877ea2..bedcbc9 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -1437,6 +1437,7 @@
       return true;
     case DeclContextKind::AbstractFunctionDecl:
     case DeclContextKind::SubscriptDecl:
+    case DeclContextKind::EnumElementDecl:
       return false;
     default:
       continue;
diff --git a/lib/IDE/ExprContextAnalysis.cpp b/lib/IDE/ExprContextAnalysis.cpp
index 8875737..a7cdf17 100644
--- a/lib/IDE/ExprContextAnalysis.cpp
+++ b/lib/IDE/ExprContextAnalysis.cpp
@@ -49,6 +49,7 @@
   case DeclContextKind::Module:
   case DeclContextKind::SerializedLocal:
   case DeclContextKind::TopLevelCodeDecl:
+  case DeclContextKind::EnumElementDecl:
     // Nothing to do for these.
     break;
 
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index 879b15a..d1a4a19 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -935,6 +935,7 @@
   switch (RangeInfo.RangeContext->getContextKind()) {
   case swift::DeclContextKind::Initializer:
   case swift::DeclContextKind::SubscriptDecl:
+  case swift::DeclContextKind::EnumElementDecl:
   case swift::DeclContextKind::AbstractFunctionDecl:
   case swift::DeclContextKind::AbstractClosureExpr:
   case swift::DeclContextKind::TopLevelCodeDecl:
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index 67ae131..0e8877f 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -1867,6 +1867,7 @@
       llvm::raw_svector_ostream outs(out);
 
       auto propTy = prop->getValueInterfaceType();
+      auto propDC = prop->getDeclContext();
 
       // Emit the type encoding for the property.
       outs << 'T';
@@ -1884,13 +1885,13 @@
       if (prop->getAttrs().hasAttribute<NSManagedAttr>())
         outs << ",D";
       
-      auto isObject = prop->getDeclContext()->mapTypeIntoContext(propTy)
+      auto isObject = propDC->mapTypeIntoContext(propTy)
           ->hasRetainablePointerRepresentation();
       auto hasObjectEncoding = typeEnc[0] == '@';
       
       // Determine the assignment semantics.
       // Get-only properties are (readonly).
-      if (!prop->isSettable(prop->getDeclContext()))
+      if (!prop->isSettable(propDC))
         outs << ",R";
       // Weak and Unowned properties are (weak).
       else if (prop->getAttrs().hasAttribute<ReferenceOwnershipAttr>())
@@ -1908,9 +1909,12 @@
       else
         (void)0;
       
-      // If the property is an instance property and has storage, emit the ivar
-      // name last.
-      if (!prop->isStatic() && prop->hasStorage())
+      // If the property is an instance property and has storage, and meanwhile
+      // its type is trivially representable in ObjC, emit the ivar name last.
+      bool isTriviallyRepresentable =
+          propTy->isTriviallyRepresentableIn(ForeignLanguage::ObjectiveC,
+                                             propDC);
+      if (!prop->isStatic() && prop->hasStorage() && isTriviallyRepresentable)
         outs << ",V" << prop->getName();
     }
 
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index c3cbe27..9a5c9b4 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -771,6 +771,7 @@
   case DeclContextKind::AbstractClosureExpr:
   case DeclContextKind::AbstractFunctionDecl:
   case DeclContextKind::SubscriptDecl:
+  case DeclContextKind::EnumElementDecl:
   case DeclContextKind::TopLevelCodeDecl:
   case DeclContextKind::Initializer:
   case DeclContextKind::SerializedLocal:
@@ -984,7 +985,7 @@
   return f.getProfiler() && m.getOptions().EmitProfileCoverageMapping;
 }
 
-void IRGenerator::emitGlobalTopLevel(bool emitForParallelEmission) {
+void IRGenerator::emitGlobalTopLevel() {
   // Generate order numbers for the functions in the SIL module that
   // correspond to definitions in the LLVM module.
   unsigned nextOrderNumber = 0;
@@ -995,10 +996,14 @@
   }
 
   // Ensure that relative symbols are collocated in the same LLVM module.
-  for (SILWitnessTable &wt : PrimaryIGM->getSILModule().getWitnessTableList()) {
+  for (auto &wt : PrimaryIGM->getSILModule().getWitnessTableList()) {
     CurrentIGMPtr IGM = getGenModule(wt.getDeclContext());
-    if (emitForParallelEmission)
-      IGM->ensureRelativeSymbolCollocation(wt);
+    ensureRelativeSymbolCollocation(wt);
+  }
+
+  for (auto &wt : PrimaryIGM->getSILModule().getDefaultWitnessTableList()) {
+    CurrentIGMPtr IGM = getGenModule(wt.getProtocol()->getDeclContext());
+    ensureRelativeSymbolCollocation(wt);
   }
 
   for (SILGlobalVariable &v : PrimaryIGM->getSILModule().getSILGlobals()) {
@@ -1903,6 +1908,8 @@
     /// Add a zero initializer.
     if (forDefinition)
       gvar->setInitializer(llvm::Constant::getNullValue(storageTypeWithContainer));
+    else
+      gvar->setComdat(nullptr);
   }
   llvm::Constant *addr = gvar;
   if (var->isInitializedObject()) {
@@ -2184,8 +2191,11 @@
   // associated with it.  The combination of the two allows us to identify the
   // @_silgen_name functions.  These are locally defined function thunks used in
   // the standard library.  Do not give them DLLImport DLL Storage.
-  if (useDllStorage() && f->hasCReferences() && !forDefinition)
-    fn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+  if (!forDefinition) {
+    fn->setComdat(nullptr);
+    if (f->hasCReferences())
+      fn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+  }
 
   // If we have an order number for this function, set it up as appropriate.
   if (hasOrderNumber) {
diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp
index 0a5244c..b6f173e 100644
--- a/lib/IRGen/GenFunc.cpp
+++ b/lib/IRGen/GenFunc.cpp
@@ -1254,7 +1254,7 @@
 
 /// Emit a partial application thunk for a function pointer applied to a partial
 /// set of argument values.
-void irgen::emitFunctionPartialApplication(
+Optional<StackAddress> irgen::emitFunctionPartialApplication(
     IRGenFunction &IGF, SILFunction &SILFn, const FunctionPointer &fn,
     llvm::Value *fnContext, Explosion &args, ArrayRef<SILParameterInfo> params,
     SubstitutionMap subs, CanSILFunctionType origType,
@@ -1270,8 +1270,6 @@
   SmallVector<SILType, 4> argValTypes;
   SmallVector<ParameterConvention, 4> argConventions;
 
-  assert(!outType->isNoEscape());
-
   // Reserve space for polymorphic bindings.
   auto bindings = NecessaryBindings::forFunctionInvocations(IGF.IGM,
                                                             origType, subs);
@@ -1398,7 +1396,7 @@
     llvm::Value *ctx = args.claimNext();
     ctx = IGF.Builder.CreateBitCast(ctx, IGF.IGM.RefCountedPtrTy);
     out.add(ctx);
-    return;
+    return {};
   }
   
   Optional<FunctionPointer> staticFn;
@@ -1437,14 +1435,20 @@
     llvm::Value *ctx = args.claimNext();
     if (isIndirectFormalParameter(*singleRefcountedConvention))
       ctx = IGF.Builder.CreateLoad(ctx, IGF.IGM.getPointerAlignment());
+
+    auto expectedClosureTy =
+        outType->isNoEscape() ? IGF.IGM.OpaquePtrTy : IGF.IGM.RefCountedPtrTy;
+
     // We might get a struct containing a pointer e.g type <{ %AClass* }>
-    if (ctx->getType() != IGF.IGM.RefCountedPtrTy)
-      ctx = IGF.coerceValue(ctx, IGF.IGM.RefCountedPtrTy, IGF.IGM.DataLayout);
+    if (ctx->getType() != expectedClosureTy)
+      ctx = IGF.coerceValue(ctx, expectedClosureTy, IGF.IGM.DataLayout);
     out.add(ctx);
-    return;
+    if (outType->isNoEscape())
+      return StackAddress();
+    return {};
   }
 
-  // Store the context arguments on the heap.
+  // Store the context arguments on the heap/stack.
   assert(argValTypes.size() == argTypeInfos.size()
          && argTypeInfos.size() == argConventions.size()
          && "argument info lists out of sync");
@@ -1457,13 +1461,26 @@
                                                        layout);
 
   llvm::Value *data;
-  if (args.empty() && layout.isKnownEmpty()) {
-    data = IGF.IGM.RefCountedNull;
-  } else {
-    // Allocate a new object.
-    HeapNonFixedOffsets offsets(IGF, layout);
 
-    data = IGF.emitUnmanagedAlloc(layout, "closure", descriptor, &offsets);
+  Optional<StackAddress> stackAddr;
+
+  if (args.empty() && layout.isKnownEmpty()) {
+    if (outType->isNoEscape())
+      data = llvm::ConstantPointerNull::get(IGF.IGM.OpaquePtrTy);
+    else
+      data = IGF.IGM.RefCountedNull;
+  } else {
+
+    // Allocate a new object on the heap or stack.
+    HeapNonFixedOffsets offsets(IGF, layout);
+    if (outType->isNoEscape()) {
+      stackAddr = IGF.emitDynamicAlloca(
+          IGF.IGM.Int8Ty, layout.emitSize(IGF.IGM), Alignment(16));
+      stackAddr = stackAddr->withAddress(IGF.Builder.CreateBitCast(
+          stackAddr->getAddress(), IGF.IGM.OpaquePtrTy));
+      data = stackAddr->getAddress().getAddress();
+    } else
+      data = IGF.emitUnmanagedAlloc(layout, "closure", descriptor, &offsets);
     Address dataAddr = layout.emitCastTo(IGF, data);
     
     unsigned i = 0;
@@ -1531,6 +1548,7 @@
   forwarder = IGF.Builder.CreateBitCast(forwarder, IGF.IGM.Int8PtrTy);
   out.add(forwarder);
   out.add(data);
+  return stackAddr;
 }
 
 /// Emit the block copy helper for a block.
diff --git a/lib/IRGen/GenFunc.h b/lib/IRGen/GenFunc.h
index 45cb6a8..04bc2e4 100644
--- a/lib/IRGen/GenFunc.h
+++ b/lib/IRGen/GenFunc.h
@@ -47,7 +47,7 @@
 
   /// Emit a partial application thunk for a function pointer applied to a
   /// partial set of argument values.
-  void emitFunctionPartialApplication(
+  Optional<StackAddress> emitFunctionPartialApplication(
       IRGenFunction &IGF, SILFunction &SILFn, const FunctionPointer &fnPtr,
       llvm::Value *fnContext, Explosion &args,
       ArrayRef<SILParameterInfo> argTypes, SubstitutionMap subs,
diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp
index c7cab4d..d4e6c5e 100644
--- a/lib/IRGen/GenOpaque.cpp
+++ b/lib/IRGen/GenOpaque.cpp
@@ -555,7 +555,10 @@
 /// location before the dynamic alloca's call.
 void IRGenFunction::emitDeallocateDynamicAlloca(StackAddress address) {
   // In coroutines, unconditionally call llvm.coro.alloca.free.
-  if (isCoroutine()) {
+  // Except if the address is invalid, this happens when this is a StackAddress
+  // for a partial_apply [stack] that did not need a context object on the
+  // stack.
+  if (isCoroutine() && address.getAddress().isValid()) {
     auto allocToken = address.getExtraInfo();
     assert(allocToken && "dynamic alloca in coroutine without alloc token?");
     auto freeFn = llvm::Intrinsic::getDeclaration(
@@ -563,7 +566,6 @@
     Builder.CreateCall(freeFn, allocToken);
     return;
   }
-
   // Otherwise, call llvm.stackrestore if an address was saved.
   auto savedSP = address.getExtraInfo();
   if (savedSP == nullptr)
@@ -1444,4 +1446,4 @@
   } else {
     storeEnumTagSinglePayload(IGF, tag, tag, address, T, isOutlined);
   }
-}
\ No newline at end of file
+}
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 01ebfd9..0d142b5 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -38,8 +38,10 @@
 #include "swift/ClangImporter/ClangModule.h"
 #include "swift/IRGen/Linking.h"
 #include "swift/SIL/SILDeclRef.h"
+#include "swift/SIL/SILDefaultWitnessTable.h"
 #include "swift/SIL/SILModule.h"
 #include "swift/SIL/SILValue.h"
+#include "swift/SIL/SILWitnessTable.h"
 #include "swift/SIL/SILWitnessVisitor.h"
 #include "swift/SIL/TypeLowering.h"
 #include "llvm/ADT/SmallString.h"
@@ -2079,7 +2081,10 @@
   setTrueConstGlobal(var);
 }
 
-void IRGenModule::ensureRelativeSymbolCollocation(SILWitnessTable &wt) {
+void IRGenerator::ensureRelativeSymbolCollocation(SILWitnessTable &wt) {
+  if (!CurrentIGM)
+    return;
+
   // Only resilient conformances use relative pointers for witness methods.
   if (wt.isDeclaration() || isAvailableExternally(wt.getLinkage()) ||
       !isResilientConformance(wt.getConformance()))
@@ -2090,7 +2095,20 @@
       continue;
     auto *witness = entry.getMethodWitness().Witness;
     if (witness)
-      IRGen.forceLocalEmitOfLazyFunction(witness);
+      forceLocalEmitOfLazyFunction(witness);
+  }
+}
+
+void IRGenerator::ensureRelativeSymbolCollocation(SILDefaultWitnessTable &wt) {
+  if (!CurrentIGM)
+    return;
+
+  for (auto &entry : wt.getEntries()) {
+    if (entry.getKind() != SILWitnessTable::Method)
+      continue;
+    auto *witness = entry.getMethodWitness().Witness;
+    if (witness)
+      forceLocalEmitOfLazyFunction(witness);
   }
 }
 
@@ -2234,6 +2252,10 @@
   if (isAvailableExternally(wt->getLinkage()))
     return;
 
+  // Ensure that relatively-referenced symbols for witness thunks are collocated
+  // in the same LLVM module.
+  IRGen.ensureRelativeSymbolCollocation(*wt);
+
   auto conf = wt->getConformance();
   PrettyStackTraceConformance _st(Context, "emitting witness table for", conf);
 
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index 4e83b4b..1f7b541 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -964,11 +964,11 @@
   }
 
   // Emit the module contents.
-  irgen.emitGlobalTopLevel(true /*emitForParallelEmission*/);
+  irgen.emitGlobalTopLevel();
 
   for (auto *File : M->getFiles()) {
     if (auto *SF = dyn_cast<SourceFile>(File)) {
-      IRGenModule *IGM = irgen.getGenModule(SF);
+      CurrentIGMPtr IGM = irgen.getGenModule(SF);
       IGM->emitSourceFile(*SF);
     } else {
       File->collectLinkLibraries([&](LinkLibrary LinkLib) {
diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index 8dd90f1..478a302 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -465,6 +465,7 @@
     case DeclContextKind::Initializer:
     case DeclContextKind::ExtensionDecl:
     case DeclContextKind::SubscriptDecl:
+    case DeclContextKind::EnumElementDecl:
     case DeclContextKind::TopLevelCodeDecl:
       return getOrCreateContext(DC->getParent());
 
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 54761c3..4f950c2 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -93,6 +93,7 @@
   class ProtocolCompositionType;
   class RootProtocolConformance;
   struct SILDeclRef;
+  class SILDefaultWitnessTable;
   class SILGlobalVariable;
   class SILModule;
   class SILProperty;
@@ -311,11 +312,7 @@
   
   /// Emit functions, variables and tables which are needed anyway, e.g. because
   /// they are externally visible.
-  /// If \p emitForParallelEmission is true ensures that symbols that are
-  /// expressed as relative pointers are collocated in the same output module
-  /// with their base symbol. For example, witness methods need to be collocated
-  /// with the witness table in the same LLVM module.
-  void emitGlobalTopLevel(bool emitForParallelEmission = false);
+  void emitGlobalTopLevel();
 
   /// Emit references to each of the protocol descriptors defined in this
   /// IR module.
@@ -355,6 +352,10 @@
     DefaultIGMForFunction[f] = CurrentIGM;
   }
 
+  void ensureRelativeSymbolCollocation(SILWitnessTable &wt);
+
+  void ensureRelativeSymbolCollocation(SILDefaultWitnessTable &wt);
+
   void noteUseOfTypeMetadata(NominalTypeDecl *type) {
     noteUseOfTypeGlobals(type, true, RequireMetadata);
   }
@@ -1386,8 +1387,6 @@
 
   void emitSharedContextDescriptor(DeclContext *dc);
 
-  void ensureRelativeSymbolCollocation(SILWitnessTable &wt);
-
   llvm::GlobalVariable *
   getGlobalForDynamicallyReplaceableThunk(LinkEntity &entity, llvm::Type *type,
                                           ForDefinition_t forDefinition);
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 5aeb617..cd81ba3 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -374,6 +374,7 @@
 {
 public:
   llvm::DenseMap<SILValue, LoweredValue> LoweredValues;
+  llvm::DenseMap<SILValue, StackAddress> LoweredPartialApplyAllocations;
   llvm::DenseMap<SILType, LoweredValue> LoweredUndefs;
 
   /// All alloc_ref instructions which allocate the object on the stack.
@@ -2527,11 +2528,16 @@
 
   // Create the thunk and function value.
   Explosion function;
-  emitFunctionPartialApplication(
+  auto closureStackAddr = emitFunctionPartialApplication(
       *this, *CurSILFn, calleeFn, innerContext, llArgs, params,
       i->getSubstitutionMap(), origCalleeTy, i->getSubstCalleeType(),
       i->getType().castTo<SILFunctionType>(), function, false);
   setLoweredExplosion(v, function);
+
+  if (closureStackAddr) {
+    assert(i->isOnStack());
+    LoweredPartialApplyAllocations[v] = *closureStackAddr;
+  }
 }
 
 void IRGenSILFunction::visitIntegerLiteralInst(swift::IntegerLiteralInst *i) {
@@ -4074,6 +4080,13 @@
 }
 
 void IRGenSILFunction::visitDeallocStackInst(swift::DeallocStackInst *i) {
+  if (auto *closure = dyn_cast<PartialApplyInst>(i->getOperand())) {
+    assert(closure->isOnStack());
+    auto stackAddr = LoweredPartialApplyAllocations[i->getOperand()];
+    emitDeallocateDynamicAlloca(stackAddr);
+    return;
+  }
+
   auto allocatedType = i->getOperand()->getType();
   const TypeInfo &allocatedTI = getTypeInfo(allocatedType);
   StackAddress stackAddr = getLoweredStackAddress(i->getOperand());
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index c62fbbf..8841829 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -1599,14 +1599,22 @@
 
 private:
   void updateLoweredTypes(SILFunction *F);
-  void recreateApplies();
-  void recreateSingleApply(SILInstruction *applyInst);
-  void recreateConvInstrs();
-  void recreateBuiltinInstrs();
-  void recreateLoadInstrs();
-  void recreateUncheckedEnumDataInstrs();
-  void recreateUncheckedTakeEnumDataAddrInst();
-  void fixStoreToBlockStorageInstrs();
+  void recreateSingleApply(SILInstruction *applyInst,
+                           SmallVectorImpl<SILInstruction *> &Delete);
+  bool recreateApply(SILInstruction &I,
+                     SmallVectorImpl<SILInstruction *> &Delete);
+  bool recreateConvInstr(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete);
+  bool recreateBuiltinInstr(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete);
+  bool recreateLoadInstr(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete);
+  bool recreateUncheckedEnumDataInstr(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete);
+  bool recreateUncheckedTakeEnumDataAddrInst(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete);
+  bool fixStoreToBlockStorageInstr(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete);
 
 private:
   llvm::SetVector<SILFunction *> modFuncs;
@@ -2369,7 +2377,8 @@
   return op;
 }
 
-void LoadableByAddress::recreateSingleApply(SILInstruction *applyInst) {
+void LoadableByAddress::recreateSingleApply(
+    SILInstruction *applyInst, SmallVectorImpl<SILInstruction *> &Delete) {
   auto *F = applyInst->getFunction();
   IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
   // Collect common info
@@ -2380,7 +2389,7 @@
     // else verification will fail with wrong SubstCalleeType
     auto calleInstr = site.getInstruction();
     if (modApplies.remove(calleInstr)) {
-      recreateSingleApply(calleInstr);
+      recreateSingleApply(calleInstr, Delete);
       callee = applySite.getCallee();
     }
   }
@@ -2481,196 +2490,215 @@
                                       .getAs<SILFunctionType>()
                                       ->getCalleeConvention();
 
-    auto newApply =
-      applyBuilder.createPartialApply(castedApply->getLoc(), callee,
-                                      applySite.getSubstitutionMap(), callArgs,
-                                      partialApplyConvention);
+    auto newApply = applyBuilder.createPartialApply(
+        castedApply->getLoc(), callee, applySite.getSubstitutionMap(), callArgs,
+        partialApplyConvention, castedApply->isOnStack());
     castedApply->replaceAllUsesWith(newApply);
     break;
   }
   default:
     llvm_unreachable("Unexpected instr: unknown apply type");
   }
-  applyInst->getParent()->erase(applyInst);
+  Delete.push_back(applyInst);
 }
 
-void LoadableByAddress::recreateApplies() {
-  while (!modApplies.empty()) {
-    auto *applyInst = modApplies.pop_back_val();
-    recreateSingleApply(applyInst);
-  }
+bool LoadableByAddress::recreateApply(
+    SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
+  if (!modApplies.count(&I))
+    return false;
+  recreateSingleApply(&I, Delete);
+  modApplies.remove(&I);
+  return true;
 }
 
-void LoadableByAddress::recreateLoadInstrs() {
-  for (auto *loadInstr : loadInstrsOfFunc) {
-    SILBuilderWithScope loadBuilder(loadInstr);
-    // If this is a load of a function for which we changed the return type:
-    // add UncheckedBitCast before the load
-    auto loadOp = loadInstr->getOperand();
-    loadOp = getOperandTypeWithCastIfNecessary(
-        loadInstr, loadOp, *getIRGenModule(), loadBuilder, MapperCache);
-    auto *newInstr = loadBuilder.createLoad(loadInstr->getLoc(), loadOp,
-                                            loadInstr->getOwnershipQualifier());
-    loadInstr->replaceAllUsesWith(newInstr);
-    loadInstr->getParent()->erase(loadInstr);
-  }
+bool LoadableByAddress::recreateLoadInstr(
+    SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
+  auto *loadInstr = dyn_cast<LoadInst>(&I);
+  if (!loadInstr || !loadInstrsOfFunc.count(loadInstr))
+    return false;
+
+  SILBuilderWithScope loadBuilder(loadInstr);
+  // If this is a load of a function for which we changed the return type:
+  // add UncheckedBitCast before the load
+  auto loadOp = loadInstr->getOperand();
+  loadOp = getOperandTypeWithCastIfNecessary(
+      loadInstr, loadOp, *getIRGenModule(), loadBuilder, MapperCache);
+  auto *newInstr = loadBuilder.createLoad(loadInstr->getLoc(), loadOp,
+                                          loadInstr->getOwnershipQualifier());
+  loadInstr->replaceAllUsesWith(newInstr);
+  Delete.push_back(loadInstr);
+  return true;
 }
 
-void LoadableByAddress::recreateUncheckedEnumDataInstrs() {
-  for (auto *enumInstr : uncheckedEnumDataOfFunc) {
-    SILBuilderWithScope enumBuilder(enumInstr);
-    SILFunction *F = enumInstr->getFunction();
-    IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
-    SILType origType = enumInstr->getType();
-    GenericEnvironment *genEnv = F->getGenericEnvironment();
-    SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod);
-    auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
-        enumInstr->getElement(), F->getModule());
-    SingleValueInstruction *newInstr = nullptr;
-    if (newType.isAddress()) {
-      newType = newType.getObjectType();
-    }
-    if (caseTy != newType) {
-      auto *takeEnum = enumBuilder.createUncheckedEnumData(
-          enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
-          caseTy);
-      newInstr = enumBuilder.createUncheckedBitCast(enumInstr->getLoc(),
-                                                    takeEnum, newType);
-    } else {
-      newInstr = enumBuilder.createUncheckedEnumData(
-          enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
-          newType);
-    }
-    enumInstr->replaceAllUsesWith(newInstr);
-    enumInstr->getParent()->erase(enumInstr);
+bool LoadableByAddress::recreateUncheckedEnumDataInstr(
+    SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
+  auto enumInstr = dyn_cast<UncheckedEnumDataInst>(&I);
+  if (!enumInstr || !uncheckedEnumDataOfFunc.count(enumInstr))
+    return false;
+  SILBuilderWithScope enumBuilder(enumInstr);
+  SILFunction *F = enumInstr->getFunction();
+  IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
+  SILType origType = enumInstr->getType();
+  GenericEnvironment *genEnv = F->getGenericEnvironment();
+  SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod);
+  auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
+      enumInstr->getElement(), F->getModule());
+  SingleValueInstruction *newInstr = nullptr;
+  if (newType.isAddress()) {
+    newType = newType.getObjectType();
   }
+  if (caseTy != newType) {
+    auto *takeEnum = enumBuilder.createUncheckedEnumData(
+        enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
+        caseTy);
+    newInstr = enumBuilder.createUncheckedBitCast(enumInstr->getLoc(), takeEnum,
+                                                  newType);
+  } else {
+    newInstr = enumBuilder.createUncheckedEnumData(
+        enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
+        newType);
+  }
+  enumInstr->replaceAllUsesWith(newInstr);
+  Delete.push_back(enumInstr);
+  return false;
 }
 
-void LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst() {
-  for (auto *enumInstr : uncheckedTakeEnumDataAddrOfFunc) {
-    SILBuilderWithScope enumBuilder(enumInstr);
-    SILFunction *F = enumInstr->getFunction();
-    IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
-    SILType origType = enumInstr->getType();
-    GenericEnvironment *genEnv = F->getGenericEnvironment();
-    SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod);
-    auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
-        enumInstr->getElement(), F->getModule());
-    SingleValueInstruction *newInstr = nullptr;
-    if (caseTy != origType.getObjectType()) {
-      auto *takeEnum = enumBuilder.createUncheckedTakeEnumDataAddr(
-          enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
-          caseTy.getAddressType());
-      newInstr = enumBuilder.createUncheckedAddrCast(
-          enumInstr->getLoc(), takeEnum, newType.getAddressType());
-    } else {
-      newInstr = enumBuilder.createUncheckedTakeEnumDataAddr(
-          enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
-          newType.getAddressType());
-    }
-    enumInstr->replaceAllUsesWith(newInstr);
-    enumInstr->getParent()->erase(enumInstr);
+bool LoadableByAddress::recreateUncheckedTakeEnumDataAddrInst(
+    SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
+  auto *enumInstr = dyn_cast<UncheckedTakeEnumDataAddrInst>(&I);
+  if (!enumInstr || !uncheckedTakeEnumDataAddrOfFunc.count(enumInstr))
+    return false;
+  SILBuilderWithScope enumBuilder(enumInstr);
+  SILFunction *F = enumInstr->getFunction();
+  IRGenModule *currIRMod = getIRGenModule()->IRGen.getGenModule(F);
+  SILType origType = enumInstr->getType();
+  GenericEnvironment *genEnv = F->getGenericEnvironment();
+  SILType newType = MapperCache.getNewSILType(genEnv, origType, *currIRMod);
+  auto caseTy = enumInstr->getOperand()->getType().getEnumElementType(
+      enumInstr->getElement(), F->getModule());
+  SingleValueInstruction *newInstr = nullptr;
+  if (caseTy != origType.getObjectType()) {
+    auto *takeEnum = enumBuilder.createUncheckedTakeEnumDataAddr(
+        enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
+        caseTy.getAddressType());
+    newInstr = enumBuilder.createUncheckedAddrCast(
+        enumInstr->getLoc(), takeEnum, newType.getAddressType());
+  } else {
+    newInstr = enumBuilder.createUncheckedTakeEnumDataAddr(
+        enumInstr->getLoc(), enumInstr->getOperand(), enumInstr->getElement(),
+        newType.getAddressType());
   }
+  enumInstr->replaceAllUsesWith(newInstr);
+  Delete.push_back(enumInstr);
+  return true;
 }
 
-void LoadableByAddress::fixStoreToBlockStorageInstrs() {
-  for (auto *instr : storeToBlockStorageInstrs) {
-    auto dest = instr->getDest();
-    auto destBlock = cast<ProjectBlockStorageInst>(dest);
-    SILType destType = destBlock->getType();
-    auto src = instr->getSrc();
-    SILType srcType = src->getType();
-    if (destType.getObjectType() != srcType) {
-      // Add cast to destType
-      SILBuilderWithScope castBuilder(instr);
-      auto *castInstr = castBuilder.createUncheckedBitCast(
-          instr->getLoc(), src, destType.getObjectType());
-      instr->setOperand(StoreInst::Src, castInstr);
-    }
+bool LoadableByAddress::fixStoreToBlockStorageInstr(
+    SILInstruction &I, SmallVectorImpl<SILInstruction *> &Delete) {
+  auto *instr = dyn_cast<StoreInst>(&I);
+  if (!instr || !storeToBlockStorageInstrs.count(instr))
+    return false;
+  auto dest = instr->getDest();
+  auto destBlock = cast<ProjectBlockStorageInst>(dest);
+  SILType destType = destBlock->getType();
+  auto src = instr->getSrc();
+  SILType srcType = src->getType();
+  if (destType.getObjectType() != srcType) {
+    // Add cast to destType
+    SILBuilderWithScope castBuilder(instr);
+    auto *castInstr = castBuilder.createUncheckedBitCast(
+        instr->getLoc(), src, destType.getObjectType());
+    instr->setOperand(StoreInst::Src, castInstr);
   }
+  return true;
 }
 
-void LoadableByAddress::recreateConvInstrs() {
-  for (auto *convInstr : conversionInstrs) {
-    IRGenModule *currIRMod =
-        getIRGenModule()->IRGen.getGenModule(convInstr->getFunction());
-    SILType currSILType = convInstr->getType();
-    if (auto *thinToPointer = dyn_cast<ThinFunctionToPointerInst>(convInstr)) {
-      currSILType = thinToPointer->getOperand()->getType();
-    }
-    auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
-    GenericEnvironment *genEnv =
-        convInstr->getFunction()->getGenericEnvironment();
-    CanSILFunctionType newFnType = MapperCache.getNewSILFunctionType(
-        genEnv, currSILFunctionType, *currIRMod);
-    SILType newType = SILType::getPrimitiveObjectType(newFnType);
-    SILBuilderWithScope convBuilder(convInstr);
-    SingleValueInstruction *newInstr = nullptr;
-    switch (convInstr->getKind()) {
-    case SILInstructionKind::ThinToThickFunctionInst: {
-      auto instr = cast<ThinToThickFunctionInst>(convInstr);
-      newInstr = convBuilder.createThinToThickFunction(
-          instr->getLoc(), instr->getOperand(), newType);
-      break;
-    }
-    case SILInstructionKind::ThinFunctionToPointerInst: {
-      auto instr = cast<ThinFunctionToPointerInst>(convInstr);
-      newType = MapperCache.getNewSILType(genEnv, instr->getType(),
-                                          *getIRGenModule());
-      newInstr = convBuilder.createThinFunctionToPointer(
-          instr->getLoc(), instr->getOperand(), newType);
-      break;
-    }
-    case SILInstructionKind::ConvertFunctionInst: {
-      auto instr = cast<ConvertFunctionInst>(convInstr);
-      newInstr = convBuilder.createConvertFunction(
-          instr->getLoc(), instr->getOperand(), newType,
-          instr->withoutActuallyEscaping());
-      break;
-    }
-    case SILInstructionKind::ConvertEscapeToNoEscapeInst: {
-      auto instr = cast<ConvertEscapeToNoEscapeInst>(convInstr);
-      newInstr = convBuilder.createConvertEscapeToNoEscape(
-          instr->getLoc(), instr->getOperand(), newType,
-          instr->isLifetimeGuaranteed());
-      break;
-    }
-    case SILInstructionKind::MarkDependenceInst: {
-      auto instr = cast<MarkDependenceInst>(convInstr);
-      newInstr = convBuilder.createMarkDependence(
-          instr->getLoc(), instr->getValue(), instr->getBase());
-      break;
-    }
-     default:
-      llvm_unreachable("Unexpected conversion instruction");
-    }
-    convInstr->replaceAllUsesWith(newInstr);
-    convInstr->getParent()->erase(convInstr);
+bool LoadableByAddress::recreateConvInstr(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete) {
+  auto *convInstr = dyn_cast<SingleValueInstruction>(&I);
+  if (!convInstr || !conversionInstrs.count(convInstr))
+    return false;
+  IRGenModule *currIRMod =
+      getIRGenModule()->IRGen.getGenModule(convInstr->getFunction());
+  SILType currSILType = convInstr->getType();
+  if (auto *thinToPointer = dyn_cast<ThinFunctionToPointerInst>(convInstr)) {
+    currSILType = thinToPointer->getOperand()->getType();
   }
+  auto currSILFunctionType = currSILType.castTo<SILFunctionType>();
+  GenericEnvironment *genEnv =
+      convInstr->getFunction()->getGenericEnvironment();
+  CanSILFunctionType newFnType = MapperCache.getNewSILFunctionType(
+      genEnv, currSILFunctionType, *currIRMod);
+  SILType newType = SILType::getPrimitiveObjectType(newFnType);
+  SILBuilderWithScope convBuilder(convInstr);
+  SingleValueInstruction *newInstr = nullptr;
+  switch (convInstr->getKind()) {
+  case SILInstructionKind::ThinToThickFunctionInst: {
+    auto instr = cast<ThinToThickFunctionInst>(convInstr);
+    newInstr = convBuilder.createThinToThickFunction(
+        instr->getLoc(), instr->getOperand(), newType);
+    break;
+  }
+  case SILInstructionKind::ThinFunctionToPointerInst: {
+    auto instr = cast<ThinFunctionToPointerInst>(convInstr);
+    newType =
+        MapperCache.getNewSILType(genEnv, instr->getType(), *getIRGenModule());
+    newInstr = convBuilder.createThinFunctionToPointer(
+        instr->getLoc(), instr->getOperand(), newType);
+    break;
+  }
+  case SILInstructionKind::ConvertFunctionInst: {
+    auto instr = cast<ConvertFunctionInst>(convInstr);
+    newInstr = convBuilder.createConvertFunction(
+        instr->getLoc(), instr->getOperand(), newType,
+        instr->withoutActuallyEscaping());
+    break;
+  }
+  case SILInstructionKind::ConvertEscapeToNoEscapeInst: {
+    auto instr = cast<ConvertEscapeToNoEscapeInst>(convInstr);
+    newInstr = convBuilder.createConvertEscapeToNoEscape(
+        instr->getLoc(), instr->getOperand(), newType,
+        instr->isLifetimeGuaranteed());
+    break;
+  }
+  case SILInstructionKind::MarkDependenceInst: {
+    auto instr = cast<MarkDependenceInst>(convInstr);
+    newInstr = convBuilder.createMarkDependence(
+        instr->getLoc(), instr->getValue(), instr->getBase());
+    break;
+  }
+  default:
+    llvm_unreachable("Unexpected conversion instruction");
+  }
+  convInstr->replaceAllUsesWith(newInstr);
+  Delete.push_back(convInstr);
+  return true;
 }
 
-void LoadableByAddress::recreateBuiltinInstrs() {
-  for (auto *builtinInstr : builtinInstrs) {
-    auto *currIRMod =
-        getIRGenModule()->IRGen.getGenModule(builtinInstr->getFunction());
-    auto *F = builtinInstr->getFunction();
-    GenericEnvironment *genEnv = F->getGenericEnvironment();
-    auto resultTy = builtinInstr->getType();
-    auto newResultTy = MapperCache.getNewSILType(genEnv, resultTy, *currIRMod);
+bool LoadableByAddress::recreateBuiltinInstr(SILInstruction &I,
+                         SmallVectorImpl<SILInstruction *> &Delete) {
+	auto builtinInstr = dyn_cast<BuiltinInst>(&I);
+  if (!builtinInstr || !builtinInstrs.count(builtinInstr))
+    return false;
+  auto *currIRMod =
+      getIRGenModule()->IRGen.getGenModule(builtinInstr->getFunction());
+  auto *F = builtinInstr->getFunction();
+  GenericEnvironment *genEnv = F->getGenericEnvironment();
+  auto resultTy = builtinInstr->getType();
+  auto newResultTy = MapperCache.getNewSILType(genEnv, resultTy, *currIRMod);
 
-    llvm::SmallVector<SILValue, 5> newArgs;
-    for (auto oldArg : builtinInstr->getArguments()) {
-      newArgs.push_back(oldArg);
-    }
-
-    SILBuilderWithScope builtinBuilder(builtinInstr);
-    auto *newInstr = builtinBuilder.createBuiltin(
-        builtinInstr->getLoc(), builtinInstr->getName(), newResultTy,
-        builtinInstr->getSubstitutions(),
-        newArgs);
-    builtinInstr->replaceAllUsesWith(newInstr);
-    builtinInstr->getParent()->erase(builtinInstr);
+  llvm::SmallVector<SILValue, 5> newArgs;
+  for (auto oldArg : builtinInstr->getArguments()) {
+    newArgs.push_back(oldArg);
   }
+
+  SILBuilderWithScope builtinBuilder(builtinInstr);
+  auto *newInstr = builtinBuilder.createBuiltin(
+      builtinInstr->getLoc(), builtinInstr->getName(), newResultTy,
+      builtinInstr->getSubstitutions(), newArgs);
+  builtinInstr->replaceAllUsesWith(newInstr);
+  Delete.push_back(builtinInstr);
+  return true;
 }
 
 void LoadableByAddress::updateLoweredTypes(SILFunction *F) {
@@ -2817,26 +2845,31 @@
     instr->getParent()->erase(instr);
   }
 
-  // Re-create all conversions for which we modified the FunctionRef
-  recreateConvInstrs();
-
-  // Re-create all builtins for which we modified the FunctionRef
-  recreateBuiltinInstrs();
-
-  // Re-create all unchecked enum data instrs of function pointers
-  recreateUncheckedEnumDataInstrs();
-
-  // Same for data addr
-  recreateUncheckedTakeEnumDataAddrInst();
-
-  // Re-create all load instrs of function pointers
-  recreateLoadInstrs();
-
-  // Re-create all applies that we modified in the module
-  recreateApplies();
-
-  // Fix all instructions that rely on block storage type
-  fixStoreToBlockStorageInstrs();
+  // Recreate the instructions in topological order. Some instructions inherit
+  // their result type from their operand.
+  for (SILFunction &CurrF : *getModule()) {
+    SmallVector<SILInstruction *, 32> Delete;
+    for (SILBasicBlock &BB : CurrF) {
+      for (SILInstruction &I : BB) {
+        if (recreateConvInstr(I, Delete))
+          continue;
+        else if (recreateBuiltinInstr(I, Delete))
+          continue;
+        else if (recreateUncheckedEnumDataInstr(I, Delete))
+          continue;
+        else if (recreateUncheckedTakeEnumDataAddrInst(I, Delete))
+          continue;
+        else if (recreateLoadInstr(I, Delete))
+          continue;
+        else if (recreateApply(I, Delete))
+          continue;
+        else
+          fixStoreToBlockStorageInstr(I, Delete);
+      }
+    }
+    for (auto *Inst : Delete)
+      Inst->eraseFromParent();
+  }
 
   // Clean up the data structs:
   modFuncs.clear();
diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt
index dcb7bdc..891579c 100644
--- a/lib/Parse/CMakeLists.txt
+++ b/lib/Parse/CMakeLists.txt
@@ -13,6 +13,7 @@
   ParsedSyntaxBuilders.cpp.gyb
   ParsedSyntaxNodes.cpp.gyb
   ParsedSyntaxRecorder.cpp.gyb
+  ParsedTrivia.cpp
   ParseExpr.cpp
   ParseGeneric.cpp
   ParseIfConfig.cpp
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 095ff69..5555caf 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -20,6 +20,7 @@
 #include "swift/AST/Identifier.h"
 #include "swift/Basic/LangOptions.h"
 #include "swift/Basic/SourceManager.h"
+#include "swift/Syntax/Trivia.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -284,15 +285,15 @@
   if (RetainComments == CommentRetentionMode::AttachToNextToken) {
     // 'CommentLength' here is the length from the *first* comment to the
     // token text (or its backtick if exist).
-    auto Iter = llvm::find_if(LeadingTrivia, [](const TriviaPiece &Piece) {
-      return Piece.isComment();
+    auto Iter = llvm::find_if(LeadingTrivia, [](const ParsedTriviaPiece &Piece) {
+      return isCommentTriviaKind(Piece.getKind());
     });
     for (auto End = LeadingTrivia.end(); Iter != End; Iter++) {
       if (Iter->getKind() == TriviaKind::Backtick)
         // Since Token::getCommentRange() doesn't take backtick into account,
         // we cannot include length of backtick.
         break;
-      CommentLength += Iter->getTextLength();
+      CommentLength += Iter->getLength();
     }
   }
 
@@ -310,9 +311,9 @@
   assert(TokStart[0] == '`' && "escaped identifier starts with backtick");
   assert(CurPtr[-1] == '`' && "escaped identifier ends with backtick");
 
-  LeadingTrivia.push_back(TriviaPiece::backtick());
+  LeadingTrivia.push_back(TriviaKind::Backtick, 1);
   assert(TrailingTrivia.empty() && "TrailingTrivia is empty here");
-  TrailingTrivia.push_back(TriviaPiece::backtick());
+  TrailingTrivia.push_back(TriviaKind::Backtick, 1);
 
   formToken(tok::identifier, TokStart);
   // If this token is at ArtificialEOF, it's forced to be tok::eof. Don't mark
@@ -2335,8 +2336,7 @@
       size_t BOMLen = ContentStart - BufferStart;
       assert(BOMLen == 3 && "UTF-8 BOM is 3 bytes");
       // Add UTF-8 BOM to LeadingTrivia.
-      auto Text = OwnedString::makeRefCounted(StringRef(CurPtr, BOMLen));
-      LeadingTrivia.push_back(TriviaPiece::garbageText(Text));
+      LeadingTrivia.push_back(TriviaKind::GarbageText, BOMLen);
       CurPtr += BOMLen;
     }
     NextToken.setAtStartOfLine(true);
@@ -2521,7 +2521,7 @@
   return L.peekNextToken();
 }
 
-void Lexer::lexTrivia(syntax::Trivia &Pieces, bool IsForTrailingTrivia) {
+void Lexer::lexTrivia(ParsedTrivia &Pieces, bool IsForTrailingTrivia) {
 Restart:
   const char *TriviaStart = CurPtr;
 
@@ -2530,30 +2530,30 @@
     if (IsForTrailingTrivia)
       break;
     NextToken.setAtStartOfLine(true);
-    Pieces.appendOrSquash(TriviaPiece::newlines(1));
+    Pieces.appendOrSquash(TriviaKind::Newline, 1);
     goto Restart;
   case '\r':
     if (IsForTrailingTrivia)
       break;
     NextToken.setAtStartOfLine(true);
     if (CurPtr[0] == '\n') {
-      Pieces.appendOrSquash(TriviaPiece::carriageReturnLineFeeds(1));
+      Pieces.appendOrSquash(TriviaKind::CarriageReturnLineFeed, 2);
       ++CurPtr;
     } else {
-      Pieces.appendOrSquash(TriviaPiece::carriageReturns(1));
+      Pieces.appendOrSquash(TriviaKind::CarriageReturn, 1);
     }
     goto Restart;
   case ' ':
-    Pieces.appendOrSquash(TriviaPiece::spaces(1));
+    Pieces.appendOrSquash(TriviaKind::Space, 1);
     goto Restart;
   case '\t':
-    Pieces.appendOrSquash(TriviaPiece::tabs(1));
+    Pieces.appendOrSquash(TriviaKind::Tab, 1);
     goto Restart;
   case '\v':
-    Pieces.appendOrSquash(TriviaPiece::verticalTabs(1));
+    Pieces.appendOrSquash(TriviaKind::VerticalTab, 1);
     goto Restart;
   case '\f':
-    Pieces.appendOrSquash(TriviaPiece::formfeeds(1));
+    Pieces.appendOrSquash(TriviaKind::Formfeed, 1);
     goto Restart;
   case '/':
     if (IsForTrailingTrivia || isKeepingComments()) {
@@ -2565,18 +2565,16 @@
       bool isDocComment = CurPtr[1] == '/';
       skipSlashSlashComment(/*EatNewline=*/false);
       size_t Length = CurPtr - TriviaStart;
-      auto Text = OwnedString::makeRefCounted(StringRef(TriviaStart, Length));
-      Pieces.push_back(isDocComment ? TriviaPiece::docLineComment(Text)
-                                    : TriviaPiece::lineComment(Text));
+      Pieces.push_back(isDocComment ? TriviaKind::DocLineComment
+                                    : TriviaKind::LineComment, Length);
       goto Restart;
     } else if (*CurPtr == '*') {
       // '/* ... */' comment.
       bool isDocComment = CurPtr[1] == '*';
       skipSlashStarComment();
       size_t Length = CurPtr - TriviaStart;
-      auto Text = OwnedString::makeRefCounted(StringRef(TriviaStart, Length));
-      Pieces.push_back(isDocComment ? TriviaPiece::docBlockComment(Text)
-                                    : TriviaPiece::blockComment(Text));
+      Pieces.push_back(isDocComment ? TriviaKind::DocBlockComment
+                                    : TriviaKind::BlockComment, Length);
       goto Restart;
     }
     break;
@@ -2588,8 +2586,7 @@
         diagnose(TriviaStart, diag::lex_hashbang_not_allowed);
       skipHashbang(/*EatNewline=*/false);
       size_t Length = CurPtr - TriviaStart;
-      auto Text = OwnedString::makeRefCounted(StringRef(TriviaStart, Length));
-      Pieces.push_back(TriviaPiece::garbageText(Text));
+      Pieces.push_back(TriviaKind::GarbageText, Length);
       goto Restart;
     }
     break;
@@ -2598,8 +2595,7 @@
     if (tryLexConflictMarker(/*EatNewline=*/false)) {
       // Conflict marker.
       size_t Length = CurPtr - TriviaStart;
-      auto Text = OwnedString::makeRefCounted(StringRef(TriviaStart, Length));
-      Pieces.push_back(TriviaPiece::garbageText(Text));
+      Pieces.push_back(TriviaKind::GarbageText, Length);
       goto Restart;
     }
     break;
@@ -2608,8 +2604,7 @@
     case NulCharacterKind::Embedded: {
       diagnoseEmbeddedNul(Diags, CurPtr - 1);
       size_t Length = CurPtr - TriviaStart;
-      auto Text = OwnedString::makeRefCounted(StringRef(TriviaStart, Length));
-      Pieces.push_back(TriviaPiece::garbageText(Text));
+      Pieces.push_back(TriviaKind::GarbageText, Length);
       goto Restart;
     }
     case NulCharacterKind::CodeCompletion:
@@ -2655,8 +2650,7 @@
     }
 
     size_t Length = CurPtr - TriviaStart;
-    auto Text = OwnedString::makeRefCounted(StringRef(TriviaStart, Length));
-    Pieces.push_back(TriviaPiece::garbageText(Text));
+    Pieces.push_back(TriviaKind::GarbageText, Length);
     goto Restart;
   }
   // Reset the cursor.
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 1959d79..0b06391 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -3045,22 +3045,13 @@
   if (auto *ext = dyn_cast<ExtensionDecl>(D)) {
     parseDeclList(ext->getBraces().Start, RBLoc, Id,
                   ParseDeclOptions(DelayedState->Flags),
-                  [&] (Decl *D) { ext->addMember(D); });
+                  ext);
     ext->setBraces({LBLoc, RBLoc});
-  } else if (auto *cd = dyn_cast<ClassDecl>(D)) {
-    auto handler = [&] (Decl *D) {
-      cd->addMember(D);
-      if (isa<DestructorDecl>(D))
-        cd->setHasDestructor();
-    };
-    parseDeclList(cd->getBraces().Start, RBLoc, Id,
-                  ParseDeclOptions(DelayedState->Flags), handler);
-    cd->setBraces({LBLoc, RBLoc});
   } else {
     auto *ntd = cast<NominalTypeDecl>(D);
     parseDeclList(ntd->getBraces().Start, RBLoc, Id,
                   ParseDeclOptions(DelayedState->Flags),
-                  [&] (Decl *D) { ntd->addMember(D); });
+                  ntd);
     ntd->setBraces({LBLoc, RBLoc});
   }
 }
@@ -3477,13 +3468,14 @@
 /// \endverbatim
 bool Parser::parseDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
                            Diag<> ErrorDiag, ParseDeclOptions Options,
-                           llvm::function_ref<void(Decl*)> handler) {
+                           IterableDeclContext *IDC) {
   ParserStatus Status;
   bool PreviousHadSemi = true;
   {
     SyntaxParsingContext ListContext(SyntaxContext, SyntaxKind::MemberDeclList);
     while (Tok.isNot(tok::r_brace)) {
-      Status |= parseDeclItem(PreviousHadSemi, Options, handler);
+      Status |= parseDeclItem(PreviousHadSemi, Options,
+                              [&](Decl *D) { IDC->addMember(D); });
       if (Tok.isAny(tok::eof, tok::pound_endif, tok::pound_else,
                     tok::pound_elseif)) {
         IsInputIncomplete = true;
@@ -3504,30 +3496,15 @@
 
 bool Parser::canDelayMemberDeclParsing() {
   // If explicitly disabled, respect the flag.
-  if (DisableDelayedParsing)
+  if (!DelayBodyParsing)
     return false;
-  // There's no fundamental reasons that SIL cannnot be lasily parsed. We need
-  // to keep SILParserTUStateBase persistent to make it happen.
-  if (isInSILMode())
-    return false;
-  // Calculating interface hash requires tokens consumed in the original order.
-  if (SF.hasInterfaceHash())
-    return false;
-  if (SF.Kind == SourceFileKind::REPL)
-    return false;
-  // We always collect the entire syntax tree for IDE uses.
-  if (SF.shouldCollectToken())
-    return false;
-  if (SF.shouldBuildSyntaxTree())
-    return false;
-  // Recovering parser status later for #sourceLocaion is not-trivial and
+  // Recovering parser status later for #sourceLocation is not-trivial and
   // it may not worth it.
   if (InPoundLineEnvironment)
     return false;
-  // The first code completion pass looks for code completion tokens extensively,
-  // so we cannot lazily parse members.
-  if (isCodeCompletionFirstPass())
-    return false;
+
+  // Skip until the matching right curly bracket; if we find a pound directive,
+  // we can't lazily parse.
   BacktrackingScope BackTrack(*this);
   bool HasPoundDirective;
   skipUntilMatchingRBrace(*this, HasPoundDirective, SyntaxContext);
@@ -3536,6 +3513,23 @@
   return !BackTrack.willBacktrack();
 }
 
+bool Parser::delayParsingDeclList(SourceLoc LBLoc, SourceLoc &RBLoc,
+                                  SourceLoc PosBeforeLB,
+                                  ParseDeclOptions Options,
+                                  IterableDeclContext *IDC) {
+  bool error = false;
+
+  if (Tok.is(tok::r_brace)) {
+    RBLoc = consumeToken();
+  } else {
+    RBLoc = Tok.getLoc();
+    error = true;
+  }
+  State->delayDeclList(IDC, Options.toRaw(), CurDeclContext, { LBLoc, RBLoc },
+                        PosBeforeLB);
+  return error;
+}
+
 /// Parse an 'extension' declaration.
 ///
 /// \verbatim
@@ -3600,17 +3594,11 @@
     Scope S(this, ScopeKind::Extension);
     ParseDeclOptions Options(PD_HasContainerType | PD_InExtension);
     if (canDelayMemberDeclParsing()) {
-      if (Tok.is(tok::r_brace)) {
-        RBLoc = consumeToken();
-      } else {
-        RBLoc = Tok.getLoc();
+      if (delayParsingDeclList(LBLoc, RBLoc, PosBeforeLB, Options, ext))
         status.setIsParseError();
-      }
-      State->delayDeclList(ext, Options.toRaw(), CurDeclContext, { LBLoc, RBLoc },
-                           PosBeforeLB);
     } else {
       if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_extension,
-                        Options, [&] (Decl *D) { ext->addMember(D); }))
+                        Options, ext))
         status.setIsParseError();
     }
 
@@ -5395,7 +5383,8 @@
 
   BodyRange.End = PreviousLoc;
 
-  if (DelayedParseCB->shouldDelayFunctionBodyParsing(*this, AFD, Attrs,
+  if (DelayedParseCB &&
+      DelayedParseCB->shouldDelayFunctionBodyParsing(*this, AFD, Attrs,
                                                      BodyRange)) {
     State->delayFunctionBodyParsing(AFD, BodyRange,
                                     BeginParserPosition.PreviousLoc);
@@ -5737,20 +5726,14 @@
     RBLoc = LBLoc;
     Status.setIsParseError();
   } else {
-    Scope S(this, ScopeKind::ClassBody);
+    Scope S(this, ScopeKind::EnumBody);
     ParseDeclOptions Options(PD_HasContainerType | PD_AllowEnumElement | PD_InEnum);
     if (canDelayMemberDeclParsing()) {
-      if (Tok.is(tok::r_brace)) {
-        RBLoc = consumeToken();
-      } else {
-        RBLoc = Tok.getLoc();
+      if (delayParsingDeclList(LBLoc, RBLoc, PosBeforeLB, Options, ED))
         Status.setIsParseError();
-      }
-      State->delayDeclList(ED, Options.toRaw(), CurDeclContext, { LBLoc, RBLoc },
-                           PosBeforeLB);
     } else {
       if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_enum,
-                        Options, [&] (Decl *D) { ED->addMember(D); }))
+                        Options, ED))
         Status.setIsParseError();
     }
   }
@@ -6025,17 +6008,11 @@
     Scope S(this, ScopeKind::StructBody);
     ParseDeclOptions Options(PD_HasContainerType | PD_InStruct);
     if (canDelayMemberDeclParsing()) {
-      if (Tok.is(tok::r_brace)) {
-        RBLoc = consumeToken();
-      } else {
-        RBLoc = Tok.getLoc();
+      if (delayParsingDeclList(LBLoc, RBLoc, PosBeforeLB, Options, SD))
         Status.setIsParseError();
-      }
-      State->delayDeclList(SD, Options.toRaw(), CurDeclContext, { LBLoc, RBLoc },
-                           PosBeforeLB);
     } else {
       if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_struct,
-                        Options, [&](Decl *D) {SD->addMember(D);}))
+                        Options,SD))
         Status.setIsParseError();
     }
   }
@@ -6149,22 +6126,11 @@
     ParseDeclOptions Options(PD_HasContainerType | PD_AllowDestructor |
                              PD_InClass);
     if (canDelayMemberDeclParsing()) {
-      if (Tok.is(tok::r_brace)) {
-        RBLoc = consumeToken();
-      } else {
-        RBLoc = Tok.getLoc();
+      if (delayParsingDeclList(LBLoc, RBLoc, PosBeforeLB, Options, CD))
         Status.setIsParseError();
-      }
-      State->delayDeclList(CD, Options.toRaw(), CurDeclContext, { LBLoc, RBLoc },
-                           PosBeforeLB);
     } else {
-      auto Handler = [&] (Decl *D) {
-        CD->addMember(D);
-        if (isa<DestructorDecl>(D))
-          CD->setHasDestructor();
-      };
       if (parseDeclList(LBLoc, RBLoc, diag::expected_rbrace_class,
-                        Options, Handler))
+                        Options, CD))
         Status.setIsParseError();
     }
   }
@@ -6259,18 +6225,11 @@
                                PD_DisallowInit |
                                PD_InProtocol);
       if (canDelayMemberDeclParsing()) {
-        if (Tok.is(tok::r_brace)) {
-          RBraceLoc = consumeToken();
-        } else {
-          RBraceLoc = Tok.getLoc();
+        if (delayParsingDeclList(LBraceLoc, RBraceLoc, PosBeforeLB, Options, Proto))
           Status.setIsParseError();
-        }
-        State->delayDeclList(Proto, Options.toRaw(), CurDeclContext,
-                             { LBraceLoc, RBraceLoc },
-                             PosBeforeLB);
       } else {
         if (parseDeclList(LBraceLoc, RBraceLoc, diag::expected_rbrace_protocol,
-                          Options, [&](Decl *D) {Proto->addMember(D);}))
+                          Options, Proto))
           Status.setIsParseError();
       }
     }
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index fd3293a..81025e0 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1165,7 +1165,7 @@
         Result = makeParserResult(
             Result,
             new (Context) DotSelfExpr(Result.get(), TokLoc, consumeToken()));
-        SyntaxContext->createNodeInPlace(SyntaxKind::DotSelfExpr);
+        SyntaxContext->createNodeInPlace(SyntaxKind::MemberAccessExpr);
         continue;
       }
 
@@ -1560,7 +1560,8 @@
             ParsedSyntaxRecorder::makeIdentifierPattern(
                                     SyntaxContext->popToken(), *SyntaxContext);
         ParsedExprSyntax ExprNode =
-            ParsedSyntaxRecorder::deferUnresolvedPatternExpr(PatternNode);
+            ParsedSyntaxRecorder::deferUnresolvedPatternExpr(PatternNode,
+                                                             *SyntaxContext);
         SyntaxContext->addSyntax(ExprNode);
       }
       return makeParserResult(new (Context) UnresolvedPatternExpr(pattern));
@@ -1635,7 +1636,7 @@
     Name = parseUnqualifiedDeclName(/*afterDot=*/true, NameLoc,
                                     diag::expected_identifier_after_dot_expr);
     if (!Name) return nullptr;
-    SyntaxContext->createNodeInPlace(SyntaxKind::ImplicitMemberExpr);
+    SyntaxContext->createNodeInPlace(SyntaxKind::MemberAccessExpr);
 
     // Check for a () suffix, which indicates a call when constructing
     // this member.  Note that this cannot be the start of a new line.
@@ -1801,7 +1802,7 @@
                     unsigned &InterpolationCount) {
   SourceLoc Loc = EntireTok.getLoc();
   ParserStatus Status;
-  Trivia EmptyTrivia;
+  ParsedTrivia EmptyTrivia;
   bool First = true;
 
   DeclName appendLiteral(Context, Context.Id_appendLiteral, { Identifier() });
@@ -2027,8 +2028,8 @@
   // Make unknown tokens to represent the open and close quote.
   Token OpenQuote(QuoteKind, OpenQuoteStr);
   Token CloseQuote(QuoteKind, CloseQuoteStr);
-  Trivia EmptyTrivia;
-  Trivia EntireTrailingTrivia = TrailingTrivia;
+  ParsedTrivia EmptyTrivia;
+  ParsedTrivia EntireTrailingTrivia = TrailingTrivia;
 
   // Add the open quote to the context; the quote should have the leading trivia
   // of the entire string token and a void trailing trivia.
@@ -2040,8 +2041,8 @@
   // We are going to mess with Tok to do reparsing for interpolated literals,
   // don't lose our 'next' token.
   llvm::SaveAndRestore<Token> SavedTok(Tok);
-  llvm::SaveAndRestore<Trivia> SavedLeadingTrivia(LeadingTrivia);
-  llvm::SaveAndRestore<Trivia> SavedTrailingTrivia(TrailingTrivia);
+  llvm::SaveAndRestore<ParsedTrivia> SavedLeadingTrivia(LeadingTrivia);
+  llvm::SaveAndRestore<ParsedTrivia> SavedTrailingTrivia(TrailingTrivia);
 
   // We're not in a place where an interpolation would be valid.
   if (!CurLocalContext) {
diff --git a/lib/Parse/ParsedRawSyntaxNode.cpp b/lib/Parse/ParsedRawSyntaxNode.cpp
index dc81ec9..c281260 100644
--- a/lib/Parse/ParsedRawSyntaxNode.cpp
+++ b/lib/Parse/ParsedRawSyntaxNode.cpp
@@ -11,18 +11,43 @@
 //===----------------------------------------------------------------------===//
 
 #include "swift/Parse/ParsedRawSyntaxNode.h"
+#include "swift/Parse/SyntaxParsingContext.h"
 
 using namespace swift;
 using namespace swift::syntax;
+using namespace llvm;
 
 ParsedRawSyntaxNode
-ParsedRawSyntaxNode::makeDeferredMissing(tok kind, SourceLoc loc) {
-  // Pass appropriate text for the missing token to have the provided location
-  // but zero length.
-  StringRef tokText = CharSourceRange{loc, 0}.str();
-  auto raw = ParsedRawSyntaxNode::makeDeferred(Token{kind, tokText}, {}, {});
-  raw.IsMissing = true;
-  return raw;
+ParsedRawSyntaxNode::makeDeferred(SyntaxKind k,
+                                  ArrayRef<ParsedRawSyntaxNode> deferredNodes,
+                                  SyntaxParsingContext &ctx) {
+  if (deferredNodes.empty()) {
+    return ParsedRawSyntaxNode(k, {});
+  }
+  ParsedRawSyntaxNode *newPtr =
+    ctx.getScratchAlloc().Allocate<ParsedRawSyntaxNode>(deferredNodes.size());
+  std::uninitialized_copy(deferredNodes.begin(), deferredNodes.end(), newPtr);
+  return ParsedRawSyntaxNode(k, makeArrayRef(newPtr, deferredNodes.size()));
+}
+
+ParsedRawSyntaxNode
+ParsedRawSyntaxNode::makeDeferred(Token tok,
+                                  const ParsedTrivia &leadingTrivia,
+                                  const ParsedTrivia &trailingTrivia,
+                                  SyntaxParsingContext &ctx) {
+  CharSourceRange tokRange = tok.getRangeWithoutBackticks();
+  size_t piecesCount = leadingTrivia.size() + trailingTrivia.size();
+  ParsedTriviaPiece *piecesPtr = nullptr;
+  if (piecesCount > 0) {
+    piecesPtr = ctx.getScratchAlloc().Allocate<ParsedTriviaPiece>(piecesCount);
+    std::uninitialized_copy(leadingTrivia.begin(), leadingTrivia.end(),
+                            piecesPtr);
+    std::uninitialized_copy(trailingTrivia.begin(), trailingTrivia.end(),
+                            piecesPtr + leadingTrivia.size());
+  }
+  return ParsedRawSyntaxNode(tok.getKind(), tokRange.getStart(),
+                             tokRange.getByteLength(), piecesPtr,
+                             leadingTrivia.size(), trailingTrivia.size());
 }
 
 void ParsedRawSyntaxNode::dump() const {
diff --git a/lib/Parse/ParsedRawSyntaxRecorder.cpp b/lib/Parse/ParsedRawSyntaxRecorder.cpp
index 184906c..41f3db8 100644
--- a/lib/Parse/ParsedRawSyntaxRecorder.cpp
+++ b/lib/Parse/ParsedRawSyntaxRecorder.cpp
@@ -18,33 +18,35 @@
 
 #include "swift/Parse/ParsedRawSyntaxRecorder.h"
 #include "swift/Parse/ParsedRawSyntaxNode.h"
+#include "swift/Parse/ParsedTrivia.h"
 #include "swift/Parse/SyntaxParseActions.h"
 #include "swift/Parse/Token.h"
 #include "swift/Syntax/SyntaxKind.h"
-#include "swift/Syntax/Trivia.h"
 
 using namespace swift;
 using namespace swift::syntax;
 
 ParsedRawSyntaxNode
 ParsedRawSyntaxRecorder::recordToken(const Token &tok,
-                                     const Trivia &leadingTrivia,
-                                     const Trivia &trailingTrivia) {
-  SourceLoc tokLoc = tok.getLoc();
-  unsigned tokLength = tok.getLength();
-  if (tok.isEscapedIdentifier()) {
-    // Adjust to account for the backticks that are included in trivia.
-    tokLoc = tokLoc.getAdvancedLoc(1);
-    tokLength -= 2;
-  }
-  unsigned leadingTriviaLen = leadingTrivia.getTextLength();
-  unsigned trailingTriviaLen = trailingTrivia.getTextLength();
-  SourceLoc offset = tokLoc.getAdvancedLoc(-leadingTriviaLen);
-  unsigned length = leadingTriviaLen + tokLength + trailingTriviaLen;
+                                     const ParsedTrivia &leadingTrivia,
+                                     const ParsedTrivia &trailingTrivia) {
+  return recordToken(tok.getKind(), tok.getRangeWithoutBackticks(),
+                     leadingTrivia.Pieces, trailingTrivia.Pieces);
+}
+
+ParsedRawSyntaxNode
+ParsedRawSyntaxRecorder::recordToken(tok tokKind, CharSourceRange tokRange,
+                                ArrayRef<ParsedTriviaPiece> leadingTrivia,
+                                ArrayRef<ParsedTriviaPiece> trailingTrivia) {
+  size_t leadingTriviaLen = ParsedTriviaPiece::getTotalLength(leadingTrivia);
+  size_t trailingTriviaLen = ParsedTriviaPiece::getTotalLength(trailingTrivia);
+  SourceLoc offset = tokRange.getStart().getAdvancedLoc(-leadingTriviaLen);
+  unsigned length = leadingTriviaLen + tokRange.getByteLength() +
+      trailingTriviaLen;
   CharSourceRange range{offset, length};
-  OpaqueSyntaxNode n = SPActions->recordToken(tok, leadingTrivia,
+  OpaqueSyntaxNode n = SPActions->recordToken(tokKind, leadingTrivia,
                                               trailingTrivia, range);
-  return ParsedRawSyntaxNode{SyntaxKind::Token, tok.getKind(), range, n};
+  return ParsedRawSyntaxNode{SyntaxKind::Token, tokKind, range, n};
 }
 
 ParsedRawSyntaxNode
@@ -61,11 +63,13 @@
   if (node.isDeferredLayout())
     return rec.recordRawSyntax(node.getKind(), node.getDeferredChildren());
   assert(node.isDeferredToken());
-  const Token &tok = node.getToken();
+  CharSourceRange tokRange = node.getDeferredTokenRangeWithoutBackticks();
+  tok tokKind = node.getTokenKind();
   if (node.isMissing())
-    return rec.recordMissingToken(tok.getKind(), tok.getLoc());
-  return rec.recordToken(tok, node.getLeadingTrivia(),
-                         node.getTrailingTrivia());
+    return rec.recordMissingToken(tokKind, tokRange.getStart());
+  return rec.recordToken(tokKind,tokRange,
+                         node.getDeferredLeadingTriviaPieces(),
+                         node.getDeferredTrailingTriviaPieces());
 }
 
 ParsedRawSyntaxNode
diff --git a/lib/Parse/ParsedSyntaxBuilders.cpp.gyb b/lib/Parse/ParsedSyntaxBuilders.cpp.gyb
index 0113cbb..8e40cba 100644
--- a/lib/Parse/ParsedSyntaxBuilders.cpp.gyb
+++ b/lib/Parse/ParsedSyntaxBuilders.cpp.gyb
@@ -29,24 +29,27 @@
 % for node in SYNTAX_NODES:
 %   if node.is_buildable():
 %     for child in node.children:
-Parsed${node.name}Builder &
-Parsed${node.name}Builder::use${child.name}(Parsed${child.type_name} ${child.name}) {
-  Layout[cursorIndex(${node.name}::Cursor::${child.name})] =
-    ${child.name}.getRaw();
-  return *this;
-}
+%       child_elt = None
+%       child_elt_type = None
 %       child_node = NODE_MAP.get(child.syntax_kind)
 %       if child_node and child_node.is_syntax_collection():
 %         child_elt = child_node.collection_element_name
 %         child_elt_type = child_node.collection_element_type
+%       end
+Parsed${node.name}Builder &
+Parsed${node.name}Builder::use${child.name}(Parsed${child.type_name} ${child.name}) {
+%       if child_elt:
+  assert(${child_elt}Nodes.empty() && "use either 'use' function or 'add', not both");
+%       end
+  Layout[cursorIndex(${node.name}::Cursor::${child.name})] =
+    ${child.name}.getRaw();
+  return *this;
+}
+%       if child_elt:
 Parsed${node.name}Builder &
 Parsed${node.name}Builder::add${child_elt}(Parsed${child_elt_type} ${child_elt}) {
-  auto &raw = Layout[cursorIndex(${node.name}::Cursor::${child.name})];
-  if (raw.isNull())
-    raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind},
-                          {${child_elt}.getRaw()});
-  else
-    raw.addDeferredChild(${child_elt}.getRaw());
+  assert(Layout[cursorIndex(${node.name}::Cursor::${child.name})].isNull() && "use either 'use' function or 'add', not both");
+  ${child_elt}Nodes.push_back(std::move(${child_elt}.getRaw()));
   return *this;
 }
 %       end
@@ -54,39 +57,62 @@
 
 Parsed${node.name}
 Parsed${node.name}Builder::record() {
-  finishLayout();
+  finishLayout(/*deferred=*/false);
+  auto &Rec = SPCtx.getRecorder();
   auto raw = Rec.recordRawSyntax(SyntaxKind::${node.syntax_kind}, Layout);
   return Parsed${node.name}(std::move(raw));
 }
 
 Parsed${node.name}
 Parsed${node.name}Builder::makeDeferred() {
-  finishLayout();
+  finishLayout(/*deferred=*/true);
   auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind},
-    Layout);
+    Layout, SPCtx);
   return Parsed${node.name}(std::move(raw));
 }
 
 Parsed${node.name}
 Parsed${node.name}Builder::build() {
-  if (IsBacktracking)
+  if (SPCtx.isBacktracking())
     return makeDeferred();
   return record();
 }
 
-void Parsed${node.name}Builder::finishLayout() {
+void Parsed${node.name}Builder::finishLayout(bool deferred) {
+  auto &Rec = SPCtx.getRecorder();
+  (void)Rec;
 % if node.children:
 %   for (idx, child) in enumerate(node.children):
+%     child_elt = None
+%     child_node = NODE_MAP.get(child.syntax_kind)
+%     if child_node and child_node.is_syntax_collection():
+%       child_elt = child_node.collection_element_name
+%     if child_elt:
+  if (!${child_elt}Nodes.empty()) {
+    if (deferred) {
+      Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind},
+                          ${child_elt}Nodes, SPCtx);
+    } else {
+      Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, ${child_elt}Nodes);
+    }
+  }
+%     end
 %     if not child.is_optional:
   if (Layout[${idx}].isNull()) {
 %       if child.is_token():
 %         token = child.main_token()
 %         tok_kind = token.kind if token else "unknown"
-    if (IsBacktracking) {
+    if (deferred) {
       Layout[${idx}] = ParsedRawSyntaxNode::makeDeferredMissing(tok::${tok_kind}, SourceLoc());
     } else {
       Layout[${idx}] = Rec.recordMissingToken(tok::${tok_kind}, SourceLoc());
     }
+%       elif child_elt:
+    if (deferred) {
+      Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind}, {}, SPCtx);
+    } else {
+      Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, {});
+    }
 %       else:
     llvm_unreachable("need missing non-token nodes ?");
 %       end
diff --git a/lib/Parse/ParsedSyntaxRecorder.cpp.gyb b/lib/Parse/ParsedSyntaxRecorder.cpp.gyb
index d504ed9..17700cc 100644
--- a/lib/Parse/ParsedSyntaxRecorder.cpp.gyb
+++ b/lib/Parse/ParsedSyntaxRecorder.cpp.gyb
@@ -98,7 +98,7 @@
 }
 
 Parsed${node.name}
-ParsedSyntaxRecorder::defer${node.syntax_kind}(${child_params}) {
+ParsedSyntaxRecorder::defer${node.syntax_kind}(${child_params}, SyntaxParsingContext &SPCtx) {
   auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, {
 %     for child in node.children:
 %       if child.is_optional:
@@ -107,7 +107,7 @@
     ${child.name}.getRaw(),
 %       end
 %     end
-  });
+  }, SPCtx);
   return Parsed${node.name}(std::move(raw));
 }
 
@@ -115,7 +115,7 @@
 ParsedSyntaxRecorder::make${node.syntax_kind}(${child_params},
     SyntaxParsingContext &SPCtx) {
   if (SPCtx.isBacktracking())
-    return defer${node.syntax_kind}(${child_move_args});
+    return defer${node.syntax_kind}(${child_move_args}, SPCtx);
   return record${node.syntax_kind}(${child_move_args}, SPCtx.getRecorder());
 }
 
@@ -135,14 +135,15 @@
 
 Parsed${node.name}
 ParsedSyntaxRecorder::defer${node.syntax_kind}(
-    ArrayRef<Parsed${node.collection_element_type}> elements) {
+    ArrayRef<Parsed${node.collection_element_type}> elements,
+    SyntaxParsingContext &SPCtx) {
   SmallVector<ParsedRawSyntaxNode, 16> layout;
   layout.reserve(elements.size());
   for (auto &element : elements) {
     layout.push_back(element.getRaw());
   }
   auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind},
-                             layout);
+                             layout, SPCtx);
   return Parsed${node.name}(std::move(raw));
 }
 
@@ -151,7 +152,7 @@
     ArrayRef<Parsed${node.collection_element_type}> elements,
     SyntaxParsingContext &SPCtx) {
   if (SPCtx.isBacktracking())
-    return defer${node.syntax_kind}(elements);
+    return defer${node.syntax_kind}(elements, SPCtx);
   return record${node.syntax_kind}(elements, SPCtx.getRecorder());
 }
 
@@ -161,7 +162,7 @@
   ParsedRawSyntaxNode raw;
   if (SPCtx.isBacktracking()) {
     // FIXME: 'loc' is not preserved when capturing a deferred layout.
-    raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, {});
+    raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, {}, SPCtx);
   } else {
     raw = SPCtx.getRecorder().recordEmptyRawSyntaxCollection(SyntaxKind::${node.syntax_kind}, loc);
   }
diff --git a/lib/Parse/ParsedTrivia.cpp b/lib/Parse/ParsedTrivia.cpp
new file mode 100644
index 0000000..7064ba2
--- /dev/null
+++ b/lib/Parse/ParsedTrivia.cpp
@@ -0,0 +1,40 @@
+//===--- ParsedTrivia.cpp - ParsedTrivia API ----------------------------*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/Parse/ParsedTrivia.h"
+#include "swift/Syntax/Trivia.h"
+#include "swift/Basic/SourceManager.h"
+
+using namespace swift;
+using namespace swift::syntax;
+
+Trivia
+ParsedTriviaPiece::convertToSyntaxTrivia(ArrayRef<ParsedTriviaPiece> pieces,
+                                         SourceLoc loc,
+                                         const SourceManager &SM,
+                                         unsigned bufferID) {
+  Trivia trivia;
+  SourceLoc curLoc = loc;
+  for (const auto &piece : pieces) {
+    CharSourceRange range{curLoc, piece.getLength()};
+    StringRef text = SM.extractText(range, bufferID);
+    trivia.push_back(TriviaPiece::fromText(piece.getKind(), text));
+    curLoc = curLoc.getAdvancedLoc(piece.getLength());
+  }
+  return trivia;
+}
+
+Trivia
+ParsedTrivia::convertToSyntaxTrivia(SourceLoc loc, const SourceManager &SM,
+                                    unsigned bufferID) const {
+  return ParsedTriviaPiece::convertToSyntaxTrivia(Pieces, loc, SM, bufferID);
+}
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index b3988bb..afb476c 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -73,7 +73,7 @@
   }
 
   Token Tok;
-  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   do {
     L.lex(Tok, LeadingTrivia, TrailingTrivia);
 
@@ -83,7 +83,7 @@
     if (F != ResetTokens.end()) {
       assert(F->isNot(tok::string_literal));
 
-      DestFunc(*F, syntax::Trivia(), syntax::Trivia());
+      DestFunc(*F, ParsedTrivia(), ParsedTrivia());
 
       auto NewState = L.getStateForBeginningOfTokenLoc(
           F->getLoc().getAdvancedLoc(F->getLength()));
@@ -95,7 +95,7 @@
       std::vector<Token> StrTokens;
       getStringPartTokens(Tok, LangOpts, SM, BufferID, StrTokens);
       for (auto &StrTok : StrTokens) {
-        DestFunc(StrTok, syntax::Trivia(), syntax::Trivia());
+        DestFunc(StrTok, ParsedTrivia(), ParsedTrivia());
       }
     } else {
       DestFunc(Tok, LeadingTrivia, TrailingTrivia);
@@ -139,7 +139,8 @@
     SourceFile &SF = *AFD->getDeclContext()->getParentSourceFile();
     SourceManager &SourceMgr = SF.getASTContext().SourceMgr;
     unsigned BufferID = SourceMgr.findBufferContainingLoc(AFD->getLoc());
-    Parser TheParser(BufferID, SF, nullptr, &ParserState);
+    Parser TheParser(BufferID, SF, nullptr, &ParserState, nullptr,
+                     /*DelayBodyParsing=*/false);
     TheParser.SyntaxContext->disable();
     std::unique_ptr<CodeCompletionCallbacks> CodeCompletion;
     if (CodeCompletionFactory) {
@@ -165,7 +166,8 @@
   SourceManager &SourceMgr = SF.getASTContext().SourceMgr;
   unsigned BufferID =
     SourceMgr.findBufferContainingLoc(ParserState.getDelayedDeclLoc());
-  Parser TheParser(BufferID, SF, nullptr, &ParserState);
+  Parser TheParser(BufferID, SF, nullptr, &ParserState, nullptr,
+                   /*DelayBodyParsing=*/false);
 
   // Disable libSyntax creation in the delayed parsing.
   TheParser.SyntaxContext->disable();
@@ -292,8 +294,8 @@
                         : CommentRetentionMode::AttachToNextToken,
            TriviaRetentionMode::WithoutTrivia, TokenizeInterpolatedString,
            SplitTokens,
-           [&](const Token &Tok, const Trivia &LeadingTrivia,
-               const Trivia &TrailingTrivia) { Tokens.push_back(Tok); });
+           [&](const Token &Tok, const ParsedTrivia &LeadingTrivia,
+               const ParsedTrivia &TrailingTrivia) { Tokens.push_back(Tok); });
 
   assert(Tokens.back().is(tok::eof));
   Tokens.pop_back(); // Remove EOF.
@@ -314,12 +316,22 @@
       CommentRetentionMode::AttachToNextToken, TriviaRetentionMode::WithTrivia,
       /*TokenizeInterpolatedString=*/false,
       /*SplitTokens=*/ArrayRef<Token>(),
-      [&](const Token &Tok, const Trivia &LeadingTrivia,
-          const Trivia &TrailingTrivia) {
+      [&](const Token &Tok, const ParsedTrivia &LeadingTrivia,
+          const ParsedTrivia &TrailingTrivia) {
+        CharSourceRange TokRange = Tok.getRangeWithoutBackticks();
+        SourceLoc LeadingTriviaLoc =
+          TokRange.getStart().getAdvancedLoc(-LeadingTrivia.getLength());
+        SourceLoc TrailingTriviaLoc =
+          TokRange.getStart().getAdvancedLoc(TokRange.getByteLength());
+        Trivia syntaxLeadingTrivia =
+          LeadingTrivia.convertToSyntaxTrivia(LeadingTriviaLoc, SM, BufferID);
+        Trivia syntaxTrailingTrivia =
+          TrailingTrivia.convertToSyntaxTrivia(TrailingTriviaLoc, SM, BufferID);
         auto Text = OwnedString::makeRefCounted(Tok.getText());
         auto ThisToken =
-            RawSyntax::make(Tok.getKind(), Text, LeadingTrivia.Pieces,
-                            TrailingTrivia.Pieces, SourcePresence::Present);
+            RawSyntax::make(Tok.getKind(), Text, syntaxLeadingTrivia.Pieces,
+                            syntaxTrailingTrivia.Pieces,
+                            SourcePresence::Present);
 
         auto ThisTokenPos = ThisToken->accumulateAbsolutePosition(RunningPos);
         Tokens.push_back({ThisToken, ThisTokenPos.getValue()});
@@ -336,15 +348,15 @@
 Parser::Parser(unsigned BufferID, SourceFile &SF, SILParserTUStateBase *SIL,
                PersistentParserState *PersistentState,
                std::shared_ptr<SyntaxParseActions> SPActions,
-               bool DisableDelayedParsing)
+               bool DelayBodyParsing)
     : Parser(BufferID, SF, &SF.getASTContext().Diags, SIL, PersistentState,
-             std::move(SPActions), DisableDelayedParsing) {}
+             std::move(SPActions), DelayBodyParsing) {}
 
 Parser::Parser(unsigned BufferID, SourceFile &SF, DiagnosticEngine* LexerDiags,
                SILParserTUStateBase *SIL,
                PersistentParserState *PersistentState,
                std::shared_ptr<SyntaxParseActions> SPActions,
-               bool DisableDelayedParsing)
+               bool DelayBodyParsing)
     : Parser(
           std::unique_ptr<Lexer>(new Lexer(
               SF.getASTContext().LangOpts, SF.getASTContext().SourceMgr,
@@ -359,7 +371,7 @@
               SF.shouldBuildSyntaxTree()
                   ? TriviaRetentionMode::WithTrivia
                   : TriviaRetentionMode::WithoutTrivia)),
-          SF, SIL, PersistentState, std::move(SPActions), DisableDelayedParsing) {}
+          SF, SIL, PersistentState, std::move(SPActions), DelayBodyParsing) {}
 
 namespace {
 
@@ -480,7 +492,7 @@
                SILParserTUStateBase *SIL,
                PersistentParserState *PersistentState,
                std::shared_ptr<SyntaxParseActions> SPActions,
-               bool DisableDelayedParsing)
+               bool DelayBodyParsing)
   : SourceMgr(SF.getASTContext().SourceMgr),
     Diags(SF.getASTContext().Diags),
     SF(SF),
@@ -488,7 +500,7 @@
     SIL(SIL),
     CurDeclContext(&SF),
     Context(SF.getASTContext()),
-    DisableDelayedParsing(DisableDelayedParsing),
+    DelayBodyParsing(DelayBodyParsing),
     TokReceiver(SF.shouldCollectToken() ?
                 new TokenRecorder(SF) :
                 new ConsumeTokenReceiver()),
@@ -580,7 +592,7 @@
 void Parser::markSplitToken(tok Kind, StringRef Txt) {
   SplitTokens.emplace_back();
   SplitTokens.back().setToken(Kind, Txt);
-  Trivia EmptyTrivia;
+  ParsedTrivia EmptyTrivia;
   SyntaxContext->addToken(SplitTokens.back(), LeadingTrivia, EmptyTrivia);
   TokReceiver->receive(SplitTokens.back());
 }
@@ -746,7 +758,7 @@
   }
   unsigned LexerOffset =
       SourceMgr.getLocOffsetInBuffer(Tok.getLoc(), L->getBufferID());
-  unsigned LeadingTriviaLen = LeadingTrivia.getTextLength();
+  unsigned LeadingTriviaLen = LeadingTrivia.getLength();
   unsigned LeadingTriviaOffset = LexerOffset - LeadingTriviaLen;
   SourceLoc LeadingTriviaLoc = Tok.getLoc().getAdvancedLoc(-LeadingTriviaLen);
   if (auto TextLength = SyntaxContext->lookupNode(LeadingTriviaOffset,
@@ -1095,7 +1107,8 @@
 
   Impl.SF->SyntaxParsingCache = SyntaxCache;
   Impl.TheParser.reset(new Parser(BufferID, *Impl.SF, /*SIL=*/nullptr,
-                                  /*PersistentState=*/nullptr, Impl.SPActions));
+                                  /*PersistentState=*/nullptr, Impl.SPActions,
+                                  /*DelayBodyParsing=*/false));
 }
 
 ParserUnit::ParserUnit(SourceManager &SM, SourceFileKind SFKind, unsigned BufferID,
@@ -1112,7 +1125,7 @@
                       TriviaRetentionMode::WithoutTrivia,
                       Offset, EndOffset));
   Impl.TheParser.reset(new Parser(std::move(Lex), *Impl.SF, /*SIL=*/nullptr,
-    /*PersistentState=*/nullptr, Impl.SPActions));
+    /*PersistentState=*/nullptr, Impl.SPActions, /*DelayBodyParsing=*/false));
 }
 
 ParserUnit::~ParserUnit() {
diff --git a/lib/Parse/SyntaxParsingContext.cpp b/lib/Parse/SyntaxParsingContext.cpp
index 9a3a908..a70c362 100644
--- a/lib/Parse/SyntaxParsingContext.cpp
+++ b/lib/Parse/SyntaxParsingContext.cpp
@@ -23,7 +23,6 @@
 #include "swift/Parse/SyntaxParsingCache.h"
 #include "swift/Parse/Token.h"
 #include "swift/Syntax/SyntaxFactory.h"
-#include "swift/Syntax/Trivia.h"
 
 using namespace swift;
 using namespace swift::syntax;
@@ -67,7 +66,7 @@
                                         ArrayRef<ParsedRawSyntaxNode> Parts) {
   assert(isUnknownKind(Kind));
   if (IsBacktracking)
-    return ParsedRawSyntaxNode::makeDeferred(Kind, Parts);
+    return ParsedRawSyntaxNode::makeDeferred(Kind, Parts, *this);
   else
     return getRecorder().recordRawSyntax(Kind, Parts);
 }
@@ -81,7 +80,7 @@
   auto &rec = getRecorder();
   auto formNode = [&](SyntaxKind kind, ArrayRef<ParsedRawSyntaxNode> layout) {
     if (nodeCreateK == SyntaxNodeCreationKind::Deferred || IsBacktracking) {
-      rawNode = ParsedRawSyntaxNode::makeDeferred(kind, layout);
+      rawNode = ParsedRawSyntaxNode::makeDeferred(kind, layout, *this);
     } else {
       rawNode = rec.recordRawSyntax(kind, layout);
     }
@@ -171,14 +170,16 @@
 }
 
 /// Add Token with Trivia to the parts.
-void SyntaxParsingContext::addToken(Token &Tok, Trivia &LeadingTrivia,
-                                    Trivia &TrailingTrivia) {
+void SyntaxParsingContext::addToken(Token &Tok,
+                                    const ParsedTrivia &LeadingTrivia,
+                                    const ParsedTrivia &TrailingTrivia) {
   if (!Enabled)
     return;
 
   ParsedRawSyntaxNode raw;
   if (IsBacktracking)
-    raw = ParsedRawSyntaxNode::makeDeferred(Tok, LeadingTrivia, TrailingTrivia);
+    raw = ParsedRawSyntaxNode::makeDeferred(Tok, LeadingTrivia, TrailingTrivia,
+                                            *this);
   else
     raw = getRecorder().recordToken(Tok, LeadingTrivia, TrailingTrivia);
   addRawSyntax(std::move(raw));
@@ -229,8 +230,6 @@
   case SyntaxKind::IdentifierExpr:
   case SyntaxKind::SpecializeExpr:
   case SyntaxKind::MemberAccessExpr:
-  case SyntaxKind::DotSelfExpr:
-  case SyntaxKind::ImplicitMemberExpr:
   case SyntaxKind::SimpleTypeIdentifier:
   case SyntaxKind::MemberTypeIdentifier:
   case SyntaxKind::FunctionCallExpr:
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index e31afb4..a8ecb77 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -116,19 +116,32 @@
                                 PersistentParserState *PersistentState,
                                 DelayedParsingCallbacks *DelayedParseCB,
                                 bool FullParse,
-                                bool DisableDelayedParsing) {
+                                bool DelayBodyParsing) {
   assert((!FullParse || (SF.canBeParsedInFull() && !SIL)) &&
          "cannot parse in full with the given parameters!");
 
   std::shared_ptr<SyntaxTreeCreator> STreeCreator;
   if (SF.shouldBuildSyntaxTree()) {
     STreeCreator = std::make_shared<SyntaxTreeCreator>(
-                   SF.SyntaxParsingCache, SF.getASTContext().getSyntaxArena());
+        SF.getASTContext().SourceMgr, BufferID,
+        SF.SyntaxParsingCache, SF.getASTContext().getSyntaxArena());
   }
 
+  // Not supported right now.
+  if (SF.Kind == SourceFileKind::REPL)
+    DelayBodyParsing = false;
+  if (SF.hasInterfaceHash())
+    DelayBodyParsing = false;
+  if (SF.shouldCollectToken())
+    DelayBodyParsing = false;
+  if (SF.shouldBuildSyntaxTree())
+    DelayBodyParsing = false;
+  if (SIL)
+    DelayBodyParsing = false;
+
   SharedTimer timer("Parsing");
   Parser P(BufferID, SF, SIL ? SIL->Impl.get() : nullptr,
-           PersistentState, STreeCreator, DisableDelayedParsing);
+           PersistentState, STreeCreator, DelayBodyParsing);
   PrettyStackTraceParser StackTrace(P);
 
   llvm::SaveAndRestore<bool> S(P.IsParsingInterfaceTokens,
@@ -157,21 +170,21 @@
                                 SILParserState *SIL,
                                 PersistentParserState *PersistentState,
                                 DelayedParsingCallbacks *DelayedParseCB,
-                                bool DisableDelayedParsing) {
+                                bool DelayBodyParsing) {
   return parseIntoSourceFileImpl(SF, BufferID, Done, SIL,
                                  PersistentState, DelayedParseCB,
                                  /*FullParse=*/SF.shouldBuildSyntaxTree(),
-                                 DisableDelayedParsing);
+                                 DelayBodyParsing);
 }
 
 bool swift::parseIntoSourceFileFull(SourceFile &SF, unsigned BufferID,
                                     PersistentParserState *PersistentState,
                                     DelayedParsingCallbacks *DelayedParseCB,
-                                    bool DisableDelayedParsing) {
+                                    bool DelayBodyParsing) {
   bool Done = false;
   return parseIntoSourceFileImpl(SF, BufferID, &Done, /*SIL=*/nullptr,
                                  PersistentState, DelayedParseCB,
-                                 /*FullParse=*/true, DisableDelayedParsing);
+                                 /*FullParse=*/true, DelayBodyParsing);
 }
 
 
@@ -4921,13 +4934,16 @@
 
   auto PartialApplyConvention = ParameterConvention::Direct_Owned;
   bool IsNonThrowingApply = false;
+  bool IsNoEscape = false;
   StringRef AttrName;
-  
-  if (parseSILOptional(AttrName, *this)) {
+
+  while (parseSILOptional(AttrName, *this)) {
     if (AttrName.equals("nothrow"))
       IsNonThrowingApply = true;
     else if (AttrName.equals("callee_guaranteed"))
       PartialApplyConvention = ParameterConvention::Direct_Guaranteed;
+    else if (AttrName.equals("on_stack"))
+      IsNoEscape = true;
     else
       return true;
   }
@@ -5058,8 +5074,10 @@
     }
 
     // FIXME: Why the arbitrary order difference in IRBuilder type argument?
-    ResultVal = B.createPartialApply(InstLoc, FnVal, subs, Args,
-                                     PartialApplyConvention);
+    ResultVal = B.createPartialApply(
+        InstLoc, FnVal, subs, Args, PartialApplyConvention,
+        IsNoEscape ? PartialApplyInst::OnStackKind::OnStack
+                   : PartialApplyInst::OnStackKind::NotOnStack);
     break;
   }
   case SILInstructionKind::TryApplyInst: {
diff --git a/lib/SIL/LoopInfo.cpp b/lib/SIL/LoopInfo.cpp
index 3cb8bc1..84f55ef 100644
--- a/lib/SIL/LoopInfo.cpp
+++ b/lib/SIL/LoopInfo.cpp
@@ -101,6 +101,9 @@
   if (isa<DynamicMethodBranchInst>(I))
     return false;
 
+  if (auto *PA = dyn_cast<PartialApplyInst>(I))
+    return !PA->isOnStack();
+
   assert(I->isTriviallyDuplicatable() &&
     "Code here must match isTriviallyDuplicatable in SILInstruction");
   return true;
diff --git a/lib/SIL/OperandOwnership.cpp b/lib/SIL/OperandOwnership.cpp
index f4cabbc..b967873 100644
--- a/lib/SIL/OperandOwnership.cpp
+++ b/lib/SIL/OperandOwnership.cpp
@@ -784,6 +784,10 @@
 
 OperandOwnershipKindMap
 OperandOwnershipKindClassifier::visitPartialApplyInst(PartialApplyInst *i) {
+  // partial_apply [stack] does not take ownership of its operands.
+  if (i->isOnStack())
+    return Map::allLive();
+
   return Map::compatibilityMap(
        // All non-trivial types should be captured.
        ValueOwnershipKind::Owned, UseLifetimeConstraint::MustBeInvalidated);
diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp
index a84f732..e4a43b0 100644
--- a/lib/SIL/SILBuilder.cpp
+++ b/lib/SIL/SILBuilder.cpp
@@ -52,7 +52,8 @@
 SILType SILBuilder::getPartialApplyResultType(SILType origTy, unsigned argCount,
                                         SILModule &M,
                                         SubstitutionMap subs,
-                                        ParameterConvention calleeConvention) {
+                                        ParameterConvention calleeConvention,
+                                        PartialApplyInst::OnStackKind onStack) {
   CanSILFunctionType FTI = origTy.castTo<SILFunctionType>();
   if (!subs.empty())
     FTI = FTI->substGenericArgs(M, subs);
@@ -65,6 +66,8 @@
   auto extInfo = FTI->getExtInfo()
     .withRepresentation(SILFunctionType::Representation::Thick)
     .withIsPseudogeneric(false);
+  if (onStack)
+    extInfo = extInfo.withNoEscape();
 
   // If the original method has an @unowned_inner_pointer return, the partial
   // application thunk will lifetime-extend 'self' for us, converting the
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index c652c9e..60c41bf 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -2663,8 +2663,10 @@
   AnyFunctionType::Param selfParam = fnType.getParams()[0];
 
   // The formal method parameters.
+  // If we actually partially-apply this, assume we'll need a thick function.
   fnType = cast<FunctionType>(fnType.getResult());
-  auto innerExtInfo = fnType->getExtInfo();
+  auto innerExtInfo =
+    fnType->getExtInfo().withRepresentation(FunctionTypeRepresentation::Swift);
   auto methodParams = fnType->getParams();
 
   auto resultType = fnType.getResult();
diff --git a/lib/SIL/SILInstruction.cpp b/lib/SIL/SILInstruction.cpp
index bfac323..fc30594 100644
--- a/lib/SIL/SILInstruction.cpp
+++ b/lib/SIL/SILInstruction.cpp
@@ -1117,6 +1117,10 @@
     if (ARI->canAllocOnStack())
       return true;
   }
+
+  if (auto *PA = dyn_cast<PartialApplyInst>(this))
+    return PA->isOnStack();
+
   return false;
 }
 
@@ -1189,6 +1193,9 @@
   if (isa<DynamicMethodBranchInst>(this))
     return false;
 
+  if (auto *PA = dyn_cast<PartialApplyInst>(this))
+    return !PA->isOnStack();
+
   // If you add more cases here, you should also update SILLoop:canDuplicate.
 
   return true;
diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp
index 28ab291..0afdb94 100644
--- a/lib/SIL/SILInstructions.cpp
+++ b/lib/SIL/SILInstructions.cpp
@@ -503,19 +503,19 @@
     // PartialApplyInst
     // should derive the type of its result by partially applying the callee's
     // type.
-    : InstructionBase(Loc, Callee, SubstCalleeTy, Subs,
-                      Args, TypeDependentOperands, SpecializationInfo,
-                      ClosureType) {}
+    : InstructionBase(Loc, Callee, SubstCalleeTy, Subs, Args,
+                      TypeDependentOperands, SpecializationInfo, ClosureType) {}
 
 PartialApplyInst *PartialApplyInst::create(
     SILDebugLocation Loc, SILValue Callee, ArrayRef<SILValue> Args,
     SubstitutionMap Subs, ParameterConvention CalleeConvention, SILFunction &F,
     SILOpenedArchetypesState &OpenedArchetypes,
-    const GenericSpecializationInformation *SpecializationInfo) {
+    const GenericSpecializationInformation *SpecializationInfo,
+    OnStackKind onStack) {
   SILType SubstCalleeTy =
       Callee->getType().substGenericArgs(F.getModule(), Subs);
   SILType ClosureType = SILBuilder::getPartialApplyResultType(
-      SubstCalleeTy, Args.size(), F.getModule(), {}, CalleeConvention);
+      SubstCalleeTy, Args.size(), F.getModule(), {}, CalleeConvention, onStack);
 
   SmallVector<SILValue, 32> TypeDependentOperands;
   collectTypeDependentOperands(TypeDependentOperands, OpenedArchetypes, F,
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index 5537923..9ac4a41 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -212,6 +212,10 @@
     // FIXME
     Buffer << "<subscript>";
     return;
+  case DeclContextKind::EnumElementDecl:
+    // FIXME
+    Buffer << "<enum element>";
+    return;
   }
   llvm_unreachable("bad decl context");
 }
@@ -1123,6 +1127,8 @@
     case ParameterConvention::Indirect_InoutAliasable:
       llvm_unreachable("unexpected callee convention!");
     }
+    if (CI->isOnStack())
+      *this << "[on_stack] ";
     visitApplyInstBase(CI);
   }
 
diff --git a/lib/SIL/SILProfiler.cpp b/lib/SIL/SILProfiler.cpp
index 64a2d41..050682d 100644
--- a/lib/SIL/SILProfiler.cpp
+++ b/lib/SIL/SILProfiler.cpp
@@ -404,7 +404,7 @@
     assert((!StartLoc || StartLoc->isValid()) &&
            "Expected start location to be valid");
     assert((!EndLoc || EndLoc->isValid()) &&
-           "Expected start location to be valid");
+           "Expected end location to be valid");
   }
 
   SourceMappingRegion(SourceMappingRegion &&Region) = default;
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index f0c36c2..f1ed279 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -2260,8 +2260,11 @@
 
   void checkDeallocStackInst(DeallocStackInst *DI) {
     require(isa<SILUndef>(DI->getOperand()) ||
-                isa<AllocStackInst>(DI->getOperand()),
-            "Operand of dealloc_stack must be an alloc_stack");
+                isa<AllocStackInst>(DI->getOperand()) ||
+                (isa<PartialApplyInst>(DI->getOperand()) &&
+                 cast<PartialApplyInst>(DI->getOperand())->isOnStack()),
+            "Operand of dealloc_stack must be an alloc_stack or partial_apply "
+            "[stack]");
   }
   void checkDeallocRefInst(DeallocRefInst *DI) {
     require(DI->getOperand()->getType().isObject(),
diff --git a/lib/SIL/ValueOwnership.cpp b/lib/SIL/ValueOwnership.cpp
index d45a668..c9e3c10 100644
--- a/lib/SIL/ValueOwnership.cpp
+++ b/lib/SIL/ValueOwnership.cpp
@@ -74,7 +74,6 @@
 CONSTANT_OWNERSHIP_INST(Owned, CopyBlockWithoutEscaping)
 CONSTANT_OWNERSHIP_INST(Owned, CopyValue)
 CONSTANT_OWNERSHIP_INST(Owned, KeyPath)
-CONSTANT_OWNERSHIP_INST(Owned, PartialApply)
 CONSTANT_OWNERSHIP_INST(Owned, InitExistentialValue)
 CONSTANT_OWNERSHIP_INST(Owned, GlobalValue) // TODO: is this correct?
 
@@ -330,6 +329,13 @@
   llvm_unreachable("Unhandled LoadOwnershipQualifier in switch.");
 }
 
+ValueOwnershipKind
+ValueOwnershipKindClassifier::visitPartialApplyInst(PartialApplyInst *PA) {
+  if (PA->isOnStack())
+    return ValueOwnershipKind::Any;
+  return ValueOwnershipKind::Owned;
+}
+
 //===----------------------------------------------------------------------===//
 //                   Builtin OwnershipValueKind Computation
 //===----------------------------------------------------------------------===//
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index 2cc12d0..feb4916 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -2292,9 +2292,13 @@
   // Map outer initializations into a tuple of inner initializations:
   //   - fill out the initialization elements with null
   TupleInitialization innerTupleInit;
-  CanTupleType innerTuple =
-    cast<TupleType>(E->getSubExpr()->getType()->getCanonicalType());
-  innerTupleInit.SubInitializations.resize(innerTuple->getNumElements());
+  if (E->isSourceScalar()) {
+    innerTupleInit.SubInitializations.push_back(nullptr);
+  } else {
+    CanTupleType innerTuple =
+      cast<TupleType>(E->getSubExpr()->getType()->getCanonicalType());
+    innerTupleInit.SubInitializations.resize(innerTuple->getNumElements());
+  }
 
   // Map all the outer initializations to their appropriate targets.
   for (unsigned outerIndex = 0; outerIndex != outerInits.size(); outerIndex++) {
@@ -2312,14 +2316,20 @@
 #endif
 
   // Emit the sub-expression into the tuple initialization we just built.
-  emitter.SGF.emitExprInto(E->getSubExpr(), &innerTupleInit);
+  if (E->isSourceScalar()) {
+    emitter.SGF.emitExprInto(E->getSubExpr(),
+                             innerTupleInit.SubInitializations[0].get());
+  } else {
+    emitter.SGF.emitExprInto(E->getSubExpr(), &innerTupleInit);
+  }
 
   outerTupleInit->finishInitialization(emitter.SGF);
 }
 
 RValue RValueEmitter::visitTupleShuffleExpr(TupleShuffleExpr *E,
                                             SGFContext C) {
-  assert(!E->isSourceScalar());
+  // FIXME: Once we're no longer using this code path for enum element payloads,
+  // also assert that !E->isSourceScalar().
   assert(!E->isResultScalar());
 
   // If we're emitting into an initialization, we can try shuffling the
@@ -2333,7 +2343,11 @@
 
   // Emit the sub-expression tuple and destructure it into elements.
   SmallVector<RValue, 4> elements;
-  visit(E->getSubExpr()).extractElements(elements);
+  if (E->isSourceScalar()) {
+    elements.push_back(visit(E->getSubExpr()));
+  } else {
+    visit(E->getSubExpr()).extractElements(elements);
+  }
   
   // Prepare a new tuple to hold the shuffled result.
   RValue result(E->getType()->getCanonicalType());
diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h
index f524069..c4c32bd 100644
--- a/lib/SILGen/SILGenFunction.h
+++ b/lib/SILGen/SILGenFunction.h
@@ -668,12 +668,6 @@
                                CanAnyFunctionType blockTy,
                                CanSILFunctionType loweredBlockTy);
 
-  /// Given a non-canonical function type, create a thunk for the function's
-  /// canonical type.
-  ManagedValue emitCanonicalFunctionThunk(SILLocation loc, ManagedValue fn,
-                                          CanSILFunctionType nonCanonicalTy,
-                                          CanSILFunctionType canonicalTy);
-
   /// Thunk with the signature of a base class method calling a derived class
   /// method.
   ///
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 9d13115..a8991af 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -1595,7 +1595,7 @@
     auto &arg = managedArgs[index];
     auto argTy = argTypes[index];
     if (argTy.isConsumed()) {
-      forwardedArgs.push_back(arg.forward(SGF));
+      forwardedArgs.push_back(arg.ensurePlusOne(SGF, loc).forward(SGF));
       continue;
     }
 
@@ -3906,150 +3906,3 @@
   scope.pop();
   B.createReturn(loc, reqtResultValue);
 }
-
-//===----------------------------------------------------------------------===//
-// Conversion to Canonical SILFunctionType Thunks
-//===----------------------------------------------------------------------===//
-
-static void translateParametersForCanonicalFunctionThunk(
-    SILGenFunction &SGF, SILLocation loc,
-    ArrayRef<ManagedValue> origParamValues,
-    ArrayRef<SILParameterInfo> newParamInfos,
-    SmallVectorImpl<ManagedValue> &newParams) {
-  assert(origParamValues.size() == newParamInfos.size());
-
-  for (auto T : llvm::zip(origParamValues, newParamInfos)) {
-    ManagedValue origParam;
-    SILParameterInfo newParamInfo;
-    std::tie(origParam, newParamInfo) = T;
-
-    if (origParam.getType().isTrivial(SGF.getModule())) {
-      newParams.emplace_back(origParam);
-      continue;
-    }
-
-    if (origParam.hasCleanup()) {
-      // If we have a +1 value and the non-canonical function expects a
-      // guaranteed parameter, borrow the parameter. Otherwise just pass off the
-      // +1 value.
-      if (newParamInfo.isGuaranteed()) {
-        origParam = origParam.borrow(SGF, loc);
-      }
-      newParams.emplace_back(origParam);
-      continue;
-    }
-
-    // Otherwise, if we have a +0 value and we want to pass it off as a +1
-    // value, perform the copy.
-    if (newParamInfo.isConsumed()) {
-      origParam = origParam.copy(SGF, loc);
-    }
-    newParams.emplace_back(origParam);
-  }
-}
-
-static void buildCanonicalFunctionThunkBody(SILGenFunction &SGF,
-                                            SILLocation loc,
-                                            CanSILFunctionType nonCanonicalTy,
-                                            CanSILFunctionType canonicalTy) {
-  SGF.F.setBare(IsBare);
-  SGF.F.setThunk(IsThunk);
-
-  FullExpr scope(SGF.Cleanups, CleanupLocation::get(loc));
-  FormalEvaluationScope formalEvalScope(SGF);
-
-  // Collect the thunk params, creating arguments for each parameter.
-  SmallVector<ManagedValue, 8> origParams;
-  SGF.collectThunkParams(loc, origParams);
-
-  // Then translate our parameters into new params.
-  SmallVector<ManagedValue, 8> newParams;
-  translateParametersForCanonicalFunctionThunk(
-      SGF, loc,
-      // We drop the front so we don't process the thunked function here. We
-      // handle that later.
-      llvm::makeArrayRef(origParams).drop_back(1),
-      nonCanonicalTy->getParameters(), newParams);
-
-  // Then grab the function we are going to call from the last parameter.
-  ManagedValue fn = origParams.back();
-
-  // Collect the arguments.
-  SmallVector<SILValue, 8> args;
-
-  // Add all of the indirect results. We can just add the SILValues directly to
-  // the args array since we do not need to perform any transformations upon
-  // them because:
-  //
-  // 1. Reabstraction can not occur as a result of a canonical/non-canonical
-  // mismatch.
-  // 2. SILGenFunction::collectThunkParams(...) does not create cleanups when it
-  // creates arguments.
-  SILFunctionConventions fnConv(canonicalTy, SGF.SGM.M);
-  transform(range(fnConv.getNumIndirectSILResults()), std::back_inserter(args),
-            [&](unsigned Index) -> SILValue {
-              return SGF.F.begin()->getArgument(Index);
-            });
-
-  // and then the rest of the arguments besides the first argument. Here we have
-  // to forward the arguments since collectThunkParams /does/ create cleanups
-  // for the parameters.
-  forwardFunctionArguments(SGF, loc, nonCanonicalTy, newParams, args);
-
-  // Perform the call.
-  SILValue result =
-      SGF.emitApplyWithRethrow(loc, fn.forward(SGF), fn.getType(), {}, args);
-
-  formalEvalScope.pop();
-  scope.pop();
-  SGF.B.createReturn(loc, result);
-}
-
-ManagedValue
-SILGenFunction::emitCanonicalFunctionThunk(SILLocation loc, ManagedValue fn,
-                                           CanSILFunctionType nonCanonicalTy,
-                                           CanSILFunctionType canonicalTy) {
-  canonicalTy = canonicalTy->getWithRepresentation(
-      SILFunctionType::Representation::Thick);
-
-  SubstitutionMap contextSubs, interfaceSubs;
-  GenericEnvironment *genericEnv = nullptr;
-
-  // These two are not used here -- but really, bridging thunks
-  // should be emitted using the formal AST type, not the lowered
-  // type
-  CanType inputSubstType;
-  CanType outputSubstType;
-  CanType dynamicSelfType;
-  auto thunkTy = buildThunkType(nonCanonicalTy, canonicalTy, inputSubstType,
-                                outputSubstType, genericEnv, interfaceSubs,
-                                dynamicSelfType);
-  assert(!dynamicSelfType && "not implemented");
-  auto thunk = SGM.getOrCreateReabstractionThunk(thunkTy, nonCanonicalTy,
-                                                 canonicalTy, F.isSerialized());
-  if (thunk->empty()) {
-    thunk->setGenericEnvironment(genericEnv);
-    SILGenFunction thunkSGF(SGM, *thunk, FunctionDC);
-    auto loc = RegularLocation::getAutoGeneratedLocation();
-    buildCanonicalFunctionThunkBody(thunkSGF, loc, nonCanonicalTy, canonicalTy);
-  }
-
-  CanSILFunctionType substFnTy = thunkTy;
-
-  if (thunkTy->getGenericSignature()) {
-    substFnTy = thunkTy->substGenericArgs(F.getModule(), interfaceSubs);
-  }
-
-  // Create it in the current function.
-  auto thunkValue = B.createFunctionRefFor(loc, thunk);
-  ManagedValue thunkedFn = B.createPartialApply(
-      loc, thunkValue, SILType::getPrimitiveObjectType(substFnTy),
-      interfaceSubs, {fn},
-      SILType::getPrimitiveObjectType(canonicalTy));
-  if (canonicalTy->isNoEscape()) {
-    auto &funcTL = getTypeLowering(canonicalTy);
-    thunkedFn =
-        B.createConvertFunction(loc, thunkedFn, funcTL.getLoweredType());
-  }
-  return thunkedFn;
-}
diff --git a/lib/SILGen/SILGenThunk.cpp b/lib/SILGen/SILGenThunk.cpp
index baaa856..a008b2d 100644
--- a/lib/SILGen/SILGenThunk.cpp
+++ b/lib/SILGen/SILGenThunk.cpp
@@ -86,38 +86,41 @@
   return ManagedValue::forUnmanaged(B.createFunctionRefFor(loc, F));
 }
 
-static ManagedValue getNextUncurryLevelRef(SILGenFunction &SGF, SILLocation loc,
-                                           SILDeclRef thunk,
-                                           ManagedValue selfArg,
-                                           SubstitutionMap curriedSubs) {
+static std::pair<ManagedValue, SILDeclRef>
+getNextUncurryLevelRef(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk,
+                       ManagedValue selfArg, SubstitutionMap curriedSubs) {
   auto *vd = thunk.getDecl();
 
   // Reference the next uncurrying level of the function.
   SILDeclRef next = SILDeclRef(vd, thunk.kind);
   assert(!next.isCurried);
 
+  auto constantInfo = SGF.SGM.Types.getConstantInfo(next);
+
   // If the function is natively foreign, reference its foreign entry point.
   if (requiresForeignToNativeThunk(vd))
-    return ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next));
+    return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)),
+            next};
 
   // If the thunk is a curry thunk for a direct method reference, we are
   // doing a direct dispatch (eg, a fragile 'super.foo()' call).
   if (thunk.isDirectReference)
-    return ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next));
-
-  auto constantInfo = SGF.SGM.Types.getConstantInfo(next);
+    return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)),
+            next};
 
   if (auto *func = dyn_cast<AbstractFunctionDecl>(vd)) {
     if (getMethodDispatch(func) == MethodDispatch::Class) {
       // Use the dynamic thunk if dynamic.
       if (vd->isObjCDynamic()) {
-        return SGF.emitDynamicMethodRef(loc, next, constantInfo.SILFnType);
+        return {SGF.emitDynamicMethodRef(loc, next, constantInfo.SILFnType),
+                next};
       }
 
       auto methodTy = SGF.SGM.Types.getConstantOverrideType(next);
       SILValue result =
           SGF.emitClassMethodRef(loc, selfArg.getValue(), next, methodTy);
-      return ManagedValue::forUnmanaged(result);
+      return {ManagedValue::forUnmanaged(result),
+              next.getOverriddenVTableEntry()};
     }
 
     // If the fully-uncurried reference is to a generic method, look up the
@@ -130,12 +133,13 @@
       auto conformance = curriedSubs.lookupConformance(origSelfType, protocol);
       auto result = SGF.B.createWitnessMethod(loc, substSelfType, *conformance,
                                               next, constantInfo.getSILType());
-      return ManagedValue::forUnmanaged(result);
+      return {ManagedValue::forUnmanaged(result), next};
     }
   }
 
   // Otherwise, emit a direct call.
-  return ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next));
+  return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)),
+          next};
 }
 
 void SILGenFunction::emitCurryThunk(SILDeclRef thunk) {
@@ -152,7 +156,8 @@
   SILLocation loc(vd);
   Scope S(*this, vd);
 
-  auto thunkFnTy = SGM.Types.getConstantInfo(thunk).SILFnType;
+  auto thunkInfo = SGM.Types.getConstantInfo(thunk);
+  auto thunkFnTy = thunkInfo.SILFnType;
   SILFunctionConventions fromConv(thunkFnTy, SGM.M);
 
   auto selfTy = fromConv.getSILType(thunkFnTy->getSelfParameter());
@@ -162,11 +167,10 @@
   // Forward substitutions.
   auto subs = F.getForwardingSubstitutionMap();
 
-  ManagedValue toFn = getNextUncurryLevelRef(*this, loc, thunk, selfArg, subs);
+  auto toFnAndRef = getNextUncurryLevelRef(*this, loc, thunk, selfArg, subs);
+  ManagedValue toFn = toFnAndRef.first;
+  SILDeclRef calleeRef = toFnAndRef.second;
 
-  // FIXME: Using the type from the ConstantInfo instead of looking at
-  // getConstantOverrideInfo() for methods looks suspect in the presence
-  // of covariant overrides and multiple vtable entries.
   SILType resultTy = fromConv.getSingleSILResultType();
   resultTy = F.mapTypeIntoContext(resultTy);
   auto substTy = toFn.getType().substGenericArgs(SGM.M, subs);
@@ -184,8 +188,27 @@
     if (resultFnTy->isABICompatibleWith(closureFnTy).isCompatible()) {
       toClosure = B.createConvertFunction(loc, toClosure, resultTy);
     } else {
+      // Compute the partially-applied abstraction pattern for the callee:
+      // just grab the pattern for the curried fn ref and "call" it.
+      assert(!calleeRef.isCurried);
+      calleeRef.isCurried = true;
+      auto appliedFnPattern = SGM.Types.getConstantInfo(calleeRef).FormalPattern
+                                       .getFunctionResultType();
+
+      auto appliedThunkPattern =
+        thunkInfo.FormalPattern.getFunctionResultType();
+
+      // The formal type should be the same for the callee and the thunk.
+      auto formalType = thunkInfo.FormalType;
+      if (auto genericSubstType = dyn_cast<GenericFunctionType>(formalType)) {
+        formalType = genericSubstType.substGenericArgs(subs);
+      }
+      formalType = cast<AnyFunctionType>(formalType.getResult());
+
       toClosure =
-          emitCanonicalFunctionThunk(loc, toClosure, closureFnTy, resultFnTy);
+        emitTransformedValue(loc, toClosure,
+                             appliedFnPattern, formalType,
+                             appliedThunkPattern, formalType);
     }
   }
   toClosure = S.popPreservingValue(toClosure);
diff --git a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
index 66e43ec..2407511 100644
--- a/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AccessSummaryAnalysis.cpp
@@ -32,7 +32,7 @@
     FunctionSummary &functionSummary = info->getSummary();
     ArgumentSummary &argSummary =
         functionSummary.getAccessForArgument(index);
-    index++;
+    ++index;
 
     auto *functionArg = cast<SILFunctionArgument>(arg);
     // Only summarize @inout_aliasable arguments.
@@ -137,6 +137,9 @@
   case SILInstructionKind::ApplyInst:
   case SILInstructionKind::TryApplyInst:
     return true;
+  // partial_apply [stack] is terminated by a dealloc_stack.
+  case SILInstructionKind::DeallocStackInst:
+    return true;
 
   case SILInstructionKind::ConvertFunctionInst:
     return llvm::all_of(cast<ConvertFunctionInst>(user)->getUses(),
@@ -423,7 +426,7 @@
       os << ", ";
     }
     os << subAccess.getDescription(BaseType, M);
-    index++;
+    ++index;
   }
   os << "]";
 
@@ -594,7 +597,7 @@
 
   const IndexTrieNode *iter = subPath;
   while (iter) {
-    length++;
+    ++length;
     iter = iter->getParent();
   }
 
@@ -628,7 +631,7 @@
   unsigned argCount = getArgumentCount();
   os << "(";
 
-  for (unsigned i = 0; i < argCount; i++) {
+  for (unsigned i = 0; i < argCount; ++i) {
     if (i > 0) {
       os << ",  ";
     }
diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp
index 2e62fe1..7e681f2 100644
--- a/lib/SILOptimizer/IPO/CapturePromotion.cpp
+++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp
@@ -1034,6 +1034,17 @@
     return isPartialApplyNonEscapingUser(Op, PAI, State);
   }
 
+  // A mark_dependence user on a partial_apply is safe.
+  if (auto *MD = dyn_cast<MarkDependenceInst>(User)) {
+    if (MD->getBase() == Op->get()) {
+      auto parent = MD->getValue();
+      while ((MD = dyn_cast<MarkDependenceInst>(parent))) {
+        parent = MD->getValue();
+      }
+      return isa<PartialApplyInst>(parent);
+    }
+  }
+
   if (auto *PBI = dyn_cast<ProjectBoxInst>(User)) {
     // It is assumed in later code that we will only have 1 project_box. This
     // can be seen since there is no code for reasoning about multiple
@@ -1198,6 +1209,26 @@
   return B.createProjectBox(Box->getLoc(), Box, 0);
 }
 
+/// Change the base in mark_dependence.
+static void
+mapMarkDependenceArguments(SingleValueInstruction *root,
+                           llvm::DenseMap<SILValue, SILValue> &map) {
+  for (auto *Use : root->getUses()) {
+    if (auto *MD = dyn_cast<MarkDependenceInst>(Use->getUser())) {
+      mapMarkDependenceArguments(MD, map);
+      auto iter = map.find(MD->getBase());
+      if (iter != map.end()) {
+        MD->setBase(iter->second);
+      }
+      // Remove mark_dependence on trivial values.
+      if (MD->getBase()->getType().isTrivial(MD->getModule())) {
+        MD->replaceAllUsesWith(MD->getValue());
+        MD->eraseFromParent();
+      }
+    }
+  }
+}
+
 /// Given a partial_apply instruction and a set of promotable indices,
 /// clone the closure with the promoted captures and replace the partial_apply
 /// with a partial_apply of the new closure, fixing up reference counting as
@@ -1236,6 +1267,8 @@
   unsigned OpCount = PAI->getNumOperands() - PAI->getNumTypeDependentOperands();
   SmallVector<SILValue, 16> Args;
   auto NumIndirectResults = calleeConv.getNumIndirectSILResults();
+  llvm::DenseMap<SILValue, SILValue> capturedMap;
+  llvm::SmallSet<SILValue, 16> newCaptures;
   for (; OpNo != OpCount; ++OpNo) {
     unsigned Index = OpNo - 1 + FirstIndex;
     if (!PromotableIndices.count(Index)) {
@@ -1250,8 +1283,18 @@
     SILValue Addr = getOrCreateProjectBoxHelper(Box);
 
     auto &typeLowering = M.getTypeLowering(Addr->getType());
-    Args.push_back(
-        typeLowering.emitLoadOfCopy(B, PAI->getLoc(), Addr, IsNotTake));
+    auto newCaptured =
+        typeLowering.emitLoadOfCopy(B, PAI->getLoc(), Addr, IsNotTake);
+    Args.push_back(newCaptured);
+
+    capturedMap[Box] = newCaptured;
+    newCaptures.insert(newCaptured);
+
+    // A partial_apply [stack] does not own the captured argument but we must
+    // destroy the projected object. We will do so after having created the new
+    // partial_apply below.
+    if (PAI->isOnStack())
+      continue;
 
     // Cleanup the captured argument.
     //
@@ -1268,7 +1311,8 @@
   // Create a new partial apply with the new arguments.
   auto *NewPAI = B.createPartialApply(
       PAI->getLoc(), FnVal, PAI->getSubstitutionMap(), Args,
-      PAI->getType().getAs<SILFunctionType>()->getCalleeConvention());
+      PAI->getType().getAs<SILFunctionType>()->getCalleeConvention(),
+      PAI->isOnStack());
   PAI->replaceAllUsesWith(NewPAI);
   PAI->eraseFromParent();
   if (FRI->use_empty()) {
@@ -1276,6 +1320,21 @@
     // TODO: If this is the last use of the closure, and if it has internal
     // linkage, we should remove it from the SILModule now.
   }
+
+  if (NewPAI->isOnStack()) {
+    // Insert destroy's of new captured arguments.
+    for (auto *Use : NewPAI->getUses()) {
+      if (auto *DS = dyn_cast<DeallocStackInst>(Use->getUser())) {
+        B.setInsertionPoint(std::next(SILBasicBlock::iterator(DS)));
+        insertDestroyOfCapturedArguments(NewPAI, B, [&](SILValue arg) -> bool {
+          return newCaptures.count(arg);
+        });
+      }
+    }
+    // Map the mark dependence arguments.
+    mapMarkDependenceArguments(NewPAI, capturedMap);
+  }
+
   return ClonedFn;
 }
 
diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp
index 6c1cdd6..0dc09f8 100644
--- a/lib/SILOptimizer/IPO/CapturePropagation.cpp
+++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp
@@ -296,6 +296,11 @@
   auto *T2TF = Builder.createThinToThickFunction(OrigPAI->getLoc(), FuncRef,
                                                  OrigPAI->getType());
   OrigPAI->replaceAllUsesWith(T2TF);
+  // Remove any dealloc_stack users.
+  SmallVector<Operand*, 16> Uses(T2TF->getUses());
+  for (auto *Use : Uses)
+    if (auto *DS = dyn_cast<DeallocStackInst>(Use->getUser()))
+      DS->eraseFromParent();
   recursivelyDeleteTriviallyDeadInstructions(OrigPAI, true);
   LLVM_DEBUG(llvm::dbgs() << "  Rewrote caller:\n" << *T2TF);
 }
diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
index 678b263..e25a59c 100644
--- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
+++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp
@@ -72,7 +72,9 @@
 #include "swift/SILOptimizer/Utils/SILInliner.h"
 #include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
 #include "swift/SILOptimizer/Utils/SpecializationMangler.h"
+#include "swift/SILOptimizer/Utils/StackNesting.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
@@ -130,7 +132,8 @@
   SILValue
   cloneCalleeConversion(SILValue calleeValue, SILValue NewClosure,
                         SILBuilder &Builder,
-                        SmallVectorImpl<PartialApplyInst *> &NeedsRelease);
+                        SmallVectorImpl<PartialApplyInst *> &NeedsRelease,
+                        llvm::DenseMap<SILValue, SILValue> &CapturedMap);
 
   SILFunction *getCloned() { return &getBuilder().getFunction(); }
   static SILFunction *cloneFunction(SILOptFunctionBuilder &FunctionBuilder,
@@ -192,7 +195,18 @@
   }
 
   bool closureHasRefSemanticContext() const {
-    return isa<PartialApplyInst>(getClosure());
+    return isa<PartialApplyInst>(getClosure()) &&
+           !cast<PartialApplyInst>(getClosure())->isOnStack();
+  }
+
+  bool destroyIfPartialApplyStack(SILBuilder &B,
+                                  SingleValueInstruction *newClosure) const {
+    auto *PA = dyn_cast<PartialApplyInst>(newClosure);
+    if (!PA || !PA->isOnStack())
+      return false;
+    insertDestroyOfCapturedArguments(PA, B);
+    B.createDeallocStack(getClosure()->getLoc(), PA);
+    return true;
   }
 
   unsigned getClosureIndex() const { return ClosureIndex; }
@@ -207,12 +221,13 @@
   SingleValueInstruction *
   createNewClosure(SILBuilder &B, SILValue V,
                    llvm::SmallVectorImpl<SILValue> &Args) const {
-    if (isa<PartialApplyInst>(getClosure()))
+    if (auto *PA = dyn_cast<PartialApplyInst>(getClosure()))
       return B.createPartialApply(getClosure()->getLoc(), V, {}, Args,
                                   getClosure()
                                       ->getType()
                                       .getAs<SILFunctionType>()
-                                      ->getCalleeConvention());
+                                      ->getCalleeConvention(),
+                                  PA->isOnStack());
 
     assert(isa<ThinToThickFunctionInst>(getClosure()) &&
            "We only support partial_apply and thin_to_thick_function");
@@ -256,6 +271,13 @@
     return getClosureParameterInfo().isConsumed();
   }
 
+  bool isClosureOnStack() const {
+    auto *PA = dyn_cast<PartialApplyInst>(getClosure());
+    if (!PA)
+      return false;
+    return PA->isOnStack();
+  }
+
   bool isTrivialNoEscapeParameter() const {
     auto ClosureParmFnTy =
         getClosureParameterInfo().getType()->getAs<SILFunctionType>();
@@ -675,16 +697,29 @@
 // Clone a chain of ConvertFunctionInsts.
 SILValue ClosureSpecCloner::cloneCalleeConversion(
     SILValue calleeValue, SILValue NewClosure, SILBuilder &Builder,
-    SmallVectorImpl<PartialApplyInst *> &NeedsRelease) {
+    SmallVectorImpl<PartialApplyInst *> &NeedsRelease,
+    llvm::DenseMap<SILValue, SILValue> &CapturedMap) {
+
+  // There might be a mark dependence on a previous closure value. Therefore, we
+  // add all closure values to the map.
+  auto addToOldToNewClosureMap = [&](SILValue origValue,
+                                     SILValue newValue) -> SILValue {
+    assert(!CapturedMap.count(origValue));
+    CapturedMap[origValue] = newValue;
+    return newValue;
+  };
+
   if (calleeValue == CallSiteDesc.getClosure())
-    return NewClosure;
+    return addToOldToNewClosureMap(calleeValue, NewClosure);
 
   if (auto *CFI = dyn_cast<ConvertFunctionInst>(calleeValue)) {
+    SILValue origCalleeValue = calleeValue;
     calleeValue = cloneCalleeConversion(CFI->getOperand(), NewClosure, Builder,
-                                        NeedsRelease);
-    return Builder.createConvertFunction(CallSiteDesc.getLoc(), calleeValue,
-                                         CFI->getType(),
-                                         CFI->withoutActuallyEscaping());
+                                        NeedsRelease, CapturedMap);
+    return addToOldToNewClosureMap(
+        origCalleeValue, Builder.createConvertFunction(
+                             CallSiteDesc.getLoc(), calleeValue, CFI->getType(),
+                             CFI->withoutActuallyEscaping()));
   }
 
   if (auto *PAI = dyn_cast<PartialApplyInst>(calleeValue)) {
@@ -693,27 +728,52 @@
                ->getType()
                .getAs<SILFunctionType>()
                ->isTrivialNoEscape());
+    SILValue origCalleeValue = calleeValue;
     calleeValue = cloneCalleeConversion(PAI->getArgument(0), NewClosure,
-                                        Builder, NeedsRelease);
+                                        Builder, NeedsRelease, CapturedMap);
     auto FunRef = Builder.createFunctionRef(CallSiteDesc.getLoc(),
                                             PAI->getReferencedFunction());
     auto NewPA = Builder.createPartialApply(
         CallSiteDesc.getLoc(), FunRef, {}, {calleeValue},
-        PAI->getType().getAs<SILFunctionType>()->getCalleeConvention());
+        PAI->getType().getAs<SILFunctionType>()->getCalleeConvention(),
+        PAI->isOnStack());
+    // If the partial_apply is on stack we will emit a dealloc_stack in the
+    // epilog.
     NeedsRelease.push_back(NewPA);
-    return NewPA;
+    return addToOldToNewClosureMap(origCalleeValue, NewPA);
   }
 
+  if (auto *MD = dyn_cast<MarkDependenceInst>(calleeValue)) {
+    SILValue origCalleeValue = calleeValue;
+    calleeValue = cloneCalleeConversion(MD->getValue(), NewClosure, Builder,
+                                        NeedsRelease, CapturedMap);
+    if (!CapturedMap.count(MD->getBase())) {
+      CallSiteDesc.getClosure()->dump();
+      MD->dump();
+      MD->getFunction()->dump();
+    }
+    assert(CapturedMap.count(MD->getBase()));
+    return addToOldToNewClosureMap(
+        origCalleeValue,
+        Builder.createMarkDependence(CallSiteDesc.getLoc(), calleeValue,
+                                     CapturedMap[MD->getBase()]));
+  }
+
+
   auto *Cvt = cast<ConvertEscapeToNoEscapeInst>(calleeValue);
+  SILValue origCalleeValue = calleeValue;
   calleeValue = cloneCalleeConversion(Cvt->getOperand(), NewClosure, Builder,
-                                      NeedsRelease);
-  return Builder.createConvertEscapeToNoEscape(
-      CallSiteDesc.getLoc(), calleeValue, Cvt->getType(), true);
+                                      NeedsRelease, CapturedMap);
+  return addToOldToNewClosureMap(
+      origCalleeValue,
+      Builder.createConvertEscapeToNoEscape(CallSiteDesc.getLoc(), calleeValue,
+                                            Cvt->getType(), true));
 }
 
 /// Populate the body of the cloned closure, modifying instructions as
-/// necessary. This is where we create the actual specialized BB Arguments.
+/// necessary. This is where we create the actual specialized BB Arguments
 void ClosureSpecCloner::populateCloned() {
+  bool needToUpdateStackNesting = false;
   SILFunction *Cloned = getCloned();
   SILFunction *ClosureUser = CallSiteDesc.getApplyCallee();
 
@@ -752,10 +812,15 @@
   unsigned NumTotalParams = ClosedOverFunConv.getNumParameters();
   unsigned NumNotCaptured = NumTotalParams - CallSiteDesc.getNumArguments();
   llvm::SmallVector<SILValue, 4> NewPAIArgs;
+  llvm::DenseMap<SILValue, SILValue> CapturedMap;
+  unsigned idx = 0;
   for (auto &PInfo : ClosedOverFunConv.getParameters().slice(NumNotCaptured)) {
     auto paramTy = ClosedOverFunConv.getSILType(PInfo);
     SILValue MappedValue = ClonedEntryBB->createFunctionArgument(paramTy);
     NewPAIArgs.push_back(MappedValue);
+    auto CapturedVal =
+        cast<PartialApplyInst>(CallSiteDesc.getClosure())->getArgument(idx++);
+    CapturedMap[CapturedVal] = MappedValue;
   }
 
   SILBuilder &Builder = getBuilder();
@@ -770,8 +835,9 @@
   // Clone a chain of ConvertFunctionInsts. This can create further
   // reabstraction partial_apply instructions.
   SmallVector<PartialApplyInst*, 4> NeedsRelease;
-  SILValue ConvertedCallee = cloneCalleeConversion(
-      CallSiteDesc.getClosureCallerArg(), NewClosure, Builder, NeedsRelease);
+  SILValue ConvertedCallee =
+      cloneCalleeConversion(CallSiteDesc.getClosureCallerArg(), NewClosure,
+                            Builder, NeedsRelease, CapturedMap);
 
   // Make sure that we actually emit the releases for reabstraction thunks. We
   // have guaranteed earlier that we only allow reabstraction thunks if the
@@ -790,7 +856,8 @@
   bool ClosureHasRefSemantics = CallSiteDesc.closureHasRefSemanticContext();
   if ((CallSiteDesc.isClosureGuaranteed() ||
        CallSiteDesc.isTrivialNoEscapeParameter()) &&
-      (ClosureHasRefSemantics || !NeedsRelease.empty())) {
+      (ClosureHasRefSemantics || !NeedsRelease.empty() ||
+       CallSiteDesc.isClosureOnStack())) {
     for (SILBasicBlock *BB : CallSiteDesc.getNonFailureExitBBs()) {
       SILBasicBlock *OpBB = getOpBasicBlock(BB);
 
@@ -804,9 +871,17 @@
         if (ClosureHasRefSemantics)
           Builder.createReleaseValue(Loc, SILValue(NewClosure),
                                      Builder.getDefaultAtomicity());
-        for (auto PAI : NeedsRelease)
-          Builder.createReleaseValue(Loc, SILValue(PAI),
-                                     Builder.getDefaultAtomicity());
+        else
+          needToUpdateStackNesting |=
+              CallSiteDesc.destroyIfPartialApplyStack(Builder, NewClosure);
+        for (auto PAI : NeedsRelease) {
+          if (PAI->isOnStack())
+            needToUpdateStackNesting |=
+                CallSiteDesc.destroyIfPartialApplyStack(Builder, PAI);
+          else
+            Builder.createReleaseValue(Loc, SILValue(PAI),
+                                       Builder.getDefaultAtomicity());
+        }
         continue;
       }
 
@@ -825,11 +900,22 @@
       if (ClosureHasRefSemantics)
         Builder.createReleaseValue(Loc, SILValue(NewClosure),
                                    Builder.getDefaultAtomicity());
-      for (auto PAI : NeedsRelease)
-        Builder.createReleaseValue(Loc, SILValue(PAI),
-                                   Builder.getDefaultAtomicity());
+      else
+        needToUpdateStackNesting |=
+            CallSiteDesc.destroyIfPartialApplyStack(Builder, NewClosure);
+      for (auto PAI : NeedsRelease) {
+        if (PAI->isOnStack())
+          needToUpdateStackNesting |=
+              CallSiteDesc.destroyIfPartialApplyStack(Builder, PAI);
+        else
+          Builder.createReleaseValue(Loc, SILValue(PAI),
+                                     Builder.getDefaultAtomicity());
+      }
     }
   }
+  if (needToUpdateStackNesting) {
+    StackNesting().correctStackNesting(Cloned);
+  }
 }
 
 //===----------------------------------------------------------------------===//
@@ -913,6 +999,10 @@
     return markReabstractionPartialApplyAsUsed(FirstClosure, Cvt->getOperand(),
                                                UsedReabstractionClosure);
   }
+  if (auto MD = dyn_cast<MarkDependenceInst>(Current)) {
+    return markReabstractionPartialApplyAsUsed(FirstClosure, MD->getValue(),
+                                               UsedReabstractionClosure);
+  }
   llvm_unreachable("Unexpect instruction");
 }
 
@@ -994,6 +1084,14 @@
       // Live range end points.
       SmallVector<SILInstruction *, 8> UsePoints;
 
+      // Set of possible arguments for mark_dependence. The base of a
+      // mark_dependence we copy must be available in the specialized function.
+      llvm::SmallSet<SILValue, 16> PossibleMarkDependenceBases;
+      if (auto *PA = dyn_cast<PartialApplyInst>(ClosureInst)) {
+        for (auto Opd : PA->getArguments())
+          PossibleMarkDependenceBases.insert(Opd);
+      }
+
       bool HaveUsedReabstraction = false;
       // Uses may grow in this loop.
       for (size_t UseIndex = 0; UseIndex < Uses.size(); ++UseIndex) {
@@ -1004,10 +1102,12 @@
         if (auto *CFI = dyn_cast<ConvertFunctionInst>(Use->getUser())) {
           // Push Uses in reverse order so they are visited in forward order.
           Uses.append(CFI->getUses().begin(), CFI->getUses().end());
+          PossibleMarkDependenceBases.insert(CFI);
           continue;
         }
         if (auto *Cvt = dyn_cast<ConvertEscapeToNoEscapeInst>(Use->getUser())) {
           Uses.append(Cvt->getUses().begin(), Cvt->getUses().end());
+          PossibleMarkDependenceBases.insert(Cvt);
           continue;
         }
 
@@ -1025,11 +1125,29 @@
                   .getAs<SILFunctionType>()
                   ->isTrivialNoEscape()) {
             Uses.append(PA->getUses().begin(), PA->getUses().end());
+            PossibleMarkDependenceBases.insert(PA);
             HaveUsedReabstraction = true;
           }
           continue;
         }
 
+        // Look through mark_dependence on partial_apply [stack].
+        if (auto *MD = dyn_cast<MarkDependenceInst>(Use->getUser())) {
+          // We can't copy a closure if the mark_dependence base is not
+          // available in the specialized function.
+          if (!PossibleMarkDependenceBases.count(MD->getBase()))
+            continue;
+          if (MD->getValue() == Use->get() &&
+              MD->getValue()->getType().is<SILFunctionType>() &&
+              MD->getValue()
+                  ->getType()
+                  .castTo<SILFunctionType>()
+                  ->isTrivialNoEscape()) {
+            Uses.append(MD->getUses().begin(), MD->getUses().end());
+            continue;
+          }
+        }
+
         // If this use is not a full apply site that we can process or an apply
         // inst with substitutions, there is nothing interesting for us to do,
         // so continue...
diff --git a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
index efae3ba..9b356e1 100644
--- a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
@@ -508,6 +508,8 @@
     case SILInstructionKind::RetainValueInst:
     case SILInstructionKind::ReleaseValueInst:
     case SILInstructionKind::EndBorrowInst:
+    // partial_apply [stack] is matched with dealloc_stack.
+    case SILInstructionKind::DeallocStackInst:
       // Benign use.
       return;
     case SILInstructionKind::TupleExtractInst:
diff --git a/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
index f00f8ec..be49685 100644
--- a/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
+++ b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp
@@ -21,6 +21,7 @@
 #include "swift/SILOptimizer/PassManager/Transforms.h"
 #include "swift/SILOptimizer/Utils/CFG.h"
 #include "swift/SILOptimizer/Utils/Local.h"
+#include "swift/SILOptimizer/Utils/StackNesting.h"
 
 #include "llvm/Support/CommandLine.h"
 
@@ -186,9 +187,148 @@
                                  SingleNonDebugNonRefCountUser, Memoized));
 }
 
+/// Insert a mark_dependence for any non-trivial argument of a partial_apply.
+static SILValue insertMarkDependenceForCapturedArguments(PartialApplyInst *PAI,
+                                                         SILBuilder &B) {
+  SILValue curr(PAI);
+  // Mark dependence on all non-trivial arguments.
+  for (auto &arg : PAI->getArgumentOperands()) {
+    if (arg.get()->getType().isTrivial(PAI->getModule()))
+      continue;
+    curr = B.createMarkDependence(PAI->getLoc(), curr, arg.get());
+  }
+
+  return curr;
+}
+
+/// Rewrite a partial_apply convert_escape_to_noescape sequence with a single
+/// apply/try_apply user to a partial_apply [stack] terminated with a
+/// dealloc_stack placed after the apply.
+///
+///   %p = partial_apply %f(%a, %b)
+///   %ne = convert_escape_to_noescape %p
+///   apply %f2(%p)
+///   destroy_value %p
+///
+///    =>
+///
+///   %p = partial_apply [stack] %f(%a, %b)
+///   %md = mark_dependence %p on %a
+///   %md2 = mark_dependence %md on %b
+///   apply %f2(%md2)
+///   dealloc_stack %p
+///   destroy_value %a
+///   destroy_value %b
+///
+/// Note: If the rewrite succeeded we have inserted a dealloc_stack. This
+/// dealloc_stack still needs to be balanced with other dealloc_stacks i.e the
+/// caller needs to use the StackNesting utility to update the dealloc_stack
+/// nesting.
+static bool tryRewriteToPartialApplyStack(
+    SILLocation &loc, PartialApplyInst *origPA,
+    ConvertEscapeToNoEscapeInst *cvt, SILInstruction *singleApplyUser,
+    SILBasicBlock::iterator &advanceIfDelete,
+    llvm::DenseMap<SILInstruction *, SILInstruction *> &Memoized) {
+
+  auto *convertOrPartialApply = cast<SingleValueInstruction>(origPA);
+  if (cvt->getOperand() != origPA)
+    convertOrPartialApply = cast<ConvertFunctionInst>(cvt->getOperand());
+
+  // Whenever we delete an instruction advance the iterator and remove the
+  // instruction from the memoized map.
+  auto saveDeleteInst = [&](SILInstruction *I) {
+    if (&*advanceIfDelete == I)
+      advanceIfDelete++;
+    Memoized.erase(I);
+    I->eraseFromParent();
+  };
+
+  // Look for a single non ref count user of the partial_apply.
+  SmallVector<SILInstruction *, 8> refCountInsts;
+  SILInstruction *singleNonDebugNonRefCountUser = nullptr;
+  for (auto *Usr : getNonDebugUses(convertOrPartialApply)) {
+    auto *I = Usr->getUser();
+    if (onlyAffectsRefCount(I)) {
+      refCountInsts.push_back(I);
+      continue;
+    }
+    if (singleNonDebugNonRefCountUser)
+      return false;
+    singleNonDebugNonRefCountUser = I;
+  }
+
+  SILBuilderWithScope B(cvt);
+
+  // The convert_escape_to_noescape is the only user of the partial_apply.
+  // Convert to a partial_apply [stack].
+  SmallVector<SILValue, 8> args;
+  for (auto &arg : origPA->getArgumentOperands())
+    args.push_back(arg.get());
+  auto newPA = B.createPartialApply(
+      origPA->getLoc(), origPA->getCallee(), origPA->getSubstitutionMap(), args,
+      origPA->getType().getAs<SILFunctionType>()->getCalleeConvention(),
+      PartialApplyInst::OnStackKind::OnStack);
+
+  // Insert mark_dependence for any non-trivial operand to the partial_apply.
+  auto closure = insertMarkDependenceForCapturedArguments(newPA, B);
+
+  // Optionally, replace the convert_function instruction.
+  if (auto *convert = dyn_cast<ConvertFunctionInst>(convertOrPartialApply)) {
+    auto origTy = convert->getType().castTo<SILFunctionType>();
+    auto origWithNoEscape = SILType::getPrimitiveObjectType(
+        origTy->getWithExtInfo(origTy->getExtInfo().withNoEscape()));
+    closure = B.createConvertFunction(convert->getLoc(), closure, origWithNoEscape, false);
+    convert->replaceAllUsesWith(closure);
+  }
+
+  // Replace the convert_escape_to_noescape uses with the new
+  // partial_apply [stack].
+  cvt->replaceAllUsesWith(closure);
+  saveDeleteInst(cvt);
+
+  // Delete the ref count operations on the original partial_apply.
+  for (auto *refInst : refCountInsts)
+    saveDeleteInst(refInst);
+  convertOrPartialApply->replaceAllUsesWith(newPA);
+  if (convertOrPartialApply != origPA)
+    saveDeleteInst(convertOrPartialApply);
+  saveDeleteInst(origPA);
+
+  // Insert destroys of arguments after the apply and the dealloc_stack.
+  if (auto *Apply = dyn_cast<ApplyInst>(singleApplyUser)) {
+    auto InsertPt = std::next(SILBasicBlock::iterator(Apply));
+    // Don't insert dealloc_stacks at unreachable.
+    if (isa<UnreachableInst>(*InsertPt))
+      return true;
+    SILBuilderWithScope B3(InsertPt);
+    B3.createDeallocStack(loc, newPA);
+    insertDestroyOfCapturedArguments(newPA, B3);
+  } else if (auto *Try = dyn_cast<TryApplyInst>(singleApplyUser)) {
+    for (auto *SuccBB : Try->getSuccessorBlocks()) {
+      SILBuilderWithScope B3(SuccBB->begin());
+      B3.createDeallocStack(loc, newPA);
+      insertDestroyOfCapturedArguments(newPA, B3);
+    }
+  } else {
+    llvm_unreachable("Unknown FullApplySite instruction kind");
+  }
+  return true;
+}
+
+static SILValue skipConvert(SILValue v) {
+  auto cvt = dyn_cast<ConvertFunctionInst>(v);
+  if (!cvt)
+    return v;
+  auto *pa = dyn_cast<PartialApplyInst>(cvt->getOperand());
+  if (!pa || !pa->hasOneUse())
+    return v;
+  return pa;
+}
+
 static bool tryExtendLifetimeToLastUse(
     ConvertEscapeToNoEscapeInst *Cvt,
-    llvm::DenseMap<SILInstruction *, SILInstruction *> &Memoized) {
+    llvm::DenseMap<SILInstruction *, SILInstruction *> &Memoized,
+    SILBasicBlock::iterator &AdvanceIfDelete) {
   // If there is a single user that is an apply this is simple: extend the
   // lifetime of the operand until after the apply.
   auto SingleUser = lookThroughRebastractionUsers(Cvt, Memoized);
@@ -203,6 +343,12 @@
     }
 
     auto loc = RegularLocation::getAutoGeneratedLocation();
+    auto origPA = dyn_cast<PartialApplyInst>(skipConvert(Cvt->getOperand()));
+    if (origPA && tryRewriteToPartialApplyStack(
+                      loc, origPA, Cvt, SingleApplyUser.getInstruction(),
+                      AdvanceIfDelete,
+                      Memoized))
+      return true;
 
     // Insert a copy at the convert_escape_to_noescape [not_guaranteed] and
     // change the instruction to the guaranteed form.
@@ -473,7 +619,7 @@
   return true;
 }
 
-static bool fixupClosureLifetimes(SILFunction &Fn) {
+static bool fixupClosureLifetimes(SILFunction &Fn, bool &checkStackNesting) {
   bool Changed = false;
 
   // tryExtendLifetimeToLastUse uses a cache of recursive instruction use
@@ -505,8 +651,9 @@
         continue;
       }
 
-      if (tryExtendLifetimeToLastUse(Cvt, MemoizedQueries)) {
+      if (tryExtendLifetimeToLastUse(Cvt, MemoizedQueries, I)) {
         Changed |= true;
+        checkStackNesting = true;
         continue;
       }
 
@@ -537,8 +684,21 @@
 
     // Fixup convert_escape_to_noescape [not_guaranteed] and
     // copy_block_without_escaping instructions.
-    if (fixupClosureLifetimes(*getFunction()))
-      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
+
+    bool checkStackNesting = false;
+    bool modifiedCFG = false;
+
+    if (fixupClosureLifetimes(*getFunction(), checkStackNesting)) {
+      if (checkStackNesting){
+        StackNesting SN;
+        modifiedCFG =
+            SN.correctStackNesting(getFunction()) == StackNesting::Changes::CFG;
+      }
+      if (modifiedCFG)
+        invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
+      else
+        invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions);
+    }
     LLVM_DEBUG(getFunction()->verify());
 
   }
diff --git a/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp b/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp
index 7ee60ec..e8afc71 100644
--- a/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp
+++ b/lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp
@@ -956,8 +956,10 @@
 static void checkNoEscapePartialApplyUse(Operand *oper, FollowUse followUses) {
   SILInstruction *user = oper->getUser();
 
-  // Ignore uses that are totally uninteresting.
-  if (isIncidentalUse(user) || onlyAffectsRefCount(user))
+  // Ignore uses that are totally uninteresting. partial_apply [stack] is
+  // terminated by a dealloc_stack instruction.
+  if (isIncidentalUse(user) || onlyAffectsRefCount(user) ||
+      isa<DeallocStackInst>(user))
     return;
 
   // Before checking conversions in general below (getSingleValueCopyOrCast),
diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
index 391e493..a8890ab 100644
--- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
+++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp
@@ -373,6 +373,17 @@
       return ThinToNoescapeCast->getOperand();
     }
 
+    // Ignore mark_dependence users. A partial_apply [stack] uses them to mark
+    // the dependence of the trivial closure context value on the captured
+    // arguments.
+    if (auto *MD = dyn_cast<MarkDependenceInst>(CalleeValue)) {
+      while (MD) {
+        CalleeValue = MD->getValue();
+        MD = dyn_cast<MarkDependenceInst>(CalleeValue);
+      }
+      return CalleeValue;
+    }
+
     auto *CFI = dyn_cast<ConvertEscapeToNoEscapeInst>(CalleeValue);
     if (!CFI)
       return CalleeValue;
diff --git a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
index bfed58f..ecf3801 100644
--- a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
+++ b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.cpp
@@ -238,13 +238,6 @@
       continue;
     }
 
-#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...)             \
-  if (isa<Load##Name##Inst>(User)) {                                           \
-    Uses.emplace_back(User, PMOUseKind::Load);                                 \
-    continue;                                                                  \
-  }
-#include "swift/AST/ReferenceStorage.def"
-
     // Stores *to* the allocation are writes.
     if (isa<StoreInst>(User) && UI->getOperandNumber() == 1) {
       if (PointeeType.is<TupleType>()) {
@@ -254,34 +247,15 @@
 
       // Coming out of SILGen, we assume that raw stores are initializations,
       // unless they have trivial type (which we classify as InitOrAssign).
-      PMOUseKind Kind;
-      if (InStructSubElement)
-        Kind = PMOUseKind::PartialStore;
-      else if (PointeeType.isTrivial(User->getModule()))
-        Kind = PMOUseKind::InitOrAssign;
-      else
-        Kind = PMOUseKind::Initialization;
-
+      auto Kind = ([&]() -> PMOUseKind {
+        if (PointeeType.isTrivial(User->getModule()))
+          return PMOUseKind::InitOrAssign;
+        return PMOUseKind::Initialization;
+      })();
       Uses.emplace_back(User, Kind);
       continue;
     }
 
-#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...)             \
-  if (auto *SI = dyn_cast<Store##Name##Inst>(User)) {                          \
-    if (UI->getOperandNumber() == 1) {                                         \
-      PMOUseKind Kind;                                                         \
-      if (InStructSubElement)                                                  \
-        Kind = PMOUseKind::PartialStore;                                       \
-      else if (SI->isInitializationOfDest())                                   \
-        Kind = PMOUseKind::Initialization;                                     \
-      else                                                                     \
-        Kind = PMOUseKind::Assign;                                             \
-      Uses.emplace_back(User, Kind);                                           \
-      continue;                                                                \
-    }                                                                          \
-  }
-#include "swift/AST/ReferenceStorage.def"
-
     if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
       // If this is a copy of a tuple, we should scalarize it so that we don't
       // have an access that crosses elements.
@@ -294,16 +268,17 @@
       // the destination, then this is an unknown assignment.  Note that we'll
       // revisit this instruction and add it to Uses twice if it is both a load
       // and store to the same aggregate.
-      PMOUseKind Kind;
-      if (UI->getOperandNumber() == 0)
-        Kind = PMOUseKind::Load;
-      else if (InStructSubElement)
-        Kind = PMOUseKind::PartialStore;
-      else if (CAI->isInitializationOfDest())
-        Kind = PMOUseKind::Initialization;
-      else
-        Kind = PMOUseKind::Assign;
-
+      //
+      // Inline constructor.
+      auto Kind = ([&]() -> PMOUseKind {
+        if (UI->getOperandNumber() == CopyAddrInst::Src)
+          return PMOUseKind::Load;
+        if (PointeeType.isTrivial(CAI->getModule()))
+          return PMOUseKind::InitOrAssign;
+        if (CAI->isInitializationOfDest())
+          return PMOUseKind::Initialization;
+        return PMOUseKind::Assign;
+      })();
       Uses.emplace_back(User, Kind);
       continue;
     }
diff --git a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h
index 348590d..9ceb4e4 100644
--- a/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h
+++ b/lib/SILOptimizer/Mandatory/PMOMemoryUseCollector.h
@@ -116,9 +116,6 @@
   /// value.
   Assign,
 
-  /// The instruction is a store to a member of a larger struct value.
-  PartialStore,
-
   /// An indirect 'inout' parameter of an Apply instruction.
   InOutUse,
 
diff --git a/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp
index a5f41f6..3a36c73 100644
--- a/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp
+++ b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp
@@ -911,7 +911,7 @@
   assert((LoadUse.isValid() || StoreUse.isValid()) &&
          "we should have a load or a store, possibly both");
   assert(StoreUse.isInvalid() || StoreUse.Kind == Assign ||
-         StoreUse.Kind == PartialStore || StoreUse.Kind == Initialization);
+         StoreUse.Kind == Initialization || StoreUse.Kind == InitOrAssign);
 
   // Now that we've emitted a bunch of instructions, including a load and store
   // but also including other stuff, update the internal state of
@@ -930,6 +930,12 @@
       // something else), track it as an access.
       if (StoreUse.isValid()) {
         StoreUse.Inst = NewInst;
+        // If our store use by the copy_addr is an assign, then we know that
+        // before we store the new value, we loaded the old value implying that
+        // our store is technically initializing memory when it occurs. So
+        // change the kind to Initialization.
+        if (StoreUse.Kind == Assign)
+          StoreUse.Kind = Initialization;
         NonLoadUses[NewInst] = Uses.size();
         Uses.push_back(StoreUse);
       }
@@ -948,11 +954,6 @@
       }
       continue;
 
-#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
-    case SILInstructionKind::Name##RetainInst: \
-    case SILInstructionKind::Name##ReleaseInst: \
-    case SILInstructionKind::StrongRetain##Name##Inst:
-#include "swift/AST/ReferenceStorage.def"
     case SILInstructionKind::RetainValueInst:
     case SILInstructionKind::StrongRetainInst:
     case SILInstructionKind::StrongReleaseInst:
@@ -983,6 +984,18 @@
 //                          Allocation Optimization
 //===----------------------------------------------------------------------===//
 
+static SILType getMemoryType(AllocationInst *memory) {
+  // Compute the type of the memory object.
+  if (auto *abi = dyn_cast<AllocBoxInst>(memory)) {
+    assert(abi->getBoxType()->getLayout()->getFields().size() == 1 &&
+           "optimizing multi-field boxes not implemented");
+    return abi->getBoxType()->getFieldType(abi->getModule(), 0);
+  }
+
+  assert(isa<AllocStackInst>(memory));
+  return cast<AllocStackInst>(memory)->getElementType();
+}
+
 namespace {
 
 /// This performs load promotion and deletes synthesized allocations if all
@@ -1008,44 +1021,27 @@
   AvailableValueDataflowContext DataflowContext;
 
 public:
-  AllocOptimize(AllocationInst *TheMemory, SmallVectorImpl<PMOMemoryUse> &Uses,
-                SmallVectorImpl<SILInstruction *> &Releases);
+  AllocOptimize(AllocationInst *memory, SmallVectorImpl<PMOMemoryUse> &uses,
+                SmallVectorImpl<SILInstruction *> &releases)
+      : Module(memory->getModule()), TheMemory(memory),
+        MemoryType(getMemoryType(memory)),
+        NumMemorySubElements(getNumSubElements(MemoryType, Module)), Uses(uses),
+        Releases(releases),
+        DataflowContext(TheMemory, NumMemorySubElements, uses) {}
 
-  bool doIt();
+  bool optimizeMemoryAccesses();
+  bool tryToRemoveDeadAllocation();
 
 private:
   bool promoteLoad(SILInstruction *Inst);
   void promoteDestroyAddr(DestroyAddrInst *DAI,
                           MutableArrayRef<AvailableValue> Values);
-  bool
-  canPromoteDestroyAddr(DestroyAddrInst *DAI,
-                        llvm::SmallVectorImpl<AvailableValue> &AvailableValues);
-
-  bool tryToRemoveDeadAllocation();
+  bool canPromoteDestroyAddr(DestroyAddrInst *DAI,
+                             SmallVectorImpl<AvailableValue> &AvailableValues);
 };
 
 } // end anonymous namespace
 
-static SILType getMemoryType(AllocationInst *TheMemory) {
-  // Compute the type of the memory object.
-  if (auto *ABI = dyn_cast<AllocBoxInst>(TheMemory)) {
-    assert(ABI->getBoxType()->getLayout()->getFields().size() == 1 &&
-           "optimizing multi-field boxes not implemented");
-    return ABI->getBoxType()->getFieldType(ABI->getModule(), 0);
-  } else {
-    assert(isa<AllocStackInst>(TheMemory));
-    return cast<AllocStackInst>(TheMemory)->getElementType();
-  }
-}
-
-AllocOptimize::AllocOptimize(AllocationInst *InputMemory,
-                             SmallVectorImpl<PMOMemoryUse> &InputUses,
-                             SmallVectorImpl<SILInstruction *> &InputReleases)
-    : Module(InputMemory->getModule()), TheMemory(InputMemory),
-      MemoryType(getMemoryType(TheMemory)),
-      NumMemorySubElements(getNumSubElements(MemoryType, Module)),
-      Uses(InputUses), Releases(InputReleases),
-      DataflowContext(TheMemory, NumMemorySubElements, Uses) {}
 
 /// If we are able to optimize \p Inst, return the source address that
 /// instruction is loading from. If we can not optimize \p Inst, then just
@@ -1149,8 +1145,7 @@
 
 /// Return true if we can promote the given destroy.
 bool AllocOptimize::canPromoteDestroyAddr(
-    DestroyAddrInst *DAI,
-    llvm::SmallVectorImpl<AvailableValue> &AvailableValues) {
+    DestroyAddrInst *DAI, SmallVectorImpl<AvailableValue> &AvailableValues) {
   SILValue Address = DAI->getOperand();
 
   // We cannot promote destroys of address-only types, because we can't expose
@@ -1224,8 +1219,49 @@
   DAI->eraseFromParent();
 }
 
-/// tryToRemoveDeadAllocation - If the allocation is an autogenerated allocation
-/// that is only stored to (after load promotion) then remove it completely.
+namespace {
+
+struct DestroyAddrPromotionState {
+  ArrayRef<SILInstruction *> destroys;
+  SmallVector<unsigned, 8> destroyAddrIndices;
+  SmallVector<AvailableValue, 32> availableValueList;
+  SmallVector<unsigned, 8> availableValueStartOffsets;
+
+  DestroyAddrPromotionState(ArrayRef<SILInstruction *> destroys)
+      : destroys(destroys) {}
+
+  unsigned size() const {
+    return destroyAddrIndices.size();
+  }
+
+  void initializeForDestroyAddr(unsigned destroyAddrIndex) {
+    availableValueStartOffsets.push_back(availableValueList.size());
+    destroyAddrIndices.push_back(destroyAddrIndex);
+  }
+
+  std::pair<DestroyAddrInst *, MutableArrayRef<AvailableValue>>
+  getData(unsigned index) {
+    unsigned destroyAddrIndex = destroyAddrIndices[index];
+    unsigned startOffset = availableValueStartOffsets[index];
+    unsigned count;
+
+    if ((availableValueStartOffsets.size() - 1) != index) {
+      count = availableValueStartOffsets[index + 1] - startOffset;
+    } else {
+      count = availableValueList.size() - startOffset;
+    }
+
+    MutableArrayRef<AvailableValue> values(&availableValueList[startOffset],
+                                           count);
+    auto *dai = cast<DestroyAddrInst>(destroys[destroyAddrIndex]);
+    return {dai, values};
+  }
+};
+
+} // end anonymous namespace
+
+/// If the allocation is an autogenerated allocation that is only stored to
+/// (after load promotion) then remove it completely.
 bool AllocOptimize::tryToRemoveDeadAllocation() {
   assert((isa<AllocBoxInst>(TheMemory) || isa<AllocStackInst>(TheMemory)) &&
          "Unhandled allocation case");
@@ -1236,29 +1272,32 @@
   // 1. They are in a transparent function.
   // 2. They are in a normal function, but didn't come from a VarDecl, or came
   //    from one that was autogenerated or inlined from a transparent function.
-  SILLocation Loc = TheMemory->getLoc();
+  SILLocation loc = TheMemory->getLoc();
   if (!TheMemory->getFunction()->isTransparent() &&
-      Loc.getAsASTNode<VarDecl>() && !Loc.isAutoGenerated() &&
-      !Loc.is<MandatoryInlinedLocation>())
+      loc.getAsASTNode<VarDecl>() && !loc.isAutoGenerated() &&
+      !loc.is<MandatoryInlinedLocation>())
     return false;
 
   // Check the uses list to see if there are any non-store uses left over after
   // load promotion and other things PMO does.
-  for (auto &U : Uses) {
+  for (auto &u : Uses) {
     // Ignore removed instructions.
-    if (U.Inst == nullptr) continue;
+    if (u.Inst == nullptr)
+      continue;
 
-    switch (U.Kind) {
+    switch (u.Kind) {
     case PMOUseKind::Assign:
-    case PMOUseKind::PartialStore:
+      // Until we can promote the value being destroyed by the assign, we can
+      // not remove deallocations with such assigns.
+      return false;
     case PMOUseKind::InitOrAssign:
       break;    // These don't prevent removal.
     case PMOUseKind::Initialization:
-      if (!isa<ApplyInst>(U.Inst) &&
+      if (!isa<ApplyInst>(u.Inst) &&
           // A copy_addr that is not a take affects the retain count
           // of the source.
-          (!isa<CopyAddrInst>(U.Inst) ||
-           cast<CopyAddrInst>(U.Inst)->isTakeOfSrc()))
+          (!isa<CopyAddrInst>(u.Inst) ||
+           cast<CopyAddrInst>(u.Inst)->isTakeOfSrc()))
         break;
       // FALL THROUGH.
      LLVM_FALLTHROUGH;
@@ -1267,7 +1306,8 @@
     case PMOUseKind::InOutUse:
     case PMOUseKind::Escape:
       LLVM_DEBUG(llvm::dbgs() << "*** Failed to remove autogenerated alloc: "
-                 "kept alive by: " << *U.Inst);
+                                 "kept alive by: "
+                              << *u.Inst);
       return false;   // These do prevent removal.
     }
   }
@@ -1289,53 +1329,39 @@
 
   // Otherwise removing the deallocation will drop any releases.  Check that
   // there is nothing preventing removal.
-  llvm::SmallVector<unsigned, 8> DestroyAddrIndices;
-  llvm::SmallVector<AvailableValue, 32> AvailableValueList;
-  llvm::SmallVector<unsigned, 8> AvailableValueStartOffsets;
+  DestroyAddrPromotionState state(Releases);
 
-  for (auto P : llvm::enumerate(Releases)) {
-    auto *R = P.value();
-    if (R == nullptr)
+  for (auto p : llvm::enumerate(Releases)) {
+    auto *r = p.value();
+    if (r == nullptr)
       continue;
 
     // We stash all of the destroy_addr that we see.
-    if (auto *DAI = dyn_cast<DestroyAddrInst>(R)) {
-      AvailableValueStartOffsets.push_back(AvailableValueList.size());
+    if (auto *dai = dyn_cast<DestroyAddrInst>(r)) {
+      state.initializeForDestroyAddr(p.index() /*destroyAddrIndex*/);
       // Make sure we can actually promote this destroy addr. If we can not,
       // then we must bail. In order to not gather available values twice, we
       // gather the available values here that we will use to promote the
       // values.
-      if (!canPromoteDestroyAddr(DAI, AvailableValueList))
+      if (!canPromoteDestroyAddr(dai, state.availableValueList))
         return false;
-      DestroyAddrIndices.push_back(P.index());
       continue;
     }
 
     LLVM_DEBUG(llvm::dbgs()
                << "*** Failed to remove autogenerated non-trivial alloc: "
                   "kept alive by release: "
-               << *R);
+               << *r);
     return false;
   }
 
   // If we reached this point, we can promote all of our destroy_addr.
-  for (auto P : llvm::enumerate(DestroyAddrIndices)) {
-    unsigned DestroyAddrIndex = P.value();
-    unsigned AvailableValueIndex = P.index();
-    unsigned StartOffset = AvailableValueStartOffsets[AvailableValueIndex];
-    unsigned Count;
-
-    if ((AvailableValueStartOffsets.size() - 1) != AvailableValueIndex) {
-      Count = AvailableValueStartOffsets[AvailableValueIndex + 1] - StartOffset;
-    } else {
-      Count = AvailableValueList.size() - StartOffset;
-    }
-
-    MutableArrayRef<AvailableValue> Values(&AvailableValueList[StartOffset],
-                                           Count);
-    auto *DAI = cast<DestroyAddrInst>(Releases[DestroyAddrIndex]);
-    promoteDestroyAddr(DAI, Values);
-    Releases[DestroyAddrIndex] = nullptr;
+  for (unsigned i : range(state.size())) {
+    DestroyAddrInst *dai;
+    MutableArrayRef<AvailableValue> values;
+    std::tie(dai, values) = state.getData(i);
+    promoteDestroyAddr(dai, values);
+    // We do not need to unset releases, since we are going to exit here.
   }
 
   LLVM_DEBUG(llvm::dbgs() << "*** Removing autogenerated non-trivial alloc: "
@@ -1349,79 +1375,135 @@
   return true;
 }
 
-/// doIt - returns true on error.
-bool AllocOptimize::doIt() {
-  bool Changed = false;
-
-  // Don't try to optimize incomplete aggregates.
-  if (MemoryType.aggregateHasUnreferenceableStorage())
-    return false;
+bool AllocOptimize::optimizeMemoryAccesses() {
+  bool changed = false;
 
   // If we've successfully checked all of the definitive initialization
   // requirements, try to promote loads.  This can explode copy_addrs, so the
   // use list may change size.
   for (unsigned i = 0; i != Uses.size(); ++i) {
-    auto &Use = Uses[i];
+    auto &use = Uses[i];
     // Ignore entries for instructions that got expanded along the way.
-    if (Use.Inst && Use.Kind == PMOUseKind::Load) {
-      if (promoteLoad(Use.Inst)) {
+    if (use.Inst && use.Kind == PMOUseKind::Load) {
+      if (promoteLoad(use.Inst)) {
         Uses[i].Inst = nullptr;  // remove entry if load got deleted.
-        Changed = true;
+        changed = true;
       }
     }
   }
-  
-  // If this is an allocation, try to remove it completely.
-  Changed |= tryToRemoveDeadAllocation();
 
-  return Changed;
+  return changed;
 }
 
-static bool optimizeMemoryAllocations(SILFunction &Fn) {
-  bool Changed = false;
-  for (auto &BB : Fn) {
-    auto I = BB.begin(), E = BB.end();
-    while (I != E) {
-      SILInstruction *Inst = &*I;
-      if (!isa<AllocBoxInst>(Inst) && !isa<AllocStackInst>(Inst)) {
-        ++I;
+//===----------------------------------------------------------------------===//
+//                           Top Level Entrypoints
+//===----------------------------------------------------------------------===//
+
+static AllocationInst *getOptimizableAllocation(SILInstruction *i) {
+  if (!isa<AllocBoxInst>(i) && !isa<AllocStackInst>(i)) {
+    return nullptr;
+  }
+
+  auto *alloc = cast<AllocationInst>(i);
+
+  // If our aggregate has unreferencable storage, we can't optimize. Return
+  // nullptr.
+  if (getMemoryType(alloc).aggregateHasUnreferenceableStorage())
+    return nullptr;
+
+  // Otherwise we are good to go. Lets try to optimize this memory!
+  return alloc;
+}
+
+static bool optimizeMemoryAccesses(SILFunction &fn) {
+  bool changed = false;
+  for (auto &bb : fn) {
+    auto i = bb.begin(), e = bb.end();
+    while (i != e) {
+      // First see if i is an allocation that we can optimize. If not, skip it.
+      AllocationInst *alloc = getOptimizableAllocation(&*i);
+      if (!alloc) {
+        ++i;
         continue;
       }
-      auto Alloc = cast<AllocationInst>(Inst);
 
-      LLVM_DEBUG(llvm::dbgs() << "*** PMO Optimize looking at: " << *Alloc
-                              << "\n");
-      PMOMemoryObjectInfo MemInfo(Alloc);
+      LLVM_DEBUG(llvm::dbgs() << "*** PMO Optimize Memory Accesses looking at: "
+                              << *alloc << "\n");
+      PMOMemoryObjectInfo memInfo(alloc);
 
       // Set up the datastructure used to collect the uses of the allocation.
-      SmallVector<PMOMemoryUse, 16> Uses;
-      SmallVector<SILInstruction*, 4> Releases;
+      SmallVector<PMOMemoryUse, 16> uses;
+      SmallVector<SILInstruction *, 4> destroys;
 
       // Walk the use list of the pointer, collecting them. If we are not able
       // to optimize, skip this value. *NOTE* We may still scalarize values
       // inside the value.
-      if (!collectPMOElementUsesFrom(MemInfo, Uses, Releases)) {
-        ++I;
+      if (!collectPMOElementUsesFrom(memInfo, uses, destroys)) {
+        ++i;
         continue;
       }
 
-      Changed |= AllocOptimize(Alloc, Uses, Releases).doIt();
-      
-      // Carefully move iterator to avoid invalidation problems.
-      ++I;
-      if (Alloc->use_empty()) {
-        Alloc->eraseFromParent();
+      AllocOptimize allocOptimize(alloc, uses, destroys);
+      changed |= allocOptimize.optimizeMemoryAccesses();
+
+      // Move onto the next instruction. We know this is safe since we do not
+      // eliminate allocations here.
+      ++i;
+    }
+  }
+
+  return changed;
+}
+
+static bool eliminateDeadAllocations(SILFunction &fn) {
+  bool changed = false;
+  for (auto &bb : fn) {
+    auto i = bb.begin(), e = bb.end();
+    while (i != e) {
+      // First see if i is an allocation that we can optimize. If not, skip it.
+      AllocationInst *alloc = getOptimizableAllocation(&*i);
+      if (!alloc) {
+        ++i;
+        continue;
+      }
+
+      LLVM_DEBUG(llvm::dbgs()
+                 << "*** PMO Dead Allocation Elimination looking at: " << *alloc
+                 << "\n");
+      PMOMemoryObjectInfo memInfo(alloc);
+
+      // Set up the datastructure used to collect the uses of the allocation.
+      SmallVector<PMOMemoryUse, 16> uses;
+      SmallVector<SILInstruction *, 4> destroys;
+
+      // Walk the use list of the pointer, collecting them. If we are not able
+      // to optimize, skip this value. *NOTE* We may still scalarize values
+      // inside the value.
+      if (!collectPMOElementUsesFrom(memInfo, uses, destroys)) {
+        ++i;
+        continue;
+      }
+
+      AllocOptimize allocOptimize(alloc, uses, destroys);
+      changed |= allocOptimize.tryToRemoveDeadAllocation();
+
+      // Move onto the next instruction. We know this is safe since we do not
+      // eliminate allocations here.
+      ++i;
+      if (alloc->use_empty()) {
+        alloc->eraseFromParent();
         ++NumAllocRemoved;
-        Changed = true;
+        changed = true;
       }
     }
   }
-  return Changed;
+
+  return changed;
 }
 
 namespace {
 
-class PredictableMemoryOptimizations : public SILFunctionTransform {
+class PredictableMemoryAccessOptimizations : public SILFunctionTransform {
   /// The entry point to the transformation.
   ///
   /// FIXME: This pass should not need to rerun on deserialized
@@ -1430,14 +1512,25 @@
   /// either indicates that this pass missing some opportunities the first time,
   /// or has a pass order dependency on other early passes.
   void run() override {
-    if (optimizeMemoryAllocations(*getFunction()))
+    // TODO: Can we invalidate here just instructions?
+    if (optimizeMemoryAccesses(*getFunction()))
+      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
+  }
+};
+
+class PredictableDeadAllocationElimination : public SILFunctionTransform {
+  void run() override {
+    if (eliminateDeadAllocations(*getFunction()))
       invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
   }
 };
 
 } // end anonymous namespace
 
+SILTransform *swift::createPredictableMemoryAccessOptimizations() {
+  return new PredictableMemoryAccessOptimizations();
+}
 
-SILTransform *swift::createPredictableMemoryOptimizations() {
-  return new PredictableMemoryOptimizations();
+SILTransform *swift::createPredictableDeadAllocationElimination() {
+  return new PredictableDeadAllocationElimination();
 }
diff --git a/lib/SILOptimizer/PassManager/PassPipeline.cpp b/lib/SILOptimizer/PassManager/PassPipeline.cpp
index 294ce42..d351b7f 100644
--- a/lib/SILOptimizer/PassManager/PassPipeline.cpp
+++ b/lib/SILOptimizer/PassManager/PassPipeline.cpp
@@ -106,12 +106,20 @@
   P.addOwnershipModelEliminator();
   P.addMandatoryInlining();
   P.addMandatorySILLinker();
-  P.addPredictableMemoryOptimizations();
+
+  // Promote loads as necessary to ensure we have enough SSA formation to emit
+  // SSA based diagnostics.
+  P.addPredictableMemoryAccessOptimizations();
 
   // Diagnostic ConstantPropagation must be rerun on deserialized functions
   // because it is sensitive to the assert configuration.
   // Consequently, certain optimization passes beyond this point will also rerun.
   P.addDiagnosticConstantPropagation();
+
+  // Now that we have emitted constant propagation diagnostics, try to eliminate
+  // dead allocations.
+  P.addPredictableDeadAllocationElimination();
+
   P.addGuaranteedARCOpts();
   P.addDiagnoseUnreachable();
   P.addDiagnoseInfiniteRecursion();
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 0fdfd4b..03138cc 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -74,9 +74,24 @@
 SILInstruction *SILCombiner::visitPartialApplyInst(PartialApplyInst *PAI) {
   // partial_apply without any substitutions or arguments is just a
   // thin_to_thick_function.
-  if (!PAI->hasSubstitutions() && (PAI->getNumArguments() == 0))
-    return Builder.createThinToThickFunction(PAI->getLoc(), PAI->getCallee(),
-                                             PAI->getType());
+  if (!PAI->hasSubstitutions() && (PAI->getNumArguments() == 0)) {
+    if (!PAI->isOnStack())
+      return Builder.createThinToThickFunction(PAI->getLoc(), PAI->getCallee(),
+                                               PAI->getType());
+
+    // Remove dealloc_stack of partial_apply [stack].
+    // Iterating while delete use a copy.
+    SmallVector<Operand *, 8> Uses(PAI->getUses());
+    for (auto *Use : Uses)
+      if (auto *dealloc = dyn_cast<DeallocStackInst>(Use->getUser()))
+        eraseInstFromFunction(*dealloc);
+    auto *thinToThick = Builder.createThinToThickFunction(
+        PAI->getLoc(), PAI->getCallee(), PAI->getType());
+    replaceInstUsesWith(*PAI, thinToThick);
+    eraseInstFromFunction(*PAI);
+    return nullptr;
+  }
+
 
   // partial_apply %reabstraction_thunk_typeAtoB(
   //    partial_apply %reabstraction_thunk_typeBtoA %closure_typeB))
@@ -138,6 +153,12 @@
 
 /// Returns true on success.
 bool PartialApplyCombiner::allocateTemporaries() {
+  // A partial_apply [stack]'s argument are not owned by the partial_apply and
+  // therefore their lifetime must outlive any uses.
+  if (PAI->isOnStack()) {
+    return true;
+  }
+
   // Copy the original arguments of the partial_apply into newly created
   // temporaries and use these temporaries instead of the original arguments
   // afterwards.
@@ -397,6 +418,15 @@
       Uses.append(CFI->getUses().begin(), CFI->getUses().end());
       continue;
     }
+    // Look through mark_dependence users of partial_apply [stack].
+    if (auto *MD = dyn_cast<MarkDependenceInst>(User)) {
+      if (MD->getValue() == Use->get() &&
+          MD->getValue()->getType().is<SILFunctionType>() &&
+          MD->getValue()->getType().castTo<SILFunctionType>()->isNoEscape()) {
+        Uses.append(MD->getUses().begin(), MD->getUses().end());
+      }
+      continue;
+    }
     // If this use of a partial_apply is not
     // an apply which uses it as a callee, bail.
     auto AI = FullApplySite::isa(User);
diff --git a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
index 0b19979..c01a13d 100644
--- a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
+++ b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp
@@ -1843,6 +1843,26 @@
   return simplifyTermWithIdenticalDestBlocks(ThisBB);
 }
 
+bool onlyContainsRefcountAndDeallocStackInst(
+    SILBasicBlock::reverse_iterator I, SILBasicBlock::reverse_iterator End) {
+  while (I != End) {
+    auto MaybeDead = I++;
+    switch (MaybeDead->getKind()) {
+      // These technically have side effects, but not ones that matter
+      // in a block that we shouldn't really reach...
+    case SILInstructionKind::StrongRetainInst:
+    case SILInstructionKind::StrongReleaseInst:
+    case SILInstructionKind::RetainValueInst:
+    case SILInstructionKind::ReleaseValueInst:
+    case SILInstructionKind::DeallocStackInst:
+      break;
+
+    default:
+      return false;
+    }
+  }
+  return true;
+}
 /// simplifyUnreachableBlock - Simplify blocks ending with unreachable by
 /// removing instructions that are safe to delete backwards until we
 /// hit an instruction we cannot delete.
@@ -1853,6 +1873,8 @@
   auto End = BB->rend();
   SmallVector<SILInstruction *, 8> DeadInstrs;
 
+  bool canIgnoreRestOfBlock = false;
+
   // Walk backwards deleting instructions that should be safe to delete
   // in a block that ends with unreachable.
   while (I != End) {
@@ -1866,10 +1888,19 @@
     case SILInstructionKind::RetainValueInst:
     case SILInstructionKind::ReleaseValueInst:
       break;
-
+    // We can only ignore a dealloc_stack instruction if we can ignore all
+    // instructions in the block.
+    case SILInstructionKind::DeallocStackInst: {
+      if (canIgnoreRestOfBlock ||
+          onlyContainsRefcountAndDeallocStackInst(MaybeDead, End)) {
+        canIgnoreRestOfBlock = true;
+        break;
+      }
+      LLVM_FALLTHROUGH;
+    }
     default:
       if (MaybeDead->mayHaveSideEffects()) {
-        if (Changed)
+         if (Changed)
           for (auto Dead : DeadInstrs)
             Dead->eraseFromParent();
         return Changed;
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index a94fc8f..1c9b872 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -2033,7 +2033,8 @@
   if (auto *PAI = dyn_cast<PartialApplyInst>(AI)) {
     auto *NewPAI = Builder.createPartialApply(
         Loc, Callee, Subs, Arguments,
-        PAI->getType().getAs<SILFunctionType>()->getCalleeConvention());
+        PAI->getType().getAs<SILFunctionType>()->getCalleeConvention(),
+        PAI->isOnStack());
     PAI->replaceAllUsesWith(NewPAI);
     return NewPAI;
   }
@@ -2404,7 +2405,8 @@
     auto Subs = ReInfo.getCallerParamSubstitutionMap();
     auto *NewPAI = Builder.createPartialApply(
         PAI->getLoc(), FRI, Subs, Arguments,
-        PAI->getType().getAs<SILFunctionType>()->getCalleeConvention());
+        PAI->getType().getAs<SILFunctionType>()->getCalleeConvention(),
+        PAI->isOnStack());
     PAI->replaceAllUsesWith(NewPAI);
     DeadApplies.insert(PAI);
     return;
diff --git a/lib/SILOptimizer/Utils/Local.cpp b/lib/SILOptimizer/Utils/Local.cpp
index 31e19f3..b18f745 100644
--- a/lib/SILOptimizer/Utils/Local.cpp
+++ b/lib/SILOptimizer/Utils/Local.cpp
@@ -1138,14 +1138,50 @@
   return true;
 }
 
+static bool
+deadMarkDependenceUser(SILInstruction *Inst,
+                       SmallVectorImpl<SILInstruction *> &DeleteInsts) {
+  if (!isa<MarkDependenceInst>(Inst))
+    return false;
+  DeleteInsts.push_back(Inst);
+  for (auto *Use : cast<SingleValueInstruction>(Inst)->getUses()) {
+    if (!deadMarkDependenceUser(Use->getUser(), DeleteInsts))
+      return false;
+  }
+  return true;
+}
+
 /// TODO: Generalize this to general objects.
 bool swift::tryDeleteDeadClosure(SingleValueInstruction *Closure,
                                  InstModCallbacks Callbacks) {
+  auto *PA = dyn_cast<PartialApplyInst>(Closure);
+
   // We currently only handle locally identified values that do not escape. We
   // also assume that the partial apply does not capture any addresses.
-  if (!isa<PartialApplyInst>(Closure) && !isa<ThinToThickFunctionInst>(Closure))
+  if (!PA && !isa<ThinToThickFunctionInst>(Closure))
     return false;
 
+  // A stack allocated partial apply does not have any release users. Delete it
+  // if the only users are the dealloc_stack and mark_dependence instructions.
+  if (PA && PA->isOnStack()) {
+    SmallVector<SILInstruction*, 8> DeleteInsts;
+    for (auto *Use : PA->getUses()) {
+      if (isa<DeallocStackInst>(Use->getUser()) ||
+          isa<DebugValueInst>(Use->getUser()))
+        DeleteInsts.push_back(Use->getUser());
+      else if (!deadMarkDependenceUser(Use->getUser(), DeleteInsts))
+        return false;
+    }
+    for (auto *Inst : reverse(DeleteInsts))
+      Callbacks.DeleteInst(Inst);
+    Callbacks.DeleteInst(PA);
+
+    // Note: the lifetime of the captured arguments is managed outside of the
+    // trivial closure value i.e: there will already be releases for the
+    // captured arguments. Releasing captured arguments is not necessary.
+    return true;
+  }
+
   // We only accept a user if it is an ARC object that can be removed if the
   // object is dead. This should be expanded in the future. This also ensures
   // that we are locally identified and non-escaping since we only allow for
@@ -1768,6 +1804,13 @@
            std::back_inserter(worklist));
       continue;
 
+    // A partial_apply [stack] marks its captured arguments with
+    // mark_dependence.
+    case SILInstructionKind::MarkDependenceInst:
+      copy(cast<SingleValueInstruction>(user)->getUses(),
+           std::back_inserter(worklist));
+      continue;
+
     // Look through any reference count instructions since these are not
     // escapes:
     case SILInstructionKind::CopyValueInst:
@@ -1778,6 +1821,8 @@
     case SILInstructionKind::RetainValueInst:
     case SILInstructionKind::ReleaseValueInst:
     case SILInstructionKind::DestroyValueInst:
+    // A partial_apply [stack] is deallocated with a dealloc_stack.
+    case SILInstructionKind::DeallocStackInst:
       continue;
     default:
       break;
@@ -1793,3 +1838,22 @@
     return None;
   return f;
 }
+
+/// Insert destroys of captured arguments of partial_apply [stack].
+void swift::insertDestroyOfCapturedArguments(
+    PartialApplyInst *PAI, SILBuilder &B,
+    llvm::function_ref<bool(SILValue)> shouldInsertDestroy) {
+  assert(PAI->isOnStack());
+
+  ApplySite site(PAI);
+  SILFunctionConventions calleeConv(site.getSubstCalleeType(),
+                                    PAI->getModule());
+  auto loc = RegularLocation::getAutoGeneratedLocation();
+  for (auto &arg : PAI->getArgumentOperands()) {
+    if (!shouldInsertDestroy(arg.get())) continue;
+    unsigned calleeArgumentIndex = site.getCalleeArgIndex(arg);
+    assert(calleeArgumentIndex >= calleeConv.getSILArgIndexOfFirstParam());
+    auto paramInfo = calleeConv.getParamInfoForSILArg(calleeArgumentIndex);
+    releasePartialApplyCapturedArg(B, loc, arg.get(), paramInfo);
+  }
+}
diff --git a/lib/SILOptimizer/Utils/StackNesting.cpp b/lib/SILOptimizer/Utils/StackNesting.cpp
index ceb0ea1..74e518a 100644
--- a/lib/SILOptimizer/Utils/StackNesting.cpp
+++ b/lib/SILOptimizer/Utils/StackNesting.cpp
@@ -110,7 +110,7 @@
     BlockInfo *BI = WorkList.pop_back_val();
     for (SILInstruction &I : *BI->Block) {
       if (I.isAllocatingStack()) {
-        auto Alloc = cast<AllocationInst>(&I);
+        auto Alloc = cast<SingleValueInstruction>(&I);
         // Register this stack location.
         unsigned CurrentBitNumber = StackLocs.size();
         StackLoc2BitNumbers[Alloc] = CurrentBitNumber;
@@ -219,12 +219,16 @@
   return isNested;
 }
 
-static SILInstruction *createDealloc(AllocationInst *Alloc,
+static SILInstruction *createDealloc(SingleValueInstruction *Alloc,
                                      SILInstruction *InsertionPoint,
                                      SILLocation Location) {
   SILBuilderWithScope B(InsertionPoint);
   switch (Alloc->getKind()) {
+    case SILInstructionKind::PartialApplyInst:
     case SILInstructionKind::AllocStackInst:
+      assert((isa<AllocStackInst>(Alloc) ||
+              cast<PartialApplyInst>(Alloc)->isOnStack()) &&
+             "wrong instruction");
       return B.createDeallocStack(Location, Alloc);
     case SILInstructionKind::AllocRefInst:
       assert(cast<AllocRefInst>(Alloc)->canAllocOnStack());
@@ -248,7 +252,7 @@
   for (int LocNr = AliveBefore.find_first(); LocNr >= 0;
        LocNr = AliveBefore.find_next(LocNr)) {
     if (!AliveAfter.test(LocNr)) {
-      AllocationInst *Alloc = StackLocs[LocNr].Alloc;
+      auto *Alloc = StackLocs[LocNr].Alloc;
       InsertionPoint = createDealloc(Alloc, InsertionPoint,
                    Location.hasValue() ? Location.getValue() : Alloc->getLoc());
       changesMade = true;
@@ -374,13 +378,13 @@
     dumpBits(BI.AliveStackLocsAtEntry);
     for (SILInstruction *StackInst : BI.StackInsts) {
       if (StackInst->isAllocatingStack()) {
-        auto AllocInst = cast<AllocationInst>(StackInst);
+        auto AllocInst = cast<SingleValueInstruction>(StackInst);
         int BitNr = StackLoc2BitNumbers.lookup(AllocInst);
         llvm::dbgs() << "  alloc #" << BitNr << ": alive=";
         dumpBits(StackLocs[BitNr].AliveLocs);
         llvm::dbgs() << "    " << *StackInst;
       } else if (StackInst->isDeallocatingStack()) {
-        auto *AllocInst = cast<AllocationInst>(StackInst->getOperand(0));
+        auto *AllocInst = cast<SingleValueInstruction>(StackInst->getOperand(0));
         int BitNr = StackLoc2BitNumbers.lookup(AllocInst);
         llvm::dbgs() << "  dealloc for #" << BitNr << "\n"
                         "    " << *StackInst;
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 5f1c3a1..f5b4594 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -7808,23 +7808,31 @@
     if (fixes == fixesPerExpr.end())
       return false;
 
-    bool diagnosed = false;
-    for (const auto *fix : fixes->second)
-      diagnosed |= fix->diagnose(E);
-    return diagnosed;
+    bool diagnosedError = false;
+    for (const auto *fix : fixes->second) {
+      auto diagnosed = fix->diagnose(E);
+
+      if (fix->isWarning()) {
+        assert(diagnosed && "warnings should always be diagnosed");
+        (void)diagnosed;
+      } else {
+        diagnosedError |= diagnosed;
+      }
+    }
+    return diagnosedError;
   };
 
-  bool diagnosed = false;
+  bool diagnosedError = false;
   E->forEachChildExpr([&](Expr *subExpr) -> Expr * {
     // Diagnose root expression at the end to
     // preserve ordering.
     if (subExpr != E)
-      diagnosed |= diagnoseExprFailures(subExpr);
+      diagnosedError |= diagnoseExprFailures(subExpr);
     return subExpr;
   });
 
-  diagnosed |= diagnoseExprFailures(E);
-  return diagnosed;
+  diagnosedError |= diagnoseExprFailures(E);
+  return diagnosedError;
 }
 
 /// Apply a given solution to the expression, producing a fully
@@ -7839,15 +7847,21 @@
     if (shouldSuppressDiagnostics())
       return nullptr;
 
-    // If we can diagnose the problem with the fixits that we've pre-assumed,
-    // do so now.
-    if (applySolutionFixes(expr, solution))
-      return nullptr;
+    bool diagnosedErrorsViaFixes = applySolutionFixes(expr, solution);
+    // If all of the available fixes would result in a warning,
+    // we can go ahead and apply this solution to AST.
+    if (!llvm::all_of(solution.Fixes, [](const ConstraintFix *fix) {
+          return fix->isWarning();
+        })) {
+      // If we already diagnosed any errors via fixes, that's it.
+      if (diagnosedErrorsViaFixes)
+        return nullptr;
 
-    // If we didn't manage to diagnose anything well, so fall back to
-    // diagnosing mining the system to construct a reasonable error message.
-    diagnoseFailureForExpr(expr);
-    return nullptr;
+      // If we didn't manage to diagnose anything well, so fall back to
+      // diagnosing mining the system to construct a reasonable error message.
+      diagnoseFailureForExpr(expr);
+      return nullptr;
+    }
   }
 
   // Mark any normal conformances used in this solution as "used".
diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h
index ea58e09..da1e3a2 100644
--- a/lib/Sema/CSFix.h
+++ b/lib/Sema/CSFix.h
@@ -111,14 +111,21 @@
   FixKind Kind;
   ConstraintLocator *Locator;
 
+  /// Determines whether this fix is simplify a warning which doesn't
+  /// require immediate source changes.
+  bool IsWarning;
+
 public:
-  ConstraintFix(ConstraintSystem &cs, FixKind kind, ConstraintLocator *locator)
-      : CS(cs), Kind(kind), Locator(locator) {}
+  ConstraintFix(ConstraintSystem &cs, FixKind kind, ConstraintLocator *locator,
+                bool warning = false)
+      : CS(cs), Kind(kind), Locator(locator), IsWarning(warning) {}
 
   virtual ~ConstraintFix();
 
   FixKind getKind() const { return Kind; }
 
+  bool isWarning() const { return IsWarning; }
+
   virtual std::string getName() const = 0;
 
   /// Diagnose a failure associated with this fix given
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index a26bd8b..927598c 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1504,17 +1504,33 @@
   if (LiteralProtocols.size() <= 1)
     return;
 
-  llvm::SmallVector<Type, 2> defaultTypes;
-  for (auto *protocol : LiteralProtocols)
-    defaultTypes.push_back(CS.TC.getDefaultType(protocol, CS.DC));
+  llvm::SmallVector<std::pair<ProtocolDecl *, Type>, 2> candidates;
+  llvm::SmallVector<ProtocolDecl *, 2> skippedProtocols;
 
-  auto result = 0;
-  for (unsigned long i = 1; i < LiteralProtocols.size(); ++i) {
+  for (auto *protocol : LiteralProtocols) {
+    if (auto defaultType = CS.TC.getDefaultType(protocol, CS.DC)) {
+      candidates.push_back({protocol, defaultType});
+      continue;
+    }
+
+    // Looks like argument expected to conform to something like
+    // `ExpressibleByNilLiteral` which doesn't have a default
+    // type and as a result can't participate in minimalization.
+    skippedProtocols.push_back(protocol);
+  }
+
+  if (candidates.size() <= 1)
+    return;
+
+  unsigned result = 0;
+  for (unsigned i = 1, n = candidates.size(); i != n; ++i) {
+    const auto &candidate = candidates[i];
+
     auto first =
-        CS.TC.conformsToProtocol(defaultTypes[i], LiteralProtocols[result],
+        CS.TC.conformsToProtocol(candidate.second, candidates[result].first,
                                  CS.DC, ConformanceCheckFlags::InExpression);
     auto second =
-        CS.TC.conformsToProtocol(defaultTypes[result], LiteralProtocols[i],
+        CS.TC.conformsToProtocol(candidates[result].second, candidate.first,
                                  CS.DC, ConformanceCheckFlags::InExpression);
     if ((first && second) || (!first && !second))
       return;
@@ -1523,9 +1539,9 @@
       result = i;
   }
 
-  auto *protocol = LiteralProtocols[result];
   LiteralProtocols.clear();
-  LiteralProtocols.insert(protocol);
+  LiteralProtocols.insert(candidates[result].first);
+  LiteralProtocols.insert(skippedProtocols.begin(), skippedProtocols.end());
 }
 
 void ConstraintSystem::ArgumentInfoCollector::dump() const {
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 5d478c9..51484c2 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -2871,7 +2871,8 @@
     /// A set of all constraints which contribute to pontential bindings.
     llvm::SmallPtrSet<Constraint *, 8> Sources;
 
-    PotentialBindings(TypeVariableType *typeVar) : TypeVar(typeVar) {}
+    PotentialBindings(TypeVariableType *typeVar)
+        : TypeVar(typeVar), PotentiallyIncomplete(isGenericParameter()) {}
 
     /// Determine whether the set of bindings is non-empty.
     explicit operator bool() const { return !Bindings.empty(); }
@@ -2937,6 +2938,16 @@
     /// Check if this binding is viable for inclusion in the set.
     bool isViable(PotentialBinding &binding) const;
 
+    bool isGenericParameter() const {
+      if (auto *locator = TypeVar->getImpl().getLocator()) {
+        auto path = locator->getPath();
+        return path.empty() ? false
+                            : path.back().getKind() ==
+                                  ConstraintLocator::GenericParameter;
+      }
+      return false;
+    }
+
     void dump(llvm::raw_ostream &out,
               unsigned indent = 0) const LLVM_ATTRIBUTE_USED {
       out.indent(indent);
diff --git a/lib/Sema/LookupVisibleDecls.cpp b/lib/Sema/LookupVisibleDecls.cpp
index 74bd513..1ed2d18 100644
--- a/lib/Sema/LookupVisibleDecls.cpp
+++ b/lib/Sema/LookupVisibleDecls.cpp
@@ -294,9 +294,9 @@
 
       // These cases are probably impossible here but can also just
       // be safely ignored.
-      case DeclKind::EnumElement:
       case DeclKind::Param:
       case DeclKind::Module:
+      case DeclKind::EnumElement:
         return;
 
       // For other kinds of values, check if we already reported a decl
diff --git a/lib/Sema/TypeCheckError.cpp b/lib/Sema/TypeCheckError.cpp
index a967828..20ead77 100644
--- a/lib/Sema/TypeCheckError.cpp
+++ b/lib/Sema/TypeCheckError.cpp
@@ -155,6 +155,11 @@
       }
     }
     
+    // Constructor delegation.
+    if (auto otherCtorDeclRef = dyn_cast<OtherConstructorDeclRefExpr>(fn)) {
+      return AbstractFunction(otherCtorDeclRef->getDecl());
+    }
+
     // Normal function references.
     if (auto declRef = dyn_cast<DeclRefExpr>(fn)) {
       ValueDecl *decl = declRef->getDecl();
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index ecb9a49..9b87eee 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -574,18 +574,9 @@
   return lookupMember(dc, type, DeclBaseName::createConstructor(), options);
 }
 
-enum : unsigned {
-  /// Never consider a candidate that's this distance away or worse.
-  UnreasonableCallEditDistance = 8,
-
-  /// Don't consider candidates that score worse than the given distance
-  /// from the best candidate.
-  MaxCallEditDistanceFromBestCandidate = 1
-};
-
-static unsigned getCallEditDistance(DeclName writtenName,
-                                    DeclName correctedName,
-                                    unsigned maxEditDistance) {
+unsigned TypeChecker::getCallEditDistance(DeclName writtenName,
+                                          DeclName correctedName,
+                                          unsigned maxEditDistance) {
   // TODO: consider arguments.
   // TODO: maybe ignore certain kinds of missing / present labels for the
   //   first argument label?
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index c62ba33..6e54386 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -31,6 +31,7 @@
 #include "swift/Basic/STLExtras.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Basic/Statistic.h"
+#include "swift/Basic/TopCollection.h"
 #include "swift/Parse/Lexer.h"
 #include "swift/Parse/LocalContext.h"
 #include "swift/Syntax/TokenKinds.h"
@@ -787,6 +788,7 @@
 
   Stmt *visitBreakStmt(BreakStmt *S) {
     LabeledStmt *Target = nullptr;
+    TopCollection<unsigned, LabeledStmt *> labelCorrections(3);
     // Pick the nearest break target that matches the specified name.
     if (S->getTargetName().empty()) {
       for (auto I = ActiveLabeledStmts.rbegin(), E = ActiveLabeledStmts.rend();
@@ -806,31 +808,39 @@
         if (S->getTargetName() == (*I)->getLabelInfo().Name) {
           Target = *I;
           break;
+        } else {
+          unsigned distance =
+            TC.getCallEditDistance(S->getTargetName(), (*I)->getLabelInfo().Name,
+                                   TypeChecker::UnreasonableCallEditDistance);
+          if (distance < TypeChecker::UnreasonableCallEditDistance)
+            labelCorrections.insert(distance, std::move(*I));
         }
       }
+      labelCorrections.filterMaxScoreRange(
+        TypeChecker::MaxCallEditDistanceFromBestCandidate);
     }
     
     if (!Target) {
       // If we're in a defer, produce a tailored diagnostic.
       if (isInDefer()) {
         TC.diagnose(S->getLoc(), diag::jump_out_of_defer, "break");
-        return nullptr;
+      } else if (S->getTargetName().empty()) {
+        // If we're dealing with an unlabeled break inside of an 'if' or 'do'
+        // statement, produce a more specific error.
+        if (std::any_of(ActiveLabeledStmts.rbegin(),
+                        ActiveLabeledStmts.rend(),
+                        [&](Stmt *S) -> bool {
+                          return isa<IfStmt>(S) || isa<DoStmt>(S);
+                        })) {
+          TC.diagnose(S->getLoc(), diag::unlabeled_break_outside_loop);
+        } else {
+          // Otherwise produce a generic error.
+          TC.diagnose(S->getLoc(), diag::break_outside_loop);
+        }
+      } else {
+        emitUnresolvedLabelDiagnostics(TC, S->getTargetLoc(), S->getTargetName(),
+                                       labelCorrections);
       }
-      
-      auto diagid = diag::break_outside_loop;
-
-      // If someone is using an unlabeled break inside of an 'if' or 'do'
-      // statement, produce a more specific error.
-      if (S->getTargetName().empty() &&
-          std::any_of(ActiveLabeledStmts.rbegin(),
-                      ActiveLabeledStmts.rend(),
-                      [&](Stmt *S) -> bool {
-                        return isa<IfStmt>(S) || isa<DoStmt>(S);
-                      })) {
-        diagid = diag::unlabeled_break_outside_loop;
-      }
-
-      TC.diagnose(S->getLoc(), diagid);
       return nullptr;
     }
     S->setTarget(Target);
@@ -839,6 +849,7 @@
 
   Stmt *visitContinueStmt(ContinueStmt *S) {
     LabeledStmt *Target = nullptr;
+    TopCollection<unsigned, LabeledStmt *> labelCorrections(3);
     // Scan to see if we are in any non-switch labeled statements (loops).  Scan
     // inside out.
     if (S->getTargetName().empty()) {
@@ -858,31 +869,68 @@
         if (S->getTargetName() == (*I)->getLabelInfo().Name) {
           Target = *I;
           break;
+        } else {
+          unsigned distance =
+            TC.getCallEditDistance(S->getTargetName(), (*I)->getLabelInfo().Name,
+                                   TypeChecker::UnreasonableCallEditDistance);
+          if (distance < TypeChecker::UnreasonableCallEditDistance)
+            labelCorrections.insert(distance, std::move(*I));
         }
       }
+      labelCorrections.filterMaxScoreRange(
+        TypeChecker::MaxCallEditDistanceFromBestCandidate);
     }
 
-    if (!Target) {
+    if (Target) {
+      // Continue cannot be used to repeat switches, use fallthrough instead.
+      if (!Target->isPossibleContinueTarget()) {
+        TC.diagnose(S->getLoc(), diag::continue_not_in_this_stmt,
+                    isa<SwitchStmt>(Target) ? "switch" : "if");
+        return nullptr;
+      }
+    } else {
       // If we're in a defer, produce a tailored diagnostic.
       if (isInDefer()) {
         TC.diagnose(S->getLoc(), diag::jump_out_of_defer, "break");
-        return nullptr;
+      } else if (S->getTargetName().empty()) {
+        // If we're dealing with an unlabeled continue, produce a generic error.
+        TC.diagnose(S->getLoc(), diag::continue_outside_loop);
+      } else {
+        emitUnresolvedLabelDiagnostics(TC, S->getTargetLoc(), S->getTargetName(),
+                                       labelCorrections);
       }
-
-      TC.diagnose(S->getLoc(), diag::continue_outside_loop);
       return nullptr;
     }
-
-    // Continue cannot be used to repeat switches, use fallthrough instead.
-    if (!Target->isPossibleContinueTarget()) {
-      TC.diagnose(S->getLoc(), diag::continue_not_in_this_stmt,
-                  isa<SwitchStmt>(Target) ? "switch" : "if");
-      return nullptr;
-    }
-
     S->setTarget(Target);
     return S;
   }
+
+  static void
+  emitUnresolvedLabelDiagnostics(TypeChecker &tc, SourceLoc targetLoc, Identifier targetName,
+                                 TopCollection<unsigned, LabeledStmt *> corrections) {
+    // If an unresolved label was used, but we have a single correction,
+    // produce the specific diagnostic and fixit.
+    if (corrections.size() == 1) {
+      tc.diagnose(targetLoc, diag::unresolved_label_corrected,
+                  targetName, corrections.begin()->Value->getLabelInfo().Name)
+        .highlight(SourceRange(targetLoc))
+        .fixItReplace(SourceRange(targetLoc),
+                      corrections.begin()->Value->getLabelInfo().Name.str());
+      tc.diagnose(corrections.begin()->Value->getLabelInfo().Loc,
+                  diag::identifier_declared_here,
+                  corrections.begin()->Value->getLabelInfo().Name);
+    } else {
+      // If we have multiple corrections or none, produce a generic diagnostic
+      // and all corrections available.
+      tc.diagnose(targetLoc, diag::unresolved_label, targetName)
+        .highlight(SourceRange(targetLoc));
+      for (auto &entry : corrections)
+        tc.diagnose(entry.Value->getLabelInfo().Loc, diag::note_typo_candidate,
+                    entry.Value->getLabelInfo().Name.str())
+          .fixItReplace(SourceRange(targetLoc),
+                        entry.Value->getLabelInfo().Name.str());
+    }
+  }
   
   Stmt *visitFallthroughStmt(FallthroughStmt *S) {
     if (!SwitchLevel) {
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index de77826..6938e35 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -2128,6 +2128,20 @@
   /// Attempt to omit needless words from the name of the given declaration.
   Optional<Identifier> omitNeedlessWords(VarDecl *var);
 
+  /// Calculate edit distance between declaration names.
+  static unsigned getCallEditDistance(DeclName writtenName,
+                                      DeclName correctedName,
+                                      unsigned maxEditDistance);
+
+  enum : unsigned {
+    /// Never consider a candidate that's this distance away or worse.
+    UnreasonableCallEditDistance = 8,
+
+    /// Don't consider candidates that score worse than the given distance
+    /// from the best candidate.
+    MaxCallEditDistanceFromBestCandidate = 1
+  };
+
   /// Check for a typo correction.
   void performTypoCorrection(DeclContext *DC,
                              DeclRefKind refKind,
diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp
index 5dfdd56..0adb592 100644
--- a/lib/Serialization/DeserializeSIL.cpp
+++ b/lib/Serialization/DeserializeSIL.cpp
@@ -1023,8 +1023,8 @@
     break;
   case SIL_INST_APPLY: {
     unsigned IsPartial;
-    SILInstApplyLayout::readRecord(scratch, IsPartial, NumSubs,
-                                   TyID, TyID2, ValID, ListOfValues);
+    SILInstApplyLayout::readRecord(scratch, IsPartial, NumSubs, TyID, TyID2,
+                                   ValID, ListOfValues);
     switch (IsPartial) {
     case SIL_APPLY:
       RawOpCode = (unsigned)SILInstructionKind::ApplyInst;
@@ -1416,11 +1416,13 @@
     for (unsigned I = 0, E = ListOfValues.size(); I < E; I++)
       Args.push_back(getLocalValue(
           ListOfValues[I], fnConv.getSILArgumentType(I + unappliedArgs)));
-
+    auto onStack = closureTy.castTo<SILFunctionType>()->isNoEscape()
+                       ? PartialApplyInst::OnStackKind::OnStack
+                       : PartialApplyInst::OnStackKind::NotOnStack;
     // FIXME: Why the arbitrary order difference in IRBuilder type argument?
     ResultVal = Builder.createPartialApply(
         Loc, FnVal, Substitutions, Args,
-        closureTy.castTo<SILFunctionType>()->getCalleeConvention());
+        closureTy.castTo<SILFunctionType>()->getCalleeConvention(), onStack);
     break;
   }
   case SILInstructionKind::BuiltinInst: {
diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h
index 2cf0f79..0f41563 100644
--- a/lib/Serialization/SILFormat.h
+++ b/lib/Serialization/SILFormat.h
@@ -379,7 +379,7 @@
     SIL_BEGIN_APPLY,
     SIL_NON_THROWING_BEGIN_APPLY
   };
-  
+
   using SILInstApplyLayout = BCRecordLayout<
     SIL_INST_APPLY,
     BCFixed<3>,           // ApplyKind
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 6e7d95e..f6d34b6 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -475,6 +475,8 @@
     return cast<AbstractFunctionDecl>(DC);
   case DeclContextKind::SubscriptDecl:
     return cast<SubscriptDecl>(DC);
+  case DeclContextKind::EnumElementDecl:
+    return cast<EnumElementDecl>(DC);
   }
 
   llvm_unreachable("Unhandled DeclContextKind in switch.");
@@ -1870,6 +1872,7 @@
   case DeclContextKind::Initializer:
   case DeclContextKind::TopLevelCodeDecl:
   case DeclContextKind::SerializedLocal:
+  case DeclContextKind::EnumElementDecl:
     llvm_unreachable("cannot cross-reference this context");
 
   case DeclContextKind::FileUnit:
@@ -2405,6 +2408,7 @@
   case DeclContextKind::SubscriptDecl:
   case DeclContextKind::GenericTypeDecl:
   case DeclContextKind::ExtensionDecl:
+  case DeclContextKind::EnumElementDecl:
     declOrDeclContextID = addDeclRef(getDeclForContext(DC));
     isDecl = true;
     break;
diff --git a/lib/Syntax/Trivia.cpp.gyb b/lib/Syntax/Trivia.cpp.gyb
index 0e66837..389bb0f6 100644
--- a/lib/Syntax/Trivia.cpp.gyb
+++ b/lib/Syntax/Trivia.cpp.gyb
@@ -24,6 +24,20 @@
 using namespace swift;
 using namespace swift::syntax;
 
+TriviaPiece TriviaPiece::fromText(TriviaKind kind, StringRef text) {
+  switch (kind) {
+% for trivia in TRIVIAS:
+  case TriviaKind::${trivia.name}:
+% if trivia.is_collection():
+    assert(text.size() % ${trivia.characters_len()} == 0);
+    return TriviaPiece(kind, text.size()/${trivia.characters_len()});
+% else:
+    return TriviaPiece(kind, OwnedString::makeRefCounted(text));
+% end
+% end
+  }
+}
+
 void TriviaPiece::dump(llvm::raw_ostream &OS, unsigned Indent) const {
   for (decltype(Count) i = 0; i < Indent; ++i)
     OS << ' ';
@@ -44,7 +58,7 @@
   OS << ')';
 }
 
-bool TriviaPiece::isComment() const {
+bool syntax::isCommentTriviaKind(TriviaKind Kind) {
   switch (Kind) {
 % for trivia in TRIVIAS:
   case TriviaKind::${trivia.name}:
diff --git a/lib/SyntaxParse/SyntaxTreeCreator.cpp b/lib/SyntaxParse/SyntaxTreeCreator.cpp
index 9571328..a20bf39 100644
--- a/lib/SyntaxParse/SyntaxTreeCreator.cpp
+++ b/lib/SyntaxParse/SyntaxTreeCreator.cpp
@@ -14,6 +14,7 @@
 #include "swift/Syntax/RawSyntax.h"
 #include "swift/Syntax/SyntaxVisitor.h"
 #include "swift/Syntax/Trivia.h"
+#include "swift/Parse/ParsedTrivia.h"
 #include "swift/Parse/SyntaxParsingCache.h"
 #include "swift/Parse/Token.h"
 #include "swift/AST/ASTContext.h"
@@ -33,9 +34,11 @@
   return raw;
 }
 
-SyntaxTreeCreator::SyntaxTreeCreator(SyntaxParsingCache *syntaxCache,
+SyntaxTreeCreator::SyntaxTreeCreator(SourceManager &SM, unsigned bufferID,
+                                     SyntaxParsingCache *syntaxCache,
                                      RC<syntax::SyntaxArena> arena)
-    : Arena(std::move(arena)),
+    : SM(SM), BufferID(bufferID),
+      Arena(std::move(arena)),
       SyntaxCache(syntaxCache),
       TokenCache(new RawSyntaxTokenCache()) {
 }
@@ -104,13 +107,30 @@
 }
 
 OpaqueSyntaxNode
-SyntaxTreeCreator::recordToken(const Token &tok,
-                               const syntax::Trivia &leadingTrivia,
-                               const syntax::Trivia &trailingTrivia,
+SyntaxTreeCreator::recordToken(tok tokenKind,
+                               ArrayRef<ParsedTriviaPiece> leadingTriviaPieces,
+                               ArrayRef<ParsedTriviaPiece> trailingTriviaPieces,
                                CharSourceRange range) {
-  auto ownedText = OwnedString::makeRefCounted(tok.getText());
-  auto raw = TokenCache->getToken(Arena, tok.getKind(), ownedText,
-                                  leadingTrivia.Pieces, trailingTrivia.Pieces);
+  size_t leadingTriviaLen =
+    ParsedTriviaPiece::getTotalLength(leadingTriviaPieces);
+  size_t trailingTriviaLen =
+    ParsedTriviaPiece::getTotalLength(trailingTriviaPieces);
+  SourceLoc tokLoc = range.getStart().getAdvancedLoc(leadingTriviaLen);
+  unsigned tokLength = range.getByteLength() -
+      leadingTriviaLen - trailingTriviaLen;
+  CharSourceRange tokRange = CharSourceRange{tokLoc, tokLength};
+  SourceLoc leadingTriviaLoc = range.getStart();
+  SourceLoc trailingTriviaLoc = tokLoc.getAdvancedLoc(tokLength);
+  Trivia syntaxLeadingTrivia =
+    ParsedTriviaPiece::convertToSyntaxTrivia(leadingTriviaPieces,
+                                             leadingTriviaLoc, SM, BufferID);
+  Trivia syntaxTrailingTrivia =
+    ParsedTriviaPiece::convertToSyntaxTrivia(trailingTriviaPieces,
+                                             trailingTriviaLoc, SM, BufferID);
+  StringRef tokenText = SM.extractText(tokRange, BufferID);
+  auto ownedText = OwnedString::makeRefCounted(tokenText);
+  auto raw = TokenCache->getToken(Arena, tokenKind, ownedText,
+                    syntaxLeadingTrivia.Pieces, syntaxTrailingTrivia.Pieces);
   OpaqueSyntaxNode opaqueN = raw.get();
   raw.resetWithoutRelease();
   return opaqueN;
diff --git a/stdlib/public/Darwin/CMakeLists.txt b/stdlib/public/Darwin/CMakeLists.txt
index 2471ef9..90e53d1 100644
--- a/stdlib/public/Darwin/CMakeLists.txt
+++ b/stdlib/public/Darwin/CMakeLists.txt
@@ -8,7 +8,7 @@
   list(APPEND SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES STATIC)
 endif()
 
-set(all_overlays "Accelerate;AppKit;ARKit;AssetsLibrary;AVFoundation;CallKit;CloudKit;Contacts;CoreAudio;CoreData;CoreFoundation;CoreGraphics;CoreImage;CoreLocation;CoreMedia;CryptoTokenKit;Dispatch;Foundation;GameplayKit;GLKit;HomeKit;IOKit;Intents;MapKit;MediaPlayer;Metal;MetalKit;ModelIO;NaturalLanguage;Network;ObjectiveC;OpenCL;os;Photos;QuartzCore;SafariServices;SceneKit;simd;SpriteKit;UIKit;Vision;WatchKit;XCTest;XPC")
+set(all_overlays "Accelerate;AppKit;ARKit;AssetsLibrary;AVFoundation;CallKit;CloudKit;Compression;Contacts;CoreAudio;CoreData;CoreFoundation;CoreGraphics;CoreImage;CoreLocation;CoreMedia;CryptoTokenKit;Dispatch;Foundation;GameplayKit;GLKit;HomeKit;IOKit;Intents;MapKit;MediaPlayer;Metal;MetalKit;ModelIO;NaturalLanguage;Network;ObjectiveC;OpenCL;os;Photos;QuartzCore;SafariServices;SceneKit;simd;SpriteKit;UIKit;Vision;WatchKit;XCTest;XPC")
 
 if(DEFINED SWIFT_OVERLAY_TARGETS)
   set(overlays_to_build ${SWIFT_OVERLAY_TARGETS})
diff --git a/stdlib/public/Darwin/Compression/CMakeLists.txt b/stdlib/public/Darwin/Compression/CMakeLists.txt
new file mode 100644
index 0000000..52167e5
--- /dev/null
+++ b/stdlib/public/Darwin/Compression/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
+add_swift_target_library(swiftCompression ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
+  Compression.swift
+
+  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
+  LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}" "-lcompression"
+  SWIFT_MODULE_DEPENDS_OSX Darwin Foundation
+  SWIFT_MODULE_DEPENDS_IOS Darwin Foundation
+  SWIFT_MODULE_DEPENDS_TVOS Darwin Foundation
+  SWIFT_MODULE_DEPENDS_WATCHOS Darwin Foundation
+
+  DEPLOYMENT_VERSION_OSX ${SWIFTLIB_DEPLOYMENT_VERSION_COMPRESSION_OSX}
+  DEPLOYMENT_VERSION_IOS ${SWIFTLIB_DEPLOYMENT_VERSION_COMPRESSION_IOS}
+  DEPLOYMENT_VERSION_TVOS ${SWIFTLIB_DEPLOYMENT_VERSION_COMPRESSION_TVOS}
+  DEPLOYMENT_VERSION_WATCHOS ${SWIFTLIB_DEPLOYMENT_VERSION_COMPRESSION_WATCHOS}
+)
diff --git a/stdlib/public/Darwin/Compression/Compression.swift b/stdlib/public/Darwin/Compression/Compression.swift
new file mode 100644
index 0000000..265b18d
--- /dev/null
+++ b/stdlib/public/Darwin/Compression/Compression.swift
@@ -0,0 +1,305 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2019 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 Darwin
+import Foundation
+@_exported import Compression
+
+/// Compression algorithms, wraps the C API constants.
+public enum Algorithm: CaseIterable {
+
+  /// LZFSE
+  case lzfse
+
+  /// Deflate (conforming to RFC 1951)
+  case zlib
+
+  /// LZ4 with simple frame encapsulation
+  case lz4
+
+  /// LZMA in a XZ container
+  case lzma
+
+  public var rawValue: compression_algorithm {
+    switch self {
+    case .lzfse: return COMPRESSION_LZFSE
+    case .zlib: return COMPRESSION_ZLIB
+    case .lz4: return COMPRESSION_LZ4
+    case .lzma: return COMPRESSION_LZMA
+    }
+  }
+}
+
+/// Compression errors
+public enum FilterError: Error {
+  /// Filter failed to initialize
+  case filterInitError
+
+  /// Invalid data in a call to compression_stream_process
+  case filterProcessError
+
+  /// Non-empty write after an output filter has been finalized
+  case writeToFinalizedFilter
+}
+
+/// Compression filter direction of operation, compress/decompress
+public enum FilterOperation {
+  /// Compress raw data to a compressed payload
+  case compress
+
+  /// Decompress a compressed payload to raw data
+  case decompress
+
+  public var rawValue: compression_stream_operation {
+    switch self {
+    case .compress: return COMPRESSION_STREAM_ENCODE
+    case .decompress: return COMPRESSION_STREAM_DECODE
+    }
+  }
+}
+
+@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
+extension compression_stream {
+
+  /// Initialize a compression_stream struct
+  ///
+  /// - Parameter operation: direction of operation
+  /// - Parameter algorithm: compression algorithm
+  ///
+  /// - Throws: `FilterError.filterInitError` if `algorithm` is not supported
+  ///           by the Compression stream API
+  ///
+  internal init(operation: FilterOperation, algorithm: Algorithm) throws {
+    self.init(dst_ptr: UnsafeMutablePointer<UInt8>.allocate(capacity:0),
+              dst_size: 0,
+              src_ptr: UnsafeMutablePointer<UInt8>.allocate(capacity:0),
+              src_size: 0,
+              state: nil)
+    let status = compression_stream_init(&self, operation.rawValue, algorithm.rawValue)
+    guard status == COMPRESSION_STATUS_OK else { throw FilterError.filterInitError }
+  }
+}
+
+@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
+public class OutputFilter {
+  private var _stream: compression_stream
+  private var _buf: UnsafeMutablePointer<UInt8>
+  private let _bufCapacity: Int
+  private let _writeFunc: (Data?) throws -> ()
+  private var _finalized: Bool = false
+
+  /// Initialize an output filter
+  ///
+  /// - Parameters:
+  /// - operation: direction of operation
+  /// - algorithm: compression algorithm
+  /// - bufferCapacity: capacity of the internal data buffer
+  /// - writeFunc: called to write the processed data
+  ///
+  /// - Throws: `FilterError.StreamInitError` if stream initialization failed
+  public init(
+    _ operation: FilterOperation,
+    using algorithm: Algorithm,
+    bufferCapacity: Int = 65536,
+    writingTo writeFunc: @escaping (Data?) throws -> ()
+  ) throws {
+    _stream = try compression_stream(operation: operation, algorithm: algorithm)
+    _buf = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferCapacity)
+    _bufCapacity = bufferCapacity
+    _writeFunc = writeFunc
+  }
+
+  /// Send data to output filter
+  ///
+  /// Processed output will be sent to the output closure.
+  /// A call with empty/nil data is interpreted as finalize().
+  /// Writing non empty/nil data to a finalized stream is an error.
+  ///
+  /// - Parameter data: data to process
+  ///
+  /// - Throws:
+  /// `FilterError.filterProcessError` if an error occurs during processing
+  /// `FilterError.writeToFinalizedFilter` if `data` is not empty/nil, and the
+  /// filter is the finalized state
+  public func write(_ data: Data?) throws {
+    // Finalize if data is empty/nil
+    if data == nil || data!.isEmpty { try finalize() ; return }
+
+    // Fail if already finalized
+    if _finalized { throw FilterError.writeToFinalizedFilter }
+
+    // Process all incoming data
+    try data!.withUnsafeBytes { (src_ptr: UnsafePointer<UInt8>) in
+      _stream.src_size = data!.count
+      _stream.src_ptr = src_ptr
+      while (_stream.src_size > 0) { _ = try process(finalizing: false) }
+    }
+  }
+
+  /// Finalize the stream, i.e. flush all data remaining in the stream
+  ///
+  /// Processed output will be sent to the output closure.
+  /// When all output has been sent, the writingTo closure is called one last time with nil data.
+  /// Once the stream is finalized, writing non empty/nil data to the stream will throw an exception.
+  ///
+  /// - Throws: `FilterError.StreamProcessError` if an error occurs during processing
+  public func finalize() throws {
+    // Do nothing if already finalized
+    if _finalized { return }
+
+    // Finalize stream
+    _stream.src_size = 0
+    var status = COMPRESSION_STATUS_OK
+    while (status != COMPRESSION_STATUS_END) { status = try process(finalizing: true) }
+
+    // Update state
+    _finalized = true
+
+    // Notify end of stream
+    try _writeFunc(nil)
+  }
+
+  // Cleanup resources.  The filter is finalized now if it was not finalized yet.
+  deinit {
+    // Finalize now if not done earlier
+    try? finalize()
+
+    // Cleanup
+    _buf.deallocate()
+    compression_stream_destroy(&_stream)
+  }
+
+  // Call compression_stream_process with current src, and dst set to _buf, then write output to the closure
+  // Return status
+  private func process(finalizing finalize: Bool) throws -> compression_status {
+    // Process current input, and write to buf
+    _stream.dst_ptr = _buf
+    _stream.dst_size = _bufCapacity
+
+    let status = compression_stream_process(&_stream, (finalize ? Int32(COMPRESSION_STREAM_FINALIZE.rawValue) : 0))
+    guard status != COMPRESSION_STATUS_ERROR else { throw FilterError.filterProcessError }
+
+    // Number of bytes written to buf
+    let writtenBytes = _bufCapacity - _stream.dst_size
+
+    // Write output
+    if writtenBytes > 0 {
+      let outData = Data(bytesNoCopy: _buf, count: writtenBytes, deallocator: .none)
+      try _writeFunc(outData)
+    }
+
+    return status
+  }
+
+}
+
+@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
+public class InputFilter {
+  private var _stream: compression_stream
+  private var _buf: Data? = nil // current input data
+  private let _bufCapacity: Int // size to read when refilling _buf
+  private let _readFunc: (Int) throws -> Data?
+  private var _eofReached: Bool = false // did we read end-of-file from the input?
+  private var _endReached: Bool = false // did we reach end-of-file from the decoder stream?
+
+  /// Initialize an input filter
+  ///
+  /// - Parameters:
+  /// - operation: direction of operation
+  /// - algorithm: compression algorithm
+  /// - bufferCapacity: capacity of the internal data buffer
+  /// - readFunc: called to read the input data
+  ///
+  /// - Throws: `FilterError.filterInitError` if filter initialization failed
+  public init(
+    _ operation: FilterOperation,
+    using algorithm: Algorithm,
+    bufferCapacity: Int = 65536,
+    readingFrom readFunc: @escaping (Int) throws -> Data?
+  ) throws {
+    _stream = try compression_stream(operation: operation, algorithm: algorithm)
+    _bufCapacity = bufferCapacity
+    _readFunc = readFunc
+  }
+
+  /// Read processed data from the filter
+  ///
+  /// Input data, when needed, is obtained from the input closure
+  /// When the input closure returns a nil or empty Data object, the filter will be
+  /// finalized, and after all processed data has been read, readData will return nil
+  /// to signal end of input
+  ///
+  /// - Parameter count: max number of bytes to read from the filter
+  ///
+  /// - Returns: a new Data object containing at most `count` output bytes, or nil if no more data is available
+  ///
+  /// - Throws:
+  /// `FilterError.filterProcessError` if an error occurs during processing
+  public func readData(ofLength count: Int) throws -> Data? {
+    // Sanity check
+    precondition(count > 0, "number of bytes to read can't be 0")
+
+    // End reached, return early, nothing to do
+    if _endReached { return nil }
+
+    // Allocate result
+    var result = Data(count: count)
+
+    try result.withUnsafeMutableBytes { (dst_ptr: UnsafeMutablePointer<UInt8>) in
+
+      // Write to result until full, or end reached
+      _stream.dst_size = count
+      _stream.dst_ptr = dst_ptr
+
+      while _stream.dst_size > 0 && !_endReached {
+
+        // Refill _buf if needed, and EOF was not yet read
+        if _stream.src_size == 0 && !_eofReached {
+          _buf = try _readFunc(_bufCapacity) // may be nil
+          // Reset src_size to full _buf size
+          if _buf?.count ?? 0 == 0 { _eofReached = true }
+          _stream.src_size = _buf?.count ?? 0
+        }
+
+        // Process some data
+        if let buf = _buf {
+          try buf.withUnsafeBytes { (src_ptr: UnsafePointer<UInt8>) in
+
+            // Next byte to read
+            _stream.src_ptr = src_ptr + buf.count - _stream.src_size
+
+            let status = compression_stream_process(&_stream, (_eofReached ? Int32(COMPRESSION_STREAM_FINALIZE.rawValue) : 0))
+            guard status != COMPRESSION_STATUS_ERROR else { throw FilterError.filterProcessError }
+            if status == COMPRESSION_STATUS_END { _endReached = true }
+          }
+        }
+        else {
+          let status = compression_stream_process(&_stream, (_eofReached ? Int32(COMPRESSION_STREAM_FINALIZE.rawValue) : 0))
+          guard status != COMPRESSION_STATUS_ERROR else { throw FilterError.filterProcessError }
+          if status == COMPRESSION_STATUS_END { _endReached = true }
+
+        }
+      }
+
+    } // result.withUnsafeMutableBytes
+
+    // Update actual size
+    result.count = count - _stream.dst_size
+    return result
+  }
+
+  // Cleanup resources
+  deinit {
+    compression_stream_destroy(&_stream)
+  }
+
+}
diff --git a/stdlib/public/Darwin/Foundation/JSONEncoder.swift b/stdlib/public/Darwin/Foundation/JSONEncoder.swift
index e5811a0..d871160 100644
--- a/stdlib/public/Darwin/Foundation/JSONEncoder.swift
+++ b/stdlib/public/Darwin/Foundation/JSONEncoder.swift
@@ -53,9 +53,9 @@
 /// `JSONEncoder` facilitates the encoding of `Encodable` values into JSON.
 // NOTE: older overlays had Foundation.JSONEncoder as the ObjC name.
 // The two must coexist, so it was renamed. The old name must not be
-// used in the new runtime. _TtC10Foundation12_JSONEncoder is the
-// mangled name for Foundation._JSONEncoder.
-@_objcRuntimeName(_TtC10Foundation12_JSONEncoder)
+// used in the new runtime. _TtC10Foundation13__JSONEncoder is the
+// mangled name for Foundation.__JSONEncoder.
+@_objcRuntimeName(_TtC10Foundation13__JSONEncoder)
 open class JSONEncoder {
     // MARK: Options
 
@@ -1017,9 +1017,9 @@
 /// `JSONDecoder` facilitates the decoding of JSON into semantic `Decodable` types.
 // NOTE: older overlays had Foundation.JSONDecoder as the ObjC name.
 // The two must coexist, so it was renamed. The old name must not be
-// used in the new runtime. _TtC10Foundation12_JSONDecoder is the
-// mangled name for Foundation._JSONDecoder.
-@_objcRuntimeName(_TtC10Foundation12_JSONDecoder)
+// used in the new runtime. _TtC10Foundation13__JSONDecoder is the
+// mangled name for Foundation.__JSONDecoder.
+@_objcRuntimeName(_TtC10Foundation13__JSONDecoder)
 open class JSONDecoder {
     // MARK: Options
 
@@ -1190,7 +1190,7 @@
             throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: error))
         }
 
-        let decoder = _JSONDecoder(referencing: topLevel, options: self.options)
+        let decoder = __JSONDecoder(referencing: topLevel, options: self.options)
         guard let value = try decoder.unbox(topLevel, as: type) else {
             throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: [], debugDescription: "The given data did not contain a top-level value."))
         }
@@ -1199,9 +1199,12 @@
     }
 }
 
-// MARK: - _JSONDecoder
+// MARK: - __JSONDecoder
 
-fileprivate class _JSONDecoder : Decoder {
+// NOTE: older overlays called this class _JSONDecoder. The two must
+// coexist without a conflicting ObjC class name, so it was renamed.
+// The old name must not be used in the new runtime.
+fileprivate class __JSONDecoder : Decoder {
     // MARK: Properties
 
     /// The decoder's storage.
@@ -1307,7 +1310,7 @@
     // MARK: Properties
 
     /// A reference to the decoder we're reading from.
-    private let decoder: _JSONDecoder
+    private let decoder: __JSONDecoder
 
     /// A reference to the container we're reading from.
     private let container: [String : Any]
@@ -1318,7 +1321,7 @@
     // MARK: - Initialization
 
     /// Initializes `self` by referencing the given decoder and container.
-    fileprivate init(referencing decoder: _JSONDecoder, wrapping container: [String : Any]) {
+    fileprivate init(referencing decoder: __JSONDecoder, wrapping container: [String : Any]) {
         self.decoder = decoder
         switch decoder.options.keyDecodingStrategy {
         case .useDefaultKeys:
@@ -1637,7 +1640,7 @@
         defer { self.decoder.codingPath.removeLast() }
 
         let value: Any = self.container[key.stringValue] ?? NSNull()
-        return _JSONDecoder(referencing: value, at: self.decoder.codingPath, options: self.decoder.options)
+        return __JSONDecoder(referencing: value, at: self.decoder.codingPath, options: self.decoder.options)
     }
 
     public func superDecoder() throws -> Decoder {
@@ -1653,7 +1656,7 @@
     // MARK: Properties
 
     /// A reference to the decoder we're reading from.
-    private let decoder: _JSONDecoder
+    private let decoder: __JSONDecoder
 
     /// A reference to the container we're reading from.
     private let container: [Any]
@@ -1667,7 +1670,7 @@
     // MARK: - Initialization
 
     /// Initializes `self` by referencing the given decoder and container.
-    fileprivate init(referencing decoder: _JSONDecoder, wrapping container: [Any]) {
+    fileprivate init(referencing decoder: __JSONDecoder, wrapping container: [Any]) {
         self.decoder = decoder
         self.container = container
         self.codingPath = decoder.codingPath
@@ -2000,11 +2003,11 @@
 
         let value = self.container[self.currentIndex]
         self.currentIndex += 1
-        return _JSONDecoder(referencing: value, at: self.decoder.codingPath, options: self.decoder.options)
+        return __JSONDecoder(referencing: value, at: self.decoder.codingPath, options: self.decoder.options)
     }
 }
 
-extension _JSONDecoder : SingleValueDecodingContainer {
+extension __JSONDecoder : SingleValueDecodingContainer {
     // MARK: SingleValueDecodingContainer Methods
 
     private func expectNonNull<T>(_ type: T.Type) throws {
@@ -2095,7 +2098,7 @@
 
 // MARK: - Concrete Value Representations
 
-extension _JSONDecoder {
+extension __JSONDecoder {
     /// Returns the given value unboxed from a container.
     fileprivate func unbox(_ value: Any, as type: Bool.Type) throws -> Bool? {
         guard !(value is NSNull) else { return nil }
diff --git a/stdlib/public/SwiftShims/SwiftStddef.h b/stdlib/public/SwiftShims/SwiftStddef.h
index eb7df54..ab6f9dc 100644
--- a/stdlib/public/SwiftShims/SwiftStddef.h
+++ b/stdlib/public/SwiftShims/SwiftStddef.h
@@ -29,11 +29,18 @@
 #endif
 
 // This selects the signed equivalent of the unsigned type chosen for size_t.
+#if __STDC_VERSION__-0 >= 201112l
 typedef __typeof__(_Generic((__swift_size_t)0,                                 \
                             unsigned long long int : (long long int)0,         \
                             unsigned long int : (long int)0,                   \
                             unsigned int : (int)0,                             \
                             unsigned short : (short)0,                         \
                             unsigned char : (signed char)0)) __swift_ssize_t;
+#elif defined(__cplusplus)
+#include <type_traits>
+using __swift_ssize_t = std::make_signed<__swift_size_t>::type;
+#else
+#error "do not have __swift_ssize_t defined"
+#endif
 
 #endif // SWIFT_STDLIB_SHIMS_SWIFT_STDDEF_H
diff --git a/stdlib/public/core/AtomicInt.swift.gyb b/stdlib/public/core/AtomicInt.swift.gyb
index 17d3484..62217f2 100644
--- a/stdlib/public/core/AtomicInt.swift.gyb
+++ b/stdlib/public/core/AtomicInt.swift.gyb
@@ -10,7 +10,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+// NOTE: older runtimes had Swift._stdlib_AtomicInt as the ObjC name.
+// The two must coexist, so it was renamed. The old name must not be
+// used in the new runtime. _TtCs18__stdlib_AtomicInt is the mangled
+// name for Swift.__stdlib_AtomicInt
 @available(swift, deprecated: 4.2, obsoleted: 5.0)
+@_objcRuntimeName(_TtCs18__stdlib_AtomicInt)
 public final class _stdlib_AtomicInt {
   internal var _value: Int
 
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index 761df17..01b9e89 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -668,9 +668,6 @@
   return Bool(Builtin.isUnique(&object))
 }
 
-@_silgen_name("_swift_reallocObject")
-internal func _reallocObject(_ object: UnsafeMutableRawPointer, _ newSizeInBytes: Int) -> UnsafeMutableRawPointer?
-
 /// Returns `true` if `object` is uniquely referenced.
 /// This provides sanity checks on top of the Builtin.
 @_transparent
diff --git a/stdlib/public/core/ClosedRange.swift b/stdlib/public/core/ClosedRange.swift
index 1468ab8..db1b1ff 100644
--- a/stdlib/public/core/ClosedRange.swift
+++ b/stdlib/public/core/ClosedRange.swift
@@ -433,6 +433,7 @@
   /// An equivalent range must be representable as a closed range.
   /// For example, passing an empty range as `other` triggers a runtime error,
   /// because an empty range cannot be represented by a closed range instance.
+  @inlinable
   public init(_ other: Range<Bound>) {
     _precondition(!other.isEmpty, "Can't form an empty closed range")
     let upperBound = other.upperBound.advanced(by: -1)
diff --git a/stdlib/public/core/ManagedBuffer.swift b/stdlib/public/core/ManagedBuffer.swift
index ab5b74c..67c0a8d 100644
--- a/stdlib/public/core/ManagedBuffer.swift
+++ b/stdlib/public/core/ManagedBuffer.swift
@@ -136,30 +136,6 @@
   }
 }
 
-@inline(never)
-public func tryReallocateUniquelyReferenced<Header, Element, Buffer: ManagedBuffer<Header, Element>>(
-  buffer: inout Buffer,
-  newMinimumCapacity: Int
-) -> Bool {
-  precondition(_isBitwiseTakable(Header.self))
-  precondition(_isBitwiseTakable(Element.self))
-  precondition(isKnownUniquelyReferenced(&buffer))
-
-  let newSizeInBytes = MemoryLayout<Header>.stride
-    + newMinimumCapacity * MemoryLayout<Element>.stride
-
-  return withUnsafeMutablePointer(to: &buffer) {
-    $0.withMemoryRebound(to: UnsafeMutableRawPointer.self, capacity: 1) {
-      if let reallocdObject = _reallocObject($0.pointee, newSizeInBytes) {
-        $0.pointee = reallocdObject
-        return true
-      } else {
-        return false
-      }
-    }
-  }
-}
-
 /// Contains a buffer object, and provides access to an instance of
 /// `Header` and contiguous storage for an arbitrary number of
 /// `Element` instances stored in that buffer.
diff --git a/stdlib/public/core/StringStorage.swift b/stdlib/public/core/StringStorage.swift
index d6f2694..a8480ac 100644
--- a/stdlib/public/core/StringStorage.swift
+++ b/stdlib/public/core/StringStorage.swift
@@ -76,9 +76,8 @@
       fallthrough
     case (_cocoaUTF8Encoding, _):
       guard maxLength >= count + 1 else { return 0 }
-      let buffer = UnsafeMutableBufferPointer(start: outputPtr, count: maxLength)
-      _ = buffer.initialize(from: UnsafeBufferPointer(start: start, count: count))
-      buffer[count] = 0
+      outputPtr.initialize(from: start, count: count)
+      outputPtr[count] = 0
       return 1
     default:
       return  _cocoaGetCStringTrampoline(self, outputPtr, maxLength, encoding)
diff --git a/stdlib/public/runtime/SwiftObject.h b/stdlib/public/runtime/SwiftObject.h
index 10e6d68..a730d51 100644
--- a/stdlib/public/runtime/SwiftObject.h
+++ b/stdlib/public/runtime/SwiftObject.h
@@ -88,11 +88,4 @@
 
 #endif
 
-namespace swift {
-
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
-HeapObject *_swift_reallocObject(HeapObject *obj, size_t size);
-
-}
-
 #endif
diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm
index 5ed874c..9c6dfbe 100644
--- a/stdlib/public/runtime/SwiftObject.mm
+++ b/stdlib/public/runtime/SwiftObject.mm
@@ -82,24 +82,6 @@
 #endif
 }
 
-bool isObjCPinned(HeapObject *obj) {
-  #if SWIFT_OBJC_INTEROP
-    /* future: implement checking the relevant objc runtime bits */
-    return true;
-  #else
-    return false;
-  #endif
-}
-
-// returns non-null if realloc was successful
-SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_SPI
-HeapObject *swift::_swift_reallocObject(HeapObject *obj, size_t size) {
- if (isObjCPinned(obj) || obj->refCounts.hasSideTable()) {
-   return nullptr;
- }
- return (HeapObject *)realloc(obj, size);
-}
-
 #if SWIFT_OBJC_INTEROP
 
 /// Replacement for ObjC object_isClass(), which is unavailable on
diff --git a/test/APINotes/Inputs/roundtrip.apinotes b/test/APINotes/Inputs/roundtrip.apinotes
deleted file mode 100644
index 9435acf..0000000
--- a/test/APINotes/Inputs/roundtrip.apinotes
+++ /dev/null
@@ -1,79 +0,0 @@
----
-Name:            AppKit
-Availability:    available
-AvailabilityMsg: ''
-Classes:
-  - Name:            NSCell
-    Availability:    available
-    AvailabilityMsg: ''
-    Methods:
-      - Selector:        init
-        MethodKind:      Instance
-        NullabilityOfRet: U
-        Availability:    available
-        AvailabilityMsg: ''
-        DesignatedInit:  true
-      - Selector:        'initImageCell:'
-        MethodKind:      Instance
-        Nullability:     [ N ]
-        NullabilityOfRet: U
-        Availability:    available
-        AvailabilityMsg: ''
-        DesignatedInit:  true
-      - Selector:        'initTextCell:'
-        MethodKind:      Instance
-        Nullability:     [ N ]
-        NullabilityOfRet: U
-        Availability:    available
-        AvailabilityMsg: ''
-        DesignatedInit:  true
-      - Selector:        'initWithCoder:'
-        MethodKind:      Instance
-        Nullability:     [ N ]
-        NullabilityOfRet: U
-        Availability:    available
-        AvailabilityMsg: ''
-        DesignatedInit:  true
-        Required:        true
-  - Name:            NSView
-    AuditedForNullability: true
-    Availability:    available
-    AvailabilityMsg: ''
-    Methods:
-      - Selector:        'addSubview:'
-        MethodKind:      Instance
-        Nullability:     [ N ]
-        NullabilityOfRet: N
-        Availability:    available
-        AvailabilityMsg: ''
-      - Selector:        'addSubview:positioned:relativeTo:'
-        MethodKind:      Instance
-        Nullability:     [ N, N, O ]
-        NullabilityOfRet: N
-        Availability:    available
-        AvailabilityMsg: ''
-      - Selector:        'beginDraggingSessionWithItems:event:source:'
-        MethodKind:      Instance
-        Nullability:     [ U, U, N ]
-        NullabilityOfRet: N
-        Availability:    available
-        AvailabilityMsg: ''
-    Properties:
-      - Name:            enclosingScrollView
-        Nullability:     O
-        Availability:    available
-        AvailabilityMsg: ''
-      - Name:            makeBackingLayer
-        Nullability:     N
-        Availability:    available
-        AvailabilityMsg: ''
-Functions:
-  - Name:            NSAvailableWindowDepths
-    NullabilityOfRet: N
-    Availability:    available
-    AvailabilityMsg: ''
-Globals:
-  - Name:            NSCalibratedWhiteColorSpace
-    Nullability:     N
-    Availability:    available
-    AvailabilityMsg: ''
diff --git a/test/APINotes/yaml-roundtrip.swift b/test/APINotes/yaml-roundtrip.swift
deleted file mode 100644
index f2a3ada..0000000
--- a/test/APINotes/yaml-roundtrip.swift
+++ /dev/null
@@ -1,7 +0,0 @@
-# RUN: %swift_driver_plain -apinotes -yaml-to-binary -o %t.apinotesc %S/Inputs/roundtrip.apinotes
-# RUN: %swift_driver_plain -apinotes -binary-to-yaml -o %t.apinotes %t.apinotesc
-
-# Note: We don't diff the results because they will change as Clang's
-# API notes support evolves, and we don't want to tie that closely to
-# a specific Clang.
-
diff --git a/test/CircularReferences/protocols.swift b/test/CircularReferences/protocols.swift
new file mode 100644
index 0000000..d071907
--- /dev/null
+++ b/test/CircularReferences/protocols.swift
@@ -0,0 +1,12 @@
+// RUN: %target-typecheck-verify-swift -debug-cycles 2>&1 | %FileCheck --allow-empty %s
+
+// Verify that protocol where clause lookups don't cause cyclic dependencies.
+
+// expected-no-diagnostics
+
+class C { }
+protocol Q { }
+protocol P where Self : Q, Self : C { }
+
+// CHECK-NOT: CYCLE DETECTED
+
diff --git a/test/ClangImporter/Inputs/app-bridging-header-to-pch.h b/test/ClangImporter/Inputs/app-bridging-header-to-pch.h
index f8d56b7..c6fb28d 100644
--- a/test/ClangImporter/Inputs/app-bridging-header-to-pch.h
+++ b/test/ClangImporter/Inputs/app-bridging-header-to-pch.h
@@ -1,3 +1,10 @@
+
+#ifndef app_bridging_header_to_pch_h
+#define app_bridging_header_to_pch_h
+
 static inline int app_function(int x) {
   return x + 27;
 }
+
+#endif
+
diff --git a/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h b/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h
index c027342..810736b 100644
--- a/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h
+++ b/test/ClangImporter/Inputs/chained-unit-test-bridging-header-to-pch.h
@@ -1,5 +1,12 @@
+
+#ifndef chained_unit_test_bridging_header_to_pch_h
+#define chained_unit_test_bridging_header_to_pch_h
+
 #include "app-bridging-header-to-pch.h"
 
 static inline int unit_test_function(int x) {
   return x + 28;
 }
+
+#endif
+
diff --git a/test/ClangImporter/cfuncs_parse.swift b/test/ClangImporter/cfuncs_parse.swift
index e5e2cb1..ba91c59 100644
--- a/test/ClangImporter/cfuncs_parse.swift
+++ b/test/ClangImporter/cfuncs_parse.swift
@@ -1,3 +1,4 @@
+// XFAIL: CPU=powerpc64le
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -I %S/Inputs %s
 
 import cfuncs
diff --git a/test/ClangImporter/inlinable_bitfields.swift b/test/ClangImporter/inlinable_bitfields.swift
index ea417b6..be6ede2 100644
--- a/test/ClangImporter/inlinable_bitfields.swift
+++ b/test/ClangImporter/inlinable_bitfields.swift
@@ -10,4 +10,4 @@
 
 // Just make sure this is a definition and not a declaration...
 
-// CHECK: define internal i32 @"$ModRM$rm$getter"
+// CHECK: define internal{{( zeroext)?}} i32 @"$ModRM$rm$getter"
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index 4a10050..971d721 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -659,7 +659,7 @@
 struct UnaryOp {}
 
 _ = -UnaryOp() // expected-error {{unary operator '-' cannot be applied to an operand of type 'UnaryOp'}}
-// expected-note@-1 {{overloads for '-' exist with these partially matching parameter lists: (Double), (Float), (Float80)}}
+// expected-note@-1 {{overloads for '-' exist with these partially matching parameter lists: (Double), (Float)}}
 
 
 // <rdar://problem/23433271> Swift compiler segfault in failure diagnosis
diff --git a/test/Constraints/sr9626.swift b/test/Constraints/sr9626.swift
new file mode 100644
index 0000000..049951b
--- /dev/null
+++ b/test/Constraints/sr9626.swift
@@ -0,0 +1,22 @@
+// RUN: %target-swift-frontend -emit-sil -verify %s | %FileCheck %s
+
+class BaseClass {}
+class SubClass: BaseClass {}
+struct Box<T> { init(_: T.Type) {} }
+
+
+func test1<T>(box: Box<T>) -> T.Type {
+  return T.self
+}
+
+func test2<T: BaseClass>(box: Box<T>) -> T.Type {
+  return T.self
+}
+
+// CHECK: [[F1:%.*]] = function_ref @$s6sr96263BoxVyACyxGxmcfC
+// CHECK-NEXT: apply [[F1]]<SubClass>({{.*}}, {{.*}})
+_ = test1(box: .init(SubClass.self))
+
+// CHECK: [[F2:%.*]] = function_ref @$s6sr96265test23boxxmAA3BoxVyxG_tAA9BaseClassCRbzlF
+// CHECK-NEXT: apply [[F2]]<SubClass>({{.*}})
+_ = test2(box: .init(SubClass.self))
diff --git a/test/Driver/fuzzer.swift b/test/Driver/fuzzer.swift
index 3903892..d83fad2 100644
--- a/test/Driver/fuzzer.swift
+++ b/test/Driver/fuzzer.swift
@@ -1,4 +1,5 @@
 // UNSUPPORTED: win32
+// UNSUPPORTED: CPU=powerpc64le
 // RUN: %swiftc_driver -driver-print-jobs -sanitize=fuzzer,address -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ %s | %FileCheck -check-prefix=LIBFUZZER %s
 
 // LIBFUZZER: libclang_rt.fuzzer
diff --git a/test/IDE/clang-importing/Inputs/bridge.h b/test/IDE/clang-importing/Inputs/bridge.h
index 920e7aa..77a08a9 100644
--- a/test/IDE/clang-importing/Inputs/bridge.h
+++ b/test/IDE/clang-importing/Inputs/bridge.h
@@ -1 +1,4 @@
+@import Foundation;
 @import somemod1;
+
+void func_in_bridge(void);
diff --git a/test/IDE/clang-importing/complete_with_clang_comments.swift b/test/IDE/clang-importing/complete_with_clang_comments.swift
index dfa17fa..b3816c0 100644
--- a/test/IDE/clang-importing/complete_with_clang_comments.swift
+++ b/test/IDE/clang-importing/complete_with_clang_comments.swift
@@ -1,5 +1,7 @@
-// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=TOP -code-completion-comments=true \
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=TOP -code-completion-comments=true \
 // RUN:    -import-objc-header %S/Inputs/bridge.h -I %S/Inputs/somemod1 -I %S/Inputs/somemod2 | %FileCheck %s -check-prefix=CHECK-TOP
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -source-filename %s -code-completion-token=TOP -code-completion-comments=true \
+// RUN:    -import-objc-header %S/Inputs/bridge.h -pch-output-dir %t.pch -I %S/Inputs/somemod1 -I %S/Inputs/somemod2 | %FileCheck %s -check-prefix=CHECK-TOP
 
 // REQUIRES: objc_interop
 
diff --git a/test/IDE/print_ast_overlay.swift b/test/IDE/print_ast_overlay.swift
index 7a60b6c..53233c4 100644
--- a/test/IDE/print_ast_overlay.swift
+++ b/test/IDE/print_ast_overlay.swift
@@ -1,17 +1,16 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-build-swift -emit-module -module-name Foo -o %t -F %S/Inputs/mock-sdk %s
+// RUN: %target-build-swift -emit-module -module-name Foo -o %t -F %S/Inputs/mock-sdk %s -Xfrontend -enable-objc-interop -Xfrontend -disable-objc-attr-requires-foundation-module
 //
-// RUN: %target-swift-ide-test -print-module -source-filename %s -I %t -F %S/Inputs/mock-sdk -module-to-print=Foo -access-filter-public > %t.printed.txt
+// RUN: %target-swift-ide-test -print-module -source-filename %s -I %t -F %S/Inputs/mock-sdk -module-to-print=Foo -access-filter-public -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_WITH_OVERLAY -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_NO_INTERNAL -strict-whitespace < %t.printed.txt
 //
-// RUN: %target-swift-ide-test -print-module -source-filename %s -I %t -F %S/Inputs/mock-sdk -module-to-print=Foo.FooSub > %t.printed.txt
+// RUN: %target-swift-ide-test -print-module -source-filename %s -I %t -F %S/Inputs/mock-sdk -module-to-print=Foo.FooSub -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_WITHOUT_OVERLAY -strict-whitespace < %t.printed.txt
 
-// XFAIL: linux, freebsd
-
-// RUN: %target-swift-ide-test -print-module -source-filename %s -I %t -F %S/Inputs/mock-sdk -module-to-print=Foo -access-filter-public -annotate-print > %t.annotated.txt
+// RUN: %target-swift-ide-test -print-module -source-filename %s -I %t -F %S/Inputs/mock-sdk -module-to-print=Foo -access-filter-public -annotate-print -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.annotated.txt
 // RUN: %FileCheck %s -check-prefix=PASS_ANNOTATED -strict-whitespace < %t.annotated.txt
+
 // REQUIRES: executable_test
 
 @_exported import Foo
diff --git a/test/IDE/print_ast_tc_decls.swift b/test/IDE/print_ast_tc_decls.swift
index 147fbc5..6fc4589 100644
--- a/test/IDE/print_ast_tc_decls.swift
+++ b/test/IDE/print_ast_tc_decls.swift
@@ -1,16 +1,16 @@
 // RUN: %empty-directory(%t)
 //
 // Build swift modules this test depends on.
-// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/foo_swift_module.swift
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/foo_swift_module.swift -enable-objc-interop -disable-objc-attr-requires-foundation-module
 //
 // FIXME: BEGIN -enable-source-import hackaround
-// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -disable-objc-attr-requires-foundation-module
+// RUN:  %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t  %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -enable-objc-interop -disable-objc-attr-requires-foundation-module
 // FIXME: END -enable-source-import hackaround
 //
 // This file should not have any syntax or type checker errors.
-// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -typecheck -verify %s -F %S/Inputs/mock-sdk -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -typecheck -verify %s -F %S/Inputs/mock-sdk -enable-objc-interop -disable-objc-attr-requires-foundation-module
 //
-// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -skip-deinit=false -print-ast-typechecked -source-filename %s -F %S/Inputs/mock-sdk -function-definitions=false -prefer-type-repr=false -print-implicit-attrs=true -disable-objc-attr-requires-foundation-module > %t.printed.txt
+// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -skip-deinit=false -print-ast-typechecked -source-filename %s -F %S/Inputs/mock-sdk -function-definitions=false -prefer-type-repr=false -print-implicit-attrs=true -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_COMMON -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_PRINT_AST -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_RW_PROP_GET_SET -strict-whitespace < %t.printed.txt
@@ -21,7 +21,7 @@
 // RUN: %FileCheck %s -check-prefix=PREFER_TYPE_PRINTING -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_QUAL_UNQUAL -strict-whitespace < %t.printed.txt
 //
-// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -skip-deinit=false -print-ast-typechecked -source-filename %s -F %S/Inputs/mock-sdk -function-definitions=false -prefer-type-repr=true -print-implicit-attrs=true -disable-objc-attr-requires-foundation-module > %t.printed.txt
+// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -skip-deinit=false -print-ast-typechecked -source-filename %s -F %S/Inputs/mock-sdk -function-definitions=false -prefer-type-repr=true -print-implicit-attrs=true -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_COMMON -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_PRINT_AST -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_RW_PROP_GET_SET -strict-whitespace < %t.printed.txt
@@ -32,8 +32,8 @@
 // RUN: %FileCheck %s -check-prefix=PREFER_TYPE_REPR_PRINTING -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_QUAL_UNQUAL -strict-whitespace < %t.printed.txt
 //
-// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -emit-module -o %t -F %S/Inputs/mock-sdk -disable-objc-attr-requires-foundation-module %s
-// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -skip-deinit=false -print-module -source-filename %s -F %S/Inputs/mock-sdk -module-to-print=print_ast_tc_decls -print-implicit-attrs=true -disable-objc-attr-requires-foundation-module > %t.printed.txt
+// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -emit-module -o %t -F %S/Inputs/mock-sdk -enable-objc-interop -disable-objc-attr-requires-foundation-module %s
+// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -swift-version 4 -skip-deinit=false -print-module -source-filename %s -F %S/Inputs/mock-sdk -module-to-print=print_ast_tc_decls -print-implicit-attrs=true -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_COMMON -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_PRINT_MODULE_INTERFACE -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_RW_PROP_NO_GET_SET -strict-whitespace < %t.printed.txt
@@ -45,20 +45,20 @@
 // RUN: %FileCheck %s -check-prefix=PASS_QUAL_UNQUAL -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_EXPLODE_PATTERN -strict-whitespace < %t.printed.txt
 //
-// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -skip-deinit=false -print-module -source-filename %s -F %S/Inputs/mock-sdk -I %t -module-to-print=print_ast_tc_decls -synthesize-sugar-on-types=true -print-implicit-attrs=true -disable-objc-attr-requires-foundation-module > %t.printed.txt
+// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -skip-deinit=false -print-module -source-filename %s -F %S/Inputs/mock-sdk -I %t -module-to-print=print_ast_tc_decls -synthesize-sugar-on-types=true -print-implicit-attrs=true -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_PRINT_MODULE_INTERFACE -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_QUAL_UNQUAL -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=SYNTHESIZE_SUGAR_ON_TYPES -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_EXPLODE_PATTERN -strict-whitespace < %t.printed.txt
 
-// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -skip-deinit=false -print-module -source-filename %s -F %S/Inputs/mock-sdk -I %t -module-to-print=print_ast_tc_decls -synthesize-sugar-on-types=true -fully-qualified-types-if-ambiguous=true -print-implicit-attrs=true -disable-objc-attr-requires-foundation-module > %t.printed.txt
+// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -skip-deinit=false -print-module -source-filename %s -F %S/Inputs/mock-sdk -I %t -module-to-print=print_ast_tc_decls -synthesize-sugar-on-types=true -fully-qualified-types-if-ambiguous=true -print-implicit-attrs=true -enable-objc-interop -disable-objc-attr-requires-foundation-module > %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_PRINT_MODULE_INTERFACE -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=PASS_QUAL_IF_AMBIGUOUS -strict-whitespace < %t.printed.txt
 // RUN: %FileCheck %s -check-prefix=SYNTHESIZE_SUGAR_ON_TYPES -strict-whitespace < %t.printed.txt
 // FIXME: %FileCheck %s -check-prefix=PASS_EXPLODE_PATTERN -strict-whitespace < %t.printed.txt
 
 // FIXME: rdar://problem/19648117 Needs splitting objc parts out
-// XFAIL: linux, freebsd
+// REQUIRES: objc_interop
 
 import Bar
 import ObjectiveC
diff --git a/test/IDE/print_ast_typechecked.swift b/test/IDE/print_ast_typechecked.swift
index 3b20e5d..e5200f0 100644
--- a/test/IDE/print_ast_typechecked.swift
+++ b/test/IDE/print_ast_typechecked.swift
@@ -15,3 +15,6 @@
 // CHECK1: {{^}}  var InternalVar1: Int, InternalVar2: Int{{$}}
 // CHECK1-NOT: private
 // CHECK1: {{^}}  var (InternalTuple1, InternalTuple2): (Int, Int){{$}}
+
+// RUN: %target-swift-ide-test -fully-qualified-types -print-ast-typechecked -access-filter-internal -source-filename %s | %FileCheck %s -check-prefix=FULLY_QUAL
+// FULLY_QUAL: public var PublicVar: Swift.Int
diff --git a/test/IDE/print_clang_decls.swift b/test/IDE/print_clang_decls.swift
index ce984e4..ecc6a8f 100644
--- a/test/IDE/print_clang_decls.swift
+++ b/test/IDE/print_clang_decls.swift
@@ -1,12 +1,12 @@
 // RUN: %empty-directory(%t)
 
-// XFAIL: linux, freebsd
+// REQUIRES: objc_interop
 
 // This file deliberately does not use %clang-importer-sdk for most RUN lines.
 // Instead, it generates custom overlay modules itself, and uses -I %t when it
 // wants to use them.
 
-// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -disable-objc-attr-requires-foundation-module
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift -enable-objc-interop -disable-objc-attr-requires-foundation-module
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
 // RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -print-module -source-filename %s -module-to-print=ctypes -function-definitions=false -prefer-type-repr=true > %t.printed.txt
diff --git a/test/IDE/print_clang_header.swift b/test/IDE/print_clang_header.swift
index 2faccf8..8ad2cdf 100644
--- a/test/IDE/print_clang_header.swift
+++ b/test/IDE/print_clang_header.swift
@@ -1,25 +1,25 @@
 // FIXME: rdar://problem/19648117 Needs splitting objc parts out
-// XFAIL: linux, freebsd
+// REQUIRES: objc_interop
 
 // RUN: echo '#include "header-to-print.h"' > %t.m
-// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.m -I %S/Inputs/print_clang_header > %t.txt
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments -enable-objc-interop -disable-objc-attr-requires-foundation-module --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.m -I %S/Inputs/print_clang_header > %t.txt
 // RUN: diff -u %S/Inputs/print_clang_header/header-to-print.h.printed.txt %t.txt
 
 // RUN: %clang %target-cc-options -isysroot %clang-importer-sdk-path -fmodules -x objective-c-header %S/Inputs/print_clang_header/header-to-print.h -o %t.h.pch
 // RUN: touch %t.empty.m
-// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.empty.m -I %S/Inputs/print_clang_header -include %t.h > %t.with-pch.txt
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments -enable-objc-interop -disable-objc-attr-requires-foundation-module --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.empty.m -I %S/Inputs/print_clang_header -include %t.h > %t.with-pch.txt
 // RUN: diff -u %S/Inputs/print_clang_header/header-to-print.h.command-line-include.printed.txt %t.with-pch.txt
-// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.empty.m -I %S/Inputs/print_clang_header -include %S/Inputs/print_clang_header/header-to-print.h > %t.with-include.txt
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments -enable-objc-interop -disable-objc-attr-requires-foundation-module --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.empty.m -I %S/Inputs/print_clang_header -include %S/Inputs/print_clang_header/header-to-print.h > %t.with-include.txt
 // RUN: diff -u %S/Inputs/print_clang_header/header-to-print.h.command-line-include.printed.txt %t.with-include.txt
 
 // RUN: echo '#include <Foo/header-to-print.h>' > %t.framework.m
 // RUN: sed -e "s:INPUT_DIR:%S/Inputs/print_clang_header:g" -e "s:OUT_DIR:%t:g" %S/Inputs/print_clang_header/Foo-vfsoverlay.yaml > %t.yaml
-// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.framework.m -F %t -ivfsoverlay %t.yaml -Xclang -fmodule-name=Foo > %t.framework.txt
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments -enable-objc-interop -disable-objc-attr-requires-foundation-module --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.framework.m -F %t -ivfsoverlay %t.yaml -Xclang -fmodule-name=Foo > %t.framework.txt
 // RUN: diff -u %S/Inputs/print_clang_header/header-to-print.h.printed.txt %t.framework.txt
 
 // Test header interface printing from a clang module, with the preprocessing record enabled before the CC args.
-// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments -Xcc -Xclang -Xcc -detailed-preprocessing-record --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.framework.m -F %t -ivfsoverlay %t.yaml > %t.module.txt
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments -Xcc -Xclang -Xcc -detailed-preprocessing-record -enable-objc-interop -disable-objc-attr-requires-foundation-module --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.framework.m -F %t -ivfsoverlay %t.yaml > %t.module.txt
 // RUN: diff -u %S/Inputs/print_clang_header/header-to-print.h.module.printed.txt %t.module.txt
 // Test header interface printing from a clang module, with the preprocessing record enabled by the CC args.
-// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.framework.m -F %t -ivfsoverlay %t.yaml -Xclang -detailed-preprocessing-record > %t.module2.txt
+// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -source-filename %s -print-header -header-to-print %S/Inputs/print_clang_header/header-to-print.h -print-regular-comments -enable-objc-interop -disable-objc-attr-requires-foundation-module --cc-args %target-cc-options -isysroot %clang-importer-sdk-path -fsyntax-only %t.framework.m -F %t -ivfsoverlay %t.yaml -Xclang -detailed-preprocessing-record > %t.module2.txt
 // RUN: diff -u %S/Inputs/print_clang_header/header-to-print.h.module.printed.txt %t.module2.txt
diff --git a/test/IDE/print_usrs.swift b/test/IDE/print_usrs.swift
index 10af321..50c4d91 100644
--- a/test/IDE/print_usrs.swift
+++ b/test/IDE/print_usrs.swift
@@ -1,6 +1,12 @@
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -disable-objc-attr-requires-foundation-module -enable-objc-interop %s
 // RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -enable-objc-interop -print-usrs -source-filename %s | %FileCheck %s -strict-whitespace
 
+#if os(Windows) && (arch(arm64) || arch(x86_64))
+typealias ObjCEnumType = Int32
+#else
+typealias ObjCEnumType = Int
+#endif
+
 import macros
 
 // CHECK: [[@LINE+1]]:8 s:14swift_ide_test1SV{{$}}
@@ -197,7 +203,7 @@
   func instanceFunc1(_ a: Int) {
 
     // CHECK: [[@LINE+1]]:16 s:14swift_ide_test10ObjCClass1C13instanceFunc1yySiF9LocalEnumL_O
-    @objc enum LocalEnum : Int {
+    @objc enum LocalEnum : ObjCEnumType {
       // CHECK: [[@LINE+1]]:12 s:14swift_ide_test10ObjCClass1C13instanceFunc1yySiF9LocalEnumL_O8someCaseyA2FmF
       case someCase
     }
@@ -240,7 +246,7 @@
 }
 
 // CHECK: [[@LINE+1]]:12 c:@M@swift_ide_test@E@ObjCEnum{{$}}
-@objc enum ObjCEnum : Int {
+@objc enum ObjCEnum : ObjCEnumType {
 
   // CHECK: [[@LINE+1]]:8 c:@M@swift_ide_test@E@ObjCEnum@ObjCEnumAmazingCase{{$}}
   case amazingCase
diff --git a/test/IRGen/Inputs/multithread_resilience_other.swift b/test/IRGen/Inputs/multithread_resilience_other.swift
new file mode 100644
index 0000000..c76e041
--- /dev/null
+++ b/test/IRGen/Inputs/multithread_resilience_other.swift
@@ -0,0 +1,3 @@
+extension Defaultable {
+  public func defaulted() {}
+}
diff --git a/test/IRGen/big_types_corner_cases.swift b/test/IRGen/big_types_corner_cases.swift
index 759573f..ef49f6c 100644
--- a/test/IRGen/big_types_corner_cases.swift
+++ b/test/IRGen/big_types_corner_cases.swift
@@ -1,4 +1,4 @@
-
+// XFAIL: CPU=powerpc64le
 // RUN: %target-swift-frontend -enable-large-loadable-types %s -emit-ir | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
 // REQUIRES: optimized_stdlib
 
diff --git a/test/IRGen/big_types_tests.sil b/test/IRGen/big_types_tests.sil
index 1925601..f956e07 100644
--- a/test/IRGen/big_types_tests.sil
+++ b/test/IRGen/big_types_tests.sil
@@ -1,9 +1,9 @@
-// RUN: %target-swift-frontend -I %S/Inputs/abi %s -emit-ir -enable-large-loadable-types | %FileCheck %s
+// RUN: %target-swift-frontend -I %S/Inputs/abi %s -emit-ir -enable-large-loadable-types -sil-verify-all | %FileCheck %s
 
 // REQUIRES: CPU=x86_64
 // REQUIRES: OS=macosx
 
-sil_stage canonical
+sil_stage lowered
 import Builtin
 import Swift
 
@@ -29,3 +29,16 @@
   %ret = tuple ()
   return %ret : $()
 }
+
+sil @capture : $@convention(thin) (@guaranteed BigStruct, Builtin.Int1) -> ()
+
+sil @test_partial_apply_stack : $@convention(thin) (@owned BigStruct, Builtin.Int1) -> () {
+entry(%x : $BigStruct, %i : $Builtin.Int1):
+  %f = function_ref @capture : $@convention(thin) (@guaranteed BigStruct, Builtin.Int1) -> ()
+  %p = partial_apply [callee_guaranteed] [on_stack] %f(%i) : $@convention(thin) (@guaranteed BigStruct, Builtin.Int1) -> ()
+  %m = mark_dependence %p : $@noescape @callee_guaranteed (@guaranteed BigStruct) -> () on %x : $BigStruct
+  %c = convert_function %m : $@noescape @callee_guaranteed (@guaranteed BigStruct) -> () to $@noescape @callee_guaranteed (@guaranteed BigStruct) -> (@error Error)
+  dealloc_stack %p : $@noescape @callee_guaranteed (@guaranteed BigStruct) -> ()
+  %ret = tuple ()
+  return %ret : $()
+}
diff --git a/test/IRGen/clang_inline_opt.swift b/test/IRGen/clang_inline_opt.swift
index db79880..4bde0f1 100644
--- a/test/IRGen/clang_inline_opt.swift
+++ b/test/IRGen/clang_inline_opt.swift
@@ -7,7 +7,7 @@
 // Sanity check that we tell Clang to generate optimizable code when
 // we're optimizing.
 
-// CHECK: define internal i32 @return7() [[CLANG_ATTRS:#[0-9]+]] {
+// CHECK: define internal{{( zeroext)?}} i32 @return7() [[CLANG_ATTRS:#[0-9]+]] {
 
 // CHECK: attributes [[CLANG_ATTRS]] = {
 // CHECK-NOT: noinline
diff --git a/test/IRGen/class_resilience_objc.swift b/test/IRGen/class_resilience_objc.swift
index 236ecbc..a6a5ce4 100644
--- a/test/IRGen/class_resilience_objc.swift
+++ b/test/IRGen/class_resilience_objc.swift
@@ -1,6 +1,7 @@
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -emit-ir -o - -primary-file %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
 
 // XFAIL: CPU=armv7k
+// XFAIL: CPU=powerpc64le
 
 // CHECK: %swift.type = type { [[INT:i32|i64]] }
 
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index 2975d77..2b576ee8 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -252,7 +252,8 @@
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s15enum_resilience25resilientEnumPartialApplyyySi0c1_A06MediumOXEF"(i8*, %swift.opaque*)
 public func resilientEnumPartialApply(_ f: (Medium) -> Int) {
 
-// CHECK:     [[CONTEXT:%.*]] = call noalias %swift.refcounted* @swift_allocObject
+// CHECK:     [[STACKALLOC:%.*]] = alloca i8
+// CHECK:     [[CONTEXT:%.*]] = bitcast i8* [[STACKALLOC]] to %swift.opaque*
 // CHECK:     call swiftcc void @"$s15enum_resilience13reabstractionyyx010resilient_A06MediumOXElF"(i8* bitcast (void (%TSi*, %swift.opaque*, %swift.refcounted*)* @"$s14resilient_enum6MediumOSiIgnd_ACSiIegnr_TRTA" to i8*), %swift.opaque* [[CONTEXT:%.*]], %swift.type* @"$sSiN")
   reabstraction(f)
 
diff --git a/test/IRGen/errors.sil b/test/IRGen/errors.sil
index a2b21c6..f393b0a 100644
--- a/test/IRGen/errors.sil
+++ b/test/IRGen/errors.sil
@@ -1,3 +1,4 @@
+// XFAIL: CPU=powerpc64le
 // RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime --check-prefix=CHECK-%target-cpu
 
 sil_stage canonical
diff --git a/test/IRGen/multithread_resilience.swift b/test/IRGen/multithread_resilience.swift
new file mode 100644
index 0000000..13c6b56
--- /dev/null
+++ b/test/IRGen/multithread_resilience.swift
@@ -0,0 +1,9 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience -enable-testing
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience -enable-resilience
+// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience -enable-testing -enable-resilience
+
+public protocol Defaultable {
+  func defaulted()
+}
diff --git a/test/IRGen/objc_bridge.swift b/test/IRGen/objc_bridge.swift
index 12fb2e8..6425f31 100644
--- a/test/IRGen/objc_bridge.swift
+++ b/test/IRGen/objc_bridge.swift
@@ -100,7 +100,7 @@
 
 // CHECK: @_PROPERTIES__TtC11objc_bridge3Bas = private constant { i32, i32, [5 x { i8*, i8* }] } {
 
-// CHECK: [[OBJC_BLOCK_PROPERTY:@.*]] = private unnamed_addr constant [11 x i8] c"T@?,N,C,Vx\00"
+// CHECK: [[OBJC_BLOCK_PROPERTY:@.*]] = private unnamed_addr constant [8 x i8] c"T@?,N,C\00"
 // CHECK: @_PROPERTIES__TtC11objc_bridge21OptionalBlockProperty = private constant {{.*}} [[OBJC_BLOCK_PROPERTY]]
 
 func getDescription(_ o: NSObject) -> String {
diff --git a/test/IRGen/objc_property_attrs.swift b/test/IRGen/objc_property_attrs.swift
index c39824b..c9934cb 100644
--- a/test/IRGen/objc_property_attrs.swift
+++ b/test/IRGen/objc_property_attrs.swift
@@ -50,11 +50,11 @@
 
   // -- Bridged value types
 
-  // nonatomic, copy, ivar k
-  // CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,C,Vk\00"
+  // nonatomic, copy
+  // CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,C\00"
   @objc var k: String = ""
-  // nonatomic, readonly, ivar l
-  // CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,R,Vl\00"
+  // nonatomic, readonly
+  // CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,R\00"
   @objc let l: String? = nil
 
   // -- Protocol types:
diff --git a/test/IRGen/objc_simd.sil b/test/IRGen/objc_simd.sil
index d257c4f..b037f54 100644
--- a/test/IRGen/objc_simd.sil
+++ b/test/IRGen/objc_simd.sil
@@ -57,7 +57,7 @@
 // armv7s-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { float, float, float, float } @simd_native_args(float, float, float, float)
 // armv7k-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { float, float, float, float } @simd_native_args(float, float, float, float)
 // powerpc64-LABEL: define{{( dllexport)?}}{{( protected)?}} void @simd_native_args(%T4simd6float4V* noalias nocapture sret, %T4simd6float4V* noalias nocapture dereferenceable({{.*}}))
-// powerpc64le-LABEL: define{{( dllexport)?}}{{( protected)?}} void @simd_native_args(%T4simd6float4V* noalias nocapture sret, %T4simd6float4V* noalias nocapture dereferenceable({{.*}}))
+// powerpc64le-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { float, float, float, float } @simd_native_args(float, float, float, float)
 // s390x-LABEL: define{{( dllexport)?}}{{( protected)?}} void @simd_native_args(%T4simd6float4V* noalias nocapture sret, %T4simd6float4V* noalias nocapture dereferenceable({{.*}}))
 sil @simd_native_args : $@convention(thin) (float4) -> float4 {
 entry(%x : $float4):
diff --git a/test/IRGen/partial_apply.sil b/test/IRGen/partial_apply.sil
index 7e443c2..87974e3 100644
--- a/test/IRGen/partial_apply.sil
+++ b/test/IRGen/partial_apply.sil
@@ -10,6 +10,9 @@
 sil @$s13partial_apply10SwiftClassCfD : $@convention(method) (SwiftClass) -> ()
 
 sil @partially_applyable_to_class : $@convention(thin) (@owned SwiftClass) -> ()
+sil @partially_applyable_to_two_classes : $@convention(thin) (@owned SwiftClass, @owned SwiftClass) -> ()
+
+sil @use_closure : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
 
 // CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @partial_apply_class(%T13partial_apply10SwiftClassC*) {{.*}} {
 // CHECK: entry:
@@ -24,6 +27,53 @@
   return %g : $@callee_owned () -> ()
 }
 
+// CHECK: define{{.*}} swiftcc void @partial_apply_class_on_stack(%T13partial_apply10SwiftClassC*)
+// CHECK: entry:
+// CHECK:   [[CTX:%.*]] = bitcast %T13partial_apply10SwiftClassC* %0 to %swift.opaque*
+// CHECK:   call swiftcc void @use_closure(i8* bitcast (void (%swift.refcounted*)* @"$s28partially_applyable_to_classTA.1" to i8*), %swift.opaque* [[CTX]])
+// CHECK:   call void bitcast (void (%swift.refcounted*)* @swift_release to void (%T13partial_apply10SwiftClassC*)*)(%T13partial_apply10SwiftClassC* %0)
+// CHECK:   ret void
+// CHECK: }
+
+sil @partial_apply_class_on_stack : $@convention(thin) (@owned SwiftClass) -> () {
+entry(%a : $SwiftClass):
+  %f = function_ref @partially_applyable_to_class : $@convention(thin) (@owned SwiftClass) -> ()
+  %c = partial_apply [callee_guaranteed] [on_stack] %f(%a) : $@convention(thin) (@owned SwiftClass) -> ()
+  %use = function_ref @use_closure : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  apply %use(%c) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  dealloc_stack %c : $@noescape @callee_guaranteed () ->()
+  strong_release %a : $SwiftClass
+  %t = tuple()
+  return %t : $()
+}
+
+// CHECK: define{{.*}} swiftcc void @partial_apply_two_classes_on_stack(%T13partial_apply10SwiftClassC*, %T13partial_apply10SwiftClassC*)
+// CHECK: entry:
+// CHECK:   [[CTX:%.*]] = alloca i8, i64 32, align 16
+// CHECK:   [[CTX2:%.*]] = bitcast i8* [[CTX]] to %swift.opaque*
+// CHECK:   [[LAYOUT:%.*]] = bitcast %swift.opaque* [[CTX2]] to <{ %swift.refcounted, %T13partial_apply10SwiftClassC*, %T13partial_apply10SwiftClassC* }>*
+// CHECK:   [[CAPTURE1:%.*]] = getelementptr inbounds <{ %swift.refcounted, %T13partial_apply10SwiftClassC*, %T13partial_apply10SwiftClassC* }>, <{ %swift.refcounted, %T13partial_apply10SwiftClassC*, %T13partial_apply10SwiftClassC* }>* [[LAYOUT]], i32 0, i32 1
+// CHECK:   store %T13partial_apply10SwiftClassC* %0, %T13partial_apply10SwiftClassC** [[CAPTURE1]], align 8
+// CHECK:   [[CAPTURE2:%.*]] = getelementptr inbounds <{ %swift.refcounted, %T13partial_apply10SwiftClassC*, %T13partial_apply10SwiftClassC* }>, <{ %swift.refcounted, %T13partial_apply10SwiftClassC*, %T13partial_apply10SwiftClassC* }>* [[LAYOUT]], i32 0, i32 2
+// CHECK:   store %T13partial_apply10SwiftClassC* %1, %T13partial_apply10SwiftClassC** [[CAPTURE2]], align 8
+// CHECK:   call swiftcc void @use_closure(i8* bitcast (void (%swift.refcounted*)* @"$s34partially_applyable_to_two_classesTA" to i8*), %swift.opaque* [[CTX2]])
+// CHECK:   call void bitcast (void (%swift.refcounted*)* @swift_release to void (%T13partial_apply10SwiftClassC*)*)(%T13partial_apply10SwiftClassC* %0)
+// CHECK:   call void bitcast (void (%swift.refcounted*)* @swift_release to void (%T13partial_apply10SwiftClassC*)*)(%T13partial_apply10SwiftClassC* %1)
+// CHECK:   ret void
+// CHECK: }
+
+sil @partial_apply_two_classes_on_stack : $@convention(thin) (@owned SwiftClass, @owned SwiftClass) -> () {
+entry(%a : $SwiftClass, %b: $SwiftClass):
+  %f = function_ref @partially_applyable_to_two_classes : $@convention(thin) (@owned SwiftClass, @owned SwiftClass) -> ()
+  %c = partial_apply [callee_guaranteed] [on_stack] %f(%a, %b) : $@convention(thin) (@owned SwiftClass, @owned SwiftClass) -> ()
+  %use = function_ref @use_closure : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  apply %use(%c) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  dealloc_stack %c : $@noescape @callee_guaranteed () ->()
+  strong_release %a : $SwiftClass
+  strong_release %b : $SwiftClass
+  %t = tuple()
+  return %t : $()
+}
 //
 // Check that partially applied generic parameters are correctly substituted
 // in the forwarder.
@@ -552,4 +602,27 @@
   return %5 : $@callee_guaranteed () -> (@owned A1, @error Error)
 }
 
+sil @capture_class : $@convention(thin) (@guaranteed A3) -> ()
+
+// CHECK-LABEL: define{{.*}} swiftcc i8* @partial_apply_stack_in_coroutine(i8* {{.*}}, %T13partial_apply2A3C*)
+// CHECK: entry:
+// CHECK:   [[CLOSURE_CONTEXT:%.*]] = bitcast %T13partial_apply2A3C* %1 to %swift.opaque*
+// CHECK:   [[CONTEXT:%.*]] = bitcast %swift.opaque* [[CLOSURE_CONTEXT]] to %swift.refcounted*
+// CHECK:   call swiftcc void @"$s13capture_classTA"(%swift.refcounted* swiftself [[CONTEXT]])
+sil @partial_apply_stack_in_coroutine : $@yield_once (@owned A3) -> () {
+entry(%0: $A3):
+  %f = function_ref @capture_class : $@convention(thin) (@guaranteed A3) -> ()
+  %p = partial_apply [callee_guaranteed] [on_stack] %f(%0) : $@convention(thin) (@guaranteed A3) -> ()
+  apply %p() : $@noescape @callee_guaranteed () -> ()
+  dealloc_stack %p : $@noescape @callee_guaranteed () -> ()
+  %1000 = integer_literal $Builtin.Int32, 1000
+  yield (), resume resume, unwind unwind
+
+resume:
+  %ret = tuple ()
+  return %ret : $()
+
+unwind:
+  unwind
+}
 sil_vtable A3 {}
diff --git a/test/IRGen/pic.swift b/test/IRGen/pic.swift
index b458b6f..a10b06f 100644
--- a/test/IRGen/pic.swift
+++ b/test/IRGen/pic.swift
@@ -60,3 +60,7 @@
 // aarch64:        str [[REG2]], [sp]
 // aarch64:        bl swift_endAccess
 // aarch64:        ldr x0, [sp]
+
+// powerpc64le-LABEL: {{_?}}$s4main10use_globalSiyF:
+// powerpc64le:        bl swift_beginAccess
+// powerpc64le:       addi 3, 3, ($s4main6globalSivp)@toc@l
diff --git a/test/Index/Store/output-failure.swift b/test/Index/Store/output-failure.swift
index 1cfa146..285443b 100644
--- a/test/Index/Store/output-failure.swift
+++ b/test/Index/Store/output-failure.swift
@@ -1,3 +1,4 @@
+// XFAIL: CPU=powerpc64le
 // RUN: %empty-directory(%t)
 // RUN: mkdir %t/idx
 
diff --git a/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift b/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
index c57ced6..2274d1c 100644
--- a/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
+++ b/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
@@ -8,7 +8,7 @@
 public struct CGFloat {
 #if arch(i386) || arch(arm)
   public typealias UnderlyingType = Float
-#elseif arch(x86_64) || arch(arm64)
+#elseif arch(x86_64) || arch(arm64) || arch(powerpc64le)
   public typealias UnderlyingType = Double
 #endif
 
diff --git a/test/Interpreter/generic_casts.swift b/test/Interpreter/generic_casts.swift
index bf87feb..ae63157 100644
--- a/test/Interpreter/generic_casts.swift
+++ b/test/Interpreter/generic_casts.swift
@@ -3,6 +3,7 @@
 // RUN: %target-codesign %t/a.out.optimized
 // RUN: %target-run %t/a.out.optimized | %FileCheck %s
 // REQUIRES: executable_test
+// XFAIL: CPU=powerpc64le
 
 // FIXME: rdar://problem/19648117 Needs splitting objc parts out
 
diff --git a/test/Misc/stats_dir_tracer.swift b/test/Misc/stats_dir_tracer.swift
index 12795d8..90be632 100644
--- a/test/Misc/stats_dir_tracer.swift
+++ b/test/Misc/stats_dir_tracer.swift
@@ -2,9 +2,9 @@
 // RUN: %target-swiftc_driver -o %t/main -module-name main -stats-output-dir %t %s -trace-stats-events
 // RUN: %FileCheck -input-file %t/*.csv %s
 
-// CHECK: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumTypesDeserialized",[0-9]+,[0-9]+,"Call","\[.*stats_dir_tracer.swift.*\]"}}
-// CHECK: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumConstraintScopes",[0-9]+,[0-9]+,"Sequence","\[.*stats_dir_tracer.swift.*\]"}}
-// CHECK: {{[0-9]+,[0-9]+,"exit","SuperclassDeclRequest","Sema.SuperclassDeclRequest",[0-9]+,[0-9]+,"Bar","\[.*stats_dir_tracer.swift.*\]"}}
+// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumTypesDeserialized",[0-9]+,[0-9]+,"Call","\[.*stats_dir_tracer.swift.*\]"}}
+// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","typecheck-expr","Sema.NumConstraintScopes",[0-9]+,[0-9]+,"Sequence","\[.*stats_dir_tracer.swift.*\]"}}
+// CHECK-DAG: {{[0-9]+,[0-9]+,"exit","SuperclassDeclRequest","Sema.SuperclassDeclRequest",[0-9]+,[0-9]+,"Bar","\[.*stats_dir_tracer.swift.*\]"}}
 
 public func foo() {
     print("hello")
diff --git a/test/ParseableInterface/ModuleCache/force-module-loading-mode-archs.swift b/test/ParseableInterface/ModuleCache/force-module-loading-mode-archs.swift
index 195b4c1..a764baf 100644
--- a/test/ParseableInterface/ModuleCache/force-module-loading-mode-archs.swift
+++ b/test/ParseableInterface/ModuleCache/force-module-loading-mode-archs.swift
@@ -1,4 +1,5 @@
 // RUN: %empty-directory(%t)
+// XFAIL: CPU=powerpc64le
 
 // 1. Not finding things is okay.
 // RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s 2>&1 | %FileCheck -check-prefix=NO-SUCH-MODULE %s
diff --git a/test/ParseableInterface/ModuleCache/force-module-loading-mode-framework.swift b/test/ParseableInterface/ModuleCache/force-module-loading-mode-framework.swift
index b1f0d5c..b2f705b 100644
--- a/test/ParseableInterface/ModuleCache/force-module-loading-mode-framework.swift
+++ b/test/ParseableInterface/ModuleCache/force-module-loading-mode-framework.swift
@@ -1,4 +1,5 @@
 // RUN: %empty-directory(%t)
+// XFAIL: CPU=powerpc64le
 
 // 1. Not finding things is okay.
 // RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s 2>&1 | %FileCheck -check-prefix=NO-SUCH-MODULE %s
diff --git a/test/ParseableInterface/ModuleCache/force-module-loading-mode.swift b/test/ParseableInterface/ModuleCache/force-module-loading-mode.swift
index 2f934bc..7d611f1 100644
--- a/test/ParseableInterface/ModuleCache/force-module-loading-mode.swift
+++ b/test/ParseableInterface/ModuleCache/force-module-loading-mode.swift
@@ -1,4 +1,5 @@
 // RUN: %empty-directory(%t)
+// XFAIL: CPU=powerpc64le
 
 // 1. Not finding things is okay.
 // RUN: not env SWIFT_FORCE_MODULE_LOADING=prefer-parseable %target-swift-frontend -typecheck -parse-stdlib -module-cache-path %t/MCP %s 2>&1 | %FileCheck -check-prefix=NO-SUCH-MODULE %s
diff --git a/test/Runtime/linux-fatal-backtrace.swift b/test/Runtime/linux-fatal-backtrace.swift
index 6df5ec3..40b6abe 100644
--- a/test/Runtime/linux-fatal-backtrace.swift
+++ b/test/Runtime/linux-fatal-backtrace.swift
@@ -4,6 +4,7 @@
 // REQUIRES: executable_test
 // REQUIRES: OS=linux-gnu
 // REQUIRES: lldb
+// XFAIL: CPU=powerpc64le
 
 // Backtraces are not emitted when optimizations are enabled. This test can not
 // run when optimizations are enabled.
diff --git a/test/SIL/Serialization/opaque_values_serialize.sil b/test/SIL/Serialization/opaque_values_serialize.sil
index a634368..4399efb 100644
--- a/test/SIL/Serialization/opaque_values_serialize.sil
+++ b/test/SIL/Serialization/opaque_values_serialize.sil
@@ -1,3 +1,4 @@
+// XFAIL: CPU=powerpc64le
 // First parse this and then emit a *.sib. Then read in the *.sib, then recreate
 // RUN: %empty-directory(%t)
 // FIXME: <rdar://problem/29281364> sil-opt -verify is broken
diff --git a/test/SILGen/enum.swift b/test/SILGen/enum.swift
index 04b0dcf..b44e005 100644
--- a/test/SILGen/enum.swift
+++ b/test/SILGen/enum.swift
@@ -1,19 +1,12 @@
 
-// RUN: %target-swift-emit-silgen -parse-stdlib -parse-as-library -module-name Swift %s | %FileCheck %s
-
-precedencegroup AssignmentPrecedence { assignment: true }
-
-enum Optional<Wrapped> {
-  case none
-  case some(Wrapped)
-}
+// RUN: %target-swift-emit-silgen -parse-as-library %s | %FileCheck %s
 
 enum Boolish {
   case falsy
   case truthy
 }
 
-// CHECK-LABEL: sil hidden [ossa] @$ss13Boolish_casesyyF
+// CHECK-LABEL: sil hidden [ossa] @$s4enum13Boolish_casesyyF
 func Boolish_cases() {
   // CHECK:       [[BOOLISH:%[0-9]+]] = metatype $@thin Boolish.Type
   // CHECK-NEXT:  [[FALSY:%[0-9]+]] = enum $Boolish, #Boolish.falsy!enumelt
@@ -24,18 +17,16 @@
   _ = Boolish.truthy
 }
 
-struct Int {}
-
 enum Optionable {
   case nought
   case mere(Int)
 }
 
-// CHECK-LABEL: sil hidden [ossa] @$ss16Optionable_casesyySiF
+// CHECK-LABEL: sil hidden [ossa] @$s4enum16Optionable_casesyySiF
 func Optionable_cases(_ x: Int) {
 
   // CHECK:       [[METATYPE:%.*]] = metatype $@thin Optionable.Type
-  // CHECK:       [[FN:%.*]] = function_ref @$ss10OptionableO4mereyABSicABmF
+  // CHECK:       [[FN:%.*]] = function_ref @$s4enum10OptionableO4mereyACSicACmFTc
   // CHECK-NEXT:  [[CTOR:%.*]] = apply [[FN]]([[METATYPE]])
   // CHECK-NEXT:  destroy_value [[CTOR]]
   _ = Optionable.mere
@@ -45,13 +36,13 @@
   _ = Optionable.mere(x)
 }
 
-// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$ss10OptionableO4mereyABSicABmF
-// CHECK:        [[FN:%.*]] = function_ref @$ss10OptionableO4mereyABSicABmF
+// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s4enum10OptionableO4mereyACSicACmF
+// CHECK:        [[FN:%.*]] = function_ref @$s4enum10OptionableO4mereyACSicACmF
 // CHECK-NEXT:   [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]](%0)
 // CHECK-NEXT:   return [[METHOD]]
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil shared [transparent] [ossa] @$ss10OptionableO4mereyABSicABmF
+// CHECK-LABEL: sil shared [transparent] [ossa] @$s4enum10OptionableO4mereyACSicACmF
 // CHECK:        [[RES:%.*]] = enum $Optionable, #Optionable.mere!enumelt.1, %0 : $Int
 // CHECK-NEXT:   return [[RES]] : $Optionable
 // CHECK-NEXT: }
@@ -65,11 +56,11 @@
   case phantom(S)
 }
 
-// CHECK-LABEL: sil hidden [ossa] @$ss17AddressOnly_casesyys1SVF
+// CHECK-LABEL: sil hidden [ossa] @$s4enum17AddressOnly_casesyyAA1SVF
 func AddressOnly_cases(_ s: S) {
 
   // CHECK:       [[METATYPE:%.*]] = metatype $@thin AddressOnly.Type
-  // CHECK:       [[FN:%.*]] = function_ref @$ss11AddressOnlyO4mereyABs1P_pcABmF
+  // CHECK:       [[FN:%.*]] = function_ref @$s4enum11AddressOnlyO4mereyAcA1P_pcACmFTc
   // CHECK-NEXT:  [[CTOR:%.*]] = apply [[FN]]([[METATYPE]])
   // CHECK-NEXT:  destroy_value [[CTOR]]
   _ = AddressOnly.mere
@@ -105,29 +96,29 @@
   // CHECK:       return
 }
 
-// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$ss11AddressOnlyO4mereyABs1P_pcABmF
-// CHECK:       [[FN:%.*]] = function_ref @$ss11AddressOnlyO4mereyABs1P_pcABmF
+// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s4enum11AddressOnlyO4mereyAcA1P_pcACmFTc
+// CHECK:       [[FN:%.*]] = function_ref @$s4enum11AddressOnlyO4mereyAcA1P_pcACmF
 // CHECK-NEXT:  [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]](%0)
 // CHECK-NEXT:  // function_ref
-// CHECK-NEXT:  [[CANONICAL_THUNK_FN:%.*]] = function_ref @$ss1P_ps11AddressOnlyOIegir_sAA_pACIegnr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed @callee_guaranteed (@in P) -> @out AddressOnly) -> @out AddressOnly
+// CHECK-NEXT:  [[CANONICAL_THUNK_FN:%.*]] = function_ref @$s4enum1P_pAA11AddressOnlyOIegir_AaB_pADIegnr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed @callee_guaranteed (@in P) -> @out AddressOnly) -> @out AddressOnly
 // CHECK-NEXT:  [[CANONICAL_THUNK:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK_FN]]([[METHOD]])
 // CHECK-NEXT:  return [[CANONICAL_THUNK]] : $@callee_guaranteed (@in_guaranteed P) -> @out AddressOnly
 // CHECK-NEXT: }
 
-// CHECK-LABEL: sil shared [transparent] [ossa] @$ss11AddressOnlyO4mereyABs1P_pcABmF : $@convention
+// CHECK-LABEL: sil shared [transparent] [ossa] @$s4enum11AddressOnlyO4mereyAcA1P_pcACmF : $@convention
 // CHECK: bb0([[ARG0:%.*]] : $*AddressOnly, [[ARG1:%.*]] : $*P, [[ARG2:%.*]] : $@thin AddressOnly.Type):
 // CHECK:        [[RET_DATA:%.*]] = init_enum_data_addr [[ARG0]] : $*AddressOnly, #AddressOnly.mere!enumelt.1
 // CHECK-NEXT:   copy_addr [take] [[ARG1]] to [initialization] [[RET_DATA]] : $*P
 // CHECK-NEXT:   inject_enum_addr [[ARG0]] : $*AddressOnly, #AddressOnly.mere!enumelt.1
 // CHECK:        return
-// CHECK-NEXT: } // end sil function '$ss11AddressOnlyO4mereyABs1P_pcABmF'
+// CHECK-NEXT: } // end sil function '$s4enum11AddressOnlyO4mereyAcA1P_pcACmF'
 
 enum PolyOptionable<T> {
   case nought
   case mere(T)
 }
 
-// CHECK-LABEL: sil hidden [ossa] @$ss20PolyOptionable_casesyyxlF
+// CHECK-LABEL: sil hidden [ossa] @$s4enum20PolyOptionable_casesyyxlF
 func PolyOptionable_cases<T>(_ t: T) {
 
 // CHECK:         [[METATYPE:%.*]] = metatype $@thin PolyOptionable<T>.Type
@@ -154,7 +145,7 @@
 
 // The substituted type is loadable and trivial here
 
-// CHECK-LABEL: sil hidden [ossa] @$ss32PolyOptionable_specialized_casesyySiF
+// CHECK-LABEL: sil hidden [ossa] @$s4enum32PolyOptionable_specialized_casesyySiF
 func PolyOptionable_specialized_cases(_ t: Int) {
 
 // CHECK:         [[METATYPE:%.*]] = metatype $@thin PolyOptionable<Int>.Type
@@ -172,23 +163,23 @@
 
 // Regression test for a bug where temporary allocations created as a result of
 // tuple implosion were not deallocated in enum constructors.
-struct String { var ptr: Builtin.NativeObject }
+struct String { var ptr: AnyObject }
 
 enum Foo { case a(P, String) }
 
 // Curry Thunk for Foo.a(_:)
 //
-// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$ss3FooO1ayABs1P_p_SStcABmF
-// CHECK:         [[FN:%.*]] = function_ref @$ss3FooO1ayABs1P_p_SStcABmF
+// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmFTc
+// CHECK:         [[FN:%.*]] = function_ref @$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmF
 // CHECK-NEXT:    [[METHOD:%.*]] = partial_apply [callee_guaranteed] [[FN]](%0)
 // CHECK-NEXT:    // function_ref
-// CHECK-NEXT:    [[CANONICAL_THUNK_FN:%.*]] = function_ref @$ss1P_pSSs3FooOIegixr_sAA_pSSACIegngr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed String, @guaranteed @callee_guaranteed (@in P, @owned String) -> @out Foo) -> @out Foo
+// CHECK-NEXT:    [[CANONICAL_THUNK_FN:%.*]] = function_ref @$s4enum1P_pAA6StringVAA3FooOIegixr_AaB_pAdFIegngr_TR : $@convention(thin) (@in_guaranteed P, @guaranteed String, @guaranteed @callee_guaranteed (@in P, @owned String) -> @out Foo) -> @out Foo
 // CHECK-NEXT:    [[CANONICAL_THUNK:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK_FN]]([[METHOD]])
 // CHECK-NEXT:    return [[CANONICAL_THUNK]]
 // CHECK-NEXT:  }
 
 // Foo.a(_:)
-// CHECK-LABEL: sil shared [transparent] [ossa] @$ss3FooO1ayABs1P_p_SStcABmF
+// CHECK-LABEL: sil shared [transparent] [ossa] @$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmF
 // CHECK: bb0([[ARG0:%.*]] : $*Foo, [[ARG1:%.*]] : $*P, [[ARG2:%.*]] : @owned $String, [[ARG3:%.*]] : $@thin Foo.Type):
 // CHECK:         [[PAYLOAD:%.*]] = init_enum_data_addr [[ARG0]] : $*Foo, #Foo.a!enumelt.1
 // CHECK-NEXT:    [[LEFT:%.*]] = tuple_element_addr [[PAYLOAD]] : $*(P, String), 0
@@ -197,7 +188,7 @@
 // CHECK-NEXT:    store [[ARG2]] to [init] [[RIGHT]]
 // CHECK-NEXT:    inject_enum_addr [[ARG0]] : $*Foo, #Foo.a!enumelt.1
 // CHECK:         return
-// CHECK-NEXT:  } // end sil function '$ss3FooO1ayABs1P_p_SStcABmF'
+// CHECK-NEXT:  } // end sil function '$s4enum3FooO1ayAcA1P_p_AA6StringVtcACmF'
 
 func Foo_cases() {
   _ = Foo.a
@@ -213,3 +204,33 @@
 func makeIndirectEnum<T>(_ payload: T) -> Indirect<T> {
   return Indirect.payload((payload, other: payload))
 }
+
+// https://bugs.swift.org/browse/SR-9675
+
+enum TrailingClosureConcrete {
+  case label(fn: () -> Int)
+  case noLabel(() -> Int)
+  case twoElementsLabel(x: Int, fn: () -> Int)
+  case twoElementsNoLabel(_ x: Int, _ fn: () -> Int)
+}
+
+func useTrailingClosureConcrete() {
+  _ = TrailingClosureConcrete.label { 0 }
+  _ = TrailingClosureConcrete.noLabel { 0 }
+  _ = TrailingClosureConcrete.twoElementsLabel(x: 0) { 0 }
+  _ = TrailingClosureConcrete.twoElementsNoLabel(0) { 0 }
+}
+
+enum TrailingClosureGeneric<T> {
+  case label(fn: () -> T)
+  case noLabel(() -> T)
+  case twoElementsLabel(x: T, fn: () -> T)
+  case twoElementsNoLabel(_ x: T, _ fn: () -> T)
+}
+
+func useTrailingClosureGeneric<T>(t: T) {
+  _ = TrailingClosureGeneric<T>.label { t }
+  _ = TrailingClosureGeneric<T>.noLabel { t }
+  _ = TrailingClosureGeneric<T>.twoElementsLabel(x: t) { t }
+  _ = TrailingClosureGeneric<T>.twoElementsNoLabel(t) { t }
+}
\ No newline at end of file
diff --git a/test/SILGen/guaranteed_normal_args_curry_thunks.swift b/test/SILGen/guaranteed_normal_args_curry_thunks.swift
index 508fcd0..90942f5 100644
--- a/test/SILGen/guaranteed_normal_args_curry_thunks.swift
+++ b/test/SILGen/guaranteed_normal_args_curry_thunks.swift
@@ -119,9 +119,9 @@
 // CHECK:   return [[THUNK_PA]]
 // CHECK: } // end sil function '$ss017LoadableClassInitA0CyABs5KlassCcfCTcTd'
 
-// Canonical Thunk.
+// Reabstraction thunk.
 //
-// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$ss5KlassCs017LoadableClassInitB0CIegxo_AbDIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableClassInitLoadable) -> @owned LoadableClassInitLoadable {
+// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCs017LoadableClassInitB0CIegxo_AbDIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableClassInitLoadable) -> @owned LoadableClassInitLoadable {
 // CHECK: bb0([[CLASS:%.*]] : @guaranteed $Klass, [[PA:%.*]] : @guaranteed $@callee_guaranteed (@owned Klass) -> @owned LoadableClassInitLoadable):
 // CHECK:   [[CLASS_COPY:%.*]] = copy_value [[CLASS]]
 // CHECK:   [[RESULT:%.*]] = apply [[PA]]([[CLASS_COPY]])
@@ -153,9 +153,9 @@
 // CHECK:   return [[THUNK_PA]]
 // CHECK: } // end sil function '$ss018LoadableStructInitA0VyABs5KlassCcfCTc'
 
-// Canonical Thunk.
+// Reabstraction thunk.
 //
-// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$ss5KlassCs018LoadableStructInitB0VIegxo_AbDIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableStructInitLoadable) -> @owned LoadableStructInitLoadable {
+// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCs018LoadableStructInitB0VIegxo_AbDIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @owned LoadableStructInitLoadable) -> @owned LoadableStructInitLoadable {
 // CHECK: bb0([[CLASS:%.*]] : @guaranteed $Klass, [[PA:%.*]] : @guaranteed $@callee_guaranteed (@owned Klass) -> @owned LoadableStructInitLoadable):
 // CHECK:   [[CLASS_COPY:%.*]] = copy_value [[CLASS]]
 // CHECK:   [[RESULT:%.*]] = apply [[PA]]([[CLASS_COPY]])
@@ -191,14 +191,14 @@
 // CHECK:   return [[THUNK]]
 // CHECK: } // end sil function '$ss25AddrOnlyStructInitGenericVyAByxGxcfCTc'
 
-// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$sxs25AddrOnlyStructInitGenericVyxGIegir_xACIegnr_lTR : $@convention(thin) <T> (@in_guaranteed T, @guaranteed @callee_guaranteed (@in T) -> @out AddrOnlyStructInitGeneric<T>) -> @out AddrOnlyStructInitGeneric<T> {
+// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$sxs25AddrOnlyStructInitGenericVyxGIegir_xACIegnr_lTR : $@convention(thin) <T> (@in_guaranteed T, @guaranteed @callee_guaranteed (@in T) -> @out AddrOnlyStructInitGeneric<T>) -> @out AddrOnlyStructInitGeneric<T> {
 // CHECK: bb0([[ARG0:%.*]] : $*AddrOnlyStructInitGeneric<T>, [[ARG1:%.*]] : $*T, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed (@in T) -> @out AddrOnlyStructInitGeneric<T>):
 // CHECK:   [[STACK:%.*]] = alloc_stack $T
 // CHECK:   copy_addr [[ARG1]] to [initialization] [[STACK]] : $*T
 // CHECK:   apply [[ARG2]]([[ARG0]], [[STACK]]) : $@callee_guaranteed (@in T) -> @out AddrOnlyStructInitGeneric<T>
 // CHECK: } // end sil function '$sxs25AddrOnlyStructInitGenericVyxGIegir_xACIegnr_lTR'
 
-// CHECK_LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCs25AddrOnlyStructInitGenericVyABGIegnr_AbEIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric<Klass>) -> @owned AddrOnlyStructInitGeneric<Klass> {
+// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCs25AddrOnlyStructInitGenericVyABGIegnr_AbEIeggo_TR : $@convention(thin) (@guaranteed Klass, @guaranteed @callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric<Klass>) -> @owned AddrOnlyStructInitGeneric<Klass> {
 // CHECK: bb0([[ARG0:%.*]] : @guaranteed $Klass, [[ARG1:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed Klass) -> @out AddrOnlyStructInitGeneric<Klass>):
 // CHECK:   [[STACK:%.*]] = alloc_stack $Klass
 // CHECK:   [[ARG0_COPY:%.*]] = copy_value [[ARG0]]
@@ -253,9 +253,9 @@
 // CHECK:   return [[CANONICAL_THUNK]]
 // CHECK: } // end sil function '$ss20ProtocolInitLoadableP1txs5KlassC_tcfCTc'
 
-// Canonical thunk
+// Reabstraction thunk.
 //
-// CHECK-LABEL: sil shared [transparent] [serializable] [thunk] [ossa] @$ss5KlassCxIegxr_ABxIeggr_s20ProtocolInitLoadableRzlTR : $@convention(thin) <Self where Self : ProtocolInitLoadable> (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @out Self) -> @out Self {
+// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$ss5KlassCxIegxr_ABxIeggr_s20ProtocolInitLoadableRzlTR : $@convention(thin) <Self where Self : ProtocolInitLoadable> (@guaranteed Klass, @guaranteed @callee_guaranteed (@owned Klass) -> @out Self) -> @out Self {
 // CHECK: bb0([[ARG0:%.*]] : $*Self, [[ARG1:%.*]] : @guaranteed $Klass, [[ARG2:%.*]] : @guaranteed $@callee_guaranteed (@owned Klass) -> @out Self):
 // CHECK:   [[ARG1_COPY:%.*]] = copy_value [[ARG1]]
 // CHECK:   apply [[ARG2]]([[ARG0]], [[ARG1_COPY]])
diff --git a/test/SILGen/partial_apply_override.swift b/test/SILGen/partial_apply_override.swift
new file mode 100644
index 0000000..07fdeaf
--- /dev/null
+++ b/test/SILGen/partial_apply_override.swift
@@ -0,0 +1,39 @@
+// RUN: %target-swift-emit-silgen %s | %FileCheck %s
+
+// rdar://45671537
+
+class Converter<Input, Output> {
+  func convert(input: Input) -> Output {
+    fatalError("Has to be overriden")
+  }
+}
+
+class StringIntConverter: Converter<String, Int> {
+  override func convert(input: String) -> Int {
+    return 0
+  }
+}
+
+public func convert(strings: [String]) -> [Int] {
+  return strings.map(StringIntConverter().convert)
+}
+
+// CHECK-LABEL: sil [ossa] @$s22partial_apply_override7convert7stringsSaySiGSaySSG_tF :
+// CHECK:      [[CONVERTER_TYPE:%.*]] = metatype $@thick StringIntConverter.Type
+// CHECK-NEXT: // function_ref
+// CHECK-NEXT: [[ALLOC_CONVERTER:%.*]] = function_ref @$s22partial_apply_override18StringIntConverterCACycfC :
+// CHECK-NEXT: [[CONVERTER:%.*]] = apply [[ALLOC_CONVERTER]]([[CONVERTER_TYPE]])
+// CHECK-NEXT: // function_ref
+// CHECK-NEXT: [[CURRY_THUNK:%.*]] = function_ref @$s22partial_apply_override18StringIntConverterC7convert5inputSiSS_tFTc : $@convention(thin) (@guaranteed StringIntConverter) -> @owned @callee_guaranteed (@guaranteed String) -> Int
+// CHECK-NEXT: [[CURRY_RESULT:%.*]] = apply [[CURRY_THUNK]]([[CONVERTER]])
+// CHECK-NEXT: destroy_value [[CONVERTER]] :
+
+// CHECK-LABEL: sil shared [thunk] [ossa] @$s22partial_apply_override18StringIntConverterC7convert5inputSiSS_tFTc : 
+// CHECK-SAME: $@convention(thin) (@guaranteed StringIntConverter) -> @owned @callee_guaranteed (@guaranteed String) -> Int
+// CHECK:      [[METHOD:%.*]] = class_method %0 : $StringIntConverter, #StringIntConverter.convert!1 : (StringIntConverter) -> (String) -> Int, $@convention(method) (@in_guaranteed String, @guaranteed StringIntConverter) -> @out Int
+// CHECK-NEXT: [[SELF_COPY:%.*]] = copy_value %0 :
+// CHECK-NEXT: [[BOUND_METHOD:%.*]] = partial_apply [callee_guaranteed] [[METHOD]]([[SELF_COPY]])
+// CHECK-NEXT: // function_ref
+// CHECK-NEXT: [[THUNK:%.*]] = function_ref @$sSSSiIegnr_SSSiIeggd_TR : $@convention(thin) (@guaranteed String, @guaranteed @callee_guaranteed (@in_guaranteed String) -> @out Int) -> Int 
+// CHECK-NEXT: [[REABSTRACTED:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[BOUND_METHOD]])
+// CHECK-NEXT: return [[REABSTRACTED]]
diff --git a/test/SILGen/reabstract.swift b/test/SILGen/reabstract.swift
index d1e09d3..9ca56aa 100644
--- a/test/SILGen/reabstract.swift
+++ b/test/SILGen/reabstract.swift
@@ -37,13 +37,12 @@
 // MANDATORY-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[T2]]
 // MANDATORY-NEXT: //{{.*}}reabstraction thunk
 // MANDATORY-NEXT: [[T3:%.*]] = function_ref [[THUNK:@.*]] :
-// MANDATORY-NEXT: [[T4:%.*]] = partial_apply [callee_guaranteed] [[T3]]([[CVT]])
-// MANDATORY-NEXT: [[CVT:%.*]] = convert_escape_to_noescape [[T4]]
+// MANDATORY-NEXT: [[T4:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[T3]]([[CVT]])
 // MANDATORY-NEXT: strong_release [[T2]]
 // MANDATORY-NEXT: // function_ref
 // MANDATORY-NEXT: [[T0:%.*]] = function_ref @$s10reabstract6takeFn{{[_0-9a-zA-Z]*}}F
-// MANDATORY-NEXT: apply [[T0]]<Int>([[CVT]])
-// MANDATORY-NEXT: strong_release [[T4]]
+// MANDATORY-NEXT: apply [[T0]]<Int>([[T4]])
+// MANDATORY-NEXT: dealloc_stack [[T4]] : $@noescape @callee_guaranteed (@in_guaranteed Int) -> @out Optional<Int>
 // MANDATORY-NEXT: strong_release [[T2]]
 // MANDATORY-NEXT: tuple ()
 // MANDATORY-NEXT: return
diff --git a/test/SILOptimizer/access_enforcement_noescape.swift b/test/SILOptimizer/access_enforcement_noescape.swift
index 212be46..002c675 100644
--- a/test/SILOptimizer/access_enforcement_noescape.swift
+++ b/test/SILOptimizer/access_enforcement_noescape.swift
@@ -85,12 +85,10 @@
   doTwo({ _ = x }, { _ = x })
 }
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape09inoutReadE01xySiz_tF : $@convention(thin) (@inout Int) -> () {
-// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
+// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape09inoutReadE01xySiz_tF'
 
 // closure #1 in inoutReadRead(x:)
@@ -119,10 +117,9 @@
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape11readBoxReadyyF : $@convention(thin) () -> () {
 // CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
 // CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
+// CHECK: apply %{{.*}}([[CVT1]], [[PA2]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape11readBoxReadyyF'
 
 // closure #1 in readBoxRead()
@@ -153,12 +150,10 @@
   doTwo({ _ = x }, { x = 42 })
 }
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape9readWriteyyF : $@convention(thin) () -> () {
-// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
+// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape9readWriteyyF'
 
 // closure #1 in readWrite()
@@ -195,10 +190,9 @@
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape12readBoxWriteyyF : $@convention(thin) () -> () {
 // CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
 // CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
+// CHECK: apply %{{.*}}([[CVT1]], [[PA2]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape12readBoxWriteyyF'
 
 // closure #1 in readBoxWrite()
@@ -230,11 +224,10 @@
 
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape12readWriteBoxyyF : $@convention(thin) () -> () {
 // CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT2]], [[CVT1]])
+// CHECK: apply %{{.*}}([[PA2]], [[CVT1]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape12readWriteBoxyyF'
 
 // closure #1 in readWriteBox()
@@ -319,12 +312,10 @@
 }
 
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape10writeWriteyyF : $@convention(thin) () -> () {
-// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
+// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape10writeWriteyyF'
 
 // closure #1 in writeWrite()
@@ -348,12 +339,10 @@
 }
 
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape010inoutWriteE01xySiz_tF : $@convention(thin) (@inout Int) -> () {
-// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed] [on_stack]
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT1]], [[CVT2]])
+// CHECK: apply %{{.*}}([[PA1]], [[PA2]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape010inoutWriteE01xySiz_tF'
 
 // closure #1 in inoutWriteWrite(x:)
@@ -381,11 +370,10 @@
 
 // CHECK-LABEL: sil hidden @$s27access_enforcement_noescape13writeWriteBoxyyF : $@convention(thin) () -> () {
 // CHECK: [[PA1:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed]
-// CHECK: [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK: [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack]
 // CHECK: [[CVT1:%.*]] = convert_escape_to_noescape [[PA1]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
 // CHECK-NOT: begin_access
-// CHECK: apply %{{.*}}([[CVT2]], [[CVT1]])
+// CHECK: apply %{{.*}}([[PA2]], [[CVT1]])
 // CHECK-LABEL: } // end sil function '$s27access_enforcement_noescape13writeWriteBoxyyF'
 
 // closure #1 in writeWriteBox()
diff --git a/test/SILOptimizer/capture_promotion.sil b/test/SILOptimizer/capture_promotion.sil
index 8dd3d86..839d794 100644
--- a/test/SILOptimizer/capture_promotion.sil
+++ b/test/SILOptimizer/capture_promotion.sil
@@ -407,3 +407,70 @@
 
   return %21 : $@callee_guaranteed () -> Int
 }
+
+// CHECK-LABEL: sil @test_capture_promotion_on_stack
+sil @test_capture_promotion_on_stack : $@convention(thin) () -> () {
+bb0:
+  %0 = tuple ()
+  %1 = alloc_box $<τ_0_0> { var τ_0_0 } <Foo>
+  %1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <Foo>, 0
+  %2 = function_ref @foo_allocating_init : $@convention(thin) (@thick Foo.Type) -> @owned Foo
+  %3 = metatype $@thick Foo.Type
+  %4 = apply %2(%3) : $@convention(thin) (@thick Foo.Type) -> @owned Foo
+  store %4 to %1a : $*Foo
+  %6 = alloc_box $<τ_0_0> { var τ_0_0 } <Baz>
+  %6a = project_box %6 : $<τ_0_0> { var τ_0_0 } <Baz>, 0
+  %7 = function_ref @baz_init : $@convention(thin) (@thin Baz.Type) -> @owned Baz
+  %8 = metatype $@thin Baz.Type
+  %9 = apply %7(%8) : $@convention(thin) (@thin Baz.Type) -> @owned Baz
+  store %9 to %6a : $*Baz
+  %11 = alloc_box $<τ_0_0> { var τ_0_0 } <Int>
+  %11a = project_box %11 : $<τ_0_0> { var τ_0_0 } <Int>, 0
+  %12 = function_ref @convert_from_integer_literal : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
+  %13 = metatype $@thin Int.Type
+  %14 = integer_literal $Builtin.Word, 3
+  %15 = apply %12(%14, %13) : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
+  store %15 to %11a : $*Int
+
+// CHECK-NOT: function_ref @closure0_guaranteed
+// CHECK: [[CLOSURE_PROMOTE:%.*]] = function_ref @$s19closure0_guaranteedTf2iii_n
+// CHECK-NOT: function_ref @closure0_guaranteed
+
+// The Foo variable is loaded from and retained, because it is a reference type
+// CHECK-NEXT: [[LOADFOO:%.*]] = load {{.*}} : $*Foo
+// CHECK-NEXT: strong_retain [[LOADFOO]] : $Foo
+
+// The Baz variable is loaded and retain_value'd, because it is a non-trivial
+// aggregate type
+// CHECK-NEXT: [[LOADBAZ:%.*]] = load {{.*}} : $*Baz
+// CHECK-NEXT: retain_value [[LOADBAZ:%.*]] : $Baz
+
+// The Int variable is loaded only, because it is trivial
+// CHECK-NEXT: [[LOADINT:%.*]] = load {{.*}} : $*Int
+
+// The partial apply has one value argument for each pair of arguments that was
+// previously used to capture and pass the variable by reference
+// CHECK-NEXT: [[PA:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[CLOSURE_PROMOTE]]([[LOADFOO]], [[LOADBAZ]], [[LOADINT]])
+// CHECK-NEXT: [[MD1:%.*]] = mark_dependence [[PA]] : $@noescape @callee_guaranteed () -> Int on [[LOADFOO]] : $Foo
+// CHECK-NEXT: [[MD2:%.*]] = mark_dependence [[MD1]] : $@noescape @callee_guaranteed () -> Int on [[LOADBAZ]] : $Baz
+// CHECK-NEXT: apply [[MD2]]() : $@noescape @callee_guaranteed () -> Int
+// CHECK-NEXT:  dealloc_stack [[PA]] : $@noescape @callee_guaranteed () -> Int
+// CHECK-NEXT:  strong_release [[LOADFOO]] : $Foo
+// CHECK-NEXT:  release_value [[LOADBAZ]] : $Baz
+// CHECK-NEXT:  strong_release {{.*}} : $<τ_0_0> { var τ_0_0 } <Int>
+// CHECK-NEXT:  strong_release {{.*}} : $<τ_0_0> { var τ_0_0 } <Baz>
+// CHECK-NEXT:  strong_release {{.*}} : $<τ_0_0> { var τ_0_0 } <Foo>
+
+  %17 = function_ref @closure0_guaranteed : $@convention(thin) (@guaranteed <τ_0_0> { var τ_0_0 } <Foo>, @guaranteed <τ_0_0> { var τ_0_0 } <Baz>, @guaranteed <τ_0_0> { var τ_0_0 } <Int>) -> Int
+  %21 = partial_apply [callee_guaranteed] [on_stack] %17(%1, %6, %11) : $@convention(thin) (@guaranteed <τ_0_0> { var τ_0_0 } <Foo>, @guaranteed <τ_0_0> { var τ_0_0 } <Baz>, @guaranteed <τ_0_0> { var τ_0_0 } <Int>) -> Int
+  %md = mark_dependence %21 :$@noescape @callee_guaranteed () -> Int on %1 : $<τ_0_0> { var τ_0_0 } <Foo>
+  %md2 = mark_dependence %md :$@noescape @callee_guaranteed () -> Int on %6 : $<τ_0_0> { var τ_0_0 } <Baz>
+  %md3 = mark_dependence %md2 :$@noescape @callee_guaranteed () -> Int on %11 : $<τ_0_0> { var τ_0_0 } <Int>
+  apply %md3() : $@noescape @callee_guaranteed () -> Int
+  dealloc_stack %21 : $@noescape @callee_guaranteed () -> Int
+  strong_release %11 : $<τ_0_0> { var τ_0_0 } <Int>
+  strong_release %6 : $<τ_0_0> { var τ_0_0 } <Baz>
+  strong_release %1 : $<τ_0_0> { var τ_0_0 } <Foo>
+  %tuple = tuple()
+  return %tuple : $()
+}
diff --git a/test/SILOptimizer/capture_propagation.sil b/test/SILOptimizer/capture_propagation.sil
index 311c078..422a144 100644
--- a/test/SILOptimizer/capture_propagation.sil
+++ b/test/SILOptimizer/capture_propagation.sil
@@ -470,3 +470,40 @@
   %2 = partial_apply %1(%0) : $@convention(method) (Int32, Int32, @thin Int32.Type) -> Bool
   return %2 : $@callee_owned (Int32, Int32) -> Bool
 }
+
+sil shared @test_capture_propagation2_callee_on_stack : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> () {
+bb0(%0 : $@noescape @callee_guaranteed () -> ()):
+  apply %0() : $@noescape @callee_guaranteed () -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+sil shared @test_capture_propagation2_thunk_on_stack : $@convention(thin) (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word, @noescape @callee_guaranteed (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> ()) -> () {
+bb0(%0 : $Builtin.Int32, %1 : $Builtin.FPIEEE32, %2 : $Builtin.RawPointer, %3 : $*Builtin.Word, %4 : $@noescape @callee_guaranteed (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> ()):
+  apply %4(%0, %1, %2, %3) : $@noescape @callee_guaranteed (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK: sil @test_capture_propagation2_caller_on_stack
+// CHECK:  [[F:%.*]] = function_ref @test_capture_propagation2_callee_on_stack : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+// CHECK:  [[F2:%.*]] = function_ref @$s40test_capture_propagation2_thunk_on_stack4_12353globalinit_33_06E7F1D906492AE070936A9B58CBAE1C_token808_TFtest_b1_C8_closureTf3pi0pd0psbpgpf_n : $@convention(thin) @noescape () -> ()
+// CHECK:  [[CL:%.*]] = thin_to_thick_function [[F2]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK:  apply [[F]]([[CL]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+// CHECK:  return
+
+sil @test_capture_propagation2_caller_on_stack : $@convention(thin) () -> () {
+  %0 = integer_literal $Builtin.Int32, 0
+  %1 = float_literal $Builtin.FPIEEE32, 0
+  %2 = string_literal utf8 "123"
+  %3 = global_addr @globalinit_33_06E7F1D906492AE070936A9B58CBAE1C_token8 : $*Builtin.Word
+  %4 = function_ref @_TFtest_capture_propagation2_closure : $@convention(thin) (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> ()
+  %5 = thin_to_thick_function %4 : $@convention(thin) (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> () to $@noescape @callee_guaranteed (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> ()
+  %6 = function_ref @test_capture_propagation2_callee_on_stack : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  %7 = function_ref @test_capture_propagation2_thunk_on_stack : $@convention(thin) (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word, @noescape @callee_guaranteed (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> ()) -> ()
+  %8 = partial_apply [callee_guaranteed] [on_stack] %7(%0, %1, %2, %3, %5) : $@convention(thin) (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word, @noescape @callee_guaranteed (Builtin.Int32, Builtin.FPIEEE32, Builtin.RawPointer, @in Builtin.Word) -> ()) -> ()
+  apply %6(%8) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  dealloc_stack %8 : $@noescape @callee_guaranteed () -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SILOptimizer/closure_lifetime_fixup.swift b/test/SILOptimizer/closure_lifetime_fixup.swift
index 02b0706..760bb2a 100644
--- a/test/SILOptimizer/closure_lifetime_fixup.swift
+++ b/test/SILOptimizer/closure_lifetime_fixup.swift
@@ -1,4 +1,10 @@
-// RUN: %target-swift-frontend %s -sil-verify-all -enable-sil-ownership -emit-sil -o - | %FileCheck %s
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend %S/../Inputs/resilient_struct.swift -enable-resilience -emit-module -emit-module-path %t/resilient_struct.swiftmodule
+// RUN: %target-swift-frontend %S/../Inputs/resilient_enum.swift -I %t -enable-resilience -emit-module -emit-module-path %t/resilient_enum.swiftmodule
+// RUN: %target-swift-frontend %s -sil-verify-all -enable-sil-ownership -emit-sil -I %t -o - | %FileCheck %s --check-prefix=CHECK --check-prefix=%target-os
+
+import resilient_struct
+import resilient_enum
 
 func use_closure(_ c : () -> () ) {
   c()
@@ -17,14 +23,13 @@
 // CHECK: bb0([[ARG:%.*]] : $C):
 // CHECK: [[F:%.*]]  = function_ref @$s22closure_lifetime_fixup10testSimple1cyAA1CC_tFyyXEfU_
 // CHECK-NEXT:  strong_retain [[ARG]] : $C
-// CHECK-NEXT:  [[PA:%.*]] = partial_apply [callee_guaranteed] [[F]]([[ARG]]) : $@convention(thin) (@guaranteed C) -> ()
-// CHECK-NEXT: strong_retain [[PA]] : $@callee_guaranteed () -> ()
-// CHECK-NEXT:  [[CVT:%.*]] = convert_escape_to_noescape [[PA]] : $@callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> ()
+// CHECK-NEXT:  [[PA:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[F]]([[ARG]]) : $@convention(thin) (@guaranteed C) -> ()
+// CHECK-NEXT:  [[CL:%.*]] = mark_dependence [[PA]] : $@noescape @callee_guaranteed () -> () on [[ARG]] : $C
 // CHECK-NEXT:  // function_ref use_closure(_:)
 // CHECK-NEXT:  [[F2:%.*]] = function_ref @$s22closure_lifetime_fixup04use_A0yyyyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
-// CHECK-NEXT:  apply [[F2]]([[CVT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
-// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> ()
-// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> ()
+// CHECK-NEXT:  apply [[F2]]([[CL]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+// CHECK-NEXT:  dealloc_stack [[PA]] : $@noescape @callee_guaranteed () -> ()
+// CHECK-NEXT:  strong_release [[ARG]] : $C
 // CHECK-NEXT:  tuple ()
 // CHECK-NEXT:  return {{.*}} : $()
 public func testSimple(c: C) {
@@ -35,19 +40,17 @@
 // CHECK:bb0([[ARG:%.*]] : $C):
 // CHECK:  [[F:%.*]] = function_ref @$s22closure_lifetime_fixup11testGeneric1cyAA1CC_tFSiyXEfU_ : $@convention(thin) (@guaranteed C) -> Int
 // CHECK-NEXT:  strong_retain [[ARG]] : $C
-// CHECK-NEXT:  [[PA:%.*]] = partial_apply [callee_guaranteed] [[F]]([[ARG]]) : $@convention(thin) (@guaranteed C) -> Int
-// CHECK-NEXT:  strong_retain [[PA]] : $@callee_guaranteed () -> Int
-// CHECK-NEXT:  [[CVT:%.*]] = convert_escape_to_noescape [[PA]] : $@callee_guaranteed () -> Int to $@noescape @callee_guaranteed () -> Int
+// CHECK-NEXT:  [[PA:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[F]]([[ARG]]) : $@convention(thin) (@guaranteed C) -> Int
+// CHECK-NEXT:  [[MD:%.*]] = mark_dependence [[PA]] : $@noescape @callee_guaranteed () -> Int on [[ARG]] : $C
 // CHECK-NEXT:  // function_ref thunk for @callee_guaranteed () -> (@unowned Int)
 // CHECK-NEXT:  [[F:%.*]] = function_ref @$sSiIgd_SiIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int
-// CHECK-NEXT:  [[PA2:%.*]] = partial_apply [callee_guaranteed] [[F]]([[CVT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int
-// CHECK-NEXT:  [[CVT2:%.*]] = convert_escape_to_noescape [[PA2]] : $@callee_guaranteed () -> @out Int to $@noescape @callee_guaranteed () -> @out Int
-// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> Int
+// CHECK-NEXT:  [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[F]]([[MD]]) : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int
 // CHECK-NEXT:  // function_ref use_closureGeneric<A>(_:)
 // CHECK-NEXT:  [[F2:%.*]] = function_ref @$s22closure_lifetime_fixup04use_A7GenericyyxyXElF : $@convention(thin) <τ_0_0> (@noescape @callee_guaranteed () -> @out τ_0_0) -> ()
-// CHECK-NEXT:  %12 = apply [[F2]]<Int>([[CVT2]]) : $@convention(thin) <τ_0_0> (@noescape @callee_guaranteed () -> @out τ_0_0) -> ()
-// CHECK-NEXT:  strong_release [[PA2]] : $@callee_guaranteed () -> @out Int
-// CHECK-NEXT:  strong_release [[PA]] : $@callee_guaranteed () -> Int
+// CHECK-NEXT:  apply [[F2]]<Int>([[PA2]]) : $@convention(thin) <τ_0_0> (@noescape @callee_guaranteed () -> @out τ_0_0) -> ()
+// CHECK-NEXT:  dealloc_stack [[PA2]]
+// CHECK-NEXT:  dealloc_stack [[PA]]
+// CHECK-NEXT:  strong_release [[ARG]]
 // CHECK-NEXT:  tuple ()
 // CHECK-NEXT:  return {{.*}} : $()
 
@@ -90,3 +93,360 @@
   }
   return result
 }
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup28to_stack_of_convert_function1pySvSg_tF
+// CHECK:  [[PA:%.*]] = partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  [[MD:%.*]] = mark_dependence [[PA]]
+// CHECK:  [[CVT:%.*]] = convert_function [[MD]]
+// CHECK:  [[REABSTRACT:%.*]] = function_ref @$sSvSSs5Error_pIgyozo_SvSSsAA_pIegnrzo_TR
+// CHECK:  [[PA2:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[REABSTRACT]]([[CVT]])
+// CHECK:  [[MAP:%.*]] = function_ref @$sSq3mapyqd__Sgqd__xKXEKlF
+// CHECK:  try_apply [[MAP]]<UnsafeMutableRawPointer, String>({{.*}}, [[PA2]], {{.*}})
+public func to_stack_of_convert_function(p: UnsafeMutableRawPointer?) {
+  _ = p.map(String.init(describing:))
+}
+
+
+public func no_dealloc_stack_before_unreachable(_ message: String, fileName: StaticString = #file, lineNumber: Int = #line) -> Never  {
+  Swift.fatalError(message, file: fileName, line: UInt(lineNumber))
+}
+
+// Make sure closures are allocated on the stack.
+func useClosure(_ c: () -> ()) {
+}
+func useClosureThrowing(_ c: () throws -> ()) throws {
+}
+func useGenericClosure<T, V>(_ c : (T) -> V) {
+}
+func useGenericClosureThrowing<T, V>(_ c: (T) throws -> V) throws {
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup12captureClass1c1dyAA1CC_AFtKF
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup10useClosureyyyyXEF
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup18useClosureThrowingyyyyKXEKF
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$sIg_ytytIegnr_TR
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup17useGenericClosureyyq_xXEr0_lF
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$ss5Error_pIgzo_ytytsAA_pIegnrzo_TR
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup25useGenericClosureThrowingyyq_xKXEKr0_l
+public func captureClass(c: C, d: C) throws {
+  useClosure {
+    c.doIt()
+    d.doIt()
+  }
+
+  try useClosureThrowing {
+    c.doIt()
+    d.doIt()
+  }
+
+  useGenericClosure {
+    c.doIt()
+    d.doIt()
+  }
+
+  try useGenericClosureThrowing {
+    c.doIt()
+    d.doIt()
+  }
+}
+
+public protocol DoIt {
+  func doIt()
+}
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup14captureGeneric1c1dyx_q_tKAA4DoItRzAaER_r0_lF
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup10useClosureyyyyXEF
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup18useClosureThrowingyyyyKXEKF
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$sIg_ytytIegnr_TR
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup17useGenericClosureyyq_xXEr0_lF
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$ss5Error_pIgzo_ytytsAA_pIegnrzo_TR
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup25useGenericClosureThrowingyyq_xKXEKr0_lF
+public func captureGeneric<C :DoIt,D: DoIt>(c: C, d: D) throws {
+  useClosure {
+    c.doIt()
+    d.doIt()
+  }
+
+  try useClosureThrowing {
+    c.doIt()
+    d.doIt()
+  }
+
+  useGenericClosure {
+    c.doIt()
+    d.doIt()
+  }
+
+  try useGenericClosureThrowing {
+    c.doIt()
+    d.doIt()
+  }
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup14captureClosure1c1d1tyq_xXE_q_xXExtKr0_lF
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  function_ref @$s22closure_lifetime_fixup10useClosureyyyyXEF
+
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  function_ref @$s22closure_lifetime_fixup18useClosureThrowingyyyyKXEKF
+
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$sIg_ytytIegnr_TR
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: function_ref @$s22closure_lifetime_fixup17useGenericClosureyyq_xXEr0_lF
+
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  function_ref @$ss5Error_pIgzo_ytytsAA_pIegnrzo_TR
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  function_ref @$s22closure_lifetime_fixup25useGenericClosureThrowingyyq_xKXEKr0_lF
+public func captureClosure<T, V>(c : (T) ->V, d: (T) -> V, t: T) throws {
+  useClosure {
+    c(t)
+    d(t)
+  }
+
+  try useClosureThrowing {
+    c(t)
+    d(t)
+  }
+
+  useGenericClosure {
+    c(t)
+    d(t)
+  }
+
+  try useGenericClosureThrowing {
+    c(t)
+    d(t)
+  }
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup16captureResilient
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+
+public func captureResilient(c: Size) throws {
+  useClosure {
+    c.method()
+  }
+
+  try useClosureThrowing {
+    c.method()
+  }
+
+  useGenericClosure {
+    c.method()
+  }
+
+  try useGenericClosureThrowing {
+    c.method()
+  }
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup10capturePOD1cy16resilient_struct5PointV_tKF
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+public func capturePOD(c: Point) throws {
+  useClosure {
+    c.method()
+  }
+
+  try useClosureThrowing {
+    c.method()
+  }
+
+  useGenericClosure {
+    c.method()
+  }
+
+  try useGenericClosureThrowing {
+    c.method()
+  }
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup11captureEnum
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+public func captureEnum(c: FullyFixedLayout, d: CustomColor) throws {
+  useClosure {
+     _ = c
+     _ = d
+  }
+
+  try useClosureThrowing {
+     _ = c
+     _ = d
+  }
+
+  useGenericClosure {
+     _ = c
+     _ = d
+  }
+
+  try useGenericClosureThrowing {
+     _ = c
+     _ = d
+  }
+}
+
+public protocol EmptyP {}
+
+public struct AddressOnlyStruct : EmptyP {}
+
+public enum AddressOnlyEnum {
+  case nought
+  case mere(EmptyP)
+  case phantom(AddressOnlyStruct)
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup22captureAddressOnlyEnum
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+public func captureAddressOnlyEnum(c: AddressOnlyEnum, d: AddressOnlyEnum) throws {
+  useClosure {
+     _ = c
+     _ = d
+  }
+
+  try useClosureThrowing {
+     _ = c
+     _ = d
+  }
+
+  useGenericClosure {
+     _ = c
+     _ = d
+  }
+
+  try useGenericClosureThrowing {
+     _ = c
+     _ = d
+  }
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup15captureProtocol
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+public func captureProtocol(c: EmptyP, d: EmptyP) throws {
+  useClosure {
+     _ = c
+     _ = d
+  }
+
+  try useClosureThrowing {
+     _ = c
+     _ = d
+  }
+
+  useGenericClosure { () -> Int in
+     _ = c
+     _ = d
+     return 0
+  }
+
+  try useGenericClosureThrowing { () -> Int in
+     _ = c
+     _ = d
+     return 0
+  }
+}
+
+public protocol Q {
+  associatedtype Element
+  func test<U>(_ c: (Element) -> U) throws
+}
+
+// CHECK-LABEL: sil @$s22closure_lifetime_fixup0A18WithAssociatedType1c1eyx_7ElementQztKAA1QRzlF
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK: try_apply
+public func closureWithAssociatedType<C : Q> (c: C, e: C.Element) throws {
+  try c.test( { _ in _ = e })
+}
+
+
+public class F<T> {
+   func test<V>(_ c: (V) throws -> T) {}
+   let t : T? = nil
+}
+
+// CHECK-LABEL: s22closure_lifetime_fixup22testClosureMethodParam1fyAA1FCyxG_tKlF
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK:  partial_apply [callee_guaranteed] [on_stack]
+// CHECK: apply
+public func testClosureMethodParam<T>(f: F<T>) throws {
+  try f.test { return f.t! }
+}
diff --git a/test/SILOptimizer/closure_specialize.sil b/test/SILOptimizer/closure_specialize.sil
index 5bc8e7d..6abcaba 100644
--- a/test/SILOptimizer/closure_specialize.sil
+++ b/test/SILOptimizer/closure_specialize.sil
@@ -808,3 +808,23 @@
   release_value %2 : $@callee_guaranteed () -> Int
   return %value : $Int
 }
+// CHECK-LABEL: sil @reabstractionTest_on_stack
+// CHECK: bb0([[A:%.*]] : $Int):
+// CHECK:  [[R:%.*]] = alloc_stack $Int
+// CHECK:  [[F:%.*]] = function_ref @$s25testClosureThunkNoEscape20aB14ConvertHelper2SiTf1nc_n
+// CHECK: apply [[F]]([[R]], [[A]])
+sil @reabstractionTest_on_stack : $(Int) -> () {
+bb0(%0 : $Int):
+  %48 = alloc_stack $Int
+  %49 = function_ref @testClosureConvertHelper2 : $@convention(thin) (Int) -> Int
+  %50 = partial_apply [callee_guaranteed] [on_stack] %49(%0) : $@convention(thin) (Int) -> Int
+  %52 = function_ref @reabstractionThunk : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int
+  %53 = partial_apply [callee_guaranteed] [on_stack] %52(%50) : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> @out Int
+  %55 = function_ref @testClosureThunkNoEscape2 : $@convention(thin) (@noescape @callee_guaranteed () -> @out Int) -> @out Int
+  apply %55(%48, %53) : $@convention(thin) (@noescape @callee_guaranteed () -> @out Int) -> @out Int
+  dealloc_stack %53 : $@noescape @callee_guaranteed () -> @out Int
+  dealloc_stack %50 : $@noescape @callee_guaranteed () -> Int
+  dealloc_stack %48 : $*Int
+  %empty = tuple ()
+  return %empty : $()
+}
diff --git a/test/SILOptimizer/inout_deshadow_integration.swift b/test/SILOptimizer/inout_deshadow_integration.swift
index cb26378..615930c 100644
--- a/test/SILOptimizer/inout_deshadow_integration.swift
+++ b/test/SILOptimizer/inout_deshadow_integration.swift
@@ -94,7 +94,7 @@
 
 // CHECK-LABEL: sil hidden @$s26inout_deshadow_integration24StructWithMutatingMethodV08mutatingG0{{[_0-9a-zA-Z]*}}F : $@convention(method) (@inout StructWithMutatingMethod) -> () {
 // CHECK-NOT: alloc_box
-// CHECK-NOT: alloc_stack
+// CHECK-NOT: alloc_stack $
 // CHECK: }
 
 // CHECK-LABEL: sil hidden @$s26inout_deshadow_integration24StructWithMutatingMethodV28testStandardLibraryOperators{{[_0-9a-zA-Z]*}}F : $@convention(method) (@inout StructWithMutatingMethod) -> () {
diff --git a/test/SILOptimizer/mandatory_inlining.sil b/test/SILOptimizer/mandatory_inlining.sil
index db99d67..6aee6a0 100644
--- a/test/SILOptimizer/mandatory_inlining.sil
+++ b/test/SILOptimizer/mandatory_inlining.sil
@@ -1184,3 +1184,23 @@
   %3 = apply %2() : $@noescape () -> Builtin.Int32
   return %3 : $Builtin.Int32
 }
+
+// CHECK-LABEL: sil @test_guaranteed_on_stack_closure
+// CHECK:  strong_retain %0 : $C
+// CHECK:  [[F:%.*]] = function_ref @use_c : $@convention(thin) (@guaranteed C) -> ()
+// CHECK:  apply [[F]](%0) : $@convention(thin) (@guaranteed C) -> ()
+// CHECK:  strong_release %0 : $C
+// CHECK-NOT:  strong_release
+// CHECK: return
+sil @test_guaranteed_on_stack_closure : $@convention(thin) (@guaranteed C) ->  () {
+bb0(%0: $C):
+  strong_retain %0 : $C
+  %closure_fun = function_ref @guaranteed_closure_func : $@convention(thin) (@guaranteed C) -> ()
+  %closure = partial_apply [on_stack] [callee_guaranteed] %closure_fun(%0) : $@convention(thin) (@guaranteed C) -> ()
+  %closure2 = mark_dependence %closure : $@noescape @callee_guaranteed () -> () on %0 : $C
+  apply %closure2() : $@noescape @callee_guaranteed () -> ()
+  strong_release %0: $C
+  dealloc_stack %closure : $@noescape @callee_guaranteed () -> ()
+  %tuple = tuple()
+  return %tuple : $()
+}
diff --git a/test/SILOptimizer/predictable_deadalloc_elim.sil b/test/SILOptimizer/predictable_deadalloc_elim.sil
new file mode 100644
index 0000000..7e40d5a
--- /dev/null
+++ b/test/SILOptimizer/predictable_deadalloc_elim.sil
@@ -0,0 +1,267 @@
+// RUN: %target-sil-opt -enable-sil-verify-all %s -predictable-deadalloc-elim | %FileCheck %s
+
+sil_stage canonical
+
+import Swift
+import Builtin
+
+// CHECK-LABEL: sil @simple_trivial_stack : $@convention(thin) (Builtin.Int32) -> () {
+// CHECK-NOT: alloc_stack
+// CHECK: } // end sil function 'simple_trivial_stack'
+sil @simple_trivial_stack : $@convention(thin) (Builtin.Int32) -> () {
+bb0(%0 : $Builtin.Int32):
+  %1 = alloc_stack $Builtin.Int32
+  store %0 to %1 : $*Builtin.Int32
+  dealloc_stack %1 : $*Builtin.Int32
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @simple_trivial_init_box : $@convention(thin) (Builtin.Int32) -> () {
+// CHECK-NOT: alloc_box
+// CHECK: } // end sil function 'simple_trivial_init_box'
+sil @simple_trivial_init_box : $@convention(thin) (Builtin.Int32) -> () {
+bb0(%0 : $Builtin.Int32):
+  %1 = alloc_box ${ var Builtin.Int32 }
+  %2 = project_box %1 : ${ var Builtin.Int32 }, 0
+  store %0 to %2 : $*Builtin.Int32
+  strong_release %1 : ${ var Builtin.Int32 }
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @simple_trivial_uninit_box : $@convention(thin) (Builtin.Int32) -> () {
+// CHECK-NOT: alloc_box
+// CHECK: } // end sil function 'simple_trivial_uninit_box'
+sil @simple_trivial_uninit_box : $@convention(thin) (Builtin.Int32) -> () {
+bb0(%0 : $Builtin.Int32):
+  %1 = alloc_box ${ var Builtin.Int32 }
+  %2 = project_box %1 : ${ var Builtin.Int32 }, 0
+  store %0 to %2 : $*Builtin.Int32
+  dealloc_box %1 : ${ var Builtin.Int32 }
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @simple_nontrivial_stack : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG:%.*]] :
+// CHECK-NEXT: strong_release [[ARG]]
+// CHECK-NEXT: tuple
+// CHECK-NEXT: return
+// CHECK: } // end sil function 'simple_nontrivial_stack'
+sil @simple_nontrivial_stack : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = alloc_stack $Builtin.NativeObject
+  store %0 to %1 : $*Builtin.NativeObject
+  destroy_addr %1 : $*Builtin.NativeObject
+  dealloc_stack %1 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We do not handle this today, since we do not understand that we need to treat
+// the strong_release of the alloc_box as a destroy_addr of the entire value.
+//
+// FIXME: We should be able to handle this.
+//
+// CHECK-LABEL: sil @simple_nontrivial_init_box : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// CHECK: alloc_box
+// CHECK: } // end sil function 'simple_nontrivial_init_box'
+sil @simple_nontrivial_init_box : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = alloc_box ${ var Builtin.NativeObject }
+  %2 = project_box %1 : ${ var Builtin.NativeObject }, 0
+  store %0 to %2 : $*Builtin.NativeObject
+  strong_release %1 : ${ var Builtin.NativeObject }
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @simple_nontrivial_uninit_box : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG:%.*]] :
+// CHECK-NEXT: strong_release [[ARG]]
+// CHECK-NEXT: tuple
+// CHECK-NEXT: return
+// CHECK: } // end sil function 'simple_nontrivial_uninit_box'
+sil @simple_nontrivial_uninit_box : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = alloc_box ${ var Builtin.NativeObject }
+  %2 = project_box %1 : ${ var Builtin.NativeObject }, 0
+  store %0 to %2 : $*Builtin.NativeObject
+  destroy_addr %2 : $*Builtin.NativeObject
+  dealloc_box %1 : ${ var Builtin.NativeObject }
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+//////////////////
+// Assign Tests //
+//////////////////
+
+// Make sure that we do eliminate this allocation
+// CHECK-LABEL: sil @simple_assign_take_trivial : $@convention(thin) (Builtin.Int32, @in Builtin.Int32) -> () {
+// CHECK-NOT: alloc_stack
+// CHECK: } // end sil function 'simple_assign_take_trivial'
+sil @simple_assign_take_trivial : $@convention(thin) (Builtin.Int32, @in Builtin.Int32) -> () {
+bb0(%0 : $Builtin.Int32, %1 : $*Builtin.Int32):
+  %2 = alloc_stack $Builtin.Int32
+  store %0 to %2 : $*Builtin.Int32
+  copy_addr [take] %1 to %2 : $*Builtin.Int32
+  dealloc_stack %2 : $*Builtin.Int32
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// In this case, we perform an init, copy. Since we do not want to lose the +1
+// on the argument, we do not eliminate this (even though with time perhaps we
+// could).
+// CHECK-LABEL: sil @simple_init_copy : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+// CHECK: alloc_stack
+// CHECK: copy_addr
+// CHECK: } // end sil function 'simple_init_copy'
+sil @simple_init_copy : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
+  %2 = alloc_stack $Builtin.NativeObject
+  store %0 to %2 : $*Builtin.NativeObject
+  destroy_addr %2 : $*Builtin.NativeObject
+  copy_addr %1 to [initialization] %2 : $*Builtin.NativeObject
+  destroy_addr %2 : $*Builtin.NativeObject
+  dealloc_stack %2 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// This we can promote successfully.
+// CHECK-LABEL: sil @simple_init_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG0:%.*]] : $Builtin.NativeObject, [[ARG1:%.*]] : $*Builtin.NativeObject):
+// CHECK-NOT: alloc_stack
+// CHECK:  strong_release [[ARG0]]
+// CHECK:  [[ARG1_LOADED:%.*]] = load [[ARG1]]
+// CHECK:  strong_release [[ARG1_LOADED]]
+// CHECK: } // end sil function 'simple_init_take'
+sil @simple_init_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
+  %2 = alloc_stack $Builtin.NativeObject
+  store %0 to %2 : $*Builtin.NativeObject
+  destroy_addr %2 : $*Builtin.NativeObject
+  copy_addr [take] %1 to [initialization] %2 : $*Builtin.NativeObject
+  destroy_addr %2 : $*Builtin.NativeObject
+  dealloc_stack %2 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// Since we are copying the input argument, we can not get rid of the copy_addr,
+// meaning we shouldn't eliminate the allocation here.
+// CHECK-LABEL: sil @simple_assign_no_take : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+// CHECK: alloc_stack
+// CHECK: copy_addr
+// CHECK: } // end sil function 'simple_assign_no_take'
+sil @simple_assign_no_take : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
+  %2 = alloc_stack $Builtin.NativeObject
+  store %0 to %2 : $*Builtin.NativeObject
+  copy_addr %1 to %2 : $*Builtin.NativeObject
+  destroy_addr %2 : $*Builtin.NativeObject
+  dealloc_stack %2 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// If PMO understood how to promote assigns, we should be able to handle this
+// case.
+// CHECK-LABEL: sil @simple_assign_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
+// CHECK: alloc_stack
+// CHECK: copy_addr
+// CHECK: } // end sil function 'simple_assign_take'
+sil @simple_assign_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
+  %2 = alloc_stack $Builtin.NativeObject
+  store %0 to %2 : $*Builtin.NativeObject
+  copy_addr [take] %1 to %2 : $*Builtin.NativeObject
+  destroy_addr %2 : $*Builtin.NativeObject
+  dealloc_stack %2 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// CHECK-LABEL: sil @simple_diamond_without_assign : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+// CHECK: bb0([[ARG:%.*]] :
+// CHECK-NOT: alloc_stack
+// CHECK-NOT: store
+// CHECK: bb3:
+// CHECK-NEXT: strong_release [[ARG]]
+// CHECK: } // end sil function 'simple_diamond_without_assign'
+sil @simple_diamond_without_assign : $@convention(thin) (@owned Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = alloc_stack $Builtin.NativeObject
+  store %0 to %1 : $*Builtin.NativeObject
+  cond_br undef, bb1, bb2
+
+bb1:
+  br bb3
+
+bb2:
+  br bb3
+
+bb3:
+  destroy_addr %1 : $*Builtin.NativeObject
+  dealloc_stack %1 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// We should not promote this due to this being an assign to %2.
+// CHECK-LABEL: sil @simple_diamond_with_assign : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+// CHECK: alloc_stack
+// CHECK: copy_addr
+// CHECK: } // end sil function 'simple_diamond_with_assign'
+sil @simple_diamond_with_assign : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
+  %2 = alloc_stack $Builtin.NativeObject
+  store %0 to %2 : $*Builtin.NativeObject
+  cond_br undef, bb1, bb2
+
+bb1:
+  copy_addr [take] %1 to %2 : $*Builtin.NativeObject
+  br bb3
+
+bb2:
+  br bb3
+
+bb3:
+  destroy_addr %2 : $*Builtin.NativeObject
+  dealloc_stack %2 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// Today PMO can not handle different available values coming from different
+// BBs. With time it can be taught to do that if necessary. That being said,
+// this test shows that we /tried/ and failed with the available value test
+// instead of failing earlier due to the copy_addr being an assign since we
+// explode the copy_addr.
+// CHECK-LABEL: sil @simple_diamond_with_assign_remove : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+// CHECK: alloc_stack
+// CHECK-NOT: copy_addr
+// CHECK: } // end sil function 'simple_diamond_with_assign_remove'
+sil @simple_diamond_with_assign_remove : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
+  %2 = alloc_stack $Builtin.NativeObject
+  store %0 to %2 : $*Builtin.NativeObject
+  cond_br undef, bb1, bb2
+
+bb1:
+  destroy_addr %2 : $*Builtin.NativeObject
+  copy_addr [take] %1 to [initialization] %2 : $*Builtin.NativeObject
+  br bb3
+
+bb2:
+  br bb3
+
+bb3:
+  destroy_addr %2 : $*Builtin.NativeObject
+  dealloc_stack %2 : $*Builtin.NativeObject
+  %9999 = tuple()
+  return %9999 : $()
+}
diff --git a/test/SILOptimizer/predictable_memopt.sil b/test/SILOptimizer/predictable_memopt.sil
index 407beac..63f6154 100644
--- a/test/SILOptimizer/predictable_memopt.sil
+++ b/test/SILOptimizer/predictable_memopt.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-verify-all %s -predictable-memopt  | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-verify-all %s -predictable-memaccess-opts -predictable-deadalloc-elim  | %FileCheck %s
 
 import Builtin
 import Swift
diff --git a/test/SILOptimizer/sil_combine_apply.sil b/test/SILOptimizer/sil_combine_apply.sil
index ed3c25c..4c9a54f 100644
--- a/test/SILOptimizer/sil_combine_apply.sil
+++ b/test/SILOptimizer/sil_combine_apply.sil
@@ -571,3 +571,68 @@
   %999 = tuple ()
   return %999 : $()
 }
+
+// CHECK-LABEL: sil shared @applied_on_stack : $@convention(thin) () -> () {
+// CHECK: bb0:
+// CHECK:   [[F:%.*]] = function_ref @indirectClosure : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64
+// CHECK:   [[STK:%.*]] = alloc_stack $Builtin.Int64
+// CHECK:   [[STK2:%.*]] = alloc_stack $Builtin.Int64
+// CHECK:   [[I:%.*]] = integer_literal $Builtin.Int64, 3
+// CHECK:   store [[I]] to [[STK2]] : $*Builtin.Int64
+// CHECK:   apply [[F]]([[STK]], [[STK2]]) : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64
+// CHECK:   dealloc_stack [[STK2]] : $*Builtin.Int64
+// CHECK:   dealloc_stack [[STK]] : $*Builtin.Int64
+// CHECK:   return %8 : $()
+
+sil shared @applied_on_stack : $@convention(thin) () -> () {
+bb0:
+  %fn = function_ref @indirectClosure : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64
+  %pa = partial_apply [callee_guaranteed] [on_stack] %fn() : $@convention(thin) (@in Builtin.Int64) -> @out Builtin.Int64
+  %out = alloc_stack $Builtin.Int64
+  %in = alloc_stack $Builtin.Int64
+  %c3 = integer_literal $Builtin.Int64, 3
+  store %c3 to %in : $*Builtin.Int64
+  %call = apply %pa(%out, %in) : $@noescape @callee_guaranteed (@in Builtin.Int64) -> @out Builtin.Int64
+  dealloc_stack %in : $*Builtin.Int64
+  dealloc_stack %out : $*Builtin.Int64
+  dealloc_stack %pa : $@noescape @callee_guaranteed (@in Builtin.Int64) -> @out Builtin.Int64
+  %999 = tuple ()
+  return %999 : $()
+}
+
+sil @guaranteed_closure_throws2 : $@convention(thin) (Builtin.Int32, @guaranteed C) -> @error Error
+
+// CHECK-LABEL: sil @test_guaranteed_closure_try_apply_on_stack
+// CHECK: bb0
+// CHECK: strong_retain
+// CHECK: strong_retain
+// CHECK: try_apply
+// CHECK: bb1
+// CHECK: strong_release
+// CHECK: strong_release
+// CHECK: br bb3
+// CHECK: bb2
+// CHECK: strong_release
+// CHECK: strong_release
+// CHECK: br bb3
+sil @test_guaranteed_closure_try_apply_on_stack : $@convention(thin) (@guaranteed C, Builtin.Int32) ->  () {
+bb0(%0: $C, %1: $Builtin.Int32):
+  strong_retain %0 : $C
+  %closure_fun = function_ref @guaranteed_closure_throws2 : $@convention(thin) (Builtin.Int32, @guaranteed C) -> @error Error
+  %closure = partial_apply [callee_guaranteed] [on_stack] %closure_fun(%0) : $@convention(thin) (Builtin.Int32, @guaranteed C) -> @error Error
+  try_apply %closure(%1) : $@noescape @callee_guaranteed (Builtin.Int32) -> @error Error, normal bb7, error bb11
+
+bb7(%callret : $()):
+	dealloc_stack %closure : $@noescape @callee_guaranteed (Builtin.Int32) -> @error Error
+	strong_release %0: $C
+  br bb99
+
+bb11(%128 : $Error):
+	dealloc_stack %closure : $@noescape @callee_guaranteed (Builtin.Int32) -> @error Error
+	strong_release %0: $C
+  br bb99
+
+bb99:
+  %t = tuple()
+  return %t : $()
+}
diff --git a/test/SILOptimizer/simplify_cfg.sil b/test/SILOptimizer/simplify_cfg.sil
index ba6cbe8..f458a34 100644
--- a/test/SILOptimizer/simplify_cfg.sil
+++ b/test/SILOptimizer/simplify_cfg.sil
@@ -2483,10 +2483,12 @@
 sil @non_throwing_closure : $@convention(thin) (Int) -> Int
 
 // CHECK-LABEL: sil @replace_try_apply_with_apply
-// CHECK: [[R:%[0-9]+]] = apply [nothrow] %0(%{{[0-9]+}}) : $@convention(thin) (@owned @callee_owned (Int) -> (Int, @error Error)) -> (Int, @error Error)
+// CHECK: [[R:%[0-9]+]] = apply [nothrow] %1(%{{[0-9]+}}) : $@convention(thin) (@owned @callee_owned (Int) -> (Int, @error Error)) -> (Int, @error Error)
+// CHECK-NEXT: dealloc_stack
 // CHECK-NEXT: return [[R]] : $Int
 sil @replace_try_apply_with_apply : $@convention(thin) () -> Int {
 bb0:
+  %as = alloc_stack $Builtin.Int32
   %0 = function_ref @rethrow_function : $@convention(thin) (@owned @callee_owned (Int) -> (Int, @error Error)) -> (Int, @error Error)
   %1 = function_ref @non_throwing_closure : $@convention(thin) (Int) -> Int
   %2 = thin_to_thick_function %1 : $@convention(thin) (Int) -> Int to $@callee_owned (Int) -> Int
@@ -2494,9 +2496,11 @@
   try_apply %0(%3) : $@convention(thin) (@owned @callee_owned (Int) -> (Int, @error Error)) -> (Int, @error Error), normal bb1, error bb2
 
 bb1(%5 : $Int):
+  dealloc_stack %as: $*Builtin.Int32
   return %5 : $Int
 
 bb2(%8 : $Error):
+  dealloc_stack %as: $*Builtin.Int32
   unreachable
 }
 
diff --git a/test/Sanitizers/asan.swift b/test/Sanitizers/asan.swift
index 9768fa7..68334f6 100644
--- a/test/Sanitizers/asan.swift
+++ b/test/Sanitizers/asan.swift
@@ -4,6 +4,9 @@
 // REQUIRES: executable_test
 // REQUIRES: asan_runtime
 
+// rdar://problem/47367694 tracks re-enabling this test for backward deployment.
+// UNSUPPORTED: remote_run
+
 // Make sure we can handle swifterror. LLVM's address sanitizer pass needs to
 // ignore swifterror addresses.
 
diff --git a/test/Sanitizers/tsan.swift b/test/Sanitizers/tsan.swift
index a9cfe9f..512bef2 100644
--- a/test/Sanitizers/tsan.swift
+++ b/test/Sanitizers/tsan.swift
@@ -4,6 +4,7 @@
 // REQUIRES: executable_test
 // REQUIRES: tsan_runtime
 // UNSUPPORTED: OS=tvos
+// UNSUPPORTED: CPU=powerpc64le
 
 // FIXME: This should be covered by "tsan_runtime"; older versions of Apple OSs
 // don't support TSan.
diff --git a/test/Serialization/sil_partial_apply_ownership.sil b/test/Serialization/sil_partial_apply_ownership.sil
index 221d2ae..ac6ef32 100644
--- a/test/Serialization/sil_partial_apply_ownership.sil
+++ b/test/Serialization/sil_partial_apply_ownership.sil
@@ -62,3 +62,17 @@
   %t = tuple ()
   return %t : $()
 }
+
+// CHECK-LABEL: sil @partial_apply_on_stack
+// CHECK:  partial_apply [callee_guaranteed] [on_stack] %{{.*}} : $@convention(thin) (Builtin.Int64) -> ()
+sil @partial_apply_on_stack : $@convention(thin) () -> () {
+entry:
+  %f = function_ref @subject : $@convention(thin) (Builtin.Int64) -> ()
+  %z = integer_literal $Builtin.Int64, 0
+  %c = partial_apply [callee_guaranteed] [on_stack] %f(%z) : $@convention(thin) (Builtin.Int64) -> ()
+  %f2 = function_ref @use : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  apply %f2(%c) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
+  dealloc_stack %c : $@noescape @callee_guaranteed () -> ()
+  %t = tuple ()
+  return %t : $()
+}
diff --git a/test/Syntax/Inputs/invalid.sed b/test/Syntax/Inputs/invalid.sed
new file mode 100644
index 0000000..41894dd
--- /dev/null
+++ b/test/Syntax/Inputs/invalid.sed
@@ -0,0 +1,32 @@
+
+# [0xC2] is utf8 2 byte character start byte.
+# 0xC2 without second byte is invalid UTF-8 sequence.
+# It becomes garbage text trivia.
+# Marker(1) is replaced to this sequence.
+s/Z1/Â/g
+
+# [0xCC, 0x82] in UTF-8 is U+0302.
+# This character is invalid for identifier start, but valid for identifier body.
+# It becomes unknown token.
+# If this type characters are conitguous, they are concatenated to one long unknown token.
+# Marker(2) is replaced to this sequence.
+s/Z2/̂/g
+
+# [0xE2, 0x80, 0x9C] in UTF-8 is U+201C, left quote.
+# It becomes single character unknown token.
+# If this left quote and right quote enclosure text,
+# they become one long unknown token.
+# Marker(3) is replaced to this sequence.
+s/Z3/“/g
+
+# [0xE2, 0x80, 0x9D] in UTF-8 is U+201D, right quote.
+# It becomes single character unknown token.
+# Marker(4) is replaced to this sequence.
+s/Z4/”/g
+
+# [0xE1, 0x9A, 0x80] in UTF-8 is U+1680.
+# This character is invalid for swift source.
+# It becomes garbage trivia.
+# Marker(5) is replaced to this sequence.
+s/Z5/ /g
+
diff --git a/test/Syntax/Inputs/nbsp.sed b/test/Syntax/Inputs/nbsp.sed
new file mode 100644
index 0000000..3d9adf5
--- /dev/null
+++ b/test/Syntax/Inputs/nbsp.sed
@@ -0,0 +1 @@
+s/Z/ /g
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index 2c1af8b..512ca73 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -51,7 +51,8 @@
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ArrayExpr>[<ArrayElement><FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr>, </ArrayElement><ArrayElement><FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr>, </ArrayElement><ArrayElement><FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr>, </ArrayElement><ArrayElement><FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr></ArrayElement>]</ArrayExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><DictionaryExpr>[<DictionaryElement><StringLiteralExpr>"a"</StringLiteralExpr>: <FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr>, </DictionaryElement><DictionaryElement><StringLiteralExpr>"b"</StringLiteralExpr>: <FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr>, </DictionaryElement><DictionaryElement><StringLiteralExpr>"c"</StringLiteralExpr>: <FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr>, </DictionaryElement><DictionaryElement><StringLiteralExpr>"d"</StringLiteralExpr>: <FunctionCallExpr><IdentifierExpr>bar3</IdentifierExpr>(<FunctionCallArgument>a:<IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr></DictionaryElement>]</DictionaryExpr></SequenceExpr><FunctionCallExpr><IdentifierExpr>
     foo</IdentifierExpr>(<FunctionCallArgument><NilLiteralExpr>nil</NilLiteralExpr>, </FunctionCallArgument><FunctionCallArgument><NilLiteralExpr>nil</NilLiteralExpr>, </FunctionCallArgument><FunctionCallArgument><NilLiteralExpr>nil</NilLiteralExpr></FunctionCallArgument>)</FunctionCallExpr><SequenceExpr><DiscardAssignmentExpr>
-    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><DotSelfExpr><FunctionCallExpr><IdentifierExpr>type</IdentifierExpr>(<FunctionCallArgument>of: <IdentifierExpr>a</IdentifierExpr></FunctionCallArgument>)</FunctionCallExpr>.self</DotSelfExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><FunctionCallExpr><IdentifierExpr>type</IdentifierExpr>(<FunctionCallArgument>of: <IdentifierExpr>a</IdentifierExpr></FunctionCallArgument>)</FunctionCallExpr>.self</MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><IdentifierExpr>a</IdentifierExpr>.`self`</MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><IdentifierExpr>A </IdentifierExpr><ArrowExpr>-> </ArrowExpr><MemberAccessExpr><IdentifierExpr>B</IdentifierExpr>.C</MemberAccessExpr><BinaryOperatorExpr><</BinaryOperatorExpr><PostfixUnaryExpr><IdentifierExpr>Int</IdentifierExpr>></PostfixUnaryExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
     _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><ArrayExpr>[<ArrayElement><SequenceExpr><TupleExpr>(<TupleElement><IdentifierExpr>A</IdentifierExpr></TupleElement>) </TupleExpr><ArrowExpr>throws -> </ArrowExpr><IdentifierExpr>B</IdentifierExpr></SequenceExpr></ArrayElement>]</ArrayExpr>()</FunctionCallExpr></SequenceExpr>
   }</CodeBlock></FunctionDecl></MemberDeclListItem><MemberDeclListItem><FunctionDecl>
@@ -90,11 +91,11 @@
   }</CodeBlock></FunctionDecl></MemberDeclListItem><MemberDeclListItem><FunctionDecl>
 
   func implictMember<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<SequenceExpr><DiscardAssignmentExpr>
-    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
-    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr>(<FunctionCallArgument>x: <IntegerLiteralExpr>12</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
-    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><ImplicitMemberExpr>.foo </ImplicitMemberExpr><ClosureExpr>{ <IntegerLiteralExpr>12 </IntegerLiteralExpr>}</ClosureExpr></FunctionCallExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
-    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><SubscriptExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr>[<FunctionCallArgument><IntegerLiteralExpr>12</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
-    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr>.bar</MemberAccessExpr></SequenceExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr>.foo</MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><MemberAccessExpr>.foo</MemberAccessExpr>(<FunctionCallArgument>x: <IntegerLiteralExpr>12</IntegerLiteralExpr></FunctionCallArgument>)</FunctionCallExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><MemberAccessExpr>.foo </MemberAccessExpr><ClosureExpr>{ <IntegerLiteralExpr>12 </IntegerLiteralExpr>}</ClosureExpr></FunctionCallExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><SubscriptExpr><MemberAccessExpr>.foo</MemberAccessExpr>[<FunctionCallArgument><IntegerLiteralExpr>12</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+    _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><MemberAccessExpr>.foo</MemberAccessExpr>.bar</MemberAccessExpr></SequenceExpr>
   }</CodeBlock></FunctionDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl>
 
   init<ParameterClause>() </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl><Attribute>
@@ -264,8 +265,8 @@
   foo</IdentifierExpr>[<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr><SubscriptExpr><IdentifierExpr>
   foo</IdentifierExpr>[] <ClosureExpr>{}</ClosureExpr></SubscriptExpr><SubscriptExpr><IdentifierExpr>
   foo</IdentifierExpr>[<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>] <ClosureExpr>{}</ClosureExpr></SubscriptExpr><SubscriptExpr><SubscriptExpr><IdentifierExpr>
-  foo</IdentifierExpr>[<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr>[<FunctionCallArgument><IntegerLiteralExpr>2</IntegerLiteralExpr>,</FunctionCallArgument><FunctionCallArgument>x:<IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr><DotSelfExpr><FunctionCallExpr><ForcedValueExpr><MemberAccessExpr><PostfixUnaryExpr><OptionalChainingExpr><IdentifierExpr>
-  foo</IdentifierExpr>?</OptionalChainingExpr>++</PostfixUnaryExpr>.bar</MemberAccessExpr>!</ForcedValueExpr>(<FunctionCallArgument><IdentifierExpr>baz</IdentifierExpr></FunctionCallArgument>)</FunctionCallExpr>.self</DotSelfExpr><MemberAccessExpr><FunctionCallExpr><IdentifierExpr>
+  foo</IdentifierExpr>[<FunctionCallArgument><IntegerLiteralExpr>1</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr>[<FunctionCallArgument><IntegerLiteralExpr>2</IntegerLiteralExpr>,</FunctionCallArgument><FunctionCallArgument>x:<IntegerLiteralExpr>3</IntegerLiteralExpr></FunctionCallArgument>]</SubscriptExpr><MemberAccessExpr><FunctionCallExpr><ForcedValueExpr><MemberAccessExpr><PostfixUnaryExpr><OptionalChainingExpr><IdentifierExpr>
+  foo</IdentifierExpr>?</OptionalChainingExpr>++</PostfixUnaryExpr>.bar</MemberAccessExpr>!</ForcedValueExpr>(<FunctionCallArgument><IdentifierExpr>baz</IdentifierExpr></FunctionCallArgument>)</FunctionCallExpr>.self</MemberAccessExpr><MemberAccessExpr><FunctionCallExpr><IdentifierExpr>
   foo</IdentifierExpr>()</FunctionCallExpr>.0</MemberAccessExpr><MemberAccessExpr><SpecializeExpr><IdentifierExpr>
   foo</IdentifierExpr><GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SpecializeExpr>.bar</MemberAccessExpr><FunctionCallExpr><SpecializeExpr><IdentifierExpr>
   foo</IdentifierExpr><GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SpecializeExpr>()</FunctionCallExpr><FunctionCallExpr><SpecializeExpr><MemberAccessExpr><IdentifierExpr>
@@ -273,7 +274,7 @@
 
   foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></IdentifierExpr>()</FunctionCallExpr><FunctionCallExpr><SpecializeExpr><IdentifierExpr>
   foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument>)</DeclNameArguments></IdentifierExpr><GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Int</SimpleTypeIdentifier></GenericArgument>> </GenericArgumentClause></SpecializeExpr><ClosureExpr>{ }</ClosureExpr></FunctionCallExpr><SequenceExpr><DiscardAssignmentExpr>
-  _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><ImplicitMemberExpr>.foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></ImplicitMemberExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
+  _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr>.foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
   _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><MemberAccessExpr><IdentifierExpr>x</IdentifierExpr>.foo<DeclNameArguments>(<DeclNameArgument>x:</DeclNameArgument><DeclNameArgument>y:</DeclNameArgument>)</DeclNameArguments></MemberAccessExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
   _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><FunctionCallExpr><IdentifierExpr>foo</IdentifierExpr>(<FunctionCallArgument><InOutExpr>&<IdentifierExpr>d</IdentifierExpr></InOutExpr></FunctionCallArgument>)</FunctionCallExpr></SequenceExpr><SequenceExpr><DiscardAssignmentExpr>
   _ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><EditorPlaceholderExpr><#Placeholder#> </EditorPlaceholderExpr><BinaryOperatorExpr>+ </BinaryOperatorExpr><EditorPlaceholderExpr><#T##(Int) -> Int#></EditorPlaceholderExpr></SequenceExpr>
@@ -318,7 +319,7 @@
     case <CaseItem><ValueBindingPattern>let <ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><IdentifierPattern>b</IdentifierPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
     case <CaseItem><ExpressionPattern><TupleExpr>(<TupleElement><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>a</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr>, </TupleElement><TupleElement><UnresolvedPatternExpr><ValueBindingPattern>var <IdentifierPattern>b</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></TupleElement>)</TupleExpr></ExpressionPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
     case <CaseItem><IsTypePattern>is <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></IsTypePattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
-    case <CaseItem><ValueBindingPattern>let <ExpressionPattern><FunctionCallExpr><ImplicitMemberExpr>.bar</ImplicitMemberExpr>(<FunctionCallArgument><UnresolvedPatternExpr><IdentifierPattern>x</IdentifierPattern></UnresolvedPatternExpr></FunctionCallArgument>)</FunctionCallExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
+    case <CaseItem><ValueBindingPattern>let <ExpressionPattern><FunctionCallExpr><MemberAccessExpr>.bar</MemberAccessExpr>(<FunctionCallArgument><UnresolvedPatternExpr><IdentifierPattern>x</IdentifierPattern></UnresolvedPatternExpr></FunctionCallArgument>)</FunctionCallExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
     case <CaseItem><ExpressionPattern><MemberAccessExpr><IdentifierExpr>MyEnum</IdentifierExpr>.foo</MemberAccessExpr></ExpressionPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
     case <CaseItem><ValueBindingPattern>let <ExpressionPattern><SequenceExpr><UnresolvedPatternExpr><IdentifierPattern>a </IdentifierPattern></UnresolvedPatternExpr><AsExpr>as <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AsExpr></SequenceExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><SwitchCaseLabel>
     case <CaseItem><ValueBindingPattern>let <ExpressionPattern><OptionalChainingExpr><UnresolvedPatternExpr><IdentifierPattern>a</IdentifierPattern></UnresolvedPatternExpr>?</OptionalChainingExpr></ExpressionPattern></ValueBindingPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase>
@@ -384,7 +385,7 @@
     case <CaseItem><ValueBindingPattern>let <IdentifierPattern>y</IdentifierPattern></ValueBindingPattern></CaseItem>:</SwitchCaseLabel><BreakStmt>
       break</BreakStmt></SwitchCase></IfConfigClause><IfConfigClause>
 #else<SwitchCase><SwitchCaseLabel>
-    case <CaseItem><ExpressionPattern><FunctionCallExpr><ImplicitMemberExpr>.foo</ImplicitMemberExpr>(<FunctionCallArgument><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>x</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></FunctionCallArgument>)</FunctionCallExpr></ExpressionPattern></CaseItem>:</SwitchCaseLabel><BreakStmt>
+    case <CaseItem><ExpressionPattern><FunctionCallExpr><MemberAccessExpr>.foo</MemberAccessExpr>(<FunctionCallArgument><UnresolvedPatternExpr><ValueBindingPattern>let <IdentifierPattern>x</IdentifierPattern></ValueBindingPattern></UnresolvedPatternExpr></FunctionCallArgument>)</FunctionCallExpr></ExpressionPattern></CaseItem>:</SwitchCaseLabel><BreakStmt>
       break</BreakStmt></SwitchCase></IfConfigClause>
 #endif</IfConfigDecl><SwitchCase><SwitchDefaultLabel>
     default:</SwitchDefaultLabel><BreakStmt>
@@ -532,7 +533,7 @@
   @_implements(<ImplementsAttributeArguments><SimpleTypeIdentifier>P</SimpleTypeIdentifier>, x</ImplementsAttributeArguments>)</Attribute>
   var <PatternBinding><IdentifierPattern>y</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier></TypeAnnotation></PatternBinding></VariableDecl></MemberDeclListItem><MemberDeclListItem><FunctionDecl><Attribute>
   @_implements(<ImplementsAttributeArguments><SimpleTypeIdentifier>P</SimpleTypeIdentifier>, g<DeclNameArguments>()</DeclNameArguments></ImplementsAttributeArguments>)</Attribute>
-  func h<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl><Attribute>
+  func h<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{ <SequenceExpr><DiscardAssignmentExpr>_ </DiscardAssignmentExpr><AssignmentExpr>= </AssignmentExpr><KeyPathExpr>\<MemberAccessExpr>.self </MemberAccessExpr></KeyPathExpr></SequenceExpr>}</CodeBlock></FunctionDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl><Attribute>
 
   @available(<AvailabilityArgument>*, </AvailabilityArgument><AvailabilityArgument><AvailabilityLabeledArgument>deprecated: <VersionTuple>1.2</VersionTuple></AvailabilityLabeledArgument>, </AvailabilityArgument><AvailabilityArgument><AvailabilityLabeledArgument>message: "ABC"</AvailabilityLabeledArgument></AvailabilityArgument>)</Attribute><DeclModifier>
   fileprivate(set) </DeclModifier>var <PatternBinding><IdentifierPattern>x</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier></TypeAnnotation></PatternBinding></VariableDecl></MemberDeclListItem>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index b17b017..22cfc0c 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -52,6 +52,7 @@
     _ = ["a": bar3(a:1), "b": bar3(a:1), "c": bar3(a:1), "d": bar3(a:1)]
     foo(nil, nil, nil)
     _ = type(of: a).self
+    _ = a.`self`
     _ = A -> B.C<Int>
     _ = [(A) throws -> B]()
   }
@@ -532,7 +533,7 @@
   @_implements(P, x)
   var y: String
   @_implements(P, g())
-  func h() {}
+  func h() { _ = \.self }
 
   @available(*, deprecated: 1.2, message: "ABC")
   fileprivate(set) var x: String
diff --git a/test/Syntax/tokens_nonbreaking_space.swift b/test/Syntax/tokens_nonbreaking_space.swift
index 97cd258..b0da4ce 100644
--- a/test/Syntax/tokens_nonbreaking_space.swift
+++ b/test/Syntax/tokens_nonbreaking_space.swift
@@ -1,4 +1,4 @@
-// RUN: cat %s | sed -e 's/'$(echo -ne "\x5a")'/'$(echo -ne "\xc2\xa0")'/g' > %t.tmp
+// RUN: cat %s | sed -f %S/Inputs/nbsp.sed > %t.tmp
 // RUN: cp -f %t.tmp %t
 // RUN: %swift-syntax-test -input-source-filename %t -dump-full-tokens 2>&1 | %FileCheck %t
 let a =Z3Z // nbsp(Z)
diff --git a/test/Syntax/tokens_unknown_and_invalid.swift b/test/Syntax/tokens_unknown_and_invalid.swift
index 98be090..3a5cb16 100644
--- a/test/Syntax/tokens_unknown_and_invalid.swift
+++ b/test/Syntax/tokens_unknown_and_invalid.swift
@@ -5,46 +5,8 @@
 // To avoid replace marker in sed command by sed itself,
 // marker is also represented in escape sequence.
 
-// RUN: cat %s | sed \
-
-// [0xC2] is utf8 2 byte character start byte.
-// 0xC2 without second byte is invalid UTF-8 sequence.
-// It becomes garbage text trivia.
-// Marker(1) is replaced to this sequence.
-
-// RUN: -e 's/'$(echo -ne "\x5a1")'/'$(echo -ne "\xc2")'/g' \
-
-// [0xCC, 0x82] in UTF-8 is U+0302.
-// This character is invalid for identifier start, but valid for identifier body.
-// It becomes unknown token.
-// If this type characters are conitguous, they are concatenated to one long unknown token.
-// Marker(2) is replaced to this sequence.
-
-// RUN: -e 's/'$(echo -ne "\x5a2")'/'$(echo -ne "\xcc\x82")'/g' \
-
-// [0xE2, 0x80, 0x9C] in UTF-8 is U+201C, left quote.
-// It becomes single character unknown token.
-// If this left quote and right quote enclosure text,
-// they become one long unknown token.
-// Marker(3) is replaced to this sequence.
-
-// RUN: -e 's/'$(echo -ne "\x5a3")'/'$(echo -ne "\xe2\x80\x9c")'/g' \
-
-// [0xE2, 0x80, 0x9D] in UTF-8 is U+201D, right quote.
-// It becomes single character unknown token.
-// Marker(4) is replaced to this sequence.
-
-// RUN: -e 's/'$(echo -ne "\x5a4")'/'$(echo -ne "\xe2\x80\x9d")'/g' \
-
-// [0xE1, 0x9A, 0x80] in UTF-8 is U+1680.
-// This character is invalid for swift source.
-// It becomes garbage trivia.
-// Marker(5) is replaced to this sequence.
-
-// RUN: -e 's/'$(echo -ne "\x5a5")'/'$(echo -ne "\xe1\x9a\x80")'/g' \
-
-// RUN: > %t
-
+// RUN: cat %s | sed -f %S/Inputs/invalid.sed > %t
+// RUN: %{python} -c "import sys; t = open(sys.argv[1], 'rb').read().replace('\r\n', '\n'); open(sys.argv[1], 'wb').write(t)" %t
 // RUN: %swift-syntax-test -input-source-filename %t -dump-full-tokens 2>&1 | %FileCheck %t
 // RUN: %round-trip-syntax-test --swift-syntax-test %swift-syntax-test --file %t
 
@@ -66,20 +28,20 @@
 jjj
 
 // Diagnostics
-// CHECK: 52:1: error: invalid UTF-8 found in source file
-// CHECK: 52:7: error: invalid UTF-8 found in source file
-// CHECK: 54:5: error: an identifier cannot begin with this character
-// CHECK: 56:5: error: an identifier cannot begin with this character
-// CHECK: 58:5: error: unicode curly quote found
-// CHECK: 58:8: error: unicode curly quote found
-// CHECK: 60:19: error: unicode curly quote found
-// CHECK: 60:5: error: unicode curly quote found
-// CHECK: 62:5: error: unicode curly quote found
-// CHECK: 65:1: error: invalid character in source file
-// CHECK: 65:9: error: invalid character in source file
+// CHECK: 14:1: error: invalid UTF-8 found in source file
+// CHECK: 14:7: error: invalid UTF-8 found in source file
+// CHECK: 16:5: error: an identifier cannot begin with this character
+// CHECK: 18:5: error: an identifier cannot begin with this character
+// CHECK: 20:5: error: unicode curly quote found
+// CHECK: 20:8: error: unicode curly quote found
+// CHECK: 22:19: error: unicode curly quote found
+// CHECK: 22:5: error: unicode curly quote found
+// CHECK: 24:5: error: unicode curly quote found
+// CHECK: 27:1: error: invalid character in source file
+// CHECK: 27:9: error: invalid character in source file
 
 // Checks around bbb
-// CHECK-LABEL: 52:3
+// CHECK-LABEL: 14:3
 // CHECK-NEXT:  (Token identifier
 // CHECK-NEXT:   (trivia newline 1)
 // CHECK-NEXT:   (trivia garbageText \302)
@@ -89,35 +51,35 @@
 // CHECK-NEXT:   (trivia garbageText \302))
 
 // Checks around ccc
-// CHECK-LABEL: 54:5
+// CHECK-LABEL: 16:5
 // CHECK-NEXT:  (Token unknown
 // CHECK-NEXT:   (text="\xCC\x82"))
 
 // Checks around ddd
-// CHECK-LABEL: 56:5
+// CHECK-LABEL: 18:5
 // CHECK-NEXT:  (Token unknown
 // CHECK-NEXT:   (text="\xCC\x82\xCC\x82\xCC\x82\xCC\x82"))
 
 // Checks around eee
-// CHECK-LABEL: 58:5
+// CHECK-LABEL: 20:5
 // CHECK-NEXT:  (Token unknown
 // CHECK-NEXT:   (text="\xE2\x80\x9C"))
-// CHECK-LABEL: 58:8
+// CHECK-LABEL: 20:8
 // CHECK-NEXT:  (Token unknown
 // CHECK-NEXT:   (text="\xE2\x80\x9C"))
 
 // Checks around fff
-// CHECK-LABEL: 60:5
+// CHECK-LABEL: 22:5
 // CHECK-NEXT:  (Token unknown
 // CHECK-NEXT:   (text="\xE2\x80\x9Chello world\xE2\x80\x9D"))
 
 // Checks around ggg
-// CHECK-LABEL: 62:5
+// CHECK-LABEL: 24:5
 // CHECK-NEXT:  (Token unknown
 // CHECK-NEXT:   (text="\xE2\x80\x9D"))
 
 // Checks around iii
-// CHECK-LABEL: 65:5
+// CHECK-LABEL: 27:5
 // CHECK-NEXT:  (Token identifier
 // CHECK-NEXT:   (trivia newline 1)
 // CHECK-NEXT:   (trivia garbageText \341\232\200)
diff --git a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
index f8a2ab1..d06683a 100644
--- a/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-abi.swift.expected
@@ -71,3 +71,5 @@
 Var _NativeSet._storage has declared type change from _RawSetStorage to __RawSetStorage
 Var _RawDictionaryStorage.empty has declared type change from _EmptyDictionarySingleton to __EmptyDictionarySingleton
 Var _RawSetStorage.empty has declared type change from _EmptySetSingleton to __EmptySetSingleton
+
+Func tryReallocateUniquelyReferenced(buffer:newMinimumCapacity:) has been removed
diff --git a/test/api-digester/Outputs/stability-stdlib-source.swift.expected b/test/api-digester/Outputs/stability-stdlib-source.swift.expected
index e69de29..5678bdb 100644
--- a/test/api-digester/Outputs/stability-stdlib-source.swift.expected
+++ b/test/api-digester/Outputs/stability-stdlib-source.swift.expected
@@ -0,0 +1 @@
+Func tryReallocateUniquelyReferenced(buffer:newMinimumCapacity:) has been removed
diff --git a/test/decl/func/rethrows.swift b/test/decl/func/rethrows.swift
index 86ca746..46de659 100644
--- a/test/decl/func/rethrows.swift
+++ b/test/decl/func/rethrows.swift
@@ -584,3 +584,22 @@
 }
 
 Box(unbox: 1) |> suchThat <| { $0 + 1 } // expected-warning {{result of operator '<|' is unused}}
+
+// Constructor delegation -vs- rethrows
+class RethrowingConstructor {
+  init(_ block: () throws -> ()) rethrows {
+    try block()
+  }
+
+  convenience init(bar: Int) {
+    self.init {
+      print("Foo!")
+    }
+  }
+
+  convenience init(baz: Int) throws {
+    try self.init {
+      try throwingFunc()
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/lit.cfg b/test/lit.cfg
index df81bfc..640c926 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -1275,6 +1275,8 @@
 config.substitutions.append(('%target-ld', config.target_ld))
 if hasattr(config, 'target_cc_options'):
     config.substitutions.append(('%target-cc-options', config.target_cc_options))
+else:
+    config.substitutions.append(('%target-cc-options', ''))
 
 config.substitutions.append(
     (r'%hardlink-or-copy\(from: *(.*), *to: *(.*)\)',
@@ -1325,7 +1327,7 @@
 config.substitutions.append(('%target-swift-modulewrap',
                              config.target_swift_modulewrap))
 
-platform_module_dir = make_path(test_resource_dir, '%target-sdk-name', run_cpu)
+platform_module_dir = make_path(test_resource_dir, config.target_sdk_name, run_cpu)
 lit_config.note('Using platform module dir: ' + platform_module_dir)
 if test_sdk_overlay_dir is not None:
     platform_sdk_overlay_dir = make_path(test_sdk_overlay_dir, run_cpu)
diff --git a/test/remote-run/upload-stderr.test-sh b/test/remote-run/upload-stderr.test-sh
index e6a883d..3ed6bd5 100644
--- a/test/remote-run/upload-stderr.test-sh
+++ b/test/remote-run/upload-stderr.test-sh
@@ -1,4 +1,5 @@
 REQUIRES: sftp_server
+// XFAIL: CPU=powerpc64le
 
 RUN: %empty-directory(%t)
 RUN: %empty-directory(%t/REMOTE/input)
diff --git a/test/stdlib/Compression.swift b/test/stdlib/Compression.swift
new file mode 100644
index 0000000..716874b
--- /dev/null
+++ b/test/stdlib/Compression.swift
@@ -0,0 +1,148 @@
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+
+import StdlibUnittest
+import Compression
+import Foundation
+
+// Read from Data
+class DataSource {
+
+  private var _buf : Data
+  private var _bufSize : Int // total byte count
+  private var _pos : Int  // next byte to read
+
+  public init(_ d: Data) {
+    _buf = d
+    _bufSize = d.count
+    _pos = 0
+  }
+
+  public func readData(ofLength len: Int) -> Data? {
+    let n = min(len,_bufSize - _pos)
+    if (n == 0) { return nil } // EOF
+    let d = _buf.subdata(in: _pos ..< _pos + n)
+    _pos += n
+    return d
+  }
+
+}
+
+@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
+func ofiltercompress_ifilterdecompress(
+  _ contents: Data, using algo: Algorithm
+) throws -> Bool {
+
+  var payload = Data()
+  var decompressed = Data()
+
+  // Output filter compress
+  let f = DataSource(contents)
+  let ofilter = try OutputFilter(.compress, using: algo) { (x: Data?) -> () in
+      if let x = x { payload.append(x) }
+  }
+  while (true) {
+    let i = f.readData(ofLength: 900)
+    try ofilter.write(i) // will finalize when i is empty
+    if i == nil { break }
+  }
+
+  // Input filter decompress
+  let g = DataSource(payload)
+  let ifilter = try InputFilter(.decompress, using: algo) { (x: Int) -> Data? in
+    return g.readData(ofLength: x)
+  }
+  while let i = try ifilter.readData(ofLength: 400) {
+    decompressed.append(i)
+  }
+
+  print("ofilter | ifilter \(algo): \(contents.count) -> \(payload.count) -> \(decompressed.count)")
+  return contents == decompressed
+}
+
+@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
+func ifiltercompress_ofilterdecompress(
+  _ contents: Data, using algo: Algorithm
+) throws -> Bool {
+
+  var payload = Data()
+  var decompressed = Data()
+
+  // Input filter compress
+  let f = DataSource(contents)
+  let ifilter = try InputFilter(.compress, using: algo) {(x: Int) -> Data? in
+    return f.readData(ofLength:x)
+  }
+  while let i = try ifilter.readData(ofLength: 400) {
+    payload.append(i)
+  }
+
+  // Output filter decompress
+  let g = DataSource(payload)
+  let ofilter = try OutputFilter(.decompress, using: algo) {(x: Data?) -> () in
+    if let x = x {
+      decompressed.append(x)
+    }
+  }
+  while (true) {
+    let i = g.readData(ofLength: 900)
+    try ofilter.write(i) // will finalize when i is empty
+    if i == nil { break }
+  }
+
+  print("ifilter | ofilter \(algo): \(contents.count) -> \(payload.count) -> \(decompressed.count)")
+
+  return contents == decompressed
+}
+
+func randomString(withBlockLength n: Int) -> String {
+  var strings = [String]()
+  for _ in 0 ..< n {
+    var s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
+      // Change some random chars
+      for _ in 1...10 {
+        let pos = Int.random(in: 0 ..< s.count)
+        let idx = s.index(s.startIndex, offsetBy: pos)
+        s = String(s[..<idx] + "#" + s[idx...])
+      }
+    strings.append(s)
+  }
+  return strings.joined(separator: "")
+}
+
+let tests = TestSuite("Compression")
+
+if #available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) {
+
+  do {
+    for blockLength in [0, 1, 2, 5, 10, 100] {
+      let testString = randomString(withBlockLength: blockLength)
+      let contents = testString.data(using: .utf8)!
+
+      for algo in Algorithm.allCases {
+        tests.test("OutputFilter/Compress/InputFilter/Decompress/\(algo)/\(blockLength)") {
+          expectDoesNotThrow({
+            expectTrue(
+              try ofiltercompress_ifilterdecompress(contents, using: algo),
+              "Failing input: \(testString)"
+            )
+          })
+        }
+
+        tests.test("InputFilter/Compress/OutputFilter/Decompress/\(algo)/\(blockLength)") {
+          expectDoesNotThrow({
+            expectTrue(
+              try ifiltercompress_ofilterdecompress(contents, using: algo),
+              "Failing input: \(testString)"
+            )
+          })
+        }
+      }
+
+    } // blockLength
+  }
+
+}
+
+runAllTests()
diff --git a/test/stdlib/ManagedBuffer.swift b/test/stdlib/ManagedBuffer.swift
index 8d39d3f..24d288c 100644
--- a/test/stdlib/ManagedBuffer.swift
+++ b/test/stdlib/ManagedBuffer.swift
@@ -40,7 +40,7 @@
 
 struct CountAndCapacity {
   var count: LifetimeTracked
-  var capacity: Int
+  let capacity: Int
 }
 
 // An example of ManagedBuffer, very similar to what Array will use.
@@ -96,23 +96,6 @@
     }
     self.count = count + 2
   }
-
-  class func tryGrow(_ buffer: inout TestManagedBuffer<T>, newCapacity: Int) -> Bool {
-    guard isKnownUniquelyReferenced(&buffer) else {
-      return false
-    }
-    guard newCapacity > buffer.capacity else {
-      return false
-    }
-
-    if tryReallocateUniquelyReferenced(buffer: &buffer,
-                                       newMinimumCapacity: newCapacity) {
-      buffer.header.capacity = newCapacity
-      return true
-    } else {
-      return false
-    }
-  }
 }
 
 class MyBuffer<T> {
@@ -258,35 +241,4 @@
   _fixLifetime(s2)
 }
 
-tests.test("canGrowUsingRealloc") {
-  #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
-  return // realloc currently unsupported on Darwin
-  #endif
-  func testGrow(_ buffer: inout TestManagedBuffer<LifetimeTracked>,
-                newCapacity: Int,
-                shouldSucceed: Bool = true) {
-    let s = TestManagedBuffer.tryGrow(&buffer, newCapacity: newCapacity)
-    expectEqual(s, shouldSucceed)
-    if shouldSucceed {
-      expectLE(newCapacity, buffer.myCapacity)
-      expectGE((newCapacity + 1) * 2, buffer.myCapacity)
-    }
-    repeat {
-      buffer.append(LifetimeTracked(buffer.count))
-    } while buffer.count < buffer.myCapacity - 2
-  }
-
-  var b = TestManagedBuffer<LifetimeTracked>.create(0)
-  // allow some over-allocation
-  expectLE(0, b.myCapacity)
-  expectGE(3, b.myCapacity)
-
-  testGrow(&b, newCapacity: 5)
-  testGrow(&b, newCapacity: 8)
-  testGrow(&b, newCapacity: 1000)
-  testGrow(&b, newCapacity: 16000)
-  var b2 = b
-  testGrow(&b, newCapacity: 2000, shouldSucceed: false)
-}
-
 runAllTests()
diff --git a/test/stmt/statements.swift b/test/stmt/statements.swift
index fd0ae6f..06e00b0 100644
--- a/test/stmt/statements.swift
+++ b/test/stmt/statements.swift
@@ -535,6 +535,70 @@
   if (x: 1) {} // expected-error {{'(x: Int)' is not convertible to 'Bool'}}
 }
 
+// Typo correction for loop labels
+for _ in [1] {
+  break outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  continue outerloop // expected-error {{use of unresolved label 'outerloop'}}
+}
+while true {
+  break outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  continue outerloop // expected-error {{use of unresolved label 'outerloop'}}
+}
+repeat {
+  break outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  continue outerloop // expected-error {{use of unresolved label 'outerloop'}}
+} while true
+
+outerLoop: for _ in [1] { // expected-note {{'outerLoop' declared here}}
+  break outerloop // expected-error {{use of unresolved label 'outerloop'; did you mean 'outerLoop'?}} {{9-18=outerLoop}}
+}
+outerLoop: for _ in [1] { // expected-note {{'outerLoop' declared here}}
+  continue outerloop // expected-error {{use of unresolved label 'outerloop'; did you mean 'outerLoop'?}} {{12-21=outerLoop}}
+}
+outerLoop: while true { // expected-note {{'outerLoop' declared here}}
+  break outerloop // expected-error {{use of unresolved label 'outerloop'; did you mean 'outerLoop'?}} {{9-18=outerLoop}}
+}
+outerLoop: while true { // expected-note {{'outerLoop' declared here}}
+  continue outerloop // expected-error {{use of unresolved label 'outerloop'; did you mean 'outerLoop'?}} {{12-21=outerLoop}}
+}
+outerLoop: repeat { // expected-note {{'outerLoop' declared here}}
+  break outerloop // expected-error {{use of unresolved label 'outerloop'; did you mean 'outerLoop'?}} {{9-18=outerLoop}}
+} while true
+outerLoop: repeat { // expected-note {{'outerLoop' declared here}}
+  continue outerloop // expected-error {{use of unresolved label 'outerloop'; did you mean 'outerLoop'?}} {{12-21=outerLoop}}
+} while true
+
+outerLoop1: for _ in [1] { // expected-note {{did you mean 'outerLoop1'?}} {{11-20=outerLoop1}}
+  outerLoop2: for _ in [1] { // expected-note {{did you mean 'outerLoop2'?}} {{11-20=outerLoop2}}
+    break outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  }
+}
+outerLoop1: for _ in [1] { // expected-note {{did you mean 'outerLoop1'?}} {{14-23=outerLoop1}}
+  outerLoop2: for _ in [1] { // expected-note {{did you mean 'outerLoop2'?}} {{14-23=outerLoop2}}
+    continue outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  }
+}
+outerLoop1: while true { // expected-note {{did you mean 'outerLoop1'?}} {{11-20=outerLoop1}}
+  outerLoop2: while true { // expected-note {{did you mean 'outerLoop2'?}} {{11-20=outerLoop2}}
+    break outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  }
+}
+outerLoop1: while true { // expected-note {{did you mean 'outerLoop1'?}} {{14-23=outerLoop1}}
+  outerLoop2: while true { // expected-note {{did you mean 'outerLoop2'?}} {{14-23=outerLoop2}}
+    continue outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  }
+}
+outerLoop1: repeat { // expected-note {{did you mean 'outerLoop1'?}} {{11-20=outerLoop1}}
+  outerLoop2: repeat { // expected-note {{did you mean 'outerLoop2'?}} {{11-20=outerLoop2}}
+    break outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  } while true
+} while true
+outerLoop1: repeat { // expected-note {{did you mean 'outerLoop1'?}} {{14-23=outerLoop1}}
+  outerLoop2: repeat { // expected-note {{did you mean 'outerLoop2'?}} {{14-23=outerLoop2}}
+    continue outerloop // expected-error {{use of unresolved label 'outerloop'}}
+  } while true
+} while true
+
 // Errors in case syntax
 class
 case, // expected-error {{expected identifier in enum 'case' declaration}} expected-error {{expected pattern}}
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
index 13989d7..7d64446 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp
@@ -413,6 +413,7 @@
     case DeclContextKind::TopLevelCodeDecl:
     case DeclContextKind::AbstractFunctionDecl:
     case DeclContextKind::SubscriptDecl:
+    case DeclContextKind::EnumElementDecl:
     case DeclContextKind::Initializer:
     case DeclContextKind::SerializedLocal:
     case DeclContextKind::ExtensionDecl:
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
index b151863..479c7e5 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp
@@ -685,7 +685,7 @@
     if (CompInv.getLangOptions().BuildSyntaxTree) {
       RC<SyntaxArena> syntaxArena{new syntax::SyntaxArena()};
       SynTreeCreator = std::make_shared<SyntaxTreeCreator>(
-          CompInv.getMainFileSyntaxParsingCache(), syntaxArena);
+          SM, BufferID, CompInv.getMainFileSyntaxParsingCache(), syntaxArena);
     }
 
     Parser.reset(
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 53ee12b..796da09 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -1,5 +1,4 @@
 add_swift_host_tool(swift
-  api_notes.cpp
   driver.cpp
   autolink_extract_main.cpp
   modulewrap_main.cpp
diff --git a/tools/driver/api_notes.cpp b/tools/driver/api_notes.cpp
deleted file mode 100644
index 57f85bb..0000000
--- a/tools/driver/api_notes.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-//===--- api_notes.cpp - Swift Compiler Frontend --------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This is the YAML to binary converter for API notes.
-///
-//===----------------------------------------------------------------------===//
-#include "clang/APINotes/APINotesYAMLCompiler.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/Triple.h"
-
-using namespace llvm;
-namespace api_notes = clang::api_notes;
-
-int apinotes_main(ArrayRef<const char *> Args) {
-
-  // Mark all our options with this category, everything else (except for
-  // -version and -help) will be hidden.
-  static cl::OptionCategory APINotesCategory("API Notes options");
-
-  static cl::opt<api_notes::ActionType>
-  Action(cl::desc("Mode:"), cl::init(api_notes::ActionType::None),
-         cl::values(
-                    clEnumValN(api_notes::ActionType::YAMLToBinary,
-                            "yaml-to-binary", "Convert YAML to binary format"),
-                    clEnumValN(api_notes::ActionType::BinaryToYAML,
-                               "binary-to-yaml",
-                               "Convert binary format to YAML"),
-                    clEnumValN(api_notes::ActionType::Dump,
-                            "dump", "Parse and dump the output")),
-         cl::cat(APINotesCategory));
-
-  static cl::opt<std::string>
-  InputFilename(cl::Positional, cl::desc("<input file>"),
-                cl::Required, cl::cat(APINotesCategory));
-
-  static cl::opt<std::string>
-  Target("target", cl::desc("Generate binary format for the given target"),
-                   cl::cat(APINotesCategory));
-
-  static cl::opt<std::string>
-  OutputFilename("o", cl::desc("Output file name"), cl::cat(APINotesCategory));
-
-  // Hide unrelated options.
-  StringMap<cl::Option *> &Options =
-      cl::getRegisteredOptions(*cl::TopLevelSubCommand);
-  for (auto &Option : Options) {
-    if (Option.second->Category != &APINotesCategory &&
-        Option.first() != "help" && Option.first() != "version") {
-      Option.second->setHiddenFlag(cl::ReallyHidden);
-    }
-  }
-
-  cl::ParseCommandLineOptions(Args.size(),
-                              Args.data(),
-                              "Swift API Notes Tool\n");
-
-  if (Action == clang::api_notes::ActionType::None) {
-    errs() << "action required\n";
-    cl::PrintHelpMessage();
-    return 1;
-  }
-
-  auto fileBufOrErr = MemoryBuffer::getFile(InputFilename);
-  if (std::error_code EC = fileBufOrErr.getError()) {
-    llvm::errs() << "\n Could not open input file: " + EC.message() << '\n';
-    return true;
-  }
-  StringRef input = fileBufOrErr.get()->getBuffer();
-
-  switch (Action) {
-  case api_notes::ActionType::None:
-    llvm_unreachable("handled above");
-
-  case api_notes::ActionType::YAMLToBinary: {
-    if (OutputFilename.empty()) {
-      errs() << "output file is required\n";
-      cl::PrintHelpMessage();
-      return 1;
-    }
-
-    api_notes::OSType targetOS = api_notes::OSType::Absent;
-    // TODO: Check that we've specified the target.
-    if (!Target.empty()) {
-      llvm::Triple target(llvm::Triple::normalize(Target));
-      switch (target.getOS()) {
-        case llvm::Triple::Darwin:
-        case llvm::Triple::MacOSX:
-          targetOS = api_notes::OSType::OSX;
-          break;
-        case llvm::Triple::IOS:
-          targetOS = api_notes::OSType::IOS;
-          break;
-        case llvm::Triple::TvOS:
-          targetOS = api_notes::OSType::TvOS;
-          break;
-        case llvm::Triple::WatchOS:
-          targetOS = api_notes::OSType::WatchOS;
-          break;
-        default:
-          errs() << "target is not supported\n";
-          return 1;
-      }
-    }
-    std::error_code EC;
-    llvm::raw_fd_ostream os(OutputFilename, EC,
-                            llvm::sys::fs::OpenFlags::F_None);
-
-    if (api_notes::compileAPINotes(input, /*sourceFile=*/nullptr, os, targetOS))
-      return 1;
-    
-    os.flush();
-
-    return os.has_error();
-  }
-
-  case api_notes::ActionType::BinaryToYAML: {
-    if (OutputFilename.empty()) {
-      errs() << "output file required\n";
-      cl::PrintHelpMessage();
-      return 1;
-    }
-
-    std::error_code EC;
-    llvm::raw_fd_ostream os(OutputFilename, EC,
-                            llvm::sys::fs::OpenFlags::F_None);
-
-    if (api_notes::decompileAPINotes(std::move(fileBufOrErr.get()), os))
-      return 1;
-    
-    os.flush();
-
-    return os.has_error();
-  }
-
-  case api_notes::ActionType::Dump:
-    return api_notes::parseAndDumpAPINotes(input);
-  }
-
-  return 1;
-}
-
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 55c5492..d8ec032 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -111,8 +111,6 @@
   return true;
 }
 
-extern int apinotes_main(ArrayRef<const char *> Args);
-
 static int run_driver(StringRef ExecName,
                        const ArrayRef<const char *> argv) {
   // Handle integrated tools.
@@ -128,10 +126,6 @@
                                                 argv.data()+argv.size()),
                              argv[0], (void *)(intptr_t)getExecutablePath);
     }
-    if (FirstArg == "-apinotes") {
-      return apinotes_main(llvm::makeArrayRef(argv.data()+1,
-                                              argv.data()+argv.size()));
-    }
   }
 
   std::string Path = getExecutablePath(argv[0]);
diff --git a/tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp b/tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp
index 6734ace..120e69f 100644
--- a/tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp
+++ b/tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp
@@ -88,14 +88,14 @@
   }
 
   static void makeCTrivia(SmallVectorImpl<CTriviaPiece> &c_trivia,
-                          const Trivia &trivia) {
+                          ArrayRef<ParsedTriviaPiece> trivia) {
     for (const auto &piece : trivia) {
       CTriviaPiece c_piece;
       auto numValue =
         WrapperTypeTraits<TriviaKind>::numericValue(piece.getKind());
       c_piece.kind = numValue;
       assert(c_piece.kind == numValue && "trivia kind value is too large");
-      c_piece.length = piece.getTextLength();
+      c_piece.length = piece.getLength();
       c_trivia.push_back(c_piece);
     }
   }
@@ -131,15 +131,15 @@
     node.present = true;
   }
 
-  OpaqueSyntaxNode recordToken(const Token &tok,
-                               const Trivia &leadingTrivia,
-                               const Trivia &trailingTrivia,
+  OpaqueSyntaxNode recordToken(tok tokenKind,
+                               ArrayRef<ParsedTriviaPiece> leadingTrivia,
+                               ArrayRef<ParsedTriviaPiece> trailingTrivia,
                                CharSourceRange range) override {
     SmallVector<CTriviaPiece, 8> c_leadingTrivia, c_trailingTrivia;
     makeCTrivia(c_leadingTrivia, leadingTrivia);
     makeCTrivia(c_trailingTrivia, trailingTrivia);
     CRawSyntaxNode node;
-    makeCRawToken(node, tok.getKind(), c_leadingTrivia, c_trailingTrivia,
+    makeCRawToken(node, tokenKind, c_leadingTrivia, c_trailingTrivia,
                   range);
     return getNodeHandler()(&node);
   }
@@ -187,6 +187,8 @@
   LangOptions langOpts;
   langOpts.BuildSyntaxTree = true;
   langOpts.CollectParsedToken = false;
+  // Disable name lookups during parsing.
+  langOpts.EnableASTScopeLookup = true;
 
   auto parseActions =
     std::make_shared<CLibParseActions>(*this, SM, bufID);
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 53121b4..c03ca90 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -3195,6 +3195,7 @@
     PrintOpts = PrintOptions::printDocInterface();
   } else {
     PrintOpts = PrintOptions::printEverything();
+    PrintOpts.FullyQualifiedTypes = options::FullyQualifiedTypes;
     PrintOpts.FullyQualifiedTypesIfAmbiguous =
       options::FullyQualifiedTypesIfAmbiguous;
     PrintOpts.SynthesizeSugarOnTypes = options::SynthesizeSugarOnTypes;
diff --git a/tools/swift-remoteast-test/swift-remoteast-test.cpp b/tools/swift-remoteast-test/swift-remoteast-test.cpp
index 0f3f50f..54d0029 100644
--- a/tools/swift-remoteast-test/swift-remoteast-test.cpp
+++ b/tools/swift-remoteast-test/swift-remoteast-test.cpp
@@ -42,8 +42,8 @@
 
 // FIXME: swiftcall
 /// func printType(forMetadata: Any.Type)
-LLVM_ATTRIBUTE_USED SWIFT_REMOTEAST_TEST_ABI
-extern "C" void printMetadataType(const Metadata *typeMetadata) {
+LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI
+printMetadataType(const Metadata *typeMetadata) {
   assert(Context && "context was not set");
 
   std::shared_ptr<MemoryReader> reader(new InProcessMemoryReader());
@@ -64,8 +64,8 @@
 
 // FIXME: swiftcall
 /// func printDynamicType(_: AnyObject)
-LLVM_ATTRIBUTE_USED SWIFT_REMOTEAST_TEST_ABI
-extern "C" void printHeapMetadataType(void *object) {
+LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI
+printHeapMetadataType(void *object) {
   assert(Context && "context was not set");
 
   std::shared_ptr<MemoryReader> reader(new InProcessMemoryReader());
@@ -127,8 +127,8 @@
 
 // FIXME: swiftcall
 /// func printTypeMemberOffset(forType: Any.Type, memberName: StaticString)
-LLVM_ATTRIBUTE_USED SWIFT_REMOTEAST_TEST_ABI
-extern "C" void printTypeMemberOffset(const Metadata *typeMetadata,
+LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI
+printTypeMemberOffset(const Metadata *typeMetadata,
                                       const char *memberName) {
   printMemberOffset(typeMetadata, memberName, /*pass metadata*/ false);
 }
@@ -136,15 +136,15 @@
 // FIXME: swiftcall
 /// func printTypeMetadataMemberOffset(forType: Any.Type,
 ///                                    memberName: StaticString)
-LLVM_ATTRIBUTE_USED SWIFT_REMOTEAST_TEST_ABI
-extern "C" void printTypeMetadataMemberOffset(const Metadata *typeMetadata,
-                                              const char *memberName) {
+LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI
+printTypeMetadataMemberOffset(const Metadata *typeMetadata,
+                              const char *memberName) {
   printMemberOffset(typeMetadata, memberName, /*pass metadata*/ true);
 }
 
 // FIXME: swiftcall
 /// func printDynamicTypeAndAddressForExistential<T>(_: T)
-LLVM_ATTRIBUTE_USED SWIFT_REMOTEAST_TEST_ABI extern "C" void
+LLVM_ATTRIBUTE_USED extern "C" void SWIFT_REMOTEAST_TEST_ABI
 printDynamicTypeAndAddressForExistential(void *object,
                                          const Metadata *typeMetadata) {
   assert(Context && "context was not set");
diff --git a/unittests/Parse/LexerTests.cpp b/unittests/Parse/LexerTests.cpp
index d694748..4233b89 100644
--- a/unittests/Parse/LexerTests.cpp
+++ b/unittests/Parse/LexerTests.cpp
@@ -4,6 +4,7 @@
 #include "swift/Basic/LangOptions.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Parse/Lexer.h"
+#include "swift/Syntax/Trivia.h"
 #include "swift/Subsystems.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Process.h"
@@ -18,6 +19,7 @@
 
 using namespace swift;
 using namespace llvm;
+using syntax::TriviaKind;
 
 // The test fixture.
 class LexerTest : public ::testing::Test {
@@ -283,7 +285,7 @@
           TriviaRetentionMode::WithoutTrivia);
   
   Token Tok;
-  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
@@ -291,16 +293,16 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::eof, Tok.getKind());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
 }
 
 TEST_F(LexerTest, BOMTokenCommentNoTrivia) {
@@ -315,7 +317,7 @@
           TriviaRetentionMode::WithoutTrivia);
   
   Token Tok;
-  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::comment, Tok.getKind());
@@ -323,8 +325,8 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
@@ -332,8 +334,8 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::comment, Tok.getKind());
@@ -341,8 +343,8 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::comment, Tok.getKind());
@@ -350,16 +352,16 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 24), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 24), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::eof, Tok.getKind());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
 }
 
 TEST_F(LexerTest, BOMAttachCommentNoTrivia) {
@@ -374,7 +376,7 @@
           TriviaRetentionMode::WithoutTrivia);
   
   Token Tok;
-  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
@@ -382,16 +384,16 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getCommentRange().getStart());
   ASSERT_EQ(10u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::eof, Tok.getKind());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getCommentRange().getStart());
   ASSERT_EQ(13u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{}}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), LeadingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
 }
 
 TEST_F(LexerTest, BOMNoCommentTrivia) {
@@ -406,7 +408,7 @@
           TriviaRetentionMode::WithTrivia);
   
   Token Tok;
-  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
@@ -414,13 +416,13 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{
-    syntax::TriviaPiece::garbageText("\xEF\xBB\xBF"),
-    syntax::TriviaPiece::lineComment("// comment"),
-    syntax::TriviaPiece::newlines(1)
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::GarbageText, strlen("\xEF\xBB\xBF")),
+    ParsedTriviaPiece(TriviaKind::LineComment, strlen("// comment")),
+    ParsedTriviaPiece(TriviaKind::Newline, 1)
   }}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{
-    syntax::TriviaPiece::spaces(1)
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::Space, 1)
   }}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
@@ -428,12 +430,12 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getCommentRange().getStart());
   ASSERT_EQ(0u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{
-    syntax::TriviaPiece::lineComment("//xx "),
-    syntax::TriviaPiece::newlines(1),
-    syntax::TriviaPiece::blockComment("/* x */")
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::LineComment, strlen("//xx ")),
+    ParsedTriviaPiece(TriviaKind::Newline, 1),
+    ParsedTriviaPiece(TriviaKind::BlockComment, strlen("/* x */"))
   }}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
 }
 
 TEST_F(LexerTest, BOMAttachCommentTrivia) {
@@ -448,7 +450,7 @@
           TriviaRetentionMode::WithTrivia);
   
   Token Tok;
-  syntax::Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
@@ -456,13 +458,13 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 14), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 3), Tok.getCommentRange().getStart());
   ASSERT_EQ(10u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{
-    syntax::TriviaPiece::garbageText("\xEF\xBB\xBF"),
-    syntax::TriviaPiece::lineComment("// comment"),
-    syntax::TriviaPiece::newlines(1)
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::GarbageText, strlen("\xEF\xBB\xBF")),
+    ParsedTriviaPiece(TriviaKind::LineComment, strlen("// comment")),
+    ParsedTriviaPiece(TriviaKind::Newline, 1)
   }}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{
-    syntax::TriviaPiece::spaces(1)
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::Space, 1)
   }}), TrailingTrivia);
   
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
@@ -470,12 +472,12 @@
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 31), Tok.getLoc());
   ASSERT_EQ(SourceMgr.getLocForOffset(BufferID, 18), Tok.getCommentRange().getStart());
   ASSERT_EQ(13u, Tok.getCommentRange().getByteLength());
-  ASSERT_EQ((syntax::Trivia{{
-    syntax::TriviaPiece::lineComment("//xx "),
-    syntax::TriviaPiece::newlines(1),
-    syntax::TriviaPiece::blockComment("/* x */")
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::LineComment, strlen("//xx ")),
+    ParsedTriviaPiece(TriviaKind::Newline, 1),
+    ParsedTriviaPiece(TriviaKind::BlockComment, strlen("/* x */"))
   }}), LeadingTrivia);
-  ASSERT_EQ((syntax::Trivia{{}}), TrailingTrivia);
+  ASSERT_EQ((ParsedTrivia{{}}), TrailingTrivia);
 }
 
 TEST_F(LexerTest, RestoreBasic) {
diff --git a/unittests/Parse/LexerTriviaTests.cpp b/unittests/Parse/LexerTriviaTests.cpp
index 565366d..33fcb16 100644
--- a/unittests/Parse/LexerTriviaTests.cpp
+++ b/unittests/Parse/LexerTriviaTests.cpp
@@ -1,13 +1,14 @@
 #include "swift/Basic/LangOptions.h"
 #include "swift/Basic/SourceManager.h"
 #include "swift/Parse/Lexer.h"
+#include "swift/Syntax/Trivia.h"
 #include "swift/Subsystems.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "gtest/gtest.h"
 
 using namespace swift;
-using namespace swift::syntax;
 using namespace llvm;
+using syntax::TriviaKind;
 
 class LexerTriviaTest : public ::testing::Test {};
 
@@ -24,22 +25,25 @@
           TriviaRetentionMode::WithTrivia);
 
   Token Tok;
-  Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("aaa", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ(LeadingTrivia, Trivia());
-  ASSERT_EQ(TrailingTrivia, (Trivia{{TriviaPiece::spaces(1)}}));
+  ASSERT_EQ(LeadingTrivia, ParsedTrivia());
+  ASSERT_EQ(TrailingTrivia,
+            (ParsedTrivia{{ParsedTriviaPiece(TriviaKind::Space, 1)}}));
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("bbb", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
   ASSERT_EQ(LeadingTrivia,
-            (Trivia{{TriviaPiece::newlines(1), TriviaPiece::spaces(1)}}));
-  ASSERT_EQ(TrailingTrivia, (Trivia{{TriviaPiece::spaces(1)}}));
+            (ParsedTrivia{{ParsedTriviaPiece(TriviaKind::Newline, 1),
+             ParsedTriviaPiece(TriviaKind::Space, 1)}}));
+  ASSERT_EQ(TrailingTrivia,
+            (ParsedTrivia{{ParsedTriviaPiece(TriviaKind::Space, 1)}}));
 
   LexerState S = L.getStateForBeginningOfToken(Tok, LeadingTrivia);
 
@@ -47,8 +51,10 @@
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("ccc", Tok.getText());
   ASSERT_FALSE(Tok.isAtStartOfLine());
-  ASSERT_EQ(LeadingTrivia, (Trivia{{TriviaPiece::blockComment("/*C*/")}}));
-  ASSERT_EQ(TrailingTrivia, Trivia());
+  ASSERT_EQ(LeadingTrivia,
+            (ParsedTrivia{{ParsedTriviaPiece(
+                             TriviaKind::BlockComment, strlen("/*C*/"))}}));
+  ASSERT_EQ(TrailingTrivia, ParsedTrivia());
 
   L.restoreState(S);
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
@@ -56,8 +62,10 @@
   ASSERT_EQ("bbb", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
   ASSERT_EQ(LeadingTrivia,
-            (Trivia{{TriviaPiece::newlines(1), TriviaPiece::spaces(1)}}));
-  ASSERT_EQ(TrailingTrivia, (Trivia{{TriviaPiece::spaces(1)}}));
+            (ParsedTrivia{{ParsedTriviaPiece(TriviaKind::Newline, 1),
+                           ParsedTriviaPiece(TriviaKind::Space, 1)}}));
+  ASSERT_EQ(TrailingTrivia,
+            (ParsedTrivia{{ParsedTriviaPiece(TriviaKind::Space, 1)}}));
 }
 
 TEST_F(LexerTriviaTest, TriviaHashbang) {
@@ -72,15 +80,15 @@
           TriviaRetentionMode::WithTrivia);
 
   Token Tok;
-  Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
 
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("aaa", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ(LeadingTrivia,
-            (Trivia{{TriviaPiece::garbageText("#!/bin/swift"),
-                     TriviaPiece::newlines(1)}}));
+  ASSERT_EQ(LeadingTrivia, (ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::GarbageText, strlen("#!/bin/swift")),
+    ParsedTriviaPiece(TriviaKind::Newline, 1)}}));
 }
 
 TEST_F(LexerTriviaTest, TriviaHashbangAfterBOM) {
@@ -95,17 +103,17 @@
           TriviaRetentionMode::WithTrivia);
 
   Token Tok;
-  Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
 
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("aaa", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
 
-  ASSERT_EQ(LeadingTrivia,
-            (Trivia{{TriviaPiece::garbageText("\xEF\xBB\xBF"),
-                     TriviaPiece::garbageText("#!/bin/swift"),
-                     TriviaPiece::newlines(1)}}));
+  ASSERT_EQ(LeadingTrivia, (ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::GarbageText, strlen("\xEF\xBB\xBF")),
+    ParsedTriviaPiece(TriviaKind::GarbageText, strlen("#!/bin/swift")),
+    ParsedTriviaPiece(TriviaKind::Newline, 1)}}));
 }
 
 TEST_F(LexerTriviaTest, TriviaConflictMarker) {
@@ -128,7 +136,7 @@
           TriviaRetentionMode::WithTrivia);
 
   Token Tok;
-  Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
@@ -144,9 +152,10 @@
       "=======\n"
       "old\n"
       ">>>>>>> 18844bc65229786b96b89a9fc7739c0f:conflict_markers.swift";
-  ASSERT_EQ(LeadingTrivia, (Trivia{{TriviaPiece::newlines(1),
-                                    TriviaPiece::garbageText(expectedTrivia),
-                                    TriviaPiece::newlines(1)}}));
+  ASSERT_EQ(LeadingTrivia, (ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::Newline, 1),
+    ParsedTriviaPiece(TriviaKind::GarbageText, expectedTrivia.size()),
+    ParsedTriviaPiece(TriviaKind::Newline, 1)}}));
 }
 
 TEST_F(LexerTriviaTest, TriviaCarriageReturn) {
@@ -162,27 +171,29 @@
           TriviaRetentionMode::WithTrivia);
 
   Token Tok;
-  Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("aaa", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ(LeadingTrivia, Trivia());
-  ASSERT_EQ(TrailingTrivia, Trivia());
+  ASSERT_EQ(LeadingTrivia, ParsedTrivia());
+  ASSERT_EQ(TrailingTrivia, ParsedTrivia());
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("bbb", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ(LeadingTrivia, (Trivia{{TriviaPiece::carriageReturns(2)}}));
-  ASSERT_EQ(TrailingTrivia, Trivia());
+  ASSERT_EQ(LeadingTrivia,
+            (ParsedTrivia{{ParsedTriviaPiece(TriviaKind::CarriageReturn, 2)}}));
+  ASSERT_EQ(TrailingTrivia, ParsedTrivia());
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::eof, Tok.getKind());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ(LeadingTrivia, (Trivia{{TriviaPiece::carriageReturns(1)}}));
-  ASSERT_EQ(TrailingTrivia, Trivia());
+  ASSERT_EQ(LeadingTrivia,
+            (ParsedTrivia{{ParsedTriviaPiece(TriviaKind::CarriageReturn, 1)}}));
+  ASSERT_EQ(TrailingTrivia, ParsedTrivia());
 }
 
 TEST_F(LexerTriviaTest, TriviaNewLines) {
@@ -202,46 +213,46 @@
           TriviaRetentionMode::WithTrivia);
 
   Token Tok;
-  Trivia LeadingTrivia, TrailingTrivia;
+  ParsedTrivia LeadingTrivia, TrailingTrivia;
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("aaa", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ((Trivia{{
-    TriviaPiece::newlines(1),
-    TriviaPiece::carriageReturns(1),
-    TriviaPiece::carriageReturnLineFeeds(1),
-    TriviaPiece::carriageReturns(2),
-    TriviaPiece::carriageReturnLineFeeds(2),
-    TriviaPiece::newlines(2)
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::Newline, 1),
+    ParsedTriviaPiece(TriviaKind::CarriageReturn, 1),
+    ParsedTriviaPiece(TriviaKind::CarriageReturnLineFeed, 2),
+    ParsedTriviaPiece(TriviaKind::CarriageReturn, 2),
+    ParsedTriviaPiece(TriviaKind::CarriageReturnLineFeed, 4),
+    ParsedTriviaPiece(TriviaKind::Newline, 2),
   }}), LeadingTrivia);
-  ASSERT_EQ(Trivia(), TrailingTrivia);
+  ASSERT_EQ(ParsedTrivia(), TrailingTrivia);
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::identifier, Tok.getKind());
   ASSERT_EQ("bbb", Tok.getText());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ((Trivia{{
-    TriviaPiece::newlines(1),
-    TriviaPiece::carriageReturns(1),
-    TriviaPiece::carriageReturnLineFeeds(1),
-    TriviaPiece::carriageReturns(2),
-    TriviaPiece::carriageReturnLineFeeds(2),
-    TriviaPiece::newlines(2)
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::Newline, 1),
+    ParsedTriviaPiece(TriviaKind::CarriageReturn, 1),
+    ParsedTriviaPiece(TriviaKind::CarriageReturnLineFeed, 2),
+    ParsedTriviaPiece(TriviaKind::CarriageReturn, 2),
+    ParsedTriviaPiece(TriviaKind::CarriageReturnLineFeed, 4),
+    ParsedTriviaPiece(TriviaKind::Newline, 2),
   }}), LeadingTrivia);
-  ASSERT_EQ(Trivia(), TrailingTrivia);
+  ASSERT_EQ(ParsedTrivia(), TrailingTrivia);
 
   L.lex(Tok, LeadingTrivia, TrailingTrivia);
   ASSERT_EQ(tok::eof, Tok.getKind());
   ASSERT_TRUE(Tok.isAtStartOfLine());
-  ASSERT_EQ((Trivia{{
-    TriviaPiece::newlines(1),
-    TriviaPiece::carriageReturns(1),
-    TriviaPiece::carriageReturnLineFeeds(1),
-    TriviaPiece::carriageReturns(2),
-    TriviaPiece::carriageReturnLineFeeds(2),
-    TriviaPiece::newlines(2)
+  ASSERT_EQ((ParsedTrivia{{
+    ParsedTriviaPiece(TriviaKind::Newline, 1),
+    ParsedTriviaPiece(TriviaKind::CarriageReturn, 1),
+    ParsedTriviaPiece(TriviaKind::CarriageReturnLineFeed, 2),
+    ParsedTriviaPiece(TriviaKind::CarriageReturn, 2),
+    ParsedTriviaPiece(TriviaKind::CarriageReturnLineFeed, 4),
+    ParsedTriviaPiece(TriviaKind::Newline, 2),
   }}), LeadingTrivia);
-  ASSERT_EQ(Trivia(), TrailingTrivia);
+  ASSERT_EQ(ParsedTrivia(), TrailingTrivia);
 }
diff --git a/utils/bug_reducer/tests/test_funcbugreducer.py b/utils/bug_reducer/tests/test_funcbugreducer.py
index 4363f7d..b917a6d 100644
--- a/utils/bug_reducer/tests/test_funcbugreducer.py
+++ b/utils/bug_reducer/tests/test_funcbugreducer.py
@@ -120,11 +120,11 @@
         output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
-        self.assertEquals(sum(output_matches), 1)
+        self.assertEqual(sum(output_matches), 1)
         # Make sure our final output command does not have -emit-sib in
         # the output. We want users to get sil output when they type in
         # the relevant command.
-        self.assertEquals([], [o for o in output if '-emit-sib' in o])
+        self.assertEqual([], [o for o in output if '-emit-sib' in o])
 
 
 if __name__ == '__main__':
diff --git a/utils/bug_reducer/tests/test_optbugreducer.py b/utils/bug_reducer/tests/test_optbugreducer.py
index 48479ba..5ef9a33 100644
--- a/utils/bug_reducer/tests/test_optbugreducer.py
+++ b/utils/bug_reducer/tests/test_optbugreducer.py
@@ -108,11 +108,11 @@
         output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
-        self.assertEquals(sum(output_matches), 1)
+        self.assertEqual(sum(output_matches), 1)
         # Make sure our final output command does not have -emit-sib in
         # the output. We want users to get sil output when they type in
         # the relevant command.
-        self.assertEquals([], [o for o in output if '-emit-sib' in o])
+        self.assertEqual([], [o for o in output if '-emit-sib' in o])
 
     def test_suffix_in_need_of_prefix(self):
         name = 'testsuffixinneedofprefix'
@@ -137,11 +137,11 @@
         output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
-        self.assertEquals(sum(output_matches), 1)
+        self.assertEqual(sum(output_matches), 1)
         # Make sure our final output command does not have -emit-sib in the
         # output. We want users to get sil output when they type in the
         # relevant command.
-        self.assertEquals([], [o for o in output if '-emit-sib' in o])
+        self.assertEqual([], [o for o in output if '-emit-sib' in o])
 
     def test_reduce_function(self):
         name = 'testreducefunction'
@@ -170,11 +170,11 @@
         output_file_re = re.compile(r'\*\*\* Final File: .*' + re_end)
         output_matches = [
             1 for o in output if output_file_re.match(o) is not None]
-        self.assertEquals(sum(output_matches), 1)
+        self.assertEqual(sum(output_matches), 1)
         # Make sure our final output command does not have -emit-sib in the
         # output. We want users to get sil output when they type in the
         # relevant command.
-        self.assertEquals([], [o for o in output if '-emit-sib' in o])
+        self.assertEqual([], [o for o in output if '-emit-sib' in o])
 
 
 if __name__ == '__main__':
diff --git a/utils/build-presets.ini b/utils/build-presets.ini
index 440cfb2..c5e093a 100644
--- a/utils/build-presets.ini
+++ b/utils/build-presets.ini
@@ -1772,3 +1772,9 @@
 swift-include-tests=0
 darwin-deployment-version-ios=10.0
 darwin-crash-reporter-client=1
+
+[preset: build_swiftsyntax_release]
+release
+no-assertions
+build-libparser-only
+swiftsyntax
diff --git a/utils/build-script b/utils/build-script
index b87da65..5b58f38 100755
--- a/utils/build-script
+++ b/utils/build-script
@@ -404,6 +404,7 @@
         if not args.test_watchos_host:
             self.platforms_to_skip_test_host.add(
                 StdlibDeploymentTarget.AppleWatch)
+        self.build_libparser_only = args.build_libparser_only
 
     def initialize_runtime_environment(self):
         """Change the program environment for building."""
@@ -697,7 +698,8 @@
             impl_args += ["--skip-test-optimized"]
         if not args.test_optimize_for_size:
             impl_args += ["--skip-test-optimize-for-size"]
-
+        if args.build_libparser_only:
+            impl_args += ["--build-libparser-only"]
         if args.android:
             impl_args += [
                 "--android-arch", args.android_arch,
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 6357370..7411576 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -103,6 +103,7 @@
     installable-package         ""               "the path to the archive of the installation directory"
     test-installable-package    ""               "whether to run post-packaging tests on the produced package"
     reconfigure                 ""               "force a CMake configuration run even if CMakeCache.txt already exists"
+    build-libparser-only        ""               "only build libSwiftSyntaxParser"
     skip-reconfigure            ""               "set to skip reconfigure"
     swift-primary-variant-sdk   ""               "default SDK for target binaries"
     swift-primary-variant-arch  ""               "default arch for target binaries"
@@ -1140,7 +1141,6 @@
 # and architecture of each stdlib target -- currently it only captures the SDK.
 #
 # We turn these targets in to SWIFT_SDKS in `calculate_targets_for_host()`
-
     if [[ $(is_cross_tools_host $1) ]] ; then
         echo "$1"
     else
@@ -1824,6 +1824,16 @@
         SWIFT_TEST="$(build_directory_bin ${LOCAL_HOST} swiftpm)/swift-test"
     fi
 
+    if [ "${BUILD_LIBPARSER_ONLY}" ]; then
+        # we don't have a compiler built so we have to use the one in the environment.
+        SWIFTC_BIN="$(xcrun_find_tool swiftc)"
+        # we don't have a swiftpm built so we have to use the one in the environment.
+        SWIFT_BUILD="$(xcrun_find_tool swift-build)"
+        SWIFT_TEST="$(xcrun_find_tool swift-test)"
+    else
+        SWIFTC_BIN="$(build_directory_bin ${LOCAL_HOST} swift)/swiftc"
+    fi
+
     swiftsyntax_build_command=("${SWIFTSYNTAX_SOURCE_DIR}/build-script.py")
     # Add --release if we have to build in release mode.
     if [[ $(is_cmake_release_build_type "${SWIFTSYNTAX_BUILD_TYPE}") ]] ; then
@@ -1836,7 +1846,7 @@
         --build-dir="${build_dir}"
         --swift-build-exec="${SWIFT_BUILD}"
         --swift-test-exec="${SWIFT_TEST}"
-        --swiftc-exec="$(build_directory_bin ${LOCAL_HOST} swift)/swiftc"
+        --swiftc-exec="${SWIFTC_BIN}"
         --syntax-parser-header-dir="${SWIFT_SOURCE_DIR}/include/swift-c/SyntaxParser"
         --syntax-parser-lib-dir="$(build_directory ${host} swift)/lib"
         --swift-syntax-test-exec="$(build_directory_bin ${LOCAL_HOST} swift)/swift-syntax-test"
@@ -2292,7 +2302,6 @@
                     -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}"
                     -DSWIFT_EMBED_BITCODE_SECTION:BOOL=$(true_false "${EMBED_BITCODE_SECTION}")
                     -DSWIFT_TOOLS_ENABLE_LTO:STRING="${SWIFT_TOOLS_ENABLE_LTO}"
                     -DSWIFT_BUILD_RUNTIME_WITH_HOST_COMPILER:BOOL=$(true_false "${BUILD_RUNTIME_WITH_HOST_COMPILER}")
@@ -2363,6 +2372,13 @@
                     )
                 fi
 
+                if [ "${SWIFT_INSTALL_COMPONENTS}" ] ; then
+                    cmake_options=(
+                        "${cmake_options[@]}"
+                        -DSWIFT_INSTALL_COMPONENTS:STRING="${SWIFT_INSTALL_COMPONENTS}"
+                    )
+                fi
+
                 if contains_product "lldb" ; then
                     lldb_build_dir=$(build_directory ${host} lldb)
                     cmake_options=(
@@ -2382,7 +2398,9 @@
                     build_targets=("${build_targets[@]}"
                                    "${SWIFT_BENCHMARK_TARGETS[@]}")
                 fi
-
+                if [ "${BUILD_LIBPARSER_ONLY}" ]; then
+                    build_targets=(libSwiftSyntaxParser)
+                fi
                 skip_build=${SKIP_BUILD_SWIFT}
                 ;;
             lldb)
@@ -3154,7 +3172,7 @@
                                 "${lldb_build_dir}/lit" \
                                 ${LLVM_LIT_ARGS} \
                                 --xunit-xml-output=${results_dir}/results.xml \
-                                --param dotest-args="--build-dir ${lldb_build_dir}/lldb-test-build.noindex ${LLDB_TEST_SUBDIR_CLAUSE} ${LLDB_TEST_CATEGORIES} -G swift-history --swift-compiler \"${LLDB_TEST_SWIFT_COMPATIBILITY}\" -t -E \"${DOTEST_EXTRA}\""
+                                --param dotest-args="--build-dir ${lldb_build_dir}/lldb-test-build.noindex ${LLDB_TEST_SUBDIR_CLAUSE} ${LLDB_TEST_CATEGORIES} -G swift-history --swift-compiler \"${LLDB_TEST_SWIFT_COMPATIBILITY}\" -t -E \"${DOTEST_EXTRA}\"" --filter=compat
                     fi
                 else
                     with_pushd "${results_dir}" \
diff --git a/utils/build_swift/driver_arguments.py b/utils/build_swift/driver_arguments.py
index e6618b9..5a399e2 100644
--- a/utils/build_swift/driver_arguments.py
+++ b/utils/build_swift/driver_arguments.py
@@ -542,6 +542,9 @@
     option('--build-ninja', toggle_true,
            help='build the Ninja tool')
 
+    option(['--build-libparser-only'], store_true('build_libparser_only'),
+           help='build only libParser for SwiftSyntax')
+
     # -------------------------------------------------------------------------
     in_group('Extra actions to perform before or in addition to building')
 
diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py
index 4dcf045..a61d466 100644
--- a/utils/build_swift/tests/expected_options.py
+++ b/utils/build_swift/tests/expected_options.py
@@ -82,6 +82,7 @@
     'build_swift_stdlib_unittest_extra': False,
     'build_swiftpm': False,
     'build_swiftsyntax': False,
+    'build_libparser_only': False,
     'build_skstresstester': False,
     'build_swiftevolve': False,
     'build_tvos': True,
@@ -400,6 +401,7 @@
     SetTrueOption('--skip-build'),
     SetTrueOption('--swiftpm', dest='build_swiftpm'),
     SetTrueOption('--swiftsyntax', dest='build_swiftsyntax'),
+    SetTrueOption('--build-libparser-only', dest='build_libparser_only'),
     SetTrueOption('--skstresstester', dest='build_skstresstester'),
     SetTrueOption('--swiftevolve', dest='build_swiftevolve'),
     SetTrueOption('-B', dest='benchmark'),
diff --git a/utils/build_swift/tests/test_driver_arguments.py b/utils/build_swift/tests/test_driver_arguments.py
index 2f2bd52..974631f 100644
--- a/utils/build_swift/tests/test_driver_arguments.py
+++ b/utils/build_swift/tests/test_driver_arguments.py
@@ -561,14 +561,14 @@
         with self.assertNotRaises(ParserError):
             namespace = self.parse_default_args(['--debug'])
 
-            self.assertEquals(namespace.cmark_build_variant, 'Debug')
-            self.assertEquals(namespace.foundation_build_variant, 'Debug')
-            self.assertEquals(namespace.libdispatch_build_variant, 'Debug')
-            self.assertEquals(namespace.libicu_build_variant, 'Debug')
-            self.assertEquals(namespace.lldb_build_variant, 'Debug')
-            self.assertEquals(namespace.llvm_build_variant, 'Debug')
-            self.assertEquals(namespace.swift_build_variant, 'Debug')
-            self.assertEquals(namespace.swift_stdlib_build_variant, 'Debug')
+            self.assertEqual(namespace.cmark_build_variant, 'Debug')
+            self.assertEqual(namespace.foundation_build_variant, 'Debug')
+            self.assertEqual(namespace.libdispatch_build_variant, 'Debug')
+            self.assertEqual(namespace.libicu_build_variant, 'Debug')
+            self.assertEqual(namespace.lldb_build_variant, 'Debug')
+            self.assertEqual(namespace.llvm_build_variant, 'Debug')
+            self.assertEqual(namespace.swift_build_variant, 'Debug')
+            self.assertEqual(namespace.swift_stdlib_build_variant, 'Debug')
 
     def test_implied_defaults_skip_build(self):
         with self.assertNotRaises(ParserError):
@@ -690,6 +690,12 @@
             self.assertFalse(namespace.test_tvos_host)
             self.assertFalse(namespace.test_watchos_host)
             self.assertFalse(namespace.test_android_host)
+            self.assertFalse(namespace.build_libparser_only)
+
+    def test_build_lib_swiftsyntaxparser_only(self):
+        with self.assertNotRaises(ParserError):
+            namespace = self.parse_default_args(['--build-libparser-only'])
+            self.assertTrue(namespace.build_libparser_only)
 
 
 if __name__ == '__main__':
diff --git a/utils/find-overlay-deps-closure.sh b/utils/find-overlay-deps-closure.sh
index 4d024ad..3b11a23 100755
--- a/utils/find-overlay-deps-closure.sh
+++ b/utils/find-overlay-deps-closure.sh
@@ -15,7 +15,7 @@
 set -o pipefail
 set -e
 
-OVERLAY_NAME_ALTERNATION="AppKit|AssetsLibrary|AVFoundation|CallKit|CloudKit|Contacts|CoreAudio|CoreData|CoreGraphics|CoreImage|CoreLocation|CoreMedia|CryptoTokenKit|dispatch|Foundation|GameplayKit|GLKit|HomeKit|IOKit|Intents|MapKit|objc|OpenCL|os|Photos|QuartzCore|SafariServices|SceneKit|simd|SpriteKit|UIKit|WatchKit|XCTest|xpc"
+OVERLAY_NAME_ALTERNATION="AppKit|AssetsLibrary|AVFoundation|CallKit|CloudKit|Compression|Contacts|CoreAudio|CoreData|CoreGraphics|CoreImage|CoreLocation|CoreMedia|CryptoTokenKit|dispatch|Foundation|GameplayKit|GLKit|HomeKit|IOKit|Intents|MapKit|objc|OpenCL|os|Photos|QuartzCore|SafariServices|SceneKit|simd|SpriteKit|UIKit|WatchKit|XCTest|xpc"
 
 function find_deps() {
     local OVERLAY_ARG=$1
@@ -39,7 +39,7 @@
         exit 123
     fi
 
-    local REGEX="./Frameworks/(${OVERLAY_NAME_ALTERNATION}).framework/.*|.*/usr/include/(xpc|dispatch|os|objc|simd)/.*\.h"
+    local REGEX="./Frameworks/(${OVERLAY_NAME_ALTERNATION}).framework/.*|.*/usr/include/(xpc|dispatch|os|objc|simd|compression)/.*\.h"
 
     # shellcheck disable=SC1004
     IFS='\
diff --git a/utils/gyb.py b/utils/gyb.py
index 5f44e18..d9ce0e7 100755
--- a/utils/gyb.py
+++ b/utils/gyb.py
@@ -751,7 +751,7 @@
 
 
 def expand(filename, line_directive=_default_line_directive, **local_bindings):
-    r"""Return the contents of the givepn template file, executed with the given
+    r"""Return the contents of the given template file, executed with the given
     local bindings.
 
     >>> from tempfile import NamedTemporaryFile
diff --git a/utils/gyb_syntax_support/ExprNodes.py b/utils/gyb_syntax_support/ExprNodes.py
index 9157436..57e7422 100644
--- a/utils/gyb_syntax_support/ExprNodes.py
+++ b/utils/gyb_syntax_support/ExprNodes.py
@@ -210,15 +210,6 @@
              Child('RightSquare', kind='RightSquareBracketToken'),
          ]),
 
-    # .foo
-    Node('ImplicitMemberExpr', kind='Expr',
-         children=[
-             Child("Dot", kind='PrefixPeriodToken'),
-             Child("Name", kind='Token'),
-             Child('DeclNameArguments', kind='DeclNameArguments',
-                   is_optional=True),
-         ]),
-
     # function-call-argument -> label? ':'? expression ','?
     Node('FunctionCallArgument', kind='Syntax',
          traits=['WithTrailingComma'],
@@ -297,27 +288,20 @@
              Child("SecondChoice", kind='Expr')
          ]),
 
-    # a.b
+    # expr?.name
     Node('MemberAccessExpr', kind='Expr',
          children=[
              # The base needs to be optional to parse expressions in key paths
              # like \.a
              Child("Base", kind='Expr', is_optional=True),
-             Child("Dot", kind='PeriodToken'),
-             Child("Name", kind='Token'),
-             Child('DeclNameArguments', kind='DeclNameArguments',
-                   is_optional=True),
-         ]),
-
-    # dot-self-expr -> expr '.' 'self'
-    Node('DotSelfExpr', kind='Expr',
-         children=[
-             Child('Expression', kind='Expr'),
-             Child('Dot', kind='Token',
+             Child("Dot", kind='Token',
                    token_choices=[
                        'PeriodToken', 'PrefixPeriodToken'
                    ]),
-             Child('SelfKeyword', kind='SelfToken'),
+             # Name could be 'self'
+             Child("Name", kind='Token'),
+             Child('DeclNameArguments', kind='DeclNameArguments',
+                   is_optional=True),
          ]),
 
     # is TypeName
diff --git a/utils/round-trip-syntax-test b/utils/round-trip-syntax-test
index 29eefe3..87cf2f7 100755
--- a/utils/round-trip-syntax-test
+++ b/utils/round-trip-syntax-test
@@ -3,6 +3,7 @@
 from __future__ import print_function, unicode_literals
 
 import argparse
+import difflib
 import logging
 import os
 import subprocess
@@ -36,62 +37,52 @@
         return [self.swift_syntax_test, self.action,
                 '-input-source-filename', self.input_filename]
 
-    @property
-    def diff_command(self):
-        return ['/usr/bin/diff', '-u', self.input_filename, '-']
-
-    def diff(self):
-        logging.debug(' '.join(self.diff_command))
-        diff = subprocess.Popen(self.diff_command, stdin=subprocess.PIPE,
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.PIPE)
-        stdout, stderr = diff.communicate(self.stdout)
-        if diff.returncode != 0:
-            return stdout
-        assert stdout == ''
-        assert stderr == ''
-        return None
-
     def run(self):
         command = self.test_command
         logging.debug(' '.join(command))
-        self.output_file = tempfile.NamedTemporaryFile('w')
-        self.stderr_file = tempfile.NamedTemporaryFile('w')
+        self.output_file = tempfile.NamedTemporaryFile('w', delete=False)
+        self.stderr_file = tempfile.NamedTemporaryFile('w', delete=False)
 
         process = subprocess.Popen(command, stdout=self.output_file,
                                    stderr=self.stderr_file)
         process.wait()
         self.returncode = process.returncode
 
+        self.output_file.close()
+        self.stderr_file.close()
+
         with open(self.output_file.name, 'r') as stdout_in:
             self.stdout = stdout_in.read()
         with open(self.stderr_file.name, 'r') as stderr_in:
             self.stderr = stderr_in.read()
 
-        self.output_file.flush()
-        self.stderr_file.flush()
+        os.remove(self.output_file.name)
+        os.remove(self.stderr_file.name)
 
-        try:
-            if self.returncode != 0:
-                if self.skip_bad_syntax:
-                    logging.warning('---===WARNING===--- Lex/parse had error'
-                                    ' diagnostics, so not diffing. Skipping'
-                                    ' this file due to -skip-bad-syntax.')
-                    logging.error(' '.join(command))
-                    return None
-                else:
-                    logging.error('---===ERROR===--- Lex/parse had error'
-                                  ' diagnostics, so not diffing.')
-                    logging.error(' '.join(command))
-                    logging.error(self.stdout)
-                    logging.error(self.stderr)
-                    raise RuntimeError()
-        finally:
-            self.output_file.close()
-            self.stderr_file.close()
+        if self.returncode != 0:
+            if self.skip_bad_syntax:
+                logging.warning('---===WARNING===--- Lex/parse had error'
+                                ' diagnostics, so not diffing. Skipping'
+                                ' this file due to -skip-bad-syntax.')
+                logging.error(' '.join(command))
+                return None
+            else:
+                logging.error('---===ERROR===--- Lex/parse had error'
+                              ' diagnostics, so not diffing.')
+                logging.error(' '.join(command))
+                logging.error(self.stdout)
+                logging.error(self.stderr)
+                raise RuntimeError()
 
-        diff = self.diff()
-        return diff
+        contents = ''.join(map(lambda l: l.decode('utf-8', errors='replace'),
+                               open(self.input_filename).readlines()))
+        lines = difflib.unified_diff(contents,
+                                     self.stdout.decode('utf-8',
+                                                        errors='replace'),
+                                     fromfile=self.input_filename,
+                                     tofile='-')
+        diff = '\n'.join(line for line in lines)
+        return diff if diff else None
 
 
 def swift_files_in_dir(d):
diff --git a/utils/rusage.py b/utils/rusage.py
index 2701a70..e0195ac 100755
--- a/utils/rusage.py
+++ b/utils/rusage.py
@@ -36,6 +36,7 @@
 import resource
 import subprocess
 import sys
+import time
 
 
 class MemAction(argparse.Action):
@@ -79,6 +80,9 @@
                     metavar="T",
                     help="time (in secs, or ..'ms', 'us')",
                     action=TimeAction)
+parser.add_argument("--wall-time",
+                    help="wall time (in secs, or ..'ms', 'us')",
+                    action='store_true')
 parser.add_argument("--enforce",
                     action='store_true',
                     default=False,
@@ -125,7 +129,13 @@
             sys.stderr.write("rusage: setrlimit(RLIMIT_RSS, %d)\n"
                              % mem)
         resource.setrlimit(resource.RLIMIT_RSS, (mem, mem))
+
+start = time.time()
 ret = subprocess.call(args.remainder)
+end = time.time()
+
+wall_time = end - start
+
 used = resource.getrusage(resource.RUSAGE_CHILDREN)
 
 if args.verbose:
@@ -144,18 +154,27 @@
 if args.verbose or over_time:
     sys.stderr.write("rusage: subprocess time: %.6f secs\n"
                      % used.ru_utime)
+    if args.wall_time:
+        sys.stderr.write("rusage: subprocess wall time: %.6f secs\n"
+                         % wall_time)
 if over_time:
     sys.stderr.write("rusage:  exceeded limit: %.6f secs\n"
                      % args.time)
 
 if args.csv:
     fieldnames = ["time", "mem", "run"]
+    row = {
+        'time': used.ru_utime,
+        'mem': used.ru_maxrss,
+        'run': args.csv_name
+    }
+    if args.wall_time:
+        row['wall'] = wall_time
+        fieldnames.insert(1, 'wall')
     out = csv.DictWriter(args.csv_output, fieldnames, dialect='excel-tab')
     if args.csv_header:
         out.writeheader()
-    out.writerow(dict(time=used.ru_utime,
-                      mem=used.ru_maxrss,
-                      run=args.csv_name))
+    out.writerow(row)
 
 if over_mem or over_time:
     sys.exit(-1)
diff --git a/validation-test/Runtime/Inputs/class-layout-from-objc/Classes.swift b/validation-test/Runtime/Inputs/class-layout-from-objc/Classes.swift
new file mode 100644
index 0000000..7c45961
--- /dev/null
+++ b/validation-test/Runtime/Inputs/class-layout-from-objc/Classes.swift
@@ -0,0 +1,65 @@
+import Resilient
+import Foundation
+import OneWordSuperclass
+
+public class StaticClass: OneWordSuperclass {
+  @objc var first: Int32 = 0
+  var middle = GrowsToInt64()
+  @objc var last: Int = 0
+
+  @objc public static var offsetOfFirst: Int {
+    // IRGen lays out Swift classes that subclass Objective-C classes as if the
+    // only superclass was NSObject, so the starting (offset % alignment) isn't
+    // always 0. This means that on 32-bit platforms we'll have a gap *before*
+    // 'first' when we need 8-byte alignment, rather than after as you'd see in
+    // a struct (or base class).
+    return max(MemoryLayout<Int>.size, MemoryLayout<GrowsToInt64>.alignment) +
+           MemoryLayout<Int>.size
+  }
+
+  @objc public static var totalSize: Int {
+    return (2 * MemoryLayout<Int>.size) +
+           (2 * MemoryLayout<GrowsToInt64>.size) + // alignment
+           MemoryLayout<Int>.size
+  }
+}
+
+/// This class has the same layout as `StaticClass`, but will be accessed using
+/// `NSClassFromString` instead of `+class`.
+public class DynamicClass: OneWordSuperclass {
+  @objc var first: Int32 = 0
+  var middle = GrowsToInt64()
+  @objc var last: Int = 0
+
+  @objc public static var offsetOfFirst: Int {
+    // See above.
+    return max(MemoryLayout<Int>.size, MemoryLayout<GrowsToInt64>.alignment) +
+           MemoryLayout<Int>.size
+  }
+
+  @objc public static var totalSize: Int {
+    return (2 * MemoryLayout<Int>.size) +
+           (2 * MemoryLayout<GrowsToInt64>.size) + // alignment
+           MemoryLayout<Int>.size
+  }
+}
+
+public class PureSwiftBaseClass {
+  var word: Int64 = 0
+}
+
+public class PureSwiftClass: PureSwiftBaseClass {
+  @objc var first: Int32 = 0
+  var middle = GrowsToInt64()
+  @objc var last: Int = 0
+
+  @objc public static var offsetOfFirst: Int {
+    return (2 * MemoryLayout<Int>.size) + MemoryLayout<Int64>.size
+  }
+
+  @objc public static var totalSize: Int {
+    return (2 * MemoryLayout<Int>.size) + MemoryLayout<Int64>.size +
+           (2 * MemoryLayout<GrowsToInt64>.size) + // alignment
+           MemoryLayout<Int>.size
+  }
+}
diff --git a/validation-test/Runtime/Inputs/class-layout-from-objc/OneWordSuperclass.h b/validation-test/Runtime/Inputs/class-layout-from-objc/OneWordSuperclass.h
new file mode 100644
index 0000000..8abbec0
--- /dev/null
+++ b/validation-test/Runtime/Inputs/class-layout-from-objc/OneWordSuperclass.h
@@ -0,0 +1,4 @@
+@import Foundation;
+
+@interface OneWordSuperclass : NSObject
+@end
diff --git a/validation-test/Runtime/Inputs/class-layout-from-objc/OneWordSuperclass.m b/validation-test/Runtime/Inputs/class-layout-from-objc/OneWordSuperclass.m
new file mode 100644
index 0000000..42d7614
--- /dev/null
+++ b/validation-test/Runtime/Inputs/class-layout-from-objc/OneWordSuperclass.m
@@ -0,0 +1,6 @@
+#import "OneWordSuperclass.h"
+
+@implementation OneWordSuperclass {
+  intptr_t unused;
+}
+@end
diff --git a/validation-test/Runtime/Inputs/class-layout-from-objc/Resilient.swift b/validation-test/Runtime/Inputs/class-layout-from-objc/Resilient.swift
new file mode 100644
index 0000000..a9f4b6e
--- /dev/null
+++ b/validation-test/Runtime/Inputs/class-layout-from-objc/Resilient.swift
@@ -0,0 +1,11 @@
+public struct GrowsToInt64 {
+  #if SMALL
+  var value: Int32
+  #elseif BIG
+  var value: Int64
+  #else
+  #error("Must define SMALL or BIG")
+  #endif
+
+  public init() { self.value = 0 }
+}
diff --git a/validation-test/Runtime/Inputs/class-layout-from-objc/module.modulemap b/validation-test/Runtime/Inputs/class-layout-from-objc/module.modulemap
new file mode 100644
index 0000000..76fb327
--- /dev/null
+++ b/validation-test/Runtime/Inputs/class-layout-from-objc/module.modulemap
@@ -0,0 +1,4 @@
+module OneWordSuperclass {
+  header "OneWordSuperclass.h"
+  export *
+}
diff --git a/validation-test/Runtime/class-layout-from-objc.m b/validation-test/Runtime/class-layout-from-objc.m
new file mode 100644
index 0000000..47cbee4
--- /dev/null
+++ b/validation-test/Runtime/class-layout-from-objc.m
@@ -0,0 +1,78 @@
+// Check that when Objective-C is first to touch a Swift class, it gives the
+// Swift runtime a chance to update instance size and ivar offset metadata.
+
+// RUN: %empty-directory(%t)
+// RUN: %target-build-swift -emit-library -emit-module -o %t/libResilient.dylib %S/Inputs/class-layout-from-objc/Resilient.swift -Xlinker -install_name -Xlinker @executable_path/libResilient.dylib -Xfrontend -enable-resilience -DSMALL
+
+// RUN: %target-clang -c %S/Inputs/class-layout-from-objc/OneWordSuperclass.m -fmodules -fobjc-arc -o %t/OneWordSuperclass.o
+// RUN: %target-build-swift -emit-library -o %t/libClasses.dylib -emit-objc-header-path %t/Classes.h -I %t -I %S/Inputs/class-layout-from-objc/ %S/Inputs/class-layout-from-objc/Classes.swift %t/OneWordSuperclass.o -Xlinker -install_name -Xlinker @executable_path/libClasses.dylib -lResilient -L %t
+// RUN: %target-clang %s -I %S/Inputs/class-layout-from-objc/ -I %t -fmodules -fobjc-arc -o %t/main -lResilient -lClasses -L %t
+// RUN: %target-codesign %t/main %t/libResilient.dylib %t/libClasses.dylib
+// RUN: %target-run %t/main OLD %t/libResilient.dylib %t/libClasses.dylib
+
+// RUN: %target-build-swift -emit-library -emit-module -o %t/libResilient.dylib %S/Inputs/class-layout-from-objc/Resilient.swift -Xlinker -install_name -Xlinker @executable_path/libResilient.dylib -Xfrontend -enable-resilience -DBIG
+// RUN: %target-codesign %t/libResilient.dylib
+// RUN: %target-run %t/main NEW %t/libResilient.dylib %t/libClasses.dylib
+
+// Try again when the class itself is also resilient.
+// RUN: %target-build-swift -emit-library -o %t/libClasses.dylib -emit-objc-header-path %t/Classes.h -I %S/Inputs/class-layout-from-objc/ -I %t %S/Inputs/class-layout-from-objc/Classes.swift %t/OneWordSuperclass.o -Xlinker -install_name -Xlinker @executable_path/libClasses.dylib -lResilient -L %t
+// RUN: %target-codesign %t/libClasses.dylib
+// RUN: %target-run %t/main OLD %t/libResilient.dylib %t/libClasses.dylib
+
+// RUN: %target-build-swift -emit-library -emit-module -o %t/libResilient.dylib %S/Inputs/class-layout-from-objc/Resilient.swift -Xlinker -install_name -Xlinker @executable_path/libResilient.dylib -Xfrontend -enable-resilience -DSMALL
+// RUN: %target-codesign %t/libResilient.dylib
+// RUN: %target-run %t/main NEW %t/libResilient.dylib %t/libClasses.dylib
+
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+
+#import <objc/runtime.h>
+#import <assert.h>
+#import <dlfcn.h>
+#import <stdbool.h>
+#import <string.h>
+
+#import "Classes.h"
+
+void checkClass(Class c) {
+  assert(c);
+
+  size_t expectedSize = [c totalSize];
+  size_t actualSize = class_getInstanceSize([c class]);
+  NSLog(@"%@: expected size %zd, actual size %zd", c, expectedSize, actualSize);
+  assert(expectedSize == actualSize);
+
+  size_t expectedOffsetOfFirst = [c offsetOfFirst];
+  size_t offsetOfFirst = ivar_getOffset(class_getInstanceVariable(c, "first"));
+  NSLog(@"expected offset of 'first' %zd, actual %zd",
+        expectedOffsetOfFirst, offsetOfFirst);
+  assert(offsetOfFirst == expectedOffsetOfFirst);
+
+  size_t offsetOfLast = ivar_getOffset(class_getInstanceVariable(c, "last"));
+  NSLog(@"offset of 'last' %zd", offsetOfLast);
+  assert(offsetOfLast == actualSize - sizeof(intptr_t));
+}
+
+int main(int argc, const char * const argv[]) {
+  assert(argc > 1);
+
+  if (!strcmp(argv[1], "OLD")) {
+    ;
+  } else if (!strcmp(argv[1], "NEW")) {
+    // Only test the new behavior on a new enough libobjc.
+    if (!dlsym(RTLD_NEXT, "_objc_realizeClassFromSwift")) {
+      fprintf(stderr, "skipping evolution tests; OS too old\n");
+      return EXIT_SUCCESS;
+    }
+  } else {
+    fprintf(stderr, "usage: %s (OLD|NEW)\n", argv[0]);
+    return EXIT_FAILURE;
+  }
+
+  @autoreleasepool {
+    NSLog(@"%zd", class_getInstanceSize([OneWordSuperclass class]));
+    checkClass([StaticClass class]);
+    checkClass(objc_getClass("Classes.DynamicClass"));
+    checkClass(objc_getClass("Classes.PureSwiftClass"));
+  }
+}
diff --git a/validation-test/Sanitizers/witness_table_lookup.swift b/validation-test/Sanitizers/witness_table_lookup.swift
index f3a9313..33994d1 100644
--- a/validation-test/Sanitizers/witness_table_lookup.swift
+++ b/validation-test/Sanitizers/witness_table_lookup.swift
@@ -3,6 +3,7 @@
 // REQUIRES: executable_test
 // REQUIRES: stress_test
 // REQUIRES: tsan_runtime
+// UNSUPPORTED: CPU=powerpc64le
 
 // Check that TSan does not report spurious races in witness table lookup.
 
diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar47266563.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar47266563.swift
new file mode 100644
index 0000000..f23f296
--- /dev/null
+++ b/validation-test/Sema/type_checker_crashers_fixed/rdar47266563.swift
@@ -0,0 +1,3 @@
+// RUN: %target-swift-frontend %s -typecheck
+
+print(true ? "readline" : nil)
diff --git a/validation-test/compiler_scale/function_bodies.gyb b/validation-test/compiler_scale/function_bodies.gyb
index 49cfe39..38b7782 100644
--- a/validation-test/compiler_scale/function_bodies.gyb
+++ b/validation-test/compiler_scale/function_bodies.gyb
@@ -3,3 +3,35 @@
 // REQUIRES: asserts
 
 func method${N}() {}
+
+class C${N} {
+    func method${N}() {}
+}
+
+extension C${N} {
+    func otherMethod${N}() {}
+}
+
+struct S${N} {
+    func method${N}() {}
+}
+
+extension S${N} {
+    func otherMethod${N}() {}
+}
+
+enum E${N} {
+    func method${N}() {}
+}
+
+extension E${N} {
+    func otherMethod${N}() {}
+}
+
+protocol P${N} {
+    func method${N}()
+}
+
+extension P${N} {
+    func otherMethod${N}() {}
+}
\ No newline at end of file
diff --git a/validation-test/execution/arc_36509461.swift b/validation-test/execution/arc_36509461.swift
index 56f4603..5c730e3 100644
--- a/validation-test/execution/arc_36509461.swift
+++ b/validation-test/execution/arc_36509461.swift
@@ -9,6 +9,9 @@
 // REQUIRES: objc_interop
 // REQUIRES: OS=macosx
 
+// rdar://problem/47367694 tracks re-enabling this test for backward deployment.
+// UNSUPPORTED: remote_run
+
 import Foundation
 
 struct FakeUUID {