20
20
21
21
#include " absl/container/flat_hash_map.h"
22
22
#include " absl/container/flat_hash_set.h"
23
+ #include " absl/log/check.h"
24
+ #include " absl/log/log.h"
23
25
#include " absl/status/status.h"
24
26
#include " absl/status/statusor.h"
25
27
#include " absl/types/span.h"
@@ -35,14 +37,14 @@ namespace {
35
37
// Perform actual analysis.
36
38
// f is the function to analyze. We only care about getting results for
37
39
// 'interesting_nodes' if the set is non-empty (otherwise all nodes are
38
- // searched). Preds returns the nodes the argument depends on . iter is the
40
+ // searched). Succs returns the nodes that depend on the argument . iter is the
39
41
// iterator to walk the function in the topological order defined by preds.
40
- template <typename Predecessors >
42
+ template <typename Successors >
41
43
std::tuple<absl::flat_hash_map<Node*, InlineBitmap>,
42
44
absl::flat_hash_map<Node*, int64_t >>
43
45
AnalyzeDependents (FunctionBase* f,
44
46
const absl::flat_hash_set<Node*>& interesting_nodes,
45
- Predecessors preds , absl::Span<Node* const > topo_sort) {
47
+ Successors succs , absl::Span<Node* const > topo_sort) {
46
48
absl::flat_hash_map<Node*, int64_t > node_ids;
47
49
node_ids.reserve (f->node_count ());
48
50
int64_t cnt = 0 ;
@@ -62,16 +64,24 @@ AnalyzeDependents(FunctionBase* f,
62
64
}
63
65
return seen_interesting_nodes_count == interesting_nodes.size ();
64
66
};
67
+ VLOG (3 ) << " Analyzing dependents of " << f->node_count () << " nodes with "
68
+ << interesting_nodes.size () << " interesting." ;
65
69
int64_t bitmap_size = f->node_count ();
66
70
absl::flat_hash_map<Node*, InlineBitmap> results;
67
71
results.reserve (f->node_count ());
68
72
for (Node* n : topo_sort) {
69
- InlineBitmap& bm = results.emplace (n, bitmap_size).first ->second ;
73
+ auto [it, inserted] = results.try_emplace (n, bitmap_size);
74
+ InlineBitmap& bm = it->second ;
70
75
bm.Set (node_ids[n]);
71
- for (Node* pred : preds (n)) {
72
- bm.Union (results.at (pred));
76
+ for (Node* succ : succs (n)) {
77
+ auto [s_it, s_new] = results.try_emplace (succ, bm);
78
+ if (!s_new) {
79
+ s_it->second .Union (bm);
80
+ }
73
81
}
74
- if (is_last_interesting_node (n)) {
82
+ if (!is_interesting (n)) {
83
+ results.erase (n);
84
+ } else if (is_last_interesting_node (n)) {
75
85
break ;
76
86
}
77
87
}
@@ -95,7 +105,7 @@ NodeDependencyAnalysis NodeDependencyAnalysis::BackwardDependents(
95
105
FunctionBase* fb, absl::Span<Node* const > nodes) {
96
106
absl::flat_hash_set<Node*> interesting (nodes.begin (), nodes.end ());
97
107
auto [dependents, node_ids] = AnalyzeDependents (
98
- fb, interesting, [](Node* node) { return node->operands (); },
108
+ fb, interesting, /* succs= */ [](Node* node) { return node->users (); },
99
109
TopoSort (fb));
100
110
return NodeDependencyAnalysis (/* is_forwards=*/ false , dependents, node_ids);
101
111
}
@@ -104,7 +114,7 @@ NodeDependencyAnalysis NodeDependencyAnalysis::ForwardDependents(
104
114
FunctionBase* fb, absl::Span<Node* const > nodes) {
105
115
absl::flat_hash_set<Node*> interesting (nodes.begin (), nodes.end ());
106
116
auto [dependents, node_ids] = AnalyzeDependents (
107
- fb, interesting, [](Node* node) { return node->users (); },
117
+ fb, interesting, /* succs= */ [](Node* node) { return node->operands (); },
108
118
ReverseTopoSort (fb));
109
119
return NodeDependencyAnalysis (/* is_forwards=*/ true , dependents, node_ids);
110
120
}
0 commit comments