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; |
} |