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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/optimize.dart (revision 17466)
+++ sdk/lib/_internal/compiler/implementation/ssa/optimize.dart (working copy)
@@ -58,6 +58,7 @@
// Previous optimizations may have generated new
// opportunities for constant folding.
new SsaConstantFolder(constantSystem, backend, work, types),
+ new SsaSimplifyInterceptors(constantSystem),
new SsaDeadCodeEliminator(types)];
runPhases(graph, phases);
if (!speculative) {
@@ -671,6 +672,8 @@
if (node.isConstant()) return node;
HType type = types[node.inputs[0]];
ClassElement constantInterceptor;
+ // TODO(ngeoffray): We should also do this optimization for one
+ // shot interceptors.
if (type.isInteger()) {
constantInterceptor = backend.jsIntClass;
} else if (type.isDouble()) {
@@ -1445,3 +1448,51 @@
// TODO(ngeoffray): Also implement it for non-intercepted calls.
}
+
+/**
+ * This phase replaces all interceptors that are used only once with
+ * one-shot interceptors. It saves code size and makes the receiver of
+ * an intercepted call a candidate for being generated at use site.
+ */
+class SsaSimplifyInterceptors extends HBaseVisitor
+ implements OptimizationPhase {
+ final String name = "SsaSimplifyInterceptors";
+ final ConstantSystem constantSystem;
+ HGraph graph;
+
+ SsaSimplifyInterceptors(this.constantSystem);
+
+ void visitGraph(HGraph graph) {
+ this.graph = graph;
+ visitDominatorTree(graph);
+ }
+
+ void visitInterceptor(HInterceptor node) {
+ if (node.usedBy.length != 1) return;
+ // [HBailoutTarget] instructions might have the interceptor as
+ // input. In such situation we let the dead code analyzer find out
+ // the interceptor is not needed.
+ if (node.usedBy[0] is !HInvokeDynamic) return;
+
+ HInvokeDynamic user = node.usedBy[0];
+
+ // If [node] was loop hoisted, we keep the interceptor.
+ if (!user.bothNotInLoopOrInSameLoop(node)) return;
+
+ // Replace the user with a [HOneShotInterceptor].
+ HConstant nullConstant = graph.addConstantNull(constantSystem);
+ List<HInstruction> inputs = new List<HInstruction>.from(user.inputs);
+ inputs[0] = nullConstant;
+ HOneShotInterceptor interceptor = new HOneShotInterceptor(
+ user.selector, inputs, node.interceptedClasses);
+
+ HBasicBlock block = user.block;
+ block.addAfter(user, interceptor);
+ block.rewrite(user, interceptor);
+ block.remove(user);
+
+ // The interceptor will be removed in the dead code elimination
+ // phase. Note that removing it here would not work because of how
+ // the [visitBasicBlock] is implemented.
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698