Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart

Issue 11348281: Put back manual inlining of List.add, List.removeLast, String.split and String.concat. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 21 matching lines...) Expand all
32 ConstantSystem constantSystem = compiler.backend.constantSystem; 32 ConstantSystem constantSystem = compiler.backend.constantSystem;
33 JavaScriptItemCompilationContext context = work.compilationContext; 33 JavaScriptItemCompilationContext context = work.compilationContext;
34 HTypeMap types = context.types; 34 HTypeMap types = context.types;
35 measure(() { 35 measure(() {
36 List<OptimizationPhase> phases = <OptimizationPhase>[ 36 List<OptimizationPhase> phases = <OptimizationPhase>[
37 // Run trivial constant folding first to optimize 37 // Run trivial constant folding first to optimize
38 // some patterns useful for type conversion. 38 // some patterns useful for type conversion.
39 new SsaConstantFolder(constantSystem, backend, work, types), 39 new SsaConstantFolder(constantSystem, backend, work, types),
40 new SsaTypeConversionInserter(compiler), 40 new SsaTypeConversionInserter(compiler),
41 new SsaTypePropagator(compiler, types), 41 new SsaTypePropagator(compiler, types),
42 new SsaConstantFolder(constantSystem, backend, work, types),
42 new SsaCheckInserter(backend, work, types, context.boundsChecked), 43 new SsaCheckInserter(backend, work, types, context.boundsChecked),
43 new SsaConstantFolder(constantSystem, backend, work, types),
44 new SsaRedundantPhiEliminator(), 44 new SsaRedundantPhiEliminator(),
45 new SsaDeadPhiEliminator(), 45 new SsaDeadPhiEliminator(),
46 new SsaConstantFolder(constantSystem, backend, work, types), 46 new SsaConstantFolder(constantSystem, backend, work, types),
47 new SsaTypePropagator(compiler, types), 47 new SsaTypePropagator(compiler, types),
48 new SsaReceiverSpecialization(compiler), 48 new SsaReceiverSpecialization(compiler),
49 new SsaGlobalValueNumberer(compiler, types), 49 new SsaGlobalValueNumberer(compiler, types),
50 new SsaCodeMotion(), 50 new SsaCodeMotion(),
51 new SsaValueRangeAnalyzer(constantSystem, types, work), 51 new SsaValueRangeAnalyzer(constantSystem, types, work),
52 // Previous optimizations may have generated new 52 // Previous optimizations may have generated new
53 // opportunities for constant folding. 53 // opportunities for constant folding.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 if (operand is HConstant) { 200 if (operand is HConstant) {
201 UnaryOperation operation = node.operation(constantSystem); 201 UnaryOperation operation = node.operation(constantSystem);
202 HConstant receiver = operand; 202 HConstant receiver = operand;
203 Constant folded = operation.fold(receiver.constant); 203 Constant folded = operation.fold(receiver.constant);
204 if (folded != null) return graph.addConstant(folded); 204 if (folded != null) return graph.addConstant(folded);
205 } 205 }
206 return node; 206 return node;
207 } 207 }
208 208
209 HInstruction handleInterceptorCall(HInvokeDynamic node) { 209 HInstruction handleInterceptorCall(HInvokeDynamic node) {
210 if (node is !HInvokeDynamicMethod) return;
210 HInstruction input = node.inputs[1]; 211 HInstruction input = node.inputs[1];
211 if (input.isString(types) 212 if (input.isString(types)
212 && node.selector.name == const SourceString('toString')) { 213 && node.selector.name == const SourceString('toString')) {
213 return node.inputs[1]; 214 return node.inputs[1];
214 } 215 }
215 // Check if this call does not need to be intercepted. 216 // Check if this call does not need to be intercepted.
216 HType type = types[input]; 217 HType type = types[input];
217 var interceptor = node.inputs[0]; 218 var interceptor = node.inputs[0];
218 if (node is HInvokeDynamicMethod 219 if (interceptor is !HThis && !type.canBePrimitive()) {
219 && interceptor is !HThis
220 && !type.canBePrimitive()) {
221 // If the type can be null, and the intercepted method can be in 220 // If the type can be null, and the intercepted method can be in
222 // the object class, keep the interceptor. 221 // the object class, keep the interceptor.
223 if (type.canBeNull() 222 if (type.canBeNull()
224 && interceptor.interceptedClasses.contains(compiler.objectClass)) { 223 && interceptor.interceptedClasses.contains(compiler.objectClass)) {
225 return node; 224 return node;
226 } 225 }
227 // Change the call to a regular invoke dynamic call. 226 // Change the call to a regular invoke dynamic call.
228 return new HInvokeDynamicMethod( 227 return new HInvokeDynamicMethod(
229 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); 228 node.selector, node.inputs.getRange(1, node.inputs.length - 1));
230 } 229 }
230
231 Selector selector = node.selector;
232 SourceString selectorName = selector.name;
233 Element target;
234 if (input.isExtendableArray(types)) {
235 if (selectorName == backend.jsArrayRemoveLast.name
236 && selector.argumentCount == 0) {
237 target = backend.jsArrayRemoveLast;
238 } else if (selectorName == backend.jsArrayAdd.name
239 && selector.argumentCount == 1
240 && selector.namedArgumentCount == 0
241 && !compiler.enableTypeAssertions) {
242 target = backend.jsArrayAdd;
243 }
244 } else if (input.isString(types)) {
245 if (selectorName == backend.jsStringSplit.name
246 && selector.argumentCount == 1
247 && selector.namedArgumentCount == 0
248 && node.inputs[2].isString(types)) {
249 target = backend.jsStringSplit;
250 } else if (selectorName == backend.jsStringConcat.name
251 && selector.argumentCount == 1
252 && selector.namedArgumentCount == 0
253 && node.inputs[2].isString(types)) {
254 target = backend.jsStringConcat;
255 }
256 }
257 if (target != null) {
258 HInvokeDynamicMethod result = new HInvokeDynamicMethod(
259 node.selector, node.inputs.getRange(1, node.inputs.length - 1));
260 result.element = target;
261 return result;
262 }
231 return node; 263 return node;
232 } 264 }
233 265
234 bool isFixedSizeListConstructor(HInvokeStatic node) { 266 bool isFixedSizeListConstructor(HInvokeStatic node) {
235 Element element = node.target.element; 267 Element element = node.target.element;
236 return element.getEnclosingClass() == compiler.listClass 268 return element.getEnclosingClass() == compiler.listClass
237 && node.inputs.length == 2 269 && node.inputs.length == 2
238 && node.inputs[1].isInteger(types); 270 && node.inputs[1].isInteger(types);
239 } 271 }
240 272
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 handler.registerCompileTimeConstant(constant); 745 handler.registerCompileTimeConstant(constant);
714 return graph.addConstant(constant); 746 return graph.addConstant(constant);
715 } 747 }
716 } 748 }
717 749
718 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { 750 class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase {
719 final HTypeMap types; 751 final HTypeMap types;
720 final ConstantSystem constantSystem; 752 final ConstantSystem constantSystem;
721 final Set<HInstruction> boundsChecked; 753 final Set<HInstruction> boundsChecked;
722 final WorkItem work; 754 final WorkItem work;
755 final JavaScriptBackend backend;
723 final String name = "SsaCheckInserter"; 756 final String name = "SsaCheckInserter";
724 HGraph graph; 757 HGraph graph;
725 Element lengthInterceptor;
726 758
727 SsaCheckInserter(JavaScriptBackend backend, 759 SsaCheckInserter(JavaScriptBackend backend,
kasperl 2012/11/29 08:10:48 this.backend
ngeoffray 2012/11/29 08:46:51 I could not because of line 763, but I removed the
728 this.work, 760 this.work,
729 this.types, 761 this.types,
730 this.boundsChecked) 762 this.boundsChecked)
731 : constantSystem = backend.constantSystem { 763 : constantSystem = backend.constantSystem,
732 lengthInterceptor = backend.jsArrayLength; 764 this.backend = backend;
733 }
734 765
735 void visitGraph(HGraph graph) { 766 void visitGraph(HGraph graph) {
736 this.graph = graph; 767 this.graph = graph;
737 visitDominatorTree(graph); 768 visitDominatorTree(graph);
738 } 769 }
739 770
740 void visitBasicBlock(HBasicBlock block) { 771 void visitBasicBlock(HBasicBlock block) {
741 HInstruction instruction = block.first; 772 HInstruction instruction = block.first;
742 while (instruction != null) { 773 while (instruction != null) {
743 HInstruction next = instruction.next; 774 HInstruction next = instruction.next;
744 instruction = instruction.accept(this); 775 instruction = instruction.accept(this);
745 instruction = next; 776 instruction = next;
746 } 777 }
747 } 778 }
748 779
749 HBoundsCheck insertBoundsCheck(HInstruction node, 780 HBoundsCheck insertBoundsCheck(HInstruction node,
750 HInstruction receiver, 781 HInstruction receiver,
751 HInstruction index) { 782 HInstruction index) {
752 bool isAssignable = !receiver.isFixedArray(types); 783 bool isAssignable = !receiver.isFixedArray(types);
753 HFieldGet length = 784 HFieldGet length = new HFieldGet(
754 new HFieldGet(lengthInterceptor, receiver, isAssignable: isAssignable); 785 backend.jsArrayLength, receiver, isAssignable: isAssignable);
755 length.guaranteedType = HType.INTEGER; 786 length.guaranteedType = HType.INTEGER;
756 types[length] = HType.INTEGER; 787 types[length] = HType.INTEGER;
757 node.block.addBefore(node, length); 788 node.block.addBefore(node, length);
758 789
759 HBoundsCheck check = new HBoundsCheck(index, length); 790 HBoundsCheck check = new HBoundsCheck(index, length);
760 node.block.addBefore(node, check); 791 node.block.addBefore(node, check);
761 boundsChecked.add(node); 792 boundsChecked.add(node);
762 return check; 793 return check;
763 } 794 }
764 795
(...skipping 23 matching lines...) Expand all
788 if (!node.receiver.isMutableArray(types)) return; 819 if (!node.receiver.isMutableArray(types)) return;
789 if (boundsChecked.contains(node)) return; 820 if (boundsChecked.contains(node)) return;
790 HInstruction index = node.index; 821 HInstruction index = node.index;
791 if (!node.index.isInteger(types)) { 822 if (!node.index.isInteger(types)) {
792 index = insertIntegerCheck(node, index); 823 index = insertIntegerCheck(node, index);
793 } 824 }
794 index = insertBoundsCheck(node, node.receiver, index); 825 index = insertBoundsCheck(node, node.receiver, index);
795 node.changeUse(node.index, index); 826 node.changeUse(node.index, index);
796 assert(node.isBuiltin(types)); 827 assert(node.isBuiltin(types));
797 } 828 }
829
830 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
831 Element element = node.element;
832 if (element != backend.jsArrayRemoveLast) return;
833 if (boundsChecked.contains(node)) return;
834 insertBoundsCheck(
835 node, node.receiver, graph.addConstantInt(0, constantSystem));
836 }
798 } 837 }
799 838
800 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { 839 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
801 final HTypeMap types; 840 final HTypeMap types;
802 final String name = "SsaDeadCodeEliminator"; 841 final String name = "SsaDeadCodeEliminator";
803 842
804 SsaDeadCodeEliminator(this.types); 843 SsaDeadCodeEliminator(this.types);
805 844
806 bool isDeadCode(HInstruction instruction) { 845 bool isDeadCode(HInstruction instruction) {
807 return !instruction.hasSideEffects(types) 846 return !instruction.hasSideEffects(types)
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 HInstruction receiver = interceptor.receiver; 1478 HInstruction receiver = interceptor.receiver;
1440 for (var user in receiver.usedBy) { 1479 for (var user in receiver.usedBy) {
1441 if (user is HInterceptor && interceptor.dominates(user)) { 1480 if (user is HInterceptor && interceptor.dominates(user)) {
1442 user.interceptedClasses = interceptor.interceptedClasses; 1481 user.interceptedClasses = interceptor.interceptedClasses;
1443 } 1482 }
1444 } 1483 }
1445 } 1484 }
1446 1485
1447 // TODO(ngeoffray): Also implement it for non-intercepted calls. 1486 // TODO(ngeoffray): Also implement it for non-intercepted calls.
1448 } 1487 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698