Version 2.13.0-123.0.dev

Merge commit '3ed83c398d15c3e13f86251e8e5f680ff5b42b79' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index e99fd45..36ef5eb 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
     "constraint, update this by running tools/generate_package_config.dart."
   ],
   "configVersion": 2,
-  "generated": "2021-03-08T09:29:10.028585",
+  "generated": "2021-03-09T13:31:13.443396",
   "generator": "tools/generate_package_config.dart",
   "packages": [
     {
@@ -339,7 +339,7 @@
       "name": "http_retry",
       "rootUri": "../third_party/pkg/http_retry",
       "packageUri": "lib/",
-      "languageVersion": "1.24"
+      "languageVersion": "2.12"
     },
     {
       "name": "http_throttle",
diff --git a/.gitignore b/.gitignore
index d7864e2..1f4ccc7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,11 +23,6 @@
 /*.vcxproj.user
 *.stamp
 
-# LLVM prebuilts
-/third_party/llvm/include
-/third_party/llvm/lib
-/third_party/llvm/.versions
-
 # Gyp generated files
 *.xcodeproj
 *.intermediate
diff --git a/BUILD.gn b/BUILD.gn
index 1140b668..5d3846c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -14,9 +14,6 @@
     testonly = true
   }
   deps = [ ":runtime" ]
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps += [ ":llvm_codegen" ]
-  }
 }
 
 group("most") {
@@ -117,21 +114,6 @@
   deps = [ "utils/analysis_server" ]
 }
 
-group("check_llvm") {
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps = [ "runtime/llvm_codegen/test" ]
-  }
-}
-
-group("llvm_codegen") {
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps = [
-      "runtime/llvm_codegen/bit",
-      "runtime/llvm_codegen/codegen",
-    ]
-  }
-}
-
 # This is the target that is built on the dart2js build bots.
 # It must depend on anything that is required by the dart2js
 # test suites.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a2ee87..2ae1e14 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,7 +20,17 @@
 - new lint: `use_named_constants`.
 - deprecation of `avoid_as`.
 
-## 2.12.0
+## 2.12.1 - 2021-03-10
+
+This is a patch release that fixes:
+
+* an unhandled exception in HTTPS connections (issue [#45047][]).
+* a typing issue in the typed_data `+` operator (issue [#45140][]).
+
+[#45047]: https://github.com/dart-lang/sdk/issues/45047
+[#45140]: https://github.com/dart-lang/sdk/issues/45140
+
+## 2.12.0 - 2021-03-03
 
 ### Language
 
@@ -318,7 +328,7 @@
 [#44072]: https://github.com/dart-lang/sdk/issues/44072
 [dart tool]: https://dart.dev/tools/dart-tool
 
-## 2.10.5 - 2020-01-21
+## 2.10.5 - 2021-01-21
 
 This is a patch release that fixes a crash in the Dart VM. (issue [#44563][]).
 
diff --git a/DEPS b/DEPS
index 8c55dd0..e47320e 100644
--- a/DEPS
+++ b/DEPS
@@ -110,7 +110,7 @@
   "http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
   "http_multi_server_rev" : "6bf4b6e5d4d890e6d54559b858ff229d79711171",
   "http_parser_rev": "5dd4d16693242049dfb43b5efa429fedbf932e98",
-  "http_retry_tag": "0.1.1",
+  "http_retry_rev": "845771af7bb5ab38ab740ce4a31f3b0c7680302b",
   "http_rev": "d5c678cd63c3e9c1d779a09acfa95b7e3af84665",
   "http_throttle_tag" : "1.0.2",
   "icu_rev" : "79326efe26e5440f530963704c3c0ff965b3a4ac",
@@ -180,18 +180,10 @@
   "chrome_tag": "84",
   "download_firefox": False,
   "firefox_tag": "67",
-
-  # An LLVM backend needs LLVM binaries and headers. To avoid build time
-  # increases we can use prebuilts. We don't want to download this on every
-  # CQ/CI bot nor do we want the average Dart developer to incur that cost.
-  # So by default we will not download prebuilts.
-  "checkout_llvm": False,
-  "llvm_revision": "fe8bd96ebd6c490ea0b5c1fb342db2d7c393a109"
 }
 
 gclient_gn_args_file = Var("dart_root") + '/build/config/gclient_args.gni'
 gclient_gn_args = [
-  'checkout_llvm'
 ]
 
 deps = {
@@ -363,7 +355,7 @@
       Var("dart_git") + "http_parser.git" + "@" + Var("http_parser_rev"),
   Var("dart_root") + "/third_party/pkg/http_retry":
       Var("dart_git") + "http_retry.git" +
-      "@" + Var("http_retry_tag"),
+      "@" + Var("http_retry_rev"),
   Var("dart_root") + "/third_party/pkg/http_throttle":
       Var("dart_git") + "http_throttle.git" +
       "@" + Var("http_throttle_tag"),
@@ -615,16 +607,6 @@
       ],
       "dep_type": "cipd",
   },
-  Var("dart_root") + "/third_party/llvm": {
-      "packages": [
-          {
-              "package": "fuchsia/lib/llvm/${{platform}}",
-              "version": "git_revision:" + Var("llvm_revision"),
-          },
-      ],
-      "condition": "checkout_llvm",
-      "dep_type": "cipd",
-  },
   Var("dart_root") + "/third_party/browsers/chrome": {
       "packages": [
           {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
index 795eabe..5b2865b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/feature_computer.dart
@@ -1004,18 +1004,24 @@
 }
 
 /// Some useful extensions on [AstNode] for this computer.
-extension AstNodeFeatureComputerExtension on AstNode {
+extension on AstNode {
   bool contains(int o) => offset <= o && o <= end;
+}
 
-  /// Return the [FunctionType], if there is one, for this [AstNode].
+/// Some useful extensions on [ArgumentList] for this computer.
+extension on ArgumentList {
+  /// Return the [FunctionType], if there is one, for this [ArgumentList].
   FunctionType get functionType {
-    if (parent is MethodInvocation) {
-      var type = (parent as MethodInvocation).staticInvokeType;
+    var parent = this.parent;
+    if (parent is InstanceCreationExpression) {
+      return parent.constructorName.staticElement?.type;
+    } else if (parent is MethodInvocation) {
+      var type = parent.staticInvokeType;
       if (type is FunctionType) {
         return type;
       }
     } else if (parent is FunctionExpressionInvocation) {
-      var type = (parent as FunctionExpressionInvocation).staticInvokeType;
+      var type = parent.staticInvokeType;
       if (type is FunctionType) {
         return type;
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index f77adbd..bd6ecf6 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -111,6 +111,11 @@
         // Setters, fields, and methods shadow a setter.
         if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
           return false;
+        } else if (element.hasDeprecated &&
+            !element.correspondingGetter.hasDeprecated) {
+          // A deprecated setter should not take priority over a non-deprecated
+          // getter.
+          return false;
         }
         _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
       }
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index 4cc0967..191aad3 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -17,7 +17,8 @@
       .map((CompletionSuggestion suggestion) => suggestion.completion)
       .toList();
 
-  void assertHasCompletion(String completion) {
+  void assertHasCompletion(String completion,
+      {ElementKind elementKind, bool isDeprecated}) {
     var expectedOffset = completion.indexOf(CURSOR_MARKER);
     if (expectedOffset >= 0) {
       if (completion.contains(CURSOR_MARKER, expectedOffset + 1)) {
@@ -51,6 +52,12 @@
     }
     expect(matchingSuggestion.selectionOffset, equals(expectedOffset));
     expect(matchingSuggestion.selectionLength, equals(0));
+    if (elementKind != null) {
+      expect(matchingSuggestion.element.kind, elementKind);
+    }
+    if (isDeprecated != null) {
+      expect(matchingSuggestion.isDeprecated, isDeprecated);
+    }
   }
 
   void assertHasNoCompletion(String completion) {
diff --git a/pkg/analysis_server/test/src/cider/assists_test.dart b/pkg/analysis_server/test/src/cider/assists_test.dart
index aa1fc47..db0e616b2 100644
--- a/pkg/analysis_server/test/src/cider/assists_test.dart
+++ b/pkg/analysis_server/test/src/cider/assists_test.dart
@@ -11,6 +11,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../utilities/mock_packages.dart';
 import 'cider_service.dart';
 
 void main() {
@@ -37,6 +38,12 @@
     expect(resultContent, expected);
   }
 
+  @override
+  void setUp() {
+    super.setUp();
+    BazelMockPackages.instance.addFlutter(resourceProvider);
+  }
+
   Future<void> test_addReturnType() async {
     await _compute(r'''
 void m() {
@@ -55,6 +62,29 @@
 ''');
   }
 
+  Future<void> test_aroundText() async {
+    await _compute('''
+import 'package:flutter/widgets.dart';
+
+main() {
+  ^Text('a');
+}
+''');
+
+    assertHasAssist(DartAssistKind.FLUTTER_WRAP_STREAM_BUILDER, r'''
+import 'package:flutter/widgets.dart';
+
+main() {
+  StreamBuilder<Object>(
+    stream: null,
+    builder: (context, snapshot) {
+      return Text('a');
+    }
+  );
+}
+''');
+  }
+
   Future<void> test_assignToLocalVariable() async {
     await _compute(r'''
 main() {
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
index 03ba7c0..124af22 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -136,7 +136,7 @@
     "kind": "CLASS",
     "name": "A",
     "location": {
-      "file": "/home/test/lib/a.dart",
+      "file": ${jsonOfPath(path)},
       "offset": 15,
       "length": 0,
       "startLine": 1,
@@ -159,7 +159,7 @@
     "kind": "CONSTRUCTOR",
     "name": "b",
     "location": {
-      "file": "/home/test/lib/a.dart",
+      "file": ${jsonOfPath(path)},
       "offset": 40,
       "length": 0,
       "startLine": 3,
diff --git a/pkg/analysis_server/test/src/services/completion/dart/completion_test.dart b/pkg/analysis_server/test/src/services/completion/dart/completion_test.dart
index 97d6219..79c79b7 100644
--- a/pkg/analysis_server/test/src/services/completion/dart/completion_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/dart/completion_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analysis_server/src/protocol_server.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../completion_test_support.dart';
@@ -9,6 +10,7 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ConstructorCompletionTest);
+    defineReflectiveTests(PropertyAccessorCompletionTest);
   });
 }
 
@@ -24,6 +26,26 @@
   C.c();
 }
 ''');
+    await getSuggestions();
     assertHasNoCompletion('C.c');
   }
 }
+
+@reflectiveTest
+class PropertyAccessorCompletionTest extends CompletionTestCase {
+  Future<void> test_constructor_abstract() async {
+    addTestFile('''
+void f(C c) {
+  c.^;
+}
+class C {
+  int get x => 0;
+  @deprecated
+  set x(int x) {}
+}
+''');
+    await getSuggestions();
+    assertHasCompletion('x',
+        elementKind: ElementKind.GETTER, isDeprecated: false);
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
index d6746b3..2a6276b 100644
--- a/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
+++ b/pkg/analysis_server/test/src/services/completion/dart/feature_computer_test.dart
@@ -31,6 +31,17 @@
     }
   }
 
+  Future<void> test_argumentList_instanceCreation() async {
+    await assertContextType('''
+class C {
+  C({String s}) {}
+}
+void f() {
+  C(s:^);
+}
+''', 'String');
+  }
+
   Future<void> test_argumentList_named_afterColon() async {
     await assertContextType('''
 void f({int i, String s, bool b}) {}
@@ -87,6 +98,17 @@
 ''', 'int');
   }
 
+  Future<void> test_argumentList_named_method() async {
+    await assertContextType('''
+class C {
+  void m(int i) {}
+}
+void f(C c) {
+  c.m(^);
+}
+''', 'int');
+  }
+
   Future<void> test_argumentList_named_unresolved_hasNamedParameters() async {
     await assertContextType('''
 void f({int i}) {}
diff --git a/pkg/analysis_server/test/src/utilities/mock_packages.dart b/pkg/analysis_server/test/src/utilities/mock_packages.dart
index c60002d..e789d2e 100644
--- a/pkg/analysis_server/test/src/utilities/mock_packages.dart
+++ b/pkg/analysis_server/test/src/utilities/mock_packages.dart
@@ -7,6 +7,71 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer_utilities/package_root.dart' as package_root;
 
+void _cacheFiles(Map<String, String> cachedFiles) {
+  var resourceProvider = PhysicalResourceProvider.INSTANCE;
+  var pathContext = resourceProvider.pathContext;
+  var packageRoot = pathContext.normalize(package_root.packageRoot);
+  var mockPath = pathContext.join(
+    packageRoot,
+    'analysis_server',
+    'test',
+    'mock_packages',
+  );
+
+  void addFiles(Resource resource) {
+    if (resource is Folder) {
+      resource.getChildren().forEach(addFiles);
+    } else if (resource is File) {
+      var relativePath = pathContext.relative(
+        resource.path,
+        from: mockPath,
+      );
+      var relativePathComponents = pathContext.split(relativePath);
+      var relativePosixPath = relativePathComponents.join('/');
+      cachedFiles[relativePosixPath] = resource.readAsStringSync();
+    }
+  }
+
+  addFiles(
+    resourceProvider.getFolder(mockPath),
+  );
+}
+
+/// Helper for copying files from "tests/mock_packages" to memory file system
+/// for Bazel.
+class BazelMockPackages {
+  static final BazelMockPackages instance = BazelMockPackages._();
+
+  /// The mapping from relative Posix paths of files to the file contents.
+  final Map<String, String> _cachedFiles = {};
+
+  BazelMockPackages._() {
+    _cacheFiles(_cachedFiles);
+  }
+
+  void addFlutter(MemoryResourceProvider provider) {
+    _addFiles(provider, 'flutter');
+  }
+
+  /// Add files of the given [packageName] to the [provider].
+  Folder _addFiles(MemoryResourceProvider provider, String packageName) {
+    var packagesPath = provider.convertPath('/workspace/third_party/dart');
+
+    for (var relativePosixPath in _cachedFiles.keys) {
+      var relativePathComponents = relativePosixPath.split('/');
+      if (relativePathComponents[0] == packageName) {
+        var relativePath = provider.pathContext.joinAll(relativePathComponents);
+        var path = provider.pathContext.join(packagesPath, relativePath);
+        var content = _cachedFiles[relativePosixPath];
+        provider.newFile(path, content);
+      }
+    }
+
+    var packagesFolder = provider.getFolder(packagesPath);
+    return packagesFolder.getChildAssumingFolder(packageName);
+  }
+}
+
 /// Helper for copying files from "tests/mock_packages" to memory file system.
 class MockPackages {
   static final MockPackages instance = MockPackages._();
@@ -15,7 +80,7 @@
   final Map<String, String> _cachedFiles = {};
 
   MockPackages._() {
-    _cacheFiles();
+    _cacheFiles(_cachedFiles);
   }
 
   Folder addFlutter(MemoryResourceProvider provider) {
@@ -60,34 +125,4 @@
     var packagesFolder = provider.getFolder(packagesPath);
     return packagesFolder.getChildAssumingFolder(packageName);
   }
-
-  void _cacheFiles() {
-    var resourceProvider = PhysicalResourceProvider.INSTANCE;
-    var pathContext = resourceProvider.pathContext;
-    var packageRoot = pathContext.normalize(package_root.packageRoot);
-    var mockPath = pathContext.join(
-      packageRoot,
-      'analysis_server',
-      'test',
-      'mock_packages',
-    );
-
-    void addFiles(Resource resource) {
-      if (resource is Folder) {
-        resource.getChildren().forEach(addFiles);
-      } else if (resource is File) {
-        var relativePath = pathContext.relative(
-          resource.path,
-          from: mockPath,
-        );
-        var relativePathComponents = pathContext.split(relativePath);
-        var relativePosixPath = relativePathComponents.join('/');
-        _cachedFiles[relativePosixPath] = resource.readAsStringSync();
-      }
-    }
-
-    addFiles(
-      resourceProvider.getFolder(mockPath),
-    );
-  }
 }
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
deleted file mode 100644
index 4d71ec1..0000000
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:args/args.dart';
-
-const String analysisOptionsFileOption = 'options';
-const String defaultLanguageVersionOption = 'default-language-version';
-const String defineVariableOption = 'D';
-const String enableExperimentOption = 'enable-experiment';
-const String enableInitializingFormalAccessFlag = 'initializing-formal-access';
-@deprecated
-const String enableSuperMixinFlag = 'supermixin';
-const String flutterAnalysisOptionsPath =
-    'package:flutter/analysis_options_user.yaml';
-const String ignoreUnrecognizedFlagsFlag = 'ignore-unrecognized-flags';
-const String implicitCastsFlag = 'implicit-casts';
-const String lintsFlag = 'lints';
-const String noImplicitDynamicFlag = 'no-implicit-dynamic';
-const String packagesOption = 'packages';
-const String sdkPathOption = 'dart-sdk';
-
-const String sdkSummaryPathOption = 'dart-sdk-summary';
-
-/// Update [options] with the value of each analysis option command line flag.
-void applyAnalysisOptionFlags(AnalysisOptionsImpl options, ArgResults args,
-    {void Function(String text)? verbosePrint}) {
-  void verbose(String text) {
-    if (verbosePrint != null) {
-      verbosePrint('Analysis options: $text');
-    }
-  }
-
-  if (args.wasParsed(enableExperimentOption)) {
-    var flags = args[enableExperimentOption] as List<String>;
-    options.contextFeatures = FeatureSet.fromEnableFlags2(
-      sdkLanguageVersion: ExperimentStatus.currentVersion,
-      flags: flags,
-    );
-  }
-
-  if (args.wasParsed(implicitCastsFlag)) {
-    options.implicitCasts = args[implicitCastsFlag];
-    verbose('$implicitCastsFlag = ${options.implicitCasts}');
-  }
-  if (args.wasParsed(noImplicitDynamicFlag)) {
-    options.implicitDynamic = !args[noImplicitDynamicFlag];
-    verbose('$noImplicitDynamicFlag = ${options.implicitDynamic}');
-  }
-  try {
-    if (args.wasParsed(lintsFlag)) {
-      options.lint = args[lintsFlag];
-      verbose('$lintsFlag = ${options.lint}');
-    }
-  } on ArgumentError {
-    // lints were not defined - ignore and fall through
-  }
-}
-
-/// Use the command-line [args] to create a context builder options.
-ContextBuilderOptions createContextBuilderOptions(
-  ResourceProvider resourceProvider,
-  ArgResults args,
-) {
-  String? absoluteNormalizedPath(String? path) {
-    if (path == null) {
-      return null;
-    }
-    var pathContext = resourceProvider.pathContext;
-    return pathContext.normalize(
-      pathContext.absolute(path),
-    );
-  }
-
-  ContextBuilderOptions builderOptions = ContextBuilderOptions();
-  builderOptions.argResults = args;
-  //
-  // File locations.
-  //
-  builderOptions.dartSdkSummaryPath = absoluteNormalizedPath(
-    args[sdkSummaryPathOption],
-  );
-  builderOptions.defaultAnalysisOptionsFilePath = absoluteNormalizedPath(
-    args[analysisOptionsFileOption],
-  );
-  builderOptions.defaultPackageFilePath = absoluteNormalizedPath(
-    args[packagesOption],
-  );
-  //
-  // Analysis options.
-  //
-  AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-  applyAnalysisOptionFlags(defaultOptions, args);
-  builderOptions.defaultOptions = defaultOptions;
-  //
-  // Declared variables.
-  //
-  Map<String, String> declaredVariables = <String, String>{};
-  List<String> variables = (args[defineVariableOption] as List).cast<String>();
-  for (String variable in variables) {
-    int index = variable.indexOf('=');
-    if (index < 0) {
-      // TODO (brianwilkerson) Decide the semantics we want in this case.
-      // The VM prints "No value given to -D option", then tries to load '-Dfoo'
-      // as a file and dies. Unless there was nothing after the '-D', in which
-      // case it prints the warning and ignores the option.
-    } else {
-      String name = variable.substring(0, index);
-      if (name.isNotEmpty) {
-        // TODO (brianwilkerson) Decide the semantics we want in the case where
-        // there is no name. If there is no name, the VM tries to load a file
-        // named '-D' and dies.
-        declaredVariables[name] = variable.substring(index + 1);
-      }
-    }
-  }
-  builderOptions.declaredVariables = declaredVariables;
-
-  return builderOptions;
-}
-
-/// Add the standard flags and options to the given [parser]. The standard flags
-/// are those that are typically used to control the way in which the code is
-/// analyzed.
-///
-/// TODO(danrubel) Update DDC to support all the options defined in this method
-/// then remove the [ddc] named argument from this method.
-void defineAnalysisArguments(ArgParser parser,
-    {bool hide = true, bool ddc = false}) {
-  parser.addOption(sdkPathOption,
-      help: 'The path to the Dart SDK.', hide: ddc && hide);
-  parser.addOption(analysisOptionsFileOption,
-      help: 'Path to an analysis options file.', hide: ddc && hide);
-  parser.addFlag('strong',
-      help: 'Enable strong mode (deprecated); this option is now ignored.',
-      defaultsTo: true,
-      hide: true,
-      negatable: true);
-  parser.addFlag('declaration-casts',
-      negatable: true,
-      help: 'Disable declaration casts in strong mode (https://goo.gl/cTLz40)\n'
-          'This option is now ignored and will be removed in a future release.',
-      hide: ddc && hide);
-  parser.addMultiOption(enableExperimentOption,
-      help: 'Enable one or more experimental features. If multiple features '
-          'are being added, they should be comma separated.',
-      splitCommas: true);
-  parser.addFlag(implicitCastsFlag,
-      negatable: true,
-      help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40).',
-      hide: ddc && hide);
-  parser.addFlag(noImplicitDynamicFlag,
-      negatable: false,
-      help: 'Disable implicit dynamic (https://goo.gl/m0UgXD).',
-      hide: ddc && hide);
-
-  //
-  // Hidden flags and options.
-  //
-  parser.addMultiOption(defineVariableOption,
-      abbr: 'D',
-      help:
-          'Define an environment declaration. For example, "-Dfoo=bar" defines '
-          'an environment declaration named "foo" whose value is "bar".',
-      hide: hide);
-  parser.addOption(packagesOption,
-      help: 'The path to the package resolution configuration file, which '
-          'supplies a mapping of package names\nto paths.',
-      hide: ddc);
-  parser.addOption(sdkSummaryPathOption,
-      help: 'The path to the Dart SDK summary file.', hide: hide);
-  parser.addFlag(enableInitializingFormalAccessFlag,
-      help:
-          'Enable support for allowing access to field formal parameters in a '
-          'constructor\'s initializer list (deprecated).',
-      defaultsTo: false,
-      negatable: false,
-      hide: hide || ddc);
-  if (!ddc) {
-    parser.addFlag(lintsFlag,
-        help: 'Show lint results.', defaultsTo: false, negatable: true);
-  }
-}
-
-/// Find arguments of the form -Dkey=value
-/// or argument pairs of the form -Dkey value
-/// and place those key/value pairs into [definedVariables].
-/// Return a list of arguments with the key/value arguments removed.
-List<String> extractDefinedVariables(
-    List<String> args, Map<String, String> definedVariables) {
-  //TODO(danrubel) extracting defined variables is already handled by the
-  // createContextBuilderOptions method.
-  // Long term we should switch to using that instead.
-  int count = args.length;
-  List<String> remainingArgs = <String>[];
-  for (int i = 0; i < count; i++) {
-    String arg = args[i];
-    if (arg == '--') {
-      while (i < count) {
-        remainingArgs.add(args[i++]);
-      }
-    } else if (arg.startsWith("-D")) {
-      int end = arg.indexOf('=');
-      if (end > 2) {
-        definedVariables[arg.substring(2, end)] = arg.substring(end + 1);
-      } else if (i + 1 < count) {
-        definedVariables[arg.substring(2)] = args[++i];
-      } else {
-        remainingArgs.add(arg);
-      }
-    } else {
-      remainingArgs.add(arg);
-    }
-  }
-  return remainingArgs;
-}
-
-/// Return a list of command-line arguments containing all of the given [args]
-/// that are defined by the given [parser]. An argument is considered to be
-/// defined by the parser if
-/// - it starts with '--' and the rest of the argument (minus any value
-///   introduced by '=') is the name of a known option,
-/// - it starts with '-' and the rest of the argument (minus any value
-///   introduced by '=') is the name of a known abbreviation, or
-/// - it starts with something other than '--' or '-'.
-///
-/// This function allows command-line tools to implement the
-/// '--ignore-unrecognized-flags' option.
-List<String> filterUnknownArguments(List<String> args, ArgParser parser) {
-  Set<String> knownOptions = HashSet<String>();
-  Set<String> knownAbbreviations = HashSet<String>();
-  parser.options.forEach((String name, Option option) {
-    knownOptions.add(name);
-    String? abbreviation = option.abbr;
-    if (abbreviation != null) {
-      knownAbbreviations.add(abbreviation);
-    }
-    if (option.negatable ?? false) {
-      knownOptions.add('no-$name');
-    }
-  });
-  String optionName(int prefixLength, String argument) {
-    int equalsOffset = argument.lastIndexOf('=');
-    if (equalsOffset < 0) {
-      return argument.substring(prefixLength);
-    }
-    return argument.substring(prefixLength, equalsOffset);
-  }
-
-  List<String> filtered = <String>[];
-  for (int i = 0; i < args.length; i++) {
-    String argument = args[i];
-    if (argument.startsWith('--') && argument.length > 2) {
-      if (knownOptions.contains(optionName(2, argument))) {
-        filtered.add(argument);
-      }
-    } else if (argument.startsWith('-') && argument.length > 1) {
-      if (knownAbbreviations.contains(optionName(1, argument))) {
-        filtered.add(argument);
-      }
-    } else {
-      filtered.add(argument);
-    }
-  }
-  return filtered;
-}
-
-/// Use the given [parser] to parse the given command-line [args], and return
-/// the result.
-ArgResults parse(
-    ResourceProvider provider, ArgParser parser, List<String> args) {
-  args = preprocessArgs(provider, args);
-  if (args.contains('--$ignoreUnrecognizedFlagsFlag')) {
-    args = filterUnknownArguments(args, parser);
-  }
-  return parser.parse(args);
-}
-
-/// Preprocess the given list of command line [args].
-/// If the final arg is `@file_path` (Bazel worker mode),
-/// then read in all the lines of that file and add those as args.
-/// Always returns a new modifiable list.
-List<String> preprocessArgs(ResourceProvider provider, List<String> args) {
-  args = List.from(args);
-  if (args.isEmpty) {
-    return args;
-  }
-  String lastArg = args.last;
-  if (lastArg.startsWith('@')) {
-    File argsFile = provider.getFile(lastArg.substring(1));
-    try {
-      args.removeLast();
-      args.addAll(argsFile
-          .readAsStringSync()
-          .replaceAll('\r\n', '\n')
-          .replaceAll('\r', '\n')
-          .split('\n')
-          .where((String line) => line.isNotEmpty));
-    } on FileSystemException catch (e) {
-      throw Exception('Failed to read file specified by $lastArg : $e');
-    }
-  }
-  return args;
-}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index a388bb3..7df7c16 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -8,8 +8,6 @@
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
-import 'package:analyzer/src/command_line/arguments.dart'
-    show applyAnalysisOptionFlags;
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
@@ -25,14 +23,12 @@
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/workspace/basic.dart';
 import 'package:analyzer/src/workspace/bazel.dart';
 import 'package:analyzer/src/workspace/gn.dart';
 import 'package:analyzer/src/workspace/package_build.dart';
 import 'package:analyzer/src/workspace/pub.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
-import 'package:args/args.dart';
 import 'package:yaml/yaml.dart';
 
 /// A utility class used to build an analysis context for a given directory.
@@ -145,15 +141,6 @@
     return driver;
   }
 
-  /// Return an analysis options object containing the default option values.
-  AnalysisOptionsImpl createDefaultOptions() {
-    AnalysisOptions? defaultOptions = builderOptions.defaultOptions;
-    if (defaultOptions == null) {
-      return AnalysisOptionsImpl();
-    }
-    return AnalysisOptionsImpl.from(defaultOptions);
-  }
-
 //  void _processAnalysisOptions(
 //      AnalysisContext context, Map<String, YamlNode> optionMap) {
 //    List<OptionsProcessor> optionsProcessors =
@@ -266,30 +253,20 @@
     AnalysisOptionsProvider optionsProvider =
         AnalysisOptionsProvider(sourceFactory);
 
-    AnalysisOptionsImpl options = createDefaultOptions();
-    File? optionsFile = getOptionsFile(path);
-    YamlMap? optionMap;
+    AnalysisOptionsImpl options = AnalysisOptionsImpl();
 
-    if (optionsFile != null) {
+    var optionsPath = builderOptions.defaultAnalysisOptionsFilePath;
+    if (optionsPath != null) {
+      var optionsFile = resourceProvider.getFile(optionsPath);
       try {
-        optionMap = optionsProvider.getOptionsFromFile(optionsFile);
-        if (contextRoot != null) {
-          contextRoot.optionsFilePath = optionsFile.path;
-        }
+        contextRoot?.optionsFilePath = optionsFile.path;
+        var optionsMap = optionsProvider.getOptionsFromFile(optionsFile);
+        applyToAnalysisOptions(options, optionsMap);
         verbose('Loaded analysis options from ${optionsFile.path}');
       } catch (e) {
         // Ignore exceptions thrown while trying to load the options file.
         verbose('Exception: $e\n  when loading ${optionsFile.path}');
       }
-    }
-
-    if (optionMap != null) {
-      applyToAnalysisOptions(options, optionMap);
-      var argResults = builderOptions.argResults;
-      if (argResults != null) {
-        applyAnalysisOptionFlags(options, argResults,
-            verbosePrint: verbosePrint);
-      }
     } else {
       verbose('Using default analysis options');
     }
@@ -306,29 +283,6 @@
     return options;
   }
 
-  /// Return the analysis options file that should be used when analyzing code in
-  /// the directory with the given [path].
-  ///
-  /// If [forceSearch] is true, then don't return the default analysis options
-  /// path. This allows cli to locate what *would* have been the analysis options
-  /// file path, and super-impose the defaults over it in-place.
-  File? getOptionsFile(String path, {bool forceSearch = false}) {
-    if (!forceSearch) {
-      String? filePath = builderOptions.defaultAnalysisOptionsFilePath;
-      if (filePath != null) {
-        return resourceProvider.getFile(filePath);
-      }
-    }
-
-    var folder = resourceProvider.getFolder(path);
-    for (var current in folder.withAncestors) {
-      var file = current.getChildAssumingFile(file_paths.analysisOptionsYaml);
-      if (file.exists) {
-        return file;
-      }
-    }
-  }
-
   /// Return the `pubspec.yaml` file that should be used when analyzing code in
   /// the directory with the given [path], possibly `null`.
   File? _findPubspecFile(String path) {
@@ -411,10 +365,6 @@
 
 /// Options used by a [ContextBuilder].
 class ContextBuilderOptions {
-  /// The results of parsing the command line arguments as defined by
-  /// [defineAnalysisArguments] or `null` if none.
-  ArgResults? argResults;
-
   /// The file path of the file containing the summary of the SDK that should be
   /// used to "analyze" the SDK. This option should only be specified by
   /// command-line tools such as 'dartanalyzer' or 'ddc'.
@@ -428,11 +378,6 @@
   /// A table mapping variable names to values for the declared variables.
   Map<String, String> declaredVariables = {};
 
-  /// The default analysis options that should be used unless some or all of them
-  /// are overridden in the analysis options file, or `null` if the default
-  /// defaults should be used.
-  AnalysisOptions? defaultOptions;
-
   /// The file path of the .packages file that should be used in place of any
   /// file found using the normal (Package Specification DEP) lookup mechanism,
   /// or `null` if the normal lookup mechanism should be used.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 3ee04f3..498c87c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -1314,7 +1314,7 @@
             sourceFactory,
             libraryContext.isLibraryUri,
             libraryContext.analysisContext,
-            libraryContext.elementFactory,
+            libraryContext.elementFactory.libraryOfUri2(library.uriStr),
             libraryContext.analysisSession.inheritanceManager,
             library,
             testingData: testingData);
@@ -1404,7 +1404,7 @@
           sourceFactory,
           libraryContext.isLibraryUri,
           libraryContext.analysisContext,
-          libraryContext.elementFactory,
+          libraryContext.elementFactory.libraryOfUri2(library.uriStr),
           libraryContext.analysisSession.inheritanceManager,
           library,
           testingData: testingData);
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 82b883d..9bd9dad 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -45,7 +45,6 @@
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/linter_visitor.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:pub_semver/pub_semver.dart';
 
@@ -70,9 +69,8 @@
   final InheritanceManager3 _inheritance;
   final bool Function(Uri) _isLibraryUri;
   final AnalysisContext _context;
-  final LinkedElementFactory _elementFactory;
 
-  late final LibraryElementImpl _libraryElement;
+  final LibraryElementImpl _libraryElement;
 
   final Map<FileState, LineInfo> _fileToLineInfo = {};
 
@@ -91,7 +89,7 @@
       this._sourceFactory,
       this._isLibraryUri,
       this._context,
-      this._elementFactory,
+      this._libraryElement,
       this._inheritance,
       this._library,
       {TestingData? testingData})
@@ -118,8 +116,6 @@
     }
     timerLibraryAnalyzerFreshUnit.stop();
 
-    _libraryElement = _elementFactory.libraryOfUri2(_library.uriStr);
-
     // Resolve URIs in directives to corresponding sources.
     FeatureSet featureSet = units[_library]!.featureSet;
     units.forEach((file, unit) {
diff --git a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
index 6c8865c..97a397f 100644
--- a/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/micro/analysis_context.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
+
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/declared_variables.dart';
@@ -40,6 +42,7 @@
   );
 
   var analysisSession = _MicroAnalysisSessionImpl(
+    fileResolver,
     declaredVariables,
     sourceFactory,
   );
@@ -90,6 +93,19 @@
 }
 
 class _FakeAnalysisDriver implements AnalysisDriver {
+  final FileResolver fileResolver;
+
+  late _MicroAnalysisSessionImpl _currentSession;
+
+  _FakeAnalysisDriver(this.fileResolver);
+
+  @override
+  AnalysisSessionImpl get currentSession {
+    _currentSession = fileResolver.contextObjects?.analysisSession
+        as _MicroAnalysisSessionImpl;
+    return _currentSession;
+  }
+
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
@@ -138,6 +154,8 @@
 }
 
 class _MicroAnalysisSessionImpl extends AnalysisSessionImpl {
+  final FileResolver fileResolver;
+
   @override
   final DeclaredVariables declaredVariables;
 
@@ -147,9 +165,10 @@
   late _MicroAnalysisContextImpl analysisContext;
 
   _MicroAnalysisSessionImpl(
+    this.fileResolver,
     this.declaredVariables,
     this.sourceFactory,
-  ) : super(_FakeAnalysisDriver());
+  ) : super(_FakeAnalysisDriver(fileResolver));
 
   @override
   ResourceProvider get resourceProvider =>
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 376a4c6..f4cce34 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:collection';
 import 'dart:convert';
 import 'dart:typed_data';
 
@@ -135,13 +134,11 @@
   /// Return the [uri] string.
   String get uriStr => uri.toString();
 
-  /// Recursively traverse imports, exports, and parts to collect all
-  /// files that are accessed.
+  /// Collect all files that are transitively referenced by this file via
+  /// imports, exports, and parts.
   void collectAllReferencedFiles(Set<String> referencedFiles) {
-    var deps = {...importedFiles, ...exportedFiles, ...partedFiles};
-    for (var file in deps) {
-      if (!referencedFiles.contains(file.path)) {
-        referencedFiles.add(file.path);
+    for (var file in {...importedFiles, ...exportedFiles, ...partedFiles}) {
+      if (referencedFiles.add(file.path)) {
         file.collectAllReferencedFiles(referencedFiles);
       }
     }
@@ -626,29 +623,30 @@
   /// [files]. Removes the [FileState]'s of the files not used for analysis from
   /// the cache. Returns the set of unused [FileState]'s.
   List<FileState> removeUnusedFiles(List<String> files) {
-    var removedFiles = <FileState>[];
-    var unusedFiles = _pathToFile.keys.toSet();
-    var deps = HashSet<String>();
+    var allReferenced = <String>{};
     for (var path in files) {
-      unusedFiles.remove(path);
-      _pathToFile[path]!.collectAllReferencedFiles(deps);
+      allReferenced.add(path);
+      _pathToFile[path]?.collectAllReferencedFiles(allReferenced);
     }
-    for (var path in deps) {
-      unusedFiles.remove(path);
-    }
-    for (var path in unusedFiles) {
+
+    var unusedPaths = _pathToFile.keys.toSet();
+    unusedPaths.removeAll(allReferenced);
+    testView.removedPaths = unusedPaths;
+
+    var removedFiles = <FileState>[];
+    for (var path in unusedPaths) {
       var file = _pathToFile.remove(path)!;
       _uriToFile.remove(file.uri);
       removedFiles.add(file);
     }
-    testView.unusedFiles = unusedFiles;
+
     return removedFiles;
   }
 }
 
 class FileSystemStateTestView {
   final List<String> refreshedFiles = [];
-  Set<String> unusedFiles = {};
+  Set<String> removedPaths = {};
 }
 
 class FileSystemStateTimer {
diff --git a/pkg/analyzer/lib/src/error/imports_verifier.dart b/pkg/analyzer/lib/src/error/imports_verifier.dart
index c421a30..6759bd2 100644
--- a/pkg/analyzer/lib/src/error/imports_verifier.dart
+++ b/pkg/analyzer/lib/src/error/imports_verifier.dart
@@ -438,7 +438,12 @@
           continue;
         }
         for (var element in elements) {
-          if (namespace.getPrefixed(prefix.name, element.name!) != null) {
+          var elementFromNamespace =
+              namespace.getPrefixed(prefix.name, element.name!);
+          if (elementFromNamespace != null) {
+            if (_isShadowing(element, elementFromNamespace)) {
+              continue;
+            }
             _unusedImports.remove(importDirective);
             _removeFromUnusedShownNamesMap(element, importDirective);
           }
@@ -454,7 +459,14 @@
       // Find import directives using namespaces.
       for (ImportDirective importDirective in _allImports) {
         var namespace = _computeNamespace(importDirective);
-        if (namespace?.get(element.name!) != null) {
+        if (namespace == null) {
+          continue;
+        }
+        var elementFromNamespace = namespace.get(element.name!);
+        if (elementFromNamespace != null) {
+          if (_isShadowing(element, elementFromNamespace)) {
+            continue;
+          }
           _unusedImports.remove(importDirective);
           _removeFromUnusedShownNamesMap(element, importDirective);
         }
@@ -563,6 +575,22 @@
     return namespace;
   }
 
+  /// Returns whether [e1] shadows [e2], assuming each is an imported element,
+  /// and that each is imported with the same prefix.
+  ///
+  /// Returns false if the source of either element is `null`.
+  bool _isShadowing(Element e1, Element e2) {
+    var source1 = e1.source;
+    if (source1 == null) {
+      return false;
+    }
+    var source2 = e2.source;
+    if (source2 == null) {
+      return false;
+    }
+    return !source1.isInSystemLibrary && source2.isInSystemLibrary;
+  }
+
   /// Remove [element] from the list of names shown by [importDirective].
   void _removeFromUnusedShownNamesMap(
       Element element, ImportDirective importDirective) {
diff --git a/pkg/analyzer/lib/src/error/override_verifier.dart b/pkg/analyzer/lib/src/error/override_verifier.dart
index 71a6d88..795a093 100644
--- a/pkg/analyzer/lib/src/error/override_verifier.dart
+++ b/pkg/analyzer/lib/src/error/override_verifier.dart
@@ -89,7 +89,12 @@
 
   /// Return `true` if the [member] overrides a member from a superinterface.
   bool _isOverride(ExecutableElement member) {
-    var name = Name(_libraryUri, member.name);
-    return _inheritance.getOverridden2(_currentClass!, name) != null;
+    var currentClass = _currentClass;
+    if (currentClass != null) {
+      var name = Name(_libraryUri, member.name);
+      return _inheritance.getOverridden2(currentClass, name) != null;
+    } else {
+      return false;
+    }
   }
 }
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 3ba35e2..a6d0a3d 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -8,7 +8,6 @@
 
 dependencies:
   _fe_analyzer_shared: ^17.0.0
-  args: ^2.0.0
   cli_util: ^0.3.0
   collection: ^1.15.0
   convert: ^3.0.0
@@ -24,8 +23,9 @@
 dev_dependencies:
   analyzer_utilities:
     path: ../analyzer_utilities
+  args: ^2.0.0
   async: ^2.5.0
-#  linter: any
+  linter: any
   matcher: ^0.12.10
   pedantic: ^1.10.0
   test: ^1.16.0
diff --git a/pkg/analyzer/test/src/command_line/arguments_test.dart b/pkg/analyzer/test/src/command_line/arguments_test.dart
deleted file mode 100644
index 139dcda5..0000000
--- a/pkg/analyzer/test/src/command_line/arguments_test.dart
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/command_line/arguments.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:args/args.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ArgumentsTest);
-  });
-}
-
-@reflectiveTest
-class ArgumentsTest with ResourceProviderMixin {
-  void test_createContextBuilderOptions_all() {
-    String dartSdkSummaryPath = 'a';
-    String defaultAnalysisOptionsFilePath = 'b';
-    String defaultPackageFilePath = 'c';
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [
-      '--dart-sdk-summary=$dartSdkSummaryPath',
-      '-Dfoo=1',
-      '-Dbar=2',
-      '--no-implicit-casts',
-      '--no-implicit-dynamic',
-      '--options=$defaultAnalysisOptionsFilePath',
-      '--packages=$defaultPackageFilePath',
-    ];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-
-    expect(
-      options.defaultAnalysisOptionsFilePath,
-      endsWith(defaultAnalysisOptionsFilePath),
-    );
-    expect(
-      options.defaultPackageFilePath,
-      endsWith(defaultPackageFilePath),
-    );
-    expect(
-      options.dartSdkSummaryPath,
-      endsWith(dartSdkSummaryPath),
-    );
-
-    var declaredVariables = options.declaredVariables;
-    expect(declaredVariables, hasLength(2));
-    expect(declaredVariables['foo'], '1');
-    expect(declaredVariables['bar'], '2');
-
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, false);
-    expect(defaultOptions.implicitDynamic, false);
-  }
-
-  void test_createContextBuilderOptions_none() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-    expect(options.dartSdkSummaryPath, isNull);
-    expect(options.declaredVariables, isEmpty);
-    expect(options.defaultAnalysisOptionsFilePath, isNull);
-    expect(options.defaultPackageFilePath, isNull);
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, true);
-    expect(defaultOptions.implicitDynamic, true);
-  }
-
-  void test_defineAnalysisArguments() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    expect(parser.options, hasLength(12));
-  }
-
-  void test_extractDefinedVariables() {
-    List<String> args = ['--a', '-Dbaz', 'go', '-Dc=d', 'e=f', '-Dy=', '-Dx'];
-    Map<String, String> definedVariables = {'one': 'two'};
-    args = extractDefinedVariables(args, definedVariables);
-    expect(args, orderedEquals(['--a', 'e=f', '-Dx']));
-    expect(definedVariables['one'], 'two');
-    expect(definedVariables['two'], isNull);
-    expect(definedVariables['baz'], 'go');
-    expect(definedVariables['go'], isNull);
-    expect(definedVariables['c'], 'd');
-    expect(definedVariables['d'], isNull);
-    expect(definedVariables['y'], '');
-    expect(definedVariables, hasLength(4));
-  }
-
-  void test_filterUnknownArguments() {
-    List<String> args = ['--a', '--b', '--c=0', '--d=1', '-e=2', '-f', 'bar'];
-    ArgParser parser = ArgParser();
-    parser.addFlag('a');
-    parser.addOption('c');
-    parser.addOption('ee', abbr: 'e');
-    parser.addFlag('ff', abbr: 'f');
-    List<String> result = filterUnknownArguments(args, parser);
-    expect(result, orderedEquals(['--a', '--c=0', '-e=2', '-f', 'bar']));
-  }
-
-  void test_implicitCast() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [
-      '--implicit-casts',
-    ];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, true);
-  }
-
-  void test_noImplicitCast() {
-    ArgParser parser = ArgParser();
-    defineAnalysisArguments(parser);
-    List<String> args = [
-      '--no-implicit-casts',
-    ];
-    ArgResults result = parse(resourceProvider, parser, args);
-    ContextBuilderOptions options =
-        createContextBuilderOptions(resourceProvider, result);
-    expect(options, isNotNull);
-    var defaultOptions = options.defaultOptions as AnalysisOptionsImpl;
-    expect(defaultOptions, isNotNull);
-    expect(defaultOptions.implicitCasts, false);
-  }
-
-  void test_parse_noReplacement_noIgnored() {
-    ArgParser parser = ArgParser();
-    parser.addFlag('xx');
-    parser.addOption('yy');
-    List<String> args = ['--xx', '--yy=abc', 'foo', 'bar'];
-    ArgResults result = parse(resourceProvider, parser, args);
-    expect(result, isNotNull);
-    expect(result['xx'], true);
-    expect(result['yy'], 'abc');
-    expect(result.rest, orderedEquals(['foo', 'bar']));
-  }
-
-  void test_preprocessArgs_noReplacement() {
-    List<String> original = ['--xx' '--yy' 'baz'];
-    List<String> result = preprocessArgs(resourceProvider, original);
-    expect(result, orderedEquals(original));
-    expect(identical(original, result), isFalse);
-  }
-
-  void test_preprocessArgs_replacement_exists() {
-    String filePath = convertPath('/args.txt');
-    newFile(filePath, content: '''
--a
---xx
-
-foo
-bar
-''');
-    List<String> result =
-        preprocessArgs(resourceProvider, ['--preserved', '@$filePath']);
-    expect(result, orderedEquals(['--preserved', '-a', '--xx', 'foo', 'bar']));
-  }
-
-  void test_preprocessArgs_replacement_nonexistent() {
-    String filePath = convertPath('/args.txt');
-    List<String> args = ['ignored', '@$filePath'];
-    try {
-      preprocessArgs(resourceProvider, args);
-      fail('Expect exception');
-    } on Exception catch (e) {
-      expect(e.toString(), contains('Failed to read file'));
-      expect(e.toString(), contains('@$filePath'));
-    }
-  }
-
-  void test_preprocessArgs_replacement_notLast() {
-    String filePath = convertPath('/args.txt');
-    List<String> args = ['a', '@$filePath', 'b'];
-    List<String> result = preprocessArgs(resourceProvider, args);
-    expect(result, orderedEquals(args));
-  }
-}
diff --git a/pkg/analyzer/test/src/command_line/test_all.dart b/pkg/analyzer/test/src/command_line/test_all.dart
deleted file mode 100644
index a4c4e71..0000000
--- a/pkg/analyzer/test/src/command_line/test_all.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'arguments_test.dart' as arguments_test;
-
-main() {
-  defineReflectiveSuite(() {
-    arguments_test.main();
-  }, name: 'command_line');
-}
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 55fb085..bd4a9fe 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -3,18 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/context/packages.dart';
 import 'package:analyzer/src/context/source.dart';
-import 'package:analyzer/src/dart/error/lint_codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/lint/linter.dart';
-import 'package:analyzer/src/lint/registry.dart';
-import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
@@ -24,7 +19,6 @@
 import 'package:analyzer/src/workspace/package_build.dart';
 import 'package:analyzer/src/workspace/pub.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
-import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -56,11 +50,6 @@
   /// invoked [createDefaultSdk].
   late final String defaultSdkPath;
 
-  late final _MockLintRule _mockLintRule;
-  late final _MockLintRule _mockLintRule2;
-  late final _MockLintRule _mockLintRule3;
-  late final _MockLintRule _mockPublicMemberApiDocs;
-
   Uri convertedDirectoryUri(String directoryPath) {
     return Uri.directory(convertPath(directoryPath),
         windows: resourceProvider.pathContext.style == path.windows.style);
@@ -88,98 +77,6 @@
     fail('Incomplete test');
   }
 
-  void test_cmdline_lint_defined() {
-    _defineMockLintRules();
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse(['--$lintsFlag']);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = <LintRule>[
-      Registry.ruleRegistry['mock_lint_rule']!,
-    ];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_cmdline_lint_off() {
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse(['--no-$lintsFlag']);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = false;
-    expected.lintRules = <LintRule>[
-      Registry.ruleRegistry['mock_lint_rule']!,
-    ];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_cmdline_lint_unspecified_1() {
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse([]);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = <LintRule>[
-      Registry.ruleRegistry['mock_lint_rule']!,
-    ];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_cmdline_lint_unspecified_2() {
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse([]);
-    var builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(resourceProvider, argResults));
-
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = false;
-    expected.lintRules = <LintRule>[];
-
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
   @failingTest
   void test_cmdline_options_override_options_file() {
     fail('No clear choice of option to override.');
@@ -205,21 +102,6 @@
 //    _expectEqualOptions(options, expected);
   }
 
-  void test_createDefaultOptions_default() {
-    // Invert a subset of the options to ensure that the default options are
-    // being returned.
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    defaultOptions.implicitCasts = !defaultOptions.implicitCasts;
-    builderOptions.defaultOptions = defaultOptions;
-    var options = builder.createDefaultOptions();
-    _expectEqualOptions(options, defaultOptions);
-  }
-
-  void test_createDefaultOptions_noDefault() {
-    var options = builder.createDefaultOptions();
-    _expectEqualOptions(options, AnalysisOptionsImpl());
-  }
-
   void test_createPackageMap_fromPackageFile_explicit() {
     // Use a package file that is outside the project directory's hierarchy.
     String rootPath = convertPath('/root');
@@ -484,49 +366,12 @@
     expect(htmlSource.exists(), isTrue);
   }
 
-  void test_getAnalysisOptions_default_noOverrides() {
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    builderOptions.defaultOptions = defaultOptions;
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - non_existent_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_getAnalysisOptions_default_overrides() {
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    defaultOptions.implicitDynamic = true;
-    builderOptions.defaultOptions = defaultOptions;
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.implicitDynamic = false;
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-analyzer:
-  strong-mode:
-    implicit-dynamic: false
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
   void test_getAnalysisOptions_gnWorkspace() {
-    String _p(String path) => convertPath(path);
-    String projectPath = _p('/workspace/some/path');
+    String projectPath = convertPath('/workspace/some/path');
     newFolder('/workspace/.jiri_root');
     newFile('/workspace/out/debug/gen/dart.sources/foo_pkg',
-        content: _p('/workspace/foo_pkg/lib'));
+        content: convertPath('/workspace/foo_pkg/lib'));
     newFolder(projectPath);
-    ArgParser argParser = ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse([]);
-    builderOptions = createContextBuilderOptions(resourceProvider, argResults);
     builder = ContextBuilder(resourceProvider, sdkManager, contentCache,
         options: builderOptions);
     AnalysisOptionsImpl expected = AnalysisOptionsImpl();
@@ -534,43 +379,6 @@
     _expectEqualOptions(options, expected);
   }
 
-  void test_getAnalysisOptions_includes() {
-    _defineMockLintRules();
-    AnalysisOptionsImpl defaultOptions = AnalysisOptionsImpl();
-    builderOptions.defaultOptions = defaultOptions;
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = <Linter>[
-      _mockLintRule,
-      _mockLintRule2,
-      _mockLintRule3
-    ];
-    newFile('/mypkgs/somepkg/lib/here.yaml', content: '''
-linter:
-  rules:
-    - mock_lint_rule3
-''');
-    String path = convertPath('/some/directory/path');
-    newFile(join(path, '.packages'), content: '''
-somepkg:../../../mypkgs/somepkg/lib
-''');
-    newFile(join(path, 'bar.yaml'), content: '''
-include: package:somepkg/here.yaml
-linter:
-  rules:
-    - mock_lint_rule2
-''');
-    newAnalysisOptionsYamlFile(path, content: '''
-include: bar.yaml
-linter:
-  rules:
-    - mock_lint_rule
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
   void test_getAnalysisOptions_invalid() {
     String path = convertPath('/some/directory/path');
     newAnalysisOptionsYamlFile(path, content: ';');
@@ -591,34 +399,6 @@
     _expectEqualOptions(options, AnalysisOptionsImpl());
   }
 
-  void test_getAnalysisOptions_noDefault_overrides() {
-    AnalysisOptionsImpl expected = AnalysisOptionsImpl();
-    expected.implicitDynamic = false;
-    String path = convertPath('/some/directory/path');
-    newAnalysisOptionsYamlFile(path, content: '''
-analyzer:
-  strong-mode:
-    implicit-dynamic: false
-''');
-
-    var options = _getAnalysisOptions(builder, path);
-    _expectEqualOptions(options, expected);
-  }
-
-  void test_getAnalysisOptions_optionsPath() {
-    String path = convertPath('/some/directory/path');
-    String filePath = newAnalysisOptionsYamlFile(path, content: '''
-linter:
-  rules:
-    - empty_constructor_bodies
-''').path;
-
-    ContextRoot root =
-        ContextRoot(path, [], pathContext: resourceProvider.pathContext);
-    _getAnalysisOptions(builder, path, contextRoot: root);
-    expect(root.optionsFilePath, filePath);
-  }
-
   void test_getAnalysisOptions_sdkVersionConstraint() {
     var projectPath = convertPath('/test');
     newPubspecYamlFile(projectPath, '''
@@ -636,36 +416,6 @@
     expect(options.sdkVersionConstraint, isNull);
   }
 
-  void test_getOptionsFile_explicit() {
-    String path = convertPath('/some/directory/path');
-    String filePath = convertPath('/options/analysis.yaml');
-    newFile(filePath);
-
-    builderOptions.defaultAnalysisOptionsFilePath = filePath;
-    var result = builder.getOptionsFile(path)!;
-    expect(result, isNotNull);
-    expect(result.path, filePath);
-  }
-
-  void test_getOptionsFile_inParentOfRoot_new() {
-    String parentPath = convertPath('/some/directory');
-    String path = join(parentPath, 'path');
-    String filePath = newAnalysisOptionsYamlFile(path).path;
-
-    var result = builder.getOptionsFile(path)!;
-    expect(result, isNotNull);
-    expect(result.path, filePath);
-  }
-
-  void test_getOptionsFile_inRoot_new() {
-    String path = convertPath('/some/directory/path');
-    String filePath = newAnalysisOptionsYamlFile(path).path;
-
-    var result = builder.getOptionsFile(path)!;
-    expect(result, isNotNull);
-    expect(result.path, filePath);
-  }
-
   void _assertPackages(Packages packages, Map<String, String> nameToPath) {
     expect(packages, isNotNull);
     expect(packages.packages, hasLength(nameToPath.length));
@@ -702,17 +452,6 @@
     );
   }
 
-  _defineMockLintRules() {
-    _mockLintRule = _MockLintRule('mock_lint_rule');
-    Registry.ruleRegistry.register(_mockLintRule);
-    _mockLintRule2 = _MockLintRule('mock_lint_rule2');
-    Registry.ruleRegistry.register(_mockLintRule2);
-    _mockLintRule3 = _MockLintRule('mock_lint_rule3');
-    Registry.ruleRegistry.register(_mockLintRule3);
-    _mockPublicMemberApiDocs = _MockLintRule('public_member_api_docs');
-    Registry.ruleRegistry.register(_mockPublicMemberApiDocs);
-  }
-
   void _expectEqualOptions(
       AnalysisOptionsImpl actual, AnalysisOptionsImpl expected) {
     // TODO(brianwilkerson) Consider moving this to AnalysisOptionsImpl.==.
@@ -772,18 +511,3 @@
     expect(locator.embedderYamls, hasLength(1));
   }
 }
-
-class _MockLintRule implements LintRule {
-  final String _name;
-
-  _MockLintRule(this._name);
-
-  @override
-  List<LintCode> get lintCodes => [LintCode(_name, '')];
-
-  @override
-  String get name => _name;
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
index ba7dffe..d532b29 100644
--- a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
@@ -5,9 +5,12 @@
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:linter/src/rules.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../resolution/context_collection_resolution.dart';
+
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisContextCollectionTest);
@@ -18,6 +21,7 @@
 class AnalysisContextCollectionTest with ResourceProviderMixin {
   void setUp() {
     MockSdk(resourceProvider: resourceProvider);
+    registerLintRules();
   }
 
   test_contextFor_noContext() {
@@ -44,6 +48,59 @@
     );
   }
 
+  test_new_analysisOptions_includes() {
+    var rootFolder = newFolder('/home/test');
+    var fooFolder = newFolder('/home/packages/foo');
+    newFile('${fooFolder.path}/lib/included.yaml', content: r'''
+linter:
+  rules:
+    - empty_statements
+''');
+
+    var packageConfigFileBuilder = PackageConfigFileBuilder()
+      ..add(name: 'foo', rootPath: fooFolder.path);
+    newPackageConfigJsonFile(
+      rootFolder.path,
+      content: packageConfigFileBuilder.toContent(toUriStr: toUriStr),
+    );
+
+    newAnalysisOptionsYamlFile(rootFolder.path, content: r'''
+include: package:foo/included.yaml
+
+linter:
+  rules:
+    - unnecessary_parenthesis
+''');
+
+    var collection = _newCollection(includedPaths: [rootFolder.path]);
+    var analysisContext = collection.contextFor(rootFolder.path);
+    var analysisOptions = analysisContext.analysisOptions;
+
+    expect(
+      analysisOptions.lintRules.map((e) => e.name),
+      unorderedEquals(['empty_statements', 'unnecessary_parenthesis']),
+    );
+  }
+
+  test_new_analysisOptions_lintRules() {
+    var rootFolder = newFolder('/home/test');
+    newAnalysisOptionsYamlFile(rootFolder.path, content: r'''
+linter:
+  rules:
+    - non_existent_lint_rule
+    - unnecessary_parenthesis
+''');
+
+    var collection = _newCollection(includedPaths: [rootFolder.path]);
+    var analysisContext = collection.contextFor(rootFolder.path);
+    var analysisOptions = analysisContext.analysisOptions;
+
+    expect(
+      analysisOptions.lintRules.map((e) => e.name),
+      unorderedEquals(['unnecessary_parenthesis']),
+    );
+  }
+
   test_new_includedPaths_notAbsolute() {
     expect(
       () => AnalysisContextCollectionImpl(includedPaths: ['root']),
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index ea7e629..6b9f30f 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -39,7 +39,6 @@
   final List<ExceptionResult> allExceptions = <ExceptionResult>[];
 
   late final String testProject;
-  late final String testProject2;
   late final String testFile;
   late final String testCode;
 
@@ -139,7 +138,6 @@
   void setUp() {
     sdk = MockSdk(resourceProvider: resourceProvider);
     testProject = convertPath('/test');
-    testProject2 = convertPath('/test/lib');
     testFile = convertPath('/test/lib/test.dart');
     logger = PerformanceLog(logBuffer);
     scheduler = AnalysisDriverScheduler(logger);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
index 932abb8..736bc62 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_caching_test.dart
@@ -113,10 +113,14 @@
     _assertNoLinkedCycles();
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/linter/issues/2399')
   test_lints() async {
     useEmptyByteStore();
 
+    // Configure without any lint, but without experiments as well.
+    writeTestPackageAnalysisOptionsFile(
+      AnalysisOptionsFileConfig(lints: []),
+    );
+
     newFile(testFilePath, content: r'''
 void f() {
   ![0].isEmpty;
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index d2c3eaf..67ea722 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -14,8 +14,7 @@
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer/src/workspace/bazel.dart';
 import 'package:crypto/crypto.dart';
-
-// import 'package:linter/src/rules.dart';
+import 'package:linter/src/rules.dart';
 
 import '../resolution/resolution.dart';
 
@@ -78,7 +77,7 @@
   }
 
   void setUp() {
-    // registerLintRules();
+    registerLintRules();
 
     logger = PerformanceLog(logBuffer);
     sdk = MockSdk(resourceProvider: resourceProvider);
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 2b84c88..5decd67 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -296,7 +296,6 @@
     ]);
   }
 
-  @FailingTest(issue: 'https://github.com/dart-lang/linter/issues/2399')
   test_analysisOptions_lints() async {
     newFile('/workspace/dart/analysis_options/lib/default.yaml', content: r'''
 linter:
@@ -545,6 +544,81 @@
 ''');
   }
 
+  test_removeFilesNotNecessaryForAnalysisOf() async {
+    var aPath = convertPath('/workspace/dart/aaa/lib/a.dart');
+    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
+    var cPath = convertPath('/workspace/dart/aaa/lib/c.dart');
+
+    newFile(aPath, content: r'''
+class A {}
+''');
+
+    newFile(bPath, content: r'''
+import 'a.dart';
+''');
+
+    newFile(cPath, content: r'''
+import 'a.dart';
+''');
+
+    await resolveFile(bPath);
+    await resolveFile(cPath);
+    fileResolver.removeFilesNotNecessaryForAnalysisOf([cPath]);
+    _assertRemovedPaths(unorderedEquals([bPath]));
+  }
+
+  test_removeFilesNotNecessaryForAnalysisOf_multiple() async {
+    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
+    var dPath = convertPath('/workspace/dart/aaa/lib/d.dart');
+    var ePath = convertPath('/workspace/dart/aaa/lib/e.dart');
+    var fPath = convertPath('/workspace/dart/aaa/lib/f.dart');
+
+    newFile('/workspace/dart/aaa/lib/a.dart', content: r'''
+class A {}
+''');
+
+    newFile(bPath, content: r'''
+class B {}
+''');
+
+    newFile('/workspace/dart/aaa/lib/c.dart', content: r'''
+class C {}
+''');
+
+    newFile(dPath, content: r'''
+import 'a.dart';
+''');
+
+    newFile(ePath, content: r'''
+import 'a.dart';
+import 'b.dart';
+''');
+
+    newFile(fPath, content: r'''
+import 'c.dart';
+ ''');
+
+    await resolveFile(dPath);
+    await resolveFile(ePath);
+    await resolveFile(fPath);
+    fileResolver.removeFilesNotNecessaryForAnalysisOf([dPath, fPath]);
+    _assertRemovedPaths(unorderedEquals([bPath, ePath]));
+  }
+
+  test_removeFilesNotNecessaryForAnalysisOf_unknown() async {
+    var aPath = convertPath('/workspace/dart/aaa/lib/a.dart');
+    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
+
+    newFile(aPath, content: r'''
+class A {}
+''');
+
+    await resolveFile(aPath);
+
+    fileResolver.removeFilesNotNecessaryForAnalysisOf([aPath, bPath]);
+    _assertRemovedPaths(isEmpty);
+  }
+
   test_resolve_part_of() async {
     newFile('/workspace/dart/test/lib/a.dart', content: r'''
 part 'test.dart';
@@ -683,64 +757,7 @@
     ]);
   }
 
-  test_unusedFiles() async {
-    var bPath = convertPath('/workspace/dart/aaa/lib/b.dart');
-    var cPath = convertPath('/workspace/dart/aaa/lib/c.dart');
-
-    newFile('/workspace/dart/aaa/lib/a.dart', content: r'''
-class A {}
-''');
-
-    newFile(bPath, content: r'''
-import 'a.dart';
-''');
-
-    newFile(cPath, content: r'''
-import 'a.dart';
-''');
-
-    await resolveFile(bPath);
-    await resolveFile(cPath);
-    fileResolver.removeFilesNotNecessaryForAnalysisOf([cPath]);
-    expect(fileResolver.fsState!.testView.unusedFiles.contains(bPath), true);
-    expect(fileResolver.fsState!.testView.unusedFiles.length, 1);
-  }
-
-  test_unusedFiles_mutilple() async {
-    var dPath = convertPath('/workspace/dart/aaa/lib/d.dart');
-    var ePath = convertPath('/workspace/dart/aaa/lib/e.dart');
-    var fPath = convertPath('/workspace/dart/aaa/lib/f.dart');
-
-    newFile('/workspace/dart/aaa/lib/a.dart', content: r'''
-class A {}
-''');
-
-    newFile('/workspace/dart/aaa/lib/b.dart', content: r'''
-class B {}
-''');
-
-    newFile('/workspace/dart/aaa/lib/c.dart', content: r'''
-class C {}
-''');
-
-    newFile(dPath, content: r'''
-import 'a.dart';
-''');
-
-    newFile(ePath, content: r'''
-import 'a.dart';
-import 'b.dart';
-''');
-
-    newFile(fPath, content: r'''
-import 'c.dart';
- ''');
-
-    await resolveFile(dPath);
-    await resolveFile(ePath);
-    await resolveFile(fPath);
-    fileResolver.removeFilesNotNecessaryForAnalysisOf([dPath, fPath]);
-    expect(fileResolver.fsState!.testView.unusedFiles.contains(ePath), true);
-    expect(fileResolver.fsState!.testView.unusedFiles.length, 2);
+  void _assertRemovedPaths(Matcher matcher) {
+    expect(fileResolver.fsState!.testView.removedPaths, matcher);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index 330c655..197e80e 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -21,7 +21,7 @@
 import 'package:analyzer/src/workspace/gn.dart';
 import 'package:analyzer/src/workspace/package_build.dart';
 import 'package:analyzer/src/workspace/pub.dart';
-// import 'package:linter/src/rules.dart';
+import 'package:linter/src/rules.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
@@ -189,7 +189,7 @@
   @mustCallSuper
   void setUp() {
     if (!_lintRulesAreRegistered) {
-      // registerLintRules();
+      registerLintRules();
       _lintRulesAreRegistered = true;
     }
 
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
index d07c28e..44ce6f8 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
@@ -37,15 +37,40 @@
 }''');
   }
 
-  test_invalid() async {
+  test_invalid_class() async {
     await assertErrorsInCode(r'''
-class A {
-}
+class A {}
+
 class B extends A {
   @override
-  int get m => 1;
-}''', [
-      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 54, 1),
+  int get foo => 1;
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 54, 3),
+    ]);
+  }
+
+  test_invalid_extension() async {
+    await assertErrorsInCode(r'''
+extension E on int {
+  @override
+  int get foo => 1;
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 43, 3),
+    ]);
+  }
+
+  test_invalid_mixin() async {
+    await assertErrorsInCode(r'''
+class A {}
+
+mixin M on A {
+  @override
+  int get foo => 1;
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER, 49, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
index 3720caa..2d47c68 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
@@ -64,15 +64,40 @@
 }''');
   }
 
-  test_invalid() async {
+  test_invalid_class() async {
     await assertErrorsInCode(r'''
-class A {
-}
+class A {}
+
 class B extends A {
   @override
-  int m() => 1;
-}''', [
-      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 50, 1),
+  void foo() {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 51, 3),
+    ]);
+  }
+
+  test_invalid_extension() async {
+    await assertErrorsInCode(r'''
+extension E on int {
+  @override
+  void foo() {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 40, 3),
+    ]);
+  }
+
+  test_invalid_mixin() async {
+    await assertErrorsInCode(r'''
+class A {}
+
+mixin M on A {
+  @override
+  void foo() {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD, 46, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
index b2f6683..ae370bf 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
@@ -37,15 +37,40 @@
 }''');
   }
 
-  test_invalid() async {
+  test_invalid_class() async {
     await assertErrorsInCode(r'''
-class A {
-}
+class A {}
+
 class B extends A {
   @override
-  set m(int x) {}
-}''', [
-      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 50, 1),
+  set foo(int _) {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 50, 3),
+    ]);
+  }
+
+  test_invalid_extension() async {
+    await assertErrorsInCode(r'''
+extension E on int {
+  @override
+  set foo(int _) {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 39, 3),
+    ]);
+  }
+
+  test_invalid_mixin() async {
+    await assertErrorsInCode(r'''
+class A {}
+
+mixin M on A {
+  @override
+  set foo(int _) {}
+}
+''', [
+      error(HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER, 45, 3),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
index b9ac11a..8cce111 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
@@ -138,6 +138,19 @@
 ''');
   }
 
+  test_as_systemLibrary() async {
+    newFile('$testPackageLibPath/a.dart', content: '''
+class File {}
+''');
+    await assertErrorsInCode(r'''
+import 'dart:io' as prefix;
+import 'a.dart' as prefix;
+prefix.File? f;
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 9),
+    ]);
+  }
+
   test_core_library() async {
     await assertNoErrorsInCode(r'''
 import 'dart:core';
@@ -429,6 +442,19 @@
     ]);
   }
 
+  test_systemLibrary() async {
+    newFile('$testPackageLibPath/lib1.dart', content: '''
+class File {}
+''');
+    await assertErrorsInCode(r'''
+import 'dart:io';
+import 'lib1.dart';
+File? f;
+''', [
+      error(HintCode.UNUSED_IMPORT, 7, 9),
+    ]);
+  }
+
   test_unusedImport() async {
     newFile('$testPackageLibPath/lib1.dart');
     await assertErrorsInCode(r'''
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index 02ae355..9969e39 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -4,7 +4,6 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'command_line/test_all.dart' as command_line;
 import 'context/test_all.dart' as context;
 import 'dart/test_all.dart' as dart;
 import 'dartdoc/test_all.dart' as dartdoc;
@@ -26,7 +25,6 @@
 
 main() {
   defineReflectiveSuite(() {
-    command_line.main();
     context.main();
     dart.main();
     dartdoc.main();
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index f5d7076..3d94108 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -5,14 +5,11 @@
 import 'dart:io' as io;
 import 'dart:isolate';
 
-import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/sdk/build_sdk_summary.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/command_line/arguments.dart'
-    show applyAnalysisOptionFlags;
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -43,7 +40,6 @@
 import 'package:linter/src/rules.dart' as linter;
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
-import 'package:pub_semver/pub_semver.dart';
 import 'package:yaml/yaml.dart';
 
 /// Shared IO sink for standard error reporting.
@@ -592,16 +588,6 @@
   }
 
   void _updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
-    var args = _commandLineOptions.contextBuilderOptions.argResults;
-    applyAnalysisOptionFlags(analysisOptions, args);
-
-    var defaultLanguageVersion = _commandLineOptions.defaultLanguageVersion;
-    if (defaultLanguageVersion != null) {
-      var nonPackageLanguageVersion =
-          Version.parse('$defaultLanguageVersion.0');
-      analysisOptions.nonPackageLanguageVersion = nonPackageLanguageVersion;
-      analysisOptions.nonPackageFeatureSet = FeatureSet.latestLanguageVersion()
-          .restrictToVersion(nonPackageLanguageVersion);
-    }
+    _commandLineOptions.updateAnalysisOptions(analysisOptions);
   }
 }
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index faba081..08897e3 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -4,18 +4,32 @@
 
 import 'dart:io' as io;
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/command_line/arguments.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer/src/util/sdk.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:args/args.dart';
+import 'package:pub_semver/pub_semver.dart';
 
+const _analysisOptionsFileOption = 'options';
 const _binaryName = 'dartanalyzer';
+const _defaultLanguageVersionOption = 'default-language-version';
+const _defineVariableOption = 'D';
+const _enableExperimentOption = 'enable-experiment';
+const _enableInitializingFormalAccessFlag = 'initializing-formal-access';
+const _ignoreUnrecognizedFlagsFlag = 'ignore-unrecognized-flags';
+const _implicitCastsFlag = 'implicit-casts';
+const _lintsFlag = 'lints';
+const _noImplicitDynamicFlag = 'no-implicit-dynamic';
+const _packagesOption = 'packages';
+const _sdkPathOption = 'dart-sdk';
+const _sdkSummaryPathOption = 'dart-sdk-summary';
 
 /// Shared exit handler.
 ///
@@ -37,6 +51,8 @@
 
 /// Analyzer commandline configuration options.
 class CommandLineOptions {
+  final ArgResults _argResults;
+
   /// The path to output analysis results when in build mode.
   final String buildAnalysisOutput;
 
@@ -71,10 +87,6 @@
   /// The path to the dart SDK summary file.
   final String dartSdkSummaryPath;
 
-  /// The default language version for files that are not in a package.
-  /// (Or null if no default language version to force.)
-  final String defaultLanguageVersion;
-
   /// Whether to disable cache flushing. This option can improve analysis
   /// speed at the expense of memory usage. It may also be useful for working
   /// around bugs.
@@ -86,15 +98,9 @@
   /// Whether to display version information
   final bool displayVersion;
 
-  /// A list of the names of the experiments that are to be enabled.
-  final List<String> enabledExperiments;
-
   /// Whether to ignore unrecognized flags
   final bool ignoreUnrecognizedFlags;
 
-  /// Whether to report lints
-  final bool lints;
-
   /// Whether to log additional analysis messages and exceptions
   final bool log;
 
@@ -148,7 +154,8 @@
   CommandLineOptions._fromArgs(
     ResourceProvider resourceProvider,
     ArgResults args,
-  )   : buildAnalysisOutput = cast(args['build-analysis-output']),
+  )   : _argResults = args,
+        buildAnalysisOutput = cast(args['build-analysis-output']),
         buildMode = cast(args['build-mode']),
         buildModePersistentWorker = cast(args['persistent_worker']),
         buildSummaryInputs =
@@ -158,20 +165,16 @@
         buildSummaryOutputSemantic =
             cast(args['build-summary-output-semantic']),
         buildSuppressExitCode = cast(args['build-suppress-exit-code']),
-        contextBuilderOptions = createContextBuilderOptions(
+        contextBuilderOptions = _createContextBuilderOptions(
           resourceProvider,
           args,
         ),
-        dartSdkPath = cast(args['dart-sdk']),
-        dartSdkSummaryPath = cast(args['dart-sdk-summary']),
-        defaultLanguageVersion = cast(args['default-language-version']),
+        dartSdkPath = cast(args[_sdkPathOption]),
+        dartSdkSummaryPath = cast(args[_sdkSummaryPathOption]),
         disableCacheFlushing = cast(args['disable-cache-flushing']),
         disableHints = cast(args['no-hints']),
         displayVersion = cast(args['version']),
-        enabledExperiments =
-            cast(args['enable-experiment'] ?? const <String>[]),
-        ignoreUnrecognizedFlags = cast(args['ignore-unrecognized-flags']),
-        lints = cast(args[lintsFlag]),
+        ignoreUnrecognizedFlags = cast(args[_ignoreUnrecognizedFlagsFlag]),
         log = cast(args['log']),
         machineFormat = args['format'] == 'machine',
         perfReport = cast(args['x-perf-report']),
@@ -194,10 +197,27 @@
   String get analysisOptionsFile =>
       contextBuilderOptions.defaultAnalysisOptionsFilePath;
 
+  /// The default language version for files that are not in a package.
+  /// (Or null if no default language version to force.)
+  String get defaultLanguageVersion {
+    return cast(_argResults[_defaultLanguageVersionOption]);
+  }
+
   /// A table mapping the names of defined variables to their values.
   Map<String, String> get definedVariables =>
       contextBuilderOptions.declaredVariables;
 
+  /// A list of the names of the experiments that are to be enabled.
+  List<String> get enabledExperiments {
+    return cast(_argResults[_enableExperimentOption]);
+  }
+
+  bool get implicitCasts => _argResults[_implicitCastsFlag] as bool;
+
+  bool get lints => _argResults[_lintsFlag] as bool;
+
+  bool get noImplicitDynamic => _argResults[_noImplicitDynamicFlag] as bool;
+
   /// The path to a `.packages` configuration file
   String get packageConfigPath => contextBuilderOptions.defaultPackageFilePath;
 
@@ -209,6 +229,99 @@
     _sourceFiles = newSourceFiles;
   }
 
+  /// Update the [analysisOptions] with flags that the user specified
+  /// explicitly. The [analysisOptions] are usually loaded from one of
+  /// `analysis_options.yaml` files, possibly with includes. We consider
+  /// flags that the user specified as command line options more important,
+  /// so override the corresponding options.
+  void updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
+    var defaultLanguageVersion = this.defaultLanguageVersion;
+    if (defaultLanguageVersion != null) {
+      var nonPackageLanguageVersion =
+          Version.parse('$defaultLanguageVersion.0');
+      analysisOptions.nonPackageLanguageVersion = nonPackageLanguageVersion;
+      analysisOptions.nonPackageFeatureSet = FeatureSet.latestLanguageVersion()
+          .restrictToVersion(nonPackageLanguageVersion);
+    }
+
+    var enabledExperiments = this.enabledExperiments;
+    if (enabledExperiments.isNotEmpty) {
+      analysisOptions.contextFeatures = FeatureSet.fromEnableFlags2(
+        sdkLanguageVersion: ExperimentStatus.currentVersion,
+        flags: enabledExperiments,
+      );
+    }
+
+    var implicitCasts = this.implicitCasts;
+    if (implicitCasts != null) {
+      analysisOptions.implicitCasts = implicitCasts;
+    }
+
+    var lints = this.lints;
+    if (lints != null) {
+      analysisOptions.lint = lints;
+    }
+
+    var noImplicitDynamic = this.noImplicitDynamic;
+    if (noImplicitDynamic != null) {
+      analysisOptions.implicitDynamic = !noImplicitDynamic;
+    }
+  }
+
+  /// Return a list of command-line arguments containing all of the given [args]
+  /// that are defined by the given [parser]. An argument is considered to be
+  /// defined by the parser if
+  /// - it starts with '--' and the rest of the argument (minus any value
+  ///   introduced by '=') is the name of a known option,
+  /// - it starts with '-' and the rest of the argument (minus any value
+  ///   introduced by '=') is the name of a known abbreviation, or
+  /// - it starts with something other than '--' or '-'.
+  ///
+  /// This function allows command-line tools to implement the
+  /// '--ignore-unrecognized-flags' option.
+  static List<String> filterUnknownArguments(
+      List<String> args, ArgParser parser) {
+    var knownOptions = <String>{};
+    var knownAbbreviations = <String>{};
+    parser.options.forEach((String name, Option option) {
+      knownOptions.add(name);
+      var abbreviation = option.abbr;
+      if (abbreviation != null) {
+        knownAbbreviations.add(abbreviation);
+      }
+      if (option.negatable ?? false) {
+        knownOptions.add('no-$name');
+      }
+    });
+    String optionName(int prefixLength, String argument) {
+      var equalsOffset = argument.lastIndexOf('=');
+      if (equalsOffset < 0) {
+        return argument.substring(prefixLength);
+      }
+      return argument.substring(prefixLength, equalsOffset);
+    }
+
+    var filtered = <String>[];
+    for (var i = 0; i < args.length; i++) {
+      var argument = args[i];
+      if (argument.startsWith('--') && argument.length > 2) {
+        if (knownOptions.contains(optionName(2, argument))) {
+          filtered.add(argument);
+        }
+      } else if (argument.startsWith('-D') && argument.indexOf('=') > 0) {
+        filtered.add(argument);
+      }
+      if (argument.startsWith('-') && argument.length > 1) {
+        if (knownAbbreviations.contains(optionName(1, argument))) {
+          filtered.add(argument);
+        }
+      } else {
+        filtered.add(argument);
+      }
+    }
+    return filtered;
+  }
+
   /// Parse [args] into [CommandLineOptions] describing the specified
   /// analyzer options. In case of a format error, calls [printAndFail], which
   /// by default prints an error message to stderr and exits.
@@ -267,6 +380,156 @@
     return options;
   }
 
+  /// Preprocess the given list of command line [args].
+  /// If the final arg is `@file_path` (Bazel worker mode),
+  /// then read in all the lines of that file and add those as args.
+  /// Always returns a new modifiable list.
+  static List<String> preprocessArgs(
+      ResourceProvider provider, List<String> args) {
+    args = List.from(args);
+    if (args.isEmpty) {
+      return args;
+    }
+    var lastArg = args.last;
+    if (lastArg.startsWith('@')) {
+      var argsFile = provider.getFile(lastArg.substring(1));
+      try {
+        args.removeLast();
+        args.addAll(argsFile
+            .readAsStringSync()
+            .replaceAll('\r\n', '\n')
+            .replaceAll('\r', '\n')
+            .split('\n')
+            .where((String line) => line.isNotEmpty));
+      } on FileSystemException catch (e) {
+        throw Exception('Failed to read file specified by $lastArg : $e');
+      }
+    }
+    return args;
+  }
+
+  /// Use the command-line [args] to create a context builder options.
+  static ContextBuilderOptions _createContextBuilderOptions(
+    ResourceProvider resourceProvider,
+    ArgResults args,
+  ) {
+    String absoluteNormalizedPath(String path) {
+      if (path == null) {
+        return null;
+      }
+      var pathContext = resourceProvider.pathContext;
+      return pathContext.normalize(
+        pathContext.absolute(path),
+      );
+    }
+
+    var builderOptions = ContextBuilderOptions();
+
+    //
+    // File locations.
+    //
+    builderOptions.dartSdkSummaryPath = absoluteNormalizedPath(
+      cast(args[_sdkSummaryPathOption]),
+    );
+    builderOptions.defaultAnalysisOptionsFilePath = absoluteNormalizedPath(
+      cast(args[_analysisOptionsFileOption]),
+    );
+    builderOptions.defaultPackageFilePath = absoluteNormalizedPath(
+      cast(args[_packagesOption]),
+    );
+    //
+    // Declared variables.
+    //
+    var declaredVariables = <String, String>{};
+    var variables = (args[_defineVariableOption] as List).cast<String>();
+    for (var variable in variables) {
+      var index = variable.indexOf('=');
+      if (index < 0) {
+        // TODO (brianwilkerson) Decide the semantics we want in this case.
+        // The VM prints "No value given to -D option", then tries to load '-Dfoo'
+        // as a file and dies. Unless there was nothing after the '-D', in which
+        // case it prints the warning and ignores the option.
+      } else {
+        var name = variable.substring(0, index);
+        if (name.isNotEmpty) {
+          // TODO (brianwilkerson) Decide the semantics we want in the case where
+          // there is no name. If there is no name, the VM tries to load a file
+          // named '-D' and dies.
+          declaredVariables[name] = variable.substring(index + 1);
+        }
+      }
+    }
+    builderOptions.declaredVariables = declaredVariables;
+
+    return builderOptions;
+  }
+
+  /// Add the standard flags and options to the given [parser]. The standard flags
+  /// are those that are typically used to control the way in which the code is
+  /// analyzed.
+  ///
+  /// TODO(danrubel) Update DDC to support all the options defined in this method
+  /// then remove the [ddc] named argument from this method.
+  static void _defineAnalysisArguments(ArgParser parser,
+      {bool hide = true, bool ddc = false}) {
+    parser.addOption(_sdkPathOption,
+        help: 'The path to the Dart SDK.', hide: ddc && hide);
+    parser.addOption(_analysisOptionsFileOption,
+        help: 'Path to an analysis options file.', hide: ddc && hide);
+    parser.addFlag('strong',
+        help: 'Enable strong mode (deprecated); this option is now ignored.',
+        defaultsTo: true,
+        hide: true,
+        negatable: true);
+    parser.addFlag('declaration-casts',
+        negatable: true,
+        help:
+            'Disable declaration casts in strong mode (https://goo.gl/cTLz40)\n'
+            'This option is now ignored and will be removed in a future release.',
+        hide: ddc && hide);
+    parser.addMultiOption(_enableExperimentOption,
+        help: 'Enable one or more experimental features. If multiple features '
+            'are being added, they should be comma separated.',
+        splitCommas: true);
+    parser.addFlag(_implicitCastsFlag,
+        negatable: true,
+        help: 'Disable implicit casts in strong mode (https://goo.gl/cTLz40).',
+        defaultsTo: null,
+        hide: ddc && hide);
+    parser.addFlag(_noImplicitDynamicFlag,
+        defaultsTo: null,
+        negatable: false,
+        help: 'Disable implicit dynamic (https://goo.gl/m0UgXD).',
+        hide: ddc && hide);
+
+    //
+    // Hidden flags and options.
+    //
+    parser.addMultiOption(_defineVariableOption,
+        abbr: 'D',
+        help:
+            'Define an environment declaration. For example, "-Dfoo=bar" defines '
+            'an environment declaration named "foo" whose value is "bar".',
+        hide: hide);
+    parser.addOption(_packagesOption,
+        help: 'The path to the package resolution configuration file, which '
+            'supplies a mapping of package names\nto paths.',
+        hide: ddc);
+    parser.addOption(_sdkSummaryPathOption,
+        help: 'The path to the Dart SDK summary file.', hide: hide);
+    parser.addFlag(_enableInitializingFormalAccessFlag,
+        help:
+            'Enable support for allowing access to field formal parameters in a '
+            'constructor\'s initializer list (deprecated).',
+        defaultsTo: false,
+        negatable: false,
+        hide: hide || ddc);
+    if (!ddc) {
+      parser.addFlag(_lintsFlag,
+          help: 'Show lint results.', defaultsTo: null, negatable: true);
+    }
+  }
+
   static String _getVersion() {
     try {
       // This is relative to bin/snapshot, so ../..
@@ -298,7 +561,7 @@
     // TODO(devoncarew): This defines some hidden flags, which would be better
     // defined with the rest of the hidden flags below (to group well with the
     // other flags).
-    defineAnalysisArguments(parser, hide: hide);
+    _defineAnalysisArguments(parser, hide: hide);
 
     parser
       ..addOption('format',
@@ -392,12 +655,12 @@
           defaultsTo: false,
           negatable: false,
           hide: hide)
-      ..addFlag(ignoreUnrecognizedFlagsFlag,
+      ..addFlag(_ignoreUnrecognizedFlagsFlag,
           help: 'Ignore unrecognized command line flags.',
           defaultsTo: false,
           negatable: false,
           hide: hide)
-      ..addOption('default-language-version',
+      ..addOption(_defaultLanguageVersionOption,
           help: 'The default language version when it is not specified via '
               'other ways (internal, tests only).',
           hide: false)
@@ -468,7 +731,7 @@
           negatable: false);
 
     try {
-      if (args.contains('--$ignoreUnrecognizedFlagsFlag')) {
+      if (args.contains('--$_ignoreUnrecognizedFlagsFlag')) {
         args = filterUnknownArguments(args, parser);
       }
       var results = parser.parse(args);
@@ -528,9 +791,9 @@
             'Note: the --strong flag is deprecated and will be removed in an '
             'future release.\n');
       }
-      if (results.wasParsed('enable-experiment')) {
+      if (results.wasParsed(_enableExperimentOption)) {
         var names =
-            (results['enable-experiment'] as List).cast<String>().toList();
+            (results[_enableExperimentOption] as List).cast<String>().toList();
         var errorFound = false;
         for (var validationResult in validateFlags(names)) {
           if (validationResult.isError) {
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 12ff74c..3085269 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -4,12 +4,17 @@
 
 import 'dart:io';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/experiments_impl.dart'
     show overrideKnownFeatures;
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/options.dart';
+import 'package:args/args.dart';
+import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -61,12 +66,14 @@
         expect(options.disableCacheFlushing, isFalse);
         expect(options.disableHints, isFalse);
         expect(options.enabledExperiments, isEmpty);
-        expect(options.lints, isFalse);
+        expect(options.lints, isNull);
         expect(options.displayVersion, isFalse);
         expect(options.infosAreFatal, isFalse);
         expect(options.ignoreUnrecognizedFlags, isFalse);
+        expect(options.implicitCasts, isNull);
         expect(options.log, isFalse);
         expect(options.machineFormat, isFalse);
+        expect(options.noImplicitDynamic, isNull);
         expect(options.batchMode, isFalse);
         expect(options.showPackageWarnings, isFalse);
         expect(options.showSdkWarnings, isFalse);
@@ -297,6 +304,360 @@
 }
 
 @reflectiveTest
+class ArgumentsTest with ResourceProviderMixin {
+  CommandLineOptions commandLineOptions;
+  String failureMessage;
+
+  void test_dartSdkSummaryPath() {
+    var expected = 'my_sdk.summary';
+    _parse(['--dart-sdk-summary=$expected', 'a.dart']);
+
+    var builderOptions = commandLineOptions.contextBuilderOptions;
+    expect(
+      builderOptions.dartSdkSummaryPath,
+      endsWith(expected),
+    );
+  }
+
+  void test_declaredVariables() {
+    _parse(['-Da=0', '-Db=', 'a.dart']);
+
+    var options = commandLineOptions.contextBuilderOptions;
+    var definedVariables = options.declaredVariables;
+
+    expect(definedVariables['a'], '0');
+    expect(definedVariables['b'], '');
+    expect(definedVariables['c'], isNull);
+  }
+
+  void test_defaultAnalysisOptionsFilePath() {
+    var expected = 'my_options.yaml';
+    _parse(['--options=$expected', 'a.dart']);
+
+    var builderOptions = commandLineOptions.contextBuilderOptions;
+    expect(
+      builderOptions.defaultAnalysisOptionsFilePath,
+      endsWith(expected),
+    );
+  }
+
+  void test_defaultPackageFilePath() {
+    var expected = 'my_package_config.json';
+    _parse(['--packages=$expected', 'a.dart']);
+
+    var builderOptions = commandLineOptions.contextBuilderOptions;
+    expect(
+      builderOptions.defaultPackageFilePath,
+      endsWith(expected),
+    );
+  }
+
+  void test_defaults() {
+    _parse(['a.dart']);
+    var builderOptions = commandLineOptions.contextBuilderOptions;
+    expect(builderOptions, isNotNull);
+    expect(builderOptions.dartSdkSummaryPath, isNull);
+    expect(builderOptions.declaredVariables, isEmpty);
+    expect(builderOptions.defaultAnalysisOptionsFilePath, isNull);
+    expect(builderOptions.defaultPackageFilePath, isNull);
+  }
+
+  void test_filterUnknownArguments() {
+    var args = ['--a', '--b', '--c=0', '--d=1', '-Da=b', '-e=2', '-f', 'bar'];
+    var parser = ArgParser();
+    parser.addFlag('a');
+    parser.addOption('c');
+    parser.addOption('ee', abbr: 'e');
+    parser.addFlag('ff', abbr: 'f');
+    var result = CommandLineOptions.filterUnknownArguments(args, parser);
+    expect(
+      result,
+      orderedEquals(['--a', '--c=0', '-Da=b', '-e=2', '-f', 'bar']),
+    );
+  }
+
+  void test_preprocessArgs_noReplacement() {
+    var original = <String>['--xx' '--yy' 'baz'];
+    var result = CommandLineOptions.preprocessArgs(resourceProvider, original);
+    expect(result, orderedEquals(original));
+    expect(identical(original, result), isFalse);
+  }
+
+  void test_preprocessArgs_replacement_exists() {
+    var filePath = convertPath('/args.txt');
+    newFile(filePath, content: '''
+-a
+--xx
+
+foo
+bar
+''');
+    var result = CommandLineOptions.preprocessArgs(
+        resourceProvider, ['--preserved', '@$filePath']);
+    expect(result, orderedEquals(['--preserved', '-a', '--xx', 'foo', 'bar']));
+  }
+
+  void test_preprocessArgs_replacement_nonexistent() {
+    var filePath = convertPath('/args.txt');
+    var args = <String>['ignored', '@$filePath'];
+    try {
+      CommandLineOptions.preprocessArgs(resourceProvider, args);
+      fail('Expect exception');
+    } on Exception catch (e) {
+      expect(e.toString(), contains('Failed to read file'));
+      expect(e.toString(), contains('@$filePath'));
+    }
+  }
+
+  void test_preprocessArgs_replacement_notLast() {
+    var filePath = convertPath('/args.txt');
+    var args = <String>['a', '@$filePath', 'b'];
+    var result = CommandLineOptions.preprocessArgs(resourceProvider, args);
+    expect(result, orderedEquals(args));
+  }
+
+  void test_updateAnalysisOptions_defaultLanguageVersion() {
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {},
+      (analysisOptions) {
+        expect(
+          analysisOptions.nonPackageLanguageVersion,
+          ExperimentStatus.currentVersion,
+        );
+        var featureSet = analysisOptions.nonPackageFeatureSet;
+        expect(featureSet.isEnabled(Feature.non_nullable), isTrue);
+      },
+    );
+
+    _applyAnalysisOptions(
+      ['--default-language-version=2.7', 'a.dart'],
+      (analysisOptions) {},
+      (analysisOptions) {
+        expect(
+          analysisOptions.nonPackageLanguageVersion,
+          Version.parse('2.7.0'),
+        );
+        var featureSet = analysisOptions.nonPackageFeatureSet;
+        expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
+      },
+    );
+  }
+
+  void test_updateAnalysisOptions_enableExperiment() {
+    var feature_a = ExperimentalFeature(
+      index: 0,
+      enableString: 'a',
+      isEnabledByDefault: false,
+      isExpired: false,
+      documentation: 'a',
+      experimentalReleaseVersion: null,
+      releaseVersion: null,
+    );
+
+    var feature_b = ExperimentalFeature(
+      index: 1,
+      enableString: 'a',
+      isEnabledByDefault: false,
+      isExpired: false,
+      documentation: 'a',
+      experimentalReleaseVersion: null,
+      releaseVersion: null,
+    );
+
+    FeatureSet featuresWithExperiments(List<String> experiments) {
+      return FeatureSet.fromEnableFlags2(
+        sdkLanguageVersion: ExperimentStatus.currentVersion,
+        flags: experiments,
+      );
+    }
+
+    overrideKnownFeatures({'a': feature_a, 'b': feature_b}, () {
+      // Replace.
+      _applyAnalysisOptions(
+        ['--enable-experiment=b', 'a.dart'],
+        (analysisOptions) {
+          analysisOptions.contextFeatures = featuresWithExperiments(['a']);
+        },
+        (analysisOptions) {
+          var featureSet = analysisOptions.contextFeatures;
+          expect(featureSet.isEnabled(feature_a), isFalse);
+          expect(featureSet.isEnabled(feature_b), isTrue);
+        },
+      );
+
+      // Don't change if not provided.
+      _applyAnalysisOptions(
+        ['a.dart'],
+        (analysisOptions) {
+          analysisOptions.contextFeatures = featuresWithExperiments(['a']);
+        },
+        (analysisOptions) {
+          var featureSet = analysisOptions.contextFeatures;
+          expect(featureSet.isEnabled(feature_a), isTrue);
+          expect(featureSet.isEnabled(feature_b), isFalse);
+        },
+      );
+    });
+  }
+
+  void test_updateAnalysisOptions_implicitCasts() {
+    // Turn on.
+    _applyAnalysisOptions(
+      ['--implicit-casts', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isTrue);
+      },
+    );
+
+    // Turn off.
+    _applyAnalysisOptions(
+      ['--no-implicit-casts', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isFalse);
+      },
+    );
+
+    // Don't change if not provided, false.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isFalse);
+      },
+    );
+
+    // Don't change if not provided, true.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitCasts = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitCasts, isTrue);
+      },
+    );
+  }
+
+  void test_updateAnalysisOptions_lints() {
+    // Turn lints on.
+    _applyAnalysisOptions(
+      ['--lints', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isTrue);
+      },
+    );
+
+    // Turn lints off.
+    _applyAnalysisOptions(
+      ['--no-lints', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isFalse);
+      },
+    );
+
+    // Don't change if not provided, false.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isFalse);
+      },
+    );
+
+    // Don't change if not provided, true.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.lint = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.lint, isTrue);
+      },
+    );
+  }
+
+  void test_updateAnalysisOptions_noImplicitDynamic() {
+    _applyAnalysisOptions(
+      ['--no-implicit-dynamic', 'a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitDynamic = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitDynamic, isFalse);
+      },
+    );
+
+    // Don't change if not provided, false.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitDynamic = false;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitDynamic, isFalse);
+      },
+    );
+
+    // Don't change if not provided, true.
+    _applyAnalysisOptions(
+      ['a.dart'],
+      (analysisOptions) {
+        analysisOptions.implicitDynamic = true;
+      },
+      (analysisOptions) {
+        expect(analysisOptions.implicitDynamic, isTrue);
+      },
+    );
+  }
+
+  void _applyAnalysisOptions(
+    List<String> args,
+    void Function(AnalysisOptionsImpl) configureInitial,
+    void Function(AnalysisOptionsImpl) checkApplied,
+  ) {
+    _parse(args);
+    expect(commandLineOptions, isNotNull);
+
+    var analysisOptions = AnalysisOptionsImpl();
+    configureInitial(analysisOptions);
+
+    commandLineOptions.updateAnalysisOptions(analysisOptions);
+    checkApplied(analysisOptions);
+  }
+
+  void _parse(List<String> args, {bool ignoreUnrecognized = true}) {
+    var resourceProvider = PhysicalResourceProvider.INSTANCE;
+    commandLineOptions = CommandLineOptions.parse(
+      resourceProvider,
+      [
+        if (ignoreUnrecognized) '--ignore-unrecognized-flags',
+        ...args,
+      ],
+      printAndFail: (msg) {
+        failureMessage = msg;
+      },
+    );
+  }
+}
+
+@reflectiveTest
 class CommandLineOptions_BuildMode_Test extends AbstractStatusTest {
   CommandLineOptions options;
   String failureMessage;
diff --git a/pkg/compiler/test/helpers/compiler_helper.dart b/pkg/compiler/test/helpers/compiler_helper.dart
index 9b5006b..8faa745 100644
--- a/pkg/compiler/test/helpers/compiler_helper.dart
+++ b/pkg/compiler/test/helpers/compiler_helper.dart
@@ -7,7 +7,6 @@
 library compiler_helper;
 
 import 'dart:async';
-import 'dart:io';
 import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/common_elements.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 06e8346..4c6b895 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2220,7 +2220,8 @@
       VariableBuilder variableBuilder = declaration;
       if (constantContext != ConstantContext.none &&
           !variableBuilder.isConst &&
-          !member.isConstructor) {
+          !member.isConstructor &&
+          !enableConstFunctionsInLibrary) {
         return new IncompleteErrorGenerator(
             this, token, fasta.messageNotAConstantExpression);
       }
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index e414321..dd5e91dd 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -537,6 +537,21 @@
   }
 
   @override
+  Statement visitFunctionDeclaration(
+      FunctionDeclaration node, TreeNode removalSentinel) {
+    if (enableConstFunctions) {
+      if (node.function != null) {
+        node.function = transform(node.function)..parent = node;
+      }
+      constantEvaluator.env.updateVariableValue(
+          node.variable, new IntermediateValue(node.function));
+    } else {
+      return super.visitFunctionDeclaration(node, removalSentinel);
+    }
+    return node;
+  }
+
+  @override
   Statement visitVariableDeclaration(
       VariableDeclaration node, TreeNode removalSentinel) {
     transformAnnotations(node.annotations, node);
@@ -2101,19 +2116,17 @@
   @override
   Constant visitMethodInvocation(MethodInvocation node) {
     // We have no support for generic method invocation at the moment.
-    if (node.arguments.types.isNotEmpty) {
+    if (node.arguments.types.isNotEmpty && !enableConstFunctions) {
       return createInvalidExpressionConstant(node, "generic method invocation");
     }
 
     // We have no support for method invocation with named arguments at the
     // moment.
-    if (node.arguments.named.isNotEmpty) {
+    if (node.arguments.named.isNotEmpty && !enableConstFunctions) {
       return createInvalidExpressionConstant(
           node, "method invocation with named arguments");
     }
 
-    final Constant receiver = _evaluateSubexpression(node.receiver);
-    if (receiver is AbortConstant) return receiver;
     final List<Constant> arguments =
         _evaluatePositionalArguments(node.arguments);
 
@@ -2125,6 +2138,36 @@
     assert(_gotError == null);
     assert(arguments != null);
 
+    final Constant receiver = _evaluateSubexpression(node.receiver);
+    if (receiver is AbortConstant) {
+      return receiver;
+    } else if (enableConstFunctions &&
+        receiver is IntermediateValue &&
+        receiver.value is FunctionNode) {
+      // Evaluate type arguments of the method invoked.
+      List<DartType> types = _evaluateTypeArguments(node, node.arguments);
+      if (types == null && _gotError != null) {
+        AbortConstant error = _gotError;
+        _gotError = null;
+        return error;
+      }
+      assert(_gotError == null);
+      assert(types != null);
+
+      // Evaluate named arguments of the method invoked.
+      final Map<String, Constant> named =
+          _evaluateNamedArguments(node.arguments);
+      if (named == null && _gotError != null) {
+        AbortConstant error = _gotError;
+        _gotError = null;
+        return error;
+      }
+      assert(_gotError == null);
+      assert(named != null);
+
+      return _handleFunctionInvocation(receiver.value, types, arguments, named);
+    }
+
     if (shouldBeUnevaluated) {
       return unevaluated(
           node,
@@ -2697,7 +2740,8 @@
     } else if (target.isExtensionMember) {
       return createErrorConstant(node, messageConstEvalExtension);
     } else if (enableConstFunctions && target.kind == ProcedureKind.Method) {
-      return _handleStaticInvocation(node, typeArguments, positionals, named);
+      return _handleFunctionInvocation(
+          node.target.function, typeArguments, positionals, named);
     }
 
     String name = target.name.text;
@@ -2711,14 +2755,12 @@
     return createInvalidExpressionConstant(node, "Invocation of $name");
   }
 
-  Constant _handleStaticInvocation(
-      StaticInvocation node,
+  Constant _handleFunctionInvocation(
+      FunctionNode function,
       List<DartType> typeArguments,
       List<Constant> positionalArguments,
       Map<String, Constant> namedArguments) {
     return withNewEnvironment(() {
-      final FunctionNode function = node.target.function;
-
       // Map arguments from caller to callee.
       for (int i = 0; i < function.typeParameters.length; i++) {
         env.addTypeParameterValue(function.typeParameters[i], typeArguments[i]);
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart
new file mode 100644
index 0000000..7d2caf5
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests local function usage, some having references to other constant values.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+int function1() {
+  int add(int a, int b) => a + b;
+  const value = add(10, 2);
+  return value;
+}
+
+const constTwo = 2;
+int function2() {
+  int addTwo(int a) {
+    int b = a + constTwo;
+    return b;
+  }
+  const value = addTwo(2);
+  return value;
+}
+
+int function3() {
+  int addTwoReturn(int a) => a + constTwo;
+  const value = addTwoReturn(3);
+  return value;
+}
+
+int function4() {
+  const localTwo = 2;
+  int addTwo(int a) => a + localTwo;
+  const value = addTwo(20);
+  return value;
+}
+
+int function5() {
+  T typeFn<T>(T a) => a;
+  const value = typeFn(3);
+  return value;
+}
+
+int function6() {
+  int optionalFn([int a = 0]) => a;
+  const value = optionalFn(1);
+  return value;
+}
+
+int function7() {
+  int namedFn({int a = 0}) => a;
+  const value = namedFn(a: 2);
+  return value;
+}
+
+void main() {
+  Expect.equals(function1(), 12);
+  Expect.equals(function2(), 4);
+  Expect.equals(function3(), 5);
+  Expect.equals(function4(), 22);
+  Expect.equals(function5(), 3);
+  Expect.equals(function6(), 1);
+  Expect.equals(function7(), 2);
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.expect
new file mode 100644
index 0000000..b20b02d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.expect
@@ -0,0 +1,65 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.transformed.expect
new file mode 100644
index 0000000..b20b02d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.strong.transformed.expect
@@ -0,0 +1,65 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline.expect
new file mode 100644
index 0000000..91aaea8
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+int function1() {}
+const constTwo = 2;
+int function2() {}
+int function3() {}
+int function4() {}
+int function5() {}
+int function6() {}
+int function7() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..44ce8bf
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+import "package:expect/expect.dart";
+
+const constTwo = 2;
+int function1() {}
+int function2() {}
+int function3() {}
+int function4() {}
+int function5() {}
+int function6() {}
+int function7() {}
+void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.expect
new file mode 100644
index 0000000..b20b02d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.expect
@@ -0,0 +1,65 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.outline.expect
new file mode 100644
index 0000000..7e9d751
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.outline.expect
@@ -0,0 +1,23 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = 2;
+static method function1() → core::int
+  ;
+static method function2() → core::int
+  ;
+static method function3() → core::int
+  ;
+static method function4() → core::int
+  ;
+static method function5() → core::int
+  ;
+static method function6() → core::int
+  ;
+static method function7() → core::int
+  ;
+static method main() → void
+  ;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.transformed.expect
new file mode 100644
index 0000000..b20b02d
--- /dev/null
+++ b/pkg/front_end/testcases/const_functions/const_functions_local_functions.dart.weak.transformed.expect
@@ -0,0 +1,65 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+static const field core::int constTwo = #C1;
+static method function1() → core::int {
+  function add(core::int a, core::int b) → core::int
+    return a.{core::num::+}(b);
+  return #C2;
+}
+static method function2() → core::int {
+  function addTwo(core::int a) → core::int {
+    core::int b = a.{core::num::+}(#C1);
+    return b;
+  }
+  return #C3;
+}
+static method function3() → core::int {
+  function addTwoReturn(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C4;
+}
+static method function4() → core::int {
+  function addTwo(core::int a) → core::int
+    return a.{core::num::+}(#C1);
+  return #C5;
+}
+static method function5() → core::int {
+  function typeFn<T extends core::Object? = dynamic>(T% a) → T%
+    return a;
+  return #C6;
+}
+static method function6() → core::int {
+  function optionalFn([core::int a = #C7]) → core::int
+    return a;
+  return #C8;
+}
+static method function7() → core::int {
+  function namedFn({core::int a = #C7}) → core::int
+    return a;
+  return #C1;
+}
+static method main() → void {
+  exp::Expect::equals(self::function1(), 12);
+  exp::Expect::equals(self::function2(), 4);
+  exp::Expect::equals(self::function3(), 5);
+  exp::Expect::equals(self::function4(), 22);
+  exp::Expect::equals(self::function5(), 3);
+  exp::Expect::equals(self::function6(), 1);
+  exp::Expect::equals(self::function7(), 2);
+}
+
+constants  {
+  #C1 = 2
+  #C2 = 12
+  #C3 = 4
+  #C4 = 5
+  #C5 = 22
+  #C6 = 3
+  #C7 = 0
+  #C8 = 1
+}
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 5eae1d9..1bc8225 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -897,9 +897,6 @@
     "..:libdart_precompiler",
     "//third_party/zlib",
   ]
-  if (defined(checkout_llvm) && checkout_llvm) {
-    deps += [ "//runtime/llvm_codegen/bit:test" ]
-  }
   include_dirs = [
     "..",
     "$target_gen_dir",
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 0c27be9..14762ed 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -99,8 +99,12 @@
   if (ShouldCaptureStdout()) {
     // For now we report print output on the Stdout stream.
     uint8_t newline[] = {'\n'};
-    Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, length);
-    Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline, sizeof(newline));
+    const char* res =
+        Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, length);
+    ASSERT(res == nullptr);
+    res = Dart_ServiceSendDataEvent("Stdout", "WriteEvent", newline,
+                                    sizeof(newline));
+    ASSERT(res == nullptr);
   }
 }
 
diff --git a/runtime/bin/eventhandler.h b/runtime/bin/eventhandler.h
index 69a8e3a..b45deac 100644
--- a/runtime/bin/eventhandler.h
+++ b/runtime/bin/eventhandler.h
@@ -90,7 +90,6 @@
 
  private:
   PriorityQueue<int64_t, Dart_Port> timeouts_;
-  int64_t next_timeout_;
 
   DISALLOW_COPY_AND_ASSIGN(TimeoutQueue);
 };
diff --git a/runtime/bin/file_support.cc b/runtime/bin/file_support.cc
index 722e321..f70253f 100644
--- a/runtime/bin/file_support.cc
+++ b/runtime/bin/file_support.cc
@@ -71,15 +71,17 @@
   }
   if (capture_stdout || capture_stderr) {
     intptr_t fd = GetFD();
+    const char* result = nullptr;
     if ((fd == STDOUT_FILENO) && capture_stdout) {
-      Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
-                                reinterpret_cast<const uint8_t*>(buffer),
-                                num_bytes);
+      result = Dart_ServiceSendDataEvent(
+          "Stdout", "WriteEvent", reinterpret_cast<const uint8_t*>(buffer),
+          num_bytes);
     } else if ((fd == STDERR_FILENO) && capture_stderr) {
-      Dart_ServiceSendDataEvent("Stderr", "WriteEvent",
-                                reinterpret_cast<const uint8_t*>(buffer),
-                                num_bytes);
+      result = Dart_ServiceSendDataEvent(
+          "Stderr", "WriteEvent", reinterpret_cast<const uint8_t*>(buffer),
+          num_bytes);
     }
+    ASSERT(result == nullptr);
   }
   return true;
 }
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index a106d42..3ed741b 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -260,13 +260,13 @@
  *
  * \param bytes_length The length of the byte array.
  *
- * \return Success if the arguments are well formed.  Otherwise, returns an
- *   error handle.
+ * \return NULL if the arguments are well formed.  Otherwise, returns an
+ *   error string. The caller is responsible for freeing the error message.
  */
-DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
-                                                  const char* event_kind,
-                                                  const uint8_t* bytes,
-                                                  intptr_t bytes_length);
+DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
+                                            const char* event_kind,
+                                            const uint8_t* bytes,
+                                            intptr_t bytes_length);
 
 /**
  * Usage statistics for a space/generation at a particular moment in time.
diff --git a/runtime/llvm_codegen/bit/BUILD.gn b/runtime/llvm_codegen/bit/BUILD.gn
deleted file mode 100644
index a021ffe..0000000
--- a/runtime/llvm_codegen/bit/BUILD.gn
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-executable("bit") {
-  sources = [ "main.cc" ]
-  root_dir = rebase_path(root_out_dir)
-  clang_dir = rebase_path("//buildtools/linux-x64/clang/bin")
-  defines = [
-    "BIT_BINARY_DIR=\"$root_dir\"",
-    "BIT_CLANG_DIR=\"$clang_dir\"",
-  ]
-  deps = [ "../../../third_party/llvm:LLVMSupport" ]
-  data_deps = [ "../codegen" ]
-}
-
-source_set("test") {
-  sources = [ "test.cc" ]
-
-  root_dir = rebase_path(root_out_dir)
-  clang_dir = rebase_path("//buildtools/linux-x64/clang/bin")
-  defines = [
-    "BIT_BINARY_DIR=\"$root_dir\"",
-    "BIT_CLANG_DIR=\"$clang_dir\"",
-  ]
-
-  deps = [ "../../../third_party/llvm:LLVMSupport" ]
-
-  include_dirs = [ "//runtime" ]
-
-  defines += [ "TESTING" ]
-}
diff --git a/runtime/llvm_codegen/bit/bit.h b/runtime/llvm_codegen/bit/bit.h
deleted file mode 100644
index ea57b03..0000000
--- a/runtime/llvm_codegen/bit/bit.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <stdio.h>
-
-#include <map>
-#include <regex>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/WithColor.h"
-
-namespace {
-
-using namespace llvm;
-
-struct Config {
-  StringRef filename;
-  StringRef out_dir;
-};
-
-StringMap<std::string> GetSubstitutions(const Config& config) {
-  // Compute all of our strings needed for substitutions.
-  StringRef test_dir = sys::path::parent_path(config.filename);
-  StringRef basename = sys::path::filename(config.filename);
-  SmallString<128> tmp_file;
-  sys::path::append(tmp_file, sys::path::Style::native, config.out_dir,
-                    basename + ".tmp");
-  SmallString<128> codegen;
-  sys::path::append(codegen, sys::path::Style::native, BIT_BINARY_DIR,
-                    "codegen");
-  SmallString<128> bit;
-  sys::path::append(bit, sys::path::Style::native, BIT_BINARY_DIR, "bit");
-
-  SmallString<128> clang;
-  sys::path::append(clang, sys::path::Style::native, BIT_CLANG_DIR, "clang");
-
-  // Set up our substitutions.
-  StringMap<std::string> subs;
-  subs["s"] = config.filename.str();
-  subs["p"] = test_dir.str();
-  subs["P"] = test_dir.str();
-  subs["t"] = tmp_file.str().str();
-  subs["{codegen}"] = codegen.str().str();
-  subs["{bit}"] = bit.str().str();
-  subs["{clang}"] = clang.str().str();
-  return subs;
-}
-
-std::string PerformSubstitutions(const StringMap<std::string>& subs,
-                                 StringRef string) {
-  std::string out = string.str();
-  for (const auto& sub : subs) {
-    std::string key = (Twine("%") + sub.getKeyData()).str();
-    size_t pos = 0;
-    while ((pos = out.find(key, pos)) != std::string::npos) {
-      if (pos != 0 && out[pos - 1] == '%') {
-        pos += key.size();
-        continue;
-      }
-      out.replace(pos, key.size(), sub.getValue());
-      pos += sub.second.size();
-    }
-  }
-  return out;
-}
-
-Optional<std::string> GetCommand(StringRef line) {
-  static Regex run_line("^;[ ]*RUN:[ ]*(.*)$");
-  SmallVector<StringRef, 2> cmd;
-  if (!run_line.match(line, &cmd)) return Optional<std::string>{};
-  assert(cmd.size() == 2);
-  return cmd[1].str();
-}
-
-}  // namespace
diff --git a/runtime/llvm_codegen/bit/main.cc b/runtime/llvm_codegen/bit/main.cc
deleted file mode 100644
index 17a5854..0000000
--- a/runtime/llvm_codegen/bit/main.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <stdio.h>
-
-#include <cctype>
-#include <map>
-#include <regex>
-
-#include "bit.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/InitLLVM.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/Program.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/VirtualFileSystem.h"
-#include "llvm/Support/WithColor.h"
-
-using namespace llvm;
-
-namespace {
-
-StringRef tool_name;
-
-LLVM_ATTRIBUTE_NORETURN void Fail(Twine message) {
-  WithColor::error(errs(), tool_name) << message << ".\n";
-  errs().flush();
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void Fail(Error e) {
-  assert(E);
-  std::string buf;
-  raw_string_ostream os(buf);
-  logAllUnhandledErrors(std::move(e), os);
-  os.flush();
-  WithColor::error(errs(), tool_name) << buf;
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void ReportError(StringRef file, std::error_code ec) {
-  assert(ec);
-  Fail(createFileError(file, ec));
-}
-
-std::string ReadFile(FILE* file) {
-  std::string output;
-  constexpr size_t buf_size = 256;
-  char buf[buf_size];
-  size_t size;
-  while ((size = fread(buf, buf_size, sizeof(buf[0]), file)))
-    output.append(buf, buf + buf_size);
-  return output;
-}
-
-bool IsPosixFullyPortablePath(StringRef path) {
-  const char* extra = "._-/";
-  for (auto c : path)
-    if (!isalnum(c) && !strchr(extra, c)) return false;
-  return true;
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  InitLLVM X(argc, argv);
-
-  // Make sure we have both arguments.
-  tool_name = argv[0];
-  if (argc != 3) Fail("expected exactly 2 arguments");
-
-  // Makes sure that stdin/stdout are setup correctly.
-  if (sys::Process::FixupStandardFileDescriptors())
-    Fail("std in/out fixup failed");
-
-  // Set our config.
-  Config config;
-  config.filename = argv[1];
-  config.out_dir = argv[2];
-
-  // Make sure we have valid filepaths.
-  if (!IsPosixFullyPortablePath(config.filename))
-    Fail("'" + config.filename + "' is not a posix fully portable filename");
-  if (!IsPosixFullyPortablePath(config.out_dir))
-    Fail("'" + config.out_dir + "' is not a posix fully portable filename");
-
-  // Compute substitutions.
-  auto subs = GetSubstitutions(config);
-
-  // The lines we execute are allowed to assume that %p will exist.
-  sys::fs::create_directory(subs["p"]);
-
-  // Open the file for reading.
-  auto buf_or = vfs::getRealFileSystem()->getBufferForFile(config.filename);
-  if (!buf_or) ReportError(config.filename, buf_or.getError());
-  auto buf = std::move(*buf_or);
-
-  // Now iterate over the lines in the file.
-  line_iterator it{*buf};
-  int count = 0;
-  for (StringRef line = *it; !it.is_at_end(); line = *++it) {
-    auto cmd = GetCommand(line);
-    if (!cmd) continue;
-    ++count;
-    auto subbed = PerformSubstitutions(subs, *cmd);
-    FILE* file = popen(subbed.c_str(), "r");
-    std::string output = ReadFile(file);
-    if (pclose(file) != 0) {
-      errs() << output << "\n";
-      Fail("Failure on line " + Twine(it.line_number()) + "\n\t" + subbed + "");
-    }
-  }
-  if (count == 0) {
-    Fail("No commands to run");
-  }
-  outs() << "Commands run: " << count << "\n";
-  return 0;
-}
diff --git a/runtime/llvm_codegen/bit/test.cc b/runtime/llvm_codegen/bit/test.cc
deleted file mode 100644
index 7b800ff..0000000
--- a/runtime/llvm_codegen/bit/test.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <stdio.h>
-
-#include <utility>
-#include <vector>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/WithColor.h"
-#include "platform/assert.h"
-#include "vm/unit_test.h"
-
-#define LIT_BINARY_DIR "/path/to/bins"
-#include "bit.h"
-
-UNIT_TEST_CASE(BasicGetSubstitutions) {
-  Config config;
-  config.filename = "/foo/bar/baz.ll";
-  config.out_dir = "/test/out/dir";
-
-  StringMap<std::string> expected;
-  expected["s"] = "/foo/bar/baz.ll";
-  expected["p"] = "/foo/bar";
-  expected["P"] = "/test/out/dir";
-  expected["t"] = "/test/out/dir/baz.ll.tmp";
-  expected["codegen"] = "/path/to/bins/codegen";
-  expected["bit"] = "/path/to/bins/bit";
-
-  StringMap<std::string> actual = GetSubstitutions(config);
-
-  EXPECT_EQ(actual.size(), expected.size());
-  for (const auto& p : actual)
-    EXPECT_EQ(p.getValue(), expected[p.getKey()]);
-}
-
-UNIT_TEST_CASE(BasicPerformSubstitutions) {
-  StringMap<std::string> subs;
-  subs["foo"] = "/foo/path";
-  subs["bar"] = "/bar/path";
-  subs["baz"] = "/baz/path";
-  std::vector<std::pair<std::string, std::string>> cases = {
-      {"%foo", "/foo/path"},
-      {"%bar", "/bar/path"},
-      {"%baz", "/baz/path"},
-      {"this has %foo, and %bar, and %baz2",
-       "this has /foo/path, and /bar/path, and /baz/path2"},
-      {"we don't want %this to expand", "we don't want %this to expand"},
-      {"%", "%"}};
-  for (const auto& test : cases) {
-    auto out = PerformSubstitutions(subs, test.first);
-    EXPECT_EQ(out, test.second);
-  }
-}
-
-UNIT_TEST_CASE(BasicGetCommand) {
-  EXPECT(!GetCommand("; this is some test"));
-  EXPECT(!GetCommand("2 + 2"));
-  EXPECT(!GetCommand("echo $VAR > %bit"));
-
-  EXPECT(GetCommand(";RUN: blarg") == Optional<std::string>{"blarg"});
-  EXPECT(GetCommand(";      RUN:        foo") == Optional<std::string>{"blarg"});
-  EXPECT(
-      GetCommand("; RUN: echo %bit %p/Input/$(%t2) > $(baz \"$BAR->%t\")") ==
-      Optional<std::string>("echo %bit %p/Input/$(%t2) > $(baz \"$BAR->%t\")"));
-}
diff --git a/runtime/llvm_codegen/codegen/BUILD.gn b/runtime/llvm_codegen/codegen/BUILD.gn
deleted file mode 100644
index 2e0a833b..0000000
--- a/runtime/llvm_codegen/codegen/BUILD.gn
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import("../../vm/compiler/compiler_sources.gni")
-
-config("config") {
-  include_dirs = [ "../../" ]
-
-  cflags = [ "-Wno-unused-private-field" ]
-}
-
-_lib_llvm_so = "../../../third_party/llvm/lib/libLLVM-9svn.so"
-
-config("llvm") {
-  include_dirs = [ "../../../third_party/llvm/include" ]
-  libs = [ _lib_llvm_so ]
-}
-
-copy("lib_llvm") {
-  sources = [ _lib_llvm_so ]
-  outputs = [ "$root_out_dir/libLLVM-9svn.so" ]
-  public_configs = [ ":llvm" ]
-}
-
-executable("codegen") {
-  sources = [
-    "custom_zone.cc",
-    "custom_zone.h",
-    "dart.cc",
-    "dart.h",
-    "main.cc",
-  ]
-
-  deps = [
-    ":lib_llvm",
-    "../../third_party/double-conversion/src:libdouble_conversion",
-  ]
-
-  configs += [ ":config" ]
-}
diff --git a/runtime/llvm_codegen/codegen/custom_zone.cc b/runtime/llvm_codegen/codegen/custom_zone.cc
deleted file mode 100644
index f514fe5..0000000
--- a/runtime/llvm_codegen/codegen/custom_zone.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "custom_zone.h"
-
-#include "platform/text_buffer.h"
-#include "platform/unicode.h"
-#include "platform/utils.h"
-#include "vm/double_conversion.h"
-#include "vm/os.h"
-
-#include "platform/assert.cc"  // NOLINT
-#include "platform/syslog_linux.cc"  // NOLINT
-#include "platform/text_buffer.cc"  // NOLINT
-#include "platform/unicode.cc"  // NOLINT
-#include "platform/utils.cc"  // NOLINT
-#include "platform/utils_linux.cc"  // NOLINT
-#include "vm/compiler/backend/sexpression.cc"  // NOLINT
-#include "vm/double_conversion.cc"  // NOLINT
-#include "vm/flags.cc"  // NOLINT
-#include "vm/os_linux.cc"  // NOLINT
-#include "vm/zone_text_buffer.cc"  // NOLINT
-
-namespace dart {
-
-void* ZoneAllocated::operator new(uintptr_t size, dart::Zone* zone) {
-  return reinterpret_cast<void*>(zone->AllocUnsafe(size));
-}
-
-Zone::~Zone() {
-  while (buffers_.size() > 0) {
-    free(buffers_.back());
-    buffers_.pop_back();
-  }
-}
-
-void* Zone::AllocUnsafe(intptr_t size) {
-  void* memory = malloc(size);
-  buffers_.push_back(memory);
-  return memory;
-}
-
-DART_EXPORT void Dart_PrepareToAbort() {
-  fprintf(stderr, "Dart_PrepareToAbort() not implemented!\n");
-  exit(1);
-}
-
-DART_EXPORT void Dart_DumpNativeStackTrace(void* context) {
-  fprintf(stderr, "Dart_DumpNativeStackTrace() not implemented!\n");
-  exit(1);
-}
-
-}  // namespace dart
diff --git a/runtime/llvm_codegen/codegen/custom_zone.h b/runtime/llvm_codegen/codegen/custom_zone.h
deleted file mode 100644
index 3b38104..0000000
--- a/runtime/llvm_codegen/codegen/custom_zone.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef RUNTIME_LLVM_CODEGEN_CODEGEN_CUSTOM_ZONE_H_
-#define RUNTIME_LLVM_CODEGEN_CODEGEN_CUSTOM_ZONE_H_
-
-#include <vector>
-
-// We use a custom zone here which doesn't depend on VM internals (e.g. handles,
-// thread, ...)
-#if defined(RUNTIME_VM_ZONE_H_)
-#error "We want our own zone implementation"
-#endif
-#define RUNTIME_VM_ZONE_H_
-
-namespace dart {
-
-class Zone {
- public:
-  Zone() {}
-  ~Zone();
-
-  template <class ElementType>
-  inline ElementType* Alloc(intptr_t length) {
-    return static_cast<ElementType*>(
-        AllocUnsafe(sizeof(ElementType) * length));
-  }
-
-  template <class ElementType>
-  inline ElementType* Realloc(ElementType* old_array,
-                              intptr_t old_length,
-                              intptr_t new_length) {
-    void* memory = AllocUnsafe(sizeof(ElementType) * new_length);
-    memmove(memory, old_array, sizeof(ElementType) * old_length);
-    return static_cast<ElementType*>(memory);
-  }
-
-  template <class ElementType>
-  void Free(ElementType* old_array, intptr_t len) {}
-
-  void* AllocUnsafe(intptr_t size);
-
- private:
-  Zone(const Zone&) = delete;
-  void operator=(const Zone&) = delete;
-  std::vector<void*> buffers_;
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_LLVM_CODEGEN_CODEGEN_CUSTOM_ZONE_H_
diff --git a/runtime/llvm_codegen/codegen/dart.cc b/runtime/llvm_codegen/codegen/dart.cc
deleted file mode 100644
index fe21974..0000000
--- a/runtime/llvm_codegen/codegen/dart.cc
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <utility>
-
-#include "dart.h"
-
-#include "llvm/ADT/StringSwitch.h"
-
-using namespace llvm;
-
-Value* DartThreadObject::GetOffset(Type* type, intptr_t offset) const {
-  auto& ctx = bb_builder_.Context();
-  auto& builder = bb_builder_.Builder();
-  auto int64ty = IntegerType::getInt64Ty(ctx);
-  // TODO: This is only correct for x86_64. On x86 we need to use 257,
-  // and only arm targets an entirely different mechanism will be
-  // required since there isn't an unused register. On Arm we can
-  // probably still use the thread register as long as we're careful
-  // to set it back on thread boundaries.
-  // On x86_64 fs (257) is used for TLS but gs (256) is unused
-  // On x86 gs (256) is used for TLS but fs (257) is unused
-  // we use the unused segment so as to not conflict with TLS which
-  // allows linking against native code that uses TLS without needing
-  // to handle any kind of context switching.
-  constexpr unsigned kDartThreadPointerAddressSpace = 256;
-  auto* ptr_tls = PointerType::get(type, kDartThreadPointerAddressSpace);
-  auto* offset_value = ConstantInt::get(int64ty, offset);
-  auto* tls_value = builder.CreateIntToPtr(offset_value, ptr_tls);
-  return builder.CreateLoad(tls_value);
-}
-
-Value* DartThreadObject::StackLimit() const {
-  auto& ctx = bb_builder_.Context();
-  return GetOffset(IntegerType::getInt64Ty(ctx), kThreadStackLimitOffset);
-}
-
-Value* BasicBlockBuilder::GetValue(const DartValue* v) {
-  auto iter = values_.find(v);
-  if (iter == values_.end()) {
-    auto* out = v->Make(*this);
-    values_[v] = out;
-    return out;
-  }
-  return iter->second;
-}
-
-DartInstruction::~DartInstruction() {}
-
-static Error CreateError(const Twine& err) {
-  return make_error<StringError>(err, inconvertibleErrorCode());
-}
-
-Value* DartConstant::Make(BasicBlockBuilder& bb_builder) const {
-  auto& ctx = bb_builder.Context();
-  switch (type) {
-    case DartConstant::Type::String:
-      auto constant = ConstantDataArray::getString(ctx, str);
-      auto gv =
-          new GlobalVariable(bb_builder.Module(), constant->getType(), true,
-                             GlobalVariable::ExternalLinkage, constant);
-      return ConstantExpr::getBitCast(gv, GetType(bb_builder));
-  }
-}
-
-Type* DartConstant::GetType(BasicBlockBuilder& bb_builder) const {
-  // TODO: Right now this returns a c-string type but that's not correct.
-  // We should move this to a generic object type (e.g. a tagged pointer).
-  auto& ctx = bb_builder.Context();
-  auto int8ty = IntegerType::getInt8Ty(ctx);
-  return PointerType::get(int8ty, 0);
-}
-
-void InstCheckStackOverflow::Build(BasicBlockBuilder& bb_builder) const {
-  auto& builder = bb_builder.Builder();
-  auto& ctx = bb_builder.Context();
-  auto& module = bb_builder.Module();
-  auto& thread_object = bb_builder.ThreadObject();
-
-  // TODO: This is only correct on 64-bit architectures.
-  auto int64ty = IntegerType::getInt64Ty(ctx);
-
-  // Get the stack pointer.
-  auto spi_type = Intrinsic::getType(ctx, Intrinsic::stacksave);
-  auto spi_func = Intrinsic::getDeclaration(&module, Intrinsic::stacksave);
-  auto sp_raw = builder.CreateCall(spi_type, spi_func);
-  auto sp = builder.CreatePtrToInt(sp_raw, int64ty);
-
-  // Get the stack limit from the thread pointer.
-  auto stack_limit = thread_object.StackLimit();
-
-  // Now compare the stack pointer and limit.
-  auto error_bb = bb_builder.AddBasicBlock();
-  auto cont_bb = bb_builder.AddBasicBlock();
-  auto cmp = builder.CreateICmpULT(sp, stack_limit);
-  builder.CreateCondBr(cmp, error_bb, cont_bb);
-
-  // Now build the error path.
-  // TODO: Don't just trap here. For now we just trap rather than
-  // handling the proper exceptional control flow here.
-  builder.SetInsertPoint(error_bb);
-  auto trap_type = Intrinsic::getType(ctx, Intrinsic::trap);
-  auto trap_func = Intrinsic::getDeclaration(&module, Intrinsic::trap);
-  builder.CreateCall(trap_type, trap_func);
-  builder.CreateBr(cont_bb);
-
-  // Now pretend as if this new block is just the end of the block we
-  // started with.
-  builder.SetInsertPoint(cont_bb);
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstCheckStackOverflow::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (CheckStackoverflow)
-  return llvm::make_unique<InstCheckStackOverflow>();
-}
-
-void InstPushArgument::Build(BasicBlockBuilder& bb_builder) const {
-  bb_builder.PushArgument(bb_builder.GetValue(arg_));
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstPushArgument::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (PushArgument <arg>)
-  if (inst->Length() != 2) {
-    return CreateError("PushArgument should have exactly 1 argument");
-  }
-  dart::SExpSymbol* arg = inst->At(1)->AsSymbol();
-  if (arg == nullptr) {
-    return CreateError("Expected PushArgument's argument to be a symbol");
-  }
-  const DartValue* dvalue = bb_builder.GetDef(arg->value());
-  if (dvalue == nullptr) {
-    return CreateError(Twine(arg->value()) + " is not a valid symbol");
-  }
-  return llvm::make_unique<InstPushArgument>(dvalue);
-}
-
-void InstStaticCall::Build(BasicBlockBuilder& bb_builder) const {
-  // inst = (StaticCall <function-symbol> <arg> ...)
-
-  SmallVector<Value*, 8> args;
-  size_t arg_count = args_len_;
-  while (arg_count > 0) {
-    arg_count--;
-    args.push_back(bb_builder.PopArgument());
-  }
-  auto& builder = bb_builder.Builder();
-
-  // Hard code the function type for now.
-  auto& ctx = bb_builder.Context();
-  auto int8ty = IntegerType::getInt8Ty(ctx);
-  auto i8ptr = PointerType::get(int8ty, 0);
-  SmallVector<Type*, 8> arg_types;
-  arg_types.push_back(i8ptr);
-  auto print_type = FunctionType::get(Type::getVoidTy(ctx), arg_types, false);
-
-  // Get the function value we need.
-  auto func = bb_builder.GetValue(function_);
-  builder.CreateCall(print_type, func, args);
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstStaticCall::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (StaticCall <function_name> { args_len <N> })
-  if (inst->Length() != 2) {
-    return CreateError("StaticCall should have exactly 1 argument");
-  }
-  dart::SExpSymbol* func = inst->At(1)->AsSymbol();
-  if (!func) {
-    return CreateError("Expected StaticCall's argument to be a symbol");
-  }
-  const DartValue* dvalue = bb_builder.GetDef(func->value());
-  dart::SExpression* args_len_expr = inst->ExtraLookupValue("args_len");
-  // If args_len_expr isn't found args_len is assumed to be zero.
-  size_t args_len = 0;
-  if (args_len_expr) {
-    dart::SExpInteger* args_len_expr_int = args_len_expr->AsInteger();
-    if (args_len_expr_int) args_len = args_len_expr_int->value();
-  }
-  return llvm::make_unique<InstStaticCall>(dvalue, 1);
-}
-
-void InstReturn::Build(BasicBlockBuilder& bb_builder) const {
-  auto& builder = bb_builder.Builder();
-  builder.CreateRetVoid();
-}
-
-Expected<std::unique_ptr<DartInstruction>> InstReturn::Construct(
-    dart::SExpList* inst,
-    DartBasicBlockBuilder& bb_builder) {
-  // inst = (Return)
-  return llvm::make_unique<InstReturn>();
-}
-
-static Expected<StringMap<DartConstant>> MakeConstants(dart::Zone* zone,
-                                                       dart::SExpList* sexpr) {
-  StringMap<DartConstant> out;
-  for (intptr_t i = 1; i < sexpr->Length(); ++i) {
-    DartConstant constant;
-    dart::SExpList* def = sexpr->At(i)->AsList();
-    if (!def) {
-      return CreateError(Twine("Stray token in constants at location ") +
-                         Twine(i) + sexpr->At(i)->ToCString(zone));
-    }
-    if (def->Length() != 3) {
-      return CreateError("Constant definitions must have exactly 3 lines");
-    }
-    dart::SExpSymbol* def_symbol = def->At(0)->AsSymbol();
-    if (def_symbol->value() != StringRef("def")) {
-      return CreateError(
-          "first element in a constant definition expected to be `def`");
-    }
-    dart::SExpSymbol* def_name = def->At(1)->AsSymbol();
-    if (!def_name) {
-      return CreateError("element after `def` in constant expected to be name");
-    }
-    dart::SExpression* def_value = def->At(2);
-    if (def_value->IsString()) {
-      constant.str = def_value->AsString()->value();
-      constant.type = DartConstant::Type::String;
-    } else {
-      return CreateError("We can't yet handle that element type");
-    }
-    out[def_name->value()] = constant;
-  }
-  return out;
-}
-
-#define FOREACH_INSTRUCTION(M)                                                 \
-  M(CheckStackOverflow)                                                        \
-  M(PushArgument)                                                              \
-  M(StaticCall)                                                                \
-  M(Return)
-
-static Expected<std::unique_ptr<DartInstruction>> MakeInstruction(
-    dart::SExpList* sexpr,
-    DartBasicBlockBuilder& bb_builder) {
-  if (sexpr->Length() < 1)
-    return CreateError("An empty list can't be an instruction");
-  dart::SExpSymbol* inst_sym = sexpr->At(0)->AsSymbol();
-  if (!inst_sym)
-    return CreateError(
-        "Expected first element of list in instruction to be a symbol");
-  using CtorFunc = std::function<Expected<std::unique_ptr<DartInstruction>>(
-      dart::SExpList*, DartBasicBlockBuilder&)>;
-  CtorFunc ctor = StringSwitch<CtorFunc>(inst_sym->value())
-#define HANDLE_INSTRUCTION_CASE(INST) .Case(#INST, Inst##INST::Construct)
-      FOREACH_INSTRUCTION(HANDLE_INSTRUCTION_CASE);
-#undef HANDLE_INSTRUCTION_CASE
-  return ctor(sexpr, bb_builder);
-}
-
-static Expected<DartBlock> MakeBlock(dart::SExpList* sexpr,
-                                     DartFunction& function,
-                                     const StringMap<const DartValue*>& env) {
-  // Construct the basic block builder
-  DartBasicBlockBuilder bb_builder;
-  for (const auto& c : function.constants)
-    bb_builder.AddDef(c.getKey(), &c.getValue());
-  for (const auto& c : env)
-    bb_builder.AddDef(c.getKey(), c.getValue());
-
-  DartBlock out;
-
-  // Make sure we have a basic block and get the name
-  if (sexpr->Length() <= 2)
-    return CreateError("too few elements in basic block");
-  dart::SExpSymbol* block_name = sexpr->At(1)->AsSymbol();
-  if (!block_name)
-    return CreateError("expected block name after `block` symbol");
-  out.name = block_name->value();
-
-  // Now construct each instruction and add it to the basic block
-  for (intptr_t i = 2; i < sexpr->Length(); ++i) {
-    dart::SExpList* inst = sexpr->At(i)->AsList();
-    if (!inst)
-      return CreateError("stray token at element " + Twine(i) +
-                         " in basic block " + out.name);
-    auto inst_or = MakeInstruction(inst, bb_builder);
-    if (!inst_or) return inst_or.takeError();
-    out.instructions.emplace_back(std::move(*inst_or));
-  }
-  return out;
-}
-
-Expected<DartFunction> MakeFunction(dart::Zone* zone,
-                                    dart::SExpression* sexpr,
-                                    const StringMap<const DartValue*>& env) {
-  // Basic checking that this s-expression looks like a function
-  dart::SExpList* flist = sexpr->AsList();
-  if (!flist) return CreateError("S-Expression was not a function list");
-  if (flist->Length() < 2)
-    return CreateError("S-Expression list was too short to be a function");
-  dart::SExpSymbol* function_symbol = flist->At(0)->AsSymbol();
-  if (function_symbol == nullptr ||
-      function_symbol->value() != StringRef("function"))
-    return CreateError(
-        "S-Expression cannot be a function as it does not start with "
-        "`function`");
-  dart::SExpSymbol* function_name = flist->At(1)->AsSymbol();
-  if (function_name == nullptr)
-    return CreateError("Expected symbol name after `function` symbol");
-
-  // Now we fill in all the details
-  DartFunction function;
-  function.name = function_name->value();
-  Optional<StringRef> normal_entry;
-  for (intptr_t i = 2; i < flist->Length(); ++i) {
-    dart::SExpList* chunk = flist->At(i)->AsList();
-    // Everything is a list so far so error out on other options
-    if (!chunk) {
-      return CreateError(Twine("Stray token in function at location ") +
-                         Twine(i) + ": " + flist->At(i)->ToCString(zone));
-    }
-    dart::SExpSymbol* chunk_symbol = chunk->At(0)->AsSymbol();
-    if (!chunk_symbol)
-      return CreateError(Twine("Expected element ") + Twine(i) +
-                         " of function to start with a symbol");
-    StringRef chunk_tag = chunk_symbol->value();
-
-    if (chunk_tag == "constants") {
-      auto constants = MakeConstants(zone, chunk);
-      if (!constants) return constants.takeError();
-      function.constants = std::move(*constants);
-    }
-
-    if (chunk_tag == "block") {
-      auto block = MakeBlock(chunk, function, env);
-      if (!block) return block.takeError();
-      StringRef name = block->name;
-      function.blocks[name] = std::move(*block);
-    }
-
-    if (chunk_tag == "normal-entry") {
-      if (chunk->Length() != 2)
-        return CreateError("Expected 1 argument to normal-entry");
-      dart::SExpSymbol* block_name = chunk->At(1)->AsSymbol();
-      if (!block_name)
-        return CreateError("expected block name after normal-entry symbol");
-      normal_entry = block_name->value();
-    }
-  }
-
-  if (normal_entry) {
-    auto iter = function.blocks.find(*normal_entry);
-    if (iter != function.blocks.end())
-      function.normal_entry = &iter->getValue();
-  } else {
-    function.normal_entry = nullptr;
-  }
-
-  return function;
-}
diff --git a/runtime/llvm_codegen/codegen/dart.h b/runtime/llvm_codegen/codegen/dart.h
deleted file mode 100644
index 826397a..0000000
--- a/runtime/llvm_codegen/codegen/dart.h
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef RUNTIME_LLVM_CODEGEN_CODEGEN_DART_H_
-#define RUNTIME_LLVM_CODEGEN_CODEGEN_DART_H_
-
-#include <memory>
-#include <vector>
-#include <string>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/ValueSymbolTable.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/WithColor.h"
-
-// Ensure to use our own zone.
-#include "custom_zone.h"
-#include "vm/compiler/backend/sexpression.h"
-
-// This file introduces several representations that exist between
-// S-Expressions and llvm IR. To explain how each part is intended
-// to be roughly translated using these I'll provide a mapping
-// showing how each part is translated.
-
-// At a high level two translations are very seamless:
-//
-// (function foo ...) -> DartFunction -> llvm::Function*
-// (block B ...) -> DartBlock -> (sort of) llvm::BasicBlock*
-//
-// Internally within a function constants are given names and are then used in
-// blocks. Each block additionally defines more names. Each of these names
-// needs to be mapped to a DartValue (more on that later) so a context to help
-// keep track of these name to DartValue mappings called a
-// DartBasicBlockBuilder exists. It is only used for to aid in the
-// (block B ...) -> DartBlock translation which is in turn used in the
-// (function foo ...) -> DartFunction translation. DartFunctions and DartBlocks
-// can be seen as validated representations of their S-Expression forms.
-
-// Within a DartBlock we have DartInstructions. Each DartInstruction either
-// has some effect (like calling a function or updating a value) or defines
-// a new name mapping it to a DartValue later. DartValues are referenced as
-// arguments to DartInstructions and map to llvm::Value*s. DartInstructions
-// have no analogue which they're directly translated to in code but they
-// do closely correspond mentally to llvm::Instruction*. The challenge is that
-// a DartInstruction might map to a near arbitrary number of llvm Instructions
-// and that mapping is very dependent on context. So instead of mapping them
-// to objects DartInstructions just know how to add their llvm Instructions to
-// an llvm::BasicBlock. These instructions might reference a verity of context
-// and so BasicBlockBuilder is passed in to provide them with this context.
-// Each DartInstruction is expected to already hold each DartValue that it
-// needs as previously supplied by the DartBasicBlockBuilder on construction.
-
-// An additional issue arises when translating DartInstructions into llvm IR.
-// Many require introducing control flow when lowered to the level of llvm IR
-// but this requires using multiple llvm::BasicBlock for a single DartBlock.
-// Luckily each DartInstruction that is not a terminator is expected to make it
-// possible for all non-exceptional control flow paths to wind up at a single
-// basic block. Since BasicBlockBuilder keeps track of a "current" basic block
-// via llvm::IRBuilder we simply ensure that after generating many blocks we
-// end each instruction which requires new basic blocks on this final basic
-// block that all generated blocks flow into. A picture better explains this:
-
-// Say you have a DartBlock B_1 it would then be mapped to llvm blocks that
-// look like this:
-//
-//                          B_1
-//                          / \
-//                         /   \
-//                 B_1_left    B_1_right
-//                         \   /
-//                          \ /
-//                         B_1_0
-//
-// And then we go on adding to B_1_0 as if it were the end of B_1 from before.
-
-// Each DartValue knows how to map itself to an llvm::Value. In llvm a Value
-// is really just anything you can give a name to in the IR but a DartValue
-// is intended to be more specific, it's a compile time representation of a
-// object, be it an integer, a tagged SMI, a pointer to a Dart Object, etc...
-// its intended to correspond to some actual object that we're computing on.
-
-// Class FunctionBuilder provides functionality for building
-// and LLVM function object including the ability to add a
-// named basic block, find an existing block, get the current
-// context/module and additionally retrieve llvm Values valid
-// in the current function.
-class FunctionBuilder {
- public:
-  FunctionBuilder(llvm::LLVMContext& ctx,
-                  llvm::Module& mod,
-                  llvm::Function& func)
-      : ctx_(ctx), mod_(mod), func_(func) {}
-  llvm::LLVMContext& Context() { return ctx_; }
-  llvm::Module& Module() { return mod_; }
-  llvm::Value* GetSymbolValue(llvm::StringRef name) {
-    auto* symtab = func_.getValueSymbolTable();
-    return symtab->lookup(name);
-  }
-  llvm::BasicBlock* AddBasicBlock() {
-    return llvm::BasicBlock::Create(ctx_, "", &func_);
-  }
-  llvm::BasicBlock* AddBasicBlock(llvm::StringRef name) {
-    auto* bb = llvm::BasicBlock::Create(ctx_, name, &func_);
-    basic_blocks_[name] = bb;
-    return bb;
-  }
-  llvm::BasicBlock* GetBasicBlock(llvm::StringRef name) const {
-    auto iter = basic_blocks_.find(name);
-    if (iter != basic_blocks_.end()) return iter->getValue();
-    return nullptr;
-  }
-
- private:
-  llvm::LLVMContext& ctx_;
-  llvm::Module& mod_;
-  llvm::Function& func_;
-  llvm::StringMap<llvm::BasicBlock*> basic_blocks_;
-};
-
-class BasicBlockBuilder;
-
-// TODO(jakehehrlich): Make this architecture dependent
-// Class DartThreadObject is used as a high level object for generating
-// code that reads fields from the thread object.
-class DartThreadObject {
- public:
-  explicit DartThreadObject(BasicBlockBuilder& bb_builder)
-      : bb_builder_(bb_builder) {}
-
-  // StackLimit returns an llvm::Value representing the stack limit
-  // of the thread object.
-  llvm::Value* StackLimit() const;
-
- private:
-  static constexpr intptr_t kThreadStackLimitOffset = 72;
-
-  BasicBlockBuilder& bb_builder_;
-
-  // GetOffset returns an llvm::Value* representing a pointer to a particular
-  // field of the thread object. It adds the specified offset to the thread
-  // pointer, and then casts to the specified type.
-  llvm::Value* GetOffset(llvm::Type* type, intptr_t offset) const;
-};
-
-class DartValue;
-
-// A class for keeping track of the basic block state and SSA values.
-// This is similar to IRBuilder but also keeps track of the argument stack and
-// basic block names.
-class BasicBlockBuilder {
- public:
-  BasicBlockBuilder(llvm::BasicBlock* bb, FunctionBuilder& fb)
-      : fb_(fb), top_(bb), builder_(bb), thread_object_(*this) {}
-  llvm::LLVMContext& Context() { return fb_.Context(); }
-  llvm::Module& Module() { return fb_.Module(); }
-  llvm::IRBuilder<>& Builder() { return builder_; }
-  const DartThreadObject& ThreadObject() { return thread_object_; }
-  llvm::BasicBlock* AddBasicBlock() { return fb_.AddBasicBlock(); }
-  llvm::BasicBlock* GetBasicBlock(llvm::StringRef Name) const {
-    return fb_.GetBasicBlock(Name);
-  }
-  llvm::Value* GetSymbolValue(llvm::StringRef name) const {
-    return fb_.GetBasicBlock(name);
-  }
-  llvm::Value* GetValue(const DartValue* v);
-  void PushArgument(llvm::Value* v) { stack_.push_back(v); }
-  llvm::Value* PopArgument() {
-    llvm::Value* out = stack_.back();
-    stack_.pop_back();
-    return out;
-  }
-
- private:
-  FunctionBuilder& fb_;
-  llvm::BasicBlock* top_;
-  llvm::SmallVector<llvm::Value*, 16> stack_;
-  llvm::IRBuilder<> builder_;
-  llvm::DenseMap<const DartValue*, llvm::Value*> values_;
-  DartThreadObject thread_object_;
-};
-
-// Class DartValue represents an SSA value from the Dart SSA
-// such that it can be converted into an llvm::Value*.
-class DartValue {
- public:
-  virtual ~DartValue() {}
-  virtual llvm::Value* Make(BasicBlockBuilder& bb_builder) const = 0;
-  virtual llvm::Type* GetType(BasicBlockBuilder& bb_builder) const = 0;
-};
-
-// Class DartBasicBlockBuilder provides helpful context for going
-// from an S-Expression basic block to a DartBlock. It just lets
-// one lookup DartValue's by name at this time.
-class DartBasicBlockBuilder {
- public:
-  void AddDef(llvm::StringRef name, const DartValue* v) { defs_[name] = v; }
-  const DartValue* GetDef(llvm::StringRef name) const {
-    auto iter = defs_.find(name);
-    if (iter != defs_.end()) return iter->getValue();
-    return nullptr;
-  }
-
- private:
-  llvm::StringMap<const DartValue*> defs_;
-};
-
-// A DartConstant is a DartValue for a constant.
-class DartConstant : public DartValue {
- public:
-  std::string str;
-  enum class Type { String };
-  Type type;
-
-  llvm::Value* Make(BasicBlockBuilder& bb_builder) const override;
-  llvm::Type* GetType(BasicBlockBuilder& bb_builder) const override;
-};
-
-// Class DartInstruction represents a step within a DartBasicBlock.
-// CheckStackOverflow or PushArgument are instructions. They contain
-// DartValues as arguments typically. SSA definitions are also
-// DartInstructions which assign DartValues to names in the function's
-// context.
-class DartInstruction {
- public:
-  virtual ~DartInstruction();
-  virtual void Build(BasicBlockBuilder& bb_builder) const = 0;
-};
-
-// Class InstCheckStackOverflow is a DartInstruction that represents
-// an instance of a CheckStackOverflow instruction.
-class InstCheckStackOverflow : public DartInstruction {
- public:
-  InstCheckStackOverflow() {}
-  ~InstCheckStackOverflow() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-};
-
-// Class InstPushArgument is a DartInstruction that represents
-// and instance of a PushArgument Instruction.
-class InstPushArgument : public DartInstruction {
- public:
-  explicit InstPushArgument(const DartValue* arg) : arg_(arg) {}
-  ~InstPushArgument() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-
- private:
-  const DartValue* arg_;
-};
-
-// Class InstStaticCall is a DartInstruction that represents a
-// StaticCall instruction.
-class InstStaticCall : public DartInstruction {
- public:
-  InstStaticCall(const DartValue* func, size_t args_len)
-      : function_(func), args_len_(args_len) {}
-  ~InstStaticCall() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-
- private:
-  const DartValue* function_;
-  size_t args_len_;
-};
-
-// Class InstReturn is a DartInstruction that represents a Return
-// instruction.
-class InstReturn : public DartInstruction {
- public:
-  InstReturn() {}
-  ~InstReturn() override {}
-  void Build(BasicBlockBuilder& bb_builder) const override;
-  static llvm::Expected<std::unique_ptr<DartInstruction>> Construct(
-      dart::SExpList* inst,
-      DartBasicBlockBuilder& bb_builder);
-};
-
-// Class DartBlock represents a validated basic block as parsed from
-// a (block ...) S-Expression.
-struct DartBlock {
-  std::string name;
-  std::vector<std::unique_ptr<DartInstruction>> instructions;
-};
-
-// Class DartFunction represents a validated function parsed from a
-// (function ...) S-Expression.
-struct DartFunction {
-  std::string name;
-  DartBlock* normal_entry;
-  llvm::StringMap<DartConstant> constants;
-  llvm::StringMap<DartBlock> blocks;
-};
-
-// MakeFunction takes an S-Expression and an environment of externally
-// defined DartValues and produces a DartFunction corresponding to the
-// S-Expression if everything is valid. If something about the syntax
-// of the S-Expression is invalid then the llvm::Expected will hold an
-// error explaining the issue.
-llvm::Expected<DartFunction> MakeFunction(
-    dart::Zone* zone,
-    dart::SExpression* sexpr,
-    const llvm::StringMap<const DartValue*>& env);
-
-#endif  // RUNTIME_LLVM_CODEGEN_CODEGEN_DART_H_
diff --git a/runtime/llvm_codegen/codegen/main.cc b/runtime/llvm_codegen/codegen/main.cc
deleted file mode 100644
index 40d8b3f..0000000
--- a/runtime/llvm_codegen/codegen/main.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "dart.h"
-
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/InitLLVM.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
-#include "llvm/Target/TargetMachine.h"
-
-using namespace llvm;
-
-namespace {
-
-StringRef tool_name;
-
-LLVM_ATTRIBUTE_NORETURN void error(Twine message) {
-  WithColor::error(errs(), "llvm-codegen") << message << ".\n";
-  errs().flush();
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void error(Error e) {
-  assert(e);
-  std::string buf;
-  raw_string_ostream os(buf);
-  logAllUnhandledErrors(std::move(e), os);
-  os.flush();
-  WithColor::error(errs(), tool_name) << buf;
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) {
-  assert(EC);
-  error(createFileError(File, EC));
-}
-
-// We need a prelude function for printing to help get something functional
-// up off the ground.
-class DartPrint : public DartValue {
- public:
-  Type* GetType(BasicBlockBuilder& bbb) const override {
-    auto& ctx = bbb.Context();
-    auto int8ty = IntegerType::getInt8Ty(ctx);
-    auto i8ptr = PointerType::get(int8ty, 0);
-    SmallVector<Type*, 1> arg_types;
-    arg_types.push_back(i8ptr);
-    return FunctionType::get(Type::getVoidTy(ctx), arg_types, false);
-  }
-  Value* Make(BasicBlockBuilder& bbb) const override {
-    auto ft = dyn_cast<FunctionType>(GetType(bbb));
-    if (ft == nullptr) return nullptr;
-    return Function::Create(ft, Function::ExternalLinkage, "dart:core::print",
-                            bbb.Module());
-  }
-};
-
-cl::opt<std::string> sexpr_file(cl::Positional,
-                                cl::desc("The input S-Expression file"));
-cl::opt<std::string> dump_obj(
-    "dump-obj",
-    cl::desc("Specifies where to output the .o file"));
-
-void Dump(Module* module, StringRef file, TargetMachine::CodeGenFileType type) {
-  legacy::PassManager pm;
-  std::error_code ec;
-  raw_fd_ostream out(file, ec);
-  if (ec) reportError(file, ec);
-  Triple target_triple{sys::getDefaultTargetTriple()};
-  TargetOptions options;
-  std::string err;
-  const Target* the_target =
-      TargetRegistry::lookupTarget(target_triple.getTriple(), err);
-  if (the_target == nullptr) error(err);
-  std::unique_ptr<TargetMachine> target(the_target->createTargetMachine(
-      target_triple.getTriple(), "generic", "", options, Reloc::PIC_));
-
-  if (target->addPassesToEmitFile(pm, out, nullptr, type, false))
-    error("couldn't add pass to emit file");
-  pm.run(*module);
-}
-
-}  // namespace
-
-int main(int argc, const char** argv) {
-  // Init llvm
-  InitLLVM X(argc, argv);
-  InitializeAllTargetInfos();
-  InitializeAllTargets();
-  InitializeAllTargetMCs();
-  InitializeAllAsmParsers();
-  InitializeAllAsmPrinters();
-
-  // Basic init
-  tool_name = argv[0];
-  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
-
-  // Read in the file
-  auto file_or = MemoryBuffer::getFile(argv[1]);
-  if (!file_or) reportError(argv[1], file_or.getError());
-  std::unique_ptr<MemoryBuffer> file = std::move(file_or.get());
-
-  // Parse the file
-  dart::Zone zone;
-  dart::SExpParser parser(&zone, file->getBufferStart(), file->getBufferSize());
-  dart::SExpression* root = parser.Parse();
-  if (root == nullptr)
-    error(Twine("SExpParser failed: ") + parser.error_message());
-
-  // Setup our basic prelude
-  StringMap<const DartValue*> prelude;
-  DartPrint print;
-  prelude["dart:core::print"] = &print;
-
-  // Convert the function into an error checked format
-  auto function_or = MakeFunction(&zone, root, prelude);
-  if (!function_or) error(function_or.takeError());
-  auto dart_function = std::move(*function_or);
-  if (!dart_function.normal_entry)
-    error(Twine("function ") + dart_function.name + " has no normal-entry");
-
-  // Setup state for output an LLVMModule
-  LLVMContext context;
-  auto module = llvm::make_unique<Module>(argv[1], context);
-  auto function_type = FunctionType::get(Type::getVoidTy(context), {}, false);
-  auto function = Function::Create(function_type, Function::ExternalLinkage,
-                                   dart_function.name, module.get());
-  FunctionBuilder fb{context, *module, *function};
-  for (auto& bbkey : dart_function.blocks) {
-    auto& bb = bbkey.getValue();
-    auto llvmbb = fb.AddBasicBlock(bb.name);
-    BasicBlockBuilder bbb{llvmbb, fb};
-    for (auto& inst : bb.instructions) {
-      inst->Build(bbb);
-    }
-  }
-
-  // Dump and print the file
-  if (!dump_obj.empty())
-    Dump(module.get(), dump_obj, LLVMTargetMachine::CGFT_ObjectFile);
-
-  module->print(llvm::outs(), nullptr);
-
-  return 0;
-}
diff --git a/runtime/llvm_codegen/test/BUILD.gn b/runtime/llvm_codegen/test/BUILD.gn
deleted file mode 100644
index 633d3dc..0000000
--- a/runtime/llvm_codegen/test/BUILD.gn
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-group("test") {
-  deps = [
-    "bit",
-    "codegen",
-  ]
-}
diff --git a/runtime/llvm_codegen/test/bit/BUILD.gn b/runtime/llvm_codegen/test/bit/BUILD.gn
deleted file mode 100644
index 068ef59..0000000
--- a/runtime/llvm_codegen/test/bit/BUILD.gn
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import("../bit_test.gni")
-
-bit_test("bit") {
-  tests = [ "basic.test" ]
-}
diff --git a/runtime/llvm_codegen/test/bit/Inputs/basic_input.test b/runtime/llvm_codegen/test/bit/Inputs/basic_input.test
deleted file mode 100644
index 092dc80..0000000
--- a/runtime/llvm_codegen/test/bit/Inputs/basic_input.test
+++ /dev/null
@@ -1 +0,0 @@
-; RUN: %{codegen} %p/../../codegen/Inputs/hello.sexp
diff --git a/runtime/llvm_codegen/test/bit/Inputs/percent.test b/runtime/llvm_codegen/test/bit/Inputs/percent.test
deleted file mode 100644
index 8b6782d..0000000
--- a/runtime/llvm_codegen/test/bit/Inputs/percent.test
+++ /dev/null
@@ -1 +0,0 @@
-this is a percent sign: %
diff --git a/runtime/llvm_codegen/test/bit/basic.test b/runtime/llvm_codegen/test/bit/basic.test
deleted file mode 100644
index 88f0479..0000000
--- a/runtime/llvm_codegen/test/bit/basic.test
+++ /dev/null
@@ -1,8 +0,0 @@
-; RUN: echo this is a test > %t1
-; RUN: echo this is a test > %t2
-; RUN: cmp %t1 %t2
-; RUN: echo this is a percent sign: % > %t3
-; RUN: cmp %t3 %p/Inputs/percent.test
-; RUN: %{bit} %p/Inputs/basic_input.test %P > %t.test
-; RUN: echo Commands run: 1 > %t.test2
-; RUN: cmp %t.test %t.test2
diff --git a/runtime/llvm_codegen/test/bit_test.gni b/runtime/llvm_codegen/test/bit_test.gni
deleted file mode 100644
index 6b19e62..0000000
--- a/runtime/llvm_codegen/test/bit_test.gni
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import("../../../build/executable_suffix.gni")
-
-# This file defines a template for running bit tests.
-#
-# - bit_test()
-#   Runs bit on the specified file.
-
-# A template for running bit. This lets bit commands be run as ninja commands.
-#
-# Parameters:
-#   tests:
-#     The list of files to input into bit
-template("bit_test") {
-  assert(defined(invoker.tests), "tests must be defined for $target_name")
-
-  action_foreach(target_name) {
-    script = "//runtime/llvm_codegen/test/run_bit.py"
-    sources = invoker.tests
-
-    deps = [ "../../bit" ]
-    inputs = [ "${root_out_dir}/bit$executable_suffix" ]
-
-    # This output is always dirty so ninja will always run this step when asked to.
-    outputs = [ "$target_gen_dir/{{source_name_part}}}" ]
-    args = [
-      "--bit",
-      rebase_path("${root_out_dir}/bit"),
-      "--test",
-      "{{source}}",
-      "--out",
-      rebase_path(target_gen_dir),
-    ]
-  }
-}
diff --git a/runtime/llvm_codegen/test/codegen/BUILD.gn b/runtime/llvm_codegen/test/codegen/BUILD.gn
deleted file mode 100644
index 34dbba2..0000000
--- a/runtime/llvm_codegen/test/codegen/BUILD.gn
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import("../bit_test.gni")
-
-bit_test("codegen") {
-  tests = [ "hello.test" ]
-}
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/hello.expected b/runtime/llvm_codegen/test/codegen/Inputs/hello.expected
deleted file mode 100644
index 8ab686e..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/hello.expected
+++ /dev/null
@@ -1 +0,0 @@
-Hello, World!
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/hello.ll.expected b/runtime/llvm_codegen/test/codegen/Inputs/hello.ll.expected
deleted file mode 100644
index 187fd59..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/hello.ll.expected
+++ /dev/null
@@ -1,35 +0,0 @@
-; ModuleID = '../../runtime/llvm_codegen/test/codegen/Inputs/hello.sexp'
-source_filename = "../../runtime/llvm_codegen/test/codegen/Inputs/hello.sexp"
-
-@0 = constant [14 x i8] c"Hello, World!\00"
-
-define void @"hello.dart::main"() {
-B1:
-  %0 = call i8* @llvm.stacksave()
-  %1 = ptrtoint i8* %0 to i64
-  %2 = load i64, i64 addrspace(256)* inttoptr (i64 72 to i64 addrspace(256)*)
-  %3 = icmp ult i64 %1, %2
-  br i1 %3, label %4, label %5
-
-4:                                                ; preds = %B1
-  call void @llvm.trap()
-  br label %5
-
-5:                                                ; preds = %4, %B1
-  call void @"dart:core::print"(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @0, i32 0, i32 0))
-  ret void
-}
-
-; Function Attrs: nounwind
-declare i8* @llvm.stacksave() #0
-
-; Function Attrs: cold noreturn nounwind
-declare void @llvm.trap() #1
-
-declare void @"dart:core::print"(i8*)
-
-; Function Attrs: nounwind
-declare void @llvm.stackprotector(i8*, i8**) #0
-
-attributes #0 = { nounwind }
-attributes #1 = { cold noreturn nounwind }
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/hello.sexp b/runtime/llvm_codegen/test/codegen/Inputs/hello.sexp
deleted file mode 100644
index c43c359..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/hello.sexp
+++ /dev/null
@@ -1,9 +0,0 @@
-(function hello.dart::main
-  (constants
-    (def v2 "Hello, World!"))
-  (normal-entry B1)
-  (block B1
-    (CheckStackOverflow)
-    (PushArgument v2)
-    (StaticCall dart:core::print { args_len 1, env (v0 arg[0]), })
-    (Return v0)))
diff --git a/runtime/llvm_codegen/test/codegen/Inputs/runtime.S b/runtime/llvm_codegen/test/codegen/Inputs/runtime.S
deleted file mode 100644
index 7bb2c76..0000000
--- a/runtime/llvm_codegen/test/codegen/Inputs/runtime.S
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-.data
-
-.type _threadObject,@object
-.size _threadObject,1400
-_threadObject:
-  .fill 1400
-
-.text
-.file "runtime.S"
-
-.globl main
-.type main,@function
-
-.globl "dart:core::print"
-.type "dart:core::print",@function
-
-.globl arch_prctl
-.type arch_prctl,@function
-
-main:
-  movq %rsp, %rax
-  subq $0x1000, %rax
-  movq %rax, [_threadObject + 72]
-  # Pass ARCH_SET_GS
-  movq $0x1001, %rdi
-  # Pass $_threadObject
-  movq $_threadObject, %rsi
-  callq arch_prctl
-  callq "hello.dart::main"
-  ret
-
-"dart:core::print":
-  callq puts
-  ret
diff --git a/runtime/llvm_codegen/test/codegen/hello.test b/runtime/llvm_codegen/test/codegen/hello.test
deleted file mode 100644
index 6b836d7..0000000
--- a/runtime/llvm_codegen/test/codegen/hello.test
+++ /dev/null
@@ -1,6 +0,0 @@
-; RUN: %{codegen} %p/Inputs/hello.sexp --dump-obj %t.o > %t.ll
-; RUN: diff %t.ll %p/Inputs/hello.ll.expected
-; RUN: %{clang} -g -c %p/Inputs/runtime.S -o %t.runtime.o
-; RUN: %{clang} %t.o %t.runtime.o -o %t.hello.exe
-; RUN: %t.hello.exe > %t.hello.exe.stdout
-; RUN: diff %t.hello.exe.stdout %p/Inputs/hello.expected
diff --git a/runtime/llvm_codegen/test/run_bit.py b/runtime/llvm_codegen/test/run_bit.py
deleted file mode 100644
index 29863f1..0000000
--- a/runtime/llvm_codegen/test/run_bit.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import subprocess
-import argparse
-
-parser = argparse.ArgumentParser(description="A tool to run the bit integration tester")
-parser.add_argument("--bit", help="Sets the path to bit")
-parser.add_argument("--test", help="Path to test to be run")
-parser.add_argument("--out", help="Path to out directory")
-args = parser.parse_args()
-
-subprocess.check_call([args.bit, args.test, args.out])
-
diff --git a/runtime/tests/vm/dart/use_trace_precompiler_flag_test.dart b/runtime/tests/vm/dart/use_trace_precompiler_flag_test.dart
new file mode 100644
index 0000000..7d41a71
--- /dev/null
+++ b/runtime/tests/vm/dart/use_trace_precompiler_flag_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test ensures that --trace-precompiler runs without issue and prints
+// valid JSON for reasons to retain objects.
+
+// OtherResources=use_dwarf_stack_traces_flag_program.dart
+
+import "dart:convert";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('trace-precompiler-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    // We can just reuse the program for the use_dwarf_stack_traces test.
+    final script = path.join(cwDir, 'use_dwarf_stack_traces_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    // Run the AOT compiler with every enabled/disabled combination of the
+    // following flags that affect object retention:
+    final retentionFlags = [
+      'retain-function-objects',
+      'dwarf-stack-traces-mode'
+    ];
+
+    for (var i = 0; i < 1 << retentionFlags.length; i++) {
+      final flags = <String>[];
+      for (var j = 0; j < retentionFlags.length; j++) {
+        final buffer = StringBuffer('--');
+        if ((i & (1 << j)) == 0) {
+          buffer.write('no-');
+        }
+        buffer.write(retentionFlags[j]);
+        flags.add(buffer.toString());
+      }
+      await testTracePrecompiler(scriptDill, flags);
+    }
+  });
+}
+
+const _jsonHeaders = {'JSON for function decisions: '};
+
+Future<void> testTracePrecompiler(String scriptDill, List<String> flags) async {
+  final result = await runHelper(genSnapshot, <String>[
+    ...flags,
+    '--trace-precompiler',
+    '--snapshot-kind=app-aot-elf',
+    '--elf=snapshot.so',
+    scriptDill,
+  ]);
+
+  Expect.equals(result.exitCode, 0);
+
+  // Tracing output is on stderr.
+  Expect.isTrue(result.stdout.isEmpty);
+  Expect.isTrue(result.stderr.isNotEmpty);
+
+  final seenHeaders = <String>{};
+  final lines =
+      Stream.value(result.stderr as String).transform(const LineSplitter());
+  await for (final s in lines) {
+    for (final header in _jsonHeaders) {
+      if (s.startsWith(header)) {
+        // We only expect a single instance of each header.
+        Expect.isFalse(seenHeaders.contains(header),
+            'multiple instances of \"$header\" seen');
+        seenHeaders.add(header);
+        final j = s.substring(header.length);
+        // For now, just test that the JSON parses and that we get back a list.
+        Expect.isTrue(json.decode(j) is List, 'not a list of decisions');
+      }
+    }
+  }
+  // Check that all headers were seen in the output.
+  for (final header in _jsonHeaders) {
+    Expect.isTrue(
+        seenHeaders.contains(header), 'no instance of \"$header\" seen');
+  }
+}
diff --git a/runtime/tests/vm/dart_2/use_trace_precompiler_flag_test.dart b/runtime/tests/vm/dart_2/use_trace_precompiler_flag_test.dart
new file mode 100644
index 0000000..7d41a71
--- /dev/null
+++ b/runtime/tests/vm/dart_2/use_trace_precompiler_flag_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test ensures that --trace-precompiler runs without issue and prints
+// valid JSON for reasons to retain objects.
+
+// OtherResources=use_dwarf_stack_traces_flag_program.dart
+
+import "dart:convert";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+import 'use_flag_test_helper.dart';
+
+main(List<String> args) async {
+  if (!isAOTRuntime) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  // These are the tools we need to be available to run on a given platform:
+  if (!await testExecutable(genSnapshot)) {
+    throw "Cannot run test as $genSnapshot not available";
+  }
+  if (!await testExecutable(aotRuntime)) {
+    throw "Cannot run test as $aotRuntime not available";
+  }
+  if (!File(platformDill).existsSync()) {
+    throw "Cannot run test as $platformDill does not exist";
+  }
+
+  await withTempDir('trace-precompiler-flag-test', (String tempDir) async {
+    final cwDir = path.dirname(Platform.script.toFilePath());
+    // We can just reuse the program for the use_dwarf_stack_traces test.
+    final script = path.join(cwDir, 'use_dwarf_stack_traces_flag_program.dart');
+    final scriptDill = path.join(tempDir, 'flag_program.dill');
+
+    // Compile script to Kernel IR.
+    await run(genKernel, <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    // Run the AOT compiler with every enabled/disabled combination of the
+    // following flags that affect object retention:
+    final retentionFlags = [
+      'retain-function-objects',
+      'dwarf-stack-traces-mode'
+    ];
+
+    for (var i = 0; i < 1 << retentionFlags.length; i++) {
+      final flags = <String>[];
+      for (var j = 0; j < retentionFlags.length; j++) {
+        final buffer = StringBuffer('--');
+        if ((i & (1 << j)) == 0) {
+          buffer.write('no-');
+        }
+        buffer.write(retentionFlags[j]);
+        flags.add(buffer.toString());
+      }
+      await testTracePrecompiler(scriptDill, flags);
+    }
+  });
+}
+
+const _jsonHeaders = {'JSON for function decisions: '};
+
+Future<void> testTracePrecompiler(String scriptDill, List<String> flags) async {
+  final result = await runHelper(genSnapshot, <String>[
+    ...flags,
+    '--trace-precompiler',
+    '--snapshot-kind=app-aot-elf',
+    '--elf=snapshot.so',
+    scriptDill,
+  ]);
+
+  Expect.equals(result.exitCode, 0);
+
+  // Tracing output is on stderr.
+  Expect.isTrue(result.stdout.isEmpty);
+  Expect.isTrue(result.stderr.isNotEmpty);
+
+  final seenHeaders = <String>{};
+  final lines =
+      Stream.value(result.stderr as String).transform(const LineSplitter());
+  await for (final s in lines) {
+    for (final header in _jsonHeaders) {
+      if (s.startsWith(header)) {
+        // We only expect a single instance of each header.
+        Expect.isFalse(seenHeaders.contains(header),
+            'multiple instances of \"$header\" seen');
+        seenHeaders.add(header);
+        final j = s.substring(header.length);
+        // For now, just test that the JSON parses and that we get back a list.
+        Expect.isTrue(json.decode(j) is List, 'not a list of decisions');
+      }
+    }
+  }
+  // Check that all headers were seen in the output.
+  for (final header in _jsonHeaders) {
+    Expect.isTrue(
+        seenHeaders.contains(header), 'no instance of \"$header\" seen');
+  }
+}
diff --git a/runtime/tools/run_clang_tidy.dart b/runtime/tools/run_clang_tidy.dart
index 5b18c61..0d9831a 100644
--- a/runtime/tools/run_clang_tidy.dart
+++ b/runtime/tools/run_clang_tidy.dart
@@ -108,12 +108,6 @@
   'runtime/vm/stack_frame_ia32.h',
   'runtime/vm/stack_frame_x64.h',
 
-  // By default the gclient checkout doesn't have llvm pulled in.
-  'runtime/llvm_codegen/bit/bit.h',
-  'runtime/llvm_codegen/bit/main.cc',
-  'runtime/llvm_codegen/bit/test.cc',
-  'runtime/llvm_codegen/codegen/main.cc',
-
   // Only available in special builds
   'runtime/bin/io_service_no_ssl.h',
   'runtime/bin/utils_win.h',
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index e0b5071..b303c7d 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -483,7 +483,7 @@
 // types in a special way). In this case subclass can set
 // kAllCanonicalObjectsAreIncludedIntoSet to |false| and override
 // IsInCanonicalSet filter.
-#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_COMPRESSED_POINTERS)
+#if !defined(DART_PRECOMPILED_RUNTIME)
 template <typename SetType,
           typename HandleType,
           typename PointerType,
@@ -5732,7 +5732,7 @@
         saved_canonical_type_arguments_(Array::Handle()),
         saved_canonical_type_parameters_(Array::Handle()) {
     saved_symbol_table_ = object_store->symbol_table();
-    if (Snapshot::IncludesCode(snapshot_kind)) {
+    if (Snapshot::IncludesStringsInROData(snapshot_kind)) {
       object_store->set_symbol_table(
           Array::Handle(HashTables::New<CanonicalStringSet>(4)));
     } else {
@@ -6634,7 +6634,8 @@
     cid = object->GetClassId();
     is_canonical = object->untag()->IsCanonical();
   }
-  if (Snapshot::IncludesCode(kind_) && is_canonical && IsStringClassId(cid) &&
+  if (Snapshot::IncludesStringsInROData(kind_) && is_canonical &&
+      IsStringClassId(cid) &&
       current_loading_unit_id_ <= LoadingUnit::kRootId) {
     cid = kStringCid;
   }
@@ -7698,7 +7699,7 @@
   serializer.WriteVersionAndFeatures(true);
   VMSerializationRoots roots(
       Array::Handle(Dart::vm_isolate_group()->object_store()->symbol_table()),
-      /*should_write_symbols=*/!Snapshot::IncludesCode(kind_));
+      /*should_write_symbols=*/!Snapshot::IncludesStringsInROData(kind_));
   ZoneGrowableArray<Object*>* objects = serializer.Serialize(&roots);
   serializer.FillHeader(serializer.kind());
   clustered_vm_size_ = serializer.bytes_written();
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 4c05ba8..460c9e0 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -102,6 +102,52 @@
 
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
 
