From 93d39be5300702d8c9892ec04a492a6056926462 Mon Sep 17 00:00:00 2001
From: Devang Patel
Date: Fri, 19 Aug 2011 23:28:12 +0000
Subject: [PATCH] Do not use named md nodes to track variables that are
completely optimized. This does not scale while doing LTO with debug info.
New approach is to include list of variables in the subprogram info directly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138145 91177308-0d34-0410-b5e6-96231b3b80d8
---
docs/SourceLevelDebugging.html | 1 +
include/llvm/Analysis/DebugInfo.h | 6 +-
lib/Analysis/DIBuilder.cpp | 36 ++++++++---
lib/Analysis/DebugInfo.cpp | 44 ++++++++++++--
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 59 ++++++++-----------
test/CodeGen/ARM/debug-info-sreg2.ll | 4 +-
.../DebugInfo/2010-06-29-InlinedFnLocalVar.ll | 5 +-
7 files changed, 100 insertions(+), 55 deletions(-)
diff --git a/docs/SourceLevelDebugging.html b/docs/SourceLevelDebugging.html
index 1bf63959817..d5bdfe69c63 100644
--- a/docs/SourceLevelDebugging.html
+++ b/docs/SourceLevelDebugging.html
@@ -433,6 +433,7 @@ global variables are collected by named metadata !llvm.dbg.gv.
Function *,;; Pointer to LLVM function
metadata, ;; Lists function template parameters
metadata ;; Function declaration descriptor
+ metadata ;; List of function variables
}
diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h
index e17b41e2534..b0cf17afc00 100644
--- a/include/llvm/Analysis/DebugInfo.h
+++ b/include/llvm/Analysis/DebugInfo.h
@@ -558,6 +558,8 @@ namespace llvm {
DISubprogram getFunctionDeclaration() const {
return getFieldAs(18);
}
+ MDNode *getVariablesNodes() const;
+ DIArray getVariables() const;
};
/// DIGlobalVariable - This is a wrapper for a global variable.
@@ -736,11 +738,11 @@ namespace llvm {
/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
/// to hold function specific information.
- NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, StringRef Name);
+ NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
/// suitable to hold function specific information.
- NamedMDNode *getFnSpecificMDNode(const Module &M, StringRef Name);
+ NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
/// createInlinedVariable - Create a new inlined variable based on current
/// variable.
diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp
index 450412f421a..5311d6f10f0 100644
--- a/lib/Analysis/DIBuilder.cpp
+++ b/lib/Analysis/DIBuilder.cpp
@@ -43,6 +43,19 @@ void DIBuilder::finalize() {
DIArray SPs = getOrCreateArray(AllSubprograms);
DIType(TempSubprograms).replaceAllUsesWith(SPs);
+ for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
+ DISubprogram SP(SPs.getElement(i));
+ if (NamedMDNode *NMD = getFnSpecificMDNode(M, SP)) {
+ SmallVector Variables;
+ for (unsigned ii = 0, ee = NMD->getNumOperands(); ii != ee; ++ii)
+ Variables.push_back(NMD->getOperand(ii));
+ if (MDNode *Temp = SP.getVariablesNodes()) {
+ DIArray AV = getOrCreateArray(Variables);
+ DIType(Temp).replaceAllUsesWith(AV);
+ }
+ NMD->eraseFromParent();
+ }
+ }
DIArray GVs = getOrCreateArray(AllGVs);
DIType(TempGVs).replaceAllUsesWith(GVs);
@@ -674,13 +687,7 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
// to preserve variable info in such situation then stash it in a
// named mdnode.
DISubprogram Fn(getDISubprogram(Scope));
- StringRef FName = "fn";
- if (Fn.getFunction())
- FName = Fn.getFunction()->getName();
- char One = '\1';
- if (FName.startswith(StringRef(&One, 1)))
- FName = FName.substr(1);
- NamedMDNode *FnLocals = getOrInsertFnSpecificMDNode(M, FName);
+ NamedMDNode *FnLocals = getOrInsertFnSpecificMDNode(M, Fn);
FnLocals->addOperand(Node);
}
return DIVariable(Node);
@@ -718,6 +725,11 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context,
Function *Fn,
MDNode *TParams,
MDNode *Decl) {
+ Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
+ MDNode *Temp = MDNode::getTemporary(VMContext, TElts);
+ Value *TVElts[] = { Temp };
+ MDNode *THolder = MDNode::get(VMContext, TVElts);
+
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
@@ -737,7 +749,8 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context,
ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
Fn,
TParams,
- Decl
+ Decl,
+ THolder
};
MDNode *Node = MDNode::get(VMContext, Elts);
@@ -760,6 +773,11 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context,
bool isOptimized,
Function *Fn,
MDNode *TParam) {
+ Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
+ MDNode *Temp = MDNode::getTemporary(VMContext, TElts);
+ Value *TVElts[] = { Temp };
+ MDNode *THolder = MDNode::get(VMContext, TVElts);
+
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
@@ -779,6 +797,8 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context,
ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
Fn,
TParam,
+ llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
+ THolder
};
MDNode *Node = MDNode::get(VMContext, Elts);
return DISubprogram(Node);
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index e6ce9e4e74c..7935fadb2fa 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -512,6 +512,23 @@ unsigned DISubprogram::isOptimized() const {
return 0;
}
+MDNode *DISubprogram::getVariablesNodes() const {
+ if (!DbgNode || DbgNode->getNumOperands() <= 19)
+ return NULL;
+ if (MDNode *Temp = dyn_cast_or_null(DbgNode->getOperand(19)))
+ return dyn_cast_or_null(Temp->getOperand(0));
+ return NULL;
+}
+
+DIArray DISubprogram::getVariables() const {
+ if (!DbgNode || DbgNode->getNumOperands() <= 19)
+ return DIArray();
+ if (MDNode *T = dyn_cast_or_null(DbgNode->getOperand(19)))
+ if (MDNode *A = dyn_cast_or_null(T->getOperand(0)))
+ return DIArray(A);
+ return DIArray();
+}
+
StringRef DIScope::getFilename() const {
if (!DbgNode)
return StringRef();
@@ -825,19 +842,34 @@ static void fixupObjcLikeName(StringRef Str, SmallVectorImpl &Out) {
/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
/// suitable to hold function specific information.
-NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, StringRef FuncName) {
+NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) {
SmallString<32> Name = StringRef("llvm.dbg.lv.");
- fixupObjcLikeName(FuncName, Name);
-
+ StringRef FName = "fn";
+ if (Fn.getFunction())
+ FName = Fn.getFunction()->getName();
+ else
+ FName = Fn.getName();
+ char One = '\1';
+ if (FName.startswith(StringRef(&One, 1)))
+ FName = FName.substr(1);
+ fixupObjcLikeName(FName, Name);
return M.getNamedMetadata(Name.str());
}
/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
/// to hold function specific information.
-NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, StringRef FuncName) {
+NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) {
SmallString<32> Name = StringRef("llvm.dbg.lv.");
- fixupObjcLikeName(FuncName, Name);
-
+ StringRef FName = "fn";
+ if (Fn.getFunction())
+ FName = Fn.getFunction()->getName();
+ else
+ FName = Fn.getName();
+ char One = '\1';
+ if (FName.startswith(StringRef(&One, 1)))
+ FName = FName.substr(1);
+ fixupObjcLikeName(FName, Name);
+
return M.getOrInsertNamedMetadata(Name.str());
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 0a284fefaa7..ad16ac1004c 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -667,31 +667,24 @@ void DwarfDebug::endModule() {
if (ProcessedSPNodes.count(SP) != 0) continue;
if (!SP.Verify()) continue;
if (!SP.isDefinition()) continue;
- StringRef FName = SP.getLinkageName();
- if (FName.empty())
- FName = SP.getName();
- NamedMDNode *NMD = getFnSpecificMDNode(*(MMI->getModule()), FName);
- if (!NMD) continue;
- unsigned E = NMD->getNumOperands();
- if (!E) continue;
+ DIArray Variables = SP.getVariables();
+ if (Variables.getNumElements() == 0) continue;
+
LexicalScope *Scope =
new LexicalScope(NULL, DIDescriptor(SP), NULL, false);
DeadFnScopeMap[SP] = Scope;
// Construct subprogram DIE and add variables DIEs.
- SmallVector Variables;
- for (unsigned I = 0; I != E; ++I) {
- DIVariable DV(NMD->getOperand(I));
- if (!DV.Verify()) continue;
- Variables.push_back(DbgVariable(DV, NULL));
- }
CompileUnit *SPCU = CUMap.lookup(TheCU);
assert (SPCU && "Unable to find Compile Unit!");
constructSubprogramDIE(SPCU, SP);
DIE *ScopeDIE = SPCU->getDIE(SP);
- for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
+ for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) {
+ DIVariable DV(Variables.getElement(vi));
+ if (!DV.Verify()) continue;
+ DbgVariable *NewVar = new DbgVariable(DV, NULL);
if (DIE *VariableDIE =
- SPCU->constructVariableDIE(&Variables[i], Scope->isAbstractScope()))
+ SPCU->constructVariableDIE(NewVar, Scope->isAbstractScope()))
ScopeDIE->addChild(VariableDIE);
}
}
@@ -977,15 +970,14 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
}
// Collect info for variables that were optimized out.
- const Function *F = MF->getFunction();
- if (NamedMDNode *NMD = getFnSpecificMDNode(*(F->getParent()), F->getName())) {
- for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
- DIVariable DV(cast(NMD->getOperand(i)));
- if (!DV || !Processed.insert(DV))
- continue;
- if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
- addScopeVariable(Scope, new DbgVariable(DV, NULL));
- }
+ LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
+ DIArray Variables = DISubprogram(FnScope->getScopeNode()).getVariables();
+ for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) {
+ DIVariable DV(Variables.getElement(i));
+ if (!DV || !DV.Verify() || !Processed.insert(DV))
+ continue;
+ if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
+ addScopeVariable(Scope, new DbgVariable(DV, NULL));
}
}
@@ -1320,18 +1312,13 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
DISubprogram SP(AScope->getScopeNode());
if (SP.Verify()) {
// Collect info for variables that were optimized out.
- StringRef FName = SP.getLinkageName();
- if (FName.empty())
- FName = SP.getName();
- if (NamedMDNode *NMD =
- getFnSpecificMDNode(*(MF->getFunction()->getParent()), FName)) {
- for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
- DIVariable DV(cast(NMD->getOperand(i)));
- if (!DV || !ProcessedVars.insert(DV))
- continue;
- if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
- addScopeVariable(Scope, new DbgVariable(DV, NULL));
- }
+ DIArray Variables = SP.getVariables();
+ for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) {
+ DIVariable DV(Variables.getElement(i));
+ if (!DV || !DV.Verify() || !ProcessedVars.insert(DV))
+ continue;
+ if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
+ addScopeVariable(Scope, new DbgVariable(DV, NULL));
}
}
if (ProcessedSPNodes.count(AScope->getScopeNode()) == 0)
diff --git a/test/CodeGen/ARM/debug-info-sreg2.ll b/test/CodeGen/ARM/debug-info-sreg2.ll
index edafcfc80f2..ee777cec54c 100644
--- a/test/CodeGen/ARM/debug-info-sreg2.ll
+++ b/test/CodeGen/ARM/debug-info-sreg2.ll
@@ -6,8 +6,8 @@ target triple = "thumbv7-apple-macosx10.6.7"
;CHECK: Ldebug_loc0:
;CHECK-NEXT: .long Ltmp1
;CHECK-NEXT: .long Ltmp2
-;CHECK-NEXT: Lset9 = Ltmp10-Ltmp9 @ Loc expr size
-;CHECK-NEXT: .short Lset9
+;CHECK-NEXT: Lset8 = Ltmp10-Ltmp9 @ Loc expr size
+;CHECK-NEXT: .short Lset8
;CHECK-NEXT: Ltmp9:
;CHECK-NEXT: .byte 144 @ DW_OP_regx for S register
diff --git a/test/DebugInfo/2010-06-29-InlinedFnLocalVar.ll b/test/DebugInfo/2010-06-29-InlinedFnLocalVar.ll
index 1d67cb44da6..001e9389cca 100644
--- a/test/DebugInfo/2010-06-29-InlinedFnLocalVar.ll
+++ b/test/DebugInfo/2010-06-29-InlinedFnLocalVar.ll
@@ -26,7 +26,7 @@ entry:
!llvm.dbg.lv.foo = !{!9, !10}
!llvm.dbg.gv = !{!16}
-!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 9, metadata !3, i1 true, i1 true, i32 0, i32 0, null, i1 false, i1 true, null} ; [ DW_TAG_subprogram ]
+!0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"", metadata !1, i32 9, metadata !3, i1 true, i1 true, i32 0, i32 0, null, i1 false, i1 true, null, null, null, metadata !24} ; [ DW_TAG_subprogram ]
!1 = metadata !{i32 524329, metadata !"bar.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ]
!2 = metadata !{i32 524305, i32 0, i32 1, metadata !"bar.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
!3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
@@ -50,3 +50,6 @@ entry:
!21 = metadata !{i32 9, i32 0, metadata !11, metadata !17}
!22 = metadata !{i32 11, i32 0, metadata !11, metadata !17}
!23 = metadata !{i32 16, i32 0, metadata !18, null}
+!24 = metadata !{metadata !25}
+!25 = metadata !{metadata !9, metadata !10}
+