[llvm] r224482 - IR: Handle self-referencing DICompositeTypes in DIBuilder

Duncan P. N. Exon Smith dexonsmith at apple.com
Wed Dec 17 16:46:16 PST 2014


Author: dexonsmith
Date: Wed Dec 17 18:46:16 2014
New Revision: 224482

URL: http://llvm.org/viewvc/llvm-project?rev=224482&view=rev
Log:
IR: Handle self-referencing DICompositeTypes in DIBuilder

Add API to DIBuilder to handle self-referencing `DICompositeType`s.

Self-references aren't expected in the debug info graph, and we take
advantage of that by only calling `resolveCycles()` on nodes that were
once forward declarations (otherwise, DIBuilder needs an expensive
tracking reference to every unresolved node it creates, which in cyclic
graphs is *all of them*).

However, clang seems to create self-referencing `DICompositeType`s.  Add
API to manage this safely.  The paired commit to clang will include the
regression test.

I'll make the `DICompositeType` API `private` in a follow-up to prevent
misuse (I've separated that to prevent build failures from missing the
clang commit).

Modified:
    llvm/trunk/include/llvm/IR/DIBuilder.h
    llvm/trunk/lib/IR/DIBuilder.cpp

Modified: llvm/trunk/include/llvm/IR/DIBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DIBuilder.h?rev=224482&r1=224481&r2=224482&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DIBuilder.h (original)
+++ llvm/trunk/include/llvm/IR/DIBuilder.h Wed Dec 17 18:46:16 2014
@@ -698,6 +698,20 @@ namespace llvm {
     Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset,
                                          DIVariable VarInfo, DIExpression Expr,
                                          Instruction *InsertBefore);
+
+    /// \brief Replace the vtable holder in the given composite type.
+    ///
+    /// If this creates a self reference, it may orphan some unresolved cycles
+    /// in the operands of \c T, so \a DIBuilder needs to track that.
+    void replaceVTableHolder(DICompositeType &T, DICompositeType VTableHolder);
+
+    /// \brief Replace arrays on a composite type.
+    ///
+    /// If \c T is resolved, but the arrays aren't -- which can happen if \c T
+    /// has a self-reference -- \a DIBuilder needs to track the array to
+    /// resolve cycles.
+    void replaceArrays(DICompositeType &T, DIArray Elements,
+                       DIArray TParems = DIArray());
   };
 } // end namespace llvm
 

Modified: llvm/trunk/lib/IR/DIBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DIBuilder.cpp?rev=224482&r1=224481&r2=224482&view=diff
==============================================================================
--- llvm/trunk/lib/IR/DIBuilder.cpp (original)
+++ llvm/trunk/lib/IR/DIBuilder.cpp Wed Dec 17 18:46:16 2014
@@ -1205,3 +1205,35 @@ Instruction *DIBuilder::insertDbgValueIn
                    MetadataAsValue::get(VMContext, Expr)};
   return CallInst::Create(ValueFn, Args, "", InsertAtEnd);
 }
+
+void DIBuilder::replaceVTableHolder(DICompositeType &T, DICompositeType VTableHolder) {
+  T.setContainingType(VTableHolder);
+
+  // If this didn't create a self-reference, just return.
+  if (T != VTableHolder)
+    return;
+
+  // Look for unresolved operands.  T has dropped RAUW support and is already
+  // marked resolved, orphaning any cycles underneath it.
+  assert(T->isResolved() && "Expected self-reference to be resolved");
+  for (const MDOperand &O : T->operands())
+    if (auto *N = dyn_cast_or_null<MDNode>(O))
+      trackIfUnresolved(N);
+}
+
+void DIBuilder::replaceArrays(DICompositeType &T, DIArray Elements,
+                              DIArray TParams) {
+  T.setArrays(Elements, TParams);
+
+  // If T isn't resolved, there's no problem.
+  if (!T->isResolved())
+    return;
+
+  // If "T" is resolved, it may be due to a self-reference cycle.  Track the
+  // arrays explicitly if they're unresolved, or else the cycles will be
+  // orphaned.
+  if (Elements)
+    trackIfUnresolved(Elements);
+  if (TParams)
+    trackIfUnresolved(TParams);
+}





More information about the llvm-commits mailing list