+// Reasons for retaining a given object.
+struct RetainReasons : public AllStatic {
+  // The LLVM pools are active and the object appears in one of them.
+  static constexpr const char* kLLVMPool = "llvm pool";
+  // The object is an invoke field dispatcher.
+  static constexpr const char* kInvokeFieldDispatcher =
+      "invoke field dispatcher";
+  // The object is a dynamic invocation forwarder.
+  static constexpr const char* kDynamicInvocationForwarder =
+      "dynamic invocation forwarder";
+  // The object is a method extractor.
+  static constexpr const char* kMethodExtractor = "method extractor";
+  // The object is for a compiled implicit closure.
+  static constexpr const char* kImplicitClosure = "implicit closure";
+  // The object is a local closure.
+  static constexpr const char* kLocalClosure = "local closure";
+  // The object is the initializer for a static field.
+  static constexpr const char* kStaticFieldInitializer =
+      "static field initializer";
+  // The object is the initializer for a late field.
+  static constexpr const char* kLateFieldInitializer = "late field initializer";
+  // The object is an implicit getter.
+  static constexpr const char* kImplicitGetter = "implicit getter";
+  // The object is an implicit setter.
+  static constexpr const char* kImplicitSetter = "implicit setter";
+  // The object is an implicit static getter.
+  static constexpr const char* kImplicitStaticGetter = "implicit static getter";
+  // The object is a function that is called through a getter method.
+  static constexpr const char* kCalledThroughGetter = "called through getter";
+  // The object is a function that is called via selector.
+  static constexpr const char* kCalledViaSelector = "called via selector";
+  // The object is a function and the flag --retain-function-objects is enabled.
+  static constexpr const char* kForcedRetain = "forced via flag";
+  // The object is a function and symbolic stack traces are enabled.
+  static constexpr const char* kSymbolicStackTraces =
+      "needed for symbolic stack traces";
+  // The object is a function that is only used via its implicit closure
+  // function, into which it was inlined.
+  static constexpr const char* kInlinedIntoICF =
+      "inlined into implicit closure function";
+  // The object is a parent function function of a non-inlined local function.
+  static constexpr const char* kLocalParent = "parent of a local function";
+  // The object has an entry point pragma that requires it be retained.
+  static constexpr const char* kEntryPointPragma = "entry point pragma";
+};
+
 class PrecompileParsedFunctionHelper : public ValueObject {
  public:
   PrecompileParsedFunctionHelper(Precompiler* precompiler,
@@ -211,6 +257,12 @@
     StackZone stack_zone(T);
     zone_ = stack_zone.GetZone();
 
+    if (FLAG_trace_precompiler) {
+      // Set up the retained reasons map now that the precompiler has an
+      // appropriate zone.
+      retained_reasons_map_ = new (Z) RetainedReasonsMap(Z);
+    }
+
     if (FLAG_use_bare_instructions) {
       // Since we keep the object pool until the end of AOT compilation, it
       // will hang on to its entries until the very end. Therefore we have
@@ -385,7 +437,7 @@
             } else if (object.IsField()) {
               AddField(Field::Cast(object));
             } else if (object.IsFunction()) {
-              AddFunction(Function::Cast(object));
+              AddFunction(Function::Cast(object), RetainReasons::kLLVMPool);
             }
           }
 
@@ -394,7 +446,7 @@
           auto& function = Function::Handle(Z);
           for (intptr_t i = 0; i < function_pool.Length(); i++) {
             function ^= function_pool.At(i);
-            AddFunction(function);
+            AddFunction(function, RetainReasons::kLLVMPool);
           }
         }
       }
