aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp18
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp5
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp250
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp57
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp1
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp55
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DIE.cpp7
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp11
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp3
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp251
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h57
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp289
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h26
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp18
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfFile.h7
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp16
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h4
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp2
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp19
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WinException.cpp22
24 files changed, 719 insertions, 408 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
index 22ecc5199742..aab3c2681339 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
@@ -194,8 +194,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
uint32_t CompUnitCount;
uint32_t LocalTypeUnitCount = 0;
uint32_t ForeignTypeUnitCount = 0;
- uint32_t BucketCount;
- uint32_t NameCount;
+ uint32_t BucketCount = 0;
+ uint32_t NameCount = 0;
uint32_t AbbrevTableSize = 0;
uint32_t AugmentationStringSize = sizeof(AugmentationString);
char AugmentationString[8] = {'L', 'L', 'V', 'M', '0', '7', '0', '0'};
@@ -549,9 +549,13 @@ void llvm::emitDWARF5AccelTable(
SmallVector<unsigned, 1> CUIndex(CUs.size());
int Count = 0;
for (const auto &CU : enumerate(CUs)) {
- if (CU.value()->getCUNode()->getNameTableKind() !=
- DICompileUnit::DebugNameTableKind::Default)
+ switch (CU.value()->getCUNode()->getNameTableKind()) {
+ case DICompileUnit::DebugNameTableKind::Default:
+ case DICompileUnit::DebugNameTableKind::Apple:
+ break;
+ default:
continue;
+ }
CUIndex[CU.index()] = Count++;
assert(CU.index() == CU.value()->getUniqueID());
const DwarfCompileUnit *MainCU =
@@ -660,9 +664,9 @@ void AccelTableBase::HashData::print(raw_ostream &OS) const {
void AccelTableBase::print(raw_ostream &OS) const {
// Print Content.
OS << "Entries: \n";
- for (const auto &Entry : Entries) {
- OS << "Name: " << Entry.first() << "\n";
- for (auto *V : Entry.second.Values)
+ for (const auto &[Name, Data] : Entries) {
+ OS << "Name: " << Name << "\n";
+ for (auto *V : Data.Values)
V->print(OS);
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
index 32d8dc793510..00ee4e1b47a8 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
@@ -10,6 +10,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include <utility>
@@ -24,7 +25,7 @@ unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) {
}
MCSymbol *AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) {
- static const uint8_t AddrSize = Asm.getDataLayout().getPointerSize();
+ static const uint8_t AddrSize = Asm.MAI->getCodePointerSize();
MCSymbol *EndLabel =
Asm.emitDwarfUnitLength("debug_addr", "Length of contribution");
@@ -65,7 +66,7 @@ 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.MAI->getCodePointerSize());
if (EndLabel)
Asm.OutStreamer->emitLabel(EndLabel);
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 8c126d20fc9a..5381dfdd184c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -26,12 +26,11 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/BinaryFormat/COFF.h"
@@ -39,6 +38,7 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
+#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineDominators.h"
@@ -67,6 +67,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GCStrategy.h"
#include "llvm/IR/GlobalAlias.h"
@@ -99,6 +100,7 @@
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/SectionKind.h"
+#include "llvm/Object/ELFTypes.h"
#include "llvm/Pass.h"
#include "llvm/Remarks/RemarkStreamer.h"
#include "llvm/Support/Casting.h"
@@ -113,6 +115,7 @@
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cassert>
#include <cinttypes>
@@ -128,6 +131,13 @@ using namespace llvm;
#define DEBUG_TYPE "asm-printer"
+static cl::opt<std::string> BasicBlockProfileDump(
+ "mbb-profile-dump", cl::Hidden,
+ cl::desc("Basic block profile dump for external cost modelling. If "
+ "matching up BBs with afterwards, the compilation must be "
+ "performed with -basic-block-sections=labels. Enabling this "
+ "flag during in-process ThinLTO is not supported."));
+
const char DWARFGroupName[] = "dwarf";
const char DWARFGroupDescription[] = "DWARF Emission";
const char DbgTimerName[] = "emit";
@@ -414,6 +424,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
AU.addRequired<GCModuleInfo>();
+ AU.addRequired<LazyMachineBlockFrequencyInfoPass>();
}
bool AsmPrinter::doInitialization(Module &M) {
@@ -475,6 +486,11 @@ bool AsmPrinter::doInitialization(Module &M) {
}
}
+ // On AIX, emit bytes for llvm.commandline metadata after .file so that the
+ // C_INFO symbol is preserved if any csect is kept by the linker.
+ if (TM.getTargetTriple().isOSBinFormatXCOFF())
+ emitModuleCommandLines(M);
+
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (const auto &I : *MI)
@@ -531,7 +547,7 @@ bool AsmPrinter::doInitialization(Module &M) {
break;
}
assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI ||
- ModuleCFISection != CFISection::EH);
+ usesCFIWithoutEH() || ModuleCFISection != CFISection::EH);
break;
default:
break;
@@ -540,7 +556,7 @@ bool AsmPrinter::doInitialization(Module &M) {
EHStreamer *ES = nullptr;
switch (MAI->getExceptionHandlingType()) {
case ExceptionHandling::None:
- if (!needsCFIForDebug())
+ if (!usesCFIWithoutEH())
break;
[[fallthrough]];
case ExceptionHandling::SjLj:
@@ -585,6 +601,16 @@ bool AsmPrinter::doInitialization(Module &M) {
HI.Handler->beginModule(&M);
}
+ if (!BasicBlockProfileDump.empty()) {
+ std::error_code PossibleFileError;
+ MBBProfileDumpFileOutput = std::make_unique<raw_fd_ostream>(
+ BasicBlockProfileDump, PossibleFileError);
+ if (PossibleFileError) {
+ M.getContext().emitError("Failed to open file for MBB Profile Dump: " +
+ PossibleFileError.message() + "\n");
+ }
+ }
+
return false;
}
@@ -704,8 +730,8 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
if (T.getArch() != Triple::aarch64 || !T.isAndroid())
OutContext.reportError(SMLoc(),
- "Tagged symbols (-fsanitize=memtag-globals) are "
- "only supported on aarch64 + Android.");
+ "tagged symbols (-fsanitize=memtag-globals) are "
+ "only supported on AArch64 Android");
OutStreamer->emitSymbolAttribute(EmittedSym, MAI->getMemtagAttr());
}
@@ -908,13 +934,6 @@ void AsmPrinter::emitFunctionHeader() {
if (F.hasFnAttribute(Attribute::Cold))
OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold);
- if (isVerbose()) {
- F.printAsOperand(OutStreamer->getCommentOS(),
- /*PrintType=*/false, F.getParent());
- emitFunctionHeaderComment();
- OutStreamer->getCommentOS() << '\n';
- }
-
// Emit the prefix data.
if (F.hasPrefixData()) {
if (MAI->hasSubsectionsViaSymbols()) {
@@ -958,6 +977,23 @@ void AsmPrinter::emitFunctionHeader() {
CurrentPatchableFunctionEntrySym = CurrentFnBegin;
}
+ // Emit the function prologue data for the indirect call sanitizer.
+ if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) {
+ assert(MD->getNumOperands() == 2);
+
+ auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
+ auto *TypeHash = mdconst::extract<Constant>(MD->getOperand(1));
+ emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig);
+ emitGlobalConstant(F.getParent()->getDataLayout(), TypeHash);
+ }
+
+ if (isVerbose()) {
+ F.printAsOperand(OutStreamer->getCommentOS(),
+ /*PrintType=*/false, F.getParent());
+ emitFunctionHeaderComment();
+ OutStreamer->getCommentOS() << '\n';
+ }
+
// Emit the function descriptor. This is a virtual function to allow targets
// 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
@@ -1005,24 +1041,6 @@ void AsmPrinter::emitFunctionHeader() {
// Emit the prologue data.
if (F.hasPrologueData())
emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData());
-
- // Emit the function prologue data for the indirect call sanitizer.
- if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) {
- assert(TM.getTargetTriple().getArch() == Triple::x86 ||
- TM.getTargetTriple().getArch() == Triple::x86_64);
- assert(MD->getNumOperands() == 2);
-
- auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
- auto *FTRTTIProxy = mdconst::extract<Constant>(MD->getOperand(1));
- assert(PrologueSig && FTRTTIProxy);
- emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig);
-
- const MCExpr *Proxy = lowerConstant(FTRTTIProxy);
- const MCExpr *FnExp = MCSymbolRefExpr::create(CurrentFnSym, OutContext);
- const MCExpr *PCRel = MCBinaryExpr::createSub(Proxy, FnExp, OutContext);
- // Use 32 bit since only small code model is supported.
- OutStreamer->emitValue(PCRel, 4u);
- }
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
@@ -1254,6 +1272,10 @@ AsmPrinter::getFunctionCFISectionType(const Function &F) const {
F.needsUnwindTableEntry())
return CFISection::EH;
+ if (MAI->usesCFIWithoutEH() && F.hasUWTable())
+ return CFISection::EH;
+
+ assert(MMI != nullptr && "Invalid machine module info");
if (MMI->hasDebugInfo() || TM.Options.ForceDwarfFrameSection)
return CFISection::Debug;
@@ -1269,14 +1291,13 @@ bool AsmPrinter::needsSEHMoves() {
return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry();
}
-bool AsmPrinter::needsCFIForDebug() const {
- return MAI->getExceptionHandlingType() == ExceptionHandling::None &&
- MAI->doesUseCFIForDebug() && ModuleCFISection == CFISection::Debug;
+bool AsmPrinter::usesCFIWithoutEH() const {
+ return MAI->usesCFIWithoutEH() && ModuleCFISection != CFISection::None;
}
void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {
ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType();
- if (!needsCFIForDebug() &&
+ if (!usesCFIWithoutEH() &&
ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
ExceptionHandlingType != ExceptionHandling::ARM)
return;
@@ -1310,21 +1331,16 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
MCConstantExpr::create(FrameOffset, OutContext));
}
-/// Returns the BB metadata to be emitted in the .llvm_bb_addr_map section for a
-/// given basic block. This can be used to capture more precise profile
-/// information. We use the last 4 bits (LSBs) to encode the following
-/// information:
-/// * (1): set if return block (ret or tail call).
-/// * (2): set if ends with a tail call.
-/// * (3): set if exception handling (EH) landing pad.
-/// * (4): set if the block can fall through to its next.
-/// The remaining bits are zero.
-static unsigned getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
+/// Returns the BB metadata to be emitted in the SHT_LLVM_BB_ADDR_MAP section
+/// for a given basic block. This can be used to capture more precise profile
+/// information.
+static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) {
const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();
- return ((unsigned)MBB.isReturnBlock()) |
- ((!MBB.empty() && TII->isTailCall(MBB.back())) << 1) |
- (MBB.isEHPad() << 2) |
- (const_cast<MachineBasicBlock &>(MBB).canFallThrough() << 3);
+ return object::BBAddrMap::BBEntry::Metadata{
+ MBB.isReturnBlock(), !MBB.empty() && TII->isTailCall(MBB.back()),
+ MBB.isEHPad(), const_cast<MachineBasicBlock &>(MBB).canFallThrough(),
+ !MBB.empty() && MBB.rbegin()->isIndirectBranch()}
+ .encode();
}
void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
@@ -1346,7 +1362,7 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
OutStreamer->AddComment("number of basic blocks");
OutStreamer->emitULEB128IntValue(MF.size());
const MCSymbol *PrevMBBEndSymbol = FunctionSymbol;
- // Emit BB Information for each basic block in the funciton.
+ // Emit BB Information for each basic block in the function.
for (const MachineBasicBlock &MBB : MF) {
const MCSymbol *MBBSymbol =
MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
@@ -1496,9 +1512,22 @@ void AsmPrinter::emitPCSections(const MachineFunction &MF) {
// constants may appear, which will simply be emitted into the current
// section (the user of MD_pcsections decides the format of encoded data).
assert(isa<MDString>(MD.getOperand(0)) && "first operand not a string");
+ bool ConstULEB128 = false;
for (const MDOperand &MDO : MD.operands()) {
if (auto *S = dyn_cast<MDString>(MDO)) {
- SwitchSection(S->getString());
+ // Found string, start of new section!
+ // Find options for this section "<section>!<opts>" - supported options:
+ // C = Compress constant integers of size 2-8 bytes as ULEB128.
+ const StringRef SecWithOpt = S->getString();
+ const size_t OptStart = SecWithOpt.find('!'); // likely npos
+ const StringRef Sec = SecWithOpt.substr(0, OptStart);
+ const StringRef Opts = SecWithOpt.substr(OptStart); // likely empty
+ ConstULEB128 = Opts.find('C') != StringRef::npos;
+#ifndef NDEBUG
+ for (char O : Opts)
+ assert((O == '!' || O == 'C') && "Invalid !pcsections options");
+#endif
+ SwitchSection(Sec);
const MCSymbol *Prev = Syms.front();
for (const MCSymbol *Sym : Syms) {
if (Sym == Prev || !Deltas) {
@@ -1510,17 +1539,30 @@ void AsmPrinter::emitPCSections(const MachineFunction &MF) {
// `base + addr`.
emitLabelDifference(Sym, Base, RelativeRelocSize);
} else {
- emitLabelDifference(Sym, Prev, 4);
+ // Emit delta between symbol and previous symbol.
+ if (ConstULEB128)
+ emitLabelDifferenceAsULEB128(Sym, Prev);
+ else
+ emitLabelDifference(Sym, Prev, 4);
}
Prev = Sym;
}
} else {
+ // Emit auxiliary data after PC.
assert(isa<MDNode>(MDO) && "expecting either string or tuple");
const auto *AuxMDs = cast<MDNode>(MDO);
for (const MDOperand &AuxMDO : AuxMDs->operands()) {
assert(isa<ConstantAsMetadata>(AuxMDO) && "expecting a constant");
- const auto *C = cast<ConstantAsMetadata>(AuxMDO);
- emitGlobalConstant(F.getParent()->getDataLayout(), C->getValue());
+ const Constant *C = cast<ConstantAsMetadata>(AuxMDO)->getValue();
+ const DataLayout &DL = F.getParent()->getDataLayout();
+ const uint64_t Size = DL.getTypeStoreSize(C->getType());
+
+ if (auto *CI = dyn_cast<ConstantInt>(C);
+ CI && ConstULEB128 && Size > 1 && Size <= 8) {
+ emitULEB128(CI->getZExtValue());
+ } else {
+ emitGlobalConstant(DL, C);
+ }
}
}
}
@@ -1582,6 +1624,7 @@ void AsmPrinter::emitFunctionBody() {
// Print out code for the function.
bool HasAnyRealCode = false;
int NumInstsInFunction = 0;
+ bool IsEHa = MMI->getModule()->getModuleFlag("eh-asynch");
bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);
for (auto &MBB : *MF) {
@@ -1620,10 +1663,25 @@ void AsmPrinter::emitFunctionBody() {
emitFrameAlloc(MI);
break;
case TargetOpcode::ANNOTATION_LABEL:
- case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());
break;
+ case TargetOpcode::EH_LABEL:
+ OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());
+ // For AsynchEH, insert a Nop if followed by a trap inst
+ // Or the exception won't be caught.
+ // (see MCConstantExpr::create(1,..) in WinException.cpp)
+ // Ignore SDiv/UDiv because a DIV with Const-0 divisor
+ // must have being turned into an UndefValue.
+ // Div with variable opnds won't be the first instruction in
+ // an EH region as it must be led by at least a Load
+ {
+ auto MI2 = std::next(MI.getIterator());
+ if (IsEHa && MI2 != MBB.end() &&
+ (MI2->mayLoadOrStore() || MI2->mayRaiseFPException()))
+ emitNops(1);
+ }
+ break;
case TargetOpcode::INLINEASM:
case TargetOpcode::INLINEASM_BR:
emitInlineAsm(&MI);
@@ -1862,6 +1920,23 @@ void AsmPrinter::emitFunctionBody() {
OutStreamer->getCommentOS() << "-- End function\n";
OutStreamer->addBlankLine();
+
+ // Output MBB ids, function names, and frequencies if the flag to dump
+ // MBB profile information has been set
+ if (MBBProfileDumpFileOutput) {
+ if (!MF->hasBBLabels())
+ MF->getContext().reportError(
+ SMLoc(),
+ "Unable to find BB labels for MBB profile dump. -mbb-profile-dump "
+ "must be called with -basic-block-sections=labels");
+ MachineBlockFrequencyInfo &MBFI =
+ getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI();
+ for (const auto &MBB : *MF) {
+ *MBBProfileDumpFileOutput.get()
+ << MF->getName() << "," << MBB.getBBID() << ","
+ << MBFI.getBlockFreqRelativeToEntryBlock(&MBB) << "\n";
+ }
+ }
}
/// Compute the number of Global Variables that uses a Constant.
@@ -2235,6 +2310,8 @@ bool AsmPrinter::doFinalization(Module &M) {
SmallVector<const GlobalAlias *, 16> AliasStack;
SmallPtrSet<const GlobalAlias *, 16> AliasVisited;
for (const auto &Alias : M.aliases()) {
+ if (Alias.hasAvailableExternallyLinkage())
+ continue;
for (const GlobalAlias *Cur = &Alias; Cur;
Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {
if (!AliasVisited.insert(Cur).second)
@@ -2258,7 +2335,9 @@ bool AsmPrinter::doFinalization(Module &M) {
emitModuleIdents(M);
// Emit bytes for llvm.commandline metadata.
- emitModuleCommandLines(M);
+ // The command line metadata is emitted earlier on XCOFF.
+ if (!TM.getTargetTriple().isOSBinFormatXCOFF())
+ emitModuleCommandLines(M);
// Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if
// split-stack is used.
@@ -2786,6 +2865,22 @@ void AsmPrinter::emitInt16(int Value) const { OutStreamer->emitInt16(Value); }
/// Emit a long directive and value.
void AsmPrinter::emitInt32(int Value) const { OutStreamer->emitInt32(Value); }
+/// EmitSLEB128 - emit the specified signed leb128 value.
+void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {
+ if (isVerbose() && Desc)
+ OutStreamer->AddComment(Desc);
+
+ OutStreamer->emitSLEB128IntValue(Value);
+}
+
+void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,
+ unsigned PadTo) const {
+ if (isVerbose() && Desc)
+ OutStreamer->AddComment(Desc);
+
+ OutStreamer->emitULEB128IntValue(Value, PadTo);
+}
+
/// Emit a long long directive and value.
void AsmPrinter::emitInt64(uint64_t Value) const {
OutStreamer->emitInt64(Value);
@@ -2799,6 +2894,12 @@ void AsmPrinter::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size);
}
+/// Emit something like ".uleb128 Hi-Lo".
+void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi,
+ const MCSymbol *Lo) const {
+ OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, 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.
@@ -3288,7 +3389,8 @@ static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) {
ExtraBitsSize = alignTo(ExtraBitsSize, 8);
ExtraBits = Realigned.getRawData()[0] &
(((uint64_t)-1) >> (64 - ExtraBitsSize));
- Realigned.lshrInPlace(ExtraBitsSize);
+ if (BitWidth >= 64)
+ Realigned.lshrInPlace(ExtraBitsSize);
} else
ExtraBits = Realigned.getRawData()[BitWidth / 64];
}
@@ -3917,16 +4019,18 @@ void AsmPrinter::emitXRayTable() {
Flags, 0, GroupName, F.hasComdat(),
MCSection::NonUniqueID, LinkedToSym);
- if (!TM.Options.XRayOmitFunctionIndex)
+ if (TM.Options.XRayFunctionIndex)
FnSledIndex = OutContext.getELFSection(
- "xray_fn_idx", ELF::SHT_PROGBITS, Flags | ELF::SHF_WRITE, 0,
- GroupName, F.hasComdat(), MCSection::NonUniqueID, LinkedToSym);
+ "xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0, GroupName, F.hasComdat(),
+ MCSection::NonUniqueID, LinkedToSym);
} else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
- InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
+ InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map",
+ MachO::S_ATTR_LIVE_SUPPORT,
SectionKind::getReadOnlyWithRel());
- if (!TM.Options.XRayOmitFunctionIndex)
- FnSledIndex = OutContext.getMachOSection(
- "__DATA", "xray_fn_idx", 0, SectionKind::getReadOnlyWithRel());
+ if (TM.Options.XRayFunctionIndex)
+ FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx",
+ MachO::S_ATTR_LIVE_SUPPORT,
+ SectionKind::getReadOnly());
} else {
llvm_unreachable("Unsupported target");
}
@@ -3937,7 +4041,8 @@ void AsmPrinter::emitXRayTable() {
// 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);
+ MCSymbol *SledsStart =
+ OutContext.createLinkerPrivateSymbol("xray_sleds_start");
OutStreamer->switchSection(InstMap);
OutStreamer->emitLabel(SledsStart);
for (const auto &Sled : Sleds) {
@@ -3968,8 +4073,17 @@ void AsmPrinter::emitXRayTable() {
OutStreamer->switchSection(FnSledIndex);
OutStreamer->emitCodeAlignment(Align(2 * WordSizeBytes),
&getSubtargetInfo());
- OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes, false);
- OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes, false);
+ // For Mach-O, use an "l" symbol as the atom of this subsection. The label
+ // difference uses a SUBTRACTOR external relocation which references the
+ // symbol.
+ MCSymbol *Dot = Ctx.createLinkerPrivateSymbol("xray_fn_idx");
+ OutStreamer->emitLabel(Dot);
+ OutStreamer->emitValueImpl(
+ MCBinaryExpr::createSub(MCSymbolRefExpr::create(SledsStart, Ctx),
+ MCSymbolRefExpr::create(Dot, Ctx), Ctx),
+ WordSizeBytes);
+ OutStreamer->emitValueImpl(MCConstantExpr::create(Sleds.size(), Ctx),
+ WordSizeBytes);
OutStreamer->switchSection(PrevSection);
}
Sleds.clear();
@@ -4041,7 +4155,7 @@ unsigned int AsmPrinter::getDwarfOffsetByteSize() const {
}
dwarf::FormParams AsmPrinter::getDwarfFormParams() const {
- return {getDwarfVersion(), uint8_t(getPointerSize()),
+ return {getDwarfVersion(), uint8_t(MAI->getCodePointerSize()),
OutStreamer->getContext().getDwarfFormat(),
doesDwarfUseRelocationsAcrossSections()};
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index ecaa64afab4d..21d0d070c247 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -32,28 +32,6 @@ using namespace llvm;
// Dwarf Emission Helper Routines
//===----------------------------------------------------------------------===//
-/// EmitSLEB128 - emit the specified signed leb128 value.
-void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {
- if (isVerbose() && Desc)
- OutStreamer->AddComment(Desc);
-
- OutStreamer->emitSLEB128IntValue(Value);
-}
-
-void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,
- unsigned PadTo) const {
- if (isVerbose() && Desc)
- OutStreamer->AddComment(Desc);
-
- OutStreamer->emitULEB128IntValue(Value, PadTo);
-}
-
-/// Emit something like ".uleb128 Hi-Lo".
-void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi,
- const MCSymbol *Lo) const {
- OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
-}
-
static const char *DecodeDWARFEncoding(unsigned Encoding) {
switch (Encoding) {
case dwarf::DW_EH_PE_absptr:
@@ -130,7 +108,7 @@ unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
default:
llvm_unreachable("Invalid encoded value.");
case dwarf::DW_EH_PE_absptr:
- return MF->getDataLayout().getPointerSize();
+ return MAI->getCodePointerSize();
case dwarf::DW_EH_PE_udata2:
return 2;
case dwarf::DW_EH_PE_udata4:
@@ -226,58 +204,59 @@ void AsmPrinter::emitCallSiteValue(uint64_t Value, unsigned Encoding) const {
//===----------------------------------------------------------------------===//
void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
+ SMLoc Loc = Inst.getLoc();
switch (Inst.getOperation()) {
default:
llvm_unreachable("Unexpected instruction");
case MCCFIInstruction::OpDefCfaOffset:
- OutStreamer->emitCFIDefCfaOffset(Inst.getOffset());
+ OutStreamer->emitCFIDefCfaOffset(Inst.getOffset(), Loc);
break;
case MCCFIInstruction::OpAdjustCfaOffset:
- OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset());
+ OutStreamer->emitCFIAdjustCfaOffset(Inst.getOffset(), Loc);
break;
case MCCFIInstruction::OpDefCfa:
- OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset());
+ OutStreamer->emitCFIDefCfa(Inst.getRegister(), Inst.getOffset(), Loc);
break;
case MCCFIInstruction::OpDefCfaRegister:
- OutStreamer->emitCFIDefCfaRegister(Inst.getRegister());
+ OutStreamer->emitCFIDefCfaRegister(Inst.getRegister(), Loc);
break;
case MCCFIInstruction::OpLLVMDefAspaceCfa:
OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(),
- Inst.getAddressSpace());
+ Inst.getAddressSpace(), Loc);
break;
case MCCFIInstruction::OpOffset:
- OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset());
+ OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset(), Loc);
break;
case MCCFIInstruction::OpRegister:
- OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2());
+ OutStreamer->emitCFIRegister(Inst.getRegister(), Inst.getRegister2(), Loc);
break;
case MCCFIInstruction::OpWindowSave:
- OutStreamer->emitCFIWindowSave();
+ OutStreamer->emitCFIWindowSave(Loc);
break;
case MCCFIInstruction::OpNegateRAState:
- OutStreamer->emitCFINegateRAState();
+ OutStreamer->emitCFINegateRAState(Loc);
break;
case MCCFIInstruction::OpSameValue:
- OutStreamer->emitCFISameValue(Inst.getRegister());
+ OutStreamer->emitCFISameValue(Inst.getRegister(), Loc);
break;
case MCCFIInstruction::OpGnuArgsSize:
- OutStreamer->emitCFIGnuArgsSize(Inst.getOffset());
+ OutStreamer->emitCFIGnuArgsSize(Inst.getOffset(), Loc);
break;
case MCCFIInstruction::OpEscape:
OutStreamer->AddComment(Inst.getComment());
- OutStreamer->emitCFIEscape(Inst.getValues());
+ OutStreamer->emitCFIEscape(Inst.getValues(), Loc);
break;
case MCCFIInstruction::OpRestore:
- OutStreamer->emitCFIRestore(Inst.getRegister());
+ OutStreamer->emitCFIRestore(Inst.getRegister(), Loc);
break;
case MCCFIInstruction::OpUndefined:
- OutStreamer->emitCFIUndefined(Inst.getRegister());
+ OutStreamer->emitCFIUndefined(Inst.getRegister(), Loc);
break;
case MCCFIInstruction::OpRememberState:
- OutStreamer->emitCFIRememberState();
+ OutStreamer->emitCFIRememberState(Loc);
break;
case MCCFIInstruction::OpRestoreState:
- OutStreamer->emitCFIRestoreState();
+ OutStreamer->emitCFIRestoreState(Loc);
break;
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index c1588aaea05e..32674bbeb061 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 0a67c4b6beb6..8161de57b58e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -16,7 +16,6 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -65,6 +64,7 @@
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cassert>
#include <cctype>
@@ -488,10 +488,10 @@ void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
// This variable was inlined. Associate it with the InlineSite.
const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram();
InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
- Site.InlinedLocals.emplace_back(Var);
+ Site.InlinedLocals.emplace_back(std::move(Var));
} else {
// This variable goes into the corresponding lexical scope.
- ScopeVariables[LS].emplace_back(Var);
+ ScopeVariables[LS].emplace_back(std::move(Var));
}
}
@@ -569,7 +569,6 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
case dwarf::DW_LANG_C89:
case dwarf::DW_LANG_C99:
case dwarf::DW_LANG_C11:
- case dwarf::DW_LANG_ObjC:
return SourceLanguage::C;
case dwarf::DW_LANG_C_plus_plus:
case dwarf::DW_LANG_C_plus_plus_03:
@@ -595,6 +594,10 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
return SourceLanguage::Swift;
case dwarf::DW_LANG_Rust:
return SourceLanguage::Rust;
+ case dwarf::DW_LANG_ObjC:
+ return SourceLanguage::ObjC;
+ case dwarf::DW_LANG_ObjC_plus_plus:
+ return SourceLanguage::ObjCpp;
default:
// There's no CodeView representation for this language, and CV doesn't
// have an "unknown" option for the language field, so we'll use MASM,
@@ -788,7 +791,6 @@ void CodeViewDebug::emitObjName() {
// Don't emit the filename if we're writing to stdout or to /dev/null.
PathRef = {};
} else {
- llvm::sys::path::remove_dots(PathStore, /*remove_dot_dot=*/true);
PathRef = PathStore;
}
@@ -1158,7 +1160,14 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.AddComment("Function section index");
OS.emitCOFFSectionIndex(Fn);
OS.AddComment("Flags");
- OS.emitInt8(0);
+ ProcSymFlags ProcFlags = ProcSymFlags::HasOptimizedDebugInfo;
+ if (FI.HasFramePointer)
+ ProcFlags |= ProcSymFlags::HasFP;
+ if (GV->hasFnAttribute(Attribute::NoReturn))
+ ProcFlags |= ProcSymFlags::IsNoReturn;
+ if (GV->hasFnAttribute(Attribute::NoInline))
+ ProcFlags |= ProcSymFlags::IsNoInline;
+ OS.emitInt8(static_cast<uint8_t>(ProcFlags));
// 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.
@@ -1262,7 +1271,8 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
const TargetFrameLowering *TFI = TSI.getFrameLowering();
const TargetRegisterInfo *TRI = TSI.getRegisterInfo();
- for (const MachineFunction::VariableDbgInfo &VI : MF.getVariableDbgInfo()) {
+ for (const MachineFunction::VariableDbgInfo &VI :
+ MF.getInStackSlotVariableDbgInfo()) {
if (!VI.Var)
continue;
assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
@@ -1290,7 +1300,8 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
// Get the frame register used and the offset.
Register FrameReg;
- StackOffset FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);
+ StackOffset FrameOffset =
+ TFI->getFrameIndexReference(*Asm->MF, VI.getStackSlot(), FrameReg);
uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);
assert(!FrameOffset.getScalable() &&
@@ -1476,6 +1487,7 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::StackPtr;
} else {
+ CurFn->HasFramePointer = true;
// If there is an FP, parameters are always relative to it.
CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::FramePtr;
if (CurFn->HasStackRealignment) {
@@ -1717,12 +1729,13 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
// Otherwise, if it has an upperboud, use (upperbound - lowerbound + 1),
// where lowerbound is from the LowerBound field of the Subrange,
// or the language default lowerbound if that field is unspecified.
- if (auto *CI = Subrange->getCount().dyn_cast<ConstantInt *>())
+ if (auto *CI = dyn_cast_if_present<ConstantInt *>(Subrange->getCount()))
Count = CI->getSExtValue();
- else if (auto *UI = Subrange->getUpperBound().dyn_cast<ConstantInt *>()) {
+ else if (auto *UI = dyn_cast_if_present<ConstantInt *>(
+ Subrange->getUpperBound())) {
// Fortran uses 1 as the default lowerbound; other languages use 0.
int64_t Lowerbound = (moduleIsInFortran()) ? 1 : 0;
- auto *LI = Subrange->getLowerBound().dyn_cast<ConstantInt *>();
+ auto *LI = dyn_cast_if_present<ConstantInt *>(Subrange->getLowerBound());
Lowerbound = (LI) ? LI->getSExtValue() : Lowerbound;
Count = UI->getSExtValue() - Lowerbound + 1;
}
@@ -1793,12 +1806,14 @@ TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) {
}
break;
case dwarf::DW_ATE_complex_float:
+ // The CodeView size for a complex represents the size of
+ // an individual component.
switch (ByteSize) {
- case 2: STK = SimpleTypeKind::Complex16; break;
- case 4: STK = SimpleTypeKind::Complex32; break;
- case 8: STK = SimpleTypeKind::Complex64; break;
- case 10: STK = SimpleTypeKind::Complex80; break;
- case 16: STK = SimpleTypeKind::Complex128; break;
+ case 4: STK = SimpleTypeKind::Complex16; break;
+ case 8: STK = SimpleTypeKind::Complex32; break;
+ case 16: STK = SimpleTypeKind::Complex64; break;
+ case 20: STK = SimpleTypeKind::Complex80; break;
+ case 32: STK = SimpleTypeKind::Complex128; break;
}
break;
case dwarf::DW_ATE_float:
@@ -3279,7 +3294,7 @@ void CodeViewDebug::emitDebugInfoForGlobals() {
// Second, emit each global that is in a comdat into its own .debug$S
// section along with its own symbol substream.
for (const CVGlobalVariable &CVGV : ComdatVariables) {
- const GlobalVariable *GV = CVGV.GVInfo.get<const GlobalVariable *>();
+ const GlobalVariable *GV = cast<const GlobalVariable *>(CVGV.GVInfo);
MCSymbol *GVSym = Asm->getSymbol(GV);
OS.AddComment("Symbol subsection for " +
Twine(GlobalValue::dropLLVMManglingEscape(GV->getName())));
@@ -3388,7 +3403,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
: getFullyQualifiedName(Scope, DIGV->getName());
if (const GlobalVariable *GV =
- CVGV.GVInfo.dyn_cast<const GlobalVariable *>()) {
+ dyn_cast_if_present<const GlobalVariable *>(CVGV.GVInfo)) {
// DataSym record, see SymbolRecord.h for more info. Thread local data
// happens to have the same format as global data.
MCSymbol *GVSym = Asm->getSymbol(GV);
@@ -3403,7 +3418,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
OS.AddComment("DataOffset");
uint64_t Offset = 0;
- if (CVGlobalVariableOffsets.find(DIGV) != CVGlobalVariableOffsets.end())
+ if (CVGlobalVariableOffsets.contains(DIGV))
// Use the offset seen while collecting info on globals.
Offset = CVGlobalVariableOffsets[DIGV];
OS.emitCOFFSecRel32(GVSym, Offset);
@@ -3415,7 +3430,7 @@ void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
emitNullTerminatedSymbolName(OS, QualifiedName, LengthOfDataRecord);
endSymbolRecord(DataEnd);
} else {
- const DIExpression *DIE = CVGV.GVInfo.get<const DIExpression *>();
+ const DIExpression *DIE = cast<const DIExpression *>(CVGV.GVInfo);
assert(DIE->isConstant() &&
"Global constant variables must contain a constant expression.");
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 495822a6e653..1455ac417824 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -13,6 +13,7 @@
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_CODEVIEWDEBUG_H
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
@@ -191,6 +192,8 @@ private:
bool HasStackRealignment = false;
bool HaveLineInfo = false;
+
+ bool HasFramePointer = false;
};
FunctionInfo *CurFn = nullptr;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
index 308d4b1b5d61..619155cafe92 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -173,9 +173,7 @@ void DIEAbbrevSet::Emit(const AsmPrinter *AP, MCSection *Section) const {
// DIE Implementation
//===----------------------------------------------------------------------===//
-DIE *DIE::getParent() const {
- return Owner.dyn_cast<DIE*>();
-}
+DIE *DIE::getParent() const { return dyn_cast_if_present<DIE *>(Owner); }
DIEAbbrev DIE::generateAbbrev() const {
DIEAbbrev Abbrev(Tag, hasChildren());
@@ -209,7 +207,7 @@ const DIE *DIE::getUnitDie() const {
DIEUnit *DIE::getUnit() const {
const DIE *UnitDie = getUnitDie();
if (UnitDie)
- return UnitDie->Owner.dyn_cast<DIEUnit*>();
+ return dyn_cast_if_present<DIEUnit *>(UnitDie->Owner);
return nullptr;
}
@@ -385,6 +383,7 @@ void DIEInteger::emitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
case dwarf::DW_FORM_strx2:
case dwarf::DW_FORM_addrx2:
case dwarf::DW_FORM_strx3:
+ case dwarf::DW_FORM_addrx3:
case dwarf::DW_FORM_strp:
case dwarf::DW_FORM_ref4:
case dwarf::DW_FORM_data4:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
index 0b40cdb0c3cc..55a0afcf7a33 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
@@ -138,6 +138,9 @@ void DbgValueHistoryMap::trimLocationRanges(
// references if any entries are removed.
SmallVector<size_t, 4> Offsets;
+ LLVM_DEBUG(dbgs() << "Trimming location ranges for function '" << MF.getName()
+ << "'\n");
+
for (auto &Record : VarEntries) {
auto &HistoryMapEntries = Record.second;
if (HistoryMapEntries.empty())
@@ -213,6 +216,8 @@ void DbgValueHistoryMap::trimLocationRanges(
// count of the closing entry, if one exists.
if (EndIndex != NoEntry)
ReferenceCount[EndIndex] -= 1;
+ LLVM_DEBUG(dbgs() << "Dropping value outside scope range of variable: ";
+ StartMI->print(llvm::dbgs()););
}
}
@@ -253,6 +258,8 @@ void DbgValueHistoryMap::trimLocationRanges(
// ToRemove indices are valid after each erase.
for (EntryIndex Idx : llvm::reverse(ToRemove))
HistoryMapEntries.erase(HistoryMapEntries.begin() + Idx);
+ LLVM_DEBUG(llvm::dbgs() << "New HistoryMap('" << LocalVar->getName()
+ << "') size: " << HistoryMapEntries.size() << "\n");
}
}
@@ -555,8 +562,8 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const {
- dbgs() << "DbgValueHistoryMap:\n";
+LLVM_DUMP_METHOD void DbgValueHistoryMap::dump(StringRef FuncName) const {
+ dbgs() << "DbgValueHistoryMap('" << FuncName << "'):\n";
for (const auto &VarRangePair : *this) {
const InlinedEntity &Var = VarRangePair.first;
const Entries &Entries = VarRangePair.second;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 858a3e75e515..eb2d992c7e75 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -223,6 +223,7 @@ bool DebugHandlerBase::isUnsignedDIType(const DIType *Ty) {
Encoding == dwarf::DW_ATE_signed_char ||
Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
Encoding == dwarf::DW_ATE_boolean ||
+ Encoding == dwarf::DW_ATE_complex_float ||
(Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
Ty->getName() == "decltype(nullptr)")) &&
"Unsupported encoding");
@@ -273,7 +274,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
InstOrdering.initialize(*MF);
if (TrimVarLocs)
DbgValues.trimLocationRanges(*MF, LScopes, InstOrdering);
- LLVM_DEBUG(DbgValues.dump());
+ LLVM_DEBUG(DbgValues.dump(MF->getName()));
// Request labels for the full history.
for (const auto &I : DbgValues) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 2008aa39ff87..726aba18bb80 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -126,7 +126,7 @@ public:
: Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
IsVariadic(IsVariadic) {
#ifndef NDEBUG
- assert(cast<DIExpression>(Expr)->isValid() ||
+ assert(Expr->isValid() ||
!any_of(Locs, [](auto LE) { return LE.isLocation(); }));
if (!IsVariadic) {
assert(ValueLocEntries.size() == 1);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
index 0515173b4a24..a96bdd034918 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocStream.h
@@ -49,7 +49,7 @@ private:
SmallVector<Entry, 32> Entries;
SmallString<256> DWARFBytes;
std::vector<std::string> Comments;
- MCSymbol *Sym;
+ MCSymbol *Sym = nullptr;
/// Only verbose textual output needs comments. This will be set to
/// true for that case, and false otherwise.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index df4fe8d49806..10c844ddb14a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -94,7 +94,7 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
shouldEmitCFI =
MAI.usesCFIForEH() && (shouldEmitPersonality || shouldEmitMoves);
else
- shouldEmitCFI = Asm->needsCFIForDebug() && shouldEmitMoves;
+ shouldEmitCFI = Asm->usesCFIWithoutEH() && shouldEmitMoves;
}
void DwarfCFIException::beginBasicBlockSection(const MachineBasicBlock &MBB) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 6dde50375a60..58ed21379d29 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -26,6 +26,7 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
@@ -266,7 +267,7 @@ void DwarfCompileUnit::addLocationAttribute(
// 16-bit platforms like MSP430 and AVR take this path, so sink this
// assert to platforms that use it.
auto GetPointerSizedFormAndOp = [this]() {
- unsigned PointerSize = Asm->getDataLayout().getPointerSize();
+ unsigned PointerSize = Asm->MAI->getCodePointerSize();
assert((PointerSize == 4 || PointerSize == 8) &&
"Add support for other sizes if necessary");
struct FormAndOp {
@@ -278,7 +279,16 @@ void DwarfCompileUnit::addLocationAttribute(
: FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};
};
if (Global->isThreadLocal()) {
- if (Asm->TM.useEmulatedTLS()) {
+ if (Asm->TM.getTargetTriple().isWasm()) {
+ // FIXME This is not guaranteed, but in practice, in static linking,
+ // if present, __tls_base's index is 1. This doesn't hold for dynamic
+ // linking, so TLS variables used in dynamic linking won't have
+ // correct debug info for now. See
+ // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823
+ addWasmRelocBaseGlobal(Loc, "__tls_base", 1);
+ addOpAddress(*Loc, Sym);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
+ } else if (Asm->TM.useEmulatedTLS()) {
// TODO: add debug info for emulated thread local mode.
} else {
// FIXME: Make this work with -gsplit-dwarf.
@@ -301,6 +311,14 @@ void DwarfCompileUnit::addLocationAttribute(
DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
: dwarf::DW_OP_form_tls_address);
}
+ } else if (Asm->TM.getTargetTriple().isWasm() &&
+ Asm->TM.getRelocationModel() == Reloc::PIC_) {
+ // FIXME This is not guaranteed, but in practice, if present,
+ // __memory_base's index is 1. See
+ // https://github.com/llvm/llvm-project/blob/19afbfe33156d211fa959dadeea46cd17b9c723c/lld/wasm/Driver.cpp#L786-L823
+ addWasmRelocBaseGlobal(Loc, "__memory_base", 1);
+ addOpAddress(*Loc, Sym);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
} else if ((Asm->TM.getRelocationModel() == Reloc::RWPI ||
Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) &&
!Asm->getObjFileLowering()
@@ -449,6 +467,39 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP) {
return ContextCU->updateSubprogramScopeDIEImpl(SP, SPDie);
}
+// Add info for Wasm-global-based relocation.
+// 'GlobalIndex' is used for split dwarf, which currently relies on a few
+// assumptions that are not guaranteed in a formal way but work in practice.
+void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
+ uint64_t GlobalIndex) {
+ // 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;
+ unsigned PointerSize = Asm->getDataLayout().getPointerSize();
+ auto *Sym = cast<MCSymbolWasm>(Asm->GetExternalSymbolSymbol(GlobalName));
+ // FIXME: this repeats what WebAssemblyMCInstLower::
+ // GetExternalSymbolSymbol does, since if there's no code that
+ // refers to this symbol, we have to set it here.
+ Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+ Sym->setGlobalType(wasm::WasmGlobalType{
+ static_cast<uint8_t>(PointerSize == 4 ? wasm::WASM_TYPE_I32
+ : wasm::WASM_TYPE_I64),
+ true});
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
+ addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);
+ if (!isDwoUnit()) {
+ addLabel(*Loc, dwarf::DW_FORM_data4, Sym);
+ } else {
+ // FIXME: when writing dwo, we need to avoid relocations. Probably
+ // the "right" solution is to treat globals the way func and data
+ // symbols are (with entries in .debug_addr).
+ // For now we hardcode the indices in the callsites. Global indices are not
+ // fixed, but in practice a few are fixed; for example, __stack_pointer is
+ // always index 0.
+ addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);
+ }
+}
+
DIE &DwarfCompileUnit::updateSubprogramScopeDIEImpl(const DISubprogram *SP,
DIE *SPDie) {
SmallVector<RangeSpan, 2> BB_List;
@@ -480,40 +531,24 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIEImpl(const DISubprogram *SP,
case TargetFrameLowering::DwarfFrameBase::CFA: {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);
+ if (FrameBase.Location.Offset != 0) {
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts);
+ addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.Offset);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
+ }
addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
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, TI_GLOBAL_RELOC);
- if (!isDwoUnit()) {
- addLabel(*Loc, dwarf::DW_FORM_data4, SPSym);
- } else {
- // FIXME: when writing dwo, we need to avoid relocations. Probably
- // the "right" solution is to treat globals the way func and data
- // symbols are (with entries in .debug_addr).
- // For now, since we only ever use index 0, this should work as-is.
- addUInt(*Loc, dwarf::DW_FORM_data4, FrameBase.Location.WasmLoc.Index);
- }
+ assert(FrameBase.Location.WasmLoc.Index == 0); // Only SP so far.
+ // For now, since we only ever use index 0, this should work as-is.
+ addWasmRelocBaseGlobal(Loc, "__stack_pointer",
+ FrameBase.Location.WasmLoc.Index);
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);
} else {
@@ -608,7 +643,7 @@ void DwarfCompileUnit::attachRangesOrLowHighPC(
assert(!Ranges.empty());
if (!DD->useRangesSection() ||
(Ranges.size() == 1 &&
- (!DD->alwaysUseRanges() ||
+ (!DD->alwaysUseRanges(*this) ||
DD->getSectionLabel(&Ranges.front().Begin->getSection()) ==
Ranges.front().Begin))) {
const RangeSpan &Front = Ranges.front();
@@ -659,7 +694,7 @@ DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,
auto *InlinedSP = getDISubprogram(DS);
// Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
// was inlined from another compile unit.
- DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
+ DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];
assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
@@ -691,10 +726,20 @@ DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,
DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
if (DD->isLexicalScopeDIENull(Scope))
return nullptr;
+ const auto *DS = Scope->getScopeNode();
auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
- if (Scope->isAbstractScope())
+ if (Scope->isAbstractScope()) {
+ assert(!getAbstractScopeDIEs().count(DS) &&
+ "Abstract DIE for this scope exists!");
+ getAbstractScopeDIEs()[DS] = ScopeDIE;
return ScopeDIE;
+ }
+ if (!Scope->getInlinedAt()) {
+ assert(!LexicalBlockDIEs.count(DS) &&
+ "Concrete out-of-line DIE for this scope exists!");
+ LexicalBlockDIEs[DS] = ScopeDIE;
+ }
attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
@@ -929,29 +974,29 @@ static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
for (auto *El : Array->getElements()) {
if (auto *Subrange = dyn_cast<DISubrange>(El)) {
if (auto Count = Subrange->getCount())
- if (auto *Dependency = Count.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))
Result.push_back(Dependency);
if (auto LB = Subrange->getLowerBound())
- if (auto *Dependency = LB.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))
Result.push_back(Dependency);
if (auto UB = Subrange->getUpperBound())
- if (auto *Dependency = UB.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))
Result.push_back(Dependency);
if (auto ST = Subrange->getStride())
- if (auto *Dependency = ST.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))
Result.push_back(Dependency);
} else if (auto *GenericSubrange = dyn_cast<DIGenericSubrange>(El)) {
if (auto Count = GenericSubrange->getCount())
- if (auto *Dependency = Count.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))
Result.push_back(Dependency);
if (auto LB = GenericSubrange->getLowerBound())
- if (auto *Dependency = LB.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))
Result.push_back(Dependency);
if (auto UB = GenericSubrange->getUpperBound())
- if (auto *Dependency = UB.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))
Result.push_back(Dependency);
if (auto ST = GenericSubrange->getStride())
- if (auto *Dependency = ST.dyn_cast<DIVariable *>())
+ if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))
Result.push_back(Dependency);
}
}
@@ -1062,35 +1107,35 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
for (DbgVariable *DV : Locals)
ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));
- // Emit imported entities (skipped in gmlt-like data).
- if (!includeMinimalInlineScopes()) {
- for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
- ScopeDIE.addChild(constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
- }
-
// Emit labels.
for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));
+ // Track other local entities (skipped in gmlt-like data).
+ // This creates mapping between CU and a set of local declarations that
+ // should be emitted for subprograms in this CU.
+ if (!includeMinimalInlineScopes() && !Scope->getInlinedAt()) {
+ auto &LocalDecls = DD->getLocalDeclsForScope(Scope->getScopeNode());
+ DeferredLocalDecls.insert(LocalDecls.begin(), LocalDecls.end());
+ }
+
// Emit inner lexical scopes.
- auto needToEmitLexicalScope = [this](LexicalScope *LS) {
- if (isa<DISubprogram>(LS->getScopeNode()))
- return true;
- auto Vars = DU->getScopeVariables().lookup(LS);
+ auto skipLexicalScope = [this](LexicalScope *S) -> bool {
+ if (isa<DISubprogram>(S->getScopeNode()))
+ return false;
+ auto Vars = DU->getScopeVariables().lookup(S);
if (!Vars.Args.empty() || !Vars.Locals.empty())
- return true;
- if (!includeMinimalInlineScopes() &&
- !ImportedEntities[LS->getScopeNode()].empty())
- return true;
- return false;
+ return false;
+ return includeMinimalInlineScopes() ||
+ DD->getLocalDeclsForScope(S->getScopeNode()).empty();
};
for (LexicalScope *LS : Scope->getChildren()) {
// If the lexical block doesn't have non-scope children, skip
// its emission and put its children directly to the parent scope.
- if (needToEmitLexicalScope(LS))
- constructScopeDIE(LS, ScopeDIE);
- else
+ if (skipLexicalScope(LS))
createAndAddScopeChildren(LS, ScopeDIE);
+ else
+ constructScopeDIE(LS, ScopeDIE);
}
return ObjectPointer;
@@ -1098,11 +1143,9 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
LexicalScope *Scope) {
- DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
- if (AbsDef)
- return;
-
auto *SP = cast<DISubprogram>(Scope->getScopeNode());
+ if (getAbstractScopeDIEs().count(SP))
+ return;
DIE *ContextDIE;
DwarfCompileUnit *ContextCU = this;
@@ -1126,14 +1169,19 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
// Passing null as the associated node because the abstract definition
// shouldn't be found by lookup.
- AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
- ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
- ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline,
+ DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
+ *ContextDIE, nullptr);
+
+ // Store the DIE before creating children.
+ ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;
+
+ ContextCU->applySubprogramAttributesToDefinition(SP, AbsDef);
+ ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline,
DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()
: dwarf::DW_FORM_implicit_const,
dwarf::DW_INL_inlined);
- if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
- ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
+ if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, AbsDef))
+ ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
}
bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
@@ -1277,21 +1325,37 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
EntityDie = getOrCreateNameSpace(NS);
else if (auto *M = dyn_cast<DIModule>(Entity))
EntityDie = getOrCreateModule(M);
- else if (auto *SP = dyn_cast<DISubprogram>(Entity))
- EntityDie = getOrCreateSubprogramDIE(SP);
- else if (auto *T = dyn_cast<DIType>(Entity))
+ else if (auto *SP = dyn_cast<DISubprogram>(Entity)) {
+ // If there is an abstract subprogram, refer to it. Note that this assumes
+ // that all the abstract subprograms have been already created (which is
+ // correct until imported entities get emitted in DwarfDebug::endModule()).
+ if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))
+ EntityDie = AbsSPDie;
+ else
+ EntityDie = getOrCreateSubprogramDIE(SP);
+ } else if (auto *T = dyn_cast<DIType>(Entity))
EntityDie = getOrCreateTypeDIE(T);
else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
EntityDie = getOrCreateGlobalVariableDIE(GV, {});
+ else if (auto *IE = dyn_cast<DIImportedEntity>(Entity))
+ EntityDie = getOrCreateImportedEntityDIE(IE);
else
EntityDie = getDIE(Entity);
assert(EntityDie);
addSourceLine(*IMDie, Module->getLine(), Module->getFile());
addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
StringRef Name = Module->getName();
- if (!Name.empty())
+ if (!Name.empty()) {
addString(*IMDie, dwarf::DW_AT_name, Name);
+ // FIXME: if consumers ever start caring about handling
+ // unnamed import declarations such as `using ::nullptr_t`
+ // or `using namespace std::ranges`, we could add the
+ // import declaration into the accelerator table with the
+ // name being the one of the entity being imported.
+ DD->addAccelNamespace(*CUNode, Name, *IMDie);
+ }
+
// This is for imported module with renamed entities (such as variables and
// subprograms).
DINodeArray Elements = Module->getElements();
@@ -1305,9 +1369,24 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
return IMDie;
}
+DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE(
+ const DIImportedEntity *IE) {
+
+ // Check for pre-existence.
+ if (DIE *Die = getDIE(IE))
+ return Die;
+
+ DIE *ContextDIE = getOrCreateContextDIE(IE->getScope());
+ assert(ContextDIE && "Empty scope for the imported entity!");
+
+ DIE *IMDie = constructImportedEntityDIE(IE);
+ ContextDIE->addChild(IMDie);
+ return IMDie;
+}
+
void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
DIE *D = getDIE(SP);
- if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
+ if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {
if (D)
// If this subprogram has an abstract definition, reference that
addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
@@ -1356,8 +1435,8 @@ void DwarfCompileUnit::createAbstractEntity(const DINode *Node,
assert(Scope && Scope->isAbstractScope());
auto &Entity = getAbstractEntities()[Node];
if (isa<const DILocalVariable>(Node)) {
- Entity = std::make_unique<DbgVariable>(
- cast<const DILocalVariable>(Node), nullptr /* IA */);;
+ Entity = std::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),
+ nullptr /* IA */);
DU->addScopeVariable(Scope, cast<DbgVariable>(Entity.get()));
} else if (isa<const DILabel>(Node)) {
Entity = std::make_unique<DbgLabel>(
@@ -1389,6 +1468,8 @@ bool DwarfCompileUnit::hasDwarfPubSections() const {
// generated for things like Gold's gdb_index generation.
case DICompileUnit::DebugNameTableKind::GNU:
return true;
+ case DICompileUnit::DebugNameTableKind::Apple:
+ return false;
case DICompileUnit::DebugNameTableKind::Default:
return DD->tuneForGDB() && !includeMinimalInlineScopes() &&
!CUNode->isDebugDirectivesOnly() &&
@@ -1599,3 +1680,29 @@ void DwarfCompileUnit::createBaseTypeDIEs() {
Btr.Die = &Die;
}
}
+
+DIE *DwarfCompileUnit::getLexicalBlockDIE(const DILexicalBlock *LB) {
+ // Assume if there is an abstract tree all the DIEs are already emitted.
+ bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram());
+ if (isAbstract && getAbstractScopeDIEs().count(LB))
+ return getAbstractScopeDIEs()[LB];
+ assert(!isAbstract && "Missed lexical block DIE in abstract tree!");
+
+ // Return a concrete DIE if it exists or nullptr otherwise.
+ return LexicalBlockDIEs.lookup(LB);
+}
+
+DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) {
+ if (isa_and_nonnull<DILocalScope>(Context)) {
+ if (auto *LFScope = dyn_cast<DILexicalBlockFile>(Context))
+ Context = LFScope->getNonLexicalBlockFileScope();
+ if (auto *LScope = dyn_cast<DILexicalBlock>(Context))
+ return getLexicalBlockDIE(LScope);
+
+ // Otherwise the context must be a DISubprogram.
+ auto *SPScope = cast<DISubprogram>(Context);
+ if (getAbstractScopeDIEs().count(SPScope))
+ return getAbstractScopeDIEs()[SPScope];
+ }
+ return DwarfUnit::getOrCreateContextDIE(Context);
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 7d87f35021bb..6ef73ebd4f7f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -61,11 +61,6 @@ class DwarfCompileUnit final : public DwarfUnit {
/// The start of the unit macro info within macro section.
MCSymbol *MacroLabelBegin;
- using ImportedEntityList = SmallVector<const MDNode *, 8>;
- using ImportedEntityMap = DenseMap<const MDNode *, ImportedEntityList>;
-
- ImportedEntityMap ImportedEntities;
-
/// GlobalNames - A map of globally visible named entities for this unit.
StringMap<const DIE *> GlobalNames;
@@ -79,7 +74,20 @@ class DwarfCompileUnit final : public DwarfUnit {
// ranges/locs.
const MCSymbol *BaseAddress = nullptr;
- DenseMap<const MDNode *, DIE *> AbstractSPDies;
+ using MDNodeSetVector =
+ SetVector<const MDNode *, SmallVector<const MDNode *, 4>,
+ SmallPtrSet<const MDNode *, 4>>;
+
+ // List of entities (either static locals, types or imports) that
+ // belong to subprograms within this CU.
+ MDNodeSetVector DeferredLocalDecls;
+
+ // List of concrete lexical block scopes belong to subprograms within this CU.
+ DenseMap<const DILocalScope *, DIE *> LexicalBlockDIEs;
+
+ // List of abstract local scopes (either DISubprogram or DILexicalBlock).
+ DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
+
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
/// DWO ID for correlating skeleton and split units.
@@ -94,10 +102,10 @@ class DwarfCompileUnit final : public DwarfUnit {
bool isDwoUnit() const override;
- DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
+ DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
- return AbstractSPDies;
- return DU->getAbstractSPDies();
+ return AbstractLocalScopeDIEs;
+ return DU->getAbstractScopeDIEs();
}
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
@@ -108,6 +116,10 @@ class DwarfCompileUnit final : public DwarfUnit {
void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override;
+ /// Add info for Wasm-global-based relocation.
+ void addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
+ uint64_t GlobalIndex);
+
public:
DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU,
@@ -171,17 +183,6 @@ public:
unsigned getOrCreateSourceID(const DIFile *File) override;
- void addImportedEntity(const DIImportedEntity* IE) {
- DIScope *Scope = IE->getScope();
- assert(Scope && "Invalid Scope encoding!");
- if (!isa<DILocalScope>(Scope))
- // No need to add imported enities that are not local declaration.
- return;
-
- auto *LocalScope = cast<DILocalScope>(Scope)->getNonLexicalBlockFileScope();
- ImportedEntities[LocalScope].push_back(IE);
- }
-
/// addRange - Add an address range to the list of ranges for this unit.
void addRange(RangeSpan Range);
@@ -213,6 +214,11 @@ public:
/// attach DW_AT_low_pc/DW_AT_high_pc labels.
DIE *constructLexicalScopeDIE(LexicalScope *Scope);
+ /// Get a DIE for the given DILexicalBlock.
+ /// Note that this function assumes that the DIE has been already created
+ /// and it's an error, if it hasn't.
+ DIE *getLexicalBlockDIE(const DILexicalBlock *LB);
+
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);
@@ -224,6 +230,10 @@ public:
void createBaseTypeDIEs();
+ /// Construct a DIE for a given scope.
+ /// This instance of 'getOrCreateContextDIE()' can handle DILocalScope.
+ DIE *getOrCreateContextDIE(const DIScope *Ty) override;
+
/// Construct a DIE for this subprogram scope.
DIE &constructSubprogramScopeDIE(const DISubprogram *Sub,
LexicalScope *Scope);
@@ -262,8 +272,9 @@ public:
void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE,
SmallVector<DbgCallSiteParam, 4> &Params);
- /// Construct import_module DIE.
- DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
+ /// Get or create a DIE for an imported entity.
+ DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE);
+ DIE *constructImportedEntityDIE(const DIImportedEntity *IE);
void finishSubprogramDefinition(const DISubprogram *SP);
void finishEntityDefinition(const DbgEntity *Entity);
@@ -360,6 +371,8 @@ public:
bool hasDwarfPubSections() const;
void addBaseTypeRef(DIEValueList &Die, int64_t Idx);
+
+ MDNodeSetVector &getDeferredLocalDecls() { return DeferredLocalDecls; }
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index cde790cc77fb..1ae17ec9b874 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -18,7 +18,7 @@
#include "DwarfUnit.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DIE.h"
@@ -53,6 +53,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cstddef>
#include <iterator>
@@ -452,14 +453,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A)
// Split DWARF would benefit object size significantly by trading reductions
// in address pool usage for slightly increased range list encodings.
- if (DwarfVersion >= 5) {
+ if (DwarfVersion >= 5)
MinimizeAddr = MinimizeAddrInV5Option;
- // FIXME: In the future, enable this by default for Split DWARF where the
- // tradeoff is more pronounced due to being able to offload the range
- // lists to the dwo file and shrink object files/reduce relocations there.
- if (MinimizeAddr == MinimizeAddrInV5::Default)
- MinimizeAddr = MinimizeAddrInV5::Disabled;
- }
Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
Asm->OutStreamer->getContext().setDwarfFormat(Dwarf64 ? dwarf::DWARF64
@@ -500,6 +495,7 @@ static StringRef getObjCMethodName(StringRef In) {
void DwarfDebug::addSubprogramNames(const DICompileUnit &CU,
const DISubprogram *SP, DIE &Die) {
if (getAccelTableKind() != AccelTableKind::Apple &&
+ CU.getNameTableKind() != DICompileUnit::DebugNameTableKind::Apple &&
CU.getNameTableKind() == DICompileUnit::DebugNameTableKind::None)
return;
@@ -513,7 +509,7 @@ void DwarfDebug::addSubprogramNames(const DICompileUnit &CU,
// well into the name table. Only do that if we are going to actually emit
// that name.
if (SP->getLinkageName() != "" && SP->getName() != SP->getLinkageName() &&
- (useAllLinkageNames() || InfoHolder.getAbstractSPDies().lookup(SP)))
+ (useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(SP)))
addAccelName(CU, SP->getLinkageName(), Die);
// If this is an Objective-C selector name add it to the ObjC accelerator
@@ -710,13 +706,13 @@ static void interpretValues(const MachineInstr *CurMI,
if (MI.isDebugInstr())
return;
- for (const MachineOperand &MO : MI.operands()) {
- if (MO.isReg() && MO.isDef() && MO.getReg().isPhysical()) {
+ for (const MachineOperand &MO : MI.all_defs()) {
+ if (MO.getReg().isPhysical()) {
for (auto &FwdReg : ForwardedRegWorklist)
if (TRI.regsOverlap(FwdReg.first, MO.getReg()))
Defs.insert(FwdReg.first);
- for (MCRegUnitIterator Units(MO.getReg(), &TRI); Units.isValid(); ++Units)
- NewClobberedRegUnits.insert(*Units);
+ for (MCRegUnit Unit : TRI.regunits(MO.getReg()))
+ NewClobberedRegUnits.insert(Unit);
}
}
};
@@ -1050,11 +1046,11 @@ void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
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())
- NewCU.addStringOffsetsStart();
-
if (!useSplitDwarf()) {
+ // Add DW_str_offsets_base to the unit DIE, except for split units.
+ if (useSegmentedStringOffsetsTable())
+ NewCU.addStringOffsetsStart();
+
NewCU.initStmtList();
// If we're using split dwarf the compilation dir is going to be in the
@@ -1097,6 +1093,13 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
if (auto *CU = CUMap.lookup(DIUnit))
return *CU;
+ if (useSplitDwarf() &&
+ !shareAcrossDWOCUs() &&
+ (!DIUnit->getSplitDebugInlining() ||
+ DIUnit->getEmissionKind() == DICompileUnit::FullDebug) &&
+ !CUMap.empty()) {
+ return *CUMap.begin()->second;
+ }
CompilationDir = DIUnit->getDirectory();
auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
@@ -1104,9 +1107,6 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
DwarfCompileUnit &NewCU = *OwnedUnit;
InfoHolder.addUnit(std::move(OwnedUnit));
- for (auto *IE : DIUnit->getImportedEntities())
- NewCU.addImportedEntity(IE);
-
// LTO with assembly output shares a single line table amongst multiple CUs.
// To avoid the compilation directory being ambiguous, let the line table
// explicitly describe the directory of all files, never relying on the
@@ -1129,14 +1129,6 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
return NewCU;
}
-void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
- const DIImportedEntity *N) {
- if (isa<DILocalScope>(N->getScope()))
- return;
- if (DIE *D = TheCU.getOrCreateContextDIE(N->getScope()))
- D->addChild(TheCU.constructImportedEntityDIE(N));
-}
-
/// Sort and unique GVEs by comparing their fragment offset.
static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &
sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
@@ -1214,16 +1206,8 @@ void DwarfDebug::beginModule(Module *M) {
DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base"));
for (DICompileUnit *CUNode : M->debug_compile_units()) {
- // FIXME: Move local imported entities into a list attached to the
- // subprogram, then this search won't be needed and a
- // getImportedEntities().empty() test should go below with the rest.
- bool HasNonLocalImportedEntities = llvm::any_of(
- CUNode->getImportedEntities(), [](const DIImportedEntity *IE) {
- return !isa<DILocalScope>(IE->getScope());
- });
-
- if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() &&
- CUNode->getRetainedTypes().empty() &&
+ if (CUNode->getImportedEntities().empty() &&
+ CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
continue;
@@ -1257,10 +1241,6 @@ void DwarfDebug::beginModule(Module *M) {
// There is no point in force-emitting a forward declaration.
CU.getOrCreateTypeDIE(RT);
}
- // Emit imported_modules last so that the relevant context is already
- // available.
- for (auto *IE : CUNode->getImportedEntities())
- constructAndAddImportedEntityDIE(CU, IE);
}
}
@@ -1300,6 +1280,8 @@ void DwarfDebug::finalizeModuleInfo() {
if (CUMap.size() > 1)
DWOName = Asm->TM.Options.MCOptions.SplitDwarfFile;
+ bool HasEmittedSplitCU = false;
+
// Handle anything that needs to be done on a per-unit basis after
// all other generation.
for (const auto &P : CUMap) {
@@ -1318,6 +1300,10 @@ void DwarfDebug::finalizeModuleInfo() {
bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
if (HasSplitUnit) {
+ (void)HasEmittedSplitCU;
+ assert((shareAcrossDWOCUs() || !HasEmittedSplitCU) &&
+ "Multiple CUs emitted into a single dwo file");
+ HasEmittedSplitCU = true;
dwarf::Attribute attrDWOName = getDwarfVersion() >= 5
? dwarf::DW_AT_dwo_name
: dwarf::DW_AT_GNU_dwo_name;
@@ -1377,11 +1363,10 @@ void DwarfDebug::finalizeModuleInfo() {
if (U.hasRangeLists())
U.addRnglistsBase();
- if (!DebugLocs.getLists().empty()) {
- if (!useSplitDwarf())
- U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base,
- DebugLocs.getSym(),
- TLOF.getDwarfLoclistsSection()->getBeginSymbol());
+ if (!DebugLocs.getLists().empty() && !useSplitDwarf()) {
+ U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base,
+ DebugLocs.getSym(),
+ TLOF.getDwarfLoclistsSection()->getBeginSymbol());
}
}
@@ -1436,8 +1421,24 @@ void DwarfDebug::endModule() {
assert(CurMI == nullptr);
for (const auto &P : CUMap) {
- auto &CU = *P.second;
- CU.createBaseTypeDIEs();
+ const auto *CUNode = cast<DICompileUnit>(P.first);
+ DwarfCompileUnit *CU = &*P.second;
+
+ // Emit imported entities.
+ for (auto *IE : CUNode->getImportedEntities()) {
+ assert(!isa_and_nonnull<DILocalScope>(IE->getScope()) &&
+ "Unexpected function-local entity in 'imports' CU field.");
+ CU->getOrCreateImportedEntityDIE(IE);
+ }
+ for (const auto *D : CU->getDeferredLocalDecls()) {
+ if (auto *IE = dyn_cast<DIImportedEntity>(D))
+ CU->getOrCreateImportedEntityDIE(IE);
+ else
+ llvm_unreachable("Unexpected local retained node!");
+ }
+
+ // Emit base types.
+ CU->createBaseTypeDIEs();
}
// If we aren't actually generating debug info (check beginModule -
@@ -1511,16 +1512,6 @@ void DwarfDebug::endModule() {
// FIXME: AbstractVariables.clear();
}
-void DwarfDebug::ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
- const DINode *Node,
- const MDNode *ScopeNode) {
- if (CU.getExistingAbstractEntity(Node))
- return;
-
- CU.createAbstractEntity(Node, LScopes.getOrCreateAbstractScope(
- cast<DILocalScope>(ScopeNode)));
-}
-
void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
const DINode *Node, const MDNode *ScopeNode) {
if (CU.getExistingAbstractEntity(Node))
@@ -1531,6 +1522,21 @@ void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
CU.createAbstractEntity(Node, Scope);
}
+static const DILocalScope *getRetainedNodeScope(const MDNode *N) {
+ const DIScope *S;
+ if (const auto *LV = dyn_cast<DILocalVariable>(N))
+ S = LV->getScope();
+ else if (const auto *L = dyn_cast<DILabel>(N))
+ S = L->getScope();
+ else if (const auto *IE = dyn_cast<DIImportedEntity>(N))
+ S = IE->getScope();
+ else
+ llvm_unreachable("Unexpected retained node!");
+
+ // Ensure the scope is not a DILexicalBlockFile.
+ return cast<DILocalScope>(S)->getNonLexicalBlockFileScope();
+}
+
// Collect variable information from side table maintained by MF.
void DwarfDebug::collectVariableInfoFromMFTable(
DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) {
@@ -1556,13 +1562,24 @@ void DwarfDebug::collectVariableInfoFromMFTable(
ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
auto RegVar = std::make_unique<DbgVariable>(
cast<DILocalVariable>(Var.first), Var.second);
- RegVar->initializeMMI(VI.Expr, VI.Slot);
+ if (VI.inStackSlot())
+ RegVar->initializeMMI(VI.Expr, VI.getStackSlot());
+ else {
+ MachineLocation MLoc(VI.getEntryValueRegister(), /*IsIndirect*/ true);
+ auto LocEntry = DbgValueLocEntry(MLoc);
+ RegVar->initializeDbgValue(DbgValueLoc(VI.Expr, LocEntry));
+ }
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())) {
+ if (DbgVariable *DbgVar = MFVars.lookup(Var)) {
+ if (DbgVar->getValueLoc())
+ LLVM_DEBUG(dbgs() << "Dropping repeated entry value debug info for "
+ "variable "
+ << VI.Var->getName() << "\n");
+ else
+ DbgVar->addMMIEntry(*RegVar);
+ } else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
MFVars.insert({Var, RegVar.get()});
ConcreteEntities.push_back(std::move(RegVar));
}
@@ -1964,19 +1981,18 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
}
- // Collect info for variables/labels that were optimized out.
+ // Collect info for retained nodes.
for (const DINode *DN : SP->getRetainedNodes()) {
- if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
- continue;
- LexicalScope *Scope = nullptr;
- if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
- Scope = LScopes.findLexicalScope(DV->getScope());
- } else if (auto *DL = dyn_cast<DILabel>(DN)) {
- Scope = LScopes.findLexicalScope(DL->getScope());
+ const auto *LS = getRetainedNodeScope(DN);
+ if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
+ if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
+ continue;
+ LexicalScope *LexS = LScopes.findLexicalScope(LS);
+ if (LexS)
+ createConcreteEntity(TheCU, *LexS, DN, nullptr);
+ } else {
+ LocalDeclsPerLS[LS].insert(DN);
}
-
- if (Scope)
- createConcreteEntity(TheCU, *Scope, DN, nullptr);
}
}
@@ -2046,7 +2062,10 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
unsigned LastAsmLine =
Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
- if (DL == PrevInstLoc) {
+ bool PrevInstInSameSection =
+ (!PrevInstBB ||
+ PrevInstBB->getSectionIDNum() == MI->getParent()->getSectionIDNum());
+ if (DL == PrevInstLoc && PrevInstInSameSection) {
// If we have an ongoing unspecified location, nothing to do here.
if (!DL)
return;
@@ -2114,25 +2133,35 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
PrevInstLoc = DL;
}
-static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {
+static std::pair<DebugLoc, bool> findPrologueEndLoc(const MachineFunction *MF) {
// First known non-DBG_VALUE and non-frame setup location marks
// the beginning of the function body.
DebugLoc LineZeroLoc;
+ const Function &F = MF->getFunction();
+
+ // Some instructions may be inserted into prologue after this function. Must
+ // keep prologue for these cases.
+ bool IsEmptyPrologue =
+ !(F.hasPrologueData() || F.getMetadata(LLVMContext::MD_func_sanitize));
for (const auto &MBB : *MF) {
for (const auto &MI : MBB) {
- if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) &&
- MI.getDebugLoc()) {
- // Scan forward to try to find a non-zero line number. The prologue_end
- // marks the first breakpoint in the function after the frame setup, and
- // a compiler-generated line 0 location is not a meaningful breakpoint.
- // If none is found, return the first location after the frame setup.
- if (MI.getDebugLoc().getLine())
- return MI.getDebugLoc();
- LineZeroLoc = MI.getDebugLoc();
+ if (!MI.isMetaInstruction()) {
+ if (!MI.getFlag(MachineInstr::FrameSetup) && MI.getDebugLoc()) {
+ // Scan forward to try to find a non-zero line number. The
+ // prologue_end marks the first breakpoint in the function after the
+ // frame setup, and a compiler-generated line 0 location is not a
+ // meaningful breakpoint. If none is found, return the first
+ // location after the frame setup.
+ if (MI.getDebugLoc().getLine())
+ return std::make_pair(MI.getDebugLoc(), IsEmptyPrologue);
+
+ LineZeroLoc = MI.getDebugLoc();
+ }
+ IsEmptyPrologue = false;
}
}
}
- return LineZeroLoc;
+ return std::make_pair(LineZeroLoc, IsEmptyPrologue);
}
/// Register a source line with debug info. Returns the unique label that was
@@ -2159,8 +2188,16 @@ static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col,
DebugLoc DwarfDebug::emitInitialLocDirective(const MachineFunction &MF,
unsigned CUID) {
+ std::pair<DebugLoc, bool> PrologEnd = findPrologueEndLoc(&MF);
+ DebugLoc PrologEndLoc = PrologEnd.first;
+ bool IsEmptyPrologue = PrologEnd.second;
+
// Get beginning of function.
- if (DebugLoc PrologEndLoc = findPrologueEndLoc(&MF)) {
+ if (PrologEndLoc) {
+ // If the prolog is empty, no need to generate scope line for the proc.
+ if (IsEmptyPrologue)
+ return PrologEndLoc;
+
// Ensure the compile unit is created if the function is called before
// beginFunction().
(void)getOrCreateDwarfCompileUnit(
@@ -2239,7 +2276,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
assert(!FnScope || SP == FnScope->getScopeNode());
- DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit());
+ DwarfCompileUnit &TheCU = getOrCreateDwarfCompileUnit(SP->getUnit());
if (TheCU.getCUNode()->isDebugDirectivesOnly()) {
PrevLabel = nullptr;
CurFn = nullptr;
@@ -2260,6 +2297,9 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
if (!TheCU.getCUNode()->getDebugInfoForProfiling() &&
TheCU.getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly &&
LScopes.getAbstractScopesList().empty() && !IsDarwin) {
+ for (const auto &R : Asm->MBBSectionRanges)
+ addArangeLabel(SymbolCU(&TheCU, R.second.BeginLabel));
+
assert(InfoHolder.getScopeVariables().empty());
PrevLabel = nullptr;
CurFn = nullptr;
@@ -2267,27 +2307,28 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
}
#ifndef NDEBUG
- size_t NumAbstractScopes = LScopes.getAbstractScopesList().size();
+ size_t NumAbstractSubprograms = LScopes.getAbstractScopesList().size();
#endif
- // Construct abstract scopes.
for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
const auto *SP = cast<DISubprogram>(AScope->getScopeNode());
for (const DINode *DN : SP->getRetainedNodes()) {
- if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
- continue;
-
- const MDNode *Scope = nullptr;
- if (auto *DV = dyn_cast<DILocalVariable>(DN))
- Scope = DV->getScope();
- else if (auto *DL = dyn_cast<DILabel>(DN))
- Scope = DL->getScope();
- else
- llvm_unreachable("Unexpected DI type!");
-
- // Collect info for variables/labels that were optimized out.
- ensureAbstractEntityIsCreated(TheCU, DN, Scope);
- assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
- && "ensureAbstractEntityIsCreated inserted abstract scopes");
+ const auto *LS = getRetainedNodeScope(DN);
+ // Ensure LexicalScope is created for the scope of this node.
+ auto *LexS = LScopes.getOrCreateAbstractScope(LS);
+ assert(LexS && "Expected the LexicalScope to be created.");
+ if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
+ // Collect info for variables/labels that were optimized out.
+ if (!Processed.insert(InlinedEntity(DN, nullptr)).second ||
+ TheCU.getExistingAbstractEntity(DN))
+ continue;
+ TheCU.createAbstractEntity(DN, LexS);
+ } else {
+ // Remember the node if this is a local declarations.
+ LocalDeclsPerLS[LS].insert(DN);
+ }
+ assert(
+ LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
+ "getOrCreateAbstractScope() inserted an abstract subprogram scope");
}
constructAbstractSubprogramScopeDIE(TheCU, AScope);
}
@@ -2308,6 +2349,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
// can be used cross-function)
InfoHolder.getScopeVariables().clear();
InfoHolder.getScopeLabels().clear();
+ LocalDeclsPerLS.clear();
PrevLabel = nullptr;
CurFn = nullptr;
}
@@ -2507,10 +2549,13 @@ void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
Asm->emitDwarfLengthOrOffset(TheU->getLength());
// Emit the pubnames for this compilation unit.
- for (const auto &GI : Globals) {
- const char *Name = GI.getKeyData();
- const DIE *Entity = GI.second;
-
+ SmallVector<std::pair<StringRef, const DIE *>, 0> Vec;
+ for (const auto &GI : Globals)
+ Vec.emplace_back(GI.first(), GI.second);
+ llvm::sort(Vec, [](auto &A, auto &B) {
+ return A.second->getOffset() < B.second->getOffset();
+ });
+ for (const auto &[Name, Entity] : Vec) {
Asm->OutStreamer->AddComment("DIE offset");
Asm->emitDwarfLengthOrOffset(Entity->getOffset());
@@ -2523,7 +2568,7 @@ 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.data(), Name.size() + 1));
}
Asm->OutStreamer->AddComment("End Mark");
@@ -2566,11 +2611,10 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
for (const auto &Op : Expr) {
assert(Op.getCode() != dwarf::DW_OP_const_type &&
"3 operand ops not yet supported");
+ assert(!Op.getSubCode() && "SubOps not yet supported");
Streamer.emitInt8(Op.getCode(), Comment != End ? *(Comment++) : "");
Offset++;
- for (unsigned I = 0; I < 2; ++I) {
- if (Op.getDescription().Op[I] == Encoding::SizeNA)
- continue;
+ for (unsigned I = 0; I < Op.getDescription().Op.size(); ++I) {
if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) {
unsigned Length =
Streamer.emitDIERef(*CU->ExprRefedBaseTypes[Op.getRawOperand(I)].Die);
@@ -3495,10 +3539,11 @@ template <typename DataT>
void DwarfDebug::addAccelNameImpl(const DICompileUnit &CU,
AccelTable<DataT> &AppleAccel, StringRef Name,
const DIE &Die) {
- if (getAccelTableKind() == AccelTableKind::None)
+ if (getAccelTableKind() == AccelTableKind::None || Name.empty())
return;
if (getAccelTableKind() != AccelTableKind::Apple &&
+ CU.getNameTableKind() != DICompileUnit::DebugNameTableKind::Apple &&
CU.getNameTableKind() != DICompileUnit::DebugNameTableKind::Default)
return;
@@ -3555,11 +3600,9 @@ dwarf::Form DwarfDebug::getDwarfSectionOffsetForm() const {
}
const MCSymbol *DwarfDebug::getSectionLabel(const MCSection *S) {
- auto I = SectionLabels.find(S);
- if (I == SectionLabels.end())
- return nullptr;
- return I->second;
+ return SectionLabels.lookup(S);
}
+
void DwarfDebug::insertSectionLabel(const MCSymbol *S) {
if (SectionLabels.insert(std::make_pair(&S->getSection(), S)).second)
if (useSplitDwarf() || getDwarfVersion() >= 5)
@@ -3583,3 +3626,13 @@ DwarfDebug::getMD5AsBytes(const DIFile *File) const {
std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.data());
return CKMem;
}
+
+bool DwarfDebug::alwaysUseRanges(const DwarfCompileUnit &CU) const {
+ if (MinimizeAddr == MinimizeAddrInV5::Ranges)
+ return true;
+ if (MinimizeAddr != MinimizeAddrInV5::Default)
+ return false;
+ if (useSplitDwarf())
+ return true;
+ return false;
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 5d2ef8ee79a7..1af4b643eb17 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -318,9 +318,14 @@ class DwarfDebug : public DebugHandlerBase {
/// This is a collection of subprogram MDNodes that are processed to
/// create DIEs.
- SetVector<const DISubprogram *, SmallVector<const DISubprogram *, 16>,
- SmallPtrSet<const DISubprogram *, 16>>
- ProcessedSPNodes;
+ SmallSetVector<const DISubprogram *, 16> ProcessedSPNodes;
+
+ /// Map function-local imported entities to their parent local scope
+ /// (either DILexicalBlock or DISubprogram) for a processed function
+ /// (including inlined subprograms).
+ using MDNodeSet = SetVector<const MDNode *, SmallVector<const MDNode *, 2>,
+ SmallPtrSet<const MDNode *, 2>>;
+ DenseMap<const DILocalScope *, MDNodeSet> LocalDeclsPerLS;
/// If nonnull, stores the current machine function we're processing.
const MachineFunction *CurFn = nullptr;
@@ -456,9 +461,6 @@ private:
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
- void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
- const DINode *Node,
- const MDNode *Scope);
void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
const DINode *Node,
const MDNode *Scope);
@@ -598,10 +600,6 @@ private:
void finishUnitAttributes(const DICompileUnit *DIUnit,
DwarfCompileUnit &NewCU);
- /// Construct imported_module or imported_declaration DIE.
- void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
- const DIImportedEntity *N);
-
/// Register a source line with debug info. Returns the unique
/// label that was emitted and which provides correspondence to the
/// source line list.
@@ -696,9 +694,7 @@ public:
/// Returns whether range encodings should be used for single entry range
/// lists.
- bool alwaysUseRanges() const {
- return MinimizeAddr == MinimizeAddrInV5::Ranges;
- }
+ bool alwaysUseRanges(const DwarfCompileUnit &) const;
// Returns whether novel exprloc addrx+offset encodings should be used to
// reduce debug_addr size.
@@ -842,6 +838,10 @@ public:
/// If the \p File has an MD5 checksum, return it as an MD5Result
/// allocated in the MCContext.
std::optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const;
+
+ MDNodeSet &getLocalDeclsForScope(const DILocalScope *S) {
+ return LocalDeclsPerLS[S];
+ }
};
} // end namespace llvm
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index ab6967f50e30..7623b7fb7c5d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -117,10 +117,10 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// Walk up the super-register chain until we find a valid number.
// For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
- for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
- Reg = TRI.getDwarfRegNum(*SR, false);
+ for (MCPhysReg SR : TRI.superregs(MachineReg)) {
+ Reg = TRI.getDwarfRegNum(SR, false);
if (Reg >= 0) {
- unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
+ unsigned Idx = TRI.getSubRegIndex(SR, MachineReg);
unsigned Size = TRI.getSubRegIdxSize(Idx);
unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
DwarfRegs.push_back(Register::createRegister(Reg, "super-register"));
@@ -142,11 +142,11 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// this doesn't find a combination of subregisters that fully cover
// the register (even though one may exist).
SmallBitVector Coverage(RegSize, false);
- for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
- unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
+ for (MCPhysReg SR : TRI.subregs(MachineReg)) {
+ unsigned Idx = TRI.getSubRegIndex(MachineReg, SR);
unsigned Size = TRI.getSubRegIdxSize(Idx);
unsigned Offset = TRI.getSubRegIdxOffset(Idx);
- Reg = TRI.getDwarfRegNum(*SR, false);
+ Reg = TRI.getDwarfRegNum(SR, false);
if (Reg < 0)
continue;
@@ -566,6 +566,12 @@ bool DwarfExpression::addExpression(
case dwarf::DW_OP_dup:
case dwarf::DW_OP_push_object_address:
case dwarf::DW_OP_over:
+ case dwarf::DW_OP_eq:
+ case dwarf::DW_OP_ne:
+ case dwarf::DW_OP_gt:
+ case dwarf::DW_OP_ge:
+ case dwarf::DW_OP_lt:
+ case dwarf::DW_OP_le:
emitOp(OpNum);
break;
case dwarf::DW_OP_deref:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
index 79a6ce7801b7..464f4f048016 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h
@@ -26,6 +26,7 @@ class DbgEntity;
class DbgVariable;
class DbgLabel;
class DINode;
+class DILocalScope;
class DwarfCompileUnit;
class DwarfUnit;
class LexicalScope;
@@ -87,7 +88,7 @@ class DwarfFile {
DenseMap<LexicalScope *, LabelList> ScopeLabels;
// Collection of abstract subprogram DIEs.
- DenseMap<const MDNode *, DIE *> AbstractSPDies;
+ DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
/// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
@@ -162,8 +163,8 @@ public:
return ScopeLabels;
}
- DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
- return AbstractSPDies;
+ DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
+ return AbstractLocalScopeDIEs;
}
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index c2ff899c04ab..d30f0ef7af34 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -543,7 +543,7 @@ void DwarfUnit::addAccess(DIE &Die, DINode::DIFlags Flags) {
}
DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {
- if (!Context || isa<DIFile>(Context))
+ if (!Context || isa<DIFile>(Context) || isa<DICompileUnit>(Context))
return &getUnitDie();
if (auto *T = dyn_cast<DIType>(Context))
return getOrCreateTypeDIE(T);
@@ -1223,7 +1223,7 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
"decl has a linkage name and it is different");
if (DeclLinkageName.empty() &&
// Always emit it for abstract subprograms.
- (DD->useAllLinkageNames() || DU->getAbstractSPDies().lookup(SP)))
+ (DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP)))
addLinkageName(SPDie, LinkageName);
if (!DeclDie)
@@ -1362,16 +1362,16 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,
DISubrange::BoundType Bound) -> void {
- if (auto *BV = Bound.dyn_cast<DIVariable *>()) {
+ if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {
if (auto *VarDIE = getDIE(BV))
addDIEEntry(DW_Subrange, Attr, *VarDIE);
- } else if (auto *BE = Bound.dyn_cast<DIExpression *>()) {
+ } else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {
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 *>()) {
+ } else if (auto *BI = dyn_cast_if_present<ConstantInt *>(Bound)) {
if (Attr == dwarf::DW_AT_count) {
if (BI->getSExtValue() != -1)
addUInt(DW_Subrange, Attr, std::nullopt, BI->getSExtValue());
@@ -1401,10 +1401,10 @@ void DwarfUnit::constructGenericSubrangeDIE(DIE &Buffer,
auto AddBoundTypeEntry = [&](dwarf::Attribute Attr,
DIGenericSubrange::BoundType Bound) -> void {
- if (auto *BV = Bound.dyn_cast<DIVariable *>()) {
+ if (auto *BV = dyn_cast_if_present<DIVariable *>(Bound)) {
if (auto *VarDIE = getDIE(BV))
addDIEEntry(DwGenericSubrange, Attr, *VarDIE);
- } else if (auto *BE = Bound.dyn_cast<DIExpression *>()) {
+ } else if (auto *BE = dyn_cast_if_present<DIExpression *>(Bound)) {
if (BE->isConstant() &&
DIExpression::SignedOrUnsignedConstant::SignedConstant ==
*BE->isConstant()) {
@@ -1463,7 +1463,7 @@ static bool hasVectorBeenPadded(const DICompositeType *CTy) {
const auto Subrange = cast<DISubrange>(Elements[0]);
const auto NumVecElements =
Subrange->getCount()
- ? Subrange->getCount().get<ConstantInt *>()->getSExtValue()
+ ? cast<ConstantInt *>(Subrange->getCount())->getSExtValue()
: 0;
// Ensure we found the element count and that the actual size is wide
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 0caa6adbfa62..8f17e94c2d1c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -245,10 +245,10 @@ public:
DIE *createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty);
/// Find existing DIE or create new DIE for the given type.
- DIE *getOrCreateTypeDIE(const MDNode *TyNode);
+ virtual DIE *getOrCreateTypeDIE(const MDNode *TyNode);
/// Get context owner's DIE.
- DIE *getOrCreateContextDIE(const DIScope *Context);
+ virtual DIE *getOrCreateContextDIE(const DIScope *Context);
/// Construct DIEs for types that contain vtables.
void constructContainingTypeDIEs();
diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index 67e2c0e07095..eef6b1d93f36 100644
--- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -410,7 +410,7 @@ MCSymbol *EHStreamer::emitExceptionTable() {
computeActionsTable(LandingPads, Actions, FirstActions);
// Compute the call-site table and call-site ranges. Normally, there is only
- // one call-site-range which covers the whole funciton. With
+ // one call-site-range which covers the whole function. With
// -basic-block-sections, there is one call-site-range per basic block
// section.
SmallVector<CallSiteEntry, 64> CallSites;
diff --git a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
index 3e75b4371033..59c3fa15885e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/PseudoProbePrinter.cpp
@@ -32,11 +32,7 @@ void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
SmallVector<InlineSite, 8> ReversedInlineStack;
auto *InlinedAt = DebugLoc ? DebugLoc->getInlinedAt() : nullptr;
while (InlinedAt) {
- const DISubprogram *SP = InlinedAt->getScope()->getSubprogram();
- // Use linkage name for C++ if possible.
- auto Name = SP->getLinkageName();
- if (Name.empty())
- Name = SP->getName();
+ auto Name = InlinedAt->getSubprogramLinkageName();
// Use caching to avoid redundant md5 computation for build speed.
uint64_t &CallerGuid = NameGuidMap[Name];
if (!CallerGuid)
@@ -46,8 +42,15 @@ void PseudoProbeHandler::emitPseudoProbe(uint64_t Guid, uint64_t Index,
ReversedInlineStack.emplace_back(CallerGuid, CallerProbeId);
InlinedAt = InlinedAt->getInlinedAt();
}
-
+ uint64_t Discriminator = 0;
+ // For now only block probes have FS discriminators. See
+ // MIRFSDiscriminator.cpp for more details.
+ if (EnableFSDiscriminator && DebugLoc &&
+ (Type == (uint64_t)PseudoProbeType::Block))
+ Discriminator = DebugLoc->getDiscriminator();
+ assert((EnableFSDiscriminator || Discriminator == 0) &&
+ "Discriminator should not be set in non-FSAFDO mode");
SmallVector<InlineSite, 8> InlineStack(llvm::reverse(ReversedInlineStack));
- Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, InlineStack,
- Asm->CurrentFnSym);
+ Asm->OutStreamer->emitPseudoProbe(Guid, Index, Type, Attr, Discriminator,
+ InlineStack, Asm->CurrentFnSym);
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 7a800438592c..6d6432b61f2d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -638,7 +638,7 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
const MCExpr *FilterOrFinally;
const MCExpr *ExceptOrNull;
- auto *Handler = UME.Handler.get<MachineBasicBlock *>();
+ auto *Handler = cast<MachineBasicBlock *>(UME.Handler);
if (UME.IsFinally) {
FilterOrFinally = create32bitRef(getMCSymbolForMBB(Asm, Handler));
ExceptOrNull = MCConstantExpr::create(0, Ctx);
@@ -762,7 +762,11 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
OS.emitInt32(0);
AddComment("EHFlags");
- OS.emitInt32(1);
+ if (MMI->getModule()->getModuleFlag("eh-asynch")) {
+ OS.emitInt32(0);
+ } else {
+ OS.emitInt32(1);
+ }
// UnwindMapEntry {
// int32_t ToState;
@@ -771,8 +775,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
if (UnwindMapXData) {
OS.emitLabel(UnwindMapXData);
for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {
- MCSymbol *CleanupSym =
- getMCSymbolForMBB(Asm, UME.Cleanup.dyn_cast<MachineBasicBlock *>());
+ MCSymbol *CleanupSym = getMCSymbolForMBB(
+ Asm, dyn_cast_if_present<MachineBasicBlock *>(UME.Cleanup));
AddComment("ToState");
OS.emitInt32(UME.ToState);
@@ -859,8 +863,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);
}
- MCSymbol *HandlerSym =
- getMCSymbolForMBB(Asm, HT.Handler.dyn_cast<MachineBasicBlock *>());
+ MCSymbol *HandlerSym = getMCSymbolForMBB(
+ Asm, dyn_cast_if_present<MachineBasicBlock *>(HT.Handler));
AddComment("Adjectives");
OS.emitInt32(HT.Adjectives);
@@ -1065,7 +1069,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
assert(!FuncInfo.SEHUnwindMap.empty());
for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
- auto *Handler = UME.Handler.get<MachineBasicBlock *>();
+ auto *Handler = cast<MachineBasicBlock *>(UME.Handler);
const MCSymbol *ExceptOrFinally =
UME.IsFinally ? getMCSymbolForMBB(Asm, Handler) : Handler->getSymbol();
// -1 is usually the base state for "unwind to caller", but for
@@ -1136,7 +1140,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
DenseMap<const MachineBasicBlock *, int> HandlerStates;
for (int State = 0; State < NumStates; ++State) {
MachineBasicBlock *HandlerBlock =
- FuncInfo.ClrEHUnwindMap[State].Handler.get<MachineBasicBlock *>();
+ cast<MachineBasicBlock *>(FuncInfo.ClrEHUnwindMap[State].Handler);
HandlerStates[HandlerBlock] = State;
// Use this loop through all handlers to verify our assumption (used in
// the MinEnclosingState computation) that enclosing funclets have lower
@@ -1297,7 +1301,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
- MachineBasicBlock *HandlerBlock = Entry.Handler.get<MachineBasicBlock *>();
+ MachineBasicBlock *HandlerBlock = cast<MachineBasicBlock *>(Entry.Handler);
MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock);
const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
MCSymbol *EndSym = EndSymbolMap[Clause.State];