| 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 * The [LiveRange] class covers a range where an instruction is live. | 8 * The [LiveRange] class covers a range where an instruction is live. |
| 9 */ | 9 */ |
| 10 class LiveRange { | 10 class LiveRange { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 | 217 |
| 218 void markInputsAsLiveInEnvironment(HInstruction instruction, | 218 void markInputsAsLiveInEnvironment(HInstruction instruction, |
| 219 LiveEnvironment environment) { | 219 LiveEnvironment environment) { |
| 220 for (int i = 0, len = instruction.inputs.length; i < len; i++) { | 220 for (int i = 0, len = instruction.inputs.length; i < len; i++) { |
| 221 markAsLiveInEnvironment(instruction.inputs[i], environment); | 221 markAsLiveInEnvironment(instruction.inputs[i], environment); |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 HInstruction unwrap(instruction) { | |
| 226 do { | |
| 227 instruction = instruction.checkedInput; | |
| 228 } while (instruction is HCheck); | |
| 229 return instruction; | |
| 230 } | |
| 231 | |
| 232 void markAsLiveInEnvironment(HInstruction instruction, | 225 void markAsLiveInEnvironment(HInstruction instruction, |
| 233 LiveEnvironment environment) { | 226 LiveEnvironment environment) { |
| 234 if (generateAtUseSite.contains(instruction)) { | 227 if (generateAtUseSite.contains(instruction)) { |
| 235 markInputsAsLiveInEnvironment(instruction, environment); | 228 markInputsAsLiveInEnvironment(instruction, environment); |
| 236 } else { | 229 } else { |
| 237 environment.add(instruction, instructionId); | 230 environment.add(instruction, instructionId); |
| 238 // Special case the HCheck instruction to mark the actual | 231 // Special case the HCheck instruction to mark the actual |
| 239 // checked instruction live. The checked instruction and the | 232 // checked instruction live. The checked instruction and the |
| 240 // [HCheck] will share the same live ranges. | 233 // [HCheck] will share the same live ranges. |
| 241 if (instruction is HCheck) { | 234 if (instruction is HCheck) { |
| 242 HInstruction checked = unwrap(instruction); | 235 HCheck check = instruction; |
| 236 HInstruction checked = check.unwrap(); |
| 243 if (!generateAtUseSite.contains(checked)) { | 237 if (!generateAtUseSite.contains(checked)) { |
| 244 environment.add(checked, instructionId); | 238 environment.add(checked, instructionId); |
| 245 } | 239 } |
| 246 } | 240 } |
| 247 } | 241 } |
| 248 } | 242 } |
| 249 | 243 |
| 250 void removeFromEnvironment(HInstruction instruction, | 244 void removeFromEnvironment(HInstruction instruction, |
| 251 LiveEnvironment environment) { | 245 LiveEnvironment environment) { |
| 252 environment.remove(instruction, instructionId); | 246 environment.remove(instruction, instructionId); |
| 253 // Special case the HCheck instruction to have the same live | 247 // Special case the HCheck instruction to have the same live |
| 254 // interval as the instruction it is checking. | 248 // interval as the instruction it is checking. |
| 255 if (instruction is HCheck) { | 249 if (instruction is HCheck) { |
| 256 HInstruction checked = unwrap(instruction); | 250 HCheck check = instruction; |
| 251 HInstruction checked = check.unwrap(); |
| 257 if (!generateAtUseSite.contains(checked)) { | 252 if (!generateAtUseSite.contains(checked)) { |
| 258 liveIntervals.putIfAbsent(checked, () => new LiveInterval()); | 253 liveIntervals.putIfAbsent(checked, () => new LiveInterval()); |
| 259 // Unconditionally force the live ranges of the HCheck to | 254 // Unconditionally force the live ranges of the HCheck to |
| 260 // be the live ranges of the instruction it is checking. | 255 // be the live ranges of the instruction it is checking. |
| 261 liveIntervals[instruction] = | 256 liveIntervals[instruction] = |
| 262 new LiveInterval.forCheck(instructionId, liveIntervals[checked]); | 257 new LiveInterval.forCheck(instructionId, liveIntervals[checked]); |
| 263 } | 258 } |
| 264 } | 259 } |
| 265 } | 260 } |
| 266 | 261 |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 | 613 |
| 619 block.forEachInstruction((HInstruction instruction) { | 614 block.forEachInstruction((HInstruction instruction) { |
| 620 handleInstruction(instruction, namer); | 615 handleInstruction(instruction, namer); |
| 621 }); | 616 }); |
| 622 } | 617 } |
| 623 | 618 |
| 624 /** | 619 /** |
| 625 * Returns whether [instruction] needs a name. Instructions that | 620 * Returns whether [instruction] needs a name. Instructions that |
| 626 * have no users or that are generated at use site do not need a name. | 621 * have no users or that are generated at use site do not need a name. |
| 627 */ | 622 */ |
| 628 bool needsName(HInstruction instruction) { | 623 bool needsName(instruction) { |
| 629 if (instruction is HThis) return false; | 624 if (instruction is HThis) return false; |
| 630 if (instruction is HParameterValue) return true; | 625 if (instruction is HParameterValue) return true; |
| 631 if (instruction.usedBy.isEmpty) return false; | 626 if (instruction.usedBy.isEmpty) return false; |
| 632 if (generateAtUseSite.contains(instruction)) return false; | 627 if (generateAtUseSite.contains(instruction)) return false; |
| 633 // A [HCheck] instruction that has control flow needs a name only if its | 628 // A [HCheck] instruction needs a name only if its |
| 634 // checked input needs a name (for example, a checked [HConstant] does not | 629 // checked input does not have a fixed name or value. |
| 635 // need a name). | 630 if (instruction is HCheck) { |
| 636 if (instruction is HCheck && instruction.isControlFlow()) { | 631 return !instruction.unwrap().isCodeMotionInvariant(); |
| 637 HCheck check = instruction; | |
| 638 return needsName(instruction.checkedInput); | |
| 639 } | 632 } |
| 640 return true; | 633 return true; |
| 641 } | 634 } |
| 642 | 635 |
| 643 /** | 636 /** |
| 644 * Returns whether [instruction] dies at the instruction [at]. | 637 * Returns whether [instruction] dies at the instruction [at]. |
| 645 */ | 638 */ |
| 646 bool diesAt(HInstruction instruction, HInstruction at) { | 639 bool diesAt(HInstruction instruction, HInstruction at) { |
| 647 LiveInterval atInterval = liveIntervals[at]; | 640 LiveInterval atInterval = liveIntervals[at]; |
| 648 LiveInterval instructionInterval = liveIntervals[instruction]; | 641 LiveInterval instructionInterval = liveIntervals[instruction]; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 if (!needsName(input)) { | 685 if (!needsName(input)) { |
| 693 names.addAssignment(predecessor, input, phi); | 686 names.addAssignment(predecessor, input, phi); |
| 694 } else { | 687 } else { |
| 695 names.addCopy(predecessor, input, phi); | 688 names.addCopy(predecessor, input, phi); |
| 696 } | 689 } |
| 697 } | 690 } |
| 698 | 691 |
| 699 namer.allocateName(phi); | 692 namer.allocateName(phi); |
| 700 } | 693 } |
| 701 } | 694 } |
| OLD | NEW |