Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: lib/compiler/implementation/ssa/variable_allocator.dart

Issue 10543027: Fixes for checked mode and change buildbot script to run dart2js tests in checked mode also. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/ssa/tracer.dart ('k') | tests/language/language_dart2js.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 108
109 /** 109 /**
110 * Remove an instruction from the liveIn set. This method also 110 * Remove an instruction from the liveIn set. This method also
111 * updates the live interval of [instruction] to contain the new 111 * updates the live interval of [instruction] to contain the new
112 * range: [id, / id contained in [liveInstructions] /]. 112 * range: [id, / id contained in [liveInstructions] /].
113 */ 113 */
114 void remove(HInstruction instruction, int id) { 114 void remove(HInstruction instruction, int id) {
115 // Special case the HCheck instruction to have the same live 115 // Special case the HCheck instruction to have the same live
116 // interval as the instruction it is checking. 116 // interval as the instruction it is checking.
117 if (instruction is HCheck) { 117 if (instruction is HCheck) {
118 HInstruction input = instruction.checkedInput; 118 var input = instruction.checkedInput;
119 while (input is HCheck) input = input.checkedInput; 119 while (input is HCheck) input = input.checkedInput;
120 liveIntervals.putIfAbsent(input, () => new LiveInterval()); 120 liveIntervals.putIfAbsent(input, () => new LiveInterval());
121 liveIntervals.putIfAbsent(instruction, () => liveIntervals[input]); 121 liveIntervals.putIfAbsent(instruction, () => liveIntervals[input]);
122 return; 122 } else {
123 LiveInterval range = liveIntervals.putIfAbsent(
124 instruction, () => new LiveInterval());
125 int lastId = liveInstructions[instruction];
126 // If [lastId] is null, then this instruction is not being used.
127 range.add(new LiveRange(id, lastId == null ? id : lastId));
128 // The instruction is defined at [id].
129 range.start = id;
123 } 130 }
124 LiveInterval range = liveIntervals.putIfAbsent(
125 instruction, () => new LiveInterval());
126 int lastId = liveInstructions[instruction];
127 // If [lastId] is null, then this instruction is not being used.
128 range.add(new LiveRange(id, lastId == null ? id : lastId));
129 // The instruction is defined at [id].
130 range.start = id;
131 liveInstructions.remove(instruction); 131 liveInstructions.remove(instruction);
132 } 132 }
133 133
134 /** 134 /**
135 * Add [instruction] to the liveIn set. If the instruction is not 135 * Add [instruction] to the liveIn set. If the instruction is not
136 * already in the set, we save the id where it dies. 136 * already in the set, we save the id where it dies.
137 */ 137 */
138 void add(HInstruction instruction, int userId) { 138 void add(HInstruction instruction, int userId) {
139 // Special case the HCheck instruction to use the actual checked
140 // instruction.
141 while (instruction is HCheck) instruction = instruction.checkedInput;
142 // Note that we are visiting the grap in post-dominator order, so 139 // Note that we are visiting the grap in post-dominator order, so
143 // the first time we see a variable is when it dies. 140 // the first time we see a variable is when it dies.
144 liveInstructions.putIfAbsent(instruction, () => userId); 141 liveInstructions.putIfAbsent(instruction, () => userId);
142 if (instruction is HCheck) {
143 // Special case the HCheck instruction to mark the actual
144 // checked instruction live.
145 liveInstructions.putIfAbsent(instruction, () => userId);
146 var input = instruction.checkedInput;
147 while (input is HCheck) input = input.checkedInput;
148 liveInstructions.putIfAbsent(input, () => userId);
149 }
145 } 150 }
146 151
147 /** 152 /**
148 * Merge this environment with [other]. Update the end id of 153 * Merge this environment with [other]. Update the end id of
149 * instructions in case they are different between this and [other]. 154 * instructions in case they are different between this and [other].
150 */ 155 */
151 void mergeWith(LiveEnvironment other) { 156 void mergeWith(LiveEnvironment other) {
152 other.liveInstructions.forEach((HInstruction instruction, int existingId) { 157 other.liveInstructions.forEach((HInstruction instruction, int existingId) {
153 // If both environments have the same instruction id of where 158 // If both environments have the same instruction id of where
154 // [instruction] dies, there is no need to update the live 159 // [instruction] dies, there is no need to update the live
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
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;
432 } 437 }
433 438
434 String allocateName(HInstruction instruction) { 439 String allocateName(HInstruction instruction) {
435 String name; 440 String name;
436 if (instruction is HCheck) { 441 if (instruction is HCheck) {
437 // Special case the check instruction to use the name of its 442 // Special case this instruction to use the name of its
438 // checked instruction. 443 // input if it has one.
439 HCheck check = instruction; 444 var temp = instruction;
440 name = names.ownName[check.checkedInput]; 445 do {
441 // If the name is null, then the checked input is being 446 temp = temp.checkedInput;
442 // generated at use site, and we don't need a name for the check 447 name = names.ownName[temp];
443 // instruction. 448 } while (name == null && temp is HCheck);
444 if (name == null) return null; 449 }
445 } else if (instruction is HParameterValue) { 450
446 HParameterValue parameter = instruction; 451 if (name == null) {
447 name = parameterNames[parameter.sourceElement]; 452 if (instruction is HParameterValue) {
kasperl 2012/06/07 08:29:14 There's something a bit fishy about the control fl
ngeoffray 2012/06/07 09:02:42 Done.
448 if (name == null) { 453 HParameterValue parameter = instruction;
449 name = allocateWithHint(parameter.sourceElement.name.slowToString()); 454 name = parameterNames[parameter.sourceElement];
450 } 455 if (name == null) {
451 } else if (instruction.sourceElement !== null) { 456 name = allocateWithHint(parameter.sourceElement.name.slowToString());
452 name = allocateWithHint(instruction.sourceElement.name.slowToString()); 457 }
453 } else { 458 } else if (instruction.sourceElement !== null) {
454 // We could not find an element for the instruction. If the 459 name = allocateWithHint(instruction.sourceElement.name.slowToString());
455 // instruction is used by a phi, try to use the name of the phi.
456 // Otherwise, just allocate a temporary name.
457 HPhi phi = firstPhiUserWithElement(instruction);
458 if (phi !== null) {
459 name = allocateWithHint(phi.sourceElement.name.slowToString());
460 } else { 460 } else {
461 name = allocateTemporary(); 461 // We could not find an element for the instruction. If the
462 // instruction is used by a phi, try to use the name of the phi.
463 // Otherwise, just allocate a temporary name.
464 HPhi phi = firstPhiUserWithElement(instruction);
465 if (phi !== null) {
466 name = allocateWithHint(phi.sourceElement.name.slowToString());
467 } else {
468 name = allocateTemporary();
469 }
462 } 470 }
463 } 471 }
464 usedNames.add(name); 472 usedNames.add(name);
kasperl 2012/06/07 08:29:14 You could also create a helper function for this l
ngeoffray 2012/06/07 09:02:42 Done.
465 names.ownName[instruction] = name; 473 names.ownName[instruction] = name;
466 return name; 474 return name;
467 } 475 }
468 476
469 /** 477 /**
470 * Frees [instruction]'s name so it can be used for other instructions. 478 * Frees [instruction]'s name so it can be used for other instructions.
471 */ 479 */
472 void freeName(HInstruction instruction) { 480 void freeName(HInstruction instruction) {
473 String ownName = names.ownName[instruction]; 481 String ownName = names.ownName[instruction];
474 if (ownName != null) { 482 if (ownName != null) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 * Returns whether [instruction] needs a name. Instructions that 535 * Returns whether [instruction] needs a name. Instructions that
528 * have no users or that are generated at use site does not need a name. 536 * have no users or that are generated at use site does not need a name.
529 */ 537 */
530 bool needsName(HInstruction instruction) { 538 bool needsName(HInstruction instruction) {
531 if (instruction.usedBy.isEmpty()) return false; 539 if (instruction.usedBy.isEmpty()) return false;
532 // TODO(ngeoffray): parameters are being generated at use site, 540 // TODO(ngeoffray): parameters are being generated at use site,
533 // but we need a name for parameters. We should probably not make 541 // but we need a name for parameters. We should probably not make
534 // them generate at use site to make things simpler. 542 // them generate at use site to make things simpler.
535 if (instruction is HParameterValue && instruction is !HThis) return true; 543 if (instruction is HParameterValue && instruction is !HThis) return true;
536 if (generateAtUseSite.contains(instruction)) return false; 544 if (generateAtUseSite.contains(instruction)) return false;
545 // A [HCheckStatement] instruction needs a name only if its
546 // checked input needs a name (e.g. a check [HConstant] does not
547 // need a name).
548 if (instruction is HCheckStatement) {
549 HCheck check = instruction;
550 return needsName(instruction.checkedInput);
551 }
537 return true; 552 return true;
538 } 553 }
539 554
540 /** 555 /**
541 * Returns whether [instruction] dies at the instruction [at]. 556 * Returns whether [instruction] dies at the instruction [at].
542 */ 557 */
543 bool diesAt(HInstruction instruction, HInstruction at) { 558 bool diesAt(HInstruction instruction, HInstruction at) {
544 LiveInterval atInterval = liveIntervals[at]; 559 LiveInterval atInterval = liveIntervals[at];
545 LiveInterval instructionInterval = liveIntervals[instruction]; 560 LiveInterval instructionInterval = liveIntervals[instruction];
546 int start = atInterval.start; 561 int start = atInterval.start;
(...skipping 24 matching lines...) Expand all
571 if (!needsName(input)) { 586 if (!needsName(input)) {
572 names.addAssignment(predecessor, input, phi); 587 names.addAssignment(predecessor, input, phi);
573 } else { 588 } else {
574 names.addCopy(predecessor, input, phi); 589 names.addCopy(predecessor, input, phi);
575 } 590 }
576 } 591 }
577 592
578 namer.allocateName(phi); 593 namer.allocateName(phi);
579 } 594 }
580 } 595 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/tracer.dart ('k') | tests/language/language_dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698