64#define DEBUG_TYPE "dwarfdebug"
66STATISTIC(NumCSParams,
"Number of dbg call site params created");
69 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
79 cl::desc(
"Generate DWARF4 type units."),
90 cl::desc(
"Make an absence of debug location information explicit."),
98 "Default for platform"),
99 clEnumValN(AccelTableKind::None,
"Disable",
"Disabled."),
100 clEnumValN(AccelTableKind::Apple,
"Apple",
"Apple"),
101 clEnumValN(AccelTableKind::Dwarf,
"Dwarf",
"DWARF")),
106 cl::desc(
"Use inlined strings rather than string section."),
114 cl::desc(
"Disable emission .debug_ranges section."),
119 cl::desc(
"Use sections+offset as references rather than labels."),
126 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
131 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
144 cl::desc(
"Which DWARF linkage-name attributes to emit."),
146 "Default for platform"),
149 "Abstract subprograms")),
154 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
155 "address pool entry sharing to reduce relocations/object size"),
157 "Default address minimization strategy"),
158 clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges,
"Ranges",
159 "Use rnglists for contiguous ranges if that allows "
160 "using a pre-existing base address"),
161 clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions,
163 "Use exprloc addrx+offset expressions for any "
164 "address with a prior base address"),
165 clEnumValN(DwarfDebug::MinimizeAddrInV5::Form,
"Form",
166 "Use addrx+offset extension form for any address "
167 "with a prior base address"),
168 clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled,
"Disabled",
170 cl::init(DwarfDebug::MinimizeAddrInV5::Default));
175 cl::desc(
"Set to false to ignore Key Instructions metadata"));
179void DebugLocDwarfExpression::emitOp(
uint8_t Op,
const char *Comment) {
185void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
197void DebugLocDwarfExpression::emitBaseTypeRef(
uint64_t Idx) {
208void DebugLocDwarfExpression::enableTemporaryBuffer() {
209 assert(!IsBuffering &&
"Already buffering?");
215void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering =
false; }
217unsigned DebugLocDwarfExpression::getTemporaryBufferSize() {
218 return TmpBuf ? TmpBuf->Bytes.size() : 0;
221void DebugLocDwarfExpression::commitTemporaryBuffer() {
224 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
225 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
226 ? TmpBuf->Comments[
Byte.index()].c_str()
230 TmpBuf->Bytes.clear();
231 TmpBuf->Comments.clear();
242 const bool IsVariadic = !SingleLocExprOpt;
245 if (!IsVariadic && !
MI->isNonListDebugValue()) {
246 assert(
MI->getNumDebugOperands() == 1 &&
247 "Mismatched DIExpression and debug operands for debug instruction.");
248 Expr = *SingleLocExprOpt;
255 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
257 }
else if (
Op.isTargetIndex()) {
260 }
else if (
Op.isImm())
262 else if (
Op.isFPImm())
264 else if (
Op.isCImm())
269 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
273 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
274 return Fragment ? Fragment->OffsetInBits : 0;
288 Expr(ValueLoc.getExpression()) {
297 return FrameIndexExprs;
301 FrameIndexExprs.insert({FI, Expr});
302 assert((FrameIndexExprs.size() == 1 ||
305 return FIE.Expr && FIE.Expr->isFragment();
307 "conflicting locations for variable");
311 bool GenerateTypeUnits,
320 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
326 if (DwarfVersion >= 5)
336 InfoHolder(
A,
"info_string", DIEValueAllocator),
337 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
338 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()) {
349 else if (TT.isOSAIX())
355 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
374 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
380 bool Dwarf64 = DwarfVersion >= 3 &&
390 TT.isOSBinFormatELF()) ||
391 TT.isOSBinFormatXCOFF();
393 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
400 UseSectionsAsReferences = TT.isNVPTX();
405 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
406 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
410 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
417 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
419 UseDWARF2Bitfields = DwarfVersion < 4;
425 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
433 UseDebugMacroSection =
442 if (DwarfVersion >= 5)
454 return Name.starts_with(
"+") ||
Name.starts_with(
"-");
461 return Name.contains(
") ");
467 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
472 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
473 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
477 return In.slice(In.find(
' ') + 1, In.find(
']'));
490 if (!SP->isDefinition())
493 if (SP->getName() !=
"")
524 if (Scope->isAbstractScope())
542 if (
auto *SkelCU =
CU.getSkeleton())
543 if (
CU.getCUNode()->getSplitDebugInlining())
551void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
553 assert(Scope && Scope->getScopeNode());
554 assert(Scope->isAbstractScope());
555 assert(!Scope->getInlinedAt());
557 auto *SP = cast<DISubprogram>(Scope->getScopeNode());
565 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
566 if (
auto *SkelCU =
CU.getSkeleton()) {
568 .constructAbstractSubprogramScopeDIE(Scope);
569 if (
CU.getCUNode()->getSplitDebugInlining())
570 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
572 CU.constructAbstractSubprogramScopeDIE(Scope);
607template <
typename ValT>
611 for (
auto Param : DescribedParams) {
612 bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0;
627 "Combined debug expression is invalid");
642 auto &ParamsForFwdReg = Worklist[Reg];
643 for (
auto Param : ParamsToAdd) {
646 return D.ParamReg == Param.ParamReg;
648 "Same parameter described twice by forwarding reg");
655 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
698 if (
MI.isDebugInstr())
702 if (MO.getReg().isPhysical()) {
703 for (
auto &FwdReg : ForwardedRegWorklist)
704 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
705 Defs.
insert(FwdReg.first);
714 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
715 if (FwdRegDefs.
empty()) {
724 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
725 for (
auto &RegUnit : ClobberedRegUnits)
726 if (
TRI.hasRegUnit(Reg, RegUnit))
731 for (
auto ParamFwdReg : FwdRegDefs) {
732 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
733 if (ParamValue->first.isImm()) {
734 int64_t Val = ParamValue->first.getImm();
736 ForwardedRegWorklist[ParamFwdReg], Params);
737 }
else if (ParamValue->first.isReg()) {
738 Register RegLoc = ParamValue->first.getReg();
739 Register SP = TLI.getStackPointerRegisterToSaveRestore();
741 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
742 if (!IsRegClobberedInMeantime(RegLoc) &&
743 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
746 ForwardedRegWorklist[ParamFwdReg], Params);
755 ForwardedRegWorklist[ParamFwdReg]);
762 for (
auto ParamFwdReg : FwdRegDefs)
763 ForwardedRegWorklist.
erase(ParamFwdReg);
770 for (
auto &New : TmpWorklistItems)
772 TmpWorklistItems.
clear();
789 if (ForwardedRegWorklist.
empty())
796 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
807 auto CSInfo = CalleesMap.
find(CallMI);
810 if (CSInfo == CalleesMap.end())
824 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
826 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
828 assert(InsertedReg &&
"Single register used to forward two arguments?");
833 for (
const auto &MO : CallMI->
uses())
834 if (MO.isReg() && MO.isUndef())
835 ForwardedRegWorklist.
erase(MO.getReg());
854 assert(std::next(Suc) == BundleEnd &&
855 "More than one instruction in call delay slot");
869 if (ShouldTryEmitEntryVals) {
873 for (
auto &RegEntry : ForwardedRegWorklist) {
880void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
885 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
892 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
895 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
899 if (!
MI.isBundledWithSucc())
901 auto Suc = std::next(
MI.getIterator());
903 (void)CallInstrBundle;
905 (void)DelaySlotBundle;
912 "Call and its successor instruction don't have same label after.");
927 if (!
MI.isCandidateForAdditionalCallInfo())
936 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
939 DIType *AllocSiteTy = dyn_cast_or_null<DIType>(
MI.getHeapAllocMarker());
945 bool PhysRegCalleeOperand =
952 PhysRegCalleeOperand =
956 unsigned CallReg = 0;
958 const Function *CalleeDecl =
nullptr;
959 if (PhysRegCalleeOperand) {
960 CallReg = CalleeOp.
getReg();
962 CalleeDecl = dyn_cast<Function>(CalleeOp.
getGlobal());
969 if (CalleeSP ==
nullptr && CallReg == 0 && AllocSiteTy ==
nullptr)
986 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
995 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
998 << (CalleeDecl ? CalleeDecl->
getName()
1001 ->getName(CallReg)))
1002 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1004 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1005 ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg, AllocSiteTy);
1012 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1019 if (!
U.hasDwarfPubSections())
1022 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1025void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1033 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1034 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1036 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1038 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1040 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1042 if (!SysRoot.
empty())
1043 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1046 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1057 if (!CompilationDir.
empty())
1058 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1059 addGnuPubAttributes(NewCU, Die);
1064 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1068 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1071 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1072 dwarf::DW_FORM_data1, RVer);
1077 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1082 ? dwarf::DW_AT_dwo_name
1083 : dwarf::DW_AT_GNU_dwo_name;
1091DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1092 if (
auto *
CU = CUMap.lookup(DIUnit))
1100 return *CUMap.begin()->second;
1104 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1105 InfoHolder.
getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1107 InfoHolder.
addUnit(std::move(OwnedUnit));
1122 finishUnitAttributes(DIUnit, NewCU);
1126 CUMap.insert({DIUnit, &NewCU});
1127 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1141 if (!
A.Expr || !
B.Expr)
1143 auto FragmentA =
A.Expr->getFragmentInfo();
1144 auto FragmentB =
B.Expr->getFragmentInfo();
1145 if (!FragmentA || !FragmentB)
1147 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1152 return A.Expr ==
B.Expr;
1167 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1168 M->debug_compile_units_end());
1169 if (NumDebugCUs == 0)
1172 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1173 SingleCU = NumDebugCUs == 1;
1178 Global.getDebugInfo(GVs);
1179 for (
auto *GVE : GVs)
1180 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1209 if (CUNode->getImportedEntities().empty() &&
1210 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1211 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1217 for (
auto *GVE : CUNode->getGlobalVariables()) {
1221 auto &GVMapEntry = GVMap[GVE->getVariable()];
1222 auto *Expr = GVE->getExpression();
1223 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1224 GVMapEntry.push_back({
nullptr, Expr});
1228 for (
auto *GVE : CUNode->getGlobalVariables()) {
1230 if (Processed.
insert(GV).second)
1234 for (
auto *Ty : CUNode->getEnumTypes())
1235 CU.getOrCreateTypeDIE(cast<DIType>(Ty));
1237 for (
auto *Ty : CUNode->getRetainedTypes()) {
1240 if (
DIType *RT = dyn_cast<DIType>(Ty))
1242 CU.getOrCreateTypeDIE(RT);
1247void DwarfDebug::finishEntityDefinitions() {
1248 for (
const auto &Entity : ConcreteEntities) {
1249 DIE *Die = Entity->getDIE();
1256 Unit->finishEntityDefinition(Entity.get());
1260void DwarfDebug::finishSubprogramDefinitions() {
1264 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1269void DwarfDebug::finalizeModuleInfo() {
1272 finishSubprogramDefinitions();
1274 finishEntityDefinitions();
1276 bool HasEmittedSplitCU =
false;
1280 for (
const auto &
P : CUMap) {
1281 auto &TheCU = *
P.second;
1282 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1284 TheCU.attachLexicalScopesAbstractOrigins();
1287 TheCU.constructContainingTypeDIEs();
1292 auto *SkCU = TheCU.getSkeleton();
1294 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1297 (void)HasEmittedSplitCU;
1299 "Multiple CUs emitted into a single dwo file");
1300 HasEmittedSplitCU =
true;
1302 ? dwarf::DW_AT_dwo_name
1303 : dwarf::DW_AT_GNU_dwo_name;
1304 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1306 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1307 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1318 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1319 dwarf::DW_FORM_data8,
ID);
1320 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1321 dwarf::DW_FORM_data8,
ID);
1326 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1330 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1341 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1352 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1355 U.setBaseAddress(TheCU.getRanges().front().Begin);
1356 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1363 U.addAddrTableBase();
1366 if (
U.hasRangeLists())
1367 U.addRnglistsBase();
1370 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1376 auto *CUNode = cast<DICompileUnit>(
P.first);
1379 if (CUNode->getMacros()) {
1380 if (UseDebugMacroSection) {
1382 TheCU.addSectionDelta(
1383 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1387 ? dwarf::DW_AT_macros
1388 : dwarf::DW_AT_GNU_macros;
1389 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1394 TheCU.addSectionDelta(
1395 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1396 U.getMacroLabelBegin(),
1399 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1400 U.getMacroLabelBegin(),
1408 if (CUNode->getDWOId())
1409 getOrCreateDwarfCompileUnit(CUNode);
1427 assert(CurFn ==
nullptr);
1430 for (
const auto &
P : CUMap) {
1431 const auto *CUNode = cast<DICompileUnit>(
P.first);
1435 for (
auto *IE : CUNode->getImportedEntities()) {
1436 assert(!isa_and_nonnull<DILocalScope>(IE->getScope()) &&
1437 "Unexpected function-local entity in 'imports' CU field.");
1438 CU->getOrCreateImportedEntityDIE(IE);
1440 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1441 if (
auto *IE = dyn_cast<DIImportedEntity>(
D))
1442 CU->getOrCreateImportedEntityDIE(IE);
1448 CU->createBaseTypeDIEs();
1457 finalizeModuleInfo();
1467 emitAbbreviations();
1473 if (UseARangesSection)
1481 emitDebugMacinfoDWO();
1491 emitDebugAbbrevDWO();
1493 emitDebugRangesDWO();
1503 emitAccelNamespaces();
1507 emitAccelDebugNames();
1516 emitDebugPubSections();
1524 if (
CU.getExistingAbstractEntity(Node))
1529 CU.createAbstractEntity(Node, Scope);
1534 if (
const auto *LV = dyn_cast<DILocalVariable>(
N))
1536 else if (
const auto *L = dyn_cast<DILabel>(
N))
1538 else if (
const auto *IE = dyn_cast<DIImportedEntity>(
N))
1544 return cast<DILocalScope>(S)->getNonLexicalBlockFileScope();
1548void DwarfDebug::collectVariableInfoFromMFTable(
1551 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1555 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1556 "Expected inlined-at fields to agree");
1558 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1565 <<
", no variable scope found\n");
1569 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1574 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1575 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1577 if (PreviousMMI &&
VI.inStackSlot())
1578 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1580 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1581 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1586 if (PreviousLoc->holds<
Loc::MMI>())
1590 <<
", conflicting fragment location types\n");
1595 auto RegVar = std::make_unique<DbgVariable>(
1596 cast<DILocalVariable>(Var.first), Var.second);
1597 if (
VI.inStackSlot())
1604 MFVars.
insert({Var, RegVar.get()});
1605 ConcreteEntities.push_back(std::move(RegVar));
1617 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1625 if (LSRange.size() == 0)
1628 const MachineInstr *LScopeBegin = LSRange.front().first;
1632 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1638 for (++Pred; Pred !=
MBB->
rend(); ++Pred) {
1641 auto PredDL = Pred->getDebugLoc();
1642 if (!PredDL || Pred->isMetaInstruction())
1646 if (
DL->getScope() == PredDL->getScope())
1649 if (!PredScope || LScope->dominates(PredScope))
1669 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1713 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1715 bool isSafeForSingleLocation =
true;
1719 for (
auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {
1723 size_t Index = std::distance(EB, EI);
1724 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1731 "Forgot label before/after instruction starting a range!");
1734 if (std::next(EI) == Entries.end()) {
1737 if (EI->isClobber())
1738 EndMI = EI->getInstr();
1740 else if (std::next(EI)->isClobber())
1744 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1746 if (EI->isDbgValue())
1752 if (EI->isDbgValue()) {
1759 if (!
Instr->isUndefDebugValue()) {
1764 if (
Instr->getDebugExpression()->isFragment())
1765 isSafeForSingleLocation =
false;
1768 StartDebugMI =
Instr;
1770 isSafeForSingleLocation =
false;
1776 if (OpenRanges.
empty())
1780 if (StartLabel == EndLabel) {
1781 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1786 for (
auto &R : OpenRanges)
1796 for (
const auto &[MBBSectionId, MBBSectionRange] :
1798 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1799 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1802 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1803 MBBSectionRange.EndLabel, Values);
1806 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1813 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1814 for (
auto &
Value : CurEntry->getValues())
1816 dbgs() <<
"-----\n";
1819 auto PrevEntry = std::next(CurEntry);
1820 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1824 if (!isSafeForSingleLocation ||
1843 RangeMBB = Entries.begin()->getInstr()->getParent();
1846 "Range MBB not found in MBBSectionRanges!");
1848 auto *NextEntry = std::next(CurEntry);
1849 auto NextRangeIt = std::next(RangeIt);
1850 while (NextEntry !=
DebugLoc.end()) {
1859 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1860 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1861 CurEntry->getValues() != NextEntry->getValues())
1863 RangeIt = NextRangeIt;
1864 NextRangeIt = std::next(RangeIt);
1865 CurEntry = NextEntry;
1866 NextEntry = std::next(CurEntry);
1876 ensureAbstractEntityIsCreatedIfScoped(TheCU,
Node,
Scope.getScopeNode());
1877 if (isa<const DILocalVariable>(
Node)) {
1878 ConcreteEntities.push_back(
1879 std::make_unique<DbgVariable>(cast<const DILocalVariable>(
Node),
1882 cast<DbgVariable>(ConcreteEntities.back().get()));
1883 }
else if (isa<const DILabel>(
Node)) {
1884 ConcreteEntities.push_back(
1885 std::make_unique<DbgLabel>(cast<const DILabel>(
Node),
1888 cast<DbgLabel>(ConcreteEntities.back().get()));
1890 return ConcreteEntities.back().get();
1898 collectVariableInfoFromMFTable(TheCU, Processed);
1901 InlinedEntity
IV =
I.first;
1906 const auto &HistoryMapEntries =
I.second;
1924 DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
1925 *Scope, LocalVar,
IV.second));
1927 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1933 size_t HistSize = HistoryMapEntries.size();
1934 bool SingleValueWithClobber =
1935 HistSize == 2 && HistoryMapEntries[1].isClobber();
1936 if (HistSize == 1 || SingleValueWithClobber) {
1938 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1950 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1955 if (isValidSingleLocation) {
1956 RegVar->emplace<
Loc::Single>(Entries[0].getValues()[0]);
1967 for (
auto &Entry : Entries)
1974 InlinedEntity IL =
I.first;
1983 Label->getScope()->getNonLexicalBlockFileScope();
1998 createConcreteEntity(TheCU, *Scope, Label, IL.second,
Sym);
2002 for (
const DINode *DN :
SP->getRetainedNodes()) {
2004 if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
2005 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2009 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2011 LocalDeclsPerLS[
LS].insert(DN);
2025 if (!
MI.isBundledWithSucc())
2027 auto Suc = std::next(
MI.getIterator());
2032 assert(Suc->isBundledWithPred() &&
2033 "Call bundle instructions are out of order");
2038 if (!NoDebug && SP->areAllCallsDescribed() &&
2040 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2077 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2083 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2089 unsigned LastAsmLine =
2097 bool ScopeUsesKeyInstructions =
2099 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2102 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2103 IsKey = KeyInstructions.contains(
MI);
2109 assert(
MI->getParent() == &*
MI->getMF()->begin());
2110 recordSourceLine(SP->getScopeLine(), 0, SP,
2115 bool PrevInstInSameSection =
2118 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2119 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2129 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2131 RecordSourceLine(
DL, Flags);
2144 if (LastAsmLine == 0)
2161 const MDNode *Scope =
nullptr;
2162 unsigned Column = 0;
2167 recordSourceLine(0, Column, Scope, 0);
2175 if (
DL.getLine() == 0 && LastAsmLine == 0)
2182 if (ScopeUsesKeyInstructions) {
2189 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2193 RecordSourceLine(
DL, Flags);
2200static std::pair<const MachineInstr *, bool>
2210 bool IsEmptyPrologue =
2211 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2216 -> std::optional<std::pair<const MachineInstr *, bool>> {
2219 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2222 if (!isFrameSetup &&
MI.getDebugLoc()) {
2228 if (
MI.getDebugLoc().getLine())
2229 return std::make_pair(&
MI, IsEmptyPrologue);
2234 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2235 NonTrivialInst = &
MI;
2237 IsEmptyPrologue =
false;
2238 return std::nullopt;
2246 auto CurBlock = MF->
begin();
2247 auto CurInst = CurBlock->begin();
2251 while (CurBlock->empty())
2252 CurInst = (++CurBlock)->begin();
2253 assert(CurInst != CurBlock->end());
2257 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2259 if (CurInst->isTerminator()) {
2268 if (CurBlock->pred_size() > 1)
2279 if (CurBlock == MF->
end())
2281 }
while (CurBlock->empty());
2282 CurInst = CurBlock->begin();
2288 if (!CurInst->isMetaInstruction()) {
2289 auto FoundInst = ExamineInst(*CurInst);
2296 auto NextInst = std::next(CurInst);
2297 if (NextInst != CurInst->getParent()->end()) {
2314 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2315 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2316 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2320 return std::make_pair(
nullptr, IsEmptyPrologue);
2326 const MDNode *S,
unsigned Flags,
unsigned CUID,
2328 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2331 unsigned FileNo = 1;
2333 if (
auto *Scope = cast_or_null<DIScope>(S)) {
2334 Fn =
Scope->getFilename();
2335 if (Line != 0 && DwarfVersion >= 4)
2336 if (
auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
2340 .getOrCreateSourceID(
Scope->getFile());
2342 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2343 Discriminator, Fn, Comment);
2354 bool IsEmptyPrologue = PrologEnd.second;
2357 if (IsEmptyPrologue) {
2365 if (!
DL ||
DL->getLine() != 0)
2376 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2386 KeyInstructions.clear();
2393 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2410 for (
auto &
MBB : *MF) {
2422 for (
auto &
MI :
MBB) {
2423 if (
MI.isMetaInstruction())
2427 if (!Loc || !Loc->getLine())
2443 KeyInstructions.insert(Buoy);
2453 auto *InlinedAt = Loc->getInlinedAt();
2456 if (!Group || !Rank)
2460 if (BuoyAtom && BuoyAtom != Group) {
2465 auto &[CandidateRank, CandidateInsts] =
2466 GroupCandidates[{InlinedAt, Group}];
2472 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2473 (CandidateRank != 0 && !CandidateInsts.empty()));
2475 assert(Rank &&
"expected nonzero rank");
2478 if (CandidateRank && CandidateRank < Rank)
2485 if (CandidateRank == Rank)
2489 else if (CandidateRank > Rank)
2490 CandidateInsts.clear();
2494 CandidateInsts.push_back(Buoy);
2495 CandidateRank = Rank;
2503 if (CandidateInsts.empty())
2509 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2510 for (
auto *
I : Insts)
2511 KeyInstructions.insert(
I);
2519 ForceIsStmtInstrs.clear();
2558 for (
auto &
MI :
MBB) {
2559 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2572 for (
auto *
MBB : PredMBBsToExamine) {
2574 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2575 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2578 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2580 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2581 ForceIsStmtInstrs.insert(
MI);
2588 CheckMBBEdge(Succ, 0);
2594 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2609 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2612 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2613 CheckMBBEdge(FBB, FBBLine);
2637 unsigned LastLine = 0;
2639 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2640 LastLine =
DL->getLine();
2645 for (
auto *Succ : SuccessorBBs)
2646 CheckMBBEdge(Succ, LastLine);
2661 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2676 computeKeyInstructions(MF);
2677 findForceIsStmtInstrs(MF);
2689 return CU.getUniqueID();
2693 const auto &CURanges =
CU->getRanges();
2694 auto &LineTable =
Asm->
OutStreamer->getContext().getMCDwarfLineTable(
2697 LineTable.getMCLineSections().addEndEntry(
2698 const_cast<MCSymbol *
>(CURanges.back().End));
2717 "endFunction should be called with the same function as beginFunction");
2732 collectEntityInfo(TheCU, SP, Processed);
2737 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2758 const auto *SP = cast<DISubprogram>(AScope->getScopeNode());
2759 for (
const DINode *DN : SP->getRetainedNodes()) {
2763 assert(LexS &&
"Expected the LexicalScope to be created.");
2764 if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
2766 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2772 LocalDeclsPerLS[LS].insert(DN);
2776 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2778 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2781 ProcessedSPNodes.insert(SP);
2787 SkelCU->constructSubprogramScopeDIE(SP, FnScope, FunctionLineTableLabel);
2789 FunctionLineTableLabel =
nullptr;
2792 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2800 LocalDeclsPerLS.clear();
2807void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2809 ::recordSourceLine(*
Asm, Line, Col, S, Flags,
2819void DwarfDebug::emitDebugInfo() {
2825void DwarfDebug::emitAbbreviations() {
2831void DwarfDebug::emitStringOffsetsTableHeader() {
2838template <
typename AccelTableT>
2839void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2847void DwarfDebug::emitAccelDebugNames() {
2849 if (getUnits().empty())
2856void DwarfDebug::emitAccelNames() {
2863void DwarfDebug::emitAccelObjC() {
2869void DwarfDebug::emitAccelNamespaces() {
2870 emitAccel(AccelNamespace,
2876void DwarfDebug::emitAccelTypes() {
2907 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2915 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2922 case dwarf::DW_TAG_class_type:
2923 case dwarf::DW_TAG_structure_type:
2924 case dwarf::DW_TAG_union_type:
2925 case dwarf::DW_TAG_enumeration_type:
2931 case dwarf::DW_TAG_typedef:
2932 case dwarf::DW_TAG_base_type:
2933 case dwarf::DW_TAG_subrange_type:
2934 case dwarf::DW_TAG_template_alias:
2936 case dwarf::DW_TAG_namespace:
2938 case dwarf::DW_TAG_subprogram:
2940 case dwarf::DW_TAG_variable:
2942 case dwarf::DW_TAG_enumerator:
2952void DwarfDebug::emitDebugPubSections() {
2953 for (
const auto &NU : CUMap) {
2964 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
2969 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
2976 CU.getDebugSectionOffset());
2981void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
2989 "pub" +
Name,
"Length of Public " +
Name +
" Info");
2995 emitSectionReference(*TheU);
3002 for (
const auto &GI : Globals)
3005 return A.second->getOffset() <
B.second->getOffset();
3007 for (
const auto &[
Name, Entity] : Vec) {
3029void DwarfDebug::emitDebugStr() {
3030 MCSection *StringOffsetsSection =
nullptr;
3032 emitStringOffsetsTableHeader();
3037 StringOffsetsSection,
true);
3044 auto Comment = Comments.begin();
3045 auto End = Comments.end();
3060 for (
const auto &
Op : Expr) {
3062 "3 operand ops not yet supported");
3071 for (
unsigned J = 0; J <
Length; ++J)
3076 Streamer.
emitInt8(
Data.getData()[J], Comment !=
End ? *(Comment++) :
"");
3087 auto *DIExpr =
Value.getExpression();
3093 if (DIExpr && DIExpr->isEntryValue()) {
3110 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3113 if (Entry.isInt()) {
3114 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3115 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3119 }
else if (Entry.isLocation()) {
3121 if (Location.isIndirect())
3127 }
else if (Entry.isTargetIndexLocation()) {
3133 }
else if (Entry.isConstantFP()) {
3136 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3137 }
else if (Entry.getConstantFP()
3140 .getBitWidth() <= 64 ) {
3142 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3145 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3146 << Entry.getConstantFP()
3157 if (!
Value.isVariadic()) {
3158 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3167 return Entry.isLocation() && !Entry.getLoc().getReg();
3172 std::move(ExprCursor),
3173 [EmitValueLocEntry, &
Value](
unsigned Idx,
3175 return EmitValueLocEntry(
Value.getLocEntries()[
Idx], Cursor);
3184 "location list entries without values are redundant");
3185 assert(Begin != End &&
"unexpected location list entry with empty range");
3190 if (
Value.isFragment()) {
3193 return P.isFragment();
3194 }) &&
"all values are expected to be fragments");
3197 for (
const auto &Fragment : Values)
3201 assert(Values.
size() == 1 &&
"only fragments may have >1 value");
3215 else if (DebugLocs.
getBytes(Entry).
size() <= std::numeric_limits<uint16_t>::max())
3235 Asm->OutStreamer->AddComment(
"Offset entry count");
3241 Asm->getDwarfOffsetByteSize());
3255 Asm->OutStreamer->AddComment(
"Offset entry count");
3256 Asm->emitInt32(DebugLocs.getLists().size());
3257 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3259 for (
const auto &
List : DebugLocs.getLists())
3260 Asm->emitLabelDifference(
List.Label, DebugLocs.getSym(),
3261 Asm->getDwarfOffsetByteSize());
3266template <
typename Ranges,
typename PayloadEmitter>
3270 unsigned StartxLength,
unsigned EndOfList,
3272 bool ShouldUseBaseAddress,
3273 PayloadEmitter EmitPayload) {
3275 auto Size = Asm->MAI->getCodePointerSize();
3279 Asm->OutStreamer->emitLabel(
Sym);
3286 for (
const auto &
Range : R)
3287 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3289 const MCSymbol *CUBase =
CU.getBaseAddress();
3290 bool BaseIsSet =
false;
3291 for (
const auto &
P : SectionRanges) {
3292 auto *
Base = CUBase;
3293 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB())) {
3303 }
else if (!
Base && ShouldUseBaseAddress) {
3304 const MCSymbol *Begin =
P.second.front()->Begin;
3309 Asm->OutStreamer->emitIntValue(-1,
Size);
3310 Asm->OutStreamer->AddComment(
" base address");
3311 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3312 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3318 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3319 Asm->emitInt8(BaseAddressx);
3320 Asm->OutStreamer->AddComment(
" base address index");
3323 }
else if (BaseIsSet && !UseDwarf5) {
3326 Asm->OutStreamer->emitIntValue(-1,
Size);
3327 Asm->OutStreamer->emitIntValue(0,
Size);
3330 for (
const auto *RS :
P.second) {
3333 assert(Begin &&
"Range without a begin symbol?");
3334 assert(
End &&
"Range without an end symbol?");
3338 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3339 Asm->emitInt8(OffsetPair);
3340 Asm->OutStreamer->AddComment(
" starting offset");
3341 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3342 Asm->OutStreamer->AddComment(
" ending offset");
3343 Asm->emitLabelDifferenceAsULEB128(
End,
Base);
3345 Asm->emitLabelDifference(Begin,
Base,
Size);
3348 }
else if (UseDwarf5) {
3349 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3350 Asm->emitInt8(StartxLength);
3351 Asm->OutStreamer->AddComment(
" start index");
3353 Asm->OutStreamer->AddComment(
" length");
3354 Asm->emitLabelDifferenceAsULEB128(
End, Begin);
3356 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3357 Asm->OutStreamer->emitSymbolValue(
End,
Size);
3364 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3368 Asm->OutStreamer->emitIntValue(0,
Size);
3369 Asm->OutStreamer->emitIntValue(0,
Size);
3376 *
List.CU, dwarf::DW_LLE_base_addressx,
3377 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
3381 DD.emitDebugLocEntryLocation(E, List.CU);
3385void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3403void DwarfDebug::emitDebugLoc() {
3411void DwarfDebug::emitDebugLocDWO() {
3451void DwarfDebug::emitDebugARanges() {
3452 if (ArangeLabels.empty())
3459 for (
const SymbolCU &SCU : ArangeLabels) {
3460 if (SCU.Sym->isInSection()) {
3462 MCSection *Section = &SCU.Sym->getSection();
3463 SectionMap[Section].push_back(SCU);
3468 SectionMap[
nullptr].push_back(SCU);
3474 for (
auto &
I : SectionMap) {
3484 Span.
Start = Cur.Sym;
3487 Spans[Cur.CU].push_back(Span);
3497 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3502 if (Cur.
CU != Prev.
CU) {
3504 Span.
Start = StartSym;
3507 Spans[Prev.
CU].push_back(Span);
3520 std::vector<DwarfCompileUnit *> CUs;
3521 for (
const auto &it : Spans) {
3528 return A->getUniqueID() <
B->getUniqueID();
3533 std::vector<ArangeSpan> &
List = Spans[
CU];
3536 if (
auto *Skel =
CU->getSkeleton())
3540 unsigned ContentSize =
3547 unsigned TupleSize = PtrSize * 2;
3554 ContentSize += (
List.size() + 1) * TupleSize;
3561 emitSectionReference(*
CU);
3577 auto SizeRef = SymSize.find(Span.Start);
3578 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3584 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3587 Size = SizeRef->second;
3603 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3604 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3606 List.CU->getCUNode()->getRangesBaseAddress() ||
3618 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3636void DwarfDebug::emitDebugRanges() {
3637 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3639 emitDebugRangesImpl(Holder,
3645void DwarfDebug::emitDebugRangesDWO() {
3646 emitDebugRangesImpl(InfoHolder,
3654 enum HeaderFlagMask {
3655#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3656#include "llvm/BinaryFormat/Dwarf.def"
3658 Asm->OutStreamer->AddComment(
"Macro information version");
3659 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3662 if (Asm->isDwarf64()) {
3663 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3664 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3666 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3667 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3669 Asm->OutStreamer->AddComment(
"debug_line_offset");
3671 Asm->emitDwarfLengthOrOffset(0);
3673 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3676void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3677 for (
auto *MN : Nodes) {
3678 if (
auto *M = dyn_cast<DIMacro>(MN))
3680 else if (
auto *
F = dyn_cast<DIMacroFile>(MN))
3681 emitMacroFile(*
F, U);
3687void DwarfDebug::emitMacro(
DIMacro &M) {
3695 if (UseDebugMacroSection) {
3698 ? dwarf::DW_MACRO_define_strx
3699 : dwarf::DW_MACRO_undef_strx;
3709 ? dwarf::DW_MACRO_GNU_define_indirect
3710 : dwarf::DW_MACRO_GNU_undef_indirect;
3730void DwarfDebug::emitMacroFileImpl(
3732 StringRef (*MacroFormToString)(
unsigned Form)) {
3755 if (UseDebugMacroSection)
3757 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3764void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3765 for (
const auto &
P : CUMap) {
3766 auto &TheCU = *
P.second;
3769 auto *CUNode = cast<DICompileUnit>(
P.first);
3770 DIMacroNodeArray Macros = CUNode->getMacros();
3775 if (UseDebugMacroSection)
3777 handleMacroNodes(Macros, U);
3784void DwarfDebug::emitDebugMacinfo() {
3786 emitDebugMacinfoImpl(UseDebugMacroSection
3787 ? ObjLower.getDwarfMacroSection()
3788 : ObjLower.getDwarfMacinfoSection());
3791void DwarfDebug::emitDebugMacinfoDWO() {
3793 emitDebugMacinfoImpl(UseDebugMacroSection
3794 ? ObjLower.getDwarfMacroDWOSection()
3795 : ObjLower.getDwarfMacinfoDWOSection());
3800void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3801 std::unique_ptr<DwarfCompileUnit> NewU) {
3803 if (!CompilationDir.
empty())
3804 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3805 addGnuPubAttributes(*NewU, Die);
3807 SkeletonHolder.
addUnit(std::move(NewU));
3812 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3813 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3823 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3830void DwarfDebug::emitDebugInfoDWO() {
3838void DwarfDebug::emitDebugAbbrevDWO() {
3843void DwarfDebug::emitDebugLineDWO() {
3845 SplitTypeUnitFileTable.
Emit(
3850void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3860void DwarfDebug::emitDebugStrDWO() {
3862 emitStringOffsetsTableHeaderDWO();
3870void DwarfDebug::emitDebugAddr() {
3881 return &SplitTypeUnitFileTable;
3892 return Result.high();
3901 if (!TypeUnitsUnderConstruction.empty() && AddrPool.
hasBeenUsed())
3904 auto Ins = TypeSignatures.try_emplace(CTy);
3906 CU.addDIETypeSignature(RefDie, Ins.first->second);
3911 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3914 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
3915 CU,
Asm,
this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(
CU));
3918 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3920 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3925 Ins.first->second = Signature;
3933 if (!CompilationDir.
empty())
3934 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
3935 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
3950 CU.applyStmtList(UnitDie);
3961 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
3962 TypeUnitsUnderConstruction.clear();
3967 AccelTypeUnitsDebugNames.
clear();
3971 for (
const auto &
TU : TypeUnitsToAdd)
3972 TypeSignatures.erase(
TU.second);
3979 CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));
3980 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
3986 for (
auto &
TU : TypeUnitsToAdd) {
3999 AccelTypeUnitsDebugNames.
clear();
4002 CU.addDIETypeSignature(RefDie, Signature);
4009template <
typename DataT>
4010void DwarfDebug::addAccelNameImpl(
4015 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit ||
Name.empty())
4032 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4033 ((&Current == &AccelDebugNames) &&
4034 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4035 "Kind is CU but TU is being processed.");
4036 assert(((&Current == &AccelDebugNames) ||
4037 ((&Current == &AccelTypeUnitsDebugNames) &&
4038 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4039 "Kind is TU but CU is being processed.");
4042 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4043 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4057 addAccelNameImpl(Unit, NameTableKind, AccelNames,
Name, Die);
4066 addAccelNameImpl(Unit, NameTableKind, AccelObjC,
Name, Die);
4073 addAccelNameImpl(Unit, NameTableKind, AccelNamespace,
Name, Die);
4079 const DIE &Die,
char Flags) {
4080 addAccelNameImpl(Unit, NameTableKind, AccelTypes,
Name, Die);
4089 return dwarf::Form::DW_FORM_sec_offset;
4091 "DWARF64 is not defined prior DWARFv3");
4093 : dwarf::Form::DW_FORM_data4;
4097 return SectionLabels.lookup(S);
4101 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4106std::optional<MD5::MD5Result>
4110 return std::nullopt;
4111 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4113 return std::nullopt;
4118 std::string ChecksumString = fromHex(Checksum->Value);
4145 auto PrevLoc =
Asm->
OutStreamer->getContext().getCurrentDwarfLoc();
4146 if (PrevLoc.getLine()) {
4148 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))
Set to false to ignore Key Instructions metadata.
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 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 recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, const MDNode *S, unsigned Flags, unsigned CUID, uint16_t DwarfVersion, ArrayRef< std::unique_ptr< DwarfCompileUnit > > DCUs, StringRef Comment={})
Register a source line with debug info.
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
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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 LLVM_ABI 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 LLVM_ABI 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.
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
LLVM_ABI 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.
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
LLVM_ABI bool isValid() const
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
Base class for scope-like contexts.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
LLVM_ABI DIScope * getScope() const
Subprogram description. Uses SubclassData1.
DIScope * getScope() const
LLVM_ABI void addTypeUnitSignature(DwarfTypeUnit &U)
Add a type unit Signature.
void convertDieToOffset()
Convert DIE entries to explicit offset.
LLVM_ABI void addTypeUnitSymbol(DwarfTypeUnit &U)
Add a type unit start symbol.
void addTypeEntries(DWARF5AccelTable &Table)
This class represents an Operation in the Expression.
LLVM_ABI 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.
DebugLoc PrevInstLoc
Previous instruction's location information.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an 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.
void beginModule(Module *M) override
const InstructionOrdering & getInstOrdering() const
void requestLabelBeforeInsn(const MachineInstr *MI)
Ensure that a label will be emitted before 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
LLVM_ABI unsigned getLine() const
LLVM_ABI MDNode * getScope() const
LLVM_ABI unsigned getCol() 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
LLVM_ABI_FOR_TEST EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
LLVM_ABI_FOR_TEST 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....
LLVM_ABI_FOR_TEST 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.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
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...
LLVM_ABI LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
LLVM_ABI 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)
LLVM_ABI void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
static LLVM_ABI 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
This holds information about one operand of a machine instruction, indicating the register class for ...
uint8_t OperandType
Information about the type of the operand.
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
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
LLVM_ABI 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.
LLVM_ABI void print(raw_ostream &OS, const SlotIndexes *=nullptr, bool IsStandalone=true) const
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
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...
mop_range uses()
Returns all operands which may be register uses.
LLVM_ABI 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.
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
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...
void insert_range(Range &&R)
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
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.
LLVM_ABI 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 TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
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.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
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()
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI StringRef RangeListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
LLVM_ABI StringRef MacroString(unsigned Encoding)
LLVM_ABI StringRef LocListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GnuMacroString(unsigned Encoding)
LLVM_ABI StringRef MacinfoString(unsigned Encoding)
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
LLVM_ABI 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...
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
OutputIt copy(R &&Range, OutputIt Out)
LLVM_ABI 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.