Add CodegenResult as the result of FunctionCompiler.compile

+ delete CodegenWorkItem
+ remove use of WorkItem in the compilation pipeline

Change-Id: I035fb8428b7bbdea9411c087e80c81e3d46d00c0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101662
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index b2dedea..e3f201f 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -8,13 +8,13 @@
 import '../elements/entities.dart';
 import '../elements/types.dart' show DartType, InterfaceType;
 import '../native/behavior.dart';
+import '../js/js.dart' as js;
 import '../universe/feature.dart';
 import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
 import '../universe/world_impact.dart'
     show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor;
 import '../util/enumset.dart';
 import '../util/util.dart' show Pair, Setlet;
-import 'work.dart' show WorkItem;
 
 class CodegenImpact extends WorldImpact {
   const CodegenImpact();
@@ -224,7 +224,9 @@
   }
 }
 
-/// [WorkItem] used exclusively by the [CodegenEnqueuer].
-abstract class CodegenWorkItem extends WorkItem {
-  CodegenRegistry get registry;
+class CodegenResult {
+  js.Fun code;
+  CodegenImpact impact;
+
+  CodegenResult(this.code, this.impact);
 }
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index ecc4dcc..23d1f20 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -6,9 +6,10 @@
 
 import '../common.dart';
 import '../common/backend_api.dart' show ImpactTransformer;
-import '../common/codegen.dart' show CodegenWorkItem;
+import '../common/codegen.dart' show CodegenResult;
 import '../common/names.dart' show Uris;
 import '../common/tasks.dart' show CompilerTask;
+import '../common/work.dart';
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../compiler.dart' show Compiler;
 import '../deferred_load.dart' show DeferredLoadTask;
@@ -54,9 +55,9 @@
 abstract class FunctionCompiler {
   void onCodegenStart(CodegenInputs codegen);
 
-  /// Generates JavaScript code for `work.element`.
-  jsAst.Fun compile(
-      CodegenWorkItem work,
+  /// Generates JavaScript code for [member].
+  CodegenResult compile(
+      MemberEntity member,
       CodegenInputs codegen,
       JClosedWorld closedWorld,
       GlobalTypeInferenceResults globalInferenceResults);
@@ -595,33 +596,29 @@
   Map<MemberEntity, WorldImpact> codegenImpactsForTesting;
 
   WorldImpact generateCode(
-      CodegenWorkItem work,
+      WorkItem work,
       JClosedWorld closedWorld,
       GlobalTypeInferenceResults globalInferenceResults,
       CodegenInputs codegen) {
-    MemberEntity element = work.element;
-    if (element.isConstructor &&
-        element.enclosingClass == closedWorld.commonElements.jsNullClass) {
+    MemberEntity member = work.element;
+    if (member.isConstructor &&
+        member.enclosingClass == closedWorld.commonElements.jsNullClass) {
       // Work around a problem compiling JSNull's constructor.
       return const WorldImpact();
     }
 
-    jsAst.Fun function = functionCompiler.compile(
-        work, codegen, closedWorld, globalInferenceResults);
-    if (function != null) {
-      if (function.sourceInformation == null) {
-        function = function.withSourceInformation(
-            sourceInformationStrategy.buildSourceMappedMarker());
-      }
-      generatedCode[element] = function;
+    CodegenResult result = functionCompiler.compile(
+        member, codegen, closedWorld, globalInferenceResults);
+    if (result.code != null) {
+      generatedCode[member] = result.code;
     }
     if (retainDataForTesting) {
       codegenImpactsForTesting ??= <MemberEntity, WorldImpact>{};
-      codegenImpactsForTesting[element] = work.registry.worldImpact;
+      codegenImpactsForTesting[member] = result.impact;
     }
-    WorldImpact worldImpact = _codegenImpactTransformer
-        .transformCodegenImpact(work.registry.worldImpact);
-    compiler.dumpInfoTask.registerImpact(element, worldImpact);
+    WorldImpact worldImpact =
+        _codegenImpactTransformer.transformCodegenImpact(result.impact);
+    compiler.dumpInfoTask.registerImpact(member, worldImpact);
     return worldImpact;
   }
 
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 96f1b69..8a3c2e0 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -8,10 +8,11 @@
 
 import '../backend_strategy.dart';
 import '../common.dart';
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry;
 import '../common/tasks.dart';
+import '../common/work.dart';
 import '../compiler.dart';
-import '../deferred_load.dart';
+import '../deferred_load.dart' hide WorkItem;
 import '../dump_info.dart';
 import '../elements/entities.dart';
 import '../enqueue.dart';
@@ -152,27 +153,23 @@
       this._globalInferenceResults, this._codegen);
 
   @override
-  CodegenWorkItem createWorkItem(MemberEntity entity) {
+  WorkItem createWorkItem(MemberEntity entity) {
     if (entity.isAbstract) return null;
     return new KernelCodegenWorkItem(
         _backend, _closedWorld, _globalInferenceResults, _codegen, entity);
   }
 }
 
-class KernelCodegenWorkItem extends CodegenWorkItem {
+class KernelCodegenWorkItem extends WorkItem {
   final JavaScriptBackend _backend;
   final JClosedWorld _closedWorld;
   @override
   final MemberEntity element;
-  @override
-  final CodegenRegistry registry;
   final GlobalTypeInferenceResults _globalInferenceResults;
   final CodegenInputs _codegen;
 
   KernelCodegenWorkItem(this._backend, this._closedWorld,
-      this._globalInferenceResults, this._codegen, this.element)
-      : registry =
-            new CodegenRegistry(_closedWorld.elementEnvironment, element);
+      this._globalInferenceResults, this._codegen, this.element);
 
   @override
   WorldImpact run() {
@@ -209,20 +206,20 @@
       this._sourceInformationStrategy);
 
   @override
-  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults results) {
+  HGraph build(MemberEntity member, JClosedWorld closedWorld,
+      GlobalTypeInferenceResults results, CodegenRegistry registry) {
     _inlineCache ??= new FunctionInlineCache(closedWorld.annotationsData);
     return _task.measure(() {
       KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
           _options,
           _reporter,
-          work.element,
-          _elementMap.getMemberThisType(work.element),
+          member,
+          _elementMap.getMemberThisType(member),
           _dumpInfoTask,
           _elementMap,
           results,
           closedWorld,
-          work.registry,
+          registry,
           _namer,
           _emitter,
           _tracer,
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 80e28c7..45aadc0 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -9,7 +9,7 @@
 
 import '../common.dart';
 import '../common/names.dart';
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry;
 import '../common/tasks.dart' show Measurer, CompilerTask;
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
@@ -78,22 +78,31 @@
     }
   }
 
-  js.Expression generateCode(CodegenWorkItem work, HGraph graph,
-      CodegenInputs codegen, JClosedWorld closedWorld) {
-    if (work.element.isField) {
-      return generateLazyInitializer(work, graph, codegen, closedWorld);
+  js.Expression generateCode(
+      MemberEntity member,
+      HGraph graph,
+      CodegenInputs codegen,
+      JClosedWorld closedWorld,
+      CodegenRegistry registry) {
+    if (member.isField) {
+      return generateLazyInitializer(
+          member, graph, codegen, closedWorld, registry);
     } else {
-      return generateMethod(work, graph, codegen, closedWorld);
+      return generateMethod(member, graph, codegen, closedWorld, registry);
     }
   }
 
-  js.Expression generateLazyInitializer(CodegenWorkItem work, HGraph graph,
-      CodegenInputs codegen, JClosedWorld closedWorld) {
+  js.Expression generateLazyInitializer(
+      FieldEntity field,
+      HGraph graph,
+      CodegenInputs codegen,
+      JClosedWorld closedWorld,
+      CodegenRegistry registry) {
     return measure(() {
       codegen.tracer.traceGraph("codegen", graph);
       SourceInformation sourceInformation = sourceInformationStrategy
-          .createBuilderForContext(work.element)
-          .buildDeclaration(work.element);
+          .createBuilderForContext(field)
+          .buildDeclaration(field);
       SsaCodeGenerator codeGenerator = new SsaCodeGenerator(
           this,
           _options,
@@ -106,19 +115,22 @@
           codegen.superMemberData,
           codegen.tracer,
           closedWorld,
-          work);
+          registry);
       codeGenerator.visitGraph(graph);
       return new js.Fun(codeGenerator.parameters, codeGenerator.body)
           .withSourceInformation(sourceInformation);
     });
   }
 
-  js.Expression generateMethod(CodegenWorkItem work, HGraph graph,
-      CodegenInputs codegen, JClosedWorld closedWorld) {
+  js.Expression generateMethod(
+      FunctionEntity method,
+      HGraph graph,
+      CodegenInputs codegen,
+      JClosedWorld closedWorld,
+      CodegenRegistry registry) {
     return measure(() {
-      FunctionEntity element = work.element;
-      if (element.asyncMarker != AsyncMarker.SYNC) {
-        work.registry.registerAsyncMarker(element.asyncMarker);
+      if (method.asyncMarker != AsyncMarker.SYNC) {
+        registry.registerAsyncMarker(method.asyncMarker);
       }
       SsaCodeGenerator codeGenerator = new SsaCodeGenerator(
           this,
@@ -132,10 +144,10 @@
           codegen.superMemberData,
           codegen.tracer,
           closedWorld,
-          work);
+          registry);
       codeGenerator.visitGraph(graph);
       codegen.tracer.traceGraph("codegen", graph);
-      return buildJavaScriptFunction(graph.needsAsyncRewrite, work.element,
+      return buildJavaScriptFunction(graph.needsAsyncRewrite, method,
           codeGenerator.parameters, codeGenerator.body);
     });
   }
@@ -171,7 +183,7 @@
   final SuperMemberData _superMemberData;
   final Tracer _tracer;
   final JClosedWorld _closedWorld;
-  final CodegenWorkItem _work;
+  final CodegenRegistry _registry;
 
   final Set<HInstruction> generateAtUseSite;
   final Set<HInstruction> controlFlowOperators;
@@ -227,7 +239,7 @@
       this._superMemberData,
       this._tracer,
       this._closedWorld,
-      this._work,
+      this._registry,
       {SourceInformation sourceInformation})
       : declaredLocals = new Set<String>(),
         collectedVariableDeclarations = new Set<String>(),
@@ -241,8 +253,6 @@
         continueAction = new Set<LabelDefinition>(),
         implicitContinueAction = new Set<JumpTarget>();
 
-  CodegenRegistry get _registry => _work.registry;
-
   JCommonElements get _commonElements => _closedWorld.commonElements;
 
   NativeData get _nativeData => _closedWorld.nativeData;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 88f9b6c..f49e608 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import '../common.dart';
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry;
 import '../common/names.dart' show Selectors;
 import '../common/tasks.dart' show Measurer, CompilerTask;
 import '../constants/constant_system.dart' as constant_system;
@@ -51,11 +51,12 @@
   String get name => 'SSA optimizer';
 
   void optimize(
-      CodegenWorkItem work,
+      MemberEntity member,
       HGraph graph,
       CodegenInputs codegen,
       JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults) {
+      GlobalTypeInferenceResults globalInferenceResults,
+      CodegenRegistry registry) {
     void runPhase(OptimizationPhase phase) {
       measureSubtask(phase.name, () => phase.visitGraph(graph));
       codegen.tracer.traceGraph(phase.name, graph);
@@ -63,7 +64,6 @@
     }
 
     bool trustPrimitives = _options.trustPrimitives;
-    CodegenRegistry registry = work.registry;
     Set<HInstruction> boundsChecked = new Set<HInstruction>();
     SsaCodeMotion codeMotion;
     SsaLoadElimination loadElimination;
@@ -71,7 +71,7 @@
     OptimizationTestLog log;
     if (retainDataForTesting) {
       loggersForTesting ??= {};
-      loggersForTesting[work.element] = log = new OptimizationTestLog();
+      loggersForTesting[member] = log = new OptimizationTestLog();
     }
 
     measure(() {
@@ -125,8 +125,7 @@
       // Simplifying interceptors is not strictly just an optimization, it is
       // required for implementation correctness because the code generator
       // assumes it is always performed.
-      runPhase(new SsaSimplifyInterceptors(
-          closedWorld, work.element.enclosingClass));
+      runPhase(new SsaSimplifyInterceptors(closedWorld, member.enclosingClass));
 
       SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(closedWorld, this);
       runPhase(dce);
@@ -142,7 +141,7 @@
           new SsaInstructionSimplifier(globalInferenceResults, _options,
               codegen.rtiSubstitutions, closedWorld, registry, log),
           new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
-          new SsaSimplifyInterceptors(closedWorld, work.element.enclosingClass),
+          new SsaSimplifyInterceptors(closedWorld, member.enclosingClass),
           new SsaDeadCodeEliminator(closedWorld, this),
         ];
       } else {
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index c6e963e..4164617 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -7,7 +7,7 @@
 import '../backend_strategy.dart';
 import '../common.dart';
 import '../common_elements.dart' show CommonElements, JElementEnvironment;
-import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/codegen.dart' show CodegenResult, CodegenRegistry;
 import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../elements/entities.dart';
 import '../elements/types.dart';
@@ -53,33 +53,42 @@
   /// Generates JavaScript code for `work.element`.
   /// Using the ssa builder, optimizer and code generator.
   @override
-  js.Fun compile(
-      CodegenWorkItem work,
+  CodegenResult compile(
+      MemberEntity member,
       CodegenInputs codegen,
       JClosedWorld closedWorld,
       GlobalTypeInferenceResults globalInferenceResults) {
-    HGraph graph = _builder.build(work, closedWorld, globalInferenceResults);
-    if (graph == null) return null;
+    CodegenRegistry registry =
+        new CodegenRegistry(closedWorld.elementEnvironment, member);
+    HGraph graph =
+        _builder.build(member, closedWorld, globalInferenceResults, registry);
+    if (graph == null) {
+      return new CodegenResult(null, registry.worldImpact);
+    }
     optimizer.optimize(
-        work, graph, codegen, closedWorld, globalInferenceResults);
-    MemberEntity element = work.element;
+        member, graph, codegen, closedWorld, globalInferenceResults, registry);
     js.Expression result =
-        generator.generateCode(work, graph, codegen, closedWorld);
+        generator.generateCode(member, graph, codegen, closedWorld, registry);
     if (graph.needsAsyncRewrite) {
       SourceInformationBuilder sourceInformationBuilder =
-          sourceInformationStrategy.createBuilderForContext(element);
+          sourceInformationStrategy.createBuilderForContext(member);
       result = _rewriteAsync(
           codegen,
           closedWorld.commonElements,
           closedWorld.elementEnvironment,
-          work.registry,
-          element,
+          registry,
+          member,
           result,
           graph.asyncElementType,
           sourceInformationBuilder.buildAsyncBody(),
           sourceInformationBuilder.buildAsyncExit());
     }
-    return result;
+    if (result.sourceInformation == null) {
+      result = result.withSourceInformation(
+          sourceInformationStrategy.buildSourceMappedMarker());
+    }
+
+    return new CodegenResult(result, registry.worldImpact);
   }
 
   js.Expression _rewriteAsync(
@@ -215,10 +224,13 @@
 }
 
 abstract class SsaBuilder {
-  /// Creates the [HGraph] for [work] or returns `null` if no code is needed
-  /// for [work].
-  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults);
+  /// Creates the [HGraph] for [member] or returns `null` if no code is needed
+  /// for [member].
+  HGraph build(
+      MemberEntity member,
+      JClosedWorld closedWorld,
+      GlobalTypeInferenceResults globalInferenceResults,
+      CodegenRegistry registry);
 }
 
 class SsaBuilderTask extends CompilerTask {
@@ -238,10 +250,14 @@
         this, codegen, _sourceInformationFactory);
   }
 
-  /// Creates the [HGraph] for [work] or returns `null` if no code is needed
-  /// for [work].
-  HGraph build(CodegenWorkItem work, JClosedWorld closedWorld,
-      GlobalTypeInferenceResults globalInferenceResults) {
-    return _builder.build(work, closedWorld, globalInferenceResults);
+  /// Creates the [HGraph] for [member] or returns `null` if no code is needed
+  /// for [member].
+  HGraph build(
+      MemberEntity member,
+      JClosedWorld closedWorld,
+      GlobalTypeInferenceResults globalInferenceResults,
+      CodegenRegistry registry) {
+    return _builder.build(
+        member, closedWorld, globalInferenceResults, registry);
   }
 }
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index b719421..9b26699 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -36,7 +36,7 @@
 
 // The immutable result of the [CodegenWorldBuilder].
 abstract class CodegenWorld extends BuiltWorld {
-  /// Calls [f] for each
+  /// Calls [f] for each generic call method on a live closure class.
   void forEachGenericClosureCallMethod(void Function(FunctionEntity) f);
 
   bool hasInvokedGetter(MemberEntity member);
diff --git a/tests/compiler/dart2js/end_to_end/exit_code_test.dart b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
index fbae05a..3cb288c 100644
--- a/tests/compiler/dart2js/end_to_end/exit_code_test.dart
+++ b/tests/compiler/dart2js/end_to_end/exit_code_test.dart
@@ -11,7 +11,7 @@
 
 import 'package:compiler/compiler_new.dart' as api;
 import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/codegen.dart';
+import 'package:compiler/src/common/work.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/dart2js.dart' as entry;
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
@@ -110,7 +110,7 @@
             useNewSourceInfo: compiler.options.useNewSourceInfo);
 
   @override
-  WorldImpact generateCode(CodegenWorkItem work, JClosedWorld closedWorld,
+  WorldImpact generateCode(WorkItem work, JClosedWorld closedWorld,
       GlobalTypeInferenceResults results, CodegenInputs codegen) {
     compiler.test('Compiler.codegen');
     return super.generateCode(work, closedWorld, results, codegen);