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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/insert_refinements.dart

Issue 1408783004: dart2js cps: Support --trust-primitives and --trust-type-annotations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge Created 5 years, 2 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 library cps_ir.optimization.insert_refinements; 5 library cps_ir.optimization.insert_refinements;
6 6
7 import 'optimizers.dart' show Pass; 7 import 'optimizers.dart' show Pass;
8 import 'cps_ir_nodes.dart'; 8 import 'cps_ir_nodes.dart';
9 import '../common/names.dart'; 9 import '../common/names.dart';
10 import '../types/types.dart' show TypeMask; 10 import '../types/types.dart' show TypeMask;
11 import 'type_mask_system.dart'; 11 import 'type_mask_system.dart';
12 import 'cps_fragment.dart';
12 13
13 /// Inserts [Refinement] nodes in the IR to allow for sparse path-sensitive 14 /// Inserts [Refinement] nodes in the IR to allow for sparse path-sensitive
14 /// type analysis in the [TypePropagator] pass. 15 /// type analysis in the [TypePropagator] pass.
15 /// 16 ///
16 /// Refinement nodes are inserted at the arms of a [Branch] node with a 17 /// Refinement nodes are inserted at the arms of a [Branch] node with a
17 /// condition of form `x is T` or `x == null`. 18 /// condition of form `x is T` or `x == null`.
18 /// 19 ///
19 /// Refinement nodes are inserted after a method invocation to refine the 20 /// Refinement nodes are inserted after a method invocation to refine the
20 /// receiver to the types that can respond to the given selector. 21 /// receiver to the types that can respond to the given selector.
21 class InsertRefinements extends TrampolineRecursiveVisitor implements Pass { 22 class InsertRefinements extends TrampolineRecursiveVisitor implements Pass {
22 String get passName => 'Insert refinement nodes'; 23 String get passName => 'Insert refinement nodes';
23 24
24 final TypeMaskSystem types; 25 final TypeMaskSystem types;
25 26
26 /// Maps unrefined primitives to its refinement currently in scope (if any). 27 /// Maps unrefined primitives to its refinement currently in scope (if any).
27 final Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{}; 28 final Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{};
28 29
29 InsertRefinements(this.types); 30 InsertRefinements(this.types);
30 31
31 void rewrite(FunctionDefinition node) { 32 void rewrite(FunctionDefinition node) {
32 visit(node.body); 33 visit(node.body);
33 } 34 }
34 35
35 /// Updates references to refer to the refinement currently in scope. 36 /// Updates references to refer to the refinement currently in scope.
36 void processReference(Reference node) { 37 void processReference(Reference node) {
37 Refinement refined = refinementFor[node.definition]; 38 Definition definition = node.definition;
38 if (refined != null) { 39 if (definition is Primitive) {
39 node.changeTo(refined); 40 Primitive prim = definition.effectiveDefinition;
41 Refinement refined = refinementFor[prim];
42 if (refined != null && refined != definition) {
43 node.changeTo(refined);
44 }
40 } 45 }
41 } 46 }
42 47
43 /// Sinks the binding of [cont] to immediately above [use]. 48 /// Sinks the binding of [cont] to immediately above [use].
44 /// 49 ///
45 /// This is used to ensure that everything in scope at [use] is also in scope 50 /// This is used to ensure that everything in scope at [use] is also in scope
46 /// inside [cont], so refinements can be inserted inside [cont] without 51 /// inside [cont], so refinements can be inserted inside [cont] without
47 /// accidentally referencing a primitive out of scope. 52 /// accidentally referencing a primitive out of scope.
48 /// 53 ///
49 /// It is always safe to do this for single-use continuations, because 54 /// It is always safe to do this for single-use continuations, because
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 // does not know about closure classes. 116 // does not know about closure classes.
112 push(cont); 117 push(cont);
113 } else { 118 } else {
114 // Filter away receivers that throw on this selector. 119 // Filter away receivers that throw on this selector.
115 TypeMask type = types.receiverTypeFor(node.selector, node.mask); 120 TypeMask type = types.receiverTypeFor(node.selector, node.mask);
116 Refinement refinement = new Refinement(receiver, type); 121 Refinement refinement = new Refinement(receiver, type);
117 pushRefinement(cont, refinement); 122 pushRefinement(cont, refinement);
118 } 123 }
119 } 124 }
120 125
126 void visitTypeCast(TypeCast node) {
127 Continuation cont = node.continuation.definition;
128 Primitive value = node.value.definition;
129
130 processReference(node.value);
131 node.typeArguments.forEach(processReference);
132
133 // Refine the type of the input.
134 sinkContinuationToUse(cont, node);
135 TypeMask type = types.subtypesOf(node.dartType).nullable();
136 Refinement refinement = new Refinement(value, type);
137 pushRefinement(cont, refinement);
138 }
139
140 void visitRefinement(Refinement node) {
141 // We found a pre-existing refinement node. These are generated by the
142 // IR builder to hold information from --trust-type-annotations.
143 // Update its input to use our own current refinement, then update the
144 // environment to use this refinement.
145 processReference(node.value);
146 Primitive value = node.value.definition.effectiveDefinition;
147 Primitive oldRefinement = refinementFor[value];
148 refinementFor[value] = node;
149 pushAction(() {
150 refinementFor[value] = oldRefinement;
151 });
152 }
153
121 CallExpression getCallWithResult(Primitive prim) { 154 CallExpression getCallWithResult(Primitive prim) {
122 if (prim is Parameter && prim.parent is Continuation) { 155 if (prim is Parameter && prim.parent is Continuation) {
123 Continuation cont = prim.parent; 156 Continuation cont = prim.parent;
124 if (cont.hasExactlyOneUse && cont.firstRef.parent is CallExpression) { 157 if (cont.hasExactlyOneUse && cont.firstRef.parent is CallExpression) {
125 return cont.firstRef.parent; 158 return cont.firstRef.parent;
126 } 159 }
127 } 160 }
128 return null; 161 return null;
129 } 162 }
130 163
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 231
199 push(trueCont); 232 push(trueCont);
200 push(falseCont); 233 push(falseCont);
201 } 234 }
202 235
203 @override 236 @override
204 Expression traverseLetCont(LetCont node) { 237 Expression traverseLetCont(LetCont node) {
205 for (Continuation cont in node.continuations) { 238 for (Continuation cont in node.continuations) {
206 if (cont.hasExactlyOneUse && 239 if (cont.hasExactlyOneUse &&
207 (cont.firstRef.parent is InvokeMethod || 240 (cont.firstRef.parent is InvokeMethod ||
241 cont.firstRef.parent is TypeCast ||
208 cont.firstRef.parent is Branch)) { 242 cont.firstRef.parent is Branch)) {
209 // Do not push the continuation here. 243 // Do not push the continuation here.
210 // visitInvokeMethod and visitBranch will do that. 244 // visitInvokeMethod, visitBranch, and visitTypeCast will do that.
211 } else { 245 } else {
212 push(cont); 246 push(cont);
213 } 247 }
214 } 248 }
215 return node.body; 249 return node.body;
216 } 250 }
217 } 251 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart ('k') | pkg/compiler/lib/src/cps_ir/remove_refinements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698