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

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),
ahe 2012/11/30 08:11:42 Add a comment explaining why you call the constant
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;
ahe 2012/11/30 08:11:42 I don't understand this line.
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) {
ahe 2012/11/30 08:11:42 Why isn't this selector.applies(backend.jsArrayRem
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 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 ConstantHandler handler = compiler.constantHandler; 742 ConstantHandler handler = compiler.constantHandler;
711 Constant constant = new ConstructedConstant( 743 Constant constant = new ConstructedConstant(
712 constantInterceptor.computeType(compiler), <Constant>[]); 744 constantInterceptor.computeType(compiler), <Constant>[]);
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;
721 final Set<HInstruction> boundsChecked; 752 final Set<HInstruction> boundsChecked;
722 final WorkItem work; 753 final WorkItem work;
754 final JavaScriptBackend backend;
723 final String name = "SsaCheckInserter"; 755 final String name = "SsaCheckInserter";
724 HGraph graph; 756 HGraph graph;
725 Element lengthInterceptor;
726 757
727 SsaCheckInserter(JavaScriptBackend backend, 758 SsaCheckInserter(this.backend,
728 this.work, 759 this.work,
729 this.types, 760 this.types,
730 this.boundsChecked) 761 this.boundsChecked);
731 : constantSystem = backend.constantSystem {
732 lengthInterceptor = backend.jsArrayLength;
733 }
734 762
735 void visitGraph(HGraph graph) { 763 void visitGraph(HGraph graph) {
736 this.graph = graph; 764 this.graph = graph;
737 visitDominatorTree(graph); 765 visitDominatorTree(graph);
738 } 766 }
739 767
740 void visitBasicBlock(HBasicBlock block) { 768 void visitBasicBlock(HBasicBlock block) {
741 HInstruction instruction = block.first; 769 HInstruction instruction = block.first;
742 while (instruction != null) { 770 while (instruction != null) {
743 HInstruction next = instruction.next; 771 HInstruction next = instruction.next;
744 instruction = instruction.accept(this); 772 instruction = instruction.accept(this);
745 instruction = next; 773 instruction = next;
746 } 774 }
747 } 775 }
748 776
749 HBoundsCheck insertBoundsCheck(HInstruction node, 777 HBoundsCheck insertBoundsCheck(HInstruction node,
750 HInstruction receiver, 778 HInstruction receiver,
751 HInstruction index) { 779 HInstruction index) {
752 bool isAssignable = !receiver.isFixedArray(types); 780 bool isAssignable = !receiver.isFixedArray(types);
753 HFieldGet length = 781 HFieldGet length = new HFieldGet(
754 new HFieldGet(lengthInterceptor, receiver, isAssignable: isAssignable); 782 backend.jsArrayLength, receiver, isAssignable: isAssignable);
755 length.guaranteedType = HType.INTEGER; 783 length.guaranteedType = HType.INTEGER;
756 types[length] = HType.INTEGER; 784 types[length] = HType.INTEGER;
757 node.block.addBefore(node, length); 785 node.block.addBefore(node, length);
758 786
759 HBoundsCheck check = new HBoundsCheck(index, length); 787 HBoundsCheck check = new HBoundsCheck(index, length);
760 node.block.addBefore(node, check); 788 node.block.addBefore(node, check);
761 boundsChecked.add(node); 789 boundsChecked.add(node);
762 return check; 790 return check;
763 } 791 }
764 792
(...skipping 23 matching lines...) Expand all
788 if (!node.receiver.isMutableArray(types)) return; 816 if (!node.receiver.isMutableArray(types)) return;
789 if (boundsChecked.contains(node)) return; 817 if (boundsChecked.contains(node)) return;
790 HInstruction index = node.index; 818 HInstruction index = node.index;
791 if (!node.index.isInteger(types)) { 819 if (!node.index.isInteger(types)) {
792 index = insertIntegerCheck(node, index); 820 index = insertIntegerCheck(node, index);
793 } 821 }
794 index = insertBoundsCheck(node, node.receiver, index); 822 index = insertBoundsCheck(node, node.receiver, index);
795 node.changeUse(node.index, index); 823 node.changeUse(node.index, index);
796 assert(node.isBuiltin(types)); 824 assert(node.isBuiltin(types));
797 } 825 }
826
827 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
828 Element element = node.element;
829 if (element != backend.jsArrayRemoveLast) return;
830 if (boundsChecked.contains(node)) return;
831 insertBoundsCheck(
832 node, node.receiver, graph.addConstantInt(0, backend.constantSystem));
833 }
798 } 834 }
799 835
800 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { 836 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
801 final HTypeMap types; 837 final HTypeMap types;
802 final String name = "SsaDeadCodeEliminator"; 838 final String name = "SsaDeadCodeEliminator";
803 839
804 SsaDeadCodeEliminator(this.types); 840 SsaDeadCodeEliminator(this.types);
805 841
806 bool isDeadCode(HInstruction instruction) { 842 bool isDeadCode(HInstruction instruction) {
807 return !instruction.hasSideEffects(types) 843 return !instruction.hasSideEffects(types)
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 HInstruction receiver = interceptor.receiver; 1475 HInstruction receiver = interceptor.receiver;
1440 for (var user in receiver.usedBy) { 1476 for (var user in receiver.usedBy) {
1441 if (user is HInterceptor && interceptor.dominates(user)) { 1477 if (user is HInterceptor && interceptor.dominates(user)) {
1442 user.interceptedClasses = interceptor.interceptedClasses; 1478 user.interceptedClasses = interceptor.interceptedClasses;
1443 } 1479 }
1444 } 1480 }
1445 } 1481 }
1446 1482
1447 // TODO(ngeoffray): Also implement it for non-intercepted calls. 1483 // TODO(ngeoffray): Also implement it for non-intercepted calls.
1448 } 1484 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698