OLD | NEW |
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 dart2js.cps_ir.redundant_join_elimination; | 5 library dart2js.cps_ir.redundant_join_elimination; |
6 | 6 |
7 import 'cps_ir_nodes.dart'; | 7 import 'cps_ir_nodes.dart'; |
8 import 'optimizers.dart'; | 8 import 'optimizers.dart'; |
9 | 9 |
10 /// Eliminates redundant join points. | 10 /// Eliminates redundant join points. |
11 /// | 11 /// |
12 /// A redundant join point is a continuation that immediately branches | 12 /// A redundant join point is a continuation that immediately branches |
13 /// based on one of its parameters, and that parameter is a constant value | 13 /// based on one of its parameters, and that parameter is a constant value |
14 /// at every invocation. Each invocation is redirected to jump directly | 14 /// at every invocation. Each invocation is redirected to jump directly |
15 /// to the branch target. | 15 /// to the branch target. |
16 /// | 16 /// |
17 /// Internally in this pass, parameters are treated as names with lexical | 17 /// Internally in this pass, parameters are treated as names with lexical |
18 /// scoping, and a given parameter "name" may be declared by more than | 18 /// scoping, and a given parameter "name" may be declared by more than |
19 /// one continuation. The reference chains for parameters are therefore | 19 /// one continuation. The reference chains for parameters are therefore |
20 /// meaningless during this pass, until repaired by [AlphaRenamer] at | 20 /// meaningless during this pass, until repaired by [AlphaRenamer] at |
21 /// the end. | 21 /// the end. |
22 class RedundantJoinEliminator extends RecursiveVisitor implements Pass { | 22 class RedundantJoinEliminator extends TrampolineRecursiveVisitor implements Pass
{ |
23 String get passName => 'Redundant join elimination'; | 23 String get passName => 'Redundant join elimination'; |
24 | 24 |
25 final Set<Branch> workSet = new Set<Branch>(); | 25 final Set<Branch> workSet = new Set<Branch>(); |
26 | 26 |
27 void rewrite(FunctionDefinition node) { | 27 void rewrite(FunctionDefinition node) { |
28 visit(node); | 28 visit(node); |
29 | 29 |
30 while (workSet.isNotEmpty) { | 30 while (workSet.isNotEmpty) { |
31 Branch branch = workSet.first; | 31 Branch branch = workSet.first; |
32 workSet.remove(branch); | 32 workSet.remove(branch); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 // continuations. [AlphaRenamer] will clean up at the end of this pass. | 132 // continuations. [AlphaRenamer] will clean up at the end of this pass. |
133 LetCont outerLetCont = branchCont.parent; | 133 LetCont outerLetCont = branchCont.parent; |
134 while (branchCont.body is LetCont) { | 134 while (branchCont.body is LetCont) { |
135 LetCont innerLetCont = branchCont.body; | 135 LetCont innerLetCont = branchCont.body; |
136 for (Continuation innerCont in innerLetCont.continuations) { | 136 for (Continuation innerCont in innerLetCont.continuations) { |
137 innerCont.parameters.addAll(branchCont.parameters); | 137 innerCont.parameters.addAll(branchCont.parameters); |
138 for (Reference ref = innerCont.firstRef; ref != null; ref = ref.next) { | 138 for (Reference ref = innerCont.firstRef; ref != null; ref = ref.next) { |
139 Expression use = ref.parent; | 139 Expression use = ref.parent; |
140 if (use is InvokeContinuation) { | 140 if (use is InvokeContinuation) { |
141 for (Parameter param in branchCont.parameters) { | 141 for (Parameter param in branchCont.parameters) { |
142 use.arguments.add(new Reference<Primitive>(param)); | 142 use.arguments.add(new Reference<Primitive>(param)..parent = use); |
143 } | 143 } |
144 } else { | 144 } else { |
145 // The branch will be eliminated, so don't worry about updating it. | 145 // The branch will be eliminated, so don't worry about updating it. |
146 assert(use == branch); | 146 assert(use == branch); |
147 } | 147 } |
148 } | 148 } |
149 } | 149 } |
150 innerLetCont.remove(); | 150 innerLetCont.remove(); |
151 innerLetCont.insertAbove(outerLetCont); | 151 innerLetCont.insertAbove(outerLetCont); |
152 } | 152 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 /// => | 208 /// => |
209 /// LetCont (k1 x = (return x)) in | 209 /// LetCont (k1 x = (return x)) in |
210 /// LetCont (k2 x' = (InvokeContinuation k3 x')) in ... | 210 /// LetCont (k2 x' = (InvokeContinuation k3 x')) in ... |
211 /// | 211 /// |
212 /// After lifting LetConts in the main pass above, parameter objects can have | 212 /// After lifting LetConts in the main pass above, parameter objects can have |
213 /// multiple bindings. Each reference implicitly refers to the binding that | 213 /// multiple bindings. Each reference implicitly refers to the binding that |
214 /// is currently in scope. | 214 /// is currently in scope. |
215 /// | 215 /// |
216 /// This returns the IR to its normal form after redundant joins have been | 216 /// This returns the IR to its normal form after redundant joins have been |
217 /// eliminated. | 217 /// eliminated. |
218 class AlphaRenamer extends RecursiveVisitor { | 218 class AlphaRenamer extends TrampolineRecursiveVisitor { |
219 Map<Parameter, Parameter> renaming = <Parameter, Parameter>{}; | 219 Map<Parameter, Parameter> renaming = <Parameter, Parameter>{}; |
220 | 220 |
221 processContinuation(Continuation cont) { | 221 processContinuation(Continuation cont) { |
222 if (cont.isReturnContinuation) return; | 222 if (cont.isReturnContinuation) return; |
223 | 223 |
224 List<Parameter> shadowedKeys = <Parameter>[]; | 224 List<Parameter> shadowedKeys = <Parameter>[]; |
225 List<Parameter> shadowedValues = <Parameter>[]; | 225 List<Parameter> shadowedValues = <Parameter>[]; |
226 | 226 |
227 // Create new parameters and update the environment. | 227 // Create new parameters and update the environment. |
228 for (int i = 0; i < cont.parameters.length; ++i) { | 228 for (int i = 0; i < cont.parameters.length; ++i) { |
(...skipping 22 matching lines...) Expand all Loading... |
251 }); | 251 }); |
252 } | 252 } |
253 | 253 |
254 processReference(Reference ref) { | 254 processReference(Reference ref) { |
255 Parameter target = renaming[ref.definition]; | 255 Parameter target = renaming[ref.definition]; |
256 if (target != null) { | 256 if (target != null) { |
257 ref.changeTo(target); | 257 ref.changeTo(target); |
258 } | 258 } |
259 } | 259 } |
260 } | 260 } |
OLD | NEW |