Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart2js.cps_ir.gvn; | 5 library dart2js.cps_ir.gvn; |
| 6 | 6 |
| 7 import 'cps_ir_nodes.dart'; | 7 import 'cps_ir_nodes.dart'; |
| 8 import '../universe/side_effects.dart'; | 8 import '../universe/side_effects.dart'; |
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 10 import 'optimizers.dart' show Pass; | 10 import 'optimizers.dart' show Pass; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 // ------------------ GLOBAL VALUE NUMBERING --------------------- | 98 // ------------------ GLOBAL VALUE NUMBERING --------------------- |
| 99 | 99 |
| 100 /// True if [prim] can be eliminated if its value is already in scope. | 100 /// True if [prim] can be eliminated if its value is already in scope. |
| 101 bool canReplaceWithExistingValue(Primitive prim) { | 101 bool canReplaceWithExistingValue(Primitive prim) { |
| 102 // Primitives that have no side effects other than potentially throwing are | 102 // Primitives that have no side effects other than potentially throwing are |
| 103 // known not the throw if the value is already in scope. Handling those | 103 // known not the throw if the value is already in scope. Handling those |
| 104 // specially is equivalent to updating refinements during GVN. | 104 // specially is equivalent to updating refinements during GVN. |
| 105 // GetLazyStatic cannot have side effects because the field has already | 105 // GetLazyStatic cannot have side effects because the field has already |
| 106 // been initialized. | 106 // been initialized. |
| 107 // TODO(asgerf): Replace GetLazyStatic in an earlier pass so it does not | 107 // TODO(asgerf): Replace GetLazyStatic in an earlier pass so it does not |
| 108 // confuse the LoopSideEffects pre-analysis. | 108 // confuse the LoopSideEffects pre-analysis. |
|
sra1
2015/12/14 18:19:41
Can we remove this TODO?
asgerf
2015/12/15 10:29:56
Missed that, thanks.
| |
| 109 return prim.isSafeForElimination || | 109 return prim.isSafeForElimination || |
| 110 prim is GetField || | 110 prim is GetField || |
| 111 prim is GetLength || | 111 prim is GetLength || |
| 112 prim is GetIndex || | 112 prim is GetIndex || |
| 113 prim is GetLazyStatic; | 113 prim is GetLazyStatic; |
| 114 } | 114 } |
| 115 | 115 |
| 116 @override | 116 @override |
| 117 Expression traverseLetPrim(LetPrim node) { | 117 Expression traverseLetPrim(LetPrim node) { |
| 118 Expression next = node.body; | 118 Expression next = node.body; |
| 119 Primitive prim = node.primitive; | 119 Primitive prim = node.primitive; |
| 120 | 120 |
| 121 loopHeaderFor[prim] = currentLoopHeader; | 121 loopHeaderFor[prim] = currentLoopHeader; |
| 122 | 122 |
| 123 if (prim is Refinement) { | 123 if (prim is Refinement) { |
| 124 // Do not share refinements (they have no runtime or code size cost), and | 124 // Do not share refinements (they have no runtime or code size cost), and |
| 125 // do not put them in the GVN table because GvnVectorBuilder unfolds | 125 // do not put them in the GVN table because GvnVectorBuilder unfolds |
| 126 // refinements by itself. | 126 // refinements by itself. |
| 127 return next; | 127 return next; |
| 128 } | 128 } |
| 129 | 129 |
| 130 // Update effect numbers due to side effects from a static initializer. | |
| 131 // GetLazyStatic is GVN'ed like a GetStatic, but the effects of the static | |
| 132 // initializer occur before reading the field. | |
| 133 if (prim is GetLazyStatic) { | |
| 134 visit(prim); | |
| 135 } | |
| 136 | |
| 130 // Compute the GVN vector for this computation. | 137 // Compute the GVN vector for this computation. |
| 131 List vector = gvnVectorBuilder.make(prim, effectNumbers); | 138 List vector = gvnVectorBuilder.make(prim, effectNumbers); |
| 132 | 139 |
| 133 // Update effect numbers due to side effects. | 140 // Update effect numbers due to side effects. |
| 134 // Do this after computing the GVN vector so the primitive's GVN is not | 141 // Do this after computing the GVN vector so the primitive's GVN is not |
| 135 // influenced by its own side effects. | 142 // influenced by its own side effects, except in the case of GetLazyStatic. |
| 136 visit(prim); | 143 if (prim is! GetLazyStatic) { |
| 144 visit(prim); | |
| 145 } | |
| 137 | 146 |
| 138 if (vector == null) { | 147 if (vector == null) { |
| 139 // The primitive is not GVN'able. Move on. | 148 // The primitive is not GVN'able. Move on. |
| 140 return next; | 149 return next; |
| 141 } | 150 } |
| 142 | 151 |
| 143 // Compute the GVN for this primitive. | 152 // Compute the GVN for this primitive. |
| 144 int gvn = gvnTable.insert(vector); | 153 int gvn = gvnTable.insert(vector); |
| 145 gvnFor[prim] = gvn; | 154 gvnFor[prim] = gvn; |
| 146 | 155 |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 vector = [GvnCode.GET_FIELD, node.field]; | 677 vector = [GvnCode.GET_FIELD, node.field]; |
| 669 } else { | 678 } else { |
| 670 vector = [GvnCode.GET_FIELD, node.field, effectNumbers.instanceField]; | 679 vector = [GvnCode.GET_FIELD, node.field, effectNumbers.instanceField]; |
| 671 } | 680 } |
| 672 } | 681 } |
| 673 | 682 |
| 674 processGetIndex(GetIndex node) { | 683 processGetIndex(GetIndex node) { |
| 675 vector = [GvnCode.GET_INDEX, effectNumbers.indexableContent]; | 684 vector = [GvnCode.GET_INDEX, effectNumbers.indexableContent]; |
| 676 } | 685 } |
| 677 | 686 |
| 678 processGetStatic(GetStatic node) { | 687 visitGetStatic(GetStatic node) { |
| 679 if (isImmutable(node.element)) { | 688 if (isImmutable(node.element)) { |
| 680 vector = [GvnCode.GET_STATIC, node.element]; | 689 vector = [GvnCode.GET_STATIC, node.element]; |
| 681 } else { | 690 } else { |
| 682 vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; | 691 vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; |
| 683 } | 692 } |
| 693 // Suppress visit to witness argument. | |
| 684 } | 694 } |
| 685 | 695 |
| 686 processGetLazyStatic(GetLazyStatic node) { | 696 processGetLazyStatic(GetLazyStatic node) { |
| 687 if (isImmutable(node.element)) { | 697 if (isImmutable(node.element)) { |
| 688 vector = [GvnCode.GET_STATIC, node.element]; | 698 vector = [GvnCode.GET_STATIC, node.element]; |
| 689 } else { | 699 } else { |
| 690 vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; | 700 vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; |
| 691 } | 701 } |
| 692 } | 702 } |
| 693 | 703 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 735 | 745 |
| 736 @override | 746 @override |
| 737 processReference(Reference ref) { | 747 processReference(Reference ref) { |
| 738 callback(ref); | 748 callback(ref); |
| 739 } | 749 } |
| 740 | 750 |
| 741 static void forEach(Primitive node, ReferenceCallback callback) { | 751 static void forEach(Primitive node, ReferenceCallback callback) { |
| 742 new InputVisitor(callback).visit(node); | 752 new InputVisitor(callback).visit(node); |
| 743 } | 753 } |
| 744 } | 754 } |
| OLD | NEW |