65#define DEBUG_TYPE "dwarfdebug"
67STATISTIC(NumCSParams,
"Number of dbg call site params created");
70 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
80 cl::desc(
"Generate DWARF4 type units."),
91 cl::desc(
"Make an absence of debug location information explicit."),
99 "Default for platform"),
100 clEnumValN(AccelTableKind::None,
"Disable",
"Disabled."),
101 clEnumValN(AccelTableKind::Apple,
"Apple",
"Apple"),
102 clEnumValN(AccelTableKind::Dwarf,
"Dwarf",
"DWARF")),
107 cl::desc(
"Use inlined strings rather than string section."),
115 cl::desc(
"Disable emission .debug_ranges section."),
120 cl::desc(
"Use sections+offset as references rather than labels."),
127 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
132 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
145 cl::desc(
"Which DWARF linkage-name attributes to emit."),
147 "Default for platform"),
150 "Abstract subprograms")),
155 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
156 "address pool entry sharing to reduce relocations/object size"),
158 "Default address minimization strategy"),
159 clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges,
"Ranges",
160 "Use rnglists for contiguous ranges if that allows "
161 "using a pre-existing base address"),
162 clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions,
164 "Use exprloc addrx+offset expressions for any "
165 "address with a prior base address"),
166 clEnumValN(DwarfDebug::MinimizeAddrInV5::Form,
"Form",
167 "Use addrx+offset extension form for any address "
168 "with a prior base address"),
169 clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled,
"Disabled",
171 cl::init(DwarfDebug::MinimizeAddrInV5::Default));
175void DebugLocDwarfExpression::emitOp(
uint8_t Op,
const char *Comment) {
181void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
193void DebugLocDwarfExpression::emitBaseTypeRef(
uint64_t Idx) {
204void DebugLocDwarfExpression::enableTemporaryBuffer() {
205 assert(!IsBuffering &&
"Already buffering?");
211void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering =
false; }
213unsigned DebugLocDwarfExpression::getTemporaryBufferSize() {
214 return TmpBuf ? TmpBuf->Bytes.size() : 0;
217void DebugLocDwarfExpression::commitTemporaryBuffer() {
220 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
221 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
222 ? TmpBuf->Comments[
Byte.index()].c_str()
226 TmpBuf->Bytes.clear();
227 TmpBuf->Comments.clear();
238 const bool IsVariadic = !SingleLocExprOpt;
241 if (!IsVariadic && !
MI->isNonListDebugValue()) {
242 assert(
MI->getNumDebugOperands() == 1 &&
243 "Mismatched DIExpression and debug operands for debug instruction.");
244 Expr = *SingleLocExprOpt;
251 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
253 }
else if (
Op.isTargetIndex()) {
256 }
else if (
Op.isImm())
258 else if (
Op.isFPImm())
260 else if (
Op.isCImm())
265 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
269 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
270 return Fragment ? Fragment->OffsetInBits : 0;
284 Expr(ValueLoc.getExpression()) {
293 return FrameIndexExprs;
297 FrameIndexExprs.insert({FI, Expr});
298 assert((FrameIndexExprs.size() == 1 ||
301 return FIE.Expr && FIE.Expr->isFragment();
303 "conflicting locations for variable");
307 bool GenerateTypeUnits,
316 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
322 if (DwarfVersion >= 5)
332 InfoHolder(
A,
"info_string", DIEValueAllocator),
333 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
334 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()) {
345 else if (TT.isOSAIX())
351 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
370 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
376 bool Dwarf64 = DwarfVersion >= 3 &&
386 TT.isOSBinFormatELF()) ||
387 TT.isOSBinFormatXCOFF();
389 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
396 UseSectionsAsReferences = TT.isNVPTX();
401 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
402 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
406 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
413 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
415 UseDWARF2Bitfields = DwarfVersion < 4;
421 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
429 UseDebugMacroSection =
438 if (DwarfVersion >= 5)
450 return Name.starts_with(
"+") ||
Name.starts_with(
"-");
457 return Name.contains(
") ");
463 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
468 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
469 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
473 return In.slice(In.find(
' ') + 1, In.find(
']'));
486 if (!SP->isDefinition())
495 if (SP->getLinkageName() !=
"" && SP->
getName() != SP->getLinkageName() &&
497 addAccelName(Unit, NameTableKind, SP->getLinkageName(), Die);
515 if (Scope->isAbstractScope())
533 if (
auto *SkelCU =
CU.getSkeleton())
534 if (
CU.getCUNode()->getSplitDebugInlining())
542void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
544 assert(Scope && Scope->getScopeNode());
545 assert(Scope->isAbstractScope());
546 assert(!Scope->getInlinedAt());
548 auto *SP = cast<DISubprogram>(Scope->getScopeNode());
556 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
557 if (
auto *SkelCU =
CU.getSkeleton()) {
559 .constructAbstractSubprogramScopeDIE(Scope);
560 if (
CU.getCUNode()->getSplitDebugInlining())
561 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
563 CU.constructAbstractSubprogramScopeDIE(Scope);
598template <
typename ValT>
602 for (
auto Param : DescribedParams) {
603 bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0;
618 "Combined debug expression is invalid");
633 auto &ParamsForFwdReg = Worklist[Reg];
634 for (
auto Param : ParamsToAdd) {
637 return D.ParamReg == Param.ParamReg;
639 "Same parameter described twice by forwarding reg");
646 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
689 if (
MI.isDebugInstr())
693 if (MO.getReg().isPhysical()) {
694 for (
auto &FwdReg : ForwardedRegWorklist)
695 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
696 Defs.
insert(FwdReg.first);
698 NewClobberedRegUnits.
insert(Unit);
706 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
707 if (FwdRegDefs.
empty()) {
709 ClobberedRegUnits.
insert(NewClobberedRegUnits.
begin(),
710 NewClobberedRegUnits.
end());
717 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
718 for (
auto &RegUnit : ClobberedRegUnits)
719 if (
TRI.hasRegUnit(Reg, RegUnit))
724 for (
auto ParamFwdReg : FwdRegDefs) {
725 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
726 if (ParamValue->first.isImm()) {
727 int64_t Val = ParamValue->first.getImm();
729 ForwardedRegWorklist[ParamFwdReg], Params);
730 }
else if (ParamValue->first.isReg()) {
731 Register RegLoc = ParamValue->first.getReg();
732 Register SP = TLI.getStackPointerRegisterToSaveRestore();
734 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
735 if (!IsRegClobberedInMeantime(RegLoc) &&
736 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
739 ForwardedRegWorklist[ParamFwdReg], Params);
748 ForwardedRegWorklist[ParamFwdReg]);
755 for (
auto ParamFwdReg : FwdRegDefs)
756 ForwardedRegWorklist.
erase(ParamFwdReg);
759 ClobberedRegUnits.
insert(NewClobberedRegUnits.
begin(),
760 NewClobberedRegUnits.
end());
764 for (
auto &New : TmpWorklistItems)
766 TmpWorklistItems.
clear();
783 if (ForwardedRegWorklist.
empty())
790 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
801 auto CSInfo = CalleesMap.
find(CallMI);
804 if (CSInfo == CalleesMap.end())
818 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
820 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
822 assert(InsertedReg &&
"Single register used to forward two arguments?");
827 for (
const auto &MO : CallMI->
uses())
828 if (MO.isReg() && MO.isUndef())
829 ForwardedRegWorklist.
erase(MO.getReg());
848 assert(std::next(Suc) == BundleEnd &&
849 "More than one instruction in call delay slot");
863 if (ShouldTryEmitEntryVals) {
867 for (
auto &RegEntry : ForwardedRegWorklist) {
874void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
879 if (!SP.areAllCallsDescribed() || !SP.isDefinition())
886 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
889 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
893 if (!
MI.isBundledWithSucc())
895 auto Suc = std::next(
MI.getIterator());
897 (void)CallInstrBundle;
899 (void)DelaySlotBundle;
906 "Call and its successor instruction don't have same label after.");
921 if (!
MI.isCandidateForCallSiteEntry())
930 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
941 unsigned CallReg = 0;
943 const Function *CalleeDecl =
nullptr;
944 if (CalleeOp.
isReg()) {
945 CallReg = CalleeOp.
getReg();
949 CalleeDecl = dyn_cast<Function>(CalleeOp.
getGlobal());
970 (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
979 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
982 << (CalleeDecl ? CalleeDecl->
getName()
986 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
988 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
989 ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg);
996 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1003 if (!
U.hasDwarfPubSections())
1006 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1009void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1017 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1018 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1020 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1022 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1024 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1026 if (!SysRoot.
empty())
1027 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1030 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1041 if (!CompilationDir.
empty())
1042 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1043 addGnuPubAttributes(NewCU, Die);
1048 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1052 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1055 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1056 dwarf::DW_FORM_data1, RVer);
1061 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1066 ? dwarf::DW_AT_dwo_name
1067 : dwarf::DW_AT_GNU_dwo_name;
1075DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1076 if (
auto *
CU = CUMap.lookup(DIUnit))
1084 return *CUMap.begin()->second;
1088 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1089 InfoHolder.
getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1091 InfoHolder.
addUnit(std::move(OwnedUnit));
1106 finishUnitAttributes(DIUnit, NewCU);
1110 CUMap.insert({DIUnit, &NewCU});
1111 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1125 if (!
A.Expr || !
B.Expr)
1127 auto FragmentA =
A.Expr->getFragmentInfo();
1128 auto FragmentB =
B.Expr->getFragmentInfo();
1129 if (!FragmentA || !FragmentB)
1131 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1136 return A.Expr ==
B.Expr;
1151 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1152 M->debug_compile_units_end());
1153 if (NumDebugCUs == 0)
1156 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1157 SingleCU = NumDebugCUs == 1;
1162 Global.getDebugInfo(GVs);
1163 for (
auto *GVE : GVs)
1164 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1193 if (CUNode->getImportedEntities().empty() &&
1194 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1195 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1201 for (
auto *GVE : CUNode->getGlobalVariables()) {
1205 auto &GVMapEntry = GVMap[GVE->getVariable()];
1206 auto *Expr = GVE->getExpression();
1207 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1208 GVMapEntry.push_back({
nullptr, Expr});
1212 for (
auto *GVE : CUNode->getGlobalVariables()) {
1214 if (Processed.
insert(GV).second)
1218 for (
auto *Ty : CUNode->getEnumTypes())
1219 CU.getOrCreateTypeDIE(cast<DIType>(Ty));
1221 for (
auto *Ty : CUNode->getRetainedTypes()) {
1224 if (
DIType *RT = dyn_cast<DIType>(Ty))
1226 CU.getOrCreateTypeDIE(RT);
1231void DwarfDebug::finishEntityDefinitions() {
1232 for (
const auto &Entity : ConcreteEntities) {
1233 DIE *Die = Entity->getDIE();
1240 Unit->finishEntityDefinition(Entity.get());
1244void DwarfDebug::finishSubprogramDefinitions() {
1248 getOrCreateDwarfCompileUnit(SP->getUnit()),
1253void DwarfDebug::finalizeModuleInfo() {
1256 finishSubprogramDefinitions();
1258 finishEntityDefinitions();
1260 bool HasEmittedSplitCU =
false;
1264 for (
const auto &
P : CUMap) {
1265 auto &TheCU = *
P.second;
1266 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1270 TheCU.constructContainingTypeDIEs();
1275 auto *SkCU = TheCU.getSkeleton();
1277 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1280 (void)HasEmittedSplitCU;
1282 "Multiple CUs emitted into a single dwo file");
1283 HasEmittedSplitCU =
true;
1285 ? dwarf::DW_AT_dwo_name
1286 : dwarf::DW_AT_GNU_dwo_name;
1287 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1289 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1290 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1301 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1302 dwarf::DW_FORM_data8,
ID);
1303 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1304 dwarf::DW_FORM_data8,
ID);
1309 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1313 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1324 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1335 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1338 U.setBaseAddress(TheCU.getRanges().front().Begin);
1339 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1346 U.addAddrTableBase();
1349 if (
U.hasRangeLists())
1350 U.addRnglistsBase();
1353 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1359 auto *CUNode = cast<DICompileUnit>(
P.first);
1362 if (CUNode->getMacros()) {
1363 if (UseDebugMacroSection) {
1365 TheCU.addSectionDelta(
1366 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1370 ? dwarf::DW_AT_macros
1371 : dwarf::DW_AT_GNU_macros;
1372 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1377 TheCU.addSectionDelta(
1378 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1379 U.getMacroLabelBegin(),
1382 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1383 U.getMacroLabelBegin(),
1391 if (CUNode->getDWOId())
1392 getOrCreateDwarfCompileUnit(CUNode);
1410 assert(CurFn ==
nullptr);
1413 for (
const auto &
P : CUMap) {
1414 const auto *CUNode = cast<DICompileUnit>(
P.first);
1418 for (
auto *IE : CUNode->getImportedEntities()) {
1419 assert(!isa_and_nonnull<DILocalScope>(IE->getScope()) &&
1420 "Unexpected function-local entity in 'imports' CU field.");
1421 CU->getOrCreateImportedEntityDIE(IE);
1423 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1424 if (
auto *IE = dyn_cast<DIImportedEntity>(
D))
1425 CU->getOrCreateImportedEntityDIE(IE);
1431 CU->createBaseTypeDIEs();
1440 finalizeModuleInfo();
1450 emitAbbreviations();
1456 if (UseARangesSection)
1464 emitDebugMacinfoDWO();
1474 emitDebugAbbrevDWO();
1476 emitDebugRangesDWO();
1486 emitAccelNamespaces();
1490 emitAccelDebugNames();
1499 emitDebugPubSections();
1507 if (
CU.getExistingAbstractEntity(Node))
1512 CU.createAbstractEntity(Node, Scope);
1517 if (
const auto *LV = dyn_cast<DILocalVariable>(
N))
1519 else if (
const auto *L = dyn_cast<DILabel>(
N))
1521 else if (
const auto *IE = dyn_cast<DIImportedEntity>(
N))
1527 return cast<DILocalScope>(S)->getNonLexicalBlockFileScope();
1531void DwarfDebug::collectVariableInfoFromMFTable(
1534 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1538 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1539 "Expected inlined-at fields to agree");
1541 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1548 <<
", no variable scope found\n");
1552 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1557 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1558 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1560 if (PreviousMMI &&
VI.inStackSlot())
1561 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1563 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1564 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1569 if (PreviousLoc->holds<
Loc::MMI>())
1573 <<
", conflicting fragment location types\n");
1578 auto RegVar = std::make_unique<DbgVariable>(
1579 cast<DILocalVariable>(Var.first), Var.second);
1580 if (
VI.inStackSlot())
1587 MFVars.
insert({Var, RegVar.get()});
1588 ConcreteEntities.push_back(std::move(RegVar));
1600 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1608 if (LSRange.size() == 0)
1611 const MachineInstr *LScopeBegin = LSRange.front().first;
1615 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1621 for (++Pred; Pred !=
MBB->
rend(); ++Pred) {
1624 auto PredDL = Pred->getDebugLoc();
1625 if (!PredDL || Pred->isMetaInstruction())
1629 if (
DL->getScope() == PredDL->getScope())
1632 if (!PredScope || LScope->dominates(PredScope))
1652 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1696 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1698 bool isSafeForSingleLocation =
true;
1702 for (
auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {
1706 size_t Index = std::distance(EB, EI);
1707 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1714 "Forgot label before/after instruction starting a range!");
1717 if (std::next(EI) == Entries.end()) {
1720 if (EI->isClobber())
1721 EndMI = EI->getInstr();
1723 else if (std::next(EI)->isClobber())
1727 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1729 if (EI->isDbgValue())
1735 if (EI->isDbgValue()) {
1742 if (!
Instr->isUndefDebugValue()) {
1747 if (
Instr->getDebugExpression()->isFragment())
1748 isSafeForSingleLocation =
false;
1751 StartDebugMI =
Instr;
1753 isSafeForSingleLocation =
false;
1759 if (OpenRanges.
empty())
1763 if (StartLabel == EndLabel) {
1764 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1769 for (
auto &R : OpenRanges)
1779 for (
const auto &[MBBSectionId, MBBSectionRange] :
1781 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1782 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1785 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1786 MBBSectionRange.EndLabel, Values);
1789 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1796 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1797 for (
auto &
Value : CurEntry->getValues())
1799 dbgs() <<
"-----\n";
1802 auto PrevEntry = std::next(CurEntry);
1803 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1807 if (!isSafeForSingleLocation ||
1826 RangeMBB = Entries.begin()->getInstr()->getParent();
1829 "Range MBB not found in MBBSectionRanges!");
1831 auto *NextEntry = std::next(CurEntry);
1832 auto NextRangeIt = std::next(RangeIt);
1833 while (NextEntry !=
DebugLoc.end()) {
1842 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1843 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1844 CurEntry->getValues() != NextEntry->getValues())
1846 RangeIt = NextRangeIt;
1847 NextRangeIt = std::next(RangeIt);
1848 CurEntry = NextEntry;
1849 NextEntry = std::next(CurEntry);
1859 ensureAbstractEntityIsCreatedIfScoped(TheCU,
Node,
Scope.getScopeNode());
1860 if (isa<const DILocalVariable>(
Node)) {
1861 ConcreteEntities.push_back(
1862 std::make_unique<DbgVariable>(cast<const DILocalVariable>(
Node),
1865 cast<DbgVariable>(ConcreteEntities.back().get()));
1866 }
else if (isa<const DILabel>(
Node)) {
1867 ConcreteEntities.push_back(
1868 std::make_unique<DbgLabel>(cast<const DILabel>(
Node),
1871 cast<DbgLabel>(ConcreteEntities.back().get()));
1873 return ConcreteEntities.back().get();
1881 collectVariableInfoFromMFTable(TheCU, Processed);
1884 InlinedEntity
IV =
I.first;
1889 const auto &HistoryMapEntries =
I.second;
1907 DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
1908 *Scope, LocalVar,
IV.second));
1910 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1916 size_t HistSize = HistoryMapEntries.size();
1917 bool SingleValueWithClobber =
1918 HistSize == 2 && HistoryMapEntries[1].isClobber();
1919 if (HistSize == 1 || SingleValueWithClobber) {
1921 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1933 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1938 if (isValidSingleLocation) {
1939 RegVar->emplace<
Loc::Single>(Entries[0].getValues()[0]);
1950 for (
auto &Entry : Entries)
1957 InlinedEntity IL =
I.first;
1966 Label->getScope()->getNonLexicalBlockFileScope();
1981 createConcreteEntity(TheCU, *Scope, Label, IL.second,
Sym);
1985 for (
const DINode *DN : SP->getRetainedNodes()) {
1987 if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
1988 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
1992 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
1994 LocalDeclsPerLS[
LS].insert(DN);
2008 if (!
MI.isBundledWithSucc())
2010 auto Suc = std::next(
MI.getIterator());
2015 assert(Suc->isBundledWithPred() &&
2016 "Call bundle instructions are out of order");
2021 if (!NoDebug && SP->areAllCallsDescribed() &&
2023 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2062 unsigned LastAsmLine =
2069 assert(
MI->getParent() == &*
MI->getMF()->begin());
2070 recordSourceLine(SP->getScopeLine(), 0, SP,
2075 bool PrevInstInSameSection =
2078 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2079 if (
DL ==
PrevInstLoc && PrevInstInSameSection && !ForceIsStmt) {
2085 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2087 const MDNode *Scope =
DL.getScope();
2088 recordSourceLine(
DL.getLine(),
DL.getCol(), Scope, Flags);
2096 if (LastAsmLine == 0)
2113 const MDNode *Scope =
nullptr;
2114 unsigned Column = 0;
2119 recordSourceLine(0, Column, Scope, 0);
2127 if (
DL.getLine() == 0 && LastAsmLine == 0)
2136 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2139 const MDNode *Scope =
DL.getScope();
2140 recordSourceLine(
DL.getLine(),
DL.getCol(), Scope, Flags);
2147static std::pair<const MachineInstr *, bool>
2157 bool IsEmptyPrologue =
2158 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2163 -> std::optional<std::pair<const MachineInstr *, bool>> {
2166 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2169 if (!isFrameSetup &&
MI.getDebugLoc()) {
2175 if (
MI.getDebugLoc().getLine())
2176 return std::make_pair(&
MI, IsEmptyPrologue);
2181 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2182 NonTrivialInst = &
MI;
2184 IsEmptyPrologue =
false;
2185 return std::nullopt;
2193 auto CurBlock = MF->
begin();
2194 auto CurInst = CurBlock->begin();
2198 while (CurBlock->empty())
2199 CurInst = (++CurBlock)->begin();
2200 assert(CurInst != CurBlock->end());
2204 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2206 if (CurInst->isTerminator()) {
2215 if (CurBlock->pred_size() > 1)
2226 if (CurBlock == MF->
end())
2228 }
while (CurBlock->empty());
2229 CurInst = CurBlock->begin();
2235 if (!CurInst->isMetaInstruction()) {
2236 auto FoundInst = ExamineInst(*CurInst);
2243 auto NextInst = std::next(CurInst);
2244 if (NextInst != CurInst->getParent()->end()) {
2261 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2262 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2263 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2267 return std::make_pair(
nullptr, IsEmptyPrologue);
2273 const MDNode *S,
unsigned Flags,
unsigned CUID,
2275 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs) {
2277 unsigned FileNo = 1;
2278 unsigned Discriminator = 0;
2279 if (
auto *Scope = cast_or_null<DIScope>(S)) {
2280 Fn = Scope->getFilename();
2281 if (Line != 0 && DwarfVersion >= 4)
2282 if (
auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
2283 Discriminator = LBF->getDiscriminator();
2286 .getOrCreateSourceID(Scope->getFile());
2288 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2300 bool IsEmptyPrologue = PrologEnd.second;
2303 if (IsEmptyPrologue) {
2311 if (!
DL ||
DL->getLine() != 0)
2322 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2335 ForceIsStmtInstrs.clear();
2374 for (
auto &
MI :
MBB) {
2375 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2377 PredMBBsToExamine.
insert(Pred);
2389 for (
auto *
MBB : PredMBBsToExamine) {
2391 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2392 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2395 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2397 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2398 ForceIsStmtInstrs.insert(
MI);
2405 CheckMBBEdge(Succ, 0);
2411 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2426 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2429 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2430 CheckMBBEdge(FBB, FBBLine);
2454 unsigned LastLine = 0;
2456 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2457 LastLine =
DL->getLine();
2462 for (
auto *Succ : SuccessorBBs)
2463 CheckMBBEdge(Succ, LastLine);
2478 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2489 findForceIsStmtInstrs(MF);
2501 return CU.getUniqueID();
2505 const auto &CURanges =
CU->getRanges();
2506 auto &LineTable =
Asm->
OutStreamer->getContext().getMCDwarfLineTable(
2509 LineTable.getMCLineSections().addEndEntry(
2510 const_cast<MCSymbol *
>(CURanges.back().End));
2529 "endFunction should be called with the same function as beginFunction");
2544 collectEntityInfo(TheCU, SP, Processed);
2549 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2570 const auto *SP = cast<DISubprogram>(AScope->getScopeNode());
2571 for (
const DINode *DN : SP->getRetainedNodes()) {
2575 assert(LexS &&
"Expected the LexicalScope to be created.");
2576 if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
2578 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2584 LocalDeclsPerLS[LS].insert(DN);
2588 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2590 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2593 ProcessedSPNodes.insert(SP);
2599 SkelCU->constructSubprogramScopeDIE(SP, FnScope, FunctionLineTableLabel);
2601 FunctionLineTableLabel =
nullptr;
2604 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2612 LocalDeclsPerLS.clear();
2619void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2621 ::recordSourceLine(*
Asm, Line, Col, S, Flags,
2631void DwarfDebug::emitDebugInfo() {
2637void DwarfDebug::emitAbbreviations() {
2643void DwarfDebug::emitStringOffsetsTableHeader() {
2650template <
typename AccelTableT>
2651void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2659void DwarfDebug::emitAccelDebugNames() {
2661 if (getUnits().empty())
2668void DwarfDebug::emitAccelNames() {
2675void DwarfDebug::emitAccelObjC() {
2681void DwarfDebug::emitAccelNamespaces() {
2682 emitAccel(AccelNamespace,
2688void DwarfDebug::emitAccelTypes() {
2719 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2727 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2734 case dwarf::DW_TAG_class_type:
2735 case dwarf::DW_TAG_structure_type:
2736 case dwarf::DW_TAG_union_type:
2737 case dwarf::DW_TAG_enumeration_type:
2743 case dwarf::DW_TAG_typedef:
2744 case dwarf::DW_TAG_base_type:
2745 case dwarf::DW_TAG_subrange_type:
2746 case dwarf::DW_TAG_template_alias:
2748 case dwarf::DW_TAG_namespace:
2750 case dwarf::DW_TAG_subprogram:
2752 case dwarf::DW_TAG_variable:
2754 case dwarf::DW_TAG_enumerator:
2764void DwarfDebug::emitDebugPubSections() {
2765 for (
const auto &NU : CUMap) {
2776 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
2781 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
2788 CU.getDebugSectionOffset());
2793void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
2801 "pub" +
Name,
"Length of Public " +
Name +
" Info");
2807 emitSectionReference(*TheU);
2814 for (
const auto &GI : Globals)
2817 return A.second->getOffset() <
B.second->getOffset();
2819 for (
const auto &[
Name, Entity] : Vec) {
2841void DwarfDebug::emitDebugStr() {
2842 MCSection *StringOffsetsSection =
nullptr;
2844 emitStringOffsetsTableHeader();
2849 StringOffsetsSection,
true);
2856 auto Comment = Comments.begin();
2857 auto End = Comments.end();
2872 for (
const auto &
Op : Expr) {
2874 "3 operand ops not yet supported");
2883 for (
unsigned J = 0; J <
Length; ++J)
2888 Streamer.
emitInt8(
Data.getData()[J], Comment !=
End ? *(Comment++) :
"");
2899 auto *DIExpr =
Value.getExpression();
2905 if (DIExpr && DIExpr->isEntryValue()) {
2922 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
2925 if (Entry.isInt()) {
2926 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
2927 BT->getEncoding() == dwarf::DW_ATE_signed_char))
2931 }
else if (Entry.isLocation()) {
2933 if (Location.isIndirect())
2939 }
else if (Entry.isTargetIndexLocation()) {
2945 }
else if (Entry.isConstantFP()) {
2948 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
2949 }
else if (Entry.getConstantFP()
2952 .getBitWidth() <= 64 ) {
2954 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
2957 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
2958 << Entry.getConstantFP()
2969 if (!
Value.isVariadic()) {
2970 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
2979 return Entry.isLocation() && !Entry.getLoc().getReg();
2984 std::move(ExprCursor),
2985 [EmitValueLocEntry, &
Value](
unsigned Idx,
2987 return EmitValueLocEntry(
Value.getLocEntries()[
Idx], Cursor);
2996 "location list entries without values are redundant");
2997 assert(Begin != End &&
"unexpected location list entry with empty range");
3002 if (
Value.isFragment()) {
3005 return P.isFragment();
3006 }) &&
"all values are expected to be fragments");
3009 for (
const auto &Fragment : Values)
3013 assert(Values.
size() == 1 &&
"only fragments may have >1 value");
3027 else if (DebugLocs.
getBytes(Entry).
size() <= std::numeric_limits<uint16_t>::max())
3047 Asm->OutStreamer->AddComment(
"Offset entry count");
3053 Asm->getDwarfOffsetByteSize());
3067 Asm->OutStreamer->AddComment(
"Offset entry count");
3068 Asm->emitInt32(DebugLocs.getLists().size());
3069 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3071 for (
const auto &
List : DebugLocs.getLists())
3072 Asm->emitLabelDifference(
List.Label, DebugLocs.getSym(),
3073 Asm->getDwarfOffsetByteSize());
3078template <
typename Ranges,
typename PayloadEmitter>
3082 unsigned StartxLength,
unsigned EndOfList,
3084 bool ShouldUseBaseAddress,
3085 PayloadEmitter EmitPayload) {
3087 auto Size = Asm->MAI->getCodePointerSize();
3091 Asm->OutStreamer->emitLabel(
Sym);
3098 for (
const auto &
Range : R)
3099 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3101 const MCSymbol *CUBase =
CU.getBaseAddress();
3102 bool BaseIsSet =
false;
3103 for (
const auto &
P : SectionRanges) {
3104 auto *
Base = CUBase;
3105 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB())) {
3115 }
else if (!
Base && ShouldUseBaseAddress) {
3116 const MCSymbol *Begin =
P.second.front()->Begin;
3121 Asm->OutStreamer->emitIntValue(-1,
Size);
3122 Asm->OutStreamer->AddComment(
" base address");
3123 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3124 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3130 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3131 Asm->emitInt8(BaseAddressx);
3132 Asm->OutStreamer->AddComment(
" base address index");
3135 }
else if (BaseIsSet && !UseDwarf5) {
3138 Asm->OutStreamer->emitIntValue(-1,
Size);
3139 Asm->OutStreamer->emitIntValue(0,
Size);
3142 for (
const auto *RS :
P.second) {
3145 assert(Begin &&
"Range without a begin symbol?");
3146 assert(
End &&
"Range without an end symbol?");
3150 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3151 Asm->emitInt8(OffsetPair);
3152 Asm->OutStreamer->AddComment(
" starting offset");
3153 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3154 Asm->OutStreamer->AddComment(
" ending offset");
3155 Asm->emitLabelDifferenceAsULEB128(
End,
Base);
3157 Asm->emitLabelDifference(Begin,
Base,
Size);
3160 }
else if (UseDwarf5) {
3161 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3162 Asm->emitInt8(StartxLength);
3163 Asm->OutStreamer->AddComment(
" start index");
3165 Asm->OutStreamer->AddComment(
" length");
3166 Asm->emitLabelDifferenceAsULEB128(
End, Begin);
3168 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3169 Asm->OutStreamer->emitSymbolValue(
End,
Size);
3176 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3180 Asm->OutStreamer->emitIntValue(0,
Size);
3181 Asm->OutStreamer->emitIntValue(0,
Size);
3188 *
List.CU, dwarf::DW_LLE_base_addressx,
3189 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
3193 DD.emitDebugLocEntryLocation(E, List.CU);
3197void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3215void DwarfDebug::emitDebugLoc() {
3223void DwarfDebug::emitDebugLocDWO() {
3263void DwarfDebug::emitDebugARanges() {
3264 if (ArangeLabels.empty())
3271 for (
const SymbolCU &SCU : ArangeLabels) {
3272 if (SCU.Sym->isInSection()) {
3274 MCSection *Section = &SCU.Sym->getSection();
3275 SectionMap[Section].push_back(SCU);
3280 SectionMap[
nullptr].push_back(SCU);
3286 for (
auto &
I : SectionMap) {
3296 Span.
Start = Cur.Sym;
3299 Spans[Cur.CU].push_back(Span);
3309 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3314 if (Cur.
CU != Prev.
CU) {
3316 Span.
Start = StartSym;
3319 Spans[Prev.
CU].push_back(Span);
3332 std::vector<DwarfCompileUnit *> CUs;
3333 for (
const auto &it : Spans) {
3340 return A->getUniqueID() <
B->getUniqueID();
3345 std::vector<ArangeSpan> &
List = Spans[
CU];
3348 if (
auto *Skel =
CU->getSkeleton())
3352 unsigned ContentSize =
3359 unsigned TupleSize = PtrSize * 2;
3366 ContentSize += (
List.size() + 1) * TupleSize;
3373 emitSectionReference(*
CU);
3389 auto SizeRef = SymSize.find(Span.Start);
3390 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3396 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3399 Size = SizeRef->second;
3415 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3416 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3418 List.CU->getCUNode()->getRangesBaseAddress() ||
3430 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3448void DwarfDebug::emitDebugRanges() {
3449 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3451 emitDebugRangesImpl(Holder,
3457void DwarfDebug::emitDebugRangesDWO() {
3458 emitDebugRangesImpl(InfoHolder,
3466 enum HeaderFlagMask {
3467#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3468#include "llvm/BinaryFormat/Dwarf.def"
3470 Asm->OutStreamer->AddComment(
"Macro information version");
3471 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3474 if (Asm->isDwarf64()) {
3475 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3476 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3478 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3479 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3481 Asm->OutStreamer->AddComment(
"debug_line_offset");
3483 Asm->emitDwarfLengthOrOffset(0);
3485 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3488void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3489 for (
auto *MN : Nodes) {
3490 if (
auto *M = dyn_cast<DIMacro>(MN))
3492 else if (
auto *
F = dyn_cast<DIMacroFile>(MN))
3493 emitMacroFile(*
F, U);
3499void DwarfDebug::emitMacro(
DIMacro &M) {
3507 if (UseDebugMacroSection) {
3510 ? dwarf::DW_MACRO_define_strx
3511 : dwarf::DW_MACRO_undef_strx;
3521 ? dwarf::DW_MACRO_GNU_define_indirect
3522 : dwarf::DW_MACRO_GNU_undef_indirect;
3542void DwarfDebug::emitMacroFileImpl(
3544 StringRef (*MacroFormToString)(
unsigned Form)) {
3567 if (UseDebugMacroSection)
3569 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3576void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3577 for (
const auto &
P : CUMap) {
3578 auto &TheCU = *
P.second;
3581 auto *CUNode = cast<DICompileUnit>(
P.first);
3582 DIMacroNodeArray Macros = CUNode->getMacros();
3587 if (UseDebugMacroSection)
3589 handleMacroNodes(Macros, U);
3596void DwarfDebug::emitDebugMacinfo() {
3598 emitDebugMacinfoImpl(UseDebugMacroSection
3599 ? ObjLower.getDwarfMacroSection()
3600 : ObjLower.getDwarfMacinfoSection());
3603void DwarfDebug::emitDebugMacinfoDWO() {
3605 emitDebugMacinfoImpl(UseDebugMacroSection
3606 ? ObjLower.getDwarfMacroDWOSection()
3607 : ObjLower.getDwarfMacinfoDWOSection());
3612void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3613 std::unique_ptr<DwarfCompileUnit> NewU) {
3615 if (!CompilationDir.
empty())
3616 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3617 addGnuPubAttributes(*NewU, Die);
3619 SkeletonHolder.
addUnit(std::move(NewU));
3624 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3625 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3635 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3642void DwarfDebug::emitDebugInfoDWO() {
3650void DwarfDebug::emitDebugAbbrevDWO() {
3655void DwarfDebug::emitDebugLineDWO() {
3657 SplitTypeUnitFileTable.
Emit(
3662void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3672void DwarfDebug::emitDebugStrDWO() {
3674 emitStringOffsetsTableHeaderDWO();
3682void DwarfDebug::emitDebugAddr() {
3693 return &SplitTypeUnitFileTable;
3704 return Result.high();
3713 if (!TypeUnitsUnderConstruction.empty() && AddrPool.
hasBeenUsed())
3716 auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0));
3718 CU.addDIETypeSignature(RefDie, Ins.first->second);
3723 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3726 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
3727 CU,
Asm,
this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(
CU));
3730 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3732 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3737 Ins.first->second = Signature;
3745 if (!CompilationDir.
empty())
3746 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
3747 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
3762 CU.applyStmtList(UnitDie);
3773 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
3774 TypeUnitsUnderConstruction.clear();
3779 AccelTypeUnitsDebugNames.
clear();
3783 for (
const auto &
TU : TypeUnitsToAdd)
3784 TypeSignatures.erase(
TU.second);
3791 CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));
3797 for (
auto &
TU : TypeUnitsToAdd) {
3810 AccelTypeUnitsDebugNames.
clear();
3813 CU.addDIETypeSignature(RefDie, Signature);
3820template <
typename DataT>
3821void DwarfDebug::addAccelNameImpl(
3826 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit ||
Name.empty())
3843 assert(((&Current == &AccelTypeUnitsDebugNames) ||
3844 ((&Current == &AccelDebugNames) &&
3845 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
3846 "Kind is CU but TU is being processed.");
3847 assert(((&Current == &AccelDebugNames) ||
3848 ((&Current == &AccelTypeUnitsDebugNames) &&
3849 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
3850 "Kind is TU but CU is being processed.");
3853 Current.
addName(
Ref, Die, Unit.getUniqueID(),
3854 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
3868 addAccelNameImpl(Unit, NameTableKind, AccelNames,
Name, Die);
3877 addAccelNameImpl(Unit, NameTableKind, AccelObjC,
Name, Die);
3884 addAccelNameImpl(Unit, NameTableKind, AccelNamespace,
Name, Die);
3890 const DIE &Die,
char Flags) {
3891 addAccelNameImpl(Unit, NameTableKind, AccelTypes,
Name, Die);
3900 return dwarf::Form::DW_FORM_sec_offset;
3902 "DWARF64 is not defined prior DWARFv3");
3904 : dwarf::Form::DW_FORM_data4;
3908 return SectionLabels.lookup(S);
3912 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
3917std::optional<MD5::MD5Result>
3921 return std::nullopt;
3922 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
3924 return std::nullopt;
3929 std::string ChecksumString = fromHex(Checksum->Value);
3931 std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.data());
3956 auto PrevLoc =
Asm->
OutStreamer->getContext().getCurrentDwarfLoc();
3957 if (PrevLoc.getLine()) {
3959 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static Expected< bool > hasObjCCategory(BitstreamCursor &Stream)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static bool isObjCClass(StringRef Name)
static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))
static void finishCallSiteParams(ValT Val, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > DescribedParams, ParamSet &Params)
Emit call site parameter entries that are described by the given value and debug expression.
static cl::opt< bool > UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden, cl::desc("Emit the GNU .debug_macro format with DWARF <5"), cl::init(false))
static cl::opt< DefaultOnOff > DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden, cl::desc("Use inlined strings rather than string section."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static bool validThroughout(LexicalScopes &LScopes, const MachineInstr *DbgValue, const MachineInstr *RangeEnd, const InstructionOrdering &Ordering)
Determine whether a singular DBG_VALUE is valid for the entirety of its enclosing lexical scope.
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
static cl::opt< LinkageNameOption > DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, cl::desc("Which DWARF linkage-name attributes to emit."), cl::values(clEnumValN(DefaultLinkageNames, "Default", "Default for platform"), clEnumValN(AllLinkageNames, "All", "All"), clEnumValN(AbstractLinkageNames, "Abstract", "Abstract subprograms")), cl::init(DefaultLinkageNames))
static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > ParamsToAdd)
Add Reg to the worklist, if it's not already present, and mark that the given parameter registers' va...
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr)
static cl::opt< DefaultOnOff > DwarfOpConvert("dwarf-op-convert", cl::Hidden, cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static std::pair< const MachineInstr *, bool > findPrologueEndLoc(const MachineFunction *MF)
static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)
Try to interpret values loaded into registers that forward parameters for CallMI.
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, const MDNode *S, unsigned Flags, unsigned CUID, uint16_t DwarfVersion, ArrayRef< std::unique_ptr< DwarfCompileUnit > > DCUs)
Register a source line with debug info.
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), 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 void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegSet &ClobberedRegUnits)
Interpret values loaded into registers by CurMI.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegSet &ClobberedRegUnits)
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
static constexpr unsigned ULEB128PadSize
static cl::opt< DefaultOnOff > DwarfSectionsAsReferences("dwarf-sections-as-references", cl::Hidden, cl::desc("Use sections+offset as references rather than labels."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
static void forBothCUs(DwarfCompileUnit &CU, Func F)
static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD)
static const DILocalScope * getRetainedNodeScope(const MDNode *N)
static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
static cl::opt< DefaultOnOff > UnknownLocations("use-unknown-locations", cl::Hidden, cl::desc("Make an absence of debug location information explicit."), cl::values(clEnumVal(Default, "At top of block or after label"), clEnumVal(Enable, "In all cases"), clEnumVal(Disable, "Never")), cl::init(Default))
static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD, const DwarfCompileUnit &CU, uint16_t DwarfVersion)
Emit the header of a DWARF 5 macro section, or the GNU extension for DWARF 4.
static cl::opt< AccelTableKind > AccelTables("accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."), cl::values(clEnumValN(AccelTableKind::Default, "Default", "Default for platform"), clEnumValN(AccelTableKind::None, "Disable", "Disabled."), clEnumValN(AccelTableKind::Apple, "Apple", "Apple"), clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")), cl::init(AccelTableKind::Default))
static cl::opt< DwarfDebug::MinimizeAddrInV5 > MinimizeAddrInV5Option("minimize-addr-in-v5", cl::Hidden, cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more " "address pool entry sharing to reduce relocations/object size"), cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default", "Default address minimization strategy"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges", "Use rnglists for contiguous ranges if that allows " "using a pre-existing base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions, "Expressions", "Use exprloc addrx+offset expressions for any " "address with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Form, "Form", "Use addrx+offset extension form for any address " "with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled", "Stuff")), cl::init(DwarfDebug::MinimizeAddrInV5::Default))
static StringRef getObjCMethodName(StringRef In)
static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, unsigned StartxLength, unsigned EndOfList, StringRef(*StringifyEnum)(unsigned), bool ShouldUseBaseAddress, PayloadEmitter EmitPayload)
static DbgValueLoc getDebugLocValue(const MachineInstr *MI)
Get .debug_loc entry for the instruction range starting at MI.
static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
unsigned const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
static bool isCopy(MachineInstr *MI)
static const uint32_t IV[8]
Class recording the (high level) value of a variable.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
void emit(AsmPrinter &Asm, MCSection *AddrSection)
void setLabel(MCSymbol *Sym)
void resetUsedFlag(bool HasBeenUsed=false)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
size_t size() const
size - Get the array size.
This class is intended to be used as a driving class for all asm writers.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
MapVector< MBBSectionID, MBBSectionRange > MBBSectionRanges
DwarfDebug * getDwarfDebug()
void emitDwarfLengthOrOffset(uint64_t Value) const
Emit 32- or 64-bit value depending on the DWARF format.
unsigned int getUnitLengthFieldByteSize() const
Returns 4 for DWARF32 and 12 for DWARF64.
TargetMachine & TM
Target machine description.
MCSymbol * getFunctionBegin() const
void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const
Emit something like ".long Hi-Lo" where the size in bytes of the directive is specified by Size and H...
const MCAsmInfo * MAI
Target Asm Printer information.
MachineFunction * MF
The current machine function.
void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset" or ".quad Label + Offset" depending on the DWARF format.
void emitInt8(int Value) const
Emit a byte directive and value.
bool hasDebugInfo() const
Returns true if valid debug info is present.
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const
Emit a unit length field.
MCContext & OutContext
This is the context for the output file that we are streaming.
MCSymbol * createTempSymbol(const Twine &Name) const
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
void emitLabelReference(const MCSymbol *Label, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label" where the size in bytes of the directive is specified by Size and L...
unsigned int getDwarfOffsetByteSize() const
Returns 4 for DWARF32 and 8 for DWARF64.
MCSymbol * getFunctionEnd() const
void emitInt16(int Value) const
Emit a short directive and value.
const DataLayout & getDataLayout() const
Return information about data layout.
uint16_t getDwarfVersion() const
void emitInt8(uint8_t Byte, const Twine &Comment) override
const bool GenerateComments
Only verbose textual output needs comments.
virtual void emitULEB128(uint64_t DWord, const Twine &Comment="", unsigned PadTo=0)=0
virtual void emitSLEB128(uint64_t DWord, const Twine &Comment="")=0
virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=0
virtual unsigned emitDIERef(const DIE &D)=0
Basic type, like 'int' or 'float'.
bool getDebugInfoForProfiling() const
bool isDebugDirectivesOnly() const
StringRef getFlags() const
static std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
unsigned getRuntimeVersion() const
bool getSplitDebugInlining() const
StringRef getSysRoot() const
StringRef getProducer() const
unsigned getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
An object containing the capability of hashing and adding hash attributes onto a DIE.
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die)
Computes the CU signature.
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
A structured debug information entry.
DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
dwarf::Tag getTag() const
Holds a DIExpression and keeps track of how many operands have been consumed so far.
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
bool isImplicit() const
Return whether this is an implicit location description.
static std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
Base class for scope-like contexts.
StringRef getFilename() const
StringRef getName() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
DIScope * getScope() const
void addTypeUnitSignature(DwarfTypeUnit &U)
Add a type unit Signature.
void convertDieToOffset()
Convert DIE entries to explicit offset.
void addTypeUnitSymbol(DwarfTypeUnit &U)
Add a type unit start symbol.
void addTypeEntries(DWARF5AccelTable &Table)
This class represents an Operation in the Expression.
std::optional< unsigned > getSubCode() const
uint64_t getEndOffset() const
Encoding
Size and signedness of expression operations' operands.
const Description & getDescription() const
uint64_t getOperandEndOffset(unsigned Idx) const
uint64_t getRawOperand(unsigned Idx) const
bool isLittleEndian() const
Layout endianness...
Used for tracking debug info about call site parameters.
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
bool hasNonEmptyLocation(const Entries &Entries) const
Test whether a vector of entries features any non-empty locations.
A single location or constant within a variable location description, with either a single entry (wit...
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
This class is used to track local variable information.
const DILocalVariable * getVariable() const
const DIType * getType() const
Base class for debug information backends.
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
AsmPrinter * Asm
Target of debug info emission.
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
MachineModuleInfo * MMI
Collected machine module information.
virtual void beginModule(Module *M)
DebugLoc PrevInstLoc
Previous instruction's location information.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
const MachineBasicBlock * PrevInstBB
void requestLabelAfterInsn(const MachineInstr *MI)
Ensure that a label will be emitted after MI.
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
DbgLabelInstrMap DbgLabels
Mapping of inlined labels and DBG_LABEL machine instruction.
const InstructionOrdering & getInstOrdering() const
void requestLabelBeforeInsn(const MachineInstr *MI)
Ensure that a label will be emitted before MI.
virtual void beginInstruction(const MachineInstr *MI)
const MachineBasicBlock * EpilogBeginBlock
This block includes epilogue instructions.
const MachineInstr * PrologEndLoc
This location indicates end of function prologue and beginning of function body.
DwarfExpression implementation for .debug_loc entries.
void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU)
Lower this entry into a DWARF expression.
Builder for DebugLocStream entries.
Builder for DebugLocStream lists.
ArrayRef< std::string > getComments(const Entry &E) const
ArrayRef< Entry > getEntries(const List &L) const
ArrayRef< char > getBytes(const Entry &E) const
MCSymbol * getSym() const
void setSym(MCSymbol *Sym)
ArrayRef< List > getLists() const
MDNode * getScope() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope)
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
DwarfCompileUnit * getSkeleton() const
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
const StringMap< const DIE * > & getGlobalNames() const
DbgEntity * getExistingAbstractEntity(const DINode *Node)
const StringMap< const DIE * > & getGlobalTypes() const
bool hasDwarfPubSections() const
Collects and handles dwarf debug information.
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
bool emitDebugEntryValues() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind)
Sets the current DWARF5AccelTable to use.
bool alwaysUseRanges(const DwarfCompileUnit &) const
Returns whether range encodings should be used for single entry range lists.
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
void skippedNonDebugFunction() override
void addArangeLabel(SymbolCU SCU)
Add a label so that arange data can be generated for it.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
AddressPool & getAddressPool()
DWARF5AccelTable & getCurrentDWARF5AccelTable()
Returns either CU or TU DWARF5AccelTable.
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
bool shareAcrossDWOCUs() const
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
const MCSymbol * getSectionLabel(const MCSection *S)
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support.
unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU)
Get Dwarf compile unit ID for line table.
const MachineInstr * emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
bool useRangesSection() const
Returns whether ranges section should be emitted.
void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null.
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)
Add a DIE to the set of types that we're going to pull into type units.
void endModule() override
Emit all Dwarf sections that should come after the content.
void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)
void beginCodeAlignment(const MachineBasicBlock &MBB) override
Process beginning of code alignment.
DwarfDebug(AsmPrinter *A)
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
void finalize()
This needs to be called last to commit any pending changes.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void setMemoryLocationKind()
Lock this down to become a memory location description.
std::optional< uint8_t > TagOffset
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void addSignedConstant(int64_t Value)
Emit a signed constant.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void addScopeLabel(LexicalScope *LS, DbgLabel *Label)
void addUnit(std::unique_ptr< DwarfCompileUnit > U)
Add a unit to the list of CUs.
void computeSizeAndOffsets()
Compute the size and offset of all the DIEs.
void setRnglistsTableBaseSym(MCSymbol *Sym)
DenseMap< LexicalScope *, ScopeVars > & getScopeVariables()
unsigned computeSizeAndOffsetsForUnit(DwarfUnit *TheU)
Compute the size and offset of all the DIEs in the given unit.
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
void emitUnit(DwarfUnit *TheU, bool UseOffsets)
Emit the given unit to its section.
const SmallVectorImpl< RangeSpanList > & getRangeLists() const
getRangeLists - Get the vector of range lists.
MCSymbol * getStringOffsetsStartSym() const
MCSymbol * getRnglistsTableBaseSym() const
DwarfStringPool & getStringPool()
Returns the string pool.
void emitAbbrevs(MCSection *)
Emit a set of abbreviations to the specific section.
void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)
Emit all of the strings to the section given.
DenseMap< LexicalScope *, LabelList > & getScopeLabels()
void addScopeVariable(LexicalScope *LS, DbgVariable *Var)
DenseMap< const DILocalScope *, DIE * > & getAbstractScopeDIEs()
const SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
unsigned getIndex() const
MCSymbol * getSymbol() const
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str)
Same as getEntry, except that you can use EntryRef::getIndex to obtain a unique ID of this entry (e....
void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)
void setTypeSignature(uint64_t Signature)
void setType(const DIE *Ty)
This dwarf writer support class manages information associated with a source file.
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)
Creates type DIE with specific context.
const DICompileUnit * getCUNode() const
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
unsigned getUniqueID() const
Gets Unique ID for this unit.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool isTailCall(const MachineInstr &MI) const override
Record instruction ordering so we can query their relative positions within a function.
LexicalScope - This class is used to track scope information.
SmallVectorImpl< InsnRange > & getRanges()
const DILocalScope * getScopeNode() const
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
ArrayRef< LexicalScope * > getAbstractScopesList() const
getAbstractScopesList - Return a reference to list of abstract scopes.
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
LexicalScope * findAbstractScope(const DILocalScope *N)
findAbstractScope - Find an abstract scope or return null.
bool empty()
empty - Return true if there is any lexical scope information available.
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
Single value location description.
Single(DbgValueLoc ValueLoc)
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
uint16_t getDwarfVersion() const
dwarf::DwarfFormat getDwarfFormat() const
void maybeSetRootFile(StringRef Directory, StringRef FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source)
void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
static void make(MCStreamer *MCOS, MCSection *Section)
MCSection * getDwarfLoclistsSection() const
MCSection * getDwarfAccelTypesSection() const
MCSection * getDwarfGnuPubNamesSection() const
MCSection * getDwarfStrOffDWOSection() const
MCSection * getDwarfRangesSection() const
MCSection * getDwarfAccelNamespaceSection() const
MCSection * getDwarfLineDWOSection() const
MCSection * getDwarfStrOffSection() const
MCSection * getDwarfInfoDWOSection() const
MCSection * getDwarfTypesDWOSection() const
MCSection * getDwarfPubNamesSection() const
MCSection * getDwarfMacroSection() const
MCSection * getDwarfStrSection() const
MCSection * getDwarfLoclistsDWOSection() const
MCSection * getDwarfMacinfoDWOSection() const
MCSection * getDwarfRnglistsSection() const
MCSection * getDwarfAddrSection() const
MCSection * getDwarfInfoSection() const
MCSection * getDwarfPubTypesSection() const
MCSection * getDwarfTypesSection(uint64_t Hash) const
MCSection * getDwarfGnuPubTypesSection() const
MCSection * getDwarfStrDWOSection() const
MCSection * getDwarfAccelNamesSection() const
MCSection * getDwarfAbbrevDWOSection() const
MCSection * getDwarfRnglistsDWOSection() const
MCSection * getDwarfAbbrevSection() const
MCSection * getDwarfMacinfoSection() const
MCSection * getDwarfLocDWOSection() const
MCSection * getDwarfARangesSection() const
MCSection * getDwarfAccelObjCSection() const
MCSection * getDwarfLocSection() const
MCSection * getDwarfMacroDWOSection() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol * getBeginSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
std::string SplitDwarfFile
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
succ_iterator succ_begin()
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
Align getAlignment() const
Return alignment of the basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const CallSiteInfoMap & getCallSitesInfo() const
bool hasBBSections() const
Returns true if this function has basic block sections enabled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & back() const
VariableDbgInfoMapTy & getVariableDbgInfo()
const MachineBasicBlock & front() const
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i....
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
iterator_range< mop_iterator > uses()
Returns a range that includes all operands which may be register uses.
unsigned getNumOperands() const
Retuns the total number of operands.
bool hasDelaySlot(QueryType Type=AnyInBundle) const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isDebugValue() const
const Module * getModule() const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A Module instance is used to store all the information related to an LLVM module.
iterator_range< debug_compile_units_iterator > debug_compile_units() const
Return an iterator for all DICompileUnits listed in this Module's llvm.dbg.cu named metadata node and...
unsigned getDwarfVersion() const
Returns the Dwarf Version by checking module flags.
bool isDwarf64() const
Returns the DWARF format by checking module flags.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool empty() const
Determine if the SetVector is empty or not.
Implements a dense probed hash-table based set with some number of buckets stored inline.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const_iterator begin() const
const_iterator end() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
const Triple & getTargetTriple() const
MCTargetOptions MCOptions
Machine level options.
DebuggerKind DebuggerTuning
Which debugger to tune for.
bool ShouldEmitDebugEntryValues() const
NOTE: There are targets that still do not support the debug entry values production.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
Triple - Helper class for working with autoconf configuration names.
bool isNVPTX() const
Tests whether the target is NVPTX (32- or 64-bit).
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
StringRef getName() const
Return a constant reference to the value's name.
void dump() const
Support for debugging, callable in GDB: V->dump()
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
StringRef RangeListEncodingString(unsigned Encoding)
StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
StringRef MacroString(unsigned Encoding)
StringRef LocListEncodingString(unsigned Encoding)
StringRef GnuMacroString(unsigned Encoding)
StringRef MacinfoString(unsigned Encoding)
StringRef OperationEncodingString(unsigned Encoding)
StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
bool isCPlusPlus(SourceLanguage S)
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
@ DWARF_VERSION
Other constants.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)
Returns an iterator to the first instruction in the bundle containing I.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
auto unique(Range &&R, Predicate P)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
AccelTableKind
The kind of accelerator tables we should emit.
@ Default
Platform default.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
@ Dwarf
DWARF v5 .debug_names.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Global
Append to llvm.global_dtors.
@ Ref
The access may reference the value stored in memory.
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
DebuggerKind
Identify a debugger for "tuning" the debug info.
@ SCE
Tune debug info for SCE targets (e.g. PS4).
@ DBX
Tune debug info for dbx.
@ Default
No specific tuning requested.
@ GDB
Tune debug info for gdb.
@ LLDB
Tune debug info for lldb.
Implement std::hash so that hash_code can be used in STL containers.
Represents a parameter whose call site value can be described by applying a debug expression to a reg...
uint64_t ParamReg
The described parameter register.
const DIExpression * Expr
Debug expression that has been built up when walking through the instruction chain that produces the ...
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
SmallVector< Encoding > Op
Encoding for Op operands.
A pair of GlobalVariable and DIExpression.
Represents an entry-value location, or a fragment of one.
Single location defined by (potentially multiple) EntryValueInfo.
Single location defined by (potentially multiple) MMI entries.
void addFrameIndexExpr(const DIExpression *Expr, int FI)
const std::set< FrameIndexExpr > & getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
A MapVector that performs no allocations if smaller than a certain size.
Helper used to pair up a symbol and its DWARF compile unit.
This struct describes target specific location.
Describes an entry of the various gnu_pub* debug sections.