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

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

Issue 1313783003: dart2js cps: Generate interceptors at use-site and share afterwards. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Revert patch #3. I read Golem results backwards. 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.loop_invariant_code_motion;
6
7 import 'optimizers.dart';
8 import 'cps_ir_nodes.dart';
9 import 'loop_hierarchy.dart';
10
11 /// Lifts primitives out of loops when it is safe and profitable.
12 ///
13 /// Currently we only do this for interceptors.
14 class LoopInvariantCodeMotion extends RecursiveVisitor implements Pass {
15 String get passName => 'Loop-invariant code motion';
16
17 final Map<Primitive, Continuation> primitiveLoop =
18 <Primitive, Continuation>{};
19
20 LoopHierarchy loopHierarchy;
21 Continuation currentLoopHeader;
22
23 /// When processing the dependencies of a primitive, [referencedLoop]
24 /// refers to the innermost loop that contains one of the dependencies
25 /// seen so far (or `null` if none of the dependencies are bound in a loop).
26 ///
27 /// This is used to determine how far the primitive can be lifted without
28 /// falling out of scope of its dependencies.
29 Continuation referencedLoop;
30
31 void rewrite(FunctionDefinition node) {
32 loopHierarchy = new LoopHierarchy(node);
33 visit(node.body);
34 }
35
36 @override
37 Expression traverseContinuation(Continuation cont) {
38 Continuation oldLoopHeader = currentLoopHeader;
39 pushAction(() {
40 currentLoopHeader = oldLoopHeader;
41 });
42 currentLoopHeader = loopHierarchy.getLoopHeader(cont);
43 for (Parameter param in cont.parameters) {
44 primitiveLoop[param] = currentLoopHeader;
45 }
46 return cont.body;
47 }
48
49 @override
50 Expression traverseLetPrim(LetPrim node) {
51 primitiveLoop[node.primitive] = currentLoopHeader;
52 if (!shouldLift(node.primitive)) {
53 return node.body;
54 }
55 referencedLoop = null;
56 visit(node.primitive); // Sets referencedLoop.
57 Expression next = node.body;
58 if (referencedLoop != currentLoopHeader) {
59 // Bind the primitive inside [referencedLoop] (possibly null),
60 // immediately before the binding of the inner loop.
61
62 // Find the inner loop.
63 Continuation loop = currentLoopHeader;
64 Continuation enclosing = loopHierarchy.getEnclosingLoop(loop);
65 while (enclosing != referencedLoop) {
66 assert(loop != null);
67 loop = enclosing;
68 enclosing = loopHierarchy.getEnclosingLoop(loop);
69 }
70 assert(loop != null);
71
72 // Remove LetPrim from its current position.
73 node.parent.body = node.body;
74 node.body.parent = node.parent;
75
76 // Insert the LetPrim immediately before the loop.
77 LetCont loopBinding = loop.parent;
78 InteriorNode newParent = loopBinding.parent;
79 newParent.body = node;
80 node.body = loopBinding;
81 loopBinding.parent = node;
82 node.parent = newParent;
83
84 // A different loop now contains the primitive.
85 primitiveLoop[node.primitive] = enclosing;
86 }
87 return next;
88 }
89
90 /// Returns the the innermost loop that effectively encloses both
91 /// c1 and c2 (or `null` if there is no such loop).
92 Continuation leastCommonAncestor(Continuation c1, Continuation c2) {
93 int d1 = getDepth(c1), d2 = getDepth(c2);
94 while (c1 != c2) {
95 if (d1 <= d2) {
96 c2 = loopHierarchy.getEnclosingLoop(c2);
97 d2 = getDepth(c2);
98 } else {
99 c1 = loopHierarchy.getEnclosingLoop(c1);
100 d1 = getDepth(c1);
101 }
102 }
103 return c1;
104 }
105
106 @override
107 void processReference(Reference ref) {
108 Continuation loop =
109 leastCommonAncestor(currentLoopHeader, primitiveLoop[ref.definition]);
110 referencedLoop = getInnerLoop(loop, referencedLoop);
111 }
112
113 int getDepth(Continuation loop) {
114 if (loop == null) return -1;
115 return loopHierarchy.loopDepth[loop];
116 }
117
118 Continuation getInnerLoop(Continuation loop1, Continuation loop2) {
119 if (loop1 == null) return loop2;
120 if (loop2 == null) return loop1;
121 if (loopHierarchy.loopDepth[loop1] > loopHierarchy.loopDepth[loop2]) {
122 return loop1;
123 } else {
124 return loop2;
125 }
126 }
127
128 bool shouldLift(Primitive prim) {
129 // Interceptors are safe and almost always profitable for lifting
130 // out of loops. Several other primitive could be lifted too, but it's not
131 // always profitable to do so.
132 return prim is Interceptor;
133 }
134 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/loop_hierarchy.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