OLD | NEW |
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 interface OptimizationPhase { | 5 interface OptimizationPhase { |
6 String get name(); | 6 String get name(); |
7 void visitGraph(HGraph graph); | 7 void visitGraph(HGraph graph); |
8 } | 8 } |
9 | 9 |
10 class SsaOptimizerTask extends CompilerTask { | 10 class SsaOptimizerTask extends CompilerTask { |
11 final JavaScriptBackend backend; | 11 final JavaScriptBackend backend; |
12 SsaOptimizerTask(JavaScriptBackend backend) | 12 SsaOptimizerTask(JavaScriptBackend backend) |
13 : this.backend = backend, | 13 : this.backend = backend, |
14 super(backend.compiler); | 14 super(backend.compiler); |
15 String get name() => 'SSA optimizer'; | 15 String get name() => 'SSA optimizer'; |
16 Compiler get compiler() => backend.compiler; | 16 Compiler get compiler() => backend.compiler; |
17 | 17 |
18 void runPhases(HGraph graph, List<OptimizationPhase> phases) { | 18 void runPhases(HGraph graph, List<OptimizationPhase> phases) { |
19 for (OptimizationPhase phase in phases) { | 19 for (OptimizationPhase phase in phases) { |
20 phase.visitGraph(graph); | 20 phase.visitGraph(graph); |
21 compiler.tracer.traceGraph(phase.name, graph); | 21 compiler.tracer.traceGraph(phase.name, graph); |
22 } | 22 } |
23 } | 23 } |
24 | 24 |
25 void optimize(WorkItem work, HGraph graph) { | 25 void optimize(WorkItem work, HGraph graph) { |
| 26 FoldingOperations foldingOperations = |
| 27 compiler.constantHandler.foldingOperations; |
26 measure(() { | 28 measure(() { |
27 List<OptimizationPhase> phases = <OptimizationPhase>[ | 29 List<OptimizationPhase> phases = <OptimizationPhase>[ |
28 // Run trivial constant folding first to optimize | 30 // Run trivial constant folding first to optimize |
29 // some patterns useful for type conversion. | 31 // some patterns useful for type conversion. |
30 new SsaConstantFolder(backend, work), | 32 new SsaConstantFolder(foldingOperations, backend, work), |
31 new SsaTypeConversionInserter(compiler), | 33 new SsaTypeConversionInserter(compiler), |
32 new SsaTypePropagator(compiler), | 34 new SsaTypePropagator(compiler), |
33 new SsaCheckInserter(backend), | 35 new SsaCheckInserter(backend), |
34 new SsaConstantFolder(backend, work), | 36 new SsaConstantFolder(foldingOperations, backend, work), |
35 new SsaRedundantPhiEliminator(), | 37 new SsaRedundantPhiEliminator(), |
36 new SsaDeadPhiEliminator(), | 38 new SsaDeadPhiEliminator(), |
37 new SsaGlobalValueNumberer(compiler), | 39 new SsaGlobalValueNumberer(compiler), |
38 new SsaCodeMotion(), | 40 new SsaCodeMotion(), |
39 new SsaDeadCodeEliminator(), | 41 new SsaDeadCodeEliminator(), |
40 new SsaRegisterRecompilationCandidates(backend, work)]; | 42 new SsaRegisterRecompilationCandidates(backend, work)]; |
41 runPhases(graph, phases); | 43 runPhases(graph, phases); |
42 }); | 44 }); |
43 } | 45 } |
44 | 46 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 } | 88 } |
87 | 89 |
88 /** | 90 /** |
89 * If both inputs to known operations are available execute the operation at | 91 * If both inputs to known operations are available execute the operation at |
90 * compile-time. | 92 * compile-time. |
91 */ | 93 */ |
92 class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { | 94 class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
93 final String name = "SsaConstantFolder"; | 95 final String name = "SsaConstantFolder"; |
94 final JavaScriptBackend backend; | 96 final JavaScriptBackend backend; |
95 final WorkItem work; | 97 final WorkItem work; |
| 98 final FoldingOperations foldingOperations; |
96 HGraph graph; | 99 HGraph graph; |
97 Compiler get compiler() => backend.compiler; | 100 Compiler get compiler() => backend.compiler; |
98 | 101 |
99 SsaConstantFolder(this.backend, this.work); | 102 SsaConstantFolder(this.foldingOperations, this.backend, this.work); |
100 | 103 |
101 void visitGraph(HGraph visitee) { | 104 void visitGraph(HGraph visitee) { |
102 graph = visitee; | 105 graph = visitee; |
103 visitDominatorTree(visitee); | 106 visitDominatorTree(visitee); |
104 } | 107 } |
105 | 108 |
106 visitBasicBlock(HBasicBlock block) { | 109 visitBasicBlock(HBasicBlock block) { |
107 HInstruction instruction = block.first; | 110 HInstruction instruction = block.first; |
108 while (instruction !== null) { | 111 while (instruction !== null) { |
109 HInstruction next = instruction.next; | 112 HInstruction next = instruction.next; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 return graph.addConstantBool(!isTrue); | 161 return graph.addConstantBool(!isTrue); |
159 } else if (input is HNot) { | 162 } else if (input is HNot) { |
160 return input.inputs[0]; | 163 return input.inputs[0]; |
161 } | 164 } |
162 return node; | 165 return node; |
163 } | 166 } |
164 | 167 |
165 HInstruction visitInvokeUnary(HInvokeUnary node) { | 168 HInstruction visitInvokeUnary(HInvokeUnary node) { |
166 HInstruction operand = node.operand; | 169 HInstruction operand = node.operand; |
167 if (operand is HConstant) { | 170 if (operand is HConstant) { |
168 UnaryOperation operation = node.operation; | 171 UnaryOperation operation = node.operation(foldingOperations); |
169 HConstant receiver = operand; | 172 HConstant receiver = operand; |
170 Constant folded = operation.fold(receiver.constant); | 173 Constant folded = operation.fold(receiver.constant); |
171 if (folded !== null) return graph.addConstant(folded); | 174 if (folded !== null) return graph.addConstant(folded); |
172 } | 175 } |
173 return node; | 176 return node; |
174 } | 177 } |
175 | 178 |
176 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { | 179 HInstruction visitInvokeInterceptor(HInvokeInterceptor node) { |
177 HInstruction input = node.inputs[1]; | 180 HInstruction input = node.inputs[1]; |
178 if (node.isLengthGetter()) { | 181 if (node.isLengthGetter()) { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 if (!node.receiver.canBePrimitive()) { | 315 if (!node.receiver.canBePrimitive()) { |
313 Selector selector = new Selector.indexSet(); | 316 Selector selector = new Selector.indexSet(); |
314 return fromInterceptorToDynamicInvocation(node, selector); | 317 return fromInterceptorToDynamicInvocation(node, selector); |
315 } | 318 } |
316 return node; | 319 return node; |
317 } | 320 } |
318 | 321 |
319 HInstruction visitInvokeBinary(HInvokeBinary node) { | 322 HInstruction visitInvokeBinary(HInvokeBinary node) { |
320 HInstruction left = node.left; | 323 HInstruction left = node.left; |
321 HInstruction right = node.right; | 324 HInstruction right = node.right; |
| 325 BinaryOperation operation = node.operation(foldingOperations); |
322 if (left is HConstant && right is HConstant) { | 326 if (left is HConstant && right is HConstant) { |
323 BinaryOperation operation = node.operation; | |
324 HConstant op1 = left; | 327 HConstant op1 = left; |
325 HConstant op2 = right; | 328 HConstant op2 = right; |
326 Constant folded = operation.fold(op1.constant, op2.constant); | 329 Constant folded = operation.fold(op1.constant, op2.constant); |
327 if (folded !== null) return graph.addConstant(folded); | 330 if (folded !== null) return graph.addConstant(folded); |
328 } | 331 } |
329 | 332 |
330 if (!left.canBePrimitive() | 333 if (!left.canBePrimitive() |
331 && node.operation.isUserDefinable() | 334 && operation.isUserDefinable() |
332 // The equals operation is being optimized in visitEquals. | 335 // The equals operation is being optimized in visitEquals. |
333 && node.operation !== const EqualsOperation()) { | 336 && node is! HEquals) { |
334 Selector selector = new Selector.binaryOperator(node.operation.name); | 337 Selector selector = new Selector.binaryOperator(operation.name); |
335 return fromInterceptorToDynamicInvocation(node, selector); | 338 return fromInterceptorToDynamicInvocation(node, selector); |
336 } | 339 } |
337 return node; | 340 return node; |
338 } | 341 } |
339 | 342 |
340 bool allUsersAreBoolifies(HInstruction instruction) { | 343 bool allUsersAreBoolifies(HInstruction instruction) { |
341 List<HInstruction> users = instruction.usedBy; | 344 List<HInstruction> users = instruction.usedBy; |
342 int length = users.length; | 345 int length = users.length; |
343 for (int i = 0; i < length; i++) { | 346 for (int i = 0; i < length; i++) { |
344 if (users[i] is! HBoolify) return false; | 347 if (users[i] is! HBoolify) return false; |
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1306 // this type for the field is still a strong signal | 1309 // this type for the field is still a strong signal |
1307 // indicating the expected type of the field. | 1310 // indicating the expected type of the field. |
1308 field.propagatedType = type; | 1311 field.propagatedType = type; |
1309 } else { | 1312 } else { |
1310 // If there are no invoked setters we know the type of | 1313 // If there are no invoked setters we know the type of |
1311 // this field for sure. | 1314 // this field for sure. |
1312 field.guaranteedType = type; | 1315 field.guaranteedType = type; |
1313 } | 1316 } |
1314 } | 1317 } |
1315 } | 1318 } |
OLD | NEW |