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

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

Issue 1426633005: dart2js cps: Better side-effect tracking in loops. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/loop_effects.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 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 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 library dart2js.cps_ir.loop_hierarchy; 5 library dart2js.cps_ir.loop_hierarchy;
6 6
7 import 'cps_ir_nodes.dart'; 7 import 'cps_ir_nodes.dart';
8 8
9 /// Determines the effective nesting of loops. 9 /// Determines the effective nesting of loops.
10 /// 10 ///
11 /// The effective nesting of loops is different from the lexical nesting, since 11 /// The effective nesting of loops is different from the lexical nesting, since
12 /// recursive continuations can generally contain all the code following 12 /// recursive continuations can generally contain all the code following
13 /// after the loop in addition to the looping code itself. 13 /// after the loop in addition to the looping code itself.
14 /// 14 ///
15 /// For example, the 'else' branch below is not effectively part of the loop: 15 /// For example, the 'else' branch below is not effectively part of the loop:
16 /// 16 ///
17 /// let rec kont x = 17 /// let rec kont x =
18 /// if (<loop condition>) 18 /// if (<loop condition>)
19 /// <loop body> 19 /// <loop body>
20 /// InvokeContinuation kont x' 20 /// InvokeContinuation kont x'
21 /// else 21 /// else
22 /// <after loop> 22 /// <after loop>
23 /// return p.foo() 23 /// return p.foo()
24 /// 24 ///
25 /// We use the term "loop" to mean recursive continuation. 25 /// We use the term "loop" to mean recursive continuation.
26 /// The `null` value is used to represent a context not part of any loop. 26 /// The `null` value is used to represent a context not part of any loop.
27 class LoopHierarchy { 27 class LoopHierarchy {
28 /// Nesting depth of the given loop. 28 /// Nesting depth of the given loop.
29 Map<Continuation, int> loopDepth = <Continuation, int>{}; 29 Map<Continuation, int> loopDepth = <Continuation, int>{};
30 30
31 /// The innermost loop (other than itself) that may be invoked recursively 31 /// The innermost loop (other than itself) that may be invoked recursively
32 /// as a result of invoking the given continuation. 32 /// as a result of invoking the given continuation.
33 Map<Continuation, Continuation> loopTarget = <Continuation, Continuation>{}; 33 Map<Continuation, Continuation> loopTarget = <Continuation, Continuation>{};
34 34
35 /// Current nesting depth. 35 /// Current nesting depth.
36 int currentDepth = 0; 36 int currentDepth = 0;
37 37
38 /// Computes the loop hierarchy for the given function. 38 /// Computes the loop hierarchy for the given function.
39 /// 39 ///
40 /// Parent pointers must be computed for [node]. 40 /// Parent pointers must be computed for [node].
41 LoopHierarchy(FunctionDefinition node) { 41 LoopHierarchy(FunctionDefinition node) {
42 _processBlock(node.body, null); 42 _processBlock(node.body, null);
43 } 43 }
44 44
45 /// Returns the innermost loop which [cont] is effectively part of. 45 /// Returns the innermost loop which [cont] is effectively part of.
46 Continuation getLoopHeader(Continuation cont) { 46 Continuation getLoopHeader(Continuation cont) {
47 return cont.isRecursive ? cont : loopTarget[cont]; 47 return cont.isRecursive ? cont : loopTarget[cont];
48 } 48 }
49 49
50 /// Returns the innermost loop which the given loop is part of, other 50 /// Returns the innermost loop which the given continuation is part of, other
51 /// than itself. 51 /// than itself.
52 Continuation getEnclosingLoop(Continuation loop) { 52 Continuation getEnclosingLoop(Continuation cont) {
53 return loopTarget[loop]; 53 return loopTarget[cont];
asgerf 2015/11/05 12:13:42 The only "change" here is that we may now ask for
54 } 54 }
55 55
56 /// Marks the innermost loop as a subloop of the other loop. 56 /// Marks the innermost loop as a subloop of the other loop.
57 /// 57 ///
58 /// Returns the innermost loop. 58 /// Returns the innermost loop.
59 /// 59 ///
60 /// Both continuations, [c1] and [c2] may be null (i.e. no loop). 60 /// Both continuations, [c1] and [c2] may be null (i.e. no loop).
61 /// 61 ///
62 /// A loop is said to be a subloop of an enclosing loop if it can invoke 62 /// A loop is said to be a subloop of an enclosing loop if it can invoke
63 /// that loop recursively. This information is stored in [loopTarget]. 63 /// that loop recursively. This information is stored in [loopTarget].
64 /// 64 ///
65 /// This method is only invoked with two distinct loops if there is a 65 /// This method is only invoked with two distinct loops if there is a
66 /// point that can reach a recursive invocation of both loops. 66 /// point that can reach a recursive invocation of both loops.
67 /// This implies that one loop is nested in the other, because they must 67 /// This implies that one loop is nested in the other, because they must
68 /// both be in scope at that point. 68 /// both be in scope at that point.
69 Continuation _markInnerLoop(Continuation c1, Continuation c2) { 69 Continuation _markInnerLoop(Continuation c1, Continuation c2) {
70 assert(c1 == null || c1.isRecursive); 70 assert(c1 == null || c1.isRecursive);
71 assert(c2 == null || c2.isRecursive); 71 assert(c2 == null || c2.isRecursive);
72 if (c1 == null) return c2; 72 if (c1 == null) return c2;
73 if (c2 == null) return c1; 73 if (c2 == null) return c1;
74 if (c1 == c2) return c1; 74 if (c1 == c2) return c1;
75 if (loopDepth[c1] > loopDepth[c2]) { 75 if (loopDepth[c1] > loopDepth[c2]) {
76 loopTarget[c1] = _markInnerLoop(loopTarget[c1], c2); 76 loopTarget[c1] = _markInnerLoop(loopTarget[c1], c2);
77 return c1; 77 return c1;
78 } else { 78 } else {
79 loopTarget[c2] = _markInnerLoop(loopTarget[c2], c1); 79 loopTarget[c2] = _markInnerLoop(loopTarget[c2], c1);
80 return c2; 80 return c2;
81 } 81 }
82 } 82 }
83 83
84 /// Analyzes the body of [cont] and returns the innermost loop 84 /// Analyzes the body of [cont] and returns the innermost loop
85 /// that can be invoked recursively from [cont] (other than [cont] itself). 85 /// that can be invoked recursively from [cont] (other than [cont] itself).
86 /// 86 ///
87 /// [catchLoop] is the innermost loop that can be invoked recursively 87 /// [catchLoop] is the innermost loop that can be invoked recursively
88 /// from the current exception handler. 88 /// from the current exception handler.
89 Continuation _processContinuation(Continuation cont, Continuation catchLoop) { 89 Continuation _processContinuation(Continuation cont, Continuation catchLoop) {
90 if (cont.isRecursive) { 90 if (cont.isRecursive) {
91 ++currentDepth; 91 ++currentDepth;
92 loopDepth[cont] = currentDepth; 92 loopDepth[cont] = currentDepth;
93 Continuation target = _processBlock(cont.body, catchLoop); 93 Continuation target = _processBlock(cont.body, catchLoop);
94 _markInnerLoop(loopTarget[cont], target); 94 _markInnerLoop(loopTarget[cont], target);
95 --currentDepth; 95 --currentDepth;
96 } else { 96 } else {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 target = _markInnerLoop(target, catchLoop); 144 target = _markInnerLoop(target, catchLoop);
145 for (Continuation cont in callContinuations) { 145 for (Continuation cont in callContinuations) {
146 // Store the loop target on each call continuation in the basic block. 146 // Store the loop target on each call continuation in the basic block.
147 // Because we walk over call continuations as part of the basic block 147 // Because we walk over call continuations as part of the basic block
148 // traversal, these do not get their loop target set otherwise. 148 // traversal, these do not get their loop target set otherwise.
149 loopTarget[cont] = target; 149 loopTarget[cont] = target;
150 } 150 }
151 return target; 151 return target;
152 } 152 }
153 } 153 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/loop_effects.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698