64#define DEBUG_TYPE "dwarfdebug"
66STATISTIC(NumCSParams,
"Number of dbg call site params created");
69 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
79 cl::desc(
"Generate DWARF4 type units."),
90 cl::desc(
"Make an absence of debug location information explicit."),
98 "Default for platform"),
106 cl::desc(
"Use inlined strings rather than string section."),
114 cl::desc(
"Disable emission .debug_ranges section."),
119 cl::desc(
"Use sections+offset as references rather than labels."),
126 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
131 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
144 cl::desc(
"Which DWARF linkage-name attributes to emit."),
146 "Default for platform"),
149 "Abstract subprograms")),
154 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
155 "address pool entry sharing to reduce relocations/object size"),
157 "Default address minimization strategy"),
159 "Use rnglists for contiguous ranges if that allows "
160 "using a pre-existing base address"),
163 "Use exprloc addrx+offset expressions for any "
164 "address with a prior base address"),
166 "Use addrx+offset extension form for any address "
167 "with a prior base address"),
175 cl::desc(
"Set to false to ignore Key Instructions metadata"));
179void DebugLocDwarfExpression::emitOp(
uint8_t Op,
const char *Comment) {
185void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
186 getActiveStreamer().emitSLEB128(
Value, Twine(
Value));
189void DebugLocDwarfExpression::emitUnsigned(uint64_t
Value) {
190 getActiveStreamer().emitULEB128(
Value, Twine(
Value));
193void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
194 getActiveStreamer().emitInt8(
Value, Twine(
Value));
197void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
209 assert(!IsBuffering &&
"Already buffering?");
211 TmpBuf = std::make_unique<TempBuffer>(OutBS.GenerateComments);
218 return TmpBuf ? TmpBuf->Bytes.size() : 0;
224 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
225 const char *
Comment = (
Byte.index() < TmpBuf->Comments.size())
226 ? TmpBuf->Comments[
Byte.index()].c_str()
228 OutBS.emitInt8(
Byte.value(), Comment);
230 TmpBuf->Bytes.clear();
231 TmpBuf->Comments.clear();
242 const bool IsVariadic = !SingleLocExprOpt;
245 if (!IsVariadic && !
MI->isNonListDebugValue()) {
246 assert(
MI->getNumDebugOperands() == 1 &&
247 "Mismatched DIExpression and debug operands for debug instruction.");
248 Expr = *SingleLocExprOpt;
255 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
257 }
else if (
Op.isTargetIndex()) {
260 }
else if (
Op.isImm())
262 else if (
Op.isFPImm())
264 else if (
Op.isCImm())
269 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
273 std::optional<DIExpression::FragmentInfo> Fragment = Expr.
getFragmentInfo();
274 return Fragment ? Fragment->OffsetInBits : 0;
288 Expr(ValueLoc.getExpression()) {
289 if (!Expr->getNumElements())
305 return FIE.Expr && FIE.Expr->isFragment();
307 "conflicting locations for variable");
311 bool GenerateTypeUnits,
320 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
326 if (DwarfVersion >= 5)
336 InfoHolder(
A,
"info_string", DIEValueAllocator),
337 SkeletonHolder(
A,
"skel_string", DIEValueAllocator),
338 IsDarwin(
A->TM.getTargetTriple().isOSDarwin()) {
339 const Triple &TT =
Asm->TM.getTargetTriple();
344 DebuggerTuning =
Asm->TM.Options.DebuggerTuning;
349 else if (TT.isOSAIX())
355 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
365 HasSplitDwarf = !
Asm->TM.Options.MCOptions.SplitDwarfFile.empty();
373 unsigned DwarfVersionNumber =
Asm->TM.Options.MCOptions.DwarfVersion;
374 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
375 :
MMI->getModule()->getDwarfVersion();
380 bool Dwarf64 = DwarfVersion >= 3 &&
389 ((
Asm->TM.Options.MCOptions.Dwarf64 ||
MMI->getModule()->isDwarf64()) &&
390 TT.isOSBinFormatELF()) ||
391 TT.isOSBinFormatXCOFF();
393 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
400 UseSectionsAsReferences = TT.isNVPTX();
405 GenerateTypeUnits = (
A->TM.getTargetTriple().isOSBinFormatELF() ||
406 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
410 DwarfVersion, GenerateTypeUnits, DebuggerTuning,
A->TM.getTargetTriple());
417 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
419 UseDWARF2Bitfields = DwarfVersion < 4;
425 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
429 EmitDebugEntryValues =
Asm->TM.Options.ShouldEmitDebugEntryValues();
433 UseDebugMacroSection =
442 if (DwarfVersion >= 5)
445 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
454 return Name.starts_with(
"+") || Name.starts_with(
"-");
461 return Name.contains(
") ");
467 Class = In.slice(In.find(
'[') + 1, In.find(
' '));
472 Class = In.slice(In.find(
'[') + 1, In.find(
'('));
473 Category = In.slice(In.find(
'[') + 1, In.find(
' '));
477 return In.slice(In.find(
' ') + 1, In.find(
']'));
490 if (!SP->isDefinition())
493 if (SP->getName() !=
"")
524 if (Scope->isAbstractScope())
542 if (
auto *SkelCU =
CU.getSkeleton())
543 if (
CU.getCUNode()->getSplitDebugInlining())
554 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
555 if (
CU.getSkeleton())
561void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
563 assert(Scope && Scope->getScopeNode());
564 assert(Scope->isAbstractScope());
565 assert(!Scope->getInlinedAt());
571 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
573 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
574 if (
auto *SkelCU =
CU.getSkeleton())
575 if (
CU.getCUNode()->getSplitDebugInlining())
576 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
610template <
typename ValT>
614 for (
auto Param : DescribedParams) {
615 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
630 "Combined debug expression is invalid");
645 auto &ParamsForFwdReg = Worklist[
Reg];
646 for (
auto Param : ParamsToAdd) {
649 return D.ParamReg == Param.ParamReg;
651 "Same parameter described twice by forwarding reg");
658 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
701 if (
MI.isDebugInstr())
705 if (MO.getReg().isPhysical()) {
706 for (
auto &FwdReg : ForwardedRegWorklist)
707 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
708 Defs.insert(FwdReg.first);
717 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
718 if (FwdRegDefs.
empty()) {
727 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
728 for (
auto &RegUnit : ClobberedRegUnits)
729 if (
TRI.hasRegUnit(
Reg, RegUnit))
734 for (
auto ParamFwdReg : FwdRegDefs) {
735 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
736 if (ParamValue->first.isImm()) {
737 int64_t Val = ParamValue->first.getImm();
739 ForwardedRegWorklist[ParamFwdReg], Params);
740 }
else if (ParamValue->first.isReg()) {
741 Register RegLoc = ParamValue->first.getReg();
742 Register SP = TLI.getStackPointerRegisterToSaveRestore();
744 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
745 if (!IsRegClobberedInMeantime(RegLoc) &&
746 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
749 ForwardedRegWorklist[ParamFwdReg], Params);
758 ForwardedRegWorklist[ParamFwdReg]);
765 for (
auto ParamFwdReg : FwdRegDefs)
766 ForwardedRegWorklist.
erase(ParamFwdReg);
773 for (
auto &New : TmpWorklistItems)
775 TmpWorklistItems.
clear();
792 if (ForwardedRegWorklist.
empty())
799 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
810 auto CSInfo = CalleesMap.
find(CallMI);
813 if (CSInfo == CalleesMap.end())
827 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
829 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
831 assert(InsertedReg &&
"Single register used to forward two arguments?");
836 for (
const auto &MO : CallMI->
uses())
837 if (MO.isReg() && MO.isUndef())
838 ForwardedRegWorklist.
erase(MO.getReg());
848 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
857 assert(std::next(Suc) == BundleEnd &&
858 "More than one instruction in call delay slot");
865 for (;
I !=
MBB->rend(); ++
I) {
872 if (ShouldTryEmitEntryVals) {
876 for (
auto &RegEntry : ForwardedRegWorklist) {
883void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
888 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
895 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
898 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
901 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
902 if (!
MI.isBundledWithSucc())
904 auto Suc = std::next(
MI.getIterator());
906 (void)CallInstrBundle;
908 (void)DelaySlotBundle;
915 "Call and its successor instruction don't have same label after.");
920 for (
const MachineBasicBlock &
MBB : MF) {
930 if (!
MI.isCandidateForAdditionalCallInfo())
939 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
947 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
948 bool PhysRegCalleeOperand =
953 const MCOperandInfo &MCOI =
955 PhysRegCalleeOperand =
959 unsigned CallReg = 0;
960 const DISubprogram *CalleeSP =
nullptr;
961 const Function *CalleeDecl =
nullptr;
962 if (PhysRegCalleeOperand) {
963 CallReg = CalleeOp.
getReg();
972 if (CalleeSP ==
nullptr && CallReg == 0 && AllocSiteTy ==
nullptr)
982 const MachineInstr *TopLevelCallMI =
989 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
998 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
1001 << (CalleeDecl ? CalleeDecl->
getName()
1002 : StringRef(MF.getSubtarget()
1004 ->getName(CallReg)))
1005 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1008 CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, CalleeDecl, IsTail,
1009 PCAddr, CallAddr, CallReg, AllocSiteTy);
1016 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1023 if (!
U.hasDwarfPubSections())
1026 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1029void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1037 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1038 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1040 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1042 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1045 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1047 if (!SysRoot.
empty())
1048 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1049 StringRef SDK = DIUnit->
getSDK();
1051 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1062 if (!CompilationDir.empty())
1063 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1064 addGnuPubAttributes(NewCU, Die);
1069 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1073 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1076 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1077 dwarf::DW_FORM_data1, RVer);
1082 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1087 ? dwarf::DW_AT_dwo_name
1088 : dwarf::DW_AT_GNU_dwo_name;
1096DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1097 if (
auto *
CU = CUMap.lookup(DIUnit))
1105 return *CUMap.begin()->second;
1109 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1110 InfoHolder.getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1111 DwarfCompileUnit &NewCU = *OwnedUnit;
1112 InfoHolder.addUnit(std::move(OwnedUnit));
1118 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1119 Asm->OutStreamer->emitDwarfFile0Directive(
1125 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1127 finishUnitAttributes(DIUnit, NewCU);
1128 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1131 CUMap.insert({DIUnit, &NewCU});
1132 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1146 if (!
A.Expr || !
B.Expr)
1148 auto FragmentA =
A.Expr->getFragmentInfo();
1149 auto FragmentB =
B.Expr->getFragmentInfo();
1150 if (!FragmentA || !FragmentB)
1152 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1157 return A.Expr ==
B.Expr;
1172 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1173 M->debug_compile_units_end());
1174 if (NumDebugCUs == 0)
1177 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1178 SingleCU = NumDebugCUs == 1;
1183 Global.getDebugInfo(GVs);
1184 for (
auto *GVE : GVs)
1185 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1193 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1201 Asm->createTempSymbol(
"rnglists_table_base"));
1204 InfoHolder.setRnglistsTableBaseSym(
1205 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1210 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1211 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1214 if (CUNode->getImportedEntities().empty() &&
1215 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1216 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1222 for (
auto *GVE : CUNode->getGlobalVariables()) {
1226 auto &GVMapEntry = GVMap[GVE->getVariable()];
1227 auto *Expr = GVE->getExpression();
1228 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1229 GVMapEntry.push_back({
nullptr, Expr});
1233 for (
auto *GVE : CUNode->getGlobalVariables()) {
1235 if (Processed.
insert(GV).second)
1239 for (
auto *Ty : CUNode->getEnumTypes())
1242 for (
auto *Ty : CUNode->getRetainedTypes()) {
1247 CU.getOrCreateTypeDIE(RT);
1252void DwarfDebug::finishEntityDefinitions() {
1253 for (
const auto &Entity : ConcreteEntities) {
1254 DIE *Die = Entity->getDIE();
1261 Unit->finishEntityDefinition(Entity.get());
1265void DwarfDebug::finishSubprogramDefinitions() {
1266 for (
const DISubprogram *SP : ProcessedSPNodes) {
1269 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1270 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1274void DwarfDebug::finalizeModuleInfo() {
1275 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1277 finishSubprogramDefinitions();
1279 finishEntityDefinitions();
1281 bool HasEmittedSplitCU =
false;
1285 for (
const auto &
P : CUMap) {
1286 auto &TheCU = *
P.second;
1287 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1289 TheCU.attachLexicalScopesAbstractOrigins();
1292 TheCU.constructContainingTypeDIEs();
1297 auto *SkCU = TheCU.getSkeleton();
1299 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1302 (void)HasEmittedSplitCU;
1304 "Multiple CUs emitted into a single dwo file");
1305 HasEmittedSplitCU =
true;
1307 ? dwarf::DW_AT_dwo_name
1308 : dwarf::DW_AT_GNU_dwo_name;
1309 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1310 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1311 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1312 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1318 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1323 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1324 dwarf::DW_FORM_data8,
ID);
1325 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1326 dwarf::DW_FORM_data8,
ID);
1329 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1331 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1335 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1344 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1346 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1351 if (!(
Asm->TM.getTargetTriple().isNVPTX() &&
tuneForGDB())) {
1357 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1360 U.setBaseAddress(TheCU.getRanges().front().Begin);
1361 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1368 U.addAddrTableBase();
1371 if (
U.hasRangeLists())
1372 U.addRnglistsBase();
1375 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1384 if (CUNode->getMacros()) {
1385 if (UseDebugMacroSection) {
1387 TheCU.addSectionDelta(
1388 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1392 ? dwarf::DW_AT_macros
1393 : dwarf::DW_AT_GNU_macros;
1394 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1399 TheCU.addSectionDelta(
1400 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1401 U.getMacroLabelBegin(),
1404 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1405 U.getMacroLabelBegin(),
1412 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1413 if (CUNode->getDWOId())
1414 getOrCreateDwarfCompileUnit(CUNode);
1417 InfoHolder.computeSizeAndOffsets();
1419 SkeletonHolder.computeSizeAndOffsets();
1423 AccelDebugNames.convertDieToOffset();
1432 assert(CurFn ==
nullptr);
1435 for (
const auto &
P : CUMap) {
1440 for (
auto *IE : CUNode->getImportedEntities()) {
1442 "Unexpected function-local entity in 'imports' CU field.");
1443 CU->getOrCreateImportedEntityDIE(IE);
1445 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1447 CU->getOrCreateImportedEntityDIE(IE);
1453 CU->createBaseTypeDIEs();
1458 if (!
Asm || !
Asm->hasDebugInfo())
1462 finalizeModuleInfo();
1472 emitAbbreviations();
1478 if (UseARangesSection)
1486 emitDebugMacinfoDWO();
1496 emitDebugAbbrevDWO();
1498 emitDebugRangesDWO();
1508 emitAccelNamespaces();
1512 emitAccelDebugNames();
1521 emitDebugPubSections();
1529 if (
CU.getExistingAbstractEntity(
Node))
1534 CU.createAbstractEntity(
Node, Scope);
1553void DwarfDebug::collectVariableInfoFromMFTable(
1555 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1556 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1557 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1560 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1561 "Expected inlined-at fields to agree");
1563 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1570 <<
", no variable scope found\n");
1574 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1578 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1579 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1580 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1582 if (PreviousMMI &&
VI.inStackSlot())
1583 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1585 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1586 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1591 if (PreviousLoc->holds<Loc::MMI>())
1592 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1595 <<
", conflicting fragment location types\n");
1600 auto RegVar = std::make_unique<DbgVariable>(
1602 if (
VI.inStackSlot())
1603 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1605 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1608 InfoHolder.addScopeVariable(Scope, RegVar.get());
1609 MFVars.
insert({Var, RegVar.get()});
1610 ConcreteEntities.push_back(std::move(RegVar));
1622 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1630 if (LSRange.size() == 0)
1633 const MachineInstr *LScopeBegin = LSRange.front().first;
1637 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1643 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1646 auto PredDL = Pred->getDebugLoc();
1647 if (!PredDL || Pred->isMetaInstruction())
1651 if (
DL->getScope() == PredDL->getScope())
1654 if (!PredScope || LScope->dominates(PredScope))
1667 if (
MBB->pred_empty() &&
1674 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1718 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1720 bool isSafeForSingleLocation =
true;
1721 const MachineInstr *StartDebugMI =
nullptr;
1722 const MachineInstr *EndMI =
nullptr;
1724 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1725 const MachineInstr *
Instr = EI->getInstr();
1728 size_t Index = std::distance(EB, EI);
1729 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1736 "Forgot label before/after instruction starting a range!");
1739 if (std::next(EI) == Entries.
end()) {
1740 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1742 if (EI->isClobber())
1743 EndMI = EI->getInstr();
1745 else if (std::next(EI)->isClobber())
1749 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1751 if (EI->isDbgValue())
1757 if (EI->isDbgValue()) {
1764 if (!
Instr->isUndefDebugValue()) {
1769 if (
Instr->getDebugExpression()->isFragment())
1770 isSafeForSingleLocation =
false;
1773 StartDebugMI =
Instr;
1775 isSafeForSingleLocation =
false;
1781 if (OpenRanges.
empty())
1785 if (StartLabel == EndLabel) {
1786 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1791 for (
auto &R : OpenRanges)
1799 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1800 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1801 for (
const auto &[MBBSectionId, MBBSectionRange] :
1802 Asm->MBBSectionRanges) {
1803 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1804 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1807 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1808 MBBSectionRange.EndLabel, Values);
1811 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1818 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1819 for (
auto &
Value : CurEntry->getValues())
1821 dbgs() <<
"-----\n";
1824 auto PrevEntry = std::next(CurEntry);
1825 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1829 if (!isSafeForSingleLocation ||
1836 if (!
Asm->MF->hasBBSections())
1844 const MachineBasicBlock *RangeMBB =
nullptr;
1845 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1846 RangeMBB = &
Asm->MF->front();
1848 RangeMBB = Entries.
begin()->getInstr()->getParent();
1850 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1851 "Range MBB not found in MBBSectionRanges!");
1853 auto *NextEntry = std::next(CurEntry);
1854 auto NextRangeIt = std::next(RangeIt);
1855 while (NextEntry !=
DebugLoc.end()) {
1856 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1863 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1864 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1865 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1866 CurEntry->getValues() != NextEntry->getValues())
1868 RangeIt = NextRangeIt;
1869 NextRangeIt = std::next(RangeIt);
1870 CurEntry = NextEntry;
1871 NextEntry = std::next(CurEntry);
1881 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1883 ConcreteEntities.push_back(
1886 InfoHolder.addScopeVariable(&Scope,
1889 ConcreteEntities.push_back(
1892 InfoHolder.addScopeLabel(&Scope,
1895 return ConcreteEntities.back().get();
1903 collectVariableInfoFromMFTable(TheCU, Processed);
1906 InlinedEntity
IV =
I.first;
1911 const auto &HistoryMapEntries =
I.second;
1915 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
1918 LexicalScope *
Scope =
nullptr;
1920 if (
const DILocation *IA =
IV.second)
1930 *Scope, LocalVar,
IV.second));
1932 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1938 size_t HistSize = HistoryMapEntries.size();
1939 bool SingleValueWithClobber =
1940 HistSize == 2 && HistoryMapEntries[1].isClobber();
1941 if (HistSize == 1 || SingleValueWithClobber) {
1943 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1945 RegVar->emplace<Loc::Single>(MInsn);
1951 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
1955 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1960 if (isValidSingleLocation) {
1961 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
1972 for (
auto &Entry : Entries)
1979 InlinedEntity IL =
I.first;
1980 const MachineInstr *
MI =
I.second;
1984 LexicalScope *
Scope =
nullptr;
1987 const DILocalScope *LocalScope =
1988 Label->getScope()->getNonLexicalBlockFileScope();
1990 if (
const DILocation *IA = IL.second)
2003 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2007 for (
const DINode *DN :
SP->getRetainedNodes()) {
2010 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2012 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2014 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2016 LocalDeclsPerLS[
LS].insert(DN);
2030 if (!
MI.isBundledWithSucc())
2032 auto Suc = std::next(
MI.getIterator());
2037 assert(Suc->isBundledWithPred() &&
2038 "Call bundle instructions are out of order");
2043 if (!NoDebug && SP->areAllCallsDescribed() &&
2045 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2047 bool IsTail =
TII->isTailCall(*
MI);
2082 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2084 if (
Asm->OutStreamer->isVerboseAsm()) {
2088 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2094 unsigned LastAsmLine =
2095 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2102 bool ScopeUsesKeyInstructions =
2104 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2107 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2108 IsKey = KeyInstructions.contains(
MI);
2114 assert(
MI->getParent() == &*
MI->getMF()->begin());
2115 recordSourceLine(SP->getScopeLine(), 0, SP,
2120 bool PrevInstInSameSection =
2122 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2123 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2124 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2134 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2136 RecordSourceLine(
DL, Flags);
2149 if (LastAsmLine == 0)
2166 const MDNode *Scope =
nullptr;
2167 unsigned Column = 0;
2172 recordSourceLine(0, Column, Scope, 0);
2180 if (
DL.getLine() == 0 && LastAsmLine == 0)
2187 if (ScopeUsesKeyInstructions) {
2194 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2198 RecordSourceLine(
DL, Flags);
2205static std::pair<const MachineInstr *, bool>
2215 bool IsEmptyPrologue =
2216 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2221 -> std::optional<std::pair<const MachineInstr *, bool>> {
2223 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2224 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2227 if (!isFrameSetup &&
MI.getDebugLoc()) {
2233 if (
MI.getDebugLoc().getLine())
2234 return std::make_pair(&
MI, IsEmptyPrologue);
2239 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2240 NonTrivialInst = &
MI;
2242 IsEmptyPrologue =
false;
2243 return std::nullopt;
2251 auto CurBlock = MF->
begin();
2252 auto CurInst = CurBlock->begin();
2256 while (CurBlock->empty())
2257 CurInst = (++CurBlock)->begin();
2258 assert(CurInst != CurBlock->end());
2262 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2264 if (CurInst->isTerminator()) {
2273 if (CurBlock->pred_size() > 1)
2284 if (CurBlock == MF->
end())
2286 }
while (CurBlock->empty());
2287 CurInst = CurBlock->begin();
2293 if (!CurInst->isMetaInstruction()) {
2294 auto FoundInst = ExamineInst(*CurInst);
2301 auto NextInst = std::next(CurInst);
2302 if (NextInst != CurInst->getParent()->end()) {
2319 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2320 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2321 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2325 return std::make_pair(
nullptr, IsEmptyPrologue);
2331 const MDNode *S,
unsigned Flags,
unsigned CUID,
2333 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2336 unsigned FileNo = 1;
2339 Fn =
Scope->getFilename();
2340 if (Line != 0 && DwarfVersion >= 4)
2345 .getOrCreateSourceID(
Scope->getFile());
2347 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2348 Discriminator, Fn, Comment);
2359 bool IsEmptyPrologue = PrologEnd.second;
2362 if (IsEmptyPrologue) {
2370 if (!
DL ||
DL->getLine() != 0)
2381 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2391 KeyInstructions.clear();
2398 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2415 for (
auto &
MBB : *MF) {
2427 for (
auto &
MI :
MBB) {
2428 if (
MI.isMetaInstruction())
2432 if (!
Loc || !
Loc->getLine())
2443 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2448 KeyInstructions.insert(Buoy);
2454 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2458 auto *InlinedAt = Loc->getInlinedAt();
2461 if (!Group || !Rank)
2465 if (BuoyAtom && BuoyAtom != Group) {
2470 auto &[CandidateRank, CandidateInsts] =
2471 GroupCandidates[{InlinedAt, Group}];
2477 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2478 (CandidateRank != 0 && !CandidateInsts.empty()));
2480 assert(Rank &&
"expected nonzero rank");
2483 if (CandidateRank && CandidateRank < Rank)
2490 if (CandidateRank == Rank)
2494 else if (CandidateRank > Rank)
2495 CandidateInsts.clear();
2499 CandidateInsts.push_back(Buoy);
2500 CandidateRank = Rank;
2508 if (CandidateInsts.empty())
2514 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2515 for (
auto *
I : Insts)
2516 KeyInstructions.insert(
I);
2524 ForceIsStmtInstrs.clear();
2556 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2557 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2560 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2563 for (
auto &
MI :
MBB) {
2564 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2577 for (
auto *
MBB : PredMBBsToExamine) {
2578 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2579 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2580 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2582 MachineInstr *
MI = MBBInstrIt->second;
2583 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2585 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2586 ForceIsStmtInstrs.insert(
MI);
2593 CheckMBBEdge(Succ, 0);
2599 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2607 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2614 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2617 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2618 CheckMBBEdge(FBB, FBBLine);
2642 unsigned LastLine = 0;
2644 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2645 LastLine =
DL->getLine();
2650 for (
auto *Succ : SuccessorBBs)
2651 CheckMBBEdge(Succ, LastLine);
2666 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2667 ?
Asm->OutStreamer->emitLineTableLabel()
2670 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2675 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2681 computeKeyInstructions(MF);
2682 findForceIsStmtInstrs(MF);
2690 if (
Asm->OutStreamer->hasRawTextSupport())
2694 return CU.getUniqueID();
2698 const auto &CURanges =
CU->getRanges();
2699 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2702 LineTable.getMCLineSections().addEndEntry(
2703 const_cast<MCSymbol *
>(CURanges.back().End));
2723 "endFunction should be called with the same function as beginFunction");
2726 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2738 collectEntityInfo(TheCU, SP, Processed);
2742 for (
const auto &R :
Asm->MBBSectionRanges)
2743 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2750 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2751 for (
const auto &R :
Asm->MBBSectionRanges)
2754 assert(InfoHolder.getScopeVariables().empty());
2761 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2765 for (
const DINode *DN : SP->getRetainedNodes()) {
2768 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2769 assert(LexS &&
"Expected the LexicalScope to be created.");
2772 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2778 LocalDeclsPerLS[LS].insert(DN);
2781 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2782 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2784 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2787 ProcessedSPNodes.insert(SP);
2791 if (!
LScopes.getAbstractScopesList().empty() &&
2793 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2794 FunctionLineTableLabel);
2796 FunctionLineTableLabel =
nullptr;
2799 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2805 InfoHolder.getScopeVariables().clear();
2806 InfoHolder.getScopeLabels().clear();
2807 LocalDeclsPerLS.clear();
2814void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2826void DwarfDebug::emitDebugInfo() {
2832void DwarfDebug::emitAbbreviations() {
2833 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2835 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2838void DwarfDebug::emitStringOffsetsTableHeader() {
2839 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2841 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2845template <
typename AccelTableT>
2846void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2848 Asm->OutStreamer->switchSection(Section);
2854void DwarfDebug::emitAccelDebugNames() {
2856 if (getUnits().
empty())
2863void DwarfDebug::emitAccelNames() {
2864 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
2870void DwarfDebug::emitAccelObjC() {
2871 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
2876void DwarfDebug::emitAccelNamespaces() {
2877 emitAccel(AccelNamespace,
2878 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
2883void DwarfDebug::emitAccelTypes() {
2884 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
2914 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2922 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2929 case dwarf::DW_TAG_class_type:
2930 case dwarf::DW_TAG_structure_type:
2931 case dwarf::DW_TAG_union_type:
2932 case dwarf::DW_TAG_enumeration_type:
2937 case dwarf::DW_TAG_typedef:
2938 case dwarf::DW_TAG_base_type:
2939 case dwarf::DW_TAG_subrange_type:
2940 case dwarf::DW_TAG_template_alias:
2942 case dwarf::DW_TAG_namespace:
2944 case dwarf::DW_TAG_subprogram:
2946 case dwarf::DW_TAG_variable:
2948 case dwarf::DW_TAG_enumerator:
2958void DwarfDebug::emitDebugPubSections() {
2959 for (
const auto &NU : CUMap) {
2960 DwarfCompileUnit *TheU = NU.second;
2967 Asm->OutStreamer->switchSection(
2968 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
2969 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
2970 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
2972 Asm->OutStreamer->switchSection(
2973 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
2974 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
2975 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
2981 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
2982 CU.getDebugSectionOffset());
2984 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
2987void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
2995 "pub" + Name,
"Length of Public " + Name +
" Info");
2997 Asm->OutStreamer->AddComment(
"DWARF Version");
3000 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
3001 emitSectionReference(*TheU);
3003 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3008 for (
const auto &GI : Globals)
3011 return A.second->getOffset() <
B.second->getOffset();
3013 for (
const auto &[Name, Entity] : Vec) {
3014 Asm->OutStreamer->AddComment(
"DIE offset");
3015 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3019 Asm->OutStreamer->AddComment(
3025 Asm->OutStreamer->AddComment(
"External Name");
3026 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3029 Asm->OutStreamer->AddComment(
"End Mark");
3030 Asm->emitDwarfLengthOrOffset(0);
3031 Asm->OutStreamer->emitLabel(EndLabel);
3035void DwarfDebug::emitDebugStr() {
3036 MCSection *StringOffsetsSection =
nullptr;
3038 emitStringOffsetsTableHeader();
3039 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3041 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3042 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3043 StringOffsetsSection,
true);
3049 auto &&Comments = DebugLocs.getComments(Entry);
3050 auto Comment = Comments.begin();
3051 auto End = Comments.end();
3058 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3060 DebugLocs.getBytes(Entry).size()),
3061 Asm->getDataLayout().isLittleEndian(), PtrSize);
3066 for (
const auto &
Op : Expr) {
3067 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3068 "3 operand ops not yet supported");
3069 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3070 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3072 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3073 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3075 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3077 for (
unsigned J = 0; J <
Length; ++J)
3082 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3093 auto *DIExpr =
Value.getExpression();
3099 if (DIExpr && DIExpr->isEntryValue()) {
3116 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3119 if (Entry.isInt()) {
3120 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3122 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3123 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3127 }
else if (Entry.isLocation()) {
3129 if (Location.isIndirect())
3135 }
else if (Entry.isTargetIndexLocation()) {
3141 }
else if (Entry.isConstantFP()) {
3144 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3145 }
else if (Entry.getConstantFP()
3148 .getBitWidth() <= 64 ) {
3150 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3153 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3154 << Entry.getConstantFP()
3165 if (!
Value.isVariadic()) {
3166 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3175 return Entry.isLocation() && !Entry.getLoc().getReg();
3180 std::move(ExprCursor),
3181 [EmitValueLocEntry, &
Value](
unsigned Idx,
3183 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3191 assert(!Values.empty() &&
3192 "location list entries without values are redundant");
3193 assert(Begin != End &&
"unexpected location list entry with empty range");
3198 if (
Value.isFragment()) {
3201 return P.isFragment();
3202 }) &&
"all values are expected to be fragments");
3205 for (
const auto &Fragment : Values)
3209 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3220 Asm->OutStreamer->AddComment(
"Loc expr size");
3222 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3223 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3224 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3243 Asm->OutStreamer->AddComment(
"Offset entry count");
3249 Asm->getDwarfOffsetByteSize());
3263 Asm->OutStreamer->AddComment(
"Offset entry count");
3264 Asm->emitInt32(DebugLocs.getLists().size());
3265 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3267 for (
const auto &List : DebugLocs.getLists())
3268 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3269 Asm->getDwarfOffsetByteSize());
3274template <
typename Ranges,
typename PayloadEmitter>
3278 unsigned StartxLength,
unsigned EndOfList,
3280 bool ShouldUseBaseAddress,
3281 PayloadEmitter EmitPayload) {
3283 auto Size = Asm->MAI->getCodePointerSize();
3287 Asm->OutStreamer->emitLabel(Sym);
3294 for (
const auto &
Range : R)
3295 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3297 const MCSymbol *CUBase =
CU.getBaseAddress();
3298 bool BaseIsSet =
false;
3299 for (
const auto &
P : SectionRanges) {
3300 auto *
Base = CUBase;
3301 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB())) {
3311 }
else if (!
Base && ShouldUseBaseAddress) {
3312 const MCSymbol *Begin =
P.second.front()->Begin;
3317 Asm->OutStreamer->emitIntValue(-1,
Size);
3318 Asm->OutStreamer->AddComment(
" base address");
3319 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3320 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3326 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3327 Asm->emitInt8(BaseAddressx);
3328 Asm->OutStreamer->AddComment(
" base address index");
3331 }
else if (BaseIsSet && !UseDwarf5) {
3334 Asm->OutStreamer->emitIntValue(-1,
Size);
3335 Asm->OutStreamer->emitIntValue(0,
Size);
3338 for (
const auto *RS :
P.second) {
3341 assert(Begin &&
"Range without a begin symbol?");
3342 assert(End &&
"Range without an end symbol?");
3346 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3347 Asm->emitInt8(OffsetPair);
3348 Asm->OutStreamer->AddComment(
" starting offset");
3349 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3350 Asm->OutStreamer->AddComment(
" ending offset");
3351 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3353 Asm->emitLabelDifference(Begin,
Base,
Size);
3354 Asm->emitLabelDifference(End,
Base,
Size);
3356 }
else if (UseDwarf5) {
3357 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3358 Asm->emitInt8(StartxLength);
3359 Asm->OutStreamer->AddComment(
" start index");
3361 Asm->OutStreamer->AddComment(
" length");
3362 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3364 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3365 Asm->OutStreamer->emitSymbolValue(End,
Size);
3372 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3376 Asm->OutStreamer->emitIntValue(0,
Size);
3377 Asm->OutStreamer->emitIntValue(0,
Size);
3384 *List.CU, dwarf::DW_LLE_base_addressx,
3385 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
3389 DD.emitDebugLocEntryLocation(E, List.CU);
3393void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3394 if (DebugLocs.getLists().empty())
3397 Asm->OutStreamer->switchSection(Sec);
3403 for (
const auto &
List : DebugLocs.getLists())
3407 Asm->OutStreamer->emitLabel(TableEnd);
3411void DwarfDebug::emitDebugLoc() {
3414 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3415 :
Asm->getObjFileLowering().getDwarfLocSection());
3419void DwarfDebug::emitDebugLocDWO() {
3422 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3427 for (
const auto &
List : DebugLocs.getLists()) {
3428 Asm->OutStreamer->switchSection(
3429 Asm->getObjFileLowering().getDwarfLocDWOSection());
3430 Asm->OutStreamer->emitLabel(
List.Label);
3432 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3441 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3442 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3443 Asm->emitULEB128(idx);
3449 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3459void DwarfDebug::emitDebugARanges() {
3460 if (ArangeLabels.empty())
3467 for (
const SymbolCU &SCU : ArangeLabels) {
3468 if (SCU.Sym->isInSection()) {
3470 MCSection *Section = &SCU.Sym->getSection();
3471 SectionMap[Section].push_back(SCU);
3476 SectionMap[
nullptr].push_back(SCU);
3480 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3482 for (
auto &
I : SectionMap) {
3490 for (
const SymbolCU &Cur :
List) {
3492 Span.
Start = Cur.Sym;
3495 Spans[Cur.CU].push_back(Span);
3501 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3505 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3506 const SymbolCU &Prev =
List[n - 1];
3507 const SymbolCU &Cur =
List[n];
3510 if (Cur.
CU != Prev.
CU) {
3512 Span.
Start = StartSym;
3515 Spans[Prev.
CU].push_back(Span);
3522 Asm->OutStreamer->switchSection(
3523 Asm->getObjFileLowering().getDwarfARangesSection());
3525 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3528 std::vector<DwarfCompileUnit *> CUs;
3529 for (
const auto &it : Spans) {
3530 DwarfCompileUnit *
CU = it.first;
3535 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3536 return A->getUniqueID() <
B->getUniqueID();
3540 for (DwarfCompileUnit *
CU : CUs) {
3541 std::vector<ArangeSpan> &
List = Spans[
CU];
3544 if (
auto *Skel =
CU->getSkeleton())
3548 unsigned ContentSize =
3550 Asm->getDwarfOffsetByteSize() +
3555 unsigned TupleSize = PtrSize * 2;
3559 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3562 ContentSize += (
List.size() + 1) * TupleSize;
3565 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3566 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3568 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3569 emitSectionReference(*
CU);
3570 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3571 Asm->emitInt8(PtrSize);
3572 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3575 Asm->OutStreamer->emitFill(Padding, 0xff);
3577 for (
const ArangeSpan &Span :
List) {
3578 Asm->emitLabelReference(Span.Start, PtrSize);
3585 auto SizeRef = SymSize.find(Span.Start);
3586 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3587 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3592 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3595 Size = SizeRef->second;
3597 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3601 Asm->OutStreamer->AddComment(
"ARange terminator");
3602 Asm->OutStreamer->emitIntValue(0, PtrSize);
3603 Asm->OutStreamer->emitIntValue(0, PtrSize);
3611 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3612 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3614 List.CU->getCUNode()->getRangesBaseAddress() ||
3626 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3629 Asm->OutStreamer->switchSection(Section);
3639 Asm->OutStreamer->emitLabel(TableEnd);
3644void DwarfDebug::emitDebugRanges() {
3645 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3647 emitDebugRangesImpl(Holder,
3649 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3650 :
Asm->getObjFileLowering().getDwarfRangesSection());
3653void DwarfDebug::emitDebugRangesDWO() {
3654 emitDebugRangesImpl(InfoHolder,
3655 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3662 enum HeaderFlagMask {
3663#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3664#include "llvm/BinaryFormat/Dwarf.def"
3666 Asm->OutStreamer->AddComment(
"Macro information version");
3667 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3670 if (Asm->isDwarf64()) {
3671 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3672 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3674 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3675 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3677 Asm->OutStreamer->AddComment(
"debug_line_offset");
3679 Asm->emitDwarfLengthOrOffset(0);
3681 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3684void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3685 for (
auto *MN : Nodes) {
3689 emitMacroFile(*
F, U);
3695void DwarfDebug::emitMacro(
DIMacro &M) {
3696 StringRef
Name =
M.getName();
3697 StringRef
Value =
M.getValue();
3703 if (UseDebugMacroSection) {
3706 ? dwarf::DW_MACRO_define_strx
3707 : dwarf::DW_MACRO_undef_strx;
3710 Asm->OutStreamer->AddComment(
"Line Number");
3711 Asm->emitULEB128(
M.getLine());
3712 Asm->OutStreamer->AddComment(
"Macro String");
3714 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3717 ? dwarf::DW_MACRO_GNU_define_indirect
3718 : dwarf::DW_MACRO_GNU_undef_indirect;
3721 Asm->OutStreamer->AddComment(
"Line Number");
3722 Asm->emitULEB128(
M.getLine());
3723 Asm->OutStreamer->AddComment(
"Macro String");
3724 Asm->emitDwarfSymbolReference(
3725 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3729 Asm->emitULEB128(
M.getMacinfoType());
3730 Asm->OutStreamer->AddComment(
"Line Number");
3731 Asm->emitULEB128(
M.getLine());
3732 Asm->OutStreamer->AddComment(
"Macro String");
3733 Asm->OutStreamer->emitBytes(Str);
3734 Asm->emitInt8(
'\0');
3738void DwarfDebug::emitMacroFileImpl(
3740 StringRef (*MacroFormToString)(
unsigned Form)) {
3742 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3743 Asm->emitULEB128(StartFile);
3744 Asm->OutStreamer->AddComment(
"Line Number");
3746 Asm->OutStreamer->AddComment(
"File Number");
3749 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3751 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3753 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3755 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3756 Asm->emitULEB128(EndFile);
3763 if (UseDebugMacroSection)
3765 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3772void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3773 for (
const auto &
P : CUMap) {
3774 auto &TheCU = *
P.second;
3776 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3778 DIMacroNodeArray Macros = CUNode->getMacros();
3781 Asm->OutStreamer->switchSection(Section);
3782 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3783 if (UseDebugMacroSection)
3785 handleMacroNodes(Macros, U);
3786 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3792void DwarfDebug::emitDebugMacinfo() {
3793 auto &ObjLower =
Asm->getObjFileLowering();
3794 emitDebugMacinfoImpl(UseDebugMacroSection
3795 ? ObjLower.getDwarfMacroSection()
3796 : ObjLower.getDwarfMacinfoSection());
3799void DwarfDebug::emitDebugMacinfoDWO() {
3800 auto &ObjLower =
Asm->getObjFileLowering();
3801 emitDebugMacinfoImpl(UseDebugMacroSection
3802 ? ObjLower.getDwarfMacroDWOSection()
3803 : ObjLower.getDwarfMacinfoDWOSection());
3808void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3809 std::unique_ptr<DwarfCompileUnit> NewU) {
3811 if (!CompilationDir.empty())
3812 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3813 addGnuPubAttributes(*NewU, Die);
3815 SkeletonHolder.addUnit(std::move(NewU));
3820 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3821 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3823 DwarfCompileUnit &NewCU = *OwnedUnit;
3824 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3831 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3838void DwarfDebug::emitDebugInfoDWO() {
3841 InfoHolder.emitUnits(
true);
3846void DwarfDebug::emitDebugAbbrevDWO() {
3848 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3851void DwarfDebug::emitDebugLineDWO() {
3853 SplitTypeUnitFileTable.Emit(
3854 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3855 Asm->getObjFileLowering().getDwarfLineDWOSection());
3858void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3860 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
3861 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
3862 InfoHolder.getStringOffsetsStartSym());
3868void DwarfDebug::emitDebugStrDWO() {
3870 emitStringOffsetsTableHeaderDWO();
3872 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
3873 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
3878void DwarfDebug::emitDebugAddr() {
3879 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
3885 const DICompileUnit *DIUnit =
CU.getCUNode();
3886 SplitTypeUnitFileTable.maybeSetRootFile(
3889 return &SplitTypeUnitFileTable;
3900 return Result.high();
3909 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
3912 auto Ins = TypeSignatures.try_emplace(CTy);
3914 CU.addDIETypeSignature(RefDie, Ins.first->second);
3919 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3920 AddrPool.resetUsedFlag();
3922 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
3923 CU,
Asm,
this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(
CU));
3926 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3928 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3929 CU.getSourceLanguage());
3933 Ins.first->second = Signature;
3941 if (!CompilationDir.empty())
3942 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
3943 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
3944 Asm->TM.Options.MCOptions.SplitDwarfFile);
3948 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
3949 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
3954 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
3955 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
3958 CU.applyStmtList(UnitDie);
3969 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
3970 TypeUnitsUnderConstruction.clear();
3974 if (AddrPool.hasBeenUsed()) {
3975 AccelTypeUnitsDebugNames.clear();
3979 for (
const auto &
TU : TypeUnitsToAdd)
3980 TypeSignatures.erase(
TU.second);
3988 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
3994 for (
auto &
TU : TypeUnitsToAdd) {
3995 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
4000 AccelDebugNames.addTypeUnitSignature(*
TU.first);
4002 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
4005 AccelTypeUnitsDebugNames.convertDieToOffset();
4006 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4007 AccelTypeUnitsDebugNames.clear();
4010 CU.addDIETypeSignature(RefDie, Signature);
4017template <
typename DataT>
4018void DwarfDebug::addAccelNameImpl(
4023 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4040 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4041 ((&Current == &AccelDebugNames) &&
4042 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4043 "Kind is CU but TU is being processed.");
4044 assert(((&Current == &AccelDebugNames) ||
4045 ((&Current == &AccelTypeUnitsDebugNames) &&
4046 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4047 "Kind is TU but CU is being processed.");
4050 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4051 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4065 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4074 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4081 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4087 const DIE &Die,
char Flags) {
4088 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4092 return Asm->OutStreamer->getContext().getDwarfVersion();
4096 if (
Asm->getDwarfVersion() >= 4)
4097 return dwarf::Form::DW_FORM_sec_offset;
4098 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4099 "DWARF64 is not defined prior DWARFv3");
4100 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4101 : dwarf::Form::DW_FORM_data4;
4105 return SectionLabels.lookup(S);
4109 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4114std::optional<MD5::MD5Result>
4118 return std::nullopt;
4119 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4121 return std::nullopt;
4126 std::string ChecksumString =
fromHex(Checksum->Value);
4143 if (
MBB.getAlignment() ==
Align(1))
4146 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4153 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4154 if (PrevLoc.getLine()) {
4155 Asm->OutStreamer->emitDwarfLocDirective(
4156 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4158 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))
static cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))
Set to false to ignore Key Instructions metadata.
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr)
static cl::opt< DefaultOnOff > DwarfOpConvert("dwarf-op-convert", cl::Hidden, cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static std::pair< const MachineInstr *, bool > findPrologueEndLoc(const MachineFunction *MF)
static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)
Try to interpret values loaded into registers that forward parameters for CallMI.
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))
MapVector< uint64_t, SmallVector< FwdRegParamInfo, 2 > > FwdRegWorklist
Register worklist for finding call site values.
static cl::opt< bool > UseDwarfRangesBaseAddressSpecifier("use-dwarf-ranges-base-address-specifier", cl::Hidden, cl::desc("Use base address specifiers in debug_ranges"), cl::init(false))
SmallSet< Register, 16 > ClobberedRegSet
Container for the set of registers known to be clobbered on the path to a call site.
static void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegSet &ClobberedRegUnits)
Interpret values loaded into registers by CurMI.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegSet &ClobberedRegUnits)
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
static constexpr unsigned ULEB128PadSize
static cl::opt< DefaultOnOff > DwarfSectionsAsReferences("dwarf-sections-as-references", cl::Hidden, cl::desc("Use sections+offset as references rather than labels."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
static void forBothCUs(DwarfCompileUnit &CU, Func F)
static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD)
static const DILocalScope * getRetainedNodeScope(const MDNode *N)
static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
static cl::opt< DefaultOnOff > UnknownLocations("use-unknown-locations", cl::Hidden, cl::desc("Make an absence of debug location information explicit."), cl::values(clEnumVal(Default, "At top of block or after label"), clEnumVal(Enable, "In all cases"), clEnumVal(Disable, "Never")), cl::init(Default))
static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, const MDNode *S, unsigned Flags, unsigned CUID, uint16_t DwarfVersion, ArrayRef< std::unique_ptr< DwarfCompileUnit > > DCUs, StringRef Comment={})
Register a source line with debug info.
static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD, const DwarfCompileUnit &CU, uint16_t DwarfVersion)
Emit the header of a DWARF 5 macro section, or the GNU extension for DWARF 4.
static cl::opt< AccelTableKind > AccelTables("accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."), cl::values(clEnumValN(AccelTableKind::Default, "Default", "Default for platform"), clEnumValN(AccelTableKind::None, "Disable", "Disabled."), clEnumValN(AccelTableKind::Apple, "Apple", "Apple"), clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")), cl::init(AccelTableKind::Default))
static cl::opt< DwarfDebug::MinimizeAddrInV5 > MinimizeAddrInV5Option("minimize-addr-in-v5", cl::Hidden, cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more " "address pool entry sharing to reduce relocations/object size"), cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default", "Default address minimization strategy"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges", "Use rnglists for contiguous ranges if that allows " "using a pre-existing base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions, "Expressions", "Use exprloc addrx+offset expressions for any " "address with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Form, "Form", "Use addrx+offset extension form for any address " "with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled", "Stuff")), cl::init(DwarfDebug::MinimizeAddrInV5::Default))
static StringRef getObjCMethodName(StringRef In)
static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, unsigned StartxLength, unsigned EndOfList, StringRef(*StringifyEnum)(unsigned), bool ShouldUseBaseAddress, PayloadEmitter EmitPayload)
static DbgValueLoc getDebugLocValue(const MachineInstr *MI)
Get .debug_loc entry for the instruction range starting at MI.
static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
static bool isCopy(MachineInstr *MI)
static const uint32_t IV[8]
Class recording the (high level) value of a variable.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
This class is intended to be used as a driving class for all asm writers.
DwarfDebug * getDwarfDebug()
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
uint16_t getDwarfVersion() const
virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=0
virtual unsigned emitDIERef(const DIE &D)=0
Basic type, like 'int' or 'float'.
bool getDebugInfoForProfiling() const
bool isDebugDirectivesOnly() const
StringRef getFlags() const
static LLVM_ABI std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
unsigned getRuntimeVersion() const
bool getSplitDebugInlining() const
StringRef getSysRoot() const
StringRef getProducer() const
DISourceLanguageName getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static LLVM_ABI std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
A structured debug information entry.
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
LLVM_ABI const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
dwarf::Tag getTag() const
Holds a DIExpression and keeps track of how many operands have been consumed so far.
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
LLVM_ABI bool isValid() const
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
Base class for scope-like contexts.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
LLVM_ABI DIScope * getScope() const
uint16_t getUnversionedName() const
Transitional API for cases where we do not yet support versioned source language names.
Subprogram description. Uses SubclassData1.
DIScope * getScope() const
Encoding
Size and signedness of expression operations' operands.
Used for tracking debug info about call site parameters.
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
SmallVector< Entry, 4 > Entries
A single location or constant within a variable location description, with either a single entry (wit...
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
const DILocalVariable * getVariable() const
const DIType * getType() const
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
AsmPrinter * Asm
Target of debug info emission.
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
MachineModuleInfo * MMI
Collected machine module information.
DebugLoc PrevInstLoc
Previous instruction's location information.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
DebugHandlerBase(AsmPrinter *A)
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
const MachineBasicBlock * PrevInstBB
void requestLabelAfterInsn(const MachineInstr *MI)
Ensure that a label will be emitted after MI.
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
DbgLabelInstrMap DbgLabels
Mapping of inlined labels and DBG_LABEL machine instruction.
void beginModule(Module *M) override
const InstructionOrdering & getInstOrdering() const
void requestLabelBeforeInsn(const MachineInstr *MI)
Ensure that a label will be emitted before MI.
const MachineBasicBlock * EpilogBeginBlock
This block includes epilogue instructions.
const MachineInstr * PrologEndLoc
This location indicates end of function prologue and beginning of function body.
DwarfExpression implementation for .debug_loc entries.
void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU)
Lower this entry into a DWARF expression.
Builder for DebugLocStream entries.
Builder for DebugLocStream lists.
ArrayRef< Entry > getEntries(const List &L) const
LLVM_ABI unsigned getLine() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)
Construct a DIE for this subprogram scope.
void createAbstractEntity(const DINode *Node, LexicalScope *Scope)
DwarfCompileUnit * getSkeleton() const
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
const StringMap< const DIE * > & getGlobalNames() const
DbgEntity * getExistingAbstractEntity(const DINode *Node)
const StringMap< const DIE * > & getGlobalTypes() const
bool hasDwarfPubSections() const
Collects and handles dwarf debug information.
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
bool emitDebugEntryValues() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind)
Sets the current DWARF5AccelTable to use.
bool alwaysUseRanges(const DwarfCompileUnit &) const
Returns whether range encodings should be used for single entry range lists.
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
bool useAppleExtensionAttributes() const
void skippedNonDebugFunction() override
void addArangeLabel(SymbolCU SCU)
Add a label so that arange data can be generated for it.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
AddressPool & getAddressPool()
DWARF5AccelTable & getCurrentDWARF5AccelTable()
Returns either CU or TU DWARF5AccelTable.
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
bool shareAcrossDWOCUs() const
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)
Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
const MCSymbol * getSectionLabel(const MCSection *S)
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support.
unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU)
Get Dwarf compile unit ID for line table.
const MachineInstr * emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
bool useRangesSection() const
Returns whether ranges section should be emitted.
void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null.
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)
Add a DIE to the set of types that we're going to pull into type units.
void endModule() override
Emit all Dwarf sections that should come after the content.
void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)
void beginCodeAlignment(const MachineBasicBlock &MBB) override
Process beginning of code alignment.
DwarfDebug(AsmPrinter *A)
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
void finalize()
This needs to be called last to commit any pending changes.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void setMemoryLocationKind()
Lock this down to become a memory location description.
std::optional< uint8_t > TagOffset
void addBooleanConstant(int64_t Value)
Emit a boolean constant.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
void addSignedConstant(int64_t Value)
Emit a signed constant.
virtual void commitTemporaryBuffer()=0
Commit the data stored in the temporary buffer to the main output.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
virtual void enableTemporaryBuffer()=0
Start emitting data to the temporary buffer.
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void setRnglistsTableBaseSym(MCSymbol *Sym)
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
const SmallVectorImpl< RangeSpanList > & getRangeLists() const
getRangeLists - Get the vector of range lists.
MCSymbol * getStringOffsetsStartSym() const
MCSymbol * getRnglistsTableBaseSym() const
DwarfStringPool & getStringPool()
Returns the string pool.
void emitAbbrevs(MCSection *)
Emit a set of abbreviations to the specific section.
void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)
Emit all of the strings to the section given.
DwarfStringPoolEntryRef: Dwarf string pool entry reference.
LLVM_ABI_FOR_TEST EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
LLVM_ABI_FOR_TEST void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)
void setTypeSignature(uint64_t Signature)
void setType(const DIE *Ty)
This dwarf writer support class manages information associated with a source file.
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)
Creates type DIE with specific context.
const DICompileUnit * getCUNode() const
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
unsigned getUniqueID() const
Gets Unique ID for this unit.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool isTailCall(const MachineInstr &MI) const override
Record instruction ordering so we can query their relative positions within a function.
This class is used to track scope information.
SmallVectorImpl< InsnRange > & getRanges()
const DILocalScope * getScopeNode() const
This class provides interface to collect and use lexical scoping information from machine instruction...
LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)
Find lexical scope, either regular or inlined, for the given DebugLoc.
LexicalScope * findAbstractScope(const DILocalScope *N)
Find an abstract scope or return null.
Single(DbgValueLoc ValueLoc)
static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)
MCSection * getDwarfLoclistsSection() const
MCSection * getDwarfRangesSection() const
MCSection * getDwarfMacroSection() const
MCSection * getDwarfMacinfoDWOSection() const
MCSection * getDwarfMacinfoSection() const
MCSection * getDwarfMacroDWOSection() const
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol * getBeginSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
uint32_t getIndex() const
Get the (implementation defined) index.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
succ_iterator succ_begin()
MBBSectionID getSectionID() const
Returns the section ID of this basic block.
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const CallSiteInfoMap & getCallSitesInfo() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
unsigned getNumOperands() const
Retuns the total number of operands.
bool hasDelaySlot(QueryType Type=AnyInBundle) const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
mop_range uses()
Returns all operands which may be register uses.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
This class implements a map that also provides access to all stored values in a deterministic order.
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
bool empty() const
Determine if the SetVector is empty or not.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void insert_range(Range &&R)
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
const Triple & getTargetTriple() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
Triple - Helper class for working with autoconf configuration names.
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI StringRef RangeListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
LLVM_ABI StringRef MacroString(unsigned Encoding)
LLVM_ABI StringRef LocListEncodingString(unsigned Encoding)
LLVM_ABI StringRef GnuMacroString(unsigned Encoding)
LLVM_ABI StringRef MacinfoString(unsigned Encoding)
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
LLVM_ABI StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
bool isCPlusPlus(SourceLanguage S)
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
@ DWARF_VERSION
Other constants.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
FunctionAddr VTableAddr Value
MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)
Returns an iterator to the first instruction in the bundle containing I.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation. The return string is half the size of ...
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto cast_or_null(const Y &Val)
auto unique(Range &&R, Predicate P)
bool isa_and_nonnull(const Y &Val)
SmallVector< DbgCallSiteParam, 4 > ParamSet
Collection used for storing debug call site parameters.
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
AccelTableKind
The kind of accelerator tables we should emit.
@ Default
Platform default.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
@ Dwarf
DWARF v5 .debug_names.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
@ Global
Append to llvm.global_dtors.
@ Ref
The access may reference the value stored in memory.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
DebuggerKind
Identify a debugger for "tuning" the debug info.
@ SCE
Tune debug info for SCE targets (e.g. PS4).
@ DBX
Tune debug info for dbx.
@ Default
No specific tuning requested.
@ GDB
Tune debug info for gdb.
@ LLDB
Tune debug info for lldb.
Implement std::hash so that hash_code can be used in STL containers.
Represents a parameter whose call site value can be described by applying a debug expression to a reg...
uint64_t ParamReg
The described parameter register.
const DIExpression * Expr
Debug expression that has been built up when walking through the instruction chain that produces the ...
This struct is a compact representation of a valid (non-zero power of two) alignment.
A pair of GlobalVariable and DIExpression.
Represents an entry-value location, or a fragment of one.
void addFrameIndexExpr(const DIExpression *Expr, int FI)
std::set< FrameIndexExpr > FrameIndexExprs
const std::set< FrameIndexExpr > & getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
A MapVector that performs no allocations if smaller than a certain size.
Helper used to pair up a symbol and its DWARF compile unit.
This struct describes target specific location.
Describes an entry of the various gnu_pub* debug sections.