r368767 - [analyzer] exploded-graph-rewriter: NFC: Refactor explorers into trimmers.
Artem Dergachev via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 13 16:04:50 PDT 2019
Author: dergachev
Date: Tue Aug 13 16:04:50 2019
New Revision: 368767
URL: http://llvm.org/viewvc/llvm-project?rev=368767&view=rev
Log:
[analyzer] exploded-graph-rewriter: NFC: Refactor explorers into trimmers.
Explorers aren't the right abstraction. For the purposes of displaying svg files
we don't care in which order do we explore the nodes. We may care about this for
other analyses, but we're not there yet.
The function of cutting out chunks of the graph is performed poorly by
the explorers, because querying predecessors/successors on the explored nodes
yields original successors/predecessors even if they aren't being explored.
Introduce a new entity, "trimmers", that do one thing but to it right: cut out
chunks of the graph. Trimmers mutate the graph, so stale edges aren't even
visible to their consumers in the pipeline. Additionally, trimmers are
intrinsically composable: multiple trimmers can be applied to the graph
sequentially.
Refactor the single-path explorer into the single-path trimmer.
Rename the test file for consistency.
Differential Revision: https://reviews.llvm.org/D65344
Added:
cfe/trunk/test/Analysis/exploded-graph-rewriter/trimmers.dot
Removed:
cfe/trunk/test/Analysis/exploded-graph-rewriter/explorers.dot
Modified:
cfe/trunk/utils/analyzer/exploded-graph-rewriter.py
Removed: cfe/trunk/test/Analysis/exploded-graph-rewriter/explorers.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/explorers.dot?rev=368766&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/explorers.dot (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/explorers.dot (removed)
@@ -1,37 +0,0 @@
-// RUN: %exploded_graph_rewriter %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK,BASIC
-// RUN: %exploded_graph_rewriter -s %s \
-// RUN: | FileCheck %s -check-prefixes=CHECK,SINGLE
-
-// FIXME: Substitution doesn't seem to work on Windows.
-// UNSUPPORTED: system-windows
-
-Node0x1 [shape=record,label=
- "{{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
-
-Node0x2 [shape=record,label=
- "{{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
-
-Node0x3 [shape=record,label=
- "{{ "node_id": 3, "pointer": "0x3", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
-
-Node0x4 [shape=record,label=
- "{{ "node_id": 4, "pointer": "0x4", "has_report": false, "is_sink": false,
- "program_state": null, "program_points": []}\l}"];
-
-// CHECK: Node0x1 -> Node0x2;
-Node0x1 -> Node0x2;
-
-// BASIC: Node0x1 -> Node0x3;
-// SINGLE-NOT: Node0x1 -> Node0x3;
-Node0x1 -> Node0x3;
-
-// CHECK: Node0x2 -> Node0x4;
-Node0x2 -> Node0x4;
-
-// BASIC: Node0x3 -> Node0x4;
-// SINGLE-NOT: Node0x3 -> Node0x4;
-Node0x3 -> Node0x4;
Added: cfe/trunk/test/Analysis/exploded-graph-rewriter/trimmers.dot
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/trimmers.dot?rev=368767&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/trimmers.dot (added)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/trimmers.dot Tue Aug 13 16:04:50 2019
@@ -0,0 +1,37 @@
+// RUN: %exploded_graph_rewriter %s \
+// RUN: | FileCheck %s -check-prefixes=CHECK,BASIC
+// RUN: %exploded_graph_rewriter -s %s \
+// RUN: | FileCheck %s -check-prefixes=CHECK,SINGLE
+
+// FIXME: Substitution doesn't seem to work on Windows.
+// UNSUPPORTED: system-windows
+
+Node0x1 [shape=record,label=
+ "{{ "node_id": 1, "pointer": "0x1", "has_report": false, "is_sink": false,
+ "program_state": null, "program_points": []}\l}"];
+
+Node0x2 [shape=record,label=
+ "{{ "node_id": 2, "pointer": "0x2", "has_report": false, "is_sink": false,
+ "program_state": null, "program_points": []}\l}"];
+
+Node0x3 [shape=record,label=
+ "{{ "node_id": 3, "pointer": "0x3", "has_report": false, "is_sink": false,
+ "program_state": null, "program_points": []}\l}"];
+
+Node0x4 [shape=record,label=
+ "{{ "node_id": 4, "pointer": "0x4", "has_report": false, "is_sink": false,
+ "program_state": null, "program_points": []}\l}"];
+
+// CHECK: Node0x1 -> Node0x2;
+Node0x1 -> Node0x2;
+
+// BASIC: Node0x1 -> Node0x3;
+// SINGLE-NOT: Node0x1 -> Node0x3;
+Node0x1 -> Node0x3;
+
+// CHECK: Node0x2 -> Node0x4;
+Node0x2 -> Node0x4;
+
+// BASIC: Node0x3 -> Node0x4;
+// SINGLE-NOT: Node0x3 -> Node0x4;
+Node0x3 -> Node0x4;
Modified: cfe/trunk/utils/analyzer/exploded-graph-rewriter.py
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/exploded-graph-rewriter.py?rev=368767&r1=368766&r2=368767&view=diff
==============================================================================
--- cfe/trunk/utils/analyzer/exploded-graph-rewriter.py (original)
+++ cfe/trunk/utils/analyzer/exploded-graph-rewriter.py Tue Aug 13 16:04:50 2019
@@ -882,37 +882,36 @@ class BasicExplorer(object):
visitor.visit_end_of_graph()
-# SinglePathExplorer traverses only a single path - the leftmost path
-# from the root. Useful when the trimmed graph is still too large
-# due to a large amount of equivalent reports.
-class SinglePathExplorer(object):
- def __init__(self):
- super(SinglePathExplorer, self).__init__()
+#===-----------------------------------------------------------------------===#
+# Trimmers cut out parts of the ExplodedGraph so that to focus on other parts.
+# Trimmers can be combined together by applying them sequentially.
+#===-----------------------------------------------------------------------===#
- def explore(self, graph, visitor):
- visitor.visit_begin_graph(graph)
- # Keep track of visited nodes in order to avoid loops.
- visited = set()
+# SinglePathTrimmer keeps only a single path - the leftmost path from the root.
+# Useful when the trimmed graph is still too large.
+class SinglePathTrimmer(object):
+ def __init__(self):
+ super(SinglePathTrimmer, self).__init__()
+
+ def trim(self, graph):
+ visited_nodes = set()
node_id = graph.root_id
while True:
- visited.add(node_id)
+ visited_nodes.add(node_id)
node = graph.nodes[node_id]
- logging.debug('Visiting ' + node_id)
- visitor.visit_node(node)
- if len(node.successors) == 0:
- break
-
- succ_id = node.successors[0]
- succ = graph.nodes[succ_id]
- logging.debug('Visiting edge: %s -> %s ' % (node_id, succ_id))
- visitor.visit_edge(node, succ)
- if succ_id in visited:
+ if len(node.successors) > 0:
+ succ_id = node.successors[0]
+ succ = graph.nodes[succ_id]
+ node.successors = [succ_id]
+ succ.predecessors = [node_id]
+ if succ_id in visited_nodes:
+ break
+ node_id = succ_id
+ else:
break
-
- node_id = succ_id
-
- visitor.visit_end_of_graph()
+ graph.nodes = {node_id: graph.nodes[node_id]
+ for node_id in visited_nodes}
#===-----------------------------------------------------------------------===#
@@ -960,10 +959,18 @@ def main():
raw_line = raw_line.strip()
graph.add_raw_line(raw_line)
- explorer = SinglePathExplorer() if args.single_path else BasicExplorer()
+ trimmers = []
+ if args.single_path:
+ trimmers.append(SinglePathTrimmer())
+
+ explorer = BasicExplorer()
+
visitor = DotDumpVisitor(args.diff, args.dark, args.gray, args.topology,
args.dump_dot_only)
+ for trimmer in trimmers:
+ trimmer.trim(graph)
+
explorer.explore(graph, visitor)
More information about the cfe-commits
mailing list