| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 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. | 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 |  | 
| 108     //   confuse the LoopSideEffects pre-analysis. |  | 
| 109     return prim.isSafeForElimination || | 107     return prim.isSafeForElimination || | 
| 110            prim is GetField || | 108            prim is GetField || | 
| 111            prim is GetLength || | 109            prim is GetLength || | 
| 112            prim is GetIndex || | 110            prim is GetIndex || | 
| 113            prim is GetLazyStatic; | 111            prim is GetLazyStatic; | 
| 114   } | 112   } | 
| 115 | 113 | 
| 116   @override | 114   @override | 
| 117   Expression traverseLetPrim(LetPrim node) { | 115   Expression traverseLetPrim(LetPrim node) { | 
| 118     Expression next = node.body; | 116     Expression next = node.body; | 
| 119     Primitive prim = node.primitive; | 117     Primitive prim = node.primitive; | 
| 120 | 118 | 
| 121     loopHeaderFor[prim] = currentLoopHeader; | 119     loopHeaderFor[prim] = currentLoopHeader; | 
| 122 | 120 | 
| 123     if (prim is Refinement) { | 121     if (prim is Refinement) { | 
| 124       // Do not share refinements (they have no runtime or code size cost), and | 122       // 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 | 123       // do not put them in the GVN table because GvnVectorBuilder unfolds | 
| 126       // refinements by itself. | 124       // refinements by itself. | 
| 127       return next; | 125       return next; | 
| 128     } | 126     } | 
| 129 | 127 | 
|  | 128     // Update effect numbers due to side effects from a static initializer. | 
|  | 129     // GetLazyStatic is GVN'ed like a GetStatic, but the effects of the static | 
|  | 130     // initializer occur before reading the field. | 
|  | 131     if (prim is GetLazyStatic) { | 
|  | 132       visit(prim); | 
|  | 133     } | 
|  | 134 | 
| 130     // Compute the GVN vector for this computation. | 135     // Compute the GVN vector for this computation. | 
| 131     List vector = gvnVectorBuilder.make(prim, effectNumbers); | 136     List vector = gvnVectorBuilder.make(prim, effectNumbers); | 
| 132 | 137 | 
| 133     // Update effect numbers due to side effects. | 138     // Update effect numbers due to side effects. | 
| 134     // Do this after computing the GVN vector so the primitive's GVN is not | 139     // Do this after computing the GVN vector so the primitive's GVN is not | 
| 135     // influenced by its own side effects. | 140     // influenced by its own side effects, except in the case of GetLazyStatic. | 
| 136     visit(prim); | 141     if (prim is! GetLazyStatic) { | 
|  | 142       visit(prim); | 
|  | 143     } | 
| 137 | 144 | 
| 138     if (vector == null) { | 145     if (vector == null) { | 
| 139       // The primitive is not GVN'able. Move on. | 146       // The primitive is not GVN'able. Move on. | 
| 140       return next; | 147       return next; | 
| 141     } | 148     } | 
| 142 | 149 | 
| 143     // Compute the GVN for this primitive. | 150     // Compute the GVN for this primitive. | 
| 144     int gvn = gvnTable.insert(vector); | 151     int gvn = gvnTable.insert(vector); | 
| 145     gvnFor[prim] = gvn; | 152     gvnFor[prim] = gvn; | 
| 146 | 153 | 
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 668       vector = [GvnCode.GET_FIELD, node.field]; | 675       vector = [GvnCode.GET_FIELD, node.field]; | 
| 669     } else { | 676     } else { | 
| 670       vector = [GvnCode.GET_FIELD, node.field, effectNumbers.instanceField]; | 677       vector = [GvnCode.GET_FIELD, node.field, effectNumbers.instanceField]; | 
| 671     } | 678     } | 
| 672   } | 679   } | 
| 673 | 680 | 
| 674   processGetIndex(GetIndex node) { | 681   processGetIndex(GetIndex node) { | 
| 675     vector = [GvnCode.GET_INDEX, effectNumbers.indexableContent]; | 682     vector = [GvnCode.GET_INDEX, effectNumbers.indexableContent]; | 
| 676   } | 683   } | 
| 677 | 684 | 
| 678   processGetStatic(GetStatic node) { | 685   visitGetStatic(GetStatic node) { | 
| 679     if (isImmutable(node.element)) { | 686     if (isImmutable(node.element)) { | 
| 680       vector = [GvnCode.GET_STATIC, node.element]; | 687       vector = [GvnCode.GET_STATIC, node.element]; | 
| 681     } else { | 688     } else { | 
| 682       vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; | 689       vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; | 
| 683     } | 690     } | 
|  | 691     // Suppress visit to witness argument. | 
| 684   } | 692   } | 
| 685 | 693 | 
| 686   processGetLazyStatic(GetLazyStatic node) { | 694   processGetLazyStatic(GetLazyStatic node) { | 
| 687     if (isImmutable(node.element)) { | 695     if (isImmutable(node.element)) { | 
| 688       vector = [GvnCode.GET_STATIC, node.element]; | 696       vector = [GvnCode.GET_STATIC, node.element]; | 
| 689     } else { | 697     } else { | 
| 690       vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; | 698       vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField]; | 
| 691     } | 699     } | 
| 692   } | 700   } | 
| 693 | 701 | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 735 | 743 | 
| 736   @override | 744   @override | 
| 737   processReference(Reference ref) { | 745   processReference(Reference ref) { | 
| 738     callback(ref); | 746     callback(ref); | 
| 739   } | 747   } | 
| 740 | 748 | 
| 741   static void forEach(Primitive node, ReferenceCallback callback) { | 749   static void forEach(Primitive node, ReferenceCallback callback) { | 
| 742     new InputVisitor(callback).visit(node); | 750     new InputVisitor(callback).visit(node); | 
| 743   } | 751   } | 
| 744 } | 752 } | 
| OLD | NEW | 
|---|