Chromium Code Reviews| 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 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 SsaProcessRecompileCandidates(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 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1164 // the if block terminates. So any use of the instruction | 1165 // the if block terminates. So any use of the instruction |
| 1165 // after the join block should be changed to the new | 1166 // after the join block should be changed to the new |
| 1166 // instruction. | 1167 // instruction. |
| 1167 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); | 1168 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); |
| 1168 } | 1169 } |
| 1169 // TODO(ngeoffray): Also change uses for the then block on a HType | 1170 // TODO(ngeoffray): Also change uses for the then block on a HType |
| 1170 // that knows it is not of a specific Type. | 1171 // that knows it is not of a specific Type. |
| 1171 } | 1172 } |
| 1172 } | 1173 } |
| 1173 } | 1174 } |
| 1175 | |
| 1176 class SsaProcessRecompileCandidates | |
| 1177 extends HBaseVisitor implements OptimizationPhase { | |
| 1178 final String name = "SsaProcessRecompileCandidates"; | |
| 1179 final JavaScriptBackend backend; | |
| 1180 final WorkItem work; | |
| 1181 HGraph graph; | |
| 1182 Compiler get compiler() => backend.compiler; | |
| 1183 | |
| 1184 SsaProcessRecompileCandidates(this.backend, this.work); | |
| 1185 | |
| 1186 void visitGraph(HGraph visitee) { | |
| 1187 graph = visitee; | |
| 1188 visitDominatorTree(visitee); | |
| 1189 } | |
| 1190 | |
| 1191 HInstruction visitEquals(HEquals node) { | |
| 1192 // Try to optimize the case where a field which is known to always be an | |
| 1193 // integer is compared with a constant integer literal. | |
| 1194 if (node.left is HFieldGet && | |
| 1195 node.right is HConstant && | |
| 1196 node.right.isInteger()) { | |
| 1197 HFieldGet left = node.left; | |
| 1198 HConstant right = node.right; | |
| 1199 if (left.element != null) { | |
| 1200 Type type = left.receiver.propagatedType.computeType(compiler); | |
| 1201 switch (compiler.phase) { | |
| 1202 case Compiler.PHASE_COMPILING: | |
| 1203 if (compiler.codegenWorld.couldHaveFieldOnlyIntegerSetters( | |
| 1204 type, left.element.name) && | |
| 1205 compiler.codegenWorld.couldHaveFieldOnlyIntegerInitializer( | |
| 1206 type, left.element.name)) { | |
| 1207 compiler.enqueuer.codegen.registerRecompilationCandidate( | |
| 1208 work.element); | |
| 1209 } | |
| 1210 break; | |
| 1211 case Compiler.PHASE_RECOMPILING: | |
| 1212 if (compiler.codegenWorld.hasFieldOnlyIntegerSetters( | |
| 1213 type, left.element.name) && | |
| 1214 compiler.codegenWorld.hasFieldOnlyIntegerInitializer( | |
| 1215 type, left.element.name)) { | |
| 1216 if (compiler.codegenWorld.hasInvokedSetter(left.element, | |
| 1217 compiler)) { | |
| 1218 // If there are invoked setters we don't know for sure that the | |
| 1219 // field will hold an integer, but the fact that the class | |
| 1220 // itselfalways sets an integer in the fiels is still a strong | |
|
floitsch
2012/06/18 13:20:40
itself always
Søren Gjesse
2012/06/19 14:35:00
Done.
| |
| 1221 // signal to indiate the expected type of the field. | |
| 1222 left.propagatedType = HType.INTEGER; | |
| 1223 graph.highTypeLikelyhood = true; | |
| 1224 } else { | |
| 1225 // If there are no invoked setters we know the type of this | |
| 1226 // field for sure. | |
| 1227 left.guaranteedType = HType.INTEGER; | |
| 1228 } | |
| 1229 } | |
| 1230 break; | |
| 1231 default: | |
| 1232 assert(false); | |
| 1233 break; | |
| 1234 } | |
| 1235 } | |
| 1236 } | |
| 1237 } | |
| 1238 } | |
| OLD | NEW |