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;
625 "Combined debug expression is invalid");
640 auto &ParamsForFwdReg = Worklist[
Reg];
641 for (
auto Param : ParamsToAdd) {
644 return D.ParamReg == Param.ParamReg;
646 "Same parameter described twice by forwarding reg");
653 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
673 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
674 for (
auto &RegUnit : ClobberedRegUnits)
675 if (
TRI.hasRegUnit(
Reg, RegUnit))
680 auto DescribeFwdRegsByCalleeSavedCopy = [&](
const DestSourcePair &CopyInst) {
681 Register CopyDestReg = CopyInst.Destination->getReg();
682 Register CopySrcReg = CopyInst.Source->getReg();
683 if (IsRegClobberedInMeantime(CopyDestReg))
687 if (!
TRI.isCalleeSavedPhysReg(CopyDestReg, *MF))
694 for (
auto FwdRegIt = ForwardedRegWorklist.
begin();
695 FwdRegIt != ForwardedRegWorklist.
end();) {
697 if (FwdRegIt->first == CopySrcReg)
699 else if (
unsigned SubRegIdx =
700 TRI.getSubRegIndex(CopySrcReg, FwdRegIt->first))
701 if (
Register CopyDestSubReg =
TRI.getSubReg(CopyDestReg, SubRegIdx))
711 FwdRegIt = ForwardedRegWorklist.
erase(FwdRegIt);
719 if (
auto CopyInst =
TII.isCopyInstr(*CurMI))
720 DescribeFwdRegsByCalleeSavedCopy(*CopyInst);
748 if (
MI.isDebugInstr())
752 if (MO.getReg().isPhysical()) {
753 for (
auto &FwdReg : ForwardedRegWorklist)
754 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
755 Defs.insert(FwdReg.first);
764 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
765 if (FwdRegDefs.
empty()) {
771 for (
auto ParamFwdReg : FwdRegDefs) {
772 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
773 if (ParamValue->first.isImm()) {
774 int64_t Val = ParamValue->first.getImm();
776 ForwardedRegWorklist[ParamFwdReg], Params);
777 }
else if (ParamValue->first.isReg()) {
778 Register RegLoc = ParamValue->first.getReg();
779 Register SP = TLI.getStackPointerRegisterToSaveRestore();
781 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
784 if (!IsRegClobberedInMeantime(RegLoc) &&
785 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
788 ForwardedRegWorklist[ParamFwdReg], Params);
797 ForwardedRegWorklist[ParamFwdReg]);
804 for (
auto ParamFwdReg : FwdRegDefs)
805 ForwardedRegWorklist.
erase(ParamFwdReg);
812 for (
auto &New : TmpWorklistItems)
814 TmpWorklistItems.
clear();
831 if (ForwardedRegWorklist.
empty())
838 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
849 auto CSInfo = CalleesMap.
find(CallMI);
852 if (CSInfo == CalleesMap.end())
866 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
868 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
870 assert(InsertedReg &&
"Single register used to forward two arguments?");
875 for (
const auto &MO : CallMI->
uses())
876 if (MO.isReg() && MO.isUndef())
877 ForwardedRegWorklist.
erase(MO.getReg());
887 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
896 assert(std::next(Suc) == BundleEnd &&
897 "More than one instruction in call delay slot");
904 for (;
I !=
MBB->rend(); ++
I) {
911 if (ShouldTryEmitEntryVals) {
915 for (
auto &RegEntry : ForwardedRegWorklist) {
922void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
927 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
934 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
937 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
940 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
941 if (!
MI.isBundledWithSucc())
943 auto Suc = std::next(
MI.getIterator());
945 (void)CallInstrBundle;
947 (void)DelaySlotBundle;
954 "Call and its successor instruction don't have same label after.");
959 for (
const MachineBasicBlock &
MBB : MF) {
969 if (!
MI.isCandidateForAdditionalCallInfo())
978 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
986 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
987 bool PhysRegCalleeOperand =
989 MachineLocation CallTarget{0};
991 const DISubprogram *CalleeSP =
nullptr;
992 const Function *CalleeDecl =
nullptr;
993 if (PhysRegCalleeOperand) {
994 bool Scalable =
false;
995 const MachineOperand *BaseOp =
nullptr;
996 const TargetRegisterInfo &
TRI =
997 *
Asm->MF->getSubtarget().getRegisterInfo();
998 if (
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, Scalable, &
TRI)) {
999 if (BaseOp && BaseOp->
isReg() && !Scalable)
1000 CallTarget = MachineLocation(BaseOp->
getReg(),
true);
1004 CallTarget = MachineLocation(CalleeOp.
getReg());
1013 if (CalleeSP ==
nullptr && CallTarget.
getReg() == 0 &&
1014 AllocSiteTy ==
nullptr)
1024 const MachineInstr *TopLevelCallMI =
1031 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1040 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1043 dbgs() <<
"CallSiteEntry: " << MF.getName() <<
" -> "
1047 MF.getSubtarget().getRegisterInfo()->getName(
1049 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1051 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1052 ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
1060 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1067 if (!
U.hasDwarfPubSections())
1070 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1073void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1081 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1082 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1084 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1087 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1090 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1091 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1094 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1098 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1100 if (!SysRoot.
empty())
1101 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1102 StringRef SDK = DIUnit->
getSDK();
1104 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1115 if (!CompilationDir.empty())
1116 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1117 addGnuPubAttributes(NewCU, Die);
1122 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1126 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1129 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1130 dwarf::DW_FORM_data1, RVer);
1135 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1140 ? dwarf::DW_AT_dwo_name
1141 : dwarf::DW_AT_GNU_dwo_name;
1149DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1150 if (
auto *
CU = CUMap.lookup(DIUnit))
1158 return *CUMap.begin()->second;
1162 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1163 InfoHolder.getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1164 DwarfCompileUnit &NewCU = *OwnedUnit;
1165 InfoHolder.addUnit(std::move(OwnedUnit));
1171 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1172 Asm->OutStreamer->emitDwarfFile0Directive(
1178 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1180 finishUnitAttributes(DIUnit, NewCU);
1181 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1184 CUMap.insert({DIUnit, &NewCU});
1185 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1199 if (!
A.Expr || !
B.Expr)
1201 auto FragmentA =
A.Expr->getFragmentInfo();
1202 auto FragmentB =
B.Expr->getFragmentInfo();
1203 if (!FragmentA || !FragmentB)
1205 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1210 return A.Expr ==
B.Expr;
1225 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1226 M->debug_compile_units_end());
1227 if (NumDebugCUs == 0)
1230 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1231 SingleCU = NumDebugCUs == 1;
1236 Global.getDebugInfo(GVs);
1237 for (
auto *GVE : GVs)
1238 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1246 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1254 Asm->createTempSymbol(
"rnglists_table_base"));
1257 InfoHolder.setRnglistsTableBaseSym(
1258 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1263 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1264 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1267 if (CUNode->getImportedEntities().empty() &&
1268 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1269 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1275 for (
auto *GVE : CUNode->getGlobalVariables()) {
1279 auto &GVMapEntry = GVMap[GVE->getVariable()];
1280 auto *Expr = GVE->getExpression();
1281 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1282 GVMapEntry.push_back({
nullptr, Expr});
1286 for (
auto *GVE : CUNode->getGlobalVariables()) {
1288 if (Processed.
insert(GV).second)
1292 for (
auto *Ty : CUNode->getEnumTypes())
1295 for (
auto *Ty : CUNode->getRetainedTypes()) {
1300 CU.getOrCreateTypeDIE(RT);
1305void DwarfDebug::finishEntityDefinitions() {
1306 for (
const auto &Entity : ConcreteEntities) {
1307 DIE *Die = Entity->getDIE();
1314 Unit->finishEntityDefinition(Entity.get());
1318void DwarfDebug::finishSubprogramDefinitions() {
1319 for (
const DISubprogram *SP : ProcessedSPNodes) {
1322 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1323 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1327void DwarfDebug::finalizeModuleInfo() {
1328 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1330 finishSubprogramDefinitions();
1332 finishEntityDefinitions();
1334 bool HasEmittedSplitCU =
false;
1338 for (
const auto &
P : CUMap) {
1339 auto &TheCU = *
P.second;
1340 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1342 TheCU.attachLexicalScopesAbstractOrigins();
1345 TheCU.constructContainingTypeDIEs();
1350 auto *SkCU = TheCU.getSkeleton();
1352 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1355 (void)HasEmittedSplitCU;
1357 "Multiple CUs emitted into a single dwo file");
1358 HasEmittedSplitCU =
true;
1360 ? dwarf::DW_AT_dwo_name
1361 : dwarf::DW_AT_GNU_dwo_name;
1362 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1363 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1364 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1365 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1371 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1376 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1377 dwarf::DW_FORM_data8,
ID);
1378 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1379 dwarf::DW_FORM_data8,
ID);
1382 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1384 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1388 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1397 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1399 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1404 if (!(
Asm->TM.getTargetTriple().isNVPTX() &&
tuneForGDB())) {
1410 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1413 U.setBaseAddress(TheCU.getRanges().front().Begin);
1414 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1421 U.addAddrTableBase();
1424 if (
U.hasRangeLists())
1425 U.addRnglistsBase();
1428 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1437 if (CUNode->getMacros()) {
1438 if (UseDebugMacroSection) {
1440 TheCU.addSectionDelta(
1441 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1445 ? dwarf::DW_AT_macros
1446 : dwarf::DW_AT_GNU_macros;
1447 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1452 TheCU.addSectionDelta(
1453 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1454 U.getMacroLabelBegin(),
1457 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1458 U.getMacroLabelBegin(),
1465 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1466 if (CUNode->getDWOId())
1467 getOrCreateDwarfCompileUnit(CUNode);
1470 InfoHolder.computeSizeAndOffsets();
1472 SkeletonHolder.computeSizeAndOffsets();
1476 AccelDebugNames.convertDieToOffset();
1485 assert(CurFn ==
nullptr);
1488 for (
const auto &
P : CUMap) {
1493 for (
auto *IE : CUNode->getImportedEntities()) {
1495 "Unexpected function-local entity in 'imports' CU field.");
1496 CU->getOrCreateImportedEntityDIE(IE);
1498 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1500 CU->getOrCreateImportedEntityDIE(IE);
1506 CU->createBaseTypeDIEs();
1511 if (!
Asm || !
Asm->hasDebugInfo())
1515 finalizeModuleInfo();
1525 emitAbbreviations();
1531 if (UseARangesSection)
1539 emitDebugMacinfoDWO();
1549 emitDebugAbbrevDWO();
1551 emitDebugRangesDWO();
1561 emitAccelNamespaces();
1565 emitAccelDebugNames();
1574 emitDebugPubSections();
1582 if (
CU.getExistingAbstractEntity(
Node))
1587 CU.createAbstractEntity(
Node, Scope);
1596void DwarfDebug::collectVariableInfoFromMFTable(
1598 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1599 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1600 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1603 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1604 "Expected inlined-at fields to agree");
1606 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1613 <<
", no variable scope found\n");
1617 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1621 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1622 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1623 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1625 if (PreviousMMI &&
VI.inStackSlot())
1626 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1628 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1629 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1634 if (PreviousLoc->holds<Loc::MMI>())
1635 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1638 <<
", conflicting fragment location types\n");
1643 auto RegVar = std::make_unique<DbgVariable>(
1645 if (
VI.inStackSlot())
1646 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1648 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1651 InfoHolder.addScopeVariable(Scope, RegVar.get());
1652 MFVars.
insert({Var, RegVar.get()});
1653 ConcreteEntities.push_back(std::move(RegVar));
1665 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1673 if (LSRange.size() == 0)
1676 const MachineInstr *LScopeBegin = LSRange.front().first;
1680 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1686 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1689 auto PredDL = Pred->getDebugLoc();
1690 if (!PredDL || Pred->isMetaInstruction())
1694 if (
DL->getScope() == PredDL->getScope())
1697 if (!PredScope || LScope->dominates(PredScope))
1710 if (
MBB->pred_empty() &&
1717 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1761 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1763 bool isSafeForSingleLocation =
true;
1764 const MachineInstr *StartDebugMI =
nullptr;
1765 const MachineInstr *EndMI =
nullptr;
1767 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1768 const MachineInstr *
Instr = EI->getInstr();
1771 size_t Index = std::distance(EB, EI);
1772 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1779 "Forgot label before/after instruction starting a range!");
1782 if (std::next(EI) == Entries.
end()) {
1783 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1785 if (EI->isClobber())
1786 EndMI = EI->getInstr();
1788 else if (std::next(EI)->isClobber())
1792 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1794 if (EI->isDbgValue())
1800 if (EI->isDbgValue()) {
1807 if (!
Instr->isUndefDebugValue()) {
1812 if (
Instr->getDebugExpression()->isFragment())
1813 isSafeForSingleLocation =
false;
1816 StartDebugMI =
Instr;
1818 isSafeForSingleLocation =
false;
1824 if (OpenRanges.
empty())
1828 if (StartLabel == EndLabel) {
1829 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1834 for (
auto &R : OpenRanges)
1842 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1843 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1844 for (
const auto &[MBBSectionId, MBBSectionRange] :
1845 Asm->MBBSectionRanges) {
1846 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1847 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1850 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1851 MBBSectionRange.EndLabel, Values);
1854 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1861 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1862 for (
auto &
Value : CurEntry->getValues())
1864 dbgs() <<
"-----\n";
1867 auto PrevEntry = std::next(CurEntry);
1868 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1872 if (!isSafeForSingleLocation ||
1879 if (!
Asm->MF->hasBBSections())
1887 const MachineBasicBlock *RangeMBB =
nullptr;
1888 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1889 RangeMBB = &
Asm->MF->front();
1891 RangeMBB = Entries.
begin()->getInstr()->getParent();
1893 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1894 "Range MBB not found in MBBSectionRanges!");
1896 auto *NextEntry = std::next(CurEntry);
1897 auto NextRangeIt = std::next(RangeIt);
1898 while (NextEntry !=
DebugLoc.end()) {
1899 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1906 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1907 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1908 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1909 CurEntry->getValues() != NextEntry->getValues())
1911 RangeIt = NextRangeIt;
1912 NextRangeIt = std::next(RangeIt);
1913 CurEntry = NextEntry;
1914 NextEntry = std::next(CurEntry);
1924 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1926 ConcreteEntities.push_back(
1929 InfoHolder.addScopeVariable(&Scope,
1932 ConcreteEntities.push_back(
1935 InfoHolder.addScopeLabel(&Scope,
1938 return ConcreteEntities.back().get();
1946 collectVariableInfoFromMFTable(TheCU, Processed);
1949 InlinedEntity
IV =
I.first;
1954 const auto &HistoryMapEntries =
I.second;
1958 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
1961 LexicalScope *
Scope =
nullptr;
1963 if (
const DILocation *IA =
IV.second)
1973 *Scope, LocalVar,
IV.second));
1975 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1981 size_t HistSize = HistoryMapEntries.size();
1982 bool SingleValueWithClobber =
1983 HistSize == 2 && HistoryMapEntries[1].isClobber();
1984 if (HistSize == 1 || SingleValueWithClobber) {
1986 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1988 RegVar->emplace<Loc::Single>(MInsn);
1994 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
1998 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
2003 if (isValidSingleLocation) {
2004 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
2015 for (
auto &Entry : Entries)
2022 InlinedEntity IL =
I.first;
2023 const MachineInstr *
MI =
I.second;
2027 LexicalScope *
Scope =
nullptr;
2030 const DILocalScope *LocalScope =
2031 Label->getScope()->getNonLexicalBlockFileScope();
2033 if (
const DILocation *IA = IL.second)
2046 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2050 for (
const DINode *DN :
SP->getRetainedNodes()) {
2053 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2055 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2057 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2059 LocalDeclsPerLS[
LS].insert(DN);
2073 if (!
MI.isBundledWithSucc())
2075 auto Suc = std::next(
MI.getIterator());
2080 assert(Suc->isBundledWithPred() &&
2081 "Call bundle instructions are out of order");
2086 if (!NoDebug && SP->areAllCallsDescribed() &&
2088 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2090 bool IsTail =
TII->isTailCall(*
MI);
2108 auto RecordLineZero = [&]() {
2112 const MDNode *Scope =
nullptr;
2113 unsigned Column = 0;
2118 recordSourceLine(0, Column, Scope, 0);
2123 unsigned LastAsmLine =
2124 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2129 if (
MI->isMetaInstruction())
2150 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2152 if (
Asm->OutStreamer->isVerboseAsm()) {
2156 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2165 bool ScopeUsesKeyInstructions =
2167 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2170 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2171 IsKey = KeyInstructions.contains(
MI);
2177 assert(
MI->getParent() == &*
MI->getMF()->begin());
2178 recordSourceLine(SP->getScopeLine(), 0, SP,
2183 bool PrevInstInSameSection =
2185 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2186 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2187 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2197 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2199 RecordSourceLine(
DL, Flags);
2212 if (LastAsmLine == 0)
2233 if (
DL.getLine() == 0 && LastAsmLine == 0)
2240 if (ScopeUsesKeyInstructions) {
2247 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2251 RecordSourceLine(
DL, Flags);
2263static std::pair<const MachineInstr *, bool>
2274 bool IsEmptyPrologue =
2275 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2280 -> std::optional<std::pair<const MachineInstr *, bool>> {
2282 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2283 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2286 if (!isFrameSetup &&
MI.getDebugLoc()) {
2292 if (
MI.getDebugLoc().getLine())
2293 return std::make_pair(&
MI, IsEmptyPrologue);
2298 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2299 NonTrivialInst = &
MI;
2301 IsEmptyPrologue =
false;
2302 return std::nullopt;
2310 auto CurBlock = MF->
begin();
2311 auto CurInst = CurBlock->begin();
2315 while (CurBlock->empty())
2316 CurInst = (++CurBlock)->begin();
2317 assert(CurInst != CurBlock->end());
2321 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2323 if (CurInst->isTerminator()) {
2332 if (CurBlock->pred_size() > 1)
2343 if (CurBlock == MF->
end())
2345 }
while (CurBlock->empty());
2346 CurInst = CurBlock->begin();
2352 if (!CurInst->isMetaInstruction()) {
2353 auto FoundInst = ExamineInst(*CurInst);
2364 if (CurInst->isCall()) {
2366 Loc &&
Loc->getLine() == 0) {
2368 unsigned ScopeLine = SP->getScopeLine();
2371 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2374 return std::make_pair(&*CurInst,
false);
2380 auto NextInst = std::next(CurInst);
2381 if (NextInst != CurInst->getParent()->end()) {
2398 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2399 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2400 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2404 return std::make_pair(
nullptr, IsEmptyPrologue);
2410 const MDNode *S,
unsigned Flags,
unsigned CUID,
2412 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2415 unsigned FileNo = 1;
2418 Fn =
Scope->getFilename();
2419 if (Line != 0 && DwarfVersion >= 4)
2424 .getOrCreateSourceID(
Scope->getFile());
2426 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2427 Discriminator, Fn, Comment);
2438 bool IsEmptyPrologue = PrologEnd.second;
2441 if (IsEmptyPrologue) {
2449 if (!
DL ||
DL->getLine() != 0)
2460 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2470 KeyInstructions.clear();
2477 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2494 for (
auto &
MBB : *MF) {
2506 for (
auto &
MI :
MBB) {
2507 if (
MI.isMetaInstruction())
2511 if (!
Loc || !
Loc->getLine())
2522 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2527 KeyInstructions.insert(Buoy);
2533 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2537 auto *InlinedAt = Loc->getInlinedAt();
2540 if (!Group || !Rank)
2544 if (BuoyAtom && BuoyAtom != Group) {
2549 auto &[CandidateRank, CandidateInsts] =
2550 GroupCandidates[{InlinedAt, Group}];
2556 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2557 (CandidateRank != 0 && !CandidateInsts.empty()));
2559 assert(Rank &&
"expected nonzero rank");
2562 if (CandidateRank && CandidateRank < Rank)
2569 if (CandidateRank == Rank)
2573 else if (CandidateRank > Rank)
2574 CandidateInsts.clear();
2578 CandidateInsts.push_back(Buoy);
2579 CandidateRank = Rank;
2587 if (CandidateInsts.empty())
2593 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2594 for (
auto *
I : Insts)
2595 KeyInstructions.insert(
I);
2603 ForceIsStmtInstrs.clear();
2635 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2636 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2639 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2642 for (
auto &
MI :
MBB) {
2643 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2656 for (
auto *
MBB : PredMBBsToExamine) {
2657 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2658 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2659 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2661 MachineInstr *
MI = MBBInstrIt->second;
2662 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2664 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2665 ForceIsStmtInstrs.insert(
MI);
2672 CheckMBBEdge(Succ, 0);
2678 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2686 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2693 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2696 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2697 CheckMBBEdge(FBB, FBBLine);
2721 unsigned LastLine = 0;
2723 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2724 LastLine =
DL->getLine();
2729 for (
auto *Succ : SuccessorBBs)
2730 CheckMBBEdge(Succ, LastLine);
2745 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2746 ?
Asm->OutStreamer->emitLineTableLabel()
2749 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2754 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2760 computeKeyInstructions(MF);
2761 findForceIsStmtInstrs(MF);
2769 if (
Asm->OutStreamer->hasRawTextSupport())
2773 return CU.getUniqueID();
2777 const auto &CURanges =
CU->getRanges();
2778 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2781 LineTable.getMCLineSections().addEndEntry(
2782 const_cast<MCSymbol *
>(CURanges.back().End));
2802 "endFunction should be called with the same function as beginFunction");
2805 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2817 collectEntityInfo(TheCU, SP, Processed);
2821 for (
const auto &R :
Asm->MBBSectionRanges)
2822 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2829 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2830 for (
const auto &R :
Asm->MBBSectionRanges)
2833 assert(InfoHolder.getScopeVariables().empty());
2840 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2844 for (
const DINode *DN : SP->getRetainedNodes()) {
2847 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2848 assert(LexS &&
"Expected the LexicalScope to be created.");
2851 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2857 LocalDeclsPerLS[LS].insert(DN);
2860 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2861 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2863 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2866 ProcessedSPNodes.insert(SP);
2870 if (!
LScopes.getAbstractScopesList().empty() &&
2872 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2873 FunctionLineTableLabel);
2875 FunctionLineTableLabel =
nullptr;
2878 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2884 InfoHolder.getScopeVariables().clear();
2885 InfoHolder.getScopeLabels().clear();
2886 LocalDeclsPerLS.clear();
2893void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2905void DwarfDebug::emitDebugInfo() {
2911void DwarfDebug::emitAbbreviations() {
2912 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2914 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2917void DwarfDebug::emitStringOffsetsTableHeader() {
2918 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2920 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2924template <
typename AccelTableT>
2925void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2927 Asm->OutStreamer->switchSection(Section);
2933void DwarfDebug::emitAccelDebugNames() {
2935 if (getUnits().
empty())
2942void DwarfDebug::emitAccelNames() {
2943 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
2949void DwarfDebug::emitAccelObjC() {
2950 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
2955void DwarfDebug::emitAccelNamespaces() {
2956 emitAccel(AccelNamespace,
2957 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
2962void DwarfDebug::emitAccelTypes() {
2963 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
2993 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
3001 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
3008 case dwarf::DW_TAG_class_type:
3009 case dwarf::DW_TAG_structure_type:
3010 case dwarf::DW_TAG_union_type:
3011 case dwarf::DW_TAG_enumeration_type:
3016 case dwarf::DW_TAG_typedef:
3017 case dwarf::DW_TAG_base_type:
3018 case dwarf::DW_TAG_subrange_type:
3019 case dwarf::DW_TAG_template_alias:
3021 case dwarf::DW_TAG_namespace:
3023 case dwarf::DW_TAG_subprogram:
3025 case dwarf::DW_TAG_variable:
3027 case dwarf::DW_TAG_enumerator:
3037void DwarfDebug::emitDebugPubSections() {
3038 for (
const auto &NU : CUMap) {
3039 DwarfCompileUnit *TheU = NU.second;
3046 Asm->OutStreamer->switchSection(
3047 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3048 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3049 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3051 Asm->OutStreamer->switchSection(
3052 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3053 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3054 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3060 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3061 CU.getDebugSectionOffset());
3063 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3066void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3074 "pub" + Name,
"Length of Public " + Name +
" Info");
3076 Asm->OutStreamer->AddComment(
"DWARF Version");
3079 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3080 emitSectionReference(*TheU);
3082 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3087 for (
const auto &GI : Globals)
3090 return A.second->getOffset() <
B.second->getOffset();
3092 for (
const auto &[Name, Entity] : Vec) {
3093 Asm->OutStreamer->AddComment(
"DIE offset");
3094 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3098 Asm->OutStreamer->AddComment(
3104 Asm->OutStreamer->AddComment(
"External Name");
3105 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3108 Asm->OutStreamer->AddComment(
"End Mark");
3109 Asm->emitDwarfLengthOrOffset(0);
3110 Asm->OutStreamer->emitLabel(EndLabel);
3114void DwarfDebug::emitDebugStr() {
3115 MCSection *StringOffsetsSection =
nullptr;
3117 emitStringOffsetsTableHeader();
3118 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3120 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3121 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3122 StringOffsetsSection,
true);
3128 auto &&Comments = DebugLocs.getComments(Entry);
3129 auto Comment = Comments.begin();
3130 auto End = Comments.end();
3137 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3139 DebugLocs.getBytes(Entry).size()),
3140 Asm->getDataLayout().isLittleEndian(), PtrSize);
3145 for (
const auto &
Op : Expr) {
3146 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3147 "3 operand ops not yet supported");
3148 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3149 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3151 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3152 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3154 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3156 for (
unsigned J = 0; J <
Length; ++J)
3161 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3172 auto *DIExpr =
Value.getExpression();
3178 if (DIExpr && DIExpr->isEntryValue()) {
3195 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3198 if (Entry.isInt()) {
3199 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3201 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3202 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3206 }
else if (Entry.isLocation()) {
3208 if (Location.isIndirect())
3214 }
else if (Entry.isTargetIndexLocation()) {
3220 }
else if (Entry.isConstantFP()) {
3223 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3224 }
else if (Entry.getConstantFP()
3227 .getBitWidth() <= 64 ) {
3229 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3232 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3233 << Entry.getConstantFP()
3244 if (!
Value.isVariadic()) {
3245 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3254 return Entry.isLocation() && !Entry.getLoc().getReg();
3259 std::move(ExprCursor),
3260 [EmitValueLocEntry, &
Value](
unsigned Idx,
3262 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3270 assert(!Values.empty() &&
3271 "location list entries without values are redundant");
3272 assert(Begin != End &&
"unexpected location list entry with empty range");
3277 if (
Value.isFragment()) {
3280 return P.isFragment();
3281 }) &&
"all values are expected to be fragments");
3284 for (
const auto &Fragment : Values)
3288 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3299 Asm->OutStreamer->AddComment(
"Loc expr size");
3301 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3302 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3303 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3322 Asm->OutStreamer->AddComment(
"Offset entry count");
3328 Asm->getDwarfOffsetByteSize());
3342 Asm->OutStreamer->AddComment(
"Offset entry count");
3343 Asm->emitInt32(DebugLocs.getLists().size());
3344 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3346 for (
const auto &List : DebugLocs.getLists())
3347 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3348 Asm->getDwarfOffsetByteSize());
3353template <
typename Ranges,
typename PayloadEmitter>
3357 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3359 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3360 auto Size = Asm->MAI->getCodePointerSize();
3364 Asm->OutStreamer->emitLabel(Sym);
3371 for (
const auto &
Range : R)
3372 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3374 const MCSymbol *CUBase =
CU.getBaseAddress();
3375 bool BaseIsSet =
false;
3376 for (
const auto &
P : SectionRanges) {
3377 auto *
Base = CUBase;
3378 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB()) ||
3379 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3389 }
else if (!
Base && ShouldUseBaseAddress) {
3390 const MCSymbol *Begin =
P.second.front()->Begin;
3395 Asm->OutStreamer->emitIntValue(-1,
Size);
3396 Asm->OutStreamer->AddComment(
" base address");
3397 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3398 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3404 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3405 Asm->emitInt8(BaseAddressx);
3406 Asm->OutStreamer->AddComment(
" base address index");
3409 }
else if (BaseIsSet && !UseDwarf5) {
3412 Asm->OutStreamer->emitIntValue(-1,
Size);
3413 Asm->OutStreamer->emitIntValue(0,
Size);
3416 for (
const auto *RS :
P.second) {
3419 assert(Begin &&
"Range without a begin symbol?");
3420 assert(End &&
"Range without an end symbol?");
3424 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3425 Asm->emitInt8(OffsetPair);
3426 Asm->OutStreamer->AddComment(
" starting offset");
3427 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3428 Asm->OutStreamer->AddComment(
" ending offset");
3429 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3431 Asm->emitLabelDifference(Begin,
Base,
Size);
3432 Asm->emitLabelDifference(End,
Base,
Size);
3434 }
else if (UseDwarf5) {
3442 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3443 Asm->emitInt8(StartxEndx);
3444 Asm->OutStreamer->AddComment(
" start index");
3446 Asm->OutStreamer->AddComment(
" end index");
3449 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3450 Asm->emitInt8(StartxLength);
3451 Asm->OutStreamer->AddComment(
" start index");
3453 Asm->OutStreamer->AddComment(
" length");
3454 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3457 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3458 Asm->OutStreamer->emitSymbolValue(End,
Size);
3465 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3469 Asm->OutStreamer->emitIntValue(0,
Size);
3470 Asm->OutStreamer->emitIntValue(0,
Size);
3478 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3479 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3482 DD.emitDebugLocEntryLocation(E, List.CU);
3486void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3487 if (DebugLocs.getLists().empty())
3490 Asm->OutStreamer->switchSection(Sec);
3496 for (
const auto &
List : DebugLocs.getLists())
3500 Asm->OutStreamer->emitLabel(TableEnd);
3504void DwarfDebug::emitDebugLoc() {
3507 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3508 :
Asm->getObjFileLowering().getDwarfLocSection());
3512void DwarfDebug::emitDebugLocDWO() {
3515 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3520 for (
const auto &
List : DebugLocs.getLists()) {
3521 Asm->OutStreamer->switchSection(
3522 Asm->getObjFileLowering().getDwarfLocDWOSection());
3523 Asm->OutStreamer->emitLabel(
List.Label);
3525 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3534 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3535 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3536 Asm->emitULEB128(idx);
3542 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3552void DwarfDebug::emitDebugARanges() {
3553 if (ArangeLabels.empty())
3560 for (
const SymbolCU &SCU : ArangeLabels) {
3561 if (SCU.Sym->isInSection()) {
3563 MCSection *Section = &SCU.Sym->getSection();
3564 SectionMap[Section].push_back(SCU);
3569 SectionMap[
nullptr].push_back(SCU);
3573 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3575 for (
auto &
I : SectionMap) {
3583 for (
const SymbolCU &Cur :
List) {
3585 Span.
Start = Cur.Sym;
3588 Spans[Cur.CU].push_back(Span);
3594 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3598 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3599 const SymbolCU &Prev =
List[n - 1];
3600 const SymbolCU &Cur =
List[n];
3603 if (Cur.
CU != Prev.
CU) {
3605 Span.
Start = StartSym;
3608 Spans[Prev.
CU].push_back(Span);
3615 Asm->OutStreamer->switchSection(
3616 Asm->getObjFileLowering().getDwarfARangesSection());
3618 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3621 std::vector<DwarfCompileUnit *> CUs;
3622 for (
const auto &it : Spans) {
3623 DwarfCompileUnit *
CU = it.first;
3628 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3629 return A->getUniqueID() <
B->getUniqueID();
3633 for (DwarfCompileUnit *
CU : CUs) {
3634 std::vector<ArangeSpan> &
List = Spans[
CU];
3637 if (
auto *Skel =
CU->getSkeleton())
3641 unsigned ContentSize =
3643 Asm->getDwarfOffsetByteSize() +
3648 unsigned TupleSize = PtrSize * 2;
3652 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3655 ContentSize += (
List.size() + 1) * TupleSize;
3658 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3659 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3661 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3662 emitSectionReference(*
CU);
3663 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3664 Asm->emitInt8(PtrSize);
3665 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3668 Asm->OutStreamer->emitFill(Padding, 0xff);
3670 for (
const ArangeSpan &Span :
List) {
3671 Asm->emitLabelReference(Span.Start, PtrSize);
3678 auto SizeRef = SymSize.find(Span.Start);
3679 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3680 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3685 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3688 Size = SizeRef->second;
3690 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3694 Asm->OutStreamer->AddComment(
"ARange terminator");
3695 Asm->OutStreamer->emitIntValue(0, PtrSize);
3696 Asm->OutStreamer->emitIntValue(0, PtrSize);
3704 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3705 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3707 List.CU->getCUNode()->getRangesBaseAddress() ||
3719 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3722 Asm->OutStreamer->switchSection(Section);
3732 Asm->OutStreamer->emitLabel(TableEnd);
3737void DwarfDebug::emitDebugRanges() {
3738 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3740 emitDebugRangesImpl(Holder,
3742 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3743 :
Asm->getObjFileLowering().getDwarfRangesSection());
3746void DwarfDebug::emitDebugRangesDWO() {
3747 emitDebugRangesImpl(InfoHolder,
3748 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3755 enum HeaderFlagMask {
3756#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3757#include "llvm/BinaryFormat/Dwarf.def"
3759 Asm->OutStreamer->AddComment(
"Macro information version");
3760 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3763 if (Asm->isDwarf64()) {
3764 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3765 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3767 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3768 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3770 Asm->OutStreamer->AddComment(
"debug_line_offset");
3772 Asm->emitDwarfLengthOrOffset(0);
3774 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3777void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3778 for (
auto *MN : Nodes) {
3782 emitMacroFile(*
F, U);
3788void DwarfDebug::emitMacro(
DIMacro &M) {
3789 StringRef
Name =
M.getName();
3790 StringRef
Value =
M.getValue();
3796 if (UseDebugMacroSection) {
3799 ? dwarf::DW_MACRO_define_strx
3800 : dwarf::DW_MACRO_undef_strx;
3803 Asm->OutStreamer->AddComment(
"Line Number");
3804 Asm->emitULEB128(
M.getLine());
3805 Asm->OutStreamer->AddComment(
"Macro String");
3807 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3810 ? dwarf::DW_MACRO_GNU_define_indirect
3811 : dwarf::DW_MACRO_GNU_undef_indirect;
3814 Asm->OutStreamer->AddComment(
"Line Number");
3815 Asm->emitULEB128(
M.getLine());
3816 Asm->OutStreamer->AddComment(
"Macro String");
3817 Asm->emitDwarfSymbolReference(
3818 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3822 Asm->emitULEB128(
M.getMacinfoType());
3823 Asm->OutStreamer->AddComment(
"Line Number");
3824 Asm->emitULEB128(
M.getLine());
3825 Asm->OutStreamer->AddComment(
"Macro String");
3826 Asm->OutStreamer->emitBytes(Str);
3827 Asm->emitInt8(
'\0');
3831void DwarfDebug::emitMacroFileImpl(
3833 StringRef (*MacroFormToString)(
unsigned Form)) {
3835 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3836 Asm->emitULEB128(StartFile);
3837 Asm->OutStreamer->AddComment(
"Line Number");
3839 Asm->OutStreamer->AddComment(
"File Number");
3842 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3844 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3846 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3848 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3849 Asm->emitULEB128(EndFile);
3856 if (UseDebugMacroSection)
3858 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3865void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3866 for (
const auto &
P : CUMap) {
3867 auto &TheCU = *
P.second;
3869 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3871 DIMacroNodeArray Macros = CUNode->getMacros();
3874 Asm->OutStreamer->switchSection(Section);
3875 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3876 if (UseDebugMacroSection)
3878 handleMacroNodes(Macros, U);
3879 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3885void DwarfDebug::emitDebugMacinfo() {
3886 auto &ObjLower =
Asm->getObjFileLowering();
3887 emitDebugMacinfoImpl(UseDebugMacroSection
3888 ? ObjLower.getDwarfMacroSection()
3889 : ObjLower.getDwarfMacinfoSection());
3892void DwarfDebug::emitDebugMacinfoDWO() {
3893 auto &ObjLower =
Asm->getObjFileLowering();
3894 emitDebugMacinfoImpl(UseDebugMacroSection
3895 ? ObjLower.getDwarfMacroDWOSection()
3896 : ObjLower.getDwarfMacinfoDWOSection());
3901void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3902 std::unique_ptr<DwarfCompileUnit> NewU) {
3904 if (!CompilationDir.empty())
3905 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3906 addGnuPubAttributes(*NewU, Die);
3908 SkeletonHolder.addUnit(std::move(NewU));
3913 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3914 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3916 DwarfCompileUnit &NewCU = *OwnedUnit;
3917 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3924 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3931void DwarfDebug::emitDebugInfoDWO() {
3934 InfoHolder.emitUnits(
true);
3939void DwarfDebug::emitDebugAbbrevDWO() {
3941 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3944void DwarfDebug::emitDebugLineDWO() {
3946 SplitTypeUnitFileTable.Emit(
3947 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3948 Asm->getObjFileLowering().getDwarfLineDWOSection());
3951void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3953 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
3954 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
3955 InfoHolder.getStringOffsetsStartSym());
3961void DwarfDebug::emitDebugStrDWO() {
3963 emitStringOffsetsTableHeaderDWO();
3965 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
3966 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
3971void DwarfDebug::emitDebugAddr() {
3972 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
3978 const DICompileUnit *DIUnit =
CU.getCUNode();
3979 SplitTypeUnitFileTable.maybeSetRootFile(
3982 return &SplitTypeUnitFileTable;
3993 return Result.high();
4002 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4005 auto Ins = TypeSignatures.try_emplace(CTy);
4007 CU.addDIETypeSignature(RefDie, Ins.first->second);
4012 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4013 AddrPool.resetUsedFlag();
4015 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4016 CU,
Asm,
this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(
CU));
4019 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4021 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4022 CU.getSourceLanguage());
4026 Ins.first->second = Signature;
4034 if (!CompilationDir.empty())
4035 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4036 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4037 Asm->TM.Options.MCOptions.SplitDwarfFile);
4041 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4042 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4047 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4048 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4051 CU.applyStmtList(UnitDie);
4062 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4063 TypeUnitsUnderConstruction.clear();
4067 if (AddrPool.hasBeenUsed()) {
4068 AccelTypeUnitsDebugNames.clear();
4072 for (
const auto &
TU : TypeUnitsToAdd)
4073 TypeSignatures.erase(
TU.second);
4081 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4087 for (
auto &
TU : TypeUnitsToAdd) {
4088 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4093 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4095 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4098 AccelTypeUnitsDebugNames.convertDieToOffset();
4099 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4100 AccelTypeUnitsDebugNames.clear();
4103 CU.addDIETypeSignature(RefDie, Signature);
4110template <
typename DataT>
4111void DwarfDebug::addAccelNameImpl(
4116 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4133 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4134 ((&Current == &AccelDebugNames) &&
4135 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4136 "Kind is CU but TU is being processed.");
4137 assert(((&Current == &AccelDebugNames) ||
4138 ((&Current == &AccelTypeUnitsDebugNames) &&
4139 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4140 "Kind is TU but CU is being processed.");
4143 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4144 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4158 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4167 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4174 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4180 const DIE &Die,
char Flags) {
4181 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4185 return Asm->OutStreamer->getContext().getDwarfVersion();
4189 if (
Asm->getDwarfVersion() >= 4)
4190 return dwarf::Form::DW_FORM_sec_offset;
4191 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4192 "DWARF64 is not defined prior DWARFv3");
4193 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4194 : dwarf::Form::DW_FORM_data4;
4198 return SectionLabels.lookup(S);
4202 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4207std::optional<MD5::MD5Result>
4211 return std::nullopt;
4212 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4214 return std::nullopt;
4219 std::string ChecksumString =
fromHex(Checksum->Value);
4236 if (
MBB.getAlignment() ==
Align(1))
4239 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4246 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4247 if (PrevLoc.getLine()) {
4248 Asm->OutStreamer->emitDwarfLocDirective(
4249 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4251 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 emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, unsigned StartxLength, unsigned StartxEndx, unsigned EndOfList, StringRef(*StringifyEnum)(unsigned), bool ShouldUseBaseAddress, PayloadEmitter EmitPayload)
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 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))
static const MCPhysReg CalleeSavedReg
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.
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
static constexpr unsigned NoRegister
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.
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.
bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)
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.