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 031922228f881912a882b621935a64d4a3312644..10046163222503727fc71ebc6a388598dc0596d3 100644 |
| --- a/pkg/compiler/lib/src/ssa/optimize.dart |
| +++ b/pkg/compiler/lib/src/ssa/optimize.dart |
| @@ -1057,6 +1057,30 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| return node; |
| } |
| + HInstruction finishSubstituted( |
| + ClassElement createdClass, HInstruction select(int index)) { |
|
Siggi Cherem (dart-lang)
2016/08/29 19:48:57
I'm not sure what 'select' means in this context.
sra1
2016/08/29 21:27:41
It is a 'select' because it picks an existing thin
|
| + HInstruction instructionForTypeVariable(TypeVariableType tv) { |
| + return select(createdClass.thisType.typeArguments.indexOf(tv)); |
| + } |
| + |
| + DartType type = createdClass.thisType |
| + .asInstanceOf(variable.element.enclosingClass) |
| + .typeArguments[variable.element.index]; |
| + if (type is TypeVariableType) { |
| + return instructionForTypeVariable(type); |
| + } |
| + List<HInstruction> arguments = <HInstruction>[]; |
| + type.forEachTypeVariable((v) { |
| + arguments.add(instructionForTypeVariable(v)); |
| + }); |
| + HInstruction replacement = new HTypeInfoExpression( |
| + TypeInfoExpressionKind.COMPLETE, |
| + type, |
| + arguments, |
| + backend.dynamicType); |
| + return replacement; |
| + } |
| + |
| // Type variable evaluated in the context of a constant can be replaced with |
| // a ground term type. |
| if (object is HConstant) { |
| @@ -1067,10 +1091,29 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| return node; |
| } |
| - // TODO(sra): HTypeInfoReadVariable on an instance creation can be replaced |
| - // with an input of the instance creation's HTypeInfoExpression (or a |
| - // HTypeInfoExpression of an input). This would in effect store-forward the |
| - // type parameters. |
| + // Store-forward and index into reified type on an instance creation. |
| + // |
| + // Look for an allocation with type information, or allocation of a |
| + // non-generic type (which extends or mixes in a generic type). |
| + |
| + if (object is HForeignNew) { |
| + return finishGroundType(object.element.thisType); |
| + } |
| + if (object is HInvokeStatic) { |
| + if (object.element == helpers.setRuntimeTypeInfo) { |
| + HInstruction allocation = object.inputs[0]; |
| + if (allocation is HForeignNew) { |
| + HInstruction typeInfo = object.inputs[1]; |
| + if (typeInfo is HTypeInfoExpression) { |
| + return finishSubstituted( |
| + allocation.element, (int index) => typeInfo.inputs[index]); |
| + } |
| + } |
| + return node; |
| + } |
| + // TODO(sra): Factory constructors pass type arguments after the value |
| + // arguments. The [select] argument indexes into these type arguments. |
| + } |
| return node; |
| } |