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

Side by Side Diff: lib/src/graph.dart

Issue 1412903002: include fields in verify_deps, refactor graph dfs (Closed) Base URL: git@github.com:dart-lang/dart2js_info.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « bin/verify_deps.dart ('k') | pubspec.yaml » ('j') | 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 /// A library to work with graphs. It contains a couple algorithms, including 5 /// A library to work with graphs. It contains a couple algorithms, including
6 /// Tarjan's algorithm to compute strongest connected components in a graph and 6 /// Tarjan's algorithm to compute strongly connected components in a graph and
7 /// Cooper et al's dominator algorithm. 7 /// Cooper et al's dominator algorithm.
8 /// 8 ///
9 /// Portions of the code in this library was adapted from 9 /// Portions of the code in this library was adapted from
10 /// `package:analyzer/src/generated/collection_utilities.dart`. 10 /// `package:analyzer/src/generated/collection_utilities.dart`.
11 // TODO(sigmund): move this into a shared place, like quiver? 11 // TODO(sigmund): move this into a shared place, like quiver?
12 library dart2js_info.src.graph; 12 library dart2js_info.src.graph;
13 13
14 import 'dart:math' as math; 14 import 'dart:math' as math;
15 15
16 abstract class Graph<N> { 16 abstract class Graph<N> {
(...skipping 17 matching lines...) Expand all
34 Set<N> seen = new Set<N>(); 34 Set<N> seen = new Set<N>();
35 bool helper(N node) { 35 bool helper(N node) {
36 if (identical(node, target)) return true; 36 if (identical(node, target)) return true;
37 if (!seen.add(node)) return false; 37 if (!seen.add(node)) return false;
38 return targetsOf(node).any(helper); 38 return targetsOf(node).any(helper);
39 } 39 }
40 return helper(source); 40 return helper(source);
41 } 41 }
42 42
43 /// Returns all nodes reachable from [root] in post order. 43 /// Returns all nodes reachable from [root] in post order.
44 List<N> postOrder(N root) { 44 Iterable<N> postOrder(N root) sync* {
45 var seen = new Set<N>(); 45 var seen = new Set<N>();
46 var result = <N>[]; 46 Iterable<N> helper(n) sync* {
47 helper(n) {
48 if (!seen.add(n)) return; 47 if (!seen.add(n)) return;
49 targetsOf(n).forEach(helper); 48 for (var x in targetsOf(n)) {
50 result.add(n); 49 yield* helper(x);
50 }
51 yield n;
51 } 52 }
52 helper(root); 53 yield* helper(root);
53 return result;
54 } 54 }
55 55
56 /// Return a list of nodes that form a cycle containing the given node. If the 56 /// Returns an iterable of all nodes reachable from [root] in preorder.
57 /// node is not part of a cycle in this graph, then a list containing only the 57 Iterable<N> preOrder(N root) sync* {
58 /// node itself will be returned. 58 var seen = new Set<N>();
59 var stack = <N>[root];
60 while (stack.isNotEmpty) {
61 var next = stack.removeLast();
62 if (!seen.contains(next)) {
63 seen.add(next);
64 yield next;
65 stack.addAll(targetsOf(next));
66 }
67 }
68 }
69
70 /// Returns a list of nodes that form a cycle containing the given node. If
71 /// the node is not part of a cycle in this graph, then a list containing only
72 /// the node itself will be returned.
59 List<N> findCycleContaining(N node) { 73 List<N> findCycleContaining(N node) {
60 assert(node != null); 74 assert(node != null);
61 _SccFinder<N> finder = new _SccFinder<N>(this); 75 _SccFinder<N> finder = new _SccFinder<N>(this);
62 return finder._componentContaining(node); 76 return finder._componentContaining(node);
63 } 77 }
64 78
65 /// Returns a dominator tree starting from root. This is a new graph, with the 79 /// Returns a dominator tree starting from root. This is a new graph, with the
66 /// same nodes as this graph, but where edges exist between a node and the 80 /// same nodes as this graph, but where edges exist between a node and the
67 /// nodes it immediately dominates. For example, this graph: 81 /// nodes it immediately dominates. For example, this graph:
68 /// 82 ///
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 class _DominatorFinder<N> { 280 class _DominatorFinder<N> {
267 final Graph<N> _graph; 281 final Graph<N> _graph;
268 Map<N, N> immediateDominators = {}; 282 Map<N, N> immediateDominators = {};
269 Map<N, int> postOrderId = {}; 283 Map<N, int> postOrderId = {};
270 _DominatorFinder(this._graph); 284 _DominatorFinder(this._graph);
271 285
272 run(N root) { 286 run(N root) {
273 immediateDominators[root] = root; 287 immediateDominators[root] = root;
274 bool changed = true; 288 bool changed = true;
275 int i = 0; 289 int i = 0;
276 var nodesInPostOrder = _graph.postOrder(root); 290 var nodesInPostOrder = _graph.postOrder(root).toList();
277 for (var n in nodesInPostOrder) { 291 for (var n in nodesInPostOrder) {
278 postOrderId[n] = i++; 292 postOrderId[n] = i++;
279 } 293 }
280 var nodesInReversedPostOrder = nodesInPostOrder.reversed; 294 var nodesInReversedPostOrder = nodesInPostOrder.reversed;
281 while (changed) { 295 while (changed) {
282 changed = false; 296 changed = false;
283 for (var n in nodesInReversedPostOrder) { 297 for (var n in nodesInReversedPostOrder) {
284 if (n == root) continue; 298 if (n == root) continue;
285 bool first = true; 299 bool first = true;
286 var idom = null; 300 var idom = null;
(...skipping 22 matching lines...) Expand all
309 while (postOrderId[finger1] < postOrderId[finger2]) { 323 while (postOrderId[finger1] < postOrderId[finger2]) {
310 finger1 = immediateDominators[finger1]; 324 finger1 = immediateDominators[finger1];
311 } 325 }
312 while (postOrderId[finger2] < postOrderId[finger1]) { 326 while (postOrderId[finger2] < postOrderId[finger1]) {
313 finger2 = immediateDominators[finger2]; 327 finger2 = immediateDominators[finger2];
314 } 328 }
315 } 329 }
316 return finger1; 330 return finger1;
317 } 331 }
318 } 332 }
OLDNEW
« no previous file with comments | « bin/verify_deps.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698