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

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

Issue 12033056: Implement "one-shot" interceptors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 new SsaDeadPhiEliminator(), 51 new SsaDeadPhiEliminator(),
52 new SsaConstantFolder(constantSystem, backend, work, types), 52 new SsaConstantFolder(constantSystem, backend, work, types),
53 new SsaTypePropagator(compiler, types), 53 new SsaTypePropagator(compiler, types),
54 new SsaReceiverSpecialization(compiler), 54 new SsaReceiverSpecialization(compiler),
55 new SsaGlobalValueNumberer(compiler, types), 55 new SsaGlobalValueNumberer(compiler, types),
56 new SsaCodeMotion(), 56 new SsaCodeMotion(),
57 new SsaValueRangeAnalyzer(constantSystem, types, work), 57 new SsaValueRangeAnalyzer(constantSystem, types, work),
58 // Previous optimizations may have generated new 58 // Previous optimizations may have generated new
59 // opportunities for constant folding. 59 // opportunities for constant folding.
60 new SsaConstantFolder(constantSystem, backend, work, types), 60 new SsaConstantFolder(constantSystem, backend, work, types),
61 new SsaSimplifyInterceptors(constantSystem),
61 new SsaDeadCodeEliminator(types)]; 62 new SsaDeadCodeEliminator(types)];
62 runPhases(graph, phases); 63 runPhases(graph, phases);
63 if (!speculative) { 64 if (!speculative) {
64 runPhase(graph, new SsaConstructionFieldTypes(backend, work, types)); 65 runPhase(graph, new SsaConstructionFieldTypes(backend, work, types));
65 } 66 }
66 }); 67 });
67 } 68 }
68 69
69 bool trySpeculativeOptimizations(CodegenWorkItem work, HGraph graph) { 70 bool trySpeculativeOptimizations(CodegenWorkItem work, HGraph graph) {
70 if (work.element.isField()) { 71 if (work.element.isField()) {
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 PrimitiveConstant primitive = constant.constant; 665 PrimitiveConstant primitive = constant.constant;
665 folded = new DartString.concat(folded, primitive.toDartString()); 666 folded = new DartString.concat(folded, primitive.toDartString());
666 } 667 }
667 return graph.addConstant(constantSystem.createString(folded, node.node)); 668 return graph.addConstant(constantSystem.createString(folded, node.node));
668 } 669 }
669 670
670 HInstruction visitInterceptor(HInterceptor node) { 671 HInstruction visitInterceptor(HInterceptor node) {
671 if (node.isConstant()) return node; 672 if (node.isConstant()) return node;
672 HType type = types[node.inputs[0]]; 673 HType type = types[node.inputs[0]];
673 ClassElement constantInterceptor; 674 ClassElement constantInterceptor;
675 // TODO(ngeoffray): We should also do this optimization for one
676 // shot interceptors.
674 if (type.isInteger()) { 677 if (type.isInteger()) {
675 constantInterceptor = backend.jsIntClass; 678 constantInterceptor = backend.jsIntClass;
676 } else if (type.isDouble()) { 679 } else if (type.isDouble()) {
677 constantInterceptor = backend.jsDoubleClass; 680 constantInterceptor = backend.jsDoubleClass;
678 } else if (type.isBoolean()) { 681 } else if (type.isBoolean()) {
679 constantInterceptor = backend.jsBoolClass; 682 constantInterceptor = backend.jsBoolClass;
680 } else if (type.isString()) { 683 } else if (type.isString()) {
681 constantInterceptor = backend.jsStringClass; 684 constantInterceptor = backend.jsStringClass;
682 } else if (type.isArray()) { 685 } else if (type.isArray()) {
683 constantInterceptor = backend.jsArrayClass; 686 constantInterceptor = backend.jsArrayClass;
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 || otherIntercepted.contains(backend.jsDoubleClass)) { 1441 || otherIntercepted.contains(backend.jsDoubleClass)) {
1439 interceptor.interceptedClasses.addAll(user.interceptedClasses); 1442 interceptor.interceptedClasses.addAll(user.interceptedClasses);
1440 } 1443 }
1441 user.interceptedClasses = interceptor.interceptedClasses; 1444 user.interceptedClasses = interceptor.interceptedClasses;
1442 } 1445 }
1443 } 1446 }
1444 } 1447 }
1445 1448
1446 // TODO(ngeoffray): Also implement it for non-intercepted calls. 1449 // TODO(ngeoffray): Also implement it for non-intercepted calls.
1447 } 1450 }
1451
1452 /**
1453 * This phase replaces all interceptors that are used only once with
1454 * one-shot interceptors. It saves code size and makes the receiver of
1455 * an intercepted call a candidate for being generated at use site.
1456 */
1457 class SsaSimplifyInterceptors extends HBaseVisitor
1458 implements OptimizationPhase {
1459 final String name = "SsaSimplifyInterceptors";
1460 final ConstantSystem constantSystem;
1461 HGraph graph;
1462
1463 SsaSimplifyInterceptors(this.constantSystem);
1464
1465 void visitGraph(HGraph graph) {
1466 this.graph = graph;
1467 visitDominatorTree(graph);
1468 }
1469
1470 void visitInterceptor(HInterceptor node) {
1471 if (node.usedBy.length != 1) return;
1472 // [HBailoutTarget] instructions might have the interceptor as
1473 // input. In such situation we let the dead code analyzer find out
1474 // the interceptor is not needed.
1475 if (node.usedBy[0] is !HInvokeDynamic) return;
1476
1477 HInvokeDynamic user = node.usedBy[0];
1478
1479 // If [node] was loop hoisted, we keep the interceptor.
1480 if (!user.bothNotInLoopOrInSameLoop(node)) return;
1481
1482 // Replace the user with a [HOneShotInterceptor].
1483 HConstant nullConstant = graph.addConstantNull(constantSystem);
1484 List<HInstruction> inputs = new List<HInstruction>.from(user.inputs);
1485 inputs[0] = nullConstant;
1486 HOneShotInterceptor interceptor = new HOneShotInterceptor(
1487 user.selector, inputs, node.interceptedClasses);
1488
1489 HBasicBlock block = user.block;
1490 block.addAfter(user, interceptor);
1491 block.rewrite(user, interceptor);
1492 block.remove(user);
1493
1494 // The interceptor will be removed in the dead code elimination
1495 // phase. Note that removing it here would not work because of how
1496 // the [visitBasicBlock] is implemented.
1497 }
1498 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698