diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index fe7cfc1..6c06628 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -232,11 +232,6 @@
             '{${_info.keys.map((k) => '$k (${k.hashCode})').join(',')}}'));
   }
 
-  /// Indicates whether information is stored for the given [node].
-  bool _hasInfoForNode(Node node) {
-    return _info[node] != null;
-  }
-
   void _printOn(StringBuffer sb) {
     sb.write('_info=$_info,');
     sb.write('_stack=$_stack,');
@@ -894,11 +889,7 @@
 
   /// Call this method just after visiting a "try/finally" statement.
   /// See [tryFinallyStatement_bodyBegin] for details.
-  ///
-  /// [finallyBlock] should be the same node that was passed to
-  /// [AssignedVariables.endNode] for the "finally" part of the try/finally
-  /// statement.
-  void tryFinallyStatement_end(Node finallyBlock);
+  void tryFinallyStatement_end();
 
   /// Call this method just before visiting the finally block of a "try/finally"
   /// statement.  See [tryFinallyStatement_bodyBegin] for details.
@@ -1439,9 +1430,9 @@
   }
 
   @override
-  void tryFinallyStatement_end(Node finallyBlock) {
-    return _wrap('tryFinallyStatement_end($finallyBlock)',
-        () => _wrapped.tryFinallyStatement_end(finallyBlock));
+  void tryFinallyStatement_end() {
+    return _wrap(
+        'tryFinallyStatement_end()', () => _wrapped.tryFinallyStatement_end());
   }
 
   @override
@@ -4095,10 +4086,7 @@
   }
 
   @override
-  void tryFinallyStatement_end(Node finallyBlock) {
-    // We used to need info for `finally` blocks but we don't anymore.
-    assert(!_assignedVariables._hasInfoForNode(finallyBlock),
-        'No assigned variables info should have been stored for $finallyBlock');
+  void tryFinallyStatement_end() {
     _TryFinallyContext<Variable, Type> context =
         _stack.removeLast() as _TryFinallyContext<Variable, Type>;
     _current = context._afterBodyAndCatches!
@@ -4741,7 +4729,7 @@
   void tryFinallyStatement_bodyBegin() {}
 
   @override
-  void tryFinallyStatement_end(Node finallyBlock) {}
+  void tryFinallyStatement_end() {}
 
   @override
   void tryFinallyStatement_finallyBegin(Node body) {}
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
index 024a4c6..afd3020 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
@@ -1640,7 +1640,6 @@
   final List<Statement> body;
   final List<Statement> finally_;
   final Node _bodyNode = Node._();
-  final Node _finallyNode = Node._();
 
   _TryFinally(this.body, this.finally_) : super._();
 
@@ -1662,7 +1661,7 @@
     body._visit(h, flow);
     flow.tryFinallyStatement_finallyBegin(_bodyNode);
     finally_._visit(h, flow);
-    flow.tryFinallyStatement_end(_finallyNode);
+    flow.tryFinallyStatement_end();
   }
 }
 
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index b061fe0..e7dd7cf 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2055,7 +2055,7 @@
       flow.tryFinallyStatement_finallyBegin(
           catchClauses.isNotEmpty ? node : body);
       finallyBlock.accept(this);
-      flow.tryFinallyStatement_end(finallyBlock);
+      flow.tryFinallyStatement_end();
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 3b061ee..05af526 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -6325,7 +6325,7 @@
       inferrer.flowAnalysis.tryFinallyStatement_finallyBegin(
           node.catchBlocks.isNotEmpty ? node : tryBodyWithAssignedInfo);
       finalizerResult = inferrer.inferStatement(node.finallyBlock);
-      inferrer.flowAnalysis.tryFinallyStatement_end(node.finallyBlock);
+      inferrer.flowAnalysis.tryFinallyStatement_end();
     }
     Statement result =
         tryBlockResult.hasChanged ? tryBlockResult.statement : node.tryBlock;
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 850669e..5b97ce5 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -1776,7 +1776,7 @@
       _flowAnalysis.tryFinallyStatement_finallyBegin(
           catchClauses.isNotEmpty ? node : body);
       _dispatch(finallyBlock);
-      _flowAnalysis.tryFinallyStatement_end(finallyBlock);
+      _flowAnalysis.tryFinallyStatement_end();
     }
     return null;
   }
diff --git a/runtime/tests/vm/dart/base_il_serialization_test.dart b/runtime/tests/vm/dart/base_il_serialization_test.dart
deleted file mode 100644
index 569b661..0000000
--- a/runtime/tests/vm/dart/base_il_serialization_test.dart
+++ /dev/null
@@ -1,16 +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.
-
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-// Just use the existing hello world test.
-import 'hello_world_test.dart' as test;
-
-main(args) {
-  test.main();
-}
diff --git a/runtime/tests/vm/dart/regress_38661_test.dart b/runtime/tests/vm/dart/regress_38661_test.dart
deleted file mode 100644
index 2e1ba13..0000000
--- a/runtime/tests/vm/dart/regress_38661_test.dart
+++ /dev/null
@@ -1,27 +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.
-
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-class A {
-  const A();
-}
-
-class B {
-  Object a = const A();
-}
-
-foo(int i) {
-  if (i == 3) {
-    new B();
-  }
-}
-
-main(args) {
-  foo(4);
-}
diff --git a/runtime/tests/vm/dart_2/base_il_serialization_test.dart b/runtime/tests/vm/dart_2/base_il_serialization_test.dart
deleted file mode 100644
index 569b661..0000000
--- a/runtime/tests/vm/dart_2/base_il_serialization_test.dart
+++ /dev/null
@@ -1,16 +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.
-
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-// Just use the existing hello world test.
-import 'hello_world_test.dart' as test;
-
-main(args) {
-  test.main();
-}
diff --git a/runtime/tests/vm/dart_2/regress_38661_test.dart b/runtime/tests/vm/dart_2/regress_38661_test.dart
deleted file mode 100644
index 2e1ba13..0000000
--- a/runtime/tests/vm/dart_2/regress_38661_test.dart
+++ /dev/null
@@ -1,27 +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.
-
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
-// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
-
-class A {
-  const A();
-}
-
-class B {
-  Object a = const A();
-}
-
-foo(int i) {
-  if (i == 3) {
-    new B();
-  }
-}
-
-main(args) {
-  foo(4);
-}
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 460c9e0..abb8ad0 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -18,7 +18,6 @@
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/il_printer.h"
-#include "vm/compiler/backend/il_serializer.h"
 #include "vm/compiler/backend/inliner.h"
 #include "vm/compiler/backend/linearscan.h"
 #include "vm/compiler/backend/range_analysis.h"
@@ -87,17 +86,6 @@
 DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
 DECLARE_FLAG(bool, print_instruction_stats);
 
-DEFINE_FLAG(charp,
-            serialize_flow_graphs_to,
-            nullptr,
-            "Serialize flow graphs to the given file");
-
-DEFINE_FLAG(bool,
-            populate_llvm_constant_pool,
-            false,
-            "Add constant pool entries from flow graphs to a special pool "
-            "serialized in AOT snapshots (with --serialize_flow_graphs_to)");
-
 Precompiler* Precompiler::singleton_ = nullptr;
 
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
@@ -234,8 +222,7 @@
       consts_to_retain_(),
       seen_table_selectors_(),
       error_(Error::Handle()),
-      get_runtime_type_is_unique_(false),
-      il_serialization_stream_(nullptr) {
+      get_runtime_type_is_unique_(false) {
   ASSERT(Precompiler::singleton_ == NULL);
   Precompiler::singleton_ = this;
 }
@@ -307,32 +294,6 @@
       ClassFinalizer::ClearAllCode(
           /*including_nonchanging_cids=*/FLAG_use_bare_instructions);
 
-      // After this point, it should be safe to serialize flow graphs produced
-      // during compilation and add constants to the LLVM constant pool.
-      //
-      // Check that both the file open and write callbacks are available, though
-      // we only use the latter during IL processing.
-      if (FLAG_serialize_flow_graphs_to != nullptr &&
-          Dart::file_write_callback() != nullptr) {
-        if (auto file_open = Dart::file_open_callback()) {
-          auto file = file_open(FLAG_serialize_flow_graphs_to, /*write=*/true);
-          set_il_serialization_stream(file);
-        }
-        if (FLAG_populate_llvm_constant_pool) {
-          auto const object_store = IG->object_store();
-          auto& llvm_constants = GrowableObjectArray::Handle(
-              Z, GrowableObjectArray::New(16, Heap::kOld));
-          auto& llvm_functions = GrowableObjectArray::Handle(
-              Z, GrowableObjectArray::New(16, Heap::kOld));
-          auto& llvm_constant_hash_table = Array::Handle(
-              Z, HashTables::New<FlowGraphSerializer::LLVMPoolMap>(16,
-                                                                   Heap::kOld));
-          object_store->set_llvm_constant_pool(llvm_constants);
-          object_store->set_llvm_function_pool(llvm_functions);
-          object_store->set_llvm_constant_hash_table(llvm_constant_hash_table);
-        }
-      }
-
       tracer_ = PrecompilerTracer::StartTracingIfRequested(this);
 
       // All stubs have already been generated, all of them share the same pool.
@@ -412,45 +373,6 @@
         }
       }
 
-      if (FLAG_serialize_flow_graphs_to != nullptr &&
-          Dart::file_write_callback() != nullptr) {
-        if (auto file_close = Dart::file_close_callback()) {
-          file_close(il_serialization_stream());
-        }
-        set_il_serialization_stream(nullptr);
-        if (FLAG_populate_llvm_constant_pool) {
-          // We don't want the Array backing for any mappings in the snapshot,
-          // only the pools themselves.
-          IG->object_store()->set_llvm_constant_hash_table(Array::null_array());
-
-          // Keep any functions, classes, etc. referenced from the LLVM pools,
-          // even if they could have been dropped due to not being otherwise
-          // needed at runtime.
-          const auto& constant_pool = GrowableObjectArray::Handle(
-              Z, IG->object_store()->llvm_constant_pool());
-          auto& object = Object::Handle(Z);
-          for (intptr_t i = 0; i < constant_pool.Length(); i++) {
-            object = constant_pool.At(i);
-            if (object.IsNull()) continue;
-            if (object.IsInstance()) {
-              AddConstObject(Instance::Cast(object));
-            } else if (object.IsField()) {
-              AddField(Field::Cast(object));
-            } else if (object.IsFunction()) {
-              AddFunction(Function::Cast(object), RetainReasons::kLLVMPool);
-            }
-          }
-
-          const auto& function_pool = GrowableObjectArray::Handle(
-              Z, IG->object_store()->llvm_function_pool());
-          auto& function = Function::Handle(Z);
-          for (intptr_t i = 0; i < function_pool.Length(); i++) {
-            function ^= function_pool.At(i);
-            AddFunction(function, RetainReasons::kLLVMPool);
-          }
-        }
-      }
-
       if (tracer_ != nullptr) {
         tracer_->Finalize();
         tracer_ = nullptr;
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 01e2892..48613ee 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -250,8 +250,6 @@
     return dispatch_table_generator_->selector_map();
   }
 
-  void* il_serialization_stream() const { return il_serialization_stream_; }
-
   static Precompiler* Instance() { return singleton_; }
 
   void AddField(const Field& field);
@@ -348,10 +346,6 @@
 
   void FinalizeAllClasses();
 
-  void set_il_serialization_stream(void* file) {
-    il_serialization_stream_ = file;
-  }
-
   Thread* thread() const { return thread_; }
   Zone* zone() const { return zone_; }
   Isolate* isolate() const { return isolate_; }
@@ -431,7 +425,6 @@
   compiler::DispatchTableGenerator* dispatch_table_generator_;
 
   bool get_runtime_type_is_unique_;
-  void* il_serialization_stream_;
 
   Phase phase_ = Phase::kPreparation;
   PrecompilerTracer* tracer_ = nullptr;
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index 3a7d6aa..192d541 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -18,9 +18,6 @@
 class AbstractType;
 class BaseTextBuffer;
 class Definition;
-class FlowGraphSerializer;
-class SExpression;
-class SExpList;
 
 template <typename T>
 class GrowableArray;
@@ -248,8 +245,6 @@
   bool Specialize(GrowableArray<intptr_t>* class_ids);
 
   void PrintTo(BaseTextBuffer* f) const;
-  SExpression* ToSExpression(FlowGraphSerializer* s) const;
-  void AddExtraInfoToSExpression(SExpList* sexp, FlowGraphSerializer* s) const;
 
   const char* ToCString() const;
 
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 38006b2..3cf8ffc 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -49,7 +49,6 @@
 class Environment;
 class FlowGraph;
 class FlowGraphCompiler;
-class FlowGraphSerializer;
 class FlowGraphVisitor;
 class ForwardInstructionIterator;
 class Instruction;
@@ -59,8 +58,6 @@
 class Range;
 class RangeAnalysis;
 class RangeBoundary;
-class SExpList;
-class SExpression;
 class SuccessorsIterable;
 class TypeUsageInfo;
 class UnboxIntegerInstr;
@@ -150,8 +147,6 @@
   void PrintTo(BaseTextBuffer* f) const;
 #endif  // defined(INCLUDE_IL_PRINTER)
 
-  SExpression* ToSExpression(FlowGraphSerializer* s) const;
-
   const char* ToCString() const;
 
   bool IsSmiValue() { return Type()->ToCid() == kSmiCid; }
@@ -569,17 +564,6 @@
 #define PRINT_OPERANDS_TO_SUPPORT
 #endif  // defined(INCLUDE_IL_PRINTER)
 
-#define TO_S_EXPRESSION_SUPPORT                                                \
-  virtual SExpression* ToSExpression(FlowGraphSerializer* s) const;
-
-#define ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT                                   \
-  virtual void AddOperandsToSExpression(SExpList* sexp,                        \
-                                        FlowGraphSerializer* s) const;
-
-#define ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT                                 \
-  virtual void AddExtraInfoToSExpression(SExpList* sexp,                       \
-                                         FlowGraphSerializer* s) const;
-
 // Together with CidRange, this represents a mapping from a range of class-ids
 // to a method for a given selector (method name).  Also can contain an
 // indication of how frequently a given method has been called at a call site.
@@ -932,11 +916,6 @@
   const char* ToCString() const;
   PRINT_TO_SUPPORT
   PRINT_OPERANDS_TO_SUPPORT
-  virtual SExpression* ToSExpression(FlowGraphSerializer* s) const;
-  virtual void AddOperandsToSExpression(SExpList* sexp,
-                                        FlowGraphSerializer* s) const;
-  virtual void AddExtraInfoToSExpression(SExpList* sexp,
-                                         FlowGraphSerializer* s) const;
 
 #define DECLARE_INSTRUCTION_TYPE_CHECK(Name, Type)                             \
   bool Is##Name() const { return (As##Name() != nullptr); }                    \
@@ -1519,9 +1498,6 @@
 
   DEFINE_INSTRUCTION_TYPE_CHECK(BlockEntry)
 
