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 import '../common.dart'; | 5 import '../common.dart'; |
6 import '../compiler.dart' show Compiler; | 6 import '../compiler.dart' show Compiler; |
7 import '../js_backend/js_backend.dart'; | 7 import '../js_backend/js_backend.dart'; |
8 | 8 |
9 import 'nodes.dart'; | 9 import 'nodes.dart'; |
10 | 10 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 * instruction. | 108 * instruction. |
109 */ | 109 */ |
110 final Map<HInstruction, int> liveInstructions; | 110 final Map<HInstruction, int> liveInstructions; |
111 | 111 |
112 /** | 112 /** |
113 * Map containing the live intervals of instructions. | 113 * Map containing the live intervals of instructions. |
114 */ | 114 */ |
115 final Map<HInstruction, LiveInterval> liveIntervals; | 115 final Map<HInstruction, LiveInterval> liveIntervals; |
116 | 116 |
117 LiveEnvironment(this.liveIntervals, this.endId) | 117 LiveEnvironment(this.liveIntervals, this.endId) |
118 : liveInstructions = new Map<HInstruction, int>(), | 118 : liveInstructions = new Map<HInstruction, int>(), |
119 loopMarkers = new Map<HBasicBlock, int>(); | 119 loopMarkers = new Map<HBasicBlock, int>(); |
120 | 120 |
121 /** | 121 /** |
122 * Remove an instruction from the liveIn set. This method also | 122 * Remove an instruction from the liveIn set. This method also |
123 * updates the live interval of [instruction] to contain the new | 123 * updates the live interval of [instruction] to contain the new |
124 * range: [id, / id contained in [liveInstructions] /]. | 124 * range: [id, / id contained in [liveInstructions] /]. |
125 */ | 125 */ |
126 void remove(HInstruction instruction, int id) { | 126 void remove(HInstruction instruction, int id) { |
127 LiveInterval interval = liveIntervals.putIfAbsent( | 127 LiveInterval interval = |
128 instruction, () => new LiveInterval()); | 128 liveIntervals.putIfAbsent(instruction, () => new LiveInterval()); |
129 int lastId = liveInstructions[instruction]; | 129 int lastId = liveInstructions[instruction]; |
130 // If [lastId] is null, then this instruction is not being used. | 130 // If [lastId] is null, then this instruction is not being used. |
131 interval.add(new LiveRange(id, lastId == null ? id : lastId)); | 131 interval.add(new LiveRange(id, lastId == null ? id : lastId)); |
132 // The instruction is defined at [id]. | 132 // The instruction is defined at [id]. |
133 interval.start = id; | 133 interval.start = id; |
134 liveInstructions.remove(instruction); | 134 liveInstructions.remove(instruction); |
135 } | 135 } |
136 | 136 |
137 /** | 137 /** |
138 * Add [instruction] to the liveIn set. If the instruction is not | 138 * Add [instruction] to the liveIn set. If the instruction is not |
(...skipping 10 matching lines...) Expand all Loading... |
149 * instructions in case they are different between this and [other]. | 149 * instructions in case they are different between this and [other]. |
150 */ | 150 */ |
151 void mergeWith(LiveEnvironment other) { | 151 void mergeWith(LiveEnvironment other) { |
152 other.liveInstructions.forEach((HInstruction instruction, int existingId) { | 152 other.liveInstructions.forEach((HInstruction instruction, int existingId) { |
153 // If both environments have the same instruction id of where | 153 // If both environments have the same instruction id of where |
154 // [instruction] dies, there is no need to update the live | 154 // [instruction] dies, there is no need to update the live |
155 // interval of [instruction]. For example the if block and the | 155 // interval of [instruction]. For example the if block and the |
156 // else block have the same end id for an instruction that is | 156 // else block have the same end id for an instruction that is |
157 // being used in the join block and defined before the if/else. | 157 // being used in the join block and defined before the if/else. |
158 if (existingId == endId) return; | 158 if (existingId == endId) return; |
159 LiveInterval range = liveIntervals.putIfAbsent( | 159 LiveInterval range = |
160 instruction, () => new LiveInterval()); | 160 liveIntervals.putIfAbsent(instruction, () => new LiveInterval()); |
161 range.add(new LiveRange(other.startId, existingId)); | 161 range.add(new LiveRange(other.startId, existingId)); |
162 liveInstructions[instruction] = endId; | 162 liveInstructions[instruction] = endId; |
163 }); | 163 }); |
164 other.loopMarkers.forEach((k, v) { loopMarkers[k] = v; }); | 164 other.loopMarkers.forEach((k, v) { |
| 165 loopMarkers[k] = v; |
| 166 }); |
165 } | 167 } |
166 | 168 |
167 void addLoopMarker(HBasicBlock header, int id) { | 169 void addLoopMarker(HBasicBlock header, int id) { |
168 assert(!loopMarkers.containsKey(header)); | 170 assert(!loopMarkers.containsKey(header)); |
169 loopMarkers[header] = id; | 171 loopMarkers[header] = id; |
170 } | 172 } |
171 | 173 |
172 void removeLoopMarker(HBasicBlock header) { | 174 void removeLoopMarker(HBasicBlock header) { |
173 assert(loopMarkers.containsKey(header)); | 175 assert(loopMarkers.containsKey(header)); |
174 loopMarkers.remove(header); | 176 loopMarkers.remove(header); |
(...skipping 28 matching lines...) Expand all Loading... |
203 */ | 205 */ |
204 final Map<HBasicBlock, LiveEnvironment> liveInstructions; | 206 final Map<HBasicBlock, LiveEnvironment> liveInstructions; |
205 | 207 |
206 /** | 208 /** |
207 * The live intervals of instructions. | 209 * The live intervals of instructions. |
208 */ | 210 */ |
209 final Map<HInstruction, LiveInterval> liveIntervals; | 211 final Map<HInstruction, LiveInterval> liveIntervals; |
210 | 212 |
211 SsaLiveIntervalBuilder( | 213 SsaLiveIntervalBuilder( |
212 this.compiler, this.generateAtUseSite, this.controlFlowOperators) | 214 this.compiler, this.generateAtUseSite, this.controlFlowOperators) |
213 : liveInstructions = new Map<HBasicBlock, LiveEnvironment>(), | 215 : liveInstructions = new Map<HBasicBlock, LiveEnvironment>(), |
214 liveIntervals = new Map<HInstruction, LiveInterval>(); | 216 liveIntervals = new Map<HInstruction, LiveInterval>(); |
215 | 217 |
216 DiagnosticReporter get reporter => compiler.reporter; | 218 DiagnosticReporter get reporter => compiler.reporter; |
217 | 219 |
218 void visitGraph(HGraph graph) { | 220 void visitGraph(HGraph graph) { |
219 visitPostDominatorTree(graph); | 221 visitPostDominatorTree(graph); |
220 if (!liveInstructions[graph.entry].isEmpty) { | 222 if (!liveInstructions[graph.entry].isEmpty) { |
221 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, 'LiveIntervalBuilder.'); | 223 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, 'LiveIntervalBuilder.'); |
222 } | 224 } |
223 } | 225 } |
224 | 226 |
225 void markInputsAsLiveInEnvironment(HInstruction instruction, | 227 void markInputsAsLiveInEnvironment( |
226 LiveEnvironment environment) { | 228 HInstruction instruction, LiveEnvironment environment) { |
227 for (int i = 0, len = instruction.inputs.length; i < len; i++) { | 229 for (int i = 0, len = instruction.inputs.length; i < len; i++) { |
228 markAsLiveInEnvironment(instruction.inputs[i], environment); | 230 markAsLiveInEnvironment(instruction.inputs[i], environment); |
229 } | 231 } |
230 } | 232 } |
231 | 233 |
232 // Returns the non-HCheck instruction, or the last [HCheck] in the | 234 // Returns the non-HCheck instruction, or the last [HCheck] in the |
233 // check chain that is not generate at use site. | 235 // check chain that is not generate at use site. |
234 // | 236 // |
235 // For example: | 237 // For example: |
236 // | 238 // |
(...skipping 11 matching lines...) Expand all Loading... |
248 HInstruction checkedInstructionOrNonGenerateAtUseSite(HCheck check) { | 250 HInstruction checkedInstructionOrNonGenerateAtUseSite(HCheck check) { |
249 var checked = check.checkedInput; | 251 var checked = check.checkedInput; |
250 while (checked is HCheck) { | 252 while (checked is HCheck) { |
251 HInstruction next = checked.checkedInput; | 253 HInstruction next = checked.checkedInput; |
252 if (generateAtUseSite.contains(next)) break; | 254 if (generateAtUseSite.contains(next)) break; |
253 checked = next; | 255 checked = next; |
254 } | 256 } |
255 return checked; | 257 return checked; |
256 } | 258 } |
257 | 259 |
258 void markAsLiveInEnvironment(HInstruction instruction, | 260 void markAsLiveInEnvironment( |
259 LiveEnvironment environment) { | 261 HInstruction instruction, LiveEnvironment environment) { |
260 if (generateAtUseSite.contains(instruction)) { | 262 if (generateAtUseSite.contains(instruction)) { |
261 markInputsAsLiveInEnvironment(instruction, environment); | 263 markInputsAsLiveInEnvironment(instruction, environment); |
262 } else { | 264 } else { |
263 environment.add(instruction, instructionId); | 265 environment.add(instruction, instructionId); |
264 // Special case the HCheck instruction to mark the actual | 266 // Special case the HCheck instruction to mark the actual |
265 // checked instruction live. The checked instruction and the | 267 // checked instruction live. The checked instruction and the |
266 // [HCheck] will share the same live ranges. | 268 // [HCheck] will share the same live ranges. |
267 if (instruction is HCheck) { | 269 if (instruction is HCheck) { |
268 HCheck check = instruction; | 270 HCheck check = instruction; |
269 HInstruction checked = checkedInstructionOrNonGenerateAtUseSite(check); | 271 HInstruction checked = checkedInstructionOrNonGenerateAtUseSite(check); |
270 if (!generateAtUseSite.contains(checked)) { | 272 if (!generateAtUseSite.contains(checked)) { |
271 environment.add(checked, instructionId); | 273 environment.add(checked, instructionId); |
272 } | 274 } |
273 } | 275 } |
274 } | 276 } |
275 } | 277 } |
276 | 278 |
277 void removeFromEnvironment(HInstruction instruction, | 279 void removeFromEnvironment( |
278 LiveEnvironment environment) { | 280 HInstruction instruction, LiveEnvironment environment) { |
279 environment.remove(instruction, instructionId); | 281 environment.remove(instruction, instructionId); |
280 // Special case the HCheck instruction to have the same live | 282 // Special case the HCheck instruction to have the same live |
281 // interval as the instruction it is checking. | 283 // interval as the instruction it is checking. |
282 if (instruction is HCheck) { | 284 if (instruction is HCheck) { |
283 HCheck check = instruction; | 285 HCheck check = instruction; |
284 HInstruction checked = checkedInstructionOrNonGenerateAtUseSite(check); | 286 HInstruction checked = checkedInstructionOrNonGenerateAtUseSite(check); |
285 if (!generateAtUseSite.contains(checked)) { | 287 if (!generateAtUseSite.contains(checked)) { |
286 liveIntervals.putIfAbsent(checked, () => new LiveInterval()); | 288 liveIntervals.putIfAbsent(checked, () => new LiveInterval()); |
287 // Unconditionally force the live ranges of the HCheck to | 289 // Unconditionally force the live ranges of the HCheck to |
288 // be the live ranges of the instruction it is checking. | 290 // be the live ranges of the instruction it is checking. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 updateLoopMarker(block); | 360 updateLoopMarker(block); |
359 } | 361 } |
360 } | 362 } |
361 | 363 |
362 void updateLoopMarker(HBasicBlock header) { | 364 void updateLoopMarker(HBasicBlock header) { |
363 LiveEnvironment env = liveInstructions[header]; | 365 LiveEnvironment env = liveInstructions[header]; |
364 int lastId = env.loopMarkers[header]; | 366 int lastId = env.loopMarkers[header]; |
365 // Update all instructions that are liveIns in [header] to have a | 367 // Update all instructions that are liveIns in [header] to have a |
366 // range that covers the loop. | 368 // range that covers the loop. |
367 env.liveInstructions.forEach((HInstruction instruction, int id) { | 369 env.liveInstructions.forEach((HInstruction instruction, int id) { |
368 LiveInterval range = env.liveIntervals.putIfAbsent( | 370 LiveInterval range = |
369 instruction, () => new LiveInterval()); | 371 env.liveIntervals.putIfAbsent(instruction, () => new LiveInterval()); |
370 range.loopUpdate(env.startId, lastId); | 372 range.loopUpdate(env.startId, lastId); |
371 env.liveInstructions[instruction] = lastId; | 373 env.liveInstructions[instruction] = lastId; |
372 }); | 374 }); |
373 | 375 |
374 env.removeLoopMarker(header); | 376 env.removeLoopMarker(header); |
375 | 377 |
376 // Update all liveIns set to contain the liveIns of [header]. | 378 // Update all liveIns set to contain the liveIns of [header]. |
377 liveInstructions.forEach((HBasicBlock block, LiveEnvironment other) { | 379 liveInstructions.forEach((HBasicBlock block, LiveEnvironment other) { |
378 if (other.loopMarkers.containsKey(header)) { | 380 if (other.loopMarkers.containsKey(header)) { |
379 env.liveInstructions.forEach((HInstruction instruction, int id) { | 381 env.liveInstructions.forEach((HInstruction instruction, int id) { |
380 other.liveInstructions[instruction] = id; | 382 other.liveInstructions[instruction] = id; |
381 }); | 383 }); |
382 other.removeLoopMarker(header); | 384 other.removeLoopMarker(header); |
383 env.loopMarkers.forEach((k, v) { other.loopMarkers[k] = v; }); | 385 env.loopMarkers.forEach((k, v) { |
| 386 other.loopMarkers[k] = v; |
| 387 }); |
384 } | 388 } |
385 }); | 389 }); |
386 } | 390 } |
387 } | 391 } |
388 | 392 |
389 /** | 393 /** |
390 * Represents a copy from one instruction to another. The codegen | 394 * Represents a copy from one instruction to another. The codegen |
391 * also uses this class to represent a copy from one variable to | 395 * also uses this class to represent a copy from one variable to |
392 * another. | 396 * another. |
393 */ | 397 */ |
(...skipping 14 matching lines...) Expand all Loading... |
408 */ | 412 */ |
409 final List<Copy> copies; | 413 final List<Copy> copies; |
410 | 414 |
411 /** | 415 /** |
412 * Assignments from an instruction that does not need a name (e.g. a | 416 * Assignments from an instruction that does not need a name (e.g. a |
413 * constant) to the phi of a successor. | 417 * constant) to the phi of a successor. |
414 */ | 418 */ |
415 final List<Copy> assignments; | 419 final List<Copy> assignments; |
416 | 420 |
417 CopyHandler() | 421 CopyHandler() |
418 : copies = new List<Copy>(), | 422 : copies = new List<Copy>(), |
419 assignments = new List<Copy>(); | 423 assignments = new List<Copy>(); |
420 | 424 |
421 void addCopy(HInstruction source, HInstruction destination) { | 425 void addCopy(HInstruction source, HInstruction destination) { |
422 copies.add(new Copy(source, destination)); | 426 copies.add(new Copy(source, destination)); |
423 } | 427 } |
424 | 428 |
425 void addAssignment(HInstruction source, HInstruction destination) { | 429 void addAssignment(HInstruction source, HInstruction destination) { |
426 assignments.add(new Copy(source, destination)); | 430 assignments.add(new Copy(source, destination)); |
427 } | 431 } |
428 | 432 |
429 String toString() => 'Copies: $copies, assignments: $assignments'; | 433 String toString() => 'Copies: $copies, assignments: $assignments'; |
(...skipping 16 matching lines...) Expand all Loading... |
446 * anywhere by reserving it when we allocate names for instructions. | 450 * anywhere by reserving it when we allocate names for instructions. |
447 */ | 451 */ |
448 final String swapTemp; | 452 final String swapTemp; |
449 | 453 |
450 String getSwapTemp() { | 454 String getSwapTemp() { |
451 allUsedNames.add(swapTemp); | 455 allUsedNames.add(swapTemp); |
452 return swapTemp; | 456 return swapTemp; |
453 } | 457 } |
454 | 458 |
455 VariableNames() | 459 VariableNames() |
456 : ownName = new Map<HInstruction, String>(), | 460 : ownName = new Map<HInstruction, String>(), |
457 copyHandlers = new Map<HBasicBlock, CopyHandler>(), | 461 copyHandlers = new Map<HBasicBlock, CopyHandler>(), |
458 allUsedNames = new Set<String>(), | 462 allUsedNames = new Set<String>(), |
459 swapTemp = 't0'; | 463 swapTemp = 't0'; |
460 | 464 |
461 int get numberOfVariables => allUsedNames.length; | 465 int get numberOfVariables => allUsedNames.length; |
462 | 466 |
463 String getName(HInstruction instruction) { | 467 String getName(HInstruction instruction) { |
464 return ownName[instruction]; | 468 return ownName[instruction]; |
465 } | 469 } |
466 | 470 |
467 CopyHandler getCopyHandler(HBasicBlock block) { | 471 CopyHandler getCopyHandler(HBasicBlock block) { |
468 return copyHandlers[block]; | 472 return copyHandlers[block]; |
469 } | 473 } |
(...skipping 21 matching lines...) Expand all Loading... |
491 * Allocates variable names for instructions, making sure they don't collide. | 495 * Allocates variable names for instructions, making sure they don't collide. |
492 */ | 496 */ |
493 class VariableNamer { | 497 class VariableNamer { |
494 final VariableNames names; | 498 final VariableNames names; |
495 final Compiler compiler; | 499 final Compiler compiler; |
496 final Set<String> usedNames; | 500 final Set<String> usedNames; |
497 final List<String> freeTemporaryNames; | 501 final List<String> freeTemporaryNames; |
498 int temporaryIndex = 0; | 502 int temporaryIndex = 0; |
499 static final RegExp regexp = new RegExp('t[0-9]+'); | 503 static final RegExp regexp = new RegExp('t[0-9]+'); |
500 | 504 |
501 VariableNamer(LiveEnvironment environment, | 505 VariableNamer(LiveEnvironment environment, this.names, this.compiler) |
502 this.names, | 506 : usedNames = new Set<String>(), |
503 this.compiler) | 507 freeTemporaryNames = new List<String>() { |
504 : usedNames = new Set<String>(), | |
505 freeTemporaryNames = new List<String>() { | |
506 // [VariableNames.swapTemp] is used when there is a cycle in a copy handler. | 508 // [VariableNames.swapTemp] is used when there is a cycle in a copy handler. |
507 // Therefore we make sure no one uses it. | 509 // Therefore we make sure no one uses it. |
508 usedNames.add(names.swapTemp); | 510 usedNames.add(names.swapTemp); |
509 | 511 |
510 // All liveIns instructions must have a name at this point, so we | 512 // All liveIns instructions must have a name at this point, so we |
511 // add them to the list of used names. | 513 // add them to the list of used names. |
512 environment.liveInstructions.forEach((HInstruction instruction, int index) { | 514 environment.liveInstructions.forEach((HInstruction instruction, int index) { |
513 String name = names.getName(instruction); | 515 String name = names.getName(instruction); |
514 if (name != null) { | 516 if (name != null) { |
515 usedNames.add(name); | 517 usedNames.add(name); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 * the liveIns set as well as all the live intervals of instructions. | 609 * the liveIns set as well as all the live intervals of instructions. |
608 * It visits the graph in dominator order, so that at each entry of a | 610 * It visits the graph in dominator order, so that at each entry of a |
609 * block, the instructions in its liveIns set have names. | 611 * block, the instructions in its liveIns set have names. |
610 * | 612 * |
611 * When visiting a block, it goes through all instructions. For each | 613 * When visiting a block, it goes through all instructions. For each |
612 * instruction, it frees the names of the inputs that die at that | 614 * instruction, it frees the names of the inputs that die at that |
613 * instruction, and allocates a name to the instruction. For each phi, | 615 * instruction, and allocates a name to the instruction. For each phi, |
614 * it adds a copy to the CopyHandler of the corresponding predecessor. | 616 * it adds a copy to the CopyHandler of the corresponding predecessor. |
615 */ | 617 */ |
616 class SsaVariableAllocator extends HBaseVisitor { | 618 class SsaVariableAllocator extends HBaseVisitor { |
617 | |
618 final Compiler compiler; | 619 final Compiler compiler; |
619 final Map<HBasicBlock, LiveEnvironment> liveInstructions; | 620 final Map<HBasicBlock, LiveEnvironment> liveInstructions; |
620 final Map<HInstruction, LiveInterval> liveIntervals; | 621 final Map<HInstruction, LiveInterval> liveIntervals; |
621 final Set<HInstruction> generateAtUseSite; | 622 final Set<HInstruction> generateAtUseSite; |
622 | 623 |
623 final VariableNames names; | 624 final VariableNames names; |
624 | 625 |
625 SsaVariableAllocator(this.compiler, | 626 SsaVariableAllocator(this.compiler, this.liveInstructions, this.liveIntervals, |
626 this.liveInstructions, | 627 this.generateAtUseSite) |
627 this.liveIntervals, | 628 : this.names = new VariableNames(); |
628 this.generateAtUseSite) | |
629 : this.names = new VariableNames(); | |
630 | 629 |
631 void visitGraph(HGraph graph) { | 630 void visitGraph(HGraph graph) { |
632 visitDominatorTree(graph); | 631 visitDominatorTree(graph); |
633 } | 632 } |
634 | 633 |
635 void visitBasicBlock(HBasicBlock block) { | 634 void visitBasicBlock(HBasicBlock block) { |
636 VariableNamer namer = new VariableNamer( | 635 VariableNamer namer = |
637 liveInstructions[block], names, compiler); | 636 new VariableNamer(liveInstructions[block], names, compiler); |
638 | 637 |
639 block.forEachPhi((HPhi phi) { | 638 block.forEachPhi((HPhi phi) { |
640 handlePhi(phi, namer); | 639 handlePhi(phi, namer); |
641 }); | 640 }); |
642 | 641 |
643 block.forEachInstruction((HInstruction instruction) { | 642 block.forEachInstruction((HInstruction instruction) { |
644 handleInstruction(instruction, namer); | 643 handleInstruction(instruction, namer); |
645 }); | 644 }); |
646 } | 645 } |
647 | 646 |
(...skipping 12 matching lines...) Expand all Loading... |
660 /** | 659 /** |
661 * Returns whether [instruction] dies at the instruction [at]. | 660 * Returns whether [instruction] dies at the instruction [at]. |
662 */ | 661 */ |
663 bool diesAt(HInstruction instruction, HInstruction at) { | 662 bool diesAt(HInstruction instruction, HInstruction at) { |
664 LiveInterval atInterval = liveIntervals[at]; | 663 LiveInterval atInterval = liveIntervals[at]; |
665 LiveInterval instructionInterval = liveIntervals[instruction]; | 664 LiveInterval instructionInterval = liveIntervals[instruction]; |
666 int start = atInterval.start; | 665 int start = atInterval.start; |
667 return instructionInterval.diesAt(start); | 666 return instructionInterval.diesAt(start); |
668 } | 667 } |
669 | 668 |
670 void freeUsedNamesAt(HInstruction instruction, | 669 void freeUsedNamesAt( |
671 HInstruction at, | 670 HInstruction instruction, HInstruction at, VariableNamer namer) { |
672 VariableNamer namer) { | |
673 if (needsName(instruction)) { | 671 if (needsName(instruction)) { |
674 if (diesAt(instruction, at)) { | 672 if (diesAt(instruction, at)) { |
675 namer.freeName(instruction); | 673 namer.freeName(instruction); |
676 } | 674 } |
677 } else if (generateAtUseSite.contains(instruction)) { | 675 } else if (generateAtUseSite.contains(instruction)) { |
678 // If the instruction is generated at use site, then all its | 676 // If the instruction is generated at use site, then all its |
679 // inputs may also die at [at]. | 677 // inputs may also die at [at]. |
680 for (int i = 0, len = instruction.inputs.length; i < len; i++) { | 678 for (int i = 0, len = instruction.inputs.length; i < len; i++) { |
681 HInstruction input = instruction.inputs[i]; | 679 HInstruction input = instruction.inputs[i]; |
682 freeUsedNamesAt(input, at, namer); | 680 freeUsedNamesAt(input, at, namer); |
(...skipping 30 matching lines...) Expand all Loading... |
713 if (!needsName(input)) { | 711 if (!needsName(input)) { |
714 names.addAssignment(predecessor, input, phi); | 712 names.addAssignment(predecessor, input, phi); |
715 } else { | 713 } else { |
716 names.addCopy(predecessor, input, phi); | 714 names.addCopy(predecessor, input, phi); |
717 } | 715 } |
718 } | 716 } |
719 | 717 |
720 namer.allocateName(phi); | 718 namer.allocateName(phi); |
721 } | 719 } |
722 } | 720 } |
OLD | NEW |