@@ -627,7 +679,7 @@
                 THR_Print("Added invoke-field-dispatcher for %s to %s\n",
                           field_name.ToCString(), subcls.ToCString());
               }
-              AddFunction(dispatcher);
+              AddFunction(dispatcher, RetainReasons::kInvokeFieldDispatcher);
             }
           }
         }
@@ -680,7 +732,9 @@
   for (auto& view : static_calls) {
     entry = view.Get<Code::kSCallTableFunctionTarget>();
     if (entry.IsFunction()) {
-      AddFunction(Function::Cast(entry), FLAG_retain_function_objects);
+      AddFunction(Function::Cast(entry), FLAG_retain_function_objects
+                                             ? RetainReasons::kForcedRetain
+                                             : nullptr);
       ASSERT(view.Get<Code::kSCallTableCodeOrTypeTarget>() == Code::null());
       continue;
     }
@@ -726,7 +780,7 @@
         Array::Handle(Z, code.inlined_id_to_function());
     for (intptr_t i = 0; i < inlined_functions.Length(); i++) {
       target ^= inlined_functions.At(i);
-      AddTypesOf(target);
+      AddFunction(target, RetainReasons::kSymbolicStackTraces);
     }
   }
 }
@@ -770,7 +824,7 @@
   } else if (entry.IsFunction()) {
     // Local closure function.
     const auto& target = Function::Cast(entry);
-    AddFunction(target);
+    AddFunction(target, RetainReasons::kLocalClosure);
   } else if (entry.IsCode()) {
     const auto& target_code = Code::Cast(entry);
     if (target_code.IsAllocationStubCode()) {
@@ -798,8 +852,26 @@
   AddType(type);
 }
 
+void Precompiler::AddRetainReason(const Object& obj, const char* reason) {
+  if (!FLAG_trace_precompiler) return;
+  if (auto const kv = retained_reasons_map_->Lookup(&obj)) {
+    if (kv->value->Lookup(reason) == nullptr) {
+      kv->value->Insert(reason);
+    }
+    return;
+  }
+  auto const key = &Object::ZoneHandle(Z, obj.ptr());
+  auto const value = new (Z) ZoneCStringSet(Z);
+  value->Insert(reason);
+  retained_reasons_map_->Insert(RetainedReasonsTrait::Pair(key, value));
+}
+
 void Precompiler::AddTypesOf(const Function& function) {
   if (function.IsNull()) return;
+  if (FLAG_trace_precompiler &&
+      retained_reasons_map_->Lookup(&function) == nullptr) {
+    FATAL("no retaining reasons given");
+  }
   if (functions_to_retain_.ContainsKey(function)) return;
   functions_to_retain_.Insert(function);
 
@@ -838,6 +910,7 @@
   // remain.
   const Function& parent = Function::Handle(Z, function.parent_function());
   if (!parent.IsNull()) {
+    AddRetainReason(parent, RetainReasons::kLocalParent);
     AddTypesOf(parent);
   }
   // A class may have all functions inlined except a local function.
@@ -930,7 +1003,7 @@
     const Function& func =
         Function::Handle(Z, Closure::Cast(instance).function());
     ASSERT(func.is_static());
-    AddFunction(func);
+    AddFunction(func, RetainReasons::kImplicitClosure);
     AddTypeArguments(TypeArguments::Handle(
         Z, Closure::Cast(instance).instantiator_type_arguments()));
     AddTypeArguments(TypeArguments::Handle(
@@ -1014,7 +1087,7 @@
                               call_selector, arguments_descriptor,
                               UntaggedFunction::kInvokeFieldDispatcher,
                               true /* create_if_absent */));
-  AddFunction(dispatcher);
+  AddFunction(dispatcher, RetainReasons::kInvokeFieldDispatcher);
 }
 
 void Precompiler::AddField(const Field& field) {
@@ -1043,11 +1116,14 @@
       (field.is_static() || field.is_late())) {
     const Function& initializer =
         Function::ZoneHandle(Z, field.EnsureInitializerFunction());
-    AddFunction(initializer);
+    const char* const reason = field.is_static()
+                                   ? RetainReasons::kStaticFieldInitializer
+                                   : RetainReasons::kLateFieldInitializer;
+    AddFunction(initializer, reason);
   }
 }
 
