Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 interface OptimizationPhase { | 5 interface OptimizationPhase { |
| 6 String get name(); | 6 String get name(); |
| 7 void visitGraph(HGraph graph); | 7 void visitGraph(HGraph graph); |
| 8 } | 8 } |
| 9 | 9 |
| 10 class SsaOptimizerTask extends CompilerTask { | 10 class SsaOptimizerTask extends CompilerTask { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 // some patterns useful for type conversion. | 29 // some patterns useful for type conversion. |
| 30 new SsaConstantFolder(backend, work), | 30 new SsaConstantFolder(backend, work), |
| 31 new SsaTypeConversionInserter(compiler), | 31 new SsaTypeConversionInserter(compiler), |
| 32 new SsaTypePropagator(compiler), | 32 new SsaTypePropagator(compiler), |
| 33 new SsaCheckInserter(backend), | 33 new SsaCheckInserter(backend), |
| 34 new SsaConstantFolder(backend, work), | 34 new SsaConstantFolder(backend, work), |
| 35 new SsaRedundantPhiEliminator(), | 35 new SsaRedundantPhiEliminator(), |
| 36 new SsaDeadPhiEliminator(), | 36 new SsaDeadPhiEliminator(), |
| 37 new SsaGlobalValueNumberer(compiler), | 37 new SsaGlobalValueNumberer(compiler), |
| 38 new SsaCodeMotion(), | 38 new SsaCodeMotion(), |
| 39 new SsaDeadCodeEliminator()]; | 39 new SsaDeadCodeEliminator(), |
| 40 new SsaGatherRecompileCandidates(backend, work)]; | |
| 40 runPhases(graph, phases); | 41 runPhases(graph, phases); |
| 41 }); | 42 }); |
| 42 } | 43 } |
| 43 | 44 |
| 44 bool trySpeculativeOptimizations(WorkItem work, HGraph graph) { | 45 bool trySpeculativeOptimizations(WorkItem work, HGraph graph) { |
| 45 return measure(() { | 46 return measure(() { |
| 46 // Run the phases that will generate type guards. | 47 // Run the phases that will generate type guards. |
| 47 List<OptimizationPhase> phases = <OptimizationPhase>[ | 48 List<OptimizationPhase> phases = <OptimizationPhase>[ |
| 48 new SsaSpeculativeTypePropagator(compiler), | 49 new SsaSpeculativeTypePropagator(compiler), |
| 49 new SsaTypeGuardInserter(compiler, work), | 50 new SsaTypeGuardInserter(compiler, work), |
| (...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1162 // the if block terminates. So any use of the instruction | 1163 // the if block terminates. So any use of the instruction |
| 1163 // after the join block should be changed to the new | 1164 // after the join block should be changed to the new |
| 1164 // instruction. | 1165 // instruction. |
| 1165 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); | 1166 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); |
| 1166 } | 1167 } |
| 1167 // TODO(ngeoffray): Also change uses for the then block on a HType | 1168 // TODO(ngeoffray): Also change uses for the then block on a HType |
| 1168 // that knows it is not of a specific Type. | 1169 // that knows it is not of a specific Type. |
| 1169 } | 1170 } |
| 1170 } | 1171 } |
| 1171 } | 1172 } |
| 1173 | |
| 1174 class SsaGatherRecompileCandidates | |
| 1175 extends HBaseVisitor implements OptimizationPhase { | |
| 1176 final String name = "SsaGatherRecompileCandidates"; | |
| 1177 final JavaScriptBackend backend; | |
| 1178 final WorkItem work; | |
| 1179 HGraph graph; | |
| 1180 Compiler get compiler() => backend.compiler; | |
| 1181 | |
| 1182 SsaGatherRecompileCandidates(this.backend, this.work); | |
| 1183 | |
| 1184 void visitGraph(HGraph visitee) { | |
| 1185 graph = visitee; | |
| 1186 visitDominatorTree(visitee); | |
| 1187 } | |
| 1188 | |
| 1189 HInstruction visitEquals(HEquals node) { | |
| 1190 // Try to optimize the case where a field which is known to always be an | |
| 1191 // integer is compared with a constant integer literal. | |
| 1192 if (node.left is HFieldGet && | |
| 1193 node.right is HConstant && | |
| 1194 node.right.isInteger()) { | |
| 1195 HFieldGet left = node.left; | |
| 1196 HConstant right = node.right; | |
| 1197 Type type = left.receiver.propagatedType.computeType(compiler); | |
|
floitsch
2012/06/15 15:00:50
move type into the 'if'?
Søren Gjesse
2012/06/18 11:32:17
Done.
| |
| 1198 if (left.element != null && right.isInteger()) { | |
|
floitsch
2012/06/15 15:00:50
we know already that right is an integer.
Søren Gjesse
2012/06/18 11:32:17
Done.
| |
| 1199 switch (compiler.pass) { | |
| 1200 case 1: | |
| 1201 if (compiler.codegenWorld.couldHaveFieldOnlyIntegerSetters( | |
| 1202 type, left.element.name) && | |
| 1203 compiler.codegenWorld.couldHaveFieldOnlyIntegerInitializer( | |
| 1204 type, left.element.name)) { | |
| 1205 compiler.enqueuer.codegen.registerRecompilationCandidate( | |
| 1206 work.element); | |
| 1207 } | |
| 1208 break; | |
| 1209 case 2: | |
| 1210 if (compiler.codegenWorld.hasFieldOnlyIntegerSetters( | |
| 1211 type, left.element.name) && | |
| 1212 compiler.codegenWorld.hasFieldOnlyIntegerInitializer( | |
| 1213 type, left.element.name)) { | |
| 1214 left.guaranteedType = HType.INTEGER; | |
| 1215 } | |
| 1216 break; | |
| 1217 } | |
| 1218 } | |
| 1219 } | |
| 1220 } | |
| 1221 } | |
| OLD | NEW |