forked from OSchip/llvm-project
Reapply 68847.
Now debug_inlined section is covered by TAI->doesDwarfUsesInlineInfoSection(), which is false by default. llvm-svn: 68964
This commit is contained in:
parent
4c7626e7b6
commit
80be3511ed
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue