@@ -28,7 +28,7 @@ using namespace mlir::LLVM::detail;
28
28
29
29
DebugImporter::DebugImporter (ModuleOp mlirModule,
30
30
bool dropDICompositeTypeElements)
31
- : recursionPruner(mlirModule.getContext() ),
31
+ : cache([&](llvm::DINode *node) { return createRecSelf (node); } ),
32
32
context (mlirModule.getContext()), mlirModule(mlirModule),
33
33
dropDICompositeTypeElements(dropDICompositeTypeElements) {}
34
34
@@ -287,16 +287,9 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
287
287
return nullptr ;
288
288
289
289
// Check for a cached instance.
290
- if (DINodeAttr attr = nodeToAttr.lookup (node))
291
- return attr;
292
-
293
- // Register with the recursive translator. If it can be handled without
294
- // recursing into it, return the result immediately.
295
- if (DINodeAttr attr = recursionPruner.pruneOrPushTranslationStack (node))
296
- return attr;
297
-
298
- auto guard = llvm::make_scope_exit (
299
- [&]() { recursionPruner.popTranslationStack (node); });
290
+ auto cacheEntry = cache.lookupOrInit (node);
291
+ if (std::optional<DINodeAttr> result = cacheEntry.get ())
292
+ return *result;
300
293
301
294
// Convert the debug metadata if possible.
302
295
auto translateNode = [this ](llvm::DINode *node) -> DINodeAttr {
@@ -335,20 +328,20 @@ DINodeAttr DebugImporter::translate(llvm::DINode *node) {
335
328
return nullptr ;
336
329
};
337
330
if (DINodeAttr attr = translateNode (node)) {
338
- auto [result, isSelfContained] =
339
- recursionPruner.finalizeTranslation (node, attr);
340
- // Only cache fully self-contained nodes.
341
- if (isSelfContained)
342
- nodeToAttr.try_emplace (node, result);
343
- return result;
331
+ // If this node was repeated, lookup its recursive ID and assign it to the
332
+ // base result.
333
+ if (cacheEntry.wasRepeated ()) {
334
+ DistinctAttr recId = nodeToRecId.lookup (node);
335
+ auto recType = cast<DIRecursiveTypeAttrInterface>(attr);
336
+ attr = cast<DINodeAttr>(recType.withRecId (recId));
337
+ }
338
+ cacheEntry.resolve (attr);
339
+ return attr;
344
340
}
341
+ cacheEntry.resolve (nullptr );
345
342
return nullptr ;
346
343
}
347
344
348
- // ===----------------------------------------------------------------------===//
349
- // RecursionPruner
350
- // ===----------------------------------------------------------------------===//
351
-
352
345
// / Get the `getRecSelf` constructor for the translated type of `node` if its
353
346
// / translated DITypeAttr supports recursion. Otherwise, returns nullptr.
354
347
static function_ref<DIRecursiveTypeAttrInterface(DistinctAttr)>
@@ -361,104 +354,20 @@ getRecSelfConstructor(llvm::DINode *node) {
361
354
.Default (CtorType ());
362
355
}
363
356
364
- DINodeAttr DebugImporter::RecursionPruner::pruneOrPushTranslationStack (
365
- llvm::DINode *node) {
366
- // If the node type is capable of being recursive, check if it's seen
367
- // before.
357
+ std::optional<DINodeAttr> DebugImporter::createRecSelf (llvm::DINode *node) {
368
358
auto recSelfCtor = getRecSelfConstructor (node);
369
- if (recSelfCtor) {
370
- // If a cyclic dependency is detected since the same node is being
371
- // traversed twice, emit a recursive self type, and mark the duplicate
372
- // node on the translationStack so it can emit a recursive decl type.
373
- auto [iter, inserted] = translationStack.try_emplace (node);
374
- if (!inserted) {
375
- // The original node may have already been assigned a recursive ID from
376
- // a different self-reference. Use that if possible.
377
- DIRecursiveTypeAttrInterface recSelf = iter->second .recSelf ;
378
- if (!recSelf) {
379
- DistinctAttr recId = nodeToRecId.lookup (node);
380
- if (!recId) {
381
- recId = DistinctAttr::create (UnitAttr::get (context));
382
- nodeToRecId[node] = recId;
383
- }
384
- recSelf = recSelfCtor (recId);
385
- iter->second .recSelf = recSelf;
386
- }
387
- // Inject the self-ref into the previous layer.
388
- translationStack.back ().second .unboundSelfRefs .insert (recSelf);
389
- return cast<DINodeAttr>(recSelf);
390
- }
359
+ if (!recSelfCtor)
360
+ return std::nullopt;
361
+
362
+ // The original node may have already been assigned a recursive ID from
363
+ // a different self-reference. Use that if possible.
364
+ DistinctAttr recId = nodeToRecId.lookup (node);
365
+ if (!recId) {
366
+ recId = DistinctAttr::create (UnitAttr::get (context));
367
+ nodeToRecId[node] = recId;
391
368
}
392
-
393
- return lookup (node);
394
- }
395
-
396
- std::pair<DINodeAttr, bool >
397
- DebugImporter::RecursionPruner::finalizeTranslation (llvm::DINode *node,
398
- DINodeAttr result) {
399
- // If `node` is not a potentially recursive type, it will not be on the
400
- // translation stack. Nothing to set in this case.
401
- if (translationStack.empty ())
402
- return {result, true };
403
- if (translationStack.back ().first != node)
404
- return {result, translationStack.back ().second .unboundSelfRefs .empty ()};
405
-
406
- TranslationState &state = translationStack.back ().second ;
407
-
408
- // If this node is actually recursive, set the recId onto `result`.
409
- if (DIRecursiveTypeAttrInterface recSelf = state.recSelf ) {
410
- auto recType = cast<DIRecursiveTypeAttrInterface>(result);
411
- result = cast<DINodeAttr>(recType.withRecId (recSelf.getRecId ()));
412
- // Remove this recSelf from the set of unbound selfRefs.
413
- state.unboundSelfRefs .erase (recSelf);
414
- }
415
-
416
- // Insert the result into our internal cache if it's not self-contained.
417
- if (!state.unboundSelfRefs .empty ()) {
418
- [[maybe_unused]] auto [_, inserted] = dependentCache.try_emplace (
419
- node, DependentTranslation{result, state.unboundSelfRefs });
420
- assert (inserted && " invalid state: caching the same DINode twice" );
421
- return {result, false };
422
- }
423
- return {result, true };
424
- }
425
-
426
- void DebugImporter::RecursionPruner::popTranslationStack (llvm::DINode *node) {
427
- // If `node` is not a potentially recursive type, it will not be on the
428
- // translation stack. Nothing to handle in this case.
429
- if (translationStack.empty () || translationStack.back ().first != node)
430
- return ;
431
-
432
- // At the end of the stack, all unbound self-refs must be resolved already,
433
- // and the entire cache should be accounted for.
434
- TranslationState &currLayerState = translationStack.back ().second ;
435
- if (translationStack.size () == 1 ) {
436
- assert (currLayerState.unboundSelfRefs .empty () &&
437
- " internal error: unbound recursive self reference at top level." );
438
- translationStack.pop_back ();
439
- return ;
440
- }
441
-
442
- // Copy unboundSelfRefs down to the previous level.
443
- TranslationState &nextLayerState = (++translationStack.rbegin ())->second ;
444
- nextLayerState.unboundSelfRefs .insert (currLayerState.unboundSelfRefs .begin (),
445
- currLayerState.unboundSelfRefs .end ());
446
- translationStack.pop_back ();
447
- }
448
-
449
- DINodeAttr DebugImporter::RecursionPruner::lookup (llvm::DINode *node) {
450
- auto cacheIter = dependentCache.find (node);
451
- if (cacheIter == dependentCache.end ())
452
- return {};
453
-
454
- DependentTranslation &entry = cacheIter->second ;
455
- if (llvm::set_is_subset (entry.unboundSelfRefs ,
456
- translationStack.back ().second .unboundSelfRefs ))
457
- return entry.attr ;
458
-
459
- // Stale cache entry.
460
- dependentCache.erase (cacheIter);
461
- return {};
369
+ DIRecursiveTypeAttrInterface recSelf = recSelfCtor (recId);
370
+ return cast<DINodeAttr>(recSelf);
462
371
}
463
372
464
373
// ===----------------------------------------------------------------------===//
0 commit comments