| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 void rewrite(FunctionDefinition node) { | 90 void rewrite(FunctionDefinition node) { |
| 91 gvnVectorBuilder = new GvnVectorBuilder(gvnFor, compiler, types); | 91 gvnVectorBuilder = new GvnVectorBuilder(gvnFor, compiler, types); |
| 92 loopHierarchy = new LoopHierarchy(node); | 92 loopHierarchy = new LoopHierarchy(node); |
| 93 loopEffects = | 93 loopEffects = |
| 94 new LoopSideEffects(node, world, loopHierarchy: loopHierarchy); | 94 new LoopSideEffects(node, world, loopHierarchy: loopHierarchy); |
| 95 visit(node); | 95 visit(node); |
| 96 } | 96 } |
| 97 | 97 |
| 98 // ------------------ GLOBAL VALUE NUMBERING --------------------- | 98 // ------------------ GLOBAL VALUE NUMBERING --------------------- |
| 99 | 99 |
| 100 /// True if [prim] can be eliminated if its value is already in scope. |
| 101 bool canReplaceWithExistingValue(Primitive prim) { |
| 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 |
| 104 // specially is equivalent to updating refinements during GVN. |
| 105 // GetLazyStatic cannot have side effects because the field has already |
| 106 // been initialized. |
| 107 // TODO(asgerf): Replace GetLazyStatic in an earlier pass so it does not |
| 108 // confuse the LoopSideEffects pre-analysis. |
| 109 return prim.isSafeForElimination || |
| 110 prim is GetField || |
| 111 prim is GetLength || |
| 112 prim is GetIndex || |
| 113 prim is GetLazyStatic; |
| 114 } |
| 115 |
| 100 @override | 116 @override |
| 101 Expression traverseLetPrim(LetPrim node) { | 117 Expression traverseLetPrim(LetPrim node) { |
| 102 Expression next = node.body; | 118 Expression next = node.body; |
| 103 Primitive prim = node.primitive; | 119 Primitive prim = node.primitive; |
| 104 | 120 |
| 105 loopHeaderFor[prim] = currentLoopHeader; | 121 loopHeaderFor[prim] = currentLoopHeader; |
| 106 | 122 |
| 107 if (prim is Refinement) { | 123 if (prim is Refinement) { |
| 108 // 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 |
| 109 // do not put them in the GVN table because GvnVectorBuilder unfolds | 125 // do not put them in the GVN table because GvnVectorBuilder unfolds |
| (...skipping 14 matching lines...) Expand all Loading... |
| 124 return next; | 140 return next; |
| 125 } | 141 } |
| 126 | 142 |
| 127 // Compute the GVN for this primitive. | 143 // Compute the GVN for this primitive. |
| 128 int gvn = gvnTable.insert(vector); | 144 int gvn = gvnTable.insert(vector); |
| 129 gvnFor[prim] = gvn; | 145 gvnFor[prim] = gvn; |
| 130 | 146 |
| 131 // Try to reuse a previously computed value with the same GVN. | 147 // Try to reuse a previously computed value with the same GVN. |
| 132 Primitive existing = environment[gvn]; | 148 Primitive existing = environment[gvn]; |
| 133 if (existing != null && | 149 if (existing != null && |
| 134 (prim.isSafeForElimination || prim is GetLazyStatic) && | 150 canReplaceWithExistingValue(prim) && |
| 135 !isTrivialPrimitive(prim)) { | 151 !isTrivialPrimitive(prim)) { |
| 136 if (prim is Interceptor) { | 152 if (prim is Interceptor) { |
| 137 Interceptor interceptor = existing; | 153 Interceptor interceptor = existing; |
| 138 interceptor.interceptedClasses.addAll(prim.interceptedClasses); | 154 interceptor.interceptedClasses.addAll(prim.interceptedClasses); |
| 139 interceptor.flags |= prim.flags; | 155 interceptor.flags |= prim.flags; |
| 140 } | 156 } |
| 141 prim..replaceUsesWith(existing)..destroy(); | 157 prim..replaceUsesWith(existing)..destroy(); |
| 142 node.remove(); | 158 node.remove(); |
| 143 return next; | 159 return next; |
| 144 } | 160 } |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 | 735 |
| 720 @override | 736 @override |
| 721 processReference(Reference ref) { | 737 processReference(Reference ref) { |
| 722 callback(ref); | 738 callback(ref); |
| 723 } | 739 } |
| 724 | 740 |
| 725 static void forEach(Primitive node, ReferenceCallback callback) { | 741 static void forEach(Primitive node, ReferenceCallback callback) { |
| 726 new InputVisitor(callback).visit(node); | 742 new InputVisitor(callback).visit(node); |
| 727 } | 743 } |
| 728 } | 744 } |
| OLD | NEW |