summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-22 20:31:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-22 20:31:01 +0000
commit8bcb0991864975618c09697b1aca10683346d9f0 (patch)
tree0afab28faa50e5f27698f8dd6c1921fff8d25e39 /contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parentb14637d118e110006a149a79b649c5695e7f419a (diff)
parent1d5ae1026e831016fc29fd927877c86af904481f (diff)
Notes
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp146
1 files changed, 52 insertions, 94 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 8fc9e980b5f1..c6457f3626d1 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -98,7 +98,8 @@ using namespace llvm::codeview;
namespace {
class CVMCAdapter : public CodeViewRecordStreamer {
public:
- CVMCAdapter(MCStreamer &OS) : OS(&OS) {}
+ CVMCAdapter(MCStreamer &OS, TypeCollection &TypeTable)
+ : OS(&OS), TypeTable(TypeTable) {}
void EmitBytes(StringRef Data) { OS->EmitBytes(Data); }
@@ -110,8 +111,24 @@ public:
void AddComment(const Twine &T) { OS->AddComment(T); }
+ void AddRawComment(const Twine &T) { OS->emitRawComment(T); }
+
+ bool isVerboseAsm() { return OS->isVerboseAsm(); }
+
+ std::string getTypeName(TypeIndex TI) {
+ std::string TypeName;
+ if (!TI.isNoneType()) {
+ if (TI.isSimple())
+ TypeName = TypeIndex::simpleTypeName(TI);
+ else
+ TypeName = TypeTable.getTypeName(TI);
+ }
+ return TypeName;
+ }
+
private:
MCStreamer *OS = nullptr;
+ TypeCollection &TypeTable;
};
} // namespace
@@ -617,13 +634,6 @@ emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S,
OS.EmitBytes(NullTerminatedString);
}
-static StringRef getTypeLeafName(TypeLeafKind TypeKind) {
- for (const EnumEntry<TypeLeafKind> &EE : getTypeLeafNames())
- if (EE.Value == TypeKind)
- return EE.Name;
- return "";
-}
-
void CodeViewDebug::emitTypeInformation() {
if (TypeTable.empty())
return;
@@ -632,30 +642,11 @@ void CodeViewDebug::emitTypeInformation() {
OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
emitCodeViewMagicVersion();
- SmallString<8> CommentPrefix;
- if (OS.isVerboseAsm()) {
- CommentPrefix += '\t';
- CommentPrefix += Asm->MAI->getCommentString();
- CommentPrefix += ' ';
- }
-
TypeTableCollection Table(TypeTable.records());
- SmallString<512> CommentBlock;
- raw_svector_ostream CommentOS(CommentBlock);
- std::unique_ptr<ScopedPrinter> SP;
- std::unique_ptr<TypeDumpVisitor> TDV;
TypeVisitorCallbackPipeline Pipeline;
- if (OS.isVerboseAsm()) {
- // To construct block comment describing the type record for readability.
- SP = llvm::make_unique<ScopedPrinter>(CommentOS);
- SP->setPrefix(CommentPrefix);
- TDV = llvm::make_unique<TypeDumpVisitor>(Table, SP.get(), false);
- Pipeline.addCallbackToPipeline(*TDV);
- }
-
// To emit type record using Codeview MCStreamer adapter
- CVMCAdapter CVMCOS(OS);
+ CVMCAdapter CVMCOS(OS, Table);
TypeRecordMapping typeMapping(CVMCOS);
Pipeline.addCallbackToPipeline(typeMapping);
@@ -664,17 +655,6 @@ void CodeViewDebug::emitTypeInformation() {
// This will fail if the record data is invalid.
CVType Record = Table.getType(*B);
- CommentBlock.clear();
-
- auto RecordLen = Record.length();
- auto RecordKind = Record.kind();
- if (OS.isVerboseAsm())
- CVMCOS.AddComment("Record length");
- CVMCOS.EmitIntValue(RecordLen - 2, 2);
- if (OS.isVerboseAsm())
- CVMCOS.AddComment("Record kind: " + getTypeLeafName(RecordKind));
- CVMCOS.EmitIntValue(RecordKind, sizeof(RecordKind));
-
Error E = codeview::visitTypeRecord(Record, *B, Pipeline);
if (E) {
@@ -682,13 +662,6 @@ void CodeViewDebug::emitTypeInformation() {
llvm_unreachable("produced malformed type record");
}
- if (OS.isVerboseAsm()) {
- // emitRawComment will insert its own tab and comment string before
- // the first line, so strip off our first one. It also prints its own
- // newline.
- OS.emitRawComment(
- CommentOS.str().drop_front(CommentPrefix.size() - 1).rtrim());
- }
B = Table.getNext(*B);
}
}
@@ -1127,8 +1100,14 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
}
for (auto HeapAllocSite : FI.HeapAllocSites) {
- const MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);
- const MCSymbol *EndLabel = std::get<1>(HeapAllocSite);
+ MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);
+ MCSymbol *EndLabel = std::get<1>(HeapAllocSite);
+
+ // The labels might not be defined if the instruction was replaced
+ // somewhere in the codegen pipeline.
+ if (!BeginLabel->isDefined() || !EndLabel->isDefined())
+ continue;
+
const DIType *DITy = std::get<2>(HeapAllocSite);
MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);
OS.AddComment("Call site offset");
@@ -1357,7 +1336,7 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
const TargetRegisterInfo *TRI = TSI.getRegisterInfo();
const MachineFrameInfo &MFI = MF->getFrameInfo();
const Function &GV = MF->getFunction();
- auto Insertion = FnDebugInfo.insert({&GV, llvm::make_unique<FunctionInfo>()});
+ auto Insertion = FnDebugInfo.insert({&GV, std::make_unique<FunctionInfo>()});
assert(Insertion.second && "function already has info");
CurFn = Insertion.first->second.get();
CurFn->FuncId = NextFuncId++;
@@ -1448,16 +1427,6 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();
maybeRecordLocation(FnStartDL, MF);
}
-
- // Find heap alloc sites and emit labels around them.
- for (const auto &MBB : *MF) {
- for (const auto &MI : MBB) {
- if (MI.getHeapAllocMarker()) {
- requestLabelBeforeInsn(&MI);
- requestLabelAfterInsn(&MI);
- }
- }
- }
}
static bool shouldEmitUdt(const DIType *T) {
@@ -2637,17 +2606,6 @@ void CodeViewDebug::emitLocalVariableList(const FunctionInfo &FI,
emitLocalVariable(FI, L);
}
-/// Only call this on endian-specific types like ulittle16_t and little32_t, or
-/// structs composed of them.
-template <typename T>
-static void copyBytesForDefRange(SmallString<20> &BytePrefix,
- SymbolKind SymKind, const T &DefRangeHeader) {
- BytePrefix.resize(2 + sizeof(T));
- ulittle16_t SymKindLE = ulittle16_t(SymKind);
- memcpy(&BytePrefix[0], &SymKindLE, 2);
- memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
-}
-
void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
const LocalVariable &Var) {
// LocalSym record, see SymbolRecord.h for more info.
@@ -2696,8 +2654,9 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
(bool(Flags & LocalSymFlags::IsParameter)
? (EncFP == FI.EncodedParamFramePtrReg)
: (EncFP == FI.EncodedLocalFramePtrReg))) {
- little32_t FPOffset = little32_t(Offset);
- copyBytesForDefRange(BytePrefix, S_DEFRANGE_FRAMEPOINTER_REL, FPOffset);
+ DefRangeFramePointerRelHeader DRHdr;
+ DRHdr.Offset = Offset;
+ OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
} else {
uint16_t RegRelFlags = 0;
if (DefRange.IsSubfield) {
@@ -2705,28 +2664,27 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
(DefRange.StructOffset
<< DefRangeRegisterRelSym::OffsetInParentShift);
}
- DefRangeRegisterRelSym::Header DRHdr;
+ DefRangeRegisterRelHeader DRHdr;
DRHdr.Register = Reg;
DRHdr.Flags = RegRelFlags;
DRHdr.BasePointerOffset = Offset;
- copyBytesForDefRange(BytePrefix, S_DEFRANGE_REGISTER_REL, DRHdr);
+ OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
}
} else {
assert(DefRange.DataOffset == 0 && "unexpected offset into register");
if (DefRange.IsSubfield) {
- DefRangeSubfieldRegisterSym::Header DRHdr;
+ DefRangeSubfieldRegisterHeader DRHdr;
DRHdr.Register = DefRange.CVRegister;
DRHdr.MayHaveNoName = 0;
DRHdr.OffsetInParent = DefRange.StructOffset;
- copyBytesForDefRange(BytePrefix, S_DEFRANGE_SUBFIELD_REGISTER, DRHdr);
+ OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
} else {
- DefRangeRegisterSym::Header DRHdr;
+ DefRangeRegisterHeader DRHdr;
DRHdr.Register = DefRange.CVRegister;
DRHdr.MayHaveNoName = 0;
- copyBytesForDefRange(BytePrefix, S_DEFRANGE_REGISTER, DRHdr);
+ OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
}
}
- OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);
}
}
@@ -2892,24 +2850,22 @@ void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {
return;
}
- // Find heap alloc sites and add to list.
- for (const auto &MBB : *MF) {
- for (const auto &MI : MBB) {
- if (MDNode *MD = MI.getHeapAllocMarker()) {
- CurFn->HeapAllocSites.push_back(std::make_tuple(getLabelBeforeInsn(&MI),
- getLabelAfterInsn(&MI),
- dyn_cast<DIType>(MD)));
- }
- }
- }
-
CurFn->Annotations = MF->getCodeViewAnnotations();
+ CurFn->HeapAllocSites = MF->getCodeViewHeapAllocSites();
CurFn->End = Asm->getFunctionEnd();
CurFn = nullptr;
}
+// Usable locations are valid with non-zero line numbers. A line number of zero
+// corresponds to optimized code that doesn't have a distinct source location.
+// In this case, we try to use the previous or next source location depending on
+// the context.
+static bool isUsableDebugLoc(DebugLoc DL) {
+ return DL && DL.getLine() != 0;
+}
+
void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
DebugHandlerBase::beginInstruction(MI);
@@ -2921,19 +2877,21 @@ void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
// If the first instruction of a new MBB has no location, find the first
// instruction with a location and use that.
DebugLoc DL = MI->getDebugLoc();
- if (!DL && MI->getParent() != PrevInstBB) {
+ if (!isUsableDebugLoc(DL) && MI->getParent() != PrevInstBB) {
for (const auto &NextMI : *MI->getParent()) {
if (NextMI.isDebugInstr())
continue;
DL = NextMI.getDebugLoc();
- if (DL)
+ if (isUsableDebugLoc(DL))
break;
}
+ // FIXME: Handle the case where the BB has no valid locations. This would
+ // probably require doing a real dataflow analysis.
}
PrevInstBB = MI->getParent();
// If we still don't have a debug location, don't record a location.
- if (!DL)
+ if (!isUsableDebugLoc(DL))
return;
maybeRecordLocation(DL, Asm->MF);
@@ -3040,7 +2998,7 @@ void CodeViewDebug::collectGlobalVariableInfo() {
auto Insertion = ScopeGlobals.insert(
{Scope, std::unique_ptr<GlobalVariableList>()});
if (Insertion.second)
- Insertion.first->second = llvm::make_unique<GlobalVariableList>();
+ Insertion.first->second = std::make_unique<GlobalVariableList>();
VariableList = Insertion.first->second.get();
} else if (GV->hasComdat())
// Emit this global variable into a COMDAT section.