aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp12
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp42
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp10
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp882
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp77
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp13
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h24
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp264
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h13
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIE.cpp90
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp9
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.h1
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp3
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp39
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp23
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp203
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h34
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp910
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h27
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfException.h3
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp134
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h74
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp2
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp8
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp78
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h1
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp50
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp12
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp4
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.cpp129
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.h2
32 files changed, 1932 insertions, 1245 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
index f6ef85a5b78f..b634b24377fe 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -46,12 +46,12 @@ void ARMException::beginFunction(const MachineFunction *MF) {
if (MoveType == AsmPrinter::CFI_M_Debug) {
if (!hasEmittedCFISections) {
if (Asm->needsOnlyDebugCFIMoves())
- Asm->OutStreamer->EmitCFISections(false, true);
+ Asm->OutStreamer->emitCFISections(false, true);
hasEmittedCFISections = true;
}
shouldEmitCFI = true;
- Asm->OutStreamer->EmitCFIStartProc(false);
+ Asm->OutStreamer->emitCFIStartProc(false);
}
}
@@ -75,7 +75,7 @@ void ARMException::endFunction(const MachineFunction *MF) {
// Emit references to personality.
if (Per) {
MCSymbol *PerSym = Asm->getSymbol(Per);
- Asm->OutStreamer->EmitSymbolAttribute(PerSym, MCSA_Global);
+ Asm->OutStreamer->emitSymbolAttribute(PerSym, MCSA_Global);
ATS.emitPersonality(PerSym);
}
@@ -109,10 +109,10 @@ void ARMException::emitTypeInfos(unsigned TTypeEncoding,
for (const GlobalValue *GV : reverse(TypeInfos)) {
if (VerboseAsm)
Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
- Asm->EmitTTypeReference(GV, TTypeEncoding);
+ Asm->emitTTypeReference(GV, TTypeEncoding);
}
- Asm->OutStreamer->EmitLabel(TTBaseLabel);
+ Asm->OutStreamer->emitLabel(TTBaseLabel);
// Emit the Exception Specifications.
if (VerboseAsm && !FilterIds.empty()) {
@@ -129,7 +129,7 @@ void ARMException::emitTypeInfos(unsigned TTypeEncoding,
Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
}
- Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
+ Asm->emitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
TTypeEncoding);
}
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
index b1b7921ea976..dea0227f7578 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
@@ -271,7 +271,7 @@ void AccelTableWriter::emitOffsets(const MCSymbol *Base) const {
continue;
PrevHash = HashValue;
Asm->OutStreamer->AddComment("Offset in Bucket " + Twine(i));
- Asm->EmitLabelDifference(Hash->Sym, Base, sizeof(uint32_t));
+ Asm->emitLabelDifference(Hash->Sym, Base, sizeof(uint32_t));
}
}
}
@@ -337,7 +337,7 @@ void AppleAccelTableWriter::emitData() const {
PrevHash != Hash->HashValue)
Asm->emitInt32(0);
// Remember to emit the label for our offset.
- Asm->OutStreamer->EmitLabel(Hash->Sym);
+ Asm->OutStreamer->emitLabel(Hash->Sym);
Asm->OutStreamer->AddComment(Hash->Name.getString());
Asm->emitDwarfStringOffset(Hash->Name);
Asm->OutStreamer->AddComment("Num DIEs");
@@ -368,9 +368,9 @@ void Dwarf5AccelTableWriter<DataT>::Header::emit(
AsmPrinter *Asm = Ctx.Asm;
Asm->OutStreamer->AddComment("Header: unit length");
- Asm->EmitLabelDifference(Ctx.ContributionEnd, Ctx.ContributionStart,
+ Asm->emitLabelDifference(Ctx.ContributionEnd, Ctx.ContributionStart,
sizeof(uint32_t));
- Asm->OutStreamer->EmitLabel(Ctx.ContributionStart);
+ Asm->OutStreamer->emitLabel(Ctx.ContributionStart);
Asm->OutStreamer->AddComment("Header: version");
Asm->emitInt16(Version);
Asm->OutStreamer->AddComment("Header: padding");
@@ -386,12 +386,12 @@ void Dwarf5AccelTableWriter<DataT>::Header::emit(
Asm->OutStreamer->AddComment("Header: name count");
Asm->emitInt32(NameCount);
Asm->OutStreamer->AddComment("Header: abbreviation table size");
- Asm->EmitLabelDifference(Ctx.AbbrevEnd, Ctx.AbbrevStart, sizeof(uint32_t));
+ Asm->emitLabelDifference(Ctx.AbbrevEnd, Ctx.AbbrevStart, sizeof(uint32_t));
Asm->OutStreamer->AddComment("Header: augmentation string size");
assert(AugmentationStringSize % 4 == 0);
Asm->emitInt32(AugmentationStringSize);
Asm->OutStreamer->AddComment("Header: augmentation string");
- Asm->OutStreamer->EmitBytes({AugmentationString, AugmentationStringSize});
+ Asm->OutStreamer->emitBytes({AugmentationString, AugmentationStringSize});
}
template <typename DataT>
@@ -453,23 +453,23 @@ void Dwarf5AccelTableWriter<DataT>::emitStringOffsets() const {
template <typename DataT>
void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
- Asm->OutStreamer->EmitLabel(AbbrevStart);
+ Asm->OutStreamer->emitLabel(AbbrevStart);
for (const auto &Abbrev : Abbreviations) {
Asm->OutStreamer->AddComment("Abbrev code");
assert(Abbrev.first != 0);
- Asm->EmitULEB128(Abbrev.first);
+ Asm->emitULEB128(Abbrev.first);
Asm->OutStreamer->AddComment(dwarf::TagString(Abbrev.first));
- Asm->EmitULEB128(Abbrev.first);
+ Asm->emitULEB128(Abbrev.first);
for (const auto &AttrEnc : Abbrev.second) {
- Asm->EmitULEB128(AttrEnc.Index, dwarf::IndexString(AttrEnc.Index).data());
- Asm->EmitULEB128(AttrEnc.Form,
+ Asm->emitULEB128(AttrEnc.Index, dwarf::IndexString(AttrEnc.Index).data());
+ Asm->emitULEB128(AttrEnc.Form,
dwarf::FormEncodingString(AttrEnc.Form).data());
}
- Asm->EmitULEB128(0, "End of abbrev");
- Asm->EmitULEB128(0, "End of abbrev");
+ Asm->emitULEB128(0, "End of abbrev");
+ Asm->emitULEB128(0, "End of abbrev");
}
- Asm->EmitULEB128(0, "End of abbrev list");
- Asm->OutStreamer->EmitLabel(AbbrevEnd);
+ Asm->emitULEB128(0, "End of abbrev list");
+ Asm->OutStreamer->emitLabel(AbbrevEnd);
}
template <typename DataT>
@@ -478,13 +478,13 @@ void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const {
assert(AbbrevIt != Abbreviations.end() &&
"Why wasn't this abbrev generated?");
- Asm->EmitULEB128(AbbrevIt->first, "Abbreviation code");
+ Asm->emitULEB128(AbbrevIt->first, "Abbreviation code");
for (const auto &AttrEnc : AbbrevIt->second) {
Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index));
switch (AttrEnc.Index) {
case dwarf::DW_IDX_compile_unit: {
DIEInteger ID(getCUIndexForEntry(Entry));
- ID.EmitValue(Asm, AttrEnc.Form);
+ ID.emitValue(Asm, AttrEnc.Form);
break;
}
case dwarf::DW_IDX_die_offset:
@@ -498,11 +498,11 @@ void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const {
}
template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() const {
- Asm->OutStreamer->EmitLabel(EntryPool);
+ Asm->OutStreamer->emitLabel(EntryPool);
for (auto &Bucket : Contents.getBuckets()) {
for (auto *Hash : Bucket) {
// Remember to emit the label for our offset.
- Asm->OutStreamer->EmitLabel(Hash->Sym);
+ Asm->OutStreamer->emitLabel(Hash->Sym);
for (const auto *Value : Hash->Values)
emitEntry(*static_cast<const DataT *>(Value));
Asm->OutStreamer->AddComment("End of list: " + Hash->Name.getString());
@@ -537,8 +537,8 @@ template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emit() const {
emitOffsets(EntryPool);
emitAbbrevs();
emitData();
- Asm->OutStreamer->EmitValueToAlignment(4, 0);
- Asm->OutStreamer->EmitLabel(ContributionEnd);
+ Asm->OutStreamer->emitValueToAlignment(4, 0);
+ Asm->OutStreamer->emitLabel(ContributionEnd);
}
void llvm::emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents,
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
index f11c7de5ed8a..883aaf5aefc4 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
@@ -30,9 +30,9 @@ MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) {
MCSymbol *EndLabel = Asm.createTempSymbol(Prefix + "end");
Asm.OutStreamer->AddComment("Length of contribution");
- Asm.EmitLabelDifference(EndLabel, BeginLabel,
+ Asm.emitLabelDifference(EndLabel, BeginLabel,
4); // TODO: Support DWARF64 format.
- Asm.OutStreamer->EmitLabel(BeginLabel);
+ Asm.OutStreamer->emitLabel(BeginLabel);
Asm.OutStreamer->AddComment("DWARF version number");
Asm.emitInt16(Asm.getDwarfVersion());
Asm.OutStreamer->AddComment("Address size");
@@ -58,7 +58,7 @@ void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) {
// Define the symbol that marks the start of the contribution.
// It is referenced via DW_AT_addr_base.
- Asm.OutStreamer->EmitLabel(AddressTableBaseSym);
+ Asm.OutStreamer->emitLabel(AddressTableBaseSym);
// Order the address pool entries by ID
SmallVector<const MCExpr *, 64> Entries(Pool.size());
@@ -70,8 +70,8 @@ void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) {
: MCSymbolRefExpr::create(I.first, Asm.OutContext);
for (const MCExpr *Entry : Entries)
- Asm.OutStreamer->EmitValue(Entry, Asm.getDataLayout().getPointerSize());
+ Asm.OutStreamer->emitValue(Entry, Asm.getDataLayout().getPointerSize());
if (EndLabel)
- Asm.OutStreamer->EmitLabel(EndLabel);
+ Asm.OutStreamer->emitLabel(EndLabel);
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 20cd9da31fbd..f8f7b74baf91 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -31,16 +31,13 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -55,7 +52,6 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
-#include "llvm/CodeGen/MachineSizeOpts.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
@@ -81,7 +77,6 @@
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
-#include "llvm/IR/RemarkStreamer.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -106,6 +101,7 @@
#include "llvm/Pass.h"
#include "llvm/Remarks/Remark.h"
#include "llvm/Remarks/RemarkFormat.h"
+#include "llvm/Remarks/RemarkStreamer.h"
#include "llvm/Remarks/RemarkStringTable.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
@@ -161,11 +157,11 @@ static gcp_map_type &getGCMap(void *&P) {
/// getGVAlignment - Return the alignment to use for the specified global
/// value. This rounds up to the preferred alignment if possible and legal.
-Align AsmPrinter::getGVAlignment(const GlobalValue *GV, const DataLayout &DL,
+Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
Align InAlign) {
Align Alignment;
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
- Alignment = Align(DL.getPreferredAlignment(GVar));
+ Alignment = DL.getPreferredAlign(GVar);
// If InAlign is specified, round it to it.
if (InAlign > Alignment)
@@ -231,7 +227,7 @@ const MCSubtargetInfo &AsmPrinter::getSubtargetInfo() const {
}
void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
- S.EmitInstruction(Inst, getSubtargetInfo());
+ S.emitInstruction(Inst, getSubtargetInfo());
}
void AsmPrinter::emitInitialRawDwarfLocDirective(const MachineFunction &MF) {
@@ -248,11 +244,8 @@ const MCSection *AsmPrinter::getCurrentSection() const {
void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
- AU.addRequired<MachineModuleInfoWrapperPass>();
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
AU.addRequired<GCModuleInfo>();
- AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
- AU.addRequired<ProfileSummaryInfoWrapperPass>();
}
bool AsmPrinter::doInitialization(Module &M) {
@@ -277,16 +270,16 @@ bool AsmPrinter::doInitialization(Module &M) {
// use the directive, where it would need the same conditionalization
// anyway.
const Triple &Target = TM.getTargetTriple();
- OutStreamer->EmitVersionForTarget(Target, M.getSDKVersion());
+ OutStreamer->emitVersionForTarget(Target, M.getSDKVersion());
// Allow the target to emit any magic that it wants at the start of the file.
- EmitStartOfAsmFile(M);
+ emitStartOfAsmFile(M);
// Very minimal debug info. It is ignored if we emit actual debug info. If we
// don't, this at least helps the user find where a global came from.
if (MAI->hasSingleParameterDotFile()) {
// .file "foo.c"
- OutStreamer->EmitFileDirective(
+ OutStreamer->emitFileDirective(
llvm::sys::path::filename(M.getSourceFileName()));
}
@@ -305,21 +298,21 @@ bool AsmPrinter::doInitialization(Module &M) {
TM.getTargetFeatureString()));
OutStreamer->AddComment("Start of file scope inline assembly");
OutStreamer->AddBlankLine();
- EmitInlineAsm(M.getModuleInlineAsm()+"\n",
+ emitInlineAsm(M.getModuleInlineAsm() + "\n",
OutContext.getSubtargetCopy(*STI), TM.Options.MCOptions);
OutStreamer->AddComment("End of file scope inline assembly");
OutStreamer->AddBlankLine();
}
if (MAI->doesSupportDebugInformation()) {
- bool EmitCodeView = MMI->getModule()->getCodeViewFlag();
+ bool EmitCodeView = M.getCodeViewFlag();
if (EmitCodeView && TM.getTargetTriple().isOSWindows()) {
Handlers.emplace_back(std::make_unique<CodeViewDebug>(this),
DbgTimerName, DbgTimerDescription,
CodeViewLineTablesGroupName,
CodeViewLineTablesGroupDescription);
}
- if (!EmitCodeView || MMI->getModule()->getDwarfVersion()) {
+ if (!EmitCodeView || M.getDwarfVersion()) {
DD = new DwarfDebug(this, &M);
DD->beginModule();
Handlers.emplace_back(std::unique_ptr<DwarfDebug>(DD), DbgTimerName,
@@ -382,8 +375,7 @@ bool AsmPrinter::doInitialization(Module &M) {
DWARFGroupDescription);
// Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2).
- if (mdconst::extract_or_null<ConstantInt>(
- MMI->getModule()->getModuleFlag("cfguard")))
+ if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard")))
Handlers.emplace_back(std::make_unique<WinCFGuard>(this), CFGuardName,
CFGuardDescription, DWARFGroupName,
DWARFGroupDescription);
@@ -397,7 +389,7 @@ static bool canBeHidden(const GlobalValue *GV, const MCAsmInfo &MAI) {
return GV->canBeOmittedFromSymbolTable();
}
-void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
+void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
GlobalValue::LinkageTypes Linkage = GV->getLinkage();
switch (Linkage) {
case GlobalValue::CommonLinkage:
@@ -407,35 +399,31 @@ void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
case GlobalValue::WeakODRLinkage:
if (MAI->hasWeakDefDirective()) {
// .globl _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
+ OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);
if (!canBeHidden(GV, *MAI))
// .weak_definition _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_WeakDefinition);
+ OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefinition);
else
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate);
- } else if (MAI->hasLinkOnceDirective()) {
+ OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate);
+ } else if (MAI->avoidWeakIfComdat() && GV->hasComdat()) {
// .globl _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
+ OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);
//NOTE: linkonce is handled by the section the symbol was assigned to.
} else {
// .weak _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Weak);
+ OutStreamer->emitSymbolAttribute(GVSym, MCSA_Weak);
}
return;
case GlobalValue::ExternalLinkage:
- // If external, declare as a global symbol: .globl _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
+ OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);
return;
case GlobalValue::PrivateLinkage:
- return;
case GlobalValue::InternalLinkage:
- if (MAI->hasDotLGloblDirective())
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_LGlobal);
return;
- case GlobalValue::AppendingLinkage:
- case GlobalValue::AvailableExternallyLinkage:
case GlobalValue::ExternalWeakLinkage:
+ case GlobalValue::AvailableExternallyLinkage:
+ case GlobalValue::AppendingLinkage:
llvm_unreachable("Should never emit this");
}
llvm_unreachable("Unknown linkage type!");
@@ -450,8 +438,27 @@ MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const {
return TM.getSymbol(GV);
}
+MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const {
+ // On ELF, use .Lfoo$local if GV is a non-interposable GlobalObject with an
+ // exact definion (intersection of GlobalValue::hasExactDefinition() and
+ // !isInterposable()). These linkages include: external, appending, internal,
+ // private. It may be profitable to use a local alias for external. The
+ // assembler would otherwise be conservative and assume a global default
+ // visibility symbol can be interposable, even if the code generator already
+ // assumed it.
+ if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) {
+ const Module &M = *GV.getParent();
+ if (TM.getRelocationModel() != Reloc::Static &&
+ M.getPIELevel() == PIELevel::Default)
+ if (GV.isDSOLocal() || (TM.getTargetTriple().isX86() &&
+ GV.getParent()->noSemanticInterposition()))
+ return getSymbolWithGlobalValueBase(&GV, "$local");
+ }
+ return TM.getSymbol(&GV);
+}
+
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
-void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
+void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
bool IsEmuTLSVar = TM.useEmulatedTLS() && GV->isThreadLocal();
assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) &&
"No emulated TLS variables in the common section");
@@ -463,7 +470,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
if (GV->hasInitializer()) {
// Check to see if this is a special global used by LLVM, if so, emit it.
- if (EmitSpecialLLVMGlobal(GV))
+ if (emitSpecialLLVMGlobal(GV))
return;
// Skip the emission of global equivalents. The symbol can be emitted later
@@ -486,7 +493,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// getOrCreateEmuTLSControlSym only creates the symbol with name and default
// attributes.
// GV's or GVSym's attributes will be used for the EmittedSym.
- EmitVisibility(EmittedSym, GV->getVisibility(), !GV->isDeclaration());
+ emitVisibility(EmittedSym, GV->getVisibility(), !GV->isDeclaration());
if (!GV->hasInitializer()) // External globals require no extra code.
return;
@@ -497,7 +504,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
"' is already defined");
if (MAI->hasDotTypeDotSizeDirective())
- OutStreamer->EmitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);
+ OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
@@ -522,7 +529,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// .comm _foo, 42, 4
const bool SupportsAlignment =
getObjFileLowering().getCommDirectiveSupportsAlignment();
- OutStreamer->EmitCommonSymbol(GVSym, Size,
+ OutStreamer->emitCommonSymbol(GVSym, Size,
SupportsAlignment ? Alignment.value() : 0);
return;
}
@@ -536,9 +543,9 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
TheSection->isVirtualSection()) {
if (Size == 0)
Size = 1; // zerofill of 0 bytes is undefined.
- EmitLinkage(GV, GVSym);
+ emitLinkage(GV, GVSym);
// .zerofill __DATA, __bss, _foo, 400, 5
- OutStreamer->EmitZerofill(TheSection, GVSym, Size, Alignment.value());
+ OutStreamer->emitZerofill(TheSection, GVSym, Size, Alignment.value());
return;
}
@@ -557,16 +564,16 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// Prefer to simply fall back to .local / .comm in this case.
if (MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {
// .lcomm _foo, 42
- OutStreamer->EmitLocalCommonSymbol(GVSym, Size, Alignment.value());
+ OutStreamer->emitLocalCommonSymbol(GVSym, Size, Alignment.value());
return;
}
// .local _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Local);
+ OutStreamer->emitSymbolAttribute(GVSym, MCSA_Local);
// .comm _foo, 42, 4
const bool SupportsAlignment =
getObjFileLowering().getCommDirectiveSupportsAlignment();
- OutStreamer->EmitCommonSymbol(GVSym, Size,
+ OutStreamer->emitCommonSymbol(GVSym, Size,
SupportsAlignment ? Alignment.value() : 0);
return;
}
@@ -588,14 +595,14 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
if (GVKind.isThreadBSS()) {
TheSection = getObjFileLowering().getTLSBSSSection();
- OutStreamer->EmitTBSSSymbol(TheSection, MangSym, Size, Alignment.value());
+ OutStreamer->emitTBSSSymbol(TheSection, MangSym, Size, Alignment.value());
} else if (GVKind.isThreadData()) {
OutStreamer->SwitchSection(TheSection);
- EmitAlignment(Alignment, GV);
- OutStreamer->EmitLabel(MangSym);
+ emitAlignment(Alignment, GV);
+ OutStreamer->emitLabel(MangSym);
- EmitGlobalConstant(GV->getParent()->getDataLayout(),
+ emitGlobalConstant(GV->getParent()->getDataLayout(),
GV->getInitializer());
}
@@ -606,18 +613,18 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
OutStreamer->SwitchSection(TLVSect);
// Emit the linkage here.
- EmitLinkage(GV, GVSym);
- OutStreamer->EmitLabel(GVSym);
+ emitLinkage(GV, GVSym);
+ OutStreamer->emitLabel(GVSym);
// Three pointers in size:
// - __tlv_bootstrap - used to make sure support exists
// - spare pointer, used when mapped by the runtime
// - pointer to mangled symbol above with initializer
unsigned PtrSize = DL.getPointerTypeSize(GV->getType());
- OutStreamer->EmitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"),
+ OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"),
PtrSize);
- OutStreamer->EmitIntValue(0, PtrSize);
- OutStreamer->EmitSymbolValue(MangSym, PtrSize);
+ OutStreamer->emitIntValue(0, PtrSize);
+ OutStreamer->emitSymbolValue(MangSym, PtrSize);
OutStreamer->AddBlankLine();
return;
@@ -627,12 +634,15 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
OutStreamer->SwitchSection(TheSection);
- EmitLinkage(GV, EmittedInitSym);
- EmitAlignment(Alignment, GV);
+ emitLinkage(GV, EmittedInitSym);
+ emitAlignment(Alignment, GV);
- OutStreamer->EmitLabel(EmittedInitSym);
+ OutStreamer->emitLabel(EmittedInitSym);
+ MCSymbol *LocalAlias = getSymbolPreferLocal(*GV);
+ if (LocalAlias != EmittedInitSym)
+ OutStreamer->emitLabel(LocalAlias);
- EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
+ emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
if (MAI->hasDotTypeDotSizeDirective())
// .size foo, 42
@@ -646,13 +656,15 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
///
/// \p Value - The value to emit.
/// \p Size - The size of the integer (in bytes) to emit.
-void AsmPrinter::EmitDebugValue(const MCExpr *Value, unsigned Size) const {
- OutStreamer->EmitValue(Value, Size);
+void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
+ OutStreamer->emitValue(Value, Size);
}
+void AsmPrinter::emitFunctionHeaderComment() {}
+
/// EmitFunctionHeader - This method emits the header for the current
/// function.
-void AsmPrinter::EmitFunctionHeader() {
+void AsmPrinter::emitFunctionHeader() {
const Function &F = MF->getFunction();
if (isVerbose())
@@ -661,29 +673,32 @@ void AsmPrinter::EmitFunctionHeader() {
<< GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n';
// Print out constants referenced by the function
- EmitConstantPool();
+ emitConstantPool();
// Print the 'header' of function.
- OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(&F, TM));
- EmitVisibility(CurrentFnSym, F.getVisibility());
+ MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM));
+ OutStreamer->SwitchSection(MF->getSection());
- if (MAI->needsFunctionDescriptors() &&
- F.getLinkage() != GlobalValue::InternalLinkage)
- EmitLinkage(&F, CurrentFnDescSym);
+ if (!MAI->hasVisibilityOnlyWithLinkage())
+ emitVisibility(CurrentFnSym, F.getVisibility());
- EmitLinkage(&F, CurrentFnSym);
+ if (MAI->needsFunctionDescriptors())
+ emitLinkage(&F, CurrentFnDescSym);
+
+ emitLinkage(&F, CurrentFnSym);
if (MAI->hasFunctionAlignment())
- EmitAlignment(MF->getAlignment(), &F);
+ emitAlignment(MF->getAlignment(), &F);
if (MAI->hasDotTypeDotSizeDirective())
- OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
+ OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
if (F.hasFnAttribute(Attribute::Cold))
- OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_Cold);
+ OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold);
if (isVerbose()) {
F.printAsOperand(OutStreamer->GetCommentOS(),
/*PrintType=*/false, F.getParent());
+ emitFunctionHeaderComment();
OutStreamer->GetCommentOS() << '\n';
}
@@ -695,14 +710,14 @@ void AsmPrinter::EmitFunctionHeader() {
// and use the .alt_entry attribute to mark the function's real entry point
// as an alternative entry point to the prefix-data symbol.
MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol();
- OutStreamer->EmitLabel(PrefixSym);
+ OutStreamer->emitLabel(PrefixSym);
- EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
+ emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
// Emit an .alt_entry directive for the actual function symbol.
- OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
+ OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
} else {
- EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
+ emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
}
}
@@ -719,7 +734,7 @@ void AsmPrinter::EmitFunctionHeader() {
if (PatchableFunctionPrefix) {
CurrentPatchableFunctionEntrySym =
OutContext.createLinkerPrivateTempSymbol();
- OutStreamer->EmitLabel(CurrentPatchableFunctionEntrySym);
+ OutStreamer->emitLabel(CurrentPatchableFunctionEntrySym);
emitNops(PatchableFunctionPrefix);
} else if (PatchableFunctionEntry) {
// May be reassigned when emitting the body, to reference the label after
@@ -728,32 +743,24 @@ void AsmPrinter::EmitFunctionHeader() {
}
// Emit the function descriptor. This is a virtual function to allow targets
- // to emit their specific function descriptor.
+ // to emit their specific function descriptor. Right now it is only used by
+ // the AIX target. The PowerPC 64-bit V1 ELF target also uses function
+ // descriptors and should be converted to use this hook as well.
if (MAI->needsFunctionDescriptors())
- EmitFunctionDescriptor();
+ emitFunctionDescriptor();
// Emit the CurrentFnSym. This is a virtual function to allow targets to do
// their wild and crazy things as required.
- EmitFunctionEntryLabel();
-
- // If the function had address-taken blocks that got deleted, then we have
- // references to the dangling symbols. Emit them at the start of the function
- // so that we don't get references to undefined symbols.
- std::vector<MCSymbol*> DeadBlockSyms;
- MMI->takeDeletedSymbolsForFunction(&F, DeadBlockSyms);
- for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) {
- OutStreamer->AddComment("Address taken block that was later removed");
- OutStreamer->EmitLabel(DeadBlockSyms[i]);
- }
+ emitFunctionEntryLabel();
if (CurrentFnBegin) {
if (MAI->useAssignmentForEHBegin()) {
MCSymbol *CurPos = OutContext.createTempSymbol();
- OutStreamer->EmitLabel(CurPos);
- OutStreamer->EmitAssignment(CurrentFnBegin,
+ OutStreamer->emitLabel(CurPos);
+ OutStreamer->emitAssignment(CurrentFnBegin,
MCSymbolRefExpr::create(CurPos, OutContext));
} else {
- OutStreamer->EmitLabel(CurrentFnBegin);
+ OutStreamer->emitLabel(CurrentFnBegin);
}
}
@@ -766,12 +773,12 @@ void AsmPrinter::EmitFunctionHeader() {
// Emit the prologue data.
if (F.hasPrologueData())
- EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData());
+ emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData());
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
/// function. This can be overridden by targets as required to do custom stuff.
-void AsmPrinter::EmitFunctionEntryLabel() {
+void AsmPrinter::emitFunctionEntryLabel() {
CurrentFnSym->redefineIfPossible();
// The function label could have already been emitted if two symbols end up
@@ -783,7 +790,13 @@ void AsmPrinter::EmitFunctionEntryLabel() {
report_fatal_error("'" + Twine(CurrentFnSym->getName()) +
"' label emitted multiple times to assembly file");
- return OutStreamer->EmitLabel(CurrentFnSym);
+ OutStreamer->emitLabel(CurrentFnSym);
+
+ if (TM.getTargetTriple().isOSBinFormatELF()) {
+ MCSymbol *Sym = getSymbolPreferLocal(MF->getFunction());
+ if (Sym != CurrentFnSym)
+ OutStreamer->emitLabel(Sym);
+ }
}
/// emitComments - Pretty-print comments for instructions.
@@ -863,7 +876,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
OS << " <- ";
// The second operand is only an offset if it's an immediate.
- bool MemLoc = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
+ bool MemLoc = MI->isIndirectDebugValue();
int64_t Offset = MemLoc ? MI->getOperand(1).getImm() : 0;
const DIExpression *Expr = MI->getDebugExpression();
if (Expr->getNumElements()) {
@@ -882,11 +895,11 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
}
// Register or immediate value. Register 0 means undef.
- if (MI->getOperand(0).isFPImm()) {
- APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
- if (MI->getOperand(0).getFPImm()->getType()->isFloatTy()) {
+ if (MI->getDebugOperand(0).isFPImm()) {
+ APFloat APF = APFloat(MI->getDebugOperand(0).getFPImm()->getValueAPF());
+ if (MI->getDebugOperand(0).getFPImm()->getType()->isFloatTy()) {
OS << (double)APF.convertToFloat();
- } else if (MI->getOperand(0).getFPImm()->getType()->isDoubleTy()) {
+ } else if (MI->getDebugOperand(0).getFPImm()->getType()->isDoubleTy()) {
OS << APF.convertToDouble();
} else {
// There is no good way to print long double. Convert a copy to
@@ -896,23 +909,23 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
&ignored);
OS << "(long double) " << APF.convertToDouble();
}
- } else if (MI->getOperand(0).isImm()) {
- OS << MI->getOperand(0).getImm();
- } else if (MI->getOperand(0).isCImm()) {
- MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
- } else if (MI->getOperand(0).isTargetIndex()) {
- auto Op = MI->getOperand(0);
+ } else if (MI->getDebugOperand(0).isImm()) {
+ OS << MI->getDebugOperand(0).getImm();
+ } else if (MI->getDebugOperand(0).isCImm()) {
+ MI->getDebugOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
+ } else if (MI->getDebugOperand(0).isTargetIndex()) {
+ auto Op = MI->getDebugOperand(0);
OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
return true;
} else {
- unsigned Reg;
- if (MI->getOperand(0).isReg()) {
- Reg = MI->getOperand(0).getReg();
+ Register Reg;
+ if (MI->getDebugOperand(0).isReg()) {
+ Reg = MI->getDebugOperand(0).getReg();
} else {
- assert(MI->getOperand(0).isFI() && "Unknown operand type");
+ assert(MI->getDebugOperand(0).isFI() && "Unknown operand type");
const TargetFrameLowering *TFI = AP.MF->getSubtarget().getFrameLowering();
- Offset += TFI->getFrameIndexReference(*AP.MF,
- MI->getOperand(0).getIndex(), Reg);
+ Offset += TFI->getFrameIndexReference(
+ *AP.MF, MI->getDebugOperand(0).getIndex(), Reg);
MemLoc = true;
}
if (Reg == 0) {
@@ -1006,7 +1019,7 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
int FrameOffset = MI.getOperand(1).getImm();
// Emit a symbol assignment.
- OutStreamer->EmitAssignment(FrameAllocSym,
+ OutStreamer->emitAssignment(FrameAllocSym,
MCConstantExpr::create(FrameOffset, OutContext));
}
@@ -1029,15 +1042,15 @@ void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
const MCSymbol *FunctionSymbol = getFunctionBegin();
uint64_t StackSize = FrameInfo.getStackSize();
- OutStreamer->EmitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());
- OutStreamer->EmitULEB128IntValue(StackSize);
+ OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());
+ OutStreamer->emitULEB128IntValue(StackSize);
OutStreamer->PopSection();
}
-static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
- MachineModuleInfo *MMI) {
- if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo())
+static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF) {
+ MachineModuleInfo &MMI = MF.getMMI();
+ if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI.hasDebugInfo())
return true;
// We might emit an EH table that uses function begin and end labels even if
@@ -1050,11 +1063,11 @@ static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
/// EmitFunctionBody - This method emits the body and trailer for a
/// function.
-void AsmPrinter::EmitFunctionBody() {
- EmitFunctionHeader();
+void AsmPrinter::emitFunctionBody() {
+ emitFunctionHeader();
// Emit target-specific gunk before the function body.
- EmitFunctionBodyStart();
+ emitFunctionBodyStart();
bool ShouldPrintDebugScopes = MMI->hasDebugInfo();
@@ -1079,9 +1092,10 @@ void AsmPrinter::EmitFunctionBody() {
// Print out code for the function.
bool HasAnyRealCode = false;
int NumInstsInFunction = 0;
+
for (auto &MBB : *MF) {
// Print a label for the basic block.
- EmitBasicBlockStart(MBB);
+ emitBasicBlockStart(MBB);
for (auto &MI : MBB) {
// Print the assembly for the instruction.
if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
@@ -1092,7 +1106,7 @@ void AsmPrinter::EmitFunctionBody() {
// If there is a pre-instruction symbol, emit a label for it here.
if (MCSymbol *S = MI.getPreInstrSymbol())
- OutStreamer->EmitLabel(S);
+ OutStreamer->emitLabel(S);
if (ShouldPrintDebugScopes) {
for (const HandlerInfo &HI : Handlers) {
@@ -1116,22 +1130,22 @@ void AsmPrinter::EmitFunctionBody() {
case TargetOpcode::ANNOTATION_LABEL:
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
- OutStreamer->EmitLabel(MI.getOperand(0).getMCSymbol());
+ OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());
break;
case TargetOpcode::INLINEASM:
case TargetOpcode::INLINEASM_BR:
- EmitInlineAsm(&MI);
+ emitInlineAsm(&MI);
break;
case TargetOpcode::DBG_VALUE:
if (isVerbose()) {
if (!emitDebugValueComment(&MI, *this))
- EmitInstruction(&MI);
+ emitInstruction(&MI);
}
break;
case TargetOpcode::DBG_LABEL:
if (isVerbose()) {
if (!emitDebugLabelComment(&MI, *this))
- EmitInstruction(&MI);
+ emitInstruction(&MI);
}
break;
case TargetOpcode::IMPLICIT_DEF:
@@ -1141,13 +1155,13 @@ void AsmPrinter::EmitFunctionBody() {
if (isVerbose()) emitKill(&MI, *this);
break;
default:
- EmitInstruction(&MI);
+ emitInstruction(&MI);
break;
}
// If there is a post-instruction symbol, emit a label for it here.
if (MCSymbol *S = MI.getPostInstrSymbol())
- OutStreamer->EmitLabel(S);
+ OutStreamer->emitLabel(S);
if (ShouldPrintDebugScopes) {
for (const HandlerInfo &HI : Handlers) {
@@ -1159,7 +1173,44 @@ void AsmPrinter::EmitFunctionBody() {
}
}
- EmitBasicBlockEnd(MBB);
+ // We need a temporary symbol for the end of this basic block, if either we
+ // have BBLabels enabled and we want to emit size directive for the BBs, or
+ // if this basic blocks marks the end of a section (except the section
+ // containing the entry basic block as the end symbol for that section is
+ // CurrentFnEnd).
+ MCSymbol *CurrentBBEnd = nullptr;
+ if ((MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels()) ||
+ (MBB.isEndSection() && !MBB.sameSection(&MF->front()))) {
+ CurrentBBEnd = OutContext.createTempSymbol();
+ OutStreamer->emitLabel(CurrentBBEnd);
+ }
+
+ // Helper for emitting the size directive associated with a basic block
+ // symbol.
+ auto emitELFSizeDirective = [&](MCSymbol *SymForSize) {
+ assert(CurrentBBEnd && "Basicblock end symbol not set!");
+ const MCExpr *SizeExp = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(CurrentBBEnd, OutContext),
+ MCSymbolRefExpr::create(SymForSize, OutContext), OutContext);
+ OutStreamer->emitELFSize(SymForSize, SizeExp);
+ };
+
+ // Emit size directive for the size of each basic block, if BBLabels is
+ // enabled.
+ if (MAI->hasDotTypeDotSizeDirective() && MF->hasBBLabels())
+ emitELFSizeDirective(MBB.getSymbol());
+
+ // Emit size directive for the size of each basic block section once we
+ // get to the end of that section.
+ if (MBB.isEndSection()) {
+ if (!MBB.sameSection(&MF->front())) {
+ if (MAI->hasDotTypeDotSizeDirective())
+ emitELFSizeDirective(CurrentSectionBeginSym);
+ MBBSectionRanges[MBB.getSectionIDNum()] =
+ MBBSectionRange{CurrentSectionBeginSym, CurrentBBEnd};
+ }
+ }
+ emitBasicBlockEnd(MBB);
}
EmittedInsts += NumInstsInFunction;
@@ -1192,6 +1243,9 @@ void AsmPrinter::EmitFunctionBody() {
}
}
+ // Switch to the original section in case basic block sections was used.
+ OutStreamer->SwitchSection(MF->getSection());
+
const Function &F = MF->getFunction();
for (const auto &BB : F) {
if (!BB.hasAddressTaken())
@@ -1200,17 +1254,17 @@ void AsmPrinter::EmitFunctionBody() {
if (Sym->isDefined())
continue;
OutStreamer->AddComment("Address of block that was removed by CodeGen");
- OutStreamer->EmitLabel(Sym);
+ OutStreamer->emitLabel(Sym);
}
// Emit target-specific gunk after the function body.
- EmitFunctionBodyEnd();
+ emitFunctionBodyEnd();
- if (needFuncLabelsForEHOrDebugInfo(*MF, MMI) ||
+ if (needFuncLabelsForEHOrDebugInfo(*MF) ||
MAI->hasDotTypeDotSizeDirective()) {
// Create a symbol for the end of function.
CurrentFnEnd = createTempSymbol("func_end");
- OutStreamer->EmitLabel(CurrentFnEnd);
+ OutStreamer->emitLabel(CurrentFnEnd);
}
// If the target wants a .size directive for the size of the function, emit
@@ -1230,8 +1284,11 @@ void AsmPrinter::EmitFunctionBody() {
HI.Handler->markFunctionEnd();
}
+ MBBSectionRanges[MF->front().getSectionIDNum()] =
+ MBBSectionRange{CurrentFnBegin, CurrentFnEnd};
+
// Print out jump tables referenced by the function.
- EmitJumpTableInfo();
+ emitJumpTableInfo();
// Emit post-function debug and/or EH information.
for (const HandlerInfo &HI : Handlers) {
@@ -1327,7 +1384,7 @@ void AsmPrinter::emitGlobalGOTEquivs() {
GlobalGOTEquivs.clear();
for (auto *GV : FailedCandidates)
- EmitGlobalVariable(GV);
+ emitGlobalVariable(GV);
}
void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
@@ -1335,9 +1392,9 @@ void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
MCSymbol *Name = getSymbol(&GIS);
if (GIS.hasExternalLinkage() || !MAI->getWeakRefDirective())
- OutStreamer->EmitSymbolAttribute(Name, MCSA_Global);
+ OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage())
- OutStreamer->EmitSymbolAttribute(Name, MCSA_WeakReference);
+ OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
else
assert(GIS.hasLocalLinkage() && "Invalid alias or ifunc linkage");
@@ -1354,19 +1411,22 @@ void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
// Set the symbol type to function if the alias has a function type.
// This affects codegen when the aliasee is not a function.
if (IsFunction)
- OutStreamer->EmitSymbolAttribute(Name, isa<GlobalIFunc>(GIS)
+ OutStreamer->emitSymbolAttribute(Name, isa<GlobalIFunc>(GIS)
? MCSA_ELF_TypeIndFunction
: MCSA_ELF_TypeFunction);
- EmitVisibility(Name, GIS.getVisibility());
+ emitVisibility(Name, GIS.getVisibility());
const MCExpr *Expr = lowerConstant(GIS.getIndirectSymbol());
if (isa<GlobalAlias>(&GIS) && MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr))
- OutStreamer->EmitSymbolAttribute(Name, MCSA_AltEntry);
+ OutStreamer->emitSymbolAttribute(Name, MCSA_AltEntry);
// Emit the directives as assignments aka .set:
- OutStreamer->EmitAssignment(Name, Expr);
+ OutStreamer->emitAssignment(Name, Expr);
+ MCSymbol *LocalAlias = getSymbolPreferLocal(GIS);
+ if (LocalAlias != Name)
+ OutStreamer->emitAssignment(LocalAlias, Expr);
if (auto *GA = dyn_cast<GlobalAlias>(&GIS)) {
// If the aliasee does not correspond to a symbol in the output, i.e. the
@@ -1384,7 +1444,7 @@ void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
}
}
-void AsmPrinter::emitRemarksSection(RemarkStreamer &RS) {
+void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
if (!RS.needsSection())
return;
@@ -1409,7 +1469,7 @@ void AsmPrinter::emitRemarksSection(RemarkStreamer &RS) {
OutContext.getObjectFileInfo()->getRemarksSection();
OutStreamer->SwitchSection(RemarksSection);
- OutStreamer->EmitBinaryData(OS.str());
+ OutStreamer->emitBinaryData(OS.str());
}
bool AsmPrinter::doFinalization(Module &M) {
@@ -1426,31 +1486,51 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit global variables.
for (const auto &G : M.globals())
- EmitGlobalVariable(&G);
+ emitGlobalVariable(&G);
// Emit remaining GOT equivalent globals.
emitGlobalGOTEquivs();
- // Emit visibility info for declarations
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+
+ // Emit linkage(XCOFF) and visibility info for declarations
for (const Function &F : M) {
if (!F.isDeclarationForLinker())
continue;
- GlobalValue::VisibilityTypes V = F.getVisibility();
- if (V == GlobalValue::DefaultVisibility)
- continue;
MCSymbol *Name = getSymbol(&F);
- EmitVisibility(Name, V, false);
+ // Function getSymbol gives us the function descriptor symbol for XCOFF.
+
+ if (!TM.getTargetTriple().isOSBinFormatXCOFF()) {
+ GlobalValue::VisibilityTypes V = F.getVisibility();
+ if (V == GlobalValue::DefaultVisibility)
+ continue;
+
+ emitVisibility(Name, V, false);
+ continue;
+ }
+
+ if (F.isIntrinsic())
+ continue;
+
+ // Handle the XCOFF case.
+ // Variable `Name` is the function descriptor symbol (see above). Get the
+ // function entry point symbol.
+ MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(&F, TM);
+ if (cast<MCSymbolXCOFF>(FnEntryPointSym)->hasRepresentedCsectSet())
+ // Emit linkage for the function entry point.
+ emitLinkage(&F, FnEntryPointSym);
+
+ // Emit linkage for the function descriptor.
+ emitLinkage(&F, Name);
}
// Emit the remarks section contents.
// FIXME: Figure out when is the safest time to emit this section. It should
// not come after debug info.
- if (RemarkStreamer *RS = M.getContext().getRemarkStreamer())
+ if (remarks::RemarkStreamer *RS = M.getContext().getMainRemarkStreamer())
emitRemarksSection(*RS);
- const TargetLoweringObjectFile &TLOF = getObjFileLowering();
-
TLOF.emitModuleMetadata(*OutStreamer, M);
if (TM.getTargetTriple().isOSBinFormatELF()) {
@@ -1462,10 +1542,10 @@ bool AsmPrinter::doFinalization(Module &M) {
OutStreamer->SwitchSection(TLOF.getDataSection());
const DataLayout &DL = M.getDataLayout();
- EmitAlignment(Align(DL.getPointerSize()));
+ emitAlignment(Align(DL.getPointerSize()));
for (const auto &Stub : Stubs) {
- OutStreamer->EmitLabel(Stub.first);
- OutStreamer->EmitSymbolValue(Stub.second.getPointer(),
+ OutStreamer->emitLabel(Stub.first);
+ OutStreamer->emitSymbolValue(Stub.second.getPointer(),
DL.getPointerSize());
}
}
@@ -1489,10 +1569,10 @@ bool AsmPrinter::doFinalization(Module &M) {
COFF::IMAGE_SCN_LNK_COMDAT,
SectionKind::getReadOnly(), Stub.first->getName(),
COFF::IMAGE_COMDAT_SELECT_ANY));
- EmitAlignment(Align(DL.getPointerSize()));
- OutStreamer->EmitSymbolAttribute(Stub.first, MCSA_Global);
- OutStreamer->EmitLabel(Stub.first);
- OutStreamer->EmitSymbolValue(Stub.second.getPointer(),
+ emitAlignment(Align(DL.getPointerSize()));
+ OutStreamer->emitSymbolAttribute(Stub.first, MCSA_Global);
+ OutStreamer->emitLabel(Stub.first);
+ OutStreamer->emitSymbolValue(Stub.second.getPointer(),
DL.getPointerSize());
}
}
@@ -1518,7 +1598,7 @@ bool AsmPrinter::doFinalization(Module &M) {
for (const auto &GO : M.global_objects()) {
if (!GO.hasExternalWeakLinkage())
continue;
- OutStreamer->EmitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference);
+ OutStreamer->emitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference);
}
}
@@ -1549,25 +1629,25 @@ bool AsmPrinter::doFinalization(Module &M) {
MP->finishAssembly(M, *MI, *this);
// Emit llvm.ident metadata in an '.ident' directive.
- EmitModuleIdents(M);
+ emitModuleIdents(M);
// Emit bytes for llvm.commandline metadata.
- EmitModuleCommandLines(M);
+ emitModuleCommandLines(M);
// Emit __morestack address if needed for indirect calls.
if (MMI->usesMorestackAddr()) {
- unsigned Align = 1;
+ Align Alignment(1);
MCSection *ReadOnlySection = getObjFileLowering().getSectionForConstant(
getDataLayout(), SectionKind::getReadOnly(),
- /*C=*/nullptr, Align);
+ /*C=*/nullptr, Alignment);
OutStreamer->SwitchSection(ReadOnlySection);
MCSymbol *AddrSymbol =
OutContext.getOrCreateSymbol(StringRef("__morestack_addr"));
- OutStreamer->EmitLabel(AddrSymbol);
+ OutStreamer->emitLabel(AddrSymbol);
unsigned PtrSize = MAI->getCodePointerSize();
- OutStreamer->EmitSymbolValue(GetExternalSymbolSymbol("__morestack"),
+ OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("__morestack"),
PtrSize);
}
@@ -1599,7 +1679,7 @@ bool AsmPrinter::doFinalization(Module &M) {
OS.flush();
if (!Flags.empty()) {
OutStreamer->SwitchSection(TLOF.getDrectveSection());
- OutStreamer->EmitBytes(Flags);
+ OutStreamer->emitBytes(Flags);
}
Flags.clear();
}
@@ -1625,7 +1705,7 @@ bool AsmPrinter::doFinalization(Module &M) {
if (!Flags.empty()) {
OutStreamer->SwitchSection(TLOF.getDrectveSection());
- OutStreamer->EmitBytes(Flags);
+ OutStreamer->emitBytes(Flags);
}
Flags.clear();
}
@@ -1635,12 +1715,12 @@ bool AsmPrinter::doFinalization(Module &M) {
if (TM.Options.EmitAddrsig) {
// Emit address-significance attributes for all globals.
- OutStreamer->EmitAddrsig();
+ OutStreamer->emitAddrsig();
for (const GlobalValue &GV : M.global_values())
if (!GV.use_empty() && !GV.isThreadLocal() &&
!GV.hasDLLImportStorageClass() && !GV.getName().startswith("llvm.") &&
!GV.hasAtLeastLocalUnnamedAddr())
- OutStreamer->EmitAddrsigSym(getSymbol(&GV));
+ OutStreamer->emitAddrsigSym(getSymbol(&GV));
}
// Emit symbol partition specifications (ELF only).
@@ -1651,11 +1731,12 @@ bool AsmPrinter::doFinalization(Module &M) {
GV.getVisibility() != GlobalValue::DefaultVisibility)
continue;
- OutStreamer->SwitchSection(OutContext.getELFSection(
- ".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0, "", ++UniqueID));
- OutStreamer->EmitBytes(GV.getPartition());
- OutStreamer->EmitZeros(1);
- OutStreamer->EmitValue(
+ OutStreamer->SwitchSection(
+ OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0,
+ "", ++UniqueID, nullptr));
+ OutStreamer->emitBytes(GV.getPartition());
+ OutStreamer->emitZeros(1);
+ OutStreamer->emitValue(
MCSymbolRefExpr::create(getSymbol(&GV), OutContext),
MAI->getCodePointerSize());
}
@@ -1663,7 +1744,7 @@ bool AsmPrinter::doFinalization(Module &M) {
// Allow the target to emit any magic that it wants at the end of the file,
// after everything else has gone out.
- EmitEndOfAsmFile(M);
+ emitEndOfAsmFile(M);
MMI = nullptr;
@@ -1686,30 +1767,31 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
const Function &F = MF.getFunction();
// Get the function symbol.
- if (MAI->needsFunctionDescriptors()) {
- assert(TM.getTargetTriple().isOSAIX() && "Function descriptor is only"
- " supported on AIX.");
+ if (!MAI->needsFunctionDescriptors()) {
+ CurrentFnSym = getSymbol(&MF.getFunction());
+ } else {
+ assert(TM.getTargetTriple().isOSAIX() &&
+ "Only AIX uses the function descriptor hooks.");
+ // AIX is unique here in that the name of the symbol emitted for the
+ // function body does not have the same name as the source function's
+ // C-linkage name.
assert(CurrentFnDescSym && "The function descriptor symbol needs to be"
- " initalized first.");
+ " initalized first.");
// Get the function entry point symbol.
- CurrentFnSym =
- OutContext.getOrCreateSymbol("." + CurrentFnDescSym->getName());
-
- MCSectionXCOFF *FnEntryPointSec =
- cast<MCSectionXCOFF>(getObjFileLowering().SectionForGlobal(&F, TM));
- // Set the containing csect.
- cast<MCSymbolXCOFF>(CurrentFnSym)->setContainingCsect(FnEntryPointSec);
- } else {
- CurrentFnSym = getSymbol(&MF.getFunction());
+ CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&F, TM);
}
CurrentFnSymForSize = CurrentFnSym;
CurrentFnBegin = nullptr;
+ CurrentSectionBeginSym = nullptr;
+ MBBSectionRanges.clear();
CurExceptionSym = nullptr;
bool NeedsLocalForSize = MAI->needsLocalForSize();
if (F.hasFnAttribute("patchable-function-entry") ||
- needFuncLabelsForEHOrDebugInfo(MF, MMI) || NeedsLocalForSize ||
+ F.hasFnAttribute("function-instrument") ||
+ F.hasFnAttribute("xray-instruction-threshold") ||
+ needFuncLabelsForEHOrDebugInfo(MF) || NeedsLocalForSize ||
MF.getTarget().Options.EmitStackSizeSection) {
CurrentFnBegin = createTempSymbol("func_begin");
if (NeedsLocalForSize)
@@ -1717,13 +1799,6 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
}
ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
- PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
- MBFI = (PSI && PSI->hasProfileSummary()) ?
- // ORE conditionally computes MBFI. If available, use it, otherwise
- // request it.
- (ORE->getBFI() ? ORE->getBFI() :
- &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()) :
- nullptr;
}
namespace {
@@ -1731,10 +1806,10 @@ namespace {
// Keep track the alignment, constpool entries per Section.
struct SectionCPs {
MCSection *S;
- unsigned Alignment;
+ Align Alignment;
SmallVector<unsigned, 4> CPEs;
- SectionCPs(MCSection *s, unsigned a) : S(s), Alignment(a) {}
+ SectionCPs(MCSection *s, Align a) : S(s), Alignment(a) {}
};
} // end anonymous namespace
@@ -1743,7 +1818,7 @@ namespace {
/// representations of the constants in the constant pool MCP. This is
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
-void AsmPrinter::EmitConstantPool() {
+void AsmPrinter::emitConstantPool() {
const MachineConstantPool *MCP = MF->getConstantPool();
const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
if (CP.empty()) return;
@@ -1753,7 +1828,7 @@ void AsmPrinter::EmitConstantPool() {
SmallVector<SectionCPs, 4> CPSections;
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
const MachineConstantPoolEntry &CPE = CP[i];
- unsigned Align = CPE.getAlignment();
+ Align Alignment = CPE.getAlign();
SectionKind Kind = CPE.getSectionKind(&getDataLayout());
@@ -1761,8 +1836,8 @@ void AsmPrinter::EmitConstantPool() {
if (!CPE.isMachineConstantPoolEntry())
C = CPE.Val.ConstVal;
- MCSection *S = getObjFileLowering().getSectionForConstant(getDataLayout(),
- Kind, C, Align);
+ MCSection *S = getObjFileLowering().getSectionForConstant(
+ getDataLayout(), Kind, C, Alignment);
// The number of sections are small, just do a linear search from the
// last section to the first.
@@ -1776,11 +1851,11 @@ void AsmPrinter::EmitConstantPool() {
}
if (!Found) {
SecIdx = CPSections.size();
- CPSections.push_back(SectionCPs(S, Align));
+ CPSections.push_back(SectionCPs(S, Alignment));
}
- if (Align > CPSections[SecIdx].Alignment)
- CPSections[SecIdx].Alignment = Align;
+ if (Alignment > CPSections[SecIdx].Alignment)
+ CPSections[SecIdx].Alignment = Alignment;
CPSections[SecIdx].CPEs.push_back(i);
}
@@ -1794,14 +1869,9 @@ void AsmPrinter::EmitConstantPool() {
if (!Sym->isUndefined())
continue;
- if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
- cast<MCSymbolXCOFF>(Sym)->setContainingCsect(
- cast<MCSectionXCOFF>(CPSections[i].S));
- }
-
if (CurSection != CPSections[i].S) {
OutStreamer->SwitchSection(CPSections[i].S);
- EmitAlignment(Align(CPSections[i].Alignment));
+ emitAlignment(Align(CPSections[i].Alignment));
CurSection = CPSections[i].S;
Offset = 0;
}
@@ -1809,25 +1879,24 @@ void AsmPrinter::EmitConstantPool() {
MachineConstantPoolEntry CPE = CP[CPI];
// Emit inter-object padding for alignment.
- unsigned AlignMask = CPE.getAlignment() - 1;
- unsigned NewOffset = (Offset + AlignMask) & ~AlignMask;
- OutStreamer->EmitZeros(NewOffset - Offset);
+ unsigned NewOffset = alignTo(Offset, CPE.getAlign());
+ OutStreamer->emitZeros(NewOffset - Offset);
Type *Ty = CPE.getType();
Offset = NewOffset + getDataLayout().getTypeAllocSize(Ty);
- OutStreamer->EmitLabel(Sym);
+ OutStreamer->emitLabel(Sym);
if (CPE.isMachineConstantPoolEntry())
- EmitMachineConstantPoolValue(CPE.Val.MachineCPVal);
+ emitMachineConstantPoolValue(CPE.Val.MachineCPVal);
else
- EmitGlobalConstant(getDataLayout(), CPE.Val.ConstVal);
+ emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal);
}
}
}
-/// EmitJumpTableInfo - Print assembly representations of the jump tables used
-/// by the current function to the current output stream.
-void AsmPrinter::EmitJumpTableInfo() {
+// Print assembly representations of the jump tables used by the current
+// function.
+void AsmPrinter::emitJumpTableInfo() {
const DataLayout &DL = MF->getDataLayout();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
if (!MJTI) return;
@@ -1848,12 +1917,12 @@ void AsmPrinter::EmitJumpTableInfo() {
OutStreamer->SwitchSection(ReadOnlySection);
}
- EmitAlignment(Align(MJTI->getEntryAlignment(DL)));
+ emitAlignment(Align(MJTI->getEntryAlignment(DL)));
// Jump tables in code sections are marked with a data_region directive
// where that's supported.
if (!JTInDiffSection)
- OutStreamer->EmitDataRegion(MCDR_DataRegionJT32);
+ OutStreamer->emitDataRegion(MCDR_DataRegionJT32);
for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
@@ -1876,7 +1945,7 @@ void AsmPrinter::EmitJumpTableInfo() {
// .set LJTSet, LBB32-base
const MCExpr *LHS =
MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
- OutStreamer->EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()),
+ OutStreamer->emitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()),
MCBinaryExpr::createSub(LHS, Base,
OutContext));
}
@@ -1890,25 +1959,21 @@ void AsmPrinter::EmitJumpTableInfo() {
// FIXME: This doesn't have to have any specific name, just any randomly
// named and numbered local label started with 'l' would work. Simplify
// GetJTISymbol.
- OutStreamer->EmitLabel(GetJTISymbol(JTI, true));
+ OutStreamer->emitLabel(GetJTISymbol(JTI, true));
MCSymbol* JTISymbol = GetJTISymbol(JTI);
- if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
- cast<MCSymbolXCOFF>(JTISymbol)->setContainingCsect(
- cast<MCSectionXCOFF>(TLOF.getSectionForJumpTable(F, TM)));
- }
- OutStreamer->EmitLabel(JTISymbol);
+ OutStreamer->emitLabel(JTISymbol);
for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii)
- EmitJumpTableEntry(MJTI, JTBBs[ii], JTI);
+ emitJumpTableEntry(MJTI, JTBBs[ii], JTI);
}
if (!JTInDiffSection)
- OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
+ OutStreamer->emitDataRegion(MCDR_DataRegionEnd);
}
/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the
/// current stream.
-void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
+void AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB,
unsigned UID) const {
assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block");
@@ -1930,7 +1995,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
// with a relocation as gp-relative, e.g.:
// .gprel32 LBB123
MCSymbol *MBBSym = MBB->getSymbol();
- OutStreamer->EmitGPRel32Value(MCSymbolRefExpr::create(MBBSym, OutContext));
+ OutStreamer->emitGPRel32Value(MCSymbolRefExpr::create(MBBSym, OutContext));
return;
}
@@ -1939,7 +2004,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
// with a relocation as gp-relative, e.g.:
// .gpdword LBB123
MCSymbol *MBBSym = MBB->getSymbol();
- OutStreamer->EmitGPRel64Value(MCSymbolRefExpr::create(MBBSym, OutContext));
+ OutStreamer->emitGPRel64Value(MCSymbolRefExpr::create(MBBSym, OutContext));
return;
}
@@ -1967,16 +2032,16 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
assert(Value && "Unknown entry kind!");
unsigned EntrySize = MJTI->getEntrySize(getDataLayout());
- OutStreamer->EmitValue(Value, EntrySize);
+ OutStreamer->emitValue(Value, EntrySize);
}
/// EmitSpecialLLVMGlobal - Check to see if the specified global is a
/// special global used by LLVM. If so, emit it and return true, otherwise
/// do nothing and return false.
-bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
+bool AsmPrinter::emitSpecialLLVMGlobal(const GlobalVariable *GV) {
if (GV->getName() == "llvm.used") {
if (MAI->hasNoDeadStrip()) // No need to emit this at all.
- EmitLLVMUsedList(cast<ConstantArray>(GV->getInitializer()));
+ emitLLVMUsedList(cast<ConstantArray>(GV->getInitializer()));
return true;
}
@@ -1990,14 +2055,14 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
assert(GV->hasInitializer() && "Not a special LLVM global!");
if (GV->getName() == "llvm.global_ctors") {
- EmitXXStructorList(GV->getParent()->getDataLayout(), GV->getInitializer(),
+ emitXXStructorList(GV->getParent()->getDataLayout(), GV->getInitializer(),
/* isCtor */ true);
return true;
}
if (GV->getName() == "llvm.global_dtors") {
- EmitXXStructorList(GV->getParent()->getDataLayout(), GV->getInitializer(),
+ emitXXStructorList(GV->getParent()->getDataLayout(), GV->getInitializer(),
/* isCtor */ false);
return true;
@@ -2008,13 +2073,13 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each
/// global in the specified llvm.used list.
-void AsmPrinter::EmitLLVMUsedList(const ConstantArray *InitList) {
+void AsmPrinter::emitLLVMUsedList(const ConstantArray *InitList) {
// Should be an array of 'i8*'.
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
const GlobalValue *GV =
dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());
if (GV)
- OutStreamer->EmitSymbolAttribute(getSymbol(GV), MCSA_NoDeadStrip);
+ OutStreamer->emitSymbolAttribute(getSymbol(GV), MCSA_NoDeadStrip);
}
}
@@ -2032,27 +2097,16 @@ struct Structor {
/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
/// priority.
-void AsmPrinter::EmitXXStructorList(const DataLayout &DL, const Constant *List,
+void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List,
bool isCtor) {
// Should be an array of '{ i32, void ()*, i8* }' structs. The first value is the
// init priority.
if (!isa<ConstantArray>(List)) return;
- // Sanity check the structors list.
- const ConstantArray *InitList = dyn_cast<ConstantArray>(List);
- if (!InitList) return; // Not an array!
- StructType *ETy = dyn_cast<StructType>(InitList->getType()->getElementType());
- if (!ETy || ETy->getNumElements() != 3 ||
- !isa<IntegerType>(ETy->getTypeAtIndex(0U)) ||
- !isa<PointerType>(ETy->getTypeAtIndex(1U)) ||
- !isa<PointerType>(ETy->getTypeAtIndex(2U)))
- return; // Not (int, ptr, ptr).
-
// Gather the structors in a form that's convenient for sorting by priority.
SmallVector<Structor, 8> Structors;
- for (Value *O : InitList->operands()) {
- ConstantStruct *CS = dyn_cast<ConstantStruct>(O);
- if (!CS) continue; // Malformed.
+ for (Value *O : cast<ConstantArray>(List)->operands()) {
+ auto *CS = cast<ConstantStruct>(O);
if (CS->getOperand(1)->isNullValue())
break; // Found a null terminator, skip the rest.
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
@@ -2090,12 +2144,12 @@ void AsmPrinter::EmitXXStructorList(const DataLayout &DL, const Constant *List,
: Obj.getStaticDtorSection(S.Priority, KeySym));
OutStreamer->SwitchSection(OutputSection);
if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())
- EmitAlignment(Align);
- EmitXXStructor(DL, S.Func);
+ emitAlignment(Align);
+ emitXXStructor(DL, S.Func);
}
}
-void AsmPrinter::EmitModuleIdents(Module &M) {
+void AsmPrinter::emitModuleIdents(Module &M) {
if (!MAI->hasIdentDirective())
return;
@@ -2105,12 +2159,12 @@ void AsmPrinter::EmitModuleIdents(Module &M) {
assert(N->getNumOperands() == 1 &&
"llvm.ident metadata entry can have only one operand");
const MDString *S = cast<MDString>(N->getOperand(0));
- OutStreamer->EmitIdent(S->getString());
+ OutStreamer->emitIdent(S->getString());
}
}
}
-void AsmPrinter::EmitModuleCommandLines(Module &M) {
+void AsmPrinter::emitModuleCommandLines(Module &M) {
MCSection *CommandLine = getObjFileLowering().getSectionForCommandLines();
if (!CommandLine)
return;
@@ -2121,14 +2175,14 @@ void AsmPrinter::EmitModuleCommandLines(Module &M) {
OutStreamer->PushSection();
OutStreamer->SwitchSection(CommandLine);
- OutStreamer->EmitZeros(1);
+ OutStreamer->emitZeros(1);
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
const MDNode *N = NMD->getOperand(i);
assert(N->getNumOperands() == 1 &&
"llvm.commandline metadata entry can have only one operand");
const MDString *S = cast<MDString>(N->getOperand(0));
- OutStreamer->EmitBytes(S->getString());
- OutStreamer->EmitZeros(1);
+ OutStreamer->emitBytes(S->getString());
+ OutStreamer->emitZeros(1);
}
OutStreamer->PopSection();
}
@@ -2139,29 +2193,23 @@ void AsmPrinter::EmitModuleCommandLines(Module &M) {
/// Emit a byte directive and value.
///
-void AsmPrinter::emitInt8(int Value) const {
- OutStreamer->EmitIntValue(Value, 1);
-}
+void AsmPrinter::emitInt8(int Value) const { OutStreamer->emitInt8(Value); }
/// Emit a short directive and value.
-void AsmPrinter::emitInt16(int Value) const {
- OutStreamer->EmitIntValue(Value, 2);
-}
+void AsmPrinter::emitInt16(int Value) const { OutStreamer->emitInt16(Value); }
/// Emit a long directive and value.
-void AsmPrinter::emitInt32(int Value) const {
- OutStreamer->EmitIntValue(Value, 4);
-}
+void AsmPrinter::emitInt32(int Value) const { OutStreamer->emitInt32(Value); }
/// Emit a long long directive and value.
void AsmPrinter::emitInt64(uint64_t Value) const {
- OutStreamer->EmitIntValue(Value, 8);
+ OutStreamer->emitInt64(Value);
}
/// Emit something like ".long Hi-Lo" where the size in bytes of the directive
/// is specified by Size and Hi/Lo specify the labels. This implicitly uses
/// .set if it avoids relocations.
-void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
+void AsmPrinter::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) const {
OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size);
}
@@ -2169,13 +2217,13 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
/// where the size in bytes of the directive is specified by Size and Label
/// specifies the label. This implicitly uses .set if it is available.
-void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
+void AsmPrinter::emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
unsigned Size,
bool IsSectionRelative) const {
if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) {
OutStreamer->EmitCOFFSecRel32(Label, Offset);
if (Size > 4)
- OutStreamer->EmitZeros(Size - 4);
+ OutStreamer->emitZeros(Size - 4);
return;
}
@@ -2185,7 +2233,7 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
Expr = MCBinaryExpr::createAdd(
Expr, MCConstantExpr::create(Offset, OutContext), OutContext);
- OutStreamer->EmitValue(Expr, Size);
+ OutStreamer->emitValue(Expr, Size);
}
//===----------------------------------------------------------------------===//
@@ -2194,17 +2242,17 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
// two boundary. If a global value is specified, and if that global has
// an explicit alignment requested, it will override the alignment request
// if required for correctness.
-void AsmPrinter::EmitAlignment(Align Alignment, const GlobalObject *GV) const {
+void AsmPrinter::emitAlignment(Align Alignment, const GlobalObject *GV) const {
if (GV)
Alignment = getGVAlignment(GV, GV->getParent()->getDataLayout(), Alignment);
- if (Alignment == Align::None())
+ if (Alignment == Align(1))
return; // 1-byte aligned: no need to emit alignment.
if (getCurrentSection()->getKind().isText())
- OutStreamer->EmitCodeAlignment(Alignment.value());
+ OutStreamer->emitCodeAlignment(Alignment.value());
else
- OutStreamer->EmitValueToAlignment(Alignment.value());
+ OutStreamer->emitValueToAlignment(Alignment.value());
}
//===----------------------------------------------------------------------===//
@@ -2232,23 +2280,22 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
}
switch (CE->getOpcode()) {
- default:
+ default: {
// If the code isn't optimized, there may be outstanding folding
// opportunities. Attempt to fold the expression using DataLayout as a
// last resort before giving up.
- if (Constant *C = ConstantFoldConstant(CE, getDataLayout()))
- if (C != CE)
- return lowerConstant(C);
+ Constant *C = ConstantFoldConstant(CE, getDataLayout());
+ if (C != CE)
+ return lowerConstant(C);
// Otherwise report the problem to the user.
- {
- std::string S;
- raw_string_ostream OS(S);
- OS << "Unsupported expression in static initializer: ";
- CE->printAsOperand(OS, /*PrintType=*/false,
- !MF ? nullptr : MF->getFunction().getParent());
- report_fatal_error(OS.str());
- }
+ std::string S;
+ raw_string_ostream OS(S);
+ OS << "Unsupported expression in static initializer: ";
+ CE->printAsOperand(OS, /*PrintType=*/false,
+ !MF ? nullptr : MF->getFunction().getParent());
+ report_fatal_error(OS.str());
+ }
case Instruction::GetElementPtr: {
// Generate a symbolic expression for the byte address
APInt OffsetAI(getDataLayout().getPointerTypeSizeInBits(CE->getType()), 0);
@@ -2434,7 +2481,7 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL,
// If this can be emitted with .ascii/.asciz, emit it as such.
if (CDS->isString())
- return AP.OutStreamer->EmitBytes(CDS->getAsString());
+ return AP.OutStreamer->emitBytes(CDS->getAsString());
// Otherwise, emit the values in successive locations.
unsigned ElementByteSize = CDS->getElementByteSize();
@@ -2443,7 +2490,7 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL,
if (AP.isVerbose())
AP.OutStreamer->GetCommentOS() << format("0x%" PRIx64 "\n",
CDS->getElementAsInteger(i));
- AP.OutStreamer->EmitIntValue(CDS->getElementAsInteger(i),
+ AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(i),
ElementByteSize);
}
} else {
@@ -2453,11 +2500,11 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL,
}
unsigned Size = DL.getTypeAllocSize(CDS->getType());
- unsigned EmittedSize = DL.getTypeAllocSize(CDS->getType()->getElementType()) *
- CDS->getNumElements();
+ unsigned EmittedSize =
+ DL.getTypeAllocSize(CDS->getElementType()) * CDS->getNumElements();
assert(EmittedSize <= Size && "Size cannot be less than EmittedSize!");
if (unsigned Padding = Size - EmittedSize)
- AP.OutStreamer->EmitZeros(Padding);
+ AP.OutStreamer->emitZeros(Padding);
}
static void emitGlobalConstantArray(const DataLayout &DL,
@@ -2488,7 +2535,7 @@ static void emitGlobalConstantVector(const DataLayout &DL,
unsigned EmittedSize = DL.getTypeAllocSize(CV->getType()->getElementType()) *
CV->getType()->getNumElements();
if (unsigned Padding = Size - EmittedSize)
- AP.OutStreamer->EmitZeros(Padding);
+ AP.OutStreamer->emitZeros(Padding);
}
static void emitGlobalConstantStruct(const DataLayout &DL,
@@ -2513,7 +2560,7 @@ static void emitGlobalConstantStruct(const DataLayout &DL,
// Insert padding - this may include padding to increase the size of the
// current field up to the ABI size (if the struct is not packed) as well
// as padding to ensure that the next field starts at the right offset.
- AP.OutStreamer->EmitZeros(PadSize);
+ AP.OutStreamer->emitZeros(PadSize);
}
assert(SizeSoFar == Layout->getSizeInBytes() &&
"Layout of constant struct may be incorrect!");
@@ -2545,22 +2592,22 @@ static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP) {
int Chunk = API.getNumWords() - 1;
if (TrailingBytes)
- AP.OutStreamer->EmitIntValue(p[Chunk--], TrailingBytes);
+ AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk--], TrailingBytes);
for (; Chunk >= 0; --Chunk)
- AP.OutStreamer->EmitIntValue(p[Chunk], sizeof(uint64_t));
+ AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t));
} else {
unsigned Chunk;
for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk)
- AP.OutStreamer->EmitIntValue(p[Chunk], sizeof(uint64_t));
+ AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t));
if (TrailingBytes)
- AP.OutStreamer->EmitIntValue(p[Chunk], TrailingBytes);
+ AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], TrailingBytes);
}
// Emit the tail padding for the long double.
const DataLayout &DL = AP.getDataLayout();
- AP.OutStreamer->EmitZeros(DL.getTypeAllocSize(ET) - DL.getTypeStoreSize(ET));
+ AP.OutStreamer->emitZeros(DL.getTypeAllocSize(ET) - DL.getTypeStoreSize(ET));
}
static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP) {
@@ -2591,9 +2638,10 @@ static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) {
// [chunk1][chunk2] ... [chunkN].
// The most significant chunk is chunkN and it should be emitted first.
// However, due to the alignment issue chunkN contains useless bits.
- // Realign the chunks so that they contain only useless information:
+ // Realign the chunks so that they contain only useful information:
// ExtraBits 0 1 (BitWidth / 64) - 1
// chu[nk1 chu][nk2 chu] ... [nkN-1 chunkN]
+ ExtraBitsSize = alignTo(ExtraBitsSize, 8);
ExtraBits = Realigned.getRawData()[0] &
(((uint64_t)-1) >> (64 - ExtraBitsSize));
Realigned.lshrInPlace(ExtraBitsSize);
@@ -2607,19 +2655,19 @@ static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) {
const uint64_t *RawData = Realigned.getRawData();
for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
uint64_t Val = DL.isBigEndian() ? RawData[e - i - 1] : RawData[i];
- AP.OutStreamer->EmitIntValue(Val, 8);
+ AP.OutStreamer->emitIntValue(Val, 8);
}
if (ExtraBitsSize) {
// Emit the extra bits after the 64-bits chunks.
// Emit a directive that fills the expected size.
- uint64_t Size = AP.getDataLayout().getTypeAllocSize(CI->getType());
+ uint64_t Size = AP.getDataLayout().getTypeStoreSize(CI->getType());
Size -= (BitWidth / 64) * 8;
assert(Size && Size * 8 >= ExtraBitsSize &&
(ExtraBits & (((uint64_t)-1) >> (64 - ExtraBitsSize)))
== ExtraBits && "Directive too small for extra bits.");
- AP.OutStreamer->EmitIntValue(ExtraBits, Size);
+ AP.OutStreamer->emitIntValue(ExtraBits, Size);
}
}
@@ -2726,30 +2774,32 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
BaseCV = dyn_cast<Constant>(CV->user_back());
if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
- return AP.OutStreamer->EmitZeros(Size);
+ return AP.OutStreamer->emitZeros(Size);
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- switch (Size) {
- case 1:
- case 2:
- case 4:
- case 8:
+ const uint64_t StoreSize = DL.getTypeStoreSize(CV->getType());
+
+ if (StoreSize < 8) {
if (AP.isVerbose())
AP.OutStreamer->GetCommentOS() << format("0x%" PRIx64 "\n",
CI->getZExtValue());
- AP.OutStreamer->EmitIntValue(CI->getZExtValue(), Size);
- return;
- default:
+ AP.OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize);
+ } else {
emitGlobalConstantLargeInt(CI, AP);
- return;
}
+
+ // Emit tail padding if needed
+ if (Size != StoreSize)
+ AP.OutStreamer->emitZeros(Size - StoreSize);
+
+ return;
}
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
return emitGlobalConstantFP(CFP, AP);
if (isa<ConstantPointerNull>(CV)) {
- AP.OutStreamer->EmitIntValue(0, Size);
+ AP.OutStreamer->emitIntValue(0, Size);
return;
}
@@ -2773,7 +2823,7 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
// to emit the value in chunks. Try to constant fold the value and emit it
// that way.
Constant *New = ConstantFoldConstant(CE, DL);
- if (New && New != CE)
+ if (New != CE)
return emitGlobalConstantImpl(DL, New, AP);
}
}
@@ -2791,22 +2841,22 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
if (AP.getObjFileLowering().supportIndirectSymViaGOTPCRel())
handleIndirectSymViaGOTPCRel(AP, &ME, BaseCV, Offset);
- AP.OutStreamer->EmitValue(ME, Size);
+ AP.OutStreamer->emitValue(ME, Size);
}
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
-void AsmPrinter::EmitGlobalConstant(const DataLayout &DL, const Constant *CV) {
+void AsmPrinter::emitGlobalConstant(const DataLayout &DL, const Constant *CV) {
uint64_t Size = DL.getTypeAllocSize(CV->getType());
if (Size)
emitGlobalConstantImpl(DL, CV, *this);
else if (MAI->hasSubsectionsViaSymbols()) {
// If the global has zero size, emit a single byte so that two labels don't
// look like they are at the same location.
- OutStreamer->EmitIntValue(0, 1);
+ OutStreamer->emitIntValue(0, 1);
}
}
-void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
+void AsmPrinter::emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
// Target doesn't support this yet!
llvm_unreachable("Target does not support EmitMachineConstantPoolValue");
}
@@ -2850,12 +2900,13 @@ MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
const DataLayout &DL = MF->getDataLayout();
SectionKind Kind = CPE.getSectionKind(&DL);
const Constant *C = CPE.Val.ConstVal;
- unsigned Align = CPE.Alignment;
+ Align Alignment = CPE.Alignment;
if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>(
- getObjFileLowering().getSectionForConstant(DL, Kind, C, Align))) {
+ getObjFileLowering().getSectionForConstant(DL, Kind, C,
+ Alignment))) {
if (MCSymbol *Sym = S->getCOMDATSymbol()) {
if (Sym->isUndefined())
- OutStreamer->EmitSymbolAttribute(Sym, MCSA_Global);
+ OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);
return Sym;
}
}
@@ -2957,10 +3008,10 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());
}
-/// EmitBasicBlockStart - This method prints the label for the specified
+/// emitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing
/// it if appropriate.
-void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) {
+void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
// End the previous funclet and start a new one.
if (MBB.isEHFuncletEntry()) {
for (const HandlerInfo &HI : Handlers) {
@@ -2971,8 +3022,8 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) {
// Emit an alignment directive for this block, if needed.
const Align Alignment = MBB.getAlignment();
- if (Alignment != Align::None())
- EmitAlignment(Alignment);
+ if (Alignment != Align(1))
+ emitAlignment(Alignment);
// If the block has its address taken, emit any labels that were used to
// reference the block. It is possible that there is more than one label
@@ -2987,7 +3038,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) {
// their corresponding BB's address taken in IR
if (BB->hasAddressTaken())
for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB))
- OutStreamer->EmitLabel(Sym);
+ OutStreamer->emitLabel(Sym);
}
// Print some verbose block comments.
@@ -3004,25 +3055,44 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) {
emitBasicBlockLoopComments(MBB, MLI, *this);
}
- // Print the main label for the block.
if (MBB.pred_empty() ||
- (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry() &&
- !MBB.hasLabelMustBeEmitted())) {
+ (!MF->hasBBLabels() && isBlockOnlyReachableByFallthrough(&MBB) &&
+ !MBB.isEHFuncletEntry() && !MBB.hasLabelMustBeEmitted())) {
if (isVerbose()) {
// NOTE: Want this comment at start of line, don't emit with AddComment.
OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",
false);
}
} else {
- if (isVerbose() && MBB.hasLabelMustBeEmitted())
+ if (isVerbose() && MBB.hasLabelMustBeEmitted()) {
OutStreamer->AddComment("Label of block must be emitted");
- OutStreamer->EmitLabel(MBB.getSymbol());
+ }
+ auto *BBSymbol = MBB.getSymbol();
+ // Switch to a new section if this basic block must begin a section.
+ if (MBB.isBeginSection()) {
+ OutStreamer->SwitchSection(
+ getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),
+ MBB, TM));
+ CurrentSectionBeginSym = BBSymbol;
+ }
+ OutStreamer->emitLabel(BBSymbol);
+ // With BB sections, each basic block must handle CFI information on its own
+ // if it begins a section.
+ if (MBB.isBeginSection())
+ for (const HandlerInfo &HI : Handlers)
+ HI.Handler->beginBasicBlock(MBB);
}
}
-void AsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) {}
+void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) {
+ // Check if CFI information needs to be updated for this MBB with basic block
+ // sections.
+ if (MBB.isEndSection())
+ for (const HandlerInfo &HI : Handlers)
+ HI.Handler->endBasicBlock(MBB);
+}
-void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
+void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility,
bool IsDefinition) const {
MCSymbolAttr Attr = MCSA_Invalid;
@@ -3040,7 +3110,7 @@ void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
}
if (Attr != MCSA_Invalid)
- OutStreamer->EmitSymbolAttribute(Sym, Attr);
+ OutStreamer->emitSymbolAttribute(Sym, Attr);
}
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
@@ -3048,6 +3118,10 @@ void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
/// the predecessor and this block is a fall-through.
bool AsmPrinter::
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
+ // With BasicBlock Sections, beginning of the section is not a fallthrough.
+ if (MBB->isBeginSection())
+ return false;
+
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
if (MBB->isEHPad() || MBB->pred_empty())
@@ -3097,11 +3171,10 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy &S) {
auto Name = S.getName();
- for (GCMetadataPrinterRegistry::iterator
- I = GCMetadataPrinterRegistry::begin(),
- E = GCMetadataPrinterRegistry::end(); I != E; ++I)
- if (Name == I->getName()) {
- std::unique_ptr<GCMetadataPrinter> GMP = I->instantiate();
+ for (const GCMetadataPrinterRegistry::entry &GCMetaPrinter :
+ GCMetadataPrinterRegistry::entries())
+ if (Name == GCMetaPrinter.getName()) {
+ std::unique_ptr<GCMetadataPrinter> GMP = GCMetaPrinter.instantiate();
GMP->S = &S;
auto IterBool = GCMap.insert(std::make_pair(&S, std::move(GMP)));
return IterBool.first->second.get();
@@ -3139,18 +3212,15 @@ void AsmPrinterHandler::markFunctionEnd() {}
// In the binary's "xray_instr_map" section, an array of these function entries
// describes each instrumentation point. When XRay patches your code, the index
// into this table will be given to your handler as a patch point identifier.
-void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out,
- const MCSymbol *CurrentFnSym) const {
- Out->EmitSymbolValue(Sled, Bytes);
- Out->EmitSymbolValue(CurrentFnSym, Bytes);
+void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out) const {
auto Kind8 = static_cast<uint8_t>(Kind);
- Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
- Out->EmitBinaryData(
+ Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
+ Out->emitBinaryData(
StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1));
- Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1));
+ Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1));
auto Padding = (4 * Bytes) - ((2 * Bytes) + 3);
assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size");
- Out->EmitZeros(Padding);
+ Out->emitZeros(Padding);
}
void AsmPrinter::emitXRayTable() {
@@ -3161,28 +3231,34 @@ void AsmPrinter::emitXRayTable() {
const Function &F = MF->getFunction();
MCSection *InstMap = nullptr;
MCSection *FnSledIndex = nullptr;
- if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) {
- auto Associated = dyn_cast<MCSymbolELF>(CurrentFnSym);
- assert(Associated != nullptr);
- auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;
- std::string GroupName;
+ const Triple &TT = TM.getTargetTriple();
+ // Use PC-relative addresses on all targets except MIPS (MIPS64 cannot use
+ // PC-relative addresses because R_MIPS_PC64 does not exist).
+ bool PCRel = !TT.isMIPS();
+ if (TT.isOSBinFormatELF()) {
+ auto LinkedToSym = cast<MCSymbolELF>(CurrentFnSym);
+ auto Flags = ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;
+ if (!PCRel)
+ Flags |= ELF::SHF_WRITE;
+ StringRef GroupName;
if (F.hasComdat()) {
Flags |= ELF::SHF_GROUP;
GroupName = F.getComdat()->getName();
}
-
- auto UniqueID = ++XRayFnUniqueID;
- InstMap =
- OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, Flags, 0,
- GroupName, UniqueID, Associated);
- FnSledIndex =
- OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0,
- GroupName, UniqueID, Associated);
+ InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
+ Flags, 0, GroupName,
+ MCSection::NonUniqueID, LinkedToSym);
+
+ if (!TM.Options.XRayOmitFunctionIndex)
+ FnSledIndex = OutContext.getELFSection(
+ "xray_fn_idx", ELF::SHT_PROGBITS, Flags | ELF::SHF_WRITE, 0,
+ GroupName, MCSection::NonUniqueID, LinkedToSym);
} else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
SectionKind::getReadOnlyWithRel());
- FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx", 0,
- SectionKind::getReadOnlyWithRel());
+ if (!TM.Options.XRayOmitFunctionIndex)
+ FnSledIndex = OutContext.getMachOSection(
+ "__DATA", "xray_fn_idx", 0, SectionKind::getReadOnlyWithRel());
} else {
llvm_unreachable("Unsupported target");
}
@@ -3192,23 +3268,46 @@ void AsmPrinter::emitXRayTable() {
// Now we switch to the instrumentation map section. Because this is done
// per-function, we are able to create an index entry that will represent the
// range of sleds associated with a function.
+ auto &Ctx = OutContext;
MCSymbol *SledsStart = OutContext.createTempSymbol("xray_sleds_start", true);
OutStreamer->SwitchSection(InstMap);
- OutStreamer->EmitLabel(SledsStart);
- for (const auto &Sled : Sleds)
- Sled.emit(WordSizeBytes, OutStreamer.get(), CurrentFnSym);
+ OutStreamer->emitLabel(SledsStart);
+ for (const auto &Sled : Sleds) {
+ if (PCRel) {
+ MCSymbol *Dot = Ctx.createTempSymbol();
+ OutStreamer->emitLabel(Dot);
+ OutStreamer->emitValueImpl(
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(Sled.Sled, Ctx),
+ MCSymbolRefExpr::create(Dot, Ctx), Ctx),
+ WordSizeBytes);
+ OutStreamer->emitValueImpl(
+ MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(CurrentFnBegin, Ctx),
+ MCBinaryExpr::createAdd(
+ MCSymbolRefExpr::create(Dot, Ctx),
+ MCConstantExpr::create(WordSizeBytes, Ctx), Ctx),
+ Ctx),
+ WordSizeBytes);
+ } else {
+ OutStreamer->emitSymbolValue(Sled.Sled, WordSizeBytes);
+ OutStreamer->emitSymbolValue(CurrentFnSym, WordSizeBytes);
+ }
+ Sled.emit(WordSizeBytes, OutStreamer.get());
+ }
MCSymbol *SledsEnd = OutContext.createTempSymbol("xray_sleds_end", true);
- OutStreamer->EmitLabel(SledsEnd);
+ OutStreamer->emitLabel(SledsEnd);
// We then emit a single entry in the index per function. We use the symbols
// that bound the instrumentation map as the range for a specific function.
// Each entry here will be 2 * word size aligned, as we're writing down two
// pointers. This should work for both 32-bit and 64-bit platforms.
- OutStreamer->SwitchSection(FnSledIndex);
- OutStreamer->EmitCodeAlignment(2 * WordSizeBytes);
- OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes, false);
- OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes, false);
- OutStreamer->SwitchSection(PrevSection);
+ if (FnSledIndex) {
+ OutStreamer->SwitchSection(FnSledIndex);
+ OutStreamer->emitCodeAlignment(2 * WordSizeBytes);
+ OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes, false);
+ OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes, false);
+ OutStreamer->SwitchSection(PrevSection);
+ }
Sleds.clear();
}
@@ -3239,31 +3338,24 @@ void AsmPrinter::emitPatchableFunctionEntries() {
const unsigned PointerSize = getPointerSize();
if (TM.getTargetTriple().isOSBinFormatELF()) {
auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC;
+ const MCSymbolELF *LinkedToSym = nullptr;
+ StringRef GroupName;
- // As of binutils 2.33, GNU as does not support section flag "o" or linkage
- // field "unique". Use SHF_LINK_ORDER if we are using the integrated
- // assembler.
+ // GNU as < 2.35 did not support section flag 'o'. Use SHF_LINK_ORDER only
+ // if we are using the integrated assembler.
if (MAI->useIntegratedAssembler()) {
Flags |= ELF::SHF_LINK_ORDER;
- std::string GroupName;
if (F.hasComdat()) {
Flags |= ELF::SHF_GROUP;
GroupName = F.getComdat()->getName();
}
- MCSection *Section = getObjFileLowering().SectionForGlobal(&F, TM);
- unsigned UniqueID =
- PatchableFunctionEntryID
- .try_emplace(Section, PatchableFunctionEntryID.size())
- .first->second;
- OutStreamer->SwitchSection(OutContext.getELFSection(
- "__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0,
- GroupName, UniqueID, cast<MCSymbolELF>(CurrentFnSym)));
- } else {
- OutStreamer->SwitchSection(OutContext.getELFSection(
- "__patchable_function_entries", ELF::SHT_PROGBITS, Flags));
+ LinkedToSym = cast<MCSymbolELF>(CurrentFnSym);
}
- EmitAlignment(Align(PointerSize));
- OutStreamer->EmitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize);
+ OutStreamer->SwitchSection(OutContext.getELFSection(
+ "__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName,
+ MCSection::NonUniqueID, LinkedToSym));
+ emitAlignment(Align(PointerSize));
+ OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize);
}
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 992e44d95306..d81a9be26d39 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -36,22 +36,23 @@ using namespace llvm;
//===----------------------------------------------------------------------===//
/// EmitSLEB128 - emit the specified signed leb128 value.
-void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
+void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {
if (isVerbose() && Desc)
OutStreamer->AddComment(Desc);
- OutStreamer->EmitSLEB128IntValue(Value);
+ OutStreamer->emitSLEB128IntValue(Value);
}
-void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc, unsigned PadTo) const {
+void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,
+ unsigned PadTo) const {
if (isVerbose() && Desc)
OutStreamer->AddComment(Desc);
- OutStreamer->EmitULEB128IntValue(Value, PadTo);
+ OutStreamer->emitULEB128IntValue(Value, PadTo);
}
/// Emit something like ".uleb128 Hi-Lo".
-void AsmPrinter::EmitLabelDifferenceAsULEB128(const MCSymbol *Hi,
+void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi,
const MCSymbol *Lo) const {
OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
}
@@ -105,7 +106,7 @@ static const char *DecodeDWARFEncoding(unsigned Encoding) {
/// encoding. If verbose assembly output is enabled, we output comments
/// describing the encoding. Desc is an optional string saying what the
/// encoding is specifying (e.g. "LSDA").
-void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
+void AsmPrinter::emitEncodingByte(unsigned Val, const char *Desc) const {
if (isVerbose()) {
if (Desc)
OutStreamer->AddComment(Twine(Desc) + " Encoding = " +
@@ -114,7 +115,7 @@ void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
OutStreamer->AddComment(Twine("Encoding = ") + DecodeDWARFEncoding(Val));
}
- OutStreamer->EmitIntValue(Val, 1);
+ OutStreamer->emitIntValue(Val, 1);
}
/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
@@ -136,16 +137,16 @@ unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
}
}
-void AsmPrinter::EmitTTypeReference(const GlobalValue *GV,
+void AsmPrinter::emitTTypeReference(const GlobalValue *GV,
unsigned Encoding) const {
if (GV) {
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
const MCExpr *Exp =
TLOF.getTTypeGlobalReference(GV, Encoding, TM, MMI, *OutStreamer);
- OutStreamer->EmitValue(Exp, GetSizeOfEncodedValue(Encoding));
+ OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
} else
- OutStreamer->EmitIntValue(0, GetSizeOfEncodedValue(Encoding));
+ OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
}
void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
@@ -159,13 +160,13 @@ void AsmPrinter::emitDwarfSymbolReference(const MCSymbol *Label,
// If the format uses relocations with dwarf, refer to the symbol directly.
if (MAI->doesDwarfUseRelocationsAcrossSections()) {
- OutStreamer->EmitSymbolValue(Label, 4);
+ OutStreamer->emitSymbolValue(Label, 4);
return;
}
}
// Otherwise, emit it as a label difference from the start of the section.
- EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
+ emitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4);
}
void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
@@ -179,27 +180,26 @@ void AsmPrinter::emitDwarfStringOffset(DwarfStringPoolEntry S) const {
emitInt32(S.Offset);
}
-void AsmPrinter::EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
- EmitLabelPlusOffset(Label, Offset, MAI->getCodePointerSize());
+void AsmPrinter::emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const {
+ // TODO: Support DWARF64
+ emitLabelPlusOffset(Label, Offset, 4);
}
-void AsmPrinter::EmitCallSiteOffset(const MCSymbol *Hi,
- const MCSymbol *Lo,
+void AsmPrinter::emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Encoding) const {
// The least significant 3 bits specify the width of the encoding
if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
- EmitLabelDifferenceAsULEB128(Hi, Lo);
+ emitLabelDifferenceAsULEB128(Hi, Lo);
else
- EmitLabelDifference(Hi, Lo, GetSizeOfEncodedValue(Encoding));
+ emitLabelDifference(Hi, Lo, GetSizeOfEncodedValue(Encoding));
}
-void AsmPrinter::EmitCallSiteValue(uint64_t Value,
- unsigned Encoding) const {
+void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const {
// The least significant 3 bits specify the width of the encoding
if ((Encoding & 0x7) == dwarf::DW_EH_PE_uleb128)
- EmitULEB128(Value);
+ emitULEB128(Value);
else
- OutStreamer->EmitIntValue(Value, GetSizeOfEncodedValue(Encoding));
+ OutStreamer->emitIntValue(Value, GetSizeOfEncodedValue(Encoding));
}
//===----------------------------------------------------------------------===//
@@ -211,40 +211,43 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
default:
llvm_unreachable("Unexpected instruction");
case MCCFIInstruction::OpDefCfaOffset:
- OutStreamer->EmitCFIDefCfaOffset(Inst.getOffset());
+ OutStreamer->emitCFIDefCfaOffset(Inst.getOffset());
break;
case MCCFIInstruction::OpAdjustCfaOffset:
- OutStreamer->EmitCFIAdjustCfaOffset(Inst.getOffset());
+ OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset());
break;
case MCCFIInstruction::OpDefCfa:
- OutStreamer->EmitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
+ OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
break;
case MCCFIInstruction::OpDefCfaRegister:
- OutStreamer->EmitCFIDefCfaRegister(Inst.getRegister());
+ OutStreamer->emitCFIDefCfaRegister(Inst.getRegister());
break;
case MCCFIInstruction::OpOffset:
- OutStreamer->EmitCFIOffset(Inst.getRegister(), Inst.getOffset());
+ OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset());
break;
case MCCFIInstruction::OpRegister:
- OutStreamer->EmitCFIRegister(Inst.getRegister(), Inst.getRegister2());
+ OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2());
break;
case MCCFIInstruction::OpWindowSave:
- OutStreamer->EmitCFIWindowSave();
+ OutStreamer->emitCFIWindowSave();
break;
case MCCFIInstruction::OpNegateRAState:
- OutStreamer->EmitCFINegateRAState();
+ OutStreamer->emitCFINegateRAState();
break;
case MCCFIInstruction::OpSameValue:
- OutStreamer->EmitCFISameValue(Inst.getRegister());
+ OutStreamer->emitCFISameValue(Inst.getRegister());
break;
case MCCFIInstruction::OpGnuArgsSize:
- OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset());
+ OutStreamer->emitCFIGnuArgsSize(Inst.getOffset());
break;
case MCCFIInstruction::OpEscape:
- OutStreamer->EmitCFIEscape(Inst.getValues());
+ OutStreamer->emitCFIEscape(Inst.getValues());
break;
case MCCFIInstruction::OpRestore:
- OutStreamer->EmitCFIRestore(Inst.getRegister());
+ OutStreamer->emitCFIRestore(Inst.getRegister());
+ break;
+ case MCCFIInstruction::OpUndefined:
+ OutStreamer->emitCFIUndefined(Inst.getRegister());
break;
}
}
@@ -256,7 +259,7 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
Twine::utohexstr(Die.getOffset()) + ":0x" +
Twine::utohexstr(Die.getSize()) + " " +
dwarf::TagString(Die.getTag()));
- EmitULEB128(Die.getAbbrevNumber());
+ emitULEB128(Die.getAbbrevNumber());
// Emit the DIE attribute values.
for (const auto &V : Die.values()) {
@@ -271,7 +274,7 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
}
// Emit an attribute using the defined form.
- V.EmitValue(this);
+ V.emitValue(this);
}
// Emit the DIE children if any.
@@ -286,7 +289,7 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const {
void AsmPrinter::emitDwarfAbbrev(const DIEAbbrev &Abbrev) const {
// Emit the abbreviations code (base 1 index.)
- EmitULEB128(Abbrev.getNumber(), "Abbreviation Code");
+ emitULEB128(Abbrev.getNumber(), "Abbreviation Code");
// Emit the abbreviations data.
Abbrev.Emit(this);
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index c631cc5360b8..538107cecd8b 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -106,7 +106,7 @@ unsigned AsmPrinter::addInlineAsmDiagBuffer(StringRef AsmStr,
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
-void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
+void AsmPrinter::emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
const MCTargetOptions &MCOptions,
const MDNode *LocMDNode,
InlineAsm::AsmDialect Dialect) const {
@@ -127,7 +127,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
if (!MCAI->useIntegratedAssembler() &&
!OutStreamer->isIntegratedAssemblerRequired()) {
emitInlineAsmStart();
- OutStreamer->EmitRawText(Str);
+ OutStreamer->emitRawText(Str);
emitInlineAsmEnd(STI, nullptr);
return;
}
@@ -489,9 +489,9 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
OS << '\n' << (char)0; // null terminate string.
}
-/// EmitInlineAsm - This method formats and emits the specified machine
-/// instruction that is an inline asm.
-void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
+/// This method formats and emits the specified machine instruction that is an
+/// inline asm.
+void AsmPrinter::emitInlineAsm(const MachineInstr *MI) const {
assert(MI->isInlineAsm() && "printInlineAsm only works on inline asms");
// Count the number of register definitions to find the asm string.
@@ -584,7 +584,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
SrcMgr.PrintMessage(Loc, SourceMgr::DK_Note, Note);
}
- EmitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD,
+ emitInlineAsm(OS.str(), getSubtargetInfo(), TM.Options.MCOptions, LocMD,
MI->getInlineAsmDialect());
// Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't
@@ -592,7 +592,6 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
OutStreamer->emitRawComment(MAI->getInlineAsmEnd());
}
-
/// PrintSpecial - Print information related to the specified machine instr
/// that is independent of the operand, and may be independent of the instr
/// itself. This can be useful for portably encoding the comment character
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
index 09f7496cd4ef..90929a217368 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ByteStreamer.h
@@ -30,8 +30,9 @@ class ByteStreamer {
public:
// For now we're just handling the calls we need for dwarf emission/hashing.
virtual void EmitInt8(uint8_t Byte, const Twine &Comment = "") = 0;
- virtual void EmitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;
- virtual void EmitULEB128(uint64_t DWord, const Twine &Comment = "", unsigned PadTo = 0) = 0;
+ virtual void emitSLEB128(uint64_t DWord, const Twine &Comment = "") = 0;
+ virtual void emitULEB128(uint64_t DWord, const Twine &Comment = "",
+ unsigned PadTo = 0) = 0;
};
class APByteStreamer final : public ByteStreamer {
@@ -44,13 +45,14 @@ public:
AP.OutStreamer->AddComment(Comment);
AP.emitInt8(Byte);
}
- void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
+ void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
AP.OutStreamer->AddComment(Comment);
- AP.EmitSLEB128(DWord);
+ AP.emitSLEB128(DWord);
}
- void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
+ void emitULEB128(uint64_t DWord, const Twine &Comment,
+ unsigned PadTo) override {
AP.OutStreamer->AddComment(Comment);
- AP.EmitULEB128(DWord);
+ AP.emitULEB128(DWord, nullptr, PadTo);
}
};
@@ -62,10 +64,11 @@ class HashingByteStreamer final : public ByteStreamer {
void EmitInt8(uint8_t Byte, const Twine &Comment) override {
Hash.update(Byte);
}
- void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
+ void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
Hash.addSLEB128(DWord);
}
- void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
+ void emitULEB128(uint64_t DWord, const Twine &Comment,
+ unsigned PadTo) override {
Hash.addULEB128(DWord);
}
};
@@ -90,7 +93,7 @@ public:
if (GenerateComments)
Comments.push_back(Comment.str());
}
- void EmitSLEB128(uint64_t DWord, const Twine &Comment) override {
+ void emitSLEB128(uint64_t DWord, const Twine &Comment) override {
raw_svector_ostream OSE(Buffer);
unsigned Length = encodeSLEB128(DWord, OSE);
if (GenerateComments) {
@@ -102,7 +105,8 @@ public:
}
}
- void EmitULEB128(uint64_t DWord, const Twine &Comment, unsigned PadTo) override {
+ void emitULEB128(uint64_t DWord, const Twine &Comment,
+ unsigned PadTo) override {
raw_svector_ostream OSE(Buffer);
unsigned Length = encodeULEB128(DWord, OSE, PadTo);
if (GenerateComments) {
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 62ad356e7f8f..3f053c7a38c7 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -101,27 +101,27 @@ public:
CVMCAdapter(MCStreamer &OS, TypeCollection &TypeTable)
: OS(&OS), TypeTable(TypeTable) {}
- void EmitBytes(StringRef Data) { OS->EmitBytes(Data); }
+ void emitBytes(StringRef Data) override { OS->emitBytes(Data); }
- void EmitIntValue(uint64_t Value, unsigned Size) {
- OS->EmitIntValueInHex(Value, Size);
+ void emitIntValue(uint64_t Value, unsigned Size) override {
+ OS->emitIntValueInHex(Value, Size);
}
- void EmitBinaryData(StringRef Data) { OS->EmitBinaryData(Data); }
+ void emitBinaryData(StringRef Data) override { OS->emitBinaryData(Data); }
- void AddComment(const Twine &T) { OS->AddComment(T); }
+ void AddComment(const Twine &T) override { OS->AddComment(T); }
- void AddRawComment(const Twine &T) { OS->emitRawComment(T); }
+ void AddRawComment(const Twine &T) override { OS->emitRawComment(T); }
- bool isVerboseAsm() { return OS->isVerboseAsm(); }
+ bool isVerboseAsm() override { return OS->isVerboseAsm(); }
- std::string getTypeName(TypeIndex TI) {
+ std::string getTypeName(TypeIndex TI) override {
std::string TypeName;
if (!TI.isNoneType()) {
if (TI.isSimple())
- TypeName = TypeIndex::simpleTypeName(TI);
+ TypeName = std::string(TypeIndex::simpleTypeName(TI));
else
- TypeName = TypeTable.getTypeName(TI);
+ TypeName = std::string(TypeTable.getTypeName(TI));
}
return TypeName;
}
@@ -183,7 +183,7 @@ StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {
if (Dir.startswith("/") || Filename.startswith("/")) {
if (llvm::sys::path::is_absolute(Filename, llvm::sys::path::Style::posix))
return Filename;
- Filepath = Dir;
+ Filepath = std::string(Dir);
if (Dir.back() != '/')
Filepath += '/';
Filepath += Filename;
@@ -195,7 +195,7 @@ StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {
// that would increase the IR size and probably not needed for other users.
// For now, just concatenate and canonicalize the path here.
if (Filename.find(':') == 1)
- Filepath = Filename;
+ Filepath = std::string(Filename);
else
Filepath = (Dir + "\\" + Filename).str();
@@ -250,8 +250,15 @@ unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) {
ChecksumAsBytes = ArrayRef<uint8_t>(
reinterpret_cast<const uint8_t *>(CKMem), Checksum.size());
switch (F->getChecksum()->Kind) {
- case DIFile::CSK_MD5: CSKind = FileChecksumKind::MD5; break;
- case DIFile::CSK_SHA1: CSKind = FileChecksumKind::SHA1; break;
+ case DIFile::CSK_MD5:
+ CSKind = FileChecksumKind::MD5;
+ break;
+ case DIFile::CSK_SHA1:
+ CSKind = FileChecksumKind::SHA1;
+ break;
+ case DIFile::CSK_SHA256:
+ CSKind = FileChecksumKind::SHA256;
+ break;
}
}
bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes,
@@ -303,12 +310,19 @@ static StringRef getPrettyScopeName(const DIScope *Scope) {
return StringRef();
}
-static const DISubprogram *getQualifiedNameComponents(
+const DISubprogram *CodeViewDebug::collectParentScopeNames(
const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) {
const DISubprogram *ClosestSubprogram = nullptr;
while (Scope != nullptr) {
if (ClosestSubprogram == nullptr)
ClosestSubprogram = dyn_cast<DISubprogram>(Scope);
+
+ // If a type appears in a scope chain, make sure it gets emitted. The
+ // frontend will be responsible for deciding if this should be a forward
+ // declaration or a complete type.
+ if (const auto *Ty = dyn_cast<DICompositeType>(Scope))
+ DeferredCompleteTypes.push_back(Ty);
+
StringRef ScopeName = getPrettyScopeName(Scope);
if (!ScopeName.empty())
QualifiedNameComponents.push_back(ScopeName);
@@ -317,24 +331,18 @@ static const DISubprogram *getQualifiedNameComponents(
return ClosestSubprogram;
}
-static std::string getQualifiedName(ArrayRef<StringRef> QualifiedNameComponents,
+static std::string formatNestedName(ArrayRef<StringRef> QualifiedNameComponents,
StringRef TypeName) {
std::string FullyQualifiedName;
for (StringRef QualifiedNameComponent :
llvm::reverse(QualifiedNameComponents)) {
- FullyQualifiedName.append(QualifiedNameComponent);
+ FullyQualifiedName.append(std::string(QualifiedNameComponent));
FullyQualifiedName.append("::");
}
- FullyQualifiedName.append(TypeName);
+ FullyQualifiedName.append(std::string(TypeName));
return FullyQualifiedName;
}
-static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name) {
- SmallVector<StringRef, 5> QualifiedNameComponents;
- getQualifiedNameComponents(Scope, QualifiedNameComponents);
- return getQualifiedName(QualifiedNameComponents, Name);
-}
-
struct CodeViewDebug::TypeLoweringScope {
TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; }
~TypeLoweringScope() {
@@ -347,7 +355,18 @@ struct CodeViewDebug::TypeLoweringScope {
CodeViewDebug &CVD;
};
-static std::string getFullyQualifiedName(const DIScope *Ty) {
+std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Scope,
+ StringRef Name) {
+ // Ensure types in the scope chain are emitted as soon as possible.
+ // This can create otherwise a situation where S_UDTs are emitted while
+ // looping in emitDebugInfoForUDTs.
+ TypeLoweringScope S(*this);
+ SmallVector<StringRef, 5> QualifiedNameComponents;
+ collectParentScopeNames(Scope, QualifiedNameComponents);
+ return formatNestedName(QualifiedNameComponents, Name);
+}
+
+std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Ty) {
const DIScope *Scope = Ty->getScope();
return getFullyQualifiedName(Scope, getPrettyScopeName(Ty));
}
@@ -418,10 +437,11 @@ getFunctionOptions(const DISubroutineType *Ty,
ReturnTy = TypeArray[0];
}
- if (auto *ReturnDCTy = dyn_cast_or_null<DICompositeType>(ReturnTy)) {
- if (isNonTrivial(ReturnDCTy))
+ // Add CxxReturnUdt option to functions that return nontrivial record types
+ // or methods that return record types.
+ if (auto *ReturnDCTy = dyn_cast_or_null<DICompositeType>(ReturnTy))
+ if (isNonTrivial(ReturnDCTy) || ClassTy)
FO |= FunctionOptions::CxxReturnUdt;
- }
// DISubroutineType is unnamed. Use DISubprogram's i.e. SPName in comparison.
if (ClassTy && isNonTrivial(ClassTy) && SPName == ClassTy->getName()) {
@@ -543,15 +563,15 @@ void CodeViewDebug::maybeRecordLocation(const DebugLoc &DL,
addLocIfNotPresent(CurFn->ChildSites, Loc);
}
- OS.EmitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(),
+ OS.emitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(),
/*PrologueEnd=*/false, /*IsStmt=*/false,
DL->getFilename(), SMLoc());
}
void CodeViewDebug::emitCodeViewMagicVersion() {
- OS.EmitValueToAlignment(4);
+ OS.emitValueToAlignment(4);
OS.AddComment("Debug section magic");
- OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
+ OS.emitInt32(COFF::DEBUG_SECTION_MAGIC);
}
void CodeViewDebug::endModule() {
@@ -600,11 +620,11 @@ void CodeViewDebug::endModule() {
// This subsection holds a file index to offset in string table table.
OS.AddComment("File index to string table offset subsection");
- OS.EmitCVFileChecksumsDirective();
+ OS.emitCVFileChecksumsDirective();
// This subsection holds the string table.
OS.AddComment("String table");
- OS.EmitCVStringTableDirective();
+ OS.emitCVStringTableDirective();
// Emit S_BUILDINFO, which points to LF_BUILDINFO. Put this in its own symbol
// subsection in the generic .debug$S section at the end. There is no
@@ -631,7 +651,7 @@ emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S,
SmallString<32> NullTerminatedString(
S.take_front(MaxRecordLength - MaxFixedRecordLength - 1));
NullTerminatedString.push_back('\0');
- OS.EmitBytes(NullTerminatedString);
+ OS.emitBytes(NullTerminatedString);
}
void CodeViewDebug::emitTypeInformation() {
@@ -674,13 +694,13 @@ void CodeViewDebug::emitTypeGlobalHashes() {
// hardcoded to version 0, SHA1.
OS.SwitchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection());
- OS.EmitValueToAlignment(4);
+ OS.emitValueToAlignment(4);
OS.AddComment("Magic");
- OS.EmitIntValue(COFF::DEBUG_HASHES_SECTION_MAGIC, 4);
+ OS.emitInt32(COFF::DEBUG_HASHES_SECTION_MAGIC);
OS.AddComment("Section Version");
- OS.EmitIntValue(0, 2);
+ OS.emitInt16(0);
OS.AddComment("Hash Algorithm");
- OS.EmitIntValue(uint16_t(GlobalTypeHashAlg::SHA1_8), 2);
+ OS.emitInt16(uint16_t(GlobalTypeHashAlg::SHA1_8));
TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
for (const auto &GHR : TypeTable.hashes()) {
@@ -696,7 +716,7 @@ void CodeViewDebug::emitTypeGlobalHashes() {
assert(GHR.Hash.size() == 8);
StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()),
GHR.Hash.size());
- OS.EmitBinaryData(S);
+ OS.emitBinaryData(S);
}
}
@@ -775,16 +795,16 @@ void CodeViewDebug::emitCompilerInformation() {
// TODO: Figure out which other flags need to be set.
OS.AddComment("Flags and language");
- OS.EmitIntValue(Flags, 4);
+ OS.emitInt32(Flags);
OS.AddComment("CPUType");
- OS.EmitIntValue(static_cast<uint64_t>(TheCPU), 2);
+ OS.emitInt16(static_cast<uint64_t>(TheCPU));
StringRef CompilerVersion = CU->getProducer();
Version FrontVer = parseVersion(CompilerVersion);
OS.AddComment("Frontend version");
for (int N = 0; N < 4; ++N)
- OS.EmitIntValue(FrontVer.Part[N], 2);
+ OS.emitInt16(FrontVer.Part[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
@@ -797,7 +817,7 @@ void CodeViewDebug::emitCompilerInformation() {
Version BackVer = {{ Major, 0, 0, 0 }};
OS.AddComment("Backend version");
for (int N = 0; N < 4; ++N)
- OS.EmitIntValue(BackVer.Part[N], 2);
+ OS.emitInt16(BackVer.Part[N]);
OS.AddComment("Null-terminated compiler version string");
emitNullTerminatedSymbolName(OS, CompilerVersion);
@@ -841,7 +861,7 @@ void CodeViewDebug::emitBuildInfo() {
MCSymbol *BISubsecEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
MCSymbol *BIEnd = beginSymbolRecord(SymbolKind::S_BUILDINFO);
OS.AddComment("LF_BUILDINFO index");
- OS.EmitIntValue(BuildInfoIndex.getIndex(), 4);
+ OS.emitInt32(BuildInfoIndex.getIndex());
endSymbolRecord(BIEnd);
endCVSubsection(BISubsecEnd);
}
@@ -858,7 +878,7 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
// for instance, will display a warning that the breakpoints are not valid if
// the pdb does not match the source.
OS.AddComment("Inlinee lines signature");
- OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
+ OS.emitInt32(unsigned(InlineeLinesSignature::Normal));
for (const DISubprogram *SP : InlinedSubprograms) {
assert(TypeIndices.count({SP, nullptr}));
@@ -870,11 +890,11 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
SP->getFilename() + Twine(':') + Twine(SP->getLine()));
OS.AddBlankLine();
OS.AddComment("Type index of inlined function");
- OS.EmitIntValue(InlineeIdx.getIndex(), 4);
+ OS.emitInt32(InlineeIdx.getIndex());
OS.AddComment("Offset into filechecksum table");
- OS.EmitCVFileChecksumOffsetDirective(FileId);
+ OS.emitCVFileChecksumOffsetDirective(FileId);
OS.AddComment("Starting line number");
- OS.EmitIntValue(SP->getLine(), 4);
+ OS.emitInt32(SP->getLine());
}
endCVSubsection(InlineEnd);
@@ -890,16 +910,16 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI,
MCSymbol *InlineEnd = beginSymbolRecord(SymbolKind::S_INLINESITE);
OS.AddComment("PtrParent");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("PtrEnd");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("Inlinee type index");
- OS.EmitIntValue(InlineeIdx.getIndex(), 4);
+ OS.emitInt32(InlineeIdx.getIndex());
unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
unsigned StartLineNum = Site.Inlinee->getLine();
- OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
+ OS.emitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
FI.Begin, FI.End);
endSymbolRecord(InlineEnd);
@@ -943,7 +963,8 @@ void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) {
void CodeViewDebug::emitDebugInfoForThunk(const Function *GV,
FunctionInfo &FI,
const MCSymbol *Fn) {
- std::string FuncName = GlobalValue::dropLLVMManglingEscape(GV->getName());
+ std::string FuncName =
+ std::string(GlobalValue::dropLLVMManglingEscape(GV->getName()));
const ThunkOrdinal ordinal = ThunkOrdinal::Standard; // Only supported kind.
OS.AddComment("Symbol subsection for " + Twine(FuncName));
@@ -952,11 +973,11 @@ void CodeViewDebug::emitDebugInfoForThunk(const Function *GV,
// Emit S_THUNK32
MCSymbol *ThunkRecordEnd = beginSymbolRecord(SymbolKind::S_THUNK32);
OS.AddComment("PtrParent");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("PtrEnd");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("PtrNext");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("Thunk section relative address");
OS.EmitCOFFSecRel32(Fn, /*Offset=*/0);
OS.AddComment("Thunk section index");
@@ -964,7 +985,7 @@ void CodeViewDebug::emitDebugInfoForThunk(const Function *GV,
OS.AddComment("Code size");
OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2);
OS.AddComment("Ordinal");
- OS.EmitIntValue(unsigned(ordinal), 1);
+ OS.emitInt8(unsigned(ordinal));
OS.AddComment("Function name");
emitNullTerminatedSymbolName(OS, FuncName);
// Additional fields specific to the thunk ordinal would go here.
@@ -1006,7 +1027,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
// If our DISubprogram name is empty, use the mangled name.
if (FuncName.empty())
- FuncName = GlobalValue::dropLLVMManglingEscape(GV->getName());
+ FuncName = std::string(GlobalValue::dropLLVMManglingEscape(GV->getName()));
// Emit FPO data, but only on 32-bit x86. No other platforms use it.
if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86)
@@ -1022,27 +1043,27 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
// These fields are filled in by tools like CVPACK which run after the fact.
OS.AddComment("PtrParent");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("PtrEnd");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("PtrNext");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
// This is the important bit that tells the debugger where the function
// code is located and what's its size:
OS.AddComment("Code size");
OS.emitAbsoluteSymbolDiff(FI.End, Fn, 4);
OS.AddComment("Offset after prologue");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("Offset before epilogue");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("Function type index");
- OS.EmitIntValue(getFuncIdForSubprogram(GV->getSubprogram()).getIndex(), 4);
+ OS.emitInt32(getFuncIdForSubprogram(GV->getSubprogram()).getIndex());
OS.AddComment("Function section relative address");
OS.EmitCOFFSecRel32(Fn, /*Offset=*/0);
OS.AddComment("Function section index");
OS.EmitCOFFSectionIndex(Fn);
OS.AddComment("Flags");
- OS.EmitIntValue(0, 1);
+ OS.emitInt8(0);
// Emit the function display name as a null-terminated string.
OS.AddComment("Function name");
// Truncate the name so we won't overflow the record length field.
@@ -1052,19 +1073,19 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
MCSymbol *FrameProcEnd = beginSymbolRecord(SymbolKind::S_FRAMEPROC);
// Subtract out the CSR size since MSVC excludes that and we include it.
OS.AddComment("FrameSize");
- OS.EmitIntValue(FI.FrameSize - FI.CSRSize, 4);
+ OS.emitInt32(FI.FrameSize - FI.CSRSize);
OS.AddComment("Padding");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("Offset of padding");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("Bytes of callee saved registers");
- OS.EmitIntValue(FI.CSRSize, 4);
+ OS.emitInt32(FI.CSRSize);
OS.AddComment("Exception handler offset");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
OS.AddComment("Exception handler section");
- OS.EmitIntValue(0, 2);
+ OS.emitInt16(0);
OS.AddComment("Flags (defines frame register)");
- OS.EmitIntValue(uint32_t(FI.FrameProcOpts), 4);
+ OS.emitInt32(uint32_t(FI.FrameProcOpts));
endSymbolRecord(FrameProcEnd);
emitLocalVariableList(FI, FI.Locals);
@@ -1088,13 +1109,13 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.EmitCOFFSecRel32(Label, /*Offset=*/0);
// FIXME: Make sure we don't overflow the max record size.
OS.EmitCOFFSectionIndex(Label);
- OS.EmitIntValue(Strs->getNumOperands(), 2);
+ OS.emitInt16(Strs->getNumOperands());
for (Metadata *MD : Strs->operands()) {
// MDStrings are null terminated, so we can do EmitBytes and get the
// nice .asciz directive.
StringRef Str = cast<MDString>(MD)->getString();
assert(Str.data()[Str.size()] == '\0' && "non-nullterminated MDString");
- OS.EmitBytes(StringRef(Str.data(), Str.size() + 1));
+ OS.emitBytes(StringRef(Str.data(), Str.size() + 1));
}
endSymbolRecord(AnnotEnd);
}
@@ -1111,7 +1132,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.AddComment("Call instruction length");
OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
OS.AddComment("Type index");
- OS.EmitIntValue(getCompleteTypeIndex(DITy).getIndex(), 4);
+ OS.emitInt32(getCompleteTypeIndex(DITy).getIndex());
endSymbolRecord(HeapAllocEnd);
}
@@ -1124,7 +1145,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
endCVSubsection(SymbolsEnd);
// We have an assembler directive that takes care of the whole line table.
- OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End);
+ OS.emitCVLinetableDirective(FI.FuncId, Fn, FI.End);
}
CodeViewDebug::LocalVarDefRange
@@ -1173,7 +1194,7 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
}
// Get the frame register used and the offset.
- unsigned FrameReg = 0;
+ Register FrameReg;
int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);
uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);
@@ -1468,12 +1489,12 @@ void CodeViewDebug::addToUDTs(const DIType *Ty) {
if (!shouldEmitUdt(Ty))
return;
- SmallVector<StringRef, 5> QualifiedNameComponents;
+ SmallVector<StringRef, 5> ParentScopeNames;
const DISubprogram *ClosestSubprogram =
- getQualifiedNameComponents(Ty->getScope(), QualifiedNameComponents);
+ collectParentScopeNames(Ty->getScope(), ParentScopeNames);
std::string FullyQualifiedName =
- getQualifiedName(QualifiedNameComponents, getPrettyScopeName(Ty));
+ formatNestedName(ParentScopeNames, getPrettyScopeName(Ty));
if (ClosestSubprogram == nullptr) {
GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
@@ -1571,7 +1592,7 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
assert(Element->getTag() == dwarf::DW_TAG_subrange_type);
const DISubrange *Subrange = cast<DISubrange>(Element);
- assert(Subrange->getLowerBound() == 0 &&
+ assert(!Subrange->getRawLowerBound() &&
"codeview doesn't support subranges with lower bounds");
int64_t Count = -1;
if (auto *CI = Subrange->getCount().dyn_cast<ConstantInt*>())
@@ -1767,11 +1788,12 @@ translatePtrToMemberRep(unsigned SizeInBytes, bool IsPMF, unsigned Flags) {
TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty,
PointerOptions PO) {
assert(Ty->getTag() == dwarf::DW_TAG_ptr_to_member_type);
+ bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());
TypeIndex ClassTI = getTypeIndex(Ty->getClassType());
- TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType(), Ty->getClassType());
+ TypeIndex PointeeTI =
+ getTypeIndex(Ty->getBaseType(), IsPMF ? Ty->getClassType() : nullptr);
PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
: PointerKind::Near32;
- bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());
PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction
: PointerMode::PointerToDataMember;
@@ -2063,7 +2085,7 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {
// order, which is what MSVC does.
if (auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
EnumeratorRecord ER(MemberAccess::Public,
- APSInt::getUnsigned(Enumerator->getValue()),
+ APSInt(Enumerator->getValue(), true),
Enumerator->getName());
ContinuationBuilder.writeMemberType(ER);
EnumeratorCount++;
@@ -2248,7 +2270,7 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {
// MSVC appears to set this flag by searching any destructor or method with
// FunctionOptions::Constructor among the emitted members. Clang AST has all
- // the members, however special member functions are not yet emitted into
+ // the members, however special member functions are not yet emitted into
// debug information. For now checking a class's non-triviality seems enough.
// FIXME: not true for a nested unnamed struct.
if (isNonTrivial(Ty))
@@ -2625,9 +2647,9 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
TypeIndex TI = Var.UseReferenceType
? getTypeIndexForReferenceTo(Var.DIVar->getType())
: getCompleteTypeIndex(Var.DIVar->getType());
- OS.EmitIntValue(TI.getIndex(), 4);
+ OS.emitInt32(TI.getIndex());
OS.AddComment("Flags");
- OS.EmitIntValue(static_cast<uint16_t>(Flags), 2);
+ OS.emitInt16(static_cast<uint16_t>(Flags));
// Truncate the name so we won't overflow the record length field.
emitNullTerminatedSymbolName(OS, Var.DIVar->getName());
endSymbolRecord(LocalEnd);
@@ -2660,7 +2682,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
: (EncFP == FI.EncodedLocalFramePtrReg))) {
DefRangeFramePointerRelHeader DRHdr;
DRHdr.Offset = Offset;
- OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
} else {
uint16_t RegRelFlags = 0;
if (DefRange.IsSubfield) {
@@ -2672,7 +2694,7 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
DRHdr.Register = Reg;
DRHdr.Flags = RegRelFlags;
DRHdr.BasePointerOffset = Offset;
- OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
}
} else {
assert(DefRange.DataOffset == 0 && "unexpected offset into register");
@@ -2681,12 +2703,12 @@ void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
DRHdr.Register = DefRange.CVRegister;
DRHdr.MayHaveNoName = 0;
DRHdr.OffsetInParent = DefRange.StructOffset;
- OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
} else {
DefRangeRegisterHeader DRHdr;
DRHdr.Register = DefRange.CVRegister;
DRHdr.MayHaveNoName = 0;
- OS.EmitCVDefRangeDirective(DefRange.Ranges, DRHdr);
+ OS.emitCVDefRangeDirective(DefRange.Ranges, DRHdr);
}
}
}
@@ -2704,9 +2726,9 @@ void CodeViewDebug::emitLexicalBlock(const LexicalBlock &Block,
const FunctionInfo& FI) {
MCSymbol *RecordEnd = beginSymbolRecord(SymbolKind::S_BLOCK32);
OS.AddComment("PtrParent");
- OS.EmitIntValue(0, 4); // PtrParent
+ OS.emitInt32(0); // PtrParent
OS.AddComment("PtrEnd");
- OS.EmitIntValue(0, 4); // PtrEnd
+ OS.emitInt32(0); // PtrEnd
OS.AddComment("Code size");
OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4); // Code Size
OS.AddComment("Function section relative address");
@@ -2914,17 +2936,17 @@ void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
MCSymbol *CodeViewDebug::beginCVSubsection(DebugSubsectionKind Kind) {
MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),
*EndLabel = MMI->getContext().createTempSymbol();
- OS.EmitIntValue(unsigned(Kind), 4);
+ OS.emitInt32(unsigned(Kind));
OS.AddComment("Subsection size");
OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4);
- OS.EmitLabel(BeginLabel);
+ OS.emitLabel(BeginLabel);
return EndLabel;
}
void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) {
- OS.EmitLabel(EndLabel);
+ OS.emitLabel(EndLabel);
// Every subsection must be aligned to a 4-byte boundary.
- OS.EmitValueToAlignment(4);
+ OS.emitValueToAlignment(4);
}
static StringRef getSymbolName(SymbolKind SymKind) {
@@ -2939,10 +2961,10 @@ MCSymbol *CodeViewDebug::beginSymbolRecord(SymbolKind SymKind) {
*EndLabel = MMI->getContext().createTempSymbol();
OS.AddComment("Record length");
OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
- OS.EmitLabel(BeginLabel);
+ OS.emitLabel(BeginLabel);
if (OS.isVerboseAsm())
OS.AddComment("Record kind: " + getSymbolName(SymKind));
- OS.EmitIntValue(unsigned(SymKind), 2);
+ OS.emitInt16(unsigned(SymKind));
return EndLabel;
}
@@ -2951,27 +2973,31 @@ void CodeViewDebug::endSymbolRecord(MCSymbol *SymEnd) {
// an extra copy of every symbol record in LLD. This increases object file
// size by less than 1% in the clang build, and is compatible with the Visual
// C++ linker.
- OS.EmitValueToAlignment(4);
- OS.EmitLabel(SymEnd);
+ OS.emitValueToAlignment(4);
+ OS.emitLabel(SymEnd);
}
void CodeViewDebug::emitEndSymbolRecord(SymbolKind EndKind) {
OS.AddComment("Record length");
- OS.EmitIntValue(2, 2);
+ OS.emitInt16(2);
if (OS.isVerboseAsm())
OS.AddComment("Record kind: " + getSymbolName(EndKind));
- OS.EmitIntValue(unsigned(EndKind), 2); // Record Kind
+ OS.emitInt16(uint16_t(EndKind)); // Record Kind
}
void CodeViewDebug::emitDebugInfoForUDTs(
- ArrayRef<std::pair<std::string, const DIType *>> UDTs) {
+ const std::vector<std::pair<std::string, const DIType *>> &UDTs) {
+#ifndef NDEBUG
+ size_t OriginalSize = UDTs.size();
+#endif
for (const auto &UDT : UDTs) {
const DIType *T = UDT.second;
assert(shouldEmitUdt(T));
-
MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT);
OS.AddComment("Type");
- OS.EmitIntValue(getCompleteTypeIndex(T).getIndex(), 4);
+ OS.emitInt32(getCompleteTypeIndex(T).getIndex());
+ assert(OriginalSize == UDTs.size() &&
+ "getCompleteTypeIndex found new UDTs!");
emitNullTerminatedSymbolName(OS, UDT.first);
endSymbolRecord(UDTRecordEnd);
}
@@ -3075,6 +3101,14 @@ void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) {
void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
const DIGlobalVariable *DIGV = CVGV.DIGV;
+
+ const DIScope *Scope = DIGV->getScope();
+ // For static data members, get the scope from the declaration.
+ if (const auto *MemberDecl = dyn_cast_or_null<DIDerivedType>(
+ DIGV->getRawStaticDataMemberDeclaration()))
+ Scope = MemberDecl->getScope();
+ std::string QualifiedName = getFullyQualifiedName(Scope, DIGV->getName());
+
if (const GlobalVariable *GV =
CVGV.GVInfo.dyn_cast<const GlobalVariable *>()) {
// DataSym record, see SymbolRecord.h for more info. Thread local data
@@ -3087,18 +3121,16 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
: SymbolKind::S_GDATA32);
MCSymbol *DataEnd = beginSymbolRecord(DataSym);
OS.AddComment("Type");
- OS.EmitIntValue(getCompleteTypeIndex(DIGV->getType()).getIndex(), 4);
+ OS.emitInt32(getCompleteTypeIndex(DIGV->getType()).getIndex());
OS.AddComment("DataOffset");
OS.EmitCOFFSecRel32(GVSym, /*Offset=*/0);
OS.AddComment("Segment");
OS.EmitCOFFSectionIndex(GVSym);
OS.AddComment("Name");
const unsigned LengthOfDataRecord = 12;
- emitNullTerminatedSymbolName(OS, DIGV->getName(), LengthOfDataRecord);
+ emitNullTerminatedSymbolName(OS, QualifiedName, LengthOfDataRecord);
endSymbolRecord(DataEnd);
} else {
- // FIXME: Currently this only emits the global variables in the IR metadata.
- // This should also emit enums and static data members.
const DIExpression *DIE = CVGV.GVInfo.get<const DIExpression *>();
assert(DIE->isConstant() &&
"Global constant variables must contain a constant expression.");
@@ -3106,7 +3138,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
OS.AddComment("Type");
- OS.EmitIntValue(getTypeIndex(DIGV->getType()).getIndex(), 4);
+ OS.emitInt32(getTypeIndex(DIGV->getType()).getIndex());
OS.AddComment("Value");
// Encoded integers shouldn't need more than 10 bytes.
@@ -3115,16 +3147,10 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
CodeViewRecordIO IO(Writer);
cantFail(IO.mapEncodedInteger(Val));
StringRef SRef((char *)data, Writer.getOffset());
- OS.EmitBinaryData(SRef);
+ OS.emitBinaryData(SRef);
OS.AddComment("Name");
- const DIScope *Scope = DIGV->getScope();
- // For static data members, get the scope from the declaration.
- if (const auto *MemberDecl = dyn_cast_or_null<DIDerivedType>(
- DIGV->getRawStaticDataMemberDeclaration()))
- Scope = MemberDecl->getScope();
- emitNullTerminatedSymbolName(OS,
- getFullyQualifiedName(Scope, DIGV->getName()));
+ emitNullTerminatedSymbolName(OS, QualifiedName);
endSymbolRecord(SConstantEnd);
}
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index b56b9047e1a9..82f0293874d0 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -310,8 +310,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitDebugInfoForRetainedTypes();
- void
- emitDebugInfoForUDTs(ArrayRef<std::pair<std::string, const DIType *>> UDTs);
+ void emitDebugInfoForUDTs(
+ const std::vector<std::pair<std::string, const DIType *>> &UDTs);
void emitDebugInfoForGlobals();
void emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals);
@@ -443,6 +443,15 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex TI,
const DIType *ClassTy = nullptr);
+ /// Collect the names of parent scopes, innermost to outermost. Return the
+ /// innermost subprogram scope if present. Ensure that parent type scopes are
+ /// inserted into the type table.
+ const DISubprogram *
+ collectParentScopeNames(const DIScope *Scope,
+ SmallVectorImpl<StringRef> &ParentScopeNames);
+ std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name);
+ std::string getFullyQualifiedName(const DIScope *Scope);
+
unsigned getPointerSizeInBytes();
protected:
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
index 84b86a71fa5f..edf82fbed650 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -67,17 +67,17 @@ void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
///
void DIEAbbrev::Emit(const AsmPrinter *AP) const {
// Emit its Dwarf tag type.
- AP->EmitULEB128(Tag, dwarf::TagString(Tag).data());
+ AP->emitULEB128(Tag, dwarf::TagString(Tag).data());
// Emit whether it has children DIEs.
- AP->EmitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());
+ AP->emitULEB128((unsigned)Children, dwarf::ChildrenString(Children).data());
// For each attribute description.
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
const DIEAbbrevData &AttrData = Data[i];
// Emit attribute type.
- AP->EmitULEB128(AttrData.getAttribute(),
+ AP->emitULEB128(AttrData.getAttribute(),
dwarf::AttributeString(AttrData.getAttribute()).data());
// Emit form type.
@@ -92,17 +92,17 @@ void DIEAbbrev::Emit(const AsmPrinter *AP) const {
llvm_unreachable("Invalid form for specified DWARF version");
}
#endif
- AP->EmitULEB128(AttrData.getForm(),
+ AP->emitULEB128(AttrData.getForm(),
dwarf::FormEncodingString(AttrData.getForm()).data());
// Emit value for DW_FORM_implicit_const.
if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
- AP->EmitSLEB128(AttrData.getValue());
+ AP->emitSLEB128(AttrData.getValue());
}
// Mark end of abbreviation.
- AP->EmitULEB128(0, "EOM(1)");
- AP->EmitULEB128(0, "EOM(2)");
+ AP->emitULEB128(0, "EOM(1)");
+ AP->emitULEB128(0, "EOM(2)");
}
LLVM_DUMP_METHOD
@@ -325,13 +325,13 @@ DIEUnit::DIEUnit(uint16_t V, uint8_t A, dwarf::Tag UnitTag)
"expected a unit TAG");
}
-void DIEValue::EmitValue(const AsmPrinter *AP) const {
+void DIEValue::emitValue(const AsmPrinter *AP) const {
switch (Ty) {
case isNone:
llvm_unreachable("Expected valid DIEValue");
#define HANDLE_DIEVALUE(T) \
case is##T: \
- getDIE##T().EmitValue(AP, Form); \
+ getDIE##T().emitValue(AP, Form); \
break;
#include "llvm/CodeGen/DIEValue.def"
}
@@ -374,7 +374,7 @@ LLVM_DUMP_METHOD void DIEValue::dump() const {
/// EmitValue - Emit integer of appropriate size.
///
-void DIEInteger::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
+void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
switch (Form) {
case dwarf::DW_FORM_implicit_const:
case dwarf::DW_FORM_flag_present:
@@ -409,7 +409,7 @@ void DIEInteger::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
case dwarf::DW_FORM_strp_sup:
case dwarf::DW_FORM_addr:
case dwarf::DW_FORM_ref_addr:
- Asm->OutStreamer->EmitIntValue(Integer, SizeOf(Asm, Form));
+ Asm->OutStreamer->emitIntValue(Integer, SizeOf(Asm, Form));
return;
case dwarf::DW_FORM_GNU_str_index:
case dwarf::DW_FORM_GNU_addr_index:
@@ -418,10 +418,10 @@ void DIEInteger::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
case dwarf::DW_FORM_addrx:
case dwarf::DW_FORM_rnglistx:
case dwarf::DW_FORM_udata:
- Asm->EmitULEB128(Integer);
+ Asm->emitULEB128(Integer);
return;
case dwarf::DW_FORM_sdata:
- Asm->EmitSLEB128(Integer);
+ Asm->emitSLEB128(Integer);
return;
default: llvm_unreachable("DIE Value form not supported yet");
}
@@ -465,8 +465,8 @@ void DIEInteger::print(raw_ostream &O) const {
/// EmitValue - Emit expression value.
///
-void DIEExpr::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
- AP->EmitDebugValue(Expr, SizeOf(AP, Form));
+void DIEExpr::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+ AP->emitDebugValue(Expr, SizeOf(AP, Form));
}
/// SizeOf - Determine size of expression value in bytes.
@@ -487,12 +487,11 @@ void DIEExpr::print(raw_ostream &O) const { O << "Expr: " << *Expr; }
/// EmitValue - Emit label value.
///
-void DIELabel::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
- AP->EmitLabelReference(Label, SizeOf(AP, Form),
- Form == dwarf::DW_FORM_strp ||
- Form == dwarf::DW_FORM_sec_offset ||
- Form == dwarf::DW_FORM_ref_addr ||
- Form == dwarf::DW_FORM_data4);
+void DIELabel::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+ AP->emitLabelReference(
+ Label, SizeOf(AP, Form),
+ Form == dwarf::DW_FORM_strp || Form == dwarf::DW_FORM_sec_offset ||
+ Form == dwarf::DW_FORM_ref_addr || Form == dwarf::DW_FORM_data4);
}
/// SizeOf - Determine size of label value in bytes.
@@ -511,10 +510,10 @@ void DIELabel::print(raw_ostream &O) const { O << "Lbl: " << Label->getName(); }
// DIEBaseTypeRef Implementation
//===----------------------------------------------------------------------===//
-void DIEBaseTypeRef::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+void DIEBaseTypeRef::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
uint64_t Offset = CU->ExprRefedBaseTypes[Index].Die->getOffset();
assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
- AP->EmitULEB128(Offset, nullptr, ULEB128PadSize);
+ AP->emitULEB128(Offset, nullptr, ULEB128PadSize);
}
unsigned DIEBaseTypeRef::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
@@ -530,8 +529,8 @@ void DIEBaseTypeRef::print(raw_ostream &O) const { O << "BaseTypeRef: " << Index
/// EmitValue - Emit delta value.
///
-void DIEDelta::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
- AP->EmitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
+void DIEDelta::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+ AP->emitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
}
/// SizeOf - Determine size of delta value in bytes.
@@ -554,7 +553,7 @@ void DIEDelta::print(raw_ostream &O) const {
/// EmitValue - Emit string value.
///
-void DIEString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+void DIEString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
// Index of string in symbol table.
switch (Form) {
case dwarf::DW_FORM_GNU_str_index:
@@ -563,13 +562,13 @@ void DIEString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
case dwarf::DW_FORM_strx2:
case dwarf::DW_FORM_strx3:
case dwarf::DW_FORM_strx4:
- DIEInteger(S.getIndex()).EmitValue(AP, Form);
+ DIEInteger(S.getIndex()).emitValue(AP, Form);
return;
case dwarf::DW_FORM_strp:
if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
- DIELabel(S.getSymbol()).EmitValue(AP, Form);
+ DIELabel(S.getSymbol()).emitValue(AP, Form);
else
- DIEInteger(S.getOffset()).EmitValue(AP, Form);
+ DIEInteger(S.getOffset()).emitValue(AP, Form);
return;
default:
llvm_unreachable("Expected valid string form");
@@ -605,9 +604,9 @@ void DIEString::print(raw_ostream &O) const {
//===----------------------------------------------------------------------===//
// DIEInlineString Implementation
//===----------------------------------------------------------------------===//
-void DIEInlineString::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+void DIEInlineString::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
if (Form == dwarf::DW_FORM_string) {
- AP->OutStreamer->EmitBytes(S);
+ AP->OutStreamer->emitBytes(S);
AP->emitInt8(0);
return;
}
@@ -630,18 +629,18 @@ void DIEInlineString::print(raw_ostream &O) const {
/// EmitValue - Emit debug information entry offset.
///
-void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+void DIEEntry::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
switch (Form) {
case dwarf::DW_FORM_ref1:
case dwarf::DW_FORM_ref2:
case dwarf::DW_FORM_ref4:
case dwarf::DW_FORM_ref8:
- AP->OutStreamer->EmitIntValue(Entry->getOffset(), SizeOf(AP, Form));
+ AP->OutStreamer->emitIntValue(Entry->getOffset(), SizeOf(AP, Form));
return;
case dwarf::DW_FORM_ref_udata:
- AP->EmitULEB128(Entry->getOffset());
+ AP->emitULEB128(Entry->getOffset());
return;
case dwarf::DW_FORM_ref_addr: {
@@ -649,11 +648,11 @@ void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
unsigned Addr = Entry->getDebugSectionOffset();
if (const MCSymbol *SectionSym =
Entry->getUnit()->getCrossSectionRelativeBaseAddress()) {
- AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
+ AP->emitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true);
return;
}
- AP->OutStreamer->EmitIntValue(Addr, SizeOf(AP, Form));
+ AP->OutStreamer->emitIntValue(Addr, SizeOf(AP, Form));
return;
}
default:
@@ -711,7 +710,7 @@ unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const {
/// EmitValue - Emit location data.
///
-void DIELoc::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
+void DIELoc::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
switch (Form) {
default: llvm_unreachable("Improper form for block");
case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;
@@ -719,11 +718,12 @@ void DIELoc::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;
case dwarf::DW_FORM_block:
case dwarf::DW_FORM_exprloc:
- Asm->EmitULEB128(Size); break;
+ Asm->emitULEB128(Size);
+ break;
}
for (const auto &V : values())
- V.EmitValue(Asm);
+ V.emitValue(Asm);
}
/// SizeOf - Determine size of location data in bytes.
@@ -762,19 +762,21 @@ unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const {
/// EmitValue - Emit block data.
///
-void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
+void DIEBlock::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
switch (Form) {
default: llvm_unreachable("Improper form for block");
case dwarf::DW_FORM_block1: Asm->emitInt8(Size); break;
case dwarf::DW_FORM_block2: Asm->emitInt16(Size); break;
case dwarf::DW_FORM_block4: Asm->emitInt32(Size); break;
- case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break;
+ case dwarf::DW_FORM_block:
+ Asm->emitULEB128(Size);
+ break;
case dwarf::DW_FORM_string: break;
case dwarf::DW_FORM_data16: break;
}
for (const auto &V : values())
- V.EmitValue(Asm);
+ V.emitValue(Asm);
}
/// SizeOf - Determine size of block data in bytes.
@@ -811,9 +813,9 @@ unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
/// EmitValue - Emit label value.
///
-void DIELocList::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const {
+void DIELocList::emitValue(const AsmPrinter *AP, dwarf::Form Form) const {
if (Form == dwarf::DW_FORM_loclistx) {
- AP->EmitULEB128(Index);
+ AP->emitULEB128(Index);
return;
}
DwarfDebug *DD = AP->getDwarfDebug();
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
index bfac8850a2a6..f26ef63eedec 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -17,10 +17,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DIE.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/MD5.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -224,8 +222,9 @@ void DIEHash::hashLocList(const DIELocList &LocList) {
HashingByteStreamer Streamer(*this);
DwarfDebug &DD = *AP->getDwarfDebug();
const DebugLocStream &Locs = DD.getDebugLocs();
- for (const auto &Entry : Locs.getEntries(Locs.getList(LocList.getValue())))
- DD.emitDebugLocEntry(Streamer, Entry, nullptr);
+ const DebugLocStream::List &List = Locs.getList(LocList.getValue());
+ for (const DebugLocStream::Entry &Entry : Locs.getEntries(List))
+ DD.emitDebugLocEntry(Streamer, Entry, List.CU);
}
// Hash an individual attribute \param Attr based on the type of attribute and
@@ -361,7 +360,7 @@ void DIEHash::computeHash(const DIE &Die) {
for (auto &C : Die.children()) {
// 7.27 Step 7
// If C is a nested type entry or a member function entry, ...
- if (isType(C.getTag()) || C.getTag() == dwarf::DW_TAG_subprogram) {
+ if (isType(C.getTag()) || (C.getTag() == dwarf::DW_TAG_subprogram && isType(C.getParent()->getTag()))) {
StringRef Name = getDIEStringAttr(C, dwarf::DW_AT_name);
// ... and has a DW_AT_name attribute
if (!Name.empty()) {
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
index 2e49514c98be..1a69f6772873 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -20,7 +20,6 @@
namespace llvm {
class AsmPrinter;
-class CompileUnit;
/// An object containing the capability of hashing and adding hash
/// attributes onto a DIE.
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
index 170fc8b6d49f..584b7614915d 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
@@ -47,7 +47,8 @@ static Register isDescribedByReg(const MachineInstr &MI) {
return 0;
// If location of variable is described using a register (directly or
// indirectly), this register is always a first operand.
- return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : Register();
+ return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg()
+ : Register();
}
bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var,
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 22f458e4b03e..880791a06d93 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -32,9 +32,9 @@ DbgVariableLocation::extractFromMachineInstruction(
DbgVariableLocation Location;
if (!Instruction.isDebugValue())
return None;
- if (!Instruction.getOperand(0).isReg())
+ if (!Instruction.getDebugOperand(0).isReg())
return None;
- Location.Register = Instruction.getOperand(0).getReg();
+ Location.Register = Instruction.getDebugOperand(0).getReg();
Location.FragmentInfo.reset();
// We only handle expressions generated by DIExpression::appendOffset,
// which doesn't require a full stack machine.
@@ -124,21 +124,6 @@ MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
return LabelsAfterInsn.lookup(MI);
}
-// Return the function-local offset of an instruction.
-const MCExpr *
-DebugHandlerBase::getFunctionLocalOffsetAfterInsn(const MachineInstr *MI) {
- MCContext &MC = Asm->OutContext;
-
- MCSymbol *Start = Asm->getFunctionBegin();
- const auto *StartRef = MCSymbolRefExpr::create(Start, MC);
-
- MCSymbol *AfterInsn = getLabelAfterInsn(MI);
- assert(AfterInsn && "Expected label after instruction");
- const auto *AfterRef = MCSymbolRefExpr::create(AfterInsn, MC);
-
- return MCBinaryExpr::createSub(AfterRef, StartRef, MC);
-}
-
/// If this type is derived from a base type then return base type size.
uint64_t DebugHandlerBase::getBaseTypeSize(const DIType *Ty) {
assert(Ty);
@@ -215,7 +200,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
continue;
auto IsDescribedByReg = [](const MachineInstr *MI) {
- return MI->getOperand(0).isReg() && MI->getOperand(0).getReg();
+ return MI->getDebugOperand(0).isReg() && MI->getDebugOperand(0).getReg();
};
// The first mention of a function argument gets the CurrentFnBegin label,
@@ -297,7 +282,7 @@ void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
if (!PrevLabel) {
PrevLabel = MMI->getContext().createTempSymbol();
- Asm->OutStreamer->EmitLabel(PrevLabel);
+ Asm->OutStreamer->emitLabel(PrevLabel);
}
I->second = PrevLabel;
}
@@ -329,7 +314,7 @@ void DebugHandlerBase::endInstruction() {
// We need a label after this instruction.
if (!PrevLabel) {
PrevLabel = MMI->getContext().createTempSymbol();
- Asm->OutStreamer->EmitLabel(PrevLabel);
+ Asm->OutStreamer->emitLabel(PrevLabel);
}
I->second = PrevLabel;
}
@@ -342,3 +327,17 @@ void DebugHandlerBase::endFunction(const MachineFunction *MF) {
LabelsBeforeInsn.clear();
LabelsAfterInsn.clear();
}
+
+void DebugHandlerBase::beginBasicBlock(const MachineBasicBlock &MBB) {
+ if (!MBB.isBeginSection())
+ return;
+
+ PrevLabel = MBB.getSymbol();
+}
+
+void DebugHandlerBase::endBasicBlock(const MachineBasicBlock &MBB) {
+ if (!MBB.isEndSection())
+ return;
+
+ PrevLabel = nullptr;
+}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index facbf22946e4..11ed1062f77e 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -47,8 +47,8 @@ void DwarfCFIExceptionBase::markFunctionEnd() {
}
void DwarfCFIExceptionBase::endFragment() {
- if (shouldEmitCFI)
- Asm->OutStreamer->EmitCFIEndProc();
+ if (shouldEmitCFI && !Asm->MF->hasBBSections())
+ Asm->OutStreamer->emitCFIEndProc();
}
DwarfCFIException::DwarfCFIException(AsmPrinter *A)
@@ -133,13 +133,13 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
if (!hasEmittedCFISections) {
if (Asm->needsOnlyDebugCFIMoves())
- Asm->OutStreamer->EmitCFISections(false, true);
+ Asm->OutStreamer->emitCFISections(false, true);
else if (Asm->TM.Options.ForceDwarfFrameSection)
- Asm->OutStreamer->EmitCFISections(true, true);
+ Asm->OutStreamer->emitCFISections(true, true);
hasEmittedCFISections = true;
}
- Asm->OutStreamer->EmitCFIStartProc(/*IsSimple=*/false);
+ Asm->OutStreamer->emitCFIStartProc(/*IsSimple=*/false);
// Indicate personality routine, if any.
if (!shouldEmitPersonality)
@@ -157,11 +157,11 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding();
const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);
- Asm->OutStreamer->EmitCFIPersonality(Sym, PerEncoding);
+ Asm->OutStreamer->emitCFIPersonality(Sym, PerEncoding);
// Provide LSDA information.
if (shouldEmitLSDA)
- Asm->OutStreamer->EmitCFILsda(ESP(Asm), TLOF.getLSDAEncoding());
+ Asm->OutStreamer->emitCFILsda(ESP(Asm), TLOF.getLSDAEncoding());
}
/// endFunction - Gather and emit post-function exception information.
@@ -172,3 +172,12 @@ void DwarfCFIException::endFunction(const MachineFunction *MF) {
emitExceptionTable();
}
+
+void DwarfCFIException::beginBasicBlock(const MachineBasicBlock &MBB) {
+ beginFragment(&MBB, getExceptionSym);
+}
+
+void DwarfCFIException::endBasicBlock(const MachineBasicBlock &MBB) {
+ if (shouldEmitCFI)
+ Asm->OutStreamer->emitCFIEndProc();
+}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index e97bcd62e8c7..296c380ae550 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -37,6 +37,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolWasm.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/Casting.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
@@ -113,8 +114,9 @@ unsigned DwarfCompileUnit::getOrCreateSourceID(const DIFile *File) {
// extend .file to support this.
unsigned CUID = Asm->OutStreamer->hasRawTextSupport() ? 0 : getUniqueID();
if (!File)
- return Asm->OutStreamer->EmitDwarfFileDirective(0, "", "", None, None, CUID);
- return Asm->OutStreamer->EmitDwarfFileDirective(
+ return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", None, None,
+ CUID);
+ return Asm->OutStreamer->emitDwarfFileDirective(
0, File->getDirectory(), File->getFilename(), getMD5AsBytes(File),
File->getSource(), CUID);
}
@@ -154,7 +156,8 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(
DeclContext = GV->getScope();
// Add name and type.
addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
- addType(*VariableDIE, GTy);
+ if (GTy)
+ addType(*VariableDIE, GTy);
// Add scoping info.
if (!GV->isLocalToUnit())
@@ -328,6 +331,8 @@ DIE *DwarfCompileUnit::getOrCreateCommonBlock(
}
void DwarfCompileUnit::addRange(RangeSpan Range) {
+ DD->insertSectionLabel(Range.Begin);
+
bool SameAsPrevCU = this == DD->getPrevCU();
DD->setPrevCU(this);
// If we have no current ranges just add the range and return, otherwise,
@@ -348,8 +353,6 @@ void DwarfCompileUnit::initStmtList() {
if (CUNode->isDebugDirectivesOnly())
return;
- // Define start line table label for each Compile Unit.
- MCSymbol *LineTableStartSym;
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
if (DD->useSectionsAsReferences()) {
LineTableStartSym = TLOF.getDwarfLineSection()->getBeginSymbol();
@@ -363,13 +366,14 @@ void DwarfCompileUnit::initStmtList() {
// left in the skeleton CU and so not included.
// The line table entries are not always emitted in assembly, so it
// is not okay to use line_table_start here.
- StmtListValue =
addSectionLabel(getUnitDie(), dwarf::DW_AT_stmt_list, LineTableStartSym,
TLOF.getDwarfLineSection()->getBeginSymbol());
}
void DwarfCompileUnit::applyStmtList(DIE &D) {
- D.addValue(DIEValueAllocator, *StmtListValue);
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+ addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,
+ TLOF.getDwarfLineSection()->getBeginSymbol());
}
void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
@@ -392,7 +396,14 @@ void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin,
DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
- attachLowHighPC(*SPDie, Asm->getFunctionBegin(), Asm->getFunctionEnd());
+ SmallVector<RangeSpan, 2> BB_List;
+ // If basic block sections are on, ranges for each basic block section has
+ // to be emitted separately.
+ for (const auto &R : Asm->MBBSectionRanges)
+ BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});
+
+ attachRangesOrLowHighPC(*SPDie, BB_List);
+
if (DD->useAppleExtensionAttributes() &&
!DD->getCurrentFunction()->getTarget().Options.DisableFramePointerElim(
*DD->getCurrentFunction()))
@@ -400,15 +411,60 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
// Only include DW_AT_frame_base in full debug info
if (!includeMinimalInlineScopes()) {
- if (Asm->MF->getTarget().getTargetTriple().isNVPTX()) {
+ const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
+ TargetFrameLowering::DwarfFrameBase FrameBase =
+ TFI->getDwarfFrameBase(*Asm->MF);
+ switch (FrameBase.Kind) {
+ case TargetFrameLowering::DwarfFrameBase::Register: {
+ if (Register::isPhysicalRegister(FrameBase.Location.Reg)) {
+ MachineLocation Location(FrameBase.Location.Reg);
+ addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
+ }
+ break;
+ }
+ case TargetFrameLowering::DwarfFrameBase::CFA: {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
- } else {
- const TargetRegisterInfo *RI = Asm->MF->getSubtarget().getRegisterInfo();
- MachineLocation Location(RI->getFrameRegister(*Asm->MF));
- if (Register::isPhysicalRegister(Location.getReg()))
- addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
+ break;
+ }
+ case TargetFrameLowering::DwarfFrameBase::WasmFrameBase: {
+ // FIXME: duplicated from Target/WebAssembly/WebAssembly.h
+ // don't want to depend on target specific headers in this code?
+ const unsigned TI_GLOBAL_RELOC = 3;
+ if (FrameBase.Location.WasmLoc.Kind == TI_GLOBAL_RELOC) {
+ // These need to be relocatable.
+ assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.
+ auto SPSym = cast<MCSymbolWasm>(
+ Asm->GetExternalSymbolSymbol("__stack_pointer"));
+ // FIXME: this repeats what WebAssemblyMCInstLower::
+ // GetExternalSymbolSymbol does, since if there's no code that
+ // refers to this symbol, we have to set it here.
+ SPSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+ SPSym->setGlobalType(wasm::WasmGlobalType{
+ uint8_t(Asm->getSubtargetInfo().getTargetTriple().getArch() ==
+ Triple::wasm64
+ ? wasm::WASM_TYPE_I64
+ : wasm::WASM_TYPE_I32),
+ true});
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
+ addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.WasmLoc.Kind);
+ addLabel(*Loc, dwarf::DW_FORM_udata, SPSym);
+ DD->addArangeLabel(SymbolCU(this, SPSym));
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
+ addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
+ } else {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ DIExpressionCursor Cursor({});
+ DwarfExpr.addWasmLocation(FrameBase.Location.WasmLoc.Kind,
+ FrameBase.Location.WasmLoc.Index);
+ DwarfExpr.addExpression(std::move(Cursor));
+ addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());
+ }
+ break;
+ }
}
}
@@ -521,9 +577,33 @@ void DwarfCompileUnit::attachRangesOrLowHighPC(
DIE &Die, const SmallVectorImpl<InsnRange> &Ranges) {
SmallVector<RangeSpan, 2> List;
List.reserve(Ranges.size());
- for (const InsnRange &R : Ranges)
- List.push_back(
- {DD->getLabelBeforeInsn(R.first), DD->getLabelAfterInsn(R.second)});
+ for (const InsnRange &R : Ranges) {
+ auto *BeginLabel = DD->getLabelBeforeInsn(R.first);
+ auto *EndLabel = DD->getLabelAfterInsn(R.second);
+
+ const auto *BeginMBB = R.first->getParent();
+ const auto *EndMBB = R.second->getParent();
+
+ const auto *MBB = BeginMBB;
+ // Basic block sections allows basic block subsets to be placed in unique
+ // sections. For each section, the begin and end label must be added to the
+ // list. If there is more than one range, debug ranges must be used.
+ // Otherwise, low/high PC can be used.
+ // FIXME: Debug Info Emission depends on block order and this assumes that
+ // the order of blocks will be frozen beyond this point.
+ do {
+ if (MBB->sameSection(EndMBB) || MBB->isEndSection()) {
+ auto MBBSectionRange = Asm->MBBSectionRanges[MBB->getSectionIDNum()];
+ List.push_back(
+ {MBB->sameSection(BeginMBB) ? BeginLabel
+ : MBBSectionRange.BeginLabel,
+ MBB->sameSection(EndMBB) ? EndLabel : MBBSectionRange.EndLabel});
+ }
+ if (MBB->sameSection(EndMBB))
+ break;
+ MBB = MBB->getNextNode();
+ } while (true);
+ }
attachRangesOrLowHighPC(Die, std::move(List));
}
@@ -654,7 +734,7 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
for (auto &Fragment : DV.getFrameIndexExprs()) {
- unsigned FrameReg = 0;
+ Register FrameReg;
const DIExpression *Expr = Fragment.Expr;
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
@@ -719,11 +799,22 @@ static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
auto *Array = dyn_cast<DICompositeType>(Var->getType());
if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
return Result;
+ if (auto *DLVar = Array->getDataLocation())
+ Result.push_back(DLVar);
for (auto *El : Array->getElements()) {
if (auto *Subrange = dyn_cast<DISubrange>(El)) {
- auto Count = Subrange->getCount();
- if (auto *Dependency = Count.dyn_cast<DIVariable *>())
- Result.push_back(Dependency);
+ if (auto Count = Subrange->getCount())
+ if (auto *Dependency = Count.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
+ if (auto LB = Subrange->getLowerBound())
+ if (auto *Dependency = LB.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
+ if (auto UB = Subrange->getUpperBound())
+ if (auto *Dependency = UB.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
+ if (auto ST = Subrange->getStride())
+ if (auto *Dependency = ST.dyn_cast<DIVariable *>())
+ Result.push_back(Dependency);
}
}
return Result;
@@ -904,13 +995,12 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
}
-/// Whether to use the GNU analog for a DWARF5 tag, attribute, or location atom.
-static bool useGNUAnalogForDwarf5Feature(DwarfDebug *DD) {
+bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
return DD->getDwarfVersion() == 4 && DD->tuneForGDB();
}
dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {
- if (!useGNUAnalogForDwarf5Feature(DD))
+ if (!useGNUAnalogForDwarf5Feature())
return Tag;
switch (Tag) {
case dwarf::DW_TAG_call_site:
@@ -924,7 +1014,7 @@ dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUTag(dwarf::Tag Tag) const {
dwarf::Attribute
DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {
- if (!useGNUAnalogForDwarf5Feature(DD))
+ if (!useGNUAnalogForDwarf5Feature())
return Attr;
switch (Attr) {
case dwarf::DW_AT_call_all_calls:
@@ -933,7 +1023,7 @@ DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {
return dwarf::DW_AT_GNU_call_site_target;
case dwarf::DW_AT_call_origin:
return dwarf::DW_AT_abstract_origin;
- case dwarf::DW_AT_call_pc:
+ case dwarf::DW_AT_call_return_pc:
return dwarf::DW_AT_low_pc;
case dwarf::DW_AT_call_value:
return dwarf::DW_AT_GNU_call_site_value;
@@ -946,7 +1036,7 @@ DwarfCompileUnit::getDwarf5OrGNUAttr(dwarf::Attribute Attr) const {
dwarf::LocationAtom
DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
- if (!useGNUAnalogForDwarf5Feature(DD))
+ if (!useGNUAnalogForDwarf5Feature())
return Loc;
switch (Loc) {
case dwarf::DW_OP_entry_value:
@@ -956,9 +1046,12 @@ DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
}
}
-DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
- DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail,
- const MCSymbol *PCAddr, const MCExpr *PCOffset, unsigned CallReg) {
+DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
+ DIE *CalleeDIE,
+ bool IsTail,
+ const MCSymbol *PCAddr,
+ const MCSymbol *CallAddr,
+ unsigned CallReg) {
// Insert a call site entry DIE within ScopeDIE.
DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),
ScopeDIE, nullptr);
@@ -968,24 +1061,41 @@ DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
MachineLocation(CallReg));
} else {
- DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
- assert(CalleeDIE && "Could not create DIE for call site entry origin");
+ assert(CalleeDIE && "No DIE for call site entry origin");
addDIEEntry(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_origin),
*CalleeDIE);
}
- if (IsTail)
+ if (IsTail) {
// Attach DW_AT_call_tail_call to tail calls for standards compliance.
addFlag(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_tail_call));
+ // Attach the address of the branch instruction to allow the debugger to
+ // show where the tail call occurred. This attribute has no GNU analog.
+ //
+ // GDB works backwards from non-standard usage of DW_AT_low_pc (in DWARF4
+ // mode -- equivalently, in DWARF5 mode, DW_AT_call_return_pc) at tail-call
+ // site entries to figure out the PC of tail-calling branch instructions.
+ // This means it doesn't need the compiler to emit DW_AT_call_pc, so we
+ // don't emit it here.
+ //
+ // There's no need to tie non-GDB debuggers to this non-standardness, as it
+ // adds unnecessary complexity to the debugger. For non-GDB debuggers, emit
+ // the standard DW_AT_call_pc info.
+ if (!useGNUAnalogForDwarf5Feature())
+ addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);
+ }
+
// Attach the return PC to allow the debugger to disambiguate call paths
// from one function to another.
- if (DD->getDwarfVersion() == 4 && DD->tuneForGDB()) {
- assert(PCAddr && "Missing PC information for a call");
- addLabelAddress(CallSiteDIE, dwarf::DW_AT_low_pc, PCAddr);
- } else if (!IsTail || DD->tuneForGDB()) {
- assert(PCOffset && "Missing return PC information for a call");
- addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset);
+ //
+ // The return PC is only really needed when the call /isn't/ a tail call, but
+ // GDB expects it in DWARF4 mode, even for tail calls (see the comment above
+ // the DW_AT_call_pc emission logic for an explanation).
+ if (!IsTail || useGNUAnalogForDwarf5Feature()) {
+ assert(PCAddr && "Missing return PC information for a call");
+ addLabelAddress(CallSiteDIE,
+ getDwarf5OrGNUAttr(dwarf::DW_AT_call_return_pc), PCAddr);
}
return CallSiteDIE;
@@ -1108,7 +1218,7 @@ void DwarfCompileUnit::emitHeader(bool UseOffsets) {
// Don't bother labeling the .dwo unit, as its offset isn't used.
if (!Skeleton && !DD->useSectionsAsReferences()) {
LabelBegin = Asm->createTempSymbol("cu_begin");
- Asm->OutStreamer->EmitLabel(LabelBegin);
+ Asm->OutStreamer->emitLabel(LabelBegin);
}
dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile
@@ -1219,15 +1329,12 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
const DIExpression *DIExpr = DV.getSingleExpression();
DwarfExpr.addFragmentOffset(DIExpr);
- if (Location.isIndirect())
- DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.setLocation(Location, DIExpr);
DIExpressionCursor Cursor(DIExpr);
- if (DIExpr->isEntryValue()) {
- DwarfExpr.setEntryValueFlag();
+ if (DIExpr->isEntryValue())
DwarfExpr.beginEntryValueExpression(Cursor);
- }
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
@@ -1285,12 +1392,6 @@ void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
Die.addValue(DIEValueAllocator, (dwarf::Attribute)0, Form, DIEExpr(Expr));
}
-void DwarfCompileUnit::addAddressExpr(DIE &Die, dwarf::Attribute Attribute,
- const MCExpr *Expr) {
- Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_addr,
- DIEExpr(Expr));
-}
-
void DwarfCompileUnit::applySubprogramAttributesToDefinition(
const DISubprogram *SP, DIE &SPDie) {
auto *SPDecl = SP->getDeclaration();
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 8491d078ed89..4ccd8c96dd0d 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -47,9 +47,9 @@ class DwarfCompileUnit final : public DwarfUnit {
unsigned UniqueID;
bool HasRangeLists = false;
- /// The attribute index of DW_AT_stmt_list in the compile unit DIE, avoiding
- /// the need to search for it in applyStmtList.
- DIE::value_iterator StmtListValue;
+ /// The start of the unit line section, this is also
+ /// reused in appyStmtList.
+ MCSymbol *LineTableStartSym;
/// Skeleton unit associated with this unit.
DwarfCompileUnit *Skeleton = nullptr;
@@ -123,6 +123,9 @@ public:
/// Apply the DW_AT_stmt_list from this compile unit to the specified DIE.
void applyStmtList(DIE &D);
+ /// Get line table start symbol for this unit.
+ MCSymbol *getLineTableStartSym() const { return LineTableStartSym; }
+
/// A pair of GlobalVariable and DIExpression.
struct GlobalExpr {
const GlobalVariable *Var;
@@ -230,6 +233,10 @@ public:
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
+ /// Whether to use the GNU analog for a DWARF5 tag, attribute, or location
+ /// atom. Only applicable when emitting otherwise DWARF4-compliant debug info.
+ bool useGNUAnalogForDwarf5Feature() const;
+
/// This takes a DWARF 5 tag and returns it or a GNU analog.
dwarf::Tag getDwarf5OrGNUTag(dwarf::Tag Tag) const;
@@ -240,19 +247,17 @@ public:
dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const;
/// Construct a call site entry DIE describing a call within \p Scope to a
- /// callee described by \p CalleeSP.
+ /// callee described by \p CalleeDIE.
+ /// \p CalleeDIE is a declaration or definition subprogram DIE for the callee.
+ /// For indirect calls \p CalleeDIE is set to nullptr.
/// \p IsTail specifies whether the call is a tail call.
- /// \p PCAddr (used for GDB + DWARF 4 tuning) points to the PC value after
- /// the call instruction.
- /// \p PCOffset (used for cases other than GDB + DWARF 4 tuning) must be
- /// non-zero for non-tail calls (in the case of non-gdb tuning, since for
- /// GDB + DWARF 5 tuning we still generate PC info for tail calls) or be the
- /// function-local offset to PC value after the call instruction.
+ /// \p PCAddr points to the PC value after the call instruction.
+ /// \p CallAddr points to the PC value at the call instruction (or is null).
/// \p CallReg is a register location for an indirect call. For direct calls
/// the \p CallReg is set to 0.
- DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,
- bool IsTail, const MCSymbol *PCAddr,
- const MCExpr *PCOffset, unsigned CallReg);
+ DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, DIE *CalleeDIE, bool IsTail,
+ const MCSymbol *PCAddr,
+ const MCSymbol *CallAddr, unsigned CallReg);
/// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params
/// were collected by the \ref collectCallSiteParameters.
/// Note: The order of parameters does not matter, since debuggers recognize
@@ -340,9 +345,6 @@ public:
/// Add a Dwarf expression attribute data and value.
void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr);
- /// Add an attribute containing an address expression to \p Die.
- void addAddressExpr(DIE &Die, dwarf::Attribute Attribute, const MCExpr *Expr);
-
void applySubprogramAttributesToDefinition(const DISubprogram *SP,
DIE &SPDie);
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 6e643ad26410..45ed5256deb9 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -95,6 +95,10 @@ static cl::opt<bool> UseDwarfRangesBaseAddressSpecifier(
"use-dwarf-ranges-base-address-specifier", cl::Hidden,
cl::desc("Use base address specifiers in debug_ranges"), cl::init(false));
+static cl::opt<bool> EmitDwarfDebugEntryValues(
+ "emit-debug-entry-values", cl::Hidden,
+ cl::desc("Emit the debug entry values"), cl::init(false));
+
static cl::opt<bool> GenerateARangeSection("generate-arange-section",
cl::Hidden,
cl::desc("Generate dwarf aranges"),
@@ -163,6 +167,11 @@ static cl::opt<LinkageNameOption>
"Abstract subprograms")),
cl::init(DefaultLinkageNames));
+static cl::opt<unsigned> LocationAnalysisSizeLimit(
+ "singlevarlocation-input-bb-limit",
+ cl::desc("Maximum block size to analyze for single-location variables"),
+ cl::init(30000), cl::Hidden);
+
static const char *const DWARFGroupName = "dwarf";
static const char *const DWARFGroupDescription = "DWARF Emission";
static const char *const DbgTimerName = "writer";
@@ -176,11 +185,11 @@ void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) {
}
void DebugLocDwarfExpression::emitSigned(int64_t Value) {
- getActiveStreamer().EmitSLEB128(Value, Twine(Value));
+ getActiveStreamer().emitSLEB128(Value, Twine(Value));
}
void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) {
- getActiveStreamer().EmitULEB128(Value, Twine(Value));
+ getActiveStreamer().emitULEB128(Value, Twine(Value));
}
void DebugLocDwarfExpression::emitData1(uint8_t Value) {
@@ -189,7 +198,7 @@ void DebugLocDwarfExpression::emitData1(uint8_t Value) {
void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
assert(Idx < (1ULL << (ULEB128PadSize * 7)) && "Idx wont fit");
- getActiveStreamer().EmitULEB128(Idx, Twine(Idx), ULEB128PadSize);
+ getActiveStreamer().emitULEB128(Idx, Twine(Idx), ULEB128PadSize);
}
bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
@@ -232,26 +241,26 @@ const DIType *DbgVariable::getType() const {
static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
const DIExpression *Expr = MI->getDebugExpression();
assert(MI->getNumOperands() == 4);
- if (MI->getOperand(0).isReg()) {
- auto RegOp = MI->getOperand(0);
- auto Op1 = MI->getOperand(1);
+ if (MI->getDebugOperand(0).isReg()) {
+ auto RegOp = MI->getDebugOperand(0);
+ auto Op1 = MI->getDebugOffset();
// If the second operand is an immediate, this is a
// register-indirect address.
assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
return DbgValueLoc(Expr, MLoc);
}
- if (MI->getOperand(0).isTargetIndex()) {
- auto Op = MI->getOperand(0);
+ if (MI->getDebugOperand(0).isTargetIndex()) {
+ auto Op = MI->getDebugOperand(0);
return DbgValueLoc(Expr,
TargetIndexLocation(Op.getIndex(), Op.getOffset()));
}
- if (MI->getOperand(0).isImm())
- return DbgValueLoc(Expr, MI->getOperand(0).getImm());
- if (MI->getOperand(0).isFPImm())
- return DbgValueLoc(Expr, MI->getOperand(0).getFPImm());
- if (MI->getOperand(0).isCImm())
- return DbgValueLoc(Expr, MI->getOperand(0).getCImm());
+ if (MI->getDebugOperand(0).isImm())
+ return DbgValueLoc(Expr, MI->getDebugOperand(0).getImm());
+ if (MI->getDebugOperand(0).isFPImm())
+ return DbgValueLoc(Expr, MI->getDebugOperand(0).getFPImm());
+ if (MI->getDebugOperand(0).isCImm())
+ return DbgValueLoc(Expr, MI->getDebugOperand(0).getCImm());
llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
}
@@ -419,6 +428,12 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
// a monolithic string offsets table without any header.
UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
+ // Emit call-site-param debug info for GDB and LLDB, if the target supports
+ // the debug entry values feature. It can also be enabled explicitly.
+ EmitDebugEntryValues = (Asm->TM.Options.ShouldEmitDebugEntryValues() &&
+ (tuneForGDB() || tuneForLLDB())) ||
+ EmitDwarfDebugEntryValues;
+
Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
}
@@ -540,11 +555,222 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
}
}
+DIE &DwarfDebug::constructSubprogramDefinitionDIE(const DISubprogram *SP) {
+ DICompileUnit *Unit = SP->getUnit();
+ assert(SP->isDefinition() && "Subprogram not a definition");
+ assert(Unit && "Subprogram definition without parent unit");
+ auto &CU = getOrCreateDwarfCompileUnit(Unit);
+ return *CU.getOrCreateSubprogramDIE(SP);
+}
+
+/// Represents a parameter whose call site value can be described by applying a
+/// debug expression to a register in the forwarded register worklist.
+struct FwdRegParamInfo {
+ /// The described parameter register.
+ unsigned ParamReg;
+
+ /// Debug expression that has been built up when walking through the
+ /// instruction chain that produces the parameter's value.
+ const DIExpression *Expr;
+};
+
+/// Register worklist for finding call site values.
+using FwdRegWorklist = MapVector<unsigned, SmallVector<FwdRegParamInfo, 2>>;
+
+/// Append the expression \p Addition to \p Original and return the result.
+static const DIExpression *combineDIExpressions(const DIExpression *Original,
+ const DIExpression *Addition) {
+ std::vector<uint64_t> Elts = Addition->getElements().vec();
+ // Avoid multiple DW_OP_stack_values.
+ if (Original->isImplicit() && Addition->isImplicit())
+ erase_if(Elts, [](uint64_t Op) { return Op == dwarf::DW_OP_stack_value; });
+ const DIExpression *CombinedExpr =
+ (Elts.size() > 0) ? DIExpression::append(Original, Elts) : Original;
+ return CombinedExpr;
+}
+
+/// Emit call site parameter entries that are described by the given value and
+/// debug expression.
+template <typename ValT>
+static void finishCallSiteParams(ValT Val, const DIExpression *Expr,
+ ArrayRef<FwdRegParamInfo> DescribedParams,
+ ParamSet &Params) {
+ for (auto Param : DescribedParams) {
+ bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0;
+
+ // TODO: Entry value operations can currently not be combined with any
+ // other expressions, so we can't emit call site entries in those cases.
+ if (ShouldCombineExpressions && Expr->isEntryValue())
+ continue;
+
+ // If a parameter's call site value is produced by a chain of
+ // instructions we may have already created an expression for the
+ // parameter when walking through the instructions. Append that to the
+ // base expression.
+ const DIExpression *CombinedExpr =
+ ShouldCombineExpressions ? combineDIExpressions(Expr, Param.Expr)
+ : Expr;
+ assert((!CombinedExpr || CombinedExpr->isValid()) &&
+ "Combined debug expression is invalid");
+
+ DbgValueLoc DbgLocVal(CombinedExpr, Val);
+ DbgCallSiteParam CSParm(Param.ParamReg, DbgLocVal);
+ Params.push_back(CSParm);
+ ++NumCSParams;
+ }
+}
+
+/// Add \p Reg to the worklist, if it's not already present, and mark that the
+/// given parameter registers' values can (potentially) be described using
+/// that register and an debug expression.
+static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg,
+ const DIExpression *Expr,
+ ArrayRef<FwdRegParamInfo> ParamsToAdd) {
+ auto I = Worklist.insert({Reg, {}});
+ auto &ParamsForFwdReg = I.first->second;
+ for (auto Param : ParamsToAdd) {
+ assert(none_of(ParamsForFwdReg,
+ [Param](const FwdRegParamInfo &D) {
+ return D.ParamReg == Param.ParamReg;
+ }) &&
+ "Same parameter described twice by forwarding reg");
+
+ // If a parameter's call site value is produced by a chain of
+ // instructions we may have already created an expression for the
+ // parameter when walking through the instructions. Append that to the
+ // new expression.
+ const DIExpression *CombinedExpr = combineDIExpressions(Expr, Param.Expr);
+ ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
+ }
+}
+
+/// Interpret values loaded into registers by \p CurMI.
+static void interpretValues(const MachineInstr *CurMI,
+ FwdRegWorklist &ForwardedRegWorklist,
+ ParamSet &Params) {
+
+ const MachineFunction *MF = CurMI->getMF();
+ const DIExpression *EmptyExpr =
+ DIExpression::get(MF->getFunction().getContext(), {});
+ const auto &TRI = *MF->getSubtarget().getRegisterInfo();
+ const auto &TII = *MF->getSubtarget().getInstrInfo();
+ const auto &TLI = *MF->getSubtarget().getTargetLowering();
+
+ // If an instruction defines more than one item in the worklist, we may run
+ // into situations where a worklist register's value is (potentially)
+ // described by the previous value of another register that is also defined
+ // by that instruction.
+ //
+ // This can for example occur in cases like this:
+ //
+ // $r1 = mov 123
+ // $r0, $r1 = mvrr $r1, 456
+ // call @foo, $r0, $r1
+ //
+ // When describing $r1's value for the mvrr instruction, we need to make sure
+ // that we don't finalize an entry value for $r0, as that is dependent on the
+ // previous value of $r1 (123 rather than 456).
+ //
+ // In order to not have to distinguish between those cases when finalizing
+ // entry values, we simply postpone adding new parameter registers to the
+ // worklist, by first keeping them in this temporary container until the
+ // instruction has been handled.
+ FwdRegWorklist TmpWorklistItems;
+
+ // If the MI is an instruction defining one or more parameters' forwarding
+ // registers, add those defines.
+ auto getForwardingRegsDefinedByMI = [&](const MachineInstr &MI,
+ SmallSetVector<unsigned, 4> &Defs) {
+ if (MI.isDebugInstr())
+ return;
+
+ for (const MachineOperand &MO : MI.operands()) {
+ if (MO.isReg() && MO.isDef() &&
+ Register::isPhysicalRegister(MO.getReg())) {
+ for (auto FwdReg : ForwardedRegWorklist)
+ if (TRI.regsOverlap(FwdReg.first, MO.getReg()))
+ Defs.insert(FwdReg.first);
+ }
+ }
+ };
+
+ // Set of worklist registers that are defined by this instruction.
+ SmallSetVector<unsigned, 4> FwdRegDefs;
+
+ getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
+ if (FwdRegDefs.empty())
+ return;
+
+ for (auto ParamFwdReg : FwdRegDefs) {
+ if (auto ParamValue = TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
+ if (ParamValue->first.isImm()) {
+ int64_t Val = ParamValue->first.getImm();
+ finishCallSiteParams(Val, ParamValue->second,
+ ForwardedRegWorklist[ParamFwdReg], Params);
+ } else if (ParamValue->first.isReg()) {
+ Register RegLoc = ParamValue->first.getReg();
+ unsigned SP = TLI.getStackPointerRegisterToSaveRestore();
+ Register FP = TRI.getFrameRegister(*MF);
+ bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP);
+ if (TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP) {
+ MachineLocation MLoc(RegLoc, /*IsIndirect=*/IsSPorFP);
+ finishCallSiteParams(MLoc, ParamValue->second,
+ ForwardedRegWorklist[ParamFwdReg], Params);
+ } else {
+ // ParamFwdReg was described by the non-callee saved register
+ // RegLoc. Mark that the call site values for the parameters are
+ // dependent on that register instead of ParamFwdReg. Since RegLoc
+ // may be a register that will be handled in this iteration, we
+ // postpone adding the items to the worklist, and instead keep them
+ // in a temporary container.
+ addToFwdRegWorklist(TmpWorklistItems, RegLoc, ParamValue->second,
+ ForwardedRegWorklist[ParamFwdReg]);
+ }
+ }
+ }
+ }
+
+ // Remove all registers that this instruction defines from the worklist.
+ for (auto ParamFwdReg : FwdRegDefs)
+ ForwardedRegWorklist.erase(ParamFwdReg);
+
+ // Now that we are done handling this instruction, add items from the
+ // temporary worklist to the real one.
+ for (auto New : TmpWorklistItems)
+ addToFwdRegWorklist(ForwardedRegWorklist, New.first, EmptyExpr, New.second);
+ TmpWorklistItems.clear();
+}
+
+static bool interpretNextInstr(const MachineInstr *CurMI,
+ FwdRegWorklist &ForwardedRegWorklist,
+ ParamSet &Params) {
+ // Skip bundle headers.
+ if (CurMI->isBundle())
+ return true;
+
+ // If the next instruction is a call we can not interpret parameter's
+ // forwarding registers or we finished the interpretation of all
+ // parameters.
+ if (CurMI->isCall())
+ return false;
+
+ if (ForwardedRegWorklist.empty())
+ return false;
+
+ // Avoid NOP description.
+ if (CurMI->getNumOperands() == 0)
+ return true;
+
+ interpretValues(CurMI, ForwardedRegWorklist, Params);
+
+ return true;
+}
+
/// Try to interpret values loaded into registers that forward parameters
/// for \p CallMI. Store parameters with interpreted value into \p Params.
static void collectCallSiteParameters(const MachineInstr *CallMI,
ParamSet &Params) {
- auto *MF = CallMI->getMF();
+ const MachineFunction *MF = CallMI->getMF();
auto CalleesMap = MF->getCallSitesInfo();
auto CallFwdRegsInfo = CalleesMap.find(CallMI);
@@ -552,18 +778,21 @@ static void collectCallSiteParameters(const MachineInstr *CallMI,
if (CallFwdRegsInfo == CalleesMap.end())
return;
- auto *MBB = CallMI->getParent();
- const auto &TRI = MF->getSubtarget().getRegisterInfo();
- const auto &TII = MF->getSubtarget().getInstrInfo();
- const auto &TLI = MF->getSubtarget().getTargetLowering();
+ const MachineBasicBlock *MBB = CallMI->getParent();
// Skip the call instruction.
auto I = std::next(CallMI->getReverseIterator());
- DenseSet<unsigned> ForwardedRegWorklist;
+ FwdRegWorklist ForwardedRegWorklist;
+
+ const DIExpression *EmptyExpr =
+ DIExpression::get(MF->getFunction().getContext(), {});
+
// Add all the forwarding registers into the ForwardedRegWorklist.
for (auto ArgReg : CallFwdRegsInfo->second) {
- bool InsertedReg = ForwardedRegWorklist.insert(ArgReg.Reg).second;
+ bool InsertedReg =
+ ForwardedRegWorklist.insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
+ .second;
assert(InsertedReg && "Single register used to forward two arguments?");
(void)InsertedReg;
}
@@ -573,107 +802,29 @@ static void collectCallSiteParameters(const MachineInstr *CallMI,
// the describeLoadedValue()). For those remaining arguments in the working
// list, for which we do not describe a loaded value by
// the describeLoadedValue(), we try to generate an entry value expression
- // for their call site value desctipion, if the call is within the entry MBB.
- // The RegsForEntryValues maps a forwarding register into the register holding
- // the entry value.
+ // for their call site value description, if the call is within the entry MBB.
// TODO: Handle situations when call site parameter value can be described
- // as the entry value within basic blocks other then the first one.
+ // as the entry value within basic blocks other than the first one.
bool ShouldTryEmitEntryVals = MBB->getIterator() == MF->begin();
- DenseMap<unsigned, unsigned> RegsForEntryValues;
- // If the MI is an instruction defining one or more parameters' forwarding
- // registers, add those defines. We can currently only describe forwarded
- // registers that are explicitly defined, but keep track of implicit defines
- // also to remove those registers from the work list.
- auto getForwardingRegsDefinedByMI = [&](const MachineInstr &MI,
- SmallVectorImpl<unsigned> &Explicit,
- SmallVectorImpl<unsigned> &Implicit) {
- if (MI.isDebugInstr())
+ // Search for a loading value in forwarding registers inside call delay slot.
+ if (CallMI->hasDelaySlot()) {
+ auto Suc = std::next(CallMI->getIterator());
+ // Only one-instruction delay slot is supported.
+ auto BundleEnd = llvm::getBundleEnd(CallMI->getIterator());
+ (void)BundleEnd;
+ assert(std::next(Suc) == BundleEnd &&
+ "More than one instruction in call delay slot");
+ // Try to interpret value loaded by instruction.
+ if (!interpretNextInstr(&*Suc, ForwardedRegWorklist, Params))
return;
-
- for (const MachineOperand &MO : MI.operands()) {
- if (MO.isReg() && MO.isDef() &&
- Register::isPhysicalRegister(MO.getReg())) {
- for (auto FwdReg : ForwardedRegWorklist) {
- if (TRI->regsOverlap(FwdReg, MO.getReg())) {
- if (MO.isImplicit())
- Implicit.push_back(FwdReg);
- else
- Explicit.push_back(FwdReg);
- }
- }
- }
- }
- };
-
- auto finishCallSiteParam = [&](DbgValueLoc DbgLocVal, unsigned Reg) {
- unsigned FwdReg = Reg;
- if (ShouldTryEmitEntryVals) {
- auto EntryValReg = RegsForEntryValues.find(Reg);
- if (EntryValReg != RegsForEntryValues.end())
- FwdReg = EntryValReg->second;
- }
-
- DbgCallSiteParam CSParm(FwdReg, DbgLocVal);
- Params.push_back(CSParm);
- ++NumCSParams;
- };
+ }
// Search for a loading value in forwarding registers.
for (; I != MBB->rend(); ++I) {
- // Skip bundle headers.
- if (I->isBundle())
- continue;
-
- // If the next instruction is a call we can not interpret parameter's
- // forwarding registers or we finished the interpretation of all parameters.
- if (I->isCall())
+ // Try to interpret values loaded by instruction.
+ if (!interpretNextInstr(&*I, ForwardedRegWorklist, Params))
return;
-
- if (ForwardedRegWorklist.empty())
- return;
-
- SmallVector<unsigned, 4> ExplicitFwdRegDefs;
- SmallVector<unsigned, 4> ImplicitFwdRegDefs;
- getForwardingRegsDefinedByMI(*I, ExplicitFwdRegDefs, ImplicitFwdRegDefs);
- if (ExplicitFwdRegDefs.empty() && ImplicitFwdRegDefs.empty())
- continue;
-
- // If the MI clobbers more then one forwarding register we must remove
- // all of them from the working list.
- for (auto Reg : concat<unsigned>(ExplicitFwdRegDefs, ImplicitFwdRegDefs))
- ForwardedRegWorklist.erase(Reg);
-
- for (auto ParamFwdReg : ExplicitFwdRegDefs) {
- if (auto ParamValue = TII->describeLoadedValue(*I, ParamFwdReg)) {
- if (ParamValue->first.isImm()) {
- int64_t Val = ParamValue->first.getImm();
- DbgValueLoc DbgLocVal(ParamValue->second, Val);
- finishCallSiteParam(DbgLocVal, ParamFwdReg);
- } else if (ParamValue->first.isReg()) {
- Register RegLoc = ParamValue->first.getReg();
- // TODO: For now, there is no use of describing the value loaded into the
- // register that is also the source registers (e.g. $r0 = add $r0, x).
- if (ParamFwdReg == RegLoc)
- continue;
-
- unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
- Register FP = TRI->getFrameRegister(*MF);
- bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP);
- if (TRI->isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP) {
- DbgValueLoc DbgLocVal(ParamValue->second,
- MachineLocation(RegLoc,
- /*IsIndirect=*/IsSPorFP));
- finishCallSiteParam(DbgLocVal, ParamFwdReg);
- // TODO: Add support for entry value plus an expression.
- } else if (ShouldTryEmitEntryVals &&
- ParamValue->second->getNumElements() == 0) {
- ForwardedRegWorklist.insert(RegLoc);
- RegsForEntryValues[RegLoc] = ParamFwdReg;
- }
- }
- }
- }
}
// Emit the call site parameter's value as an entry value.
@@ -682,15 +833,8 @@ static void collectCallSiteParameters(const MachineInstr *CallMI,
DIExpression *EntryExpr = DIExpression::get(
MF->getFunction().getContext(), {dwarf::DW_OP_LLVM_entry_value, 1});
for (auto RegEntry : ForwardedRegWorklist) {
- unsigned FwdReg = RegEntry;
- auto EntryValReg = RegsForEntryValues.find(RegEntry);
- if (EntryValReg != RegsForEntryValues.end())
- FwdReg = EntryValReg->second;
-
- DbgValueLoc DbgLocVal(EntryExpr, MachineLocation(RegEntry));
- DbgCallSiteParam CSParm(FwdReg, DbgLocVal);
- Params.push_back(CSParm);
- ++NumCSParams;
+ MachineLocation MLoc(RegEntry.first);
+ finishCallSiteParams(MLoc, EntryExpr, RegEntry.second, Params);
}
}
}
@@ -711,7 +855,25 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
assert(TII && "TargetInstrInfo not found: cannot label tail calls");
- bool ApplyGNUExtensions = getDwarfVersion() == 4 && tuneForGDB();
+
+ // Delay slot support check.
+ auto delaySlotSupported = [&](const MachineInstr &MI) {
+ if (!MI.isBundledWithSucc())
+ return false;
+ auto Suc = std::next(MI.getIterator());
+ auto CallInstrBundle = getBundleStart(MI.getIterator());
+ (void)CallInstrBundle;
+ auto DelaySlotBundle = getBundleStart(Suc);
+ (void)DelaySlotBundle;
+ // Ensure that label after call is following delay slot instruction.
+ // Ex. CALL_INSTRUCTION {
+ // DELAY_SLOT_INSTRUCTION }
+ // LABEL_AFTER_CALL
+ assert(getLabelAfterInsn(&*CallInstrBundle) ==
+ getLabelAfterInsn(&*DelaySlotBundle) &&
+ "Call and its successor instruction don't have same label after.");
+ return true;
+ };
// Emit call site entries for each call or tail call in the function.
for (const MachineBasicBlock &MBB : MF) {
@@ -724,11 +886,16 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
// Skip instructions which aren't calls. Both calls and tail-calling jump
// instructions (e.g TAILJMPd64) are classified correctly here.
- if (!MI.isCall())
+ if (!MI.isCandidateForCallSiteEntry())
continue;
- // TODO: Add support for targets with delay slots (see: beginInstruction).
- if (MI.hasDelaySlot())
+ // Skip instructions marked as frame setup, as they are not interesting to
+ // the user.
+ if (MI.getFlag(MachineInstr::FrameSetup))
+ continue;
+
+ // Check if delay slot support is enabled.
+ if (MI.hasDelaySlot() && !delaySlotSupported(*&MI))
return;
// If this is a direct call, find the callee's subprogram.
@@ -739,7 +906,7 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
continue;
unsigned CallReg = 0;
- const DISubprogram *CalleeSP = nullptr;
+ DIE *CalleeDIE = nullptr;
const Function *CalleeDecl = nullptr;
if (CalleeOp.isReg()) {
CallReg = CalleeOp.getReg();
@@ -749,7 +916,19 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
CalleeDecl = dyn_cast<Function>(CalleeOp.getGlobal());
if (!CalleeDecl || !CalleeDecl->getSubprogram())
continue;
- CalleeSP = CalleeDecl->getSubprogram();
+ const DISubprogram *CalleeSP = CalleeDecl->getSubprogram();
+
+ if (CalleeSP->isDefinition()) {
+ // Ensure that a subprogram DIE for the callee is available in the
+ // appropriate CU.
+ CalleeDIE = &constructSubprogramDefinitionDIE(CalleeSP);
+ } else {
+ // Create the declaration DIE if it is missing. This is required to
+ // support compilation of old bitcode with an incomplete list of
+ // retained metadata.
+ CalleeDIE = CU.getOrCreateSubprogramDIE(CalleeSP);
+ }
+ assert(CalleeDIE && "Must have a DIE for the callee");
}
// TODO: Omit call site entries for runtime calls (objc_msgSend, etc).
@@ -762,25 +941,21 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
const MachineInstr *TopLevelCallMI =
MI.isInsideBundle() ? &*getBundleStart(MI.getIterator()) : &MI;
- // For tail calls, for non-gdb tuning, no return PC information is needed.
- // For regular calls (and tail calls in GDB tuning), the return PC
- // is needed to disambiguate paths in the call graph which could lead to
- // some target function.
- const MCExpr *PCOffset =
- (IsTail && !tuneForGDB())
- ? nullptr
- : getFunctionLocalOffsetAfterInsn(TopLevelCallMI);
-
- // Return address of a call-like instruction for a normal call or a
- // jump-like instruction for a tail call. This is needed for
- // GDB + DWARF 4 tuning.
+ // For non-tail calls, the return PC is needed to disambiguate paths in
+ // the call graph which could lead to some target function. For tail
+ // calls, no return PC information is needed, unless tuning for GDB in
+ // DWARF4 mode in which case we fake a return PC for compatibility.
const MCSymbol *PCAddr =
- ApplyGNUExtensions
+ (!IsTail || CU.useGNUAnalogForDwarf5Feature())
? const_cast<MCSymbol *>(getLabelAfterInsn(TopLevelCallMI))
: nullptr;
- assert((IsTail || PCOffset || PCAddr) &&
- "Call without return PC information");
+ // For tail calls, it's necessary to record the address of the branch
+ // instruction so that the debugger can show where the tail call occurred.
+ const MCSymbol *CallAddr =
+ IsTail ? getLabelBeforeInsn(TopLevelCallMI) : nullptr;
+
+ assert((IsTail || PCAddr) && "Non-tail call without return PC");
LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> "
<< (CalleeDecl ? CalleeDecl->getName()
@@ -789,13 +964,11 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
->getName(CallReg)))
<< (IsTail ? " [IsTail]" : "") << "\n");
- DIE &CallSiteDIE =
- CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, IsTail, PCAddr,
- PCOffset, CallReg);
+ DIE &CallSiteDIE = CU.constructCallSiteEntryDIE(
+ ScopeDIE, CalleeDIE, IsTail, PCAddr, CallAddr, CallReg);
- // GDB and LLDB support call site parameter debug info.
- if (Asm->TM.Options.EnableDebugEntryValues &&
- (tuneForGDB() || tuneForLLDB())) {
+ // Optionally emit call-site-param debug info.
+ if (emitDebugEntryValues()) {
ParamSet Params;
// Try to interpret values of call site parameters.
collectCallSiteParameters(&MI, Params);
@@ -828,6 +1001,12 @@ void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
DIUnit->getSourceLanguage());
NewCU.addString(Die, dwarf::DW_AT_name, FN);
+ StringRef SysRoot = DIUnit->getSysRoot();
+ if (!SysRoot.empty())
+ NewCU.addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
+ StringRef SDK = DIUnit->getSDK();
+ if (!SDK.empty())
+ NewCU.addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
// Add DW_str_offsets_base to the unit DIE, except for split units.
if (useSegmentedStringOffsetsTable() && !useSplitDwarf())
@@ -840,7 +1019,6 @@ void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
// skeleton CU and so we don't need to duplicate it here.
if (!CompilationDir.empty())
NewCU.addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
-
addGnuPubAttributes(NewCU, Die);
}
@@ -905,11 +1083,6 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
}
- // Create DIEs for function declarations used for call site debug info.
- for (auto Scope : DIUnit->getRetainedTypes())
- if (auto *SP = dyn_cast_or_null<DISubprogram>(Scope))
- NewCU.getOrCreateSubprogramDIE(SP);
-
CUMap.insert({DIUnit, &NewCU});
CUDieMap.insert({&NewCU.getUnitDie(), &NewCU});
return NewCU;
@@ -1161,8 +1334,7 @@ void DwarfDebug::finalizeModuleInfo() {
// We don't keep track of which addresses are used in which CU so this
// is a bit pessimistic under LTO.
- if ((!AddrPool.isEmpty() || TheCU.hasRangeLists()) &&
- (getDwarfVersion() >= 5 || HasSplitUnit))
+ if ((HasSplitUnit || getDwarfVersion() >= 5) && !AddrPool.isEmpty())
U.addAddrTableBase();
if (getDwarfVersion() >= 5) {
@@ -1178,18 +1350,31 @@ void DwarfDebug::finalizeModuleInfo() {
}
auto *CUNode = cast<DICompileUnit>(P.first);
- // If compile Unit has macros, emit "DW_AT_macro_info" attribute.
+ // If compile Unit has macros, emit "DW_AT_macro_info/DW_AT_macros"
+ // attribute.
if (CUNode->getMacros()) {
- if (useSplitDwarf())
- TheCU.addSectionDelta(TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
+ if (getDwarfVersion() >= 5) {
+ if (useSplitDwarf())
+ TheCU.addSectionDelta(
+ TheCU.getUnitDie(), dwarf::DW_AT_macros, U.getMacroLabelBegin(),
+ TLOF.getDwarfMacroDWOSection()->getBeginSymbol());
+ else
+ U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
- TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol());
- else
- U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
- U.getMacroLabelBegin(),
- TLOF.getDwarfMacinfoSection()->getBeginSymbol());
+ TLOF.getDwarfMacroSection()->getBeginSymbol());
+ } else {
+ if (useSplitDwarf())
+ TheCU.addSectionDelta(
+ TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
+ U.getMacroLabelBegin(),
+ TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol());
+ else
+ U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
+ U.getMacroLabelBegin(),
+ TLOF.getDwarfMacinfoSection()->getBeginSymbol());
+ }
+ }
}
- }
// Emit all frontend-produced Skeleton CUs, i.e., Clang modules.
for (auto *CUNode : MMI->getModule()->debug_compile_units())
@@ -1221,8 +1406,6 @@ void DwarfDebug::endModule() {
// Finalize the debug info for the module.
finalizeModuleInfo();
- emitDebugStr();
-
if (useSplitDwarf())
// Emit debug_loc.dwo/debug_loclists.dwo section.
emitDebugLocDWO();
@@ -1247,9 +1430,11 @@ void DwarfDebug::endModule() {
// Emit info into a debug macinfo.dwo section.
emitDebugMacinfoDWO();
else
- // Emit info into a debug macinfo section.
+ // Emit info into a debug macinfo/macro section.
emitDebugMacinfo();
+ emitDebugStr();
+
if (useSplitDwarf()) {
emitDebugStrDWO();
emitDebugInfoDWO();
@@ -1308,6 +1493,7 @@ void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
void DwarfDebug::collectVariableInfoFromMFTable(
DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) {
SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
+ LLVM_DEBUG(dbgs() << "DwarfDebug: collecting variables from MF side table\n");
for (const auto &VI : Asm->MF->getVariableDbgInfo()) {
if (!VI.Var)
continue;
@@ -1319,13 +1505,18 @@ void DwarfDebug::collectVariableInfoFromMFTable(
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
// If variable scope is not found then skip this variable.
- if (!Scope)
+ if (!Scope) {
+ LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()
+ << ", no variable scope found\n");
continue;
+ }
ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
auto RegVar = std::make_unique<DbgVariable>(
cast<DILocalVariable>(Var.first), Var.second);
RegVar->initializeMMI(VI.Expr, VI.Slot);
+ LLVM_DEBUG(dbgs() << "Created DbgVariable for " << VI.Var->getName()
+ << "\n");
if (DbgVariable *DbgVar = MFVars.lookup(Var))
DbgVar->addMMIEntry(*RegVar);
else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
@@ -1353,11 +1544,20 @@ static bool validThroughout(LexicalScopes &LScopes,
if (LSRange.size() == 0)
return false;
+
// Determine if the DBG_VALUE is valid at the beginning of its lexical block.
const MachineInstr *LScopeBegin = LSRange.front().first;
// Early exit if the lexical scope begins outside of the current block.
if (LScopeBegin->getParent() != MBB)
return false;
+
+ // If there are instructions belonging to our scope in another block, and
+ // we're not a constant (see DWARF2 comment below), then we can't be
+ // validThroughout.
+ const MachineInstr *LScopeEnd = LSRange.back().second;
+ if (RangeEnd && LScopeEnd->getParent() != MBB)
+ return false;
+
MachineBasicBlock::const_reverse_iterator Pred(DbgValue);
for (++Pred; Pred != MBB->rend(); ++Pred) {
if (Pred->getFlag(MachineInstr::FrameSetup))
@@ -1378,19 +1578,35 @@ static bool validThroughout(LexicalScopes &LScopes,
if (!RangeEnd)
return true;
- // Fail if there are instructions belonging to our scope in another block.
- const MachineInstr *LScopeEnd = LSRange.back().second;
- if (LScopeEnd->getParent() != MBB)
- return false;
-
// Single, constant DBG_VALUEs in the prologue are promoted to be live
// throughout the function. This is a hack, presumably for DWARF v2 and not
// necessarily correct. It would be much better to use a dbg.declare instead
// if we know the constant is live throughout the scope.
- if (DbgValue->getOperand(0).isImm() && MBB->pred_empty())
+ if (DbgValue->getDebugOperand(0).isImm() && MBB->pred_empty())
return true;
- return false;
+ // Now check for situations where an "open-ended" DBG_VALUE isn't enough to
+ // determine eligibility for a single location, e.g. nested scopes, inlined
+ // functions.
+ // FIXME: For now we just handle a simple (but common) case where the scope
+ // is contained in MBB. We could be smarter here.
+ //
+ // At this point we know that our scope ends in MBB. So, if RangeEnd exists
+ // outside of the block we can ignore it; the location is just leaking outside
+ // its scope.
+ assert(LScopeEnd->getParent() == MBB && "Scope ends outside MBB");
+ if (RangeEnd->getParent() != DbgValue->getParent())
+ return true;
+
+ // The location range and variable's enclosing scope are both contained within
+ // MBB, test if location terminates before end of scope.
+ for (auto I = RangeEnd->getIterator(); I != MBB->end(); ++I)
+ if (&*I == LScopeEnd)
+ return false;
+
+ // There's a single location which starts at the scope start, and ends at or
+ // after the scope end.
+ return true;
}
/// Build the location list for all DBG_VALUEs in the function that
@@ -1426,8 +1642,10 @@ static bool validThroughout(LexicalScopes &LScopes,
// [1-3) [(reg0, fragment 0, 32), (reg1, fragment 32, 32)]
// [3-4) [(reg1, fragment 32, 32), (123, fragment 64, 32)]
// [4-) [(@g, fragment 0, 96)]
-bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
- const DbgValueHistoryMap::Entries &Entries) {
+bool DwarfDebug::buildLocationList(
+ SmallVectorImpl<DebugLocEntry> &DebugLoc,
+ const DbgValueHistoryMap::Entries &Entries,
+ DenseSet<const MachineBasicBlock *> &VeryLargeBlocks) {
using OpenRange =
std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
SmallVector<OpenRange, 4> OpenRanges;
@@ -1453,7 +1671,8 @@ bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
const MCSymbol *EndLabel;
if (std::next(EI) == Entries.end()) {
- EndLabel = Asm->getFunctionEnd();
+ const MachineBasicBlock &EndMBB = Asm->MF->back();
+ EndLabel = Asm->MBBSectionRanges[EndMBB.getSectionIDNum()].EndLabel;
if (EI->isClobber())
EndMI = EI->getInstr();
}
@@ -1522,8 +1741,14 @@ bool DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
DebugLoc.pop_back();
}
- return DebugLoc.size() == 1 && isSafeForSingleLocation &&
- validThroughout(LScopes, StartDebugMI, EndMI);
+ // If there's a single entry, safe for a single location, and not part of
+ // an over-sized basic block, then ask validThroughout whether this
+ // location can be represented as a single variable location.
+ if (DebugLoc.size() != 1 || !isSafeForSingleLocation)
+ return false;
+ if (VeryLargeBlocks.count(StartDebugMI->getParent()))
+ return false;
+ return validThroughout(LScopes, StartDebugMI, EndMI);
}
DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU,
@@ -1555,6 +1780,13 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
// Grab the variable info that was squirreled away in the MMI side-table.
collectVariableInfoFromMFTable(TheCU, Processed);
+ // Identify blocks that are unreasonably sized, so that we can later
+ // skip lexical scope analysis over them.
+ DenseSet<const MachineBasicBlock *> VeryLargeBlocks;
+ for (const auto &MBB : *CurFn)
+ if (MBB.size() > LocationAnalysisSizeLimit)
+ VeryLargeBlocks.insert(&MBB);
+
for (const auto &I : DbgValues) {
InlinedEntity IV = I.first;
if (Processed.count(IV))
@@ -1591,7 +1823,8 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
if (HistSize == 1 || SingleValueWithClobber) {
const auto *End =
SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr;
- if (validThroughout(LScopes, MInsn, End)) {
+ if (VeryLargeBlocks.count(MInsn->getParent()) == 0 &&
+ validThroughout(LScopes, MInsn, End)) {
RegVar->initializeDbgValue(MInsn);
continue;
}
@@ -1606,7 +1839,8 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
// Build the location list for this variable.
SmallVector<DebugLocEntry, 8> Entries;
- bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
+ bool isValidSingleLocation =
+ buildLocationList(Entries, HistoryMapEntries, VeryLargeBlocks);
// Check whether buildLocationList managed to merge all locations to one
// that is valid throughout the variable's scope. If so, produce single
@@ -1675,11 +1909,45 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
// Process beginning of an instruction.
void DwarfDebug::beginInstruction(const MachineInstr *MI) {
+ const MachineFunction &MF = *MI->getMF();
+ const auto *SP = MF.getFunction().getSubprogram();
+ bool NoDebug =
+ !SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug;
+
+ // Delay slot support check.
+ auto delaySlotSupported = [](const MachineInstr &MI) {
+ if (!MI.isBundledWithSucc())
+ return false;
+ auto Suc = std::next(MI.getIterator());
+ (void)Suc;
+ // Ensure that delay slot instruction is successor of the call instruction.
+ // Ex. CALL_INSTRUCTION {
+ // DELAY_SLOT_INSTRUCTION }
+ assert(Suc->isBundledWithPred() &&
+ "Call bundle instructions are out of order");
+ return true;
+ };
+
+ // When describing calls, we need a label for the call instruction.
+ if (!NoDebug && SP->areAllCallsDescribed() &&
+ MI->isCandidateForCallSiteEntry(MachineInstr::AnyInBundle) &&
+ (!MI->hasDelaySlot() || delaySlotSupported(*MI))) {
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
+ bool IsTail = TII->isTailCall(*MI);
+ // For tail calls, we need the address of the branch instruction for
+ // DW_AT_call_pc.
+ if (IsTail)
+ requestLabelBeforeInsn(MI);
+ // For non-tail calls, we need the return address for the call for
+ // DW_AT_call_return_pc. Under GDB tuning, this information is needed for
+ // tail calls as well.
+ requestLabelAfterInsn(MI);
+ }
+
DebugHandlerBase::beginInstruction(MI);
assert(CurMI);
- const auto *SP = MI->getMF()->getFunction().getSubprogram();
- if (!SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug)
+ if (NoDebug)
return;
// Check if source location changes, but ignore DBG_VALUE and CFI locations.
@@ -1693,11 +1961,6 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
unsigned LastAsmLine =
Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
- // Request a label after the call in order to emit AT_return_pc information
- // in call site entries. TODO: Add support for targets with delay slots.
- if (SP->areAllCallsDescribed() && MI->isCall() && !MI->hasDelaySlot())
- requestLabelAfterInsn(MI);
-
if (DL == PrevInstLoc) {
// If we have an ongoing unspecified location, nothing to do here.
if (!DL)
@@ -1796,7 +2059,7 @@ static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col,
FileNo = static_cast<DwarfCompileUnit &>(*DCUs[CUID])
.getOrCreateSourceID(Scope->getFile());
}
- Asm.OutStreamer->EmitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
+ Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
Discriminator, Fn);
}
@@ -1828,9 +2091,6 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
if (SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug)
return;
- SectionLabels.insert(std::make_pair(&Asm->getFunctionBegin()->getSection(),
- Asm->getFunctionBegin()));
-
DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
// Set DwarfDwarfCompileUnitID in MCContext to the Compile Unit this function
@@ -1878,7 +2138,9 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
collectEntityInfo(TheCU, SP, Processed);
// Add the range of this function to the list of ranges for the CU.
- TheCU.addRange({Asm->getFunctionBegin(), Asm->getFunctionEnd()});
+ // With basic block sections, add ranges for all basic block sections.
+ for (const auto &R : Asm->MBBSectionRanges)
+ TheCU.addRange({R.second.BeginLabel, R.second.EndLabel});
// Under -gmlt, skip building the subprogram if there are no inlined
// subroutines inside it. But with -fdebug-info-for-profiling, the subprogram
@@ -2107,7 +2369,7 @@ void DwarfDebug::emitDebugPubSections() {
void DwarfDebug::emitSectionReference(const DwarfCompileUnit &CU) {
if (useSectionsAsReferences())
- Asm->EmitDwarfOffset(CU.getSection()->getBeginSymbol(),
+ Asm->emitDwarfOffset(CU.getSection()->getBeginSymbol(),
CU.getDebugSectionOffset());
else
Asm->emitDwarfSymbolReference(CU.getLabelBegin());
@@ -2123,9 +2385,9 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
Asm->OutStreamer->AddComment("Length of Public " + Name + " Info");
MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin");
MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end");
- Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
+ Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
- Asm->OutStreamer->EmitLabel(BeginLabel);
+ Asm->OutStreamer->emitLabel(BeginLabel);
Asm->OutStreamer->AddComment("DWARF Version");
Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION);
@@ -2153,12 +2415,12 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
}
Asm->OutStreamer->AddComment("External Name");
- Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1));
+ Asm->OutStreamer->emitBytes(StringRef(Name, GI.getKeyLength() + 1));
}
Asm->OutStreamer->AddComment("End Mark");
Asm->emitInt32(0);
- Asm->OutStreamer->EmitLabel(EndLabel);
+ Asm->OutStreamer->emitLabel(EndLabel);
}
/// Emit null-terminated strings into a debug str section.
@@ -2189,7 +2451,7 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
DWARFDataExtractor Data(StringRef(DebugLocs.getBytes(Entry).data(),
DebugLocs.getBytes(Entry).size()),
Asm->getDataLayout().isLittleEndian(), PtrSize);
- DWARFExpression Expr(Data, getDwarfVersion(), PtrSize);
+ DWARFExpression Expr(Data, PtrSize, Asm->OutContext.getDwarfFormat());
using Encoding = DWARFExpression::Operation::Encoding;
uint64_t Offset = 0;
@@ -2202,18 +2464,14 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
if (Op.getDescription().Op[I] == Encoding::SizeNA)
continue;
if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) {
- if (CU) {
- uint64_t Offset = CU->ExprRefedBaseTypes[Op.getRawOperand(I)].Die->getOffset();
- assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
- Asm->EmitULEB128(Offset, nullptr, ULEB128PadSize);
- } else {
- // Emit a reference to the 'generic type'.
- Asm->EmitULEB128(0, nullptr, ULEB128PadSize);
- }
- // Make sure comments stay aligned.
- for (unsigned J = 0; J < ULEB128PadSize; ++J)
- if (Comment != End)
- Comment++;
+ uint64_t Offset =
+ CU->ExprRefedBaseTypes[Op.getRawOperand(I)].Die->getOffset();
+ assert(Offset < (1ULL << (ULEB128PadSize * 7)) && "Offset wont fit");
+ Streamer.emitULEB128(Offset, "", ULEB128PadSize);
+ // Make sure comments stay aligned.
+ for (unsigned J = 0; J < ULEB128PadSize; ++J)
+ if (Comment != End)
+ Comment++;
} else {
for (uint64_t J = Offset; J < Op.getOperandEndOffset(I); ++J)
Streamer.EmitInt8(Data.getData()[J], Comment != End ? *(Comment++) : "");
@@ -2239,14 +2497,11 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.addUnsignedConstant(Value.getInt());
} else if (Value.isLocation()) {
MachineLocation Location = Value.getLoc();
- if (Location.isIndirect())
- DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.setLocation(Location, DIExpr);
DIExpressionCursor Cursor(DIExpr);
- if (DIExpr->isEntryValue()) {
- DwarfExpr.setEntryValueFlag();
+ if (DIExpr->isEntryValue())
DwarfExpr.beginEntryValueExpression(Cursor);
- }
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
@@ -2256,7 +2511,7 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
TargetIndexLocation Loc = Value.getTargetIndexLocation();
// TODO TargetIndexLocation is a target-independent. Currently only the WebAssembly-specific
// encoding is supported.
- DwarfExpr.addWasmLocation(Loc.Index, Loc.Offset);
+ DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
} else if (Value.isConstantFP()) {
APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
DwarfExpr.addUnsignedConstant(RawBytes);
@@ -2280,8 +2535,7 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
assert(llvm::all_of(Values, [](DbgValueLoc P) {
return P.isFragment();
}) && "all values are expected to be fragments");
- assert(std::is_sorted(Values.begin(), Values.end()) &&
- "fragments are expected to be sorted");
+ assert(llvm::is_sorted(Values) && "fragments are expected to be sorted");
for (auto Fragment : Values)
DwarfDebug::emitDebugLocValue(AP, BT, Fragment, DwarfExpr);
@@ -2300,7 +2554,7 @@ void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry,
// Emit the size.
Asm->OutStreamer->AddComment("Loc expr size");
if (getDwarfVersion() >= 5)
- Asm->EmitULEB128(DebugLocs.getBytes(Entry).size());
+ Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
Asm->emitInt16(DebugLocs.getBytes(Entry).size());
else {
@@ -2314,41 +2568,19 @@ void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry,
emitDebugLocEntry(Streamer, Entry, CU);
}
-// Emit the common part of the DWARF 5 range/locations list tables header.
-static void emitListsTableHeaderStart(AsmPrinter *Asm,
- MCSymbol *TableStart,
- MCSymbol *TableEnd) {
- // Build the table header, which starts with the length field.
- Asm->OutStreamer->AddComment("Length");
- Asm->EmitLabelDifference(TableEnd, TableStart, 4);
- Asm->OutStreamer->EmitLabel(TableStart);
- // Version number (DWARF v5 and later).
- Asm->OutStreamer->AddComment("Version");
- Asm->emitInt16(Asm->OutStreamer->getContext().getDwarfVersion());
- // Address size.
- Asm->OutStreamer->AddComment("Address size");
- Asm->emitInt8(Asm->MAI->getCodePointerSize());
- // Segment selector size.
- Asm->OutStreamer->AddComment("Segment selector size");
- Asm->emitInt8(0);
-}
-
// Emit the header of a DWARF 5 range list table list table. Returns the symbol
// that designates the end of the table for the caller to emit when the table is
// complete.
static MCSymbol *emitRnglistsTableHeader(AsmPrinter *Asm,
const DwarfFile &Holder) {
- MCSymbol *TableStart = Asm->createTempSymbol("debug_rnglist_table_start");
- MCSymbol *TableEnd = Asm->createTempSymbol("debug_rnglist_table_end");
- emitListsTableHeaderStart(Asm, TableStart, TableEnd);
+ MCSymbol *TableEnd = mcdwarf::emitListsTableHeaderStart(*Asm->OutStreamer);
Asm->OutStreamer->AddComment("Offset entry count");
Asm->emitInt32(Holder.getRangeLists().size());
- Asm->OutStreamer->EmitLabel(Holder.getRnglistsTableBaseSym());
+ Asm->OutStreamer->emitLabel(Holder.getRnglistsTableBaseSym());
for (const RangeSpanList &List : Holder.getRangeLists())
- Asm->EmitLabelDifference(List.Label, Holder.getRnglistsTableBaseSym(),
- 4);
+ Asm->emitLabelDifference(List.Label, Holder.getRnglistsTableBaseSym(), 4);
return TableEnd;
}
@@ -2358,18 +2590,16 @@ static MCSymbol *emitRnglistsTableHeader(AsmPrinter *Asm,
// complete.
static MCSymbol *emitLoclistsTableHeader(AsmPrinter *Asm,
const DwarfDebug &DD) {
- MCSymbol *TableStart = Asm->createTempSymbol("debug_loclist_table_start");
- MCSymbol *TableEnd = Asm->createTempSymbol("debug_loclist_table_end");
- emitListsTableHeaderStart(Asm, TableStart, TableEnd);
+ MCSymbol *TableEnd = mcdwarf::emitListsTableHeaderStart(*Asm->OutStreamer);
const auto &DebugLocs = DD.getDebugLocs();
Asm->OutStreamer->AddComment("Offset entry count");
Asm->emitInt32(DebugLocs.getLists().size());
- Asm->OutStreamer->EmitLabel(DebugLocs.getSym());
+ Asm->OutStreamer->emitLabel(DebugLocs.getSym());
for (const auto &List : DebugLocs.getLists())
- Asm->EmitLabelDifference(List.Label, DebugLocs.getSym(), 4);
+ Asm->emitLabelDifference(List.Label, DebugLocs.getSym(), 4);
return TableEnd;
}
@@ -2387,7 +2617,7 @@ static void emitRangeList(
bool UseDwarf5 = DD.getDwarfVersion() >= 5;
// Emit our symbol so we can find the beginning of the range.
- Asm->OutStreamer->EmitLabel(Sym);
+ Asm->OutStreamer->emitLabel(Sym);
// Gather all the ranges that apply to the same section so they can share
// a base address entry.
@@ -2406,9 +2636,9 @@ static void emitRangeList(
if (!UseDwarf5) {
Base = NewBase;
BaseIsSet = true;
- Asm->OutStreamer->EmitIntValue(-1, Size);
+ Asm->OutStreamer->emitIntValue(-1, Size);
Asm->OutStreamer->AddComment(" base address");
- Asm->OutStreamer->EmitSymbolValue(Base, Size);
+ Asm->OutStreamer->emitSymbolValue(Base, Size);
} else if (NewBase != Begin || P.second.size() > 1) {
// Only use a base address if
// * the existing pool address doesn't match (NewBase != Begin)
@@ -2418,13 +2648,13 @@ static void emitRangeList(
Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
Asm->emitInt8(BaseAddressx);
Asm->OutStreamer->AddComment(" base address index");
- Asm->EmitULEB128(DD.getAddressPool().getIndex(Base));
+ Asm->emitULEB128(DD.getAddressPool().getIndex(Base));
}
} else if (BaseIsSet && !UseDwarf5) {
BaseIsSet = false;
assert(!Base);
- Asm->OutStreamer->EmitIntValue(-1, Size);
- Asm->OutStreamer->EmitIntValue(0, Size);
+ Asm->OutStreamer->emitIntValue(-1, Size);
+ Asm->OutStreamer->emitIntValue(0, Size);
}
for (const auto *RS : P.second) {
@@ -2438,23 +2668,23 @@ static void emitRangeList(
Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
Asm->emitInt8(OffsetPair);
Asm->OutStreamer->AddComment(" starting offset");
- Asm->EmitLabelDifferenceAsULEB128(Begin, Base);
+ Asm->emitLabelDifferenceAsULEB128(Begin, Base);
Asm->OutStreamer->AddComment(" ending offset");
- Asm->EmitLabelDifferenceAsULEB128(End, Base);
+ Asm->emitLabelDifferenceAsULEB128(End, Base);
} else {
- Asm->EmitLabelDifference(Begin, Base, Size);
- Asm->EmitLabelDifference(End, Base, Size);
+ Asm->emitLabelDifference(Begin, Base, Size);
+ Asm->emitLabelDifference(End, Base, Size);
}
} else if (UseDwarf5) {
Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
Asm->emitInt8(StartxLength);
Asm->OutStreamer->AddComment(" start index");
- Asm->EmitULEB128(DD.getAddressPool().getIndex(Begin));
+ Asm->emitULEB128(DD.getAddressPool().getIndex(Begin));
Asm->OutStreamer->AddComment(" length");
- Asm->EmitLabelDifferenceAsULEB128(End, Begin);
+ Asm->emitLabelDifferenceAsULEB128(End, Begin);
} else {
- Asm->OutStreamer->EmitSymbolValue(Begin, Size);
- Asm->OutStreamer->EmitSymbolValue(End, Size);
+ Asm->OutStreamer->emitSymbolValue(Begin, Size);
+ Asm->OutStreamer->emitSymbolValue(End, Size);
}
EmitPayload(*RS);
}
@@ -2465,8 +2695,8 @@ static void emitRangeList(
Asm->emitInt8(EndOfList);
} else {
// Terminate the list with two 0 values.
- Asm->OutStreamer->EmitIntValue(0, Size);
- Asm->OutStreamer->EmitIntValue(0, Size);
+ Asm->OutStreamer->emitIntValue(0, Size);
+ Asm->OutStreamer->emitIntValue(0, Size);
}
}
@@ -2496,7 +2726,7 @@ void DwarfDebug::emitDebugLocImpl(MCSection *Sec) {
emitLocList(*this, Asm, List);
if (TableEnd)
- Asm->OutStreamer->EmitLabel(TableEnd);
+ Asm->OutStreamer->emitLabel(TableEnd);
}
// Emit locations into the .debug_loc/.debug_loclists section.
@@ -2519,7 +2749,7 @@ void DwarfDebug::emitDebugLocDWO() {
for (const auto &List : DebugLocs.getLists()) {
Asm->OutStreamer->SwitchSection(
Asm->getObjFileLowering().getDwarfLocDWOSection());
- Asm->OutStreamer->EmitLabel(List.Label);
+ Asm->OutStreamer->emitLabel(List.Label);
for (const auto &Entry : DebugLocs.getEntries(List)) {
// GDB only supports startx_length in pre-standard split-DWARF.
@@ -2527,14 +2757,15 @@ void DwarfDebug::emitDebugLocDWO() {
// offset_pair, so the implementations can't really share much since they
// need to use different representations)
// * as of October 2018, at least
- // Ideally/in v5, this could use SectionLabels to reuse existing addresses
- // in the address pool to minimize object size/relocations.
+ //
+ // In v5 (see emitLocList), this uses SectionLabels to reuse existing
+ // addresses in the address pool to minimize object size/relocations.
Asm->emitInt8(dwarf::DW_LLE_startx_length);
unsigned idx = AddrPool.getIndex(Entry.Begin);
- Asm->EmitULEB128(idx);
+ Asm->emitULEB128(idx);
// Also the pre-standard encoding is slightly different, emitting this as
// an address-length entry here, but its a ULEB128 in DWARFv5 loclists.
- Asm->EmitLabelDifference(Entry.End, Entry.Begin, 4);
+ Asm->emitLabelDifference(Entry.End, Entry.Begin, 4);
emitDebugLocEntryLocation(Entry, List.CU);
}
Asm->emitInt8(dwarf::DW_LLE_end_of_list);
@@ -2679,11 +2910,11 @@ void DwarfDebug::emitDebugARanges() {
Asm->OutStreamer->emitFill(Padding, 0xff);
for (const ArangeSpan &Span : List) {
- Asm->EmitLabelReference(Span.Start, PtrSize);
+ Asm->emitLabelReference(Span.Start, PtrSize);
// Calculate the size as being from the span start to it's end.
if (Span.End) {
- Asm->EmitLabelDifference(Span.End, Span.Start, PtrSize);
+ Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
} else {
// For symbols without an end marker (e.g. common), we
// write a single arange entry containing just that one symbol.
@@ -2691,13 +2922,13 @@ void DwarfDebug::emitDebugARanges() {
if (Size == 0)
Size = 1;
- Asm->OutStreamer->EmitIntValue(Size, PtrSize);
+ Asm->OutStreamer->emitIntValue(Size, PtrSize);
}
}
Asm->OutStreamer->AddComment("ARange terminator");
- Asm->OutStreamer->EmitIntValue(0, PtrSize);
- Asm->OutStreamer->EmitIntValue(0, PtrSize);
+ Asm->OutStreamer->emitIntValue(0, PtrSize);
+ Asm->OutStreamer->emitIntValue(0, PtrSize);
}
}
@@ -2733,7 +2964,7 @@ void DwarfDebug::emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section
emitRangeList(*this, Asm, List);
if (TableEnd)
- Asm->OutStreamer->EmitLabel(TableEnd);
+ Asm->OutStreamer->emitLabel(TableEnd);
}
/// Emit address ranges into the .debug_ranges section or into the DWARF v5
@@ -2752,6 +2983,27 @@ void DwarfDebug::emitDebugRangesDWO() {
Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
}
+/// Emit the header of a DWARF 5 macro section.
+static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD,
+ const DwarfCompileUnit &CU) {
+ enum HeaderFlagMask {
+#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ };
+ uint8_t Flags = 0;
+ Asm->OutStreamer->AddComment("Macro information version");
+ Asm->emitInt16(5);
+ // We are setting Offset and line offset flags unconditionally here,
+ // since we're only supporting DWARF32 and line offset should be mostly
+ // present.
+ // FIXME: Add support for DWARF64.
+ Flags |= MACRO_FLAG_DEBUG_LINE_OFFSET;
+ Asm->OutStreamer->AddComment("Flags: 32 bit, debug_line_offset present");
+ Asm->emitInt8(Flags);
+ Asm->OutStreamer->AddComment("debug_line_offset");
+ Asm->OutStreamer->emitSymbolValue(CU.getLineTableStartSym(), /*Size=*/4);
+}
+
void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
for (auto *MN : Nodes) {
if (auto *M = dyn_cast<DIMacro>(MN))
@@ -2764,26 +3016,72 @@ void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
}
void DwarfDebug::emitMacro(DIMacro &M) {
- Asm->EmitULEB128(M.getMacinfoType());
- Asm->EmitULEB128(M.getLine());
StringRef Name = M.getName();
StringRef Value = M.getValue();
- Asm->OutStreamer->EmitBytes(Name);
- if (!Value.empty()) {
- // There should be one space between macro name and macro value.
- Asm->emitInt8(' ');
- Asm->OutStreamer->EmitBytes(Value);
+ bool UseMacro = getDwarfVersion() >= 5;
+
+ if (UseMacro) {
+ unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
+ ? dwarf::DW_MACRO_define_strx
+ : dwarf::DW_MACRO_undef_strx;
+ Asm->OutStreamer->AddComment(dwarf::MacroString(Type));
+ Asm->emitULEB128(Type);
+ Asm->OutStreamer->AddComment("Line Number");
+ Asm->emitULEB128(M.getLine());
+ Asm->OutStreamer->AddComment("Macro String");
+ if (!Value.empty())
+ Asm->emitULEB128(this->InfoHolder.getStringPool()
+ .getIndexedEntry(*Asm, (Name + " " + Value).str())
+ .getIndex());
+ else
+ // DW_MACRO_undef_strx doesn't have a value, so just emit the macro
+ // string.
+ Asm->emitULEB128(this->InfoHolder.getStringPool()
+ .getIndexedEntry(*Asm, (Name).str())
+ .getIndex());
+ } else {
+ Asm->OutStreamer->AddComment(dwarf::MacinfoString(M.getMacinfoType()));
+ Asm->emitULEB128(M.getMacinfoType());
+ Asm->OutStreamer->AddComment("Line Number");
+ Asm->emitULEB128(M.getLine());
+ Asm->OutStreamer->AddComment("Macro String");
+ Asm->OutStreamer->emitBytes(Name);
+ if (!Value.empty()) {
+ // There should be one space between macro name and macro value.
+ Asm->emitInt8(' ');
+ Asm->OutStreamer->AddComment("Macro Value=");
+ Asm->OutStreamer->emitBytes(Value);
+ }
+ Asm->emitInt8('\0');
}
- Asm->emitInt8('\0');
+}
+
+void DwarfDebug::emitMacroFileImpl(
+ DIMacroFile &F, DwarfCompileUnit &U, unsigned StartFile, unsigned EndFile,
+ StringRef (*MacroFormToString)(unsigned Form)) {
+
+ Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
+ Asm->emitULEB128(StartFile);
+ Asm->OutStreamer->AddComment("Line Number");
+ Asm->emitULEB128(F.getLine());
+ Asm->OutStreamer->AddComment("File Number");
+ Asm->emitULEB128(U.getOrCreateSourceID(F.getFile()));
+ handleMacroNodes(F.getElements(), U);
+ Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
+ Asm->emitULEB128(EndFile);
}
void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
+ // DWARFv5 macro and DWARFv4 macinfo share some common encodings,
+ // so for readibility/uniformity, We are explicitly emitting those.
assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
- Asm->EmitULEB128(dwarf::DW_MACINFO_start_file);
- Asm->EmitULEB128(F.getLine());
- Asm->EmitULEB128(U.getOrCreateSourceID(F.getFile()));
- handleMacroNodes(F.getElements(), U);
- Asm->EmitULEB128(dwarf::DW_MACINFO_end_file);
+ bool UseMacro = getDwarfVersion() >= 5;
+ if (UseMacro)
+ emitMacroFileImpl(F, U, dwarf::DW_MACRO_start_file,
+ dwarf::DW_MACRO_end_file, dwarf::MacroString);
+ else
+ emitMacroFileImpl(F, U, dwarf::DW_MACINFO_start_file,
+ dwarf::DW_MACINFO_end_file, dwarf::MacinfoString);
}
void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
@@ -2796,20 +3094,28 @@ void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
if (Macros.empty())
continue;
Asm->OutStreamer->SwitchSection(Section);
- Asm->OutStreamer->EmitLabel(U.getMacroLabelBegin());
+ Asm->OutStreamer->emitLabel(U.getMacroLabelBegin());
+ if (getDwarfVersion() >= 5)
+ emitMacroHeader(Asm, *this, U);
handleMacroNodes(Macros, U);
Asm->OutStreamer->AddComment("End Of Macro List Mark");
Asm->emitInt8(0);
}
}
-/// Emit macros into a debug macinfo section.
+/// Emit macros into a debug macinfo/macro section.
void DwarfDebug::emitDebugMacinfo() {
- emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoSection());
+ auto &ObjLower = Asm->getObjFileLowering();
+ emitDebugMacinfoImpl(getDwarfVersion() >= 5
+ ? ObjLower.getDwarfMacroSection()
+ : ObjLower.getDwarfMacinfoSection());
}
void DwarfDebug::emitDebugMacinfoDWO() {
- emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoDWOSection());
+ auto &ObjLower = Asm->getObjFileLowering();
+ emitDebugMacinfoImpl(getDwarfVersion() >= 5
+ ? ObjLower.getDwarfMacroDWOSection()
+ : ObjLower.getDwarfMacinfoDWOSection());
}
// DWARF5 Experimental Separate Dwarf emitters.
@@ -2819,7 +3125,6 @@ void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
if (!CompilationDir.empty())
NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
-
addGnuPubAttributes(*NewU, Die);
SkeletonHolder.addUnit(std::move(NewU));
@@ -3073,3 +3378,8 @@ uint16_t DwarfDebug::getDwarfVersion() const {
const MCSymbol *DwarfDebug::getSectionLabel(const MCSection *S) {
return SectionLabels.find(S)->second;
}
+void DwarfDebug::insertSectionLabel(const MCSymbol *S) {
+ if (SectionLabels.insert(std::make_pair(&S->getSection(), S)).second)
+ if (useSplitDwarf() || getDwarfVersion() >= 5)
+ AddrPool.getIndex(S);
+}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index f90dd48458ea..ad2f2f3edd8e 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -49,7 +49,6 @@ namespace llvm {
class AsmPrinter;
class ByteStreamer;
-class DebugLocEntry;
class DIE;
class DwarfCompileUnit;
class DwarfExpression;
@@ -59,7 +58,6 @@ class LexicalScope;
class MachineFunction;
class MCSection;
class MCSymbol;
-class MDNode;
class Module;
//===----------------------------------------------------------------------===//
@@ -327,7 +325,7 @@ class DwarfDebug : public DebugHandlerBase {
const MachineFunction *CurFn = nullptr;
/// If nonnull, stores the CU in which the previous subprogram was contained.
- const DwarfCompileUnit *PrevCU;
+ const DwarfCompileUnit *PrevCU = nullptr;
/// As an optimization, there is no need to emit an entry in the directory
/// table for the same directory as DW_AT_comp_dir.
@@ -386,6 +384,11 @@ class DwarfDebug : public DebugHandlerBase {
/// a monolithic sequence of string offsets.
bool UseSegmentedStringOffsetsTable;
+ /// Enable production of call site parameters needed to print the debug entry
+ /// values. Useful for testing purposes when a debugger does not support the
+ /// feature yet.
+ bool EmitDebugEntryValues;
+
/// Separated Dwarf Variables
/// In general these will all be for bits that are left in the
/// original object file, rather than things that are meant
@@ -442,6 +445,9 @@ class DwarfDebug : public DebugHandlerBase {
/// Construct a DIE for this abstract scope.
void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);
+ /// Construct a DIE for the subprogram definition \p SP and return it.
+ DIE &constructSubprogramDefinitionDIE(const DISubprogram *SP);
+
/// Construct DIEs for call site entries describing the calls in \p MF.
void constructCallSiteEntryDIEs(const DISubprogram &SP, DwarfCompileUnit &CU,
DIE &ScopeDIE, const MachineFunction &MF);
@@ -520,6 +526,9 @@ class DwarfDebug : public DebugHandlerBase {
void emitDebugMacinfoImpl(MCSection *Section);
void emitMacro(DIMacro &M);
void emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U);
+ void emitMacroFileImpl(DIMacroFile &F, DwarfCompileUnit &U,
+ unsigned StartFile, unsigned EndFile,
+ StringRef (*MacroFormToString)(unsigned Form));
void handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U);
/// DWARF 5 Experimental Split Dwarf Emitters
@@ -583,8 +592,10 @@ class DwarfDebug : public DebugHandlerBase {
/// function that describe the same variable. If the resulting
/// list has only one entry that is valid for entire variable's
/// scope return true.
- bool buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
- const DbgValueHistoryMap::Entries &Entries);
+ bool buildLocationList(
+ SmallVectorImpl<DebugLocEntry> &DebugLoc,
+ const DbgValueHistoryMap::Entries &Entries,
+ DenseSet<const MachineBasicBlock *> &VeryLargeBlocks);
/// Collect variable information from the side table maintained by MF.
void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU,
@@ -631,7 +642,6 @@ public:
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier,
DIE &Die, const DICompositeType *CTy);
- friend class NonTypeUnitContext;
class NonTypeUnitContext {
DwarfDebug *DD;
decltype(DwarfDebug::TypeUnitsUnderConstruction) TypeUnitsUnderConstruction;
@@ -705,6 +715,10 @@ public:
return UseSegmentedStringOffsetsTable;
}
+ bool emitDebugEntryValues() const {
+ return EmitDebugEntryValues;
+ }
+
bool shareAcrossDWOCUs() const;
/// Returns the Dwarf Version.
@@ -765,6 +779,7 @@ public:
void addSectionLabel(const MCSymbol *Sym);
const MCSymbol *getSectionLabel(const MCSection *S);
+ void insertSectionLabel(const MCSymbol *S);
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
const DbgValueLoc &Value,
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfException.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
index 24bbf58b91ec..c2956380438f 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -66,6 +66,9 @@ public:
void beginFragment(const MachineBasicBlock *MBB,
ExceptionSymbolProvider ESP) override;
+
+ void beginBasicBlock(const MachineBasicBlock &MBB) override;
+ void endBasicBlock(const MachineBasicBlock &MBB) override;
};
class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase {
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 310647f15a5e..d4762121d105 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -40,12 +40,12 @@ void DwarfExpression::emitConstu(uint64_t Value) {
}
void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
- assert(DwarfReg >= 0 && "invalid negative dwarf register number");
- assert((isUnknownLocation() || isRegisterLocation()) &&
- "location description already locked down");
- LocationKind = Register;
- if (DwarfReg < 32) {
- emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
+ assert(DwarfReg >= 0 && "invalid negative dwarf register number");
+ assert((isUnknownLocation() || isRegisterLocation()) &&
+ "location description already locked down");
+ LocationKind = Register;
+ if (DwarfReg < 32) {
+ emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
} else {
emitOp(dwarf::DW_OP_regx, Comment);
emitUnsigned(DwarfReg);
@@ -100,7 +100,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
unsigned MachineReg, unsigned MaxSize) {
if (!llvm::Register::isPhysicalRegister(MachineReg)) {
if (isFrameRegister(TRI, MachineReg)) {
- DwarfRegs.push_back({-1, 0, nullptr});
+ DwarfRegs.push_back(Register::createRegister(-1, nullptr));
return true;
}
return false;
@@ -110,7 +110,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// If this is a valid register number, emit it.
if (Reg >= 0) {
- DwarfRegs.push_back({Reg, 0, nullptr});
+ DwarfRegs.push_back(Register::createRegister(Reg, nullptr));
return true;
}
@@ -122,7 +122,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
unsigned Size = TRI.getSubRegIdxSize(Idx);
unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
- DwarfRegs.push_back({Reg, 0, "super-register"});
+ DwarfRegs.push_back(Register::createRegister(Reg, "super-register"));
// Use a DW_OP_bit_piece to describe the sub-register.
setSubRegisterPiece(Size, RegOffset);
return true;
@@ -149,8 +149,8 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
if (Reg < 0)
continue;
- // Intersection between the bits we already emitted and the bits
- // covered by this subregister.
+ // Used to build the intersection between the bits we already
+ // emitted and the bits covered by this subregister.
SmallBitVector CurSubReg(RegSize, false);
CurSubReg.set(Offset, Offset + Size);
@@ -159,10 +159,13 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
if (Offset < MaxSize && CurSubReg.test(Coverage)) {
// Emit a piece for any gap in the coverage.
if (Offset > CurPos)
- DwarfRegs.push_back(
- {-1, Offset - CurPos, "no DWARF register encoding"});
- DwarfRegs.push_back(
- {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
+ DwarfRegs.push_back(Register::createSubRegister(
+ -1, Offset - CurPos, "no DWARF register encoding"));
+ if (Offset == 0 && Size >= MaxSize)
+ DwarfRegs.push_back(Register::createRegister(Reg, "sub-register"));
+ else
+ DwarfRegs.push_back(Register::createSubRegister(
+ Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"));
}
// Mark it as emitted.
Coverage.set(Offset, Offset + Size);
@@ -173,7 +176,8 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
return false;
// Found a partial or complete DWARF encoding.
if (CurPos < RegSize)
- DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"});
+ DwarfRegs.push_back(Register::createSubRegister(
+ -1, RegSize - CurPos, "no DWARF register encoding"));
return true;
}
@@ -233,8 +237,17 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
// If the register can only be described by a complex expression (i.e.,
// multiple subregisters) it doesn't safely compose with another complex
// expression. For example, it is not possible to apply a DW_OP_deref
- // operation to multiple DW_OP_pieces.
- if (HasComplexExpression && DwarfRegs.size() > 1) {
+ // operation to multiple DW_OP_pieces, since composite location descriptions
+ // do not push anything on the DWARF stack.
+ //
+ // DW_OP_entry_value operations can only hold a DWARF expression or a
+ // register location description, so we can't emit a single entry value
+ // covering a composite location description. In the future we may want to
+ // emit entry value operations for each register location in the composite
+ // location, but until that is supported do not emit anything.
+ if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {
+ if (IsEmittingEntryValue)
+ cancelEntryValue();
DwarfRegs.clear();
LocationKind = Unknown;
return false;
@@ -244,18 +257,19 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
// a call site parameter expression and if that expression is just a register
// location, emit it with addBReg and offset 0, because we should emit a DWARF
// expression representing a value, rather than a location.
- if (!isMemoryLocation() && !HasComplexExpression && (!isParameterValue() ||
- isEntryValue())) {
+ if (!isMemoryLocation() && !HasComplexExpression &&
+ (!isParameterValue() || isEntryValue())) {
for (auto &Reg : DwarfRegs) {
if (Reg.DwarfRegNo >= 0)
addReg(Reg.DwarfRegNo, Reg.Comment);
- addOpPiece(Reg.Size);
+ addOpPiece(Reg.SubRegSize);
}
if (isEntryValue())
finalizeEntryValue();
- if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4)
+ if (isEntryValue() && !isIndirect() && !isParameterValue() &&
+ DwarfVersion >= 4)
emitOp(dwarf::DW_OP_stack_value);
DwarfRegs.clear();
@@ -276,7 +290,7 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
auto Reg = DwarfRegs[0];
bool FBReg = isFrameRegister(TRI, MachineReg);
int SignedOffset = 0;
- assert(Reg.Size == 0 && "subregister has same size as superregister");
+ assert(!Reg.isSubRegister() && "full register expected");
// Pattern-match combinations for which more efficient representations exist.
// [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
@@ -314,6 +328,25 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
return true;
}
+void DwarfExpression::setEntryValueFlags(const MachineLocation &Loc) {
+ LocationFlags |= EntryValue;
+ if (Loc.isIndirect())
+ LocationFlags |= Indirect;
+}
+
+void DwarfExpression::setLocation(const MachineLocation &Loc,
+ const DIExpression *DIExpr) {
+ if (Loc.isIndirect())
+ // Do not treat entry value descriptions of indirect parameters as memory
+ // locations. This allows DwarfExpression::addReg() to add DW_OP_regN to an
+ // entry value description.
+ if (!DIExpr->isEntryValue())
+ setMemoryLocationKind();
+
+ if (DIExpr->isEntryValue())
+ setEntryValueFlags(Loc);
+}
+
void DwarfExpression::beginEntryValueExpression(
DIExpressionCursor &ExprCursor) {
auto Op = ExprCursor.take();
@@ -325,7 +358,6 @@ void DwarfExpression::beginEntryValueExpression(
assert(Op->getArg(0) == 1 &&
"Can currently only emit entry values covering a single operation");
- emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
IsEmittingEntryValue = true;
enableTemporaryBuffer();
}
@@ -334,6 +366,8 @@ void DwarfExpression::finalizeEntryValue() {
assert(IsEmittingEntryValue && "Entry value not open?");
disableTemporaryBuffer();
+ emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
+
// Emit the entry value's size operand.
unsigned Size = getTemporaryBufferSize();
emitUnsigned(Size);
@@ -344,7 +378,35 @@ void DwarfExpression::finalizeEntryValue() {
IsEmittingEntryValue = false;
}
-/// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
+void DwarfExpression::cancelEntryValue() {
+ assert(IsEmittingEntryValue && "Entry value not open?");
+ disableTemporaryBuffer();
+
+ // The temporary buffer can't be emptied, so for now just assert that nothing
+ // has been emitted to it.
+ assert(getTemporaryBufferSize() == 0 &&
+ "Began emitting entry value block before cancelling entry value");
+
+ IsEmittingEntryValue = false;
+}
+
+unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,
+ dwarf::TypeKind Encoding) {
+ // Reuse the base_type if we already have one in this CU otherwise we
+ // create a new one.
+ unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
+ for (; I != E; ++I)
+ if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
+ CU.ExprRefedBaseTypes[I].Encoding == Encoding)
+ break;
+
+ if (I == E)
+ CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
+ return I;
+}
+
+/// Assuming a well-formed expression, match "DW_OP_deref*
+/// DW_OP_LLVM_fragment?".
static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
while (ExprCursor) {
auto Op = ExprCursor.take();
@@ -361,6 +423,10 @@ static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
unsigned FragmentOffsetInBits) {
+ // Entry values can currently only cover the initial register location,
+ // and not any other parts of the following DWARF expression.
+ assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
+
// If we need to mask out a subregister, do it now, unless the next
// operation would emit an OpPiece anyway.
auto N = ExprCursor.peek();
@@ -431,6 +497,7 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
case dwarf::DW_OP_lit0:
case dwarf::DW_OP_not:
case dwarf::DW_OP_dup:
+ case dwarf::DW_OP_push_object_address:
emitOp(OpNum);
break;
case dwarf::DW_OP_deref:
@@ -451,24 +518,13 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
if (DwarfVersion >= 5) {
emitOp(dwarf::DW_OP_convert);
- // Reuse the base_type if we already have one in this CU otherwise we
- // create a new one.
- unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
- for (; I != E; ++I)
- if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
- CU.ExprRefedBaseTypes[I].Encoding == Encoding)
- break;
-
- if (I == E)
- CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
-
// If targeting a location-list; simply emit the index into the raw
// byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
// fitted with means to extract it later.
// If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
// (containing the index and a resolve mechanism during emit) into the
// DIE value list.
- emitBaseTypeRef(I);
+ emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));
} else {
if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
if (Encoding == dwarf::DW_ATE_signed)
@@ -573,10 +629,10 @@ void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
emitOp(dwarf::DW_OP_and);
}
-void DwarfExpression::addWasmLocation(unsigned Index, int64_t Offset) {
+void DwarfExpression::addWasmLocation(unsigned Index, uint64_t Offset) {
assert(LocationKind == Implicit || LocationKind == Unknown);
LocationKind = Implicit;
emitOp(dwarf::DW_OP_WASM_location);
emitUnsigned(Index);
- emitSigned(Offset);
+ emitUnsigned(Offset);
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 46c07b1d5b6b..757b17511453 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -30,6 +30,7 @@ class APInt;
class DwarfCompileUnit;
class DIELoc;
class TargetRegisterInfo;
+class MachineLocation;
/// Holds a DIExpression and keeps track of how many operands have been consumed
/// so far.
@@ -107,8 +108,21 @@ protected:
/// Holds information about all subregisters comprising a register location.
struct Register {
int DwarfRegNo;
- unsigned Size;
+ unsigned SubRegSize;
const char *Comment;
+
+ /// Create a full register, no extra DW_OP_piece operators necessary.
+ static Register createRegister(int RegNo, const char *Comment) {
+ return {RegNo, 0, Comment};
+ }
+
+ /// Create a subregister that needs a DW_OP_piece operator with SizeInBits.
+ static Register createSubRegister(int RegNo, unsigned SizeInBits,
+ const char *Comment) {
+ return {RegNo, SizeInBits, Comment};
+ }
+
+ bool isSubRegister() const { return SubRegSize; }
};
/// Whether we are currently emitting an entry value operation.
@@ -129,37 +143,31 @@ protected:
/// The kind of location description being produced.
enum { Unknown = 0, Register, Memory, Implicit };
- /// The flags of location description being produced.
- enum { EntryValue = 1, CallSiteParamValue };
+ /// Additional location flags which may be combined with any location kind.
+ /// Currently, entry values are not supported for the Memory location kind.
+ enum { EntryValue = 1 << 0, Indirect = 1 << 1, CallSiteParamValue = 1 << 2 };
unsigned LocationKind : 3;
- unsigned LocationFlags : 2;
+ unsigned LocationFlags : 3;
unsigned DwarfVersion : 4;
public:
- bool isUnknownLocation() const {
- return LocationKind == Unknown;
- }
+ /// Set the location (\p Loc) and \ref DIExpression (\p DIExpr) to describe.
+ void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr);
- bool isMemoryLocation() const {
- return LocationKind == Memory;
- }
+ bool isUnknownLocation() const { return LocationKind == Unknown; }
- bool isRegisterLocation() const {
- return LocationKind == Register;
- }
+ bool isMemoryLocation() const { return LocationKind == Memory; }
- bool isImplicitLocation() const {
- return LocationKind == Implicit;
- }
+ bool isRegisterLocation() const { return LocationKind == Register; }
- bool isEntryValue() const {
- return LocationFlags & EntryValue;
- }
+ bool isImplicitLocation() const { return LocationKind == Implicit; }
- bool isParameterValue() {
- return LocationFlags & CallSiteParamValue;
- }
+ bool isEntryValue() const { return LocationFlags & EntryValue; }
+
+ bool isIndirect() const { return LocationFlags & Indirect; }
+
+ bool isParameterValue() { return LocationFlags & CallSiteParamValue; }
Optional<uint8_t> TagOffset;
@@ -209,7 +217,8 @@ protected:
/// Return whether the given machine register is the frame register in the
/// current function.
- virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
+ virtual bool isFrameRegister(const TargetRegisterInfo &TRI,
+ unsigned MachineReg) = 0;
/// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
/// register location description.
@@ -267,6 +276,9 @@ protected:
/// DWARF block which has been emitted to the temporary buffer.
void finalizeEntryValue();
+ /// Cancel the emission of an entry value.
+ void cancelEntryValue();
+
~DwarfExpression() = default;
public:
@@ -294,14 +306,10 @@ public:
}
/// Lock this down to become an entry value location.
- void setEntryValueFlag() {
- LocationFlags |= EntryValue;
- }
+ void setEntryValueFlags(const MachineLocation &Loc);
/// Lock this down to become a call site parameter location.
- void setCallSiteParamValueFlag() {
- LocationFlags |= CallSiteParamValue;
- }
+ void setCallSiteParamValueFlag() { LocationFlags |= CallSiteParamValue; }
/// Emit a machine register location. As an optimization this may also consume
/// the prefix of a DwarfExpression if a more efficient representation for
@@ -323,6 +331,10 @@ public:
/// any operands here.
void beginEntryValueExpression(DIExpressionCursor &ExprCursor);
+ /// Return the index of a base type with the given properties and
+ /// create one if necessary.
+ unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding);
+
/// Emit all remaining operations in the DIExpressionCursor.
///
/// \param FragmentOffsetInBits If this is one fragment out of multiple
@@ -340,7 +352,7 @@ public:
/// Emit location information expressed via WebAssembly location + offset
/// The Index is an identifier for locals, globals or operand stack.
- void addWasmLocation(unsigned Index, int64_t Offset);
+ void addWasmLocation(unsigned Index, uint64_t Offset);
};
/// DwarfExpression implementation for .debug_loc entries.
@@ -374,6 +386,7 @@ class DebugLocDwarfExpression final : public DwarfExpression {
bool isFrameRegister(const TargetRegisterInfo &TRI,
unsigned MachineReg) override;
+
public:
DebugLocDwarfExpression(unsigned DwarfVersion, BufferByteStreamer &BS,
DwarfCompileUnit &CU)
@@ -403,6 +416,7 @@ class DIEDwarfExpression final : public DwarfExpression {
bool isFrameRegister(const TargetRegisterInfo &TRI,
unsigned MachineReg) override;
+
public:
DIEDwarfExpression(const AsmPrinter &AP, DwarfCompileUnit &CU, DIELoc &DIE);
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
index e5c4db58f477..812e6383288f 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp
@@ -53,7 +53,7 @@ void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) {
Asm->emitDwarfDIE(TheU->getUnitDie());
if (MCSymbol *EndLabel = TheU->getEndLabel())
- Asm->OutStreamer->EmitLabel(EndLabel);
+ Asm->OutStreamer->emitLabel(EndLabel);
}
// Compute the size and offset for each DIE.
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
index 2a76dcb1b082..a43929d8e8f7 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
@@ -71,7 +71,7 @@ void DwarfStringPool::emitStringOffsetsTableHeader(AsmPrinter &Asm,
// referenced by most unit headers via DW_AT_str_offsets_base.
// Split units do not use the attribute.
if (StartSym)
- Asm.OutStreamer->EmitLabel(StartSym);
+ Asm.OutStreamer->emitLabel(StartSym);
}
void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
@@ -100,12 +100,12 @@ void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
// Emit a label for reference from debug information entries.
if (ShouldCreateSymbols)
- Asm.OutStreamer->EmitLabel(Entry->getValue().Symbol);
+ Asm.OutStreamer->emitLabel(Entry->getValue().Symbol);
// Emit the string itself with a terminating null byte.
Asm.OutStreamer->AddComment("string offset=" +
Twine(Entry->getValue().Offset));
- Asm.OutStreamer->EmitBytes(
+ Asm.OutStreamer->emitBytes(
StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
}
@@ -125,6 +125,6 @@ void DwarfStringPool::emit(AsmPrinter &Asm, MCSection *StrSection,
if (UseRelativeOffsets)
Asm.emitDwarfStringOffset(Entry->getValue());
else
- Asm.OutStreamer->EmitIntValue(Entry->getValue().Offset, size);
+ Asm.OutStreamer->emitIntValue(Entry->getValue().Offset, size);
}
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 53747aef77fd..e958f38e486b 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -188,8 +188,9 @@ int64_t DwarfUnit::getDefaultLowerBound() const {
/// Check whether the DIE for this MDNode can be shared across CUs.
bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const {
- // When the MDNode can be part of the type system, the DIE can be shared
- // across CUs.
+ // When the MDNode can be part of the type system (this includes subprogram
+ // declarations *and* subprogram definitions, even local definitions), the
+ // DIE must be shared across CUs.
// Combining type units and cross-CU DIE sharing is lower value (since
// cross-CU DIE sharing is used in LTO and removes type redundancy at that
// level already) but may be implementable for some value in projects
@@ -197,9 +198,7 @@ bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const {
// together.
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
return false;
- return (isa<DIType>(D) ||
- (isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) &&
- !DD->generateTypeUnits();
+ return (isa<DIType>(D) || isa<DISubprogram>(D)) && !DD->generateTypeUnits();
}
DIE *DwarfUnit::getDIE(const DINode *D) const {
@@ -1046,6 +1045,8 @@ void DwarfUnit::constructTemplateTypeParameterDIE(
addType(ParamDIE, TP->getType());
if (!TP->getName().empty())
addString(ParamDIE, dwarf::DW_AT_name, TP->getName());
+ if (TP->isDefault() && (DD->getDwarfVersion() >= 5))
+ addFlag(ParamDIE, dwarf::DW_AT_default_value);
}
void DwarfUnit::constructTemplateValueParameterDIE(
@@ -1058,6 +1059,8 @@ void DwarfUnit::constructTemplateValueParameterDIE(
addType(ParamDIE, VP->getType());
if (!VP->getName().empty())
addString(ParamDIE, dwarf::DW_AT_name, VP->getName());
+ if (VP->isDefault() && (DD->getDwarfVersion() >= 5))
+ addFlag(ParamDIE, dwarf::DW_AT_default_value);
if (Metadata *Val = VP->getValue()) {
if (ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))
addConstantValue(ParamDIE, CI, VP->getType());
@@ -1123,8 +1126,13 @@ DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {
M->getConfigurationMacros());
if (!M->getIncludePath().empty())
addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath());
- if (!M->getSysRoot().empty())
- addString(MDie, dwarf::DW_AT_LLVM_sysroot, M->getSysRoot());
+ if (!M->getAPINotesFile().empty())
+ addString(MDie, dwarf::DW_AT_LLVM_apinotes, M->getAPINotesFile());
+ if (M->getFile())
+ addUInt(MDie, dwarf::DW_AT_decl_file, None,
+ getOrCreateSourceID(M->getFile()));
+ if (M->getLineNo())
+ addUInt(MDie, dwarf::DW_AT_decl_line, None, M->getLineNo());
return &MDie;
}
@@ -1166,6 +1174,14 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
DIE *DeclDie = nullptr;
StringRef DeclLinkageName;
if (auto *SPDecl = SP->getDeclaration()) {
+ DITypeRefArray DeclArgs, DefinitionArgs;
+ DeclArgs = SPDecl->getType()->getTypeArray();
+ DefinitionArgs = SP->getType()->getTypeArray();
+
+ if (DeclArgs.size() && DefinitionArgs.size())
+ if (DefinitionArgs[0] != NULL && DeclArgs[0] != DefinitionArgs[0])
+ addType(SPDie, DefinitionArgs[0]);
+
DeclDie = getDIE(SPDecl);
assert(DeclDie && "This DIE should've already been constructed when the "
"definition DIE was created in "
@@ -1333,20 +1349,40 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
// C/C++. The Count value is the number of elements. Values are 64 bit. If
// Count == -1 then the array is unbounded and we do not emit
// DW_AT_lower_bound and DW_AT_count attributes.
- int64_t LowerBound = SR->getLowerBound();
int64_t DefaultLowerBound = getDefaultLowerBound();
int64_t Count = -1;
if (auto *CI = SR->getCount().dyn_cast<ConstantInt*>())
Count = CI->getSExtValue();
- if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
- addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, None, LowerBound);
+ auto addBoundTypeEntry = [&](dwarf::Attribute Attr,
+ DISubrange::BoundType Bound) -> void {
+ if (auto *BV = Bound.dyn_cast<DIVariable *>()) {
+ if (auto *VarDIE = getDIE(BV))
+ addDIEEntry(DW_Subrange, Attr, *VarDIE);
+ } else if (auto *BE = Bound.dyn_cast<DIExpression *>()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(BE);
+ addBlock(DW_Subrange, Attr, DwarfExpr.finalize());
+ } else if (auto *BI = Bound.dyn_cast<ConstantInt *>()) {
+ if (Attr != dwarf::DW_AT_lower_bound || DefaultLowerBound == -1 ||
+ BI->getSExtValue() != DefaultLowerBound)
+ addSInt(DW_Subrange, Attr, dwarf::DW_FORM_sdata, BI->getSExtValue());
+ }
+ };
+
+ addBoundTypeEntry(dwarf::DW_AT_lower_bound, SR->getLowerBound());
if (auto *CV = SR->getCount().dyn_cast<DIVariable*>()) {
if (auto *CountVarDIE = getDIE(CV))
addDIEEntry(DW_Subrange, dwarf::DW_AT_count, *CountVarDIE);
} else if (Count != -1)
addUInt(DW_Subrange, dwarf::DW_AT_count, None, Count);
+
+ addBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());
+
+ addBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());
}
DIE *DwarfUnit::getIndexTyDie() {
@@ -1398,6 +1434,17 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
CTy->getSizeInBits() / CHAR_BIT);
}
+ if (DIVariable *Var = CTy->getDataLocation()) {
+ if (auto *VarDIE = getDIE(Var))
+ addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE);
+ } else if (DIExpression *Expr = CTy->getDataLocationExp()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
+ DwarfExpr.setMemoryLocationKind();
+ DwarfExpr.addExpression(Expr);
+ addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());
+ }
+
// Emit the element type.
addType(Buffer, CTy->getBaseType());
@@ -1438,8 +1485,7 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);
StringRef Name = Enum->getName();
addString(Enumerator, dwarf::DW_AT_name, Name);
- auto Value = static_cast<uint64_t>(Enum->getValue());
- addConstantValue(Enumerator, IsUnsigned, Value);
+ addConstantValue(Enumerator, Enum->getValue(), IsUnsigned);
if (IndexEnumerators)
addGlobalName(Name, Enumerator, Context);
}
@@ -1623,8 +1669,8 @@ void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) {
StringRef Prefix = isDwoUnit() ? "debug_info_dwo_" : "debug_info_";
MCSymbol *BeginLabel = Asm->createTempSymbol(Prefix + "start");
EndLabel = Asm->createTempSymbol(Prefix + "end");
- Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
- Asm->OutStreamer->EmitLabel(BeginLabel);
+ Asm->emitLabelDifference(EndLabel, BeginLabel, 4);
+ Asm->OutStreamer->emitLabel(BeginLabel);
} else
Asm->emitInt32(getHeaderSize() + getUnitDie().getSize());
@@ -1662,10 +1708,10 @@ void DwarfTypeUnit::emitHeader(bool UseOffsets) {
DD->useSplitDwarf() ? dwarf::DW_UT_split_type
: dwarf::DW_UT_type);
Asm->OutStreamer->AddComment("Type Signature");
- Asm->OutStreamer->EmitIntValue(TypeSignature, sizeof(TypeSignature));
+ Asm->OutStreamer->emitIntValue(TypeSignature, sizeof(TypeSignature));
Asm->OutStreamer->AddComment("Type DIE Offset");
// In a skeleton type unit there is no type DIE so emit a zero offset.
- Asm->OutStreamer->EmitIntValue(Ty ? Ty->getOffset() : 0,
+ Asm->OutStreamer->emitIntValue(Ty ? Ty->getOffset() : 0,
sizeof(Ty->getOffset()));
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 46c52a1faf4b..34f3a34ed336 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -27,7 +27,6 @@
namespace llvm {
-class MachineLocation;
class MachineOperand;
class ConstantInt;
class ConstantFP;
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index 31dfaaac836e..99ee4567fa58 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -426,18 +426,18 @@ MCSymbol *EHStreamer::emitExceptionTable() {
// EHABI). In this case LSDASection will be NULL.
if (LSDASection)
Asm->OutStreamer->SwitchSection(LSDASection);
- Asm->EmitAlignment(Align(4));
+ Asm->emitAlignment(Align(4));
// Emit the LSDA.
MCSymbol *GCCETSym =
Asm->OutContext.getOrCreateSymbol(Twine("GCC_except_table")+
Twine(Asm->getFunctionNumber()));
- Asm->OutStreamer->EmitLabel(GCCETSym);
- Asm->OutStreamer->EmitLabel(Asm->getCurExceptionSym());
+ Asm->OutStreamer->emitLabel(GCCETSym);
+ Asm->OutStreamer->emitLabel(Asm->getCurExceptionSym());
// Emit the LSDA header.
- Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
- Asm->EmitEncodingByte(TTypeEncoding, "@TType");
+ Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+ Asm->emitEncodingByte(TTypeEncoding, "@TType");
MCSymbol *TTBaseLabel = nullptr;
if (HaveTTData) {
@@ -447,8 +447,8 @@ MCSymbol *EHStreamer::emitExceptionTable() {
// the type table. See PR35809 or GNU as bug 4029.
MCSymbol *TTBaseRefLabel = Asm->createTempSymbol("ttbaseref");
TTBaseLabel = Asm->createTempSymbol("ttbase");
- Asm->EmitLabelDifferenceAsULEB128(TTBaseLabel, TTBaseRefLabel);
- Asm->OutStreamer->EmitLabel(TTBaseRefLabel);
+ Asm->emitLabelDifferenceAsULEB128(TTBaseLabel, TTBaseRefLabel);
+ Asm->OutStreamer->emitLabel(TTBaseRefLabel);
}
bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
@@ -456,9 +456,9 @@ MCSymbol *EHStreamer::emitExceptionTable() {
// Emit the landing pad call site table.
MCSymbol *CstBeginLabel = Asm->createTempSymbol("cst_begin");
MCSymbol *CstEndLabel = Asm->createTempSymbol("cst_end");
- Asm->EmitEncodingByte(CallSiteEncoding, "Call site");
- Asm->EmitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel);
- Asm->OutStreamer->EmitLabel(CstBeginLabel);
+ Asm->emitEncodingByte(CallSiteEncoding, "Call site");
+ Asm->emitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel);
+ Asm->OutStreamer->emitLabel(CstBeginLabel);
// SjLj / Wasm Exception handling
if (IsSJLJ || IsWasm) {
@@ -472,7 +472,7 @@ MCSymbol *EHStreamer::emitExceptionTable() {
Asm->OutStreamer->AddComment(">> Call Site " + Twine(idx) + " <<");
Asm->OutStreamer->AddComment(" On exception at call site "+Twine(idx));
}
- Asm->EmitULEB128(idx);
+ Asm->emitULEB128(idx);
// Offset of the first associated action record, relative to the start of
// the action table. This value is biased by 1 (1 indicates the start of
@@ -484,7 +484,7 @@ MCSymbol *EHStreamer::emitExceptionTable() {
Asm->OutStreamer->AddComment(" Action: " +
Twine((S.Action - 1) / 2 + 1));
}
- Asm->EmitULEB128(S.Action);
+ Asm->emitULEB128(S.Action);
}
} else {
// Itanium LSDA exception handling
@@ -524,23 +524,23 @@ MCSymbol *EHStreamer::emitExceptionTable() {
// Offset of the call site relative to the start of the procedure.
if (VerboseAsm)
Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) + " <<");
- Asm->EmitCallSiteOffset(BeginLabel, EHFuncBeginSym, CallSiteEncoding);
+ Asm->emitCallSiteOffset(BeginLabel, EHFuncBeginSym, CallSiteEncoding);
if (VerboseAsm)
Asm->OutStreamer->AddComment(Twine(" Call between ") +
BeginLabel->getName() + " and " +
EndLabel->getName());
- Asm->EmitCallSiteOffset(EndLabel, BeginLabel, CallSiteEncoding);
+ Asm->emitCallSiteOffset(EndLabel, BeginLabel, CallSiteEncoding);
// Offset of the landing pad relative to the start of the procedure.
if (!S.LPad) {
if (VerboseAsm)
Asm->OutStreamer->AddComment(" has no landing pad");
- Asm->EmitCallSiteValue(0, CallSiteEncoding);
+ Asm->emitCallSiteValue(0, CallSiteEncoding);
} else {
if (VerboseAsm)
Asm->OutStreamer->AddComment(Twine(" jumps to ") +
S.LPad->LandingPadLabel->getName());
- Asm->EmitCallSiteOffset(S.LPad->LandingPadLabel, EHFuncBeginSym,
+ Asm->emitCallSiteOffset(S.LPad->LandingPadLabel, EHFuncBeginSym,
CallSiteEncoding);
}
@@ -554,10 +554,10 @@ MCSymbol *EHStreamer::emitExceptionTable() {
Asm->OutStreamer->AddComment(" On action: " +
Twine((S.Action - 1) / 2 + 1));
}
- Asm->EmitULEB128(S.Action);
+ Asm->emitULEB128(S.Action);
}
}
- Asm->OutStreamer->EmitLabel(CstEndLabel);
+ Asm->OutStreamer->emitLabel(CstEndLabel);
// Emit the Action Table.
int Entry = 0;
@@ -584,7 +584,7 @@ MCSymbol *EHStreamer::emitExceptionTable() {
else
Asm->OutStreamer->AddComment(" Cleanup");
}
- Asm->EmitSLEB128(Action.ValueForTypeID);
+ Asm->emitSLEB128(Action.ValueForTypeID);
// Action Record
//
@@ -598,15 +598,15 @@ MCSymbol *EHStreamer::emitExceptionTable() {
Asm->OutStreamer->AddComment(" Continue to action "+Twine(NextAction));
}
}
- Asm->EmitSLEB128(Action.NextAction);
+ Asm->emitSLEB128(Action.NextAction);
}
if (HaveTTData) {
- Asm->EmitAlignment(Align(4));
+ Asm->emitAlignment(Align(4));
emitTypeInfos(TTypeEncoding, TTBaseLabel);
}
- Asm->EmitAlignment(Align(4));
+ Asm->emitAlignment(Align(4));
return GCCETSym;
}
@@ -629,10 +629,10 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) {
TypeInfos.rend())) {
if (VerboseAsm)
Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--));
- Asm->EmitTTypeReference(GV, TTypeEncoding);
+ Asm->emitTTypeReference(GV, TTypeEncoding);
}
- Asm->OutStreamer->EmitLabel(TTBaseLabel);
+ Asm->OutStreamer->emitLabel(TTBaseLabel);
// Emit the Exception Specifications.
if (VerboseAsm && !FilterIds.empty()) {
@@ -649,6 +649,6 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) {
Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry));
}
- Asm->EmitULEB128(TypeID);
+ Asm->emitULEB128(TypeID);
}
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
index 3849644d1584..59a84e6f2d7b 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
@@ -72,7 +72,7 @@ void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
**/
// Align to address width.
- AP.EmitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
+ AP.emitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
// Emit PointCount.
OS.AddComment("safe point count");
@@ -84,7 +84,7 @@ void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
// Emit the address of the safe point.
OS.AddComment("safe point address");
MCSymbol *Label = PI->Label;
- AP.EmitLabelPlusOffset(Label /*Hi*/, 0 /*Offset*/, 4 /*Size*/);
+ AP.emitLabelPlusOffset(Label /*Hi*/, 0 /*Offset*/, 4 /*Size*/);
}
// Stack information never change in safe points! Only print info from the
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index b4eda5fa8c58..8fa83f515910 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -66,8 +66,8 @@ static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) {
MCSymbol *Sym = AP.OutContext.getOrCreateSymbol(TmpStr);
- AP.OutStreamer->EmitSymbolAttribute(Sym, MCSA_Global);
- AP.OutStreamer->EmitLabel(Sym);
+ AP.OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);
+ AP.OutStreamer->emitLabel(Sym);
}
void OcamlGCMetadataPrinter::beginAssembly(Module &M, GCModuleInfo &Info,
@@ -106,7 +106,7 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
EmitCamlGlobal(M, AP, "data_end");
// FIXME: Why does ocaml emit this??
- AP.OutStreamer->EmitIntValue(0, IntPtrSize);
+ AP.OutStreamer->emitIntValue(0, IntPtrSize);
AP.OutStreamer->SwitchSection(AP.getObjFileLowering().getDataSection());
EmitCamlGlobal(M, AP, "frametable");
@@ -129,7 +129,7 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
report_fatal_error(" Too much descriptor for ocaml GC");
}
AP.emitInt16(NumDescriptors);
- AP.EmitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
+ AP.emitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(),
IE = Info.funcinfo_end();
@@ -164,7 +164,7 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
Twine(LiveCount) + " >= 65536.");
}
- AP.OutStreamer->EmitSymbolValue(J->Label, IntPtrSize);
+ AP.OutStreamer->emitSymbolValue(J->Label, IntPtrSize);
AP.emitInt16(FrameSize);
AP.emitInt16(LiveCount);
@@ -180,7 +180,7 @@ void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info,
AP.emitInt16(K->StackOffset);
}
- AP.EmitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
+ AP.emitAlignment(IntPtrSize == 4 ? Align(4) : Align(8));
}
}
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
index 444b0ed17b6d..baef4d2cc849 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
@@ -27,7 +27,7 @@ void WasmException::endModule() {
Mangler::getNameWithPrefix(NameStr, "__cpp_exception", Asm->getDataLayout());
if (Asm->OutContext.lookupSymbol(NameStr)) {
MCSymbol *ExceptionSym = Asm->GetExternalSymbolSymbol("__cpp_exception");
- Asm->OutStreamer->EmitLabel(ExceptionSym);
+ Asm->OutStreamer->emitLabel(ExceptionSym);
}
}
@@ -58,7 +58,7 @@ void WasmException::endFunction(const MachineFunction *MF) {
// end marker and set the size as the difference between the start end the end
// marker.
MCSymbol *LSDAEndLabel = Asm->createTempSymbol("GCC_except_table_end");
- Asm->OutStreamer->EmitLabel(LSDAEndLabel);
+ Asm->OutStreamer->emitLabel(LSDAEndLabel);
MCContext &OutContext = Asm->OutStreamer->getContext();
const MCExpr *SizeExp = MCBinaryExpr::createSub(
MCSymbolRefExpr::create(LSDAEndLabel, OutContext),
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 0398675577cd..cd8077e7d548 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -34,6 +34,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
@@ -203,11 +204,11 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB,
// We want our funclet's entry point to be aligned such that no nops will be
// present after the label.
- Asm->EmitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()),
+ Asm->emitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()),
&F);
// Now that we've emitted the alignment directive, point at our funclet.
- Asm->OutStreamer->EmitLabel(Sym);
+ Asm->OutStreamer->emitLabel(Sym);
}
// Mark 'Sym' as starting our funclet.
@@ -276,7 +277,7 @@ void WinException::endFuncletImpl() {
StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
Twine("$cppxdata$", FuncLinkageName));
- Asm->OutStreamer->EmitValue(create32bitRef(FuncInfoXData), 4);
+ Asm->OutStreamer->emitValue(create32bitRef(FuncInfoXData), 4);
} else if (Per == EHPersonality::MSVC_Win64SEH && MF->hasEHFunclets() &&
!CurrentFuncletEntry->isEHFuncletEntry()) {
// If this is the parent function in Win64 SEH, emit the LSDA immediately
@@ -336,7 +337,7 @@ const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,
int WinException::getFrameIndexOffset(int FrameIndex,
const WinEHFuncInfo &FuncInfo) {
const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
- unsigned UnusedReg;
+ Register UnusedReg;
if (Asm->MAI->usesWindowsCFI()) {
int Offset =
TFI.getFrameIndexReferencePreferSP(*Asm->MF, FrameIndex, UnusedReg,
@@ -566,7 +567,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
const MCExpr *MCOffset =
MCConstantExpr::create(FuncInfo.SEHSetFrameOffset, Ctx);
- Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset);
+ Asm->OutStreamer->emitAssignment(ParentFrameOffset, MCOffset);
}
// Use the assembler to compute the number of table entries through label
@@ -579,9 +580,9 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
const MCExpr *EntrySize = MCConstantExpr::create(16, Ctx);
const MCExpr *EntryCount = MCBinaryExpr::createDiv(LabelDiff, EntrySize, Ctx);
AddComment("Number of call sites");
- OS.EmitValue(EntryCount, 4);
+ OS.emitValue(EntryCount, 4);
- OS.EmitLabel(TableBegin);
+ OS.emitLabel(TableBegin);
// Iterate over all the invoke try ranges. Unlike MSVC, LLVM currently only
// models exceptions from invokes. LLVM also allows arbitrary reordering of
@@ -609,7 +610,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
LastEHState = StateChange.NewState;
}
- OS.EmitLabel(TableEnd);
+ OS.emitLabel(TableEnd);
}
void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
@@ -641,14 +642,14 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
}
AddComment("LabelStart");
- OS.EmitValue(getLabel(BeginLabel), 4);
+ OS.emitValue(getLabel(BeginLabel), 4);
AddComment("LabelEnd");
- OS.EmitValue(getLabel(EndLabel), 4);
+ OS.emitValue(getLabel(EndLabel), 4);
AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
: "CatchAll");
- OS.EmitValue(FilterOrFinally, 4);
+ OS.emitValue(FilterOrFinally, 4);
AddComment(UME.IsFinally ? "Null" : "ExceptionHandler");
- OS.EmitValue(ExceptOrNull, 4);
+ OS.emitValue(ExceptOrNull, 4);
assert(UME.ToState < State && "states should decrease");
State = UME.ToState;
@@ -713,55 +714,55 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
// EHFlags & 1 -> Synchronous exceptions only, no async exceptions.
// EHFlags & 2 -> ???
// EHFlags & 4 -> The function is noexcept(true), unwinding can't continue.
- OS.EmitValueToAlignment(4);
- OS.EmitLabel(FuncInfoXData);
+ OS.emitValueToAlignment(4);
+ OS.emitLabel(FuncInfoXData);
AddComment("MagicNumber");
- OS.EmitIntValue(0x19930522, 4);
+ OS.emitInt32(0x19930522);
AddComment("MaxState");
- OS.EmitIntValue(FuncInfo.CxxUnwindMap.size(), 4);
+ OS.emitInt32(FuncInfo.CxxUnwindMap.size());
AddComment("UnwindMap");
- OS.EmitValue(create32bitRef(UnwindMapXData), 4);
+ OS.emitValue(create32bitRef(UnwindMapXData), 4);
AddComment("NumTryBlocks");
- OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4);
+ OS.emitInt32(FuncInfo.TryBlockMap.size());
AddComment("TryBlockMap");
- OS.EmitValue(create32bitRef(TryBlockMapXData), 4);
+ OS.emitValue(create32bitRef(TryBlockMapXData), 4);
AddComment("IPMapEntries");
- OS.EmitIntValue(IPToStateTable.size(), 4);
+ OS.emitInt32(IPToStateTable.size());
AddComment("IPToStateXData");
- OS.EmitValue(create32bitRef(IPToStateXData), 4);
+ OS.emitValue(create32bitRef(IPToStateXData), 4);
if (Asm->MAI->usesWindowsCFI()) {
AddComment("UnwindHelp");
- OS.EmitIntValue(UnwindHelpOffset, 4);
+ OS.emitInt32(UnwindHelpOffset);
}
AddComment("ESTypeList");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
AddComment("EHFlags");
- OS.EmitIntValue(1, 4);
+ OS.emitInt32(1);
// UnwindMapEntry {
// int32_t ToState;
// void (*Action)();
// };
if (UnwindMapXData) {
- OS.EmitLabel(UnwindMapXData);
+ OS.emitLabel(UnwindMapXData);
for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {
MCSymbol *CleanupSym =
getMCSymbolForMBB(Asm, UME.Cleanup.dyn_cast<MachineBasicBlock *>());
AddComment("ToState");
- OS.EmitIntValue(UME.ToState, 4);
+ OS.emitInt32(UME.ToState);
AddComment("Action");
- OS.EmitValue(create32bitRef(CleanupSym), 4);
+ OS.emitValue(create32bitRef(CleanupSym), 4);
}
}
@@ -773,7 +774,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
// HandlerType *HandlerArray;
// };
if (TryBlockMapXData) {
- OS.EmitLabel(TryBlockMapXData);
+ OS.emitLabel(TryBlockMapXData);
SmallVector<MCSymbol *, 1> HandlerMaps;
for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
@@ -795,19 +796,19 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
"bad trymap interval");
AddComment("TryLow");
- OS.EmitIntValue(TBME.TryLow, 4);
+ OS.emitInt32(TBME.TryLow);
AddComment("TryHigh");
- OS.EmitIntValue(TBME.TryHigh, 4);
+ OS.emitInt32(TBME.TryHigh);
AddComment("CatchHigh");
- OS.EmitIntValue(TBME.CatchHigh, 4);
+ OS.emitInt32(TBME.CatchHigh);
AddComment("NumCatches");
- OS.EmitIntValue(TBME.HandlerArray.size(), 4);
+ OS.emitInt32(TBME.HandlerArray.size());
AddComment("HandlerArray");
- OS.EmitValue(create32bitRef(HandlerMapXData), 4);
+ OS.emitValue(create32bitRef(HandlerMapXData), 4);
}
// All funclets use the same parent frame offset currently.
@@ -829,7 +830,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
// void (*Handler)();
// int32_t ParentFrameOffset; // x64 and AArch64 only
// };
- OS.EmitLabel(HandlerMapXData);
+ OS.emitLabel(HandlerMapXData);
for (const WinEHHandlerType &HT : TBME.HandlerArray) {
// Get the frame escape label with the offset of the catch object. If
// the index is INT_MAX, then there is no catch object, and we should
@@ -847,20 +848,20 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
getMCSymbolForMBB(Asm, HT.Handler.dyn_cast<MachineBasicBlock *>());
AddComment("Adjectives");
- OS.EmitIntValue(HT.Adjectives, 4);
+ OS.emitInt32(HT.Adjectives);
AddComment("Type");
- OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4);
+ OS.emitValue(create32bitRef(HT.TypeDescriptor), 4);
AddComment("CatchObjOffset");
- OS.EmitValue(FrameAllocOffsetRef, 4);
+ OS.emitValue(FrameAllocOffsetRef, 4);
AddComment("Handler");
- OS.EmitValue(create32bitRef(HandlerSym), 4);
+ OS.emitValue(create32bitRef(HandlerSym), 4);
if (shouldEmitPersonality) {
AddComment("ParentFrameOffset");
- OS.EmitIntValue(ParentFrameOffset, 4);
+ OS.emitInt32(ParentFrameOffset);
}
}
}
@@ -871,12 +872,12 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
// int32_t State;
// };
if (IPToStateXData) {
- OS.EmitLabel(IPToStateXData);
+ OS.emitLabel(IPToStateXData);
for (auto &IPStatePair : IPToStateTable) {
AddComment("IP");
- OS.EmitValue(IPStatePair.first, 4);
+ OS.emitValue(IPStatePair.first, 4);
AddComment("ToState");
- OS.EmitIntValue(IPStatePair.second, 4);
+ OS.emitInt32(IPStatePair.second);
}
}
}
@@ -956,7 +957,7 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
MCContext &Ctx = Asm->OutContext;
MCSymbol *ParentFrameOffset =
Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
- Asm->OutStreamer->EmitAssignment(ParentFrameOffset,
+ Asm->OutStreamer->emitAssignment(ParentFrameOffset,
MCConstantExpr::create(Offset, Ctx));
}
@@ -979,8 +980,8 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
// Emit the __ehtable label that we use for llvm.x86.seh.lsda.
MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName);
- OS.EmitValueToAlignment(4);
- OS.EmitLabel(LSDALabel);
+ OS.emitValueToAlignment(4);
+ OS.emitLabel(LSDALabel);
const auto *Per = cast<Function>(F.getPersonalityFn()->stripPointerCasts());
StringRef PerName = Per->getName();
@@ -1011,7 +1012,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
int GSCookieOffset = -2;
const MachineFrameInfo &MFI = MF->getFrameInfo();
if (MFI.hasStackProtectorIndex()) {
- unsigned UnusedReg;
+ Register UnusedReg;
const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
int SSPIdx = MFI.getStackProtectorIndex();
GSCookieOffset = TFI->getFrameIndexReference(*MF, SSPIdx, UnusedReg);
@@ -1021,20 +1022,20 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
// TODO(etienneb): Get rid of this value and change it for and assertion.
int EHCookieOffset = 9999;
if (FuncInfo.EHGuardFrameIndex != INT_MAX) {
- unsigned UnusedReg;
+ Register UnusedReg;
const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering();
int EHGuardIdx = FuncInfo.EHGuardFrameIndex;
EHCookieOffset = TFI->getFrameIndexReference(*MF, EHGuardIdx, UnusedReg);
}
AddComment("GSCookieOffset");
- OS.EmitIntValue(GSCookieOffset, 4);
+ OS.emitInt32(GSCookieOffset);
AddComment("GSCookieXOROffset");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
AddComment("EHCookieOffset");
- OS.EmitIntValue(EHCookieOffset, 4);
+ OS.emitInt32(EHCookieOffset);
AddComment("EHCookieXOROffset");
- OS.EmitIntValue(0, 4);
+ OS.emitInt32(0);
BaseState = -2;
}
@@ -1047,11 +1048,11 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
// _except_handler4 it's -2. Do that replacement here if necessary.
int ToState = UME.ToState == -1 ? BaseState : UME.ToState;
AddComment("ToState");
- OS.EmitIntValue(ToState, 4);
+ OS.emitInt32(ToState);
AddComment(UME.IsFinally ? "Null" : "FilterFunction");
- OS.EmitValue(create32bitRef(UME.Filter), 4);
+ OS.emitValue(create32bitRef(UME.Filter), 4);
AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler");
- OS.EmitValue(create32bitRef(ExceptOrFinally), 4);
+ OS.emitValue(create32bitRef(ExceptOrFinally), 4);
}
}
@@ -1124,9 +1125,9 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
// Write out a sentinel indicating the end of the standard (Windows) xdata
// and the start of the additional (CLR) info.
- OS.EmitIntValue(0xffffffff, 4);
+ OS.emitInt32(0xffffffff);
// Write out the number of funclets
- OS.EmitIntValue(NumStates, 4);
+ OS.emitInt32(NumStates);
// Walk the machine blocks/instrs, computing and emitting a few things:
// 1. Emit a list of the offsets to each handler entry, in lexical order.
@@ -1164,7 +1165,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
}
// Emit the function/funclet end and, if this is a funclet (and not the
// root function), record it in the EndSymbolMap.
- OS.EmitValue(getOffset(EndSymbol, FuncBeginSym), 4);
+ OS.emitValue(getOffset(EndSymbol, FuncBeginSym), 4);
if (FuncletState != NullState) {
// Record the end of the handler.
EndSymbolMap[FuncletState] = EndSymbol;
@@ -1217,7 +1218,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
}
// Now emit the clause info, starting with the number of clauses.
- OS.EmitIntValue(Clauses.size(), 4);
+ OS.emitInt32(Clauses.size());
for (ClrClause &Clause : Clauses) {
// Emit a CORINFO_EH_CLAUSE :
/*
@@ -1299,18 +1300,18 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
assert(Clause.EnclosingState > MinClauseMap[Clause.State]);
Flags |= 8;
}
- OS.EmitIntValue(Flags, 4);
+ OS.emitInt32(Flags);
// Write the clause start/end
- OS.EmitValue(ClauseBegin, 4);
- OS.EmitValue(ClauseEnd, 4);
+ OS.emitValue(ClauseBegin, 4);
+ OS.emitValue(ClauseEnd, 4);
// Write out the handler start/end
- OS.EmitValue(HandlerBegin, 4);
- OS.EmitValue(HandlerEnd, 4);
+ OS.emitValue(HandlerBegin, 4);
+ OS.emitValue(HandlerEnd, 4);
// Write out the type token or filter offset
assert(Entry.HandlerType != ClrHandlerType::Filter && "NYI: filters");
- OS.EmitIntValue(Entry.TypeToken, 4);
+ OS.emitInt32(Entry.TypeToken);
}
}
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.h b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.h
index dc5036302131..8bd5d1bc6d2a 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.h
+++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/WinException.h
@@ -16,12 +16,10 @@
#include "EHStreamer.h"
namespace llvm {
-class Function;
class GlobalValue;
class MachineFunction;
class MCExpr;
class MCSection;
-class Value;
struct WinEHFuncInfo;
class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {