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 |