-bool Precompiler::MustRetainFunction(const Function& function) {
+const char* Precompiler::MustRetainFunction(const Function& function) {
   // There are some cases where we must retain, even if there are no directly
   // observable need for function objects at runtime. Here, we check for cases
   // where the function is not marked with the vm:entry-point pragma, which also
@@ -1057,42 +1133,57 @@
   // * Selector matches a symbol used in Resolver::ResolveDynamic calls
   //   in dart_entry.cc or dart_api_impl.cc.
   // * _Closure.call (used in async stack handling)
-  if (function.is_native()) return true;
+  if (function.is_native()) {
+    return "native function";
+  }
 
   // Resolver::ResolveDynamic uses.
   const auto& selector = String::Handle(Z, function.name());
-  if (selector.ptr() == Symbols::toString().ptr()) return true;
-  if (selector.ptr() == Symbols::AssignIndexToken().ptr()) return true;
-  if (selector.ptr() == Symbols::IndexToken().ptr()) return true;
-  if (selector.ptr() == Symbols::hashCode().ptr()) return true;
-  if (selector.ptr() == Symbols::NoSuchMethod().ptr()) return true;
-  if (selector.ptr() == Symbols::EqualOperator().ptr()) return true;
+  if (selector.ptr() == Symbols::toString().ptr() ||
+      selector.ptr() == Symbols::AssignIndexToken().ptr() ||
+      selector.ptr() == Symbols::IndexToken().ptr() ||
+      selector.ptr() == Symbols::hashCode().ptr() ||
+      selector.ptr() == Symbols::NoSuchMethod().ptr() ||
+      selector.ptr() == Symbols::EqualOperator().ptr()) {
+    return "used by VM in Resolver::ResolveDynamic call";
+  }
 
   // Use the same check for _Closure.call as in stack_trace.{h|cc}.
   if (selector.ptr() == Symbols::Call().ptr()) {
     const auto& name = String::Handle(Z, function.QualifiedScrubbedName());
-    if (name.Equals(Symbols::_ClosureCall())) return true;
+    if (name.Equals(Symbols::_ClosureCall())) {
+      return "_Closure.call";
+    }
   }
 
   // We have to retain functions which can be a target of a SwitchableCall
   // at AOT runtime, since the AOT runtime needs to be able to find the
   // function object in the class.
-  if (function.NeedsMonomorphicCheckedEntry(Z) ||
-      Function::IsDynamicInvocationForwarderName(function.name())) {
-    return true;
+  if (function.NeedsMonomorphicCheckedEntry(Z)) {
+    return "needs monomorphic checked entry";
+  }
+  if (Function::IsDynamicInvocationForwarderName(function.name())) {
+    return "dynamic invocation forwarder";
   }
 
-  return false;
+  return nullptr;
 }
 
-void Precompiler::AddFunction(const Function& function, bool retain) {
+void Precompiler::AddFunction(const Function& function,
+                              const char* retain_reason) {
   if (is_tracing()) {
     tracer_->WriteFunctionRef(function);
   }
 
-  if (possibly_retained_functions_.ContainsKey(function)) return;
+  if (retain_reason == nullptr) {
+    retain_reason = MustRetainFunction(function);
+  }
+  if (retain_reason != nullptr) {
+    AddRetainReason(function, retain_reason);
+  }
 
-  if (retain || MustRetainFunction(function)) {
+  if (possibly_retained_functions_.ContainsKey(function)) return;
+  if (retain_reason != nullptr) {
     possibly_retained_functions_.Insert(function);
   }
 
@@ -1251,7 +1342,7 @@
 
           if (type == EntryPointPragma::kAlways ||
               type == EntryPointPragma::kCallOnly) {
-            AddFunction(function);
+            AddFunction(function, RetainReasons::kEntryPointPragma);
             entry_point_functions_.Insert(function);
           }
 
@@ -1260,7 +1351,7 @@
               function.kind() != UntaggedFunction::kConstructor &&
               !function.IsSetterFunction()) {
             function2 = function.ImplicitClosureFunction();
-            AddFunction(function2);
+            AddFunction(function2, RetainReasons::kEntryPointPragma);
             entry_point_functions_.Insert(function2);
           }
 
@@ -1274,7 +1365,7 @@
           for (intptr_t i = 0; i < implicit_getters.Length(); ++i) {
             field ^= implicit_getters.At(i);
             if (function.accessor_field() == field.ptr()) {
-              AddFunction(function);
+              AddFunction(function, RetainReasons::kImplicitGetter);
               entry_point_functions_.Insert(function);
             }
           }
@@ -1284,7 +1375,7 @@
           for (intptr_t i = 0; i < implicit_setters.Length(); ++i) {
             field ^= implicit_setters.At(i);
             if (function.accessor_field() == field.ptr()) {
-              AddFunction(function);
+              AddFunction(function, RetainReasons::kImplicitSetter);
               entry_point_functions_.Insert(function);
             }
           }
@@ -1294,7 +1385,7 @@
           for (intptr_t i = 0; i < implicit_static_getters.Length(); ++i) {
             field ^= implicit_static_getters.At(i);
             if (function.accessor_field() == field.ptr()) {
-              AddFunction(function);
+              AddFunction(function, RetainReasons::kImplicitStaticGetter);
               entry_point_functions_.Insert(function);
             }
           }
@@ -1339,10 +1430,12 @@
 
         selector = function.name();
         if (IsSent(selector)) {
-          AddFunction(function);
+          AddFunction(function, RetainReasons::kCalledViaSelector);
         }
         if (IsHitByTableSelector(function)) {
-          AddFunction(function, FLAG_retain_function_objects);
+          AddFunction(function, FLAG_retain_function_objects
+                                    ? RetainReasons::kForcedRetain
+                                    : nullptr);
         }
 
         bool found_metadata = false;
@@ -1359,14 +1452,14 @@
           // method foo first.
           selector2 = Field::NameFromGetter(selector);
           if (IsSent(selector2)) {
-            AddFunction(function);
+            AddFunction(function, RetainReasons::kCalledThroughGetter);
           }
           selector2 = Function::CreateDynamicInvocationForwarderName(selector2);
           if (IsSent(selector2)) {
             selector2 =
                 Function::CreateDynamicInvocationForwarderName(selector);
             function2 = function.GetDynamicInvocationForwarder(selector2);
-            AddFunction(function2);
+            AddFunction(function2, RetainReasons::kDynamicInvocationForwarder);
           }
         } else if (function.kind() == UntaggedFunction::kRegularFunction) {
           selector2 = Field::LookupGetterSymbol(selector);
@@ -1383,11 +1476,11 @@
               // Closurization.
               // Function is foo and somewhere get:foo is called.
               function2 = function.ImplicitClosureFunction();
-              AddFunction(function2);
+              AddFunction(function2, RetainReasons::kImplicitClosure);
 
               // Add corresponding method extractor.
               function2 = function.GetMethodExtractor(selector2);
-              AddFunction(function2);
+              AddFunction(function2, RetainReasons::kMethodExtractor);
             }
           }
         }
@@ -1414,12 +1507,14 @@
             if (is_getter) {
               if (metadata.getter_called_dynamically) {
                 function2 = function.GetDynamicInvocationForwarder(selector2);
-                AddFunction(function2);
+                AddFunction(function2,
+                            RetainReasons::kDynamicInvocationForwarder);
               }
             } else {
               if (metadata.method_or_setter_called_dynamically) {
                 function2 = function.GetDynamicInvocationForwarder(selector2);
-                AddFunction(function2);
+                AddFunction(function2,
+                            RetainReasons::kDynamicInvocationForwarder);
               }
             }
           }
