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: |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 && !input.isJsStatement()) { | 51 && !input.isJsStatement()) { |
52 if (input.isPure()) { | 52 if (input.isPure()) { |
53 // Only consider a pure input if it is in the same loop. | 53 // Only consider a pure input if it is in the same loop. |
54 // Otherwise, we might move GVN'ed instruction back into the | 54 // Otherwise, we might move GVN'ed instruction back into the |
55 // loop. | 55 // loop. |
56 if (user.hasSameLoopHeaderAs(input)) { | 56 if (user.hasSameLoopHeaderAs(input)) { |
57 // Move it closer to [user], so that instructions in | 57 // Move it closer to [user], so that instructions in |
58 // between do not prevent making it generate at use site. | 58 // between do not prevent making it generate at use site. |
59 input.moveBefore(user); | 59 input.moveBefore(user); |
60 pureInputs.add(input); | 60 pureInputs.add(input); |
| 61 // Previous computations done on [input] are now invalid |
| 62 // because we moved [input] to another place. So all |
| 63 // non code motion invariant instructions need |
| 64 // to be removed from the [generateAtUseSite] set. |
| 65 input.inputs.forEach((instruction) { |
| 66 if (!instruction.isCodeMotionInvariant()) { |
| 67 generateAtUseSite.remove(instruction); |
| 68 } |
| 69 }); |
61 // Visit the pure input now so that the expected inputs | 70 // Visit the pure input now so that the expected inputs |
62 // are after the expected inputs of [user]. | 71 // are after the expected inputs of [user]. |
63 input.accept(this); | 72 input.accept(this); |
64 } | 73 } |
65 } else { | 74 } else { |
66 expectedInputs.add(input); | 75 expectedInputs.add(input); |
67 } | 76 } |
68 } | 77 } |
69 } | 78 } |
70 } | 79 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 assert(!generateAtUseSite.contains(nextInput)); | 162 assert(!generateAtUseSite.contains(nextInput)); |
154 assert(nextInput.usedBy.length == 1); | 163 assert(nextInput.usedBy.length == 1); |
155 if (identical(nextInput, instruction)) { | 164 if (identical(nextInput, instruction)) { |
156 return true; | 165 return true; |
157 } | 166 } |
158 } | 167 } |
159 return false; | 168 return false; |
160 } | 169 } |
161 | 170 |
162 block.last.accept(this); | 171 block.last.accept(this); |
163 bool dontVisitPure = false; | |
164 for (HInstruction instruction = block.last.previous; | 172 for (HInstruction instruction = block.last.previous; |
165 instruction != null; | 173 instruction != null; |
166 instruction = instruction.previous) { | 174 instruction = instruction.previous) { |
167 if (generateAtUseSite.contains(instruction)) { | 175 if (generateAtUseSite.contains(instruction)) { |
168 continue; | 176 continue; |
169 } | 177 } |
170 if (instruction.isCodeMotionInvariant()) { | 178 if (instruction.isCodeMotionInvariant()) { |
171 markAsGenerateAtUseSite(instruction); | 179 markAsGenerateAtUseSite(instruction); |
172 continue; | 180 continue; |
173 } | 181 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } | 372 } |
365 | 373 |
366 // If [thenInput] is defined in the first predecessor, then it is only used | 374 // If [thenInput] is defined in the first predecessor, then it is only used |
367 // by [phi] and can be generated at use site. | 375 // by [phi] and can be generated at use site. |
368 if (identical(thenInput.block, end.predecessors[0])) { | 376 if (identical(thenInput.block, end.predecessors[0])) { |
369 assert(thenInput.usedBy.length == 1); | 377 assert(thenInput.usedBy.length == 1); |
370 markAsGenerateAtUseSite(thenInput); | 378 markAsGenerateAtUseSite(thenInput); |
371 } | 379 } |
372 } | 380 } |
373 } | 381 } |
OLD | NEW |