| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Instead of emitting each SSA instruction with a temporary variable | 8 * Instead of emitting each SSA instruction with a temporary variable |
| 9 * mark instructions that can be emitted at their use-site. | 9 * mark instructions that can be emitted at their use-site. |
| 10 * For example, in: | 10 * For example, in: |
| 11 * t0 = 4; | 11 * t0 = 4; |
| 12 * t1 = 3; | 12 * t1 = 3; |
| 13 * t2 = add(t0, t1); | 13 * t2 = add(t0, t1); |
| 14 * t0 and t1 would be marked and the resulting code would then be: | 14 * t0 and t1 would be marked and the resulting code would then be: |
| 15 * t2 = add(4, 3); | 15 * t2 = add(4, 3); |
| 16 */ | 16 */ |
| 17 class SsaInstructionMerger extends HBaseVisitor { | 17 class SsaInstructionMerger extends HBaseVisitor { |
| 18 final Compiler compiler; |
| 18 /** | 19 /** |
| 19 * List of [HInstruction] that the instruction merger expects in | 20 * List of [HInstruction] that the instruction merger expects in |
| 20 * order when visiting the inputs of an instruction. | 21 * order when visiting the inputs of an instruction. |
| 21 */ | 22 */ |
| 22 List<HInstruction> expectedInputs; | 23 List<HInstruction> expectedInputs; |
| 23 /** | 24 /** |
| 24 * Set of pure [HInstruction] that the instruction merger expects to | 25 * Set of pure [HInstruction] that the instruction merger expects to |
| 25 * find. The order of pure instructions do not matter, as they will | 26 * find. The order of pure instructions do not matter, as they will |
| 26 * not be affected by side effects. | 27 * not be affected by side effects. |
| 27 */ | 28 */ |
| 28 Set<HInstruction> pureInputs; | 29 Set<HInstruction> pureInputs; |
| 29 Set<HInstruction> generateAtUseSite; | 30 Set<HInstruction> generateAtUseSite; |
| 30 | 31 |
| 31 void markAsGenerateAtUseSite(HInstruction instruction) { | 32 void markAsGenerateAtUseSite(HInstruction instruction) { |
| 32 assert(!instruction.isJsStatement()); | 33 assert(!instruction.isJsStatement()); |
| 33 generateAtUseSite.add(instruction); | 34 generateAtUseSite.add(instruction); |
| 34 } | 35 } |
| 35 | 36 |
| 36 SsaInstructionMerger(this.generateAtUseSite); | 37 SsaInstructionMerger(this.generateAtUseSite, this.compiler); |
| 37 | 38 |
| 38 void visitGraph(HGraph graph) { | 39 void visitGraph(HGraph graph) { |
| 39 visitDominatorTree(graph); | 40 visitDominatorTree(graph); |
| 40 } | 41 } |
| 41 | 42 |
| 42 void analyzeInputs(HInstruction user, int start) { | 43 void analyzeInputs(HInstruction user, int start) { |
| 43 List<HInstruction> inputs = user.inputs; | 44 List<HInstruction> inputs = user.inputs; |
| 44 for (int i = start; i < inputs.length; i++) { | 45 for (int i = start; i < inputs.length; i++) { |
| 45 HInstruction input = inputs[i]; | 46 HInstruction input = inputs[i]; |
| 46 if (!generateAtUseSite.contains(input) | 47 if (!generateAtUseSite.contains(input) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 // A type guard should not generate its input at use site, otherwise | 98 // A type guard should not generate its input at use site, otherwise |
| 98 // they would not be alive. | 99 // they would not be alive. |
| 99 void visitTypeGuard(HTypeGuard instruction) {} | 100 void visitTypeGuard(HTypeGuard instruction) {} |
| 100 | 101 |
| 101 // An identity operation must only have its inputs generated at use site if | 102 // An identity operation must only have its inputs generated at use site if |
| 102 // does not require an expression with multiple uses (because of null / | 103 // does not require an expression with multiple uses (because of null / |
| 103 // undefined). | 104 // undefined). |
| 104 void visitIdentity(HIdentity instruction) { | 105 void visitIdentity(HIdentity instruction) { |
| 105 HInstruction left = instruction.left; | 106 HInstruction left = instruction.left; |
| 106 HInstruction right = instruction.right; | 107 HInstruction right = instruction.right; |
| 107 if (singleIdentityComparison(left, right) != null) { | 108 if (singleIdentityComparison(left, right, compiler) != null) { |
| 108 super.visitIdentity(instruction); | 109 super.visitIdentity(instruction); |
| 109 } | 110 } |
| 110 // Do nothing. | 111 // Do nothing. |
| 111 } | 112 } |
| 112 | 113 |
| 113 void visitTypeConversion(HTypeConversion instruction) { | 114 void visitTypeConversion(HTypeConversion instruction) { |
| 114 if (!instruction.isChecked) { | 115 if (!instruction.isChecked) { |
| 115 markAsGenerateAtUseSite(instruction); | 116 markAsGenerateAtUseSite(instruction); |
| 116 } else if (!instruction.isArgumentTypeCheck | 117 } else if (!instruction.isArgumentTypeCheck |
| 117 && !instruction.isReceiverTypeCheck) { | 118 && !instruction.isReceiverTypeCheck) { |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 } | 379 } |
| 379 | 380 |
| 380 // If [thenInput] is defined in the first predecessor, then it is only used | 381 // If [thenInput] is defined in the first predecessor, then it is only used |
| 381 // by [phi] and can be generated at use site. | 382 // by [phi] and can be generated at use site. |
| 382 if (identical(thenInput.block, end.predecessors[0])) { | 383 if (identical(thenInput.block, end.predecessors[0])) { |
| 383 assert(thenInput.usedBy.length == 1); | 384 assert(thenInput.usedBy.length == 1); |
| 384 markAsGenerateAtUseSite(thenInput); | 385 markAsGenerateAtUseSite(thenInput); |
| 385 } | 386 } |
| 386 } | 387 } |
| 387 } | 388 } |
| OLD | NEW |