| Index: pkg/compiler/lib/src/ssa/optimize.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
|
| index 553709b44c2878ee11e78a811a39c0a842c00b95..3ac8e272e90908d5812798de127ec87d154297d9 100644
|
| --- a/pkg/compiler/lib/src/ssa/optimize.dart
|
| +++ b/pkg/compiler/lib/src/ssa/optimize.dart
|
| @@ -2,7 +2,7 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| -import '../common/codegen.dart' show CodegenWorkItem;
|
| +import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
|
| import '../common/tasks.dart' show CompilerTask;
|
| import '../compiler.dart' show Compiler;
|
| import '../constants/constant_system.dart';
|
| @@ -50,22 +50,23 @@ class SsaOptimizerTask extends CompilerTask {
|
|
|
| ConstantSystem constantSystem = compiler.backend.constantSystem;
|
| bool trustPrimitives = compiler.options.trustPrimitives;
|
| + CodegenRegistry registry = work.registry;
|
| Set<HInstruction> boundsChecked = new Set<HInstruction>();
|
| SsaCodeMotion codeMotion;
|
| measure(() {
|
| List<OptimizationPhase> phases = <OptimizationPhase>[
|
| // Run trivial instruction simplification first to optimize
|
| // some patterns useful for type conversion.
|
| - new SsaInstructionSimplifier(constantSystem, backend, this),
|
| + new SsaInstructionSimplifier(constantSystem, backend, this, registry),
|
| new SsaTypeConversionInserter(compiler),
|
| new SsaRedundantPhiEliminator(),
|
| new SsaDeadPhiEliminator(),
|
| new SsaTypePropagator(compiler),
|
| // After type propagation, more instructions can be
|
| // simplified.
|
| - new SsaInstructionSimplifier(constantSystem, backend, this),
|
| + new SsaInstructionSimplifier(constantSystem, backend, this, registry),
|
| new SsaCheckInserter(trustPrimitives, backend, boundsChecked),
|
| - new SsaInstructionSimplifier(constantSystem, backend, this),
|
| + new SsaInstructionSimplifier(constantSystem, backend, this, registry),
|
| new SsaCheckInserter(trustPrimitives, backend, boundsChecked),
|
| new SsaTypePropagator(compiler),
|
| // Run a dead code eliminator before LICM because dead
|
| @@ -83,7 +84,7 @@ class SsaOptimizerTask extends CompilerTask {
|
| new SsaValueRangeAnalyzer(compiler, constantSystem, this),
|
| // Previous optimizations may have generated new
|
| // opportunities for instruction simplification.
|
| - new SsaInstructionSimplifier(constantSystem, backend, this),
|
| + new SsaInstructionSimplifier(constantSystem, backend, this, registry),
|
| new SsaCheckInserter(trustPrimitives, backend, boundsChecked),
|
| ];
|
| phases.forEach(runPhase);
|
| @@ -102,7 +103,7 @@ class SsaOptimizerTask extends CompilerTask {
|
| new SsaGlobalValueNumberer(compiler),
|
| new SsaCodeMotion(),
|
| new SsaValueRangeAnalyzer(compiler, constantSystem, this),
|
| - new SsaInstructionSimplifier(constantSystem, backend, this),
|
| + new SsaInstructionSimplifier(constantSystem, backend, this, registry),
|
| new SsaCheckInserter(trustPrimitives, backend, boundsChecked),
|
| new SsaSimplifyInterceptors(compiler, constantSystem, work.element),
|
| new SsaDeadCodeEliminator(compiler, this),
|
| @@ -112,7 +113,7 @@ class SsaOptimizerTask extends CompilerTask {
|
| new SsaTypePropagator(compiler),
|
| // Run the simplifier to remove unneeded type checks inserted by
|
| // type propagation.
|
| - new SsaInstructionSimplifier(constantSystem, backend, this),
|
| + new SsaInstructionSimplifier(constantSystem, backend, this, registry),
|
| ];
|
| }
|
| phases.forEach(runPhase);
|
| @@ -155,11 +156,13 @@ class SsaInstructionSimplifier extends HBaseVisitor
|
| final String name = "SsaInstructionSimplifier";
|
| final JavaScriptBackend backend;
|
| final ConstantSystem constantSystem;
|
| + final CodegenRegistry registry;
|
| HGraph graph;
|
| Compiler get compiler => backend.compiler;
|
| final SsaOptimizerTask optimizer;
|
|
|
| - SsaInstructionSimplifier(this.constantSystem, this.backend, this.optimizer);
|
| + SsaInstructionSimplifier(
|
| + this.constantSystem, this.backend, this.optimizer, this.registry);
|
|
|
| CoreClasses get coreClasses => compiler.coreClasses;
|
|
|
| @@ -1159,36 +1162,44 @@ class SsaInstructionSimplifier extends HBaseVisitor
|
|
|
| // Match:
|
| //
|
| - // setRuntimeTypeInfo(
|
| - // HCreate(ClassElement),
|
| - // HTypeInfoExpression(t_0, t_1, t_2, ...));
|
| + // HCreate(ClassElement,
|
| + // [arg_i,
|
| + // ...,
|
| + // HTypeInfoExpression(t_0, t_1, t_2, ...)]);
|
| //
|
| // The `t_i` are the values of the type parameters of ClassElement.
|
| - if (object is HInvokeStatic) {
|
| - if (object.element == helpers.setRuntimeTypeInfo) {
|
| - HInstruction allocation = object.inputs[0];
|
| - if (allocation is HCreate) {
|
| - HInstruction typeInfo = object.inputs[1];
|
| - if (typeInfo is HTypeInfoExpression) {
|
| - return finishSubstituted(
|
| - allocation.element, (int index) => typeInfo.inputs[index]);
|
| - }
|
| +
|
| + if (object is HCreate) {
|
| + void registerInstantiations() {
|
| + // Forwarding the type variable references might cause the HCreate to
|
| + // become dead. This breaks the algorithm for generating the per-type
|
| + // runtime type information, so we instantiate them here in case the
|
| + // HCreate becomes dead.
|
| + object.instantiatedTypes?.forEach(registry.registerInstantiation);
|
| + }
|
| +
|
| + if (object.hasRtiInput) {
|
| + HInstruction typeInfo = object.rtiInput;
|
| + if (typeInfo is HTypeInfoExpression) {
|
| + registerInstantiations();
|
| + return finishSubstituted(
|
| + object.element, (int index) => typeInfo.inputs[index]);
|
| }
|
| - return node;
|
| + } else {
|
| + // Non-generic type (which extends or mixes in a generic type, for
|
| + // example CodeUnits extends UnmodifiableListBase<int>). Also used for
|
| + // raw-type when the type parameters are elided.
|
| + registerInstantiations();
|
| + return finishSubstituted(
|
| + object.element,
|
| + // If there are type arguments, all type arguments are 'dynamic'.
|
| + (int i) => graph.addConstantNull(compiler));
|
| }
|
| - // TODO(sra): Factory constructors pass type arguments after the value
|
| - // arguments. The [select] argument indexes into these type arguments.
|
| }
|
|
|
| - // Non-generic type (which extends or mixes in a generic type, for example
|
| - // CodeUnits extends UnmodifiableListBase<int>).
|
| - // Also used for raw-type when the type parameters are elided.
|
| - if (object is HCreate) {
|
| - return finishSubstituted(
|
| - object.element,
|
| - // If there are type arguments, all type arguments are 'dynamic'.
|
| - (int i) => graph.addConstantNull(compiler));
|
| - }
|
| + // TODO(sra): Factory constructors pass type arguments after the value
|
| + // arguments. The [selectTypeArgumentFromObjectCreation] argument of
|
| + // [finishSubstituted] indexes into these type arguments.
|
|
|
| return node;
|
| }
|
|
|