Chromium Code Reviews| Index: pkg/compiler/lib/src/ssa/optimize.dart |
| diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart |
| index d872aec0e47305ae4f8590e1b5c7361c4db4580c..be43d1813185f479446846a8df3d7a9a4586a29a 100644 |
| --- a/pkg/compiler/lib/src/ssa/optimize.dart |
| +++ b/pkg/compiler/lib/src/ssa/optimize.dart |
| @@ -1185,7 +1185,8 @@ class SsaInstructionSimplifier extends HBaseVisitor |
| selector, |
| input.instructionType, // receiver mask. |
| inputs, |
| - toStringType)..sourceInformation = node.sourceInformation; |
| + toStringType) |
| + ..sourceInformation = node.sourceInformation; |
| return result; |
| } |
| return null; |
| @@ -2294,9 +2295,9 @@ class SsaTypeConversionInserter extends HBaseVisitor |
| } |
| /** |
| - * Optimization phase that tries to eliminate memory loads (for |
| - * example [HFieldGet]), when it knows the value stored in that memory |
| - * location. |
| + * Optimization phase that tries to eliminate memory loads (for example |
| + * [HFieldGet]), when it knows the value stored in that memory location, and |
| + * stores that overwrite with the same value. |
| */ |
| class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| final BackendHelpers _helpers; |
| @@ -2393,9 +2394,12 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| } |
| void visitFieldSet(HFieldSet instruction) { |
| + FieldEntity element = instruction.element; |
| HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck(); |
| - memorySet.registerFieldValueUpdate( |
| - instruction.element, receiver, instruction.inputs.last); |
| + if (memorySet.registerFieldValueUpdate( |
| + element, receiver, instruction.value)) { |
| + instruction.block.remove(instruction); |
| + } |
| } |
| void visitCreate(HCreate instruction) { |
| @@ -2482,8 +2486,10 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| } |
| void visitStaticStore(HStaticStore instruction) { |
| - memorySet.registerFieldValueUpdate( |
| - instruction.element, null, instruction.inputs.last); |
| + if (memorySet.registerFieldValueUpdate( |
| + instruction.element, null, instruction.inputs.last)) { |
| + instruction.block.remove(instruction); |
| + } |
| } |
| void visitLiteralList(HLiteralList instruction) { |
| @@ -2613,23 +2619,25 @@ class MemorySet { |
| /** |
| * Sets `receiver.element` to contain [value]. Kills all potential places that |
| - * may be affected by this update. |
| + * may be affected by this update. Returns `true` if the update is redundant. |
| */ |
| - void registerFieldValueUpdate( |
| + bool registerFieldValueUpdate( |
| MemberEntity element, HInstruction receiver, HInstruction value) { |
| assert(receiver == null || receiver == receiver.nonCheck()); |
| if (closedWorld.nativeData.isNativeMember(element)) { |
| - return; // TODO(14955): Remove this restriction? |
| + return false; // TODO(14955): Remove this restriction? |
| } |
| - // [value] is being set in some place in memory, we remove it from |
| - // the non-escaping set. |
| + // [value] is being set in some place in memory, we remove it from the |
| + // non-escaping set. |
| nonEscapingReceivers.remove(value.nonCheck()); |
|
Siggi Cherem (dart-lang)
2017/04/28 22:22:38
if the assignments is redundant, would the kill he
sra1
2017/04/28 23:25:24
I would expect so, but it is not worth skipping.
I
|
| Map<HInstruction, HInstruction> map = |
| fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{}); |
| + bool isRedundant = map[receiver] == value; |
| map.forEach((key, value) { |
| if (mayAlias(receiver, key)) map[key] = null; |
| }); |
| map[receiver] = value; |
| + return isRedundant; |
| } |
| /** |