Chromium Code Reviews| 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 f15dceba538109b5baf66911a00f60440c742aa2..7e547022e47b62972fef1c4cbe1ef91239b11d7e 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,21 +50,22 @@ class SsaOptimizerTask extends CompilerTask { |
| ConstantSystem constantSystem = compiler.backend.constantSystem; |
| bool trustPrimitives = compiler.options.trustPrimitives; |
| + CodegenRegistry registry = work.registry; |
| Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| 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 |
| @@ -82,7 +83,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); |
| @@ -101,7 +102,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), |
| @@ -111,7 +112,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); |
| @@ -154,11 +155,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; |
| @@ -1158,36 +1161,46 @@ 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((type) { |
| + registry.registerInstantiation(type); |
|
Siggi Cherem (dart-lang)
2016/09/07 17:49:38
use tearoff here too.
sra1
2016/09/07 18:16:07
Done.
|
| + }); |
| + } |
| + |
| + if (object.hasRtiInput) { |
| + HInstruction typeInfo = object.rtiInput; |
| + if (typeInfo is HTypeInfoExpression) { |
| + registerInstantiations(); |
|
Siggi Cherem (dart-lang)
2016/09/07 17:49:38
minor nit: how about we remove the `registerInstan
sra1
2016/09/07 18:16:07
I'll leave it as-is for now. It will need to be re
|
| + 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; |
| } |