summaryrefslogtreecommitdiffstats
path: root/test/Bitcode
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-23 04:59:22 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-23 04:59:22 +0000
commit29fa04dd53ab57fce295f0cf8c5c00560c724805 (patch)
tree4955b1e6a44b88cf4b0d583659c2d48e34813935 /test/Bitcode
parentf2d5595f96d3d7d03c258233fbc171210fb9cd6d (diff)
BitcodeWriter: Emit uniqued subgraphs after all distinct nodes
Since forward references for uniqued node operands are expensive (and those for distinct node operands are cheap due to DistinctMDOperandPlaceholder), minimize forward references in uniqued node operands. Moreover, guarantee that when a cycle is broken by a distinct node, none of the uniqued nodes have any forward references. In ValueEnumerator::EnumerateMetadata, enumerate uniqued node subgraphs first, delaying distinct nodes until all uniqued nodes have been handled. This guarantees that uniqued nodes only have forward references when there is a uniquing cycle (since r267276 changed ValueEnumerator::organizeMetadata to partition distinct nodes in front of uniqued nodes as a post-pass). Note that a single uniqued subgraph can hit multiple distinct nodes at its leaves. Ideally these would themselves be emitted in post-order, but this commit doesn't attempt that; I think it requires an extra pass through the edges, which I'm not convinced is worth it (since DistinctMDOperandPlaceholder makes forward references quite cheap between distinct nodes). I've added two testcases: - test/Bitcode/mdnodes-distinct-in-post-order.ll is just like test/Bitcode/mdnodes-in-post-order.ll, except with distinct nodes instead of uniqued ones. This confirms that, in the absence of uniqued nodes, distinct nodes are still emitted in post-order. - test/Bitcode/mdnodes-distinct-nodes-break-cycles.ll is the minimal example where a naive post-order traversal would cause one uniqued node to forward-reference another. IOW, it's the motivating test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267278 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Bitcode')
-rw-r--r--test/Bitcode/mdnodes-distinct-in-post-order.ll24
-rw-r--r--test/Bitcode/mdnodes-distinct-nodes-break-cycles.ll29
2 files changed, 53 insertions, 0 deletions
diff --git a/test/Bitcode/mdnodes-distinct-in-post-order.ll b/test/Bitcode/mdnodes-distinct-in-post-order.ll
new file mode 100644
index 000000000000..6e6ba604235b
--- /dev/null
+++ b/test/Bitcode/mdnodes-distinct-in-post-order.ll
@@ -0,0 +1,24 @@
+; RUN: llvm-as <%s | llvm-bcanalyzer -dump | FileCheck %s
+; Check that distinct nodes are emitted in post-order to avoid unnecessary
+; forward references.
+
+; Nodes in this testcase are numbered to match how they are referenced in
+; bitcode. !3 is referenced as opN=3.
+
+; The leafs should come first (in either order).
+; CHECK: <DISTINCT_NODE/>
+; CHECK-NEXT: <DISTINCT_NODE/>
+!1 = distinct !{}
+!2 = distinct !{}
+
+; CHECK-NEXT: <DISTINCT_NODE op0=1 op1=2/>
+!3 = distinct !{!1, !2}
+
+; CHECK-NEXT: <DISTINCT_NODE op0=1 op1=3 op2=2/>
+!4 = distinct !{!1, !3, !2}
+
+; Note: named metadata nodes are not cannot reference null so their operands
+; are numbered off-by-one.
+; CHECK-NEXT: <NAME
+; CHECK-NEXT: <NAMED_NODE op0=3/>
+!named = !{!4}
diff --git a/test/Bitcode/mdnodes-distinct-nodes-break-cycles.ll b/test/Bitcode/mdnodes-distinct-nodes-break-cycles.ll
new file mode 100644
index 000000000000..51701d10c03b
--- /dev/null
+++ b/test/Bitcode/mdnodes-distinct-nodes-break-cycles.ll
@@ -0,0 +1,29 @@
+; RUN: llvm-as <%s | llvm-bcanalyzer -dump | FileCheck %s
+; Check that distinct nodes break uniquing cycles, so that uniqued subgraphs
+; are always in post-order.
+;
+; It may not be immediately obvious why this is an interesting graph. There
+; are three nodes in a cycle, and one of them (!1) is distinct. Because the
+; entry point is !2, a naive post-order traversal would give !3, !1, !2; but
+; this means when !3 is parsed the reader will need a forward reference for !2.
+; Forward references for uniqued node operands are expensive, whereas they're
+; cheap for distinct node operands. If the distinct node is emitted first, the
+; uniqued nodes don't need any forward references at all.
+
+; Nodes in this testcase are numbered to match how they are referenced in
+; bitcode. !3 is referenced as opN=3.
+
+; CHECK: <DISTINCT_NODE op0=3/>
+!1 = distinct !{!3}
+
+; CHECK-NEXT: <NODE op0=1/>
+!2 = !{!1}
+
+; CHECK-NEXT: <NODE op0=2/>
+!3 = !{!2}
+
+; Note: named metadata nodes are not cannot reference null so their operands
+; are numbered off-by-one.
+; CHECK-NEXT: <NAME
+; CHECK-NEXT: <NAMED_NODE op0=1/>
+!named = !{!2}