-  TO_S_EXPRESSION_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  protected:
   BlockEntryInstr(intptr_t block_id,
@@ -1822,7 +1798,6 @@
   virtual bool HasUnknownSideEffects() const { return false; }
 
   PRINT_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   // Classes that have access to predecessors_ when inlining.
@@ -2269,7 +2244,6 @@
 
   PRINT_OPERANDS_TO_SUPPORT
   PRINT_TO_SUPPORT
-  TO_S_EXPRESSION_SUPPORT
 
   bool UpdateType(CompileType new_type) {
     if (type_ == nullptr) {
@@ -2382,7 +2356,6 @@
  protected:
   friend class RangeAnalysis;
   friend class Value;
-  friend class FlowGraphSerializer;  // To access type_ directly.
 
   Range* range_ = nullptr;
 
@@ -2617,7 +2590,6 @@
   virtual bool MayThrow() const { return false; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); }
@@ -2723,7 +2695,6 @@
   intptr_t offset() const { return offset_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const intptr_t offset_;
@@ -2774,7 +2745,6 @@
   intptr_t offset() const { return offset_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const intptr_t offset_;
@@ -2906,7 +2876,6 @@
   virtual bool ComputeCanDeoptimize() const { return false; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const Code& code_;
@@ -3188,7 +3157,6 @@
   }
 
   PRINT_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   BlockEntryInstr* block_;
@@ -3299,7 +3267,6 @@
            (operation_cid() == other_comparison->operation_cid());
   }
 
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
   DEFINE_INSTRUCTION_TYPE_CHECK(Comparison)
 
@@ -3438,7 +3405,6 @@
   virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
 
   PRINT_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
@@ -3592,7 +3558,6 @@
                           Register tmp = kNoRegister);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const Object& value_;
@@ -3759,7 +3724,6 @@
   virtual Value* RedefinedValue() const;
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const TokenPosition token_pos_;
@@ -3850,7 +3814,6 @@
   const char* ToCString() const;
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const SpecialParameterKind kind_;
@@ -3960,7 +3923,6 @@
         ArgumentsSizeWithoutTypeArgs(), argument_names());
   }
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
@@ -4005,7 +3967,6 @@
   Code::EntryKind entry_kind() const { return entry_kind_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const Code::EntryKind entry_kind_;
@@ -4103,8 +4064,6 @@
   Code::EntryKind entry_kind() const { return entry_kind_; }
   void set_entry_kind(Code::EntryKind value) { entry_kind_ = value; }
 
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
   DEFINE_INSTRUCTION_TYPE_CHECK(InstanceCallBase);
 
   bool receiver_is_not_smi() const { return receiver_is_not_smi_; }
@@ -4220,7 +4179,6 @@
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
   bool MatchesCoreName(const String& name);
 
@@ -4295,7 +4253,6 @@
   static TypePtr ComputeRuntimeType(const CallTargets& targets);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   PolymorphicInstanceCallInstr(const InstructionSource& source,
@@ -4434,8 +4391,7 @@
 
   bool AttributesEqual(Instruction* other) const;
 
-  PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT;
+  PRINT_OPERANDS_TO_SUPPORT;
 
  private:
   Condition EmitComparisonCodeRegConstant(FlowGraphCompiler* compiler,
@@ -4868,8 +4824,6 @@
   const class BinaryFeedback& BinaryFeedback();
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const ICData* ic_data_;
@@ -4916,7 +4870,6 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const LocalVariable& local_;
@@ -5048,7 +5001,6 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
  private:
   const LocalVariable& local_;
@@ -5098,8 +5050,6 @@
   void SetupNative();
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   void set_native_c_function(NativeFunction value) {
@@ -5292,7 +5242,6 @@
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const TokenPosition token_pos_;
@@ -5423,8 +5372,6 @@
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   friend class JitCallSpecializer;  // For ASSERT(initialization_).
@@ -5684,7 +5631,6 @@
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const bool index_unboxed_;
@@ -5988,7 +5934,6 @@
 
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   compiler::Assembler::CanBeSmi CanValueBeSmi() const {
@@ -6170,8 +6115,6 @@
   }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   virtual void RawSetInputAt(intptr_t i, Value* value) {
@@ -6639,8 +6582,6 @@
   virtual bool AttributesEqual(Instruction* other) const;
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   intptr_t OffsetInBytes() const { return slot().offset_in_bytes(); }
@@ -7469,7 +7410,6 @@
   }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
   DECLARE_COMPARISON_INSTRUCTION(DoubleTestOp)
 
@@ -7642,7 +7582,6 @@
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
   DECLARE_INSTRUCTION(CheckedSmiOp)
 
@@ -7767,7 +7706,6 @@
   virtual void InferRange(RangeAnalysis* analysis, Range* range);
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
 
   DEFINE_INSTRUCTION_TYPE_CHECK(BinaryIntegerOp)
 
@@ -8220,7 +8158,6 @@
   }
 
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   const TokenPosition token_pos_;
@@ -8792,7 +8729,6 @@
 
   virtual Value* RedefinedValue() const;
 
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
   PRINT_OPERANDS_TO_SUPPORT
 
@@ -9323,8 +9259,6 @@
 
   DECLARE_INSTRUCTION(SimdOp)
   PRINT_OPERANDS_TO_SUPPORT
-  ADD_OPERANDS_TO_S_EXPRESSION_SUPPORT
-  ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
 
  private:
   SimdOpInstr(Kind kind, intptr_t deopt_id)
@@ -9539,7 +9473,6 @@
                        Definition* result) const;
 
   void PrintTo(BaseTextBuffer* f) const;
-  SExpression* ToSExpression(FlowGraphSerializer* s) const;
   const char* ToCString() const;
 
   // Deep copy an environment.  The 'length' parameter may be less than the
diff --git a/runtime/vm/compiler/backend/il_deserializer.cc b/runtime/vm/compiler/backend/il_deserializer.cc
deleted file mode 100644
index eb7f1fa..0000000
--- a/runtime/vm/compiler/backend/il_deserializer.cc
+++ /dev/null
@@ -1,2520 +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 "vm/compiler/backend/il_deserializer.h"
-
-#include "vm/compiler/backend/il_serializer.h"
-#include "vm/compiler/backend/range_analysis.h"
-#include "vm/compiler/call_specializer.h"
-#include "vm/compiler/frontend/base_flow_graph_builder.h"
-#include "vm/compiler/jit/compiler.h"
-#include "vm/flags.h"
-#include "vm/json_writer.h"
-#include "vm/os.h"
-
-namespace dart {
-
-DEFINE_FLAG(bool,
-            trace_round_trip_serialization,
-            false,
-            "Print out tracing information during round trip serialization.");
-DEFINE_FLAG(bool,
-            print_json_round_trip_results,
-            false,
-            "Print out results of each round trip serialization in JSON form.");
-
-// Contains the contents of a single round-trip result.
-struct RoundTripResults : public ValueObject {
-  explicit RoundTripResults(Zone* zone, const Function& func)
-      : function(func), unhandled(zone, 2) {}
-
-  // The function for which a flow graph was being parsed.
-  const Function& function;
-  // Whether the round trip succeeded.
-  bool success = false;
-  // An array of unhandled instructions found in the flow graph.
-  GrowableArray<Instruction*> unhandled;
-  // The serialized form of the flow graph, if computed.
-  SExpression* serialized = nullptr;
-  // The error information from the deserializer, if an error occurred.
-  const char* error_message = nullptr;
-  SExpression* error_sexp = nullptr;
-};
-
-// Return a textual description of how to find the sub-expression [to_find]
-// inside a [root] S-Expression.
-static const char* GetSExpressionPosition(Zone* zone,
-                                          SExpression* root,
-                                          SExpression* to_find) {
-  // The S-expression to find _is_ the root, so no description is needed.
-  if (root == to_find) return "";
-  // The S-expression to find cannot be a sub-expression of the given root,
-  // so return nullptr to signal this.
-  if (!root->IsList()) return nullptr;
-  auto const list = root->AsList();
-  for (intptr_t i = 0, n = list->Length(); i < n; i++) {
-    if (auto const str = GetSExpressionPosition(zone, list->At(i), to_find)) {
-      return OS::SCreate(zone, "element %" Pd "%s%s", i,
-                         *str == '\0' ? "" : " -> ", str);
-    }
-  }
-  auto it = list->ExtraIterator();
-  while (auto kv = it.Next()) {
-    if (auto const str = GetSExpressionPosition(zone, kv->value, to_find)) {
-      return OS::SCreate(zone, "label %s%s%s", kv->key,
-                         *str == '\0' ? "" : " -> ", str);
-    }
-  }
-  return nullptr;
-}
-
-static void PrintRoundTripResults(Zone* zone, const RoundTripResults& results) {
-  // A few checks to make sure we'll print out enough info. First, if there are
-  // no unhandled instructions, then we should have serialized the flow graph.
-  ASSERT(!results.unhandled.is_empty() || results.serialized != nullptr);
-  // If we failed, then either there are unhandled instructions or we have
-  // an appropriate error message and sexp from the FlowGraphDeserializer.
-  ASSERT(results.success || !results.unhandled.is_empty() ||
-         (results.error_message != nullptr && results.error_sexp != nullptr));
-
-  JSONWriter js;
-
-  js.OpenObject();
-  js.PrintProperty("function", results.function.ToFullyQualifiedCString());
-  js.PrintPropertyBool("success", results.success);
-
-  if (!results.unhandled.is_empty()) {
-    CStringMap<intptr_t> count_map(zone);
-    for (auto inst : results.unhandled) {
-      auto const name = inst->DebugName();
-      auto const old_count = count_map.LookupValue(name);
-      count_map.Update({name, old_count + 1});
-    }
-
-    auto count_it = count_map.GetIterator();
-    js.OpenObject("unhandled");
-    while (auto kv = count_it.Next()) {
-      js.PrintProperty64(kv->key, kv->value);
-    }
-    js.CloseObject();
-  }
-
-  if (results.serialized != nullptr) {
-    TextBuffer buf(1000);
-    results.serialized->SerializeTo(zone, &buf, "");
-    js.PrintProperty("serialized", buf.buffer());
-  }
-
-  if (results.error_message != nullptr) {
-    js.OpenObject("error");
-    js.PrintProperty("message", results.error_message);
-
-    ASSERT(results.error_sexp != nullptr);
-    TextBuffer buf(1000);
-    results.error_sexp->SerializeTo(zone, &buf, "");
-    js.PrintProperty("expression", buf.buffer());
-
-    auto const sexp_position =
-        GetSExpressionPosition(zone, results.serialized, results.error_sexp);
-    js.PrintProperty("path", sexp_position);
-    js.CloseObject();
-  }
-
-  js.CloseObject();
-  THR_Print("Results of round trip serialization: %s\n", js.buffer()->buffer());
-}
-
-void FlowGraphDeserializer::RoundTripSerialization(CompilerPassState* state) {
-  auto const flow_graph = state->flow_graph();
-
-  // The deserialized flow graph must be in the same zone as the original flow
-  // graph, to ensure it has the right lifetime. Thus, we leave an explicit
-  // use of [flow_graph->zone()] in the deserializer construction.
-  //
-  // Otherwise, it would be nice to use a StackZone to limit the lifetime of the
-  // serialized form (and other values created with this [zone] variable), since
-  // it only needs to live for the dynamic extent of this method.
-  //
-  // However, creating a StackZone for it also changes the zone associated with
-  // the thread. Also, some parts of the VM used in later updates to the
-  // deserializer implicitly pick up the zone to use either from a passed-in
-  // thread or the current thread instead of taking an explicit zone.
-  //
-  // For now, just serialize into the same zone as the original flow graph, and
-  // we can revisit this if this causes a performance issue or if we can ensure
-  // that those VM parts mentioned can be passed an explicit zone.
-  Zone* const zone = flow_graph->zone();
-
-  // Final flow graph, if we successfully serialize and deserialize.
-  FlowGraph* new_graph = nullptr;
-
-  // Stored information for printing results if requested.
-  RoundTripResults results(zone, flow_graph->function());
-
-  FlowGraphDeserializer::AllUnhandledInstructions(flow_graph,
-                                                  &results.unhandled);
-  if (results.unhandled.is_empty()) {
-    results.serialized = FlowGraphSerializer::SerializeToSExp(zone, flow_graph);
-
-    if (FLAG_trace_round_trip_serialization && results.serialized != nullptr) {
-      TextBuffer buf(1000);
-      results.serialized->SerializeTo(zone, &buf, "");
-      THR_Print("Serialized flow graph:\n%s\n", buf.buffer());
-    }
-
-    // For the deserializer, use the thread from the compiler pass and zone
-    // associated with the existing flow graph to make sure the new flow graph
-    // has the right lifetime.
-    FlowGraphDeserializer d(state->thread, flow_graph->zone(),
-                            results.serialized, &flow_graph->parsed_function());
-    new_graph = d.ParseFlowGraph();
-    if (new_graph == nullptr) {
-      ASSERT(d.error_message() != nullptr && d.error_sexp() != nullptr);
-      if (FLAG_trace_round_trip_serialization) {
-        THR_Print("Failure during deserialization: %s\n", d.error_message());
-        THR_Print("At S-expression %s\n", d.error_sexp()->ToCString(zone));
-        if (auto const pos = GetSExpressionPosition(zone, results.serialized,
-                                                    d.error_sexp())) {
-          THR_Print("Path from root: %s\n", pos);
-        }
-      }
-      results.error_message = d.error_message();
-      results.error_sexp = d.error_sexp();
-    } else {
-      if (FLAG_trace_round_trip_serialization) {
-        THR_Print("Successfully deserialized graph for %s\n",
-                  results.serialized->AsList()->At(1)->AsSymbol()->value());
-      }
-      results.success = true;
-    }
-  } else if (FLAG_trace_round_trip_serialization) {
-    THR_Print("Cannot serialize graph due to instruction: %s\n",
-              results.unhandled.At(0)->DebugName());
-  }
-
-  if (FLAG_print_json_round_trip_results) PrintRoundTripResults(zone, results);
-
-  if (new_graph != nullptr) {
-    state->set_flow_graph(new_graph);
-  }
-}
-
-#define HANDLED_CASE(name)                                                     \
-  if (inst->Is##name()) return true;
-bool FlowGraphDeserializer::IsHandledInstruction(Instruction* inst) {
-  if (auto const const_inst = inst->AsConstant()) {
-    return IsHandledConstant(const_inst->value());
-  }
-  FOR_EACH_HANDLED_BLOCK_TYPE_IN_DESERIALIZER(HANDLED_CASE)
-  FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLED_CASE)
-  return false;
-}
-#undef HANDLED_CASE
-
-void FlowGraphDeserializer::AllUnhandledInstructions(
-    const FlowGraph* graph,
-    GrowableArray<Instruction*>* unhandled) {
-  ASSERT(graph != nullptr);
-  ASSERT(unhandled != nullptr);
-  for (auto block_it = graph->reverse_postorder_iterator(); !block_it.Done();
-       block_it.Advance()) {
-    auto const entry = block_it.Current();
-    if (!IsHandledInstruction(entry)) unhandled->Add(entry);
-    // Check that the Phi instructions in JoinEntrys do not have pair
-    // representation.
-    if (auto const join_block = entry->AsJoinEntry()) {
-      auto const phis = join_block->phis();
-      auto const length = ((phis == nullptr) ? 0 : phis->length());
-      for (intptr_t i = 0; i < length; i++) {
-        auto const current = phis->At(i);
-        for (intptr_t j = 0; j < current->InputCount(); j++) {
-          if (current->InputAt(j)->definition()->HasPairRepresentation()) {
-            unhandled->Add(current);
-          }
-        }
-      }
-    }
-    if (auto const def_block = entry->AsBlockEntryWithInitialDefs()) {
-      auto const defs = def_block->initial_definitions();
-      for (intptr_t i = 0; i < defs->length(); i++) {
-        auto const current = defs->At(i);
-        if (!IsHandledInstruction(current)) unhandled->Add(current);
-      }
-    }
-    for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
-      auto current = it.Current();
-      // We handle branches, so we need to check the comparison instruction.
-      if (current->IsBranch()) current = current->AsBranch()->comparison();
-      if (!IsHandledInstruction(current)) unhandled->Add(current);
-    }
-  }
-}
-
-// Keep in sync with work in ParseDartValue. Right now, this is just a shallow
-// check, not a deep one.
-bool FlowGraphDeserializer::IsHandledConstant(const Object& obj) {
-  if (obj.IsArray()) return Array::Cast(obj).IsImmutable();
-  return obj.IsNull() || obj.IsClass() || obj.IsFunction() || obj.IsField() ||
-         obj.IsInstance();
-}
-
-SExpression* FlowGraphDeserializer::Retrieve(SExpList* list, intptr_t index) {
-  if (list == nullptr) return nullptr;
-  if (list->Length() <= index) {
-    StoreError(list, "expected at least %" Pd " element(s) in list", index + 1);
-    return nullptr;
-  }
-  auto const elem = list->At(index);
-  if (elem == nullptr) {
-    StoreError(list, "null value at index %" Pd "", index);
-  }
-  return elem;
-}
-
-SExpression* FlowGraphDeserializer::Retrieve(SExpList* list, const char* key) {
-  if (list == nullptr) return nullptr;
-  if (!list->ExtraHasKey(key)) {
-    StoreError(list, "expected an extra info entry for key %s", key);
-    return nullptr;
-  }
-  auto const elem = list->ExtraLookupValue(key);
-  if (elem == nullptr) {
-    StoreError(list, "null value for key %s", key);
-  }
-  return elem;
-}
-
-FlowGraph* FlowGraphDeserializer::ParseFlowGraph() {
-  auto const root = CheckTaggedList(root_sexp_, "FlowGraph");
-  if (root == nullptr) return nullptr;
-
-  intptr_t deopt_id = DeoptId::kNone;
-  if (auto const deopt_id_sexp =
-          CheckInteger(root->ExtraLookupValue("deopt_id"))) {
-    deopt_id = deopt_id_sexp->value();
-  }
-  EntryInfo common_info = {0, kInvalidTryIndex, deopt_id};
-
-  auto const graph = DeserializeGraphEntry(root, common_info);
-
-  PrologueInfo pi(-1, -1);
-  flow_graph_ = new (zone()) FlowGraph(*parsed_function_, graph, 0, pi);
-  flow_graph_->CreateCommonConstants();
-
-  intptr_t pos = 2;
-  if (auto const pool = CheckTaggedList(Retrieve(root, pos), "Constants")) {
-    if (!ParseConstantPool(pool)) return nullptr;
-    pos++;
-  }
-
-  // The deopt environment for the graph entry may use entries from the
-  // constant pool, so that must be parsed first.
-  if (auto const env_sexp = CheckList(root->ExtraLookupValue("env"))) {
-    current_block_ = graph;
-    auto const env = ParseEnvironment(env_sexp);
-    if (env == nullptr) return nullptr;
-    env->DeepCopyTo(zone(), graph);
-  }
-
-  auto const entries_sexp = CheckTaggedList(Retrieve(root, pos), "Entries");
-  if (!ParseEntries(entries_sexp)) return nullptr;
-  pos++;
-
-  // Now prime the block worklist with entries. We keep the block worklist
-  // in reverse order so that we can just pop the next block for content
-  // parsing off the end.
-  BlockWorklist block_worklist(zone(), entries_sexp->Length() - 1);
-
-  const auto& indirect_entries = graph->indirect_entries();
-  for (auto indirect_entry : indirect_entries) {
-    block_worklist.Add(indirect_entry->block_id());
-  }
-
-  const auto& catch_entries = graph->catch_entries();
-  for (auto catch_entry : catch_entries) {
-    block_worklist.Add(catch_entry->block_id());
-  }
-
-  if (auto const osr_entry = graph->osr_entry()) {
-    block_worklist.Add(osr_entry->block_id());
-  }
-  if (auto const unchecked_entry = graph->unchecked_entry()) {
-    block_worklist.Add(unchecked_entry->block_id());
-  }
-  if (auto const normal_entry = graph->normal_entry()) {
-    block_worklist.Add(normal_entry->block_id());
-  }
-
-  if (!ParseBlocks(root, pos, &block_worklist)) return nullptr;
-
-  // Before we return the new graph, make sure all definitions were found for
-  // all pending values.
-  if (values_map_.Length() > 0) {
-    auto it = values_map_.GetIterator();
-    auto const kv = it.Next();
-    ASSERT(kv->value->length() > 0);
-    const auto& value_info = kv->value->At(0);
-    StoreError(value_info.sexp, "no definition found for use in flow graph");
-    return nullptr;
-  }
-
-  flow_graph_->set_max_block_id(max_block_id_);
-  // The highest numbered SSA temp might need two slots (e.g. for unboxed
-  // integers on 32-bit platforms), so we add 2 to the highest seen SSA temp
-  // index to get to the new current SSA temp index. In cases where the highest
-  // numbered SSA temp originally had only one slot assigned, this can result
-  // in different SSA temp numbering in later passes between the original and
-  // deserialized graphs.
-  flow_graph_->set_current_ssa_temp_index(max_ssa_index_ + 2);
-  // Now that the deserializer has finished re-creating all the blocks in the
-  // flow graph, the blocks must be rediscovered. In addition, if ComputeSSA
-  // has already been run, dominators must be recomputed as well.
-  flow_graph_->DiscoverBlocks();
-  // Currently we only handle SSA graphs, so always do this.
-  GrowableArray<BitVector*> dominance_frontier;
-  flow_graph_->ComputeDominators(&dominance_frontier);
-
-  return flow_graph_;
-}
-
-bool FlowGraphDeserializer::ParseConstantPool(SExpList* pool) {
-  ASSERT(flow_graph_ != nullptr);
-  if (pool == nullptr) return false;
-  // Definitions in the constant pool may refer to later definitions. However,
-  // there should be no cycles possible between constant objects, so using a
-  // worklist algorithm we should always be able to make progress.
-  // Since we will not be adding new definitions, we make the initial size of
-  // the worklist the number of definitions in the constant pool.
-  GrowableArray<SExpList*> worklist(zone(), pool->Length() - 1);
-  // In order to ensure that the definition order is the same in the original
-  // flow graph, we can't just simply call GetConstant() whenever we
-  // successfully parse a constant. Instead, we'll create a stand-in
-  // ConstantInstr that we can temporarily stick in the definition_map_, and
-  // then once finished we'll go back through, add the constants via
-  // GetConstant() and parse any extra information.
-  DirectChainedHashMap<RawPointerKeyValueTrait<SExpList, ConstantInstr*>>
-      parsed_constants(zone());
-  // We keep old_worklist in reverse order so that we can just RemoveLast
-  // to get elements in their original order.
-  for (intptr_t i = pool->Length() - 1; i > 0; i--) {
-    const auto def_sexp = CheckTaggedList(pool->At(i), "def");
-    if (def_sexp == nullptr) return false;
-    worklist.Add(def_sexp);
-  }
-  while (true) {
-    const intptr_t worklist_len = worklist.length();
-    GrowableArray<SExpList*> parse_failures(zone(), worklist_len);
-    while (!worklist.is_empty()) {
-      const auto def_sexp = worklist.RemoveLast();
-      auto& obj = Object::ZoneHandle(zone());
-      if (!ParseDartValue(Retrieve(def_sexp, 2), &obj)) {
-        parse_failures.Add(def_sexp);
-        continue;
-      }
-      ConstantInstr* def = new (zone()) ConstantInstr(obj);
-      // Instead of parsing the whole definition, just get the SSA index so
-      // we can insert it into the definition_map_.
-      intptr_t index;
-      auto const name_sexp = CheckSymbol(Retrieve(def_sexp, 1));
-      if (!ParseSSATemp(name_sexp, &index)) return false;
-      def->set_ssa_temp_index(index);
-      ASSERT(!definition_map_.HasKey(index));
-      definition_map_.Insert(index, def);
-      parsed_constants.Insert({def_sexp, def});
-    }
-    if (parse_failures.is_empty()) break;
-    // We've gone through the whole worklist without success, so return
-    // the last error we encountered.
-    if (parse_failures.length() == worklist_len) return false;
-    // worklist was added to in order, so we need to reverse its contents
-    // when we add them to old_worklist.
-    while (!parse_failures.is_empty()) {
-      worklist.Add(parse_failures.RemoveLast());
-    }
-  }
-  // Now loop back through the constant pool definition S-expressions and
-  // get the real ConstantInstrs the flow graph will be using and finish
-  // parsing.
-  for (intptr_t i = 1; i < pool->Length(); i++) {
-    auto const def_sexp = CheckTaggedList(pool->At(i));
-    auto const temp_def = parsed_constants.LookupValue(def_sexp);
-    ASSERT(temp_def != nullptr);
-    // Remove the temporary definition from definition_map_ so this doesn't get
-    // flagged as a redefinition.
-    definition_map_.Remove(temp_def->ssa_temp_index());
-    ConstantInstr* real_def = flow_graph_->GetConstant(temp_def->value());
-    if (!ParseDefinitionWithParsedBody(def_sexp, real_def)) return false;
-    ASSERT(temp_def->ssa_temp_index() == real_def->ssa_temp_index());
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseEntries(SExpList* list) {
-  ASSERT(flow_graph_ != nullptr);
-  if (list == nullptr) return false;
-  for (intptr_t i = 1; i < list->Length(); i++) {
-    const auto entry = CheckTaggedList(Retrieve(list, i));
-    if (entry == nullptr) return false;
-    intptr_t block_id;
-    if (!ParseBlockId(CheckSymbol(Retrieve(entry, 1)), &block_id)) {
-      return false;
-    }
-    if (block_map_.LookupValue(block_id) != nullptr) {
-      StoreError(entry->At(1), "multiple entries for block found");
-      return false;
-    }
-    const auto tag = entry->Tag();
-    if (ParseBlockHeader(entry, block_id, tag) == nullptr) return false;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseBlocks(SExpList* list,
-                                        intptr_t pos,
-                                        BlockWorklist* worklist) {
-  // First, ensure that all the block headers have been parsed. Set up a
-  // map from block IDs to S-expressions and the max_block_id while we're at it.
-  IntMap<SExpList*> block_sexp_map(zone());
-  for (intptr_t i = pos, n = list->Length(); i < n; i++) {
-    auto const block_sexp = CheckTaggedList(Retrieve(list, i), "Block");
-    intptr_t block_id;
-    if (!ParseBlockId(CheckSymbol(Retrieve(block_sexp, 1)), &block_id)) {
-      return false;
-    }
-    if (block_sexp_map.LookupValue(block_id) != nullptr) {
-      StoreError(block_sexp->At(1), "multiple definitions of block found");
-      return false;
-    }
-    block_sexp_map.Insert(block_id, block_sexp);
-    auto const type_tag =
-        CheckSymbol(block_sexp->ExtraLookupValue("block_type"));
-    // Entry block headers are already parsed, but others aren't.
-    if (block_map_.LookupValue(block_id) == nullptr) {
-      if (ParseBlockHeader(block_sexp, block_id, type_tag) == nullptr) {
-        return false;
-      }
-    }
-    if (max_block_id_ < block_id) max_block_id_ = block_id;
-  }
-
-  // Now start parsing the contents of blocks from the worklist. We use an
-  // IntMap to keep track of what blocks have already been fully parsed.
-  IntMap<bool> fully_parsed_block_map(zone());
-  while (!worklist->is_empty()) {
-    auto const block_id = worklist->RemoveLast();
-
-    // If we've already encountered this block, skip it.
-    if (fully_parsed_block_map.LookupValue(block_id)) continue;
-
-    auto const block_sexp = block_sexp_map.LookupValue(block_id);
-    ASSERT(block_sexp != nullptr);
-
-    current_block_ = block_map_.LookupValue(block_id);
-    ASSERT(current_block_ != nullptr);
-    ASSERT(current_block_->PredecessorCount() > 0);
-
-    if (!ParseBlockContents(block_sexp, worklist)) return false;
-
-    // Mark this block as done.
-    fully_parsed_block_map.Insert(block_id, true);
-  }
-
-  // Double-check that all blocks were reached by the worklist algorithm.
-  auto it = block_sexp_map.GetIterator();
-  while (auto kv = it.Next()) {
-    if (!fully_parsed_block_map.LookupValue(kv->key)) {
-      StoreError(kv->value, "block unreachable in flow graph");
-      return false;
-    }
-  }
-
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseInitialDefinitions(SExpList* list) {
-  ASSERT(current_block_ != nullptr);
-  ASSERT(current_block_->IsBlockEntryWithInitialDefs());
-  auto const block = current_block_->AsBlockEntryWithInitialDefs();
-  if (list == nullptr) return false;
-  for (intptr_t i = 2; i < list->Length(); i++) {
-    const auto def_sexp = CheckTaggedList(Retrieve(list, i), "def");
-    const auto def = ParseDefinition(def_sexp);
-    if (def == nullptr) return false;
-    flow_graph_->AddToInitialDefinitions(block, def);
-  }
-  return true;
-}
-
-BlockEntryInstr* FlowGraphDeserializer::ParseBlockHeader(SExpList* list,
-                                                         intptr_t block_id,
-                                                         SExpSymbol* tag) {
-  ASSERT(flow_graph_ != nullptr);
-  // We should only parse block headers once.
-  ASSERT(block_map_.LookupValue(block_id) == nullptr);
-  if (list == nullptr) return nullptr;
-
-#if defined(DEBUG)
-  intptr_t parsed_block_id;
-  auto const id_sexp = CheckSymbol(Retrieve(list, 1));
-  if (!ParseBlockId(id_sexp, &parsed_block_id)) return nullptr;
-  ASSERT(block_id == parsed_block_id);
-#endif
-
-  auto const kind = FlowGraphSerializer::BlockEntryTagToKind(tag);
-
-  intptr_t deopt_id = DeoptId::kNone;
-  if (auto const deopt_int = CheckInteger(list->ExtraLookupValue("deopt_id"))) {
-    deopt_id = deopt_int->value();
-  }
-  intptr_t try_index = kInvalidTryIndex;
-  if (auto const try_int = CheckInteger(list->ExtraLookupValue("try_index"))) {
-    try_index = try_int->value();
-  }
-
-  BlockEntryInstr* block = nullptr;
-  EntryInfo common_info = {block_id, try_index, deopt_id};
-  switch (kind) {
-    case FlowGraphSerializer::kTarget:
-      block = DeserializeTargetEntry(list, common_info);
-      break;
-    case FlowGraphSerializer::kNormal:
-      block = DeserializeFunctionEntry(list, common_info);
-      if (block != nullptr) {
-        auto const graph = flow_graph_->graph_entry();
-        graph->set_normal_entry(block->AsFunctionEntry());
-      }
-      break;
-    case FlowGraphSerializer::kUnchecked: {
-      block = DeserializeFunctionEntry(list, common_info);
-      if (block != nullptr) {
-        auto const graph = flow_graph_->graph_entry();
-        graph->set_unchecked_entry(block->AsFunctionEntry());
-      }
-      break;
-    }
-    case FlowGraphSerializer::kJoin:
-      block = DeserializeJoinEntry(list, common_info);
-      break;
-    case FlowGraphSerializer::kInvalid:
-      StoreError(tag, "invalid block entry tag");
-      return nullptr;
-    default:
-      StoreError(tag, "unhandled block type");
-      return nullptr;
-  }
-  if (block == nullptr) return nullptr;
-
-  block_map_.Insert(block_id, block);
-  return block;
-}
-
-bool FlowGraphDeserializer::ParsePhis(SExpList* list) {
-  ASSERT(current_block_ != nullptr && current_block_->IsJoinEntry());
-  auto const join = current_block_->AsJoinEntry();
-  const intptr_t start_pos = 2;
-  auto const end_pos = SkipPhis(list);
-  if (end_pos < start_pos) return false;
-
-  for (intptr_t i = start_pos; i < end_pos; i++) {
-    auto const def_sexp = CheckTaggedList(Retrieve(list, i), "def");
-    auto const phi_sexp = CheckTaggedList(Retrieve(def_sexp, 2), "Phi");
-    // SkipPhis should already have checked which instructions, if any,
-    // are Phi definitions.
-    ASSERT(phi_sexp != nullptr);
-
-    // This is a generalization of FlowGraph::AddPhi where we let ParseValue
-    // create the values (as they may contain type information).
-    auto const phi = new (zone()) PhiInstr(join, phi_sexp->Length() - 1);
-    phi->mark_alive();
-    for (intptr_t i = 0, n = phi_sexp->Length() - 1; i < n; i++) {
-      auto const val = ParseValue(Retrieve(phi_sexp, i + 1));
-      if (val == nullptr) return false;
-      phi->SetInputAt(i, val);
-      val->definition()->AddInputUse(val);
-    }
-    join->InsertPhi(phi);
-
-    if (!ParseDefinitionWithParsedBody(def_sexp, phi)) return false;
-  }
-
-  return true;
-}
-
-intptr_t FlowGraphDeserializer::SkipPhis(SExpList* list) {
-  // All blocks are S-exps of the form (Block B# inst...), so skip the first
-  // two entries and then skip any Phi definitions.
-  for (intptr_t i = 2, n = list->Length(); i < n; i++) {
-    auto const def_sexp = CheckTaggedList(Retrieve(list, i), "def");
-    if (def_sexp == nullptr) return i;
-    auto const phi_sexp = CheckTaggedList(Retrieve(def_sexp, 2), "Phi");
-    if (phi_sexp == nullptr) return i;
-  }
-
-  StoreError(list, "block is empty or contains only Phi definitions");
-  return -1;
-}
-
-bool FlowGraphDeserializer::ParseBlockContents(SExpList* list,
-                                               BlockWorklist* worklist) {
-  ASSERT(current_block_ != nullptr);
-
-  // Parse any Phi definitions now before parsing the block environment.
-  if (current_block_->IsJoinEntry()) {
-    if (!ParsePhis(list)) return false;
-  }
-
-  // For blocks with initial definitions or phi definitions, this needs to be
-  // done after those are parsed. In addition, block environments can also use
-  // definitions from dominating blocks, so we need the contents of dominating
-  // blocks to first be parsed.
-  //
-  // However, we must parse the environment before parsing any instructions
-  // in the body of the block to ensure we don't mistakenly allow local
-  // definitions to appear in the environment.
-  if (auto const env_sexp = CheckList(list->ExtraLookupValue("env"))) {
-    auto const env = ParseEnvironment(env_sexp);
-    if (env == nullptr) return false;
-    env->DeepCopyTo(zone(), current_block_);
-  }
-
-  auto const pos = SkipPhis(list);
-  if (pos < 2) return false;
-  Instruction* last_inst = current_block_;
-  for (intptr_t i = pos, n = list->Length(); i < n; i++) {
-    auto const inst = ParseInstruction(CheckTaggedList(Retrieve(list, i)));
-    if (inst == nullptr) return false;
-    last_inst = last_inst->AppendInstruction(inst);
-  }
-
-  ASSERT(last_inst != nullptr && last_inst != current_block_);
-  if (last_inst->SuccessorCount() > 0) {
-    for (intptr_t i = last_inst->SuccessorCount() - 1; i >= 0; i--) {
-      auto const succ_block = last_inst->SuccessorAt(i);
-      succ_block->AddPredecessor(current_block_);
-      worklist->Add(succ_block->block_id());
-    }
-  }
-
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseDefinitionWithParsedBody(SExpList* list,
-                                                          Definition* def) {
-  if (auto const type_sexp =
-          CheckTaggedList(list->ExtraLookupValue("type"), "CompileType")) {
-    CompileType* typ = ParseCompileType(type_sexp);
-    if (typ == nullptr) return false;
-    def->UpdateType(*typ);
-  }
-
-  if (auto const range_sexp =
-          CheckTaggedList(list->ExtraLookupValue("range"), "Range")) {
-    Range range;
-    if (!ParseRange(range_sexp, &range)) return false;
-    def->set_range(range);
-  }
-
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (name_sexp == nullptr) return false;
-
-  // If the name is "_", this is a subclass of Definition where there's no real
-  // "result" that's being bound. We were just here to add Definition-specific
-  // extra info.
-  if (name_sexp->Equals("_")) return true;
-
-  intptr_t index;
-  if (ParseSSATemp(name_sexp, &index)) {
-    if (definition_map_.HasKey(index)) {
-      StoreError(list, "multiple definitions for the same SSA index");
-      return false;
-    }
-    def->set_ssa_temp_index(index);
-    if (index > max_ssa_index_) max_ssa_index_ = index;
-  } else {
-    // TODO(sstrickl): Add temp support for non-SSA computed graphs.
-    StoreError(list, "unhandled name for definition");
-    return false;
-  }
-
-  definition_map_.Insert(index, def);
-  if (!FixPendingValues(index, def)) return false;
-  return true;
-}
-
-Definition* FlowGraphDeserializer::ParseDefinition(SExpList* list) {
-  if (list == nullptr) return nullptr;
-  ASSERT(list->Tag() != nullptr && list->Tag()->Equals("def"));
-  auto const inst_sexp = CheckTaggedList(Retrieve(list, 2));
-  auto const inst = ParseInstruction(inst_sexp);
-  if (inst == nullptr) return nullptr;
-  if (auto const def = inst->AsDefinition()) {
-    if (!ParseDefinitionWithParsedBody(list, def)) return nullptr;
-    return def;
-  } else {
-    StoreError(list, "instruction cannot be body of definition");
-    return nullptr;
-  }
-}
-
-Instruction* FlowGraphDeserializer::ParseInstruction(SExpList* list) {
-  if (list == nullptr) return nullptr;
-  auto const tag = list->Tag();
-  if (tag->Equals("def")) return ParseDefinition(list);
-
-  intptr_t deopt_id = DeoptId::kNone;
-  if (auto const deopt_int = CheckInteger(list->ExtraLookupValue("deopt_id"))) {
-    deopt_id = deopt_int->value();
-  }
-  TokenPosition token_pos = TokenPosition::kNoSource;
-  if (auto const token_int =
-          CheckInteger(list->ExtraLookupValue("token_pos"))) {
-    token_pos = TokenPosition::Deserialize(token_int->value());
-  }
-  intptr_t inlining_id = -1;
-  if (auto const inlining_int =
-          CheckInteger(list->ExtraLookupValue("inlining_id"))) {
-    inlining_id = inlining_int->value();
-  }
-  InstrInfo common_info = {deopt_id, InstructionSource(token_pos, inlining_id)};
-
-  // Parse the environment before handling the instruction, as we may have
-  // references to PushArguments and parsing the instruction may pop
-  // PushArguments off the stack.
-  // TODO(alexmarkov): revise as it may not be needed anymore.
-  Environment* env = nullptr;
-  if (auto const env_sexp = CheckList(list->ExtraLookupValue("env"))) {
-    env = ParseEnvironment(env_sexp);
-    if (env == nullptr) return nullptr;
-  }
-
-  Instruction* inst = nullptr;
-
-#define HANDLE_CASE(name)                                                      \
-  case kHandled##name:                                                         \
-    inst = Deserialize##name(list, common_info);                               \
-    break;
-  switch (HandledInstructionForTag(tag)) {
-    FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLE_CASE)
-    case kHandledInvalid:
-      StoreError(tag, "unhandled instruction");
-      return nullptr;
-  }
-#undef HANDLE_CASE
-
-  if (inst == nullptr) return nullptr;
-  if (env != nullptr) env->DeepCopyTo(zone(), inst);
-  return inst;
-}
-
-FunctionEntryInstr* FlowGraphDeserializer::DeserializeFunctionEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  ASSERT(flow_graph_ != nullptr);
-  auto const graph = flow_graph_->graph_entry();
-  auto const block = new (zone())
-      FunctionEntryInstr(graph, info.block_id, info.try_index, info.deopt_id);
-  current_block_ = block;
-  if (!ParseInitialDefinitions(sexp)) return nullptr;
-  return block;
-}
-
-GraphEntryInstr* FlowGraphDeserializer::DeserializeGraphEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  auto const name_sexp = CheckSymbol(Retrieve(sexp, 1));
-  // TODO(sstrickl): If the FlowGraphDeserializer was constructed with a
-  // non-null ParsedFunction, we should check that the name matches here.
-  // If not, then we should create an appropriate ParsedFunction here.
-  if (name_sexp == nullptr) return nullptr;
-
-  intptr_t osr_id = Compiler::kNoOSRDeoptId;
-  if (auto const osr_id_sexp = CheckInteger(sexp->ExtraLookupValue("osr_id"))) {
-    osr_id = osr_id_sexp->value();
-  }
-
-  ASSERT(parsed_function_ != nullptr);
-  return new (zone()) GraphEntryInstr(*parsed_function_, osr_id, info.deopt_id);
-}
-
-JoinEntryInstr* FlowGraphDeserializer::DeserializeJoinEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  return new (zone())
-      JoinEntryInstr(info.block_id, info.try_index, info.deopt_id);
-}
-
-TargetEntryInstr* FlowGraphDeserializer::DeserializeTargetEntry(
-    SExpList* sexp,
-    const EntryInfo& info) {
-  return new (zone())
-      TargetEntryInstr(info.block_id, info.try_index, info.deopt_id);
-}
-
-AllocateObjectInstr* FlowGraphDeserializer::DeserializeAllocateObject(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& cls = Class::ZoneHandle(zone());
-  auto const cls_sexp = CheckTaggedList(Retrieve(sexp, 1), "Class");
-  if (!ParseClass(cls_sexp, &cls)) return nullptr;
-
-  Value* type_arguments = nullptr;
-  if (cls.NumTypeArguments() > 0) {
-    type_arguments = ParseValue(Retrieve(sexp, 2));
-    if (type_arguments == nullptr) return nullptr;
-  }
-
-  auto const inst =
-      new (zone()) AllocateObjectInstr(info.source, cls, type_arguments);
-
-  if (auto const closure_sexp = CheckTaggedList(
-          sexp->ExtraLookupValue("closure_function"), "Function")) {
-    auto& closure_function = Function::Handle(zone());
-    if (!ParseFunction(closure_sexp, &closure_function)) return nullptr;
-    inst->set_closure_function(closure_function);
-  }
-
-  if (auto const ident_sexp = CheckSymbol(sexp->ExtraLookupValue("identity"))) {
-    auto id = AliasIdentity::Unknown();
-    if (!AliasIdentity::Parse(ident_sexp->value(), &id)) {
-      return nullptr;
-    }
-    inst->SetIdentity(id);
-  }
-
-  return inst;
-}
-
-AssertAssignableInstr* FlowGraphDeserializer::DeserializeAssertAssignable(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  auto const dst_type = ParseValue(Retrieve(sexp, 2));
-  if (dst_type == nullptr) return nullptr;
-
-  auto const inst_type_args = ParseValue(Retrieve(sexp, 3));
-  if (inst_type_args == nullptr) return nullptr;
-
-  auto const func_type_args = ParseValue(Retrieve(sexp, 4));
-  if (func_type_args == nullptr) return nullptr;
-
-  auto& dst_name = String::ZoneHandle(zone());
-  auto const dst_name_sexp = Retrieve(sexp, "name");
-  if (!ParseDartValue(dst_name_sexp, &dst_name)) return nullptr;
-
-  auto kind = AssertAssignableInstr::Kind::kUnknown;
-  if (auto const kind_sexp = CheckSymbol(sexp->ExtraLookupValue("kind"))) {
-    if (!AssertAssignableInstr::ParseKind(kind_sexp->value(), &kind)) {
-      StoreError(kind_sexp, "unknown AssertAssignable kind");
-      return nullptr;
-    }
-  }
-
-  return new (zone())
-      AssertAssignableInstr(info.source, val, dst_type, inst_type_args,
-                            func_type_args, dst_name, info.deopt_id, kind);
-}
-
-AssertBooleanInstr* FlowGraphDeserializer::DeserializeAssertBoolean(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  return new (zone()) AssertBooleanInstr(info.source, val, info.deopt_id);
-}
-
-BooleanNegateInstr* FlowGraphDeserializer::DeserializeBooleanNegate(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const value = ParseValue(Retrieve(sexp, 1));
-  if (value == nullptr) return nullptr;
-
-  return new (zone()) BooleanNegateInstr(value);
-}
-
-BranchInstr* FlowGraphDeserializer::DeserializeBranch(SExpList* sexp,
-                                                      const InstrInfo& info) {
-  auto const comp_sexp = CheckTaggedList(Retrieve(sexp, 1));
-  auto const comp_inst = ParseInstruction(comp_sexp);
-  if (comp_inst == nullptr) return nullptr;
-  if (!comp_inst->IsComparison()) {
-    StoreError(sexp->At(1), "expected comparison instruction");
-    return nullptr;
-  }
-  auto const comparison = comp_inst->AsComparison();
-
-  auto const true_block = FetchBlock(CheckSymbol(Retrieve(sexp, 2)));
-  if (true_block == nullptr) return nullptr;
-  if (!true_block->IsTargetEntry()) {
-    StoreError(sexp->At(2), "true successor is not a target block");
-    return nullptr;
-  }
-
-  auto const false_block = FetchBlock(CheckSymbol(Retrieve(sexp, 3)));
-  if (false_block == nullptr) return nullptr;
-  if (!false_block->IsTargetEntry()) {
-    StoreError(sexp->At(3), "false successor is not a target block");
-    return nullptr;
-  }
-
-  auto const branch = new (zone()) BranchInstr(comparison, info.deopt_id);
-  *branch->true_successor_address() = true_block->AsTargetEntry();
-  *branch->false_successor_address() = false_block->AsTargetEntry();
-  return branch;
-}
-
-CheckNullInstr* FlowGraphDeserializer::DeserializeCheckNull(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  auto& func_name = String::ZoneHandle(zone());
-  if (auto const name_sexp =
-          CheckString(sexp->ExtraLookupValue("function_name"))) {
-    func_name = String::New(name_sexp->value(), Heap::kOld);
-  }
-
-  return new (zone())
-      CheckNullInstr(val, func_name, info.deopt_id, info.source);
-}
-
-CheckStackOverflowInstr* FlowGraphDeserializer::DeserializeCheckStackOverflow(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  intptr_t stack_depth = 0;
-  if (auto const stack_sexp =
-          CheckInteger(sexp->ExtraLookupValue("stack_depth"))) {
-    stack_depth = stack_sexp->value();
-  }
-
-  intptr_t loop_depth = 0;
-  if (auto const loop_sexp =
-          CheckInteger(sexp->ExtraLookupValue("loop_depth"))) {
-    loop_depth = loop_sexp->value();
-  }
-
-  auto kind = CheckStackOverflowInstr::kOsrAndPreemption;
-  if (auto const kind_sexp = CheckSymbol(sexp->ExtraLookupValue("kind"))) {
-    ASSERT(kind_sexp->Equals("OsrOnly"));
-    kind = CheckStackOverflowInstr::kOsrOnly;
-  }
-
-  return new (zone()) CheckStackOverflowInstr(info.source, stack_depth,
-                                              loop_depth, info.deopt_id, kind);
-}
-
-ConstantInstr* FlowGraphDeserializer::DeserializeConstant(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  Object& obj = Object::ZoneHandle(zone());
-  if (!ParseDartValue(Retrieve(sexp, 1), &obj)) return nullptr;
-  return new (zone()) ConstantInstr(obj, info.source);
-}
-
-DebugStepCheckInstr* FlowGraphDeserializer::DeserializeDebugStepCheck(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto kind = UntaggedPcDescriptors::kAnyKind;
-  if (auto const kind_sexp = CheckSymbol(Retrieve(sexp, "stub_kind"))) {
-    if (!UntaggedPcDescriptors::ParseKind(kind_sexp->value(), &kind)) {
-      StoreError(kind_sexp, "not a valid UntaggedPcDescriptors::Kind name");
-      return nullptr;
-    }
-  }
-  return new (zone()) DebugStepCheckInstr(info.source, kind, info.deopt_id);
-}
-
-GotoInstr* FlowGraphDeserializer::DeserializeGoto(SExpList* sexp,
-                                                  const InstrInfo& info) {
-  auto const block = FetchBlock(CheckSymbol(Retrieve(sexp, 1)));
-  if (block == nullptr) return nullptr;
-  if (!block->IsJoinEntry()) {
-    StoreError(sexp->At(1), "target of goto must be join entry");
-    return nullptr;
-  }
-  return new (zone()) GotoInstr(block->AsJoinEntry(), info.deopt_id);
-}
-
-InstanceCallInstr* FlowGraphDeserializer::DeserializeInstanceCall(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& interface_target = Function::ZoneHandle(zone());
-  auto& tearoff_interface_target = Function::ZoneHandle(zone());
-  if (!ParseDartValue(Retrieve(sexp, "interface_target"), &interface_target)) {
-    return nullptr;
-  }
-  if (!ParseDartValue(Retrieve(sexp, "tearoff_interface_target"),
-                      &tearoff_interface_target)) {
-    return nullptr;
-  }
-  auto& function_name = String::ZoneHandle(zone());
-  // If we have an explicit function_name value, then use that value. Otherwise,
-  // if we have an non-null interface_target, use its name.
-  if (auto const name_sexp = sexp->ExtraLookupValue("function_name")) {
-    if (!ParseDartValue(name_sexp, &function_name)) return nullptr;
-  } else if (!interface_target.IsNull()) {
-    function_name = interface_target.name();
-  } else if (!tearoff_interface_target.IsNull()) {
-    function_name = tearoff_interface_target.name();
-  }
-
-  auto token_kind = Token::Kind::kILLEGAL;
-  if (auto const kind_sexp =
-          CheckSymbol(sexp->ExtraLookupValue("token_kind"))) {
-    if (!Token::FromStr(kind_sexp->value(), &token_kind)) {
-      StoreError(kind_sexp, "unexpected token kind");
-      return nullptr;
-    }
-  }
-
-  CallInfo call_info(zone());
-  if (!ParseCallInfo(sexp, &call_info)) return nullptr;
-
-  intptr_t checked_arg_count = 0;
-  if (auto const checked_sexp =
-          CheckInteger(sexp->ExtraLookupValue("checked_arg_count"))) {
-    checked_arg_count = checked_sexp->value();
-  }
-
-  auto const inst = new (zone()) InstanceCallInstr(
-      info.source, function_name, token_kind, call_info.inputs,
-      call_info.type_args_len, call_info.argument_names, checked_arg_count,
-      info.deopt_id, interface_target, tearoff_interface_target);
-
-  if (call_info.result_type != nullptr) {
-    inst->SetResultType(zone(), *call_info.result_type);
-  }
-
-  inst->set_entry_kind(call_info.entry_kind);
-
-  if (auto const ic_data_sexp =
-          CheckTaggedList(Retrieve(sexp, "ic_data"), "ICData")) {
-    if (!CreateICData(ic_data_sexp, inst)) return nullptr;
-  }
-
-  return inst;
-}
-
-LoadClassIdInstr* FlowGraphDeserializer::DeserializeLoadClassId(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const val = ParseValue(Retrieve(sexp, 1));
-  if (val == nullptr) return nullptr;
-
-  return new (zone()) LoadClassIdInstr(val);
-}
-
-LoadFieldInstr* FlowGraphDeserializer::DeserializeLoadField(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const instance = ParseValue(Retrieve(sexp, 1));
-  if (instance == nullptr) return nullptr;
-
-  const Slot* slot;
-  if (!ParseSlot(CheckTaggedList(Retrieve(sexp, 2)), &slot)) return nullptr;
-
-  bool calls_initializer = false;
-  if (auto const calls_initializer_sexp =
-          CheckBool(sexp->ExtraLookupValue("calls_initializer"))) {
-    calls_initializer = calls_initializer_sexp->value();
-  }
-
-  return new (zone()) LoadFieldInstr(instance, *slot, info.source,
-                                     calls_initializer, info.deopt_id);
-}
-
-NativeCallInstr* FlowGraphDeserializer::DeserializeNativeCall(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& function = Function::ZoneHandle(zone());
-  if (!ParseDartValue(Retrieve(sexp, "function"), &function)) return nullptr;
-  if (!function.IsFunction()) {
-    StoreError(sexp->At(1), "expected a Function value");
-    return nullptr;
-  }
-
-  auto const name_sexp = CheckString(Retrieve(sexp, "name"));
-  if (name_sexp == nullptr) return nullptr;
-  const auto& name =
-      String::ZoneHandle(zone(), String::New(name_sexp->value()));
-
-  bool link_lazily = false;
-  if (auto const link_sexp = CheckBool(sexp->ExtraLookupValue("link_lazily"))) {
-    link_lazily = link_sexp->value();
-  }
-
-  CallInfo call_info(zone());
-  if (!ParseCallInfo(sexp, &call_info)) return nullptr;
-
-  return new (zone()) NativeCallInstr(&name, &function, link_lazily,
-                                      info.source, call_info.inputs);
-}
-
-ParameterInstr* FlowGraphDeserializer::DeserializeParameter(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  ASSERT(current_block_ != nullptr);
-  if (auto const index_sexp = CheckInteger(Retrieve(sexp, 1))) {
-    const auto param_offset_sexp =
-        CheckInteger(sexp->ExtraLookupValue("param_offset"));
-    ASSERT(param_offset_sexp != nullptr);
-    const auto representation_sexp =
-        CheckSymbol(sexp->ExtraLookupValue("representation"));
-    Representation representation;
-    if (!Location::ParseRepresentation(representation_sexp->value(),
-                                       &representation)) {
-      StoreError(representation_sexp, "unknown parameter representation");
-    }
-    return new (zone())
-        ParameterInstr(index_sexp->value(), param_offset_sexp->value(),
-                       current_block_, representation);
-  }
-  return nullptr;
-}
-
-ReturnInstr* FlowGraphDeserializer::DeserializeReturn(SExpList* list,
-                                                      const InstrInfo& info) {
-  Value* val = ParseValue(Retrieve(list, 1));
-  if (val == nullptr) return nullptr;
-  return new (zone()) ReturnInstr(info.source, val, info.deopt_id);
-}
-
-SpecialParameterInstr* FlowGraphDeserializer::DeserializeSpecialParameter(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  ASSERT(current_block_ != nullptr);
-  auto const kind_sexp = CheckSymbol(Retrieve(sexp, 1));
-  if (kind_sexp == nullptr) return nullptr;
-  SpecialParameterInstr::SpecialParameterKind kind;
-  if (!SpecialParameterInstr::ParseKind(kind_sexp->value(), &kind)) {
-    StoreError(kind_sexp, "unknown special parameter kind");
-    return nullptr;
-  }
-  return new (zone())
-      SpecialParameterInstr(kind, info.deopt_id, current_block_);
-}
-
-StaticCallInstr* FlowGraphDeserializer::DeserializeStaticCall(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto& function = Function::ZoneHandle(zone());
-  auto const function_sexp =
-      CheckTaggedList(Retrieve(sexp, "function"), "Function");
-  if (!ParseFunction(function_sexp, &function)) return nullptr;
-
-  CallInfo call_info(zone());
-  if (!ParseCallInfo(sexp, &call_info)) return nullptr;
-
-  intptr_t call_count = 0;
-  if (auto const call_count_sexp =
-          CheckInteger(sexp->ExtraLookupValue("call_count"))) {
-    call_count = call_count_sexp->value();
-  }
-
-  auto rebind_rule = ICData::kStatic;
-  if (auto const rebind_sexp =
-          CheckSymbol(sexp->ExtraLookupValue("rebind_rule"))) {
-    if (!ICData::ParseRebindRule(rebind_sexp->value(), &rebind_rule)) {
-      StoreError(rebind_sexp, "unknown rebind rule value");
-      return nullptr;
-    }
-  }
-
-  auto const inst = new (zone()) StaticCallInstr(
-      info.source, function, call_info.type_args_len, call_info.argument_names,
-      call_info.inputs, info.deopt_id, call_count, rebind_rule);
-
-  if (call_info.result_type != nullptr) {
-    inst->SetResultType(zone(), *call_info.result_type);
-  }
-
-  inst->set_entry_kind(call_info.entry_kind);
-
-  if (auto const ic_data_sexp =
-          CheckTaggedList(sexp->ExtraLookupValue("ic_data"), "ICData")) {
-    if (!CreateICData(ic_data_sexp, inst)) return nullptr;
-  }
-
-  return inst;
-}
-
-StoreInstanceFieldInstr* FlowGraphDeserializer::DeserializeStoreInstanceField(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const instance = ParseValue(Retrieve(sexp, 1));
-  if (instance == nullptr) return nullptr;
-
-  const Slot* slot = nullptr;
-  if (!ParseSlot(CheckTaggedList(Retrieve(sexp, 2), "Slot"), &slot)) {
-    return nullptr;
-  }
-
-  auto const value = ParseValue(Retrieve(sexp, 3));
-  if (value == nullptr) return nullptr;
-
-  auto barrier_type = kNoStoreBarrier;
-  if (auto const bar_sexp = CheckBool(sexp->ExtraLookupValue("emit_barrier"))) {
-    if (bar_sexp->value()) barrier_type = kEmitStoreBarrier;
-  }
-
-  auto kind = StoreInstanceFieldInstr::Kind::kOther;
-  if (auto const init_sexp = CheckBool(sexp->ExtraLookupValue("is_init"))) {
-    if (init_sexp->value()) kind = StoreInstanceFieldInstr::Kind::kInitializing;
-  }
-
-  return new (zone()) StoreInstanceFieldInstr(*slot, instance, value,
-                                              barrier_type, info.source, kind);
-}
-
-StrictCompareInstr* FlowGraphDeserializer::DeserializeStrictCompare(
-    SExpList* sexp,
-    const InstrInfo& info) {
-  auto const token_sexp = CheckSymbol(Retrieve(sexp, 1));
-  if (token_sexp == nullptr) return nullptr;
-  Token::Kind kind;
-  if (!Token::FromStr(token_sexp->value(), &kind)) return nullptr;
-
-  auto const left = ParseValue(Retrieve(sexp, 2));
-  if (left == nullptr) return nullptr;
-
-  auto const right = ParseValue(Retrieve(sexp, 3));
-  if (right == nullptr) return nullptr;
-
-  bool needs_check = false;
-  if (auto const check_sexp = CheckBool(Retrieve(sexp, "needs_check"))) {
-    needs_check = check_sexp->value();
-  }
-
-  return new (zone()) StrictCompareInstr(info.source, kind, left, right,
-                                         needs_check, info.deopt_id);
-}
-
-ThrowInstr* FlowGraphDeserializer::DeserializeThrow(SExpList* sexp,
-                                                    const InstrInfo& info) {
-  Value* exception = ParseValue(Retrieve(sexp, 1));
-  if (exception == nullptr) return nullptr;
-  return new (zone()) ThrowInstr(info.source, info.deopt_id, exception);
-}
-
-bool FlowGraphDeserializer::ParseCallInfo(SExpList* call,
-                                          CallInfo* out,
-                                          intptr_t num_extra_inputs) {
-  ASSERT(out != nullptr);
-
-  if (auto const len_sexp =
-          CheckInteger(call->ExtraLookupValue("type_args_len"))) {
-    out->type_args_len = len_sexp->value();
-  }
-
-  if (auto const arg_names_sexp =
-          CheckList(call->ExtraLookupValue("arg_names"))) {
-    out->argument_names = Array::New(arg_names_sexp->Length(), Heap::kOld);
-    for (intptr_t i = 0, n = arg_names_sexp->Length(); i < n; i++) {
-      auto name_sexp = CheckString(Retrieve(arg_names_sexp, i));
-      if (name_sexp == nullptr) return false;
-      tmp_string_ = String::New(name_sexp->value(), Heap::kOld);
-      out->argument_names.SetAt(i, tmp_string_);
-    }
-  }
-
-  if (auto const args_len_sexp =
-          CheckInteger(call->ExtraLookupValue("args_len"))) {
-    out->args_len = args_len_sexp->value();
-  }
-
-  if (auto const result_sexp = CheckTaggedList(
-          call->ExtraLookupValue("result_type"), "CompileType")) {
-    out->result_type = ParseCompileType(result_sexp);
-  }
-
-  if (auto const kind_sexp =
-          CheckSymbol(call->ExtraLookupValue("entry_kind"))) {
-    if (!Code::ParseEntryKind(kind_sexp->value(), &out->entry_kind))
-      return false;
-  }
-
-  // Type arguments are wrapped in a TypeArguments array, so no matter how
-  // many there are, they are contained in a single pushed argument.
-  auto const all_args_len = (out->type_args_len > 0 ? 1 : 0) + out->args_len;
-
-  const intptr_t num_inputs = all_args_len + num_extra_inputs;
-  out->inputs = new (zone()) InputsArray(zone(), num_inputs);
-  for (intptr_t i = 0; i < num_inputs; ++i) {
-    auto const input = ParseValue(Retrieve(call, 1 + i));
-    if (input == nullptr) return false;
-    out->inputs->Add(input);
-  }
-
-  return true;
-}
-
-Value* FlowGraphDeserializer::ParseValue(SExpression* sexp,
-                                         bool allow_pending) {
-  CompileType* type = nullptr;
-  bool inherit_type = false;
-  auto name = sexp->AsSymbol();
-  if (name == nullptr) {
-    auto const list = CheckTaggedList(sexp, "value");
-    name = CheckSymbol(Retrieve(list, 1));
-    if (auto const type_sexp =
-            CheckTaggedList(list->ExtraLookupValue("type"), "CompileType")) {
-      type = ParseCompileType(type_sexp);
-      if (type == nullptr) return nullptr;
-    } else if (auto const inherit_sexp =
-                   CheckBool(list->ExtraLookupValue("inherit_type"))) {
-      inherit_type = inherit_sexp->value();
-    } else {
-      // We assume that the type should be inherited from the definition for
-      // for (value ...) forms without an explicit type.
-      inherit_type = true;
-    }
-  }
-  intptr_t index;
-  if (!ParseUse(name, &index)) return nullptr;
-  auto const def = definition_map_.LookupValue(index);
-  Value* val;
-  if (def == nullptr) {
-    if (!allow_pending) {
-      StoreError(sexp, "found use prior to definition");
-      return nullptr;
-    }
-    val = AddNewPendingValue(sexp, index, inherit_type);
-  } else {
-    val = new (zone()) Value(def);
-    if (inherit_type) {
-      if (def->HasType()) {
-        val->reaching_type_ = def->Type();
-      } else {
-        StoreError(sexp, "value inherits type, but no type found");
-        return nullptr;
-      }
-    }
-  }
-  if (type != nullptr) val->SetReachingType(type);
-  return val;
-}
-
-CompileType* FlowGraphDeserializer::ParseCompileType(SExpList* sexp) {
-  // TODO(sstrickl): Currently we only print out nullable if it's false
-  // (or during verbose printing). Switch this when NNBD is the standard.
-  bool nullable = CompileType::kNullable;
-  if (auto const nullable_sexp =
-          CheckBool(sexp->ExtraLookupValue("nullable"))) {
-    nullable = nullable_sexp->value() ? CompileType::kNullable
-                                      : CompileType::kNonNullable;
-  }
-
-  intptr_t cid = kIllegalCid;
-  if (auto const cid_sexp = CheckInteger(sexp->ExtraLookupValue("cid"))) {
-    // TODO(sstrickl): Check that the cid is a valid concrete cid, or a cid
-    // otherwise found in CompileTypes like kIllegalCid or kDynamicCid.
-    cid = cid_sexp->value();
-  }
-
-  AbstractType* type = nullptr;
-  if (auto const type_sexp = sexp->ExtraLookupValue("type")) {
-    auto& type_handle = AbstractType::ZoneHandle(zone());
-    if (!ParseAbstractType(type_sexp, &type_handle)) return nullptr;
-    type = &type_handle;
-  }
-  return new (zone()) CompileType(nullable, cid, type);
-}
-
-Environment* FlowGraphDeserializer::ParseEnvironment(SExpList* list) {
-  if (list == nullptr) return nullptr;
-  intptr_t fixed_param_count = 0;
-  if (auto const fpc_sexp =
-          CheckInteger(list->ExtraLookupValue("fixed_param_count"))) {
-    fixed_param_count = fpc_sexp->value();
-  }
-  Environment* outer_env = nullptr;
-  if (auto const outer_sexp = CheckList(list->ExtraLookupValue("outer"))) {
-    outer_env = ParseEnvironment(outer_sexp);
-    if (outer_env == nullptr) return nullptr;
-    if (auto const deopt_sexp =
-            CheckInteger(outer_sexp->ExtraLookupValue("deopt_id"))) {
-      outer_env->deopt_id_ = deopt_sexp->value();
-    }
-  }
-
-  ASSERT(parsed_function_ != nullptr);
-  auto const env = new (zone()) Environment(list->Length(), fixed_param_count,
-                                            *parsed_function_, outer_env);
-
-  for (intptr_t i = 0; i < list->Length(); i++) {
-    auto const elem_sexp = Retrieve(list, i);
-    if (elem_sexp == nullptr) return nullptr;
-    auto val = ParseValue(elem_sexp, /*allow_pending=*/false);
-    if (val == nullptr) return nullptr;
-    env->PushValue(val);
-  }
-
-  return env;
-}
-
-bool FlowGraphDeserializer::ParseDartValue(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-  *out = Object::null();
-
-  if (auto const sym = sexp->AsSymbol()) {
-    // We'll use the null value in *out as a marker later, so go ahead and exit
-    // early if we parse one.
-    if (sym->Equals("null")) return true;
-    if (sym->Equals("sentinel")) {
-      *out = Object::sentinel().ptr();
-      return true;
-    }
-
-    // The only other symbols that should appear in Dart value position are
-    // names of constant definitions.
-    auto const val = ParseValue(sym, /*allow_pending=*/false);
-    if (val == nullptr) return false;
-    if (!val->BindsToConstant()) {
-      StoreError(sym, "not a reference to a constant definition");
-      return false;
-    }
-    *out = val->BoundConstant().ptr();
-    // Values used in constant definitions have already been canonicalized,
-    // so just exit.
-    return true;
-  }
-
-  // Other instance values may need to be canonicalized, so do that before
-  // returning.
-  if (auto const b = sexp->AsBool()) {
-    *out = Bool::Get(b->value()).ptr();
-  } else if (auto const str = sexp->AsString()) {
-    *out = String::New(str->value(), Heap::kOld);
-  } else if (auto const i = sexp->AsInteger()) {
-    *out = Integer::New(i->value(), Heap::kOld);
-  } else if (auto const d = sexp->AsDouble()) {
-    *out = Double::New(d->value(), Heap::kOld);
-  } else if (auto const list = CheckTaggedList(sexp)) {
-    auto const tag = list->Tag();
-    if (tag->Equals("Class")) {
-      return ParseClass(list, out);
-    } else if (tag->Equals("Type")) {
-      return ParseType(list, out);
-    } else if (tag->Equals("TypeArguments")) {
-      return ParseTypeArguments(list, out);
-    } else if (tag->Equals("Field")) {
-      return ParseField(list, out);
-    } else if (tag->Equals("Function")) {
-      return ParseFunction(list, out);
-    } else if (tag->Equals("FunctionType")) {
-      return ParseFunctionType(list, out);
-    } else if (tag->Equals("TypeParameter")) {
-      return ParseTypeParameter(list, out);
-    } else if (tag->Equals("Array")) {
-      return ParseArray(list, out);
-    } else if (tag->Equals("ImmutableList")) {
-      return ParseImmutableList(list, out);
-    } else if (tag->Equals("Instance")) {
-      return ParseInstance(list, out);
-    } else if (tag->Equals("Closure")) {
-      return ParseClosure(list, out);
-    } else if (tag->Equals("TypeRef")) {
-      return ParseTypeRef(list, out);
-    }
-  }
-
-  // If we're here and still haven't gotten a non-null value, then something
-  // went wrong. (Likely an unrecognized value.)
-  if (out->IsNull()) {
-    StoreError(sexp, "unhandled Dart value");
-    return false;
-  }
-
-  if (!out->IsInstance()) return true;
-  return CanonicalizeInstance(sexp, out);
-}
-
-bool FlowGraphDeserializer::CanonicalizeInstance(SExpression* sexp,
-                                                 Object* out) {
-  ASSERT(out != nullptr);
-  if (!out->IsInstance()) return true;
-  // Instance::Canonicalize uses the current zone for the passed in thread,
-  // not an explicitly provided zone. This means we cannot be run in a context
-  // where [thread()->zone()] does not match [zone()] (e.g., due to StackZone)
-  // until this is addressed.
-  *out = Instance::Cast(*out).Canonicalize(thread());
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseAbstractType(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-
-  // If it's a symbol, it should be a reference to a constant definition, which
-  // is handled in ParseType.
-  if (auto const sym = sexp->AsSymbol()) {
-    return ParseType(sexp, out);
-  } else if (auto const list = CheckTaggedList(sexp)) {
-    auto const tag = list->Tag();
-    if (tag->Equals("Type")) {
-      return ParseType(list, out);
-    } else if (tag->Equals("TypeParameter")) {
-      return ParseTypeParameter(list, out);
-    } else if (tag->Equals("TypeRef")) {
-      return ParseTypeRef(list, out);
-    }
-  }
-
-  StoreError(sexp, "not an AbstractType");
-  return false;
-}
-
-bool FlowGraphDeserializer::ParseClass(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  auto const ref_sexp = Retrieve(list, 1);
-  if (ref_sexp == nullptr) return false;
-  if (auto const cid_sexp = ref_sexp->AsInteger()) {
-    ClassTable* table = thread()->isolate_group()->class_table();
-    if (!table->HasValidClassAt(cid_sexp->value())) {
-      StoreError(cid_sexp, "no valid class found for cid");
-      return false;
-    }
-    *out = table->At(cid_sexp->value());
-  } else if (auto const name_sexp = ref_sexp->AsSymbol()) {
-    if (!ParseCanonicalName(name_sexp, out)) return false;
-    if (!out->IsClass()) {
-      StoreError(name_sexp, "expected the name of a class");
-      return false;
-    }
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseClosure(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  auto& function = Function::ZoneHandle(zone());
-  auto const function_sexp = CheckTaggedList(Retrieve(list, 1), "Function");
-  if (!ParseFunction(function_sexp, &function)) return false;
-
-  auto& context = Context::ZoneHandle(zone());
-  if (list->ExtraLookupValue("context") != nullptr) {
-    StoreError(list, "closures with contexts currently unhandled");
-    return false;
-  }
-
-  auto& inst_type_args = TypeArguments::ZoneHandle(zone());
-  if (auto const type_args_sexp = Retrieve(list, "inst_type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &inst_type_args)) return false;
-  }
-
-  auto& func_type_args = TypeArguments::ZoneHandle(zone());
-  if (auto const type_args_sexp = Retrieve(list, "func_type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &func_type_args)) return false;
-  }
-
-  auto& delayed_type_args = TypeArguments::ZoneHandle(zone());
-  if (auto const type_args_sexp = Retrieve(list, "delayed_type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &delayed_type_args)) {
-      return false;
-    }
-  }
-
-  *out = Closure::New(inst_type_args, func_type_args, delayed_type_args,
-                      function, context, Heap::kOld);
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseField(SExpList* list, Object* out) {
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (!ParseCanonicalName(name_sexp, out)) return false;
-  if (!out->IsField()) {
-    StoreError(list, "expected a Field name");
-    return false;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseFunction(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (!ParseCanonicalName(name_sexp, out)) return false;
-  if (!out->IsFunction()) {
-    StoreError(list, "expected a Function name");
-    return false;
-  }
-  auto& function = Function::Cast(*out);
-  // Check the kind expected by the S-expression if one was specified.
-  if (auto const kind_sexp = CheckSymbol(list->ExtraLookupValue("kind"))) {
-    UntaggedFunction::Kind kind;
-    if (!UntaggedFunction::ParseKind(kind_sexp->value(), &kind)) {
-      StoreError(kind_sexp, "unexpected function kind");
-      return false;
-    }
-    if (function.kind() != kind) {
-      auto const kind_str = UntaggedFunction::KindToCString(function.kind());
-      StoreError(list, "retrieved function has kind %s", kind_str);
-      return false;
-    }
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseFunctionType(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-  auto& type_params = TypeArguments::ZoneHandle(zone());
-  if (auto const type_params_sexp = Retrieve(list, "type_params")) {
-    if (!ParseTypeArguments(type_params_sexp, &type_params)) return false;
-  }
-  auto& result_type = AbstractType::ZoneHandle(zone());
-  if (auto const result_type_sexp = Retrieve(list, "result_type")) {
-    if (!ParseAbstractType(result_type_sexp, &result_type)) return false;
-  }
-  auto& parameter_types = Array::ZoneHandle(zone());
-  if (auto const parameter_types_sexp = Retrieve(list, "parameter_types")) {
-    if (!ParseDartValue(parameter_types_sexp, &parameter_types)) return false;
-  }
-  auto& parameter_names = Array::ZoneHandle(zone());
-  if (auto const parameter_names_sexp = Retrieve(list, "parameter_names")) {
-    if (!ParseDartValue(parameter_names_sexp, &parameter_names)) return false;
-  }
-  intptr_t packed_fields;
-  if (auto const packed_fields_sexp =
-          CheckInteger(list->ExtraLookupValue("packed_fields"))) {
-    packed_fields = packed_fields_sexp->value();
-  } else {
-    return false;
-  }
-  auto& sig = FunctionType::ZoneHandle(zone(), FunctionType::New());
-  sig.set_type_parameters(type_params);
-  sig.set_result_type(result_type);
-  sig.set_parameter_types(parameter_types);
-  sig.set_parameter_names(parameter_names);
-  sig.set_packed_fields(packed_fields);
-  *out = sig.ptr();
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseArray(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  *out = Array::New(list->Length() - 1, Heap::kOld);
-  auto& arr = Array::Cast(*out);
-  // Arrays may contain other arrays, so we'll need a new handle in which to
-  // store elements.
-  auto& elem = Object::Handle(zone());
-  for (intptr_t i = 1; i < list->Length(); i++) {
-    if (!ParseDartValue(Retrieve(list, i), &elem)) return false;
-    arr.SetAt(i - 1, elem);
-  }
-  if (auto type_args_sexp = list->ExtraLookupValue("type_args")) {
-    if (!ParseTypeArguments(type_args_sexp, &array_type_args_)) return false;
-    arr.SetTypeArguments(array_type_args_);
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseImmutableList(SExpList* list, Object* out) {
-  if (!ParseArray(list, out)) return false;
-
-  Array::Cast(*out).MakeImmutable();
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseInstance(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-  auto const cid_sexp = CheckInteger(Retrieve(list, 1));
-  if (cid_sexp == nullptr) return false;
-
-  auto const table = thread()->isolate_group()->class_table();
-  if (!table->HasValidClassAt(cid_sexp->value())) {
-    StoreError(cid_sexp, "cid is not valid");
-    return false;
-  }
-
-  ASSERT(cid_sexp->value() != kNullCid);  // Must use canonical instances.
-  ASSERT(cid_sexp->value() != kBoolCid);  // Must use canonical instances.
-  instance_class_ = table->At(cid_sexp->value());
-  *out = Instance::New(instance_class_, Heap::kOld);
-  auto& instance = Instance::Cast(*out);
-
-  if (auto const type_args = list->ExtraLookupValue("type_args")) {
-    instance_type_args_ = TypeArguments::null();
-    if (!ParseTypeArguments(type_args, &instance_type_args_)) return false;
-    if (!instance_class_.IsGeneric()) {
-      StoreError(list,
-                 "type arguments provided for an instance of a "
-                 "non-generic class");
-      return false;
-    }
-    instance.SetTypeArguments(instance_type_args_);
-  }
-
-  // Pick out and store the final instance fields of the class, as values must
-  // be provided for them. Error if there are any non-final instance fields.
-  instance_fields_array_ = instance_class_.fields();
-  auto const field_count = instance_fields_array_.Length();
-  GrowableArray<const Field*> final_fields(zone(), field_count);
-  for (intptr_t i = 0, n = field_count; i < n; i++) {
-    instance_field_ = Field::RawCast(instance_fields_array_.At(i));
-    if (!instance_field_.is_instance()) continue;
-    if (!instance_field_.is_final()) {
-      StoreError(list, "class for instance has non-final instance fields");
-      return false;
-    }
-    auto& fresh_handle = Field::Handle(zone(), instance_field_.ptr());
-    final_fields.Add(&fresh_handle);
-  }
-
-  // If there is no (Fields...) sub-expression or it has no extra info, then
-  // ensure there are no final fields before returning the canonicalized form.
-  SExpList* fields_sexp = nullptr;
-  bool fields_provided = list->Length() > 2;
-  if (fields_provided) {
-    fields_sexp = CheckTaggedList(Retrieve(list, 2), "Fields");
-    if (fields_sexp == nullptr) return false;
-    fields_provided = fields_sexp->ExtraLength() != 0;
-  }
-  if (!fields_provided) {
-    if (!final_fields.is_empty()) {
-      StoreError(list, "values not provided for final fields of instance");
-      return false;
-    }
-    return CanonicalizeInstance(list, out);
-  }
-
-  // At this point, we have final instance field values to set on the new
-  // instance before canonicalization. When setting instance fields, we may
-  // cause field guards to be invalidated. Because of this, we must either be
-  // running on the mutator thread or be at a safepoint when calling `SetField`.
-  //
-  // For IR round-trips, the constants we create have already existed before in
-  // the VM heap, which means field invalidation cannot occur. Thus, we create a
-  // closure that sets the fields of the instance and then conditionally run
-  // that closure at a safepoint if not in the mutator thread.
-  //
-  // TODO(dartbug.com/36882): When deserializing IR that was not generated
-  // during the RoundTripSerialization pass, we are no longer guaranteed that
-  // deserialization of instances will not invalidate field guards. Thus, we may
-  // need to support invalidating field guards on non-mutator threads or fall
-  // back onto forcing the deserialization to happen on the mutator thread.
-  auto set_instance_fields = [&]() {
-    auto& inst = Instance::Cast(*out);
-    // We'll need to allocate a handle for the parsed value as we may have
-    // instances as field values and so this function may be re-entered.
-    auto& value = Object::Handle(zone());
-    for (auto field : final_fields) {
-      tmp_string_ = field->UserVisibleName();
-      auto const name = tmp_string_.ToCString();
-      auto const value_sexp = Retrieve(fields_sexp, name);
-      if (value_sexp == nullptr) {
-        StoreError(list, "no value provided for final instance field %s", name);
-        return false;
-      }
-      if (!ParseDartValue(value_sexp, &value)) return false;
-      inst.SetField(*field, value);
-    }
-    return true;
-  };
-
-  auto const t = Thread::Current();
-  if (!t->IsMutatorThread()) {
-    SafepointOperationScope safepoint_scope(t);
-    if (!set_instance_fields()) return false;
-  } else {
-    if (!set_instance_fields()) return false;
-  }
-
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseType(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-
-  if (auto const sym = sexp->AsSymbol()) {
-    auto const val = ParseValue(sexp, /*allow_pending=*/false);
-    if (val == nullptr) {
-      StoreError(sexp, "expected type or reference to constant definition");
-      return false;
-    }
-    if (!val->BindsToConstant()) {
-      StoreError(sexp, "reference to non-constant definition");
-      return false;
-    }
-    *out = val->BoundConstant().ptr();
-    if (!out->IsType()) {
-      StoreError(sexp, "expected Type constant");
-      return false;
-    }
-    return true;
-  }
-  auto const list = CheckTaggedList(sexp, "Type");
-  if (list == nullptr) return false;
-
-  const auto hash_sexp = CheckInteger(list->ExtraLookupValue("hash"));
-  const auto is_recursive = hash_sexp != nullptr;
-  // This isn't necessary the hash value we will have in the new FlowGraph, but
-  // it will be how this type is referred to by TypeRefs in the serialized one.
-  auto const old_hash = is_recursive ? hash_sexp->value() : 0;
-  ZoneGrowableArray<TypeRef*>* pending_typerefs = nullptr;
-  if (is_recursive) {
-    if (pending_typeref_map_.LookupValue(old_hash) != nullptr) {
-      StoreError(sexp, "already parsing a type with hash %" Pd64 "",
-                 hash_sexp->value());
-      return false;
-    }
-    pending_typerefs = new (zone()) ZoneGrowableArray<TypeRef*>(zone(), 2);
-    pending_typeref_map_.Insert(old_hash, pending_typerefs);
-  }
-
-  const auto cls_sexp = CheckTaggedList(Retrieve(list, 1), "Class");
-  if (cls_sexp == nullptr) {
-    // TODO(sstrickl): Handle types not derived from classes.
-    StoreError(list, "non-class types not currently handled");
-    return false;
-  }
-  TokenPosition token_pos = TokenPosition::kNoSource;
-  if (const auto pos_sexp = CheckInteger(list->ExtraLookupValue("token_pos"))) {
-    token_pos = TokenPosition::Deserialize(pos_sexp->value());
-  }
-  auto type_args_ptr = &Object::null_type_arguments();
-  if (const auto ta_sexp = list->ExtraLookupValue("type_args")) {
-    // ParseTypeArguments may re-enter ParseType after setting the contents of
-    // the passed in handle, so we need to allocate a new handle here.
-    auto& type_args = TypeArguments::Handle(zone());
-    if (!ParseTypeArguments(ta_sexp, &type_args)) return false;
-    type_args_ptr = &type_args;
-  }
-  // Guaranteed not to re-enter ParseType.
-  if (!ParseClass(cls_sexp, &type_class_)) return false;
-  const Nullability nullability =
-      type_class_.IsNullClass() ? Nullability::kNullable : Nullability::kLegacy;
-  *out = Type::New(type_class_, *type_args_ptr, nullability);
-  auto& type = Type::Cast(*out);
-  if (is_recursive) {
-    while (!pending_typerefs->is_empty()) {
-      auto const ref = pending_typerefs->RemoveLast();
-      ASSERT(ref != nullptr);
-      ref->set_type(type);
-    }
-    pending_typeref_map_.Remove(old_hash);
-
-    // If there are still pending typerefs, we can't canonicalize yet until
-    // an enclosing type where we have resolved them. This is a conservative
-    // check, as we do not ensure that any of the still-pending typerefs are
-    // found within this type.
-    //
-    // This is within the is_recursive check because if this type was
-    // non-recursive, then even if there are pending type refs, we are
-    // guaranteed that none of them are in this type.
-    if (ArePendingTypeRefs()) return true;
-  }
-
-  // Need to set this for canonicalization. We ensure in the serializer
-  // that only finalized types are successfully serialized.
-  type.SetIsFinalized();
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseTypeArguments(SExpression* sexp, Object* out) {
-  ASSERT(out != nullptr);
-  if (sexp == nullptr) return false;
-
-  if (auto const sym = sexp->AsSymbol()) {
-    auto const val = ParseValue(sexp, /*allow_pending=*/false);
-    if (val == nullptr) {
-      StoreError(sexp,
-                 "expected type arguments or reference to constant definition");
-      return false;
-    }
-    if (!val->BindsToConstant()) {
-      StoreError(sexp, "reference to non-constant definition");
-      return false;
-    }
-    *out = val->BoundConstant().ptr();
-    if (!out->IsTypeArguments()) {
-      StoreError(sexp, "expected TypeArguments constant");
-      return false;
-    }
-    return true;
-  }
-  auto const list = CheckTaggedList(sexp, "TypeArguments");
-  if (list == nullptr) return false;
-
-  *out = TypeArguments::New(list->Length() - 1, Heap::kOld);
-  auto& type_args = TypeArguments::Cast(*out);
-  // We may reenter ParseTypeArguments while parsing one of the elements, so we
-  // need a fresh handle here.
-  auto& elem = AbstractType::Handle(zone());
-  for (intptr_t i = 1, n = list->Length(); i < n; i++) {
-    if (!ParseAbstractType(Retrieve(list, i), &elem)) return false;
-    type_args.SetTypeAt(i - 1, elem);
-  }
-
-  // If there are still pending typerefs, we can't canonicalize yet.
-  if (ArePendingTypeRefs()) return true;
-
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseTypeParameter(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  Class& cls = Class::Handle();
-  if (auto const cid_sexp = CheckInteger(list->ExtraLookupValue("cid"))) {
-    const intptr_t cid = cid_sexp->value();
-    ClassTable* table = thread()->isolate_group()->class_table();
-    if (!table->HasValidClassAt(cid)) {
-      StoreError(cid_sexp, "no valid class found for cid");
-      return false;
-    }
-    cls = table->At(cid);
-  } else {
-    return false;
-  }
-  auto const base_sexp = CheckInteger(list->ExtraLookupValue("base"));
-  if (base_sexp == nullptr) return false;
-  intptr_t base = base_sexp->value();
-  auto const index_sexp = CheckInteger(list->ExtraLookupValue("index"));
-  if (index_sexp == nullptr) return false;
-  intptr_t index = index_sexp->value();
-  auto const name_sexp = CheckSymbol(Retrieve(list, 1));
-  if (name_sexp == nullptr) return false;
-  tmp_string_ = String::New(name_sexp->value());
-
-  *out =
-      TypeParameter::New(cls, base, index, tmp_string_, Object::dynamic_type(),
-                         false, Nullability::kLegacy);
-  TypeParameter::Cast(*out).SetIsFinalized();
-  return CanonicalizeInstance(list, out);
-}
-
-bool FlowGraphDeserializer::ParseTypeRef(SExpList* list, Object* out) {
-  ASSERT(out != nullptr);
-  if (list == nullptr) return false;
-
-  const bool contains_type = list->Length() > 1;
-  if (contains_type) {
-    auto& type = Type::Handle(zone());
-    if (!ParseAbstractType(Retrieve(list, 1), &type)) return false;
-    *out = TypeRef::New(type);
-    // If the TypeRef appears outside the referrent, then the referrent
-    // should be already canonicalized. This serves as a double-check that
-    // is the case.
-    return CanonicalizeInstance(list, out);
-  }
-  // If there is no type in the body, then this must be a referrent to
-  // a Type containing this TypeRef. That means we must have a hash value.
-  auto const hash_sexp = CheckInteger(Retrieve(list, "hash"));
-  if (hash_sexp == nullptr) return false;
-  auto const old_hash = hash_sexp->value();
-  auto const pending = pending_typeref_map_.LookupValue(old_hash);
-  if (pending == nullptr) {
-    StoreError(list, "reference to recursive type found outside type");
-    return false;
-  }
-  *out = TypeRef::New(Object::null_abstract_type());
-  pending->Add(static_cast<TypeRef*>(out));
-
-  // We can only canonicalize TypeRefs appearing within their referrent
-  // when its containing value is canonicalized.
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseCanonicalName(SExpSymbol* sym, Object* obj) {
-  ASSERT(obj != nullptr);
-  if (sym == nullptr) return false;
-  auto const name = sym->value();
-  // TODO(sstrickl): No library URL, handle this better.
-  if (*name == ':') {
-    StoreError(sym, "expected non-empty library");
-    return false;
-  }
-  const char* lib_end = nullptr;
-  if (auto const first = strchr(name, ':')) {
-    lib_end = strchr(first + 1, ':');
-    if (lib_end == nullptr) lib_end = strchr(first + 1, '\0');
-  } else {
-    StoreError(sym, "malformed library");
-    return false;
-  }
-  tmp_string_ =
-      String::FromUTF8(reinterpret_cast<const uint8_t*>(name), lib_end - name);
-  name_library_ = Library::LookupLibrary(thread(), tmp_string_);
-  if (*lib_end == '\0') {
-    *obj = name_library_.ptr();
-    return true;
-  }
-  const char* const class_start = lib_end + 1;
-  if (*class_start == '\0') {
-    StoreError(sym, "no class found after colon");
-    return false;
-  }
-  // If classes are followed by another part, it's either a function
-  // (separated by ':') or a field (separated by '.').
-  const char* class_end = strchr(class_start, ':');
-  if (class_end == nullptr) class_end = strchr(class_start, '.');
-  if (class_end == nullptr) class_end = strchr(class_start, '\0');
-  const bool empty_name = class_end == class_start;
-  name_class_ = Class::null();
-  if (empty_name) {
-    name_class_ = name_library_.toplevel_class();
-  } else {
-    tmp_string_ = String::FromUTF8(
-        reinterpret_cast<const uint8_t*>(class_start), class_end - class_start);
-    name_class_ = name_library_.LookupClassAllowPrivate(tmp_string_);
-  }
-  if (name_class_.IsNull()) {
-    StoreError(sym, "failure looking up class %s in library %s",
-               empty_name ? "at top level" : tmp_string_.ToCString(),
-               name_library_.ToCString());
-    return false;
-  }
-  if (*class_end == '\0') {
-    *obj = name_class_.ptr();
-    return true;
-  }
-  if (*class_end == '.') {
-    if (class_end[1] == '\0') {
-      StoreError(sym, "no field name found after period");
-      return false;
-    }
-    const char* const field_start = class_end + 1;
-    const char* field_end = strchr(field_start, '\0');
-    tmp_string_ = String::FromUTF8(
-        reinterpret_cast<const uint8_t*>(field_start), field_end - field_start);
-    name_field_ = name_class_.LookupFieldAllowPrivate(tmp_string_);
-    if (name_field_.IsNull()) {
-      StoreError(sym, "failure looking up field %s in class %s",
-                 tmp_string_.ToCString(),
-                 empty_name ? "at top level" : name_class_.ToCString());
-      return false;
-    }
-    *obj = name_field_.ptr();
-    return true;
-  }
-  if (class_end[1] == '\0') {
-    StoreError(sym, "no function name found after final colon");
-    return false;
-  }
-  const char* func_start = class_end + 1;
-  name_function_ = Function::null();
-  while (true) {
-    const char* func_end = strchr(func_start, ':');
-    intptr_t name_len = func_end - func_start;
-    bool is_forwarder = false;
-    if (func_end != nullptr && name_len == 3) {
-      // Special case for getters/setters, where they are prefixed with "get:"
-      // or "set:", as those colons should not be used as separators.
-      if (strncmp(func_start, "get", 3) == 0 ||
-          strncmp(func_start, "set", 3) == 0) {
-        func_end = strchr(func_end + 1, ':');
-      } else if (strncmp(func_start, "dyn", 3) == 0) {
-        // Dynamic invocation forwarders start with "dyn:" and we'll need to
-        // look up the base function and then retrieve the forwarder from it.
-        is_forwarder = true;
-        func_start = func_end + 1;
-        func_end = strchr(func_end + 1, ':');
-      }
-    }
-    if (func_end == nullptr) func_end = strchr(func_start, '\0');
-    name_len = func_end - func_start;
-
-    // Check for tearoff names before we overwrite the contents of tmp_string_.
-    if (!name_function_.IsNull()) {
-      ASSERT(!tmp_string_.IsNull());
-      auto const parent_name = tmp_string_.ToCString();
-      // ImplicitClosureFunctions (tearoffs) have the same name as the Function
-      // to which they are attached. We currently don't handle any other kinds
-      // of local functions.
-      if (name_function_.HasImplicitClosureFunction() && *func_end == '\0' &&
-          strncmp(parent_name, func_start, name_len) == 0) {
-        *obj = name_function_.ImplicitClosureFunction();
-        return true;
-      }
-      StoreError(sym, "no handling for local functions");
-      return false;
-    }
-
-    // Check for the prefix "<anonymous ..." in the name and fail if found,
-    // since we can't resolve these.
-    static auto const anon_prefix = "<anonymous ";
-    static const intptr_t prefix_len = strlen(anon_prefix);
-    if ((name_len > prefix_len) &&
-        strncmp(anon_prefix, func_start, prefix_len) == 0) {
-      StoreError(sym, "cannot resolve anonymous values");
-      return false;
-    }
-
-    tmp_string_ = String::FromUTF8(reinterpret_cast<const uint8_t*>(func_start),
-                                   name_len);
-    name_function_ = name_class_.LookupFunctionAllowPrivate(tmp_string_);
-    if (name_function_.IsNull()) {
-      StoreError(sym, "failure looking up function %s in class %s",
-                 tmp_string_.ToCString(), name_class_.ToCString());
-      return false;
-    }
-    if (is_forwarder) {
-      tmp_string_ = name_function_.name();
-      tmp_string_ = Function::CreateDynamicInvocationForwarderName(tmp_string_);
-      name_function_ =
-          name_function_.GetDynamicInvocationForwarder(tmp_string_);
-    }
-    if (func_end[0] == '\0') break;
-    if (func_end[1] == '\0') {
-      StoreError(sym, "no function name found after final colon");
-      return false;
-    }
-    func_start = func_end + 1;
-  }
-  *obj = name_function_.ptr();
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseSlot(SExpList* list, const Slot** out) {
-  ASSERT(out != nullptr);
-  const auto offset_sexp = CheckInteger(Retrieve(list, 1));
-  if (offset_sexp == nullptr) return false;
-  const auto offset = offset_sexp->value();
-
-  const auto kind_sexp = CheckSymbol(Retrieve(list, "kind"));
-  if (kind_sexp == nullptr) return false;
-  Slot::Kind kind;
-  if (!Slot::ParseKind(kind_sexp->value(), &kind)) {
-    StoreError(kind_sexp, "unknown Slot kind");
-    return false;
-  }
-
-  switch (kind) {
-    case Slot::Kind::kDartField: {
-      auto& field = Field::ZoneHandle(zone());
-      const auto field_sexp = CheckTaggedList(Retrieve(list, "field"), "Field");
-      if (!ParseDartValue(field_sexp, &field)) return false;
-      ASSERT(parsed_function_ != nullptr);
-      *out =
-          &Slot::Get(kernel::BaseFlowGraphBuilder::MayCloneField(zone(), field),
-                     parsed_function_);
-      break;
-    }
-    case Slot::Kind::kTypeArguments:
-      *out = &Slot::GetTypeArgumentsSlotAt(thread(), offset);
-      break;
-    case Slot::Kind::kTypeArgumentsIndex:
-      *out = &Slot::GetTypeArgumentsIndexSlot(thread(), offset);
-      break;
-    case Slot::Kind::kArrayElement:
-      *out = &Slot::GetArrayElementSlot(thread(), offset);
-      break;
-    case Slot::Kind::kCapturedVariable:
-      StoreError(kind_sexp, "unhandled Slot kind");
-      return false;
-    default:
-      *out = &Slot::GetNativeSlot(kind);
-      break;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseRange(SExpList* list, Range* out) {
-  if (list == nullptr) return false;
-  RangeBoundary min, max;
-  if (!ParseRangeBoundary(Retrieve(list, 1), &min)) return false;
-  if (list->Length() == 2) {
-    max = min;
-  } else {
-    if (!ParseRangeBoundary(Retrieve(list, 2), &max)) return false;
-  }
-  out->min_ = min;
-  out->max_ = max;
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseRangeBoundary(SExpression* sexp,
-                                               RangeBoundary* out) {
-  if (sexp == nullptr) return false;
-  if (auto const int_sexp = sexp->AsInteger()) {
-    out->kind_ = RangeBoundary::Kind::kConstant;
-    out->value_ = int_sexp->value();
-  } else if (auto const sym_sexp = sexp->AsSymbol()) {
-    if (!RangeBoundary::ParseKind(sym_sexp->value(), &out->kind_)) return false;
-  } else if (auto const list_sexp = sexp->AsList()) {
-    intptr_t index;
-    if (!ParseUse(CheckSymbol(Retrieve(list_sexp, 1)), &index)) return false;
-    auto const def = definition_map_.LookupValue(index);
-    if (def == nullptr) {
-      StoreError(list_sexp, "no definition for symbolic range boundary");
-      return false;
-    }
-    out->kind_ = RangeBoundary::Kind::kSymbol;
-    out->value_ = reinterpret_cast<intptr_t>(def);
-    if (auto const offset_sexp =
-            CheckInteger(list_sexp->ExtraLookupValue("offset"))) {
-      auto const offset = offset_sexp->value();
-      if (!RangeBoundary::IsValidOffsetForSymbolicRangeBoundary(offset)) {
-        StoreError(sexp, "invalid offset for symbolic range boundary");
-        return false;
-      }
-      out->offset_ = offset;
-    }
-  } else {
-    StoreError(sexp, "unexpected value for range boundary");
-    return false;
-  }
-  return true;
-}
-
-bool FlowGraphDeserializer::ParseBlockId(SExpSymbol* sym, intptr_t* out) {
-  return ParseSymbolAsPrefixedInt(sym, 'B', out);
-}
-
-bool FlowGraphDeserializer::ParseSSATemp(SExpSymbol* sym, intptr_t* out) {
-  return ParseSymbolAsPrefixedInt(sym, 'v', out);
-}
-
-bool FlowGraphDeserializer::ParseUse(SExpSymbol* sym, intptr_t* out) {
-  // TODO(sstrickl): Handle non-SSA temp uses.
-  return ParseSSATemp(sym, out);
-}
-
-bool FlowGraphDeserializer::ParseSymbolAsPrefixedInt(SExpSymbol* sym,
-                                                     char prefix,
-                                                     intptr_t* out) {
-  ASSERT(out != nullptr);
-  if (sym == nullptr) return false;
-  auto const name = sym->value();
-  if (*name != prefix) {
-    StoreError(sym, "expected symbol starting with '%c'", prefix);
-    return false;
-  }
-  int64_t i;
-  if (!OS::StringToInt64(name + 1, &i)) {
-    StoreError(sym, "expected number following symbol prefix '%c'", prefix);
-    return false;
-  }
-  *out = i;
-  return true;
-}
-
-bool FlowGraphDeserializer::ArePendingTypeRefs() const {
-  // We'll do a deep check, because while there may be recursive types still
-  // being parsed, if there are no pending type refs to those recursive types,
-  // we're still good to canonicalize.
-  if (pending_typeref_map_.IsEmpty()) return false;
-  auto it = pending_typeref_map_.GetIterator();
-  while (auto kv = it.Next()) {
-    if (!kv->value->is_empty()) return true;
-  }
-  return false;
-}
-
-bool FlowGraphDeserializer::CreateICData(SExpList* list, Instruction* inst) {
-  ASSERT(inst != nullptr);
-  if (list == nullptr) return false;
-
-  const String* function_name = nullptr;
-  Array& arguments_descriptor = Array::Handle(zone());
-  intptr_t num_args_checked;
-  ICData::RebindRule rebind_rule;
-
-  if (auto const call = inst->AsInstanceCall()) {
-    function_name = &call->function_name();
-    arguments_descriptor = call->GetArgumentsDescriptor();
-    num_args_checked = call->checked_argument_count();
-    rebind_rule = ICData::RebindRule::kInstance;
-  } else if (auto const call = inst->AsStaticCall()) {
-    function_name = &String::Handle(zone(), call->function().name());
-    arguments_descriptor = call->GetArgumentsDescriptor();
-    num_args_checked =
-        MethodRecognizer::NumArgsCheckedForStaticCall(call->function());
-    rebind_rule = ICData::RebindRule::kStatic;
-  } else {
-    StoreError(list, "unexpected instruction type for ICData");
-    return false;
-  }
-
-  auto type_ptr = &Object::null_abstract_type();
-  if (auto const type_sexp = list->ExtraLookupValue("receivers_static_type")) {
-    auto& type = AbstractType::ZoneHandle(zone());
-    if (!ParseAbstractType(type_sexp, &type)) return false;
-    type_ptr = &type;
-  }
-
-  ASSERT(parsed_function_ != nullptr);
-  auto& ic_data = ICData::ZoneHandle(
-      zone(), ICData::New(parsed_function_->function(), *function_name,
-                          arguments_descriptor, inst->deopt_id(),
-                          num_args_checked, rebind_rule, *type_ptr));
-
-  if (auto const is_mega_sexp =
-          CheckBool(list->ExtraLookupValue("is_megamorphic"))) {
-    ic_data.set_is_megamorphic(is_mega_sexp->value());
-  }
-
-  auto const class_table = thread()->isolate_group()->class_table();
-  GrowableArray<intptr_t> class_ids(zone(), 2);
-  for (intptr_t i = 1, n = list->Length(); i < n; i++) {
-    auto const entry = CheckList(Retrieve(list, i));
-    if (entry == nullptr) return false;
-    ASSERT(ic_data.NumArgsTested() == entry->Length());
-
-    intptr_t count = 0;
-    if (auto const count_sexp =
-            CheckInteger(entry->ExtraLookupValue("count"))) {
-      count = count_sexp->value();
-    }
-
-    auto& target = Function::ZoneHandle(zone());
-    if (!ParseDartValue(Retrieve(entry, "target"), &target)) return false;
-
-    // We can't use AddCheck for NumArgsTested < 2. We'll handle 0 here, and
-    // 1 after the for loop.
-    if (entry->Length() == 0) {
-      if (count != 0) {
-        StoreError(entry, "expected a zero count for no checked args");
-        return false;
-      }
-      ic_data = ICData::NewForStaticCall(parsed_function_->function(), target,
-                                         arguments_descriptor, inst->deopt_id(),
-                                         num_args_checked, rebind_rule);
-      continue;
-    }
-
-    class_ids.Clear();
-    for (intptr_t j = 0, num_cids = entry->Length(); j < num_cids; j++) {
-      auto const cid_sexp = CheckInteger(Retrieve(entry, j));
-      if (cid_sexp == nullptr) return false;
-      const intptr_t cid = cid_sexp->value();
-      // kObjectCid is a special case used for AddTarget() entries with
-      // a non-zero number of checked arguments.
-      if (cid != kObjectCid && !class_table->HasValidClassAt(cid)) {
-        StoreError(cid_sexp, "cid is not a valid class");
-        return false;
-      }
-      class_ids.Add(cid);
-    }
-
-    if (entry->Length() == 1) {
-      ic_data.AddReceiverCheck(class_ids.At(0), target, count);
-    } else {
-      ic_data.AddCheck(class_ids, target, count);
-    }
-  }
-
-  if (auto const call = inst->AsInstanceCall()) {
-    call->set_ic_data(const_cast<const ICData*>(&ic_data));
-  } else if (auto const call = inst->AsStaticCall()) {
-    call->set_ic_data(&ic_data);
-  }
-
-  return true;
-}
-
-Value* FlowGraphDeserializer::AddNewPendingValue(SExpression* sexp,
-                                                 intptr_t index,
-                                                 bool inherit_type) {
-  ASSERT(flow_graph_ != nullptr);
-  auto const value = new (zone()) Value(flow_graph_->constant_null());
-  ASSERT(!definition_map_.HasKey(index));
-  auto list = values_map_.LookupValue(index);
-  if (list == nullptr) {
-    list = new (zone()) ZoneGrowableArray<PendingValue>(zone(), 2);
-    values_map_.Insert(index, list);
-  }
-  list->Add({sexp, value, inherit_type});
-  return value;
-}
-
-bool FlowGraphDeserializer::FixPendingValues(intptr_t index, Definition* def) {
-  if (auto value_list = values_map_.LookupValue(index)) {
-    for (intptr_t i = 0; i < value_list->length(); i++) {
-      const auto& value_info = value_list->At(i);
-      auto const value = value_info.value;
-      const bool inherit_type = value_info.inherit_type;
-      value->BindTo(def);
-      if (!inherit_type) continue;
-      if (def->HasType()) {
-        value->reaching_type_ = def->Type();
-      } else {
-        StoreError(value_info.sexp, "value inherits type, but no type found");
-        return false;
-      }
-    }
-    values_map_.Remove(index);
-  }
-  return true;
-}
-
-BlockEntryInstr* FlowGraphDeserializer::FetchBlock(SExpSymbol* sym) {
-  if (sym == nullptr) return nullptr;
-  intptr_t block_id;
-  if (!ParseBlockId(sym, &block_id)) return nullptr;
-  auto const entry = block_map_.LookupValue(block_id);
-  if (entry == nullptr) {
-    StoreError(sym, "reference to undefined block");
-    return nullptr;
-  }
-  return entry;
-}
-
-#define BASE_CHECK_DEF(name, type)                                             \
-  SExp##name* FlowGraphDeserializer::Check##name(SExpression* sexp) {          \
-    if (sexp == nullptr) return nullptr;                                       \
-    if (!sexp->Is##name()) {                                                   \
-      StoreError(sexp, "expected " #name);                                     \
-      return nullptr;                                                          \
-    }                                                                          \
-    return sexp->As##name();                                                   \
-  }
-
-FOR_EACH_S_EXPRESSION(BASE_CHECK_DEF)
-
-#undef BASE_CHECK_DEF
-
-bool FlowGraphDeserializer::IsTag(SExpression* sexp, const char* label) {
-  auto const sym = CheckSymbol(sexp);
-  if (sym == nullptr) return false;
-  if (label != nullptr && !sym->Equals(label)) {
-    StoreError(sym, "expected symbol %s", label);
-    return false;
-  }
-  return true;
-}
-
-SExpList* FlowGraphDeserializer::CheckTaggedList(SExpression* sexp,
-                                                 const char* label) {
-  auto const list = CheckList(sexp);
-  const intptr_t tag_pos = 0;
-  if (!IsTag(Retrieve(list, tag_pos), label)) return nullptr;
-  return list;
-}
-
-void FlowGraphDeserializer::StoreError(SExpression* sexp,
-                                       const char* format,
-                                       ...) {
-  va_list args;
-  va_start(args, format);
-  const char* const message = OS::VSCreate(zone(), format, args);
-  va_end(args);
-  error_sexp_ = sexp;
-  error_message_ = message;
-}
-
-void FlowGraphDeserializer::ReportError() const {
-  ASSERT(error_sexp_ != nullptr);
-  ASSERT(error_message_ != nullptr);
-  OS::PrintErr("Unable to deserialize flow_graph: %s\n", error_message_);
-  OS::PrintErr("Error at S-expression %s\n", error_sexp_->ToCString(zone()));
-  OS::Abort();
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/backend/il_deserializer.h b/runtime/vm/compiler/backend/il_deserializer.h
deleted file mode 100644
index 5049850..0000000
--- a/runtime/vm/compiler/backend/il_deserializer.h
+++ /dev/null
@@ -1,421 +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_VM_COMPILER_BACKEND_IL_DESERIALIZER_H_
-#define RUNTIME_VM_COMPILER_BACKEND_IL_DESERIALIZER_H_
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-#error "AOT runtime should not use compiler sources (including header files)"
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-#include "platform/assert.h"
-
-#include "vm/allocation.h"
-#include "vm/compiler/backend/flow_graph.h"
-#include "vm/compiler/backend/il.h"
-#include "vm/compiler/backend/sexpression.h"
-#include "vm/compiler/compiler_pass.h"
-#include "vm/object.h"
-#include "vm/parser.h"
-#include "vm/thread.h"
-#include "vm/zone.h"
-
-namespace dart {
-
-// Deserializes FlowGraphs from S-expressions.
-class FlowGraphDeserializer : ValueObject {
- public:
-  // Adds to the given array all the instructions in the flow graph that are
-  // guaranteed not to be handled by the current implementation of the
-  // FlowGraphDeserializer. This way, we can filter out graphs that are
-  // guaranteed not to be deserializable before going through the round-trip
-  // serialization process.
-  //
-  // Note that there may be other reasons that the deserializer may fail on
-  // a given flow graph, so no new members of the array is necessary, but not
-  // sufficient, for a successful round-trip pass.
-  static void AllUnhandledInstructions(const FlowGraph* graph,
-                                       GrowableArray<Instruction*>* out);
-
-  // Takes the FlowGraph from [state] and runs it through the serializer
-  // and deserializer. If the deserializer successfully deserializes the
-  // graph, then the FlowGraph in [state] is replaced with the new one.
-  static void RoundTripSerialization(CompilerPassState* state);
-
-  FlowGraphDeserializer(Thread* thread,
-                        Zone* zone,
-                        SExpression* root,
-                        const ParsedFunction* pf = nullptr)
-      : thread_(ASSERT_NOTNULL(thread)),
-        zone_(ASSERT_NOTNULL(zone)),
-        root_sexp_(ASSERT_NOTNULL(root)),
-        parsed_function_(pf),
-        block_map_(zone),
-        definition_map_(zone),
-        values_map_(zone),
-        recursive_types_map_(zone),
-        pending_typeref_map_(zone),
-        array_type_args_(TypeArguments::Handle(zone)),
-        instance_class_(Class::Handle(zone)),
-        instance_field_(Field::Handle(zone)),
-        instance_fields_array_(Array::Handle(zone)),
-        instance_type_args_(TypeArguments::Handle(zone)),
-        name_class_(Class::Handle(zone)),
-        name_field_(Field::Handle(zone)),
-        name_function_(Function::Handle(zone)),
-        name_library_(Library::Handle(zone)),
-        type_class_(Class::Handle(zone)),
-        type_param_class_(Class::Handle(zone)),
-        tmp_string_(String::Handle(zone)) {
-    // See canonicalization comment in ParseDartValue as to why this is
-    // currently necessary.
-    ASSERT(thread->zone() == zone);
-  }
-
-  // Walks [root_sexp_] and constructs a new FlowGraph.
-  FlowGraph* ParseFlowGraph();
-
-  const char* error_message() const { return error_message_; }
-  SExpression* error_sexp() const { return error_sexp_; }
-
-  // Prints the current error information to stderr and aborts.
-  DART_NORETURN void ReportError() const;
-
- private:
-#define FOR_EACH_HANDLED_BLOCK_TYPE_IN_DESERIALIZER(M)                         \
-  M(FunctionEntry)                                                             \
-  M(GraphEntry)                                                                \
-  M(JoinEntry)                                                                 \
-  M(TargetEntry)
-
-#define FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(M)                        \
-  M(AllocateObject)                                                            \
-  M(AssertAssignable)                                                          \
-  M(AssertBoolean)                                                             \
-  M(BooleanNegate)                                                             \
-  M(Branch)                                                                    \
-  M(CheckNull)                                                                 \
-  M(CheckStackOverflow)                                                        \
-  M(Constant)                                                                  \
-  M(DebugStepCheck)                                                            \
-  M(Goto)                                                                      \
-  M(InstanceCall)                                                              \
-  M(LoadClassId)                                                               \
-  M(LoadField)                                                                 \
-  M(NativeCall)                                                                \
-  M(Parameter)                                                                 \
-  M(Return)                                                                    \
-  M(SpecialParameter)                                                          \
-  M(StaticCall)                                                                \
-  M(StoreInstanceField)                                                        \
-  M(StrictCompare)                                                             \
-  M(Throw)
-
-  // Helper methods for AllUnhandledInstructions.
-  static bool IsHandledInstruction(Instruction* inst);
-  static bool IsHandledConstant(const Object& obj);
-
-  // **GENERAL DESIGN NOTES FOR PARSING METHODS**
-  //
-  // For functions that take an SExpression or a subclass, they should return
-  // an error signal (false, nullptr, etc.) without changing the error state if
-  // passed in nullptr. This way, methods can be chained without intermediate
-  // checking.
-  //
-  // Also, for parsing methods for expressions that are known to be of a certain
-  // form, they will take the appropriate subclass of SExpression and assume
-  // that the form was already pre-checked by the caller. For forms that are
-  // tagged lists, this includes the fact that there is at least one element
-  // and the first element is a symbol. If the form can only have one possible
-  // tag, they also assume the tag has already been checked.
-
-  // Helper functions that do length/key exists checking and also check that
-  // the retrieved element is not nullptr. Notably, do not use these if the
-  // retrieved element is optional, to avoid changing the error state
-  // unnecessarily.
-  SExpression* Retrieve(SExpList* list, intptr_t index);
-  SExpression* Retrieve(SExpList* list, const char* key);
-
-  bool ParseConstantPool(SExpList* pool);
-  bool ParseEntries(SExpList* list);
-
-  using BlockWorklist = GrowableArray<intptr_t>;
-
-  // Starts parsing the contents of [list], where the blocks begin at position
-  // [pos] and [worklist] contains the blocks whose body instructions should
-  // be parsed first.
-  bool ParseBlocks(SExpList* list, intptr_t pos, BlockWorklist* worklist);
-
-  // Block parsing is split into two passes. This pass adds function entries
-  // to the flow graph and also parses initial definitions found in the Entries
-  // list. The block is added to the [block_map_] before returning.
-  BlockEntryInstr* ParseBlockHeader(SExpList* list,
-                                    intptr_t block_id,
-                                    SExpSymbol* tag);
-
-  // Expects [current_block_] to be set before calling.
-  bool ParseInitialDefinitions(SExpList* list);
-
-  // Expects [current_block_] to be set before calling.
-  // Takes the tagged list to parse and the index where parsing should start.
-  // Attempts to parse Phi definitions until the first non-Phi instruction.
-  bool ParsePhis(SExpList* list);
-
-  // Expects [current_block_] to be set before calling.
-  // Returns the position of the first non-Phi instruction in a block.
-  intptr_t SkipPhis(SExpList* list);
-
-  // Parses the deopt environment, Phi definitions for JoinEntrys, and the
-  // instructions in the body of the block. Adds the IDs of the block successors
-  // to the worklist, if any. [current_block_] and [pushed_stack_] must be set
-  // before calling.
-  bool ParseBlockContents(SExpList* list, BlockWorklist* worklist);
-
-  // Helper function used by ParseConstantPool, ParsePhis, and ParseDefinition.
-  // This handles all the extra information stored in (def ...) expressions,
-  // and also ensures the index of the definition is appropriately adjusted to
-  // match those found in the serialized form.
-  bool ParseDefinitionWithParsedBody(SExpList* list, Definition* def);
-
-  Definition* ParseDefinition(SExpList* list);
-  Instruction* ParseInstruction(SExpList* list);
-
-  struct EntryInfo {
-    intptr_t block_id;
-    intptr_t try_index;
-    intptr_t deopt_id;
-  };
-
-#define HANDLER_DECL(name)                                                     \
-  name##Instr* Deserialize##name(SExpList* list, const EntryInfo& info);
-
-  FOR_EACH_HANDLED_BLOCK_TYPE_IN_DESERIALIZER(HANDLER_DECL);
-
-#undef HANDLER_DECL
-
-  struct InstrInfo {
-    const intptr_t deopt_id;
-    const InstructionSource source;
-  };
-
-  enum HandledInstruction {
-#define HANDLED_INST_DECL(name) kHandled##name,
-    FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLED_INST_DECL)
-#undef HANDLED_INST_DECL
-    // clang-format off
-    kHandledInvalid = -1,
-    // clang-format on
-  };
-
-#define HANDLE_CASE(name)                                                      \
-  if (strcmp(tag->value(), #name) == 0) return kHandled##name;
-  HandledInstruction HandledInstructionForTag(SExpSymbol* tag) {
-    ASSERT(tag != nullptr);
-    FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLE_CASE)
-    return kHandledInvalid;
-  }
-#undef HANDLE_CASE
-
-#define HANDLER_DECL(name)                                                     \
-  name##Instr* Deserialize##name(SExpList* list, const InstrInfo& info);
-
-  FOR_EACH_HANDLED_INSTRUCTION_IN_DESERIALIZER(HANDLER_DECL);
-
-#undef HANDLER_DECL
-
-  // Common information parsed from call instruction S-expressions.
-  struct CallInfo : public ValueObject {
-    explicit CallInfo(Zone* zone) : argument_names(Array::ZoneHandle(zone)) {}
-
-    Array& argument_names;
-    intptr_t type_args_len = 0;
-    intptr_t args_len = 0;
-    InputsArray* inputs = nullptr;
-    CompileType* result_type = nullptr;
-    Code::EntryKind entry_kind = Code::EntryKind::kNormal;
-  };
-
-  // Helper function for parsing call instructions that returns a structure
-  // of information common to all calls.
-  bool ParseCallInfo(SExpList* call,
-                     CallInfo* out,
-                     intptr_t num_extra_inputs = 0);
-
-  // Parses [sexp] as a value form, that is, either the binding name for
-  // a definition as a symbol or the form (value <name> { ... }).
-  // If [allow_pending], then values for definitions not already in the
-  // [definition_map_] will be added to the [values_map_], otherwise,
-  // values for definitions not yet seen cause an error to be stored and
-  // nullptr to be returned.
-  Value* ParseValue(SExpression* sexp, bool allow_pending = true);
-  CompileType* ParseCompileType(SExpList* list);
-
-  // Parses [list] as an environment form: a list containing either binding
-  // names for definitions or a# for pushed arguments (where # is the depth
-  // of the argument from the top of the stack). Requires [pushed_stack_] to
-  // be set if any references to pushed arguments are found.
-  Environment* ParseEnvironment(SExpList* list);
-
-  // Parsing functions for which there are no good distinguished error
-  // values, so use out parameters and a boolean return instead.
-
-  // Parses a Dart value and returns a canonicalized result.
-  bool ParseDartValue(SExpression* sexp, Object* out);
-
-  // Canonicalizes and replaces the original contents of the handle pointed to
-  // by [inst] if [inst] is an Instance (if not, it trivially succeeds). The
-  // replacement happens whether successful or not. [sexp] is the SExpression
-  // to be used for error reporting.
-  bool CanonicalizeInstance(SExpression* sexp, Object* inst);
-
-  // Helper functions for ParseDartValue for parsing particular type of values.
-  // If necessary, they canonicalize the returned value, and so may be used
-  // directly by other code as well. Helpers that take SExpression* take either
-  // serialized constants or references to constant definitions.
-  //
-  // Due to particulars of operator=() on non-Object values, for a given X,
-  // ParseX takes Object* instead of X* for the out parameter.
-  bool ParseAbstractType(SExpression* sexp, Object* out);
-  bool ParseClass(SExpList* list, Object* out);
-  bool ParseClosure(SExpList* list, Object* out);
-  bool ParseField(SExpList* list, Object* out);
-  bool ParseFunction(SExpList* list, Object* out);
-  bool ParseSignature(SExpList* list, Object* out);
-  bool ParseArray(SExpList* list, Object* out);
-  bool ParseImmutableList(SExpList* list, Object* out);
-  bool ParseInstance(SExpList* list, Object* out);
-  bool ParseType(SExpression* sexp, Object* out);
-  bool ParseFunctionType(SExpList* list, Object* out);
-  bool ParseTypeParameter(SExpList* list, Object* out);
-  bool ParseTypeArguments(SExpression* sexp, Object* out);
-  bool ParseTypeRef(SExpList* list, Object* out);
-
-  bool ParseCanonicalName(SExpSymbol* sym, Object* out);
-
-  const Field& MayCloneField(const Field& field) const;
-  bool ParseSlot(SExpList* list, const Slot** out);
-  bool ParseRange(SExpList* list, Range* out);
-  bool ParseRangeBoundary(SExpression* sexp, RangeBoundary* out);
-
-  bool ParseBlockId(SExpSymbol* sym, intptr_t* out);
-  bool ParseSSATemp(SExpSymbol* sym, intptr_t* out);
-  bool ParseUse(SExpSymbol* sym, intptr_t* out);
-  bool ParseSymbolAsPrefixedInt(SExpSymbol* sym, char prefix, intptr_t* out);
-
-  bool ArePendingTypeRefs() const;
-
-  // Allocates a new ICData structure. [list] is the ICData S-expression, while
-  // [inst] is the Instruction generated from the instruction S-expression
-  // containing [list].
-  bool CreateICData(SExpList* list, Instruction* inst);
-
-  // Helper function for creating a placeholder value when the definition
-  // with index [i] has not yet been seen. If [inherit_type], then the type of
-  // the definition should be used as the reaching type for the use. [s] is used
-  // for any errors that occur when resolving the pending value.
-  Value* AddNewPendingValue(SExpression* s, intptr_t i, bool inherit_type);
-
-  // Helper function for rebinding values pending on this definition.
-  bool FixPendingValues(intptr_t index, Definition* def);
-
-  // Retrieves the block corresponding to the given block ID symbol from
-  // [block_map_]. Assumes all blocks have had their header parsed.
-  BlockEntryInstr* FetchBlock(SExpSymbol* sym);
-
-  // Utility functions for checking the shape of an S-expression.
-  // If these functions return nullptr for a non-null argument, they have the
-  // side effect of setting the stored error message.
-#define BASE_CHECK_DECL(name, type) SExp##name* Check##name(SExpression* sexp);
-  FOR_EACH_S_EXPRESSION(BASE_CHECK_DECL)
-#undef BASE_CHECK_DECL
-
-  // Checks whether [sexp] is a symbol with the given label.
-  bool IsTag(SExpression* sexp, const char* label);
-
-  // A version of CheckList that also checks that the list has at least one
-  // element and that the first element is a symbol. If [label] is non-null,
-  // then the initial symbol element is checked against it.
-  SExpList* CheckTaggedList(SExpression* sexp, const char* label = nullptr);
-
-  // Stores appropriate error information using the SExpression as the location
-  // and the rest of the arguments as an error message for the user.
-  void StoreError(SExpression* s, const char* fmt, ...) PRINTF_ATTRIBUTE(3, 4);
-
-  Thread* thread() const { return thread_; }
-  Zone* zone() const { return zone_; }
-
-  Thread* const thread_;
-  Zone* const zone_;
-  SExpression* const root_sexp_;
-  const ParsedFunction* parsed_function_;
-
-  FlowGraph* flow_graph_ = nullptr;
-  BlockEntryInstr* current_block_ = nullptr;
-  intptr_t max_block_id_ = -1;
-  intptr_t max_ssa_index_ = -1;
-
-  // Map from block IDs to blocks. Does not contain an entry for block 0
-  // (the graph entry), since it is only used at known points and is already
-  // available via [flow_graph_].
-  IntMap<BlockEntryInstr*> block_map_;
-
-  // Map from variable indexes to definitions.
-  IntMap<Definition*> definition_map_;
-
-  // Information needed to handle uses seen prior to their definitions.
-  struct PendingValue {
-    // SExpression used for error reporting.
-    SExpression* sexp;
-    // Value to be rebound once the right definition is found.
-    Value* value;
-    // Whether the type should inherit the type of the found definition.
-    bool inherit_type;
-  };
-
-  // Map from variable indices to lists of values. The list of values are
-  // values that were parsed prior to the corresponding definition being found.
-  IntMap<ZoneGrowableArray<PendingValue>*> values_map_;
-
-  // Map from hash values to SExpLists. This is used by ParseTypeRef to
-  // determine whether or not the recursive type it refers to is being currently
-  // built. The SExpList can be used to report hash collisions.
-  IntMap<SExpList*> recursive_types_map_;
-
-  // Map from hash values to arrays of TypeRefs. This is used by ParseType and
-  // ParseTypeRef to store and later fill in TypeRefs pending on the type being
-  // constructed. Since entries are added at the start of parsing recursive
-  // Type S-exps and removed before the resulting Type is successfully returned,
-  // this map should be empty outside of parsing recursive types.
-  IntMap<ZoneGrowableArray<TypeRef*>*> pending_typeref_map_;
-
-  // Temporary handles used by functions that are not re-entrant or where the
-  // handle is not live after the re-entrant call. Comments show which handles
-  // are expected to only be used within a single method.
-  TypeArguments& array_type_args_;     // ParseImmutableList
-  Class& instance_class_;              // ParseInstance
-  Field& instance_field_;              // ParseInstance
-  Array& instance_fields_array_;       // ParseInstance
-  TypeArguments& instance_type_args_;  // ParseInstance
-  Class& name_class_;                  // ParseCanonicalName
-  Field& name_field_;                  // ParseCanonicalName
-  Function& name_function_;            // ParseCanonicalName
-  Library& name_library_;              // ParseCanonicalName
-  Class& type_class_;                  // ParseType
-  Class& type_param_class_;            // ParseTypeParameter
-  // Uses of string handles tend to be immediate, so we only need one.
-  String& tmp_string_;
-
-  // Stores a message appropriate to surfacing to the user when an error
-  // occurs.
-  const char* error_message_ = nullptr;
-  // Stores the location of the deserialization error by containing the
-  // S-expression which caused the failure.
-  SExpression* error_sexp_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(FlowGraphDeserializer);
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_DESERIALIZER_H_
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
deleted file mode 100644
index 31fd469..0000000
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ /dev/null
@@ -1,1508 +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 "vm/compiler/backend/il_serializer.h"
-
-#include "vm/compiler/backend/flow_graph.h"
-#include "vm/compiler/backend/il.h"
-#include "vm/compiler/backend/range_analysis.h"
-#include "vm/compiler/method_recognizer.h"
-#include "vm/object_store.h"
-#include "vm/os.h"
-#include "vm/zone_text_buffer.h"
-
-namespace dart {
-
-DEFINE_FLAG(bool,
-            serialize_flow_graph_types,
-            true,
-            "Serialize inferred type information in flow graphs");
-
-DEFINE_FLAG(bool,
-            verbose_flow_graph_serialization,
-            false,
-            "Serialize extra information useful for debugging");
-
-DEFINE_FLAG(bool,
-            pretty_print_serialization,
-            false,
-            "Format serialized output nicely");
-
-DECLARE_FLAG(bool, populate_llvm_constant_pool);
-
-const char* const FlowGraphSerializer::initial_indent = "";
-
-FlowGraphSerializer::FlowGraphSerializer(Zone* zone,
-                                         const FlowGraph* flow_graph)
-    : flow_graph_(ASSERT_NOTNULL(flow_graph)),
-      zone_(zone),
-      object_store_(flow_graph->thread()->isolate_group()->object_store()),
-      open_recursive_types_(zone_),
-      llvm_constants_(
-          GrowableObjectArray::Handle(zone_,
-                                      object_store_->llvm_constant_pool())),
-      llvm_functions_(
-          GrowableObjectArray::Handle(zone_,
-                                      object_store_->llvm_function_pool())),
-      llvm_constant_map_(zone_, object_store_->llvm_constant_hash_table()),
-      llvm_index_(Smi::Handle(zone_)),
-      tmp_string_(String::Handle(zone_)),
-      array_type_args_((TypeArguments::Handle(zone_))),
-      closure_context_(Context::Handle(zone_)),
-      closure_function_(Function::Handle(zone_)),
-      closure_type_args_(TypeArguments::Handle(zone_)),
-      code_owner_(Object::Handle(zone_)),
-      context_parent_(Context::Handle(zone_)),
-      context_elem_(Object::Handle(zone_)),
-      function_type_args_(TypeArguments::Handle(zone_)),
-      ic_data_target_(Function::Handle(zone_)),
-      ic_data_type_(AbstractType::Handle(zone_)),
-      instance_field_(Field::Handle(zone_)),
-      instance_type_args_(TypeArguments::Handle(zone_)),
-      serialize_library_(Library::Handle(zone_)),
-      serialize_owner_(Class::Handle(zone_)),
-      serialize_parent_(Function::Handle(zone_)),
-      type_arguments_elem_(AbstractType::Handle(zone_)),
-      type_class_(Class::Handle(zone_)),
-      type_signature_(FunctionType::Handle(zone_)),
-      type_ref_type_(AbstractType::Handle(zone_)) {
-  // Double-check that the zone in the flow graph is a parent of the
-  // zone we'll be using for serialization.
-  ASSERT(flow_graph->zone()->ContainsNestedZone(zone));
-}
-
-FlowGraphSerializer::~FlowGraphSerializer() {
-  object_store_->set_llvm_constant_hash_table(llvm_constant_map_.Release());
-}
-
-void FlowGraphSerializer::SerializeToBuffer(Zone* zone,
-                                            const FlowGraph* flow_graph,
-                                            BaseTextBuffer* buffer) {
-  ASSERT(buffer != nullptr);
-  auto const sexp = SerializeToSExp(zone, flow_graph);
-  if (FLAG_pretty_print_serialization) {
-    sexp->SerializeTo(zone, buffer, initial_indent);
-  } else {
-    sexp->SerializeToLine(buffer);
-  }
-  buffer->AddString("\n\n");
-}
-
-SExpression* FlowGraphSerializer::SerializeToSExp(Zone* zone,
-                                                  const FlowGraph* flow_graph) {
-  FlowGraphSerializer serializer(zone, flow_graph);
-  return serializer.FlowGraphToSExp();
-}
-
-#define KIND_STR(name) #name,
-static const char* block_entry_kind_tags[FlowGraphSerializer::kNumEntryKinds] =
-    {FOR_EACH_BLOCK_ENTRY_KIND(KIND_STR)};
-#undef KIND_STR
-
-FlowGraphSerializer::BlockEntryKind FlowGraphSerializer::BlockEntryTagToKind(
-    SExpSymbol* tag) {
-  if (tag == nullptr) return kTarget;
-  auto const str = tag->value();
-  for (intptr_t i = 0; i < kNumEntryKinds; i++) {
-    auto const current = block_entry_kind_tags[i];
-    if (strcmp(str, current) == 0) return static_cast<BlockEntryKind>(i);
-  }
-  return kInvalid;
-}
-
-void FlowGraphSerializer::AddBool(SExpList* sexp, bool b) {
-  sexp->Add(new (zone()) SExpBool(b));
-}
-
-void FlowGraphSerializer::AddInteger(SExpList* sexp, intptr_t i) {
-  sexp->Add(new (zone()) SExpInteger(i));
-}
-
-void FlowGraphSerializer::AddString(SExpList* sexp, const char* cstr) {
-  sexp->Add(new (zone()) SExpString(cstr));
-}
-
-void FlowGraphSerializer::AddSymbol(SExpList* sexp, const char* cstr) {
-  sexp->Add(new (zone()) SExpSymbol(cstr));
-}
-
-void FlowGraphSerializer::AddExtraBool(SExpList* sexp,
-                                       const char* label,
-                                       bool b) {
-  sexp->AddExtra(label, new (zone()) SExpBool(b));
-}
-
-void FlowGraphSerializer::AddExtraInteger(SExpList* sexp,
-                                          const char* label,
-                                          intptr_t i) {
-  sexp->AddExtra(label, new (zone()) SExpInteger(i));
-}
-
-void FlowGraphSerializer::AddExtraString(SExpList* sexp,
-                                         const char* label,
-                                         const char* cstr) {
-  sexp->AddExtra(label, new (zone()) SExpString(cstr));
-}
-
-void FlowGraphSerializer::AddExtraSymbol(SExpList* sexp,
-                                         const char* label,
-                                         const char* cstr) {
-  sexp->AddExtra(label, new (zone()) SExpSymbol(cstr));
-}
-
-SExpression* FlowGraphSerializer::BlockIdToSExp(intptr_t block_id) {
-  return new (zone()) SExpSymbol(OS::SCreate(zone(), "B%" Pd "", block_id));
-}
-
-void FlowGraphSerializer::SerializeCanonicalName(BaseTextBuffer* b,
-                                                 const Object& obj) {
-  ASSERT(!obj.IsNull());
-  if (obj.IsFunction()) {
-    const auto& function = Function::Cast(obj);
-    tmp_string_ = function.name();
-    // We only want private keys removed, no other changes.
-    tmp_string_ = String::RemovePrivateKey(tmp_string_);
-    const char* function_name = tmp_string_.ToCString();
-    // If this function is an inner closure then the parent points to its
-    // containing function, which will also be part of the canonical name.
-    //
-    // We retrieve the owner before retrieving the parent function, as the
-    // inner closure chain may be arbitrarily deep and serialize_parent_ is
-    // passed in on recursive calls. When it is, then changing serialize_parent_
-    // to the parent function also changes the contents of obj and thus we'd
-    // no longer be able to retrieve the child function or its owner.
-    //
-    // This does mean that serialize_owner_ gets overwritten for each recursive
-    // call until we reach the end of the chain, but we only use its contents at
-    // the end of the chain anyway.
-    serialize_owner_ = function.Owner();
-    serialize_parent_ = function.parent_function();
-    if (!serialize_parent_.IsNull()) {
-      SerializeCanonicalName(b, serialize_parent_);
-    } else {
-      ASSERT(!serialize_owner_.IsNull());
-      SerializeCanonicalName(b, serialize_owner_);
-    }
-    b->Printf(":%s", function_name);
-  } else if (obj.IsClass()) {
-    const auto& cls = Class::Cast(obj);
-    tmp_string_ = cls.ScrubbedName();
-    const char* class_name = tmp_string_.ToCString();
-    serialize_library_ = cls.library();
-    if (!serialize_library_.IsNull()) {
-      SerializeCanonicalName(b, serialize_library_);
-    }
-    b->Printf(":%s", class_name);
-  } else if (obj.IsLibrary()) {
-    const Library& lib = Library::Cast(obj);
-    tmp_string_ = lib.url();
-    const char* lib_name = tmp_string_.ToCString();
-    if (lib_name[0] == '\0') return;
-    b->AddString(lib_name);
-  } else if (obj.IsField()) {
-    const auto& field = Field::Cast(obj);
-    tmp_string_ = field.UserVisibleName();
-    const char* field_name = tmp_string_.ToCString();
-    serialize_owner_ = field.Owner();
-    ASSERT(!serialize_owner_.IsNull());
-    SerializeCanonicalName(b, serialize_owner_);
-    b->Printf(".%s", field_name);
-  } else {
-    UNREACHABLE();
-  }
-}
-
-SExpression* FlowGraphSerializer::CanonicalNameToSExp(const Object& obj) {
-  ASSERT(!obj.IsNull());
-  ZoneTextBuffer b(zone_, 100);
-  SerializeCanonicalName(&b, obj);
-  return new (zone()) SExpSymbol(b.buffer());
-}
-
-SExpSymbol* FlowGraphSerializer::BlockEntryKindToTag(BlockEntryKind k) {
-  ASSERT(k >= 0 && k < kNumEntryKinds);
-  return new (zone()) SExpSymbol(block_entry_kind_tags[k]);
-}
-
-#define KIND_TAG(name) block_entry_kind_tags[k##name]
-SExpSymbol* FlowGraphSerializer::BlockEntryTag(const BlockEntryInstr* entry) {
-  if (entry == nullptr) return nullptr;
-  if (entry->IsGraphEntry()) {
-    return BlockEntryKindToTag(kGraph);
-  }
-  if (entry->IsOsrEntry()) {
-    return BlockEntryKindToTag(kOSR);
-  }
-  if (entry->IsCatchBlockEntry()) {
-    return BlockEntryKindToTag(kCatch);
-  }
-  if (entry->IsIndirectEntry()) {
-    return BlockEntryKindToTag(kIndirect);
-  }
-  if (entry->IsFunctionEntry()) {
-    if (entry == flow_graph()->graph_entry()->normal_entry()) {
-      return BlockEntryKindToTag(kNormal);
-    }
-    if (entry == flow_graph()->graph_entry()->unchecked_entry()) {
-      return BlockEntryKindToTag(kUnchecked);
-    }
-  }
-  if (entry->IsJoinEntry()) {
-    return BlockEntryKindToTag(kJoin);
-  }
-  return nullptr;
-}
-#undef KIND_TAG
-
-SExpression* FlowGraphSerializer::FunctionEntryToSExp(
-    const BlockEntryInstr* entry) {
-  if (entry == nullptr) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  sexp->Add(BlockEntryTag(entry));
-  sexp->Add(BlockIdToSExp(entry->block_id()));
-  if (auto const with_defs = entry->AsBlockEntryWithInitialDefs()) {
-    auto const initial_defs = with_defs->initial_definitions();
-    for (intptr_t i = 0; i < initial_defs->length(); i++) {
-      sexp->Add(initial_defs->At(i)->ToSExpression(this));
-    }
-  }
-
-  // Also include the extra info here, to avoid having to find the
-  // corresponding block to get it.
-  entry->BlockEntryInstr::AddExtraInfoToSExpression(sexp, this);
-
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::EntriesToSExp(const GraphEntryInstr* start) {
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Entries");
-  if (auto const normal = FunctionEntryToSExp(start->normal_entry())) {
-    sexp->Add(normal);
-  }
-  if (auto const unchecked = FunctionEntryToSExp(start->unchecked_entry())) {
-    sexp->Add(unchecked);
-  }
-  if (auto const osr = FunctionEntryToSExp(start->osr_entry())) {
-    sexp->Add(osr);
-  }
-  for (intptr_t i = 0; i < start->catch_entries().length(); i++) {
-    sexp->Add(FunctionEntryToSExp(start->catch_entries().At(i)));
-  }
-  for (intptr_t i = 0; i < start->indirect_entries().length(); i++) {
-    sexp->Add(FunctionEntryToSExp(start->indirect_entries().At(i)));
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::FlowGraphToSExp() {
-  auto const start = flow_graph()->graph_entry();
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "FlowGraph");
-  sexp->Add(CanonicalNameToSExp(flow_graph()->function()));
-  AddExtraInteger(sexp, "deopt_id", start->deopt_id());
-  if (start->env() != nullptr) {
-    sexp->AddExtra("env", start->env()->ToSExpression(this));
-  }
-  if (start->IsCompiledForOsr()) {
-    AddExtraInteger(sexp, "osr_id", start->osr_id());
-  }
-  if (auto const constants = ConstantPoolToSExp(start)) {
-    sexp->Add(constants);
-  }
-  sexp->Add(EntriesToSExp(start));
-  auto& block_order = flow_graph()->reverse_postorder();
-  // Skip the first block, which will be the graph entry block (B0). We
-  // output all its information as part of the function expression, so it'll
-  // just show up as an empty block here.
-  ASSERT(block_order[0]->IsGraphEntry());
-  for (intptr_t i = 1; i < block_order.length(); ++i) {
-    sexp->Add(block_order[i]->ToSExpression(this));
-  }
-  if (FLAG_populate_llvm_constant_pool) {
-    auto const new_index = llvm_functions_.Length();
-    llvm_functions_.Add(flow_graph_->function());
-    AddExtraInteger(sexp, "llvm_index", new_index);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::UseToSExp(const Definition* definition) {
-  ASSERT(definition != nullptr);
-  ASSERT(definition->HasSSATemp() || definition->HasTemp());
-  if (definition->HasSSATemp()) {
-    const intptr_t temp_index = definition->ssa_temp_index();
-    const auto name_cstr = OS::SCreate(zone(), "v%" Pd "", temp_index);
-    if (definition->HasPairRepresentation()) {
-      auto sexp = new (zone()) SExpList(zone());
-      AddSymbol(sexp, name_cstr);
-      AddSymbol(sexp, OS::SCreate(zone(), "v%" Pd "", temp_index + 1));
-      return sexp;
-    } else {
-      return new (zone()) SExpSymbol(name_cstr);
-    }
-  } else if (definition->HasTemp()) {
-    const intptr_t temp_index = definition->temp_index();
-    return new (zone()) SExpSymbol(OS::SCreate(zone(), "t%" Pd "", temp_index));
-  }
-  UNREACHABLE();
-}
-
-SExpression* FlowGraphSerializer::ClassToSExp(const Class& cls) {
-  if (cls.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Class");
-  AddInteger(sexp, cls.id());
-  if (FLAG_verbose_flow_graph_serialization) {
-    sexp->AddExtra("name", CanonicalNameToSExp(cls));
-    // Currently, AbstractTypeToSExp assumes that serializing a class cannot
-    // re-enter it. If we make that possible by serializing parts of a class
-    // that can contain AbstractTypes, especially types that are not type
-    // parameters or type references, fix AbstractTypeToSExp appropriately.
-  }
-  return sexp;
-}
-
-static bool ShouldSerializeType(CompileType* type) {
-  return (FLAG_verbose_flow_graph_serialization ||
-          FLAG_serialize_flow_graph_types) &&
-         type != nullptr;
-}
-
-SExpression* FlowGraphSerializer::FieldToSExp(const Field& field) {
-  if (field.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Field");
-  sexp->Add(CanonicalNameToSExp(field));
-  CompileType t(field.is_nullable(), field.guarded_cid(), nullptr);
-  if (ShouldSerializeType(&t)) {
-    sexp->AddExtra("type", t.ToSExpression(this));
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::AbstractTypeToSExp(const AbstractType& t) {
-  if (t.IsNull()) return nullptr;
-  ASSERT(t.IsFinalized());
-  auto sexp = new (zone()) SExpList(zone());
-  if (t.IsTypeParameter()) {
-    const auto& param = TypeParameter::Cast(t);
-    AddSymbol(sexp, "TypeParameter");
-    AddExtraInteger(sexp, "cid", param.parameterized_class_id());
-    AddExtraInteger(sexp, "base", param.base());
-    AddExtraInteger(sexp, "index", param.index());
-    tmp_string_ = param.name();
-    AddSymbol(sexp, tmp_string_.ToCString());
-    // TODO(regis): bound, default argument, flags, nullability, hash.
-    return sexp;
-  }
-  if (t.IsTypeRef()) {
-    const auto& ref = TypeRef::Cast(t);
-    AddSymbol(sexp, "TypeRef");
-    type_ref_type_ = ref.type();
-    auto const hash = type_ref_type_.Hash();
-    // Check to see if this is a TypeRef to a type we're currently serializing.
-    // If it is not, then we need to serialize the underlying type, as it
-    // otherwise won't be available when deserializing.
-    auto const open_type = open_recursive_types_.LookupValue(hash);
-    if (open_type == nullptr) {
-      // Allocate a new handle as we may re-enter the TypeRef branch.
-      auto& type = AbstractType::Handle(zone(), ref.type());
-      sexp->Add(AbstractTypeToSExp(type));
-      // If we serialized the referrent, then we don't need this information,
-      // but it may be useful for debugging so add it in verbose mode.
-      if (FLAG_verbose_flow_graph_serialization) {
-        AddExtraInteger(sexp, "hash", hash);
-      }
-    } else {
-      // Make sure we didn't have a hash collision.
-      ASSERT(open_type->Equals(type_ref_type_));
-      AddExtraInteger(sexp, "hash", hash);
-    }
-    if (FLAG_verbose_flow_graph_serialization) {
-      AddExtraString(sexp, "type", type_ref_type_.ToCString());
-    }
-    return sexp;
-  }
-  // We want to check for the type being recursive before we may serialize
-  // any sub-parts that include possible TypeRefs to this type.
-  const bool is_recursive = t.IsRecursive();
-  intptr_t hash = 0;
-  if (is_recursive) {
-    hash = t.Hash();
-    AddExtraInteger(sexp, "hash", hash);
-    open_recursive_types_.Insert(hash, &t);
-  }
-  if (t.IsFunctionType()) {
-    const auto& sig = FunctionType::Handle(zone(), FunctionType::Cast(t).ptr());
-    AddSymbol(sexp, "FunctionType");
-    function_type_args_ = sig.type_parameters();
-    if (auto const ta_sexp = NonEmptyTypeArgumentsToSExp(function_type_args_)) {
-      sexp->AddExtra("type_params", ta_sexp);
-    }
-    auto& type = AbstractType::Handle(zone(), sig.result_type());
-    sexp->AddExtra("result_type", AbstractTypeToSExp(type));
-    auto& parameter_types = Array::Handle(zone(), sig.parameter_types());
-    sexp->AddExtra("parameter_types", ArrayToSExp(parameter_types));
-    auto& parameter_names = Array::Handle(zone(), sig.parameter_names());
-    sexp->AddExtra("parameter_names", ArrayToSExp(parameter_names));
-    AddExtraInteger(sexp, "packed_fields", sig.packed_fields());
-    // If we were parsing a recursive type, we're now done building it, so
-    // remove it from the open recursive types.
-    if (is_recursive) open_recursive_types_.Remove(hash);
-    return sexp;
-  }
-  ASSERT(t.IsType());
-  AddSymbol(sexp, "Type");
-  const auto& type = Type::Cast(t);
-  if (type.HasTypeClass()) {
-    type_class_ = type.type_class();
-    // This avoids re-entry as long as serializing a class doesn't involve
-    // serializing concrete (non-parameter, non-reference) types.
-    sexp->Add(DartValueToSExp(type_class_));
-  } else {
-    // TODO(dartbug.com/36882): Actually structure non-class types instead of
-    // just printing out this version.
-    AddExtraString(sexp, "name", type.ToCString());
-  }
-  // Since type arguments may themselves be instantiations of generic
-  // types, we may call back into this function in the middle of printing
-  // the TypeArguments and so we must allocate a fresh handle here.
-  const auto& args = TypeArguments::Handle(zone(), type.arguments());
-  if (auto const args_sexp = NonEmptyTypeArgumentsToSExp(args)) {
-    sexp->AddExtra("type_args", args_sexp);
-  }
-  // If we were parsing a recursive type, we're now done building it, so
-  // remove it from the open recursive types.
-  if (is_recursive) open_recursive_types_.Remove(hash);
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::CodeToSExp(const Code& code) {
-  if (code.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Code");
-  if (code.IsStubCode()) {
-    AddSymbol(sexp, StubCode::NameOfStub(code.EntryPoint()));
-    if (FLAG_verbose_flow_graph_serialization) {
-      AddExtraSymbol(sexp, "kind", "stub");
-    }
-    return sexp;
-  }
-  code_owner_ = code.owner();
-  if (!code_owner_.IsNull() && FLAG_verbose_flow_graph_serialization) {
-    if (code_owner_.IsClass()) {
-      AddExtraSymbol(sexp, "kind", "allocate");
-    } else if (code_owner_.IsAbstractType()) {
-      AddExtraSymbol(sexp, "kind", "type_test");
-    } else {
-      ASSERT(code_owner_.IsFunction());
-      AddExtraSymbol(sexp, "kind", "function");
-    }
-  }
-  sexp->Add(DartValueToSExp(code_owner_));
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::TypeArgumentsToSExp(const TypeArguments& ta) {
-  if (ta.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "TypeArguments");
-  for (intptr_t i = 0; i < ta.Length(); i++) {
-    type_arguments_elem_ = ta.TypeAt(i);
-    sexp->Add(DartValueToSExp(type_arguments_elem_));
-  }
-  if (FLAG_verbose_flow_graph_serialization && ta.IsRecursive()) {
-    AddExtraInteger(sexp, "hash", ta.Hash());
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::InstanceToSExp(const Instance& inst) {
-  if (inst.IsNull()) return nullptr;
-
-  // Since InstanceToSExp may use ObjectToSExp (via DartValueToSExp) for field
-  // values that aren't entries in the constant pool, and ObjectToSExp may
-  // re-enter InstanceToSExp, allocate fresh handles here for the argument to
-  // DartValueToSExp and other handles that are live across the call.
-  const auto& instance_class = Class::Handle(zone(), inst.clazz());
-  const auto& instance_fields_array =
-      Array::Handle(zone(), instance_class.fields());
-  auto& instance_field_value = Object::Handle(zone());
-
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Instance");
-  AddInteger(sexp, instance_class.id());
-  auto const fields = new (zone()) SExpList(zone());
-  AddSymbol(fields, "Fields");
-  for (intptr_t i = 0; i < instance_fields_array.Length(); i++) {
-    instance_field_ = Field::RawCast(instance_fields_array.At(i));
-    // We don't need to serialize static fields, since they're shared by
-    // all instances.
-    if (instance_field_.is_static()) continue;
-    // We should only be getting const instances, which means that we
-    // should only see final instance fields.
-    ASSERT(instance_field_.is_final());
-    tmp_string_ = instance_field_.UserVisibleName();
-    auto const label = tmp_string_.ToCString();
-    instance_field_value = inst.GetField(instance_field_);
-    fields->AddExtra(label, DartValueToSExp(instance_field_value));
-  }
-  if (fields->ExtraLength() != 0 || FLAG_verbose_flow_graph_serialization) {
-    sexp->Add(fields);
-  }
-  if (instance_class.IsGeneric()) {
-    instance_type_args_ = inst.GetTypeArguments();
-    if (auto const args = NonEmptyTypeArgumentsToSExp(instance_type_args_)) {
-      sexp->AddExtra("type_args", args);
-    }
-  }
-  if (FLAG_verbose_flow_graph_serialization) {
-    AddExtraInteger(sexp, "size", inst.InstanceSize());
-    // We know the following won't call back into InstanceToSExp because we're
-    // providing it a class.
-    if (auto const cls = DartValueToSExp(instance_class)) {
-      sexp->AddExtra("class", cls);
-    }
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::FunctionToSExp(const Function& func) {
-  if (func.IsNull()) return nullptr;
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Function");
-  sexp->Add(CanonicalNameToSExp(func));
-  if (func.IsRecognized()) {
-    AddExtraSymbol(sexp, "recognized",
-                   MethodRecognizer::KindToCString(func.recognized_kind()));
-  }
-  if (func.is_native()) {
-    tmp_string_ = func.native_name();
-    if (!tmp_string_.IsNull()) {
-      AddExtraSymbol(sexp, "native_name", tmp_string_.ToCString());
-    }
-  }
-  if (func.kind() != UntaggedFunction::Kind::kRegularFunction ||
-      FLAG_verbose_flow_graph_serialization) {
-    AddExtraSymbol(sexp, "kind", UntaggedFunction::KindToCString(func.kind()));
-  }
-  function_type_args_ = func.type_parameters();
-  if (auto const ta_sexp = NonEmptyTypeArgumentsToSExp(function_type_args_)) {
-    sexp->AddExtra("type_args", ta_sexp);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ImmutableListToSExp(const Array& arr) {
-  if (arr.IsNull()) return nullptr;
-  // We should only be getting immutable lists when serializing Dart values
-  // in flow graphs.
-  ASSERT(arr.IsImmutable());
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "ImmutableList");
-  // We allocate a new Object handle to use for the calls to DartValueToSExp
-  // in case any Array elements contain non-constant-pool, non-empty Arrays.
-  auto& array_elem = Object::Handle(zone());
-  for (intptr_t i = 0; i < arr.Length(); i++) {
-    array_elem = arr.At(i);
-    sexp->Add(DartValueToSExp(array_elem));
-  }
-  array_type_args_ = arr.GetTypeArguments();
-  if (auto const type_args_sexp = TypeArgumentsToSExp(array_type_args_)) {
-    sexp->AddExtra("type_args", type_args_sexp);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ArrayToSExp(const Array& arr) {
-  if (arr.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Array");
-  auto& array_elem = Object::Handle(zone());
-  for (intptr_t i = 0; i < arr.Length(); i++) {
-    array_elem = arr.At(i);
-    sexp->Add(DartValueToSExp(array_elem));
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ClosureToSExp(const Closure& c) {
-  if (c.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Closure");
-  closure_function_ = c.function();
-  if (auto const func = FunctionToSExp(closure_function_)) {
-    sexp->Add(func);
-  }
-  closure_context_ = c.context();
-  if (auto const context = ContextToSExp(closure_context_)) {
-    sexp->AddExtra("context", context);
-  }
-  closure_type_args_ = c.function_type_arguments();
-  if (auto const type_args = NonEmptyTypeArgumentsToSExp(closure_type_args_)) {
-    sexp->AddExtra("func_type_args", type_args);
-  }
-  closure_type_args_ = c.instantiator_type_arguments();
-  if (auto const type_args = NonEmptyTypeArgumentsToSExp(closure_type_args_)) {
-    sexp->AddExtra("inst_type_args", type_args);
-  }
-  closure_type_args_ = c.delayed_type_arguments();
-  if (auto const type_args = NonEmptyTypeArgumentsToSExp(closure_type_args_)) {
-    sexp->AddExtra("delayed_type_args", type_args);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ContextToSExp(const Context& c) {
-  if (c.IsNull()) return nullptr;
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Context");
-  for (intptr_t i = 0; i < c.num_variables(); i++) {
-    context_elem_ = c.At(i);
-    auto const elem_sexp = DartValueToSExp(context_elem_);
-    if (elem_sexp == nullptr) return nullptr;
-    sexp->Add(elem_sexp);
-  }
-  context_parent_ = c.parent();
-  if (auto const parent_sexp = ContextToSExp(context_parent_)) {
-    sexp->AddExtra("parent", parent_sexp);
-  }
-  return sexp;
-}
-
-SExpression* FlowGraphSerializer::ObjectToSExp(const Object& dartval) {
-  if (dartval.IsNull()) {
-    return new (zone()) SExpSymbol("null");
-  }
-  if (dartval.ptr() == Object::sentinel().ptr()) {
-    return new (zone()) SExpSymbol("sentinel");
-  }
-  if (dartval.IsString()) {
-    return new (zone()) SExpString(dartval.ToCString());
-  }
-  if (dartval.IsSmi()) {
-    return new (zone()) SExpInteger(Smi::Cast(dartval).Value());
-  }
-  if (dartval.IsMint()) {
-    return new (zone()) SExpInteger(Mint::Cast(dartval).value());
-  }
-  if (dartval.IsBool()) {
-    return new (zone()) SExpBool(Bool::Cast(dartval).value());
-  }
-  if (dartval.IsDouble()) {
-    return new (zone()) SExpDouble(Double::Cast(dartval).value());
-  }
-  if (dartval.IsField()) {
-    return FieldToSExp(Field::Cast(dartval));
-  }
-  if (dartval.IsClass()) {
-    return ClassToSExp(Class::Cast(dartval));
-  }
-  if (dartval.IsTypeArguments()) {
-    return TypeArgumentsToSExp(TypeArguments::Cast(dartval));
-  }
-  if (dartval.IsCode()) {
-    return CodeToSExp(Code::Cast(dartval));
-  }
-  if (dartval.IsArray()) {
-    return ImmutableListToSExp(Array::Cast(dartval));
-  }
-  if (dartval.IsFunction()) {
-    return FunctionToSExp(Function::Cast(dartval));
-  }
-  if (dartval.IsClosure()) {
-    return ClosureToSExp(Closure::Cast(dartval));
-  }
-  if (dartval.IsAbstractType()) {
-    return AbstractTypeToSExp(AbstractType::Cast(dartval));
-  }
-  ASSERT(dartval.IsInstance());
-  return InstanceToSExp(Instance::Cast(dartval));
-}
-
-SExpression* FlowGraphSerializer::DartValueToSExp(const Object& obj) {
-  if (auto const def = flow_graph()->GetExistingConstant(obj)) {
-    ASSERT(def->IsDefinition());
-    return UseToSExp(def->AsDefinition());
-  }
-  return ObjectToSExp(obj);
-}
-
-SExpression* FlowGraphSerializer::NonEmptyTypeArgumentsToSExp(
-    const TypeArguments& ta) {
-  if (ta.IsNull() || ta.Length() == 0) return nullptr;
-  return DartValueToSExp(ta);
-}
-
-SExpression* FlowGraphSerializer::ConstantPoolToSExp(
-    const GraphEntryInstr* start) {
-  auto const initial_defs = start->initial_definitions();
-  if (initial_defs == nullptr || initial_defs->is_empty()) return nullptr;
-  auto constant_list = new (zone()) SExpList(zone());
-  AddSymbol(constant_list, "Constants");
-  for (intptr_t i = 0; i < initial_defs->length(); i++) {
-    ASSERT(initial_defs->At(i)->IsConstant());
-    auto const definition = initial_defs->At(i)->AsDefinition();
-    auto elem = new (zone()) SExpList(zone());
-    AddSymbol(elem, "def");
-    elem->Add(UseToSExp(definition));
-    // Use ObjectToSExp here, not DartValueToSExp!
-    const auto& value = definition->AsConstant()->value();
-    elem->Add(ObjectToSExp(value));
-    AddDefinitionExtraInfoToSExp(definition, elem);
-    // Only add constants to the LLVM constant pool that are actually used in
-    // the flow graph.
-    if (FLAG_populate_llvm_constant_pool && definition->HasUses()) {
-      auto const pool_len = llvm_constants_.Length();
-      llvm_index_ = Smi::New(pool_len);
-      llvm_index_ ^= llvm_constant_map_.InsertOrGetValue(value, llvm_index_);
-      if (llvm_index_.Value() == pool_len) {
-        llvm_constants_.Add(value);
-      }
-      AddExtraInteger(elem, "llvm_index", llvm_index_.Value());
-    }
-    constant_list->Add(elem);
-  }
-  return constant_list;
-}
-
-SExpression* Instruction::ToSExpression(FlowGraphSerializer* s) const {
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, DebugName());
-  AddOperandsToSExpression(sexp, s);
-  AddExtraInfoToSExpression(sexp, s);
-  return sexp;
-}
-
-SExpression* BlockEntryInstr::ToSExpression(FlowGraphSerializer* s) const {
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "Block");
-  sexp->Add(s->BlockIdToSExp(block_id()));
-  AddOperandsToSExpression(sexp, s);
-  AddExtraInfoToSExpression(sexp, s);
-  return sexp;
-}
-
-void BlockEntryInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (try_index() != kInvalidTryIndex) {
-    s->AddExtraInteger(sexp, "try_index", try_index());
-  }
-  if (auto const entry_tag = s->BlockEntryTag(this)) {
-    sexp->AddExtra("block_type", entry_tag);
-  }
-  if (FLAG_verbose_flow_graph_serialization) {
-    if (PredecessorCount() > 0) {
-      auto const preds = new (s->zone()) SExpList(s->zone());
-      for (intptr_t i = 0; i < PredecessorCount(); i++) {
-        preds->Add(s->BlockIdToSExp(PredecessorAt(i)->block_id()));
-      }
-      sexp->AddExtra("predecessors", preds);
-    }
-  }
-}
-
-void BlockEntryInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  for (const auto* inst = next_; inst != nullptr; inst = inst->next_) {
-    sexp->Add(inst->ToSExpression(s));
-  }
-}
-
-void JoinEntryInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  if (auto phi_list = phis()) {
-    for (intptr_t i = 0; i < phi_list->length(); i++) {
-      sexp->Add(phi_list->At(i)->ToSExpression(s));
-    }
-  }
-  BlockEntryInstr::AddOperandsToSExpression(sexp, s);
-}
-
-void Instruction::AddOperandsToSExpression(SExpList* sexp,
-                                           FlowGraphSerializer* s) const {
-  for (intptr_t i = 0; i < InputCount(); ++i) {
-    if (InputAt(i) == nullptr) continue;
-    sexp->Add(InputAt(i)->ToSExpression(s));
-  }
-}
-
-void Instruction::AddExtraInfoToSExpression(SExpList* sexp,
-                                            FlowGraphSerializer* s) const {
-  if (GetDeoptId() != DeoptId::kNone) {
-    s->AddExtraInteger(sexp, "deopt_id", GetDeoptId());
-  }
-  if (env() != nullptr) {
-    sexp->AddExtra("env", env()->ToSExpression(s));
-  }
-  if (!token_pos().IsNoSource()) {
-    s->AddExtraInteger(sexp, "token_pos", token_pos().Serialize());
-  }
-  if (has_inlining_id()) {
-    s->AddExtraInteger(sexp, "inlining_id", inlining_id());
-  }
-}
-
-SExpression* Range::ToSExpression(FlowGraphSerializer* s) {
-  auto const sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "Range");
-  sexp->Add(min_.ToSExpression(s));
-  if (!max_.Equals(min_)) sexp->Add(max_.ToSExpression(s));
-  return sexp;
-}
-
-SExpression* RangeBoundary::ToSExpression(FlowGraphSerializer* s) {
-  switch (kind_) {
-    case kSymbol: {
-      auto const sexp = new (s->zone()) SExpList(s->zone());
-      sexp->Add(s->UseToSExp(symbol()));
-      if (offset() != 0) {
-        s->AddExtraInteger(sexp, "offset", offset());
-      }
-      return sexp;
-    }
-    case kConstant:
-      return new (s->zone()) SExpInteger(value_);
-    default:
-      return new (s->zone()) SExpSymbol(RangeBoundary::KindToCString(kind_));
-  }
-}
-
-bool FlowGraphSerializer::HasDefinitionExtraInfo(const Definition* def) {
-  return ShouldSerializeType(def->type_) || def->range() != nullptr;
-}
-
-void FlowGraphSerializer::AddDefinitionExtraInfoToSExp(const Definition* def,
-                                                       SExpList* sexp) {
-  // Type() isn't a const method as it can cause changes to the type_
-  // field, so access type_ directly instead.
-  if (ShouldSerializeType(def->type_)) {
-    sexp->AddExtra("type", def->type_->ToSExpression(this));
-  }
-  if (def->range() != nullptr) {
-    sexp->AddExtra("range", def->range()->ToSExpression(this));
-  }
-}
-
-SExpression* Definition::ToSExpression(FlowGraphSerializer* s) const {
-  // If we don't have a temp index, then this is a Definition that has no
-  // usable result.
-  const bool binds_name = HasSSATemp() || HasTemp();
-  // Don't serialize non-binding definitions as definitions unless we either
-  // have Definition-specific extra info or we're in verbose mode.
-  if (!binds_name && !FLAG_verbose_flow_graph_serialization &&
-      !s->HasDefinitionExtraInfo(this)) {
-    return Instruction::ToSExpression(s);
-  }
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "def");
-  if (binds_name) {
-    sexp->Add(s->UseToSExp(this));
-  } else {
-    // Since there is Definition-specific extra info to serialize, we use "_"
-    // as the bound name, which lets the deserializer know the result is unused.
-    s->AddSymbol(sexp, "_");
-  }
-  // Add only Definition-specific extra info to this form. Any extra info
-  // that is Instruction-specific or specific to the actual instruction type is
-  // added to the nested instruction form.
-  s->AddDefinitionExtraInfoToSExp(this, sexp);
-  sexp->Add(Instruction::ToSExpression(s));
-  return sexp;
-}
-
-void AssertAssignableInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  sexp->AddExtra("name", s->DartValueToSExp(dst_name()));
-}
-
-void ConstantInstr::AddOperandsToSExpression(SExpList* sexp,
-                                             FlowGraphSerializer* s) const {
-  sexp->Add(s->DartValueToSExp(value()));
-}
-
-void BranchInstr::AddOperandsToSExpression(SExpList* sexp,
-                                           FlowGraphSerializer* s) const {
-  sexp->Add(comparison()->ToSExpression(s));
-  sexp->Add(s->BlockIdToSExp(true_successor()->block_id()));
-  sexp->Add(s->BlockIdToSExp(false_successor()->block_id()));
-}
-
-void ParameterInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  s->AddInteger(sexp, index());
-  s->AddExtraInteger(sexp, "param_offset", param_offset());
-  s->AddExtraSymbol(sexp, "representation",
-                    Location::RepresentationToCString(representation()));
-}
-
-void SpecialParameterInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  ASSERT(kind() < SpecialParameterInstr::kNumKinds);
-  s->AddSymbol(sexp, KindToCString(kind()));
-}
-
-SExpression* FlowGraphSerializer::LocalVariableToSExp(const LocalVariable& v) {
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "LocalVariable");
-  if (!v.name().IsNull()) {
-    AddSymbol(sexp, v.name().ToCString());
-  }
-  if (v.index().IsValid()) {
-    AddExtraInteger(sexp, "index", v.index().value());
-  }
-  return sexp;
-}
-
-void LoadLocalInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  sexp->Add(s->LocalVariableToSExp(local()));
-}
-
-void StoreLocalInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  sexp->Add(s->LocalVariableToSExp(local()));
-}
-
-SExpression* FlowGraphSerializer::SlotToSExp(const Slot& slot) {
-  auto sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "Slot");
-  AddInteger(sexp, slot.offset_in_bytes());
-  AddExtraSymbol(sexp, "kind", Slot::KindToCString(slot.kind()));
-  if (slot.IsDartField()) {
-    sexp->AddExtra("field", DartValueToSExp(slot.field()));
-  }
-  return sexp;
-}
-
-void LoadFieldInstr::AddOperandsToSExpression(SExpList* sexp,
-                                              FlowGraphSerializer* s) const {
-  sexp->Add(instance()->ToSExpression(s));
-  sexp->Add(s->SlotToSExp(slot()));
-}
-
-void LoadFieldInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (calls_initializer() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "calls_initializer", calls_initializer());
-  }
-}
-
-void StoreInstanceFieldInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  sexp->Add(instance()->ToSExpression(s));
-  sexp->Add(s->SlotToSExp(slot()));
-  sexp->Add(value()->ToSExpression(s));
-}
-
-void StoreInstanceFieldInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (is_initialization_ || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "is_init", is_initialization_);
-  }
-  if (emit_store_barrier_ != kNoStoreBarrier ||
-      FLAG_verbose_flow_graph_serialization) {
-    // Make sure that we aren't seeing a new value added to the StoreBarrierType
-    // enum that isn't handled by the serializer.
-    ASSERT(emit_store_barrier_ == kNoStoreBarrier ||
-           emit_store_barrier_ == kEmitStoreBarrier);
-    s->AddExtraBool(sexp, "emit_barrier",
-                    emit_store_barrier_ != kNoStoreBarrier);
-  }
-}
-
-void LoadIndexedUnsafeInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (offset() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "offset", offset());
-  }
-}
-
-void StoreIndexedUnsafeInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (offset() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "offset", offset());
-  }
-}
-
-void ComparisonInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, Token::Str(kind()));
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void StrictCompareInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (needs_number_check_ || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "needs_check", needs_number_check_);
-  }
-}
-
-void DoubleTestOpInstr::AddOperandsToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  const bool negated = kind() != Token::kEQ;
-  switch (op_kind()) {
-    case MethodRecognizer::kDouble_getIsNaN:
-      s->AddSymbol(sexp, negated ? "IsNotNaN" : "IsNaN");
-      break;
-    case MethodRecognizer::kDouble_getIsInfinite:
-      s->AddSymbol(sexp, negated ? "IsNotInfinite" : "IsInfinite");
-      break;
-    default:
-      UNREACHABLE();
-  }
-  sexp->Add(value()->ToSExpression(s));
-}
-
-void GotoInstr::AddOperandsToSExpression(SExpList* sexp,
-                                         FlowGraphSerializer* s) const {
-  sexp->Add(s->BlockIdToSExp(successor()->block_id()));
-}
-
-void DebugStepCheckInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (stub_kind_ != UntaggedPcDescriptors::kAnyKind ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const stub_kind_name =
-        UntaggedPcDescriptors::KindToCString(stub_kind_);
-    ASSERT(stub_kind_name != nullptr);
-    s->AddExtraSymbol(sexp, "stub_kind", stub_kind_name);
-  }
-}
-
-SExpression* FlowGraphSerializer::ICDataToSExp(const ICData* ic_data) {
-  auto const sexp = new (zone()) SExpList(zone());
-  AddSymbol(sexp, "ICData");
-
-  if (ic_data->is_tracking_exactness()) {
-    ic_data_type_ = ic_data->receivers_static_type();
-    sexp->AddExtra("receivers_static_type", AbstractTypeToSExp(ic_data_type_));
-  }
-
-  if (ic_data->is_megamorphic() || FLAG_verbose_flow_graph_serialization) {
-    AddExtraBool(sexp, "is_megamorphic", ic_data->is_megamorphic());
-  }
-
-  auto const num_checks = ic_data->NumberOfChecks();
-  GrowableArray<intptr_t> class_ids(zone(), 2);
-  for (intptr_t i = 0; i < num_checks; i++) {
-    auto const entry = new (zone()) SExpList(zone());
-
-    auto const count = ic_data->GetCountAt(i);
-    if (count > 0 || FLAG_verbose_flow_graph_serialization) {
-      AddExtraInteger(entry, "count", count);
-    }
-
-    class_ids.Clear();
-    ic_data->GetCheckAt(i, &class_ids, &ic_data_target_);
-    entry->AddExtra("target", DartValueToSExp(ic_data_target_));
-    for (auto const cid : class_ids) {
-      entry->Add(new (zone()) SExpInteger(cid));
-    }
-
-    sexp->Add(entry);
-  }
-
-  if (FLAG_verbose_flow_graph_serialization) {
-    AddExtraSymbol(sexp, "rebind_rule",
-                   ICData::RebindRuleToCString(ic_data->rebind_rule()));
-    tmp_string_ = ic_data->target_name();
-    AddExtraString(sexp, "target_name", tmp_string_.ToCString());
-    ic_data_target_ = ic_data->Owner();
-    sexp->AddExtra("owner", DartValueToSExp(ic_data_target_));
-    AddExtraInteger(sexp, "num_args_tested", ic_data->NumArgsTested());
-    auto& args_desc = Array::Handle(zone(), ic_data->arguments_descriptor());
-    sexp->AddExtra("arguments_descriptor", DartValueToSExp(args_desc));
-  }
-
-  return sexp;
-}
-
-void TailCallInstr::AddOperandsToSExpression(SExpList* sexp,
-                                             FlowGraphSerializer* s) const {
-  if (auto const code = s->DartValueToSExp(code_)) {
-    sexp->Add(code);
-  }
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void NativeCallInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void NativeCallInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                FlowGraphSerializer* s) const {
-  TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
-  if (auto const func = s->DartValueToSExp(function())) {
-    sexp->AddExtra("function", func);
-  }
-  if (!native_name().IsNull()) {
-    s->AddExtraString(sexp, "name", native_name().ToCString());
-  }
-  if (link_lazily() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "link_lazily", link_lazily());
-  }
-}
-
-template <intptr_t kExtraInputs>
-void TemplateDartCall<kExtraInputs>::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (type_args_len() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "type_args_len", type_args_len());
-  }
-  s->AddExtraInteger(sexp, "args_len", ArgumentCountWithoutTypeArgs());
-
-  const auto& arg_names = argument_names();
-  if (!arg_names.IsNull()) {
-    auto arg_names_sexp = new (s->zone()) SExpList(s->zone());
-    auto& str = String::Handle(s->zone());
-    for (intptr_t i = 0; i < arg_names.Length(); i++) {
-      str = String::RawCast(arg_names.At(i));
-      arg_names_sexp->Add(s->ObjectToSExp(str));
-    }
-    sexp->AddExtra("arg_names", arg_names_sexp);
-  }
-
-  ASSERT(!HasPushArguments());
-}
-
-void ClosureCallInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  // For now, just here to ensure TemplateDartCall<1>::AddExtraInfoToSExpression
-  // gets instantiated.
-  TemplateDartCall<1>::AddExtraInfoToSExpression(sexp, s);
-}
-
-void StaticCallInstr::AddOperandsToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void StaticCallInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                FlowGraphSerializer* s) const {
-  TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
-
-  if (auto const func = s->DartValueToSExp(function())) {
-    sexp->AddExtra("function", func);
-  }
-
-  if (HasICData()) {
-    sexp->AddExtra("ic_data", s->ICDataToSExp(ic_data()));
-  } else if (CallCount() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "call_count", CallCount());
-  }
-
-  if (rebind_rule_ != ICData::kStatic ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const str = ICData::RebindRuleToCString(rebind_rule_);
-    ASSERT(str != nullptr);
-    s->AddExtraSymbol(sexp, "rebind_rule", str);
-  }
-
-  if (ShouldSerializeType(result_type())) {
-    sexp->AddExtra("result_type", result_type()->ToSExpression(s));
-  }
-
-  if (entry_kind() != Code::EntryKind::kNormal ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const kind_str = Code::EntryKindToCString(entry_kind());
-    s->AddExtraSymbol(sexp, "entry_kind", kind_str);
-  }
-}
-
-void InstanceCallBaseInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void InstanceCallBaseInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  TemplateDartCall<0>::AddExtraInfoToSExpression(sexp, s);
-
-  if (auto const target = s->DartValueToSExp(interface_target())) {
-    sexp->AddExtra("interface_target", target);
-  }
-
-  if (auto const target = s->DartValueToSExp(tearoff_interface_target())) {
-    sexp->AddExtra("tearoff_interface_target", target);
-  }
-
-  if (HasICData()) {
-    sexp->AddExtra("ic_data", s->ICDataToSExp(ic_data()));
-  }
-
-  if (function_name().IsNull()) {
-    if (!interface_target().IsNull() || !tearoff_interface_target().IsNull()) {
-      s->AddExtraSymbol(sexp, "function_name", "null");
-    }
-  } else {
-    if (interface_target().IsNull() ||
-        (function_name().ptr() != interface_target().name() &&
-         function_name().ptr() != tearoff_interface_target().name())) {
-      s->AddExtraString(sexp, "function_name", function_name().ToCString());
-    }
-  }
-
-  if (token_kind() != Token::kILLEGAL) {
-    s->AddExtraSymbol(sexp, "token_kind", Token::Str(token_kind()));
-  }
-
-  if (ShouldSerializeType(result_type())) {
-    sexp->AddExtra("result_type", result_type()->ToSExpression(s));
-  }
-
-  if (entry_kind() != Code::EntryKind::kNormal ||
-      FLAG_verbose_flow_graph_serialization) {
-    auto const kind_str = Code::EntryKindToCString(entry_kind());
-    s->AddExtraSymbol(sexp, "entry_kind", kind_str);
-  }
-}
-
-void InstanceCallInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  InstanceCallBaseInstr::AddExtraInfoToSExpression(sexp, s);
-
-  if (checked_argument_count() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "checked_arg_count", checked_argument_count());
-  }
-}
-
-void PolymorphicInstanceCallInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  InstanceCallBaseInstr::AddExtraInfoToSExpression(sexp, s);
-
-  if (targets().length() > 0 || FLAG_verbose_flow_graph_serialization) {
-    auto elem_list = new (s->zone()) SExpList(s->zone());
-    for (intptr_t i = 0; i < targets().length(); i++) {
-      auto elem = new (s->zone()) SExpList(s->zone());
-      const TargetInfo* ti = targets().TargetAt(i);
-      if (ti->cid_start == ti->cid_end) {
-        s->AddInteger(elem, ti->cid_start);
-      } else {
-        auto range = new (s->zone()) SExpList(s->zone());
-        s->AddInteger(range, ti->cid_start);
-        s->AddInteger(range, ti->cid_end);
-        elem->Add(range);
-      }
-      if (auto const target = s->DartValueToSExp(*ti->target)) {
-        elem->Add(target);
-      }
-      elem_list->Add(elem);
-    }
-    sexp->AddExtra("targets", elem_list);
-  }
-}
-
-void AllocateObjectInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  if (auto const sexp_cls = s->DartValueToSExp(cls())) {
-    sexp->Add(sexp_cls);
-  }
-  if (type_arguments() != nullptr) {
-    sexp->Add(type_arguments()->ToSExpression(s));
-  }
-}
-
-void AllocateObjectInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  s->AddExtraInteger(sexp, "size", cls().target_instance_size());
-  if (auto const closure = s->DartValueToSExp(closure_function())) {
-    sexp->AddExtra("closure_function", closure);
-  }
-  if (!Identity().IsUnknown() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraSymbol(sexp, "identity", Identity().ToCString());
-  }
-}
-
-void BinaryIntegerOpInstr::AddOperandsToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, Token::Str(op_kind()));
-  sexp->Add(left()->ToSExpression(s));
-  sexp->Add(right()->ToSExpression(s));
-}
-
-void CheckedSmiOpInstr::AddOperandsToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, Token::Str(op_kind()));
-  sexp->Add(left()->ToSExpression(s));
-  sexp->Add(right()->ToSExpression(s));
-}
-
-// clang-format off
-static const char* simd_op_kind_string[] = {
-#define CASE(Arity, Mask, Name, ...) #Name,
-  SIMD_OP_LIST(CASE, CASE)
-#undef CASE
-  "IllegalSimdOp",
-};
-// clang-format on
-
-void SimdOpInstr::AddOperandsToSExpression(SExpList* sexp,
-                                           FlowGraphSerializer* s) const {
-  s->AddSymbol(sexp, simd_op_kind_string[kind()]);
-  Instruction::AddOperandsToSExpression(sexp, s);
-}
-
-void SimdOpInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                            FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (HasMask()) {
-    s->AddExtraInteger(sexp, "mask", mask());
-  }
-}
-
-void LoadIndexedInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                                 FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (aligned() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "aligned", aligned());
-  }
-  if (index_scale() > 1 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "scale", index_scale());
-  }
-  if (class_id() != kDynamicCid || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "cid", class_id());
-  }
-}
-
-void StoreIndexedInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (aligned() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "aligned", aligned());
-  }
-  if (index_scale() > 1 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "scale", index_scale());
-  }
-  if (class_id() != kDynamicCid || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "cid", class_id());
-  }
-}
-
-void CheckStackOverflowInstr::AddExtraInfoToSExpression(
-    SExpList* sexp,
-    FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (stack_depth() > 0 || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "stack_depth", stack_depth());
-  }
-  if (in_loop() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "loop_depth", loop_depth());
-  }
-  if (kind_ != kOsrAndPreemption) {
-    ASSERT(kind_ == kOsrOnly);
-    s->AddExtraSymbol(sexp, "kind", "OsrOnly");
-  }
-}
-
-void CheckNullInstr::AddExtraInfoToSExpression(SExpList* sexp,
-                                               FlowGraphSerializer* s) const {
-  Instruction::AddExtraInfoToSExpression(sexp, s);
-  if (!function_name_.IsNull()) {
-    s->AddExtraString(sexp, "function_name", function_name_.ToCString());
-  }
-}
-
-SExpression* Value::ToSExpression(FlowGraphSerializer* s) const {
-  auto name = s->UseToSExp(definition());
-  // If we're not serializing types or there is no reaching type for this use,
-  // just serialize the use as the bound name.
-  if (!ShouldSerializeType(reaching_type_)) return name;
-
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "value");
-  sexp->Add(name);
-  // If there is no owner for the type, then serialize the type in full.
-  // Otherwise the owner should be the definition, so we'll inherit the type
-  // from it. (That is, (value v<X>) with no explicit type info means the
-  // reaching type comes from the definition of v<X>.) We'll serialize an
-  // "inherit_type" extra info field to make this explicit when in verbose mode.
-  if (reaching_type_->owner() == nullptr) {
-    sexp->AddExtra("type", reaching_type_->ToSExpression(s));
-  } else {
-    ASSERT(reaching_type_->owner() == definition());
-  }
-  if (FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "inherit_type",
-                    reaching_type_->owner() == definition());
-  }
-  return sexp;
-}
-
-SExpression* CompileType::ToSExpression(FlowGraphSerializer* s) const {
-  ASSERT(FLAG_verbose_flow_graph_serialization ||
-         FLAG_serialize_flow_graph_types);
-
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  s->AddSymbol(sexp, "CompileType");
-  AddExtraInfoToSExpression(sexp, s);
-  return sexp;
-}
-
-void CompileType::AddExtraInfoToSExpression(SExpList* sexp,
-                                            FlowGraphSerializer* s) const {
-  if (cid_ != kIllegalCid || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraInteger(sexp, "cid", cid_);
-  }
-  // TODO(sstrickl): Currently we only print out nullable if it's false
-  // (or during verbose printing). Switch this when NNBD is the standard.
-  if (!is_nullable() || FLAG_verbose_flow_graph_serialization) {
-    s->AddExtraBool(sexp, "nullable", is_nullable());
-  }
-  if (type_ != nullptr) {
-    sexp->AddExtra("type", s->DartValueToSExp(*type_));
-  }
-}
-
-SExpression* Environment::ToSExpression(FlowGraphSerializer* s) const {
-  auto sexp = new (s->zone()) SExpList(s->zone());
-  for (intptr_t i = 0; i < values_.length(); ++i) {
-    ASSERT(!values_[i]->definition()->IsPushArgument());
-    sexp->Add(values_[i]->ToSExpression(s));
-    // TODO(sstrickl): This currently assumes that there are no locations in the
-    // environment (e.g. before register allocation). If we ever want to print
-    // out environments on steps after AllocateRegisters, we'll need to handle
-    // locations as well.
-    ASSERT(locations_ == nullptr || locations_[i].IsInvalid());
-  }
-  if (outer_ != NULL) {
-    auto outer_sexp = outer_->ToSExpression(s)->AsList();
-    if (outer_->deopt_id_ != DeoptId::kNone) {
-      s->AddExtraInteger(outer_sexp, "deopt_id", outer_->deopt_id_);
-    }
-    sexp->AddExtra("outer", outer_sexp);
-  }
-  return sexp;
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/backend/il_serializer.h b/runtime/vm/compiler/backend/il_serializer.h
deleted file mode 100644
index fda5731..0000000
--- a/runtime/vm/compiler/backend/il_serializer.h
+++ /dev/null
@@ -1,198 +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_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
-#define RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-#error "AOT runtime should not use compiler sources (including header files)"
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-#include "platform/assert.h"
-#include "platform/text_buffer.h"
-
-#include "vm/allocation.h"
-#include "vm/compiler/backend/flow_graph.h"
-#include "vm/compiler/backend/il.h"
-#include "vm/compiler/backend/sexpression.h"
-#include "vm/hash_table.h"
-#include "vm/object.h"
-#include "vm/zone.h"
-
-namespace dart {
-
-// Flow graph serialization.
-class FlowGraphSerializer : ValueObject {
- public:
-#define FOR_EACH_BLOCK_ENTRY_KIND(M)                                           \
-  M(Target)                                                                    \
-  M(Join)                                                                      \
-  M(Graph)                                                                     \
-  M(Normal)                                                                    \
-  M(Unchecked)                                                                 \
-  M(OSR)                                                                       \
-  M(Catch)                                                                     \
-  M(Indirect)
-
-  enum BlockEntryKind {
-#define KIND_DECL(name) k##name,
-    FOR_EACH_BLOCK_ENTRY_KIND(KIND_DECL)
-#undef KIND_DECL
-    // clang-format off
-    kNumEntryKinds,
-    kInvalid = -1,
-    // clang-format on
-  };
-
-  // Special case: returns kTarget for a nullptr input.
-  static BlockEntryKind BlockEntryTagToKind(SExpSymbol* tag);
-  SExpSymbol* BlockEntryKindToTag(BlockEntryKind k);
-  static bool BlockEntryKindHasInitialDefs(BlockEntryKind kind);
-
-  static void SerializeToBuffer(Zone* zone,
-                                const FlowGraph* flow_graph,
-                                BaseTextBuffer* buffer);
-  static SExpression* SerializeToSExp(Zone* zone, const FlowGraph* flow_graph);
-
-  const FlowGraph* flow_graph() const { return flow_graph_; }
-  Zone* zone() const { return zone_; }
-
-  SExpression* FlowGraphToSExp();
-
-  SExpSymbol* BlockEntryTag(const BlockEntryInstr* entry);
-  SExpression* BlockIdToSExp(intptr_t block_id);
-  SExpression* CanonicalNameToSExp(const Object& obj);
-  SExpression* UseToSExp(const Definition* definition);
-
-  // Helper method for creating canonical names.
-  void SerializeCanonicalName(BaseTextBuffer* b, const Object& obj);
-
-  // Methods for serializing Dart values. If the argument
-  // value is the null object, the null pointer is returned.
-  SExpression* AbstractTypeToSExp(const AbstractType& typ);
-  SExpression* ArrayToSExp(const Array& arr);
-  SExpression* ImmutableListToSExp(const Array& arr);
-  SExpression* ClassToSExp(const Class& cls);
-  SExpression* ClosureToSExp(const Closure& c);
-  SExpression* ContextToSExp(const Context& c);
-  SExpression* CodeToSExp(const Code& c);
-  SExpression* FieldToSExp(const Field& f);
-  SExpression* FunctionToSExp(const Function& f);
-  SExpression* InstanceToSExp(const Instance& obj);
-  SExpression* TypeArgumentsToSExp(const TypeArguments& ta);
-
-  // A method for serializing a Dart value of arbitrary type. Unlike the
-  // type-specific methods, this returns the symbol "null" for the null object.
-  SExpression* ObjectToSExp(const Object& obj);
-
-  // A wrapper method for ObjectToSExp that first checks and sees if
-  // the provided value is in the constant pool. If it is, then it
-  // returns a reference to the constant definition via UseToSExp.
-  SExpression* DartValueToSExp(const Object& obj);
-
-  // A wrapper method for TypeArgumentsToSExp that also returns nullptr if the
-  // type arguments are empty and checks against the constant pool.
-  SExpression* NonEmptyTypeArgumentsToSExp(const TypeArguments& ta);
-
-  // Methods for serializing IL-specific values.
-  SExpression* LocalVariableToSExp(const LocalVariable& v);
-  SExpression* SlotToSExp(const Slot& s);
-  SExpression* ICDataToSExp(const ICData* ic_data);
-
-  // Helper methods for adding Definition-specific extra info.
-  bool HasDefinitionExtraInfo(const Definition* def);
-  void AddDefinitionExtraInfoToSExp(const Definition* def, SExpList* sexp);
-
-  // Helper methods for adding atoms to S-expression lists
-  void AddBool(SExpList* sexp, bool b);
-  void AddInteger(SExpList* sexp, intptr_t i);
-  void AddString(SExpList* sexp, const char* cstr);
-  void AddSymbol(SExpList* sexp, const char* cstr);
-  void AddExtraBool(SExpList* sexp, const char* label, bool b);
-  void AddExtraInteger(SExpList* sexp, const char* label, intptr_t i);
-  void AddExtraString(SExpList* sexp, const char* label, const char* cstr);
-  void AddExtraSymbol(SExpList* sexp, const char* label, const char* cstr);
-
- private:
-  friend class Precompiler;  // For LLVMConstantsMap.
-
-  FlowGraphSerializer(Zone* zone, const FlowGraph* flow_graph);
-  ~FlowGraphSerializer();
-
-  static const char* const initial_indent;
-
-  // Helper methods for the function level that are not used by any
-  // instruction serialization methods.
-  SExpression* FunctionEntryToSExp(const BlockEntryInstr* entry);
-  SExpression* EntriesToSExp(const GraphEntryInstr* start);
-  SExpression* ConstantPoolToSExp(const GraphEntryInstr* start);
-
-  const FlowGraph* const flow_graph_;
-  Zone* const zone_;
-  ObjectStore* const object_store_;
-
-  // A map of currently open (being serialized) recursive types. We use this
-  // to determine whether to serialize the referred types in TypeRefs.
-  IntMap<const AbstractType*> open_recursive_types_;
-
-  // Used for --populate-llvm-constant-pool in ConstantPoolToSExp.
-  class LLVMPoolMapKeyEqualsTraits : public AllStatic {
-   public:
-    static const char* Name() { return "LLVMPoolMapKeyEqualsTraits"; }
-    static bool ReportStats() { return false; }
-
-    static bool IsMatch(const Object& a, const Object& b) {
-      return a.ptr() == b.ptr();
-    }
-    static uword Hash(const Object& obj) {
-      if (obj.IsSmi()) return static_cast<uword>(obj.ptr());
-      if (obj.IsInstance()) return Instance::Cast(obj).CanonicalizeHash();
-      return obj.GetClassId();
-    }
-  };
-  typedef UnorderedHashMap<LLVMPoolMapKeyEqualsTraits> LLVMPoolMap;
-
-  GrowableObjectArray& llvm_constants_;
-  GrowableObjectArray& llvm_functions_;
-  LLVMPoolMap llvm_constant_map_;
-  Smi& llvm_index_;
-
-  // Handles used across functions, where the contained value is used
-  // immediately and does not need to live across calls to other serializer
-  // functions.
-  String& tmp_string_;
-
-  // Handles for use within a single function in the following cases:
-  //
-  // * The function is guaranteed to not be re-entered during execution.
-  // * The contained value is not live across any possible re-entry.
-  //
-  // Generally, the most likely source of possible re-entry is calling
-  // DartValueToSExp with a sub-element of type Object, but any call to a
-  // FlowGraphSerializer method that may eventually enter one of the methods
-  // listed below should be examined with care.
-  TypeArguments& array_type_args_;     // ArrayToSExp
-  Context& closure_context_;           // ClosureToSExp
-  Function& closure_function_;         // ClosureToSExp
-  TypeArguments& closure_type_args_;   // ClosureToSExp
-  Object& code_owner_;                 // CodeToSExp
-  Context& context_parent_;            // ContextToSExp
-  Object& context_elem_;               // ContextToSExp
-  TypeArguments& function_type_args_;  // FunctionToSExp
-  Function& ic_data_target_;           // ICDataToSExp
-  AbstractType& ic_data_type_;         // ICDataToSExp
-  Field& instance_field_;              // InstanceToSExp
-  TypeArguments& instance_type_args_;  // InstanceToSExp
-  Library& serialize_library_;         // SerializeCanonicalName
-  Class& serialize_owner_;             // SerializeCanonicalName
-  Function& serialize_parent_;         // SerializeCanonicalName
-  AbstractType& type_arguments_elem_;  // TypeArgumentsToSExp
-  Class& type_class_;                  // AbstractTypeToSExp
-  FunctionType& type_signature_;       // AbstractTypeToSExp
-  AbstractType& type_ref_type_;        // AbstractTypeToSExp
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_SERIALIZER_H_
diff --git a/runtime/vm/compiler/backend/range_analysis.h b/runtime/vm/compiler/backend/range_analysis.h
index 7491def..ab21d74 100644
--- a/runtime/vm/compiler/backend/range_analysis.h
+++ b/runtime/vm/compiler/backend/range_analysis.h
@@ -14,9 +14,6 @@
 
 namespace dart {
 
-class SExpression;
-class FlowGraphSerializer;
-
 class RangeBoundary : public ValueObject {
  public:
 #define FOR_EACH_RANGE_BOUNDARY_KIND(V)                                        \
@@ -246,7 +243,6 @@
 
   void PrintTo(BaseTextBuffer* f) const;
   const char* ToCString() const;
-  SExpression* ToSExpression(FlowGraphSerializer* s);
 
   static RangeBoundary Add(const RangeBoundary& a,
                            const RangeBoundary& b,
@@ -347,7 +343,6 @@
 
   void PrintTo(BaseTextBuffer* f) const;
   static const char* ToCString(const Range* range);
-  SExpression* ToSExpression(FlowGraphSerializer* s);
 
   bool Equals(const Range* other) {
     ASSERT(min_.IsUnknown() == max_.IsUnknown());
diff --git a/runtime/vm/compiler/backend/sexpression.cc b/runtime/vm/compiler/backend/sexpression.cc
deleted file mode 100644
index 7307ef3..0000000
--- a/runtime/vm/compiler/backend/sexpression.cc
+++ /dev/null
@@ -1,686 +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 "vm/compiler/backend/sexpression.h"
-
-#include <ctype.h>
-#include "platform/utils.h"
-#include "vm/double_conversion.h"
-#include "vm/zone_text_buffer.h"
-
-namespace dart {
-
-SExpression* SExpression::FromCString(Zone* zone, const char* str) {
-  SExpParser parser(zone, str);
-  auto sexp = parser.Parse();
-  if (sexp == nullptr) parser.ReportError();
-  return sexp;
-}
-
-const char* SExpression::ToCString(Zone* zone) const {
-  ZoneTextBuffer buf(zone, 1 * KB);
-  SerializeToLine(&buf);
-  return buf.buffer();
-}
-
-bool SExpBool::Equals(SExpression* sexp) const {
-  if (auto const b = sexp->AsBool()) return b->Equals(value());
-  return false;
-}
-
-bool SExpBool::Equals(bool val) const {
-  return value() == val;
-}
-
-void SExpBool::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->AddString(value() ? SExpParser::kBoolTrueSymbol
-                            : SExpParser::kBoolFalseSymbol);
-}
-
-bool SExpDouble::Equals(SExpression* sexp) const {
-  if (auto const d = sexp->AsDouble()) return d->Equals(value());
-  return false;
-}
-
-bool SExpDouble::Equals(double val) const {
-  return value() == val;
-}
-
-void SExpDouble::SerializeToLine(BaseTextBuffer* buffer) const {
-  // Use existing Dart serialization for Doubles.
-  const intptr_t kBufSize = 128;
-  char strbuf[kBufSize];
-  DoubleToCString(value(), strbuf, kBufSize);
-  buffer->Printf("%s", strbuf);
-}
-
-bool SExpInteger::Equals(SExpression* sexp) const {
-  if (auto const i = sexp->AsInteger()) return i->Equals(value());
-  return false;
-}
-
-bool SExpInteger::Equals(int64_t val) const {
-  return value() == val;
-}
-
-void SExpInteger::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->Printf("%" Pd64 "", value());
-}
-
-bool SExpString::Equals(SExpression* sexp) const {
-  if (auto const s = sexp->AsString()) return s->Equals(value());
-  return false;
-}
-
-bool SExpString::Equals(const char* str) const {
-  return strcmp(value(), str) == 0;
-}
-
-void SExpString::SerializeToLine(BaseTextBuffer* buffer) const {
-  TextBuffer buf(80);
-  buf.AddChar('"');
-  buf.AddEscapedString(value());
-  buf.AddChar('"');
-  buffer->AddString(buf.buffer());
-}
-
-bool SExpSymbol::Equals(SExpression* sexp) const {
-  if (auto const s = sexp->AsSymbol()) return s->Equals(value());
-  return false;
-}
-
-bool SExpSymbol::Equals(const char* str) const {
-  return strcmp(value(), str) == 0;
-}
-
-void SExpSymbol::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->AddString(value());
-}
-
-void SExpList::Add(SExpression* sexp) {
-  contents_.Add(sexp);
-}
-
-void SExpList::AddExtra(const char* label, SExpression* value) {
-  ASSERT(!extra_info_.HasKey(label));
-  extra_info_.Insert({label, value});
-}
-
-bool SExpList::Equals(SExpression* sexp) const {
-  if (!sexp->IsList()) return false;
-  auto list = sexp->AsList();
-  if (Length() != list->Length()) return false;
-  if (ExtraLength() != list->ExtraLength()) return false;
-  for (intptr_t i = 0; i < Length(); i++) {
-    if (!At(i)->Equals(list->At(i))) return false;
-  }
-  auto this_it = ExtraIterator();
-  while (auto kv = this_it.Next()) {
-    if (!list->ExtraHasKey(kv->key)) return false;
-    if (!kv->value->Equals(list->ExtraLookupValue(kv->key))) return false;
-  }
-  return true;
-}
-
-const char* const SExpList::kElemIndent = " ";
-const char* const SExpList::kExtraIndent = "  ";
-
-static intptr_t HandleLineBreaking(Zone* zone,
-                                   BaseTextBuffer* buffer,
-                                   SExpression* element,
-                                   BaseTextBuffer* line_buffer,
-                                   const char* sub_indent,
-                                   intptr_t width,
-                                   bool leading_space,
-                                   intptr_t remaining) {
-  element->SerializeToLine(line_buffer);
-  const intptr_t single_line_width = line_buffer->length();
-  const intptr_t leading_length = leading_space ? 1 : 0;
-
-  if ((leading_length + single_line_width) < remaining) {
-    if (leading_space) buffer->AddChar(' ');
-    buffer->AddString(line_buffer->buffer());
-    line_buffer->Clear();
-    return remaining - (leading_length + single_line_width);
-  }
-  const intptr_t old_length = buffer->length();
-  buffer->Printf("\n%s", sub_indent);
-  const intptr_t line_used = buffer->length() - old_length + 1;
-  remaining = width - line_used;
-  if ((single_line_width < remaining) || element->IsAtom()) {
-    buffer->AddString(line_buffer->buffer());
-    line_buffer->Clear();
-    return remaining - single_line_width;
-  }
-  line_buffer->Clear();
-  element->SerializeTo(zone, buffer, sub_indent, width);
-  return 0;
-}
-
-// Assumes that we are starting on a line after [indent] amount of space.
-void SExpList::SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width) const {
-  TextBuffer single_line(width);
-  const char* sub_indent = OS::SCreate(zone, "%s%s", indent, kElemIndent);
-
-  buffer->AddChar('(');
-  intptr_t remaining = width - strlen(indent) - 1;
-  for (intptr_t i = 0; i < contents_.length(); i++) {
-    remaining = HandleLineBreaking(zone, buffer, contents_.At(i), &single_line,
-                                   sub_indent, width, i != 0, remaining);
-  }
-
-  if (!extra_info_.IsEmpty()) {
-    SerializeExtraInfoToLine(&single_line);
-    if (single_line.length() < remaining - 1) {
-      buffer->Printf(" %s", single_line.buffer());
-    } else {
-      const intptr_t old_length = buffer->length();
-      buffer->Printf("\n%s", sub_indent);
-      const intptr_t line_used = buffer->length() - old_length + 1;
-      remaining = width - line_used;
-      if (single_line.length() < remaining) {
-        buffer->AddString(single_line.buffer());
-      } else {
-        SerializeExtraInfoTo(zone, buffer, sub_indent, width);
-      }
-    }
-  }
-  buffer->AddChar(')');
-}
-
-void SExpList::SerializeToLine(BaseTextBuffer* buffer) const {
-  buffer->AddChar('(');
-  for (intptr_t i = 0; i < contents_.length(); i++) {
-    if (i != 0) buffer->AddChar(' ');
-    contents_.At(i)->SerializeToLine(buffer);
-  }
-  if (!extra_info_.IsEmpty()) {
-    buffer->AddChar(' ');
-    SerializeExtraInfoToLine(buffer);
-  }
-  buffer->AddChar(')');
-}
-
-void SExpList::SerializeExtraInfoTo(Zone* zone,
-                                    BaseTextBuffer* buffer,
-                                    const char* indent,
-                                    int width) const {
-  const char* sub_indent = OS::SCreate(zone, "%s%s", indent, kExtraIndent);
-  TextBuffer single_line(width);
-
-  buffer->AddChar('{');
-  auto it = ExtraIterator();
-  while (auto kv = it.Next()) {
-    const intptr_t old_length = buffer->length();
-    buffer->Printf("\n%s%s", sub_indent, kv->key);
-    const intptr_t remaining = width - (buffer->length() - old_length + 1);
-    HandleLineBreaking(zone, buffer, kv->value, &single_line, sub_indent, width,
-                       /*leading_space=*/true, remaining);
-    buffer->AddChar(',');
-  }
-  buffer->Printf("\n%s}", indent);
-}
-
-void SExpList::SerializeExtraInfoToLine(BaseTextBuffer* buffer) const {
-  buffer->AddString("{");
-  auto it = ExtraIterator();
-  while (auto kv = it.Next()) {
-    buffer->Printf(" %s ", kv->key);
-    kv->value->SerializeToLine(buffer);
-    buffer->AddChar(',');
-  }
-  buffer->AddString(" }");
-}
-
-const char* const SExpParser::kBoolTrueSymbol = "true";
-const char* const SExpParser::kBoolFalseSymbol = "false";
-char const SExpParser::kDoubleExponentChar =
-    DoubleToStringConstants::kExponentChar;
-const char* const SExpParser::kDoubleInfinitySymbol =
-    DoubleToStringConstants::kInfinitySymbol;
-const char* const SExpParser::kDoubleNaNSymbol =
-    DoubleToStringConstants::kNaNSymbol;
-
-const char* const SExpParser::ErrorStrings::kOpenString =
-    "unterminated quoted string starting at position %" Pd "";
-const char* const SExpParser::ErrorStrings::kBadUnicodeEscape =
-    "malformed Unicode escape";
-const char* const SExpParser::ErrorStrings::kOpenSExpList =
-    "unterminated S-expression list starting at position %" Pd "";
-const char* const SExpParser::ErrorStrings::kOpenMap =
-    "unterminated extra info map starting at position %" Pd "";
-const char* const SExpParser::ErrorStrings::kNestedMap =
-    "extra info map start when already within extra info map";
-const char* const SExpParser::ErrorStrings::kMapOutsideList =
-    "extra info map start not within S-expression list";
-const char* const SExpParser::ErrorStrings::kNonSymbolLabel =
-    "non-symbol in label position for extra info map";
-const char* const SExpParser::ErrorStrings::kNoMapLabel =
-    "no extra info map label provided";
-const char* const SExpParser::ErrorStrings::kRepeatedMapLabel =
-    "extra info map label %s provided more than once";
-const char* const SExpParser::ErrorStrings::kNoMapValue =
-    "no value provided for extra info map label %s";
-const char* const SExpParser::ErrorStrings::kExtraMapValue =
-    "extra value following label %s in extra info map";
-const char* const SExpParser::ErrorStrings::kUnexpectedComma =
-    "comma found outside extra info map";
-const char* const SExpParser::ErrorStrings::kUnexpectedRightParen =
-    "unexpected closing parenthesis";
-const char* const SExpParser::ErrorStrings::kUnexpectedRightCurly =
-    "unexpected closing curly brace";
-
-#define PARSE_ERROR(x, ...)                                                    \
-  StoreError(x, __VA_ARGS__);                                                  \
-  return nullptr
-
-SExpression* SExpParser::Parse() {
-  Reset();
-  while (auto token = GetNextToken()) {
-    const intptr_t start_pos = token->cstr() - buffer_;
-    switch (token->type()) {
-      case kLeftParen: {
-        if (in_extra_) {
-          if (cur_label_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kNonSymbolLabel);
-          } else if (cur_value_ != nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kExtraMapValue, cur_label_);
-          }
-        }
-        auto sexp = new (zone_) SExpList(zone_, start_pos);
-        list_stack_.Add(sexp);
-        in_extra_stack_.Add(in_extra_);
-        extra_start_stack_.Add(extra_start_);
-        cur_label_stack_.Add(cur_label_);
-        in_extra_ = false;
-        extra_start_ = -1;
-        cur_label_ = nullptr;
-        break;
-      }
-      case kRightParen: {
-        if (list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kUnexpectedRightParen);
-        }
-        if (in_extra_) {
-          PARSE_ERROR(start_pos, ErrorStrings::kOpenMap, extra_start_);
-        }
-        auto sexp = list_stack_.RemoveLast();
-        in_extra_ = in_extra_stack_.RemoveLast();
-        extra_start_ = extra_start_stack_.RemoveLast();
-        cur_label_ = cur_label_stack_.RemoveLast();
-        if (list_stack_.is_empty()) return sexp;
-        if (in_extra_) {
-          if (cur_label_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kOpenMap, extra_start_);
-          }
-          cur_value_ = sexp;
-        } else {
-          list_stack_.Last()->Add(sexp);
-        }
-        break;
-      }
-      case kLeftCurly:
-        if (in_extra_) {
-          PARSE_ERROR(start_pos, ErrorStrings::kNestedMap);
-        }
-        if (list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kMapOutsideList);
-        }
-        extra_start_ = start_pos;
-        in_extra_ = true;
-        break;
-      case kRightCurly:
-        if (!in_extra_ || list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kUnexpectedRightCurly);
-        }
-        if (cur_label_ != nullptr) {
-          if (cur_value_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kNoMapValue, cur_label_);
-          }
-          list_stack_.Last()->AddExtra(cur_label_, cur_value_);
-          cur_label_ = nullptr;
-          cur_value_ = nullptr;
-        }
-        in_extra_ = false;
-        extra_start_ = -1;
-        break;
-      case kComma: {
-        if (!in_extra_ || list_stack_.is_empty()) {
-          PARSE_ERROR(start_pos, ErrorStrings::kUnexpectedComma);
-        }
-        if (cur_label_ == nullptr) {
-          PARSE_ERROR(start_pos, ErrorStrings::kNoMapLabel);
-        } else if (cur_value_ == nullptr) {
-          PARSE_ERROR(start_pos, ErrorStrings::kNoMapValue, cur_label_);
-        }
-        list_stack_.Last()->AddExtra(cur_label_, cur_value_);
-        cur_label_ = nullptr;
-        cur_value_ = nullptr;
-        break;
-      }
-      case kSymbol: {
-        auto sexp = TokenToSExpression(token);
-        ASSERT(sexp->IsSymbol());
-        if (in_extra_) {
-          if (cur_value_ != nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kExtraMapValue, cur_label_);
-          }
-          if (cur_label_ == nullptr) {
-            const char* const label = sexp->AsSymbol()->value();
-            if (list_stack_.Last()->ExtraHasKey(label)) {
-              PARSE_ERROR(start_pos, ErrorStrings::kRepeatedMapLabel, label);
-            }
-            cur_label_ = sexp->AsSymbol()->value();
-          } else {
-            cur_value_ = sexp;
-          }
-        } else if (!list_stack_.is_empty()) {
-          list_stack_.Last()->Add(sexp);
-        } else {
-          return sexp;
-        }
-        break;
-      }
-      case kBoolean:
-      case kInteger:
-      case kDouble:
-      case kQuotedString: {
-        auto sexp = TokenToSExpression(token);
-        // TokenToSExpression has already set the error info, so just return.
-        if (sexp == nullptr) return nullptr;
-        if (in_extra_) {
-          if (cur_label_ == nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kNonSymbolLabel);
-          } else if (cur_value_ != nullptr) {
-            PARSE_ERROR(start_pos, ErrorStrings::kExtraMapValue, cur_label_);
-          }
-          cur_value_ = sexp;
-        } else if (!list_stack_.is_empty()) {
-          list_stack_.Last()->Add(sexp);
-        } else {
-          return sexp;
-        }
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
-  }
-  if (in_extra_) {
-    PARSE_ERROR(buffer_size_, ErrorStrings::kOpenMap, extra_start_);
-  } else if (!list_stack_.is_empty()) {
-    const intptr_t list_start = list_stack_.Last()->start();
-    PARSE_ERROR(buffer_size_, ErrorStrings::kOpenSExpList, list_start);
-  }
-  UNREACHABLE();
-}
-
-SExpression* SExpParser::TokenToSExpression(Token* token) {
-  const intptr_t start_pos = token->cstr() - buffer_;
-  switch (token->type()) {
-    case kSymbol:
-      return new (zone_) SExpSymbol(token->ToCString(zone_), start_pos);
-    case kInteger: {
-      const char* cstr = token->ToCString(zone_);
-      int64_t val;
-      if (!OS::StringToInt64(cstr, &val)) return nullptr;
-      return new (zone_) SExpInteger(val, start_pos);
-    }
-    case kBoolean: {
-      const bool is_true =
-          strncmp(token->cstr(), kBoolTrueSymbol, token->length()) == 0;
-      ASSERT(is_true ||
-             strncmp(token->cstr(), kBoolFalseSymbol, token->length()) == 0);
-      return new (zone_) SExpBool(is_true, start_pos);
-    }
-    case kDouble: {
-      double val;
-      if (!CStringToDouble(token->cstr(), token->length(), &val)) {
-        return nullptr;
-      }
-      return new (zone_) SExpDouble(val, start_pos);
-    }
-    case kQuotedString: {
-      const char* const cstr = token->cstr();
-      char* const buf = zone_->Alloc<char>(token->length());
-      // Skip the initial quote
-      ASSERT(cstr[0] == '"');
-      intptr_t old_pos = 1;
-      intptr_t new_pos = 0;
-      // The string _should_ end in a quote.
-      while (old_pos < token->length() - 1) {
-        if (cstr[old_pos] == '"') break;
-        if (cstr[old_pos] != '\\') {
-          buf[new_pos++] = cstr[old_pos++];
-          continue;
-        }
-        old_pos++;
-        if (old_pos >= token->length()) {
-          PARSE_ERROR(start_pos + old_pos, ErrorStrings::kOpenString,
-                      start_pos);
-        }
-        const intptr_t escape_pos = start_pos + old_pos - 1;
-        switch (cstr[old_pos]) {
-          case 'b':
-            buf[new_pos] = '\b';
-            break;
-          case 'f':
-            buf[new_pos] = '\f';
-            break;
-          case 'n':
-            buf[new_pos] = '\n';
-            break;
-          case 'r':
-            buf[new_pos] = '\r';
-            break;
-          case 't':
-            buf[new_pos] = '\t';
-            break;
-          case 'u': {
-            const intptr_t first = old_pos + 1;
-            const intptr_t last = old_pos + 4;
-            if (last >= token->length()) {
-              PARSE_ERROR(escape_pos, ErrorStrings::kBadUnicodeEscape);
-            }
-            intptr_t val = 0;
-            for (const char *cursor = cstr + first, *end = cstr + last + 1;
-                 cursor < end; cursor++) {
-              val *= 16;
-              if (!Utils::IsHexDigit(*cursor)) {
-                PARSE_ERROR(escape_pos, ErrorStrings::kBadUnicodeEscape);
-              }
-              val += Utils::HexDigitToInt(*cursor);
-            }
-            // Currently, just handle encoded ASCII instead of doing
-            // handling Unicode characters.
-            // (TextBuffer::AddEscapedString uses this for characters < 0x20.)
-            ASSERT(val <= 0x7F);
-            old_pos = last;
-            buf[new_pos] = val;
-            break;
-          }
-          default:
-            // Identity escapes.
-            buf[new_pos] = cstr[old_pos];
-            break;
-        }
-        old_pos++;
-        new_pos++;
-      }
-      if (cstr[old_pos] != '"') {
-        PARSE_ERROR(start_pos + token->length(), ErrorStrings::kOpenString,
-                    start_pos);
-      }
-      buf[new_pos] = '\0';
-      return new (zone_) SExpString(buf, start_pos);
-    }
-    default:
-      UNREACHABLE();
-  }
-}
-
-#undef PARSE_ERROR
-
-SExpParser::Token* SExpParser::GetNextToken() {
-  intptr_t start_pos = cur_pos_;
-  while (start_pos < buffer_size_) {
-    if (isspace(buffer_[start_pos]) == 0) break;
-    start_pos++;
-  }
-  if (start_pos >= buffer_size_) return nullptr;
-  const char* start = buffer_ + start_pos;
-  switch (*start) {
-    case '(':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kLeftParen, start, 1);
-    case ')':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kRightParen, start, 1);
-    case ',':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kComma, start, 1);
-    case '{':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kLeftCurly, start, 1);
-    case '}':
-      cur_pos_ = start_pos + 1;
-      return new (zone_) Token(kRightCurly, start, 1);
-    case '"': {
-      intptr_t len = 1;
-      while (start_pos + len < buffer_size_) {
-        char curr = start[len];
-        len++;  // Length should include the quote, if any.
-        if (curr == '\\') {
-          // Skip past next character (if any), since it cannot
-          // end the quoted string due to being escaped.
-          if (start_pos + len >= buffer_size_) break;
-          len++;
-          continue;
-        }
-        if (curr == '"') break;
-      }
-      cur_pos_ = start_pos + len;
-      return new (zone_) Token(kQuotedString, start, len);
-    }
-    default:
-      break;
-  }
-  intptr_t len = 0;
-  // Start number detection after possible negation sign.
-  if (start[len] == '-') {
-    len++;
-    if ((start_pos + len) >= buffer_size_) {
-      cur_pos_ = start_pos + len;
-      return new (zone_) Token(kSymbol, start, len);
-    }
-  }
-  // Keep the currently detected token type. Start off by assuming we have
-  // an integer, then fall back to doubles if we see parts appropriate for
-  // those but not integers, and fall back to symbols otherwise.
-  TokenType type = kInteger;
-  bool saw_exponent = false;
-  while ((start_pos + len) < buffer_size_) {
-    // Both numbers and symbols cannot contain these values, so we are at the
-    // end of whichever one we're in.
-    if (!IsSymbolContinue(start[len])) break;
-    if (type == kInteger && start[len] == '.') {
-      type = kDouble;
-      len++;
-      continue;
-    }
-    if (type != kSymbol && !saw_exponent && start[len] == kDoubleExponentChar) {
-      saw_exponent = true;
-      type = kDouble;
-      len++;
-      // Skip past negation in exponent if any.
-      if ((start_pos + len) < buffer_size_ && start[len] == '-') len++;
-      continue;
-    }
-    // If we find a character that can't appear in a number, then fall back
-    // to symbol-ness.
-    if (isdigit(start[len]) == 0) type = kSymbol;
-    len++;
-  }
-  cur_pos_ = start_pos + len;
-  // Skip special symbol detection if we don't have a symbol.
-  if (type != kSymbol) return new (zone_) Token(type, start, len);
-  // Check for special symbols used for booleans and certain Double values.
-  switch (len) {
-    case 3:
-      if (strncmp(start, kDoubleNaNSymbol, len) == 0) type = kDouble;
-      break;
-    case 4:
-      if (strncmp(start, kBoolTrueSymbol, len) == 0) type = kBoolean;
-      break;
-    case 5:
-      if (strncmp(start, kBoolFalseSymbol, len) == 0) type = kBoolean;
-      break;
-    case 8:
-      if (strncmp(start, kDoubleInfinitySymbol, len) == 0) type = kDouble;
-      break;
-    case 9:
-      if (start[0] == '-' &&
-          strncmp(start + 1, kDoubleInfinitySymbol, len - 1) == 0) {
-        type = kDouble;
-      }
-      break;
-    default:
-      break;
-  }
-  return new (zone_) Token(type, start, len);
-}
-
-bool SExpParser::IsSymbolContinue(char c) {
-  return (isspace(c) == 0) && c != '(' && c != ')' && c != ',' && c != '{' &&
-         c != '}' && c != '"';
-}
-
-const char* const SExpParser::Token::TokenNames[kMaxTokens] = {
-#define S_EXP_TOKEN_NAME_STRING(name) #name,
-    S_EXP_TOKEN_LIST(S_EXP_TOKEN_NAME_STRING)
-#undef S_EXP_TOKEN_NAME_STRING
-};
-
-const char* SExpParser::Token::ToCString(Zone* zone) {
-  char* const buffer = zone->Alloc<char>(len_ + 1);
-  strncpy(buffer, cstr_, len_);
-  buffer[len_] = '\0';
-  return buffer;
-}
-
-void SExpParser::Reset() {
-  cur_pos_ = 0;
-  in_extra_ = false;
-  extra_start_ = -1;
-  cur_label_ = nullptr;
-  cur_value_ = nullptr;
-  list_stack_.Clear();
-  in_extra_stack_.Clear();
-  extra_start_stack_.Clear();
-  cur_label_stack_.Clear();
-  error_pos_ = -1;
-  error_message_ = nullptr;
-}
-
-void SExpParser::StoreError(intptr_t pos, const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  const char* const message = OS::VSCreate(zone_, format, args);
-  va_end(args);
-  error_pos_ = pos;
-  error_message_ = message;
-}
-
-void SExpParser::ReportError() const {
-  ASSERT(error_message_ != nullptr);
-  ASSERT(error_pos_ >= 0);
-  OS::PrintErr("Unable to parse s-expression: %s\n", buffer_);
-  OS::PrintErr("Error at character %" Pd ": %s\n", error_pos_, error_message_);
-  OS::Abort();
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/backend/sexpression.h b/runtime/vm/compiler/backend/sexpression.h
deleted file mode 100644
index 6bdc36e..0000000
--- a/runtime/vm/compiler/backend/sexpression.h
+++ /dev/null
@@ -1,305 +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_VM_COMPILER_BACKEND_SEXPRESSION_H_
-#define RUNTIME_VM_COMPILER_BACKEND_SEXPRESSION_H_
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-#error "AOT runtime should not use compiler sources (including header files)"
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-#include "platform/text_buffer.h"
-
-#include "vm/allocation.h"
-#include "vm/growable_array.h"
-#include "vm/hash_map.h"
-#include "vm/zone.h"
-
-namespace dart {
-
-#define FOR_EACH_S_EXPRESSION_ATOM(M)                                          \
-  M(Bool, bool)                                                                \
-  M(Double, double)                                                            \
-  M(Integer, int64_t)                                                          \
-  M(String, const char*)                                                       \
-  M(Symbol, const char*)
-
-#define FOR_EACH_S_EXPRESSION(M)                                               \
-  FOR_EACH_S_EXPRESSION_ATOM(M)                                                \
-  M(List, _)
-
-#define FOR_EACH_ABSTRACT_S_EXPRESSION(M) M(Atom, _)
-
-#define FORWARD_DECLARATION(name, value_type) class SExp##name;
-FOR_EACH_S_EXPRESSION(FORWARD_DECLARATION)
-FOR_EACH_ABSTRACT_S_EXPRESSION(FORWARD_DECLARATION)
-#undef FORWARD_DECLARATION
-
-// Abstract base class for S-expressions used as an intermediate form for the
-// IL serializer. These aren't true (LISP-like) S-expressions, as the atoms
-// are more restricted and the lists have extra information. Here is an
-// illustrative BNF-style grammar of the current serialized form of
-// S-expressions that includes non-whitespace literal tokens:
-//
-// <s-exp>      ::= <atom> | <list>
-// <atom>       ::= <bool> | <integer> | <string> | <symbol>
-// <list>       ::= '(' <s-exp>* <extra-info>? ')'
-// <extra-info> ::= '{' <extra-elem>* '}'
-// <extra-elem> ::= <symbol> <s-exp> ','
-//
-// Here, <string>s are double-quoted strings with backslash escaping and
-// <symbol>s are sequences of consecutive non-whitespace characters that do not
-// include commas (,), parentheses (()), curly braces ({}), or the double-quote
-// character (").
-//
-// In addition, the <extra-info> is considered a map from symbol labels to
-// S-expression values, and as such each symbol used as a key in an <extra-info>
-// block should only appear once as a key within that block.
-class SExpression : public ZoneAllocated {
- public:
-  explicit SExpression(intptr_t start = kInvalidPos) : start_(start) {}
-  virtual ~SExpression() {}
-
-  static intptr_t const kInvalidPos = -1;
-
-  static SExpression* FromCString(Zone* zone, const char* cstr);
-  const char* ToCString(Zone* zone) const;
-  intptr_t start() const { return start_; }
-
-#define S_EXPRESSION_TYPE_CHECK(name, value_type)                              \
-  bool Is##name() const { return (As##name() != nullptr); }                    \
-  SExp##name* As##name() {                                                     \
-    auto const const_this = const_cast<const SExpression*>(this);              \
-    return const_cast<SExp##name*>(const_this->As##name());                    \
-  }                                                                            \
-  virtual const SExp##name* As##name() const { return nullptr; }
-
-  FOR_EACH_S_EXPRESSION(S_EXPRESSION_TYPE_CHECK)
-  FOR_EACH_ABSTRACT_S_EXPRESSION(S_EXPRESSION_TYPE_CHECK)
-
-  virtual const char* DebugName() const = 0;
-  virtual bool Equals(SExpression* sexp) const = 0;
-  virtual void SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width = 80) const = 0;
-  virtual void SerializeToLine(BaseTextBuffer* buffer) const = 0;
-
- private:
-  // Starting character position of the s-expression in the original
-  // serialization, if it was deserialized.
-  intptr_t const start_;
-  DISALLOW_COPY_AND_ASSIGN(SExpression);
-};
-
-class SExpAtom : public SExpression {
- public:
-  explicit SExpAtom(intptr_t start = kInvalidPos) : SExpression(start) {}
-
-  virtual const SExpAtom* AsAtom() const { return this; }
-  // No atoms have sub-elements, so they always print to a single line.
-  virtual void SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width = 80) const {
-    SerializeToLine(buffer);
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SExpAtom);
-};
-
-#define DEFINE_S_EXPRESSION_TYPE_CHECK(name)                                   \
-  virtual const SExp##name* As##name() const { return this; }                  \
-  virtual const char* DebugName() const { return #name; }
-
-// The various concrete S-expression atom classes are thin wrappers around
-// their contained value that includes serialization and type check methods.
-#define DEFINE_S_EXPRESSION_ATOM_CLASS(name, value_type)                       \
-  class SExp##name : public SExpAtom {                                         \
-   public:                                                                     \
-    explicit SExp##name(value_type val, intptr_t start = kInvalidPos)          \
-        : SExpAtom(start), val_(val) {}                                        \
-    value_type value() const { return val_; }                                  \
-    virtual bool Equals(SExpression* sexp) const;                              \
-    bool Equals(value_type val) const;                                         \
-    virtual void SerializeToLine(BaseTextBuffer* buffer) const;                \
-    DEFINE_S_EXPRESSION_TYPE_CHECK(name)                                       \
-   private:                                                                    \
-    value_type const val_;                                                     \
-    DISALLOW_COPY_AND_ASSIGN(SExp##name);                                      \
-  };
-
-FOR_EACH_S_EXPRESSION_ATOM(DEFINE_S_EXPRESSION_ATOM_CLASS)
-
-// A list of S-expressions. Unlike normal S-expressions, an S-expression list
-// also contains a hash map kept separate from the elements, which we use for
-// extra non-argument information for IL instructions.
-class SExpList : public SExpression {
- public:
-  explicit SExpList(Zone* zone, intptr_t start = kInvalidPos)
-      : SExpression(start), contents_(zone, 2), extra_info_(zone) {}
-
-  using ExtraInfoHashMap = CStringMap<SExpression*>;
-
-  void Add(SExpression* sexp);
-  void AddExtra(const char* label, SExpression* value);
-
-  SExpression* At(intptr_t i) const { return contents_.At(i); }
-  intptr_t Length() const { return contents_.length(); }
-
-  intptr_t ExtraLength() const { return extra_info_.Length(); }
-  ExtraInfoHashMap::Iterator ExtraIterator() const {
-    return extra_info_.GetIterator();
-  }
-  bool ExtraHasKey(const char* cstr) const { return extra_info_.HasKey(cstr); }
-  SExpression* ExtraLookupValue(const char* cstr) const {
-    return extra_info_.LookupValue(cstr);
-  }
-
-  // Shortcut for retrieving the tag from a tagged list (list that contains an
-  // initial symbol). Returns nullptr if the list is not a tagged list.
-  SExpSymbol* Tag() const {
-    if (Length() == 0 || !At(0)->IsSymbol()) return nullptr;
-    return At(0)->AsSymbol();
-  }
-
-  DEFINE_S_EXPRESSION_TYPE_CHECK(List)
-  virtual bool Equals(SExpression* sexp) const;
-  virtual void SerializeTo(Zone* zone,
-                           BaseTextBuffer* buffer,
-                           const char* indent,
-                           intptr_t width = 80) const;
-  virtual void SerializeToLine(BaseTextBuffer* buffer) const;
-
- private:
-  static const char* const kElemIndent;
-  static const char* const kExtraIndent;
-
-  void SerializeExtraInfoTo(Zone* zone,
-                            BaseTextBuffer* buffer,
-                            const char* indent,
-                            int width) const;
-  void SerializeExtraInfoToLine(BaseTextBuffer* buffer) const;
-
-  ZoneGrowableArray<SExpression*> contents_;
-  ExtraInfoHashMap extra_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(SExpList);
-};
-
-class SExpParser : public ValueObject {
- public:
-  SExpParser(Zone* zone, const char* cstr)
-      : SExpParser(zone, cstr, strlen(cstr)) {}
-  SExpParser(Zone* zone, const char* cstr, intptr_t len)
-      : zone_(zone),
-        buffer_(ASSERT_NOTNULL(cstr)),
-        buffer_size_(strnlen(cstr, len)),
-        cur_label_(nullptr),
-        cur_value_(nullptr),
-        list_stack_(zone, 2),
-        in_extra_stack_(zone, 2),
-        extra_start_stack_(zone, 2),
-        cur_label_stack_(zone, 2),
-        error_message_(nullptr) {}
-
-  // Constants used in serializing and deserializing S-expressions.
-  static const char* const kBoolTrueSymbol;
-  static const char* const kBoolFalseSymbol;
-  static char const kDoubleExponentChar;
-  static const char* const kDoubleInfinitySymbol;
-  static const char* const kDoubleNaNSymbol;
-
-  struct ErrorStrings : AllStatic {
-    static const char* const kOpenString;
-    static const char* const kBadUnicodeEscape;
-    static const char* const kOpenSExpList;
-    static const char* const kOpenMap;
-    static const char* const kNestedMap;
-    static const char* const kMapOutsideList;
-    static const char* const kNonSymbolLabel;
-    static const char* const kNoMapLabel;
-    static const char* const kRepeatedMapLabel;
-    static const char* const kNoMapValue;
-    static const char* const kExtraMapValue;
-    static const char* const kUnexpectedComma;
-    static const char* const kUnexpectedRightParen;
-    static const char* const kUnexpectedRightCurly;
-  };
-
-  intptr_t error_pos() const { return error_pos_; }
-  const char* error_message() const { return error_message_; }
-
-  const char* Input() const { return buffer_; }
-  SExpression* Parse();
-  DART_NORETURN void ReportError() const;
-
- private:
-#define S_EXP_TOKEN_LIST(M)                                                    \
-  M(LeftParen)                                                                 \
-  M(RightParen)                                                                \
-  M(Comma)                                                                     \
-  M(LeftCurly)                                                                 \
-  M(RightCurly)                                                                \
-  M(QuotedString)                                                              \
-  M(Integer)                                                                   \
-  M(Double)                                                                    \
-  M(Boolean)                                                                   \
-  M(Symbol)
-
-  // clang-format off
-#define DEFINE_S_EXP_TOKEN_ENUM_LINE(name) k##name,
-  enum TokenType {
-    S_EXP_TOKEN_LIST(DEFINE_S_EXP_TOKEN_ENUM_LINE)
-    kMaxTokens,
-  };
-#undef DEFINE_S_EXP_TOKEN_ENUM
-  // clang-format on
-
-  class Token : public ZoneAllocated {
-   public:
-    Token(TokenType type, const char* cstr, intptr_t len)
-        : type_(type), cstr_(cstr), len_(len) {}
-
-    TokenType type() const { return type_; }
-    intptr_t length() const { return len_; }
-    const char* cstr() const { return cstr_; }
-    const char* DebugName() const { return TokenNames[type()]; }
-    const char* ToCString(Zone* zone);
-
-   private:
-    static const char* const TokenNames[kMaxTokens];
-
-    TokenType const type_;
-    const char* const cstr_;
-    intptr_t const len_;
-  };
-
-  SExpression* TokenToSExpression(Token* token);
-  Token* GetNextToken();
-  void Reset();
-  void StoreError(intptr_t pos, const char* format, ...) PRINTF_ATTRIBUTE(3, 4);
-
-  static bool IsSymbolContinue(char c);
-
-  Zone* const zone_;
-  const char* const buffer_;
-  intptr_t const buffer_size_;
-  intptr_t cur_pos_ = 0;
-  bool in_extra_ = false;
-  intptr_t extra_start_ = -1;
-  const char* cur_label_;
-  SExpression* cur_value_;
-  ZoneGrowableArray<SExpList*> list_stack_;
-  ZoneGrowableArray<bool> in_extra_stack_;
-  ZoneGrowableArray<intptr_t> extra_start_stack_;
-  ZoneGrowableArray<const char*> cur_label_stack_;
-  intptr_t error_pos_ = -1;
-  const char* error_message_;
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_COMPILER_BACKEND_SEXPRESSION_H_
diff --git a/runtime/vm/compiler/backend/sexpression_test.cc b/runtime/vm/compiler/backend/sexpression_test.cc
deleted file mode 100644
index 8c0edac..0000000
--- a/runtime/vm/compiler/backend/sexpression_test.cc
+++ /dev/null
@@ -1,355 +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 "vm/compiler/backend/sexpression.h"
-
-#include <cmath>
-#include "platform/assert.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-#define EXPECT_SEXP_PARSE_ERROR(sexp, parser, pos, message)                    \
-  do {                                                                         \
-    if (sexp != nullptr) {                                                     \
-      dart::Expect(__FILE__, __LINE__)                                         \
-          .Fail("parse unexpectedly succeeded for \"%s\"", parser.Input());    \
-    }                                                                          \
-    EXPECT_EQ(pos, parser.error_pos());                                        \
-    EXPECT_STREQ(message, parser.error_message());                             \
-  } while (false);
-
-#define EXPECT_SEXP_PARSE_SUCCESS(sexp, parser)                                \
-  do {                                                                         \
-    if (sexp == nullptr) {                                                     \
-      EXPECT_NOTNULL(parser.error_message());                                  \
-      dart::Expect(__FILE__, __LINE__)                                         \
-          .Fail("parse unexpectedly failed at \"%s\": %" Pd ": %s",            \
-                parser.Input() + parser.error_pos(), parser.error_pos(),       \
-                parser.error_message());                                       \
-    }                                                                          \
-  } while (false);
-
-static const char* const shared_sexp_cstr =
-    "(def v0 (Constant 3) { type (CompileType 147 { nullable false, name "
-    "\"T{Smi}\"}), })";
-
-static void CheckDeserializedSExpParts(SExpression* sexp) {
-  EXPECT_NOTNULL(sexp);
-  EXPECT(sexp->IsList());
-  SExpList* list = sexp->AsList();
-  EXPECT_EQ(3, list->Length());
-  EXPECT_NOTNULL(list->At(0));
-  EXPECT(list->At(0)->IsSymbol());
-  EXPECT_STREQ("def", list->At(0)->AsSymbol()->value());
-  EXPECT_NOTNULL(list->At(1));
-  EXPECT(list->At(1)->IsSymbol());
-  EXPECT_STREQ("v0", list->At(1)->AsSymbol()->value());
-  EXPECT_NOTNULL(list->At(2));
-  EXPECT(list->At(2)->IsList());
-
-  SExpList* sublist = list->At(2)->AsList();
-  EXPECT_EQ(2, sublist->Length());
-  EXPECT_NOTNULL(sublist->At(0));
-  EXPECT(sublist->At(0)->IsSymbol());
-  EXPECT_STREQ("Constant", sublist->At(0)->AsSymbol()->value());
-  EXPECT_NOTNULL(sublist->At(1));
-  EXPECT(sublist->At(1)->IsInteger());
-  EXPECT_EQ(3, sublist->At(1)->AsInteger()->value());
-  EXPECT_EQ(0, sublist->ExtraLength());
-
-  EXPECT_EQ(1, list->ExtraLength());
-  EXPECT(list->ExtraHasKey("type"));
-  EXPECT(list->ExtraLookupValue("type")->IsList());
-
-  SExpList* ctype = list->ExtraLookupValue("type")->AsList();
-  EXPECT_EQ(2, ctype->Length());
-  EXPECT_NOTNULL(ctype->At(0));
-  EXPECT(ctype->At(0)->IsSymbol());
-  EXPECT_STREQ("CompileType", ctype->At(0)->AsSymbol()->value());
-  EXPECT_NOTNULL(ctype->At(1));
-  EXPECT(ctype->At(1)->IsInteger());
-  EXPECT_EQ(147, ctype->At(1)->AsInteger()->value());
-
-  EXPECT_EQ(2, ctype->ExtraLength());
-  EXPECT(ctype->ExtraHasKey("nullable"));
-  EXPECT(ctype->ExtraLookupValue("nullable")->IsBool());
-  EXPECT(!ctype->ExtraLookupValue("nullable")->AsBool()->value());
-  EXPECT(ctype->ExtraHasKey("name"));
-  EXPECT(ctype->ExtraLookupValue("name")->IsString());
-  EXPECT_STREQ(ctype->ExtraLookupValue("name")->AsString()->value(), "T{Smi}");
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExp) {
-  Zone* const zone = Thread::Current()->zone();
-  SExpression* sexp = SExpression::FromCString(zone, shared_sexp_cstr);
-  CheckDeserializedSExpParts(sexp);
-
-  // Treating escaped backslash appropriately so string is terminated.
-  {
-    const char* const cstr = "(def v0 (Constant 3) { foo \"123\\\\\" })";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    EXPECT_EQ(1, sexp->AsList()->ExtraLength());
-    EXPECT(sexp->AsList()->ExtraHasKey("foo"));
-    auto val = sexp->AsList()->ExtraLookupValue("foo");
-    EXPECT(val->IsString());
-    EXPECT_STREQ("123\\", val->AsString()->value());
-  }
-  // Valid unicode escapes are properly handled.
-  {
-    const char* const cstr =
-        "(def v0 (Constant 3) { foo \"\\u0001\\u0020\\u0054\" })";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    EXPECT_EQ(1, sexp->AsList()->ExtraLength());
-    EXPECT(sexp->AsList()->ExtraHasKey("foo"));
-    auto val = sexp->AsList()->ExtraLookupValue("foo");
-    EXPECT(val->IsString());
-    EXPECT_STREQ("\x01 T", val->AsString()->value());
-  }
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpNumbers) {
-  Zone* const zone = Thread::Current()->zone();
-
-  // Negative integers are handled.
-  {
-    const char* const cstr = "(-4 -50 -1414243)";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    auto list = sexp->AsList();
-    EXPECT_EQ(3, list->Length());
-    EXPECT_EQ(0, list->ExtraLength());
-    for (intptr_t i = 0; i < list->Length(); i++) {
-      EXPECT(list->At(i)->IsInteger());
-      EXPECT(list->At(i)->AsInteger()->value() < 0);
-    }
-  }
-
-  // Various decimal/exponent Doubles are appropriately handled.
-  {
-    const char* const cstr = "(1.05 0.05 .03 1e100 1e-100)";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    auto list = sexp->AsList();
-    EXPECT_EQ(5, list->Length());
-    EXPECT_EQ(0, list->ExtraLength());
-    EXPECT(list->At(0)->IsDouble());
-    double val = list->At(0)->AsDouble()->value();
-    EXPECT(val > 1.04 && val < 1.06);
-    EXPECT(list->At(1)->IsDouble());
-    val = list->At(1)->AsDouble()->value();
-    EXPECT(val > 0.04 && val < 0.06);
-    EXPECT(list->At(2)->IsDouble());
-    val = list->At(2)->AsDouble()->value();
-    EXPECT(val > 0.02 && val < 0.04);
-    EXPECT(list->At(3)->IsDouble());
-    val = list->At(3)->AsDouble()->value();
-    EXPECT(val > 0.9e100 && val < 1.1e100);
-    EXPECT(list->At(4)->IsDouble());
-    val = list->At(4)->AsDouble()->value();
-    EXPECT(val > 0.9e-100 && val < 1.1e-100);
-  }
-
-  // Special Double symbols are appropriately handled.
-  {
-    const char* const cstr = "(NaN Infinity -Infinity)";
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    EXPECT_SEXP_PARSE_SUCCESS(sexp, parser);
-    EXPECT(sexp->IsList());
-    auto list = sexp->AsList();
-    EXPECT_EQ(3, list->Length());
-    EXPECT_EQ(0, list->ExtraLength());
-    EXPECT(list->At(0)->IsDouble());
-    double val = list->At(0)->AsDouble()->value();
-    EXPECT(isnan(val));
-    EXPECT(list->At(1)->IsDouble());
-    val = list->At(1)->AsDouble()->value();
-    EXPECT(val > 0.0);
-    EXPECT(isinf(val));
-    EXPECT(list->At(2)->IsDouble());
-    val = list->At(2)->AsDouble()->value();
-    EXPECT(val < 0.0);
-    EXPECT(isinf(val));
-  }
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpRoundTrip) {
-  Zone* const zone = Thread::Current()->zone();
-  SExpression* sexp = SExpression::FromCString(zone, shared_sexp_cstr);
-
-  TextBuffer buf(100);
-  sexp->SerializeTo(zone, &buf, "", 9999);
-  SExpression* round_trip = SExpression::FromCString(zone, buf.buffer());
-  CheckDeserializedSExpParts(round_trip);
-  EXPECT(sexp->Equals(round_trip));
-
-  char* const old_serialization = buf.Steal();
-  round_trip->SerializeTo(zone, &buf, "", 9999);
-  char* const new_serialization = buf.buffer();
-  EXPECT_STREQ(old_serialization, new_serialization);
-  free(old_serialization);
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpMapsJoined) {
-  Zone* const zone = Thread::Current()->zone();
-  // Same as shared_sexp_cstr except we split the map on the CompileType into
-  // two parts.
-  const char* const cstr =
-      "(def v0 (Constant 3) { type (CompileType { nullable false } 147 { name "
-      "\"T{Smi}\"}), })";
-  SExpression* sexp = SExpression::FromCString(zone, cstr);
-  CheckDeserializedSExpParts(sexp);
-}
-
-ISOLATE_UNIT_TEST_CASE(DeserializeSExpFailures) {
-  Zone* const zone = Thread::Current()->zone();
-  // Unterminated s-exp list
-  {
-    const char* const before_start = "(def v0 ";
-    const char* const after_start = "(Constant 3";
-    const char* const cstr =
-        OS::SCreate(zone, "%s%s", before_start, after_start);
-    const intptr_t start_pos = strlen(before_start);
-    const intptr_t error_pos = strlen(cstr);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenSExpList, start_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Non-symbol label in map pair
-  {
-    const char* const before_error = "(def v0 (Constant 3) { ";
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "3 4 })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        SExpParser::ErrorStrings::kNonSymbolLabel;
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // No values in a map pair
-  {
-    const char* const label = "foo";
-    const char* const before_error =
-        OS::SCreate(zone, "(def v0 (Constant 3) { %s ", label);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "})";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kNoMapValue, label);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Multiple values in a map pair
-  {
-    const char* const label = "foo";
-    const char* const before_error =
-        OS::SCreate(zone, "(def v0 (Constant 3) { %s 4 ", label);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "5, })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kExtraMapValue, label);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unterminated quoted string
-  {
-    const char* const before_string =
-        OS::SCreate(zone, "(def v0 (Constant 3) { foo ");
-    const intptr_t string_pos = strlen(before_string);
-    const char* const error = "\"abc })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_string, error);
-    const intptr_t error_pos = strlen(cstr);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenString, string_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unterminated extra info map
-  {
-    const char* const before_map = "(def v0 (Constant 3) ";
-    const intptr_t map_pos = strlen(before_map);
-    const char* const map_start = "{ foo 3, ";
-    const char* const before_error =
-        OS::SCreate(zone, "%s%s", before_map, map_start);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = ")";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenMap, map_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Repeated extra info map label
-  {
-    const char* const label = "foo";
-    const char* const before_error =
-        OS::SCreate(zone, "(def v0 (Constant 3) { %s 3, ", label);
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = OS::SCreate(zone, "%s 4, })", label);
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kRepeatedMapLabel, label);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unicode escape with non-hex digits.
-  {
-    const char* const before_error = "(def v0 (Constant 3) { foo \"123";
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "\\u12FG\" })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        SExpParser::ErrorStrings::kBadUnicodeEscape;
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Unicode escape with less than four hex digits.
-  {
-    const char* const before_error = "(def v0 (Constant 3) { foo \"123";
-    const intptr_t error_pos = strlen(before_error);
-    const char* const error = "\\u12\" })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_error, error);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        SExpParser::ErrorStrings::kBadUnicodeEscape;
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-  // Treating backslashed quote appropriately to detect unterminated string
-  {
-    const char* const before_string = "(def v0 (Constant 3) { foo ";
-    const intptr_t string_pos = strlen(before_string);
-    const char* const error = "\"123\\\" })";
-    const char* const cstr = OS::SCreate(zone, "%s%s", before_string, error);
-    const intptr_t error_pos = strlen(cstr);
-    SExpParser parser(zone, cstr, strlen(cstr));
-    SExpression* const sexp = parser.Parse();
-    const char* const expected_message =
-        OS::SCreate(zone, SExpParser::ErrorStrings::kOpenString, string_pos);
-    EXPECT_SEXP_PARSE_ERROR(sexp, parser, error_pos, expected_message);
-  }
-}
-
-}  // namespace dart
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index 2a6f91f..1dfcdce 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -8,9 +8,7 @@
 #include "vm/compiler/backend/branch_optimizer.h"
 #include "vm/compiler/backend/constant_propagator.h"
 #include "vm/compiler/backend/flow_graph_checker.h"
-#include "vm/compiler/backend/il_deserializer.h"
 #include "vm/compiler/backend/il_printer.h"
-#include "vm/compiler/backend/il_serializer.h"
 #include "vm/compiler/backend/inliner.h"
 #include "vm/compiler/backend/linearscan.h"
 #include "vm/compiler/backend/range_analysis.h"
@@ -80,14 +78,6 @@
                       "List of comma separated compilation passes flags. "
                       "Use -Name to disable a pass, Name to print IL after it. "
                       "Do --compiler-passes=help for more information.");
-DEFINE_FLAG(bool,
-            early_round_trip_serialization,
-            false,
-            "Perform early round trip serialization compiler pass.");
-DEFINE_FLAG(bool,
-            late_round_trip_serialization,
-            false,
-            "Perform late round trip serialization compiler pass.");
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
 
@@ -286,9 +276,6 @@
     PipelineMode mode,
     CompilerPassState* pass_state) {
   INVOKE_PASS(ComputeSSA);
-  if (FLAG_early_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS(SetOuterInliningId);
   INVOKE_PASS(TypePropagation);
   INVOKE_PASS(Canonicalize);
@@ -309,10 +296,6 @@
   INVOKE_PASS_AOT(DelayAllocations);
   INVOKE_PASS(EliminateWriteBarriers);
   INVOKE_PASS(FinalizeGraph);
-  INVOKE_PASS_AOT(SerializeGraph);
-  if (FLAG_late_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS(AllocateRegisters);
   INVOKE_PASS(ReorderBlocks);
   return pass_state->flow_graph();
@@ -321,9 +304,6 @@
 FlowGraph* CompilerPass::RunPipeline(PipelineMode mode,
                                      CompilerPassState* pass_state) {
   INVOKE_PASS(ComputeSSA);
-  if (FLAG_early_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS_AOT(ApplyClassIds);
   INVOKE_PASS_AOT(TypePropagation);
   INVOKE_PASS(ApplyICData);
@@ -382,12 +362,6 @@
   INVOKE_PASS(AllocationSinking_DetachMaterializations);
   INVOKE_PASS(EliminateWriteBarriers);
   INVOKE_PASS(FinalizeGraph);
-  // If we are serializing the flow graph, do it now before we start
-  // doing register allocation.
-  INVOKE_PASS_AOT(SerializeGraph);
-  if (FLAG_late_round_trip_serialization) {
-    INVOKE_PASS(RoundTripSerialization);
-  }
   INVOKE_PASS(AllocateRegisters);
   INVOKE_PASS(ReorderBlocks);
   return pass_state->flow_graph();
@@ -576,27 +550,4 @@
   flow_graph->RemoveRedefinitions();
 });
 
-#if defined(DART_PRECOMPILER)
-COMPILER_PASS(SerializeGraph, {
-  if (state->precompiler == nullptr) return false;
-  if (auto stream = state->precompiler->il_serialization_stream()) {
-    auto file_write = Dart::file_write_callback();
-    ASSERT(file_write != nullptr);
-
-    const intptr_t kInitialBufferSize = 1 * MB;
-    TextBuffer buffer(kInitialBufferSize);
-    StackZone stack_zone(Thread::Current());
-    FlowGraphSerializer::SerializeToBuffer(stack_zone.GetZone(), flow_graph,
-                                           &buffer);
-
-    file_write(buffer.buffer(), buffer.length(), stream);
-  }
-});
-#endif
-
-COMPILER_PASS(RoundTripSerialization, {
-  FlowGraphDeserializer::RoundTripSerialization(state);
-  ASSERT(state->flow_graph() != nullptr);
-})
-
 }  // namespace dart
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h
index 1904561..39dc9bd 100644
--- a/runtime/vm/compiler/compiler_pass.h
+++ b/runtime/vm/compiler/compiler_pass.h
@@ -44,9 +44,7 @@
   V(OptimizeTypedDataAccesses)                                                 \
   V(RangeAnalysis)                                                             \
   V(ReorderBlocks)                                                             \
-  V(RoundTripSerialization)                                                    \
   V(SelectRepresentations)                                                     \
-  V(SerializeGraph)                                                            \
   V(SetOuterInliningId)                                                        \
   V(TryCatchOptimization)                                                      \
   V(TryOptimizePatterns)                                                       \
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index edfa863..8cc4b39 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -57,13 +57,9 @@
   "backend/il.h",
   "backend/il_arm.cc",
   "backend/il_arm64.cc",
-  "backend/il_deserializer.cc",
-  "backend/il_deserializer.h",
   "backend/il_ia32.cc",
   "backend/il_printer.cc",
   "backend/il_printer.h",
-  "backend/il_serializer.cc",
-  "backend/il_serializer.h",
   "backend/il_x64.cc",
   "backend/inliner.cc",
   "backend/inliner.h",
@@ -79,8 +75,6 @@
   "backend/range_analysis.h",
   "backend/redundancy_elimination.cc",
   "backend/redundancy_elimination.h",
-  "backend/sexpression.cc",
-  "backend/sexpression.h",
   "backend/slot.cc",
   "backend/slot.h",
   "backend/type_propagator.cc",
@@ -175,7 +169,6 @@
   "backend/range_analysis_test.cc",
   "backend/reachability_fence_test.cc",
   "backend/redundancy_elimination_test.cc",
-  "backend/sexpression_test.cc",
   "backend/slot_test.cc",
   "backend/type_propagator_test.cc",
   "backend/typed_data_aot_test.cc",
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 65332f5..3835109 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -53,10 +53,6 @@
 DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr");
 DECLARE_FLAG(bool, strong);
 
-#if defined(DART_PRECOMPILED_RUNTIME)
-DEFINE_FLAG(bool, print_llvm_constant_pool, false, "Print LLVM constant pool");
-#endif
-
 Isolate* Dart::vm_isolate_ = NULL;
 int64_t Dart::start_time_micros_ = 0;
 ThreadPool* Dart::thread_pool_ = NULL;
@@ -811,52 +807,6 @@
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
 
-#if defined(DART_PRECOMPILED_RUNTIME)
-static void PrintLLVMConstantPool(Thread* T, Isolate* I) {
-  StackZone printing_zone(T);
-  HandleScope printing_scope(T);
-  TextBuffer b(1000);
-  const auto& constants = GrowableObjectArray::Handle(
-      I->group()->object_store()->llvm_constant_pool());
-  if (constants.IsNull()) {
-    b.AddString("No constant pool information in snapshot.\n\n");
-  } else {
-    auto const len = constants.Length();
-    b.Printf("Constant pool contents (length %" Pd "):\n", len);
-    auto& obj = Object::Handle();
-    for (intptr_t i = 0; i < len; i++) {
-      obj = constants.At(i);
-      b.Printf("  %5" Pd ": ", i);
-      if (obj.IsString()) {
-        b.AddChar('"');
-        b.AddEscapedString(obj.ToCString());
-        b.AddChar('"');
-      } else {
-        b.AddString(obj.ToCString());
-      }
-      b.AddChar('\n');
-    }
-    b.AddString("End of constant pool.\n\n");
-  }
-  const auto& functions = GrowableObjectArray::Handle(
-      I->group()->object_store()->llvm_function_pool());
-  if (functions.IsNull()) {
-    b.AddString("No function pool information in snapshot.\n\n");
-  } else {
-    auto const len = functions.Length();
-    b.Printf("Function pool contents (length %" Pd "):\n", len);
-    auto& obj = Function::Handle();
-    for (intptr_t i = 0; i < len; i++) {
-      obj ^= functions.At(i);
-      ASSERT(!obj.IsNull());
-      b.Printf("  %5" Pd ": %s\n", i, obj.ToFullyQualifiedCString());
-    }
-    b.AddString("End of function pool.\n\n");
-  }
-  THR_Print("%s", b.buffer());
-}
-#endif
-
 ErrorPtr Dart::InitializeIsolate(const uint8_t* snapshot_data,
                                  const uint8_t* snapshot_instructions,
                                  const uint8_t* kernel_buffer,
@@ -913,11 +863,6 @@
 #if !defined(TARGET_ARCH_IA32)
     ASSERT(IG->object_store()->build_method_extractor_code() != Code::null());
 #endif
-#if defined(DART_PRECOMPILED_RUNTIME)
-    if (FLAG_print_llvm_constant_pool) {
-      PrintLLVMConstantPool(T, I);
-    }
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
   } else {
 #if !defined(TARGET_ARCH_IA32)
     if (I != Dart::vm_isolate()) {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 19f8743..cdda785 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2256,8 +2256,6 @@
   }
 
  private:
-  friend class FlowGraphSerializer;  // For is_megamorphic()
-
   static ICDataPtr New();
 
   // Grows the array and also sets the argument to the index that should be used
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 7554f4d..55f8b6d 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -169,9 +169,6 @@
   RW(Function, complete_on_async_return)                                       \
   RW(Function, complete_on_async_error)                                        \
   RW(Class, async_star_stream_controller)                                      \
-  RW(GrowableObjectArray, llvm_constant_pool)                                  \
-  RW(GrowableObjectArray, llvm_function_pool)                                  \
-  RW(Array, llvm_constant_hash_table)                                          \
   RW(CompressedStackMaps, canonicalized_stack_map_entries)                     \
   RW(ObjectPool, global_object_pool)                                           \
   RW(Array, unique_dynamic_targets)                                            \
diff --git a/tools/VERSION b/tools/VERSION
index 8f43000..cf2e335 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 123
+PRERELEASE 124
 PRERELEASE_PATCH 0
\ No newline at end of file
