diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/AsmPrinter')
33 files changed, 1365 insertions, 897 deletions
diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp index 8b1376ab363d..15cfbd5c40ff 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -12,26 +12,19 @@ //===----------------------------------------------------------------------===// #include "DwarfException.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" -#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {} @@ -67,16 +60,16 @@ void ARMException::beginFunction(const MachineFunction *MF) { /// void ARMException::endFunction(const MachineFunction *MF) { ARMTargetStreamer &ATS = getTargetStreamer(); - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); const Function *Per = nullptr; - if (F->hasPersonalityFn()) - Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); + if (F.hasPersonalityFn()) + Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); bool forceEmitPersonality = - F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) && - F->needsUnwindTableEntry(); + F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) && + F.needsUnwindTableEntry(); bool shouldEmitPersonality = forceEmitPersonality || !MF->getLandingPads().empty(); - if (!Asm->MF->getFunction()->needsUnwindTableEntry() && + if (!Asm->MF->getFunction().needsUnwindTableEntry() && !shouldEmitPersonality) ATS.emitCantUnwind(); else if (shouldEmitPersonality) { diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp index ec552e0640e9..59ed0324bdb0 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---*- C++ -*--===// +//===- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---------------===// // // The LLVM Compiler Infrastructure // @@ -8,9 +8,12 @@ //===----------------------------------------------------------------------===// #include "AddressPool.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/IR/DataLayout.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/Target/TargetLoweringObjectFile.h" +#include <utility> using namespace llvm; diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h index ba3e3b7c315d..990a158d87cd 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AddressPool.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/AddressPool.h - Dwarf Debug Framework -----*- C++ -*--===// +//===- llvm/CodeGen/AddressPool.h - Dwarf Debug Framework -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,11 +11,13 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_ADDRESSPOOL_H #include "llvm/ADT/DenseMap.h" -#include "llvm/MC/MCSymbol.h" namespace llvm { -class MCSection; + class AsmPrinter; +class MCSection; +class MCSymbol; + // Collection of addresses for this unit and assorted labels. // A Symbol->unsigned mapping of addresses used by indirect // references. @@ -23,6 +25,7 @@ class AddressPool { struct AddressPoolEntry { unsigned Number; bool TLS; + AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {} }; DenseMap<const MCSymbol *, AddressPoolEntry> Pool; @@ -31,10 +34,10 @@ class AddressPool { /// the last "resetUsedFlag" call. Used to implement type unit fallback - a /// type that references addresses cannot be placed in a type unit when using /// fission. - bool HasBeenUsed; + bool HasBeenUsed = false; public: - AddressPool() : HasBeenUsed(false) {} + AddressPool() = default; /// \brief Returns the index into the address pool with the given /// label/symbol. @@ -48,5 +51,7 @@ public: void resetUsedFlag() { HasBeenUsed = false; } }; -} -#endif + +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_ADDRESSPOOL_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index ff427c9a0d75..31037095aa2b 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1,4 +1,4 @@ -//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===// +//===- AsmPrinter.cpp - Common AsmPrinter code ----------------------------===// // // The LLVM Compiler Infrastructure // @@ -29,10 +29,11 @@ #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/ObjectUtils.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/BinaryFormat/ELF.h" -#include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/GCMetadata.h" #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/CodeGen/GCStrategy.h" @@ -46,10 +47,19 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" +#include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Comdat.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -62,14 +72,18 @@ #include "llvm/IR/GlobalObject.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCCodePadder.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSection.h" @@ -78,29 +92,28 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/SectionKind.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/Path.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Target/TargetOptions.h" #include <algorithm> #include <cassert> #include <cinttypes> #include <cstdint> +#include <iterator> #include <limits> #include <memory> #include <string> @@ -129,7 +142,8 @@ static cl::opt<bool> char AsmPrinter::ID = 0; -typedef DenseMap<GCStrategy*, std::unique_ptr<GCMetadataPrinter>> gcp_map_type; +using gcp_map_type = DenseMap<GCStrategy *, std::unique_ptr<GCMetadataPrinter>>; + static gcp_map_type &getGCMap(void *&P) { if (!P) P = new gcp_map_type(); @@ -184,7 +198,6 @@ bool AsmPrinter::isPositionIndependent() const { } /// getFunctionNumber - Return a unique ID for the current function. -/// unsigned AsmPrinter::getFunctionNumber() const { return MF->getFunctionNumber(); } @@ -221,8 +234,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<MachineModuleInfo>(); AU.addRequired<MachineOptimizationRemarkEmitterPass>(); AU.addRequired<GCModuleInfo>(); - if (isVerbose()) - AU.addRequired<MachineLoopInfo>(); + AU.addRequired<MachineLoopInfo>(); } bool AsmPrinter::doInitialization(Module &M) { @@ -242,28 +254,8 @@ bool AsmPrinter::doInitialization(Module &M) { // alternative is duplicated code in each of the target asm printers that // use the directive, where it would need the same conditionalization // anyway. - const Triple &TT = TM.getTargetTriple(); - // If there is a version specified, Major will be non-zero. - if (TT.isOSDarwin() && TT.getOSMajorVersion() != 0) { - unsigned Major, Minor, Update; - MCVersionMinType VersionType; - if (TT.isWatchOS()) { - VersionType = MCVM_WatchOSVersionMin; - TT.getWatchOSVersion(Major, Minor, Update); - } else if (TT.isTvOS()) { - VersionType = MCVM_TvOSVersionMin; - TT.getiOSVersion(Major, Minor, Update); - } else if (TT.isMacOSX()) { - VersionType = MCVM_OSXVersionMin; - if (!TT.getMacOSXVersion(Major, Minor, Update)) - Major = 0; - } else { - VersionType = MCVM_IOSVersionMin; - TT.getiOSVersion(Major, Minor, Update); - } - if (Major != 0) - OutStreamer->EmitVersionMin(VersionType, Major, Minor, Update); - } + const Triple &Target = TM.getTargetTriple(); + OutStreamer->EmitVersionForTarget(Target); // Allow the target to emit any magic that it wants at the start of the file. EmitStartOfAsmFile(M); @@ -272,7 +264,8 @@ bool AsmPrinter::doInitialization(Module &M) { // don't, this at least helps the user find where a global came from. if (MAI->hasSingleParameterDotFile()) { // .file "foo.c" - OutStreamer->EmitFileDirective(M.getSourceFileName()); + OutStreamer->EmitFileDirective( + llvm::sys::path::filename(M.getSourceFileName())); } GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); @@ -628,35 +621,35 @@ void AsmPrinter::EmitDebugThreadLocal(const MCExpr *Value, /// EmitFunctionHeader - This method emits the header for the current /// function. void AsmPrinter::EmitFunctionHeader() { - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); if (isVerbose()) OutStreamer->GetCommentOS() << "-- Begin function " - << GlobalValue::dropLLVMManglingEscape(F->getName()) << '\n'; + << GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n'; // Print out constants referenced by the function EmitConstantPool(); // Print the 'header' of function. - OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(F, TM)); - EmitVisibility(CurrentFnSym, F->getVisibility()); + OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(&F, TM)); + EmitVisibility(CurrentFnSym, F.getVisibility()); - EmitLinkage(F, CurrentFnSym); + EmitLinkage(&F, CurrentFnSym); if (MAI->hasFunctionAlignment()) - EmitAlignment(MF->getAlignment(), F); + EmitAlignment(MF->getAlignment(), &F); if (MAI->hasDotTypeDotSizeDirective()) OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); if (isVerbose()) { - F->printAsOperand(OutStreamer->GetCommentOS(), - /*PrintType=*/false, F->getParent()); + F.printAsOperand(OutStreamer->GetCommentOS(), + /*PrintType=*/false, F.getParent()); OutStreamer->GetCommentOS() << '\n'; } // Emit the prefix data. - if (F->hasPrefixData()) { + if (F.hasPrefixData()) { if (MAI->hasSubsectionsViaSymbols()) { // Preserving prefix data on platforms which use subsections-via-symbols // is a bit tricky. Here we introduce a symbol for the prefix data @@ -665,12 +658,12 @@ void AsmPrinter::EmitFunctionHeader() { MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol(); OutStreamer->EmitLabel(PrefixSym); - EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData()); + EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData()); // Emit an .alt_entry directive for the actual function symbol. OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_AltEntry); } else { - EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData()); + EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData()); } } @@ -682,7 +675,7 @@ void AsmPrinter::EmitFunctionHeader() { // references to the dangling symbols. Emit them at the start of the function // so that we don't get references to undefined symbols. std::vector<MCSymbol*> DeadBlockSyms; - MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms); + MMI->takeDeletedSymbolsForFunction(&F, DeadBlockSyms); for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) { OutStreamer->AddComment("Address taken block that was later removed"); OutStreamer->EmitLabel(DeadBlockSyms[i]); @@ -707,8 +700,8 @@ void AsmPrinter::EmitFunctionHeader() { } // Emit the prologue data. - if (F->hasPrologueData()) - EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrologueData()); + if (F.hasPrologueData()) + EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData()); } /// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the @@ -729,9 +722,11 @@ void AsmPrinter::EmitFunctionEntryLabel() { } /// emitComments - Pretty-print comments for instructions. -static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS, +/// It returns true iff the sched comment was emitted. +/// Otherwise it returns false. +static bool emitComments(const MachineInstr &MI, raw_ostream &CommentOS, AsmPrinter *AP) { - const MachineFunction *MF = MI.getParent()->getParent(); + const MachineFunction *MF = MI.getMF(); const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); // Check for spills and reloads @@ -773,12 +768,16 @@ static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS, CommentOS << " Reload Reuse"; } - if (Commented && AP->EnablePrintSchedInfo) - // If any comment was added above and we need sched info comment then - // add this new comment just after the above comment w/o "\n" between them. - CommentOS << " " << MF->getSubtarget().getSchedInfoStr(MI) << "\n"; - else if (Commented) + if (Commented) { + if (AP->EnablePrintSchedInfo) { + // If any comment was added above and we need sched info comment then add + // this new comment just after the above comment w/o "\n" between them. + CommentOS << " " << MF->getSubtarget().getSchedInfoStr(MI) << "\n"; + return true; + } CommentOS << "\n"; + } + return false; } /// emitImplicitDef - This method emits the specified machine instruction @@ -789,7 +788,7 @@ void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const { SmallString<128> Str; raw_svector_ostream OS(Str); OS << "implicit-def: " - << PrintReg(RegNo, MF->getSubtarget().getRegisterInfo()); + << printReg(RegNo, MF->getSubtarget().getRegisterInfo()); OutStreamer->AddComment(OS.str()); OutStreamer->AddBlankLine(); @@ -802,10 +801,8 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &Op = MI->getOperand(i); assert(Op.isReg() && "KILL instruction must have only register operands"); - OS << ' ' - << PrintReg(Op.getReg(), - AP.MF->getSubtarget().getRegisterInfo()) - << (Op.isDef() ? "<def>" : "<kill>"); + OS << ' ' << (Op.isDef() ? "def " : "killed ") + << printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo()); } AP.OutStreamer->AddComment(OS.str()); AP.OutStreamer->AddBlankLine(); @@ -890,7 +887,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { } if (MemLoc) OS << '['; - OS << PrintReg(Reg, AP.MF->getSubtarget().getRegisterInfo()); + OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo()); } if (MemLoc) @@ -901,9 +898,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { return true; } -AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() { +AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() const { if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && - MF->getFunction()->needsUnwindTableEntry()) + MF->getFunction().needsUnwindTableEntry()) return CFI_M_EH; if (MMI->hasDebugInfo()) @@ -913,7 +910,7 @@ AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() { } bool AsmPrinter::needsSEHMoves() { - return MAI->usesWindowsCFI() && MF->getFunction()->needsUnwindTableEntry(); + return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry(); } void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) { @@ -951,6 +948,31 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) { MCConstantExpr::create(FrameOffset, OutContext)); } +void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) { + if (!MF.getTarget().Options.EmitStackSizeSection) + return; + + MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection(); + if (!StackSizeSection) + return; + + const MachineFrameInfo &FrameInfo = MF.getFrameInfo(); + // Don't emit functions with dynamic stack allocations. + if (FrameInfo.hasVarSizedObjects()) + return; + + OutStreamer->PushSection(); + OutStreamer->SwitchSection(StackSizeSection); + + const MCSymbol *FunctionSymbol = getSymbol(&MF.getFunction()); + uint64_t StackSize = FrameInfo.getStackSize(); + OutStreamer->EmitValue(MCSymbolRefExpr::create(FunctionSymbol, OutContext), + /* size = */ 8); + OutStreamer->EmitULEB128IntValue(StackSize); + + OutStreamer->PopSection(); +} + static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF, MachineModuleInfo *MMI) { if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo()) @@ -958,10 +980,10 @@ static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF, // We might emit an EH table that uses function begin and end labels even if // we don't have any landingpads. - if (!MF.getFunction()->hasPersonalityFn()) + if (!MF.getFunction().hasPersonalityFn()) return false; return !isNoOpWithoutInvoke( - classifyEHPersonality(MF.getFunction()->getPersonalityFn())); + classifyEHPersonality(MF.getFunction().getPersonalityFn())); } /// EmitFunctionBody - This method emits the body and trailer for a @@ -981,7 +1003,6 @@ void AsmPrinter::EmitFunctionBody() { // Print a label for the basic block. EmitBasicBlockStart(MBB); for (auto &MI : MBB) { - // Print the assembly for the instruction. if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() && !MI.isDebugValue()) { @@ -998,18 +1019,18 @@ void AsmPrinter::EmitFunctionBody() { } } - if (isVerbose()) - emitComments(MI, OutStreamer->GetCommentOS(), this); + if (isVerbose() && emitComments(MI, OutStreamer->GetCommentOS(), this)) { + MachineInstr *MIP = const_cast<MachineInstr *>(&MI); + MIP->setAsmPrinterFlag(MachineInstr::NoSchedComment); + } switch (MI.getOpcode()) { case TargetOpcode::CFI_INSTRUCTION: emitCFIInstruction(MI); break; - case TargetOpcode::LOCAL_ESCAPE: emitFrameAlloc(MI); break; - case TargetOpcode::EH_LABEL: case TargetOpcode::GC_LABEL: OutStreamer->EmitLabel(MI.getOperand(0).getMCSymbol()); @@ -1049,7 +1070,7 @@ void AsmPrinter::EmitFunctionBody() { EmittedInsts += NumInstsInFunction; MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionCount", - MF->getFunction()->getSubprogram(), + MF->getFunction().getSubprogram(), &MF->front()); R << ore::NV("NumInstructions", NumInstsInFunction) << " instructions in function"; @@ -1077,8 +1098,8 @@ void AsmPrinter::EmitFunctionBody() { } } - const Function *F = MF->getFunction(); - for (const auto &BB : *F) { + const Function &F = MF->getFunction(); + for (const auto &BB : F) { if (!BB.hasAddressTaken()) continue; MCSymbol *Sym = GetBlockAddressSymbol(&BB); @@ -1125,6 +1146,9 @@ void AsmPrinter::EmitFunctionBody() { HI.Handler->endFunction(MF); } + // Emit section containing stack size metadata. + emitStackSizeSection(*MF); + if (isVerbose()) OutStreamer->GetCommentOS() << "-- End function\n"; @@ -1380,6 +1404,16 @@ bool AsmPrinter::doFinalization(Module &M) { PtrSize); } + // Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if + // split-stack is used. + if (TM.getTargetTriple().isOSBinFormatELF() && MMI->hasSplitStack()) { + OutStreamer->SwitchSection( + OutContext.getELFSection(".note.GNU-split-stack", ELF::SHT_PROGBITS, 0)); + if (MMI->hasNosplitStack()) + OutStreamer->SwitchSection( + OutContext.getELFSection(".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0)); + } + // If we don't have any trampolines, then we don't require stack memory // to be executable. Some targets have a directive to declare this. Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); @@ -1408,7 +1442,7 @@ MCSymbol *AsmPrinter::getCurExceptionSym() { void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { this->MF = &MF; // Get the function symbol. - CurrentFnSym = getSymbol(MF.getFunction()); + CurrentFnSym = getSymbol(&MF.getFunction()); CurrentFnSymForSize = CurrentFnSym; CurrentFnBegin = nullptr; CurExceptionSym = nullptr; @@ -1420,8 +1454,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { } ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE(); - if (isVerbose()) - LI = &getAnalysis<MachineLoopInfo>(); + LI = &getAnalysis<MachineLoopInfo>(); const TargetSubtargetInfo &STI = MF.getSubtarget(); EnablePrintSchedInfo = PrintSchedule.getNumOccurrences() @@ -1446,7 +1479,6 @@ namespace { /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by /// the code generator. -/// void AsmPrinter::EmitConstantPool() { const MachineConstantPool *MCP = MF->getConstantPool(); const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); @@ -1526,7 +1558,6 @@ void AsmPrinter::EmitConstantPool() { /// EmitJumpTableInfo - Print assembly representations of the jump tables used /// by the current function to the current output stream. -/// void AsmPrinter::EmitJumpTableInfo() { const DataLayout &DL = MF->getDataLayout(); const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); @@ -1537,14 +1568,14 @@ void AsmPrinter::EmitJumpTableInfo() { // Pick the directive to use to print the jump table entries, and switch to // the appropriate section. - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); const TargetLoweringObjectFile &TLOF = getObjFileLowering(); bool JTInDiffSection = !TLOF.shouldPutJumpTableInFunctionSection( MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32, - *F); + F); if (JTInDiffSection) { // Drop it in the readonly section. - MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(*F, TM); + MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM); OutStreamer->SwitchSection(ReadOnlySection); } @@ -1723,7 +1754,7 @@ struct Structor { Structor() = default; }; -} // end anonymous namespace +} // end anonymous namespace /// EmitXXStructorList - Emit the ctor or dtor list taking into account the init /// priority. @@ -1818,13 +1849,11 @@ void AsmPrinter::EmitInt8(int Value) const { } /// EmitInt16 - Emit a short directive and value. -/// void AsmPrinter::EmitInt16(int Value) const { OutStreamer->EmitIntValue(Value, 2); } /// EmitInt32 - Emit a long directive and value. -/// void AsmPrinter::EmitInt32(int Value) const { OutStreamer->EmitIntValue(Value, 4); } @@ -1866,7 +1895,6 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, // byte alignment. If a global value is specified, and if that global has // an explicit alignment requested, it will override the alignment request // if required for correctness. -// void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalObject *GV) const { if (GV) NumBits = getGVAlignmentLog2(GV, GV->getParent()->getDataLayout(), NumBits); @@ -1921,7 +1949,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { raw_string_ostream OS(S); OS << "Unsupported expression in static initializer: "; CE->printAsOperand(OS, /*PrintType=*/false, - !MF ? nullptr : MF->getFunction()->getParent()); + !MF ? nullptr : MF->getFunction().getParent()); report_fatal_error(OS.str()); } case Instruction::GetElementPtr: { @@ -2317,7 +2345,6 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, // // cstexpr := <gotequiv> - <foo> + gotpcrelcst, where // gotpcrelcst := <offset from @foo base> + <cst> - // MCValue MV; if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute()) return; @@ -2348,7 +2375,6 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, // If gotpcrelcst is positive it means that we can safely fold the pc rel // displacement into the GOTPCREL. We can also can have an extra offset <cst> // if the target knows how to encode it. - // int64_t GOTPCRelCst = Offset + MV.getConstant(); if (GOTPCRelCst < 0) return; @@ -2370,7 +2396,6 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, // .long 42 // foo: // .long bar@GOTPCREL+<gotpcrelcst> - // AsmPrinter::GOTEquivUsePair Result = AP.GlobalGOTEquivs[GOTEquivSym]; const GlobalVariable *GV = Result.first; int NumUses = (int)Result.second; @@ -2550,7 +2575,6 @@ static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, << " Depth=" << Loop->getLoopDepth() << '\n'; } - /// PrintChildLoopComment - Print comments about child loops within /// the loop for this basic block, with nesting. static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, @@ -2603,6 +2627,23 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB, PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); } +void AsmPrinter::setupCodePaddingContext(const MachineBasicBlock &MBB, + MCCodePaddingContext &Context) const { + assert(MF != nullptr && "Machine function must be valid"); + assert(LI != nullptr && "Loop info must be valid"); + Context.IsPaddingActive = !MF->hasInlineAsm() && + !MF->getFunction().optForSize() && + TM.getOptLevel() != CodeGenOpt::None; + const MachineLoop *CurrentLoop = LI->getLoopFor(&MBB); + Context.IsBasicBlockInsideInnermostLoop = + CurrentLoop != nullptr && CurrentLoop->getSubLoops().empty(); + Context.IsBasicBlockReachableViaFallthrough = + std::find(MBB.pred_begin(), MBB.pred_end(), MBB.getPrevNode()) != + MBB.pred_end(); + Context.IsBasicBlockReachableViaBranch = + MBB.pred_size() > 0 && !isBlockOnlyReachableByFallthrough(&MBB); +} + /// EmitBasicBlockStart - This method prints the label for the specified /// MachineBasicBlock, an alignment (if present) and a comment describing /// it if appropriate. @@ -2618,6 +2659,9 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { // Emit an alignment directive for this block, if needed. if (unsigned Align = MBB.getAlignment()) EmitAlignment(Align); + MCCodePaddingContext Context; + setupCodePaddingContext(MBB, Context); + OutStreamer->EmitCodePaddingBasicBlockStart(Context); // If the block has its address taken, emit any labels that were used to // reference the block. It is possible that there is more than one label @@ -2652,13 +2696,20 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry())) { if (isVerbose()) { // NOTE: Want this comment at start of line, don't emit with AddComment. - OutStreamer->emitRawComment(" BB#" + Twine(MBB.getNumber()) + ":", false); + OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":", + false); } } else { OutStreamer->EmitLabel(MBB.getSymbol()); } } +void AsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) { + MCCodePaddingContext Context; + setupCodePaddingContext(MBB, Context); + OutStreamer->EmitCodePaddingBasicBlockEnd(Context); +} + void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition) const { MCSymbolAttr Attr = MCSA_Invalid; @@ -2765,10 +2816,13 @@ void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out, Out->EmitSymbolValue(Sled, Bytes); Out->EmitSymbolValue(CurrentFnSym, Bytes); auto Kind8 = static_cast<uint8_t>(Kind); - Out->EmitBytes(StringRef(reinterpret_cast<const char *>(&Kind8), 1)); - Out->EmitBytes( + Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1)); + Out->EmitBinaryData( StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1)); - Out->EmitZeros(2 * Bytes - 2); // Pad the previous two entries + Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1)); + auto Padding = (4 * Bytes) - ((2 * Bytes) + 3); + assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size"); + Out->EmitZeros(Padding); } void AsmPrinter::emitXRayTable() { @@ -2776,23 +2830,26 @@ void AsmPrinter::emitXRayTable() { return; auto PrevSection = OutStreamer->getCurrentSectionOnly(); - auto Fn = MF->getFunction(); + const Function &F = MF->getFunction(); MCSection *InstMap = nullptr; MCSection *FnSledIndex = nullptr; if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) { - if (Fn->hasComdat()) { - InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, - Fn->getComdat()->getName()); - FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, - Fn->getComdat()->getName()); - } else { - InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC); - FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC); + auto Associated = dyn_cast<MCSymbolELF>(CurrentFnSym); + assert(Associated != nullptr); + auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER; + std::string GroupName; + if (F.hasComdat()) { + Flags |= ELF::SHF_GROUP; + GroupName = F.getComdat()->getName(); } + + auto UniqueID = ++XRayFnUniqueID; + InstMap = + OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, Flags, 0, + GroupName, UniqueID, Associated); + FnSledIndex = + OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0, + GroupName, UniqueID, Associated); } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) { InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0, SectionKind::getReadOnlyWithRel()); @@ -2802,15 +2859,7 @@ void AsmPrinter::emitXRayTable() { llvm_unreachable("Unsupported target"); } - // Before we switch over, we force a reference to a label inside the - // xray_fn_idx sections. This makes sure that the xray_fn_idx section is kept - // live by the linker if the function is not garbage-collected. Since this - // function is always called just before the function's end, we assume that - // this is happening after the last return instruction. auto WordSizeBytes = MAI->getCodePointerSize(); - MCSymbol *IdxRef = OutContext.createTempSymbol("xray_fn_idx_synth_", true); - OutStreamer->EmitCodeAlignment(16); - OutStreamer->EmitSymbolValue(IdxRef, WordSizeBytes, false); // Now we switch to the instrumentation map section. Because this is done // per-function, we are able to create an index entry that will represent the @@ -2829,24 +2878,23 @@ void AsmPrinter::emitXRayTable() { // pointers. This should work for both 32-bit and 64-bit platforms. OutStreamer->SwitchSection(FnSledIndex); OutStreamer->EmitCodeAlignment(2 * WordSizeBytes); - OutStreamer->EmitLabel(IdxRef); - OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes); - OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes); + OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes, false); + OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes, false); OutStreamer->SwitchSection(PrevSection); Sleds.clear(); } void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, - SledKind Kind) { - auto Fn = MI.getParent()->getParent()->getFunction(); - auto Attr = Fn->getFnAttribute("function-instrument"); - bool LogArgs = Fn->hasFnAttribute("xray-log-args"); + SledKind Kind, uint8_t Version) { + const Function &F = MI.getMF()->getFunction(); + auto Attr = F.getFnAttribute("function-instrument"); + bool LogArgs = F.hasFnAttribute("xray-log-args"); bool AlwaysInstrument = Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always"; if (Kind == SledKind::FUNCTION_ENTER && LogArgs) Kind = SledKind::LOG_ARGS_ENTER; - Sleds.emplace_back( - XRayFunctionEntry{ Sled, CurrentFnSym, Kind, AlwaysInstrument, Fn }); + Sleds.emplace_back(XRayFunctionEntry{Sled, CurrentFnSym, Kind, + AlwaysInstrument, &F, Version}); } uint16_t AsmPrinter::getDwarfVersion() const { diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 0edf9051d342..08eb14e242c5 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -12,14 +12,12 @@ //===----------------------------------------------------------------------===// #include "ByteStreamer.h" -#include "DwarfDebug.h" -#include "DwarfExpression.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DIE.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" #include "llvm/IR/DataLayout.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -28,9 +26,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MachineLocation.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; #define DEBUG_TYPE "asm-printer" @@ -48,12 +44,19 @@ void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const { } /// EmitULEB128 - emit the specified unsigned leb128 value. -void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc, - unsigned PadTo) const { +void AsmPrinter::EmitPaddedULEB128(uint64_t Value, unsigned PadTo, + const char *Desc) const { if (isVerbose() && Desc) OutStreamer->AddComment(Desc); - OutStreamer->EmitULEB128IntValue(Value, PadTo); + OutStreamer->EmitPaddedULEB128IntValue(Value, PadTo); +} + +void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const { + if (isVerbose() && Desc) + OutStreamer->AddComment(Desc); + + OutStreamer->EmitULEB128IntValue(Value); } static const char *DecodeDWARFEncoding(unsigned Encoding) { @@ -212,6 +215,9 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { case MCCFIInstruction::OpEscape: OutStreamer->EmitCFIEscape(Inst.getValues()); break; + case MCCFIInstruction::OpRestore: + OutStreamer->EmitCFIRestore(Inst.getRegister()); + break; } } diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index eae79ad101d3..04a72ba3d738 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -17,6 +17,9 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/InlineAsm.h" @@ -32,10 +35,7 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; #define DEBUG_TYPE "asm-printer" @@ -144,6 +144,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, " we don't have an asm parser for this target\n"); Parser->setAssemblerDialect(Dialect); Parser->setTargetParser(*TAP.get()); + Parser->setEnablePrintSchedInfo(EnablePrintSchedInfo); if (Dialect == InlineAsm::AD_Intel) // We need this flag to be able to parse numbers like "0bH" Parser->setParsingInlineAsm(true); @@ -513,7 +514,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const { // Reset SanitizeAddress based on the function's attribute. MCTargetOptions MCOptions = TM.Options.MCOptions; MCOptions.SanitizeAddress = - MF->getFunction()->hasFnAttribute(Attribute::SanitizeAddress); + MF->getFunction().hasFnAttribute(Attribute::SanitizeAddress); EmitInlineAsm(OS.str(), getSubtargetInfo(), MCOptions, LocMD, MI->getInlineAsmDialect()); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index a81d56e9618b..1d0a003dc50a 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "CodeViewDebug.h" +#include "DwarfExpression.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -19,9 +20,9 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/Triple.h" @@ -34,9 +35,14 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Config/llvm-config.h" #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" #include "llvm/DebugInfo/CodeView/Line.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" @@ -61,17 +67,15 @@ #include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/SMLoc.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Support/ScopedPrinter.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include <algorithm> #include <cassert> #include <cctype> @@ -86,6 +90,9 @@ using namespace llvm; using namespace llvm::codeview; +static cl::opt<bool> EmitDebugGlobalHashes("emit-codeview-ghash-section", + cl::ReallyHidden, cl::init(false)); + CodeViewDebug::CodeViewDebug(AsmPrinter *AP) : DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) { // If module doesn't have named metadata anchors or COFF debug section @@ -153,12 +160,19 @@ StringRef CodeViewDebug::getFullFilepath(const DIFile *File) { } unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) { + StringRef FullPath = getFullFilepath(F); unsigned NextId = FileIdMap.size() + 1; - auto Insertion = FileIdMap.insert(std::make_pair(F, NextId)); + auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId)); if (Insertion.second) { // We have to compute the full filepath and emit a .cv_file directive. - StringRef FullPath = getFullFilepath(F); - bool Success = OS.EmitCVFileDirective(NextId, FullPath); + std::string Checksum = fromHex(F->getChecksum()); + void *CKMem = OS.getContext().allocate(Checksum.size(), 1); + memcpy(CKMem, Checksum.data(), Checksum.size()); + ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem), + Checksum.size()); + DIFile::ChecksumKind ChecksumKind = F->getChecksumKind(); + bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes, + static_cast<unsigned>(ChecksumKind)); (void)Success; assert(Success && ".cv_file directive failed"); } @@ -270,7 +284,7 @@ TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) { // Build the fully qualified name of the scope. std::string ScopeName = getFullyQualifiedName(Scope); StringIdRecord SID(TypeIndex(), ScopeName); - auto TI = TypeTable.writeKnownType(SID); + auto TI = TypeTable.writeLeafType(SID); return recordTypeIndexForDINode(Scope, TI); } @@ -295,12 +309,12 @@ TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) { TypeIndex ClassType = getTypeIndex(Class); MemberFuncIdRecord MFuncId(ClassType, getMemberFunctionType(SP, Class), DisplayName); - TI = TypeTable.writeKnownType(MFuncId); + TI = TypeTable.writeLeafType(MFuncId); } else { // Otherwise, this must be a free function. TypeIndex ParentScope = getScopeIndex(Scope); FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName); - TI = TypeTable.writeKnownType(FuncId); + TI = TypeTable.writeLeafType(FuncId); } return recordTypeIndexForDINode(SP, TI); @@ -324,8 +338,9 @@ TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP, // function type, as the complete class type is likely to reference this // member function type. TypeLoweringScope S(*this); - TypeIndex TI = - lowerTypeMemberFunction(SP->getType(), Class, SP->getThisAdjustment()); + const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0; + TypeIndex TI = lowerTypeMemberFunction( + SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod); return recordTypeIndexForDINode(SP, TI, Class); } @@ -476,10 +491,13 @@ void CodeViewDebug::endModule() { OS.AddComment("String table"); OS.EmitCVStringTableDirective(); - // Emit type information last, so that any types we translate while emitting - // function info are included. + // Emit type information and hashes last, so that any types we translate while + // emitting function info are included. emitTypeInformation(); + if (EmitDebugGlobalHashes) + emitTypeGlobalHashes(); + clear(); } @@ -496,11 +514,6 @@ static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S) { } void CodeViewDebug::emitTypeInformation() { - // Do nothing if we have no debug info or if no non-trivial types were emitted - // to TypeTable during codegen. - NamedMDNode *CU_Nodes = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); - if (!CU_Nodes) - return; if (TypeTable.empty()) return; @@ -545,7 +558,39 @@ void CodeViewDebug::emitTypeInformation() { } } -namespace { +void CodeViewDebug::emitTypeGlobalHashes() { + if (TypeTable.empty()) + return; + + // Start the .debug$H section with the version and hash algorithm, currently + // hardcoded to version 0, SHA1. + OS.SwitchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection()); + + OS.EmitValueToAlignment(4); + OS.AddComment("Magic"); + OS.EmitIntValue(COFF::DEBUG_HASHES_SECTION_MAGIC, 4); + OS.AddComment("Section Version"); + OS.EmitIntValue(0, 2); + OS.AddComment("Hash Algorithm"); + OS.EmitIntValue(uint16_t(GlobalTypeHashAlg::SHA1), 2); + + TypeIndex TI(TypeIndex::FirstNonSimpleIndex); + for (const auto &GHR : TypeTable.hashes()) { + if (OS.isVerboseAsm()) { + // Emit an EOL-comment describing which TypeIndex this hash corresponds + // to, as well as the stringified SHA1 hash. + SmallString<32> Comment; + raw_svector_ostream CommentOS(Comment); + CommentOS << formatv("{0:X+} [{1}]", TI.getIndex(), GHR); + OS.AddComment(Comment); + ++TI; + } + assert(GHR.Hash.size() % 20 == 0); + StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()), + GHR.Hash.size()); + OS.EmitBinaryData(S); + } +} static SourceLanguage MapDWLangToCVLang(unsigned DWLang) { switch (DWLang) { @@ -572,6 +617,8 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) { return SourceLanguage::Cobol; case dwarf::DW_LANG_Java: return SourceLanguage::Java; + case dwarf::DW_LANG_D: + return SourceLanguage::D; 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, @@ -580,9 +627,11 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) { } } +namespace { struct Version { int Part[4]; }; +} // end anonymous namespace // Takes a StringRef like "clang 4.0.0.0 (other nonsense 123)" and parses out // the version number. @@ -605,20 +654,19 @@ static Version parseVersion(StringRef Name) { static CPUType mapArchToCVCPUType(Triple::ArchType Type) { switch (Type) { - case Triple::ArchType::x86: - return CPUType::Pentium3; - case Triple::ArchType::x86_64: - return CPUType::X64; - case Triple::ArchType::thumb: - return CPUType::Thumb; - default: - report_fatal_error("target architecture doesn't map to a CodeView " - "CPUType"); + case Triple::ArchType::x86: + return CPUType::Pentium3; + case Triple::ArchType::x86_64: + return CPUType::X64; + case Triple::ArchType::thumb: + return CPUType::Thumb; + case Triple::ArchType::aarch64: + return CPUType::ARM64; + default: + report_fatal_error("target architecture doesn't map to a CodeView CPUType"); } } -} // end anonymous namespace - void CodeViewDebug::emitCompilerInformation() { MCContext &Context = MMI->getContext(); MCSymbol *CompilerBegin = Context.createTempSymbol(), @@ -678,8 +726,10 @@ void CodeViewDebug::emitInlineeLinesSubsection() { OS.AddComment("Inlinee lines subsection"); MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines); - // We don't provide any extra file info. - // FIXME: Find out if debuggers use this info. + // We emit the checksum info for files. This is used by debuggers to + // determine if a pdb matches the source before loading it. Visual Studio, + // for instance, will display a warning that the breakpoints are not valid if + // the pdb does not match the source. OS.AddComment("Inlinee lines signature"); OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4); @@ -692,13 +742,10 @@ void CodeViewDebug::emitInlineeLinesSubsection() { OS.AddComment("Inlined function " + SP->getName() + " starts at " + SP->getFilename() + Twine(':') + Twine(SP->getLine())); OS.AddBlankLine(); - // The filechecksum table uses 8 byte entries for now, and file ids start at - // 1. - unsigned FileOffset = (FileId - 1) * 8; OS.AddComment("Type index of inlined function"); OS.EmitIntValue(InlineeIdx.getIndex(), 4); OS.AddComment("Offset into filechecksum table"); - OS.EmitIntValue(FileOffset, 4); + OS.EmitCVFileChecksumOffsetDirective(FileId); OS.AddComment("Starting line number"); OS.EmitIntValue(SP->getLine(), 4); } @@ -799,6 +846,10 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, if (FuncName.empty()) FuncName = GlobalValue::dropLLVMManglingEscape(GV->getName()); + // Emit FPO data, but only on 32-bit x86. No other platforms use it. + if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86) + OS.EmitCVFPOData(Fn); + // Emit a symbol subsection, required by VS2012+ to find function boundaries. OS.AddComment("Symbol subsection for " + Twine(FuncName)); MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols); @@ -858,6 +909,30 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, emitInlinedCallSite(FI, InlinedAt, I->second); } + for (auto Annot : FI.Annotations) { + MCSymbol *Label = Annot.first; + MDTuple *Strs = cast<MDTuple>(Annot.second); + MCSymbol *AnnotBegin = MMI->getContext().createTempSymbol(), + *AnnotEnd = MMI->getContext().createTempSymbol(); + OS.AddComment("Record length"); + OS.emitAbsoluteSymbolDiff(AnnotEnd, AnnotBegin, 2); + OS.EmitLabel(AnnotBegin); + OS.AddComment("Record kind: S_ANNOTATION"); + OS.EmitIntValue(SymbolKind::S_ANNOTATION, 2); + OS.EmitCOFFSecRel32(Label, /*Offset=*/0); + // FIXME: Make sure we don't overflow the max record size. + OS.EmitCOFFSectionIndex(Label); + OS.EmitIntValue(Strs->getNumOperands(), 2); + for (Metadata *MD : Strs->operands()) { + // MDStrings are null terminated, so we can do EmitBytes and get the + // nice .asciz directive. + StringRef Str = cast<MDString>(MD)->getString(); + assert(Str.data()[Str.size()] == '\0' && "non-nullterminated MDString"); + OS.EmitBytes(StringRef(Str.data(), Str.size() + 1)); + } + OS.EmitLabel(AnnotEnd); + } + if (SP != nullptr) emitDebugInfoForUDTs(LocalUDTs); @@ -947,13 +1022,110 @@ void CodeViewDebug::collectVariableInfoFromMFTable( } } +static bool canUseReferenceType(const DbgVariableLocation &Loc) { + return !Loc.LoadChain.empty() && Loc.LoadChain.back() == 0; +} + +static bool needsReferenceType(const DbgVariableLocation &Loc) { + return Loc.LoadChain.size() == 2 && Loc.LoadChain.back() == 0; +} + +void CodeViewDebug::calculateRanges( + LocalVariable &Var, const DbgValueHistoryMap::InstrRanges &Ranges) { + const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo(); + + // Calculate the definition ranges. + for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { + const InsnRange &Range = *I; + const MachineInstr *DVInst = Range.first; + assert(DVInst->isDebugValue() && "Invalid History entry"); + // FIXME: Find a way to represent constant variables, since they are + // relatively common. + Optional<DbgVariableLocation> Location = + DbgVariableLocation::extractFromMachineInstruction(*DVInst); + if (!Location) + continue; + + // CodeView can only express variables in register and variables in memory + // at a constant offset from a register. However, for variables passed + // indirectly by pointer, it is common for that pointer to be spilled to a + // stack location. For the special case of one offseted load followed by a + // zero offset load (a pointer spilled to the stack), we change the type of + // the local variable from a value type to a reference type. This tricks the + // debugger into doing the load for us. + if (Var.UseReferenceType) { + // We're using a reference type. Drop the last zero offset load. + if (canUseReferenceType(*Location)) + Location->LoadChain.pop_back(); + else + continue; + } else if (needsReferenceType(*Location)) { + // This location can't be expressed without switching to a reference type. + // Start over using that. + Var.UseReferenceType = true; + Var.DefRanges.clear(); + calculateRanges(Var, Ranges); + return; + } + + // We can only handle a register or an offseted load of a register. + if (Location->Register == 0 || Location->LoadChain.size() > 1) + continue; + { + LocalVarDefRange DR; + DR.CVRegister = TRI->getCodeViewRegNum(Location->Register); + DR.InMemory = !Location->LoadChain.empty(); + DR.DataOffset = + !Location->LoadChain.empty() ? Location->LoadChain.back() : 0; + if (Location->FragmentInfo) { + DR.IsSubfield = true; + DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8; + } else { + DR.IsSubfield = false; + DR.StructOffset = 0; + } + + if (Var.DefRanges.empty() || + Var.DefRanges.back().isDifferentLocation(DR)) { + Var.DefRanges.emplace_back(std::move(DR)); + } + } + + // Compute the label range. + const MCSymbol *Begin = getLabelBeforeInsn(Range.first); + const MCSymbol *End = getLabelAfterInsn(Range.second); + if (!End) { + // This range is valid until the next overlapping bitpiece. In the + // common case, ranges will not be bitpieces, so they will overlap. + auto J = std::next(I); + const DIExpression *DIExpr = DVInst->getDebugExpression(); + while (J != E && + !fragmentsOverlap(DIExpr, J->first->getDebugExpression())) + ++J; + if (J != E) + End = getLabelBeforeInsn(J->first); + else + End = Asm->getFunctionEnd(); + } + + // If the last range end is our begin, just extend the last range. + // Otherwise make a new range. + SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R = + Var.DefRanges.back().Ranges; + if (!R.empty() && R.back().second == Begin) + R.back().second = End; + else + R.emplace_back(Begin, End); + + // FIXME: Do more range combining. + } +} + void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) { DenseSet<InlinedVariable> Processed; // Grab the variable info that was squirreled away in the MMI side-table. collectVariableInfoFromMFTable(Processed); - const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo(); - for (const auto &I : DbgValues) { InlinedVariable IV = I.first; if (Processed.count(IV)) @@ -976,87 +1148,15 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) { LocalVariable Var; Var.DIVar = DIVar; - // Calculate the definition ranges. - for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { - const InsnRange &Range = *I; - const MachineInstr *DVInst = Range.first; - assert(DVInst->isDebugValue() && "Invalid History entry"); - const DIExpression *DIExpr = DVInst->getDebugExpression(); - bool IsSubfield = false; - unsigned StructOffset = 0; - - // Handle fragments. - auto Fragment = DIExpr->getFragmentInfo(); - if (Fragment) { - IsSubfield = true; - StructOffset = Fragment->OffsetInBits / 8; - } else if (DIExpr->getNumElements() > 0) { - continue; // Ignore unrecognized exprs. - } - - // Bail if operand 0 is not a valid register. This means the variable is a - // simple constant, or is described by a complex expression. - // FIXME: Find a way to represent constant variables, since they are - // relatively common. - unsigned Reg = - DVInst->getOperand(0).isReg() ? DVInst->getOperand(0).getReg() : 0; - if (Reg == 0) - continue; - - // Handle the two cases we can handle: indirect in memory and in register. - unsigned CVReg = TRI->getCodeViewRegNum(Reg); - bool InMemory = DVInst->getOperand(1).isImm(); - int Offset = InMemory ? DVInst->getOperand(1).getImm() : 0; - { - LocalVarDefRange DR; - DR.CVRegister = CVReg; - DR.InMemory = InMemory; - DR.DataOffset = Offset; - DR.IsSubfield = IsSubfield; - DR.StructOffset = StructOffset; - - if (Var.DefRanges.empty() || - Var.DefRanges.back().isDifferentLocation(DR)) { - Var.DefRanges.emplace_back(std::move(DR)); - } - } - - // Compute the label range. - const MCSymbol *Begin = getLabelBeforeInsn(Range.first); - const MCSymbol *End = getLabelAfterInsn(Range.second); - if (!End) { - // This range is valid until the next overlapping bitpiece. In the - // common case, ranges will not be bitpieces, so they will overlap. - auto J = std::next(I); - while (J != E && - !fragmentsOverlap(DIExpr, J->first->getDebugExpression())) - ++J; - if (J != E) - End = getLabelBeforeInsn(J->first); - else - End = Asm->getFunctionEnd(); - } - - // If the last range end is our begin, just extend the last range. - // Otherwise make a new range. - SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &Ranges = - Var.DefRanges.back().Ranges; - if (!Ranges.empty() && Ranges.back().second == Begin) - Ranges.back().second = End; - else - Ranges.emplace_back(Begin, End); - - // FIXME: Do more range combining. - } - + calculateRanges(Var, Ranges); recordLocalVariable(std::move(Var), InlinedAt); } } void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) { - const Function *GV = MF->getFunction(); - assert(FnDebugInfo.count(GV) == false); - CurFn = &FnDebugInfo[GV]; + const Function &GV = MF->getFunction(); + assert(FnDebugInfo.count(&GV) == false); + CurFn = &FnDebugInfo[&GV]; CurFn->FuncId = NextFuncId++; CurFn->Begin = Asm->getFunctionBegin(); @@ -1087,10 +1187,40 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) { } } -void CodeViewDebug::addToUDTs(const DIType *Ty, TypeIndex TI) { +static bool shouldEmitUdt(const DIType *T) { + if (!T) + return false; + + // MSVC does not emit UDTs for typedefs that are scoped to classes. + if (T->getTag() == dwarf::DW_TAG_typedef) { + if (DIScope *Scope = T->getScope().resolve()) { + switch (Scope->getTag()) { + case dwarf::DW_TAG_structure_type: + case dwarf::DW_TAG_class_type: + case dwarf::DW_TAG_union_type: + return false; + } + } + } + + while (true) { + if (!T || T->isForwardDecl()) + return false; + + const DIDerivedType *DT = dyn_cast<DIDerivedType>(T); + if (!DT) + return true; + T = DT->getBaseType().resolve(); + } + return true; +} + +void CodeViewDebug::addToUDTs(const DIType *Ty) { // Don't record empty UDTs. if (Ty->getName().empty()) return; + if (!shouldEmitUdt(Ty)) + return; SmallVector<StringRef, 5> QualifiedNameComponents; const DISubprogram *ClosestSubprogram = getQualifiedNameComponents( @@ -1099,10 +1229,11 @@ void CodeViewDebug::addToUDTs(const DIType *Ty, TypeIndex TI) { std::string FullyQualifiedName = getQualifiedName(QualifiedNameComponents, getPrettyScopeName(Ty)); - if (ClosestSubprogram == nullptr) - GlobalUDTs.emplace_back(std::move(FullyQualifiedName), TI); - else if (ClosestSubprogram == CurrentSubprogram) - LocalUDTs.emplace_back(std::move(FullyQualifiedName), TI); + if (ClosestSubprogram == nullptr) { + GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty); + } else if (ClosestSubprogram == CurrentSubprogram) { + LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty); + } // TODO: What if the ClosestSubprogram is neither null or the current // subprogram? Currently, the UDT just gets dropped on the floor. @@ -1139,7 +1270,8 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) { // The member function type of a member function pointer has no // ThisAdjustment. return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy, - /*ThisAdjustment=*/0); + /*ThisAdjustment=*/0, + /*IsStaticMethod=*/false); } return lowerTypeFunction(cast<DISubroutineType>(Ty)); case dwarf::DW_TAG_enumeration_type: @@ -1160,7 +1292,7 @@ TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) { TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef); StringRef TypeName = Ty->getName(); - addToUDTs(Ty, UnderlyingTypeIndex); + addToUDTs(Ty); if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) && TypeName == "HRESULT") @@ -1193,11 +1325,12 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) { "codeview doesn't support subranges with lower bounds"); int64_t Count = Subrange->getCount(); - // Variable Length Array (VLA) has Count equal to '-1'. - // Replace with Count '1', assume it is the minimum VLA length. - // FIXME: Make front-end support VLA subrange and emit LF_DIMVARLU. + // Forward declarations of arrays without a size and VLAs use a count of -1. + // Emit a count of zero in these cases to match what MSVC does for arrays + // without a size. MSVC doesn't support VLAs, so it's not clear what we + // should do for them even if we could distinguish them. if (Count == -1) - Count = 1; + Count = 0; // Update the element size and element type index for subsequent subranges. ElementSize *= Count; @@ -1209,7 +1342,7 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) { StringRef Name = (i == 0) ? Ty->getName() : ""; ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name); - ElementTypeIndex = TypeTable.writeKnownType(AR); + ElementTypeIndex = TypeTable.writeLeafType(AR); } return ElementTypeIndex; @@ -1342,7 +1475,7 @@ TypeIndex CodeViewDebug::lowerTypePointer(const DIDerivedType *Ty) { // do. PointerOptions PO = PointerOptions::None; PointerRecord PR(PointeeTI, PK, PM, PO, Ty->getSizeInBits() / 8); - return TypeTable.writeKnownType(PR); + return TypeTable.writeLeafType(PR); } static PointerToMemberRepresentation @@ -1393,7 +1526,7 @@ TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty) { MemberPointerInfo MPI( ClassTI, translatePtrToMemberRep(SizeInBytes, IsPMF, Ty->getFlags())); PointerRecord PR(PointeeTI, PK, PM, PO, SizeInBytes, MPI); - return TypeTable.writeKnownType(PR); + return TypeTable.writeLeafType(PR); } /// Given a DWARF calling convention, get the CodeView equivalent. If we don't @@ -1432,7 +1565,7 @@ TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) { } TypeIndex ModifiedTI = getTypeIndex(BaseTy); ModifierRecord MR(ModifiedTI, Mods); - return TypeTable.writeKnownType(MR); + return TypeTable.writeLeafType(MR); } TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) { @@ -1449,18 +1582,19 @@ TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) { } ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); - TypeIndex ArgListIndex = TypeTable.writeKnownType(ArgListRec); + TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec); CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); ProcedureRecord Procedure(ReturnTypeIndex, CC, FunctionOptions::None, ArgTypeIndices.size(), ArgListIndex); - return TypeTable.writeKnownType(Procedure); + return TypeTable.writeLeafType(Procedure); } TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, const DIType *ClassTy, - int ThisAdjustment) { + int ThisAdjustment, + bool IsStaticMethod) { // Lower the containing class type. TypeIndex ClassType = getTypeIndex(ClassTy); @@ -1475,26 +1609,22 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, ReturnTypeIndex = ReturnAndArgTypesRef.front(); ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); } - TypeIndex ThisTypeIndex = TypeIndex::Void(); - if (!ArgTypeIndices.empty()) { + TypeIndex ThisTypeIndex; + if (!IsStaticMethod && !ArgTypeIndices.empty()) { ThisTypeIndex = ArgTypeIndices.front(); ArgTypeIndices = ArgTypeIndices.drop_front(); } ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); - TypeIndex ArgListIndex = TypeTable.writeKnownType(ArgListRec); + TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec); CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); - // TODO: Need to use the correct values for: - // FunctionOptions - // ThisPointerAdjustment. + // TODO: Need to use the correct values for FunctionOptions. MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC, FunctionOptions::None, ArgTypeIndices.size(), ArgListIndex, ThisAdjustment); - TypeIndex TI = TypeTable.writeKnownType(MFR); - - return TI; + return TypeTable.writeLeafType(MFR); } TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) { @@ -1503,7 +1633,7 @@ TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) { SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near); VFTableShapeRecord VFTSR(Slots); - return TypeTable.writeKnownType(VFTSR); + return TypeTable.writeLeafType(VFTSR); } static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) { @@ -1530,6 +1660,9 @@ static MethodOptions translateMethodOptionFlags(const DISubprogram *SP) { static MethodKind translateMethodKindFlags(const DISubprogram *SP, bool Introduced) { + if (SP->getFlags() & DINode::FlagStaticMember) + return MethodKind::Static; + switch (SP->getVirtuality()) { case dwarf::DW_VIRTUALITY_none: break; @@ -1542,8 +1675,6 @@ static MethodKind translateMethodKindFlags(const DISubprogram *SP, llvm_unreachable("unhandled virtuality case"); } - // FIXME: Get Clang to mark DISubprogram as static and do something with it. - return MethodKind::Vanilla; } @@ -1593,9 +1724,8 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) { if (Ty->isForwardDecl()) { CO |= ClassOptions::ForwardReference; } else { - FieldListRecordBuilder FLRB(TypeTable); - - FLRB.begin(); + ContinuationRecordBuilder ContinuationBuilder; + ContinuationBuilder.begin(ContinuationRecordKind::FieldList); for (const DINode *Element : Ty->getElements()) { // We assume that the frontend provides all members in source declaration // order, which is what MSVC does. @@ -1603,18 +1733,18 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) { EnumeratorRecord ER(MemberAccess::Public, APSInt::getUnsigned(Enumerator->getValue()), Enumerator->getName()); - FLRB.writeMemberType(ER); + ContinuationBuilder.writeMemberType(ER); EnumeratorCount++; } } - FTI = FLRB.end(true); + FTI = TypeTable.insertRecord(ContinuationBuilder); } std::string FullName = getFullyQualifiedName(Ty); EnumRecord ER(EnumeratorCount, CO, FTI, FullName, Ty->getIdentifier(), getTypeIndex(Ty->getBaseType())); - return TypeTable.writeKnownType(ER); + return TypeTable.writeLeafType(ER); } //===----------------------------------------------------------------------===// @@ -1643,7 +1773,7 @@ struct llvm::ClassInfo { TypeIndex VShapeTI; - std::vector<const DICompositeType *> NestedClasses; + std::vector<const DIType *> NestedTypes; }; void CodeViewDebug::clear() { @@ -1694,12 +1824,14 @@ ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) { } else if (DDTy->getTag() == dwarf::DW_TAG_pointer_type && DDTy->getName() == "__vtbl_ptr_type") { Info.VShapeTI = getTypeIndex(DDTy); + } else if (DDTy->getTag() == dwarf::DW_TAG_typedef) { + Info.NestedTypes.push_back(DDTy); } else if (DDTy->getTag() == dwarf::DW_TAG_friend) { // Ignore friend members. It appears that MSVC emitted info about // friends in the past, but modern versions do not. } } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) { - Info.NestedClasses.push_back(Composite); + Info.NestedTypes.push_back(Composite); } // Skip other unrecognized kinds of elements. } @@ -1715,7 +1847,7 @@ TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) { std::string FullName = getFullyQualifiedName(Ty); ClassRecord CR(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0, FullName, Ty->getIdentifier()); - TypeIndex FwdDeclTI = TypeTable.writeKnownType(CR); + TypeIndex FwdDeclTI = TypeTable.writeLeafType(CR); if (!Ty->isForwardDecl()) DeferredCompleteTypes.push_back(Ty); return FwdDeclTI; @@ -1741,16 +1873,17 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) { ClassRecord CR(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI, SizeInBytes, FullName, Ty->getIdentifier()); - TypeIndex ClassTI = TypeTable.writeKnownType(CR); + TypeIndex ClassTI = TypeTable.writeLeafType(CR); if (const auto *File = Ty->getFile()) { StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(File)); - TypeIndex SIDI = TypeTable.writeKnownType(SIDR); + TypeIndex SIDI = TypeTable.writeLeafType(SIDR); + UdtSourceLineRecord USLR(ClassTI, SIDI, Ty->getLine()); - TypeTable.writeKnownType(USLR); + TypeTable.writeLeafType(USLR); } - addToUDTs(Ty, ClassTI); + addToUDTs(Ty); return ClassTI; } @@ -1760,7 +1893,7 @@ TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) { ClassOptions::ForwardReference | getCommonClassOptions(Ty); std::string FullName = getFullyQualifiedName(Ty); UnionRecord UR(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier()); - TypeIndex FwdDeclTI = TypeTable.writeKnownType(UR); + TypeIndex FwdDeclTI = TypeTable.writeLeafType(UR); if (!Ty->isForwardDecl()) DeferredCompleteTypes.push_back(Ty); return FwdDeclTI; @@ -1782,14 +1915,15 @@ TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) { UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName, Ty->getIdentifier()); - TypeIndex UnionTI = TypeTable.writeKnownType(UR); + TypeIndex UnionTI = TypeTable.writeLeafType(UR); StringIdRecord SIR(TypeIndex(0x0), getFullFilepath(Ty->getFile())); - TypeIndex SIRI = TypeTable.writeKnownType(SIR); + TypeIndex SIRI = TypeTable.writeLeafType(SIR); + UdtSourceLineRecord USLR(UnionTI, SIRI, Ty->getLine()); - TypeTable.writeKnownType(USLR); + TypeTable.writeLeafType(USLR); - addToUDTs(Ty, UnionTI); + addToUDTs(Ty); return UnionTI; } @@ -1802,8 +1936,8 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { // list record. unsigned MemberCount = 0; ClassInfo Info = collectClassInfo(Ty); - FieldListRecordBuilder FLBR(TypeTable); - FLBR.begin(); + ContinuationRecordBuilder ContinuationBuilder; + ContinuationBuilder.begin(ContinuationRecordKind::FieldList); // Create base classes. for (const DIDerivedType *I : Info.Inheritance) { @@ -1821,14 +1955,14 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset, VBTableIndex); - FLBR.writeMemberType(VBCR); + ContinuationBuilder.writeMemberType(VBCR); } else { assert(I->getOffsetInBits() % 8 == 0 && "bases must be on byte boundaries"); BaseClassRecord BCR(translateAccessFlags(Ty->getTag(), I->getFlags()), getTypeIndex(I->getBaseType()), I->getOffsetInBits() / 8); - FLBR.writeMemberType(BCR); + ContinuationBuilder.writeMemberType(BCR); } } @@ -1842,7 +1976,7 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { if (Member->isStaticMember()) { StaticDataMemberRecord SDMR(Access, MemberBaseType, MemberName); - FLBR.writeMemberType(SDMR); + ContinuationBuilder.writeMemberType(SDMR); MemberCount++; continue; } @@ -1851,7 +1985,7 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { if ((Member->getFlags() & DINode::FlagArtificial) && Member->getName().startswith("_vptr$")) { VFPtrRecord VFPR(getTypeIndex(Member->getBaseType())); - FLBR.writeMemberType(VFPR); + ContinuationBuilder.writeMemberType(VFPR); MemberCount++; continue; } @@ -1868,12 +2002,12 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { StartBitOffset -= MemberOffsetInBits; BitFieldRecord BFR(MemberBaseType, Member->getSizeInBits(), StartBitOffset); - MemberBaseType = TypeTable.writeKnownType(BFR); + MemberBaseType = TypeTable.writeLeafType(BFR); } uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8; DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes, MemberName); - FLBR.writeMemberType(DMR); + ContinuationBuilder.writeMemberType(DMR); MemberCount++; } @@ -1898,40 +2032,42 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { } assert(!Methods.empty() && "Empty methods map entry"); if (Methods.size() == 1) - FLBR.writeMemberType(Methods[0]); + ContinuationBuilder.writeMemberType(Methods[0]); else { + // FIXME: Make this use its own ContinuationBuilder so that + // MethodOverloadList can be split correctly. MethodOverloadListRecord MOLR(Methods); - TypeIndex MethodList = TypeTable.writeKnownType(MOLR); + TypeIndex MethodList = TypeTable.writeLeafType(MOLR); + OverloadedMethodRecord OMR(Methods.size(), MethodList, Name); - FLBR.writeMemberType(OMR); + ContinuationBuilder.writeMemberType(OMR); } } // Create nested classes. - for (const DICompositeType *Nested : Info.NestedClasses) { + for (const DIType *Nested : Info.NestedTypes) { NestedTypeRecord R(getTypeIndex(DITypeRef(Nested)), Nested->getName()); - FLBR.writeMemberType(R); + ContinuationBuilder.writeMemberType(R); MemberCount++; } - TypeIndex FieldTI = FLBR.end(true); + TypeIndex FieldTI = TypeTable.insertRecord(ContinuationBuilder); return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount, - !Info.NestedClasses.empty()); + !Info.NestedTypes.empty()); } TypeIndex CodeViewDebug::getVBPTypeIndex() { if (!VBPType.getIndex()) { // Make a 'const int *' type. ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const); - TypeIndex ModifiedTI = TypeTable.writeKnownType(MR); + TypeIndex ModifiedTI = TypeTable.writeLeafType(MR); PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64 : PointerKind::Near32; PointerMode PM = PointerMode::Pointer; PointerOptions PO = PointerOptions::None; PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes()); - - VBPType = TypeTable.writeKnownType(PR); + VBPType = TypeTable.writeLeafType(PR); } return VBPType; @@ -1957,6 +2093,16 @@ TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) { return recordTypeIndexForDINode(Ty, TI, ClassTy); } +TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(DITypeRef TypeRef) { + DIType *Ty = TypeRef.resolve(); + PointerRecord PR(getTypeIndex(Ty), + getPointerSizeInBytes() == 8 ? PointerKind::Near64 + : PointerKind::Near32, + PointerMode::LValueReference, PointerOptions::None, + Ty->getSizeInBits() / 8); + return TypeTable.writeLeafType(PR); +} + TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) { const DIType *Ty = TypeRef.resolve(); @@ -2064,7 +2210,9 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) { Flags |= LocalSymFlags::IsOptimizedOut; OS.AddComment("TypeIndex"); - TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType()); + TypeIndex TI = Var.UseReferenceType + ? getTypeIndexForReferenceTo(Var.DIVar->getType()) + : getCompleteTypeIndex(Var.DIVar->getType()); OS.EmitIntValue(TI.getIndex(), 4); OS.AddComment("Flags"); OS.EmitIntValue(static_cast<uint16_t>(Flags), 2); @@ -2125,19 +2273,21 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) { } void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) { - const Function *GV = MF->getFunction(); - assert(FnDebugInfo.count(GV)); - assert(CurFn == &FnDebugInfo[GV]); + const Function &GV = MF->getFunction(); + assert(FnDebugInfo.count(&GV)); + assert(CurFn == &FnDebugInfo[&GV]); - collectVariableInfo(GV->getSubprogram()); + collectVariableInfo(GV.getSubprogram()); // Don't emit anything if we don't have any line tables. if (!CurFn->HaveLineInfo) { - FnDebugInfo.erase(GV); + FnDebugInfo.erase(&GV); CurFn = nullptr; return; } + CurFn->Annotations = MF->getCodeViewAnnotations(); + CurFn->End = Asm->getFunctionEnd(); CurFn = nullptr; @@ -2156,6 +2306,8 @@ void CodeViewDebug::beginInstruction(const MachineInstr *MI) { DebugLoc DL = MI->getDebugLoc(); if (!DL && MI->getParent() != PrevInstBB) { for (const auto &NextMI : *MI->getParent()) { + if (NextMI.isDebugValue()) + continue; DL = NextMI.getDebugLoc(); if (DL) break; @@ -2187,8 +2339,11 @@ void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) { } void CodeViewDebug::emitDebugInfoForUDTs( - ArrayRef<std::pair<std::string, TypeIndex>> UDTs) { - for (const std::pair<std::string, codeview::TypeIndex> &UDT : UDTs) { + ArrayRef<std::pair<std::string, const DIType *>> UDTs) { + for (const auto &UDT : UDTs) { + const DIType *T = UDT.second; + assert(shouldEmitUdt(T)); + MCSymbol *UDTRecordBegin = MMI->getContext().createTempSymbol(), *UDTRecordEnd = MMI->getContext().createTempSymbol(); OS.AddComment("Record length"); @@ -2199,7 +2354,7 @@ void CodeViewDebug::emitDebugInfoForUDTs( OS.EmitIntValue(unsigned(SymbolKind::S_UDT), 2); OS.AddComment("Type"); - OS.EmitIntValue(UDT.second.getIndex(), 4); + OS.EmitIntValue(getCompleteTypeIndex(T).getIndex(), 4); emitNullTerminatedSymbolName(OS, UDT.first); OS.EmitLabel(UDTRecordEnd); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index fd8f60425c24..69e93640d7ef 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -23,8 +23,8 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" #include "llvm/IR/DebugLoc.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" @@ -52,7 +52,7 @@ class MachineFunction; class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { MCStreamer &OS; BumpPtrAllocator Allocator; - codeview::TypeTableBuilder TypeTable; + codeview::GlobalTypeTableBuilder TypeTable; /// Represents the most general definition range. struct LocalVarDefRange { @@ -94,6 +94,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { struct LocalVariable { const DILocalVariable *DIVar = nullptr; SmallVector<LocalVarDefRange, 1> DefRanges; + bool UseReferenceType = false; }; struct InlineSite { @@ -118,6 +119,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { SmallVector<LocalVariable, 1> Locals; + std::vector<std::pair<MCSymbol *, MDNode *>> Annotations; + const MCSymbol *Begin = nullptr; const MCSymbol *End = nullptr; unsigned FuncId = 0; @@ -147,6 +150,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP); + void calculateRanges(LocalVariable &Var, + const DbgValueHistoryMap::InstrRanges &Ranges); + static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children, const FunctionInfo &FI, const InlineSite &Site); @@ -155,8 +161,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { /// emit at the end of the TU. MapVector<const Function *, FunctionInfo> FnDebugInfo; - /// Map from DIFile to .cv_file id. - DenseMap<const DIFile *, unsigned> FileIdMap; + /// Map from full file path to .cv_file id. Full paths are built from DIFiles + /// and are stored in FileToFilepathMap; + DenseMap<StringRef, unsigned> FileIdMap; /// All inlined subprograms in the order they should be emitted. SmallSetVector<const DISubprogram *, 4> InlinedSubprograms; @@ -187,8 +194,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { // The UDTs we have seen while processing types; each entry is a pair of type // index and type name. - std::vector<std::pair<std::string, codeview::TypeIndex>> LocalUDTs, - GlobalUDTs; + std::vector<std::pair<std::string, const DIType *>> LocalUDTs; + std::vector<std::pair<std::string, const DIType *>> GlobalUDTs; using FileToFilepathMapTy = std::map<const DIFile *, std::string>; FileToFilepathMapTy FileToFilepathMap; @@ -212,6 +219,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { void emitTypeInformation(); + void emitTypeGlobalHashes(); + void emitCompilerInformation(); void emitInlineeLinesSubsection(); @@ -222,8 +231,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { void emitDebugInfoForRetainedTypes(); - void emitDebugInfoForUDTs( - ArrayRef<std::pair<std::string, codeview::TypeIndex>> UDTs); + void + emitDebugInfoForUDTs(ArrayRef<std::pair<std::string, const DIType *>> UDTs); void emitDebugInfoForGlobal(const DIGlobalVariable *DIGV, const GlobalVariable *GV, MCSymbol *GVSym); @@ -259,6 +268,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { codeview::TypeIndex getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef = DITypeRef()); + codeview::TypeIndex getTypeIndexForReferenceTo(DITypeRef TypeRef); + codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP, const DICompositeType *Class); @@ -266,7 +277,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { codeview::TypeIndex getVBPTypeIndex(); - void addToUDTs(const DIType *Ty, codeview::TypeIndex TI); + void addToUDTs(const DIType *Ty); codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy); codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty); @@ -279,7 +290,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty); codeview::TypeIndex lowerTypeMemberFunction(const DISubroutineType *Ty, const DIType *ClassTy, - int ThisAdjustment); + int ThisAdjustment, + bool IsStaticMethod); codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 886e6e264b3e..b3148db30cd6 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -777,6 +777,7 @@ void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break; case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break; case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break; + case dwarf::DW_FORM_data16: break; } for (const auto &V : values()) @@ -791,6 +792,7 @@ unsigned DIEBlock::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { case dwarf::DW_FORM_block2: return Size + sizeof(int16_t); case dwarf::DW_FORM_block4: return Size + sizeof(int32_t); case dwarf::DW_FORM_block: return Size + getULEB128Size(Size); + case dwarf::DW_FORM_data16: return 16; default: llvm_unreachable("Improper form for block"); } } diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp index c2ad9db81cfd..856758c8e4f6 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp -------------===// +//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp --------------===// // // The LLVM Compiler Infrastructure // @@ -9,17 +9,24 @@ #include "DbgValueHistoryCalculator.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/IR/DebugInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" -#include <algorithm> +#include <cassert> #include <map> +#include <utility> + using namespace llvm; #define DEBUG_TYPE "dwarfdebug" @@ -72,10 +79,12 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const { } namespace { + // Maps physreg numbers to the variables they describe. -typedef DbgValueHistoryMap::InlinedVariable InlinedVariable; -typedef std::map<unsigned, SmallVector<InlinedVariable, 1>> RegDescribedVarsMap; -} +using InlinedVariable = DbgValueHistoryMap::InlinedVariable; +using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>; + +} // end anonymous namespace // \brief Claim that @Var is not described by @RegNo anymore. static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, @@ -83,7 +92,7 @@ static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, const auto &I = RegVars.find(RegNo); assert(RegNo != 0U && I != RegVars.end()); auto &VarSet = I->second; - const auto &VarPos = find(VarSet, Var); + const auto &VarPos = llvm::find(VarSet, Var); assert(VarPos != VarSet.end()); VarSet.erase(VarPos); // Don't keep empty sets in a map to keep it as small as possible. diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h index 16d2d7fd7e99..a7b0562e8102 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ----*- C++ -*--===// +//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,9 +13,11 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/IR/DebugInfoMetadata.h" +#include <utility> namespace llvm { +class DILocalVariable; class MachineFunction; class MachineInstr; class TargetRegisterInfo; @@ -29,11 +31,11 @@ class DbgValueHistoryMap { // instruction of the next instruction range, or until the end of the // function. public: - typedef std::pair<const MachineInstr *, const MachineInstr *> InstrRange; - typedef SmallVector<InstrRange, 4> InstrRanges; - typedef std::pair<const DILocalVariable *, const DILocation *> - InlinedVariable; - typedef MapVector<InlinedVariable, InstrRanges> InstrRangesMap; + using InstrRange = std::pair<const MachineInstr *, const MachineInstr *>; + using InstrRanges = SmallVector<InstrRange, 4>; + using InlinedVariable = + std::pair<const DILocalVariable *, const DILocation *>; + using InstrRangesMap = MapVector<InlinedVariable, InstrRanges>; private: InstrRangesMap VarInstrRanges; @@ -41,6 +43,7 @@ private: public: void startInstrRange(InlinedVariable Var, const MachineInstr &MI); void endInstrRange(InlinedVariable Var, const MachineInstr &MI); + // Returns register currently describing @Var. If @Var is currently // unaccessible or is not described by a register, returns 0. unsigned getRegisterForVar(InlinedVariable Var) const; @@ -54,6 +57,7 @@ public: void calculateDbgValueHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &Result); -} -#endif +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index 0971c5942203..d94b0e5c2118 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -13,16 +13,76 @@ //===----------------------------------------------------------------------===// #include "DebugHandlerBase.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DebugInfo.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; +Optional<DbgVariableLocation> +DbgVariableLocation::extractFromMachineInstruction( + const MachineInstr &Instruction) { + DbgVariableLocation Location; + if (!Instruction.isDebugValue()) + return None; + if (!Instruction.getOperand(0).isReg()) + return None; + Location.Register = Instruction.getOperand(0).getReg(); + Location.FragmentInfo.reset(); + // We only handle expressions generated by DIExpression::appendOffset, + // which doesn't require a full stack machine. + int64_t Offset = 0; + const DIExpression *DIExpr = Instruction.getDebugExpression(); + auto Op = DIExpr->expr_op_begin(); + while (Op != DIExpr->expr_op_end()) { + switch (Op->getOp()) { + case dwarf::DW_OP_constu: { + int Value = Op->getArg(0); + ++Op; + if (Op != DIExpr->expr_op_end()) { + switch (Op->getOp()) { + case dwarf::DW_OP_minus: + Offset -= Value; + break; + case dwarf::DW_OP_plus: + Offset += Value; + break; + default: + continue; + } + } + } break; + case dwarf::DW_OP_plus_uconst: + Offset += Op->getArg(0); + break; + case dwarf::DW_OP_LLVM_fragment: + Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)}; + break; + case dwarf::DW_OP_deref: + Location.LoadChain.push_back(Offset); + Offset = 0; + break; + default: + return None; + } + ++Op; + } + + // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE + // instruction. + // FIXME: Replace these with DIExpression. + if (Instruction.isIndirectDebugValue()) + Location.LoadChain.push_back(Offset); + + return Location; +} + DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} // Each LexicalScope has first instruction and last instruction to mark @@ -119,7 +179,7 @@ static bool hasDebugInfo(const MachineModuleInfo *MMI, const MachineFunction *MF) { if (!MMI->hasDebugInfo()) return false; - auto *SP = MF->getFunction()->getSubprogram(); + auto *SP = MF->getFunction().getSubprogram(); if (!SP) return false; assert(SP->getUnit()); @@ -163,7 +223,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) { // label, so arguments are visible when breaking at function entry. const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable(); if (DIVar->isParameter() && - getDISubprogram(DIVar->getScope())->describes(MF->getFunction())) { + getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) { LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin(); if (Ranges.front().first->getDebugExpression()->isFragment()) { // Mark all non-overlapping initial fragments. diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h index 659a921e1fc5..245d70038de9 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h @@ -17,14 +17,38 @@ #include "AsmPrinterHandler.h" #include "DbgValueHistoryCalculator.h" +#include "llvm/ADT/Optional.h" #include "llvm/CodeGen/LexicalScopes.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/IR/DebugInfoMetadata.h" namespace llvm { class AsmPrinter; +class MachineInstr; class MachineModuleInfo; +/// Represents the location at which a variable is stored. +struct DbgVariableLocation { + /// Base register. + unsigned Register; + + /// Chain of offsetted loads necessary to load the value if it lives in + /// memory. Every load except for the last is pointer-sized. + SmallVector<int64_t, 1> LoadChain; + + /// Present if the location is part of a larger variable. + llvm::Optional<llvm::DIExpression::FragmentInfo> FragmentInfo; + + /// Extract a VariableLocation from a MachineInstr. + /// This will only work if Instruction is a debug value instruction + /// and the associated DIExpression is in one of the supported forms. + /// If these requirements are not met, the returned Optional will not + /// have a value. + static Optional<DbgVariableLocation> + extractFromMachineInstruction(const MachineInstr &Instruction); +}; + /// Base class for debug information backends. Common functionality related to /// tracking which variables and scopes are alive at a given PC live here. class DebugHandlerBase : public AsmPrinterHandler { diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index a68e8cc6b4b3..3d6d8a76529c 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -81,7 +81,7 @@ public: if (isLocation()) { llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " "; if (Loc.isIndirect()) - llvm::dbgs() << '+' << Loc.getOffset(); + llvm::dbgs() << "+0"; llvm::dbgs() << "} "; } else if (isConstantInt()) diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp index 9c324ea26ac8..c21b3d3451ad 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp @@ -1,4 +1,4 @@ -//=-- llvm/CodeGen/DwarfAccelTable.cpp - Dwarf Accelerator Tables -*- C++ -*-=// +//===- llvm/CodeGen/DwarfAccelTable.cpp - Dwarf Accelerator Tables --------===// // // The LLVM Compiler Infrastructure // @@ -12,16 +12,22 @@ //===----------------------------------------------------------------------===// #include "DwarfAccelTable.h" -#include "DwarfCompileUnit.h" -#include "DwarfDebug.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DIE.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <limits> +#include <vector> using namespace llvm; @@ -142,13 +148,13 @@ void DwarfAccelTable::EmitBuckets(AsmPrinter *Asm) { unsigned index = 0; for (size_t i = 0, e = Buckets.size(); i < e; ++i) { Asm->OutStreamer->AddComment("Bucket " + Twine(i)); - if (Buckets[i].size() != 0) + if (!Buckets[i].empty()) Asm->EmitInt32(index); else - Asm->EmitInt32(UINT32_MAX); + Asm->EmitInt32(std::numeric_limits<uint32_t>::max()); // Buckets point in the list of hashes, not to the data. Do not // increment the index multiple times in case of hash collisions. - uint64_t PrevHash = UINT64_MAX; + uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); for (auto *HD : Buckets[i]) { uint32_t HashValue = HD->HashValue; if (PrevHash != HashValue) @@ -161,7 +167,7 @@ void DwarfAccelTable::EmitBuckets(AsmPrinter *Asm) { // Walk through the buckets and emit the individual hashes for each // bucket. void DwarfAccelTable::EmitHashes(AsmPrinter *Asm) { - uint64_t PrevHash = UINT64_MAX; + uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); for (size_t i = 0, e = Buckets.size(); i < e; ++i) { for (HashList::const_iterator HI = Buckets[i].begin(), HE = Buckets[i].end(); @@ -181,7 +187,7 @@ void DwarfAccelTable::EmitHashes(AsmPrinter *Asm) { // beginning of the section. The non-section symbol will be output later // when we emit the actual data. void DwarfAccelTable::emitOffsets(AsmPrinter *Asm, const MCSymbol *SecBegin) { - uint64_t PrevHash = UINT64_MAX; + uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); for (size_t i = 0, e = Buckets.size(); i < e; ++i) { for (HashList::const_iterator HI = Buckets[i].begin(), HE = Buckets[i].end(); @@ -205,13 +211,14 @@ void DwarfAccelTable::emitOffsets(AsmPrinter *Asm, const MCSymbol *SecBegin) { // Terminate each HashData bucket with 0. void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D) { for (size_t i = 0, e = Buckets.size(); i < e; ++i) { - uint64_t PrevHash = UINT64_MAX; + uint64_t PrevHash = std::numeric_limits<uint64_t>::max(); for (HashList::const_iterator HI = Buckets[i].begin(), HE = Buckets[i].end(); HI != HE; ++HI) { // Terminate the previous entry if there is no hash collision // with the current one. - if (PrevHash != UINT64_MAX && PrevHash != (*HI)->HashValue) + if (PrevHash != std::numeric_limits<uint64_t>::max() && + PrevHash != (*HI)->HashValue) Asm->EmitInt32(0); // Remember to emit the label for our offset. Asm->OutStreamer->EmitLabel((*HI)->Sym); @@ -257,31 +264,30 @@ void DwarfAccelTable::emit(AsmPrinter *Asm, const MCSymbol *SecBegin, } #ifndef NDEBUG -void DwarfAccelTable::print(raw_ostream &O) { - - Header.print(O); - HeaderData.print(O); +void DwarfAccelTable::print(raw_ostream &OS) { + Header.print(OS); + HeaderData.print(OS); - O << "Entries: \n"; + OS << "Entries: \n"; for (StringMap<DataArray>::const_iterator EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { - O << "Name: " << EI->getKeyData() << "\n"; + OS << "Name: " << EI->getKeyData() << "\n"; for (HashDataContents *HD : EI->second.Values) - HD->print(O); + HD->print(OS); } - O << "Buckets and Hashes: \n"; + OS << "Buckets and Hashes: \n"; for (size_t i = 0, e = Buckets.size(); i < e; ++i) for (HashList::const_iterator HI = Buckets[i].begin(), HE = Buckets[i].end(); HI != HE; ++HI) - (*HI)->print(O); + (*HI)->print(OS); - O << "Data: \n"; + OS << "Data: \n"; for (std::vector<HashData *>::const_iterator DI = Data.begin(), DE = Data.end(); DI != DE; ++DI) - (*DI)->print(O); + (*DI)->print(OS); } #endif diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h index b1ef8cfe989d..f56199dc8e72 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfAccelTable.h @@ -1,4 +1,4 @@ -//==-- llvm/CodeGen/DwarfAccelTable.h - Dwarf Accelerator Tables -*- C++ -*-==// +//==- llvm/CodeGen/DwarfAccelTable.h - Dwarf Accelerator Tables --*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -15,16 +15,19 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFACCELTABLE_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/DIE.h" +#include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" -#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/raw_ostream.h" +#include <cstddef> +#include <cstdint> #include <vector> // The dwarf accelerator tables are an indirect hash table optimized @@ -65,44 +68,35 @@ class AsmPrinter; class DwarfDebug; class DwarfAccelTable { - - static uint32_t HashDJB(StringRef Str) { - uint32_t h = 5381; - for (unsigned i = 0, e = Str.size(); i != e; ++i) - h = ((h << 5) + h) + Str[i]; - return h; - } - // Helper function to compute the number of buckets needed based on // the number of unique hashes. - void ComputeBucketCount(void); + void ComputeBucketCount(); struct TableHeader { - uint32_t magic; // 'HASH' magic value to allow endian detection - uint16_t version; // Version number. - uint16_t hash_function; // The hash function enumeration that was used. - uint32_t bucket_count; // The number of buckets in this hash table. - uint32_t hashes_count; // The total number of unique hash values - // and hash data offsets in this table. - uint32_t header_data_len; // The bytes to skip to get to the hash - // indexes (buckets) for correct alignment. + uint32_t magic = MagicHash; // 'HASH' magic value to allow endian detection + uint16_t version = 1; // Version number. + uint16_t hash_function = dwarf::DW_hash_function_djb; + // The hash function enumeration that was used. + uint32_t bucket_count = 0; // The number of buckets in this hash table. + uint32_t hashes_count = 0; // The total number of unique hash values + // and hash data offsets in this table. + uint32_t header_data_len; // The bytes to skip to get to the hash + // indexes (buckets) for correct alignment. // Also written to disk is the implementation specific header data. static const uint32_t MagicHash = 0x48415348; - TableHeader(uint32_t data_len) - : magic(MagicHash), version(1), - hash_function(dwarf::DW_hash_function_djb), bucket_count(0), - hashes_count(0), header_data_len(data_len) {} + TableHeader(uint32_t data_len) : header_data_len(data_len) {} #ifndef NDEBUG - void print(raw_ostream &O) { - O << "Magic: " << format("0x%x", magic) << "\n" - << "Version: " << version << "\n" - << "Hash Function: " << hash_function << "\n" - << "Bucket Count: " << bucket_count << "\n" - << "Header Data Length: " << header_data_len << "\n"; + void print(raw_ostream &OS) { + OS << "Magic: " << format("0x%x", magic) << "\n" + << "Version: " << version << "\n" + << "Hash Function: " << hash_function << "\n" + << "Bucket Count: " << bucket_count << "\n" + << "Header Data Length: " << header_data_len << "\n"; } + void dump() { print(dbgs()); } #endif }; @@ -127,11 +121,13 @@ public: uint16_t form; // DWARF DW_FORM_ defines constexpr Atom(uint16_t type, uint16_t form) : type(type), form(form) {} + #ifndef NDEBUG - void print(raw_ostream &O) { - O << "Type: " << dwarf::AtomTypeString(type) << "\n" - << "Form: " << dwarf::FormEncodingString(form) << "\n"; + void print(raw_ostream &OS) { + OS << "Type: " << dwarf::AtomTypeString(type) << "\n" + << "Form: " << dwarf::FormEncodingString(form) << "\n"; } + void dump() { print(dbgs()); } #endif }; @@ -145,11 +141,12 @@ private: : die_offset_base(offset), Atoms(AtomList.begin(), AtomList.end()) {} #ifndef NDEBUG - void print(raw_ostream &O) { - O << "die_offset_base: " << die_offset_base << "\n"; + void print(raw_ostream &OS) { + OS << "die_offset_base: " << die_offset_base << "\n"; for (size_t i = 0; i < Atoms.size(); i++) - Atoms[i].print(O); + Atoms[i].print(OS); } + void dump() { print(dbgs()); } #endif }; @@ -168,11 +165,12 @@ public: char Flags; // Specific flags to output HashDataContents(const DIE *D, char Flags) : Die(D), Flags(Flags) {} + #ifndef NDEBUG - void print(raw_ostream &O) const { - O << " Offset: " << Die->getOffset() << "\n"; - O << " Tag: " << dwarf::TagString(Die->getTag()) << "\n"; - O << " Flags: " << Flags << "\n"; + void print(raw_ostream &OS) const { + OS << " Offset: " << Die->getOffset() << "\n" + << " Tag: " << dwarf::TagString(Die->getTag()) << "\n" + << " Flags: " << Flags << "\n"; } #endif }; @@ -183,39 +181,41 @@ private: DwarfStringPoolEntryRef Name; std::vector<HashDataContents *> Values; }; + friend struct HashData; + struct HashData { StringRef Str; uint32_t HashValue; MCSymbol *Sym; DwarfAccelTable::DataArray &Data; // offsets + HashData(StringRef S, DwarfAccelTable::DataArray &Data) : Str(S), Data(Data) { - HashValue = DwarfAccelTable::HashDJB(S); + HashValue = dwarf::djbHash(S); } + #ifndef NDEBUG - void print(raw_ostream &O) { - O << "Name: " << Str << "\n"; - O << " Hash Value: " << format("0x%x", HashValue) << "\n"; - O << " Symbol: "; + void print(raw_ostream &OS) { + OS << "Name: " << Str << "\n"; + OS << " Hash Value: " << format("0x%x", HashValue) << "\n"; + OS << " Symbol: "; if (Sym) - O << *Sym; + OS << *Sym; else - O << "<none>"; - O << "\n"; + OS << "<none>"; + OS << "\n"; for (HashDataContents *C : Data.Values) { - O << " Offset: " << C->Die->getOffset() << "\n"; - O << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n"; - O << " Flags: " << C->Flags << "\n"; + OS << " Offset: " << C->Die->getOffset() << "\n"; + OS << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n"; + OS << " Flags: " << C->Flags << "\n"; } } + void dump() { print(dbgs()); } #endif }; - DwarfAccelTable(const DwarfAccelTable &) = delete; - void operator=(const DwarfAccelTable &) = delete; - // Internal Functions void EmitHeader(AsmPrinter *); void EmitBuckets(AsmPrinter *); @@ -231,25 +231,31 @@ private: TableHeaderData HeaderData; std::vector<HashData *> Data; - typedef StringMap<DataArray, BumpPtrAllocator &> StringEntries; + using StringEntries = StringMap<DataArray, BumpPtrAllocator &>; + StringEntries Entries; // Buckets/Hashes/Offsets - typedef std::vector<HashData *> HashList; - typedef std::vector<HashList> BucketList; + using HashList = std::vector<HashData *>; + using BucketList = std::vector<HashList>; BucketList Buckets; HashList Hashes; // Public Implementation public: DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom>); + DwarfAccelTable(const DwarfAccelTable &) = delete; + DwarfAccelTable &operator=(const DwarfAccelTable &) = delete; + void AddName(DwarfStringPoolEntryRef Name, const DIE *Die, char Flags = 0); void FinalizeTable(AsmPrinter *, StringRef); void emit(AsmPrinter *, const MCSymbol *, DwarfDebug *); #ifndef NDEBUG - void print(raw_ostream &O); + void print(raw_ostream &OS); void dump() { print(dbgs()); } #endif }; -} -#endif + +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFACCELTABLE_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp index dd7f7931b06b..cbb4c48b4d88 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -12,13 +12,12 @@ //===----------------------------------------------------------------------===// #include "DwarfException.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" @@ -31,11 +30,7 @@ #include "llvm/MC/MachineLocation.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; DwarfCFIExceptionBase::DwarfCFIExceptionBase(AsmPrinter *A) @@ -92,7 +87,7 @@ static MCSymbol *getExceptionSym(AsmPrinter *Asm) { void DwarfCFIException::beginFunction(const MachineFunction *MF) { shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); // If any landing pads survive, we need an EH table. bool hasLandingPads = !MF->getLandingPads().empty(); @@ -105,17 +100,17 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); unsigned PerEncoding = TLOF.getPersonalityEncoding(); const Function *Per = nullptr; - if (F->hasPersonalityFn()) - Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); + if (F.hasPersonalityFn()) + Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); // Emit a personality function even when there are no landing pads forceEmitPersonality = // ...if a personality function is explicitly specified - F->hasPersonalityFn() && + F.hasPersonalityFn() && // ... and it's not known to be a noop in the absence of invokes !isNoOpWithoutInvoke(classifyEHPersonality(Per)) && // ... and we're not explicitly asked not to emit it - F->needsUnwindTableEntry(); + F.needsUnwindTableEntry(); shouldEmitPersonality = (forceEmitPersonality || @@ -148,8 +143,8 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB, if (!shouldEmitPersonality) return; - auto *F = MBB->getParent()->getFunction(); - auto *P = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); + auto &F = MBB->getParent()->getFunction(); + auto *P = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); assert(P && "Expected personality function"); // If we are forced to emit this personality, make sure to record diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 333d14a11af5..c8cd8eb8ffd3 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units -----------===// +//===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===// // // The LLVM Compiler Infrastructure // @@ -12,38 +12,58 @@ //===----------------------------------------------------------------------===// #include "DwarfCompileUnit.h" +#include "AddressPool.h" +#include "DwarfDebug.h" #include "DwarfExpression.h" +#include "DwarfUnit.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DIE.h" +#include "llvm/CodeGen/LexicalScopes.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/IR/Constants.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DataLayout.h" -#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/GlobalVariable.h" -#include "llvm/IR/Instruction.h" -#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MachineLocation.h" +#include "llvm/Support/Casting.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Target/TargetOptions.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <iterator> +#include <memory> +#include <string> +#include <utility> -namespace llvm { +using namespace llvm; DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) - : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID), - Skeleton(nullptr), BaseAddress(nullptr) { + : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) { insertDIE(Node, &getUnitDie()); MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin"); } /// addLabelAddress - Add a dwarf label attribute data and value using /// DW_FORM_addr or DW_FORM_GNU_addr_index. -/// void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label) { - // Don't use the address pool in non-fission or in the skeleton unit itself. // FIXME: Once GDB supports this, it's probably worthwhile using the address // pool from the skeleton - maybe even in non-fission (possibly fewer @@ -336,23 +356,15 @@ void DwarfCompileUnit::constructScopeDIE( if (DD->isLexicalScopeDIENull(Scope)) return; - unsigned ChildScopeCount; + bool HasNonScopeChildren = false; // We create children here when we know the scope DIE is not going to be // null and the children will be added to the scope DIE. - createScopeChildrenDIE(Scope, Children, &ChildScopeCount); - - // Skip imported directives in gmlt-like data. - if (!includeMinimalInlineScopes()) { - // There is no need to emit empty lexical block DIE. - for (const auto *IE : ImportedEntities[DS]) - Children.push_back( - constructImportedEntityDIE(cast<DIImportedEntity>(IE))); - } + createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren); // If there are only other scopes as children, put them directly in the // parent instead, as this scope would serve no purpose. - if (Children.size() == ChildScopeCount) { + if (!HasNonScopeChildren) { FinalChildren.insert(FinalChildren.end(), std::make_move_iterator(Children.begin()), std::make_move_iterator(Children.end())); @@ -488,14 +500,12 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, if (const MachineInstr *DVInsn = DV.getMInsn()) { assert(DVInsn->getNumOperands() == 4); if (DVInsn->getOperand(0).isReg()) { - const MachineOperand RegOp = DVInsn->getOperand(0); + auto RegOp = DVInsn->getOperand(0); + auto Op1 = DVInsn->getOperand(1); // If the second operand is an immediate, this is an indirect value. - if (DVInsn->getOperand(1).isImm()) { - MachineLocation Location(RegOp.getReg(), - DVInsn->getOperand(1).getImm()); - addVariableAddress(DV, *VariableDie, Location); - } else if (RegOp.getReg()) - addVariableAddress(DV, *VariableDie, MachineLocation(RegOp.getReg())); + assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset"); + MachineLocation Location(RegOp.getReg(), Op1.isImm()); + addVariableAddress(DV, *VariableDie, Location); } else if (DVInsn->getOperand(0).isImm()) { // This variable is described by a single constant. // Check whether it has a DIExpression. @@ -557,20 +567,27 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope, SmallVectorImpl<DIE *> &Children, - unsigned *ChildScopeCount) { + bool *HasNonScopeChildren) { + assert(Children.empty()); DIE *ObjectPointer = nullptr; for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope)) Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); - unsigned ChildCountWithoutScopes = Children.size(); + // Skip imported directives in gmlt-like data. + if (!includeMinimalInlineScopes()) { + // There is no need to emit empty lexical block DIE. + for (const auto *IE : ImportedEntities[Scope->getScopeNode()]) + Children.push_back( + constructImportedEntityDIE(cast<DIImportedEntity>(IE))); + } + + if (HasNonScopeChildren) + *HasNonScopeChildren = !Children.empty(); for (LexicalScope *LS : Scope->getChildren()) constructScopeDIE(LS, Children); - if (ChildScopeCount) - *ChildScopeCount = Children.size() - ChildCountWithoutScopes; - return ObjectPointer; } @@ -726,7 +743,7 @@ DbgVariable *DwarfCompileUnit::getExistingAbstractVariable( void DwarfCompileUnit::createAbstractVariable(const DILocalVariable *Var, LexicalScope *Scope) { assert(Scope && Scope->isAbstractScope()); - auto AbsDbgVariable = make_unique<DbgVariable>(Var, /* IA */ nullptr); + auto AbsDbgVariable = llvm::make_unique<DbgVariable>(Var, /* IA */ nullptr); DU->addScopeVariable(Scope, AbsDbgVariable.get()); getAbstractVariables()[Var] = std::move(AbsDbgVariable); } @@ -744,10 +761,19 @@ void DwarfCompileUnit::emitHeader(bool UseOffsets) { DwarfUnit::emitCommonHeader(UseOffsets, UT); } +bool DwarfCompileUnit::hasDwarfPubSections() const { + // Opting in to GNU Pubnames/types overrides the default to ensure these are + // generated for things like Gold's gdb_index generation. + if (CUNode->getGnuPubnames()) + return true; + + return DD->tuneForGDB() && !includeMinimalInlineScopes(); +} + /// addGlobalName - Add a new global name to the compile unit. void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Name.str(); GlobalNames[FullName] = &Die; @@ -755,7 +781,7 @@ void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die, void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Name.str(); // Insert, allowing the entry to remain as-is if it's already present @@ -768,7 +794,7 @@ void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name, /// Add a new global type to the unit. void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Ty->getName().str(); GlobalTypes[FullName] = &Die; @@ -776,7 +802,7 @@ void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die, void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context) { - if (!DD->hasDwarfPubSections(includeMinimalInlineScopes())) + if (!hasDwarfPubSections()) return; std::string FullName = getParentContextString(Context) + Ty->getName().str(); // Insert, allowing the entry to remain as-is if it's already present @@ -790,6 +816,12 @@ void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty, /// DbgVariable based on provided MachineLocation. void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die, MachineLocation Location) { + // addBlockByrefAddress is obsolete and will be removed soon. + // The clang frontend always generates block byref variables with a + // complex expression that encodes exactly what addBlockByrefAddress + // would do. + assert((!DV.isBlockByrefVariable() || DV.hasComplexAddress()) && + "block byref variable without a complex expression"); if (DV.hasComplexAddress()) addComplexAddress(DV, Die, dwarf::DW_AT_location, Location); else if (DV.isBlockByrefVariable()) @@ -806,12 +838,7 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute, if (Location.isIndirect()) DwarfExpr.setMemoryLocationKind(); - SmallVector<uint64_t, 8> Ops; - if (Location.isIndirect() && Location.getOffset()) { - Ops.push_back(dwarf::DW_OP_plus_uconst); - Ops.push_back(Location.getOffset()); - } - DIExpressionCursor Cursor(Ops); + DIExpressionCursor Cursor({}); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; @@ -835,13 +862,7 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, if (Location.isIndirect()) DwarfExpr.setMemoryLocationKind(); - SmallVector<uint64_t, 8> Ops; - if (Location.isIndirect() && Location.getOffset()) { - Ops.push_back(dwarf::DW_OP_plus_uconst); - Ops.push_back(Location.getOffset()); - } - Ops.append(DIExpr->elements_begin(), DIExpr->elements_end()); - DIExpressionCursor Cursor(Ops); + DIExpressionCursor Cursor(DIExpr); const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; @@ -898,4 +919,3 @@ bool DwarfCompileUnit::includeMinimalInlineScopes() const { return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly || (DD->useSplitDwarf() && !Skeleton); } -} // end llvm namespace diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index e38672792867..68482eb7e358 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfCompileUnit.h - Dwarf Compile Unit ---*- C++ -*--===// +//===- llvm/CodeGen/DwarfCompileUnit.h - Dwarf Compile Unit -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,19 +14,32 @@ #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H +#include "DbgValueHistoryCalculator.h" +#include "DwarfDebug.h" #include "DwarfUnit.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/IR/DebugInfo.h" +#include "llvm/CodeGen/DIE.h" +#include "llvm/CodeGen/LexicalScopes.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/Support/Casting.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <memory> namespace llvm { -class StringRef; class AsmPrinter; -class DIE; -class DwarfDebug; class DwarfFile; +class GlobalVariable; +class MCExpr; class MCSymbol; -class LexicalScope; +class MDNode; class DwarfCompileUnit final : public DwarfUnit { /// A numeric ID unique among all CUs in the module @@ -37,7 +50,7 @@ class DwarfCompileUnit final : public DwarfUnit { DIE::value_iterator StmtListValue; /// Skeleton unit associated with this unit. - DwarfCompileUnit *Skeleton; + DwarfCompileUnit *Skeleton = nullptr; /// The start of the unit within its section. MCSymbol *LabelBegin; @@ -45,9 +58,8 @@ class DwarfCompileUnit final : public DwarfUnit { /// The start of the unit macro info within macro section. MCSymbol *MacroLabelBegin; - typedef llvm::SmallVector<const MDNode *, 8> ImportedEntityList; - typedef llvm::DenseMap<const MDNode *, ImportedEntityList> - ImportedEntityMap; + using ImportedEntityList = SmallVector<const MDNode *, 8>; + using ImportedEntityMap = DenseMap<const MDNode *, ImportedEntityList>; ImportedEntityMap ImportedEntities; @@ -66,7 +78,7 @@ class DwarfCompileUnit final : public DwarfUnit { // The base address of this unit, if any. Used for relative references in // ranges/locs. - const MCSymbol *BaseAddress; + const MCSymbol *BaseAddress = nullptr; DenseMap<const MDNode *, DIE *> AbstractSPDies; DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables; @@ -164,6 +176,7 @@ public: void attachRangesOrLowHighPC(DIE &D, const SmallVectorImpl<InsnRange> &Ranges); + /// \brief This scope represents inlined body of a function. Construct /// DIE to represent this concrete inlined copy of the function. DIE *constructInlinedScopeDIE(LexicalScope *Scope); @@ -181,7 +194,7 @@ public: /// A helper function to create children of a Scope DIE. DIE *createScopeChildrenDIE(LexicalScope *Scope, SmallVectorImpl<DIE *> &Children, - unsigned *ChildScopeCount = nullptr); + bool *HasNonScopeChildren = nullptr); /// \brief Construct a DIE for this subprogram scope. void constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope); @@ -195,8 +208,9 @@ public: void finishSubprogramDefinition(const DISubprogram *SP); void finishVariableDefinition(const DbgVariable &Var); + /// Find abstract variable associated with Var. - typedef DbgValueHistoryMap::InlinedVariable InlinedVariable; + using InlinedVariable = DbgValueHistoryMap::InlinedVariable; DbgVariable *getExistingAbstractVariable(InlinedVariable IV, const DILocalVariable *&Cleansed); DbgVariable *getExistingAbstractVariable(InlinedVariable IV); @@ -275,8 +289,10 @@ public: void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; } const MCSymbol *getBaseAddress() const { return BaseAddress; } + + bool hasDwarfPubSections() const; }; -} // end llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index f1b4d9f20ca9..2c9c7d4f3146 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ---------------===// +//===- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ----------------===// // // The LLVM Compiler Infrastructure // @@ -15,43 +15,67 @@ #include "ByteStreamer.h" #include "DIEHash.h" #include "DebugLocEntry.h" +#include "DebugLocStream.h" +#include "DwarfAccelTable.h" #include "DwarfCompileUnit.h" #include "DwarfExpression.h" +#include "DwarfFile.h" #include "DwarfUnit.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DIE.h" +#include "llvm/CodeGen/LexicalScopes.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DebugInfo.h" -#include "llvm/IR/Instructions.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Module.h" -#include "llvm/IR/ValueHandle.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/MC/MachineLocation.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Pass.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" -#include "llvm/Support/Path.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <string> +#include <utility> +#include <vector> using namespace llvm; @@ -61,10 +85,9 @@ static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, cl::desc("Disable debug info printing")); -static cl::opt<bool> -GenerateGnuPubSections("generate-gnu-dwarf-pub-sections", cl::Hidden, - cl::desc("Generate GNU-style pubnames and pubtypes"), - cl::init(false)); +static cl::opt<bool> UseDwarfRangesBaseAddressSpecifier( + "use-dwarf-ranges-base-address-specifier", cl::Hidden, + cl::desc("Use base address specifiers in debug_ranges"), cl::init(false)); static cl::opt<bool> GenerateARangeSection("generate-arange-section", cl::Hidden, @@ -75,9 +98,7 @@ static cl::opt<bool> SplitDwarfCrossCuReferences( "split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false)); -namespace { enum DefaultOnOff { Default, Enable, Disable }; -} static cl::opt<DefaultOnOff> UnknownLocations( "use-unknown-locations", cl::Hidden, @@ -94,19 +115,12 @@ DwarfAccelTables("dwarf-accel-tables", cl::Hidden, clEnumVal(Disable, "Disabled")), cl::init(Default)); -static cl::opt<DefaultOnOff> -DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden, - cl::desc("Generate DWARF pubnames and pubtypes sections"), - cl::values(clEnumVal(Default, "Default for platform"), - clEnumVal(Enable, "Enabled"), - clEnumVal(Disable, "Disabled")), - cl::init(Default)); - enum LinkageNameOption { DefaultLinkageNames, AllLinkageNames, AbstractLinkageNames }; + static cl::opt<LinkageNameOption> DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, cl::desc("Which DWARF linkage-name attributes to emit."), @@ -142,8 +156,6 @@ bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI, return false; } -//===----------------------------------------------------------------------===// - bool DbgVariable::isBlockByrefVariable() const { assert(Var && "Invalid complex DbgVariable!"); return Var->getType().resolve()->isBlockByrefStruct(); @@ -198,17 +210,54 @@ ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const { if (FrameIndexExprs.size() == 1) return FrameIndexExprs; - assert(all_of(FrameIndexExprs, - [](const FrameIndexExpr &A) { return A.Expr->isFragment(); }) && + assert(llvm::all_of(FrameIndexExprs, + [](const FrameIndexExpr &A) { + return A.Expr->isFragment(); + }) && "multiple FI expressions without DW_OP_LLVM_fragment"); std::sort(FrameIndexExprs.begin(), FrameIndexExprs.end(), [](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool { return A.Expr->getFragmentInfo()->OffsetInBits < B.Expr->getFragmentInfo()->OffsetInBits; }); + return FrameIndexExprs; } +void DbgVariable::addMMIEntry(const DbgVariable &V) { + assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry"); + assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry"); + assert(V.Var == Var && "conflicting variable"); + assert(V.IA == IA && "conflicting inlined-at location"); + + assert(!FrameIndexExprs.empty() && "Expected an MMI entry"); + assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry"); + + // FIXME: This logic should not be necessary anymore, as we now have proper + // deduplication. However, without it, we currently run into the assertion + // below, which means that we are likely dealing with broken input, i.e. two + // non-fragment entries for the same variable at different frame indices. + if (FrameIndexExprs.size()) { + auto *Expr = FrameIndexExprs.back().Expr; + if (!Expr || !Expr->isFragment()) + return; + } + + for (const auto &FIE : V.FrameIndexExprs) + // Ignore duplicate entries. + if (llvm::none_of(FrameIndexExprs, [&](const FrameIndexExpr &Other) { + return FIE.FI == Other.FI && FIE.Expr == Other.Expr; + })) + FrameIndexExprs.push_back(FIE); + + assert((FrameIndexExprs.size() == 1 || + llvm::all_of(FrameIndexExprs, + [](FrameIndexExpr &FIE) { + return FIE.Expr && FIE.Expr->isFragment(); + })) && + "conflicting locations for variable"); +} + static const DwarfAccelTable::Atom TypeAtoms[] = { DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4), DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2), @@ -225,9 +274,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) dwarf::DW_FORM_data4)), AccelNamespace(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), - AccelTypes(TypeAtoms), DebuggerTuning(DebuggerKind::Default) { - - CurFn = nullptr; + AccelTypes(TypeAtoms) { const Triple &TT = Asm->TM.getTargetTriple(); // Make sure we know our "debugger tuning." The target option takes @@ -278,7 +325,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) } // Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h. -DwarfDebug::~DwarfDebug() { } +DwarfDebug::~DwarfDebug() = default; static bool isObjCClass(StringRef Name) { return Name.startswith("+") || Name.startswith("-"); @@ -389,20 +436,8 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, } } -bool DwarfDebug::hasDwarfPubSections(bool includeMinimalInlineScopes) const { - // Opting in to GNU Pubnames/types overrides the default to ensure these are - // generated for things like Gold's gdb_index generation. - if (GenerateGnuPubSections) - return true; - - if (DwarfPubSections == Default) - return tuneForGDB() && !includeMinimalInlineScopes; - - return DwarfPubSections == Enable; -} - void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const { - if (!hasDwarfPubSections(U.includeMinimalInlineScopes())) + if (!U.hasDwarfPubSections()) return; U.addFlag(D, dwarf::DW_AT_GNU_pubnames); @@ -417,7 +452,7 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { StringRef FN = DIUnit->getFilename(); CompilationDir = DIUnit->getDirectory(); - auto OwnedUnit = make_unique<DwarfCompileUnit>( + auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>( InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder); DwarfCompileUnit &NewCU = *OwnedUnit; DIE &Die = NewCU.getUnitDie(); @@ -428,6 +463,9 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { Asm->TM.Options.MCOptions.SplitDwarfFile); } + 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 @@ -494,6 +532,8 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { 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)); } @@ -503,13 +543,18 @@ static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> & sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) { std::sort(GVEs.begin(), GVEs.end(), [](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) { - if (A.Expr != B.Expr && A.Expr && B.Expr) { - auto FragmentA = A.Expr->getFragmentInfo(); - auto FragmentB = B.Expr->getFragmentInfo(); - if (FragmentA && FragmentB) - return FragmentA->OffsetInBits < FragmentB->OffsetInBits; - } - return false; + // Sort order: first null exprs, then exprs without fragment + // info, then sort by fragment offset in bits. + // FIXME: Come up with a more comprehensive comparator so + // the sorting isn't non-deterministic, and so the following + // std::unique call works correctly. + if (!A.Expr || !B.Expr) + return !!B.Expr; + auto FragmentA = A.Expr->getFragmentInfo(); + auto FragmentB = B.Expr->getFragmentInfo(); + if (!FragmentA || !FragmentB) + return !!FragmentB; + return FragmentA->OffsetInBits < FragmentB->OffsetInBits; }); GVEs.erase(std::unique(GVEs.begin(), GVEs.end(), [](DwarfCompileUnit::GlobalExpr A, @@ -546,18 +591,31 @@ void DwarfDebug::beginModule() { } for (DICompileUnit *CUNode : M->debug_compile_units()) { - if (CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() && - CUNode->getGlobalVariables().empty() && - CUNode->getImportedEntities().empty() && CUNode->getMacros().empty()) + // 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() && + CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty()) continue; DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(CUNode); - for (auto *IE : CUNode->getImportedEntities()) - CU.addImportedEntity(IE); // Global Variables. - for (auto *GVE : CUNode->getGlobalVariables()) - GVMap[GVE->getVariable()].push_back({nullptr, GVE->getExpression()}); + for (auto *GVE : CUNode->getGlobalVariables()) { + // Don't bother adding DIGlobalVariableExpressions listed in the CU if we + // already know about the variable and it isn't adding a constant + // expression. + auto &GVMapEntry = GVMap[GVE->getVariable()]; + auto *Expr = GVE->getExpression(); + if (!GVMapEntry.size() || (Expr && Expr->isConstant())) + GVMapEntry.push_back({nullptr, Expr}); + } DenseSet<DIGlobalVariable *> Processed; for (auto *GVE : CUNode->getGlobalVariables()) { DIGlobalVariable *GV = GVE->getVariable(); @@ -682,6 +740,11 @@ void DwarfDebug::finalizeModuleInfo() { TLOF.getDwarfMacinfoSection()->getBeginSymbol()); } + // Emit all frontend-produced Skeleton CUs, i.e., Clang modules. + for (auto *CUNode : MMI->getModule()->debug_compile_units()) + if (CUNode->getDWOId()) + getOrCreateDwarfCompileUnit(CUNode); + // Compute DIE offsets and sizes. InfoHolder.computeSizeAndOffsets(); if (useSplitDwarf()) @@ -744,12 +807,7 @@ void DwarfDebug::endModule() { } // Emit the pubnames and pubtypes sections if requested. - // The condition is optimistically correct - any CU not using GMLT (& - // implicit/default pubnames state) might still have pubnames. - if (hasDwarfPubSections(/* gmlt */ false)) { - emitDebugPubNames(GenerateGnuPubSections); - emitDebugPubTypes(GenerateGnuPubSections); - } + emitDebugPubSections(); // clean up. // FIXME: AbstractVariables.clear(); @@ -775,9 +833,11 @@ void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU, LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode))) CU.createAbstractVariable(Cleansed, Scope); } + // Collect variable information from side table maintained by MF. void DwarfDebug::collectVariableInfoFromMFTable( DwarfCompileUnit &TheCU, DenseSet<InlinedVariable> &Processed) { + SmallDenseMap<InlinedVariable, DbgVariable *> MFVars; for (const auto &VI : Asm->MF->getVariableDbgInfo()) { if (!VI.Var) continue; @@ -793,26 +853,28 @@ void DwarfDebug::collectVariableInfoFromMFTable( continue; ensureAbstractVariableIsCreatedIfScoped(TheCU, Var, Scope->getScopeNode()); - auto RegVar = make_unique<DbgVariable>(Var.first, Var.second); + auto RegVar = llvm::make_unique<DbgVariable>(Var.first, Var.second); RegVar->initializeMMI(VI.Expr, VI.Slot); - if (InfoHolder.addScopeVariable(Scope, RegVar.get())) + if (DbgVariable *DbgVar = MFVars.lookup(Var)) + DbgVar->addMMIEntry(*RegVar); + else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) { + MFVars.insert({Var, RegVar.get()}); ConcreteVariables.push_back(std::move(RegVar)); + } } } // Get .debug_loc entry for the instruction range starting at MI. static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) { const DIExpression *Expr = MI->getDebugExpression(); - assert(MI->getNumOperands() == 4); if (MI->getOperand(0).isReg()) { - MachineLocation MLoc; + auto RegOp = MI->getOperand(0); + auto Op1 = MI->getOperand(1); // If the second operand is an immediate, this is a // register-indirect address. - if (!MI->getOperand(1).isImm()) - MLoc.set(MI->getOperand(0).getReg()); - else - MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); + assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset"); + MachineLocation MLoc(RegOp.getReg(), Op1.isImm()); return DebugLocEntry::Value(Expr, MLoc); } if (MI->getOperand(0).isImm()) @@ -967,7 +1029,8 @@ DbgVariable *DwarfDebug::createConcreteVariable(DwarfCompileUnit &TheCU, LexicalScope &Scope, InlinedVariable IV) { ensureAbstractVariableIsCreatedIfScoped(TheCU, IV, Scope.getScopeNode()); - ConcreteVariables.push_back(make_unique<DbgVariable>(IV.first, IV.second)); + ConcreteVariables.push_back( + llvm::make_unique<DbgVariable>(IV.first, IV.second)); InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get()); return ConcreteVariables.back().get(); } @@ -1100,7 +1163,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { DebugHandlerBase::beginInstruction(MI); assert(CurMI); - const auto *SP = MI->getParent()->getParent()->getFunction()->getSubprogram(); + const auto *SP = MI->getMF()->getFunction().getSubprogram(); if (!SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug) return; @@ -1198,7 +1261,7 @@ static DebugLoc findPrologueEndLoc(const MachineFunction *MF) { void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) { CurFn = MF; - auto *SP = MF->getFunction()->getSubprogram(); + auto *SP = MF->getFunction().getSubprogram(); assert(LScopes.empty() || SP == LScopes.getCurrentFunctionScope()->getScopeNode()); if (SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug) return; @@ -1234,7 +1297,7 @@ void DwarfDebug::skippedNonDebugFunction() { // Gather and emit post-function debug information. void DwarfDebug::endFunctionImpl(const MachineFunction *MF) { - const DISubprogram *SP = MF->getFunction()->getSubprogram(); + const DISubprogram *SP = MF->getFunction().getSubprogram(); assert(CurFn == MF && "endFunction should be called with the same function as beginFunction"); @@ -1309,8 +1372,8 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, if (auto *Scope = cast_or_null<DIScope>(S)) { Fn = Scope->getFilename(); Dir = Scope->getDirectory(); - if (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope)) - if (getDwarfVersion() >= 4) + if (Line != 0 && getDwarfVersion() >= 4) + if (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope)) Discriminator = LBF->getDiscriminator(); unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID(); @@ -1440,84 +1503,74 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, } } -/// emitDebugPubNames - Emit visible names into a debug pubnames section. -/// -void DwarfDebug::emitDebugPubNames(bool GnuStyle) { - MCSection *PSec = GnuStyle - ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() - : Asm->getObjFileLowering().getDwarfPubNamesSection(); - - emitDebugPubSection(GnuStyle, PSec, "Names", - &DwarfCompileUnit::getGlobalNames); -} - -void DwarfDebug::emitDebugPubSection( - bool GnuStyle, MCSection *PSec, StringRef Name, - const StringMap<const DIE *> &(DwarfCompileUnit::*Accessor)() const) { +/// emitDebugPubSections - Emit visible names and types into debug pubnames and +/// pubtypes sections. +void DwarfDebug::emitDebugPubSections() { for (const auto &NU : CUMap) { DwarfCompileUnit *TheU = NU.second; - - const auto &Globals = (TheU->*Accessor)(); - - if (!hasDwarfPubSections(TheU->includeMinimalInlineScopes())) + if (!TheU->hasDwarfPubSections()) continue; - if (auto *Skeleton = TheU->getSkeleton()) - TheU = Skeleton; + bool GnuStyle = TheU->getCUNode()->getGnuPubnames(); - // Start the dwarf pubnames section. - Asm->OutStreamer->SwitchSection(PSec); + Asm->OutStreamer->SwitchSection( + GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() + : Asm->getObjFileLowering().getDwarfPubNamesSection()); + emitDebugPubSection(GnuStyle, "Names", TheU, TheU->getGlobalNames()); - // Emit the header. - Asm->OutStreamer->AddComment("Length of Public " + Name + " Info"); - MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin"); - MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end"); - Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); + Asm->OutStreamer->SwitchSection( + GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() + : Asm->getObjFileLowering().getDwarfPubTypesSection()); + emitDebugPubSection(GnuStyle, "Types", TheU, TheU->getGlobalTypes()); + } +} - Asm->OutStreamer->EmitLabel(BeginLabel); +void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name, + DwarfCompileUnit *TheU, + const StringMap<const DIE *> &Globals) { + if (auto *Skeleton = TheU->getSkeleton()) + TheU = Skeleton; - Asm->OutStreamer->AddComment("DWARF Version"); - Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); + // Emit the header. + Asm->OutStreamer->AddComment("Length of Public " + Name + " Info"); + MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin"); + MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end"); + Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); - Asm->OutStreamer->AddComment("Offset of Compilation Unit Info"); - Asm->emitDwarfSymbolReference(TheU->getLabelBegin()); + Asm->OutStreamer->EmitLabel(BeginLabel); - Asm->OutStreamer->AddComment("Compilation Unit Length"); - Asm->EmitInt32(TheU->getLength()); + Asm->OutStreamer->AddComment("DWARF Version"); + Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); - // Emit the pubnames for this compilation unit. - for (const auto &GI : Globals) { - const char *Name = GI.getKeyData(); - const DIE *Entity = GI.second; + Asm->OutStreamer->AddComment("Offset of Compilation Unit Info"); + Asm->emitDwarfSymbolReference(TheU->getLabelBegin()); - Asm->OutStreamer->AddComment("DIE offset"); - Asm->EmitInt32(Entity->getOffset()); + Asm->OutStreamer->AddComment("Compilation Unit Length"); + Asm->EmitInt32(TheU->getLength()); - if (GnuStyle) { - dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); - Asm->OutStreamer->AddComment( - Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + - dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); - Asm->EmitInt8(Desc.toBits()); - } + // Emit the pubnames for this compilation unit. + for (const auto &GI : Globals) { + const char *Name = GI.getKeyData(); + const DIE *Entity = GI.second; + + Asm->OutStreamer->AddComment("DIE offset"); + Asm->EmitInt32(Entity->getOffset()); - Asm->OutStreamer->AddComment("External Name"); - Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1)); + if (GnuStyle) { + dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); + Asm->OutStreamer->AddComment( + Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " + + dwarf::GDBIndexEntryLinkageString(Desc.Linkage)); + Asm->EmitInt8(Desc.toBits()); } - Asm->OutStreamer->AddComment("End Mark"); - Asm->EmitInt32(0); - Asm->OutStreamer->EmitLabel(EndLabel); + Asm->OutStreamer->AddComment("External Name"); + Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1)); } -} - -void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { - MCSection *PSec = GnuStyle - ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() - : Asm->getObjFileLowering().getDwarfPubTypesSection(); - emitDebugPubSection(GnuStyle, PSec, "Types", - &DwarfCompileUnit::getGlobalTypes); + Asm->OutStreamer->AddComment("End Mark"); + Asm->EmitInt32(0); + Asm->OutStreamer->EmitLabel(EndLabel); } /// Emit null-terminated strings into a debug str section. @@ -1553,13 +1606,7 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, MachineLocation Location = Value.getLoc(); if (Location.isIndirect()) DwarfExpr.setMemoryLocationKind(); - SmallVector<uint64_t, 8> Ops; - if (Location.isIndirect() && Location.getOffset()) { - Ops.push_back(dwarf::DW_OP_plus_uconst); - Ops.push_back(Location.getOffset()); - } - Ops.append(DIExpr->elements_begin(), DIExpr->elements_end()); - DIExpressionCursor Cursor(Ops); + DIExpressionCursor Cursor(DIExpr); const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) return; @@ -1580,7 +1627,7 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, const DebugLocEntry::Value &Value = Values[0]; if (Value.isFragment()) { // Emit all fragments that belong to the same variable and range. - assert(all_of(Values, [](DebugLocEntry::Value P) { + assert(llvm::all_of(Values, [](DebugLocEntry::Value P) { return P.isFragment(); }) && "all values are expected to be fragments"); assert(std::is_sorted(Values.begin(), Values.end()) && @@ -1844,17 +1891,49 @@ void DwarfDebug::emitDebugRanges() { // Emit our symbol so we can find the beginning of the range. Asm->OutStreamer->EmitLabel(List.getSym()); + // Gather all the ranges that apply to the same section so they can share + // a base address entry. + MapVector<const MCSection *, std::vector<const RangeSpan *>> MV; for (const RangeSpan &Range : List.getRanges()) { - const MCSymbol *Begin = Range.getStart(); - const MCSymbol *End = Range.getEnd(); - assert(Begin && "Range without a begin symbol?"); - assert(End && "Range without an end symbol?"); - if (auto *Base = TheCU->getBaseAddress()) { - Asm->EmitLabelDifference(Begin, Base, Size); - Asm->EmitLabelDifference(End, Base, Size); - } else { - Asm->OutStreamer->EmitSymbolValue(Begin, Size); - Asm->OutStreamer->EmitSymbolValue(End, Size); + MV[&Range.getStart()->getSection()].push_back(&Range); + } + + auto *CUBase = TheCU->getBaseAddress(); + bool BaseIsSet = false; + for (const auto &P : MV) { + // Don't bother with a base address entry if there's only one range in + // this section in this range list - for example ranges for a CU will + // usually consist of single regions from each of many sections + // (-ffunction-sections, or just C++ inline functions) except under LTO + // or optnone where there may be holes in a single CU's section + // contrubutions. + auto *Base = CUBase; + if (!Base && P.second.size() > 1 && + UseDwarfRangesBaseAddressSpecifier) { + BaseIsSet = true; + // FIXME/use care: This may not be a useful base address if it's not + // the lowest address/range in this object. + Base = P.second.front()->getStart(); + Asm->OutStreamer->EmitIntValue(-1, Size); + Asm->OutStreamer->EmitSymbolValue(Base, Size); + } else if (BaseIsSet) { + BaseIsSet = false; + Asm->OutStreamer->EmitIntValue(-1, Size); + Asm->OutStreamer->EmitIntValue(0, Size); + } + + for (const auto *RS : P.second) { + const MCSymbol *Begin = RS->getStart(); + const MCSymbol *End = RS->getEnd(); + assert(Begin && "Range without a begin symbol?"); + assert(End && "Range without an end symbol?"); + if (Base) { + Asm->EmitLabelDifference(Begin, Base, Size); + Asm->EmitLabelDifference(End, Base, Size); + } else { + Asm->OutStreamer->EmitSymbolValue(Begin, Size); + Asm->OutStreamer->EmitSymbolValue(End, Size); + } } } @@ -1943,7 +2022,7 @@ void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die, // DW_AT_addr_base, DW_AT_ranges_base. DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) { - auto OwnedUnit = make_unique<DwarfCompileUnit>( + auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>( CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder); DwarfCompileUnit &NewCU = *OwnedUnit; NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection()); @@ -2024,8 +2103,8 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, bool TopLevelType = TypeUnitsUnderConstruction.empty(); AddrPool.resetUsedFlag(); - auto OwnedUnit = make_unique<DwarfTypeUnit>(CU, Asm, this, &InfoHolder, - getDwoLineTable(CU)); + auto OwnedUnit = llvm::make_unique<DwarfTypeUnit>(CU, Asm, this, &InfoHolder, + getDwoLineTable(CU)); DwarfTypeUnit &NewTU = *OwnedUnit; DIE &UnitDie = NewTU.getUnitDie(); TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 78ee9a162029..2ae0b418a91e 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfDebug.h - Dwarf Debug Framework ------*- C++ -*--===// +//===- llvm/CodeGen/DwarfDebug.h - Dwarf Debug Framework --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,40 +14,52 @@ #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H +#include "AddressPool.h" #include "DbgValueHistoryCalculator.h" #include "DebugHandlerBase.h" #include "DebugLocStream.h" #include "DwarfAccelTable.h" #include "DwarfFile.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/CodeGen/DIE.h" -#include "llvm/CodeGen/LexicalScopes.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/Metadata.h" #include "llvm/MC/MCDwarf.h" -#include "llvm/MC/MachineLocation.h" #include "llvm/Support/Allocator.h" #include "llvm/Target/TargetOptions.h" +#include <cassert> +#include <cstdint> +#include <limits> #include <memory> +#include <utility> +#include <vector> namespace llvm { class AsmPrinter; class ByteStreamer; -class ConstantInt; -class ConstantFP; class DebugLocEntry; +class DIE; class DwarfCompileUnit; -class DwarfDebug; class DwarfTypeUnit; class DwarfUnit; -class MachineModuleInfo; +class LexicalScope; +class MachineFunction; +class MCSection; +class MCSymbol; +class MDNode; +class Module; //===----------------------------------------------------------------------===// /// This class is used to track local variable information. @@ -89,7 +101,7 @@ public: assert(!MInsn && "Already initialized?"); assert((!E || E->isValid()) && "Expected valid expression"); - assert(FI != INT_MAX && "Expected valid index"); + assert(FI != std::numeric_limits<int>::max() && "Expected valid index"); FrameIndexExprs.push_back({FI, E}); } @@ -111,10 +123,12 @@ public: // Accessors. const DILocalVariable *getVariable() const { return Var; } const DILocation *getInlinedAt() const { return IA; } + const DIExpression *getSingleExpression() const { assert(MInsn && FrameIndexExprs.size() <= 1); return FrameIndexExprs.size() ? FrameIndexExprs[0].Expr : nullptr; } + void setDIE(DIE &D) { TheDIE = &D; } DIE *getDIE() const { return TheDIE; } void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; } @@ -124,30 +138,7 @@ public: /// Get the FI entries, sorted by fragment offset. ArrayRef<FrameIndexExpr> getFrameIndexExprs() const; bool hasFrameIndexExprs() const { return !FrameIndexExprs.empty(); } - - void addMMIEntry(const DbgVariable &V) { - assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry"); - assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry"); - assert(V.Var == Var && "conflicting variable"); - assert(V.IA == IA && "conflicting inlined-at location"); - - assert(!FrameIndexExprs.empty() && "Expected an MMI entry"); - assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry"); - - if (FrameIndexExprs.size()) { - auto *Expr = FrameIndexExprs.back().Expr; - // Get rid of duplicate non-fragment entries. More than one non-fragment - // dbg.declare makes no sense so ignore all but the first. - if (!Expr || !Expr->isFragment()) - return; - } - FrameIndexExprs.append(V.FrameIndexExprs.begin(), V.FrameIndexExprs.end()); - assert(all_of(FrameIndexExprs, - [](FrameIndexExpr &FIE) { - return FIE.Expr && FIE.Expr->isFragment(); - }) && - "conflicting locations for variable"); - } + void addMMIEntry(const DbgVariable &V); // Translate tag to proper Dwarf tag. dwarf::Tag getTag() const { @@ -157,6 +148,7 @@ public: return dwarf::DW_TAG_variable; } + /// Return true if DbgVariable is artificial. bool isArtificial() const { if (Var->isArtificial()) @@ -182,6 +174,7 @@ public: "Invalid Expr for DBG_VALUE"); return !FrameIndexExprs.empty(); } + bool isBlockByrefVariable() const; const DIType *getType() const; @@ -191,10 +184,10 @@ private: } }; - /// Helper used to pair up a symbol and its DWARF compile unit. struct SymbolCU { SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {} + const MCSymbol *Sym; DwarfCompileUnit *CU; }; @@ -230,7 +223,7 @@ class DwarfDebug : public DebugHandlerBase { ProcessedSPNodes; /// If nonnull, stores the current machine function we're processing. - const MachineFunction *CurFn; + const MachineFunction *CurFn = nullptr; /// If nonnull, stores the CU in which the previous subprogram was contained. const DwarfCompileUnit *PrevCU; @@ -296,17 +289,7 @@ class DwarfDebug : public DebugHandlerBase { DwarfAccelTable AccelTypes; // Identify a debugger for "tuning" the debug info. - DebuggerKind DebuggerTuning; - - /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. - /// - /// Returns whether we are "tuning" for a given debugger. - /// Should be used only within the constructor, to set feature flags. - /// @{ - bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; } - bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } - bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } - /// @} + DebuggerKind DebuggerTuning = DebuggerKind::Default; MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); @@ -314,7 +297,7 @@ class DwarfDebug : public DebugHandlerBase { return InfoHolder.getUnits(); } - typedef DbgValueHistoryMap::InlinedVariable InlinedVariable; + using InlinedVariable = DbgValueHistoryMap::InlinedVariable; void ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable Var, const MDNode *Scope); @@ -358,21 +341,12 @@ class DwarfDebug : public DebugHandlerBase { /// Emit type dies into a hashed accelerator table. void emitAccelTypes(); - /// Emit visible names into a debug pubnames section. - /// \param GnuStyle determines whether or not we want to emit - /// additional information into the table ala newer gcc for gdb - /// index. - void emitDebugPubNames(bool GnuStyle = false); + /// Emit visible names and types into debug pubnames and pubtypes sections. + void emitDebugPubSections(); - /// Emit visible types into a debug pubtypes section. - /// \param GnuStyle determines whether or not we want to emit - /// additional information into the table ala newer gcc for gdb - /// index. - void emitDebugPubTypes(bool GnuStyle = false); - - void emitDebugPubSection( - bool GnuStyle, MCSection *PSec, StringRef Name, - const StringMap<const DIE *> &(DwarfCompileUnit::*Accessor)() const); + void emitDebugPubSection(bool GnuStyle, StringRef Name, + DwarfCompileUnit *TheU, + const StringMap<const DIE *> &Globals); /// Emit null-terminated strings into a debug str section. void emitDebugStr(); @@ -561,11 +535,19 @@ public: /// going to be null. bool isLexicalScopeDIENull(LexicalScope *Scope); - bool hasDwarfPubSections(bool includeMinimalInlineScopes) const; - /// Find the matching DwarfCompileUnit for the given CU DIE. DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); } + + /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. + /// + /// Returns whether we are "tuning" for a given debugger. + /// @{ + bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; } + bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } + bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } + /// @} }; -} // End of namespace llvm -#endif +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 3a8568cf39ae..68d25fe37b43 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework ----------===// +//===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===// // // The LLVM Compiler Infrastructure // @@ -12,13 +12,15 @@ //===----------------------------------------------------------------------===// #include "DwarfExpression.h" -#include "DwarfDebug.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/Support/ErrorHandling.h" +#include <algorithm> +#include <cassert> +#include <cstdint> using namespace llvm; @@ -128,6 +130,8 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI, unsigned Size = TRI.getSubRegIdxSize(Idx); unsigned Offset = TRI.getSubRegIdxOffset(Idx); Reg = TRI.getDwarfRegNum(*SR, false); + if (Reg < 0) + continue; // Intersection between the bits we already emitted and the bits // covered by this subregister. @@ -136,14 +140,14 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI, // If this sub-register has a DWARF number and we haven't covered // its range, emit a DWARF piece for it. - if (Reg >= 0 && CurSubReg.test(Coverage)) { + if (CurSubReg.test(Coverage)) { // Emit a piece for any gap in the coverage. if (Offset > CurPos) DwarfRegs.push_back({-1, Offset - CurPos, nullptr}); DwarfRegs.push_back( {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"}); if (Offset >= MaxSize) - break; + break; // Mark it as emitted. Coverage.set(Offset, Offset + Size); @@ -336,9 +340,10 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, break; case dwarf::DW_OP_plus: case dwarf::DW_OP_minus: + case dwarf::DW_OP_mul: emitOp(Op->getOp()); break; - case dwarf::DW_OP_deref: { + case dwarf::DW_OP_deref: assert(LocationKind != Register); if (LocationKind != Memory && isMemoryLocation(ExprCursor)) // Turning this into a memory location description makes the deref @@ -347,7 +352,6 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, else emitOp(dwarf::DW_OP_deref); break; - } case dwarf::DW_OP_constu: assert(LocationKind != Register); emitOp(dwarf::DW_OP_constu); @@ -383,7 +387,6 @@ void DwarfExpression::maskSubRegister() { addAnd(Mask); } - void DwarfExpression::finalize() { assert(DwarfRegs.size() == 0 && "dwarf registers not emitted"); // Emit any outstanding DW_OP_piece operations to mask out subregisters. diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index 728f8ad9225b..ea5cbc40ba35 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===// +//===- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,21 +14,29 @@ #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H -#include "llvm/IR/DebugInfo.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include <cassert> +#include <cstdint> +#include <iterator> namespace llvm { class AsmPrinter; +class APInt; class ByteStreamer; -class TargetRegisterInfo; class DwarfUnit; class DIELoc; +class TargetRegisterInfo; /// Holds a DIExpression and keeps track of how many operands have been consumed /// so far. class DIExpressionCursor { DIExpression::expr_op_iterator Start, End; + public: DIExpressionCursor(const DIExpression *Expr) { if (!Expr) { @@ -42,8 +50,7 @@ public: DIExpressionCursor(ArrayRef<uint64_t> Expr) : Start(Expr.begin()), End(Expr.end()) {} - DIExpressionCursor(const DIExpressionCursor &C) - : Start(C.Start), End(C.End) {} + DIExpressionCursor(const DIExpressionCursor &) = default; /// Consume one operation. Optional<DIExpression::ExprOperand> take() { @@ -73,8 +80,10 @@ public: return *Next; } + /// Determine whether there are any operations left in this expression. operator bool() const { return Start != End; } + DIExpression::expr_op_iterator begin() const { return Start; } DIExpression::expr_op_iterator end() const { return End; } @@ -122,10 +131,13 @@ protected: /// Output a dwarf operand and an optional assembler comment. virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0; + /// Emit a raw signed value. virtual void emitSigned(int64_t Value) = 0; + /// Emit a raw unsigned value. virtual void emitUnsigned(uint64_t Value) = 0; + /// Return whether the given machine register is the frame register in the /// current function. virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0; @@ -133,8 +145,10 @@ protected: /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF /// register location description. void addReg(int DwarfReg, const char *Comment = nullptr); + /// Emit a DW_OP_breg operation. void addBReg(int DwarfReg, int Offset); + /// Emit DW_OP_fbreg <Offset>. void addFBReg(int Offset); @@ -156,7 +170,6 @@ protected: bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg, unsigned MaxSize = ~1U); - /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment. /// \param OffsetInBits This is an optional offset into the location that /// is at the top of the DWARF stack. @@ -164,6 +177,7 @@ protected: /// Emit a shift-right dwarf operation. void addShr(unsigned ShiftBy); + /// Emit a bitwise and dwarf operation. void addAnd(unsigned Mask); @@ -181,6 +195,7 @@ protected: void addStackValue(); ~DwarfExpression() = default; + public: DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {} @@ -189,8 +204,10 @@ public: /// Emit a signed constant. void addSignedConstant(int64_t Value); + /// Emit an unsigned constant. void addUnsignedConstant(uint64_t Value); + /// Emit an unsigned constant. void addUnsignedConstant(const APInt &Value); @@ -213,6 +230,7 @@ public: bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, unsigned MachineReg, unsigned FragmentOffsetInBits = 0); + /// Emit all remaining operations in the DIExpressionCursor. /// /// \param FragmentOffsetInBits If this is one fragment out of multiple @@ -235,6 +253,7 @@ class DebugLocDwarfExpression final : public DwarfExpression { void emitUnsigned(uint64_t Value) override; bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) override; + public: DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS) : DwarfExpression(DwarfVersion), BS(BS) {} @@ -253,11 +272,13 @@ const AsmPrinter &AP; unsigned MachineReg) override; public: DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE); + DIELoc *finalize() { DwarfExpression::finalize(); return &DIE; } }; -} -#endif +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp index 595f1d91c4bf..3c04c969192d 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework ----------------===// +//===- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework -----------------===// // // The LLVM Compiler Infrastructure // @@ -11,13 +11,16 @@ #include "DwarfCompileUnit.h" #include "DwarfDebug.h" #include "DwarfUnit.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/IR/DataLayout.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DIE.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/Support/LEB128.h" -#include "llvm/Target/TargetLoweringObjectFile.h" +#include <algorithm> +#include <cstdint> + +using namespace llvm; -namespace llvm { DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA) : Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {} @@ -113,4 +116,3 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { Vars.push_back(Var); return true; } -} diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h index 54924e9806ed..167ca13c19c1 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfFile.h - Dwarf Debug Framework -------*- C++ -*--===// +//===- llvm/CodeGen/DwarfFile.h - Dwarf Debug Framework ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,30 +10,25 @@ #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H -#include "AddressPool.h" #include "DwarfStringPool.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/DIE.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/Allocator.h" #include <memory> +#include <utility> namespace llvm { + class AsmPrinter; class DbgVariable; class DwarfCompileUnit; class DwarfUnit; -class DIEAbbrev; -class MCSymbol; -class DIE; class LexicalScope; -class StringRef; -class DwarfDebug; class MCSection; -class MDNode; + class DwarfFile { // Target of Dwarf emission, used for sizing of abbreviations. AsmPrinter *Asm; @@ -106,6 +101,7 @@ public: DenseMap<const MDNode *, DIE *> &getAbstractSPDies() { return AbstractSPDies; } + DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> &getAbstractVariables() { return AbstractVariables; } @@ -113,9 +109,12 @@ public: void insertDIE(const MDNode *TypeMD, DIE *Die) { DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die)); } + DIE *getDIE(const MDNode *TypeMD) { return DITypeNodeToDieMap.lookup(TypeMD); } }; -} -#endif + +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp index 2066f745e318..aa5f01e88933 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework ----------===// +//===- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework -----------===// // // The LLVM Compiler Infrastructure // @@ -8,9 +8,14 @@ //===----------------------------------------------------------------------===// #include "DwarfStringPool.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCStreamer.h" +#include <cassert> +#include <utility> using namespace llvm; diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h index 93a168485a54..1cac3b7c8432 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfStringPool.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/DwarfStringPool.h - Dwarf Debug Framework -*- C++ -*--===// +//===- llvm/CodeGen/DwarfStringPool.h - Dwarf Debug Framework ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,29 +11,28 @@ #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFSTRINGPOOL_H #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/DwarfStringPoolEntry.h" #include "llvm/Support/Allocator.h" -#include <utility> namespace llvm { class AsmPrinter; -class MCSymbol; class MCSection; -class StringRef; // Collection of strings for this unit and assorted symbols. // A String->Symbol mapping of strings used by indirect // references. class DwarfStringPool { - typedef DwarfStringPoolEntry EntryTy; + using EntryTy = DwarfStringPoolEntry; + StringMap<EntryTy, BumpPtrAllocator &> Pool; StringRef Prefix; unsigned NumBytes = 0; bool ShouldCreateSymbols; public: - typedef DwarfStringPoolEntryRef EntryRef; + using EntryRef = DwarfStringPoolEntryRef; DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix); @@ -45,5 +44,7 @@ public: /// Get a reference to an entry in the string pool. EntryRef getEntry(AsmPrinter &Asm, StringRef Str); }; -} -#endif + +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFSTRINGPOOL_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 4f4ebfc56297..911e46235781 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -22,6 +22,9 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalValue.h" @@ -33,9 +36,6 @@ #include "llvm/MC/MachineLocation.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include <cassert> #include <cstdint> #include <string> @@ -473,11 +473,7 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die, if (Location.isIndirect()) DwarfExpr.setMemoryLocationKind(); - SmallVector<uint64_t, 9> Ops; - if (Location.isIndirect() && Location.getOffset()) { - Ops.push_back(dwarf::DW_OP_plus_uconst); - Ops.push_back(Location.getOffset()); - } + SmallVector<uint64_t, 6> Ops; // If we started with a pointer to the __Block_byref... struct, then // the first thing we need to do is dereference the pointer (DW_OP_deref). if (isPointer) @@ -964,8 +960,9 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) { // This is outside the DWARF spec, but GDB expects a DW_AT_containing_type // inside C++ composite types to point to the base class with the vtable. - if (auto *ContainingType = - dyn_cast_or_null<DICompositeType>(resolve(CTy->getVTableHolder()))) + // Rust uses DW_AT_containing_type to link a vtable to the type + // for which it was created. + if (auto *ContainingType = resolve(CTy->getVTableHolder())) addDIEEntry(Buffer, dwarf::DW_AT_containing_type, *getOrCreateTypeDIE(ContainingType)); diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp index e14d5be1177a..3cdab57bca70 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp @@ -1,4 +1,4 @@ -//===-- CodeGen/AsmPrinter/EHStreamer.cpp - Exception Directive Streamer --===// +//===- CodeGen/AsmPrinter/EHStreamer.cpp - Exception Directive Streamer ---===// // // The LLVM Compiler Infrastructure // @@ -12,22 +12,34 @@ //===----------------------------------------------------------------------===// #include "EHStreamer.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Twine.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineOperand.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/LEB128.h" -#include "llvm/Target/TargetLoweringObjectFile.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <vector> using namespace llvm; EHStreamer::EHStreamer(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} -EHStreamer::~EHStreamer() {} +EHStreamer::~EHStreamer() = default; /// How many leading type ids two landing pads have in common. unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L, @@ -50,7 +62,6 @@ unsigned EHStreamer:: computeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, SmallVectorImpl<ActionEntry> &Actions, SmallVectorImpl<unsigned> &FirstActions) { - // The action table follows the call-site table in the LSDA. The individual // records are of two types: // @@ -478,13 +489,14 @@ void EHStreamer::emitExceptionTable() { sizeof(int8_t) + // TType format (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size TTypeBaseOffset; // TType base offset - unsigned SizeAlign = (4 - TotalSize) & 3; + unsigned PadBytes = (4 - TotalSize) & 3; if (HaveTTData) { // Account for any extra padding that will be added to the call site table // length. - Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign); - SizeAlign = 0; + Asm->EmitPaddedULEB128(TTypeBaseOffset, TTypeBaseOffsetSize + PadBytes, + "@TType base offset"); + PadBytes = 0; } bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); @@ -494,7 +506,9 @@ void EHStreamer::emitExceptionTable() { Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); // Add extra padding if it wasn't added to the TType base offset. - Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); + Asm->EmitPaddedULEB128(CallSiteTableLength, + CallSiteTableLengthSize + PadBytes, + "Call site table length"); // Emit the landing pad site information. unsigned idx = 0; @@ -547,7 +561,9 @@ void EHStreamer::emitExceptionTable() { Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); // Add extra padding if it wasn't added to the TType base offset. - Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); + Asm->EmitPaddedULEB128(CallSiteTableLength, + CallSiteTableLengthSize + PadBytes, + "Call site table length"); unsigned Entry = 0; for (SmallVectorImpl<CallSiteEntry>::const_iterator diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h index 080fdd14b467..7962b761d8de 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h @@ -1,4 +1,4 @@ -//===-- EHStreamer.h - Exception Handling Directive Streamer ---*- C++ -*--===// +//===- EHStreamer.h - Exception Handling Directive Streamer -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,17 +16,16 @@ #include "AsmPrinterHandler.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Compiler.h" namespace llvm { + +class AsmPrinter; struct LandingPadInfo; -class MachineModuleInfo; class MachineInstr; -class MachineFunction; +class MachineModuleInfo; class MCSymbol; -class MCSymbolRefExpr; - -template <typename T> -class SmallVectorImpl; +template <typename T> class SmallVectorImpl; /// Emits exception handling directives. class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler { @@ -45,11 +44,12 @@ protected: struct PadRange { // The index of the landing pad. unsigned PadIndex; + // The index of the begin and end labels in the landing pad's label lists. unsigned RangeIndex; }; - typedef DenseMap<MCSymbol *, PadRange> RangeMapType; + using RangeMapType = DenseMap<MCSymbol *, PadRange>; /// Structure describing an entry in the actions table. struct ActionEntry { @@ -66,6 +66,7 @@ protected: // LPad contains the landing pad start labels. const LandingPadInfo *LPad; // Null indicates that there is no landing pad. + unsigned Action; }; @@ -131,7 +132,7 @@ public: /// `false' otherwise. static bool callToNoUnwindFunction(const MachineInstr *MI); }; -} -#endif +} // end namespace llvm +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp index c5795559fb7d..e459c02c9a6e 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp @@ -19,6 +19,7 @@ #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/GCs.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" @@ -26,7 +27,6 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Target/TargetLoweringObjectFile.h" using namespace llvm; diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp index 035f1a0063aa..e0cc241dd23f 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/GCMetadata.h" #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/CodeGen/GCs.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/Mangler.h" @@ -26,7 +27,6 @@ #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Target/TargetLoweringObjectFile.h" #include <cctype> #include <cstddef> #include <cstdint> diff --git a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 5d485f213573..a6a8e84a949f 100644 --- a/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/contrib/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "WinException.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/Dwarf.h" @@ -20,6 +19,10 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/CodeGen/TargetLoweringObjectFile.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/CodeGen/WinEHFuncInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Mangler.h" @@ -30,15 +33,9 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCWin64EH.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; WinException::WinException(AsmPrinter *A) : EHStreamer(A) { @@ -66,7 +63,7 @@ void WinException::beginFunction(const MachineFunction *MF) { bool hasLandingPads = !MF->getLandingPads().empty(); bool hasEHFunclets = MF->hasEHFunclets(); - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); shouldEmitMoves = Asm->needsSEHMoves() && MF->hasWinCFI(); @@ -75,14 +72,14 @@ void WinException::beginFunction(const MachineFunction *MF) { EHPersonality Per = EHPersonality::Unknown; const Function *PerFn = nullptr; - if (F->hasPersonalityFn()) { - PerFn = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); + if (F.hasPersonalityFn()) { + PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); Per = classifyEHPersonality(PerFn); } - bool forceEmitPersonality = F->hasPersonalityFn() && + bool forceEmitPersonality = F.hasPersonalityFn() && !isNoOpWithoutInvoke(Per) && - F->needsUnwindTableEntry(); + F.needsUnwindTableEntry(); shouldEmitPersonality = forceEmitPersonality || ((hasLandingPads || hasEHFunclets) && @@ -101,7 +98,7 @@ void WinException::beginFunction(const MachineFunction *MF) { // functions may still refer to it. const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); StringRef FLinkageName = - GlobalValue::dropLLVMManglingEscape(MF->getFunction()->getName()); + GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName); } shouldEmitLSDA = hasEHFunclets; @@ -118,10 +115,10 @@ void WinException::endFunction(const MachineFunction *MF) { if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA) return; - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); EHPersonality Per = EHPersonality::Unknown; - if (F->hasPersonalityFn()) - Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts()); + if (F.hasPersonalityFn()) + Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts()); // Get rid of any dead landing pads if we're not using funclets. In funclet // schemes, the landing pad is not actually reachable. It only exists so @@ -173,8 +170,8 @@ static MCSymbol *getMCSymbolForMBB(AsmPrinter *Asm, // Give catches and cleanups a name based off of their parent function and // their funclet entry block's number. const MachineFunction *MF = MBB->getParent(); - const Function *F = MF->getFunction(); - StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName()); + const Function &F = MF->getFunction(); + StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); MCContext &Ctx = MF->getContext(); StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch"; return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" + @@ -186,7 +183,7 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) { CurrentFuncletEntry = &MBB; - const Function *F = Asm->MF->getFunction(); + const Function &F = Asm->MF->getFunction(); // If a symbol was not provided for the funclet, invent one. if (!Sym) { Sym = getMCSymbolForMBB(Asm, &MBB); @@ -201,7 +198,7 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB, // We want our funclet's entry point to be aligned such that no nops will be // present after the label. Asm->EmitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()), - F); + &F); // Now that we've emitted the alignment directive, point at our funclet. Asm->OutStreamer->EmitLabel(Sym); @@ -218,8 +215,8 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB, const Function *PerFn = nullptr; // Determine which personality routine we are using for this funclet. - if (F->hasPersonalityFn()) - PerFn = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); + if (F.hasPersonalityFn()) + PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); const MCSymbol *PersHandlerSym = TLOF.getCFIPersonalitySymbol(PerFn, Asm->TM, MMI); @@ -240,10 +237,10 @@ void WinException::endFunclet() { const MachineFunction *MF = Asm->MF; if (shouldEmitMoves || shouldEmitPersonality) { - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); EHPersonality Per = EHPersonality::Unknown; - if (F->hasPersonalityFn()) - Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts()); + if (F.hasPersonalityFn()) + Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts()); // Emit an UNWIND_INFO struct describing the prologue. Asm->OutStreamer->EmitWinEHHandlerData(); @@ -252,7 +249,7 @@ void WinException::endFunclet() { !CurrentFuncletEntry->isCleanupFuncletEntry()) { // If this is a C++ catch funclet (or the parent function), // emit a reference to the LSDA for the parent function. - StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName()); + StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol( Twine("$cppxdata$", FuncLinkageName)); Asm->OutStreamer->EmitValue(create32bitRef(FuncInfoXData), 4); @@ -536,7 +533,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { // Emit a label assignment with the SEH frame offset so we can use it for // llvm.x86.seh.recoverfp. StringRef FLinkageName = - GlobalValue::dropLLVMManglingEscape(MF->getFunction()->getName()); + GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName()); MCSymbol *ParentFrameOffset = Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName); const MCExpr *MCOffset = @@ -631,11 +628,11 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo, } void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { - const Function *F = MF->getFunction(); + const Function &F = MF->getFunction(); auto &OS = *Asm->OutStreamer; const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo(); - StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName()); + StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); SmallVector<std::pair<const MCExpr *, int>, 4> IPToStateTable; MCSymbol *FuncInfoXData = nullptr; @@ -941,8 +938,8 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo, /// indexed by state number instead of IP. void WinException::emitExceptHandlerTable(const MachineFunction *MF) { MCStreamer &OS = *Asm->OutStreamer; - const Function *F = MF->getFunction(); - StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName()); + const Function &F = MF->getFunction(); + StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName()); bool VerboseAsm = OS.isVerboseAsm(); auto AddComment = [&](const Twine &Comment) { @@ -959,7 +956,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) { OS.EmitLabel(LSDALabel); const Function *Per = - dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts()); + dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()); StringRef PerName = Per->getName(); int BaseState = -1; if (PerName == "_except_handler4") { |