32 using namespace llvm::dwarf;
35 if (
auto *LocalScope = dyn_cast_or_null<DILocalScope>(Scope))
56 for (
auto DIG : CU->getGlobalVariables()) {
57 if (!addGlobalVariable(DIG))
59 auto *GV = DIG->getVariable();
60 processScope(GV->getScope());
61 processType(GV->getType().resolve());
63 for (
auto *ET : CU->getEnumTypes())
65 for (
auto *RT : CU->getRetainedTypes())
66 if (
auto *
T = dyn_cast<DIType>(RT))
69 processSubprogram(cast<DISubprogram>(RT));
70 for (
auto *
Import : CU->getImportedEntities()) {
71 auto *Entity =
Import->getEntity().resolve();
72 if (
auto *
T = dyn_cast<DIType>(Entity))
74 else if (
auto *SP = dyn_cast<DISubprogram>(Entity))
75 processSubprogram(SP);
76 else if (
auto *NS = dyn_cast<DINamespace>(Entity))
77 processScope(NS->getScope());
78 else if (
auto *M = dyn_cast<DIModule>(Entity))
79 processScope(M->getScope());
83 if (
auto *SP = cast_or_null<DISubprogram>(
F.getSubprogram()))
84 processSubprogram(SP);
90 processScope(Loc->getScope());
91 processLocation(M, Loc->getInlinedAt());
94 void DebugInfoFinder::processType(
DIType *DT) {
98 if (
auto *
ST = dyn_cast<DISubroutineType>(DT)) {
100 processType(Ref.resolve());
103 if (
auto *DCT = dyn_cast<DICompositeType>(DT)) {
104 processType(DCT->getBaseType().resolve());
106 if (
auto *
T = dyn_cast<DIType>(
D))
108 else if (
auto *SP = dyn_cast<DISubprogram>(
D))
109 processSubprogram(SP);
113 if (
auto *DDT = dyn_cast<DIDerivedType>(DT)) {
114 processType(DDT->getBaseType().resolve());
118 void DebugInfoFinder::processScope(
DIScope *Scope) {
121 if (
auto *Ty = dyn_cast<DIType>(Scope)) {
125 if (
auto *CU = dyn_cast<DICompileUnit>(Scope)) {
129 if (
auto *SP = dyn_cast<DISubprogram>(Scope)) {
130 processSubprogram(SP);
133 if (!addScope(Scope))
135 if (
auto *LB = dyn_cast<DILexicalBlockBase>(Scope)) {
136 processScope(LB->getScope());
137 }
else if (
auto *NS = dyn_cast<DINamespace>(Scope)) {
138 processScope(NS->getScope());
139 }
else if (
auto *M = dyn_cast<DIModule>(Scope)) {
140 processScope(M->getScope());
144 void DebugInfoFinder::processSubprogram(
DISubprogram *SP) {
145 if (!addSubprogram(SP))
148 processType(SP->getType());
149 for (
auto *Element : SP->getTemplateParams()) {
150 if (
auto *TType = dyn_cast<DITemplateTypeParameter>(Element)) {
151 processType(TType->getType().resolve());
152 }
else if (
auto *TVal = dyn_cast<DITemplateValueParameter>(Element)) {
153 processType(TVal->getType().resolve());
168 if (!NodesSeen.insert(DV).second)
170 processScope(DV->getScope());
171 processType(DV->getType().resolve());
183 if (!NodesSeen.insert(DV).second)
185 processScope(DV->getScope());
186 processType(DV->getType().resolve());
189 bool DebugInfoFinder::addType(
DIType *DT) {
193 if (!NodesSeen.insert(DT).second)
196 TYs.push_back(const_cast<DIType *>(DT));
203 if (!NodesSeen.insert(CU).second)
211 if (!NodesSeen.insert(DIG).second)
222 if (!NodesSeen.insert(SP).second)
229 bool DebugInfoFinder::addScope(
DIScope *Scope) {
236 if (!NodesSeen.insert(Scope).second)
238 Scopes.push_back(Scope);
243 bool Changed =
false;
250 for (
auto II = BB.begin(),
End = BB.end(); II !=
End;) {
252 if (isa<DbgInfoIntrinsic>(&I)) {
267 bool Changed =
false;
277 NMD->
getName() ==
"llvm.gcov") {
286 for (
auto &GV : M.globals()) {
296 Materializer->setStripDebugInfo();
304 class DebugTypeInfoRemoval {
309 MDNode *EmptySubroutineType;
333 auto Replacement = Replacements.find(M);
334 if (Replacement != Replacements.end())
335 return Replacement->second;
339 MDNode *mapNode(
Metadata *
N) {
return dyn_cast_or_null<MDNode>(map(N)); }
343 void traverseAndRemap(
MDNode *
N) { traverse(N); }
348 auto *FileAndScope = cast_or_null<DIFile>(map(MDS->
getFile()));
351 auto *
Type = cast_or_null<DISubroutineType>(map(MDS->getType()));
352 DITypeRef ContainingType(map(MDS->getContainingType()));
353 auto *
Unit = cast_or_null<DICompileUnit>(map(MDS->getUnit()));
354 auto Variables =
nullptr;
355 auto TemplateParams =
nullptr;
358 auto distinctMDSubprogram = [&]() {
361 FileAndScope, MDS->getLine(),
Type, MDS->isLocalToUnit(),
362 MDS->isDefinition(), MDS->getScopeLine(), ContainingType,
363 MDS->getVirtuality(), MDS->getVirtualIndex(),
364 MDS->getThisAdjustment(), MDS->getFlags(), MDS->isOptimized(),
Unit,
365 TemplateParams, Declaration, Variables);
369 return distinctMDSubprogram();
373 FileAndScope, MDS->getLine(),
Type, MDS->isLocalToUnit(),
374 MDS->isDefinition(), MDS->getScopeLine(), ContainingType,
375 MDS->getVirtuality(), MDS->getVirtualIndex(), MDS->getThisAdjustment(),
376 MDS->getFlags(), MDS->isOptimized(),
Unit, TemplateParams, Declaration,
379 StringRef OldLinkageName = MDS->getLinkageName();
382 auto OrigLinkage = NewToLinkageName.find(NewMDS);
383 if (OrigLinkage != NewToLinkageName.end()) {
384 if (OrigLinkage->second == OldLinkageName)
390 return distinctMDSubprogram();
393 NewToLinkageName.insert({NewMDS, MDS->getLinkageName()});
403 auto *
File = cast_or_null<DIFile>(map(CU->
getFile()));
405 MDTuple *RetainedTypes =
nullptr;
406 MDTuple *GlobalVariables =
nullptr;
407 MDTuple *ImportedEntities =
nullptr;
412 RetainedTypes, GlobalVariables, ImportedEntities, CU->
getMacros(),
417 auto *Scope = map(MLD->getScope());
418 auto *InlinedAt = map(MLD->getInlinedAt());
421 MLD->getColumn(), Scope, InlinedAt);
439 if (Replacements.count(N))
445 if (
auto *MDSub = dyn_cast<DISubprogram>(N)) {
446 remap(MDSub->getUnit());
447 return getReplacementSubprogram(MDSub);
449 if (isa<DISubroutineType>(N))
450 return EmptySubroutineType;
451 if (
auto *CU = dyn_cast<DICompileUnit>(N))
452 return getReplacementCU(CU);
455 if (
auto *MDLB = dyn_cast<DILexicalBlockBase>(N))
457 return mapNode(MDLB->getScope());
458 if (
auto *MLD = dyn_cast<DILocation>(N))
459 return getReplacementMDLocation(MLD);
466 return getReplacementMDNode(N);
468 Replacements[
N] = doRemap(N);
477 void DebugTypeInfoRemoval::traverse(
MDNode *N) {
478 if (!N || Replacements.count(N))
484 if (
auto *MDS = dyn_cast<DISubprogram>(Parent))
485 return Child == MDS->getVariables().
get();
494 while (!ToVisit.
empty()) {
495 auto *N = ToVisit.
back();
496 if (!Opened.
insert(N).second) {
503 if (
auto *MDN = dyn_cast_or_null<MDNode>(
I))
504 if (!Opened.
count(MDN) && !Replacements.count(MDN) && !prune(N, MDN) &&
505 !isa<DICompileUnit>(MDN))
511 bool Changed =
false;
516 while (!DbgVal->use_empty())
517 cast<Instruction>(DbgVal->user_back())->eraseFromParent();
518 DbgVal->eraseFromParent();
522 RemoveUses(
"llvm.dbg.declare");
523 RemoveUses(
"llvm.dbg.value");
531 if (NMD->
getName() ==
"llvm.dbg.cu")
543 Mapper.traverseAndRemap(Node);
544 auto *NewNode = Mapper.mapNode(Node);
545 Changed |= Node != NewNode;
553 if (
auto *SP =
F.getSubprogram()) {
554 Mapper.traverseAndRemap(SP);
555 auto *NewSP = cast<DISubprogram>(Mapper.mapNode(SP));
556 Changed |= SP != NewSP;
557 F.setSubprogram(NewSP);
565 auto &DL =
I.getDebugLoc();
566 auto *Scope = DL.getScope();
567 MDNode *InlinedAt = DL.getInlinedAt();
568 Scope = remap(Scope);
569 InlinedAt = remap(InlinedAt);
578 for (
auto &NMD : M.getNamedMDList()) {
595 if (
auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
597 return Val->getZExtValue();
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
StringRef getName() const
void push_back(const T &Elt)
void processLocation(const Module &M, const DILocation *Loc)
Process debug info location.
A Module instance is used to store all the information related to an LLVM module. ...
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
StringRef getFlags() const
Implements a dense probed hash-table based set.
unsigned getNumOperands() const
Return number of MDNode operands.
named_metadata_iterator named_metadata_end()
unsigned getDebugMetadataVersionFromModule(const Module &M)
Return Debug Info Metadata Version by checking module flags.
void reset()
Clear all lists.
bool getSplitDebugInlining() const
bool stripDebugInfo(Function &F)
void reserve(size_type N)
void processModule(const Module &M)
Process entire module and collect debug info anchors.
Tagged DWARF-like metadata node.
uint64_t getDWOId() const
DILocation * get() const
Get the underlying DILocation.
void eraseFromParent()
Drop all references and remove the node from parent module.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
bool stripNonLineTableDebugInfo(Module &M)
Downgrade the debug info in a module to contain only line table information.
Holds a subclass of DINode.
DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
LLVM_NODISCARD bool empty() const
iterator_range< debug_compile_units_iterator > debug_compile_units() const
Return an iterator for all DICompileUnits listed in this Module's llvm.dbg.cu named metadata node and...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
DIScopeRef getScope() const
DIScopeRef getScope() const
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
unsigned getRuntimeVersion() const
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
iterator_range< iterator > functions()
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
StringRef getName() const
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(const ValueT &V)
unsigned getSourceLanguage() const
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
A pair of DIGlobalVariable and DIExpression.
static const unsigned End
DIMacroNodeArray getMacros() const
void processValue(const Module &M, const DbgValueInst *DVI)
Process DbgValueInst.
Base class for scope-like contexts.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Iterator for intrusive lists based on ilist_node.
Import typeid resolutions from summary and globals.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Type array for a subprogram.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
size_type count(const ValueT &V) const
Return 1 if the specified key is in the set, 0 otherwise.
This represents the llvm.dbg.value instruction.
void processDeclare(const Module &M, const DbgDeclareInst *DDI)
Process DbgDeclareInst.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
op_range operands() const
LLVMContext & getContext() const
std::vector< uint8_t > Unit
DILocalVariable * getVariable() const
DILocalVariable * getVariable() const
iterator_range< global_iterator > globals()
StringRef - Represent a constant reference to a string, i.e.
DISubprogram * getSubprogram() const
Get the subprogram for this scope.
This represents the llvm.dbg.declare instruction.
StringRef getProducer() const
named_metadata_iterator named_metadata_begin()
LLVMContext & getContext() const
Get the global data context.
StringRef getSplitDebugFilename() const