@@ -1606,6 +1701,9 @@
           // static calls, etc.
           function2 = function.ImplicitClosureFunction();
           retain = function2.HasCode();
+          if (retain) {
+            AddRetainReason(function, RetainReasons::kInlinedIntoICF);
+          }
         }
         if (retain) {
           function.DropUncompiledImplicitClosureFunction();
@@ -1642,6 +1740,7 @@
       // parents and their enclosing classes and libraries.
       parent_function = function.parent_function();
       while (!parent_function.IsNull()) {
+        AddRetainReason(parent_function, RetainReasons::kLocalParent);
         AddTypesOf(parent_function);
         parent_function = parent_function.parent_function();
       }
@@ -1772,6 +1871,38 @@
   Code& code = Code::Handle(Z);
   Object& owner = Object::Handle(Z);
   GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z);
+  JSONWriter json;
+
+  if (FLAG_trace_precompiler) {
+    json.OpenArray();
+  }
+
+  auto retain_function = [&](const Function& function) {
+    if (FLAG_trace_precompiler) {
+      auto const name = function.ToLibNamePrefixedQualifiedCString();
+      auto const kind = UntaggedFunction::KindToCString(function.kind());
+      json.OpenObject();
+      json.PrintProperty("name", name);
+      json.PrintProperty("kind", kind);
+      json.PrintPropertyBool("retained", true);
+      LogBlock lb;
+      THR_Print("Retaining %s function %s\n", kind, name);
+      json.OpenArray("reasons");
+      if (auto const kv = retained_reasons_map_->Lookup(&function)) {
+        auto it = kv->value->GetIterator();
+        for (auto cstrp = it.Next(); cstrp != nullptr; cstrp = it.Next()) {
+          ASSERT(*cstrp != nullptr);
+          json.PrintValue(*cstrp);
+          THR_Print("Reason: %s\n", *cstrp);
+        }
+      } else {
+        THR_Print("No reasons recorded\n");
+      }
+      json.CloseArray();
+      json.CloseObject();
+    }
+    retained_functions.Add(function);
+  };
 
   auto drop_function = [&](const Function& function) {
     if (function.HasCode()) {
@@ -1786,8 +1917,14 @@
     }
     dropped_function_count_++;
     if (FLAG_trace_precompiler) {
-      THR_Print("Dropping function %s\n",
-                function.ToLibNamePrefixedQualifiedCString());
+      auto const name = function.ToLibNamePrefixedQualifiedCString();
+      auto const kind = UntaggedFunction::KindToCString(function.kind());
+      json.OpenObject();
+      json.PrintProperty("name", name);
+      json.PrintProperty("kind", kind);
+      json.PrintPropertyBool("retained", false);
+      json.CloseObject();
+      THR_Print("Dropping %s function %s\n", kind, name);
     }
   };
 
