aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp117
1 files changed, 70 insertions, 47 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index b15e750aaf85..bbb0504550c3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -273,9 +273,9 @@ static StringRef getPrettyScopeName(const DIScope *Scope) {
return "<unnamed-tag>";
case dwarf::DW_TAG_namespace:
return "`anonymous namespace'";
+ default:
+ return StringRef();
}
-
- return StringRef();
}
const DISubprogram *CodeViewDebug::collectParentScopeNames(
@@ -358,6 +358,25 @@ TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) {
return recordTypeIndexForDINode(Scope, TI);
}
+static StringRef removeTemplateArgs(StringRef Name) {
+ // Remove template args from the display name. Assume that the template args
+ // are the last thing in the name.
+ if (Name.empty() || Name.back() != '>')
+ return Name;
+
+ int OpenBrackets = 0;
+ for (int i = Name.size() - 1; i >= 0; --i) {
+ if (Name[i] == '>')
+ ++OpenBrackets;
+ else if (Name[i] == '<') {
+ --OpenBrackets;
+ if (OpenBrackets == 0)
+ return Name.substr(0, i);
+ }
+ }
+ return Name;
+}
+
TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {
assert(SP);
@@ -367,8 +386,9 @@ TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {
return I->second;
// The display name includes function template arguments. Drop them to match
- // MSVC.
- StringRef DisplayName = SP->getName().split('<').first;
+ // MSVC. We need to have the template arguments in the DISubprogram name
+ // because they are used in other symbol records, such as S_GPROC32_IDs.
+ StringRef DisplayName = removeTemplateArgs(SP->getName());
const DIScope *Scope = SP->getScope();
TypeIndex TI;
@@ -784,6 +804,9 @@ void CodeViewDebug::emitCompilerInformation() {
// The low byte of the flags indicates the source language.
Flags = MapDWLangToCVLang(CU->getSourceLanguage());
// TODO: Figure out which other flags need to be set.
+ if (MMI->getModule()->getProfileSummary(/*IsCS*/ false) != nullptr) {
+ Flags |= static_cast<uint32_t>(CompileSym3Flags::PGO);
+ }
OS.AddComment("Flags and language");
OS.emitInt32(Flags);
@@ -794,8 +817,8 @@ void CodeViewDebug::emitCompilerInformation() {
StringRef CompilerVersion = CU->getProducer();
Version FrontVer = parseVersion(CompilerVersion);
OS.AddComment("Frontend version");
- for (int N = 0; N < 4; ++N)
- OS.emitInt16(FrontVer.Part[N]);
+ for (int N : FrontVer.Part)
+ OS.emitInt16(N);
// Some Microsoft tools, like Binscope, expect a backend version number of at
// least 8.something, so we'll coerce the LLVM version into a form that
@@ -807,8 +830,8 @@ void CodeViewDebug::emitCompilerInformation() {
Major = std::min<int>(Major, std::numeric_limits<uint16_t>::max());
Version BackVer = {{ Major, 0, 0, 0 }};
OS.AddComment("Backend version");
- for (int N = 0; N < 4; ++N)
- OS.emitInt16(BackVer.Part[N]);
+ for (int N : BackVer.Part)
+ OS.emitInt16(N);
OS.AddComment("Null-terminated compiler version string");
emitNullTerminatedSymbolName(OS, CompilerVersion);
@@ -1357,7 +1380,7 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
CurFn->CSRSize = MFI.getCVBytesOfCalleeSavedRegisters();
CurFn->FrameSize = MFI.getStackSize();
CurFn->OffsetAdjustment = MFI.getOffsetAdjustment();
- CurFn->HasStackRealignment = TRI->needsStackRealignment(*MF);
+ CurFn->HasStackRealignment = TRI->hasStackRealignment(*MF);
// For this function S_FRAMEPROC record, figure out which codeview register
// will be the frame pointer.
@@ -1408,6 +1431,10 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
if (Asm->TM.getOptLevel() != CodeGenOpt::None &&
!GV.hasOptSize() && !GV.hasOptNone())
FPO |= FrameProcedureOptions::OptimizedForSpeed;
+ if (GV.hasProfileData()) {
+ FPO |= FrameProcedureOptions::ValidProfileCounts;
+ FPO |= FrameProcedureOptions::ProfileGuidedOptimization;
+ }
// FIXME: Set GuardCfg when it is implemented.
CurFn->FrameProcOpts = FPO;
@@ -1460,6 +1487,9 @@ static bool shouldEmitUdt(const DIType *T) {
case dwarf::DW_TAG_class_type:
case dwarf::DW_TAG_union_type:
return false;
+ default:
+ // do nothing.
+ ;
}
}
}
@@ -2005,10 +2035,13 @@ static MethodKind translateMethodKindFlags(const DISubprogram *SP,
static TypeRecordKind getRecordKind(const DICompositeType *Ty) {
switch (Ty->getTag()) {
- case dwarf::DW_TAG_class_type: return TypeRecordKind::Class;
- case dwarf::DW_TAG_structure_type: return TypeRecordKind::Struct;
+ case dwarf::DW_TAG_class_type:
+ return TypeRecordKind::Class;
+ case dwarf::DW_TAG_structure_type:
+ return TypeRecordKind::Struct;
+ default:
+ llvm_unreachable("unexpected tag");
}
- llvm_unreachable("unexpected tag");
}
/// Return ClassOptions that should be present on both the forward declaration
@@ -2083,6 +2116,7 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {
// We assume that the frontend provides all members in source declaration
// order, which is what MSVC does.
if (auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
+ // FIXME: Is it correct to always emit these as unsigned here?
EnumeratorRecord ER(MemberAccess::Public,
APSInt(Enumerator->getValue(), true),
Enumerator->getName());
@@ -3124,6 +3158,27 @@ void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) {
}
}
+void CodeViewDebug::emitConstantSymbolRecord(const DIType *DTy, APSInt &Value,
+ const std::string &QualifiedName) {
+ MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
+ OS.AddComment("Type");
+ OS.emitInt32(getTypeIndex(DTy).getIndex());
+
+ OS.AddComment("Value");
+
+ // Encoded integers shouldn't need more than 10 bytes.
+ uint8_t Data[10];
+ BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
+ CodeViewRecordIO IO(Writer);
+ cantFail(IO.mapEncodedInteger(Value));
+ StringRef SRef((char *)Data, Writer.getOffset());
+ OS.emitBinaryData(SRef);
+
+ OS.AddComment("Name");
+ emitNullTerminatedSymbolName(OS, QualifiedName);
+ endSymbolRecord(SConstantEnd);
+}
+
void CodeViewDebug::emitStaticConstMemberList() {
for (const DIDerivedType *DTy : StaticConstMembers) {
const DIScope *Scope = DTy->getScope();
@@ -3139,24 +3194,8 @@ void CodeViewDebug::emitStaticConstMemberList() {
else
llvm_unreachable("cannot emit a constant without a value");
- std::string QualifiedName = getFullyQualifiedName(Scope, DTy->getName());
-
- MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
- OS.AddComment("Type");
- OS.emitInt32(getTypeIndex(DTy->getBaseType()).getIndex());
- OS.AddComment("Value");
-
- // Encoded integers shouldn't need more than 10 bytes.
- uint8_t Data[10];
- BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
- CodeViewRecordIO IO(Writer);
- cantFail(IO.mapEncodedInteger(Value));
- StringRef SRef((char *)Data, Writer.getOffset());
- OS.emitBinaryData(SRef);
-
- OS.AddComment("Name");
- emitNullTerminatedSymbolName(OS, QualifiedName);
- endSymbolRecord(SConstantEnd);
+ emitConstantSymbolRecord(DTy->getBaseType(), Value,
+ getFullyQualifiedName(Scope, DTy->getName()));
}
}
@@ -3220,22 +3259,6 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
? true
: DebugHandlerBase::isUnsignedDIType(DIGV->getType());
APSInt Value(APInt(/*BitWidth=*/64, DIE->getElement(1)), isUnsigned);
-
- MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
- OS.AddComment("Type");
- OS.emitInt32(getTypeIndex(DIGV->getType()).getIndex());
- OS.AddComment("Value");
-
- // Encoded integers shouldn't need more than 10 bytes.
- uint8_t data[10];
- BinaryStreamWriter Writer(data, llvm::support::endianness::little);
- CodeViewRecordIO IO(Writer);
- cantFail(IO.mapEncodedInteger(Value));
- StringRef SRef((char *)data, Writer.getOffset());
- OS.emitBinaryData(SRef);
-
- OS.AddComment("Name");
- emitNullTerminatedSymbolName(OS, QualifiedName);
- endSymbolRecord(SConstantEnd);
+ emitConstantSymbolRecord(DIGV->getType(), Value, QualifiedName);
}
}