Index: lib/compiler/implementation/ssa/codegen.dart |
diff --git a/lib/compiler/implementation/ssa/codegen.dart b/lib/compiler/implementation/ssa/codegen.dart |
index 98a7c72ccf61d68f50a04916fd76a659f32ff031..114e781d29a57573691104861bb86c0072f450c2 100644 |
--- a/lib/compiler/implementation/ssa/codegen.dart |
+++ b/lib/compiler/implementation/ssa/codegen.dart |
@@ -1102,7 +1102,9 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
* Sequentialize a list of conceptually parallel copies. Parallel |
* copies may contain cycles, that this method breaks. |
*/ |
- void sequentializeCopies(List<Copy> copies) { |
+ void sequentializeCopies(List<Copy> copies, |
+ String tempName, |
ngeoffray
2012/10/25 11:27:45
Why parameterizing tempName? It's swapTemp for bot
floitsch
2012/10/31 14:49:19
I don't want sequentializeCopies to deal with the
|
+ void doAssignment(String target, String source)) { |
// Map to keep track of the current location (ie the variable that |
// holds the initial value) of a variable. |
Map<String, String> currentLocation = new Map<String, String>(); |
@@ -1120,10 +1122,8 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
// Prune [copies] by removing self-copies. |
List<Copy> prunedCopies = <Copy>[]; |
for (Copy copy in copies) { |
- String sourceName = variableNames.getName(copy.source); |
- String destinationName = variableNames.getName(copy.destination); |
- if (sourceName != destinationName) { |
- prunedCopies.add(new Copy(sourceName, destinationName)); |
+ if (copy.source != copy.destination) { |
+ prunedCopies.add(copy); |
} |
} |
copies = prunedCopies; |
@@ -1153,7 +1153,7 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
// Since [source] might have been updated, use the current |
// location of [source] |
String copy = currentLocation[source]; |
- emitAssignment(destination, copy); |
+ doAssignment(destination, copy); |
// Now [destination] is the current location of [source]. |
currentLocation[source] = destination; |
// If [source] hasn't been updated and needs to have a value, |
@@ -1171,8 +1171,7 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
// cycle that we break by using a temporary name. |
if (currentLocation[current] != null |
&& current != currentLocation[initialValue[current]]) { |
- String tempName = variableNames.swapTemp; |
- emitAssignment(tempName, current); |
+ doAssignment(tempName, current); |
currentLocation[current] = tempName; |
// [current] can now be safely updated. Copies of [current] |
// will now use [tempName]. |
@@ -1185,7 +1184,13 @@ abstract class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor { |
CopyHandler handler = variableNames.getCopyHandler(node); |
if (handler == null) return; |
- sequentializeCopies(handler.copies); |
+ // Map the instructions to strings. |
+ List<Copy> copies = handler.copies.map((Copy copy) { |
+ return new Copy(variableNames.getName(copy.source), |
+ variableNames.getName(copy.destination)); |
+ }); |
+ |
+ sequentializeCopies(copies, variableNames.swapTemp, emitAssignment); |
for (Copy copy in handler.assignments) { |
String name = variableNames.getName(copy.destination); |
@@ -2794,26 +2799,32 @@ class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { |
pushExpressionAsStatement(new js.Assignment(generateStateUse(), |
new js.LiteralNumber('0'))); |
js.Block setupBlock = new js.Block.empty(); |
- int i = 0; |
- for (HInstruction input in node.inputs) { |
+ List<Copy> copies = <Copy>[]; |
+ for (int i = 0; i < node.inputs.length; i++) { |
+ HInstruction input = node.inputs[i]; |
input = unwrap(input); |
String name = variableNames.getName(input); |
- if (!isVariableDeclared(name)) { |
- declaredVariables.add(name); |
+ String source = "env$i"; |
+ copies.add(new Copy(source, name)); |
+ } |
+ sequentializeCopies(copies, |
+ variableNames.swapTemp, |
+ (String target, String source) { |
+ if (!isVariableDeclared(target)) { |
+ declaredVariables.add(target); |
js.VariableInitialization init = |
- new js.VariableInitialization(new js.VariableDeclaration(name), |
- new js.VariableUse('env$i')); |
+ new js.VariableInitialization(new js.VariableDeclaration(target), |
+ new js.VariableUse(source)); |
js.Expression varList = |
new js.VariableDeclarationList(<js.VariableInitialization>[init]); |
setupBlock.statements.add(new js.ExpressionStatement(varList)); |
} else { |
- js.Expression target = new js.VariableUse(name); |
- js.Expression source = new js.VariableUse('env$i'); |
- js.Expression assignment = new js.Assignment(target, source); |
+ js.Expression jsTarget = new js.VariableUse(target); |
+ js.Expression jsSource = new js.VariableUse(source); |
+ js.Expression assignment = new js.Assignment(jsTarget, jsSource); |
setupBlock.statements.add(new js.ExpressionStatement(assignment)); |
} |
- i++; |
- } |
+ }); |
setupBlock.statements.add(new js.Break(null)); |
js.Case setupClause = |
new js.Case(new js.LiteralNumber('${node.state}'), setupBlock); |