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 { |
| 11 final JavaScriptBackend backend; | 11 final JavaScriptBackend backend; |
| 12 SsaOptimizerTask(JavaScriptBackend backend) | 12 SsaOptimizerTask(JavaScriptBackend backend) |
| 13 : this.backend = backend, | 13 : this.backend = backend, |
| 14 super(backend.compiler); | 14 super(backend.compiler); |
| 15 String get name() => 'SSA optimizer'; | 15 String get name() => 'SSA optimizer'; |
| 16 Compiler get compiler() => backend.compiler; | 16 Compiler get compiler() => backend.compiler; |
| 17 | 17 |
| 18 void runPhases(HGraph graph, List<OptimizationPhase> phases) { | 18 void runPhases(HGraph graph, List<OptimizationPhase> phases) { |
| 19 for (OptimizationPhase phase in phases) { | 19 for (OptimizationPhase phase in phases) { |
| 20 phase.visitGraph(graph); | 20 phase.visitGraph(graph); |
| 21 compiler.tracer.traceGraph(phase.name, graph); | 21 compiler.tracer.traceGraph(phase.name, graph); |
| 22 } | 22 } |
| 23 } | 23 } |
| 24 | 24 |
| 25 void optimize(WorkItem work, HGraph graph) { | 25 void optimize(WorkItem work, HGraph graph) { |
| 26 measure(() { | 26 measure(() { |
| 27 List<OptimizationPhase> phases = <OptimizationPhase>[ | 27 List<OptimizationPhase> phases = <OptimizationPhase>[ |
| 28 // Run trivial constant folding first to optimize | 28 // Run trivial constant folding first to optimize |
| 29 // some patterns useful for type conversion. | 29 // some patterns useful for type conversion. |
| 30 new SsaConstantFolder(backend), | 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), | 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 runPhases(graph, phases); | 40 runPhases(graph, phases); |
| 41 }); | 41 }); |
| 42 } | 42 } |
| 43 | 43 |
| 44 bool trySpeculativeOptimizations(WorkItem work, HGraph graph) { | 44 bool trySpeculativeOptimizations(WorkItem work, HGraph graph) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 | 85 |
| 86 /** | 86 /** |
| 87 * If both inputs to known operations are available execute the operation at | 87 * If both inputs to known operations are available execute the operation at |
| 88 * compile-time. | 88 * compile-time. |
| 89 */ | 89 */ |
| 90 class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { | 90 class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
| 91 final String name = "SsaConstantFolder"; | 91 final String name = "SsaConstantFolder"; |
| 92 final JavaScriptBackend backend; | 92 final JavaScriptBackend backend; |
| 93 final WorkItem work; | |
| 93 HGraph graph; | 94 HGraph graph; |
| 94 Compiler get compiler() => backend.compiler; | 95 Compiler get compiler() => backend.compiler; |
| 95 | 96 |
| 96 SsaConstantFolder(this.backend); | 97 SsaConstantFolder(this.backend, this.work); |
| 97 | 98 |
| 98 void visitGraph(HGraph visitee) { | 99 void visitGraph(HGraph visitee) { |
| 99 graph = visitee; | 100 graph = visitee; |
| 100 visitDominatorTree(visitee); | 101 visitDominatorTree(visitee); |
| 101 } | 102 } |
| 102 | 103 |
| 103 visitBasicBlock(HBasicBlock block) { | 104 visitBasicBlock(HBasicBlock block) { |
| 104 HInstruction instruction = block.first; | 105 HInstruction instruction = block.first; |
| 105 while (instruction !== null) { | 106 while (instruction !== null) { |
| 106 HInstruction next = instruction.next; | 107 HInstruction next = instruction.next; |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 if (receiver.propagatedType.canBeNull()) return node; | 574 if (receiver.propagatedType.canBeNull()) return node; |
| 574 Type type = receiver.propagatedType.computeType(compiler); | 575 Type type = receiver.propagatedType.computeType(compiler); |
| 575 if (type === null) return node; | 576 if (type === null) return node; |
| 576 Element field = compiler.world.locateSingleField(type, node.name); | 577 Element field = compiler.world.locateSingleField(type, node.name); |
| 577 if (field === null) return node; | 578 if (field === null) return node; |
| 578 Modifiers modifiers = field.modifiers; | 579 Modifiers modifiers = field.modifiers; |
| 579 bool isFinalOrConst = false; | 580 bool isFinalOrConst = false; |
| 580 if (modifiers != null) { | 581 if (modifiers != null) { |
| 581 isFinalOrConst = modifiers.isFinal() || modifiers.isConst(); | 582 isFinalOrConst = modifiers.isFinal() || modifiers.isConst(); |
| 582 } | 583 } |
| 584 // If field is not final or const but no setters are used then the field | |
|
floitsch
2012/06/13 12:51:10
move this comment down to the "isFinalOrConst = tr
Søren Gjesse
2012/06/14 06:37:10
Done.
| |
| 585 // might be considered final anyway as it will be either un-initialized | |
| 586 // or initialized in the constructor initializer list. | |
| 587 if (!isFinalOrConst && | |
| 588 !compiler.codegenWorld.hasInvokedSetter(field, compiler) && | |
|
ngeoffray
2012/06/13 22:02:26
Why don't you just use the resolverWorld here?
Søren Gjesse
2012/06/14 06:37:10
Because I don't know how. If that is possible we s
| |
| 589 !compiler.codegenWorld.hasFieldSetter(field, compiler)) { | |
| 590 switch (compiler.pass) { | |
| 591 case 1: | |
| 592 compiler.enqueuer.codegen.addToRecompilationCandidates(work.element); | |
| 593 break; | |
| 594 case 2: | |
| 595 isFinalOrConst = true; | |
| 596 break; | |
| 597 } | |
| 598 } | |
| 583 return new HFieldGet(field, node.inputs[0], isFinalOrConst: isFinalOrConst); | 599 return new HFieldGet(field, node.inputs[0], isFinalOrConst: isFinalOrConst); |
| 584 } | 600 } |
| 585 | 601 |
| 586 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { | 602 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| 587 HInstruction receiver = node.inputs[0]; | 603 HInstruction receiver = node.inputs[0]; |
| 588 if (!receiver.propagatedType.isUseful()) return node; | 604 if (!receiver.propagatedType.isUseful()) return node; |
| 589 if (receiver.propagatedType.canBeNull()) return node; | 605 if (receiver.propagatedType.canBeNull()) return node; |
| 590 Type type = receiver.propagatedType.computeType(compiler); | 606 Type type = receiver.propagatedType.computeType(compiler); |
| 591 if (type === null) return node; | 607 if (type === null) return node; |
| 592 Element field = compiler.world.locateSingleField(type, node.name); | 608 Element field = compiler.world.locateSingleField(type, node.name); |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1140 // the if block terminates. So any use of the instruction | 1156 // the if block terminates. So any use of the instruction |
| 1141 // after the join block should be changed to the new | 1157 // after the join block should be changed to the new |
| 1142 // instruction. | 1158 // instruction. |
| 1143 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); | 1159 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); |
| 1144 } | 1160 } |
| 1145 // TODO(ngeoffray): Also change uses for the then block on a HType | 1161 // TODO(ngeoffray): Also change uses for the then block on a HType |
| 1146 // that knows it is not of a specific Type. | 1162 // that knows it is not of a specific Type. |
| 1147 } | 1163 } |
| 1148 } | 1164 } |
| 1149 } | 1165 } |
| OLD | NEW |