summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp77
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h45
2 files changed, 51 insertions, 71 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index d2a8bfeb321..f1716361a1d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -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);
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 089c752caac..4294b4fd694 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -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);
OpenPOWER on IntegriCloud