| Index: pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
|
| diff --git a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
|
| index 9ca641e87c458a81bbfcc0818aeb7d8b02002798..32a8cffb065d6e313599dec255ff5bc4a3d16b9f 100644
|
| --- a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
|
| +++ b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
|
| @@ -34,7 +34,7 @@ class VariableMerger extends RecursiveVisitor implements Pass {
|
| builder.build(node.parameters, body);
|
| _computeLiveness(builder.blocks);
|
| Map<Variable, Variable> subst =
|
| - _computeRegisterAllocation(builder.blocks);
|
| + _computeRegisterAllocation(builder.blocks, node.parameters);
|
| new SubstituteVariables(subst).apply(node);
|
| });
|
| }
|
| @@ -355,20 +355,20 @@ const bool NO_PRESERVE_VARS = const bool.fromEnvironment('NO_PRESERVE_VARS');
|
| ///
|
| /// We never merge variables that originated from distinct source variables,
|
| /// so we build a separate register interference graph for each source variable.
|
| -Map<Variable, Variable> _computeRegisterAllocation(List<Block> blocks) {
|
| +Map<Variable, Variable> _computeRegisterAllocation(List<Block> blocks,
|
| + List<Variable> parameters) {
|
| Map<Variable, Set<Variable>> interference = <Variable, Set<Variable>>{};
|
|
|
| /// Group for the given variable. We attempt to merge variables in the same
|
| /// group.
|
| - /// By default, variables are grouped based on their source variable, but
|
| - /// this can be disabled for testing purposes.
|
| - Local group(Variable variable) {
|
| - if (NO_PRESERVE_VARS) {
|
| - // Parameters may not occur more than once in a parameter list,
|
| - // so except for parameters, we try to merge all variables.
|
| - return variable.element is ParameterElement ? variable.element : null;
|
| - }
|
| - return variable.element;
|
| + /// By default, variables are grouped based on their source variable name,
|
| + /// but this can be disabled for testing purposes.
|
| + String group(Variable variable) {
|
| + if (NO_PRESERVE_VARS) return '';
|
| + // Group variables based on the source variable's name, not its element,
|
| + // so if multiple locals are declared with the same name, they will
|
| + // map to the same (hoisted) variable in the output.
|
| + return variable.element == null ? '' : variable.element.name;
|
| }
|
|
|
| Set<Variable> empty = new Set<Variable>();
|
| @@ -377,7 +377,7 @@ Map<Variable, Variable> _computeRegisterAllocation(List<Block> blocks) {
|
| // live after the assignment (if it came from the same source variable).
|
| for (Block block in blocks) {
|
| // Group the liveOut set by source variable.
|
| - Map<Local, Set<Variable>> liveOut = <Local, Set<Variable>>{};
|
| + Map<String, Set<Variable>> liveOut = <String, Set<Variable>>{};
|
| for (Variable variable in block.liveOut) {
|
| liveOut.putIfAbsent(
|
| group(variable),
|
| @@ -414,10 +414,21 @@ Map<Variable, Variable> _computeRegisterAllocation(List<Block> blocks) {
|
| List<Variable> variables = interference.keys.toList();
|
| variables.sort((x, y) => interference[y].length - interference[x].length);
|
|
|
| - Map<Local, List<Variable>> registers = <Local, List<Variable>>{};
|
| + Map<String, List<Variable>> registers = <String, List<Variable>>{};
|
| Map<Variable, Variable> subst = <Variable, Variable>{};
|
|
|
| + // Parameters are special in that they must have a ParameterElement and
|
| + // cannot be merged with each other. Ensure that they are not substituted.
|
| + // Other variables can still be substituted by a parameter.
|
| + for (Variable parameter in parameters) {
|
| + subst[parameter] = parameter;
|
| + registers[group(parameter)] = <Variable>[parameter];
|
| + }
|
| +
|
| for (Variable v1 in variables) {
|
| + // Parameters have already been assigned a substitute; skip those.
|
| + if (subst.containsKey(v1)) continue;
|
| +
|
| List<Variable> register = registers[group(v1)];
|
|
|
| // Optimization: For the first variable in a group, allocate a new color
|
|
|