1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

[codeview] Remove custom line info struct in favor of DebugLoc

The only functional change would be that we might emit multiple filename
segments on code like this:

  void f() {
  #include "p1/../t.h"
  #include "p2/../t.h"
  }

I believe these get separate DIFile metadata nodes, but will have the
same canonicalized absolute path. Previously by computing the path up
front and comparing it we would merge the line info segments.

llvm-svn: 257966
This commit is contained in:
Reid Kleckner 2016-01-16 00:09:09 +00:00
parent 266f53a305
commit fde903e415
2 changed files with 51 additions and 71 deletions

View File

@ -22,20 +22,13 @@ using namespace llvm::codeview;
namespace llvm {
StringRef CodeViewDebug::getFullFilepath(const MDNode *S) {
assert(S);
assert((isa<DICompileUnit>(S) || isa<DIFile>(S) || isa<DISubprogram>(S) ||
isa<DILexicalBlockBase>(S)) &&
"Unexpected scope info");
auto *Scope = cast<DIScope>(S);
StringRef Dir = Scope->getDirectory(),
Filename = Scope->getFilename();
std::string &Filepath =
DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)];
StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {
std::string &Filepath = FileToFilepathMap[File];
if (!Filepath.empty())
return Filepath;
StringRef Dir = File->getDirectory(), Filename = File->getFilename();
// Clang emits directory and relative filename info into the IR, but CodeView
// operates on full paths. We could change Clang to emit full paths too, but
// that would increase the IR size and probably not needed for other users.
@ -82,36 +75,25 @@ StringRef CodeViewDebug::getFullFilepath(const MDNode *S) {
}
void CodeViewDebug::maybeRecordLocation(DebugLoc DL,
const MachineFunction *MF) {
const MDNode *Scope = DL.getScope();
const MachineFunction *MF) {
// Skip this instruction if it has the same location as the previous one.
if (DL == CurFn->LastLoc)
return;
const DIScope *Scope = DL.get()->getScope();
if (!Scope)
return;
unsigned LineNumber = DL.getLine();
// Skip this line if it is longer than the maximum we can record.
if (LineNumber > COFF::CVL_MaxLineNumber)
if (DL.getLine() > COFF::CVL_MaxLineNumber)
return;
unsigned ColumnNumber = DL.getCol();
// Truncate the column number if it is longer than the maximum we can record.
if (ColumnNumber > COFF::CVL_MaxColumnNumber)
ColumnNumber = 0;
StringRef Filename = getFullFilepath(Scope);
// Skip this instruction if it has the same file:line as the previous one.
assert(CurFn);
if (!CurFn->Instrs.empty()) {
const InstrInfoTy &LastInstr = InstrInfo[CurFn->Instrs.back()];
if (LastInstr.Filename == Filename && LastInstr.LineNumber == LineNumber &&
LastInstr.ColumnNumber == ColumnNumber)
return;
}
FileNameRegistry.add(Filename);
CurFn->LastLoc = DL;
MCSymbol *MCL = Asm->MMI->getContext().createTempSymbol();
Asm->OutStreamer->EmitLabel(MCL);
CurFn->Instrs.push_back(MCL);
InstrInfo[MCL] = InstrInfoTy(Filename, LineNumber, ColumnNumber);
LabelsAndLocs[MCL] = DL;
}
CodeViewDebug::CodeViewDebug(AsmPrinter *AP)
@ -195,6 +177,10 @@ static void EmitLabelDiff(MCStreamer &Streamer,
Streamer.EmitValue(AddrDelta, Size);
}
static const DIFile *getFileFromLoc(DebugLoc DL) {
return DL.get()->getScope()->getFile();
}
void CodeViewDebug::emitDebugInfoForFunction(const Function *GV) {
// For each function there is a separate subsection
// which holds the PC to file:line table.
@ -258,13 +244,14 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV) {
// number of the respective instruction that starts a new segment.
DenseMap<size_t, size_t> FilenameSegmentLengths;
size_t LastSegmentEnd = 0;
StringRef PrevFilename = InstrInfo[FI.Instrs[0]].Filename;
const DIFile *PrevFile = getFileFromLoc(LabelsAndLocs[FI.Instrs[0]]);
for (size_t J = 1, F = FI.Instrs.size(); J != F; ++J) {
if (PrevFilename == InstrInfo[FI.Instrs[J]].Filename)
const DIFile *CurFile = getFileFromLoc(LabelsAndLocs[FI.Instrs[J]]);
if (PrevFile == CurFile)
continue;
FilenameSegmentLengths[LastSegmentEnd] = J - LastSegmentEnd;
LastSegmentEnd = J;
PrevFilename = InstrInfo[FI.Instrs[J]].Filename;
PrevFile = CurFile;
}
FilenameSegmentLengths[LastSegmentEnd] = FI.Instrs.size() - LastSegmentEnd;
@ -297,8 +284,11 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV) {
for (size_t ColSegI = LastSegmentStart,
ColSegEnd = ColSegI + FilenameSegmentLengths[LastSegmentStart];
ColSegI != ColSegEnd; ++ColSegI) {
unsigned ColumnNumber = InstrInfo[FI.Instrs[ColSegI]].ColumnNumber;
assert(ColumnNumber <= COFF::CVL_MaxColumnNumber);
unsigned ColumnNumber = LabelsAndLocs[FI.Instrs[ColSegI]].getCol();
// Truncate the column number if it is longer than the maximum we can
// record.
if (ColumnNumber > COFF::CVL_MaxColumnNumber)
ColumnNumber = 0;
Asm->EmitInt16(ColumnNumber); // Start column
Asm->EmitInt16(0); // End column
}
@ -307,22 +297,21 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV) {
for (size_t J = 0, F = FI.Instrs.size(); J != F; ++J) {
MCSymbol *Instr = FI.Instrs[J];
assert(InstrInfo.count(Instr));
assert(LabelsAndLocs.count(Instr));
if (FilenameSegmentLengths.count(J)) {
// We came to a beginning of a new filename segment.
FinishPreviousChunk();
StringRef CurFilename = InstrInfo[FI.Instrs[J]].Filename;
assert(FileNameRegistry.Infos.count(CurFilename));
size_t IndexInStringTable =
FileNameRegistry.Infos[CurFilename].FilenameID;
const DIFile *File = getFileFromLoc(LabelsAndLocs[FI.Instrs[J]]);
StringRef CurFilename = getFullFilepath(File);
size_t IndexInFileTable = FileNameRegistry.add(CurFilename);
// Each segment starts with the offset of the filename
// in the string table.
Asm->OutStreamer->AddComment(
"Segment for file '" + Twine(CurFilename) + "' begins");
MCSymbol *FileSegmentBegin = Asm->MMI->getContext().createTempSymbol();
Asm->OutStreamer->EmitLabel(FileSegmentBegin);
Asm->EmitInt32(8 * IndexInStringTable);
Asm->EmitInt32(8 * IndexInFileTable);
// Number of PC records in the lookup table.
size_t SegmentLength = FilenameSegmentLengths[J];
@ -337,7 +326,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV) {
// The first PC with the given linenumber and the linenumber itself.
EmitLabelDiff(*Asm->OutStreamer, Fn, Instr);
uint32_t LineNumber = InstrInfo[Instr].LineNumber;
uint32_t LineNumber = LabelsAndLocs[Instr].getLine();
assert(LineNumber <= COFF::CVL_MaxLineNumber);
uint32_t LineData = LineNumber | COFF::CVL_IsStatement;
Asm->EmitInt32(LineData);

View File

@ -36,10 +36,12 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler {
// For each function, store a vector of labels to its instructions, as well as
// to the end of the function.
struct FunctionInfo {
DebugLoc LastLoc;
SmallVector<MCSymbol *, 10> Instrs;
MCSymbol *End;
FunctionInfo() : End(nullptr) {}
} *CurFn;
};
FunctionInfo *CurFn;
typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
FnDebugInfoTy FnDebugInfo;
@ -47,20 +49,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler {
// order while emitting subsections.
SmallVector<const Function *, 10> VisitedFunctions;
// InstrInfoTy - Holds the Filename:LineNumber information for every
// instruction with a unique debug location.
struct InstrInfoTy {
StringRef Filename;
unsigned LineNumber;
unsigned ColumnNumber;
InstrInfoTy() : LineNumber(0), ColumnNumber(0) {}
InstrInfoTy(StringRef Filename, unsigned LineNumber, unsigned ColumnNumber)
: Filename(Filename), LineNumber(LineNumber),
ColumnNumber(ColumnNumber) {}
};
DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
DenseMap<MCSymbol *, DebugLoc> LabelsAndLocs;
// FileNameRegistry - Manages filenames observed while generating debug info
// by filtering out duplicates and bookkeeping the offsets in the string
@ -81,14 +70,17 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler {
}
// Add Filename to the registry, if it was not observed before.
void add(StringRef Filename) {
if (Infos.count(Filename))
return;
size_t add(StringRef Filename) {
size_t OldSize = Infos.size();
Infos[Filename].FilenameID = OldSize;
Infos[Filename].StartOffset = LastOffset;
LastOffset += Filename.size() + 1;
Filenames.push_back(Filename);
bool Inserted;
StringMap<PerFileInfo>::iterator It;
std::tie(It, Inserted) = Infos.insert(
std::make_pair(Filename, PerFileInfo{OldSize, LastOffset}));
if (Inserted) {
LastOffset += Filename.size() + 1;
Filenames.push_back(Filename);
}
return It->second.FilenameID;
}
void clear() {
@ -98,17 +90,16 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public AsmPrinterHandler {
}
} FileNameRegistry;
typedef std::map<std::pair<StringRef, StringRef>, std::string>
DirAndFilenameToFilepathMapTy;
DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
StringRef getFullFilepath(const MDNode *S);
typedef std::map<const DIFile *, std::string> FileToFilepathMapTy;
FileToFilepathMapTy FileToFilepathMap;
StringRef getFullFilepath(const DIFile *S);
void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
void clear() {
assert(CurFn == nullptr);
FileNameRegistry.clear();
InstrInfo.clear();
LabelsAndLocs.clear();
}
void emitDebugInfoForFunction(const Function *GV);