| 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 /** | 5 /** |
| 6 * The [LiveRange] class covers a range where an instruction is live. | 6 * The [LiveRange] class covers a range where an instruction is live. |
| 7 */ | 7 */ |
| 8 class LiveRange { | 8 class LiveRange { |
| 9 final int start; | 9 final int start; |
| 10 // [end] is not final because it can be updated due to loops. | 10 // [end] is not final because it can be updated due to loops. |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 handler.addAssignment(source, destination); | 378 handler.addAssignment(source, destination); |
| 379 } | 379 } |
| 380 } | 380 } |
| 381 | 381 |
| 382 /** | 382 /** |
| 383 * Allocates variable names for instructions, making sure they don't collide. | 383 * Allocates variable names for instructions, making sure they don't collide. |
| 384 */ | 384 */ |
| 385 class VariableNamer { | 385 class VariableNamer { |
| 386 final VariableNames names; | 386 final VariableNames names; |
| 387 final Set<String> usedNames; | 387 final Set<String> usedNames; |
| 388 final Map<Element, String> parameterNames; |
| 388 | 389 |
| 389 VariableNamer(LiveEnvironment environment, this.names) | 390 VariableNamer(LiveEnvironment environment, this.names, this.parameterNames) |
| 390 : usedNames = new Set<String>() { | 391 : usedNames = new Set<String>() { |
| 391 // [VariableNames.SWAP_TEMP] is being used when there is a cycle | 392 // [VariableNames.SWAP_TEMP] is being used when there is a cycle |
| 392 // in a copy handler. Therefore we make sure no one will use it. | 393 // in a copy handler. Therefore we make sure no one will use it. |
| 393 usedNames.add(VariableNames.SWAP_TEMP); | 394 usedNames.add(VariableNames.SWAP_TEMP); |
| 394 | 395 |
| 395 // All liveIns instructions must have a name at this point, so we | 396 // All liveIns instructions must have a name at this point, so we |
| 396 // add them to the list of used names. | 397 // add them to the list of used names. |
| 397 environment.liveInstructions.forEach((HInstruction instruction, int index) { | 398 environment.liveInstructions.forEach((HInstruction instruction, int index) { |
| 398 String name = names.getName(instruction); | 399 String name = names.getName(instruction); |
| 399 if (name !== null) { | 400 if (name !== null) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 // Special case the check instruction to use the name of its | 436 // Special case the check instruction to use the name of its |
| 436 // checked instruction. | 437 // checked instruction. |
| 437 HCheck check = instruction; | 438 HCheck check = instruction; |
| 438 name = names.ownName[check.checkedInput]; | 439 name = names.ownName[check.checkedInput]; |
| 439 // If the name is null, then the checked input is being | 440 // If the name is null, then the checked input is being |
| 440 // generated at use site, and we don't need a name for the check | 441 // generated at use site, and we don't need a name for the check |
| 441 // instruction. | 442 // instruction. |
| 442 if (name == null) return; | 443 if (name == null) return; |
| 443 } else if (instruction is HParameterValue) { | 444 } else if (instruction is HParameterValue) { |
| 444 HParameterValue parameter = instruction; | 445 HParameterValue parameter = instruction; |
| 445 name = allocateWithHint(parameter.element.name.slowToString()); | 446 name = parameterNames[parameter.element]; |
| 447 if (name == null) { |
| 448 name = allocateWithHint(parameter.element.name.slowToString()); |
| 449 } |
| 446 } else if (instruction.sourceElement !== null) { | 450 } else if (instruction.sourceElement !== null) { |
| 447 name = allocateWithHint(instruction.sourceElement.name.slowToString()); | 451 name = allocateWithHint(instruction.sourceElement.name.slowToString()); |
| 448 } else { | 452 } else { |
| 449 // We could not find an element for the instruction. If the | 453 // We could not find an element for the instruction. If the |
| 450 // instruction is used by a phi, try to use the name of the phi. | 454 // instruction is used by a phi, try to use the name of the phi. |
| 451 // Otherwise, just allocate a temporary name. | 455 // Otherwise, just allocate a temporary name. |
| 452 HPhi phi = firstPhiUserWithElement(instruction); | 456 HPhi phi = firstPhiUserWithElement(instruction); |
| 453 if (phi !== null) { | 457 if (phi !== null) { |
| 454 name = allocateWithHint(phi.sourceElement.name.slowToString()); | 458 name = allocateWithHint(phi.sourceElement.name.slowToString()); |
| 455 } else { | 459 } else { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 483 * instruction, it frees the names of the inputs that die at that | 487 * instruction, it frees the names of the inputs that die at that |
| 484 * instruction, and allocates a name to the instruction. For each phi, | 488 * instruction, and allocates a name to the instruction. For each phi, |
| 485 * it adds a copy to the CopyHandler of the corresponding predecessor. | 489 * it adds a copy to the CopyHandler of the corresponding predecessor. |
| 486 */ | 490 */ |
| 487 class SsaVariableAllocator extends HBaseVisitor { | 491 class SsaVariableAllocator extends HBaseVisitor { |
| 488 | 492 |
| 489 final Compiler compiler; | 493 final Compiler compiler; |
| 490 final Map<HBasicBlock, LiveEnvironment> liveInstructions; | 494 final Map<HBasicBlock, LiveEnvironment> liveInstructions; |
| 491 final Map<HInstruction, LiveInterval> liveIntervals; | 495 final Map<HInstruction, LiveInterval> liveIntervals; |
| 492 final Set<HInstruction> generateAtUseSite; | 496 final Set<HInstruction> generateAtUseSite; |
| 497 final Map<Element, String> parameterNames; |
| 493 | 498 |
| 494 final VariableNames names; | 499 final VariableNames names; |
| 495 | 500 |
| 496 SsaVariableAllocator(this.compiler, | 501 SsaVariableAllocator(this.compiler, |
| 497 this.liveInstructions, | 502 this.liveInstructions, |
| 498 this.liveIntervals, | 503 this.liveIntervals, |
| 499 this.generateAtUseSite) | 504 this.generateAtUseSite, |
| 505 this.parameterNames) |
| 500 : names = new VariableNames(); | 506 : names = new VariableNames(); |
| 501 | 507 |
| 502 void visitGraph(HGraph graph) { | 508 void visitGraph(HGraph graph) { |
| 503 visitDominatorTree(graph); | 509 visitDominatorTree(graph); |
| 504 } | 510 } |
| 505 | 511 |
| 506 void visitBasicBlock(HBasicBlock block) { | 512 void visitBasicBlock(HBasicBlock block) { |
| 507 VariableNamer namer = new VariableNamer(liveInstructions[block], names); | 513 VariableNamer namer = new VariableNamer( |
| 514 liveInstructions[block], names, parameterNames); |
| 508 | 515 |
| 509 block.forEachPhi((HPhi phi) { | 516 block.forEachPhi((HPhi phi) { |
| 510 handlePhi(phi, namer); | 517 handlePhi(phi, namer); |
| 511 }); | 518 }); |
| 512 | 519 |
| 513 block.forEachInstruction((HInstruction instruction) { | 520 block.forEachInstruction((HInstruction instruction) { |
| 514 handleInstruction(instruction, namer); | 521 handleInstruction(instruction, namer); |
| 515 }); | 522 }); |
| 516 } | 523 } |
| 517 | 524 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 if (!needsName(input)) { | 570 if (!needsName(input)) { |
| 564 names.addAssignment(predecessor, input, phi); | 571 names.addAssignment(predecessor, input, phi); |
| 565 } else { | 572 } else { |
| 566 names.addCopy(predecessor, input, phi); | 573 names.addCopy(predecessor, input, phi); |
| 567 } | 574 } |
| 568 } | 575 } |
| 569 | 576 |
| 570 namer.allocateName(phi); | 577 namer.allocateName(phi); |
| 571 } | 578 } |
| 572 } | 579 } |
| OLD | NEW |