Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1215)

Side by Side Diff: pkg/compiler/lib/src/ssa/nodes.dart

Issue 2260223002: Add SSA instructions for reified type information (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import '../closure.dart'; 5 import '../closure.dart';
6 import '../common.dart'; 6 import '../common.dart';
7 import '../compiler.dart' show Compiler; 7 import '../compiler.dart' show Compiler;
8 import '../constants/constant_system.dart'; 8 import '../constants/constant_system.dart';
9 import '../constants/values.dart'; 9 import '../constants/values.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 R visitTruncatingDivide(HTruncatingDivide node); 92 R visitTruncatingDivide(HTruncatingDivide node);
93 R visitTry(HTry node); 93 R visitTry(HTry node);
94 R visitTypeConversion(HTypeConversion node); 94 R visitTypeConversion(HTypeConversion node);
95 R visitTypeKnown(HTypeKnown node); 95 R visitTypeKnown(HTypeKnown node);
96 R visitYield(HYield node); 96 R visitYield(HYield node);
97 R visitReadTypeVariable(HReadTypeVariable node); 97 R visitReadTypeVariable(HReadTypeVariable node);
98 R visitFunctionType(HFunctionType node); 98 R visitFunctionType(HFunctionType node);
99 R visitVoidType(HVoidType node); 99 R visitVoidType(HVoidType node);
100 R visitInterfaceType(HInterfaceType node); 100 R visitInterfaceType(HInterfaceType node);
101 R visitDynamicType(HDynamicType node); 101 R visitDynamicType(HDynamicType node);
102
103 R visitTypeInfoReadRaw(HTypeInfoReadRaw node);
104 R visitTypeInfoReadVariable(HTypeInfoReadVariable node);
105 R visitTypeInfoExpression(HTypeInfoExpression node);
102 } 106 }
103 107
104 abstract class HGraphVisitor { 108 abstract class HGraphVisitor {
105 visitDominatorTree(HGraph graph) { 109 visitDominatorTree(HGraph graph) {
106 void visitBasicBlockAndSuccessors(HBasicBlock block) { 110 void visitBasicBlockAndSuccessors(HBasicBlock block) {
107 visitBasicBlock(block); 111 visitBasicBlock(block);
108 List dominated = block.dominatedBlocks; 112 List dominated = block.dominatedBlocks;
109 for (int i = 0; i < dominated.length; i++) { 113 for (int i = 0; i < dominated.length; i++) {
110 visitBasicBlockAndSuccessors(dominated[i]); 114 visitBasicBlockAndSuccessors(dominated[i]);
111 } 115 }
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 visitIsViaInterceptor(HIsViaInterceptor node) => visitInstruction(node); 391 visitIsViaInterceptor(HIsViaInterceptor node) => visitInstruction(node);
388 visitTypeConversion(HTypeConversion node) => visitCheck(node); 392 visitTypeConversion(HTypeConversion node) => visitCheck(node);
389 visitTypeKnown(HTypeKnown node) => visitCheck(node); 393 visitTypeKnown(HTypeKnown node) => visitCheck(node);
390 visitReadTypeVariable(HReadTypeVariable node) => visitInstruction(node); 394 visitReadTypeVariable(HReadTypeVariable node) => visitInstruction(node);
391 visitFunctionType(HFunctionType node) => visitInstruction(node); 395 visitFunctionType(HFunctionType node) => visitInstruction(node);
392 visitVoidType(HVoidType node) => visitInstruction(node); 396 visitVoidType(HVoidType node) => visitInstruction(node);
393 visitInterfaceType(HInterfaceType node) => visitInstruction(node); 397 visitInterfaceType(HInterfaceType node) => visitInstruction(node);
394 visitDynamicType(HDynamicType node) => visitInstruction(node); 398 visitDynamicType(HDynamicType node) => visitInstruction(node);
395 visitAwait(HAwait node) => visitInstruction(node); 399 visitAwait(HAwait node) => visitInstruction(node);
396 visitYield(HYield node) => visitInstruction(node); 400 visitYield(HYield node) => visitInstruction(node);
401
402 visitTypeInfoReadRaw(HTypeInfoReadRaw node) => visitInstruction(node);
403 visitTypeInfoReadVariable(HTypeInfoReadVariable node) =>
404 visitInstruction(node);
405 visitTypeInfoExpression(HTypeInfoExpression node) => visitInstruction(node);
397 } 406 }
398 407
399 class SubGraph { 408 class SubGraph {
400 // The first and last block of the sub-graph. 409 // The first and last block of the sub-graph.
401 final HBasicBlock start; 410 final HBasicBlock start;
402 final HBasicBlock end; 411 final HBasicBlock end;
403 412
404 const SubGraph(this.start, this.end); 413 const SubGraph(this.start, this.end);
405 414
406 bool contains(HBasicBlock block) { 415 bool contains(HBasicBlock block) {
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 static const int INVOKE_DYNAMIC_TYPECODE = 29; 856 static const int INVOKE_DYNAMIC_TYPECODE = 29;
848 static const int SHIFT_RIGHT_TYPECODE = 30; 857 static const int SHIFT_RIGHT_TYPECODE = 30;
849 static const int READ_TYPE_VARIABLE_TYPECODE = 31; 858 static const int READ_TYPE_VARIABLE_TYPECODE = 31;
850 static const int FUNCTION_TYPE_TYPECODE = 32; 859 static const int FUNCTION_TYPE_TYPECODE = 32;
851 static const int VOID_TYPE_TYPECODE = 33; 860 static const int VOID_TYPE_TYPECODE = 33;
852 static const int INTERFACE_TYPE_TYPECODE = 34; 861 static const int INTERFACE_TYPE_TYPECODE = 34;
853 static const int DYNAMIC_TYPE_TYPECODE = 35; 862 static const int DYNAMIC_TYPE_TYPECODE = 35;
854 static const int TRUNCATING_DIVIDE_TYPECODE = 36; 863 static const int TRUNCATING_DIVIDE_TYPECODE = 36;
855 static const int IS_VIA_INTERCEPTOR_TYPECODE = 37; 864 static const int IS_VIA_INTERCEPTOR_TYPECODE = 37;
856 865
866 static const int TYPE_INFO_READ_RAW_TYPECODE = 38;
867 static const int TYPE_INFO_READ_VARIABLE_TYPECODE = 39;
868 static const int TYPE_INFO_EXPRESSION_TYPECODE = 40;
869
857 HInstruction(this.inputs, this.instructionType) 870 HInstruction(this.inputs, this.instructionType)
858 : id = idCounter++, 871 : id = idCounter++,
859 usedBy = <HInstruction>[] { 872 usedBy = <HInstruction>[] {
860 assert(inputs.every((e) => e != null)); 873 assert(inputs.every((e) => e != null));
861 } 874 }
862 875
863 int get hashCode => id; 876 int get hashCode => id;
864 877
865 bool useGvn() => _useGvn; 878 bool useGvn() => _useGvn;
866 void setUseGvn() { 879 void setUseGvn() {
(...skipping 2308 matching lines...) Expand 10 before | Expand all | Expand 10 after
3175 HBasicBlock get end { 3188 HBasicBlock get end {
3176 // We don't create a switch block if there are no cases. 3189 // We don't create a switch block if there are no cases.
3177 assert(!statements.isEmpty); 3190 assert(!statements.isEmpty);
3178 return statements.last.end; 3191 return statements.last.end;
3179 } 3192 }
3180 3193
3181 bool accept(HStatementInformationVisitor visitor) => 3194 bool accept(HStatementInformationVisitor visitor) =>
3182 visitor.visitSwitchInfo(this); 3195 visitor.visitSwitchInfo(this);
3183 } 3196 }
3184 3197
3198 /// Reads raw reified type info from an object.
3199 class HTypeInfoReadRaw extends HInstruction {
3200 HTypeInfoReadRaw(HInstruction receiver, TypeMask instructionType)
3201 : super(<HInstruction>[receiver], instructionType) {
3202 setUseGvn();
3203 }
3204
3205 accept(HVisitor visitor) => visitor.visitTypeInfoReadRaw(this);
3206
3207 bool canThrow() => false;
3208
3209 int typeCode() => HInstruction.TYPE_INFO_READ_RAW_TYPECODE;
3210 bool typeEquals(HInstruction other) => other is HTypeInfoReadRaw;
3211
3212 bool dataEquals(HTypeInfoReadRaw other) {
3213 return true;
3214 }
3215 }
3216
3217 /// Reads a type variable from an object. The read may be a simple indexing of
3218 /// the type parameters or it may require 'substitution'.
3219 class HTypeInfoReadVariable extends HInstruction {
3220 /// The type variable being read.
3221 final TypeVariableType variable;
3222
3223 HTypeInfoReadVariable(
3224 this.variable, HInstruction receiver, TypeMask instructionType)
3225 : super(<HInstruction>[receiver], instructionType) {
3226 setUseGvn();
3227 }
3228
3229 accept(HVisitor visitor) => visitor.visitTypeInfoReadVariable(this);
3230
3231 bool canThrow() => false;
3232
3233 int typeCode() => HInstruction.TYPE_INFO_READ_VARIABLE_TYPECODE;
3234 bool typeEquals(HInstruction other) => other is HTypeInfoReadVariable;
3235
3236 bool dataEquals(HTypeInfoReadVariable other) {
3237 return variable.element == other.variable.element;
3238 }
3239 }
3240
3241 enum TypeInfoExpressionKind { COMPLETE, INSTANCE }
3242
3243 /// Constructs a representation of a closed or ground-term type (that is, a type
3244 /// without type variables).
3245 ///
3246 /// There are two forms:
3247 ///
3248 /// - COMPLETE: A complete form that is self contained, used for the values of
3249 /// type parameters and non-raw is-checks.
3250 ///
3251 /// - INSTANCE: A headless flat form for representing the sequence of values of
Siggi Cherem (dart-lang) 2016/08/19 18:21:46 I'm trying to understand the need for the distinct
sra1 2016/08/19 18:47:44 Correct. This is just how it is currently done. I
3252 /// the type parameters of an instance of a generic type.
3253 ///
3254 /// The COMPLETE form value is constructed from [dartType] by replacing the type
3255 /// variables with consecutive values from [arguments], in the order generated
Siggi Cherem (dart-lang) 2016/08/19 18:21:46 [arguments] => [inputs]?
sra1 2016/08/19 18:47:43 Done.
3256 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are
3257 /// treated as 'holes' in the term, which means that it must be ensured at
3258 /// construction, that duplicate occurences of a type variable in [dartType] are
3259 /// assigned the same value.
3260 ///
3261 /// The INSTANCE form is constructed as a list of [arguments]. This is the same
Siggi Cherem (dart-lang) 2016/08/19 18:21:46 ditto?
sra1 2016/08/19 18:47:43 Done.
3262 /// as the COMPLETE form for the 'thisType', except the root term's type is
3263 /// missing; this is implicit as the raw type of instance. The [dartType] of
3264 /// the INSTANCE form must be the thisType of some class.
3265 ///
3266 /// We want to remove the constrains on the INSTANCE form. In the meantime we
3267 /// get by with a tree of TypeExpressions. Consider:
3268 ///
3269 /// class Foo<T> {
3270 /// ... new Set<List<T>>()
3271 /// }
3272 /// class Set<E1> {
3273 /// factory Set() => new _LinkedHashSet<E1>();
3274 /// }
3275 /// class List<E2> { ... }
3276 /// class _LinkedHashSet<E3> { ... }
3277 ///
3278 /// After inlining the factory constructor for `Set<E1>`, the HForeignNew
3279 /// should have type `_LinkedHashSet<List<T>>` and the TypeExpression should be
3280 /// a tree:
3281 ///
3282 /// HForeignNew(dartType: _LinkedHashSet<List<T>>,
3283 /// [], // No arguments
3284 /// HTypeInfoExpression(INSTANCE,
3285 /// dartType: _LinkedHashSet<E3>, // _LinkedHashSet's thisType
3286 /// HTypeInfoExpression(COMPLETE, // E3 = List<T>
3287 /// dartType: List<E2>,
3288 /// HTypeInfoReadVariable(this, T)))) // E2 = T
3289
3290 // TODO(sra): The INSTANCE form requires the actual instance for full
3291 // interpretation. If the COMPLETE form was used on instances, then we could
3292 // simplify HTypeInfoReadVariable without an object.
3293
3294 class HTypeInfoExpression extends HInstruction {
3295 final TypeInfoExpressionKind kind;
3296 final DartType dartType;
3297 HTypeInfoExpression(this.kind, this.dartType, List<HInstruction> inputs,
3298 TypeMask instructionType)
3299 : super(inputs, instructionType) {
3300 setUseGvn();
3301 }
3302
3303 accept(HVisitor visitor) => visitor.visitTypeInfoExpression(this);
3304
3305 bool canThrow() => false;
3306
3307 int typeCode() => HInstruction.TYPE_INFO_EXPRESSION_TYPECODE;
3308 bool typeEquals(HInstruction other) => other is HTypeInfoExpression;
3309
3310 bool dataEquals(HTypeInfoExpression other) {
3311 return kind == other.kind && dartType == other.dartType;
3312 }
3313
3314 String toString() => 'HTypeInfoExpression $kindAsString $dartType';
3315
3316 String get kindAsString {
3317 switch (kind) {
3318 case TypeInfoExpressionKind.COMPLETE: return 'COMPLETE';
3319 case TypeInfoExpressionKind.INSTANCE: return 'INSTANCE';
3320 }
3321 }
3322 }
3323
3324
3185 class HReadTypeVariable extends HInstruction { 3325 class HReadTypeVariable extends HInstruction {
3186 /// The type variable being read. 3326 /// The type variable being read.
3187 final TypeVariableType dartType; 3327 final TypeVariableType dartType;
3188 3328
3189 final bool hasReceiver; 3329 final bool hasReceiver;
3190 3330
3191 HReadTypeVariable( 3331 HReadTypeVariable(
3192 this.dartType, HInstruction receiver, TypeMask instructionType) 3332 this.dartType, HInstruction receiver, TypeMask instructionType)
3193 : hasReceiver = true, 3333 : hasReceiver = true,
3194 super(<HInstruction>[receiver], instructionType) { 3334 super(<HInstruction>[receiver], instructionType) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3277 class HDynamicType extends HRuntimeType { 3417 class HDynamicType extends HRuntimeType {
3278 HDynamicType(DynamicType dartType, TypeMask instructionType) 3418 HDynamicType(DynamicType dartType, TypeMask instructionType)
3279 : super(const <HInstruction>[], dartType, instructionType); 3419 : super(const <HInstruction>[], dartType, instructionType);
3280 3420
3281 accept(HVisitor visitor) => visitor.visitDynamicType(this); 3421 accept(HVisitor visitor) => visitor.visitDynamicType(this);
3282 3422
3283 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE; 3423 int typeCode() => HInstruction.DYNAMIC_TYPE_TYPECODE;
3284 3424
3285 bool typeEquals(HInstruction other) => other is HDynamicType; 3425 bool typeEquals(HInstruction other) => other is HDynamicType;
3286 } 3426 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698