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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/let_sinking.dart

Issue 1322403002: dart2js cps: Change interceptor pipeline. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library dart2js.cps_ir.let_sinking;
6
7 import 'cps_ir_nodes.dart';
8 import 'optimizers.dart';
9 import 'loop_hierarchy.dart';
10
11 /// Sinks single-use primitives to the use when this is safe and profitable.
12 ///
13 /// To avoid sinking non-constant primitives into loops, this pass performs a
14 /// control-flow analysis to determine the effective nesting of loops.
15 ///
16 /// In the example below, the value 'p' can be sunk to its use site in the
17 /// 'else' branch because that branch is not effectively part of a loop,
18 /// despite being lexically nested in a recursive continuation.
19 ///
20 /// let prim p = getInterceptor(<something>)
21 /// let rec kont x =
22 /// if (<loop condition>)
23 /// <loop body>
24 /// InvokeContinuation kont x'
25 /// else
26 /// <after loop>
27 /// return p.foo()
28 ///
29 class LetSinker extends RecursiveVisitor implements Pass {
30 String get passName => 'Let sinking';
31
32 LoopHierarchy loopHierarchy;
33 List<Continuation> stack = <Continuation>[];
34
35 /// Maps a sinkable primitive to its loop header.
36 Map<Primitive, Continuation> loopHeaderForPrimitive =
37 <Primitive, Continuation>{};
38
39 Continuation currentLoopHeader;
40
41 void rewrite(FunctionDefinition node) {
42 new ParentVisitor().visit(node);
43 loopHierarchy = new LoopHierarchy(node);
44 visit(node.body);
45 }
46
47 @override
48 Expression traverseLetPrim(LetPrim node) {
49 Primitive prim = node.primitive;
50 if (prim.hasExactlyOneUse && prim.isSafeForReordering) {
51 // This can potentially be sunk. Register the loop header, so when we
52 // find the use site, we can check if they are in the same loop.
53 loopHeaderForPrimitive[prim] = currentLoopHeader;
54 pushAction(() {
55 if (node.primitive != null) {
56 // The primitive could not be sunk. Try to sink dependencies here.
57 visit(node.primitive);
58 } else {
59 // The primitive was sunk. Destroy the old LetPrim.
60 InteriorNode parent = node.parent;
61 parent.body = node.body;
62 node.body.parent = parent;
63 }
64 });
65 } else {
66 visit(node.primitive);
67 }
68
69 // Visit the body, wherein this primitive may be sunk to its use site.
70 return node.body;
71 }
72
73 @override
74 Expression traverseContinuation(Continuation cont) {
75 Continuation oldLoopHeader = currentLoopHeader;
76 pushAction(() {
77 currentLoopHeader = oldLoopHeader;
78 });
79 currentLoopHeader = loopHierarchy.getLoopHeader(cont);
80 return cont.body;
81 }
82
83 void processReference(Reference ref) {
84 Definition definition = ref.definition;
85 if (definition is Primitive &&
86 definition is! Parameter &&
87 definition.hasExactlyOneUse &&
88 definition.isSafeForReordering) {
89 // Check if use is in the same loop.
90 Continuation bindingLoop = loopHeaderForPrimitive.remove(definition);
91 if (bindingLoop == currentLoopHeader || definition is Constant) {
92 // Sink the definition.
93
94 Expression use = getEnclosingExpression(ref.parent);
95 LetPrim binding = definition.parent;
96 binding.primitive = null; // Mark old binding for deletion.
97 LetPrim newBinding = new LetPrim(definition);
98 definition.parent = newBinding;
99 InteriorNode useParent = use.parent;
100 useParent.body = newBinding;
101 newBinding.body = use;
102 use.parent = newBinding;
103 newBinding.parent = useParent;
104
105 // Now that the final binding location has been found, sink the
106 // dependencies of the definition down here as well.
107 visit(definition);
108 }
109 }
110 }
111
112 Expression getEnclosingExpression(Node node) {
113 while (node is! Expression) {
114 node = node.parent;
115 }
116 return node;
117 }
118 }
119
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart ('k') | pkg/compiler/lib/src/cps_ir/optimizers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698