| 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 16 matching lines...) Expand all Loading... |
| 27 phase.visitGraph(graph); | 27 phase.visitGraph(graph); |
| 28 compiler.tracer.traceGraph(phase.name, graph); | 28 compiler.tracer.traceGraph(phase.name, graph); |
| 29 assert(graph.isValid()); | 29 assert(graph.isValid()); |
| 30 } | 30 } |
| 31 | 31 |
| 32 void optimize(CodegenWorkItem work, HGraph graph, bool speculative) { | 32 void optimize(CodegenWorkItem work, HGraph graph, bool speculative) { |
| 33 ConstantSystem constantSystem = compiler.backend.constantSystem; | 33 ConstantSystem constantSystem = compiler.backend.constantSystem; |
| 34 JavaScriptItemCompilationContext context = work.compilationContext; | 34 JavaScriptItemCompilationContext context = work.compilationContext; |
| 35 measure(() { | 35 measure(() { |
| 36 List<OptimizationPhase> phases = <OptimizationPhase>[ | 36 List<OptimizationPhase> phases = <OptimizationPhase>[ |
| 37 // Run trivial constant folding first to optimize | 37 // Run trivial instruction simplification first to optimize |
| 38 // some patterns useful for type conversion. | 38 // some patterns useful for type conversion. |
| 39 new SsaConstantFolder(constantSystem, backend, work), | 39 new SsaInstructionSimplifier(constantSystem, backend, work), |
| 40 new SsaTypeConversionInserter(compiler), | 40 new SsaTypeConversionInserter(compiler), |
| 41 new SsaNonSpeculativeTypePropagator(compiler), | 41 new SsaNonSpeculativeTypePropagator(compiler), |
| 42 new SsaConstantFolder(constantSystem, backend, work), | 42 // After type propagation, more instructions can be |
| 43 // The constant folder affects the types of instructions, so | 43 // simplified. |
| 44 // we run the type propagator again. Note that this would | 44 new SsaInstructionSimplifier(constantSystem, backend, work), |
| 45 // not be necessary if types were directly stored on | |
| 46 // instructions. | |
| 47 new SsaNonSpeculativeTypePropagator(compiler), | |
| 48 new SsaCheckInserter(backend, work, context.boundsChecked), | 45 new SsaCheckInserter(backend, work, context.boundsChecked), |
| 49 new SsaRedundantPhiEliminator(), | 46 new SsaRedundantPhiEliminator(), |
| 50 new SsaDeadPhiEliminator(), | 47 new SsaDeadPhiEliminator(), |
| 51 new SsaConstantFolder(constantSystem, backend, work), | 48 new SsaInstructionSimplifier(constantSystem, backend, work), |
| 52 new SsaNonSpeculativeTypePropagator(compiler), | 49 new SsaNonSpeculativeTypePropagator(compiler), |
| 53 // Run a dead code eliminator before LICM because dead | 50 // Run a dead code eliminator before LICM because dead |
| 54 // interceptors are often in the way of LICM'able instructions. | 51 // interceptors are often in the way of LICM'able instructions. |
| 55 new SsaDeadCodeEliminator(), | 52 new SsaDeadCodeEliminator(), |
| 56 new SsaGlobalValueNumberer(compiler), | 53 new SsaGlobalValueNumberer(compiler), |
| 57 new SsaCodeMotion(), | 54 new SsaCodeMotion(), |
| 58 new SsaValueRangeAnalyzer(compiler, constantSystem, work), | 55 new SsaValueRangeAnalyzer(compiler, constantSystem, work), |
| 59 // Previous optimizations may have generated new | 56 // Previous optimizations may have generated new |
| 60 // opportunities for constant folding. | 57 // opportunities for instruction simplification. |
| 61 new SsaConstantFolder(constantSystem, backend, work), | 58 new SsaInstructionSimplifier(constantSystem, backend, work), |
| 62 new SsaSimplifyInterceptors(compiler, constantSystem, work), | 59 new SsaSimplifyInterceptors(compiler, constantSystem, work), |
| 63 new SsaDeadCodeEliminator()]; | 60 new SsaDeadCodeEliminator()]; |
| 64 runPhases(graph, phases); | 61 runPhases(graph, phases); |
| 65 }); | 62 }); |
| 66 } | 63 } |
| 67 | 64 |
| 68 bool trySpeculativeOptimizations(CodegenWorkItem work, HGraph graph) { | 65 bool trySpeculativeOptimizations(CodegenWorkItem work, HGraph graph) { |
| 69 if (work.element.isField()) { | 66 if (work.element.isField()) { |
| 70 // Lazy initializers may not have bailout methods. | 67 // Lazy initializers may not have bailout methods. |
| 71 return false; | 68 return false; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 new SsaCheckInserter(backend, work, context.boundsChecked), | 112 new SsaCheckInserter(backend, work, context.boundsChecked), |
| 116 new SsaNonSpeculativeTypePropagator(compiler)]); | 113 new SsaNonSpeculativeTypePropagator(compiler)]); |
| 117 }); | 114 }); |
| 118 } | 115 } |
| 119 } | 116 } |
| 120 | 117 |
| 121 /** | 118 /** |
| 122 * If both inputs to known operations are available execute the operation at | 119 * If both inputs to known operations are available execute the operation at |
| 123 * compile-time. | 120 * compile-time. |
| 124 */ | 121 */ |
| 125 class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { | 122 class SsaInstructionSimplifier extends HBaseVisitor |
| 126 final String name = "SsaConstantFolder"; | 123 implements OptimizationPhase { |
| 124 final String name = "SsaInstructionSimplifier"; |
| 127 final JavaScriptBackend backend; | 125 final JavaScriptBackend backend; |
| 128 final CodegenWorkItem work; | 126 final CodegenWorkItem work; |
| 129 final ConstantSystem constantSystem; | 127 final ConstantSystem constantSystem; |
| 130 HGraph graph; | 128 HGraph graph; |
| 131 Compiler get compiler => backend.compiler; | 129 Compiler get compiler => backend.compiler; |
| 132 | 130 |
| 133 SsaConstantFolder(this.constantSystem, this.backend, this.work); | 131 SsaInstructionSimplifier(this.constantSystem, this.backend, this.work); |
| 134 | 132 |
| 135 void visitGraph(HGraph visitee) { | 133 void visitGraph(HGraph visitee) { |
| 136 graph = visitee; | 134 graph = visitee; |
| 137 visitDominatorTree(visitee); | 135 visitDominatorTree(visitee); |
| 138 } | 136 } |
| 139 | 137 |
| 140 visitBasicBlock(HBasicBlock block) { | 138 visitBasicBlock(HBasicBlock block) { |
| 141 HInstruction instruction = block.first; | 139 HInstruction instruction = block.first; |
| 142 while (instruction != null) { | 140 while (instruction != null) { |
| 143 HInstruction next = instruction.next; | 141 HInstruction next = instruction.next; |
| (...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 // that knows it is not of a specific Type. | 1337 // that knows it is not of a specific Type. |
| 1340 } | 1338 } |
| 1341 | 1339 |
| 1342 for (HIf ifUser in notIfUsers) { | 1340 for (HIf ifUser in notIfUsers) { |
| 1343 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); | 1341 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); |
| 1344 // TODO(ngeoffray): Also change uses for the then block on a HType | 1342 // TODO(ngeoffray): Also change uses for the then block on a HType |
| 1345 // that knows it is not of a specific Type. | 1343 // that knows it is not of a specific Type. |
| 1346 } | 1344 } |
| 1347 } | 1345 } |
| 1348 } | 1346 } |
| OLD | NEW |