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())
551void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
553 assert(Scope && Scope->getScopeNode());
554 assert(Scope->isAbstractScope());
555 assert(!Scope->getInlinedAt());
561 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
562 if (
auto *SkelCU =
CU.getSkeleton()) {
564 .constructAbstractSubprogramScopeDIE(Scope);
565 if (
CU.getCUNode()->getSplitDebugInlining())
566 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
568 CU.constructAbstractSubprogramScopeDIE(Scope);
603template <
typename ValT>
607 for (
auto Param : DescribedParams) {
608 bool ShouldCombineExpressions = Expr && Param.Expr->
getNumElements() > 0;
623 "Combined debug expression is invalid");
638 auto &ParamsForFwdReg = Worklist[
Reg];
639 for (
auto Param : ParamsToAdd) {
642 return D.ParamReg == Param.ParamReg;
644 "Same parameter described twice by forwarding reg");
651 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
694 if (
MI.isDebugInstr())
698 if (MO.getReg().isPhysical()) {
699 for (
auto &FwdReg : ForwardedRegWorklist)
700 if (
TRI.regsOverlap(FwdReg.first, MO.getReg()))
701 Defs.insert(FwdReg.first);
710 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
711 if (FwdRegDefs.
empty()) {
720 auto IsRegClobberedInMeantime = [&](
Register Reg) ->
bool {
721 for (
auto &RegUnit : ClobberedRegUnits)
722 if (
TRI.hasRegUnit(
Reg, RegUnit))
727 for (
auto ParamFwdReg : FwdRegDefs) {
728 if (
auto ParamValue =
TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
729 if (ParamValue->first.isImm()) {
730 int64_t Val = ParamValue->first.getImm();
732 ForwardedRegWorklist[ParamFwdReg], Params);
733 }
else if (ParamValue->first.isReg()) {
734 Register RegLoc = ParamValue->first.getReg();
735 Register SP = TLI.getStackPointerRegisterToSaveRestore();
737 bool IsSPorFP = (RegLoc == SP) || (RegLoc ==
FP);
738 if (!IsRegClobberedInMeantime(RegLoc) &&
739 (
TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
742 ForwardedRegWorklist[ParamFwdReg], Params);
751 ForwardedRegWorklist[ParamFwdReg]);
758 for (
auto ParamFwdReg : FwdRegDefs)
759 ForwardedRegWorklist.
erase(ParamFwdReg);
766 for (
auto &New : TmpWorklistItems)
768 TmpWorklistItems.
clear();
785 if (ForwardedRegWorklist.
empty())
792 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
803 auto CSInfo = CalleesMap.
find(CallMI);
806 if (CSInfo == CalleesMap.end())
820 for (
const auto &ArgReg : CSInfo->second.ArgRegPairs) {
822 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
824 assert(InsertedReg &&
"Single register used to forward two arguments?");
829 for (
const auto &MO : CallMI->
uses())
830 if (MO.isReg() && MO.isUndef())
831 ForwardedRegWorklist.
erase(MO.getReg());
841 bool ShouldTryEmitEntryVals =
MBB->getIterator() == MF->
begin();
850 assert(std::next(Suc) == BundleEnd &&
851 "More than one instruction in call delay slot");
858 for (;
I !=
MBB->rend(); ++
I) {
865 if (ShouldTryEmitEntryVals) {
869 for (
auto &RegEntry : ForwardedRegWorklist) {
876void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
881 if (!
SP.areAllCallsDescribed() || !
SP.isDefinition())
888 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
891 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
894 auto delaySlotSupported = [&](
const MachineInstr &
MI) {
895 if (!
MI.isBundledWithSucc())
897 auto Suc = std::next(
MI.getIterator());
899 (void)CallInstrBundle;
901 (void)DelaySlotBundle;
908 "Call and its successor instruction don't have same label after.");
913 for (
const MachineBasicBlock &
MBB : MF) {
923 if (!
MI.isCandidateForAdditionalCallInfo())
932 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
940 const MachineOperand &CalleeOp =
TII->getCalleeOperand(
MI);
941 bool PhysRegCalleeOperand =
946 const MCOperandInfo &MCOI =
948 PhysRegCalleeOperand =
952 unsigned CallReg = 0;
953 const DISubprogram *CalleeSP =
nullptr;
954 const Function *CalleeDecl =
nullptr;
955 if (PhysRegCalleeOperand) {
956 CallReg = CalleeOp.
getReg();
965 if (CalleeSP ==
nullptr && CallReg == 0 && AllocSiteTy ==
nullptr)
975 const MachineInstr *TopLevelCallMI =
982 const MCSymbol *PCAddr = (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
991 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
994 << (CalleeDecl ? CalleeDecl->
getName()
995 : StringRef(MF.getSubtarget()
998 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1001 CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, CalleeDecl, IsTail,
1002 PCAddr, CallAddr, CallReg, AllocSiteTy);
1009 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1016 if (!
U.hasDwarfPubSections())
1019 U.addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1022void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1030 std::string ProducerWithFlags =
Producer.str() +
" " +
Flags.str();
1031 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1033 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1035 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1037 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1039 if (!SysRoot.
empty())
1040 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1041 StringRef SDK = DIUnit->
getSDK();
1043 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1054 if (!CompilationDir.empty())
1055 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1056 addGnuPubAttributes(NewCU, Die);
1061 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1065 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1068 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1069 dwarf::DW_FORM_data1, RVer);
1074 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1079 ? dwarf::DW_AT_dwo_name
1080 : dwarf::DW_AT_GNU_dwo_name;
1088DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1089 if (
auto *
CU = CUMap.lookup(DIUnit))
1097 return *CUMap.begin()->second;
1101 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1102 InfoHolder.getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1103 DwarfCompileUnit &NewCU = *OwnedUnit;
1104 InfoHolder.addUnit(std::move(OwnedUnit));
1110 if (!
Asm->OutStreamer->hasRawTextSupport() || SingleCU)
1111 Asm->OutStreamer->emitDwarfFile0Directive(
1117 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoDWOSection());
1119 finishUnitAttributes(DIUnit, NewCU);
1120 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
1123 CUMap.insert({DIUnit, &NewCU});
1124 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1138 if (!
A.Expr || !
B.Expr)
1140 auto FragmentA =
A.Expr->getFragmentInfo();
1141 auto FragmentB =
B.Expr->getFragmentInfo();
1142 if (!FragmentA || !FragmentB)
1144 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1149 return A.Expr ==
B.Expr;
1164 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1165 M->debug_compile_units_end());
1166 if (NumDebugCUs == 0)
1169 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1170 SingleCU = NumDebugCUs == 1;
1175 Global.getDebugInfo(GVs);
1176 for (
auto *GVE : GVs)
1177 GVMap[GVE->getVariable()].push_back({&
Global, GVE->getExpression()});
1185 .setStringOffsetsStartSym(
Asm->createTempSymbol(
"str_offsets_base"));
1193 Asm->createTempSymbol(
"rnglists_table_base"));
1196 InfoHolder.setRnglistsTableBaseSym(
1197 Asm->createTempSymbol(
"rnglists_dwo_table_base"));
1202 AddrPool.setLabel(
Asm->createTempSymbol(
"addr_table_base"));
1203 DebugLocs.setSym(
Asm->createTempSymbol(
"loclists_table_base"));
1206 if (CUNode->getImportedEntities().empty() &&
1207 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1208 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1214 for (
auto *GVE : CUNode->getGlobalVariables()) {
1218 auto &GVMapEntry = GVMap[GVE->getVariable()];
1219 auto *Expr = GVE->getExpression();
1220 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1221 GVMapEntry.push_back({
nullptr, Expr});
1225 for (
auto *GVE : CUNode->getGlobalVariables()) {
1227 if (Processed.
insert(GV).second)
1231 for (
auto *Ty : CUNode->getEnumTypes())
1234 for (
auto *Ty : CUNode->getRetainedTypes()) {
1239 CU.getOrCreateTypeDIE(RT);
1244void DwarfDebug::finishEntityDefinitions() {
1245 for (
const auto &Entity : ConcreteEntities) {
1246 DIE *Die = Entity->getDIE();
1253 Unit->finishEntityDefinition(Entity.get());
1257void DwarfDebug::finishSubprogramDefinitions() {
1258 for (
const DISubprogram *SP : ProcessedSPNodes) {
1261 getOrCreateDwarfCompileUnit(
SP->getUnit()),
1262 [&](DwarfCompileUnit &
CU) { CU.finishSubprogramDefinition(SP); });
1266void DwarfDebug::finalizeModuleInfo() {
1267 const TargetLoweringObjectFile &TLOF =
Asm->getObjFileLowering();
1269 finishSubprogramDefinitions();
1271 finishEntityDefinitions();
1273 bool HasEmittedSplitCU =
false;
1277 for (
const auto &
P : CUMap) {
1278 auto &TheCU = *
P.second;
1279 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1281 TheCU.attachLexicalScopesAbstractOrigins();
1284 TheCU.constructContainingTypeDIEs();
1289 auto *SkCU = TheCU.getSkeleton();
1291 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1294 (void)HasEmittedSplitCU;
1296 "Multiple CUs emitted into a single dwo file");
1297 HasEmittedSplitCU =
true;
1299 ? dwarf::DW_AT_dwo_name
1300 : dwarf::DW_AT_GNU_dwo_name;
1301 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1302 StringRef DWOName =
Asm->TM.Options.MCOptions.SplitDwarfFile;
1303 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1304 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1310 DIEHash(
Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1315 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1316 dwarf::DW_FORM_data8,
ID);
1317 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1318 dwarf::DW_FORM_data8,
ID);
1321 if (
getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1323 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1327 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1336 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
1338 if (
unsigned NumRanges = TheCU.getRanges().size()) {
1343 if (!(
Asm->TM.getTargetTriple().isNVPTX() &&
tuneForGDB())) {
1349 U.addUInt(
U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1352 U.setBaseAddress(TheCU.getRanges().front().Begin);
1353 U.attachRangesOrLowHighPC(
U.getUnitDie(), TheCU.takeRanges());
1360 U.addAddrTableBase();
1363 if (
U.hasRangeLists())
1364 U.addRnglistsBase();
1367 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_loclists_base,
1376 if (CUNode->getMacros()) {
1377 if (UseDebugMacroSection) {
1379 TheCU.addSectionDelta(
1380 TheCU.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
1384 ? dwarf::DW_AT_macros
1385 : dwarf::DW_AT_GNU_macros;
1386 U.addSectionLabel(
U.getUnitDie(), MacrosAttr,
U.getMacroLabelBegin(),
1391 TheCU.addSectionDelta(
1392 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1393 U.getMacroLabelBegin(),
1396 U.addSectionLabel(
U.getUnitDie(), dwarf::DW_AT_macro_info,
1397 U.getMacroLabelBegin(),
1404 for (
auto *CUNode :
MMI->getModule()->debug_compile_units())
1405 if (CUNode->getDWOId())
1406 getOrCreateDwarfCompileUnit(CUNode);
1409 InfoHolder.computeSizeAndOffsets();
1411 SkeletonHolder.computeSizeAndOffsets();
1415 AccelDebugNames.convertDieToOffset();
1424 assert(CurFn ==
nullptr);
1427 for (
const auto &
P : CUMap) {
1432 for (
auto *IE : CUNode->getImportedEntities()) {
1434 "Unexpected function-local entity in 'imports' CU field.");
1435 CU->getOrCreateImportedEntityDIE(IE);
1437 for (
const auto *
D :
CU->getDeferredLocalDecls()) {
1439 CU->getOrCreateImportedEntityDIE(IE);
1445 CU->createBaseTypeDIEs();
1450 if (!
Asm || !
Asm->hasDebugInfo())
1454 finalizeModuleInfo();
1464 emitAbbreviations();
1470 if (UseARangesSection)
1478 emitDebugMacinfoDWO();
1488 emitDebugAbbrevDWO();
1490 emitDebugRangesDWO();
1500 emitAccelNamespaces();
1504 emitAccelDebugNames();
1513 emitDebugPubSections();
1521 if (
CU.getExistingAbstractEntity(
Node))
1526 CU.createAbstractEntity(
Node, Scope);
1545void DwarfDebug::collectVariableInfoFromMFTable(
1547 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1548 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1549 for (
const auto &VI :
Asm->MF->getVariableDbgInfo()) {
1552 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1553 "Expected inlined-at fields to agree");
1555 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1562 <<
", no variable scope found\n");
1566 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1570 if (DbgVariable *PreviousLoc = MFVars.
lookup(Var)) {
1571 auto *PreviousMMI = std::get_if<Loc::MMI>(PreviousLoc);
1572 auto *PreviousEntryValue = std::get_if<Loc::EntryValue>(PreviousLoc);
1574 if (PreviousMMI &&
VI.inStackSlot())
1575 PreviousMMI->addFrameIndexExpr(
VI.Expr,
VI.getStackSlot());
1577 else if (PreviousEntryValue &&
VI.inEntryValueRegister())
1578 PreviousEntryValue->addExpr(
VI.getEntryValueRegister(), *
VI.Expr);
1583 if (PreviousLoc->holds<Loc::MMI>())
1584 PreviousLoc->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(),
1587 <<
", conflicting fragment location types\n");
1592 auto RegVar = std::make_unique<DbgVariable>(
1594 if (
VI.inStackSlot())
1595 RegVar->emplace<Loc::MMI>(
VI.Expr,
VI.getStackSlot());
1597 RegVar->emplace<Loc::EntryValue>(
VI.getEntryValueRegister(), *
VI.Expr);
1600 InfoHolder.addScopeVariable(Scope, RegVar.get());
1601 MFVars.
insert({Var, RegVar.get()});
1602 ConcreteEntities.push_back(std::move(RegVar));
1614 assert(
DbgValue->getDebugLoc() &&
"DBG_VALUE without a debug location");
1622 if (LSRange.size() == 0)
1625 const MachineInstr *LScopeBegin = LSRange.front().first;
1629 if (!Ordering.isBefore(
DbgValue, LScopeBegin)) {
1635 for (++Pred; Pred !=
MBB->rend(); ++Pred) {
1638 auto PredDL = Pred->getDebugLoc();
1639 if (!PredDL || Pred->isMetaInstruction())
1643 if (
DL->getScope() == PredDL->getScope())
1646 if (!PredScope || LScope->dominates(PredScope))
1659 if (
MBB->pred_empty() &&
1666 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1710 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1712 bool isSafeForSingleLocation =
true;
1713 const MachineInstr *StartDebugMI =
nullptr;
1714 const MachineInstr *EndMI =
nullptr;
1716 for (
auto EB = Entries.
begin(), EI = EB, EE = Entries.
end(); EI != EE; ++EI) {
1717 const MachineInstr *
Instr = EI->getInstr();
1720 size_t Index = std::distance(EB, EI);
1721 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1728 "Forgot label before/after instruction starting a range!");
1731 if (std::next(EI) == Entries.
end()) {
1732 const MachineBasicBlock &EndMBB =
Asm->MF->back();
1734 if (EI->isClobber())
1735 EndMI = EI->getInstr();
1737 else if (std::next(EI)->isClobber())
1741 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1743 if (EI->isDbgValue())
1749 if (EI->isDbgValue()) {
1756 if (!
Instr->isUndefDebugValue()) {
1761 if (
Instr->getDebugExpression()->isFragment())
1762 isSafeForSingleLocation =
false;
1765 StartDebugMI =
Instr;
1767 isSafeForSingleLocation =
false;
1773 if (OpenRanges.
empty())
1777 if (StartLabel == EndLabel) {
1778 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1783 for (
auto &R : OpenRanges)
1791 if (
Asm->MF->hasBBSections() && StartLabel ==
Asm->getFunctionBegin() &&
1792 !
Instr->getParent()->sameSection(&
Asm->MF->front())) {
1793 for (
const auto &[MBBSectionId, MBBSectionRange] :
1794 Asm->MBBSectionRanges) {
1795 if (
Instr->getParent()->getSectionID() == MBBSectionId) {
1796 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1799 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1800 MBBSectionRange.EndLabel, Values);
1803 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1810 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1811 for (
auto &
Value : CurEntry->getValues())
1813 dbgs() <<
"-----\n";
1816 auto PrevEntry = std::next(CurEntry);
1817 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1821 if (!isSafeForSingleLocation ||
1828 if (!
Asm->MF->hasBBSections())
1836 const MachineBasicBlock *RangeMBB =
nullptr;
1837 if (
DebugLoc[0].getBeginSym() ==
Asm->getFunctionBegin())
1838 RangeMBB = &
Asm->MF->front();
1840 RangeMBB = Entries.
begin()->getInstr()->getParent();
1842 assert(RangeIt !=
Asm->MBBSectionRanges.end() &&
1843 "Range MBB not found in MBBSectionRanges!");
1845 auto *NextEntry = std::next(CurEntry);
1846 auto NextRangeIt = std::next(RangeIt);
1847 while (NextEntry !=
DebugLoc.end()) {
1848 if (NextRangeIt ==
Asm->MBBSectionRanges.end())
1855 if ((RangeIt->second.EndLabel !=
Asm->getFunctionEnd() &&
1856 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1857 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1858 CurEntry->getValues() != NextEntry->getValues())
1860 RangeIt = NextRangeIt;
1861 NextRangeIt = std::next(RangeIt);
1862 CurEntry = NextEntry;
1863 NextEntry = std::next(CurEntry);
1873 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1875 ConcreteEntities.push_back(
1878 InfoHolder.addScopeVariable(&Scope,
1881 ConcreteEntities.push_back(
1884 InfoHolder.addScopeLabel(&Scope,
1887 return ConcreteEntities.back().get();
1895 collectVariableInfoFromMFTable(TheCU, Processed);
1898 InlinedEntity
IV =
I.first;
1903 const auto &HistoryMapEntries =
I.second;
1907 if (!
DbgValues.hasNonEmptyLocation(HistoryMapEntries))
1910 LexicalScope *
Scope =
nullptr;
1912 if (
const DILocation *IA =
IV.second)
1922 *Scope, LocalVar,
IV.second));
1924 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1930 size_t HistSize = HistoryMapEntries.size();
1931 bool SingleValueWithClobber =
1932 HistSize == 2 && HistoryMapEntries[1].isClobber();
1933 if (HistSize == 1 || SingleValueWithClobber) {
1935 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1937 RegVar->emplace<Loc::Single>(MInsn);
1943 DebugLocStream::ListBuilder
List(DebugLocs, TheCU, *
Asm, *RegVar);
1947 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1952 if (isValidSingleLocation) {
1953 RegVar->emplace<Loc::Single>(Entries[0].getValues()[0]);
1964 for (
auto &Entry : Entries)
1971 InlinedEntity IL =
I.first;
1972 const MachineInstr *
MI =
I.second;
1976 LexicalScope *
Scope =
nullptr;
1979 const DILocalScope *LocalScope =
1980 Label->getScope()->getNonLexicalBlockFileScope();
1982 if (
const DILocation *IA = IL.second)
1995 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
1999 for (
const DINode *DN :
SP->getRetainedNodes()) {
2002 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2004 LexicalScope *LexS =
LScopes.findLexicalScope(LS);
2006 createConcreteEntity(TheCU, *LexS, DN,
nullptr);
2008 LocalDeclsPerLS[
LS].insert(DN);
2022 if (!
MI.isBundledWithSucc())
2024 auto Suc = std::next(
MI.getIterator());
2029 assert(Suc->isBundledWithPred() &&
2030 "Call bundle instructions are out of order");
2035 if (!NoDebug && SP->areAllCallsDescribed() &&
2037 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
2039 bool IsTail =
TII->isTailCall(*
MI);
2074 auto RecordSourceLine = [
this](
auto &
DL,
auto Flags) {
2076 if (
Asm->OutStreamer->isVerboseAsm()) {
2080 recordSourceLine(
DL.getLine(),
DL.getCol(),
DL.getScope(), Flags,
2086 unsigned LastAsmLine =
2087 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2094 bool ScopeUsesKeyInstructions =
2096 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2099 if (ScopeUsesKeyInstructions &&
DL &&
DL.getLine())
2100 IsKey = KeyInstructions.contains(
MI);
2106 assert(
MI->getParent() == &*
MI->getMF()->begin());
2107 recordSourceLine(SP->getScopeLine(), 0, SP,
2112 bool PrevInstInSameSection =
2114 PrevInstBB->getSectionID() ==
MI->getParent()->getSectionID());
2115 bool ForceIsStmt = ForceIsStmtInstrs.contains(
MI);
2116 if (PrevInstInSameSection && !ForceIsStmt &&
DL.isSameSourceLocation(
PrevInstLoc)) {
2126 if ((LastAsmLine == 0 &&
DL.getLine() != 0) || Flags) {
2128 RecordSourceLine(
DL, Flags);
2141 if (LastAsmLine == 0)
2158 const MDNode *Scope =
nullptr;
2159 unsigned Column = 0;
2164 recordSourceLine(0, Column, Scope, 0);
2172 if (
DL.getLine() == 0 && LastAsmLine == 0)
2179 if (ScopeUsesKeyInstructions) {
2186 if (
DL.getLine() && (
DL.getLine() != OldLine || ForceIsStmt))
2190 RecordSourceLine(
DL, Flags);
2197static std::pair<const MachineInstr *, bool>
2207 bool IsEmptyPrologue =
2208 !(
F.hasPrologueData() ||
F.getMetadata(LLVMContext::MD_func_sanitize));
2213 -> std::optional<std::pair<const MachineInstr *, bool>> {
2215 bool isCopy = (
TII.isCopyInstr(
MI) ?
true :
false);
2216 bool isTrivRemat =
TII.isTriviallyReMaterializable(
MI);
2219 if (!isFrameSetup &&
MI.getDebugLoc()) {
2225 if (
MI.getDebugLoc().getLine())
2226 return std::make_pair(&
MI, IsEmptyPrologue);
2231 if (!
isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2232 NonTrivialInst = &
MI;
2234 IsEmptyPrologue =
false;
2235 return std::nullopt;
2243 auto CurBlock = MF->
begin();
2244 auto CurInst = CurBlock->begin();
2248 while (CurBlock->empty())
2249 CurInst = (++CurBlock)->begin();
2250 assert(CurInst != CurBlock->end());
2254 auto getNextInst = [&CurBlock, &CurInst, MF]() ->
bool {
2256 if (CurInst->isTerminator()) {
2265 if (CurBlock->pred_size() > 1)
2276 if (CurBlock == MF->
end())
2278 }
while (CurBlock->empty());
2279 CurInst = CurBlock->begin();
2285 if (!CurInst->isMetaInstruction()) {
2286 auto FoundInst = ExamineInst(*CurInst);
2293 auto NextInst = std::next(CurInst);
2294 if (NextInst != CurInst->getParent()->end()) {
2311 if (NonTrivialInst && NonTrivialInst->
getParent() == &*MF->
begin()) {
2312 IsEmptyPrologue = NonTrivialInst == &*MF->
begin()->begin();
2313 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2317 return std::make_pair(
nullptr, IsEmptyPrologue);
2323 const MDNode *S,
unsigned Flags,
unsigned CUID,
2325 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs,
2328 unsigned FileNo = 1;
2331 Fn =
Scope->getFilename();
2332 if (Line != 0 && DwarfVersion >= 4)
2337 .getOrCreateSourceID(
Scope->getFile());
2339 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2340 Discriminator, Fn, Comment);
2351 bool IsEmptyPrologue = PrologEnd.second;
2354 if (IsEmptyPrologue) {
2362 if (!
DL ||
DL->getLine() != 0)
2373 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2383 KeyInstructions.clear();
2390 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2407 for (
auto &
MBB : *MF) {
2419 for (
auto &
MI :
MBB) {
2420 if (
MI.isMetaInstruction())
2424 if (!
Loc || !
Loc->getLine())
2435 bool IsCallLike =
MI.isCall() ||
TII.isTailCall(
MI);
2440 KeyInstructions.insert(Buoy);
2446 if (!
Loc->getAtomGroup() || !
Loc->getAtomRank())
2450 auto *InlinedAt = Loc->getInlinedAt();
2453 if (!Group || !Rank)
2457 if (BuoyAtom && BuoyAtom != Group) {
2462 auto &[CandidateRank, CandidateInsts] =
2463 GroupCandidates[{InlinedAt, Group}];
2469 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2470 (CandidateRank != 0 && !CandidateInsts.empty()));
2472 assert(Rank &&
"expected nonzero rank");
2475 if (CandidateRank && CandidateRank < Rank)
2482 if (CandidateRank == Rank)
2486 else if (CandidateRank > Rank)
2487 CandidateInsts.clear();
2491 CandidateInsts.push_back(Buoy);
2492 CandidateRank = Rank;
2500 if (CandidateInsts.empty())
2506 for (
const auto &[
_, Insts] : GroupCandidates.
values())
2507 for (
auto *
I : Insts)
2508 KeyInstructions.insert(
I);
2516 ForceIsStmtInstrs.clear();
2548 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2549 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2552 for (
auto &
MBB : *
const_cast<MachineFunction *
>(MF)) {
2555 for (
auto &
MI :
MBB) {
2556 if (
MI.getDebugLoc() &&
MI.getDebugLoc()->getLine()) {
2569 for (
auto *
MBB : PredMBBsToExamine) {
2570 auto CheckMBBEdge = [&](MachineBasicBlock *Succ,
unsigned OutgoingLine) {
2571 auto MBBInstrIt = PotentialIsStmtMBBInstrs.
find(Succ);
2572 if (MBBInstrIt == PotentialIsStmtMBBInstrs.
end())
2574 MachineInstr *
MI = MBBInstrIt->second;
2575 if (
MI->getDebugLoc()->getLine() == OutgoingLine)
2577 PotentialIsStmtMBBInstrs.
erase(MBBInstrIt);
2578 ForceIsStmtInstrs.insert(
MI);
2585 CheckMBBEdge(Succ, 0);
2591 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2599 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
2606 if (!AnalyzeFailed && !
Cond.empty() && FBB !=
nullptr &&
2609 assert(MIIt->isBranch() &&
"Bad result from analyzeBranch?");
2610 CheckMBBEdge(FBB, FBBLine);
2634 unsigned LastLine = 0;
2636 if (
auto DL = MIIt->getDebugLoc();
DL &&
DL->getLine()) {
2637 LastLine =
DL->getLine();
2642 for (
auto *Succ : SuccessorBBs)
2643 CheckMBBEdge(Succ, LastLine);
2658 FunctionLineTableLabel =
CU.emitFuncLineTableOffsets()
2659 ?
Asm->OutStreamer->emitLineTableLabel()
2662 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2667 *MF,
Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2673 computeKeyInstructions(MF);
2674 findForceIsStmtInstrs(MF);
2682 if (
Asm->OutStreamer->hasRawTextSupport())
2686 return CU.getUniqueID();
2690 const auto &CURanges =
CU->getRanges();
2691 auto &LineTable =
Asm->OutStreamer->getContext().getMCDwarfLineTable(
2694 LineTable.getMCLineSections().addEndEntry(
2695 const_cast<MCSymbol *
>(CURanges.back().End));
2715 "endFunction should be called with the same function as beginFunction");
2718 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2730 collectEntityInfo(TheCU, SP, Processed);
2734 for (
const auto &R :
Asm->MBBSectionRanges)
2735 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2742 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2743 for (
const auto &R :
Asm->MBBSectionRanges)
2746 assert(InfoHolder.getScopeVariables().empty());
2753 size_t NumAbstractSubprograms =
LScopes.getAbstractScopesList().size();
2757 for (
const DINode *DN : SP->getRetainedNodes()) {
2760 auto *LexS =
LScopes.getOrCreateAbstractScope(LS);
2761 assert(LexS &&
"Expected the LexicalScope to be created.");
2764 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second ||
2770 LocalDeclsPerLS[LS].insert(DN);
2773 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2774 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2776 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2779 ProcessedSPNodes.insert(SP);
2783 if (!
LScopes.getAbstractScopesList().empty() &&
2785 SkelCU->constructSubprogramScopeDIE(SP,
F, FnScope,
2786 FunctionLineTableLabel);
2788 FunctionLineTableLabel =
nullptr;
2791 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2797 InfoHolder.getScopeVariables().clear();
2798 InfoHolder.getScopeLabels().clear();
2799 LocalDeclsPerLS.clear();
2806void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *S,
2818void DwarfDebug::emitDebugInfo() {
2824void DwarfDebug::emitAbbreviations() {
2825 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2827 Holder.
emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevSection());
2830void DwarfDebug::emitStringOffsetsTableHeader() {
2831 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
2833 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffSection(),
2837template <
typename AccelTableT>
2838void DwarfDebug::emitAccel(AccelTableT &Accel,
MCSection *Section,
2840 Asm->OutStreamer->switchSection(Section);
2846void DwarfDebug::emitAccelDebugNames() {
2848 if (getUnits().
empty())
2855void DwarfDebug::emitAccelNames() {
2856 emitAccel(AccelNames,
Asm->getObjFileLowering().getDwarfAccelNamesSection(),
2862void DwarfDebug::emitAccelObjC() {
2863 emitAccel(AccelObjC,
Asm->getObjFileLowering().getDwarfAccelObjCSection(),
2868void DwarfDebug::emitAccelNamespaces() {
2869 emitAccel(AccelNamespace,
2870 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
2875void DwarfDebug::emitAccelTypes() {
2876 emitAccel(AccelTypes,
Asm->getObjFileLowering().getDwarfAccelTypesSection(),
2906 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2914 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2921 case dwarf::DW_TAG_class_type:
2922 case dwarf::DW_TAG_structure_type:
2923 case dwarf::DW_TAG_union_type:
2924 case dwarf::DW_TAG_enumeration_type:
2930 case dwarf::DW_TAG_typedef:
2931 case dwarf::DW_TAG_base_type:
2932 case dwarf::DW_TAG_subrange_type:
2933 case dwarf::DW_TAG_template_alias:
2935 case dwarf::DW_TAG_namespace:
2937 case dwarf::DW_TAG_subprogram:
2939 case dwarf::DW_TAG_variable:
2941 case dwarf::DW_TAG_enumerator:
2951void DwarfDebug::emitDebugPubSections() {
2952 for (
const auto &NU : CUMap) {
2953 DwarfCompileUnit *TheU = NU.second;
2960 Asm->OutStreamer->switchSection(
2961 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
2962 :
Asm->getObjFileLowering().getDwarfPubNamesSection());
2963 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
2965 Asm->OutStreamer->switchSection(
2966 GnuStyle ?
Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
2967 :
Asm->getObjFileLowering().getDwarfPubTypesSection());
2968 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
2974 Asm->emitDwarfOffset(
CU.getSection()->getBeginSymbol(),
2975 CU.getDebugSectionOffset());
2977 Asm->emitDwarfSymbolReference(
CU.getLabelBegin());
2980void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
2988 "pub" + Name,
"Length of Public " + Name +
" Info");
2990 Asm->OutStreamer->AddComment(
"DWARF Version");
2993 Asm->OutStreamer->AddComment(
"Offset of Compilation Unit Info");
2994 emitSectionReference(*TheU);
2996 Asm->OutStreamer->AddComment(
"Compilation Unit Length");
3001 for (
const auto &GI : Globals)
3004 return A.second->getOffset() <
B.second->getOffset();
3006 for (
const auto &[Name, Entity] : Vec) {
3007 Asm->OutStreamer->AddComment(
"DIE offset");
3008 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3012 Asm->OutStreamer->AddComment(
3018 Asm->OutStreamer->AddComment(
"External Name");
3019 Asm->OutStreamer->emitBytes(StringRef(
Name.data(),
Name.size() + 1));
3022 Asm->OutStreamer->AddComment(
"End Mark");
3023 Asm->emitDwarfLengthOrOffset(0);
3024 Asm->OutStreamer->emitLabel(EndLabel);
3028void DwarfDebug::emitDebugStr() {
3029 MCSection *StringOffsetsSection =
nullptr;
3031 emitStringOffsetsTableHeader();
3032 StringOffsetsSection =
Asm->getObjFileLowering().getDwarfStrOffSection();
3034 DwarfFile &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3035 Holder.
emitStrings(
Asm->getObjFileLowering().getDwarfStrSection(),
3036 StringOffsetsSection,
true);
3042 auto &&Comments = DebugLocs.getComments(Entry);
3043 auto Comment = Comments.begin();
3044 auto End = Comments.end();
3051 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3053 DebugLocs.getBytes(Entry).size()),
3054 Asm->getDataLayout().isLittleEndian(), PtrSize);
3059 for (
const auto &
Op : Expr) {
3060 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
3061 "3 operand ops not yet supported");
3062 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
3063 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
3065 for (
unsigned I = 0;
I <
Op.getDescription().
Op.size(); ++
I) {
3066 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
3068 Streamer.
emitDIERef(*
CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die);
3070 for (
unsigned J = 0; J <
Length; ++J)
3075 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
3086 auto *DIExpr =
Value.getExpression();
3092 if (DIExpr && DIExpr->isEntryValue()) {
3109 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
3112 if (Entry.isInt()) {
3113 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_boolean))
3115 else if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
3116 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3120 }
else if (Entry.isLocation()) {
3122 if (Location.isIndirect())
3128 }
else if (Entry.isTargetIndexLocation()) {
3134 }
else if (Entry.isConstantFP()) {
3137 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3138 }
else if (Entry.getConstantFP()
3141 .getBitWidth() <= 64 ) {
3143 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3146 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
3147 << Entry.getConstantFP()
3158 if (!
Value.isVariadic()) {
3159 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
3168 return Entry.isLocation() && !Entry.getLoc().getReg();
3173 std::move(ExprCursor),
3174 [EmitValueLocEntry, &
Value](
unsigned Idx,
3176 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
3184 assert(!Values.empty() &&
3185 "location list entries without values are redundant");
3186 assert(Begin != End &&
"unexpected location list entry with empty range");
3191 if (
Value.isFragment()) {
3194 return P.isFragment();
3195 }) &&
"all values are expected to be fragments");
3198 for (
const auto &Fragment : Values)
3202 assert(Values.size() == 1 &&
"only fragments may have >1 value");
3213 Asm->OutStreamer->AddComment(
"Loc expr size");
3215 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3216 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3217 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3236 Asm->OutStreamer->AddComment(
"Offset entry count");
3242 Asm->getDwarfOffsetByteSize());
3256 Asm->OutStreamer->AddComment(
"Offset entry count");
3257 Asm->emitInt32(DebugLocs.getLists().size());
3258 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3260 for (
const auto &List : DebugLocs.getLists())
3261 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3262 Asm->getDwarfOffsetByteSize());
3267template <
typename Ranges,
typename PayloadEmitter>
3271 unsigned StartxLength,
unsigned EndOfList,
3273 bool ShouldUseBaseAddress,
3274 PayloadEmitter EmitPayload) {
3276 auto Size = Asm->MAI->getCodePointerSize();
3280 Asm->OutStreamer->emitLabel(Sym);
3287 for (
const auto &
Range : R)
3288 SectionRanges[&
Range.Begin->getSection()].push_back(&
Range);
3290 const MCSymbol *CUBase =
CU.getBaseAddress();
3291 bool BaseIsSet =
false;
3292 for (
const auto &
P : SectionRanges) {
3293 auto *
Base = CUBase;
3294 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.
tuneForGDB())) {
3304 }
else if (!
Base && ShouldUseBaseAddress) {
3305 const MCSymbol *Begin =
P.second.front()->Begin;
3310 Asm->OutStreamer->emitIntValue(-1,
Size);
3311 Asm->OutStreamer->AddComment(
" base address");
3312 Asm->OutStreamer->emitSymbolValue(
Base,
Size);
3313 }
else if (NewBase != Begin ||
P.second.size() > 1) {
3319 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3320 Asm->emitInt8(BaseAddressx);
3321 Asm->OutStreamer->AddComment(
" base address index");
3324 }
else if (BaseIsSet && !UseDwarf5) {
3327 Asm->OutStreamer->emitIntValue(-1,
Size);
3328 Asm->OutStreamer->emitIntValue(0,
Size);
3331 for (
const auto *RS :
P.second) {
3334 assert(Begin &&
"Range without a begin symbol?");
3335 assert(End &&
"Range without an end symbol?");
3339 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3340 Asm->emitInt8(OffsetPair);
3341 Asm->OutStreamer->AddComment(
" starting offset");
3342 Asm->emitLabelDifferenceAsULEB128(Begin,
Base);
3343 Asm->OutStreamer->AddComment(
" ending offset");
3344 Asm->emitLabelDifferenceAsULEB128(End,
Base);
3346 Asm->emitLabelDifference(Begin,
Base,
Size);
3347 Asm->emitLabelDifference(End,
Base,
Size);
3349 }
else if (UseDwarf5) {
3350 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3351 Asm->emitInt8(StartxLength);
3352 Asm->OutStreamer->AddComment(
" start index");
3354 Asm->OutStreamer->AddComment(
" length");
3355 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3357 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
3358 Asm->OutStreamer->emitSymbolValue(End,
Size);
3365 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
3369 Asm->OutStreamer->emitIntValue(0,
Size);
3370 Asm->OutStreamer->emitIntValue(0,
Size);
3377 *List.CU, dwarf::DW_LLE_base_addressx,
3378 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
3382 DD.emitDebugLocEntryLocation(E, List.CU);
3386void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
3387 if (DebugLocs.getLists().empty())
3390 Asm->OutStreamer->switchSection(Sec);
3396 for (
const auto &
List : DebugLocs.getLists())
3400 Asm->OutStreamer->emitLabel(TableEnd);
3404void DwarfDebug::emitDebugLoc() {
3407 ?
Asm->getObjFileLowering().getDwarfLoclistsSection()
3408 :
Asm->getObjFileLowering().getDwarfLocSection());
3412void DwarfDebug::emitDebugLocDWO() {
3415 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3420 for (
const auto &
List : DebugLocs.getLists()) {
3421 Asm->OutStreamer->switchSection(
3422 Asm->getObjFileLowering().getDwarfLocDWOSection());
3423 Asm->OutStreamer->emitLabel(
List.Label);
3425 for (
const auto &Entry : DebugLocs.getEntries(
List)) {
3434 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3435 unsigned idx = AddrPool.getIndex(
Entry.Begin);
3436 Asm->emitULEB128(idx);
3442 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3452void DwarfDebug::emitDebugARanges() {
3453 if (ArangeLabels.empty())
3460 for (
const SymbolCU &SCU : ArangeLabels) {
3461 if (SCU.Sym->isInSection()) {
3463 MCSection *Section = &SCU.Sym->getSection();
3464 SectionMap[Section].push_back(SCU);
3469 SectionMap[
nullptr].push_back(SCU);
3473 DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans;
3475 for (
auto &
I : SectionMap) {
3483 for (
const SymbolCU &Cur :
List) {
3485 Span.
Start = Cur.Sym;
3488 Spans[Cur.CU].push_back(Span);
3494 List.push_back(SymbolCU(
nullptr,
Asm->OutStreamer->endSection(Section)));
3498 for (
size_t n = 1, e =
List.size(); n < e; n++) {
3499 const SymbolCU &Prev =
List[n - 1];
3500 const SymbolCU &Cur =
List[n];
3503 if (Cur.
CU != Prev.
CU) {
3505 Span.
Start = StartSym;
3508 Spans[Prev.
CU].push_back(Span);
3515 Asm->OutStreamer->switchSection(
3516 Asm->getObjFileLowering().getDwarfARangesSection());
3518 unsigned PtrSize =
Asm->MAI->getCodePointerSize();
3521 std::vector<DwarfCompileUnit *> CUs;
3522 for (
const auto &it : Spans) {
3523 DwarfCompileUnit *
CU = it.first;
3528 llvm::sort(CUs, [](
const DwarfCompileUnit *
A,
const DwarfCompileUnit *
B) {
3529 return A->getUniqueID() <
B->getUniqueID();
3533 for (DwarfCompileUnit *
CU : CUs) {
3534 std::vector<ArangeSpan> &
List = Spans[
CU];
3537 if (
auto *Skel =
CU->getSkeleton())
3541 unsigned ContentSize =
3543 Asm->getDwarfOffsetByteSize() +
3548 unsigned TupleSize = PtrSize * 2;
3552 Asm->getUnitLengthFieldByteSize() + ContentSize,
Align(TupleSize));
3555 ContentSize += (
List.size() + 1) * TupleSize;
3558 Asm->emitDwarfUnitLength(ContentSize,
"Length of ARange Set");
3559 Asm->OutStreamer->AddComment(
"DWARF Arange version number");
3561 Asm->OutStreamer->AddComment(
"Offset Into Debug Info Section");
3562 emitSectionReference(*
CU);
3563 Asm->OutStreamer->AddComment(
"Address Size (in bytes)");
3564 Asm->emitInt8(PtrSize);
3565 Asm->OutStreamer->AddComment(
"Segment Size (in bytes)");
3568 Asm->OutStreamer->emitFill(Padding, 0xff);
3570 for (
const ArangeSpan &Span :
List) {
3571 Asm->emitLabelReference(Span.Start, PtrSize);
3578 auto SizeRef = SymSize.find(Span.Start);
3579 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3580 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3585 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3588 Size = SizeRef->second;
3590 Asm->OutStreamer->emitIntValue(
Size, PtrSize);
3594 Asm->OutStreamer->AddComment(
"ARange terminator");
3595 Asm->OutStreamer->emitIntValue(0, PtrSize);
3596 Asm->OutStreamer->emitIntValue(0, PtrSize);
3604 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3605 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3607 List.CU->getCUNode()->getRangesBaseAddress() ||
3619 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3622 Asm->OutStreamer->switchSection(Section);
3632 Asm->OutStreamer->emitLabel(TableEnd);
3637void DwarfDebug::emitDebugRanges() {
3638 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3640 emitDebugRangesImpl(Holder,
3642 ?
Asm->getObjFileLowering().getDwarfRnglistsSection()
3643 :
Asm->getObjFileLowering().getDwarfRangesSection());
3646void DwarfDebug::emitDebugRangesDWO() {
3647 emitDebugRangesImpl(InfoHolder,
3648 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3655 enum HeaderFlagMask {
3656#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3657#include "llvm/BinaryFormat/Dwarf.def"
3659 Asm->OutStreamer->AddComment(
"Macro information version");
3660 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3663 if (Asm->isDwarf64()) {
3664 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3665 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3667 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3668 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3670 Asm->OutStreamer->AddComment(
"debug_line_offset");
3672 Asm->emitDwarfLengthOrOffset(0);
3674 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3677void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3678 for (
auto *MN : Nodes) {
3682 emitMacroFile(*
F, U);
3688void DwarfDebug::emitMacro(
DIMacro &M) {
3689 StringRef
Name =
M.getName();
3690 StringRef
Value =
M.getValue();
3696 if (UseDebugMacroSection) {
3699 ? dwarf::DW_MACRO_define_strx
3700 : dwarf::DW_MACRO_undef_strx;
3703 Asm->OutStreamer->AddComment(
"Line Number");
3704 Asm->emitULEB128(
M.getLine());
3705 Asm->OutStreamer->AddComment(
"Macro String");
3707 InfoHolder.getStringPool().getIndexedEntry(*
Asm, Str).getIndex());
3710 ? dwarf::DW_MACRO_GNU_define_indirect
3711 : dwarf::DW_MACRO_GNU_undef_indirect;
3714 Asm->OutStreamer->AddComment(
"Line Number");
3715 Asm->emitULEB128(
M.getLine());
3716 Asm->OutStreamer->AddComment(
"Macro String");
3717 Asm->emitDwarfSymbolReference(
3718 InfoHolder.getStringPool().getEntry(*
Asm, Str).getSymbol());
3722 Asm->emitULEB128(
M.getMacinfoType());
3723 Asm->OutStreamer->AddComment(
"Line Number");
3724 Asm->emitULEB128(
M.getLine());
3725 Asm->OutStreamer->AddComment(
"Macro String");
3726 Asm->OutStreamer->emitBytes(Str);
3727 Asm->emitInt8(
'\0');
3731void DwarfDebug::emitMacroFileImpl(
3733 StringRef (*MacroFormToString)(
unsigned Form)) {
3735 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3736 Asm->emitULEB128(StartFile);
3737 Asm->OutStreamer->AddComment(
"Line Number");
3739 Asm->OutStreamer->AddComment(
"File Number");
3742 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3744 Asm->OutContext.getDwarfVersion(),
F.getSource()));
3746 Asm->emitULEB128(
U.getOrCreateSourceID(&
F));
3748 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3749 Asm->emitULEB128(EndFile);
3756 if (UseDebugMacroSection)
3758 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3765void DwarfDebug::emitDebugMacinfoImpl(
MCSection *Section) {
3766 for (
const auto &
P : CUMap) {
3767 auto &TheCU = *
P.second;
3769 DwarfCompileUnit &
U = SkCU ? *SkCU : TheCU;
3771 DIMacroNodeArray Macros = CUNode->getMacros();
3774 Asm->OutStreamer->switchSection(Section);
3775 Asm->OutStreamer->emitLabel(
U.getMacroLabelBegin());
3776 if (UseDebugMacroSection)
3778 handleMacroNodes(Macros, U);
3779 Asm->OutStreamer->AddComment(
"End Of Macro List Mark");
3785void DwarfDebug::emitDebugMacinfo() {
3786 auto &ObjLower =
Asm->getObjFileLowering();
3787 emitDebugMacinfoImpl(UseDebugMacroSection
3788 ? ObjLower.getDwarfMacroSection()
3789 : ObjLower.getDwarfMacinfoSection());
3792void DwarfDebug::emitDebugMacinfoDWO() {
3793 auto &ObjLower =
Asm->getObjFileLowering();
3794 emitDebugMacinfoImpl(UseDebugMacroSection
3795 ? ObjLower.getDwarfMacroDWOSection()
3796 : ObjLower.getDwarfMacinfoDWOSection());
3801void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3802 std::unique_ptr<DwarfCompileUnit> NewU) {
3804 if (!CompilationDir.empty())
3805 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3806 addGnuPubAttributes(*NewU, Die);
3808 SkeletonHolder.addUnit(std::move(NewU));
3813 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3814 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3816 DwarfCompileUnit &NewCU = *OwnedUnit;
3817 NewCU.
setSection(
Asm->getObjFileLowering().getDwarfInfoSection());
3824 initSkeletonUnit(
CU, NewCU.
getUnitDie(), std::move(OwnedUnit));
3831void DwarfDebug::emitDebugInfoDWO() {
3834 InfoHolder.emitUnits(
true);
3839void DwarfDebug::emitDebugAbbrevDWO() {
3841 InfoHolder.emitAbbrevs(
Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3844void DwarfDebug::emitDebugLineDWO() {
3846 SplitTypeUnitFileTable.Emit(
3847 *
Asm->OutStreamer, MCDwarfLineTableParams(),
3848 Asm->getObjFileLowering().getDwarfLineDWOSection());
3851void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3853 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
3854 *
Asm,
Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
3855 InfoHolder.getStringOffsetsStartSym());
3861void DwarfDebug::emitDebugStrDWO() {
3863 emitStringOffsetsTableHeaderDWO();
3865 MCSection *OffSec =
Asm->getObjFileLowering().getDwarfStrOffDWOSection();
3866 InfoHolder.emitStrings(
Asm->getObjFileLowering().getDwarfStrDWOSection(),
3871void DwarfDebug::emitDebugAddr() {
3872 AddrPool.emit(*
Asm,
Asm->getObjFileLowering().getDwarfAddrSection());
3878 const DICompileUnit *DIUnit =
CU.getCUNode();
3879 SplitTypeUnitFileTable.maybeSetRootFile(
3882 return &SplitTypeUnitFileTable;
3893 return Result.high();
3902 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
3905 auto Ins = TypeSignatures.try_emplace(CTy);
3907 CU.addDIETypeSignature(RefDie, Ins.first->second);
3912 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3913 AddrPool.resetUsedFlag();
3915 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
3916 CU,
Asm,
this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(
CU));
3919 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3921 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3926 Ins.first->second = Signature;
3934 if (!CompilationDir.empty())
3935 NewTU.
addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
3936 NewTU.
addString(UnitDie, dwarf::DW_AT_dwo_name,
3937 Asm->TM.Options.MCOptions.SplitDwarfFile);
3941 ?
Asm->getObjFileLowering().getDwarfTypesDWOSection()
3942 :
Asm->getObjFileLowering().getDwarfInfoDWOSection();
3947 ?
Asm->getObjFileLowering().getDwarfTypesSection(Signature)
3948 :
Asm->getObjFileLowering().getDwarfInfoSection(Signature);
3951 CU.applyStmtList(UnitDie);
3962 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
3963 TypeUnitsUnderConstruction.clear();
3967 if (AddrPool.hasBeenUsed()) {
3968 AccelTypeUnitsDebugNames.clear();
3972 for (
const auto &
TU : TypeUnitsToAdd)
3973 TypeSignatures.erase(
TU.second);
3981 CU.updateAcceleratorTables(CTy->
getScope(), CTy, RefDie);
3987 for (
auto &
TU : TypeUnitsToAdd) {
3988 InfoHolder.computeSizeAndOffsetsForUnit(
TU.first.get());
3993 AccelDebugNames.addTypeUnitSignature(*
TU.first);
3995 AccelDebugNames.addTypeUnitSymbol(*
TU.first);
3998 AccelTypeUnitsDebugNames.convertDieToOffset();
3999 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4000 AccelTypeUnitsDebugNames.clear();
4003 CU.addDIETypeSignature(RefDie, Signature);
4010template <
typename DataT>
4011void DwarfDebug::addAccelNameImpl(
4016 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4033 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4034 ((&Current == &AccelDebugNames) &&
4035 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4036 "Kind is CU but TU is being processed.");
4037 assert(((&Current == &AccelDebugNames) ||
4038 ((&Current == &AccelTypeUnitsDebugNames) &&
4039 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4040 "Kind is TU but CU is being processed.");
4043 Current.
addName(
Ref, Die, Unit.getUniqueID(),
4044 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4058 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4067 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4074 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4080 const DIE &Die,
char Flags) {
4081 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4085 return Asm->OutStreamer->getContext().getDwarfVersion();
4089 if (
Asm->getDwarfVersion() >= 4)
4090 return dwarf::Form::DW_FORM_sec_offset;
4091 assert((!
Asm->isDwarf64() || (
Asm->getDwarfVersion() == 3)) &&
4092 "DWARF64 is not defined prior DWARFv3");
4093 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4094 : dwarf::Form::DW_FORM_data4;
4098 return SectionLabels.lookup(S);
4102 if (SectionLabels.insert(std::make_pair(&S->
getSection(), S)).second)
4107std::optional<MD5::MD5Result>
4111 return std::nullopt;
4112 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
4114 return std::nullopt;
4119 std::string ChecksumString =
fromHex(Checksum->Value);
4136 if (
MBB.getAlignment() ==
Align(1))
4139 auto *SP =
MBB.getParent()->getFunction().getSubprogram();
4146 auto PrevLoc =
Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4147 if (PrevLoc.getLine()) {
4148 Asm->OutStreamer->emitDwarfLocDirective(
4149 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0,
StringRef());
4151 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
unsigned 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
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.
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.