| 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 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 } | 564 } |
| 565 HType combinedType = value.propagatedType.intersection(node.propagatedType); | 565 HType combinedType = value.propagatedType.intersection(node.propagatedType); |
| 566 return (combinedType == value.propagatedType) ? value : node; | 566 return (combinedType == value.propagatedType) ? value : node; |
| 567 } | 567 } |
| 568 | 568 |
| 569 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 569 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 570 HInstruction receiver = node.inputs[0]; | 570 HInstruction receiver = node.inputs[0]; |
| 571 if (!receiver.propagatedType.isUseful()) return node; | 571 if (!receiver.propagatedType.isUseful()) return node; |
| 572 Type type = receiver.propagatedType.computeType(compiler); | 572 Type type = receiver.propagatedType.computeType(compiler); |
| 573 if (type === null) return node; | 573 if (type === null) return node; |
| 574 if (!compiler.world.isOnlyFields(type, node.name)) return node; | 574 Element field = compiler.world.locateSingleField(type, node.name); |
| 575 ClassElement cls = type.element; | 575 if (field === null) return node; |
| 576 if (cls === null) return node; | 576 Modifiers modifiers = field.modifiers; |
| 577 Element element = cls.lookupLocalMember(node.name); | |
| 578 // If a subclass overrides a final field then there will be two fields, | |
| 579 // and here the final field will be used. | |
| 580 if (element === null) return node; | |
| 581 Modifiers modifiers = element.modifiers; | |
| 582 bool isFinalOrConst = false; | 577 bool isFinalOrConst = false; |
| 583 if (modifiers != null) { | 578 if (modifiers != null) { |
| 584 isFinalOrConst = modifiers.isFinal() || modifiers.isConst(); | 579 isFinalOrConst = modifiers.isFinal() || modifiers.isConst(); |
| 585 } | 580 } |
| 586 return new HFieldGet(node.name, | 581 return new HFieldGet(field, node.inputs[0], isFinalOrConst: isFinalOrConst); |
| 587 node.inputs[0], | |
| 588 isFinalOrConst: isFinalOrConst); | |
| 589 } | 582 } |
| 590 | 583 |
| 591 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { | 584 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| 592 HInstruction receiver = node.inputs[0]; | 585 HInstruction receiver = node.inputs[0]; |
| 593 if (!receiver.propagatedType.isUseful()) return node; | 586 if (!receiver.propagatedType.isUseful()) return node; |
| 594 Type type = receiver.propagatedType.computeType(compiler); | 587 Type type = receiver.propagatedType.computeType(compiler); |
| 595 if (type === null) return node; | 588 if (type === null) return node; |
| 596 if (!compiler.world.isOnlyFields(type, node.name)) return node; | 589 Element field = compiler.world.locateSingleField(type, node.name); |
| 597 return new HFieldSet(node.name, node.inputs[0], node.inputs[1]); | 590 if (field === null) return node; |
| 591 return new HFieldSet(field, node.inputs[0], node.inputs[1]); |
| 598 } | 592 } |
| 599 } | 593 } |
| 600 | 594 |
| 601 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { | 595 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { |
| 602 final String name = "SsaCheckInserter"; | 596 final String name = "SsaCheckInserter"; |
| 603 Element lengthInterceptor; | 597 Element lengthInterceptor; |
| 604 | 598 |
| 605 SsaCheckInserter(JavaScriptBackend backend) { | 599 SsaCheckInserter(JavaScriptBackend backend) { |
| 606 SourceString lengthString = const SourceString('length'); | 600 SourceString lengthString = const SourceString('length'); |
| 607 lengthInterceptor = | 601 lengthInterceptor = |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 // the if block terminates. So any use of the instruction | 1124 // the if block terminates. So any use of the instruction |
| 1131 // after the join block should be changed to the new | 1125 // after the join block should be changed to the new |
| 1132 // instruction. | 1126 // instruction. |
| 1133 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); | 1127 changeUsesDominatedBy(ifUser.joinBlock, input, convertedType); |
| 1134 } | 1128 } |
| 1135 // TODO(ngeoffray): Also change uses for the then block on a HType | 1129 // TODO(ngeoffray): Also change uses for the then block on a HType |
| 1136 // that knows it is not of a specific Type. | 1130 // that knows it is not of a specific Type. |
| 1137 } | 1131 } |
| 1138 } | 1132 } |
| 1139 } | 1133 } |
| OLD | NEW |