summaryrefslogtreecommitdiff
path: root/lib/IR/DebugInfo.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:01:22 +0000
commit71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch)
tree5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/IR/DebugInfo.cpp
parent31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff)
downloadsrc-test2-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.tar.gz
src-test2-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.zip
Notes
Diffstat (limited to 'lib/IR/DebugInfo.cpp')
-rw-r--r--lib/IR/DebugInfo.cpp88
1 files changed, 75 insertions, 13 deletions
diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp
index 6b9bc689a446..c5d39c544304 100644
--- a/lib/IR/DebugInfo.cpp
+++ b/lib/IR/DebugInfo.cpp
@@ -79,9 +79,19 @@ void DebugInfoFinder::processModule(const Module &M) {
processScope(M->getScope());
}
}
- for (auto &F : M.functions())
+ for (auto &F : M.functions()) {
if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
processSubprogram(SP);
+ // There could be subprograms from inlined functions referenced from
+ // instructions only. Walk the function to find them.
+ for (const BasicBlock &BB : F) {
+ for (const Instruction &I : BB) {
+ if (!I.getDebugLoc())
+ continue;
+ processLocation(M, I.getDebugLoc().get());
+ }
+ }
+ }
}
void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
@@ -239,6 +249,38 @@ bool DebugInfoFinder::addScope(DIScope *Scope) {
return true;
}
+static llvm::MDNode *stripDebugLocFromLoopID(llvm::MDNode *N) {
+ assert(N->op_begin() != N->op_end() && "Missing self reference?");
+
+ // if there is no debug location, we do not have to rewrite this MDNode.
+ if (std::none_of(N->op_begin() + 1, N->op_end(), [](const MDOperand &Op) {
+ return isa<DILocation>(Op.get());
+ }))
+ return N;
+
+ // If there is only the debug location without any actual loop metadata, we
+ // can remove the metadata.
+ if (std::none_of(N->op_begin() + 1, N->op_end(), [](const MDOperand &Op) {
+ return !isa<DILocation>(Op.get());
+ }))
+ return nullptr;
+
+ SmallVector<Metadata *, 4> Args;
+ // Reserve operand 0 for loop id self reference.
+ auto TempNode = MDNode::getTemporary(N->getContext(), None);
+ Args.push_back(TempNode.get());
+ // Add all non-debug location operands back.
+ for (auto Op = N->op_begin() + 1; Op != N->op_end(); Op++) {
+ if (!isa<DILocation>(*Op))
+ Args.push_back(*Op);
+ }
+
+ // Set the first operand to itself.
+ MDNode *LoopID = MDNode::get(N->getContext(), Args);
+ LoopID->replaceOperandWith(0, LoopID);
+ return LoopID;
+}
+
bool llvm::stripDebugInfo(Function &F) {
bool Changed = false;
if (F.getSubprogram()) {
@@ -246,6 +288,7 @@ bool llvm::stripDebugInfo(Function &F) {
F.setSubprogram(nullptr);
}
+ llvm::DenseMap<llvm::MDNode*, llvm::MDNode*> LoopIDsMap;
for (BasicBlock &BB : F) {
for (auto II = BB.begin(), End = BB.end(); II != End;) {
Instruction &I = *II++; // We may delete the instruction, increment now.
@@ -259,6 +302,15 @@ bool llvm::stripDebugInfo(Function &F) {
I.setDebugLoc(DebugLoc());
}
}
+
+ auto *TermInst = BB.getTerminator();
+ if (auto *LoopID = TermInst->getMetadata(LLVMContext::MD_loop)) {
+ auto *NewLoopID = LoopIDsMap.lookup(LoopID);
+ if (!NewLoopID)
+ NewLoopID = LoopIDsMap[LoopID] = stripDebugLocFromLoopID(LoopID);
+ if (NewLoopID != LoopID)
+ TermInst->setMetadata(LLVMContext::MD_loop, NewLoopID);
+ }
}
return Changed;
}
@@ -410,7 +462,8 @@ private:
CU->isOptimized(), CU->getFlags(), CU->getRuntimeVersion(),
CU->getSplitDebugFilename(), DICompileUnit::LineTablesOnly, EnumTypes,
RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros(),
- CU->getDWOId(), CU->getSplitDebugInlining());
+ CU->getDWOId(), CU->getSplitDebugInlining(),
+ CU->getDebugInfoForProfiling());
}
DILocation *getReplacementMDLocation(DILocation *MLD) {
@@ -558,17 +611,26 @@ bool llvm::stripNonLineTableDebugInfo(Module &M) {
}
for (auto &BB : F) {
for (auto &I : BB) {
- if (I.getDebugLoc() == DebugLoc())
- continue;
-
- // Make a replacement.
- auto &DL = I.getDebugLoc();
- auto *Scope = DL.getScope();
- MDNode *InlinedAt = DL.getInlinedAt();
- Scope = remap(Scope);
- InlinedAt = remap(InlinedAt);
- I.setDebugLoc(
- DebugLoc::get(DL.getLine(), DL.getCol(), Scope, InlinedAt));
+ auto remapDebugLoc = [&](DebugLoc DL) -> DebugLoc {
+ auto *Scope = DL.getScope();
+ MDNode *InlinedAt = DL.getInlinedAt();
+ Scope = remap(Scope);
+ InlinedAt = remap(InlinedAt);
+ return DebugLoc::get(DL.getLine(), DL.getCol(), Scope, InlinedAt);
+ };
+
+ if (I.getDebugLoc() != DebugLoc())
+ I.setDebugLoc(remapDebugLoc(I.getDebugLoc()));
+
+ // Remap DILocations in untyped MDNodes (e.g., llvm.loop).
+ SmallVector<std::pair<unsigned, MDNode *>, 2> MDs;
+ I.getAllMetadata(MDs);
+ for (auto Attachment : MDs)
+ if (auto *T = dyn_cast_or_null<MDTuple>(Attachment.second))
+ for (unsigned N = 0; N < T->getNumOperands(); ++N)
+ if (auto *Loc = dyn_cast_or_null<DILocation>(T->getOperand(N)))
+ if (Loc != DebugLoc())
+ T->replaceOperandWith(N, remapDebugLoc(Loc));
}
}
}