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"),
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"),
159 "Use rnglists for contiguous ranges if that allows "
160 "using a pre-existing base address"),
163 "Use exprloc addrx+offset expressions for any "
164 "address with a prior base address"),
166 "Use addrx+offset extension form for any address "
167 "with a prior base address"),
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) {
186 getActiveStreamer().emitSLEB128(
Value, Twine(
Value));
189void DebugLocDwarfExpression::emitUnsigned(uint64_t
Value) {
190 getActiveStreamer().emitULEB128(
Value, Twine(
Value));
193void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
194 getActiveStreamer().emitInt8(
Value, Twine(
Value));
197void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
209 assert(!IsBuffering &&
"Already buffering?");
211 TmpBuf = std::make_unique<TempBuffer>(OutBS.GenerateComments);
218 return TmpBuf ? TmpBuf->Bytes.size() : 0;
224 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
225 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
226 ? TmpBuf->Comments[
Byte.index()].c_str()
228 OutBS.emitInt8(
Byte.value(), Comment);
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()) {
289 if (!Expr->getNumElements())
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()) {
339 const Triple &TT =
Asm->TM.getTargetTriple();
344 DebuggerTuning =
Asm->TM.Options.DebuggerTuning;
349 else if (TT.isOSAIX())
355 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
365 HasSplitDwarf = !
Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
373 unsigned DwarfVersionNumber =
Asm->TM.Options.MCOptions.DwarfVersion;
374 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
375 :
MMI->getModule()->getDwarfVersion();
380 bool Dwarf64 = DwarfVersion >= 3 &&
389 ((
Asm->TM.Options.MCOptions.Dwarf64 ||
MMI->getModule()->isDwarf64()) &&
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;
429 EmitDebugEntryValues =
Asm->TM.Options.ShouldEmitDebugEntryValues();
433 UseDebugMacroSection =
442 if (DwarfVersion >= 5)
445 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
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())
554 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
555 if (
CU.getSkeleton())
561void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
563 assert(Scope && Scope->getScopeNode());
564 assert(Scope->isAbstractScope());
565 assert(!Scope->getInlinedAt());
571 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
573 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
574 if (
auto *SkelCU =
CU.getSkeleton())
575 if (
CU.getCUNode()->getSplitDebugInlining())
576 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
610template <
typename ValT>
614 for (
auto Param : DescribedParams) {
615 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
630 "Combined debug expression is invalid");
645 auto &ParamsForFwdReg = Worklist[
Reg];
646 for (
auto Param : ParamsToAdd) {
649 return D.ParamReg == Param.ParamReg;
651 "Same parameter described twice by forwarding reg");
658 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
701 if (
MI.isDebugInstr())
705 if (MO.getReg().isPhysical()) {
706 for (
auto &FwdReg : ForwardedRegWorklist)
707 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
708 Defs.insert(FwdReg.first);
717 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
718 if (FwdRegDefs.
empty()) {
727 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
728 for (
auto &RegUnit : ClobberedRegUnits)
729 if (
TRI.hasRegUnit(
Reg, RegUnit))
734 for (
auto ParamFwdReg : FwdRegDefs) {
735 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
736 if (ParamValue->first.isImm()) {
737 int64_t Val = ParamValue->first.getImm();
739 ForwardedRegWorklist[ParamFwdReg], Params);
740 }
else if (ParamValue->first.isReg()) {
741 Register RegLoc = ParamValue->first.getReg();
742 Register SP = TLI.getStackPointerRegisterToSaveRestore();
744 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
745 if (!IsRegClobberedInMeantime(RegLoc) &&
746 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
749 ForwardedRegWorklist[ParamFwdReg], Params);
758 ForwardedRegWorklist[ParamFwdReg]);
765 for (
auto ParamFwdReg : FwdRegDefs)
766 ForwardedRegWorklist.
erase(ParamFwdReg);
773 for (
auto &New : TmpWorklistItems)
775 TmpWorklistItems.
clear();
792 if (ForwardedRegWorklist.
empty())
799 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
810 auto CSInfo = CalleesMap.
find(CallMI);
813 if (CSInfo == CalleesMap.end())
827 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
829 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
831 assert(InsertedReg &&
"Single register used to forward two arguments?");
836 for (
const auto &MO : CallMI->
uses())
837 if (MO.isReg() && MO.isUndef())
838 ForwardedRegWorklist.
erase(MO.getReg());
848 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
857 assert(std::next(Suc) == BundleEnd &&
858 "More than one instruction in call delay slot");
865 for (;
I !=
MBB->rend(); ++
I) {
872 if (ShouldTryEmitEntryVals) {
876 for (
auto &RegEntry : ForwardedRegWorklist) {
883void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
888 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
895 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
898 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
901 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
902 if (!
MI.isBundledWithSucc())
904 auto Suc = std::next(
MI.getIterator());
906 (void)CallInstrBundle;
908 (void)DelaySlotBundle;
915 "Call and its successor instruction don't have same label after.");
920 for (
const MachineBasicBlock &
MBB : MF) {
930 if (!
MI.isCandidateForAdditionalCallInfo())
939 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
947 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
948 bool PhysRegCalleeOperand =
953 const MCOperandInfo &MCOI =
955 PhysRegCalleeOperand =
959 unsigned CallReg = 0;
960 const DISubprogram *CalleeSP =
nullptr;
961 const Function *CalleeDecl =
nullptr;
962 if (PhysRegCalleeOperand) {
963 CallReg = CalleeOp.
getReg();
972 if (CalleeSP ==
nullptr && CallReg == 0 && AllocSiteTy ==
nullptr)
982 const MachineInstr *TopLevelCallMI =
989 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
998 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1001 << (CalleeDecl ? CalleeDecl->
getName()
1002 : StringRef(MF.getSubtarget()
1004 ->getName(CallReg)))
1005 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1008 CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, CalleeDecl, IsTail,
1009 PCAddr, CallAddr, CallReg, AllocSiteTy);
1016 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1023 if (!
U.hasDwarfPubSections())
1026 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1029void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1037 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1038 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1040 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1043 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1046 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1047 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1050 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1054 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1056 if (!SysRoot.
empty())
1057 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1058 StringRef SDK = DIUnit->
getSDK();
1060 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1071 if (!CompilationDir.empty())
1072 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1073 addGnuPubAttributes(NewCU, Die);
1078 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1082 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1085 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1086 dwarf::DW_FORM_data1, RVer);
1091 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1096 ? dwarf::DW_AT_dwo_name
1097 : dwarf::DW_AT_GNU_dwo_name;
1105DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1106 if (
auto *
CU = CUMap.lookup(DIUnit))
1114 return *CUMap.begin()->second;
1118 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1119 InfoHolder.getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1120 DwarfCompileUnit &NewCU = *OwnedUnit;
1121 InfoHolder.addUnit(std::move(OwnedUnit));
1127 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1128 Asm->OutStreamer->emitDwarfFile0Directive(
1134 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1136 finishUnitAttributes(DIUnit, NewCU);
1137 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1140 CUMap.insert({DIUnit, &NewCU});
1141 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1155 if (!
A.Expr || !
B.Expr)
1157 auto FragmentA =
A.Expr->getFragmentInfo();
1158 auto FragmentB =
B.Expr->getFragmentInfo();
1159 if (!FragmentA || !FragmentB)
1161 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1166 return A.Expr ==
B.Expr;
1181 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1182 M->debug_compile_units_end());
1183 if (NumDebugCUs == 0)
1186 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1187 SingleCU = NumDebugCUs == 1;
1192 Global.getDebugInfo(GVs);
1193 for (
auto *GVE : GVs)
1194 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1202 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1210 Asm->createTempSymbol(
"rnglists_table_base"));
1213 InfoHolder.setRnglistsTableBaseSym(
1214 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1219 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1220 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1223 if (CUNode->getImportedEntities().empty() &&
1224 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1225 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1231 for (
auto *GVE : CUNode->getGlobalVariables()) {
1235 auto &GVMapEntry = GVMap[GVE->getVariable()];
1236 auto *Expr = GVE->getExpression();
1237 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1238 GVMapEntry.push_back({
nullptr, Expr});
1242 for (
auto *GVE : CUNode->getGlobalVariables()) {
1244 if (Processed.
insert(GV).second)
1248 for (
auto *Ty : CUNode->getEnumTypes())
1251 for (
auto *Ty : CUNode->getRetainedTypes()) {
1256 CU.getOrCreateTypeDIE(RT);
1261void DwarfDebug::finishEntityDefinitions() {
1262 for (
const auto &Entity : ConcreteEntities) {
1263 DIE *Die = Entity->getDIE();
1270 Unit->finishEntityDefinition(Entity.get());
1274void DwarfDebug::finishSubprogramDefinitions() {
1275 for (
const DISubprogram *SP : ProcessedSPNodes) {
1278 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1279 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1283void DwarfDebug::finalizeModuleInfo() {
1284 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1286 finishSubprogramDefinitions();
1288 finishEntityDefinitions();
1290 bool HasEmittedSplitCU =
false;
1294 for (
const auto &
P : CUMap) {
1295 auto &TheCU = *
P.second;
1296 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1298 TheCU.attachLexicalScopesAbstractOrigins();
1301 TheCU.constructContainingTypeDIEs();
1306 auto *SkCU = TheCU.getSkeleton();
1308 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1311 (void)HasEmittedSplitCU;
1313 "Multiple CUs emitted into a single dwo file");
1314 HasEmittedSplitCU =
true;
1316 ? dwarf::DW_AT_dwo_name
1317 : dwarf::DW_AT_GNU_dwo_name;
1318 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1319 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1320 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1321 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1327 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1332 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1333 dwarf::DW_FORM_data8,
ID);
1334 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1335 dwarf::DW_FORM_data8,
ID);
1338 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1340 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1344 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1353 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1355 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1360 if (!(
Asm->TM.getTargetTriple().isNVPTX() &&
tuneForGDB())) {
1366 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1369 U.setBaseAddress(TheCU.getRanges().front().Begin);
1370 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1377 U.addAddrTableBase();
1380 if (
U.hasRangeLists())
1381 U.addRnglistsBase();
1384 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1393 if (CUNode->getMacros()) {
1394 if (UseDebugMacroSection) {
1396 TheCU.addSectionDelta(
1397 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1401 ? dwarf::DW_AT_macros
1402 : dwarf::DW_AT_GNU_macros;
1403 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1408 TheCU.addSectionDelta(
1409 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1410 U.getMacroLabelBegin(),
1413 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1414 U.getMacroLabelBegin(),
1421 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1422 if (CUNode->getDWOId())
1423 getOrCreateDwarfCompileUnit(CUNode);
1426 InfoHolder.computeSizeAndOffsets();
1428 SkeletonHolder.computeSizeAndOffsets();
1432 AccelDebugNames.convertDieToOffset();
1441 assert(CurFn ==
nullptr);
1444 for (
const auto &
P : CUMap) {
1449 for (
auto *IE : CUNode->getImportedEntities()) {
1451 "Unexpected function-local entity in 'imports' CU field.");
1452 CU->getOrCreateImportedEntityDIE(IE);
1454 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1456 CU->getOrCreateImportedEntityDIE(IE);
1462 CU->createBaseTypeDIEs();
1467 if (!
Asm || !
Asm->hasDebugInfo())
1471 finalizeModuleInfo();
1481 emitAbbreviations();
1487 if (UseARangesSection)
1495 emitDebugMacinfoDWO();
1505 emitDebugAbbrevDWO();
1507 emitDebugRangesDWO();
1517 emitAccelNamespaces();
1521 emitAccelDebugNames();
1530 emitDebugPubSections();
1538 if (
CU.getExistingAbstractEntity(
Node))
1543 CU.createAbstractEntity(
Node, Scope);
1552void DwarfDebug::collectVariableInfoFromMFTable(
1554 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1555 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1556 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1559 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1560 "Expected inlined-at fields to agree");
1562 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1569 <<
", no variable scope found\n");
1573 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1577 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1578 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1579 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1581 if (PreviousMMI &&
VI.inStackSlot())
1582 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1584 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1585 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1590 if (PreviousLoc->holds<Loc::MMI>())
1591 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1594 <<
", conflicting fragment location types\n");
1599 auto RegVar = std::make_unique<DbgVariable>(
1601 if (
VI.inStackSlot())
1602 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1604 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1607 InfoHolder.addScopeVariable(Scope, RegVar.get());
1608 MFVars.
insert({Var, RegVar.get()});
1609 ConcreteEntities.push_back(std::move(RegVar));
1621 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1629 if (LSRange.size() == 0)
1632 const MachineInstr *LScopeBegin = LSRange.front().first;
1636 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1642 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1645 auto PredDL = Pred->getDebugLoc();
1646 if (!PredDL || Pred->isMetaInstruction())
1650 if (
DL->getScope() == PredDL->getScope())
1653 if (!PredScope || LScope->dominates(PredScope))
1666 if (
MBB->pred_empty() &&
1673 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1717 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1719 bool isSafeForSingleLocation =
true;
1720 const MachineInstr *StartDebugMI =
nullptr;
1721 const MachineInstr *EndMI =
nullptr;
1723 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1724 const MachineInstr *
Instr = EI->getInstr();
1727 size_t Index = std::distance(EB, EI);
1728 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1735 "Forgot label before/after instruction starting a range!");
1738 if (std::next(EI) == Entries.
end()) {
1739 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1741 if (EI->isClobber())
1742 EndMI = EI->getInstr();
1744 else if (std::next(EI)->isClobber())
1748 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1750 if (EI->isDbgValue())
1756 if (EI->isDbgValue()) {
1763 if (!
Instr->isUndefDebugValue()) {
1768 if (
Instr->getDebugExpression()->isFragment())
1769 isSafeForSingleLocation =
false;
1772 StartDebugMI =
Instr;
1774 isSafeForSingleLocation =
false;
1780 if (OpenRanges.
empty())
1784 if (StartLabel == EndLabel) {
1785 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1790 for (
auto &R : OpenRanges)
1798 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1799 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1800 for (
const auto &[MBBSectionId, MBBSectionRange] :
1801 Asm->MBBSectionRanges) {
1802 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1803 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1806 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1807 MBBSectionRange.EndLabel, Values);
1810 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1817 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1818 for (
auto &
Value : CurEntry->getValues())
1820 dbgs() <<
"-----\n";
1823 auto PrevEntry = std::next(CurEntry);
1824 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1828 if (!isSafeForSingleLocation ||
1835 if (!
Asm->MF->hasBBSections())
1843 const MachineBasicBlock *RangeMBB =
nullptr;
1844 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1845 RangeMBB = &
Asm->MF->front();
1847 RangeMBB = Entries.
begin()->getInstr()->getParent();
1849 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1850 "Range MBB not found in MBBSectionRanges!");
1852 auto *NextEntry = std::next(CurEntry);
1853 auto NextRangeIt = std::next(RangeIt);
1854 while (NextEntry !=
DebugLoc.end()) {
1855 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1862 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1863 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1864 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1865 CurEntry->getValues() != NextEntry->getValues())
1867 RangeIt = NextRangeIt;
1868 NextRangeIt = std::next(RangeIt);
1869 CurEntry = NextEntry;
1870 NextEntry = std::next(CurEntry);
1880 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1882 ConcreteEntities.push_back(
1885 InfoHolder.addScopeVariable(&Scope,
1888 ConcreteEntities.push_back(
1891 InfoHolder.addScopeLabel(&Scope,
1894 return ConcreteEntities.back().get();
1902 collectVariableInfoFromMFTable(TheCU, Processed);
1905 InlinedEntity
IV =
I.first;
1910 const auto &HistoryMapEntries =
I.second;
1914 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
1917 LexicalScope *
Scope =
nullptr;
1919 if (
const DILocation *IA =
IV.second)
1929 *Scope, LocalVar,
IV.second));
1931 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1937 size_t HistSize = HistoryMapEntries.size();
1938 bool SingleValueWithClobber =
1939 HistSize == 2 && HistoryMapEntries[1].isClobber();
1940 if (HistSize == 1 || SingleValueWithClobber) {
1942 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1944 RegVar->emplace<Loc::Single>(MInsn);
1950 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
1954 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1959 if (isValidSingleLocation) {
1960 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
1971 for (
auto &Entry : Entries)
1978 InlinedEntity IL =
I.first;
1979 const MachineInstr *
MI =
I.second;
1983 LexicalScope *
Scope =
nullptr;
1986 const DILocalScope *LocalScope =
1987 Label->getScope()->getNonLexicalBlockFileScope();
1989 if (
const DILocation *IA = IL.second)
2002 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2006 for (
const DINode *DN :
SP->getRetainedNodes()) {
2009 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2011 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2013 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2015 LocalDeclsPerLS[
LS].insert(DN);
2029 if (!
MI.isBundledWithSucc())
2031 auto Suc = std::next(
MI.getIterator());
2036 assert(Suc->isBundledWithPred() &&
2037 "Call bundle instructions are out of order");
2042 if (!NoDebug && SP->areAllCallsDescribed() &&
2044 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2046 bool IsTail =
TII->isTailCall(*
MI);
2064 auto RecordLineZero = [&]() {
2068 const MDNode *Scope =
nullptr;
2069 unsigned Column = 0;
2074 recordSourceLine(0, Column, Scope, 0);
2079 unsigned LastAsmLine =
2080 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2085 if (
MI->isMetaInstruction())
2106 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2108 if (
Asm->OutStreamer->isVerboseAsm()) {
2112 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2121 bool ScopeUsesKeyInstructions =
2123 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2126 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2127 IsKey = KeyInstructions.contains(
MI);
2133 assert(
MI->getParent() == &*
MI->getMF()->begin());
2134 recordSourceLine(SP->getScopeLine(), 0, SP,
2139 bool PrevInstInSameSection =
2141 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2142 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2143 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2153 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2155 RecordSourceLine(
DL, Flags);
2168 if (LastAsmLine == 0)
2189 if (
DL.getLine() == 0 && LastAsmLine == 0)
2196 if (ScopeUsesKeyInstructions) {
2203 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2207 RecordSourceLine(
DL, Flags);
2219static std::pair<const MachineInstr *, bool>
2230 bool IsEmptyPrologue =
2231 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2236 -> std::optional<std::pair<const MachineInstr *, bool>> {
2238 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2239 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2242 if (!isFrameSetup &&
MI.getDebugLoc()) {
2248 if (
MI.getDebugLoc().getLine())
2249 return std::make_pair(&
MI, IsEmptyPrologue);
2254 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2255 NonTrivialInst = &
MI;
2257 IsEmptyPrologue =
false;
2258 return std::nullopt;
2266 auto CurBlock = MF->
begin();
2267 auto CurInst = CurBlock->begin();
2271 while (CurBlock->empty())
2272 CurInst = (++CurBlock)->begin();
2273 assert(CurInst != CurBlock->end());
2277 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2279 if (CurInst->isTerminator()) {
2288 if (CurBlock->pred_size() > 1)
2299 if (CurBlock == MF->
end())
2301 }
while (CurBlock->empty());
2302 CurInst = CurBlock->begin();
2308 if (!CurInst->isMetaInstruction()) {
2309 auto FoundInst = ExamineInst(*CurInst);
2320 if (CurInst->isCall()) {
2322 Loc &&
Loc->getLine() == 0) {
2324 unsigned ScopeLine = SP->getScopeLine();
2327 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2330 return std::make_pair(&*CurInst,
false);
2336 auto NextInst = std::next(CurInst);
2337 if (NextInst != CurInst->getParent()->end()) {
2354 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2355 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2356 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2360 return std::make_pair(
nullptr, IsEmptyPrologue);
2366 const MDNode *S,
unsigned Flags,
unsigned CUID,
2368 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2371 unsigned FileNo = 1;
2374 Fn =
Scope->getFilename();
2375 if (Line != 0 && DwarfVersion >= 4)
2380 .getOrCreateSourceID(
Scope->getFile());
2382 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2383 Discriminator, Fn, Comment);
2394 bool IsEmptyPrologue = PrologEnd.second;
2397 if (IsEmptyPrologue) {
2405 if (!
DL ||
DL->getLine() != 0)
2416 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2426 KeyInstructions.clear();
2433 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2450 for (
auto &
MBB : *MF) {
2462 for (
auto &
MI :
MBB) {
2463 if (
MI.isMetaInstruction())
2467 if (!
Loc || !
Loc->getLine())
2478 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2483 KeyInstructions.insert(Buoy);
2489 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2493 auto *InlinedAt = Loc->getInlinedAt();
2496 if (!Group || !Rank)
2500 if (BuoyAtom && BuoyAtom != Group) {
2505 auto &[CandidateRank, CandidateInsts] =
2506 GroupCandidates[{InlinedAt, Group}];
2512 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2513 (CandidateRank != 0 && !CandidateInsts.empty()));
2515 assert(Rank &&
"expected nonzero rank");
2518 if (CandidateRank && CandidateRank < Rank)
2525 if (CandidateRank == Rank)
2529 else if (CandidateRank > Rank)
2530 CandidateInsts.clear();
2534 CandidateInsts.push_back(Buoy);
2535 CandidateRank = Rank;
2543 if (CandidateInsts.empty())
2549 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2550 for (
auto *
I : Insts)
2551 KeyInstructions.insert(
I);
2559 ForceIsStmtInstrs.clear();
2591 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2592 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2595 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2598 for (
auto &
MI :
MBB) {
2599 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2612 for (
auto *
MBB : PredMBBsToExamine) {
2613 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2614 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2615 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2617 MachineInstr *
MI = MBBInstrIt->second;
2618 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2620 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2621 ForceIsStmtInstrs.insert(
MI);
2628 CheckMBBEdge(Succ, 0);
2634 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2642 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2649 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2652 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2653 CheckMBBEdge(FBB, FBBLine);
2677 unsigned LastLine = 0;
2679 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2680 LastLine =
DL->getLine();
2685 for (
auto *Succ : SuccessorBBs)
2686 CheckMBBEdge(Succ, LastLine);
2701 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2702 ?
Asm->OutStreamer->emitLineTableLabel()
2705 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2710 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2716 computeKeyInstructions(MF);
2717 findForceIsStmtInstrs(MF);
2725 if (
Asm->OutStreamer->hasRawTextSupport())
2729 return CU.getUniqueID();
2733 const auto &CURanges =
CU->getRanges();
2734 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2737 LineTable.getMCLineSections().addEndEntry(
2738 const_cast<MCSymbol *
>(CURanges.back().End));
2758 "endFunction should be called with the same function as beginFunction");
2761 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2773 collectEntityInfo(TheCU, SP, Processed);
2777 for (
const auto &R :
Asm->MBBSectionRanges)
2778 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2785 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2786 for (
const auto &R :
Asm->MBBSectionRanges)
2789 assert(InfoHolder.getScopeVariables().empty());
2796 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2800 for (
const DINode *DN : SP->getRetainedNodes()) {
2803 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2804 assert(LexS &&
"Expected the LexicalScope to be created.");
2807 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2813 LocalDeclsPerLS[LS].insert(DN);
2816 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2817 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2819 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2822 ProcessedSPNodes.insert(SP);
2826 if (!
LScopes.getAbstractScopesList().empty() &&
2828 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2829 FunctionLineTableLabel);
2831 FunctionLineTableLabel =
nullptr;
2834 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2840 InfoHolder.getScopeVariables().clear();
2841 InfoHolder.getScopeLabels().clear();
2842 LocalDeclsPerLS.clear();
2849void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2861void DwarfDebug::emitDebugInfo() {
2867void DwarfDebug::emitAbbreviations() {
2868 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2870 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2873void DwarfDebug::emitStringOffsetsTableHeader() {
2874 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2876 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2880template <
typename AccelTableT>
2881void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2883 Asm->OutStreamer->switchSection(Section);
2889void DwarfDebug::emitAccelDebugNames() {
2891 if (getUnits().
empty())
2898void DwarfDebug::emitAccelNames() {
2899 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
2905void DwarfDebug::emitAccelObjC() {
2906 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
2911void DwarfDebug::emitAccelNamespaces() {
2912 emitAccel(AccelNamespace,
2913 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
2918void DwarfDebug::emitAccelTypes() {
2919 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
2949 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2957 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2964 case dwarf::DW_TAG_class_type:
2965 case dwarf::DW_TAG_structure_type:
2966 case dwarf::DW_TAG_union_type:
2967 case dwarf::DW_TAG_enumeration_type:
2972 case dwarf::DW_TAG_typedef:
2973 case dwarf::DW_TAG_base_type:
2974 case dwarf::DW_TAG_subrange_type:
2975 case dwarf::DW_TAG_template_alias:
2977 case dwarf::DW_TAG_namespace:
2979 case dwarf::DW_TAG_subprogram:
2981 case dwarf::DW_TAG_variable:
2983 case dwarf::DW_TAG_enumerator:
2993void DwarfDebug::emitDebugPubSections() {
2994 for (
const auto &NU : CUMap) {
2995 DwarfCompileUnit *TheU = NU.second;
3002 Asm->OutStreamer->switchSection(
3003 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3004 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3005 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3007 Asm->OutStreamer->switchSection(
3008 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3009 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3010 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3016 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3017 CU.getDebugSectionOffset());
3019 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3022void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3030 "pub" + Name,
"Length of Public " + Name +
" Info");
3032 Asm->OutStreamer->AddComment(
"DWARF Version");
3035 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3036 emitSectionReference(*TheU);
3038 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3043 for (
const auto &GI : Globals)
3046 return A.second->getOffset() <
B.second->getOffset();
3048 for (
const auto &[Name, Entity] : Vec) {
3049 Asm->OutStreamer->AddComment(
"DIE offset");
3050 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3054 Asm->OutStreamer->AddComment(
3060 Asm->OutStreamer->AddComment(
"External Name");
3061 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3064 Asm->OutStreamer->AddComment(
"End Mark");
3065 Asm->emitDwarfLengthOrOffset(0);
3066 Asm->OutStreamer->emitLabel(EndLabel);
3070void DwarfDebug::emitDebugStr() {
3071 MCSection *StringOffsetsSection =
nullptr;
3073 emitStringOffsetsTableHeader();
3074 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3076 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3077 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3078 StringOffsetsSection,
true);
3084 auto &&Comments = DebugLocs.getComments(Entry);
3085 auto Comment = Comments.begin();
3086 auto End = Comments.end();
3093 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3095 DebugLocs.getBytes(Entry).size()),
3096 Asm->getDataLayout().isLittleEndian(), PtrSize);
3101 for (
const auto &
Op : Expr) {
3102 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3103 "3 operand ops not yet supported");
3104 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3105 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3107 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3108 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3110 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3112 for (
unsigned J = 0; J <
Length; ++J)
3117 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3128 auto *DIExpr =
Value.getExpression();
3134 if (DIExpr && DIExpr->isEntryValue()) {
3151 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3154 if (Entry.isInt()) {
3155 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3157 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3158 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3162 }
else if (Entry.isLocation()) {
3164 if (Location.isIndirect())
3170 }
else if (Entry.isTargetIndexLocation()) {
3176 }
else if (Entry.isConstantFP()) {
3179 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3180 }
else if (Entry.getConstantFP()
3183 .getBitWidth() <= 64 ) {
3185 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3188 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3189 << Entry.getConstantFP()
3200 if (!
Value.isVariadic()) {
3201 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3210 return Entry.isLocation() && !Entry.getLoc().getReg();
3215 std::move(ExprCursor),
3216 [EmitValueLocEntry, &
Value](
unsigned Idx,
3218 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3226 assert(!Values.empty() &&
3227 "location list entries without values are redundant");
3228 assert(Begin != End &&
"unexpected location list entry with empty range");
3233 if (
Value.isFragment()) {
3236 return P.isFragment();
3237 }) &&
"all values are expected to be fragments");
3240 for (
const auto &Fragment : Values)
3244 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3255 Asm->OutStreamer->AddComment(
"Loc expr size");
3257 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3258 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3259 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3278 Asm->OutStreamer->AddComment(
"Offset entry count");
3284 Asm->getDwarfOffsetByteSize());
3298 Asm->OutStreamer->AddComment(
"Offset entry count");
3299 Asm->emitInt32(DebugLocs.getLists().size());
3300 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3302 for (
const auto &List : DebugLocs.getLists())
3303 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3304 Asm->getDwarfOffsetByteSize());
3309template <
typename Ranges,
typename PayloadEmitter>
3313 unsigned StartxLength,
unsigned EndOfList,
3315 bool ShouldUseBaseAddress,
3316 PayloadEmitter EmitPayload) {
3318 auto Size = Asm->MAI->getCodePointerSize();
3322 Asm->OutStreamer->emitLabel(Sym);
3329 for (
const auto &
Range : R)
3330 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3332 const MCSymbol *CUBase =
CU.getBaseAddress();
3333 bool BaseIsSet =
false;
3334 for (
const auto &
P : SectionRanges) {
3335 auto *
Base = CUBase;
3336 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB())) {
3346 }
else if (!
Base && ShouldUseBaseAddress) {
3347 const MCSymbol *Begin =
P.second.front()->Begin;
3352 Asm->OutStreamer->emitIntValue(-1,
Size);
3353 Asm->OutStreamer->AddComment(
" base address");
3354 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3355 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3361 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3362 Asm->emitInt8(BaseAddressx);
3363 Asm->OutStreamer->AddComment(
" base address index");
3366 }
else if (BaseIsSet && !UseDwarf5) {
3369 Asm->OutStreamer->emitIntValue(-1,
Size);
3370 Asm->OutStreamer->emitIntValue(0,
Size);
3373 for (
const auto *RS :
P.second) {
3376 assert(Begin &&
"Range without a begin symbol?");
3377 assert(End &&
"Range without an end symbol?");
3381 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3382 Asm->emitInt8(OffsetPair);
3383 Asm->OutStreamer->AddComment(
" starting offset");
3384 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3385 Asm->OutStreamer->AddComment(
" ending offset");
3386 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3388 Asm->emitLabelDifference(Begin,
Base,
Size);
3389 Asm->emitLabelDifference(End,
Base,
Size);
3391 }
else if (UseDwarf5) {
3392 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3393 Asm->emitInt8(StartxLength);
3394 Asm->OutStreamer->AddComment(
" start index");
3396 Asm->OutStreamer->AddComment(
" length");
3397 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3399 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3400 Asm->OutStreamer->emitSymbolValue(End,
Size);
3407 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3411 Asm->OutStreamer->emitIntValue(0,
Size);
3412 Asm->OutStreamer->emitIntValue(0,
Size);
3419 *List.CU, dwarf::DW_LLE_base_addressx,
3420 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
3424 DD.emitDebugLocEntryLocation(E, List.CU);
3428void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3429 if (DebugLocs.getLists().empty())
3432 Asm->OutStreamer->switchSection(Sec);
3438 for (
const auto &
List : DebugLocs.getLists())
3442 Asm->OutStreamer->emitLabel(TableEnd);
3446void DwarfDebug::emitDebugLoc() {
3449 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3450 :
Asm->getObjFileLowering().getDwarfLocSection());
3454void DwarfDebug::emitDebugLocDWO() {
3457 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3462 for (
const auto &
List : DebugLocs.getLists()) {
3463 Asm->OutStreamer->switchSection(
3464 Asm->getObjFileLowering().getDwarfLocDWOSection());
3465 Asm->OutStreamer->emitLabel(
List.Label);
3467 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3476 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3477 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3478 Asm->emitULEB128(idx);
3484 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3494void DwarfDebug::emitDebugARanges() {
3495 if (ArangeLabels.empty())
3502 for (
const SymbolCU &SCU : ArangeLabels) {
3503 if (SCU.Sym->isInSection()) {
3505 MCSection *Section = &SCU.Sym->getSection();
3506 SectionMap[Section].push_back(SCU);
3511 SectionMap[
nullptr].push_back(SCU);
3515 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3517 for (
auto &
I : SectionMap) {
3525 for (
const SymbolCU &Cur :
List) {
3527 Span.
Start = Cur.Sym;
3530 Spans[Cur.CU].push_back(Span);
3536 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3540 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3541 const SymbolCU &Prev =
List[n - 1];
3542 const SymbolCU &Cur =
List[n];
3545 if (Cur.
CU != Prev.
CU) {
3547 Span.
Start = StartSym;
3550 Spans[Prev.
CU].push_back(Span);
3557 Asm->OutStreamer->switchSection(
3558 Asm->getObjFileLowering().getDwarfARangesSection());
3560 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3563 std::vector<DwarfCompileUnit *> CUs;
3564 for (
const auto &it : Spans) {
3565 DwarfCompileUnit *
CU = it.first;
3570 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3571 return A->getUniqueID() <
B->getUniqueID();
3575 for (DwarfCompileUnit *
CU : CUs) {
3576 std::vector<ArangeSpan> &
List = Spans[
CU];
3579 if (
auto *Skel =
CU->getSkeleton())
3583 unsigned ContentSize =
3585 Asm->getDwarfOffsetByteSize() +
3590 unsigned TupleSize = PtrSize * 2;
3594 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3597 ContentSize += (
List.size() + 1) * TupleSize;
3600 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3601 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3603 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3604 emitSectionReference(*
CU);
3605 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3606 Asm->emitInt8(PtrSize);
3607 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3610 Asm->OutStreamer->emitFill(Padding, 0xff);
3612 for (
const ArangeSpan &Span :
List) {
3613 Asm->emitLabelReference(Span.Start, PtrSize);
3620 auto SizeRef = SymSize.find(Span.Start);
3621 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3622 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3627 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3630 Size = SizeRef->second;
3632 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3636 Asm->OutStreamer->AddComment(
"ARange terminator");
3637 Asm->OutStreamer->emitIntValue(0, PtrSize);
3638 Asm->OutStreamer->emitIntValue(0, PtrSize);
3646 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3647 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3649 List.CU->getCUNode()->getRangesBaseAddress() ||
3661 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3664 Asm->OutStreamer->switchSection(Section);
3674 Asm->OutStreamer->emitLabel(TableEnd);
3679void DwarfDebug::emitDebugRanges() {
3680 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3682 emitDebugRangesImpl(Holder,
3684 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3685 :
Asm->getObjFileLowering().getDwarfRangesSection());
3688void DwarfDebug::emitDebugRangesDWO() {
3689 emitDebugRangesImpl(InfoHolder,
3690 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3697 enum HeaderFlagMask {
3698#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3699#include "llvm/BinaryFormat/Dwarf.def"
3701 Asm->OutStreamer->AddComment(
"Macro information version");
3702 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3705 if (Asm->isDwarf64()) {
3706 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3707 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3709 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3710 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3712 Asm->OutStreamer->AddComment(
"debug_line_offset");
3714 Asm->emitDwarfLengthOrOffset(0);
3716 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3719void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3720 for (
auto *MN : Nodes) {
3724 emitMacroFile(*
F, U);
3730void DwarfDebug::emitMacro(
DIMacro &M) {
3731 StringRef
Name =
M.getName();
3732 StringRef
Value =
M.getValue();
3738 if (UseDebugMacroSection) {
3741 ? dwarf::DW_MACRO_define_strx
3742 : dwarf::DW_MACRO_undef_strx;
3745 Asm->OutStreamer->AddComment(
"Line Number");
3746 Asm->emitULEB128(
M.getLine());
3747 Asm->OutStreamer->AddComment(
"Macro String");
3749 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3752 ? dwarf::DW_MACRO_GNU_define_indirect
3753 : dwarf::DW_MACRO_GNU_undef_indirect;
3756 Asm->OutStreamer->AddComment(
"Line Number");
3757 Asm->emitULEB128(
M.getLine());
3758 Asm->OutStreamer->AddComment(
"Macro String");
3759 Asm->emitDwarfSymbolReference(
3760 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3764 Asm->emitULEB128(
M.getMacinfoType());
3765 Asm->OutStreamer->AddComment(
"Line Number");
3766 Asm->emitULEB128(
M.getLine());
3767 Asm->OutStreamer->AddComment(
"Macro String");
3768 Asm->OutStreamer->emitBytes(Str);
3769 Asm->emitInt8(
'\0');
3773void DwarfDebug::emitMacroFileImpl(
3775 StringRef (*MacroFormToString)(
unsigned Form)) {
3777 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3778 Asm->emitULEB128(StartFile);
3779 Asm->OutStreamer->AddComment(
"Line Number");
3781 Asm->OutStreamer->AddComment(
"File Number");
3784 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3786 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3788 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3790 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3791 Asm->emitULEB128(EndFile);
3798 if (UseDebugMacroSection)
3800 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3807void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3808 for (
const auto &
P : CUMap) {
3809 auto &TheCU = *
P.second;
3811 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3813 DIMacroNodeArray Macros = CUNode->getMacros();
3816 Asm->OutStreamer->switchSection(Section);
3817 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3818 if (UseDebugMacroSection)
3820 handleMacroNodes(Macros, U);
3821 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3827void DwarfDebug::emitDebugMacinfo() {
3828 auto &ObjLower =
Asm->getObjFileLowering();
3829 emitDebugMacinfoImpl(UseDebugMacroSection
3830 ? ObjLower.getDwarfMacroSection()
3831 : ObjLower.getDwarfMacinfoSection());
3834void DwarfDebug::emitDebugMacinfoDWO() {
3835 auto &ObjLower =
Asm->getObjFileLowering();
3836 emitDebugMacinfoImpl(UseDebugMacroSection
3837 ? ObjLower.getDwarfMacroDWOSection()
3838 : ObjLower.getDwarfMacinfoDWOSection());
3843void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3844 std::unique_ptr<DwarfCompileUnit> NewU) {
3846 if (!CompilationDir.empty())
3847 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3848 addGnuPubAttributes(*NewU, Die);
3850 SkeletonHolder.addUnit(std::move(NewU));
3855 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3856 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3858 DwarfCompileUnit &NewCU = *OwnedUnit;
3859 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3866 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3873void DwarfDebug::emitDebugInfoDWO() {
3876 InfoHolder.emitUnits(
true);
3881void DwarfDebug::emitDebugAbbrevDWO() {
3883 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3886void DwarfDebug::emitDebugLineDWO() {
3888 SplitTypeUnitFileTable.Emit(
3889 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3890 Asm->getObjFileLowering().getDwarfLineDWOSection());
3893void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3895 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
3896 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
3897 InfoHolder.getStringOffsetsStartSym());
3903void DwarfDebug::emitDebugStrDWO() {
3905 emitStringOffsetsTableHeaderDWO();
3907 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
3908 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
3913void DwarfDebug::emitDebugAddr() {
3914 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
3920 const DICompileUnit *DIUnit =
CU.getCUNode();
3921 SplitTypeUnitFileTable.maybeSetRootFile(
3924 return &SplitTypeUnitFileTable;
3935 return Result.high();
3944 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
3947 auto Ins = TypeSignatures.try_emplace(CTy);
3949 CU.addDIETypeSignature(RefDie, Ins.first->second);
3954 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3955 AddrPool.resetUsedFlag();
3957 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
3958 CU,
Asm,
this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(
CU));
3961 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3963 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3964 CU.getSourceLanguage());
3968 Ins.first->second = Signature;
3976 if (!CompilationDir.empty())
3977 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
3978 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
3979 Asm->TM.Options.MCOptions.SplitDwarfFile);
3983 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
3984 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
3989 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
3990 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
3993 CU.applyStmtList(UnitDie);
4004 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4005 TypeUnitsUnderConstruction.clear();
4009 if (AddrPool.hasBeenUsed()) {
4010 AccelTypeUnitsDebugNames.clear();
4014 for (
const auto &
TU : TypeUnitsToAdd)
4015 TypeSignatures.erase(
TU.second);
4023 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4029 for (
auto &
TU : TypeUnitsToAdd) {
4030 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4035 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4037 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4040 AccelTypeUnitsDebugNames.convertDieToOffset();
4041 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4042 AccelTypeUnitsDebugNames.clear();
4045 CU.addDIETypeSignature(RefDie, Signature);
4052template <
typename DataT>
4053void DwarfDebug::addAccelNameImpl(
4058 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4075 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4076 ((&Current == &AccelDebugNames) &&
4077 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4078 "Kind is CU but TU is being processed.");
4079 assert(((&Current == &AccelDebugNames) ||
4080 ((&Current == &AccelTypeUnitsDebugNames) &&
4081 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4082 "Kind is TU but CU is being processed.");
4085 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4086 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4100 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4109 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4116 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4122 const DIE &Die,
char Flags) {
4123 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4127 return Asm->OutStreamer->getContext().getDwarfVersion();
4131 if (
Asm->getDwarfVersion() >= 4)
4132 return dwarf::Form::DW_FORM_sec_offset;
4133 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4134 "DWARF64 is not defined prior DWARFv3");
4135 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4136 : dwarf::Form::DW_FORM_data4;
4140 return SectionLabels.lookup(S);
4144 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4149std::optional<MD5::MD5Result>
4153 return std::nullopt;
4154 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4156 return std::nullopt;
4161 std::string ChecksumString =
fromHex(Checksum->Value);
4178 if (
MBB.getAlignment() ==
Align(1))
4181 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4188 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4189 if (PrevLoc.getLine()) {
4190 Asm->OutStreamer->emitDwarfLocDirective(
4191 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4193 Asm->OutStreamer->getCurrentSectionOnly());
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< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define clEnumVal(ENUMVAL, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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))
SmallSet< MCRegUnit, 16 > ClobberedRegUnitSet
Container for the set of register units known to be clobbered on the path to a call site.
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 bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
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))
MapVector< uint64_t, SmallVector< FwdRegParamInfo, 2 > > FwdRegWorklist
Register worklist for finding call site values.
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 emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
static const DILocalScope * getRetainedNodeScope(const MDNode *N)
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 DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
static void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
Interpret values loaded into registers by CurMI.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
This class is intended to be used as a driving class for all asm writers.
DwarfDebug * getDwarfDebug()
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
uint16_t getDwarfVersion() const
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
DISourceLanguageName getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static LLVM_ABI std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
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
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
bool hasVersionedName() const
Subprogram description. Uses SubclassData1.
DIScope * getScope() const
Encoding
Size and signedness of expression operations' operands.
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...
SmallVector< Entry, 4 > Entries
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.
const DILocalVariable * getVariable() const
const DIType * getType() const
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.
DebugHandlerBase(AsmPrinter *A)
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< Entry > getEntries(const List &L) const
LLVM_ABI unsigned getLine() 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 addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
void createAbstractEntity(const DINode *Node, LexicalScope *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.
DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)
Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
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.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
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 addBooleanConstant(int64_t Value)
Emit a boolean constant.
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.
virtual void commitTemporaryBuffer()=0
Commit the data stored in the temporary buffer to the main output.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
virtual void enableTemporaryBuffer()=0
Start emitting data to the temporary buffer.
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void setRnglistsTableBaseSym(MCSymbol *Sym)
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation 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.
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
LLVM_ABI_FOR_TEST EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
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.
This class is used to track scope information.
SmallVectorImpl< InsnRange > & getRanges()
const DILocalScope * getScopeNode() const
This class provides interface to collect and use lexical scoping information from machine instruction...
LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)
Find lexical scope, either regular or inlined, for the given DebugLoc.
LexicalScope * findAbstractScope(const DILocalScope *N)
Find an abstract scope or return null.
Single(DbgValueLoc ValueLoc)
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
MCSection * getDwarfLoclistsSection() const
MCSection * getDwarfRangesSection() const
MCSection * getDwarfMacroSection() const
MCSection * getDwarfMacinfoDWOSection() const
MCSection * getDwarfMacinfoSection() const
MCSection * getDwarfMacroDWOSection() const
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 ...
uint32_t getIndex() const
Get the (implementation defined) index.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
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.
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const CallSiteInfoMap & getCallSitesInfo() const
Function & getFunction()
Return the LLVM function that this machine code represents.
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
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.
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.
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)
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
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 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...
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
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.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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)
FunctionAddr VTableAddr Value
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.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation. The return string is half the size of ...
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto cast_or_null(const Y &Val)
auto unique(Range &&R, Predicate P)
bool isa_and_nonnull(const Y &Val)
SmallVector< DbgCallSiteParam, 4 > ParamSet
Collection used for storing debug call site parameters.
auto dyn_cast_or_null(const Y &Val)
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.
A pair of GlobalVariable and DIExpression.
Represents an entry-value location, or a fragment of one.
void addFrameIndexExpr(const DIExpression *Expr, int FI)
std::set< FrameIndexExpr > FrameIndexExprs
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.