@@ -1806,7 +1943,7 @@
         function ^= functions.At(j);
         function.DropUncompiledImplicitClosureFunction();
         if (functions_to_retain_.ContainsKey(function)) {
-          retained_functions.Add(function);
+          retain_function(function);
         } else {
           drop_function(function);
         }
@@ -1831,7 +1968,7 @@
           if (functions_to_retain_.ContainsKey(function)) {
             retained_functions.Add(name);
             retained_functions.Add(desc);
-            retained_functions.Add(function);
+            retain_function(function);
           } else {
             drop_function(function);
           }
@@ -1853,13 +1990,18 @@
   retained_functions = GrowableObjectArray::New();
   ClosureFunctionsCache::ForAllClosureFunctions([&](const Function& function) {
     if (functions_to_retain_.ContainsKey(function)) {
-      retained_functions.Add(function);
+      retain_function(function);
     } else {
       drop_function(function);
     }
     return true;  // Continue iteration.
   });
   IG->object_store()->set_closure_functions(retained_functions);
+
+  if (FLAG_trace_precompiler) {
+    json.CloseArray();
+    THR_Print("JSON for function decisions: %s\n", json.ToCString());
+  }
 }
 
 void Precompiler::DropFields() {
@@ -1867,6 +2009,7 @@
   Class& cls = Class::Handle(Z);
   Array& fields = Array::Handle(Z);
   Field& field = Field::Handle(Z);
+  Function& function = Function::Handle(Z);
   GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z);
   AbstractType& type = AbstractType::Handle(Z);
 
