aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2009-04-13 17:02:03 +0000
committerDevang Patel <dpatel@apple.com>2009-04-13 17:02:03 +0000
commit88bf96e5db9d7fa999ad190277610595540dc3e0 (patch)
tree79bed8c466e81f423ce51b124633991d975c5082
parent744d46240036334b2e15e53b4c3e2814141fca3d (diff)
downloadexternal_llvm-88bf96e5db9d7fa999ad190277610595540dc3e0.zip
external_llvm-88bf96e5db9d7fa999ad190277610595540dc3e0.tar.gz
external_llvm-88bf96e5db9d7fa999ad190277610595540dc3e0.tar.bz2
Reapply 68847.
Now debug_inlined section is covered by TAI->doesDwarfUsesInlineInfoSection(), which is false by default. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68964 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/DwarfWriter.h7
-rw-r--r--include/llvm/Target/TargetAsmInfo.h16
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp130
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp18
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp22
-rw-r--r--lib/Target/TargetAsmInfo.cpp2
-rw-r--r--lib/Target/X86/X86TargetAsmInfo.cpp2
7 files changed, 190 insertions, 7 deletions
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
index 8e82718..e7d9266 100644
--- a/include/llvm/CodeGen/DwarfWriter.h
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -94,6 +94,9 @@ public:
/// RecordRegionStart - Indicate the start of a region.
unsigned RecordRegionStart(GlobalVariable *V);
+ /// RecordRegionStart - Indicate the start of a region.
+ unsigned RecordRegionStart(GlobalVariable *V, unsigned ID);
+
/// RecordRegionEnd - Indicate the end of a region.
unsigned RecordRegionEnd(GlobalVariable *V);
@@ -107,6 +110,10 @@ public:
/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
/// be emitted.
bool ShouldEmitDwarfDebug() const;
+
+ //// RecordInlineInfo - Global variable GV is inlined at the location marked
+ //// by LabelID label.
+ void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID);
};
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index b871009..e493538 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -463,6 +463,10 @@ namespace llvm {
///
bool DwarfRequiresFrameSection; // Defaults to true.
+ /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to
+ /// encode inline subroutine information.
+ bool DwarfUsesInlineInfoSection; // Defaults to false.
+
/// SupportsMacInfo - true if the Dwarf output supports macro information
///
bool SupportsMacInfoSection; // Defaults to true
@@ -506,7 +510,11 @@ namespace llvm {
/// DwarfPubTypesSection - Section directive for Dwarf info.
///
const char *DwarfPubTypesSection; // Defaults to ".debug_pubtypes".
-
+
+ /// DwarfDebugInlineSection - Section directive for inline info.
+ ///
+ const char *DwarfDebugInlineSection; // Defaults to ".debug_inlined"
+
/// DwarfStrSection - Section directive for Dwarf info.
///
const char *DwarfStrSection; // Defaults to ".debug_str".
@@ -847,6 +855,9 @@ namespace llvm {
bool doesDwarfRequireFrameSection() const {
return DwarfRequiresFrameSection;
}
+ bool doesDwarfUsesInlineInfoSection() const {
+ return DwarfUsesInlineInfoSection;
+ }
bool doesSupportMacInfoSection() const {
return SupportsMacInfoSection;
}
@@ -880,6 +891,9 @@ namespace llvm {
const char *getDwarfPubTypesSection() const {
return DwarfPubTypesSection;
}
+ const char *getDwarfDebugInlineSection() const {
+ return DwarfDebugInlineSection;
+ }
const char *getDwarfStrSection() const {
return DwarfStrSection;
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index 4582f4a..c619bc5 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -1252,6 +1252,10 @@ class DwarfDebug : public Dwarf {
/// DbgScopeMap - Tracks the scopes in the current function.
DenseMap<GlobalVariable *, DbgScope *> DbgScopeMap;
+ /// InlineInfo - Keep track of inlined functions and their location.
+ /// This information is used to populate debug_inlined section.
+ DenseMap<GlobalVariable *, SmallVector<unsigned, 4> > InlineInfo;
+
/// DebugTimer - Timer for the Dwarf debug writer.
Timer *DebugTimer;
@@ -2027,15 +2031,18 @@ private:
for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
// Define the Scope debug information entry.
DbgScope *Scope = Scopes[j];
- // FIXME - Ignore inlined functions for the time being.
- if (!Scope->getParent()) continue;
unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
// Ignore empty scopes.
if (StartID == EndID && StartID != 0) continue;
- if (Scope->getScopes().empty() && Scope->getVariables().empty()) continue;
+
+ // Do not ignore inlined scope even if it is empty. Inlined scope
+ // does not have any parent.
+ if (Scope->getParent()
+ && Scope->getScopes().empty() && Scope->getVariables().empty())
+ continue;
if (StartID == ParentStartID && EndID == ParentEndID) {
// Just add stuff to the parent scope.
@@ -2781,6 +2788,77 @@ private:
}
}
+ /// EmitDebugInlineInfo - Emit inline info using following format.
+ /// Section Header:
+ /// 1. length of section
+ /// 2. Dwarf version number
+ /// 3. address size.
+ ///
+ /// Entries (one "entry" for each function that was inlined):
+ ///
+ /// 1. offset into __debug_str section for MIPS linkage name, if exists;
+ /// otherwise offset into __debug_str for regular function name.
+ /// 2. offset into __debug_str section for regular function name.
+ /// 3. an unsigned LEB128 number indicating the number of distinct inlining
+ /// instances for the function.
+ ///
+ /// The rest of the entry consists of a {die_offset, low_pc} pair for each
+ /// inlined instance; the die_offset points to the inlined_subroutine die in
+ /// the __debug_info section, and the low_pc is the starting address for the
+ /// inlining instance.
+ void EmitDebugInlineInfo() {
+ if (!TAI->doesDwarfUsesInlineInfoSection())
+ return;
+
+ if (!MainCU)
+ return;
+
+ Asm->SwitchToDataSection(TAI->getDwarfDebugInlineSection());
+ Asm->EOL();
+ EmitDifference("debug_inlined_end", 1,
+ "debug_inlined_begin", 1, true);
+ Asm->EOL("Length of Debug Inlined Information Entry");
+
+ EmitLabel("debug_inlined_begin", 1);
+
+ Asm->EmitInt16(DWARF_VERSION); Asm->EOL("Dwarf Version");
+ Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
+
+ for (DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator
+ I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) {
+ GlobalVariable *GV = I->first;
+ SmallVector<unsigned, 4> &Labels = I->second;
+ DISubprogram SP(GV);
+ std::string Name;
+ std::string LName;
+
+ SP.getLinkageName(LName);
+ SP.getName(Name);
+
+ Asm->EmitString(LName.empty() ? Name : LName);
+ Asm->EOL("MIPS linkage name");
+
+ Asm->EmitString(Name); Asm->EOL("Function name");
+
+ Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count");
+
+ for (SmallVector<unsigned, 4>::iterator LI = Labels.begin(),
+ LE = Labels.end(); LI != LE; ++LI) {
+ DIE *SP = MainCU->getDieMapSlotFor(GV);
+ Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset");
+
+ if (TD->getPointerSize() == sizeof(int32_t))
+ O << TAI->getData32bitsDirective();
+ else
+ O << TAI->getData64bitsDirective();
+ PrintLabelName("label", *LI); Asm->EOL("low_pc");
+ }
+ }
+
+ EmitLabel("debug_inlined_end", 1);
+ Asm->EOL();
+ }
+
/// GetOrCreateSourceID - Look up the source id with the given directory and
/// source file names. If none currently exists, create a new id and insert it
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
@@ -3131,6 +3209,9 @@ public:
// Emit info into a debug macinfo section.
EmitDebugMacInfo();
+ // Emit inline info.
+ EmitDebugInlineInfo();
+
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
}
@@ -3337,6 +3418,20 @@ public:
return ID;
}
+ /// RecordRegionStart - Indicate the start of a region.
+ unsigned RecordRegionStart(GlobalVariable *V, unsigned ID) {
+ if (TimePassesIsEnabled)
+ DebugTimer->startTimer();
+
+ DbgScope *Scope = getOrCreateScope(V);
+ if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID);
+
+ if (TimePassesIsEnabled)
+ DebugTimer->stopTimer();
+
+ return ID;
+ }
+
/// RecordRegionEnd - Indicate the end of a region.
unsigned RecordRegionEnd(GlobalVariable *V) {
if (TimePassesIsEnabled)
@@ -3377,6 +3472,23 @@ public:
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
}
+
+ //// RecordInlineInfo - Global variable GV is inlined at the location marked
+ //// by LabelID label.
+ void RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) {
+ MMI->RecordUsedDbgLabel(LabelID);
+ DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator
+ I = InlineInfo.find(GV);
+ if (I == InlineInfo.end()) {
+ SmallVector<unsigned, 4> Labels;
+ Labels.push_back(LabelID);
+ InlineInfo[GV] = Labels;
+ return;
+ }
+
+ SmallVector<unsigned, 4> &Labels = I->second;
+ Labels.push_back(LabelID);
+ }
};
//===----------------------------------------------------------------------===//
@@ -4535,6 +4647,11 @@ unsigned DwarfWriter::RecordRegionStart(GlobalVariable *V) {
return DD->RecordRegionStart(V);
}
+/// RecordRegionStart - Indicate the start of a region.
+unsigned DwarfWriter::RecordRegionStart(GlobalVariable *V, unsigned ID) {
+ return DD->RecordRegionStart(V, ID);
+}
+
/// RecordRegionEnd - Indicate the end of a region.
unsigned DwarfWriter::RecordRegionEnd(GlobalVariable *V) {
return DD->RecordRegionEnd(V);
@@ -4556,3 +4673,10 @@ void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex) {
bool DwarfWriter::ShouldEmitDwarfDebug() const {
return DD->ShouldEmitDwarfDebug();
}
+
+//// RecordInlineInfo - Global variable GV is inlined at the location marked
+//// by LabelID label.
+void DwarfWriter::RecordInlineInfo(GlobalVariable *GV, unsigned LabelID) {
+ DD->RecordInlineInfo(GV, LabelID);
+}
+
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 251e96a..cc425e5 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -377,11 +377,23 @@ bool FastISel::SelectCall(User *I) {
// Record the source line.
unsigned Line = Subprogram.getLineNumber();
- DW->RecordSourceLine(Line, 0, SrcFile);
+ unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
- // llvm.dbg.func_start also defines beginning of function scope.
- DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
+ std::string SPName;
+ Subprogram.getLinkageName(SPName);
+ if (!SPName.empty()
+ && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+ // This is a beginning of inlined function.
+ DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()),
+ LabelID);
+ const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
+ BuildMI(MBB, DL, II).addImm(LabelID);
+ DW->RecordInlineInfo(Subprogram.getGV(), LabelID);
+ } else {
+ // llvm.dbg.func_start also defines beginning of function scope.
+ DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
+ }
}
return true;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index effb215..b596643 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -3955,6 +3955,18 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
DwarfWriter *DW = DAG.getDwarfWriter();
DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
if (DW && DW->ValidDebugInfo(REI.getContext())) {
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ DISubprogram Subprogram(cast<GlobalVariable>(REI.getContext()));
+ std::string SPName;
+ Subprogram.getLinkageName(SPName);
+ if (!SPName.empty()
+ && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+ // This is end of inlined function. Debugging information for
+ // inlined function is not handled yet (only supported by FastISel).
+ return 0;
+ }
+
unsigned LabelID =
DW->RecordRegionEnd(cast<GlobalVariable>(REI.getContext()));
if (Fast)
@@ -3974,6 +3986,16 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
// what (most?) gdb expects.
MachineFunction &MF = DAG.getMachineFunction();
DISubprogram Subprogram(cast<GlobalVariable>(SP));
+
+ std::string SPName;
+ Subprogram.getLinkageName(SPName);
+ if (!SPName.empty()
+ && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+ // This is beginning of inlined function. Debugging information for
+ // inlined function is not handled yet (only supported by FastISel).
+ return 0;
+ }
+
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
std::string Dir, FN;
unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp
index 4d9ec33..6a2de6f 100644
--- a/lib/Target/TargetAsmInfo.cpp
+++ b/lib/Target/TargetAsmInfo.cpp
@@ -101,6 +101,7 @@ void TargetAsmInfo::fillDefaultValues() {
SupportsDebugInformation = false;
SupportsExceptionHandling = false;
DwarfRequiresFrameSection = true;
+ DwarfUsesInlineInfoSection = false;
SupportsMacInfoSection = true;
NonLocalEHFrameLabel = false;
GlobalEHDirective = 0;
@@ -112,6 +113,7 @@ void TargetAsmInfo::fillDefaultValues() {
DwarfFrameSection = ".debug_frame";
DwarfPubNamesSection = ".debug_pubnames";
DwarfPubTypesSection = ".debug_pubtypes";
+ DwarfDebugInlineSection = ".debug_inlined";
DwarfStrSection = ".debug_str";
DwarfLocSection = ".debug_loc";
DwarfARangesSection = ".debug_aranges";
diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp
index f1d97a3..5dda5f4 100644
--- a/lib/Target/X86/X86TargetAsmInfo.cpp
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp
@@ -112,6 +112,8 @@ X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM):
DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
+ DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug";
+ DwarfUsesInlineInfoSection = true;
DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";