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

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

Issue 1375213003: dart2js cps: Maintain parent pointers instead of recomputing them. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix 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 'shrinking_reductions.dart' show ParentVisitor;
9 import 'cps_ir_nodes.dart'; 8 import 'cps_ir_nodes.dart';
10 import '../types/constants.dart'; 9 import '../types/constants.dart';
11 import '../constants/values.dart'; 10 import '../constants/values.dart';
12 import '../common/names.dart'; 11 import '../common/names.dart';
13 import '../universe/universe.dart'; 12 import '../universe/universe.dart';
14 import '../elements/elements.dart'; 13 import '../elements/elements.dart';
15 import '../types/types.dart' show TypeMask; 14 import '../types/types.dart' show TypeMask;
16 import 'type_mask_system.dart'; 15 import 'type_mask_system.dart';
17 16
18 /// Inserts [Refinement] nodes in the IR to allow for sparse path-sensitive 17 /// Inserts [Refinement] nodes in the IR to allow for sparse path-sensitive
19 /// type analysis in the [TypePropagator] pass. 18 /// type analysis in the [TypePropagator] pass.
20 /// 19 ///
21 /// Refinement nodes are inserted at the arms of a [Branch] node with a 20 /// Refinement nodes are inserted at the arms of a [Branch] node with a
22 /// condition of form `x is T` or `x == null`. 21 /// condition of form `x is T` or `x == null`.
23 /// 22 ///
24 /// Refinement nodes are inserted after a method invocation to refine the 23 /// Refinement nodes are inserted after a method invocation to refine the
25 /// receiver to the types that can respond to the given selector. 24 /// receiver to the types that can respond to the given selector.
26 class InsertRefinements extends RecursiveVisitor implements Pass { 25 class InsertRefinements extends TrampolineRecursiveVisitor implements Pass {
27 String get passName => 'Insert refinement nodes'; 26 String get passName => 'Insert refinement nodes';
28 27
29 final TypeMaskSystem types; 28 final TypeMaskSystem types;
30 29
31 /// Maps unrefined primitives to its refinement currently in scope (if any). 30 /// Maps unrefined primitives to its refinement currently in scope (if any).
32 final Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{}; 31 final Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{};
33 32
34 InsertRefinements(this.types); 33 InsertRefinements(this.types);
35 34
36 void rewrite(FunctionDefinition node) { 35 void rewrite(FunctionDefinition node) {
37 new ParentVisitor().visit(node);
38 visit(node.body); 36 visit(node.body);
39 } 37 }
40 38
41 /// Updates references to refer to the refinement currently in scope. 39 /// Updates references to refer to the refinement currently in scope.
42 void processReference(Reference node) { 40 void processReference(Reference node) {
43 Refinement refined = refinementFor[node.definition]; 41 Refinement refined = refinementFor[node.definition];
44 if (refined != null) { 42 if (refined != null) {
45 node.changeTo(refined); 43 node.changeTo(refined);
46 } 44 }
47 } 45 }
(...skipping 25 matching lines...) Expand all
73 let.insertAbove(use); 71 let.insertAbove(use);
74 } 72 }
75 73
76 Primitive unfoldInterceptor(Primitive prim) { 74 Primitive unfoldInterceptor(Primitive prim) {
77 return prim is Interceptor ? prim.input.definition : prim; 75 return prim is Interceptor ? prim.input.definition : prim;
78 } 76 }
79 77
80 /// Enqueues [cont] for processing in a context where [refined] is the 78 /// Enqueues [cont] for processing in a context where [refined] is the
81 /// current refinement for its value. 79 /// current refinement for its value.
82 void pushRefinement(Continuation cont, Refinement refined) { 80 void pushRefinement(Continuation cont, Refinement refined) {
81 refined.value.parent = refined;
Kevin Millikin (Google) 2015/10/05 12:04:37 Is this necessary here? It looks like the constru
asgerf 2015/10/12 13:18:32 You're right, done.
83 Primitive value = refined.effectiveDefinition; 82 Primitive value = refined.effectiveDefinition;
84 Primitive currentRefinement = refinementFor[value]; 83 Primitive currentRefinement = refinementFor[value];
85 pushAction(() { 84 pushAction(() {
86 refinementFor[value] = currentRefinement; 85 refinementFor[value] = currentRefinement;
87 if (refined.hasNoUses) { 86 if (refined.hasNoUses) {
88 // Clean up refinements that are not used. 87 // Clean up refinements that are not used.
89 refined.destroy(); 88 refined.destroy();
90 } else { 89 } else {
91 LetPrim let = new LetPrim(refined); 90 LetPrim let = new LetPrim(refined);
92 refined.parent = let; 91 refined.parent = let;
(...skipping 21 matching lines...) Expand all
114 // here is also in scope inside the continuations. 113 // here is also in scope inside the continuations.
115 sinkContinuationToUse(cont, node); 114 sinkContinuationToUse(cont, node);
116 115
117 if (node.selector.isClosureCall) { 116 if (node.selector.isClosureCall) {
118 // Do not try to refine the receiver of closure calls; the class world 117 // Do not try to refine the receiver of closure calls; the class world
119 // does not know about closure classes. 118 // does not know about closure classes.
120 push(cont); 119 push(cont);
121 } else { 120 } else {
122 // Filter away receivers that throw on this selector. 121 // Filter away receivers that throw on this selector.
123 TypeMask type = types.receiverTypeFor(node.selector, node.mask); 122 TypeMask type = types.receiverTypeFor(node.selector, node.mask);
124 pushRefinement(cont, new Refinement(receiver, type)); 123 Refinement refinement = new Refinement(receiver, type);
124 pushRefinement(cont, refinement);
125 } 125 }
126 } 126 }
127 127
128 CallExpression getCallWithResult(Primitive prim) { 128 CallExpression getCallWithResult(Primitive prim) {
129 if (prim is Parameter && prim.parent is Continuation) { 129 if (prim is Parameter && prim.parent is Continuation) {
130 Continuation cont = prim.parent; 130 Continuation cont = prim.parent;
131 if (cont.hasExactlyOneUse && cont.firstRef.parent is CallExpression) { 131 if (cont.hasExactlyOneUse && cont.firstRef.parent is CallExpression) {
132 return cont.firstRef.parent; 132 return cont.firstRef.parent;
133 } 133 }
134 } 134 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 cont.firstRef.parent is Branch)) { 215 cont.firstRef.parent is Branch)) {
216 // Do not push the continuation here. 216 // Do not push the continuation here.
217 // visitInvokeMethod and visitBranch will do that. 217 // visitInvokeMethod and visitBranch will do that.
218 } else { 218 } else {
219 push(cont); 219 push(cont);
220 } 220 }
221 } 221 }
222 return node.body; 222 return node.body;
223 } 223 }
224 } 224 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698