[llvm] r267276 - BitcodeWriter: Emit distinct nodes before uniqued nodes

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 22 21:42:39 PDT 2016


Author: dexonsmith
Date: Fri Apr 22 23:42:39 2016
New Revision: 267276

URL: http://llvm.org/viewvc/llvm-project?rev=267276&view=rev
Log:
BitcodeWriter: Emit distinct nodes before uniqued nodes

When an operand of a distinct node hasn't been read yet, the reader can
use a DistinctMDOperandPlaceholder.  This is much cheaper than forward
referencing from a uniqued node.  Change
ValueEnumerator::organizeMetadata to partition distinct nodes and
uniqued nodes to reduce the overhead of cycles broken by distinct nodes.

Mehdi measured this for me; this removes most of the RAUW from the
importing step of -flto=thin, even after a WIP patch that removes
string-based DITypeRefs (introducing many more cycles to the metadata
graph).

Added:
    llvm/trunk/test/Bitcode/mdnodes-distinct-nodes-first.ll
Modified:
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=267276&r1=267275&r2=267276&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Fri Apr 22 23:42:39 2016
@@ -647,6 +647,22 @@ void ValueEnumerator::EnumerateFunctionL
   EnumerateValue(Local->getValue());
 }
 
+static unsigned getMetadataTypeOrder(const Metadata *MD) {
+  // Strings are emitted in bulk and must come first.
+  if (isa<MDString>(MD))
+    return 0;
+
+  // ConstantAsMetadata doesn't reference anything.  We may as well shuffle it
+  // to the front since we can detect it.
+  auto *N = dyn_cast<MDNode>(MD);
+  if (!N)
+    return 1;
+
+  // The reader is fast forward references for distinct node operands, but slow
+  // when uniqued operands are unresolved.
+  return N->isDistinct() ? 2 : 3;
+}
+
 void ValueEnumerator::organizeMetadata() {
   assert(MetadataMap.size() == MDs.size() &&
          "Metadata map and vector out of sync");
@@ -668,14 +684,10 @@ void ValueEnumerator::organizeMetadata()
   // be unique, the result of std::sort will be deterministic.  There's no need
   // for std::stable_sort.
   std::sort(Order.begin(), Order.end(), [this](MDIndex LHS, MDIndex RHS) {
-    return std::make_tuple(LHS.F, !isa<MDString>(LHS.get(MDs)), LHS.ID) <
-           std::make_tuple(RHS.F, !isa<MDString>(RHS.get(MDs)), RHS.ID);
+    return std::make_tuple(LHS.F, getMetadataTypeOrder(LHS.get(MDs)), LHS.ID) <
+           std::make_tuple(RHS.F, getMetadataTypeOrder(RHS.get(MDs)), RHS.ID);
   });
 
-  // Return early if nothing is moving to functions and there are no strings.
-  if (!Order.back().F && !isa<MDString>(Order.front().get(MDs)))
-    return;
-
   // Rebuild MDs, index the metadata ranges for each function in FunctionMDs,
   // and fix up MetadataMap.
   std::vector<const Metadata *> OldMDs = std::move(MDs);

Added: llvm/trunk/test/Bitcode/mdnodes-distinct-nodes-first.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bitcode/mdnodes-distinct-nodes-first.ll?rev=267276&view=auto
==============================================================================
--- llvm/trunk/test/Bitcode/mdnodes-distinct-nodes-first.ll (added)
+++ llvm/trunk/test/Bitcode/mdnodes-distinct-nodes-first.ll Fri Apr 22 23:42:39 2016
@@ -0,0 +1,18 @@
+; RUN: llvm-as <%s | llvm-bcanalyzer -dump | FileCheck %s
+; Check that distinct nodes are emitted before uniqued nodes, even if that
+; breaks post-order traversals.
+
+; Nodes in this testcase are numbered to match how they are referenced in
+; bitcode.  !1 is referenced as opN=1.
+
+; CHECK:       <DISTINCT_NODE op0=2/>
+!1 = distinct !{!2}
+
+; CHECK-NEXT:  <NODE op0=1/>
+!2 = !{!1}
+
+; 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}




More information about the llvm-commits mailing list