[Mlir-commits] [mlir] [MLIR][LLVM] Support Recursive DITypes (PR #80251)

Billy Zhu llvmlistbot at llvm.org
Thu Feb 29 22:27:45 PST 2024


================
@@ -247,12 +242,47 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
   if (DINodeAttr attr = nodeToAttr.lookup(node))
     return attr;
 
-  // Return nullptr if a cyclic dependency is detected since the same node is
-  // being traversed twice. This check avoids infinite recursion if the debug
-  // metadata contains cycles.
-  if (!translationStack.insert(node))
-    return nullptr;
-  auto guard = llvm::make_scope_exit([&]() { translationStack.pop_back(); });
+  // If a cyclic dependency is detected since the same node is being traversed
+  // twice, emit a recursive self type, and mark the duplicate node on the
+  // translationStack so it can emit a recursive decl type.
+  auto *typeNode = dyn_cast<llvm::DIType>(node);
+  if (typeNode) {
+    auto [iter, inserted] = typeTranslationStack.try_emplace(typeNode, nullptr);
+    if (!inserted) {
+      // The original node may have already been assigned a recursive ID from
+      // a different self-reference. Use that if possible.
+      DistinctAttr recId = iter->second;
+      if (!recId) {
+        recId = DistinctAttr::create(UnitAttr::get(context));
+        iter->second = recId;
+      }
+      unboundRecursiveSelfRefs.back().insert(recId);
+      return DIRecursiveTypeAttr::get(recId);
+    }
+  } else {
+    bool inserted =
+        nonTypeTranslationStack.insert({node, typeTranslationStack.size()});
----------------
zyx-billy wrote:

ah, I was thinking about the first cyclic example in `mlir/test/Target/LLVMIR/Import/debug-info.ll`, where we have:
```
!comp = !DICompositeType(elements: !{!sp}, ...)
!sp = !DISubprogram(scope: !comp, ...)
```
So technically one can consider either the type to be recursive, or the subprogram to be recursive. For now I'm limiting all recursions to go through at least a type, and this stack is used to check that.
I suppose we can remove the check, but then it'll just stack overflow if we ever get a purely non-type cycle. Would an error be better instead?

https://github.com/llvm/llvm-project/pull/80251


More information about the Mlir-commits mailing list