| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class OptimizationPhase { | 7 abstract class OptimizationPhase { |
| 8 String get name; | 8 String get name; |
| 9 void visitGraph(HGraph graph); | 9 void visitGraph(HGraph graph); |
| 10 } | 10 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 // The constant folder affects the types of instructions, so | 43 // The constant folder affects the types of instructions, so |
| 44 // we run the type propagator again. Note that this would | 44 // we run the type propagator again. Note that this would |
| 45 // not be necessary if types were directly stored on | 45 // not be necessary if types were directly stored on |
| 46 // instructions. | 46 // instructions. |
| 47 new SsaNonSpeculativeTypePropagator(compiler), | 47 new SsaNonSpeculativeTypePropagator(compiler), |
| 48 new SsaCheckInserter(backend, work, context.boundsChecked), | 48 new SsaCheckInserter(backend, work, context.boundsChecked), |
| 49 new SsaRedundantPhiEliminator(), | 49 new SsaRedundantPhiEliminator(), |
| 50 new SsaDeadPhiEliminator(), | 50 new SsaDeadPhiEliminator(), |
| 51 new SsaConstantFolder(constantSystem, backend, work), | 51 new SsaConstantFolder(constantSystem, backend, work), |
| 52 new SsaNonSpeculativeTypePropagator(compiler), | 52 new SsaNonSpeculativeTypePropagator(compiler), |
| 53 // Run a dead code eliminator before LICM because dead |
| 54 // interceptors are often in the way of LICM'able instructions. |
| 55 new SsaDeadCodeEliminator(), |
| 53 new SsaGlobalValueNumberer(compiler), | 56 new SsaGlobalValueNumberer(compiler), |
| 54 new SsaCodeMotion(), | 57 new SsaCodeMotion(), |
| 55 new SsaValueRangeAnalyzer(compiler, constantSystem, work), | 58 new SsaValueRangeAnalyzer(compiler, constantSystem, work), |
| 56 // Previous optimizations may have generated new | 59 // Previous optimizations may have generated new |
| 57 // opportunities for constant folding. | 60 // opportunities for constant folding. |
| 58 new SsaConstantFolder(constantSystem, backend, work), | 61 new SsaConstantFolder(constantSystem, backend, work), |
| 59 new SsaSimplifyInterceptors(compiler, constantSystem, work), | 62 new SsaSimplifyInterceptors(compiler, constantSystem, work), |
| 60 new SsaDeadCodeEliminator()]; | 63 new SsaDeadCodeEliminator()]; |
| 61 runPhases(graph, phases); | 64 runPhases(graph, phases); |
| 62 }); | 65 }); |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 for (int i = graph.blocks.length - 1; i >= 0; i--) { | 1009 for (int i = graph.blocks.length - 1; i >= 0; i--) { |
| 1007 HBasicBlock block = graph.blocks[i]; | 1010 HBasicBlock block = graph.blocks[i]; |
| 1008 if (block.isLoopHeader()) { | 1011 if (block.isLoopHeader()) { |
| 1009 int changesFlags = loopChangesFlags[block.id]; | 1012 int changesFlags = loopChangesFlags[block.id]; |
| 1010 HLoopInformation info = block.loopInformation; | 1013 HLoopInformation info = block.loopInformation; |
| 1011 // Iterate over all blocks of this loop. Note that blocks in | 1014 // Iterate over all blocks of this loop. Note that blocks in |
| 1012 // inner loops are not visited here, but we know they | 1015 // inner loops are not visited here, but we know they |
| 1013 // were visited before because we are iterating in post-order. | 1016 // were visited before because we are iterating in post-order. |
| 1014 // So instructions that are GVN'ed in an inner loop are in their | 1017 // So instructions that are GVN'ed in an inner loop are in their |
| 1015 // loop entry, and [info.blocks] contains this loop entry. | 1018 // loop entry, and [info.blocks] contains this loop entry. |
| 1019 moveLoopInvariantCodeFromBlock(block, block, changesFlags); |
| 1016 for (HBasicBlock other in info.blocks) { | 1020 for (HBasicBlock other in info.blocks) { |
| 1017 moveLoopInvariantCodeFromBlock(other, block, changesFlags); | 1021 moveLoopInvariantCodeFromBlock(other, block, changesFlags); |
| 1018 } | 1022 } |
| 1019 } | 1023 } |
| 1020 } | 1024 } |
| 1021 } | 1025 } |
| 1022 | 1026 |
| 1023 void moveLoopInvariantCodeFromBlock(HBasicBlock block, | 1027 void moveLoopInvariantCodeFromBlock(HBasicBlock block, |
| 1024 HBasicBlock loopHeader, | 1028 HBasicBlock loopHeader, |
| 1025 int changesFlags) { | 1029 int changesFlags) { |
| 1026 assert(block.parentLoopHeader == loopHeader); | 1030 assert(block.parentLoopHeader == loopHeader); |
| 1027 HBasicBlock preheader = loopHeader.predecessors[0]; | 1031 HBasicBlock preheader = loopHeader.predecessors[0]; |
| 1028 int dependsFlags = SideEffects.computeDependsOnFlags(changesFlags); | 1032 int dependsFlags = SideEffects.computeDependsOnFlags(changesFlags); |
| 1029 HInstruction instruction = block.first; | 1033 HInstruction instruction = block.first; |
| 1034 bool firstInstructionInLoop = block == loopHeader; |
| 1030 while (instruction != null) { | 1035 while (instruction != null) { |
| 1031 HInstruction next = instruction.next; | 1036 HInstruction next = instruction.next; |
| 1032 if (instruction.useGvn() | 1037 if (instruction.useGvn() |
| 1033 && !instruction.canThrow() | 1038 && (!instruction.canThrow() || firstInstructionInLoop) |
| 1034 && !instruction.sideEffects.dependsOn(dependsFlags)) { | 1039 && !instruction.sideEffects.dependsOn(dependsFlags)) { |
| 1035 bool loopInvariantInputs = true; | 1040 bool loopInvariantInputs = true; |
| 1036 List<HInstruction> inputs = instruction.inputs; | 1041 List<HInstruction> inputs = instruction.inputs; |
| 1037 for (int i = 0, length = inputs.length; i < length; i++) { | 1042 for (int i = 0, length = inputs.length; i < length; i++) { |
| 1038 if (isInputDefinedAfterDominator(inputs[i], preheader)) { | 1043 if (isInputDefinedAfterDominator(inputs[i], preheader)) { |
| 1039 loopInvariantInputs = false; | 1044 loopInvariantInputs = false; |
| 1040 break; | 1045 break; |
| 1041 } | 1046 } |
| 1042 } | 1047 } |
| 1043 | 1048 |
| 1044 // If the inputs are loop invariant, we can move the | 1049 // If the inputs are loop invariant, we can move the |
| 1045 // instruction from the current block to the pre-header block. | 1050 // instruction from the current block to the pre-header block. |
| 1046 if (loopInvariantInputs) { | 1051 if (loopInvariantInputs) { |
| 1047 block.detach(instruction); | 1052 block.detach(instruction); |
| 1048 preheader.moveAtExit(instruction); | 1053 preheader.moveAtExit(instruction); |
| 1054 } else { |
| 1055 firstInstructionInLoop = false; |
| 1049 } | 1056 } |
| 1050 } | 1057 } |
| 1051 int oldChangesFlags = changesFlags; | 1058 int oldChangesFlags = changesFlags; |
| 1052 changesFlags |= instruction.sideEffects.getChangesFlags(); | 1059 changesFlags |= instruction.sideEffects.getChangesFlags(); |
| 1053 if (oldChangesFlags != changesFlags) { | 1060 if (oldChangesFlags != changesFlags) { |
| 1054 dependsFlags = SideEffects.computeDependsOnFlags(changesFlags); | 1061 dependsFlags = SideEffects.computeDependsOnFlags(changesFlags); |
| 1055 } | 1062 } |
| 1056 instruction = next; | 1063 instruction = next; |
| 1057 } | 1064 } |
| 1058 } | 1065 } |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 // that knows it is not of a specific Type. | 1330 // that knows it is not of a specific Type. |
| 1324 } | 1331 } |
| 1325 | 1332 |
| 1326 for (HIf ifUser in notIfUsers) { | 1333 for (HIf ifUser in notIfUsers) { |
| 1327 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); | 1334 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); |
| 1328 // TODO(ngeoffray): Also change uses for the then block on a HType | 1335 // TODO(ngeoffray): Also change uses for the then block on a HType |
| 1329 // that knows it is not of a specific Type. | 1336 // that knows it is not of a specific Type. |
| 1330 } | 1337 } |
| 1331 } | 1338 } |
| 1332 } | 1339 } |
| OLD | NEW |