mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-13 00:10:37 +00:00
MCDwarf: Refactor line table handling into a single data structure
This replaces several "compile unit ID -> thing" mappings in favor of one mapping from CUID to the whole line table structure (files, directories, and lines). This is another step along the way to refactoring out reusable components of line table handling for use when generating debug_line.dwo for fission type units. Also, might be a good basis to fold some of this handling down into MCStreamers to avoid the special case of "One line table when doing asm printing, line table per CU otherwise" by building it into the different MCStreamer implementations. llvm-svn: 203821
This commit is contained in:
parent
c33b600343
commit
7cff204c6a
@ -108,9 +108,7 @@ namespace llvm {
|
|||||||
/// We now emit a line table for each compile unit. To reduce the prologue
|
/// We now emit a line table for each compile unit. To reduce the prologue
|
||||||
/// size of each line table, the files and directories used by each compile
|
/// size of each line table, the files and directories used by each compile
|
||||||
/// unit are separated.
|
/// unit are separated.
|
||||||
typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap;
|
std::map<unsigned, MCDwarfFileTable> MCDwarfFileTablesCUMap;
|
||||||
MCDwarfFilesMap MCDwarfFilesCUMap;
|
|
||||||
std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap;
|
|
||||||
|
|
||||||
/// The current dwarf line information from the last dwarf .loc directive.
|
/// The current dwarf line information from the last dwarf .loc directive.
|
||||||
MCDwarfLoc CurrentDwarfLoc;
|
MCDwarfLoc CurrentDwarfLoc;
|
||||||
@ -146,13 +144,8 @@ namespace llvm {
|
|||||||
/// Darwin).
|
/// Darwin).
|
||||||
bool AllowTemporaryLabels;
|
bool AllowTemporaryLabels;
|
||||||
|
|
||||||
/// The dwarf line information from the .loc directives for the sections
|
|
||||||
/// with assembled machine instructions have after seeing .loc directives.
|
|
||||||
std::map<unsigned, MCLineSection> MCLineSections;
|
|
||||||
/// The Compile Unit ID that we are currently processing.
|
/// The Compile Unit ID that we are currently processing.
|
||||||
unsigned DwarfCompileUnitID;
|
unsigned DwarfCompileUnitID;
|
||||||
/// The line table start symbol for each Compile Unit.
|
|
||||||
DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;
|
|
||||||
|
|
||||||
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
|
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
|
||||||
|
|
||||||
@ -298,26 +291,38 @@ namespace llvm {
|
|||||||
|
|
||||||
bool hasDwarfFiles() const {
|
bool hasDwarfFiles() const {
|
||||||
// Traverse MCDwarfFilesCUMap and check whether each entry is empty.
|
// Traverse MCDwarfFilesCUMap and check whether each entry is empty.
|
||||||
MCDwarfFilesMap::const_iterator MapB, MapE;
|
for (const auto &FileTable : MCDwarfFileTablesCUMap)
|
||||||
for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end();
|
if (!FileTable.second.getMCDwarfFiles().empty())
|
||||||
MapB != MapE; MapB++)
|
|
||||||
if (!MapB->second.empty())
|
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
|
const std::map<unsigned, MCDwarfFileTable> &getMCDwarfFileTables() const {
|
||||||
return MCDwarfFilesCUMap[CUID];
|
return MCDwarfFileTablesCUMap;
|
||||||
}
|
|
||||||
const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
|
|
||||||
return MCDwarfDirsCUMap[CUID];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<unsigned, MCLineSection> &getMCLineSections() const {
|
MCDwarfFileTable &getMCDwarfFileTable(unsigned CUID) {
|
||||||
return MCLineSections;
|
return MCDwarfFileTablesCUMap[CUID];
|
||||||
}
|
}
|
||||||
std::map<unsigned, MCLineSection> &getMCLineSections() {
|
|
||||||
return MCLineSections;
|
const MCDwarfFileTable &getMCDwarfFileTable(unsigned CUID) const {
|
||||||
|
auto I = MCDwarfFileTablesCUMap.find(CUID);
|
||||||
|
assert(I != MCDwarfFileTablesCUMap.end());
|
||||||
|
return I->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
|
||||||
|
return getMCDwarfFileTable(CUID).getMCDwarfFiles();
|
||||||
|
}
|
||||||
|
const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
|
||||||
|
return getMCDwarfFileTable(CUID).getMCDwarfDirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasMCLineSections() const {
|
||||||
|
for (const auto &Table : MCDwarfFileTablesCUMap)
|
||||||
|
if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
unsigned getDwarfCompileUnitID() {
|
unsigned getDwarfCompileUnitID() {
|
||||||
return DwarfCompileUnitID;
|
return DwarfCompileUnitID;
|
||||||
@ -325,18 +330,11 @@ namespace llvm {
|
|||||||
void setDwarfCompileUnitID(unsigned CUIndex) {
|
void setDwarfCompileUnitID(unsigned CUIndex) {
|
||||||
DwarfCompileUnitID = CUIndex;
|
DwarfCompileUnitID = CUIndex;
|
||||||
}
|
}
|
||||||
const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const {
|
|
||||||
return MCLineTableSymbols;
|
|
||||||
}
|
|
||||||
MCSymbol *getMCLineTableSymbol(unsigned ID) const {
|
MCSymbol *getMCLineTableSymbol(unsigned ID) const {
|
||||||
DenseMap<unsigned, MCSymbol *>::const_iterator CIter =
|
return getMCDwarfFileTable(ID).getLabel();
|
||||||
MCLineTableSymbols.find(ID);
|
|
||||||
if (CIter == MCLineTableSymbols.end())
|
|
||||||
return NULL;
|
|
||||||
return CIter->second;
|
|
||||||
}
|
}
|
||||||
void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
|
void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
|
||||||
MCLineTableSymbols[ID] = Sym;
|
getMCDwarfFileTable(ID).setLabel(Sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setCurrentDwarfLoc - saves the information from the currently parsed
|
/// setCurrentDwarfLoc - saves the information from the currently parsed
|
||||||
|
@ -200,6 +200,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class MCDwarfFileTable {
|
class MCDwarfFileTable {
|
||||||
|
MCSymbol *Label;
|
||||||
|
SmallVector<StringRef, 3> MCDwarfDirs;
|
||||||
|
SmallVector<MCDwarfFile *, 3> MCDwarfFiles;
|
||||||
|
MCLineSection MCLineSections;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//
|
//
|
||||||
// This emits the Dwarf file and the line tables for all Compile Units.
|
// This emits the Dwarf file and the line tables for all Compile Units.
|
||||||
@ -208,7 +213,38 @@ public:
|
|||||||
//
|
//
|
||||||
// This emits the Dwarf file and the line tables for a given Compile Unit.
|
// This emits the Dwarf file and the line tables for a given Compile Unit.
|
||||||
//
|
//
|
||||||
static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
|
const MCSymbol *EmitCU(MCStreamer *MCOS) const;
|
||||||
|
|
||||||
|
const SmallVectorImpl<StringRef> &getMCDwarfDirs() const {
|
||||||
|
return MCDwarfDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallVectorImpl<StringRef> &getMCDwarfDirs() {
|
||||||
|
return MCDwarfDirs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles() const {
|
||||||
|
return MCDwarfFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles() {
|
||||||
|
return MCDwarfFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MCLineSection &getMCLineSections() const {
|
||||||
|
return MCLineSections;
|
||||||
|
}
|
||||||
|
MCLineSection &getMCLineSections() {
|
||||||
|
return MCLineSections;
|
||||||
|
}
|
||||||
|
|
||||||
|
MCSymbol *getLabel() const {
|
||||||
|
return Label;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLabel(MCSymbol *Label) {
|
||||||
|
this->Label = Label;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MCDwarfLineAddr {
|
class MCDwarfLineAddr {
|
||||||
|
@ -84,13 +84,10 @@ void MCContext::reset() {
|
|||||||
Symbols.clear();
|
Symbols.clear();
|
||||||
Allocator.Reset();
|
Allocator.Reset();
|
||||||
Instances.clear();
|
Instances.clear();
|
||||||
MCDwarfFilesCUMap.clear();
|
MCDwarfFileTablesCUMap.clear();
|
||||||
MCDwarfDirsCUMap.clear();
|
|
||||||
MCGenDwarfLabelEntries.clear();
|
MCGenDwarfLabelEntries.clear();
|
||||||
DwarfDebugFlags = StringRef();
|
DwarfDebugFlags = StringRef();
|
||||||
MCLineSections.clear();
|
|
||||||
DwarfCompileUnitID = 0;
|
DwarfCompileUnitID = 0;
|
||||||
MCLineTableSymbols.clear();
|
|
||||||
CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
|
CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
|
||||||
|
|
||||||
// If we have the MachO uniquing map, free it.
|
// If we have the MachO uniquing map, free it.
|
||||||
@ -337,8 +334,9 @@ unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
|
|||||||
// Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
|
// Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
|
||||||
// to not be less than one. This needs to be change to be not less than zero.
|
// to not be less than one. This needs to be change to be not less than zero.
|
||||||
|
|
||||||
SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
|
MCDwarfFileTable &Table = MCDwarfFileTablesCUMap[CUID];
|
||||||
SmallVectorImpl<StringRef>& MCDwarfDirs = MCDwarfDirsCUMap[CUID];
|
SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = Table.getMCDwarfFiles();
|
||||||
|
SmallVectorImpl<StringRef>& MCDwarfDirs = Table.getMCDwarfDirs();
|
||||||
// Make space for this FileNumber in the MCDwarfFiles vector if needed.
|
// Make space for this FileNumber in the MCDwarfFiles vector if needed.
|
||||||
if (FileNumber >= MCDwarfFiles.size()) {
|
if (FileNumber >= MCDwarfFiles.size()) {
|
||||||
MCDwarfFiles.resize(FileNumber + 1);
|
MCDwarfFiles.resize(FileNumber + 1);
|
||||||
@ -399,7 +397,7 @@ unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
|
|||||||
/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
|
/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
|
||||||
/// currently is assigned and false otherwise.
|
/// currently is assigned and false otherwise.
|
||||||
bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
|
bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
|
||||||
SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
|
const SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = getMCDwarfFiles(CUID);
|
||||||
if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
|
if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -82,7 +82,8 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
|
|||||||
|
|
||||||
// Add the line entry to this section's entries.
|
// Add the line entry to this section's entries.
|
||||||
MCOS->getContext()
|
MCOS->getContext()
|
||||||
.getMCLineSections()[MCOS->getContext().getDwarfCompileUnitID()]
|
.getMCDwarfFileTable(MCOS->getContext().getDwarfCompileUnitID())
|
||||||
|
.getMCLineSections()
|
||||||
.addLineEntry(LineEntry, Section);
|
.addLineEntry(LineEntry, Section);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,27 +206,31 @@ EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section,
|
|||||||
//
|
//
|
||||||
const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
|
const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
|
||||||
MCContext &context = MCOS->getContext();
|
MCContext &context = MCOS->getContext();
|
||||||
// Switch to the section where the table will be emitted into.
|
|
||||||
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
|
|
||||||
|
|
||||||
const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols =
|
|
||||||
MCOS->getContext().getMCLineTableSymbols();
|
|
||||||
// CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
|
// CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
|
||||||
// not exist, CUID will be 0 and MCLineTableSymbols will be empty.
|
// not exist, CUID will be 0 and MCLineTableSymbols will be empty.
|
||||||
// Handle Compile Unit 0, the line table start symbol is the section symbol.
|
// Handle Compile Unit 0, the line table start symbol is the section symbol.
|
||||||
const MCSymbol *LineStartSym = EmitCU(MCOS, 0);
|
auto I = MCOS->getContext().getMCDwarfFileTables().begin(),
|
||||||
|
E = MCOS->getContext().getMCDwarfFileTables().end();
|
||||||
|
|
||||||
|
// Switch to the section where the table will be emitted into.
|
||||||
|
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
|
||||||
|
|
||||||
|
const MCSymbol *LineStartSym = I->second.EmitCU(MCOS);
|
||||||
// Handle the rest of the Compile Units.
|
// Handle the rest of the Compile Units.
|
||||||
for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++)
|
for (++I; I != E; ++I)
|
||||||
EmitCU(MCOS, Is);
|
I->second.EmitCU(MCOS);
|
||||||
|
|
||||||
return LineStartSym;
|
return LineStartSym;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
|
const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS) const {
|
||||||
MCContext &context = MCOS->getContext();
|
MCContext &context = MCOS->getContext();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create a symbol at the beginning of the line table.
|
// Create a symbol at the beginning of the line table.
|
||||||
MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID);
|
MCSymbol *LineStartSym = Label;
|
||||||
if (!LineStartSym)
|
if (!LineStartSym)
|
||||||
LineStartSym = context.CreateTempSymbol();
|
LineStartSym = context.CreateTempSymbol();
|
||||||
// Set the value of the symbol, as we are at the start of the line table.
|
// Set the value of the symbol, as we are at the start of the line table.
|
||||||
@ -276,8 +281,6 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
|
|||||||
// Put out the directory and file tables.
|
// Put out the directory and file tables.
|
||||||
|
|
||||||
// First the directory table.
|
// First the directory table.
|
||||||
const SmallVectorImpl<StringRef> &MCDwarfDirs =
|
|
||||||
context.getMCDwarfDirs(CUID);
|
|
||||||
for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
|
for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
|
||||||
MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
|
MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
|
||||||
MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
|
MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
|
||||||
@ -285,8 +288,6 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
|
|||||||
MCOS->EmitIntValue(0, 1); // Terminate the directory list
|
MCOS->EmitIntValue(0, 1); // Terminate the directory list
|
||||||
|
|
||||||
// Second the file table.
|
// Second the file table.
|
||||||
const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
|
|
||||||
MCOS->getContext().getMCDwarfFiles(CUID);
|
|
||||||
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
|
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
|
||||||
MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName
|
MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName
|
||||||
MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
|
MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
|
||||||
@ -302,15 +303,11 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
|
|||||||
MCOS->EmitLabel(ProEndSym);
|
MCOS->EmitLabel(ProEndSym);
|
||||||
|
|
||||||
// Put out the line tables.
|
// Put out the line tables.
|
||||||
const std::map<unsigned, MCLineSection> &MCLineSections =
|
for (const auto &LineSec : MCLineSections.getMCLineEntries())
|
||||||
MCOS->getContext().getMCLineSections();
|
EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
|
||||||
auto Iter = MCLineSections.find(CUID);
|
|
||||||
if (Iter != MCLineSections.end())
|
|
||||||
for (const auto &LineSec : Iter->second.getMCLineEntries())
|
|
||||||
EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
|
|
||||||
|
|
||||||
if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() &&
|
if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() &&
|
||||||
Iter == MCLineSections.end()) {
|
MCLineSections.getMCLineEntries().empty()) {
|
||||||
// The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
|
// The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
|
||||||
// it requires:
|
// it requires:
|
||||||
// total_length >= prologue_length + 10
|
// total_length >= prologue_length + 10
|
||||||
@ -729,7 +726,7 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
|
|||||||
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
|
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
|
||||||
|
|
||||||
// If there are no line table entries then do not emit any section contents.
|
// If there are no line table entries then do not emit any section contents.
|
||||||
if (context.getMCLineSections().empty())
|
if (!context.hasMCLineSections())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Output the data for .debug_aranges section.
|
// Output the data for .debug_aranges section.
|
||||||
|
@ -379,8 +379,7 @@ void MCObjectStreamer::EmitZeros(uint64_t NumBytes) {
|
|||||||
void MCObjectStreamer::FinishImpl() {
|
void MCObjectStreamer::FinishImpl() {
|
||||||
// Dump out the dwarf file & directory tables and line tables.
|
// Dump out the dwarf file & directory tables and line tables.
|
||||||
const MCSymbol *LineSectionSymbol = NULL;
|
const MCSymbol *LineSectionSymbol = NULL;
|
||||||
if (!getContext().getMCLineTableSymbols().empty() ||
|
if (getContext().hasMCLineSections())
|
||||||
getContext().hasDwarfFiles())
|
|
||||||
LineSectionSymbol = MCDwarfFileTable::Emit(this);
|
LineSectionSymbol = MCDwarfFileTable::Emit(this);
|
||||||
|
|
||||||
// If we are generating dwarf for assembly source files dump out the sections.
|
// If we are generating dwarf for assembly source files dump out the sections.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user