[dart2js] Add tracing for codegen phases
Change-Id: Iace4d6037e7071d7642e510f0616c869cf30946b
Reviewed-on: https://dart-review.googlesource.com/c/93928
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 1252521..ebf05c2 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -31,6 +31,7 @@
import '../native/behavior.dart';
import '../native/enqueue.dart';
import '../options.dart';
+import '../tracer.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
import '../universe/use.dart'
@@ -40,6 +41,11 @@
import 'nodes.dart';
import 'variable_allocator.dart';
+abstract class CodegenPhase {
+ String get name => '$runtimeType';
+ void visitGraph(HGraph graph);
+}
+
class SsaCodeGeneratorTask extends CompilerTask {
final JavaScriptBackend backend;
final SourceInformationStrategy sourceInformationFactory;
@@ -89,6 +95,7 @@
.createBuilderForContext(work.element)
.buildDeclaration(work.element);
SsaCodeGenerator codegen = new SsaCodeGenerator(
+ this,
backend.compiler.options,
backend.emitter,
backend.nativeCodegenEnqueuer,
@@ -98,6 +105,7 @@
backend.rtiEncoder,
backend.namer,
backend.superMemberData,
+ backend.tracer,
closedWorld,
work);
codegen.visitGraph(graph);
@@ -114,6 +122,7 @@
work.registry.registerAsyncMarker(element.asyncMarker);
}
SsaCodeGenerator codegen = new SsaCodeGenerator(
+ this,
backend.compiler.options,
backend.emitter,
backend.nativeCodegenEnqueuer,
@@ -123,6 +132,7 @@
backend.rtiEncoder,
backend.namer,
backend.superMemberData,
+ backend.tracer,
closedWorld,
work);
codegen.visitGraph(graph);
@@ -152,6 +162,7 @@
/// This includes declarations, which are generated as expressions.
bool isGeneratingExpression = false;
+ final CompilerTask _codegenTask;
final CompilerOptions _options;
final CodeEmitterTask _emitter;
final NativeCodegenEnqueuer _nativeEnqueuer;
@@ -161,6 +172,7 @@
final RuntimeTypesEncoder _rtiEncoder;
final Namer _namer;
final SuperMemberData _superMemberData;
+ final Tracer _tracer;
final JClosedWorld _closedWorld;
final CodegenWorkItem _work;
@@ -207,6 +219,7 @@
Queue<HBasicBlock> blockQueue;
SsaCodeGenerator(
+ this._codegenTask,
this._options,
this._emitter,
this._nativeEnqueuer,
@@ -216,6 +229,7 @@
this._rtiEncoder,
this._namer,
this._superMemberData,
+ this._tracer,
this._closedWorld,
this._work,
{SourceInformation sourceInformation})
@@ -352,27 +366,34 @@
}
void preGenerateMethod(HGraph graph) {
- new SsaInstructionSelection(_options, _closedWorld, _interceptorData)
- .visitGraph(graph);
- new SsaTypeKnownRemover().visitGraph(graph);
- new SsaTrustedCheckRemover(_options).visitGraph(graph);
+ void runPhase(CodegenPhase phase, {bool traceGraph = true}) {
+ _codegenTask.measureSubtask(phase.name, () => phase.visitGraph(graph));
+ if (traceGraph) {
+ _tracer.traceGraph(phase.name, graph);
+ }
+ assert(graph.isValid(), 'Graph not valid after ${phase.name}');
+ }
+
+ runPhase(
+ new SsaInstructionSelection(_options, _closedWorld, _interceptorData));
+ runPhase(new SsaTypeKnownRemover());
+ runPhase(new SsaTrustedCheckRemover(_options));
// TODO(sra): Re-enable chaining.
- // new SsaAssignmentChaining(_options, _closedWorld).visitGraph(graph);
- new SsaInstructionMerger(
- _abstractValueDomain, generateAtUseSite, _superMemberData)
- .visitGraph(graph);
- new SsaConditionMerger(generateAtUseSite, controlFlowOperators)
- .visitGraph(graph);
- new SsaShareRegionConstants(_options).visitGraph(graph);
+ // runPhase(new SsaAssignmentChaining(_options, _closedWorld));
+ runPhase(new SsaInstructionMerger(
+ _abstractValueDomain, generateAtUseSite, _superMemberData));
+ runPhase(new SsaConditionMerger(generateAtUseSite, controlFlowOperators));
+ runPhase(new SsaShareRegionConstants(_options));
+
SsaLiveIntervalBuilder intervalBuilder =
new SsaLiveIntervalBuilder(generateAtUseSite, controlFlowOperators);
- intervalBuilder.visitGraph(graph);
+ runPhase(intervalBuilder, traceGraph: false);
SsaVariableAllocator allocator = new SsaVariableAllocator(
_namer,
intervalBuilder.liveInstructions,
intervalBuilder.liveIntervals,
generateAtUseSite);
- allocator.visitGraph(graph);
+ runPhase(allocator, traceGraph: false);
variableNames = allocator.names;
shouldGroupVarDeclarations = allocator.names.numberOfVariables > 1;
}
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index ab2684b..082f46a 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -10,11 +10,12 @@
import '../options.dart';
import '../universe/selector.dart' show Selector;
import '../world.dart' show JClosedWorld;
+import 'codegen.dart' show CodegenPhase;
import 'nodes.dart';
/// Replaces some instructions with specialized versions to make codegen easier.
/// Caches codegen information on nodes.
-class SsaInstructionSelection extends HBaseVisitor {
+class SsaInstructionSelection extends HBaseVisitor with CodegenPhase {
final JClosedWorld _closedWorld;
final InterceptorData _interceptorData;
final CompilerOptions _options;
@@ -341,7 +342,7 @@
/// Remove [HTypeKnown] instructions from the graph, to make codegen
/// analysis easier.
-class SsaTypeKnownRemover extends HBaseVisitor {
+class SsaTypeKnownRemover extends HBaseVisitor with CodegenPhase {
void visitGraph(HGraph graph) {
visitDominatorTree(graph);
}
@@ -368,7 +369,7 @@
/// Remove [HTypeConversion] instructions from the graph in '--trust-primitives'
/// mode.
-class SsaTrustedCheckRemover extends HBaseVisitor {
+class SsaTrustedCheckRemover extends HBaseVisitor with CodegenPhase {
final CompilerOptions _options;
SsaTrustedCheckRemover(this._options);
@@ -402,7 +403,7 @@
/// b.y = v;
/// -->
/// b.y = a.x = v;
-class SsaAssignmentChaining extends HBaseVisitor {
+class SsaAssignmentChaining extends HBaseVisitor with CodegenPhase {
final JClosedWorld _closedWorld;
final CompilerOptions _options;
//HGraph graph;
@@ -566,7 +567,7 @@
/// t2 = add(t0, t1);
/// t0 and t1 would be marked and the resulting code would then be:
/// t2 = add(4, 3);
-class SsaInstructionMerger extends HBaseVisitor {
+class SsaInstructionMerger extends HBaseVisitor with CodegenPhase {
final AbstractValueDomain _abstractValueDomain;
final SuperMemberData _superMemberData;
@@ -866,7 +867,7 @@
/// Detect control flow arising from short-circuit logical and
/// conditional operators, and prepare the program to be generated
/// using these operators instead of nested ifs and boolean variables.
-class SsaConditionMerger extends HGraphVisitor {
+class SsaConditionMerger extends HGraphVisitor with CodegenPhase {
Set<HInstruction> generateAtUseSite;
Set<HInstruction> controlFlowOperators;
@@ -1040,7 +1041,7 @@
/// Insert 'caches' for whole-function region-constants when the local minified
/// name would be shorter than repeated references. These are caches for 'this'
/// and constant values.
-class SsaShareRegionConstants extends HBaseVisitor {
+class SsaShareRegionConstants extends HBaseVisitor with CodegenPhase {
final CompilerOptions _options;
SsaShareRegionConstants(this._options);
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index 6837537..aca7c88 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -4,6 +4,7 @@
import '../common.dart';
import '../js_backend/js_backend.dart';
+import 'codegen.dart' show CodegenPhase;
import 'nodes.dart';
/// The [LiveRange] class covers a range where an instruction is live.
@@ -153,7 +154,7 @@
/// Builds the live intervals of each instruction. The algorithm visits
/// the graph post-dominator tree to find the last uses of an
/// instruction, and computes the liveIns of each basic block.
-class SsaLiveIntervalBuilder extends HBaseVisitor {
+class SsaLiveIntervalBuilder extends HBaseVisitor with CodegenPhase {
final Set<HInstruction> generateAtUseSite;
final Set<HInstruction> controlFlowOperators;
@@ -561,7 +562,7 @@
/// instruction, it frees the names of the inputs that die at that
/// instruction, and allocates a name to the instruction. For each phi,
/// it adds a copy to the CopyHandler of the corresponding predecessor.
-class SsaVariableAllocator extends HBaseVisitor {
+class SsaVariableAllocator extends HBaseVisitor with CodegenPhase {
final Namer _namer;
final Map<HBasicBlock, LiveEnvironment> liveInstructions;
final Map<HInstruction, LiveInterval> liveIntervals;