@@ -1888,13 +2031,32 @@
         }
 #endif
         if (retain) {
+          if (FLAG_trace_precompiler) {
+            function = field.InitializerFunction();
+            if (!function.IsNull()) {
+              THR_Print("Retaining initializer function for %s field %s\n",
+                        field.is_static() ? "static" : "instance",
+                        function.ToLibNamePrefixedQualifiedCString());
+            }
+            THR_Print("Retaining %s field %s\n",
+                      field.is_static() ? "static" : "instance",
+                      field.ToCString());
+          }
           retained_fields.Add(field);
           type = field.type();
           AddType(type);
         } else {
           dropped_field_count_++;
           if (FLAG_trace_precompiler) {
-            THR_Print("Dropping field %s\n", field.ToCString());
+            function = field.InitializerFunction();
+            if (!function.IsNull()) {
+              THR_Print("Dropping initializer function for %s field %s\n",
+                        field.is_static() ? "static" : "instance",
+                        function.ToLibNamePrefixedQualifiedCString());
+            }
+            THR_Print("Dropping %s field %s\n",
+                      field.is_static() ? "static" : "instance",
+                      field.ToCString());
           }
 
           // This cleans up references to field current and initial values.
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 4544053..01e2892 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -295,6 +295,7 @@
   void AddAnnotatedRoots();
   void Iterate();
 
+  void AddRetainReason(const Object& obj, const char* reason);
   void AddType(const AbstractType& type);
   void AddTypesOf(const Class& cls);
   void AddTypesOf(const Function& function);
@@ -306,12 +307,13 @@
   void AddConstObject(const class Instance& instance);
   void AddClosureCall(const String& selector,
                       const Array& arguments_descriptor);
-  void AddFunction(const Function& function, bool retain = true);
+  void AddFunction(const Function& function, const char* retain_reason);
   void AddInstantiatedClass(const Class& cls);
   void AddSelector(const String& selector);
   bool IsSent(const String& selector);
   bool IsHitByTableSelector(const Function& function);
-  bool MustRetainFunction(const Function& function);
+  // Returns the reason if the function must be retained, otherwise nullptr.
+  const char* MustRetainFunction(const Function& function);
 
   void ProcessFunction(const Function& function);
   void CheckForNewDynamicFunctions();
@@ -355,6 +357,39 @@
   Isolate* isolate() const { return isolate_; }
   IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
 
+  struct RetainedReasonsTrait {
+    using Key = const Object*;
+    using Value = ZoneCStringSet*;
+
+    struct Pair {
+      Key key;
+      Value value;
+
+      Pair() : key(nullptr), value(nullptr) {}
+      Pair(Key key, Value value) : key(key), value(value) {}
+    };
+
+    static Key KeyOf(Pair kv) { return kv.key; }
+
+    static Value ValueOf(Pair kv) { return kv.value; }
+
+    static inline intptr_t Hashcode(Key key) {
+      if (key->IsFunction()) {
+        return Function::Cast(*key).Hash();
+      }
+      if (key->IsClass()) {
+        return Utils::WordHash(Class::Cast(*key).id());
+      }
+      return Utils::WordHash(key->GetClassId());
+    }
+
+    static inline bool IsKeyEqual(Pair pair, Key key) {
+      return pair.key->ptr() == key->ptr();
+    }
+  };
+
+  using RetainedReasonsMap = ZoneDirectChainedHashMap<RetainedReasonsTrait>;
+
   Thread* thread_;
   Zone* zone_;
   Isolate* isolate_;
@@ -383,6 +418,7 @@
   FunctionSet possibly_retained_functions_;
   FieldSet fields_to_retain_;
   FunctionSet functions_to_retain_;
+  RetainedReasonsMap* retained_reasons_map_ = nullptr;
   ClassSet classes_to_retain_;
   TypeArgumentsSet typeargs_to_retain_;
   AbstractTypeSet types_to_retain_;
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 2759abd..0a64dc3 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -4504,23 +4504,6 @@
   return locs;
 }
 
-void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Check that the type of the value is allowed in conditional context.
-  ASSERT(locs()->always_calls());
-
-  auto object_store = compiler->isolate_group()->object_store();
-  const auto& assert_boolean_stub =
-      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
-
-  compiler::Label done;
-  __ CompareObject(AssertBooleanABI::kObjectReg, Object::null_instance());
-  __ BranchIf(NOT_EQUAL, &done);
-  compiler->GenerateStubCall(source(), assert_boolean_stub,
-                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
-                             deopt_id());
-  __ Bind(&done);
-}
-
 LocationSummary* PhiInstr::MakeLocationSummary(Zone* zone,
                                                bool optimizing) const {
   UNREACHABLE();
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 5d9b0e9..d795185 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -822,6 +822,23 @@
   return summary;
 }
 
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ tst(AssertBooleanABI::kObjectReg,
+         compiler::Operand(compiler::target::ObjectAlignment::kBoolVsNullMask));
+  __ b(&done, NOT_ZERO);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
 static Condition TokenKindToSmiCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -7895,16 +7912,8 @@
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register input = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    __ eor(
-        result, input,
-        compiler::Operand(compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    __ LoadObject(result, Bool::True());
-    __ cmp(result, compiler::Operand(input));
-    __ LoadObject(result, Bool::False(), EQ);
-  }
+  __ eor(result, input,
+         compiler::Operand(compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 5f4a51c..d3c8abb 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -720,6 +720,21 @@
   return summary;
 }
 
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ tbnz(&done, AssertBooleanABI::kObjectReg, kBoolVsNullBitPosition);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
 static Condition TokenKindToSmiCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -6925,17 +6940,9 @@
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register input = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    __ eori(
-        result, input,
-        compiler::Immediate(compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    __ LoadObject(result, Bool::True());
-    __ LoadObject(TMP, Bool::False());
-    __ CompareRegisters(result, input);
-    __ csel(result, TMP, result, EQ);
-  }
+  __ eori(
+      result, input,
+      compiler::Immediate(compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index e192ce4..45a2ad9 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -508,6 +508,24 @@
   return summary;
 }
 
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ testl(
+      AssertBooleanABI::kObjectReg,
+      compiler::Immediate(compiler::target::ObjectAlignment::kBoolVsNullMask));
+  __ j(NOT_ZERO, &done, compiler::Assembler::kNearJump);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
 static Condition TokenKindToSmiCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -6836,30 +6854,16 @@
 
 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
-  return LocationSummary::Make(zone, 1,
-                               value()->Type()->ToCid() == kBoolCid
-                                   ? Location::SameAsFirstInput()
-                                   : Location::RequiresRegister(),
+  return LocationSummary::Make(zone, 1, Location::SameAsFirstInput(),
                                LocationSummary::kNoCall);
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register input = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    ASSERT(input == result);
-    __ xorl(result, compiler::Immediate(
-                        compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    ASSERT(input != result);
-    compiler::Label done;
-    __ LoadObject(result, Bool::True());
-    __ CompareRegisters(result, input);
-    __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-    __ LoadObject(result, Bool::False());
-    __ Bind(&done);
-  }
+  ASSERT(input == result);
+  __ xorl(result, compiler::Immediate(
+                      compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index a42852b..971d6cc 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -656,6 +656,24 @@
   return summary;
 }
 
+void AssertBooleanInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(locs()->always_calls());
+
+  auto object_store = compiler->isolate_group()->object_store();
+  const auto& assert_boolean_stub =
+      Code::ZoneHandle(compiler->zone(), object_store->assert_boolean_stub());
+
+  compiler::Label done;
+  __ testq(
+      AssertBooleanABI::kObjectReg,
+      compiler::Immediate(compiler::target::ObjectAlignment::kBoolVsNullMask));
+  __ j(NOT_ZERO, &done, compiler::Assembler::kNearJump);
+  compiler->GenerateStubCall(source(), assert_boolean_stub,
+                             /*kind=*/UntaggedPcDescriptors::kOther, locs(),
+                             deopt_id());
+  __ Bind(&done);
+}
+
 static Condition TokenKindToIntCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ:
@@ -861,7 +879,6 @@
   if (true_condition != kInvalidCondition) {
     EmitBranchOnCondition(compiler, true_condition, labels);
   }
-
   Register result = locs()->out(0).reg();
   compiler::Label done;
   __ Bind(&is_false);
@@ -7417,30 +7434,16 @@
 
 LocationSummary* BooleanNegateInstr::MakeLocationSummary(Zone* zone,
                                                          bool opt) const {
-  return LocationSummary::Make(zone, 1,
-                               value()->Type()->ToCid() == kBoolCid
-                                   ? Location::SameAsFirstInput()
-                                   : Location::RequiresRegister(),
+  return LocationSummary::Make(zone, 1, Location::SameAsFirstInput(),
                                LocationSummary::kNoCall);
 }
 
 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register input = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
-
-  if (value()->Type()->ToCid() == kBoolCid) {
-    ASSERT(input == result);
-    __ xorq(result, compiler::Immediate(
-                        compiler::target::ObjectAlignment::kBoolValueMask));
-  } else {
-    ASSERT(input != result);
-    compiler::Label done;
-    __ LoadObject(result, Bool::True());
-    __ CompareRegisters(result, input);
-    __ j(NOT_EQUAL, &done, compiler::Assembler::kNearJump);
-    __ LoadObject(result, Bool::False());
-    __ Bind(&done);
-  }
+  ASSERT(input == result);
+  __ xorq(result, compiler::Immediate(
+                      compiler::target::ObjectAlignment::kBoolValueMask));
 }
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Zone* zone,
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 580d5e9..8fcc8b9 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6278,29 +6278,33 @@
 #endif
 }
 
-DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
-                                                  const char* event_kind,
-                                                  const uint8_t* bytes,
-                                                  intptr_t bytes_length) {
+DART_EXPORT char* Dart_ServiceSendDataEvent(const char* stream_id,
+                                            const char* event_kind,
+                                            const uint8_t* bytes,
+                                            intptr_t bytes_length) {
 #if !defined(PRODUCT)
-  DARTSCOPE(Thread::Current());
-  Isolate* I = T->isolate();
   if (stream_id == NULL) {
-    RETURN_NULL_ERROR(stream_id);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'stream_id' to be "
+        "non-null.");
   }
   if (event_kind == NULL) {
-    RETURN_NULL_ERROR(event_kind);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'event_kind' to be "
+        "non-null.");
   }
   if (bytes == NULL) {
-    RETURN_NULL_ERROR(bytes);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'bytes' to be non-null.");
   }
   if (bytes_length < 0) {
-    return Api::NewError("%s expects argument 'bytes_length' to be >= 0.",
-                         CURRENT_FUNC);
+    return Utils::StrDup(
+        "Dart_ServiceSendDataEvent expects argument 'bytes_length' to be >= "
+        "0.");
   }
-  Service::SendEmbedderEvent(I, stream_id, event_kind, bytes, bytes_length);
+  Service::SendEmbedderEvent(stream_id, event_kind, bytes, bytes_length);
 #endif
-  return Api::Success();
+  return nullptr;
 }
 
 DART_EXPORT void Dart_SetGCEventCallback(Dart_GCEventCallback callback) {
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 88d58ba..5af4c15 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -5,6 +5,7 @@
 #ifndef RUNTIME_VM_HASH_MAP_H_
 #define RUNTIME_VM_HASH_MAP_H_
 
+#include "platform/utils.h"
 #include "vm/growable_array.h"  // For Malloc, EmptyBase
 #include "vm/hash.h"
 #include "vm/zone.h"
@@ -439,6 +440,20 @@
   void operator=(const MallocDirectChainedHashMap& other) = delete;
 };
 
+template <typename KeyValueTrait>
+class ZoneDirectChainedHashMap
+    : public BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone> {
+ public:
+  ZoneDirectChainedHashMap()
+      : BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone>(
+            ThreadState::Current()->zone()) {}
+  explicit ZoneDirectChainedHashMap(Zone* zone)
+      : BaseDirectChainedHashMap<KeyValueTrait, ZoneAllocated, Zone>(zone) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ZoneDirectChainedHashMap);
+};
+
 template <typename T>
 class PointerKeyValueTrait {
  public:
@@ -489,8 +504,47 @@
   static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
 };
 
+class CStringSetKeyValueTrait : public PointerKeyValueTrait<const char> {
+ public:
+  using Key = PointerKeyValueTrait<const char>::Key;
+  using Value = PointerKeyValueTrait<const char>::Value;
+  using Pair = PointerKeyValueTrait<const char>::Pair;
+
+  static intptr_t Hashcode(Key key) {
+    ASSERT(key != nullptr);
+    return Utils::StringHash(key, strlen(key));
+  }
+  static bool IsKeyEqual(Pair kv, Key key) {
+    ASSERT(kv != nullptr && key != nullptr);
+    return kv == key || strcmp(kv, key) == 0;
+  }
+};
+
+template <typename B, typename Allocator>
+class BaseCStringSet
+    : public BaseDirectChainedHashMap<CStringSetKeyValueTrait, B, Allocator> {
+ public:
+  explicit BaseCStringSet(Allocator* allocator)
+      : BaseDirectChainedHashMap<CStringSetKeyValueTrait, B, Allocator>(
+            allocator) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BaseCStringSet);
+};
+
+class ZoneCStringSet : public BaseCStringSet<ZoneAllocated, Zone> {
+ public:
+  ZoneCStringSet()
+      : BaseCStringSet<ZoneAllocated, Zone>(ThreadState::Current()->zone()) {}
+  explicit ZoneCStringSet(Zone* zone)
+      : BaseCStringSet<ZoneAllocated, Zone>(zone) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ZoneCStringSet);
+};
+
 template <typename V>
