Chromium Code Reviews| 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 * Contains the mapping between instructions and their names for code | 341 * Contains the mapping between instructions and their names for code |
| 342 * generation, as well as the [CopyHandler] for each basic block. | 342 * generation, as well as the [CopyHandler] for each basic block. |
| 343 */ | 343 */ |
| 344 class VariableNames { | 344 class VariableNames { |
| 345 final Map<HInstruction, String> ownName; | 345 final Map<HInstruction, String> ownName; |
| 346 final Map<HBasicBlock, CopyHandler> copyHandlers; | 346 final Map<HBasicBlock, CopyHandler> copyHandlers; |
| 347 /** | 347 /** |
| 348 * Name that is being used as a temporary to break cycles in | 348 * Name that is being used as a temporary to break cycles in |
| 349 * parallel copies. We make sure this name is not being used | 349 * parallel copies. We make sure this name is not being used |
| 350 * anywhere by reserving it when we allocate names for instructions. | 350 * anywhere by reserving it when we allocate names for instructions. |
| 351 * TODO(ngeoffray): This isn't true for parameters, and we should | |
| 352 * rename the parameter name, to keep it simple. | |
| 353 */ | 351 */ |
| 354 static final String SWAP_TEMP = 't0'; | 352 final String swapTemp; |
| 355 | 353 |
| 356 VariableNames() | 354 VariableNames(Map<Element, String> parameterNames) |
| 357 : ownName = new Map<HInstruction, String>(), | 355 : ownName = new Map<HInstruction, String>(), |
| 358 copyHandlers = new Map<HBasicBlock, CopyHandler>(); | 356 copyHandlers = new Map<HBasicBlock, CopyHandler>(), |
| 357 swapTemp = computeSwapTemp(parameterNames); | |
| 358 | |
| 359 static String computeSwapTemp(Map<Element, String> parameterNames) { | |
| 360 Set<String> parameters = new Set<String>.from(parameterNames.getValues()); | |
|
Lasse Reichstein Nielsen
2012/06/07 08:53:21
Can't you use this.names somehow, since it's initi
ngeoffray
2012/06/07 09:10:41
As discussed, there is no extra field in this clas
| |
| 361 String name = 't0'; | |
| 362 int i = 1; | |
| 363 while (parameters.contains(name)) name = 't${i++}'; | |
| 364 return name; | |
| 365 } | |
| 359 | 366 |
| 360 String getName(HInstruction instruction) { | 367 String getName(HInstruction instruction) { |
| 361 return ownName[instruction]; | 368 return ownName[instruction]; |
| 362 } | 369 } |
| 363 | 370 |
| 364 CopyHandler getCopyHandler(HBasicBlock block) { | 371 CopyHandler getCopyHandler(HBasicBlock block) { |
| 365 return copyHandlers[block]; | 372 return copyHandlers[block]; |
| 366 } | 373 } |
| 367 | 374 |
| 368 bool hasName(HInstruction instruction) => ownName.containsKey(instruction); | 375 bool hasName(HInstruction instruction) => ownName.containsKey(instruction); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 383 /** | 390 /** |
| 384 * Allocates variable names for instructions, making sure they don't collide. | 391 * Allocates variable names for instructions, making sure they don't collide. |
| 385 */ | 392 */ |
| 386 class VariableNamer { | 393 class VariableNamer { |
| 387 final VariableNames names; | 394 final VariableNames names; |
| 388 final Set<String> usedNames; | 395 final Set<String> usedNames; |
| 389 final Map<Element, String> parameterNames; | 396 final Map<Element, String> parameterNames; |
| 390 | 397 |
| 391 VariableNamer(LiveEnvironment environment, this.names, this.parameterNames) | 398 VariableNamer(LiveEnvironment environment, this.names, this.parameterNames) |
| 392 : usedNames = new Set<String>() { | 399 : usedNames = new Set<String>() { |
| 393 // [VariableNames.SWAP_TEMP] is being used when there is a cycle | 400 // [VariableNames.swapTemp] is being used when there is a cycle |
| 394 // in a copy handler. Therefore we make sure no one will use it. | 401 // in a copy handler. Therefore we make sure no one will use it. |
| 395 usedNames.add(VariableNames.SWAP_TEMP); | 402 usedNames.add(names.swapTemp); |
| 396 | 403 |
| 397 // All liveIns instructions must have a name at this point, so we | 404 // All liveIns instructions must have a name at this point, so we |
| 398 // add them to the list of used names. | 405 // add them to the list of used names. |
| 399 environment.liveInstructions.forEach((HInstruction instruction, int index) { | 406 environment.liveInstructions.forEach((HInstruction instruction, int index) { |
| 400 String name = names.getName(instruction); | 407 String name = names.getName(instruction); |
| 401 if (name !== null) { | 408 if (name !== null) { |
| 402 usedNames.add(name); | 409 usedNames.add(name); |
| 403 } | 410 } |
| 404 }); | 411 }); |
| 405 } | 412 } |
| 406 | 413 |
| 407 String allocateWithHint(String originalName) { | 414 String allocateWithHint(String originalName) { |
| 408 int i = 0; | 415 int i = 0; |
| 409 String name = JsNames.getValid(originalName); | 416 String name = JsNames.getValid(originalName); |
| 410 while (usedNames.contains(name)) { | 417 while (usedNames.contains(name)) { |
| 411 name = JsNames.getValid('$originalName${i++}'); | 418 name = JsNames.getValid('$originalName${i++}'); |
| 412 } | 419 } |
| 413 return name; | 420 return name; |
| 414 } | 421 } |
| 415 | 422 |
| 416 String allocateTemporary() { | 423 String allocateTemporary() { |
| 417 // Don't start at 0 because t0 is being used for | 424 int i = 0; |
| 418 // [VariableNames.SWAP_TEMP]. | |
| 419 int i = 1; | |
| 420 String name = 't${i++}'; | 425 String name = 't${i++}'; |
| 421 while (usedNames.contains(name)) name = 't${i++}'; | 426 while (usedNames.contains(name)) name = 't${i++}'; |
|
Lasse Reichstein Nielsen
2012/06/07 08:53:21
This looks like something that has quadratic perfo
ngeoffray
2012/06/07 09:10:41
Good point. Done.
| |
| 422 return name; | 427 return name; |
| 423 } | 428 } |
| 424 | 429 |
| 425 HPhi firstPhiUserWithElement(HInstruction instruction) { | 430 HPhi firstPhiUserWithElement(HInstruction instruction) { |
| 426 for (HInstruction user in instruction.usedBy) { | 431 for (HInstruction user in instruction.usedBy) { |
| 427 if (user is HPhi && user.sourceElement !== null) { | 432 if (user is HPhi && user.sourceElement !== null) { |
| 428 return user; | 433 return user; |
| 429 } | 434 } |
| 430 } | 435 } |
| 431 return null; | 436 return null; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 final Map<HInstruction, LiveInterval> liveIntervals; | 501 final Map<HInstruction, LiveInterval> liveIntervals; |
| 497 final Set<HInstruction> generateAtUseSite; | 502 final Set<HInstruction> generateAtUseSite; |
| 498 final Map<Element, String> parameterNames; | 503 final Map<Element, String> parameterNames; |
| 499 | 504 |
| 500 final VariableNames names; | 505 final VariableNames names; |
| 501 | 506 |
| 502 SsaVariableAllocator(this.compiler, | 507 SsaVariableAllocator(this.compiler, |
| 503 this.liveInstructions, | 508 this.liveInstructions, |
| 504 this.liveIntervals, | 509 this.liveIntervals, |
| 505 this.generateAtUseSite, | 510 this.generateAtUseSite, |
| 506 this.parameterNames) | 511 parameterNames) |
| 507 : names = new VariableNames(); | 512 : this.names = new VariableNames(parameterNames), |
| 513 this.parameterNames = parameterNames; | |
| 508 | 514 |
| 509 void visitGraph(HGraph graph) { | 515 void visitGraph(HGraph graph) { |
| 510 visitDominatorTree(graph); | 516 visitDominatorTree(graph); |
| 511 } | 517 } |
| 512 | 518 |
| 513 void visitBasicBlock(HBasicBlock block) { | 519 void visitBasicBlock(HBasicBlock block) { |
| 514 VariableNamer namer = new VariableNamer( | 520 VariableNamer namer = new VariableNamer( |
| 515 liveInstructions[block], names, parameterNames); | 521 liveInstructions[block], names, parameterNames); |
| 516 | 522 |
| 517 block.forEachPhi((HPhi phi) { | 523 block.forEachPhi((HPhi phi) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 571 if (!needsName(input)) { | 577 if (!needsName(input)) { |
| 572 names.addAssignment(predecessor, input, phi); | 578 names.addAssignment(predecessor, input, phi); |
| 573 } else { | 579 } else { |
| 574 names.addCopy(predecessor, input, phi); | 580 names.addCopy(predecessor, input, phi); |
| 575 } | 581 } |
| 576 } | 582 } |
| 577 | 583 |
| 578 namer.allocateName(phi); | 584 namer.allocateName(phi); |
| 579 } | 585 } |
| 580 } | 586 } |
| OLD | NEW |