summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-18 00:46:16 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2014-12-18 00:46:16 +0000
commit97f07c2778d5a82bae0418e1f05f44baa388c046 (patch)
tree7ba9903562e9aff04d23e6e9fb7673ec2b13d7f2
parentd927bd8d15183809789c875ba7371e92145a688e (diff)
downloadbcm5719-llvm-97f07c2778d5a82bae0418e1f05f44baa388c046.tar.gz
bcm5719-llvm-97f07c2778d5a82bae0418e1f05f44baa388c046.zip
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). llvm-svn: 224482
-rw-r--r--llvm/include/llvm/IR/DIBuilder.h14
-rw-r--r--llvm/lib/IR/DIBuilder.cpp32
2 files changed, 46 insertions, 0 deletions
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index 859bd52bda5..5482de87d6c 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -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
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index ee7e6a2b21b..1874d31e0a5 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -1205,3 +1205,35 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,
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);
+}
OpenPOWER on IntegriCloud