@@ -300,6 +300,299 @@ bool llvm::StripDebugInfo(Module &M) {
300
300
return Changed;
301
301
}
302
302
303
+ namespace {
304
+
305
+ // / Helper class to downgrade -g metadata to -gline-tables-only metadata.
306
+ class DebugTypeInfoRemoval {
307
+ DenseMap<Metadata *, Metadata *> Replacements;
308
+
309
+ public:
310
+ // / The (void)() type.
311
+ MDNode *EmptySubroutineType;
312
+
313
+ private:
314
+ // / Remember what linkage name we originally had before stripping. If we end
315
+ // / up making two subprograms identical who originally had different linkage
316
+ // / names, then we need to make one of them distinct, to avoid them getting
317
+ // / uniqued. Maps the new node to the old linkage name.
318
+ DenseMap<DISubprogram *, StringRef> NewToLinkageName;
319
+
320
+ // TODO: Remember the distinct subprogram we created for a given linkage name,
321
+ // so that we can continue to unique whenever possible. Map <newly created
322
+ // node, old linkage name> to the first (possibly distinct) mdsubprogram
323
+ // created for that combination. This is not strictly needed for correctness,
324
+ // but can cut down on the number of MDNodes and let us diff cleanly with the
325
+ // output of -gline-tables-only.
326
+
327
+ public:
328
+ DebugTypeInfoRemoval (LLVMContext &C)
329
+ : EmptySubroutineType(DISubroutineType::get(C, DINode::FlagZero, 0 ,
330
+ MDNode::get (C, {}))) {}
331
+
332
+ Metadata *map (Metadata *M) {
333
+ if (!M)
334
+ return nullptr ;
335
+ auto Replacement = Replacements.find (M);
336
+ if (Replacement != Replacements.end ())
337
+ return Replacement->second ;
338
+
339
+ return M;
340
+ }
341
+ MDNode *mapNode (Metadata *N) { return dyn_cast_or_null<MDNode>(map (N)); }
342
+
343
+ // / Recursively remap N and all its referenced children. Does a DF post-order
344
+ // / traversal, so as to remap bottoms up.
345
+ void traverseAndRemap (MDNode *N) { traverse (N); }
346
+
347
+ private:
348
+ // Create a new DISubprogram, to replace the one given.
349
+ DISubprogram *getReplacementSubprogram (DISubprogram *MDS) {
350
+ auto *FileAndScope = cast_or_null<DIFile>(map (MDS->getFile ()));
351
+ StringRef LinkageName = MDS->getName ().empty () ? MDS->getLinkageName () : " " ;
352
+ DISubprogram *Declaration = nullptr ;
353
+ auto *Type = cast_or_null<DISubroutineType>(map (MDS->getType ()));
354
+ DITypeRef ContainingType (map (MDS->getContainingType ()));
355
+ auto *Unit = cast_or_null<DICompileUnit>(map (MDS->getUnit ()));
356
+ auto Variables = nullptr ;
357
+ auto TemplateParams = nullptr ;
358
+
359
+ // Make a distinct DISubprogram, for situations that warrent it.
360
+ auto distinctMDSubprogram = [&]() {
361
+ return DISubprogram::getDistinct (
362
+ MDS->getContext (), FileAndScope, MDS->getName (), LinkageName,
363
+ FileAndScope, MDS->getLine (), Type, MDS->isLocalToUnit (),
364
+ MDS->isDefinition (), MDS->getScopeLine (), ContainingType,
365
+ MDS->getVirtuality (), MDS->getVirtualIndex (),
366
+ MDS->getThisAdjustment (), MDS->getFlags (), MDS->isOptimized (), Unit,
367
+ TemplateParams, Declaration, Variables);
368
+ };
369
+
370
+ if (MDS->isDistinct ())
371
+ return distinctMDSubprogram ();
372
+
373
+ auto *NewMDS = DISubprogram::get (
374
+ MDS->getContext (), FileAndScope, MDS->getName (), LinkageName,
375
+ FileAndScope, MDS->getLine (), Type, MDS->isLocalToUnit (),
376
+ MDS->isDefinition (), MDS->getScopeLine (), ContainingType,
377
+ MDS->getVirtuality (), MDS->getVirtualIndex (), MDS->getThisAdjustment (),
378
+ MDS->getFlags (), MDS->isOptimized (), Unit, TemplateParams, Declaration,
379
+ Variables);
380
+
381
+ StringRef OldLinkageName = MDS->getLinkageName ();
382
+
383
+ // See if we need to make a distinct one.
384
+ auto OrigLinkage = NewToLinkageName.find (NewMDS);
385
+ if (OrigLinkage != NewToLinkageName.end ()) {
386
+ if (OrigLinkage->second == OldLinkageName)
387
+ // We're good.
388
+ return NewMDS;
389
+
390
+ // Otherwise, need to make a distinct one.
391
+ // TODO: Query the map to see if we already have one.
392
+ return distinctMDSubprogram ();
393
+ }
394
+
395
+ NewToLinkageName.insert ({NewMDS, MDS->getLinkageName ()});
396
+ return NewMDS;
397
+ }
398
+
399
+ // / Create a new compile unit, to replace the one given
400
+ DICompileUnit *getReplacementCU (DICompileUnit *CU) {
401
+ // Drop skeleton CUs.
402
+ if (CU->getDWOId ())
403
+ return nullptr ;
404
+
405
+ auto *File = cast_or_null<DIFile>(map (CU->getFile ()));
406
+ MDTuple *EnumTypes = nullptr ;
407
+ MDTuple *RetainedTypes = nullptr ;
408
+ MDTuple *GlobalVariables = nullptr ;
409
+ MDTuple *ImportedEntities = nullptr ;
410
+ return DICompileUnit::getDistinct (
411
+ CU->getContext (), CU->getSourceLanguage (), File, CU->getProducer (),
412
+ CU->isOptimized (), CU->getFlags (), CU->getRuntimeVersion (),
413
+ CU->getSplitDebugFilename (), DICompileUnit::LineTablesOnly, EnumTypes,
414
+ RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros (),
415
+ CU->getDWOId (), CU->getSplitDebugInlining ());
416
+ }
417
+
418
+ DILocation *getReplacementMDLocation (DILocation *MLD) {
419
+ auto *Scope = map (MLD->getScope ());
420
+ auto *InlinedAt = map (MLD->getInlinedAt ());
421
+ if (MLD->isDistinct ())
422
+ return DILocation::getDistinct (MLD->getContext (), MLD->getLine (),
423
+ MLD->getColumn (), Scope, InlinedAt);
424
+ return DILocation::get (MLD->getContext (), MLD->getLine (), MLD->getColumn (),
425
+ Scope, InlinedAt);
426
+ }
427
+
428
+ // / Create a new generic MDNode, to replace the one given
429
+ MDNode *getReplacementMDNode (MDNode *N) {
430
+ SmallVector<Metadata *, 8 > Ops;
431
+ Ops.reserve (N->getNumOperands ());
432
+ for (auto &I : N->operands ())
433
+ if (I)
434
+ Ops.push_back (map (I));
435
+ auto *Ret = MDNode::get (N->getContext (), Ops);
436
+ return Ret;
437
+ }
438
+
439
+ // / Attempt to re-map N to a newly created node.
440
+ void remap (MDNode *N) {
441
+ if (Replacements.count (N))
442
+ return ;
443
+
444
+ auto doRemap = [&](MDNode *N) -> MDNode * {
445
+ if (!N)
446
+ return nullptr ;
447
+ if (auto *MDSub = dyn_cast<DISubprogram>(N)) {
448
+ remap (MDSub->getUnit ());
449
+ return getReplacementSubprogram (MDSub);
450
+ }
451
+ if (isa<DISubroutineType>(N))
452
+ return EmptySubroutineType;
453
+ if (auto *CU = dyn_cast<DICompileUnit>(N))
454
+ return getReplacementCU (CU);
455
+ if (isa<DIFile>(N))
456
+ return N;
457
+ if (auto *MDLB = dyn_cast<DILexicalBlockBase>(N))
458
+ // Remap to our referenced scope (recursively).
459
+ return mapNode (MDLB->getScope ());
460
+ if (auto *MLD = dyn_cast<DILocation>(N))
461
+ return getReplacementMDLocation (MLD);
462
+
463
+ // Otherwise, if we see these, just drop them now. Not strictly necessary,
464
+ // but this speeds things up a little.
465
+ if (isa<DINode>(N))
466
+ return nullptr ;
467
+
468
+ return getReplacementMDNode (N);
469
+ };
470
+ Replacements[N] = doRemap (N);
471
+ }
472
+
473
+ // / Do the remapping traversal.
474
+ void traverse (MDNode *);
475
+ };
476
+
477
+ } // Anonymous namespace.
478
+
479
+ void DebugTypeInfoRemoval::traverse (MDNode *N) {
480
+ if (!N || Replacements.count (N))
481
+ return ;
482
+
483
+ // To avoid cycles, as well as for efficiency sake, we will sometimes prune
484
+ // parts of the graph.
485
+ auto prune = [](MDNode *Parent, MDNode *Child) {
486
+ if (auto *MDS = dyn_cast<DISubprogram>(Parent))
487
+ return Child == MDS->getVariables ().get ();
488
+ return false ;
489
+ };
490
+
491
+ SmallVector<MDNode *, 16 > ToVisit;
492
+ DenseSet<MDNode *> Opened;
493
+
494
+ // Visit each node starting at N in post order, and map them.
495
+ ToVisit.push_back (N);
496
+ while (!ToVisit.empty ()) {
497
+ auto *N = ToVisit.back ();
498
+ if (!Opened.insert (N).second ) {
499
+ // Close it.
500
+ remap (N);
501
+ ToVisit.pop_back ();
502
+ continue ;
503
+ }
504
+ for (auto &I : N->operands ())
505
+ if (auto *MDN = dyn_cast_or_null<MDNode>(I))
506
+ if (!Opened.count (MDN) && !Replacements.count (MDN) && !prune (N, MDN) &&
507
+ !isa<DICompileUnit>(MDN))
508
+ ToVisit.push_back (MDN);
509
+ }
510
+ }
511
+
512
+ bool llvm::stripNonLineTableDebugInfo (Module &M) {
513
+ bool Changed = false ;
514
+
515
+ // First off, delete the debug intrinsics.
516
+ auto RemoveUses = [&](StringRef Name) {
517
+ if (auto *DbgVal = M.getFunction (Name)) {
518
+ while (!DbgVal->use_empty ())
519
+ cast<Instruction>(DbgVal->user_back ())->eraseFromParent ();
520
+ DbgVal->eraseFromParent ();
521
+ Changed = true ;
522
+ }
523
+ };
524
+ RemoveUses (" llvm.dbg.declare" );
525
+ RemoveUses (" llvm.dbg.value" );
526
+
527
+ // Delete non-CU debug info named metadata nodes.
528
+ for (auto NMI = M.named_metadata_begin (), NME = M.named_metadata_end ();
529
+ NMI != NME;) {
530
+ NamedMDNode *NMD = &*NMI;
531
+ ++NMI;
532
+ // Specifically keep dbg.cu around.
533
+ if (NMD->getName () == " llvm.dbg.cu" )
534
+ continue ;
535
+ }
536
+
537
+ // Drop all dbg attachments from global variables.
538
+ for (auto &GV : M.globals ())
539
+ GV.eraseMetadata (LLVMContext::MD_dbg);
540
+
541
+ DebugTypeInfoRemoval Mapper (M.getContext ());
542
+ auto remap = [&](llvm::MDNode *Node) -> llvm::MDNode * {
543
+ if (!Node)
544
+ return nullptr ;
545
+ Mapper.traverseAndRemap (Node);
546
+ auto *NewNode = Mapper.mapNode (Node);
547
+ Changed |= Node != NewNode;
548
+ Node = NewNode;
549
+ return NewNode;
550
+ };
551
+
552
+ // Rewrite the DebugLocs to be equivalent to what
553
+ // -gline-tables-only would have created.
554
+ for (auto &F : M) {
555
+ if (auto *SP = F.getSubprogram ()) {
556
+ Mapper.traverseAndRemap (SP);
557
+ auto *NewSP = cast<DISubprogram>(Mapper.mapNode (SP));
558
+ Changed |= SP != NewSP;
559
+ F.setSubprogram (NewSP);
560
+ }
561
+ for (auto &BB : F) {
562
+ for (auto &I : BB) {
563
+ if (I.getDebugLoc () == DebugLoc ())
564
+ continue ;
565
+
566
+ // Make a replacement.
567
+ auto &DL = I.getDebugLoc ();
568
+ auto *Scope = DL.getScope ();
569
+ MDNode *InlinedAt = DL.getInlinedAt ();
570
+ Scope = remap (Scope);
571
+ InlinedAt = remap (InlinedAt);
572
+ I.setDebugLoc (
573
+ DebugLoc::get (DL.getLine (), DL.getCol (), Scope, InlinedAt));
574
+ }
575
+ }
576
+ }
577
+
578
+ // Create a new llvm.dbg.cu, which is equivalent to the one
579
+ // -gline-tables-only would have created.
580
+ for (auto &NMD : M.getNamedMDList ()) {
581
+ SmallVector<MDNode *, 8 > Ops;
582
+ for (MDNode *Op : NMD.operands ())
583
+ Ops.push_back (remap (Op));
584
+
585
+ if (!Changed)
586
+ continue ;
587
+
588
+ NMD.clearOperands ();
589
+ for (auto *Op : Ops)
590
+ if (Op)
591
+ NMD.addOperand (Op);
592
+ }
593
+ return Changed;
594
+ }
595
+
303
596
unsigned llvm::getDebugMetadataVersionFromModule (const Module &M) {
304
597
if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
305
598
M.getModuleFlag (" Debug Info Version" )))
0 commit comments