-class CStringKeyValueTrait : public RawPointerKeyValueTrait<const char, V> {
+class CStringMapKeyValueTrait : public RawPointerKeyValueTrait<const char, V> {
  public:
   typedef typename RawPointerKeyValueTrait<const char, V>::Key Key;
   typedef typename RawPointerKeyValueTrait<const char, V>::Value Value;
@@ -498,11 +552,7 @@
 
   static intptr_t Hashcode(Key key) {
     ASSERT(key != nullptr);
-    intptr_t hash = 0;
-    for (size_t i = 0; i < strlen(key); i++) {
-      hash = CombineHashes(hash, key[i]);
-    }
-    return FinalizeHash(hash, kBitsPerWord - 1);
+    return Utils::StringHash(key, strlen(key));
   }
   static bool IsKeyEqual(Pair kv, Key key) {
     ASSERT(kv.key != nullptr && key != nullptr);
@@ -510,12 +560,27 @@
   }
 };
 
-template <typename V>
-class CStringMap : public DirectChainedHashMap<CStringKeyValueTrait<V>> {
+template <typename V, typename B, typename Allocator>
+class BaseCStringMap
+    : public BaseDirectChainedHashMap<CStringMapKeyValueTrait<V>,
+                                      B,
+                                      Allocator> {
  public:
-  CStringMap() : DirectChainedHashMap<CStringKeyValueTrait<V>>() {}
+  explicit BaseCStringMap(Allocator* allocator)
+      : BaseDirectChainedHashMap<CStringMapKeyValueTrait<V>, B, Allocator>(
+            allocator) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BaseCStringMap);
+};
+
+template <typename V>
+class CStringMap : public BaseCStringMap<V, ValueObject, Zone> {
+ public:
+  CStringMap()
+      : BaseCStringMap<V, ValueObject, Zone>(ThreadState::Current()->zone()) {}
   explicit CStringMap(Zone* zone)
-      : DirectChainedHashMap<CStringKeyValueTrait<V>>(zone) {}
+      : BaseCStringMap<V, ValueObject, Zone>(zone) {}
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CStringMap);
diff --git a/runtime/vm/hash_map_test.cc b/runtime/vm/hash_map_test.cc
index b6d6f57..27385d9 100644
--- a/runtime/vm/hash_map_test.cc
+++ b/runtime/vm/hash_map_test.cc
@@ -114,6 +114,22 @@
   EXPECT(map2.LookupValue(&v3) == &v1);
 }
 
+TEST_CASE(ZoneDirectChainedHashMap) {
+  auto zone = thread->zone();
+  auto const map = new (zone)
+      ZoneDirectChainedHashMap<PointerKeyValueTrait<TestValue>>(zone);
+  EXPECT(map->IsEmpty());
+  TestValue v1(0);
+  TestValue v2(1);
+  TestValue v3(0);
+  map->Insert(&v1);
+  EXPECT(map->LookupValue(&v1) == &v1);
+  map->Insert(&v2);
+  EXPECT(map->LookupValue(&v1) == &v1);
+  EXPECT(map->LookupValue(&v2) == &v2);
+  EXPECT(map->LookupValue(&v3) == &v1);
+}
+
 class IntptrPair {
  public:
   IntptrPair() : first_(-1), second_(-1) {}
@@ -206,6 +222,43 @@
   }
 }
 
+TEST_CASE(ZoneCStringSet) {
+  auto zone = thread->zone();
+
+  const char* const kConst1 = "test";
+  const char* const kConst2 = "test 2";
+
+  char* const str1 = OS::SCreate(zone, "%s", kConst1);
+  char* const str2 = OS::SCreate(zone, "%s", kConst2);
+  char* const str3 = OS::SCreate(zone, "%s", kConst1);
+
+  // Make sure these strings are pointer-distinct, but C-string-equal.
+  EXPECT_NE(str1, str3);
+  EXPECT_STREQ(str1, str3);
+
+  auto const set = new (zone) ZoneCStringSet(zone);
+  EXPECT(set->IsEmpty());
+
+  set->Insert(str1);
+  EXPECT_NOTNULL(set->Lookup(str1));
+  EXPECT_NULLPTR(set->Lookup(str2));
+  EXPECT_NOTNULL(set->Lookup(str3));
+
+  set->Insert(str2);
+  EXPECT_NOTNULL(set->Lookup(str1));
+  EXPECT_NOTNULL(set->Lookup(str2));
+  EXPECT_NOTNULL(set->Lookup(str3));
+
+  EXPECT(set->Remove(str3));
+  EXPECT_NULLPTR(set->Lookup(str1));
+  EXPECT_NOTNULL(set->Lookup(str2));
+  EXPECT_NULLPTR(set->Lookup(str3));
+
+  EXPECT(!set->Remove(str3));
+  EXPECT(set->Remove(str2));
+  EXPECT(set->IsEmpty());
+}
+
 TEST_CASE(CStringMap) {
   const char* const kConst1 = "test";
   const char* const kConst2 = "test 2";
@@ -270,9 +323,9 @@
   EXPECT_STREQ(str1, str3);
   EXPECT_STREQ(str1, str4);
 
-  CStringKeyValueTrait<intptr_t>::Pair p1 = {str1, 1};
-  CStringKeyValueTrait<intptr_t>::Pair p2 = {str2, 2};
-  CStringKeyValueTrait<intptr_t>::Pair p3 = {str3, 3};
+  CStringMapKeyValueTrait<intptr_t>::Pair p1 = {str1, 1};
+  CStringMapKeyValueTrait<intptr_t>::Pair p2 = {str2, 2};
+  CStringMapKeyValueTrait<intptr_t>::Pair p3 = {str3, 3};
 
   CStringMap<intptr_t> map;
   EXPECT(map.IsEmpty());
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index af6332c..4d07a98 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -569,6 +569,9 @@
   ASSERT((static_cast<uword>(false_) & kBoolValueMask) != 0);
   ASSERT(static_cast<uword>(false_) ==
          (static_cast<uword>(true_) | kBoolValueMask));
+  ASSERT((static_cast<uword>(null_) & kBoolVsNullMask) == 0);
+  ASSERT((static_cast<uword>(true_) & kBoolVsNullMask) != 0);
+  ASSERT((static_cast<uword>(false_) & kBoolVsNullMask) != 0);
 }
 
 void Object::InitVtables() {
@@ -23581,23 +23584,6 @@
   return ExternalTwoByteString::raw(result);
 }
 
-BoolPtr Bool::New(bool value) {
-  ASSERT(IsolateGroup::Current()->object_store()->bool_class() !=
-         Class::null());
-  Bool& result = Bool::Handle();
-  {
-    // Since the two boolean instances are singletons we allocate them straight
-    // in the old generation.
-    ObjectPtr raw =
-        Object::Allocate(Bool::kClassId, Bool::InstanceSize(), Heap::kOld);
-    NoSafepointScope no_safepoint;
-    result ^= raw;
-  }
-  result.set_value(value);
-  result.SetCanonical();
-  return result.ptr();
-}
-
 const char* Bool::ToCString() const {
   return value() ? "true" : "false";
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index f38ceba..19f8743 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -9583,11 +9583,6 @@
   }
 
  private:
-  void set_value(bool value) const { StoreNonPointer(&untag()->value_, value); }
-
-  // New should only be called to initialize the two legal bool values.
-  static BoolPtr New(bool value);
-
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Bool, Instance);
   friend class Class;
   friend class Object;  // To initialize the true and false values.
diff --git a/runtime/vm/pointer_tagging.h b/runtime/vm/pointer_tagging.h
index a26c158..90dd053 100644
--- a/runtime/vm/pointer_tagging.h
+++ b/runtime/vm/pointer_tagging.h
@@ -37,6 +37,10 @@
   static constexpr intptr_t kBoolValueBitPosition = kObjectAlignmentLog2;
   static constexpr intptr_t kBoolValueMask = 1 << kBoolValueBitPosition;
 
+  // Discriminate between bool and null based on bit after the alignment bit.
+  static constexpr intptr_t kBoolVsNullBitPosition = kObjectAlignmentLog2 + 1;
+  static constexpr intptr_t kBoolVsNullMask = 1 << kBoolVsNullBitPosition;
+
   static constexpr intptr_t kTrueOffsetFromNull = kObjectAlignment * 2;
   static constexpr intptr_t kFalseOffsetFromNull = kObjectAlignment * 3;
 };
@@ -58,6 +62,10 @@
 static constexpr intptr_t kBoolValueBitPosition =
     HostObjectAlignment::kBoolValueBitPosition;
 static constexpr intptr_t kBoolValueMask = HostObjectAlignment::kBoolValueMask;
+static constexpr intptr_t kBoolVsNullBitPosition =
+    HostObjectAlignment::kBoolVsNullBitPosition;
+static constexpr intptr_t kBoolVsNullMask =
+    HostObjectAlignment::kBoolVsNullMask;
 static constexpr intptr_t kTrueOffsetFromNull =
     HostObjectAlignment::kTrueOffsetFromNull;
 static constexpr intptr_t kFalseOffsetFromNull =
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index ee7a7ec..e56f4eae 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -4309,12 +4309,11 @@
   Service::HandleEvent(&event);
 }
 
-void Service::SendEmbedderEvent(Isolate* isolate,
-                                const char* stream_id,
+void Service::SendEmbedderEvent(const char* stream_id,
                                 const char* event_kind,
                                 const uint8_t* bytes,
                                 intptr_t bytes_len) {
-  ServiceEvent event(isolate, ServiceEvent::kEmbedder);
+  ServiceEvent event(ServiceEvent::kEmbedder);
   event.set_embedder_kind(event_kind);
   event.set_embedder_stream_id(stream_id);
   event.set_bytes(bytes, bytes_len);
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 00a3f32..99c7e20 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -125,8 +125,7 @@
   static void SendEchoEvent(Isolate* isolate, const char* text);
   static void SendInspectEvent(Isolate* isolate, const Object& inspectee);
 
-  static void SendEmbedderEvent(Isolate* isolate,
-                                const char* stream_id,
+  static void SendEmbedderEvent(const char* stream_id,
                                 const char* event_kind,
                                 const uint8_t* bytes,
                                 intptr_t bytes_len);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 93678d0..174a88f 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -139,6 +139,14 @@
     return (kind == kFullJIT) || (kind == kFullAOT);
   }
 
+  static bool IncludesStringsInROData(Kind kind) {
+#if !defined(DART_COMPRESSED_POINTERS)
+    return IncludesCode(kind);
+#else
+    return false;
+#endif
+  }
+
   const uint8_t* Addr() const { return reinterpret_cast<const uint8_t*>(this); }
 
   const uint8_t* DataImage() const {
diff --git a/tests/language/const_functions/const_functions_local_functions_test.dart b/tests/language/const_functions/const_functions_local_functions_test.dart
new file mode 100644
index 0000000..dc3eacb
--- /dev/null
+++ b/tests/language/const_functions/const_functions_local_functions_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests local function usage, some having references to other constant values.
+
+// SharedOptions=--enable-experiment=const-functions
+
+import "package:expect/expect.dart";
+
+int function1() {
+  int add(int a, int b) => a + b;
+  const value = add(10, 2);
+  //            ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+const constTwo = 2;
+int function2() {
+  int addTwo(int a) {
+    int b = a + constTwo;
+    return b;
+  }
+
+  const value = addTwo(2);
+  //            ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function3() {
+  int addTwoReturn(int a) => a + constTwo;
+  const value = addTwoReturn(3);
+  //            ^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function4() {
+  const localTwo = 2;
+  int addTwo(int a) => a + localTwo;
+  const value = addTwo(20);
+  //            ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function5() {
+  T typeFn<T>(T a) => a;
+  const value = typeFn(3);
+  //            ^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function6() {
+  int optionalFn([int a = 0]) => a;
+  const value = optionalFn(1);
+  //            ^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+int function7() {
+  int namedFn({int a = 0}) => a;
+  const value = namedFn(a: 2);
+  //            ^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+  return value;
+}
+
+void main() {
+  Expect.equals(function1(), 12);
+  Expect.equals(function2(), 4);
+  Expect.equals(function3(), 5);
+  Expect.equals(function4(), 22);
+  Expect.equals(function5(), 3);
+  Expect.equals(function6(), 1);
+  Expect.equals(function7(), 2);
+}
diff --git a/third_party/llvm/BUILD.gn b/third_party/llvm/BUILD.gn
deleted file mode 100644
index bb18f60..0000000
--- a/third_party/llvm/BUILD.gn
+++ /dev/null
@@ -1,1520 +0,0 @@
-# Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-declare_args() {
-  llvm_prefix = "//third_party/llvm"
-}
-
-template("llvm_library") {
-  config(target_name + "_config") {
-    visibility = [ ":*" ]
-    include_dirs = [ "include" ]
-    libs = [ "lib/lib${target_name}.a" ]
-  }
-
-  group(target_name) {
-    forward_variables_from(invoker, [ "deps" ])
-    public_configs = [ ":${target_name}_config" ]
-  }
-}
-
-llvm_library("LLVMDemangle") {
-}
-
-llvm_library("LLVMSupport") {
-  deps = [ ":LLVMDemangle" ]
-}
-
-llvm_library("LLVMAArch64Utils") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMBinaryFormat") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMDebugInfoMSF") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMDebugInfoCodeView") {
-  deps = [
-    ":LLVMDebugInfoMSF",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMC") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMDebugInfoCodeView",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64AsmPrinter") {
-  deps = [
-    ":LLVMAArch64Utils",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMAArch64Desc") {
-  deps = [
-    ":LLVMAArch64AsmPrinter",
-    ":LLVMAArch64Info",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMCParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64AsmParser") {
-  deps = [
-    ":LLVMAArch64Desc",
-    ":LLVMAArch64Info",
-    ":LLVMAArch64Utils",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMCore") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBitReader") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMObject") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMBitReader",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMProfileData") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAnalysis") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMCore",
-    ":LLVMObject",
-    ":LLVMProfileData",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBitWriter") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMTransformUtils") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAggressiveInstCombine") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMInstCombine") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMScalarOpts") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMInstCombine",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMTarget") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMProfileData",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMAsmPrinter") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMBinaryFormat",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMDebugInfoCodeView",
-    ":LLVMDebugInfoMSF",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMSelectionDAG") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMGlobalISel") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMAArch64CodeGen") {
-  deps = [
-    ":LLVMAArch64AsmPrinter",
-    ":LLVMAArch64Desc",
-    ":LLVMAArch64Info",
-    ":LLVMAArch64Utils",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMCDisassembler") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAArch64Disassembler") {
-  deps = [
-    ":LLVMAArch64Desc",
-    ":LLVMAArch64Info",
-    ":LLVMAArch64Utils",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUUtils") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUAsmPrinter") {
-  deps = [
-    ":LLVMAMDGPUUtils",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMAMDGPUDesc") {
-  deps = [
-    ":LLVMAMDGPUAsmPrinter",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAMDGPUAsmParser") {
-  deps = [
-    ":LLVMAMDGPUDesc",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAsmParser") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMIRReader") {
-  deps = [
-    ":LLVMAsmParser",
-    ":LLVMBitReader",
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLinker") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMVectorize") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMInstrumentation") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMProfileData",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMipo") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCore",
-    ":LLVMIRReader",
-    ":LLVMInstCombine",
-    ":LLVMInstrumentation",
-    ":LLVMLinker",
-    ":LLVMObject",
-    ":LLVMProfileData",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-  ]
-}
-
-llvm_library("LLVMAMDGPUCodeGen") {
-  deps = [
-    ":LLVMAMDGPUAsmPrinter",
-    ":LLVMAMDGPUDesc",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMAMDGPUDisassembler") {
-  deps = [
-    ":LLVMAMDGPUDesc",
-    ":LLVMAMDGPUInfo",
-    ":LLVMAMDGPUUtils",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARCAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARCInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMARCDesc") {
-  deps = [
-    ":LLVMARCAsmPrinter",
-    ":LLVMARCInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARCCodeGen") {
-  deps = [
-    ":LLVMARCAsmPrinter",
-    ":LLVMARCDesc",
-    ":LLVMARCInfo",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMARCDisassembler") {
-  deps = [
-    ":LLVMARCInfo",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMUtils") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMARMAsmPrinter") {
-  deps = [
-    ":LLVMARMUtils",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMARMDesc") {
-  deps = [
-    ":LLVMARMAsmPrinter",
-    ":LLVMARMInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMAsmParser") {
-  deps = [
-    ":LLVMARMDesc",
-    ":LLVMARMInfo",
-    ":LLVMARMUtils",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMARMCodeGen") {
-  deps = [
-    ":LLVMARMAsmPrinter",
-    ":LLVMARMDesc",
-    ":LLVMARMInfo",
-    ":LLVMARMUtils",
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMARMDisassembler") {
-  deps = [
-    ":LLVMARMDesc",
-    ":LLVMARMInfo",
-    ":LLVMARMUtils",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRInfo") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRDesc") {
-  deps = [
-    ":LLVMAVRAsmPrinter",
-    ":LLVMAVRInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRAsmParser") {
-  deps = [
-    ":LLVMAVRDesc",
-    ":LLVMAVRInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMAVRCodeGen") {
-  deps = [
-    ":LLVMAVRAsmPrinter",
-    ":LLVMAVRDesc",
-    ":LLVMAVRInfo",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMAVRDisassembler") {
-  deps = [
-    ":LLVMAVRInfo",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMBPFDesc") {
-  deps = [
-    ":LLVMBPFAsmPrinter",
-    ":LLVMBPFInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFAsmParser") {
-  deps = [
-    ":LLVMBPFDesc",
-    ":LLVMBPFInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMBPFCodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMBPFAsmPrinter",
-    ":LLVMBPFDesc",
-    ":LLVMBPFInfo",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMBPFDisassembler") {
-  deps = [
-    ":LLVMBPFInfo",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMCoroutines") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMCoverage") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMObject",
-    ":LLVMProfileData",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMDebugInfoDWARF") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMDebugInfoPDB") {
-  deps = [
-    ":LLVMDebugInfoCodeView",
-    ":LLVMDebugInfoMSF",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMOption") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMDlltoolDriver") {
-  deps = [
-    ":LLVMObject",
-    ":LLVMOption",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRuntimeDyld") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMExecutionEngine") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMRuntimeDyld",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMCJIT") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMExecutionEngine",
-    ":LLVMObject",
-    ":LLVMRuntimeDyld",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMFuzzMutate") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCore",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMHexagonInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMHexagonDesc") {
-  deps = [
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMHexagonAsmParser") {
-  deps = [
-    ":LLVMHexagonDesc",
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMHexagonCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMHexagonAsmParser",
-    ":LLVMHexagonDesc",
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMHexagonDisassembler") {
-  deps = [
-    ":LLVMHexagonDesc",
-    ":LLVMHexagonInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMInterpreter") {
-  deps = [
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMExecutionEngine",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMObjCARCOpts") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMCore",
-    ":LLVMSupport",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMPasses") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMInstCombine",
-    ":LLVMInstrumentation",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMLTO") {
-  deps = [
-    ":LLVMAggressiveInstCombine",
-    ":LLVMAnalysis",
-    ":LLVMBitReader",
-    ":LLVMBitWriter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMInstCombine",
-    ":LLVMLinker",
-    ":LLVMMC",
-    ":LLVMObjCARCOpts",
-    ":LLVMObject",
-    ":LLVMPasses",
-    ":LLVMScalarOpts",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMLanaiInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMLanaiAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLanaiDesc") {
-  deps = [
-    ":LLVMLanaiAsmPrinter",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLanaiAsmParser") {
-  deps = [
-    ":LLVMLanaiDesc",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLanaiCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMLanaiAsmParser",
-    ":LLVMLanaiAsmPrinter",
-    ":LLVMLanaiDesc",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMLanaiDisassembler") {
-  deps = [
-    ":LLVMLanaiDesc",
-    ":LLVMLanaiInfo",
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLibDriver") {
-  deps = [
-    ":LLVMBinaryFormat",
-    ":LLVMObject",
-    ":LLVMOption",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMLineEditor") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMMIRParser") {
-  deps = [
-    ":LLVMAsmParser",
-    ":LLVMBinaryFormat",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMSP430AsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMSP430Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMMSP430Desc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMSP430AsmPrinter",
-    ":LLVMMSP430Info",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMSP430CodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMMSP430AsmPrinter",
-    ":LLVMMSP430Desc",
-    ":LLVMMSP430Info",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMipsAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMipsInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMMipsDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMipsAsmPrinter",
-    ":LLVMMipsInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMipsAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMMipsDesc",
-    ":LLVMMipsInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMMipsCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMMipsAsmPrinter",
-    ":LLVMMipsDesc",
-    ":LLVMMipsInfo",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMMipsDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMMipsInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNVPTXAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNVPTXInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMNVPTXDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMNVPTXAsmPrinter",
-    ":LLVMNVPTXInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNVPTXCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMNVPTXAsmPrinter",
-    ":LLVMNVPTXDesc",
-    ":LLVMNVPTXInfo",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMVectorize",
-    ":LLVMipo",
-  ]
-}
-
-llvm_library("LLVMX86Utils") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMX86AsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMX86Utils",
-  ]
-}
-
-llvm_library("LLVMX86Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMX86Desc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMObject",
-    ":LLVMSupport",
-    ":LLVMX86AsmPrinter",
-    ":LLVMX86Info",
-  ]
-}
-
-llvm_library("LLVMX86CodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMX86AsmPrinter",
-    ":LLVMX86Desc",
-    ":LLVMX86Info",
-    ":LLVMX86Utils",
-  ]
-}
-
-llvm_library("LLVMNios2AsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNios2Info") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMNios2Desc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMNios2AsmPrinter",
-    ":LLVMNios2Info",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMNios2CodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMGlobalISel",
-    ":LLVMMC",
-    ":LLVMNios2Desc",
-    ":LLVMNios2Info",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMObjectYAML") {
-  deps = [
-    ":LLVMDebugInfoCodeView",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMOrcJIT") {
-  deps = [
-    ":LLVMCore",
-    ":LLVMExecutionEngine",
-    ":LLVMMC",
-    ":LLVMObject",
-    ":LLVMRuntimeDyld",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMPowerPCAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMPowerPCInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMPowerPCDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMPowerPCAsmPrinter",
-    ":LLVMPowerPCInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMPowerPCAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMPowerPCDesc",
-    ":LLVMPowerPCInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMPowerPCCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMPowerPCAsmPrinter",
-    ":LLVMPowerPCDesc",
-    ":LLVMPowerPCInfo",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-  ]
-}
-
-llvm_library("LLVMPowerPCDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMPowerPCInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMRISCVDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMRISCVAsmPrinter",
-    ":LLVMRISCVInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMRISCVDesc",
-    ":LLVMRISCVInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMRISCVCodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMRISCVAsmPrinter",
-    ":LLVMRISCVDesc",
-    ":LLVMRISCVInfo",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMRISCVDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMRISCVInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMSparcDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSparcAsmPrinter",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSparcDesc",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSparcCodeGen") {
-  deps = [
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSparcAsmPrinter",
-    ":LLVMSparcDesc",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMSparcDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSparcInfo",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSymbolize") {
-  deps = [
-    ":LLVMDebugInfoDWARF",
-    ":LLVMDebugInfoPDB",
-    ":LLVMDemangle",
-    ":LLVMObject",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSystemZAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMSystemZInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMSystemZDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMSystemZAsmPrinter",
-    ":LLVMSystemZInfo",
-  ]
-}
-
-llvm_library("LLVMSystemZAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMSystemZDesc",
-    ":LLVMSystemZInfo",
-  ]
-}
-
-llvm_library("LLVMSystemZCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMSystemZAsmPrinter",
-    ":LLVMSystemZDesc",
-    ":LLVMSystemZInfo",
-    ":LLVMTarget",
-  ]
-}
-
-llvm_library("LLVMSystemZDisassembler") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMSystemZDesc",
-    ":LLVMSystemZInfo",
-  ]
-}
-
-llvm_library("LLVMTableGen") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMTestingSupport") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMWebAssemblyInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMWebAssemblyAsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMWebAssemblyAsmPrinter",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMScalarOpts",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMWebAssemblyAsmPrinter",
-    ":LLVMWebAssemblyDesc",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWebAssemblyDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMWebAssemblyInfo",
-  ]
-}
-
-llvm_library("LLVMWindowsManifest") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMX86AsmParser") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMMCParser",
-    ":LLVMSupport",
-    ":LLVMX86AsmPrinter",
-    ":LLVMX86Desc",
-    ":LLVMX86Info",
-  ]
-}
-
-llvm_library("LLVMX86Disassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMX86Info",
-  ]
-}
-
-llvm_library("LLVMXCoreAsmPrinter") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-  ]
-}
-
-llvm_library("LLVMXCoreInfo") {
-  deps = [ ":LLVMSupport" ]
-}
-
-llvm_library("LLVMXCoreDesc") {
-  deps = [
-    ":LLVMMC",
-    ":LLVMSupport",
-    ":LLVMXCoreAsmPrinter",
-    ":LLVMXCoreInfo",
-  ]
-}
-
-llvm_library("LLVMXCoreCodeGen") {
-  deps = [
-    ":LLVMAnalysis",
-    ":LLVMAsmPrinter",
-    ":LLVMCodeGen",
-    ":LLVMCore",
-    ":LLVMMC",
-    ":LLVMSelectionDAG",
-    ":LLVMSupport",
-    ":LLVMTarget",
-    ":LLVMTransformUtils",
-    ":LLVMXCoreAsmPrinter",
-    ":LLVMXCoreDesc",
-    ":LLVMXCoreInfo",
-  ]
-}
-
-llvm_library("LLVMXCoreDisassembler") {
-  deps = [
-    ":LLVMMCDisassembler",
-    ":LLVMSupport",
-    ":LLVMXCoreInfo",
-  ]
-}
diff --git a/tools/VERSION b/tools/VERSION
index b39a857..8f43000 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 122
+PRERELEASE 123
 PRERELEASE_PATCH 0
\ No newline at end of file