65#define DEBUG_TYPE "dwarfdebug"
67STATISTIC(NumCSParams,
"Number of dbg call site params created");
70 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
80 cl::desc(
"Generate DWARF4 type units."),
91 cl::desc(
"Make an absence of debug location information explicit."),
99 "Default for platform"),
107 cl::desc(
"Use inlined strings rather than string section."),
115 cl::desc(
"Disable emission .debug_ranges section."),
120 cl::desc(
"Use sections+offset as references rather than labels."),
127 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
132 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
145 cl::desc(
"Which DWARF linkage-name attributes to emit."),
147 "Default for platform"),
150 "Abstract subprograms")),
155 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
156 "address pool entry sharing to reduce relocations/object size"),
158 "Default address minimization strategy"),
160 "Use rnglists for contiguous ranges if that allows "
161 "using a pre-existing base address"),
164 "Use exprloc addrx+offset expressions for any "
165 "address with a prior base address"),
167 "Use addrx+offset extension form for any address "
168 "with a prior base address"),
176 cl::desc(
"Set to false to ignore Key Instructions metadata"));
180void DebugLocDwarfExpression::emitOp(
uint8_t Op,
const char *Comment) {
186void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
187 getActiveStreamer().emitSLEB128(
Value, Twine(
Value));
190void DebugLocDwarfExpression::emitUnsigned(uint64_t
Value) {
191 getActiveStreamer().emitULEB128(
Value, Twine(
Value));
194void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
195 getActiveStreamer().emitInt8(
Value, Twine(
Value));
198void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
210 assert(!IsBuffering &&
"Already buffering?");
212 TmpBuf = std::make_unique<TempBuffer>(OutBS.GenerateComments);
219 return TmpBuf ? TmpBuf->Bytes.size() : 0;
225 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
226 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
227 ? TmpBuf->Comments[
Byte.index()].c_str()
229 OutBS.emitInt8(
Byte.value(), Comment);
231 TmpBuf->Bytes.clear();
232 TmpBuf->Comments.clear();
243 const bool IsVariadic = !SingleLocExprOpt;
246 if (!IsVariadic && !
MI->isNonListDebugValue()) {
247 assert(
MI->getNumDebugOperands() == 1 &&
248 "Mismatched DIExpression and debug operands for debug instruction.");
249 Expr = *SingleLocExprOpt;
256 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
258 }
else if (
Op.isTargetIndex()) {
261 }
else if (
Op.isImm())
263 else if (
Op.isFPImm())
265 else if (
Op.isCImm())
270 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
274 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
275 return Fragment ? Fragment->OffsetInBits : 0;
289 Expr(ValueLoc.getExpression()) {
290 if (!Expr->getNumElements())
306 return FIE.Expr && FIE.Expr->isFragment();
308 "conflicting locations for variable");
312 bool GenerateTypeUnits,
321 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
327 if (DwarfVersion >= 5)
337 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
338 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()),
340 const Triple &TT =
Asm->TM.getTargetTriple();
345 DebuggerTuning =
Asm->TM.Options.DebuggerTuning;
350 else if (TT.isOSAIX())
366 HasSplitDwarf = !
Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
374 unsigned DwarfVersionNumber =
Asm->TM.Options.MCOptions.DwarfVersion;
375 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
376 :
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())
402 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
403 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
407 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
414 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
416 UseDWARF2Bitfields = DwarfVersion < 4;
422 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
426 EmitDebugEntryValues =
Asm->TM.Options.ShouldEmitDebugEntryValues();
430 UseDebugMacroSection =
439 if (DwarfVersion >= 5)
442 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
451 return Name.starts_with(
"+") || Name.starts_with(
"-");
458 return Name.contains(
") ");
464 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
469 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
470 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
474 return In.slice(In.find(
' ') + 1, In.find(
']'));
487 if (!SP->isDefinition())
490 if (SP->getName() !=
"")
521 if (Scope->isAbstractScope())
539 if (
auto *SkelCU =
CU.getSkeleton())
540 if (
CU.getCUNode()->getSplitDebugInlining())
551 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
552 if (
CU.getSkeleton())
558void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
560 assert(Scope && Scope->getScopeNode());
561 assert(Scope->isAbstractScope());
562 assert(!Scope->getInlinedAt());
568 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
570 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
571 if (
auto *SkelCU =
CU.getSkeleton())
572 if (
CU.getCUNode()->getSplitDebugInlining())
573 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
607template <
typename ValT>
611 for (
auto Param : DescribedParams) {
612 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
622 "Combined debug expression is invalid");
637 auto &ParamsForFwdReg = Worklist[
Reg];
638 for (
auto Param : ParamsToAdd) {
641 return D.ParamReg == Param.ParamReg;
643 "Same parameter described twice by forwarding reg");
650 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
670 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
671 for (
auto &RegUnit : ClobberedRegUnits)
672 if (
TRI.hasRegUnit(
Reg, RegUnit))
677 auto DescribeFwdRegsByCalleeSavedCopy = [&](
const DestSourcePair &CopyInst) {
678 Register CopyDestReg = CopyInst.Destination->getReg();
679 Register CopySrcReg = CopyInst.Source->getReg();
680 if (IsRegClobberedInMeantime(CopyDestReg))
684 if (!
TRI.isCalleeSavedPhysReg(CopyDestReg, *MF))
691 for (
auto FwdRegIt = ForwardedRegWorklist.
begin();
692 FwdRegIt != ForwardedRegWorklist.
end();) {
694 if (FwdRegIt->first == CopySrcReg)
696 else if (
unsigned SubRegIdx =
697 TRI.getSubRegIndex(CopySrcReg, FwdRegIt->first))
698 if (
Register CopyDestSubReg =
TRI.getSubReg(CopyDestReg, SubRegIdx))
708 FwdRegIt = ForwardedRegWorklist.
erase(FwdRegIt);
716 if (
auto CopyInst =
TII.isCopyInstr(*CurMI))
717 DescribeFwdRegsByCalleeSavedCopy(*CopyInst);
745 if (
MI.isDebugInstr())
749 if (MO.getReg().isPhysical()) {
750 for (
auto &FwdReg : ForwardedRegWorklist)
751 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
752 Defs.insert(FwdReg.first);
761 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
762 if (FwdRegDefs.
empty()) {
768 for (
auto ParamFwdReg : FwdRegDefs) {
769 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
770 if (ParamValue->first.isImm()) {
771 int64_t Val = ParamValue->first.getImm();
773 ForwardedRegWorklist[ParamFwdReg], Params);
774 }
else if (ParamValue->first.isReg()) {
775 Register RegLoc = ParamValue->first.getReg();
776 Register SP = TLI.getStackPointerRegisterToSaveRestore();
778 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
781 if (!IsRegClobberedInMeantime(RegLoc) &&
782 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
785 ForwardedRegWorklist[ParamFwdReg], Params);
794 ForwardedRegWorklist[ParamFwdReg]);
801 for (
auto ParamFwdReg : FwdRegDefs)
802 ForwardedRegWorklist.
erase(ParamFwdReg);
809 for (
auto &New : TmpWorklistItems)
811 TmpWorklistItems.
clear();
828 if (ForwardedRegWorklist.
empty())
835 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
846 auto CSInfo = CalleesMap.
find(CallMI);
849 if (CSInfo == CalleesMap.end())
863 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
865 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
867 assert(InsertedReg &&
"Single register used to forward two arguments?");
872 for (
const auto &MO : CallMI->
uses())
873 if (MO.isReg() && MO.isUndef())
874 ForwardedRegWorklist.
erase(MO.getReg());
884 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
893 assert(std::next(Suc) == BundleEnd &&
894 "More than one instruction in call delay slot");
901 for (;
I !=
MBB->rend(); ++
I) {
908 if (ShouldTryEmitEntryVals) {
912 for (
auto &RegEntry : ForwardedRegWorklist) {
919void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
924 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
931 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
934 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
937 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
938 if (!
MI.isBundledWithSucc())
940 auto Suc = std::next(
MI.getIterator());
942 (void)CallInstrBundle;
944 (void)DelaySlotBundle;
951 "Call and its successor instruction don't have same label after.");
956 auto addCallSiteTargetForIndirectCalls = [&](
const MachineInstr *
MI,
958 const MachineFunction *MF =
MI->getMF();
960 auto CSInfo = CalleesMap.
find(
MI);
962 if (CSInfo == CalleesMap.end() || !CSInfo->second.CallTarget)
965 MDNode *CallTarget = CSInfo->second.CallTarget;
967 assert(!CallSiteDIE.findAttribute(dwarf::DW_AT_LLVM_virtual_call_origin) &&
968 "DW_AT_LLVM_virtual_call_origin already exists");
970 DIE *CalleeDIE =
CU.getOrCreateSubprogramDIE(CalleeSP,
nullptr);
971 assert(CalleeDIE &&
"Could not create DIE for call site entry origin");
972 CU.addDIEEntry(CallSiteDIE,
973 CU.getDwarf5OrGNUAttr(dwarf::DW_AT_LLVM_virtual_call_origin),
976 CU.addLinkageNamesToDeclarations(*
this, *CalleeSP, *CalleeDIE);
980 for (
const MachineBasicBlock &
MBB : MF) {
990 if (!
MI.isCandidateForAdditionalCallInfo())
999 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
1007 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
1008 bool PhysRegCalleeOperand =
1010 MachineLocation CallTarget{0};
1012 const DISubprogram *CalleeSP =
nullptr;
1013 const Function *CalleeDecl =
nullptr;
1014 if (PhysRegCalleeOperand) {
1015 bool Scalable =
false;
1016 const MachineOperand *BaseOp =
nullptr;
1017 const TargetRegisterInfo &
TRI =
1018 *
Asm->MF->getSubtarget().getRegisterInfo();
1019 if (
TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, Scalable, &
TRI)) {
1020 if (BaseOp && BaseOp->
isReg() && !Scalable)
1021 CallTarget = MachineLocation(BaseOp->
getReg(),
true);
1025 CallTarget = MachineLocation(CalleeOp.
getReg());
1034 if (CalleeSP ==
nullptr && CallTarget.
getReg() == 0 &&
1035 AllocSiteTy ==
nullptr)
1045 const MachineInstr *TopLevelCallMI =
1052 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
1061 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1064 dbgs() <<
"CallSiteEntry: " << MF.getName() <<
" -> "
1068 MF.getSubtarget().getRegisterInfo()->getName(
1070 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1072 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1073 ScopeDIE, CalleeSP, CalleeDecl, IsTail, PCAddr, CallAddr, CallTarget,
1077 addCallSiteTargetForIndirectCalls(TopLevelCallMI, CallSiteDIE);
1084 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1091 if (!
U.hasDwarfPubSections())
1094 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1097void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1105 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1106 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1108 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1111 NewCU.
addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1114 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1115 NewCU.
addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1118 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1122 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1127 if (!SysRoot.
empty())
1128 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1129 StringRef SDK = DIUnit->
getSDK();
1131 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1142 if (!CompilationDir.empty())
1143 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1144 addGnuPubAttributes(NewCU, Die);
1149 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1153 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1156 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1157 dwarf::DW_FORM_data1, RVer);
1162 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1167 ? dwarf::DW_AT_dwo_name
1168 : dwarf::DW_AT_GNU_dwo_name;
1175 if (
auto *
CU = CUMap.lookup(DIUnit))
1182 return CUMap.begin()->second;
1190DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1191 if (
auto *
CU = getDwarfCompileUnit(DIUnit))
1196 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1198 DwarfCompileUnit &NewCU = *OwnedUnit;
1205 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1206 Asm->OutStreamer->emitDwarfFile0Directive(
1212 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1214 finishUnitAttributes(DIUnit, NewCU);
1215 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1218 CUMap.insert({DIUnit, &NewCU});
1219 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1233 if (!
A.Expr || !
B.Expr)
1235 auto FragmentA =
A.Expr->getFragmentInfo();
1236 auto FragmentB =
B.Expr->getFragmentInfo();
1237 if (!FragmentA || !FragmentB)
1239 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1244 return A.Expr ==
B.Expr;
1259 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1260 M->debug_compile_units_end());
1261 if (NumDebugCUs == 0)
1264 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1265 SingleCU = NumDebugCUs == 1;
1272 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1280 Asm->createTempSymbol(
"rnglists_table_base"));
1284 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1289 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1290 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1293 if (CUNode->getImportedEntities().empty() &&
1294 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1295 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1300 for (
auto *Ty : CUNode->getEnumTypes()) {
1302 "Unexpected function-local entity in 'enums' CU field.");
1306 for (
auto *Ty : CUNode->getRetainedTypes()) {
1309 CU.getOrCreateTypeDIE(RT);
1314void DwarfDebug::finishEntityDefinitions() {
1315 for (
const auto &Entity : ConcreteEntities) {
1316 DIE *Die = Entity->getDIE();
1323 Unit->finishEntityDefinition(Entity.get());
1327void DwarfDebug::finishSubprogramDefinitions() {
1328 for (
const DISubprogram *SP : ProcessedSPNodes) {
1331 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1332 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1336void DwarfDebug::finalizeModuleInfo() {
1337 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1339 finishSubprogramDefinitions();
1341 finishEntityDefinitions();
1343 bool HasEmittedSplitCU =
false;
1347 for (
const auto &
P : CUMap) {
1348 auto &TheCU = *
P.second;
1349 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1351 TheCU.attachLexicalScopesAbstractOrigins();
1354 TheCU.constructContainingTypeDIEs();
1359 auto *SkCU = TheCU.getSkeleton();
1361 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1364 (void)HasEmittedSplitCU;
1366 "Multiple CUs emitted into a single dwo file");
1367 HasEmittedSplitCU =
true;
1369 ? dwarf::DW_AT_dwo_name
1370 : dwarf::DW_AT_GNU_dwo_name;
1371 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1372 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1373 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1374 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1380 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1385 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1386 dwarf::DW_FORM_data8,
ID);
1387 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1388 dwarf::DW_FORM_data8,
ID);
1391 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1393 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1397 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1406 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1408 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1415 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1418 U.setBaseAddress(TheCU.getRanges().front().Begin);
1419 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1426 U.addAddrTableBase();
1429 if (
U.hasRangeLists())
1430 U.addRnglistsBase();
1433 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1442 if (CUNode->getMacros()) {
1443 if (UseDebugMacroSection) {
1445 TheCU.addSectionDelta(
1446 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1450 ? dwarf::DW_AT_macros
1451 : dwarf::DW_AT_GNU_macros;
1452 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1457 TheCU.addSectionDelta(
1458 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1459 U.getMacroLabelBegin(),
1462 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1463 U.getMacroLabelBegin(),
1470 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1471 if (CUNode->getDWOId())
1472 getOrCreateDwarfCompileUnit(CUNode);
1477 SkeletonHolder.computeSizeAndOffsets();
1481 AccelDebugNames.convertDieToOffset();
1490 assert(CurFn ==
nullptr);
1500 Global.getDebugInfo(GVs);
1501 for (
auto *GVE : GVs)
1502 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1513 for (
auto *GVE : CUNode->getGlobalVariables()) {
1517 auto &GVMapEntry = GVMap[GVE->getVariable()];
1518 auto *Expr = GVE->getExpression();
1519 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1520 GVMapEntry.push_back({
nullptr, Expr});
1523 for (
auto *GVE : CUNode->getGlobalVariables()) {
1525 if (Processed.
insert(GV).second)
1530 for (
auto *IE : CUNode->getImportedEntities()) {
1532 "Unexpected function-local entity in 'imports' CU field.");
1533 CU->getOrCreateImportedEntityDIE(IE);
1537 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1539 CU->getOrCreateImportedEntityDIE(IE);
1541 CU->getOrCreateTypeDIE(Ty);
1547 CU->createBaseTypeDIEs();
1552 if (!
Asm || !
Asm->hasDebugInfo())
1556 finalizeModuleInfo();
1566 emitAbbreviations();
1572 if (UseARangesSection)
1580 emitDebugMacinfoDWO();
1590 emitDebugAbbrevDWO();
1592 emitDebugRangesDWO();
1602 emitAccelNamespaces();
1606 emitAccelDebugNames();
1615 emitDebugPubSections();
1623 if (
CU.getExistingAbstractEntity(
Node))
1628 CU.createAbstractEntity(
Node, Scope);
1637void DwarfDebug::collectVariableInfoFromMFTable(
1639 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1640 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1641 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1644 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1645 "Expected inlined-at fields to agree");
1647 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1654 <<
", no variable scope found\n");
1658 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1662 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1663 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1664 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1666 if (PreviousMMI &&
VI.inStackSlot())
1667 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1669 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1670 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1675 if (PreviousLoc->holds<Loc::MMI>())
1676 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1679 <<
", conflicting fragment location types\n");
1684 auto RegVar = std::make_unique<DbgVariable>(
1686 if (
VI.inStackSlot())
1687 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1689 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1692 InfoHolder.addScopeVariable(Scope, RegVar.get());
1693 MFVars.
insert({Var, RegVar.get()});
1694 ConcreteEntities.push_back(std::move(RegVar));
1706 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1714 if (LSRange.size() == 0)
1717 const MachineInstr *LScopeBegin = LSRange.front().first;
1721 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1727 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1730 auto PredDL = Pred->getDebugLoc();
1731 if (!PredDL || Pred->isMetaInstruction())
1735 if (
DL->getScope() == PredDL->getScope())
1738 if (!PredScope || LScope->dominates(PredScope))
1751 if (
MBB->pred_empty() &&
1758 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1802 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1804 bool isSafeForSingleLocation =
true;
1805 const MachineInstr *StartDebugMI =
nullptr;
1806 const MachineInstr *EndMI =
nullptr;
1808 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1809 const MachineInstr *
Instr = EI->getInstr();
1812 size_t Index = std::distance(EB, EI);
1813 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1820 "Forgot label before/after instruction starting a range!");
1823 if (std::next(EI) == Entries.
end()) {
1824 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1826 if (EI->isClobber())
1827 EndMI = EI->getInstr();
1829 else if (std::next(EI)->isClobber())
1833 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1835 if (EI->isDbgValue())
1841 if (EI->isDbgValue()) {
1848 if (!
Instr->isUndefDebugValue()) {
1853 if (
Instr->getDebugExpression()->isFragment())
1854 isSafeForSingleLocation =
false;
1857 StartDebugMI =
Instr;
1859 isSafeForSingleLocation =
false;
1865 if (OpenRanges.
empty())
1869 if (StartLabel == EndLabel) {
1870 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1875 for (
auto &R : OpenRanges)
1883 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1884 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1885 for (
const auto &[MBBSectionId, MBBSectionRange] :
1886 Asm->MBBSectionRanges) {
1887 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1888 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel,
Values);
1891 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1892 MBBSectionRange.EndLabel,
Values);
1902 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1903 for (
auto &
Value : CurEntry->getValues())
1905 dbgs() <<
"-----\n";
1908 auto PrevEntry = std::next(CurEntry);
1909 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1913 if (!isSafeForSingleLocation ||
1920 if (!
Asm->MF->hasBBSections())
1928 const MachineBasicBlock *RangeMBB =
nullptr;
1929 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1930 RangeMBB = &
Asm->MF->front();
1932 RangeMBB = Entries.
begin()->getInstr()->getParent();
1934 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1935 "Range MBB not found in MBBSectionRanges!");
1937 auto *NextEntry = std::next(CurEntry);
1938 auto NextRangeIt = std::next(RangeIt);
1939 while (NextEntry !=
DebugLoc.end()) {
1940 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1947 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1948 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1949 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1950 CurEntry->getValues() != NextEntry->getValues())
1952 RangeIt = NextRangeIt;
1953 NextRangeIt = std::next(RangeIt);
1954 CurEntry = NextEntry;
1955 NextEntry = std::next(CurEntry);
1965 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1967 ConcreteEntities.push_back(
1973 ConcreteEntities.push_back(
1979 return ConcreteEntities.back().get();
1987 collectVariableInfoFromMFTable(TheCU, Processed);
1990 InlinedEntity
IV =
I.first;
1995 const auto &HistoryMapEntries =
I.second;
1999 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
2002 LexicalScope *
Scope =
nullptr;
2004 if (
const DILocation *IA =
IV.second)
2014 *Scope, LocalVar,
IV.second));
2016 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
2022 size_t HistSize = HistoryMapEntries.size();
2023 bool SingleValueWithClobber =
2024 HistSize == 2 && HistoryMapEntries[1].isClobber();
2025 if (HistSize == 1 || SingleValueWithClobber) {
2027 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
2029 RegVar->emplace<Loc::Single>(MInsn);
2035 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
2039 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
2044 if (isValidSingleLocation) {
2045 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
2056 for (
auto &Entry : Entries)
2063 InlinedEntity IL =
I.first;
2064 const MachineInstr *
MI =
I.second;
2068 LexicalScope *
Scope =
nullptr;
2071 const DILocalScope *LocalScope =
2072 Label->getScope()->getNonLexicalBlockFileScope();
2074 if (
const DILocation *IA = IL.second)
2087 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2091 for (
const DINode *DN :
SP->getRetainedNodes()) {
2094 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2096 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2098 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2100 LocalDeclsPerLS[
LS].insert(DN);
2114 if (!
MI.isBundledWithSucc())
2116 auto Suc = std::next(
MI.getIterator());
2121 assert(Suc->isBundledWithPred() &&
2122 "Call bundle instructions are out of order");
2127 if (!NoDebug && SP->areAllCallsDescribed() &&
2129 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2131 bool IsTail =
TII->isTailCall(*
MI);
2149 auto RecordLineZero = [&]() {
2153 const MDNode *Scope =
nullptr;
2154 unsigned Column = 0;
2159 recordSourceLine(0, Column, Scope, 0);
2164 unsigned LastAsmLine =
2165 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2170 if (
MI->isMetaInstruction())
2191 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2193 if (
Asm->OutStreamer->isVerboseAsm()) {
2197 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2206 bool ScopeUsesKeyInstructions =
2208 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2211 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2212 IsKey = KeyInstructions.contains(
MI);
2218 assert(
MI->getParent() == &*
MI->getMF()->begin());
2219 recordSourceLine(SP->getScopeLine(), 0, SP,
2224 bool PrevInstInSameSection =
2226 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2227 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2228 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2238 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2240 RecordSourceLine(
DL, Flags);
2253 if (LastAsmLine == 0)
2274 if (
DL.getLine() == 0 && LastAsmLine == 0)
2281 if (ScopeUsesKeyInstructions) {
2288 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2303 if (
Asm->OutStreamer->isVerboseAsm()) {
2307 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2316static std::pair<const MachineInstr *, bool>
2327 bool IsEmptyPrologue =
2328 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2333 -> std::optional<std::pair<const MachineInstr *, bool>> {
2335 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2336 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2339 if (!isFrameSetup &&
MI.getDebugLoc()) {
2345 if (
MI.getDebugLoc().getLine())
2346 return std::make_pair(&
MI, IsEmptyPrologue);
2351 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2352 NonTrivialInst = &
MI;
2354 IsEmptyPrologue =
false;
2355 return std::nullopt;
2363 auto CurBlock = MF->
begin();
2364 auto CurInst = CurBlock->begin();
2368 while (CurBlock->empty())
2369 CurInst = (++CurBlock)->begin();
2370 assert(CurInst != CurBlock->end());
2374 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2376 if (CurInst->isTerminator()) {
2385 if (CurBlock->pred_size() > 1)
2396 if (CurBlock == MF->
end())
2398 }
while (CurBlock->empty());
2399 CurInst = CurBlock->begin();
2405 if (!CurInst->isMetaInstruction()) {
2406 auto FoundInst = ExamineInst(*CurInst);
2417 if (CurInst->isCall()) {
2419 Loc &&
Loc->getLine() == 0) {
2421 unsigned ScopeLine = SP->getScopeLine();
2424 const_cast<MachineInstr *
>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2427 return std::make_pair(&*CurInst,
false);
2433 auto NextInst = std::next(CurInst);
2434 if (NextInst != CurInst->getParent()->end()) {
2451 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2452 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2453 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2457 return std::make_pair(
nullptr, IsEmptyPrologue);
2463 const MDNode *S,
unsigned Flags,
unsigned CUID,
2465 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2468 unsigned FileNo = 1;
2471 Fn =
Scope->getFilename();
2472 if (Line != 0 && DwarfVersion >= 4)
2477 .getOrCreateSourceID(
Scope->getFile());
2479 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2480 Discriminator, Fn, Comment);
2491 bool IsEmptyPrologue = PrologEnd.second;
2494 if (IsEmptyPrologue) {
2502 if (!
DL ||
DL->getLine() != 0)
2513 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2523 KeyInstructions.clear();
2530 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2547 for (
auto &
MBB : *MF) {
2559 for (
auto &
MI :
MBB) {
2560 if (
MI.isMetaInstruction())
2564 if (!
Loc || !
Loc->getLine())
2575 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2580 KeyInstructions.insert(Buoy);
2586 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2590 auto *InlinedAt = Loc->getInlinedAt();
2593 if (!Group || !Rank)
2597 if (BuoyAtom && BuoyAtom != Group) {
2602 auto &[CandidateRank, CandidateInsts] =
2603 GroupCandidates[{InlinedAt, Group}];
2609 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2610 (CandidateRank != 0 && !CandidateInsts.empty()));
2612 assert(Rank &&
"expected nonzero rank");
2615 if (CandidateRank && CandidateRank < Rank)
2622 if (CandidateRank == Rank)
2626 else if (CandidateRank > Rank)
2627 CandidateInsts.clear();
2631 CandidateInsts.push_back(Buoy);
2632 CandidateRank = Rank;
2640 if (CandidateInsts.empty())
2646 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2647 for (
auto *
I : Insts)
2648 KeyInstructions.insert(
I);
2656 ForceIsStmtInstrs.clear();
2688 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2689 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2692 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2695 for (
auto &
MI :
MBB) {
2696 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2709 for (
auto *
MBB : PredMBBsToExamine) {
2710 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2711 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2712 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2714 MachineInstr *
MI = MBBInstrIt->second;
2715 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2717 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2718 ForceIsStmtInstrs.insert(
MI);
2725 CheckMBBEdge(Succ, 0);
2731 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2739 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2746 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2749 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2750 CheckMBBEdge(FBB, FBBLine);
2774 unsigned LastLine = 0;
2776 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2777 LastLine =
DL->getLine();
2782 for (
auto *Succ : SuccessorBBs)
2783 CheckMBBEdge(Succ, LastLine);
2798 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2799 ?
Asm->OutStreamer->emitLineTableLabel()
2802 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2810 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2816 computeKeyInstructions(MF);
2817 findForceIsStmtInstrs(MF);
2825 if (
Asm->OutStreamer->hasRawTextSupport())
2829 return CU.getUniqueID();
2833 const auto &CURanges =
CU->getRanges();
2834 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2837 LineTable.getMCLineSections().addEndEntry(
2838 const_cast<MCSymbol *
>(CURanges.back().End));
2858 "endFunction should be called with the same function as beginFunction");
2861 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2873 collectEntityInfo(TheCU, SP, Processed);
2877 for (
const auto &R :
Asm->MBBSectionRanges)
2878 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2885 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2886 for (
const auto &R :
Asm->MBBSectionRanges)
2896 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2900 for (
const DINode *DN : SP->getRetainedNodes()) {
2903 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2904 assert(LexS &&
"Expected the LexicalScope to be created.");
2907 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2913 LocalDeclsPerLS[LS].insert(DN);
2916 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2917 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2919 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2922 ProcessedSPNodes.insert(SP);
2926 if (!
LScopes.getAbstractScopesList().empty() &&
2928 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2929 FunctionLineTableLabel);
2931 FunctionLineTableLabel =
nullptr;
2934 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2942 LocalDeclsPerLS.clear();
2949void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2961void DwarfDebug::emitDebugInfo() {
2967void DwarfDebug::emitAbbreviations() {
2970 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2973void DwarfDebug::emitStringOffsetsTableHeader() {
2976 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2980template <
typename AccelTableT>
2981void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2983 Asm->OutStreamer->switchSection(Section);
2989void DwarfDebug::emitAccelDebugNames() {
2998void DwarfDebug::emitAccelNames() {
2999 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
3005void DwarfDebug::emitAccelObjC() {
3006 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
3011void DwarfDebug::emitAccelNamespaces() {
3012 emitAccel(AccelNamespace,
3013 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
3018void DwarfDebug::emitAccelTypes() {
3019 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
3049 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
3057 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
3064 case dwarf::DW_TAG_class_type:
3065 case dwarf::DW_TAG_structure_type:
3066 case dwarf::DW_TAG_union_type:
3067 case dwarf::DW_TAG_enumeration_type:
3072 case dwarf::DW_TAG_typedef:
3073 case dwarf::DW_TAG_base_type:
3074 case dwarf::DW_TAG_subrange_type:
3075 case dwarf::DW_TAG_template_alias:
3077 case dwarf::DW_TAG_namespace:
3079 case dwarf::DW_TAG_subprogram:
3081 case dwarf::DW_TAG_variable:
3083 case dwarf::DW_TAG_enumerator:
3093void DwarfDebug::emitDebugPubSections() {
3094 for (
const auto &NU : CUMap) {
3095 DwarfCompileUnit *TheU = NU.second;
3102 Asm->OutStreamer->switchSection(
3103 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3104 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
3105 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
3107 Asm->OutStreamer->switchSection(
3108 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3109 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
3110 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
3116 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
3117 CU.getDebugSectionOffset());
3119 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
3122void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
3130 "pub" + Name,
"Length of Public " + Name +
" Info");
3132 Asm->OutStreamer->AddComment(
"DWARF Version");
3135 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3136 emitSectionReference(*TheU);
3138 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3143 for (
const auto &GI : Globals)
3146 return A.second->getOffset() <
B.second->getOffset();
3148 for (
const auto &[Name, Entity] : Vec) {
3149 Asm->OutStreamer->AddComment(
"DIE offset");
3150 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3154 Asm->OutStreamer->AddComment(
3160 Asm->OutStreamer->AddComment(
"External Name");
3161 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3164 Asm->OutStreamer->AddComment(
"End Mark");
3165 Asm->emitDwarfLengthOrOffset(0);
3166 Asm->OutStreamer->emitLabel(EndLabel);
3170void DwarfDebug::emitDebugStr() {
3171 MCSection *StringOffsetsSection =
nullptr;
3173 emitStringOffsetsTableHeader();
3174 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3177 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3178 StringOffsetsSection,
true);
3184 auto &&Comments = DebugLocs.getComments(Entry);
3185 auto Comment = Comments.begin();
3186 auto End = Comments.end();
3193 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3195 DebugLocs.getBytes(Entry).size()),
3196 Asm->getDataLayout().isLittleEndian(), PtrSize);
3201 for (
const auto &
Op : Expr) {
3202 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3203 "3 operand ops not yet supported");
3204 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3205 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3207 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3208 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3210 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3212 for (
unsigned J = 0; J <
Length; ++J)
3217 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3228 auto *DIExpr =
Value.getExpression();
3234 if (DIExpr && DIExpr->isEntryValue()) {
3251 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3254 if (Entry.isInt()) {
3255 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean)) {
3260 bool IsSigned =
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3261 BT->getEncoding() == dwarf::DW_ATE_signed_char);
3273 bool IsByteSized = TypeBitSize % 8 == 0;
3275 IsSigned ? !
isIntN(GenericBitSize, Entry.getInt())
3277 static_cast<uint64_t>(Entry.getInt()));
3278 if (TypeBitSize > GenericBitSize && IsByteSized && IsOutOfRange) {
3280 APInt(
static_cast<unsigned>(TypeBitSize),
3281 static_cast<uint64_t>(Entry.getInt()), IsSigned),
3291 }
else if (Entry.isLocation()) {
3293 if (Location.isIndirect())
3299 }
else if (Entry.isTargetIndexLocation()) {
3305 }
else if (Entry.isConstantFP()) {
3308 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3309 }
else if (Entry.getConstantFP()
3312 .getBitWidth() <= 64 ) {
3314 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3317 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3318 << Entry.getConstantFP()
3329 if (!
Value.isVariadic()) {
3330 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3339 return Entry.isLocation() && !Entry.getLoc().getReg();
3344 std::move(ExprCursor),
3345 [EmitValueLocEntry, &
Value](
unsigned Idx,
3347 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3355 assert(!Values.empty() &&
3356 "location list entries without values are redundant");
3357 assert(Begin != End &&
"unexpected location list entry with empty range");
3362 if (
Value.isFragment()) {
3365 return P.isFragment();
3366 }) &&
"all values are expected to be fragments");
3369 for (
const auto &Fragment : Values)
3373 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3384 Asm->OutStreamer->AddComment(
"Loc expr size");
3386 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3387 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3388 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3407 Asm->OutStreamer->AddComment(
"Offset entry count");
3413 Asm->getDwarfOffsetByteSize());
3427 Asm->OutStreamer->AddComment(
"Offset entry count");
3428 Asm->emitInt32(DebugLocs.getLists().size());
3429 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3431 for (
const auto &List : DebugLocs.getLists())
3432 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3433 Asm->getDwarfOffsetByteSize());
3438template <
typename Ranges,
typename PayloadEmitter>
3442 unsigned OffsetPair,
unsigned StartxLength,
unsigned StartxEndx,
3444 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3445 auto Size = Asm->MAI.getCodePointerSize();
3449 Asm->OutStreamer->emitLabel(Sym);
3456 for (
const auto &
Range : R)
3457 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3459 const MCSymbol *CUBase =
CU.getBaseAddress();
3460 bool BaseIsSet =
false;
3461 for (
const auto &
P : SectionRanges) {
3462 auto *
Base = CUBase;
3464 (DD.
useSplitDwarf() && UseDwarf5 &&
P.first->isLinkerRelaxable())) {
3467 }
else if (!
Base && ShouldUseBaseAddress) {
3468 const MCSymbol *Begin =
P.second.front()->Begin;
3473 Asm->OutStreamer->emitIntValue(-1,
Size);
3474 Asm->OutStreamer->AddComment(
" base address");
3475 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3476 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3482 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3483 Asm->emitInt8(BaseAddressx);
3484 Asm->OutStreamer->AddComment(
" base address index");
3487 }
else if (BaseIsSet && !UseDwarf5) {
3490 Asm->OutStreamer->emitIntValue(-1,
Size);
3491 Asm->OutStreamer->emitIntValue(0,
Size);
3494 for (
const auto *RS :
P.second) {
3497 assert(Begin &&
"Range without a begin symbol?");
3498 assert(End &&
"Range without an end symbol?");
3502 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3503 Asm->emitInt8(OffsetPair);
3504 Asm->OutStreamer->AddComment(
" starting offset");
3505 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3506 Asm->OutStreamer->AddComment(
" ending offset");
3507 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3509 Asm->emitLabelDifference(Begin,
Base,
Size);
3510 Asm->emitLabelDifference(End,
Base,
Size);
3512 }
else if (UseDwarf5) {
3520 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3521 Asm->emitInt8(StartxEndx);
3522 Asm->OutStreamer->AddComment(
" start index");
3524 Asm->OutStreamer->AddComment(
" end index");
3527 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3528 Asm->emitInt8(StartxLength);
3529 Asm->OutStreamer->AddComment(
" start index");
3531 Asm->OutStreamer->AddComment(
" length");
3532 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3535 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3536 Asm->OutStreamer->emitSymbolValue(End,
Size);
3543 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3547 Asm->OutStreamer->emitIntValue(0,
Size);
3548 Asm->OutStreamer->emitIntValue(0,
Size);
3556 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3557 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3560 DD.emitDebugLocEntryLocation(E, List.CU);
3564void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3565 if (DebugLocs.getLists().empty())
3568 Asm->OutStreamer->switchSection(Sec);
3574 for (
const auto &
List : DebugLocs.getLists())
3578 Asm->OutStreamer->emitLabel(TableEnd);
3582void DwarfDebug::emitDebugLoc() {
3585 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3586 :
Asm->getObjFileLowering().getDwarfLocSection());
3590void DwarfDebug::emitDebugLocDWO() {
3593 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3598 for (
const auto &
List : DebugLocs.getLists()) {
3599 Asm->OutStreamer->switchSection(
3600 Asm->getObjFileLowering().getDwarfLocDWOSection());
3601 Asm->OutStreamer->emitLabel(
List.Label);
3603 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3612 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3613 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3614 Asm->emitULEB128(idx);
3620 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3630void DwarfDebug::emitDebugARanges() {
3631 if (ArangeLabels.empty())
3638 for (
const SymbolCU &SCU : ArangeLabels) {
3639 if (SCU.Sym->isInSection()) {
3641 MCSection *Section = &SCU.Sym->getSection();
3642 SectionMap[Section].push_back(SCU);
3647 SectionMap[
nullptr].push_back(SCU);
3651 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3653 for (
auto &
I : SectionMap) {
3661 for (
const SymbolCU &Cur :
List) {
3663 Span.
Start = Cur.Sym;
3666 Spans[Cur.CU].push_back(Span);
3672 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3676 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3677 const SymbolCU &Prev =
List[n - 1];
3678 const SymbolCU &Cur =
List[n];
3681 if (Cur.
CU != Prev.
CU) {
3683 Span.
Start = StartSym;
3686 Spans[Prev.
CU].push_back(Span);
3693 Asm->OutStreamer->switchSection(
3694 Asm->getObjFileLowering().getDwarfARangesSection());
3696 unsigned PtrSize =
Asm->MAI.getCodePointerSize();
3699 std::vector<DwarfCompileUnit *> CUs;
3700 for (
const auto &it : Spans) {
3701 DwarfCompileUnit *
CU = it.first;
3706 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3707 return A->getUniqueID() <
B->getUniqueID();
3711 for (DwarfCompileUnit *
CU : CUs) {
3712 std::vector<ArangeSpan> &
List = Spans[
CU];
3715 if (
auto *Skel =
CU->getSkeleton())
3719 unsigned ContentSize =
3721 Asm->getDwarfOffsetByteSize() +
3726 unsigned TupleSize = PtrSize * 2;
3730 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3733 ContentSize += (
List.size() + 1) * TupleSize;
3736 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3737 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3739 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3740 emitSectionReference(*
CU);
3741 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3742 Asm->emitInt8(PtrSize);
3743 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3746 Asm->OutStreamer->emitFill(Padding, 0xff);
3748 for (
const ArangeSpan &Span :
List) {
3749 Asm->emitLabelReference(Span.Start, PtrSize);
3756 auto SizeRef = SymSize.find(Span.Start);
3757 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3758 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3763 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3766 Size = SizeRef->second;
3768 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3772 Asm->OutStreamer->AddComment(
"ARange terminator");
3773 Asm->OutStreamer->emitIntValue(0, PtrSize);
3774 Asm->OutStreamer->emitIntValue(0, PtrSize);
3782 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3783 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3785 List.CU->getCUNode()->getRangesBaseAddress() ||
3797 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3800 Asm->OutStreamer->switchSection(Section);
3810 Asm->OutStreamer->emitLabel(TableEnd);
3815void DwarfDebug::emitDebugRanges() {
3818 emitDebugRangesImpl(Holder,
3820 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3821 :
Asm->getObjFileLowering().getDwarfRangesSection());
3824void DwarfDebug::emitDebugRangesDWO() {
3826 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3833 enum HeaderFlagMask {
3834#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3835#include "llvm/BinaryFormat/Dwarf.def"
3837 Asm->OutStreamer->AddComment(
"Macro information version");
3838 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3841 if (Asm->isDwarf64()) {
3842 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3843 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3845 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3846 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3848 Asm->OutStreamer->AddComment(
"debug_line_offset");
3850 Asm->emitDwarfLengthOrOffset(0);
3852 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3855void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3856 for (
auto *MN : Nodes) {
3860 emitMacroFile(*
F, U);
3866void DwarfDebug::emitMacro(
DIMacro &M) {
3867 StringRef
Name =
M.getName();
3868 StringRef
Value =
M.getValue();
3874 if (UseDebugMacroSection) {
3877 ? dwarf::DW_MACRO_define_strx
3878 : dwarf::DW_MACRO_undef_strx;
3881 Asm->OutStreamer->AddComment(
"Line Number");
3882 Asm->emitULEB128(
M.getLine());
3883 Asm->OutStreamer->AddComment(
"Macro String");
3885 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3888 ? dwarf::DW_MACRO_GNU_define_indirect
3889 : dwarf::DW_MACRO_GNU_undef_indirect;
3892 Asm->OutStreamer->AddComment(
"Line Number");
3893 Asm->emitULEB128(
M.getLine());
3894 Asm->OutStreamer->AddComment(
"Macro String");
3895 Asm->emitDwarfSymbolReference(
3896 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3900 Asm->emitULEB128(
M.getMacinfoType());
3901 Asm->OutStreamer->AddComment(
"Line Number");
3902 Asm->emitULEB128(
M.getLine());
3903 Asm->OutStreamer->AddComment(
"Macro String");
3904 Asm->OutStreamer->emitBytes(Str);
3905 Asm->emitInt8(
'\0');
3909void DwarfDebug::emitMacroFileImpl(
3911 StringRef (*MacroFormToString)(
unsigned Form)) {
3913 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3914 Asm->emitULEB128(StartFile);
3915 Asm->OutStreamer->AddComment(
"Line Number");
3917 Asm->OutStreamer->AddComment(
"File Number");
3920 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3922 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3924 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3926 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3927 Asm->emitULEB128(EndFile);
3934 if (UseDebugMacroSection)
3936 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3943void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3944 for (
const auto &
P : CUMap) {
3945 auto &TheCU = *
P.second;
3947 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3949 DIMacroNodeArray Macros = CUNode->getMacros();
3952 Asm->OutStreamer->switchSection(Section);
3953 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3954 if (UseDebugMacroSection)
3956 handleMacroNodes(Macros, U);
3957 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3963void DwarfDebug::emitDebugMacinfo() {
3964 auto &ObjLower =
Asm->getObjFileLowering();
3965 emitDebugMacinfoImpl(UseDebugMacroSection
3966 ? ObjLower.getDwarfMacroSection()
3967 : ObjLower.getDwarfMacinfoSection());
3970void DwarfDebug::emitDebugMacinfoDWO() {
3971 auto &ObjLower =
Asm->getObjFileLowering();
3972 emitDebugMacinfoImpl(UseDebugMacroSection
3973 ? ObjLower.getDwarfMacroDWOSection()
3974 : ObjLower.getDwarfMacinfoDWOSection());
3979void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3980 std::unique_ptr<DwarfCompileUnit> NewU) {
3982 if (!CompilationDir.empty())
3983 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3984 addGnuPubAttributes(*NewU, Die);
3986 SkeletonHolder.addUnit(std::move(NewU));
3991 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3992 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3994 DwarfCompileUnit &NewCU = *OwnedUnit;
3995 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
4002 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
4009void DwarfDebug::emitDebugInfoDWO() {
4017void DwarfDebug::emitDebugAbbrevDWO() {
4019 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
4022void DwarfDebug::emitDebugLineDWO() {
4024 SplitTypeUnitFileTable.Emit(
4025 *
Asm->OutStreamer, MCDwarfLineTableParams(),
4026 Asm->getObjFileLowering().getDwarfLineDWOSection());
4029void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
4031 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
4032 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
4039void DwarfDebug::emitDebugStrDWO() {
4041 emitStringOffsetsTableHeaderDWO();
4043 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
4044 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
4049void DwarfDebug::emitDebugAddr() {
4050 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
4056 const DICompileUnit *DIUnit =
CU.getCUNode();
4057 SplitTypeUnitFileTable.maybeSetRootFile(
4060 return &SplitTypeUnitFileTable;
4071 return Result.high();
4080 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
4083 auto Ins = TypeSignatures.try_emplace(CTy);
4085 CU.addDIETypeSignature(RefDie, Ins.first->second);
4090 bool TopLevelType = TypeUnitsUnderConstruction.empty();
4091 AddrPool.resetUsedFlag();
4093 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
4097 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
4099 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
4100 CU.getSourceLanguage());
4104 Ins.first->second = Signature;
4112 if (!CompilationDir.empty())
4113 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
4114 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
4115 Asm->TM.Options.MCOptions.SplitDwarfFile);
4119 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
4120 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
4125 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4126 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4129 CU.applyStmtList(UnitDie);
4140 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4141 TypeUnitsUnderConstruction.clear();
4145 if (AddrPool.hasBeenUsed()) {
4146 AccelTypeUnitsDebugNames.clear();
4150 for (
const auto &
TU : TypeUnitsToAdd)
4151 TypeSignatures.erase(
TU.second);
4159 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
4165 for (
auto &
TU : TypeUnitsToAdd) {
4166 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4171 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4173 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4176 AccelTypeUnitsDebugNames.convertDieToOffset();
4177 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4178 AccelTypeUnitsDebugNames.clear();
4181 CU.addDIETypeSignature(RefDie, Signature);
4188template <
typename DataT>
4189void DwarfDebug::addAccelNameImpl(
4194 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4211 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4212 ((&Current == &AccelDebugNames) &&
4213 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4214 "Kind is CU but TU is being processed.");
4215 assert(((&Current == &AccelDebugNames) ||
4216 ((&Current == &AccelTypeUnitsDebugNames) &&
4217 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4218 "Kind is TU but CU is being processed.");
4221 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4222 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4236 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4245 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4252 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4258 const DIE &Die,
char Flags) {
4259 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4263 return Asm->OutStreamer->getContext().getDwarfVersion();
4267 if (
Asm->getDwarfVersion() >= 4)
4268 return dwarf::Form::DW_FORM_sec_offset;
4269 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4270 "DWARF64 is not defined prior DWARFv3");
4271 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4272 : dwarf::Form::DW_FORM_data4;
4276 return SectionLabels.lookup(S);
4280 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4285std::optional<MD5::MD5Result>
4289 return std::nullopt;
4290 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4292 return std::nullopt;
4297 std::string ChecksumString =
fromHex(Checksum->Value);
4314 if (
MBB.getAlignment() ==
Align(1))
4317 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4324 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4325 if (PrevLoc.getLine()) {
4326 Asm->OutStreamer->emitDwarfLocDirective(
4327 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4329 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))
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))
MapVector< Register, SmallVector< FwdRegParamInfo, 2 > > FwdRegWorklist
Register worklist for finding call site values.
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
static constexpr unsigned ULEB128PadSize
static cl::opt< DefaultOnOff > DwarfSectionsAsReferences("dwarf-sections-as-references", cl::Hidden, cl::desc("Use sections+offset as references rather than labels."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
static void 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 DILocalScope * getRetainedNodeScope(const MDNode *N)
static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
static 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.
Class for arbitrary precision integers.
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.
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.
const MCAsmInfo & MAI
Target Asm Printer information.
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.
static LLVM_ABI DILocalScope * getRetainedNodeScope(MDNode *N)
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
Return the entry for the specified key, or a default constructed value if no such entry exists.
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 ...
virtual bool shouldResetBaseAddress(const MCSection &Section) const
Whether the target requires resetting the base address in range/loc lists.
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.
virtual bool shouldAttachCompileUnitRanges() const
Whether to attach ranges/low_pc to the compile unit DIE in endModule.
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.
virtual void finishTargetUnitAttributes(const DICompileUnit &DIUnit, DwarfCompileUnit &NewCU)
Target-specific compile unit attribute finalization.
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 SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
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.
virtual void initializeTargetDebugInfo(const MachineFunction &MF)
Target-specific debug info initialization at function start.
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)
virtual void recordTargetSourceLine(const DebugLoc &DL, unsigned Flags)
Target-specific source line recording.
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.
DwarfFile InfoHolder
Holder for the file specific debug information.
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 addImplicitValue(const APInt &Value, const AsmPrinter &AP)
Emit an implicit value.
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)
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
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.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
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",...
Represent a constant reference to a string, i.e.
constexpr bool empty() const
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)
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 ...
RelativeUniformCounterPtr Values
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.
LLVM_ABI bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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...
@ Ref
The access may reference the value stored in memory.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
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...
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
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.