| 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 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 } | 392 } |
| 393 } | 393 } |
| 394 | 394 |
| 395 /** | 395 /** |
| 396 * Allocates variable names for instructions, making sure they don't collide. | 396 * Allocates variable names for instructions, making sure they don't collide. |
| 397 */ | 397 */ |
| 398 class VariableNamer { | 398 class VariableNamer { |
| 399 final VariableNames names; | 399 final VariableNames names; |
| 400 final Set<String> usedNames; | 400 final Set<String> usedNames; |
| 401 final Map<Element, String> parameterNames; | 401 final Map<Element, String> parameterNames; |
| 402 final List<String> freeTemporaryNames; |
| 402 int temporaryIndex = 0; | 403 int temporaryIndex = 0; |
| 403 | 404 |
| 404 VariableNamer(LiveEnvironment environment, this.names, this.parameterNames) | 405 VariableNamer(LiveEnvironment environment, this.names, this.parameterNames) |
| 405 : usedNames = new Set<String>() { | 406 : usedNames = new Set<String>(), |
| 407 freeTemporaryNames = new List<String>() { |
| 406 // [VariableNames.swapTemp] is being used when there is a cycle | 408 // [VariableNames.swapTemp] is being used when there is a cycle |
| 407 // in a copy handler. Therefore we make sure no one will use it. | 409 // in a copy handler. Therefore we make sure no one will use it. |
| 408 usedNames.add(names.swapTemp); | 410 usedNames.add(names.swapTemp); |
| 409 | 411 |
| 410 // All liveIns instructions must have a name at this point, so we | 412 // All liveIns instructions must have a name at this point, so we |
| 411 // add them to the list of used names. | 413 // add them to the list of used names. |
| 412 environment.liveInstructions.forEach((HInstruction instruction, int index) { | 414 environment.liveInstructions.forEach((HInstruction instruction, int index) { |
| 413 String name = names.getName(instruction); | 415 String name = names.getName(instruction); |
| 414 if (name !== null) { | 416 if (name !== null) { |
| 415 usedNames.add(name); | 417 usedNames.add(name); |
| 416 } | 418 } |
| 417 }); | 419 }); |
| 418 } | 420 } |
| 419 | 421 |
| 420 String allocateWithHint(String originalName) { | 422 String allocateWithHint(String originalName) { |
| 421 int i = 0; | 423 int i = 0; |
| 422 String name = JsNames.getValid(originalName); | 424 String name = JsNames.getValid(originalName); |
| 423 while (usedNames.contains(name)) { | 425 while (usedNames.contains(name)) { |
| 424 name = JsNames.getValid('$originalName${i++}'); | 426 name = JsNames.getValid('$originalName${i++}'); |
| 425 } | 427 } |
| 426 return name; | 428 return name; |
| 427 } | 429 } |
| 428 | 430 |
| 429 String allocateTemporary() { | 431 String allocateTemporary() { |
| 432 while (!freeTemporaryNames.isEmpty()) { |
| 433 String name = freeTemporaryNames.removeLast(); |
| 434 if (!usedNames.contains(name)) return name; |
| 435 } |
| 430 String name = 't${temporaryIndex++}'; | 436 String name = 't${temporaryIndex++}'; |
| 431 while (usedNames.contains(name)) name = 't${temporaryIndex++}'; | 437 while (usedNames.contains(name)) name = 't${temporaryIndex++}'; |
| 432 return name; | 438 return name; |
| 433 } | 439 } |
| 434 | 440 |
| 435 HPhi firstPhiUserWithElement(HInstruction instruction) { | 441 HPhi firstPhiUserWithElement(HInstruction instruction) { |
| 436 for (HInstruction user in instruction.usedBy) { | 442 for (HInstruction user in instruction.usedBy) { |
| 437 if (user is HPhi && user.sourceElement !== null) { | 443 if (user is HPhi && user.sourceElement !== null) { |
| 438 return user; | 444 return user; |
| 439 } | 445 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 names.ownName[instruction] = name; | 489 names.ownName[instruction] = name; |
| 484 return name; | 490 return name; |
| 485 } | 491 } |
| 486 | 492 |
| 487 /** | 493 /** |
| 488 * Frees [instruction]'s name so it can be used for other instructions. | 494 * Frees [instruction]'s name so it can be used for other instructions. |
| 489 */ | 495 */ |
| 490 void freeName(HInstruction instruction) { | 496 void freeName(HInstruction instruction) { |
| 491 String ownName = names.ownName[instruction]; | 497 String ownName = names.ownName[instruction]; |
| 492 if (ownName != null) { | 498 if (ownName != null) { |
| 499 RegExp regexp = const RegExp('t[0-9]+'); |
| 500 // We check if we have already looked for temporary names |
| 501 // because if we haven't, chances are the temporary we allocate |
| 502 // in this block can match a phi with the same name in the |
| 503 // successor block. |
| 504 if (temporaryIndex != 0 && regexp.hasMatch(ownName)) { |
| 505 freeTemporaryNames.addLast(ownName); |
| 506 } |
| 493 usedNames.remove(ownName); | 507 usedNames.remove(ownName); |
| 494 } | 508 } |
| 495 } | 509 } |
| 496 } | 510 } |
| 497 | 511 |
| 498 /** | 512 /** |
| 499 * Visits all blocks in the graph, sets names to instructions, and | 513 * Visits all blocks in the graph, sets names to instructions, and |
| 500 * creates the [CopyHandler] for each block. This class needs to have | 514 * creates the [CopyHandler] for each block. This class needs to have |
| 501 * the liveIns set as well as all the live intervals of instructions. | 515 * the liveIns set as well as all the live intervals of instructions. |
| 502 * It visits the graph in dominator order, so that at each entry of a | 516 * It visits the graph in dominator order, so that at each entry of a |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 if (!needsName(input)) { | 611 if (!needsName(input)) { |
| 598 names.addAssignment(predecessor, input, phi); | 612 names.addAssignment(predecessor, input, phi); |
| 599 } else { | 613 } else { |
| 600 names.addCopy(predecessor, input, phi); | 614 names.addCopy(predecessor, input, phi); |
| 601 } | 615 } |
| 602 } | 616 } |
| 603 | 617 |
| 604 namer.allocateName(phi); | 618 namer.allocateName(phi); |
| 605 } | 619 } |
| 606 } | 620 } |
| OLD | NEW |