Go to the documentation of this file.
66 #define DEBUG_TYPE "dwarfdebug"
68 STATISTIC(NumCSParams,
"Number of dbg call site params created");
71 "use-dwarf-ranges-base-address-specifier",
cl::Hidden,
81 cl::desc(
"Generate DWARF4 type units."),
92 cl::desc(
"Make an absence of debug location information explicit."),
100 "Default for platform"),
108 cl::desc(
"Use inlined strings rather than string section."),
116 cl::desc(
"Disable emission .debug_ranges section."),
121 cl::desc(
"Use sections+offset as references rather than labels."),
128 cl::desc(
"Emit the GNU .debug_macro format with DWARF <5"),
133 cl::desc(
"Enable use of the DWARFv5 DW_OP_convert operator"),
146 cl::desc(
"Which DWARF linkage-name attributes to emit."),
148 "Default for platform"),
151 "Abstract subprograms")),
156 cl::desc(
"Always use DW_AT_ranges in DWARFv5 whenever it could allow more "
157 "address pool entry sharing to reduce relocations/object size"),
159 "Default address minimization strategy"),
161 "Use rnglists for contiguous ranges if that allows "
162 "using a pre-existing base address"),
165 "Use exprloc addrx+offset expressions for any "
166 "address with a prior base address"),
168 "Use addrx+offset extension form for any address "
169 "with a prior base address"),
176 void DebugLocDwarfExpression::emitOp(uint8_t
Op,
const char *Comment) {
182 void DebugLocDwarfExpression::emitSigned(int64_t
Value) {
186 void DebugLocDwarfExpression::emitUnsigned(uint64_t
Value) {
190 void DebugLocDwarfExpression::emitData1(uint8_t
Value) {
194 void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
205 void DebugLocDwarfExpression::enableTemporaryBuffer() {
206 assert(!IsBuffering &&
"Already buffering?");
212 void DebugLocDwarfExpression::disableTemporaryBuffer() { IsBuffering =
false; }
214 unsigned DebugLocDwarfExpression::getTemporaryBufferSize() {
215 return TmpBuf ? TmpBuf->Bytes.size() : 0;
218 void DebugLocDwarfExpression::commitTemporaryBuffer() {
221 for (
auto Byte :
enumerate(TmpBuf->Bytes)) {
222 const char *Comment = (
Byte.index() < TmpBuf->Comments.size())
223 ? TmpBuf->Comments[
Byte.index()].c_str()
227 TmpBuf->Bytes.clear();
228 TmpBuf->Comments.clear();
238 const bool IsVariadic =
MI->isDebugValueList();
244 MI->isNonListDebugValue() &&
MI->isDebugOffsetImm());
246 }
else if (
Op.isTargetIndex()) {
247 DbgValueLocEntries.push_back(
249 }
else if (
Op.isImm())
251 else if (
Op.isFPImm())
253 else if (
Op.isCImm())
258 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
262 assert(FrameIndexExprs.empty() &&
"Already initialized?");
263 assert(!ValueLoc.get() &&
"Already initialized?");
271 if (
E->getNumElements())
272 FrameIndexExprs.push_back({0,
E});
276 if (FrameIndexExprs.size() == 1)
277 return FrameIndexExprs;
280 [](
const FrameIndexExpr &A) {
281 return A.Expr->isFragment();
283 "multiple FI expressions without DW_OP_LLVM_fragment");
285 [](
const FrameIndexExpr &A,
const FrameIndexExpr &
B) ->
bool {
286 return A.Expr->getFragmentInfo()->OffsetInBits <
287 B.Expr->getFragmentInfo()->OffsetInBits;
290 return FrameIndexExprs;
294 assert(DebugLocListIndex == ~0U && !ValueLoc.get() &&
"not an MMI entry");
295 assert(V.DebugLocListIndex == ~0U && !V.ValueLoc.get() &&
"not an MMI entry");
299 assert(!FrameIndexExprs.empty() &&
"Expected an MMI entry");
300 assert(!V.FrameIndexExprs.empty() &&
"Expected an MMI entry");
306 if (FrameIndexExprs.size()) {
307 auto *Expr = FrameIndexExprs.back().Expr;
308 if (!Expr || !Expr->isFragment())
312 for (
const auto &FIE : V.FrameIndexExprs)
315 return FIE.FI ==
Other.FI && FIE.Expr ==
Other.Expr;
317 FrameIndexExprs.push_back(FIE);
319 assert((FrameIndexExprs.size() == 1 ||
321 [](FrameIndexExpr &FIE) {
322 return FIE.Expr && FIE.Expr->isFragment();
324 "conflicting locations for variable");
328 bool GenerateTypeUnits,
336 if (GenerateTypeUnits)
342 if (DwarfVersion >= 5)
352 InfoHolder(A,
"info_string", DIEValueAllocator),
353 SkeletonHolder(A,
"skel_string", DIEValueAllocator),
354 IsDarwin(A->
TM.getTargetTriple().isOSDarwin()) {
363 else if (TT.isPS4CPU())
369 UseInlineStrings = TT.isNVPTX() ||
tuneForDBX();
373 UseLocSection = !TT.isNVPTX();
387 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
393 bool Dwarf64 = DwarfVersion >= 3 &&
403 TT.isOSBinFormatELF()) ||
404 TT.isOSBinFormatXCOFF();
406 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
413 UseSectionsAsReferences = TT.isNVPTX();
418 GenerateTypeUnits = (A->TM.getTargetTriple().isOSBinFormatELF() ||
419 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
423 DwarfVersion, GenerateTypeUnits, DebuggerTuning, A->TM.getTargetTriple());
430 UseGNUTLSOpcode =
tuneForGDB() || DwarfVersion < 3;
433 UseDWARF2Bitfields = (DwarfVersion < 4) ||
tuneForGDB();
439 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
447 UseDebugMacroSection =
456 if (DwarfVersion >= 5) {
474 return Name.startswith(
"+") ||
Name.startswith(
"-");
487 Class =
In.slice(
In.find(
'[') + 1,
In.find(
' '));
492 Class =
In.slice(
In.find(
'[') + 1,
In.find(
'('));
493 Category =
In.slice(
In.find(
'[') + 1,
In.find(
' '));
497 return In.slice(
In.find(
' ') + 1,
In.find(
']'));
507 if (!SP->isDefinition())
516 if (SP->getLinkageName() !=
"" && SP->
getName() != SP->getLinkageName() &&
536 if (
Scope->isAbstractScope())
544 if (Ranges.size() > 1)
554 if (
auto *SkelCU =
CU.getSkeleton())
555 if (
CU.getCUNode()->getSplitDebugInlining())
563 void DwarfDebug::constructAbstractSubprogramScopeDIE(
DwarfCompileUnit &SrcCU,
569 auto *SP = cast<DISubprogram>(
Scope->getScopeNode());
577 auto &
CU = getOrCreateDwarfCompileUnit(SP->getUnit());
578 if (
auto *SkelCU =
CU.getSkeleton()) {
580 .constructAbstractSubprogramScopeDIE(
Scope);
581 if (
CU.getCUNode()->getSplitDebugInlining())
582 SkelCU->constructAbstractSubprogramScopeDIE(
Scope);
584 CU.constructAbstractSubprogramScopeDIE(
Scope);
588 DIE &DwarfDebug::constructSubprogramDefinitionDIE(
const DISubprogram *SP) {
590 assert(SP->isDefinition() &&
"Subprogram not a definition");
591 assert(Unit &&
"Subprogram definition without parent unit");
592 auto &
CU = getOrCreateDwarfCompileUnit(Unit);
593 return *
CU.getOrCreateSubprogramDIE(SP);
624 template <
typename ValT>
628 for (
auto Param : DescribedParams) {
629 bool ShouldCombineExpressions = Expr &&
Param.Expr->getNumElements() > 0;
644 "Combined debug expression is invalid");
648 Params.push_back(CSParm);
660 auto &ParamsForFwdReg =
I.first->second;
661 for (
auto Param : ParamsToAdd) {
664 return D.ParamReg ==
Param.ParamReg;
666 "Same parameter described twice by forwarding reg");
673 ParamsForFwdReg.push_back({
Param.ParamReg, CombinedExpr});
714 if (
MI.isDebugInstr())
718 if (MO.isReg() && MO.isDef() &&
720 for (
auto &FwdReg : ForwardedRegWorklist)
722 Defs.
insert(FwdReg.first);
730 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
731 if (FwdRegDefs.
empty())
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);
748 ForwardedRegWorklist[ParamFwdReg], Params);
757 ForwardedRegWorklist[ParamFwdReg]);
764 for (
auto ParamFwdReg : FwdRegDefs)
765 ForwardedRegWorklist.
erase(ParamFwdReg);
769 for (
auto &New : TmpWorklistItems)
771 TmpWorklistItems.clear();
787 if (ForwardedRegWorklist.
empty())
805 auto CallFwdRegsInfo = CalleesMap.
find(CallMI);
808 if (CallFwdRegsInfo == CalleesMap.end())
822 for (
const auto &ArgReg : CallFwdRegsInfo->second) {
824 ForwardedRegWorklist.
insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
826 assert(InsertedReg &&
"Single register used to forward two arguments?");
831 for (
auto &MO : CallMI->
uses())
832 if (MO.isReg() && MO.isUndef())
833 ForwardedRegWorklist.
erase(MO.getReg());
851 assert(std::next(Suc) == BundleEnd &&
852 "More than one instruction in call delay slot");
866 if (ShouldTryEmitEntryVals) {
870 for (
auto &RegEntry : ForwardedRegWorklist) {
877 void DwarfDebug::constructCallSiteEntryDIEs(
const DISubprogram &SP,
882 if (!SP.areAllCallsDescribed() || !SP.isDefinition())
889 CU.addFlag(ScopeDIE,
CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
892 assert(
TII &&
"TargetInstrInfo not found: cannot label tail calls");
896 if (!
MI.isBundledWithSucc())
898 auto Suc = std::next(
MI.getIterator());
900 (void)CallInstrBundle;
902 (void)DelaySlotBundle;
909 "Call and its successor instruction don't have same label after.");
924 if (!
MI.isCandidateForCallSiteEntry())
933 if (
MI.hasDelaySlot() && !delaySlotSupported(*&
MI))
943 unsigned CallReg = 0;
944 DIE *CalleeDIE =
nullptr;
945 const Function *CalleeDecl =
nullptr;
946 if (CalleeOp.
isReg()) {
947 CallReg = CalleeOp.
getReg();
951 CalleeDecl = dyn_cast<Function>(CalleeOp.
getGlobal());
956 if (CalleeSP->isDefinition()) {
959 CalleeDIE = &constructSubprogramDefinitionDIE(CalleeSP);
964 CalleeDIE =
CU.getOrCreateSubprogramDIE(CalleeSP);
966 assert(CalleeDIE &&
"Must have a DIE for the callee");
984 (!IsTail ||
CU.useGNUAnalogForDwarf5Feature())
993 assert((IsTail || PCAddr) &&
"Non-tail call without return PC");
996 << (CalleeDecl ? CalleeDecl->
getName()
1000 << (IsTail ?
" [IsTail]" :
"") <<
"\n");
1002 DIE &CallSiteDIE =
CU.constructCallSiteEntryDIE(
1003 ScopeDIE, CalleeDIE, IsTail, PCAddr, CallAddr, CallReg);
1010 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1020 U.
addFlag(
D, dwarf::DW_AT_GNU_pubnames);
1023 void DwarfDebug::finishUnitAttributes(
const DICompileUnit *DIUnit,
1031 std::string ProducerWithFlags = Producer.
str() +
" " + Flags.
str();
1032 NewCU.
addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1034 NewCU.
addString(Die, dwarf::DW_AT_producer, Producer);
1036 NewCU.
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1038 NewCU.
addString(Die, dwarf::DW_AT_name, FN);
1040 if (!SysRoot.
empty())
1041 NewCU.
addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1044 NewCU.
addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1055 if (!CompilationDir.
empty())
1056 NewCU.
addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1057 addGnuPubAttributes(NewCU, Die);
1062 NewCU.
addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1066 NewCU.
addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1069 NewCU.
addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1070 dwarf::DW_FORM_data1, RVer);
1075 NewCU.
addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1080 ? dwarf::DW_AT_dwo_name
1081 : dwarf::DW_AT_GNU_dwo_name;
1089 DwarfDebug::getOrCreateDwarfCompileUnit(
const DICompileUnit *DIUnit) {
1090 if (
auto *
CU = CUMap.lookup(DIUnit))
1095 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
1096 InfoHolder.
getUnits().size(), DIUnit,
Asm,
this, &InfoHolder);
1116 finishUnitAttributes(DIUnit, NewCU);
1120 CUMap.insert({DIUnit, &NewCU});
1121 CUDieMap.insert({&NewCU.
getUnitDie(), &NewCU});
1127 if (isa<DILocalScope>(
N->getScope()))
1143 if (!A.Expr || !
B.Expr)
1145 auto FragmentA = A.Expr->getFragmentInfo();
1146 auto FragmentB =
B.Expr->getFragmentInfo();
1147 if (!FragmentA || !FragmentB)
1149 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1151 GVEs.
erase(std::unique(GVEs.begin(), GVEs.end(),
1154 return A.Expr == B.Expr;
1169 unsigned NumDebugCUs = std::distance(
M->debug_compile_units_begin(),
1170 M->debug_compile_units_end());
1171 assert(NumDebugCUs > 0 &&
"Asm unexpectedly initialized");
1173 "DebugInfoAvailabilty unexpectedly not initialized");
1174 SingleCU = NumDebugCUs == 1;
1179 Global.getDebugInfo(GVs);
1180 for (
auto *GVE : GVs)
1181 GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()});
1215 return !isa<DILocalScope>(IE->getScope());
1218 if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() &&
1219 CUNode->getRetainedTypes().empty() &&
1220 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1226 for (
auto *GVE : CUNode->getGlobalVariables()) {
1230 auto &GVMapEntry = GVMap[GVE->getVariable()];
1231 auto *Expr = GVE->getExpression();
1232 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1233 GVMapEntry.push_back({
nullptr, Expr});
1236 for (
auto *GVE : CUNode->getGlobalVariables()) {
1238 if (Processed.
insert(GV).second)
1242 for (
auto *Ty : CUNode->getEnumTypes()) {
1245 CU.getOrCreateTypeDIE(cast<DIType>(Ty));
1247 for (
auto *Ty : CUNode->getRetainedTypes()) {
1250 if (
DIType *RT = dyn_cast<DIType>(Ty))
1252 CU.getOrCreateTypeDIE(RT);
1256 for (
auto *
IE : CUNode->getImportedEntities())
1257 constructAndAddImportedEntityDIE(
CU,
IE);
1261 void DwarfDebug::finishEntityDefinitions() {
1262 for (
const auto &Entity : ConcreteEntities) {
1263 DIE *Die = Entity->getDIE();
1274 void DwarfDebug::finishSubprogramDefinitions() {
1278 getOrCreateDwarfCompileUnit(SP->getUnit()),
1283 void DwarfDebug::finalizeModuleInfo() {
1286 finishSubprogramDefinitions();
1288 finishEntityDefinitions();
1294 if (CUMap.size() > 1)
1299 for (
const auto &
P : CUMap) {
1300 auto &TheCU = *
P.second;
1316 ? dwarf::DW_AT_dwo_name
1317 : dwarf::DW_AT_GNU_dwo_name;
1318 finishUnitAttributes(TheCU.
getCUNode(), TheCU);
1321 SkCU->addString(SkCU->getUnitDie(), attrDWOName,
1331 dwarf::DW_FORM_data8,
ID);
1332 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1333 dwarf::DW_FORM_data8,
ID);
1338 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1342 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1353 if (
unsigned NumRanges = TheCU.
getRanges().size()) {
1374 if (!DebugLocs.
getLists().empty()) {
1382 auto *CUNode = cast<DICompileUnit>(
P.first);
1385 if (CUNode->getMacros()) {
1386 if (UseDebugMacroSection) {
1393 ? dwarf::DW_AT_macros
1394 : dwarf::DW_AT_GNU_macros;
1414 if (CUNode->getDWOId())
1415 getOrCreateDwarfCompileUnit(CUNode);
1425 assert(CurFn ==
nullptr);
1428 for (
const auto &
P : CUMap) {
1429 auto &
CU = *
P.second;
1430 CU.createBaseTypeDIEs();
1439 finalizeModuleInfo();
1449 emitAbbreviations();
1463 emitDebugMacinfoDWO();
1473 emitDebugAbbrevDWO();
1475 emitDebugRangesDWO();
1485 emitAccelNamespaces();
1489 emitAccelDebugNames();
1498 emitDebugPubSections();
1506 const MDNode *ScopeNode) {
1507 if (
CU.getExistingAbstractEntity(Node))
1511 cast<DILocalScope>(ScopeNode)));
1516 if (
CU.getExistingAbstractEntity(Node))
1521 CU.createAbstractEntity(Node,
Scope);
1525 void DwarfDebug::collectVariableInfoFromMFTable(
1528 LLVM_DEBUG(
dbgs() <<
"DwarfDebug: collecting variables from MF side table\n");
1532 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1533 "Expected inlined-at fields to agree");
1535 InlinedEntity Var(
VI.Var,
VI.Loc->getInlinedAt());
1542 <<
", no variable scope found\n");
1546 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first,
Scope->getScopeNode());
1547 auto RegVar = std::make_unique<DbgVariable>(
1548 cast<DILocalVariable>(Var.first), Var.second);
1549 RegVar->initializeMMI(
VI.Expr,
VI.Slot);
1553 DbgVar->addMMIEntry(*RegVar);
1555 MFVars.
insert({Var, RegVar.get()});
1556 ConcreteEntities.push_back(
std::move(RegVar));
1577 if (LSRange.size() == 0)
1580 const MachineInstr *LScopeBegin = LSRange.front().first;
1584 if (!Ordering.
isBefore(DbgValue, LScopeBegin)) {
1590 for (++Pred; Pred !=
MBB->
rend(); ++Pred) {
1593 auto PredDL = Pred->getDebugLoc();
1594 if (!PredDL || Pred->isMetaInstruction())
1598 if (
DL->getScope() == PredDL->getScope())
1601 if (!PredScope || LScope->dominates(PredScope))
1621 if (Ordering.
isBefore(RangeEnd, LScopeEnd))
1665 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1667 bool isSafeForSingleLocation =
true;
1671 for (
auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {
1675 size_t Index = std::distance(EB, EI);
1676 erase_if(OpenRanges, [&](OpenRange &R) {
return R.first <=
Index; });
1683 "Forgot label before/after instruction starting a range!");
1686 if (std::next(EI) == Entries.end()) {
1689 if (EI->isClobber())
1690 EndMI = EI->getInstr();
1692 else if (std::next(EI)->isClobber())
1696 assert(EndLabel &&
"Forgot label after instruction ending a range!");
1698 if (EI->isDbgValue())
1704 if (EI->isDbgValue()) {
1717 isSafeForSingleLocation =
false;
1720 StartDebugMI = Instr;
1722 isSafeForSingleLocation =
false;
1728 if (OpenRanges.empty())
1732 if (StartLabel == EndLabel) {
1733 LLVM_DEBUG(
dbgs() <<
"Omitting location list entry with empty range.\n");
1738 for (
auto &R : OpenRanges)
1739 Values.push_back(
R.second);
1740 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1746 dbgs() << CurEntry->getValues().size() <<
" Values:\n";
1747 for (
auto &
Value : CurEntry->getValues())
1749 dbgs() <<
"-----\n";
1752 auto PrevEntry = std::next(CurEntry);
1753 if (PrevEntry !=
DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1757 return DebugLoc.size() == 1 && isSafeForSingleLocation &&
1766 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node,
Scope.getScopeNode());
1767 if (isa<const DILocalVariable>(Node)) {
1768 ConcreteEntities.push_back(
1769 std::make_unique<DbgVariable>(cast<const DILocalVariable>(Node),
1772 cast<DbgVariable>(ConcreteEntities.back().get()));
1773 }
else if (isa<const DILabel>(Node)) {
1774 ConcreteEntities.push_back(
1775 std::make_unique<DbgLabel>(cast<const DILabel>(Node),
1778 cast<DbgLabel>(ConcreteEntities.back().get()));
1780 return ConcreteEntities.back().get();
1788 collectVariableInfoFromMFTable(TheCU, Processed);
1791 InlinedEntity IV =
I.first;
1792 if (Processed.
count(IV))
1796 const auto &HistoryMapEntries =
I.second;
1814 DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
1817 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1823 size_t HistSize = HistoryMapEntries.size();
1824 bool SingleValueWithClobber =
1825 HistSize == 2 && HistoryMapEntries[1].isClobber();
1826 if (HistSize == 1 || SingleValueWithClobber) {
1828 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() :
nullptr;
1844 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1849 if (isValidSingleLocation) {
1861 for (
auto &Entry : Entries)
1862 Entry.finalize(*
Asm, List,
BT, TheCU);
1868 InlinedEntity IL =
I.first;
1877 Label->getScope()->getNonLexicalBlockFileScope();
1892 createConcreteEntity(TheCU, *
Scope, Label, IL.second, Sym);
1896 for (
const DINode *DN : SP->getRetainedNodes()) {
1897 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
1900 if (
auto *DV = dyn_cast<DILocalVariable>(DN)) {
1902 }
else if (
auto *
DL = dyn_cast<DILabel>(DN)) {
1907 createConcreteEntity(TheCU, *
Scope, DN,
nullptr);
1920 if (!
MI.isBundledWithSucc())
1922 auto Suc = std::next(
MI.getIterator());
1927 assert(Suc->isBundledWithPred() &&
1928 "Call bundle instructions are out of order");
1933 if (!NoDebug && SP->areAllCallsDescribed() &&
1935 (!
MI->hasDelaySlot() || delaySlotSupported(*
MI))) {
1963 unsigned LastAsmLine =
1972 if (LastAsmLine == 0 &&
DL.getLine() != 0) {
1975 recordSourceLine(
DL.getLine(),
DL.getCol(),
Scope, 0);
1983 if (LastAsmLine == 0)
2001 unsigned Column = 0;
2006 recordSourceLine(0, Column,
Scope, 0);
2014 if (
DL.getLine() == 0 && LastAsmLine == 0)
2024 if (
DL.getLine() &&
DL.getLine() != OldLine)
2028 recordSourceLine(
DL.getLine(),
DL.getCol(),
Scope, Flags);
2038 for (
const auto &
MBB : *MF)
2039 for (
const auto &
MI :
MBB)
2042 return MI.getDebugLoc();
2049 const MDNode *
S,
unsigned Flags,
unsigned CUID,
2051 ArrayRef<std::unique_ptr<DwarfCompileUnit>> DCUs) {
2053 unsigned FileNo = 1;
2054 unsigned Discriminator = 0;
2055 if (
auto *
Scope = cast_or_null<DIScope>(
S)) {
2056 Fn =
Scope->getFilename();
2057 if (Line != 0 && DwarfVersion >= 4)
2058 if (
auto *LBF = dyn_cast<DILexicalBlockFile>(
Scope))
2059 Discriminator = LBF->getDiscriminator();
2062 .getOrCreateSourceID(
Scope->getFile());
2064 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2074 (void)getOrCreateDwarfCompileUnit(
2125 "endFunction should be called with the same function as beginFunction");
2140 collectEntityInfo(TheCU, SP, Processed);
2145 TheCU.
addRange({R.second.BeginLabel, R.second.EndLabel});
2164 auto *SP = cast<DISubprogram>(AScope->getScopeNode());
2165 for (
const DINode *DN : SP->getRetainedNodes()) {
2166 if (!Processed.
insert(InlinedEntity(DN,
nullptr)).second)
2170 if (
auto *DV = dyn_cast<DILocalVariable>(DN))
2171 Scope = DV->getScope();
2172 else if (
auto *
DL = dyn_cast<DILabel>(DN))
2178 ensureAbstractEntityIsCreated(TheCU, DN,
Scope);
2180 &&
"ensureAbstractEntityIsCreated inserted abstract scopes");
2182 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2185 ProcessedSPNodes.insert(SP);
2190 SkelCU->constructSubprogramScopeDIE(SP, FnScope);
2193 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2207 void DwarfDebug::recordSourceLine(
unsigned Line,
unsigned Col,
const MDNode *
S,
2209 ::recordSourceLine(*
Asm, Line, Col,
S, Flags,
2219 void DwarfDebug::emitDebugInfo() {
2225 void DwarfDebug::emitAbbreviations() {
2231 void DwarfDebug::emitStringOffsetsTableHeader() {
2238 template <
typename AccelTableT>
2247 void DwarfDebug::emitAccelDebugNames() {
2249 if (getUnits().
empty())
2256 void DwarfDebug::emitAccelNames() {
2263 void DwarfDebug::emitAccelObjC() {
2269 void DwarfDebug::emitAccelNamespaces() {
2270 emitAccel(AccelNamespace,
2276 void DwarfDebug::emitAccelTypes() {
2307 if (Die->
getTag() == dwarf::DW_TAG_compile_unit)
2315 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2322 case dwarf::DW_TAG_class_type:
2323 case dwarf::DW_TAG_structure_type:
2324 case dwarf::DW_TAG_union_type:
2325 case dwarf::DW_TAG_enumeration_type:
2331 case dwarf::DW_TAG_typedef:
2332 case dwarf::DW_TAG_base_type:
2333 case dwarf::DW_TAG_subrange_type:
2335 case dwarf::DW_TAG_namespace:
2337 case dwarf::DW_TAG_subprogram:
2339 case dwarf::DW_TAG_variable:
2341 case dwarf::DW_TAG_enumerator:
2351 void DwarfDebug::emitDebugPubSections() {
2352 for (
const auto &NU : CUMap) {
2363 emitDebugPubSection(GnuStyle,
"Names", TheU, TheU->
getGlobalNames());
2368 emitDebugPubSection(GnuStyle,
"Types", TheU, TheU->
getGlobalTypes());
2375 CU.getDebugSectionOffset());
2380 void DwarfDebug::emitDebugPubSection(
bool GnuStyle,
StringRef Name,
2388 "pub" +
Name,
"Length of Public " +
Name +
" Info");
2394 emitSectionReference(*TheU);
2400 for (
const auto &GI : Globals) {
2401 const char *
Name = GI.getKeyData();
2402 const DIE *Entity = GI.second;
2425 void DwarfDebug::emitDebugStr() {
2426 MCSection *StringOffsetsSection =
nullptr;
2428 emitStringOffsetsTableHeader();
2433 StringOffsetsSection,
true);
2440 auto Comment = Comments.
begin();
2441 auto End = Comments.end();
2456 for (
auto &
Op : Expr) {
2457 assert(
Op.getCode() != dwarf::DW_OP_const_type &&
2458 "3 operand ops not yet supported");
2459 Streamer.
emitInt8(
Op.getCode(), Comment != End ? *(Comment++) :
"");
2461 for (
unsigned I = 0;
I < 2; ++
I) {
2462 if (
Op.getDescription().Op[
I] == Encoding::SizeNA)
2464 if (
Op.getDescription().Op[
I] == Encoding::BaseTypeRef) {
2466 CU->ExprRefedBaseTypes[
Op.getRawOperand(
I)].Die->getOffset();
2474 for (uint64_t J =
Offset; J <
Op.getOperandEndOffset(
I); ++J)
2475 Streamer.
emitInt8(
Data.getData()[J], Comment != End ? *(Comment++) :
"");
2486 auto *DIExpr =
Value.getExpression();
2492 if (DIExpr && DIExpr->isEntryValue()) {
2509 auto EmitValueLocEntry = [&DwarfExpr, &
BT,
2512 if (Entry.isInt()) {
2513 if (
BT && (
BT->getEncoding() == dwarf::DW_ATE_signed ||
2514 BT->getEncoding() == dwarf::DW_ATE_signed_char))
2518 }
else if (Entry.isLocation()) {
2526 }
else if (Entry.isTargetIndexLocation()) {
2532 }
else if (Entry.isConstantFP()) {
2535 DwarfExpr.
addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
2536 }
else if (Entry.getConstantFP()
2539 .getBitWidth() <= 64 ) {
2541 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
2544 dbgs() <<
"Skipped DwarfExpression creation for ConstantFP of size"
2545 << Entry.getConstantFP()
2556 if (!
Value.isVariadic()) {
2557 if (!EmitValueLocEntry(
Value.getLocEntries()[0], ExprCursor))
2566 return Entry.isLocation() && !Entry.getLoc().getReg();
2572 [EmitValueLocEntry, &
Value](
unsigned Idx,
2574 return EmitValueLocEntry(
Value.getLocEntries()[Idx], Cursor);
2582 assert(!Values.empty() &&
2583 "location list entries without values are redundant");
2584 assert(Begin != End &&
"unexpected location list entry with empty range");
2589 if (
Value.isFragment()) {
2592 return P.isFragment();
2593 }) &&
"all values are expected to be fragments");
2596 for (
const auto &Fragment : Values)
2600 assert(Values.size() == 1 &&
"only fragments may have >1 value");
2634 Asm->OutStreamer->AddComment(
"Offset entry count");
2640 Asm->getDwarfOffsetByteSize());
2654 Asm->OutStreamer->AddComment(
"Offset entry count");
2655 Asm->emitInt32(DebugLocs.getLists().size());
2656 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
2658 for (
const auto &
List : DebugLocs.getLists())
2659 Asm->emitLabelDifference(
List.Label, DebugLocs.getSym(),
2660 Asm->getDwarfOffsetByteSize());
2665 template <
typename Ranges,
typename PayloadEmitter>
2669 unsigned StartxLength,
unsigned EndOfList,
2671 bool ShouldUseBaseAddress,
2672 PayloadEmitter EmitPayload) {
2674 auto Size =
Asm->MAI->getCodePointerSize();
2678 Asm->OutStreamer->emitLabel(Sym);
2684 for (
const auto &Range : R)
2685 SectionRanges[&Range.Begin->getSection()].push_back(&Range);
2687 const MCSymbol *CUBase =
CU.getBaseAddress();
2688 bool BaseIsSet =
false;
2689 for (
const auto &
P : SectionRanges) {
2690 auto *Base = CUBase;
2691 if (!Base && ShouldUseBaseAddress) {
2692 const MCSymbol *Begin =
P.second.front()->Begin;
2697 Asm->OutStreamer->emitIntValue(-1,
Size);
2698 Asm->OutStreamer->AddComment(
" base address");
2699 Asm->OutStreamer->emitSymbolValue(Base,
Size);
2700 }
else if (NewBase != Begin ||
P.second.size() > 1) {
2706 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
2707 Asm->emitInt8(BaseAddressx);
2708 Asm->OutStreamer->AddComment(
" base address index");
2711 }
else if (BaseIsSet && !UseDwarf5) {
2714 Asm->OutStreamer->emitIntValue(-1,
Size);
2715 Asm->OutStreamer->emitIntValue(0,
Size);
2718 for (
const auto *RS :
P.second) {
2721 assert(Begin &&
"Range without a begin symbol?");
2722 assert(End &&
"Range without an end symbol?");
2726 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
2727 Asm->emitInt8(OffsetPair);
2728 Asm->OutStreamer->AddComment(
" starting offset");
2729 Asm->emitLabelDifferenceAsULEB128(Begin, Base);
2730 Asm->OutStreamer->AddComment(
" ending offset");
2731 Asm->emitLabelDifferenceAsULEB128(End, Base);
2733 Asm->emitLabelDifference(Begin, Base,
Size);
2734 Asm->emitLabelDifference(End, Base,
Size);
2736 }
else if (UseDwarf5) {
2737 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
2738 Asm->emitInt8(StartxLength);
2739 Asm->OutStreamer->AddComment(
" start index");
2741 Asm->OutStreamer->AddComment(
" length");
2742 Asm->emitLabelDifferenceAsULEB128(End, Begin);
2744 Asm->OutStreamer->emitSymbolValue(Begin,
Size);
2745 Asm->OutStreamer->emitSymbolValue(End,
Size);
2752 Asm->OutStreamer->AddComment(StringifyEnum(
EndOfList));
2756 Asm->OutStreamer->emitIntValue(0,
Size);
2757 Asm->OutStreamer->emitIntValue(0,
Size);
2764 *
List.CU, dwarf::DW_LLE_base_addressx,
2765 dwarf::DW_LLE_offset_pair, dwarf::DW_LLE_startx_length,
2769 DD.emitDebugLocEntryLocation(E, List.CU);
2773 void DwarfDebug::emitDebugLocImpl(
MCSection *Sec) {
2783 for (
const auto &List : DebugLocs.
getLists())
2791 void DwarfDebug::emitDebugLoc() {
2799 void DwarfDebug::emitDebugLocDWO() {
2807 for (
const auto &List : DebugLocs.
getLists()) {
2812 for (
const auto &Entry : DebugLocs.
getEntries(List)) {
2822 unsigned idx = AddrPool.
getIndex(Entry.Begin);
2839 void DwarfDebug::emitDebugARanges() {
2844 for (
const SymbolCU &SCU : ArangeLabels) {
2845 if (SCU.Sym->isInSection()) {
2848 if (!
Section->getKind().isMetadata())
2849 SectionMap[
Section].push_back(SCU);
2854 SectionMap[
nullptr].push_back(SCU);
2860 for (
auto &
I : SectionMap) {
2863 if (
List.size() < 1)
2871 Span.
Start = Cur.Sym;
2874 Spans[Cur.CU].push_back(Span);
2898 for (
size_t n = 1,
e =
List.size();
n <
e;
n++) {
2903 if (Cur.
CU != Prev.
CU) {
2905 Span.
Start = StartSym;
2908 Spans[Prev.
CU].push_back(Span);
2921 std::vector<DwarfCompileUnit *> CUs;
2922 for (
const auto &
it : Spans) {
2929 return A->getUniqueID() <
B->getUniqueID();
2934 std::vector<ArangeSpan> &
List = Spans[
CU];
2937 if (
auto *Skel =
CU->getSkeleton())
2941 unsigned ContentSize =
2948 unsigned TupleSize = PtrSize * 2;
2954 ContentSize += Padding;
2955 ContentSize += (
List.size() + 1) * TupleSize;
2962 emitSectionReference(*
CU);
2979 uint64_t
Size = SymSize[Span.Start];
2997 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
2998 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_end_of_list,
3000 List.CU->getCUNode()->getRangesBaseAddress() ||
3012 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3030 void DwarfDebug::emitDebugRanges() {
3031 const auto &Holder =
useSplitDwarf() ? SkeletonHolder : InfoHolder;
3033 emitDebugRangesImpl(Holder,
3039 void DwarfDebug::emitDebugRangesDWO() {
3040 emitDebugRangesImpl(InfoHolder,
3048 enum HeaderFlagMask {
3049 #define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3050 #include "llvm/BinaryFormat/Dwarf.def"
3052 Asm->OutStreamer->AddComment(
"Macro information version");
3053 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3056 if (
Asm->isDwarf64()) {
3057 Asm->OutStreamer->AddComment(
"Flags: 64 bit, debug_line_offset present");
3058 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3060 Asm->OutStreamer->AddComment(
"Flags: 32 bit, debug_line_offset present");
3061 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3063 Asm->OutStreamer->AddComment(
"debug_line_offset");
3065 Asm->emitDwarfLengthOrOffset(0);
3067 Asm->emitDwarfSymbolReference(
CU.getLineTableStartSym());
3070 void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
3071 for (
auto *MN : Nodes) {
3072 if (
auto *M = dyn_cast<DIMacro>(MN))
3074 else if (
auto *
F = dyn_cast<DIMacroFile>(MN))
3075 emitMacroFile(*
F, U);
3081 void DwarfDebug::emitMacro(
DIMacro &M) {
3089 if (UseDebugMacroSection) {
3092 ? dwarf::DW_MACRO_define_strx
3093 : dwarf::DW_MACRO_undef_strx;
3103 ? dwarf::DW_MACRO_GNU_define_indirect
3104 : dwarf::DW_MACRO_GNU_undef_indirect;
3124 void DwarfDebug::emitMacroFileImpl(
3149 if (UseDebugMacroSection)
3151 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3159 for (
const auto &
P : CUMap) {
3160 auto &TheCU = *
P.second;
3163 auto *CUNode = cast<DICompileUnit>(
P.first);
3164 DIMacroNodeArray Macros = CUNode->getMacros();
3169 if (UseDebugMacroSection)
3171 handleMacroNodes(Macros, U);
3178 void DwarfDebug::emitDebugMacinfo() {
3180 emitDebugMacinfoImpl(UseDebugMacroSection
3181 ? ObjLower.getDwarfMacroSection()
3182 : ObjLower.getDwarfMacinfoSection());
3185 void DwarfDebug::emitDebugMacinfoDWO() {
3187 emitDebugMacinfoImpl(UseDebugMacroSection
3188 ? ObjLower.getDwarfMacroDWOSection()
3189 : ObjLower.getDwarfMacinfoDWOSection());
3194 void DwarfDebug::initSkeletonUnit(
const DwarfUnit &U,
DIE &Die,
3195 std::unique_ptr<DwarfCompileUnit> NewU) {
3197 if (!CompilationDir.
empty())
3198 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3199 addGnuPubAttributes(*NewU, Die);
3206 auto OwnedUnit = std::make_unique<DwarfCompileUnit>(
3207 CU.getUniqueID(),
CU.getCUNode(),
Asm,
this, &SkeletonHolder,
3224 void DwarfDebug::emitDebugInfoDWO() {
3232 void DwarfDebug::emitDebugAbbrevDWO() {
3237 void DwarfDebug::emitDebugLineDWO() {
3239 SplitTypeUnitFileTable.
Emit(
3244 void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3254 void DwarfDebug::emitDebugStrDWO() {
3256 emitStringOffsetsTableHeaderDWO();
3264 void DwarfDebug::emitDebugAddr() {
3275 return &SplitTypeUnitFileTable;
3286 return Result.high();
3295 if (!TypeUnitsUnderConstruction.empty() && AddrPool.
hasBeenUsed())
3298 auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0));
3300 CU.addDIETypeSignature(RefDie,
Ins.first->second);
3304 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3307 auto OwnedUnit = std::make_unique<DwarfTypeUnit>(
CU,
Asm,
this, &InfoHolder,
3308 getDwoLineTable(
CU));
3311 TypeUnitsUnderConstruction.emplace_back(
std::move(OwnedUnit), CTy);
3313 NewTU.
addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3318 Ins.first->second = Signature;
3333 CU.applyStmtList(UnitDie);
3344 auto TypeUnitsToAdd =
std::move(TypeUnitsUnderConstruction);
3345 TypeUnitsUnderConstruction.clear();
3354 for (
const auto &TU : TypeUnitsToAdd)
3355 TypeSignatures.erase(TU.second);
3361 CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));
3367 for (
auto &TU : TypeUnitsToAdd) {
3372 CU.addDIETypeSignature(RefDie, Signature);
3375 DwarfDebug::NonTypeUnitContext::NonTypeUnitContext(
DwarfDebug *DD)
3377 TypeUnitsUnderConstruction(
std::
move(DD->TypeUnitsUnderConstruction)), AddrPoolUsed(DD->AddrPool.hasBeenUsed()) {
3378 DD->TypeUnitsUnderConstruction.clear();
3383 DD->TypeUnitsUnderConstruction =
std::move(TypeUnitsUnderConstruction);
3395 template <
typename DataT>
3414 AccelDebugNames.addName(Ref, Die);
3425 addAccelNameImpl(
CU, AccelNames,
Name, Die);
3432 addAccelNameImpl(
CU, AccelObjC,
Name, Die);
3437 addAccelNameImpl(
CU, AccelNamespace,
Name, Die);
3441 const DIE &Die,
char Flags) {
3442 addAccelNameImpl(
CU, AccelTypes,
Name, Die);
3451 return dwarf::Form::DW_FORM_sec_offset;
3453 "DWARF64 is not defined prior DWARFv3");
3455 : dwarf::Form::DW_FORM_data4;
3459 auto I = SectionLabels.find(
S);
3460 if (
I == SectionLabels.end())
3465 if (SectionLabels.insert(std::make_pair(&
S->getSection(),
S)).second)
3481 std::string ChecksumString = fromHex(Checksum->Value);
3483 std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.
Bytes.data());
StringRef getFilename() const
bool isDebugValue() const
bool isTailCall(const MachineInstr &MI) const override
MCSection * getDwarfRangesSection() const
EntryRef getEntry(AsmPrinter &Asm, StringRef Str)
Get a reference to an entry in the string pool.
MCSection * getDwarfAddrSection() const
void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const
Emit something like ".long Hi-Lo" where the size in bytes of the directive is specified by Size and H...
DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope)
Construct a DIE for this subprogram scope.
bool isUndefDebugValue() const
Return true if the instruction is a debug value which describes a part of a variable as unavailable.
const DILocation * getInlinedAt() const
MCSection * getDwarfAccelObjCSection() const
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
void addRnglistsBase()
Add the DW_AT_rnglists_base attribute to the unit DIE.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
iterator erase(const_iterator CI)
DIE::value_iterator addSectionLabel(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label, const MCSymbol *Sec)
Add a Dwarf section label attribute data and value.
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
void setType(const DIE *Ty)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
StringRef MacroString(unsigned Encoding)
MCSection * getDwarfMacroSection() const
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
const StringMap< const DIE * > & getGlobalNames() const
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))
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
AddressPool & getAddressPool()
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
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))
void addFlag(DIE &Die, dwarf::Attribute Attribute)
Add a flag that is true to the DIE.
VariableDbgInfoMapTy & getVariableDbgInfo()
dwarf::DwarfFormat getDwarfFormat() const
MCSection * getDwarfPubTypesSection() const
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
bool isDwarf64() const
Returns the DWARF format by checking module flags.
DebuggerKind
Identify a debugger for "tuning" the debug info.
@ Dwarf
DWARF v5 .debug_names.
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))
const GlobalValue * getGlobal() const
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...
MCSymbol * createTempSymbol(const Twine &Name) const
DwarfDebug * getDwarfDebug()
iterator_range< mop_iterator > debug_operands()
Returns a range over all operands that are used to determine the variable location for this DBG_VALUE...
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.
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::lookup 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...
void dump() const
Support for debugging, callable in GDB: V->dump()
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
DIE * getOrCreateContextDIE(const DIScope *Context)
Get context owner's DIE.
virtual const TargetInstrInfo * getInstrInfo() const
DenseMap< const MDNode *, DIE * > & getAbstractSPDies()
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))
MCSection * getDwarfLoclistsSection() const
Reference model for inliner Oz decision policy Note this model is also referenced by test Transforms Inline ML tests if replacing it
const MCAsmInfo * MAI
Target Asm Printer information.
bool emitDebugEntryValues() const
This struct describes target specific location.
static constexpr size_t npos
static constexpr unsigned ULEB128PadSize
MCSymbol * getBeginSymbol()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
void initializeDbgValue(DbgValueLoc Value)
LexicalScope - This class is used to track scope information.
detail::enumerator< R > enumerate(R &&TheRange)
Given an input range, returns a new range whose values are are pair (A,B) such that A is the 0-based ...
DISubprogram * getSubprogram() const
Get the attached subprogram.
void addAccelName(const DICompileUnit &CU, StringRef Name, const DIE &Die)
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
const MachineBasicBlock & back() const
void skippedNonDebugFunction() override
Triple - Helper class for working with autoconf configuration names.
StringRef getName() const
void resetUsedFlag(bool HasBeenUsed=false)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
DebugLoc PrevInstLoc
Previous instruction's location information.
bool hasDebugInfo() const
Returns true if valid debug info is present.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool addScopeVariable(LexicalScope *LS, DbgVariable *Var)
iterator_range< debug_compile_units_iterator > debug_compile_units() const
Return an iterator for all DICompileUnits listed in this Module's llvm.dbg.cu named metadata node and...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
void beginModule(Module *M) override
The instances of the Type class are immutable: once they are created, they are never changed.
void attachRangesOrLowHighPC(DIE &D, SmallVector< RangeSpan, 2 > Ranges)
Optional< uint8_t > TagOffset
void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)
Add a string attribute data and value.
reverse_self_iterator getReverseIterator()
unsigned int getDwarfOffsetByteSize() const
Returns 4 for DWARF32 and 8 for DWARF64.
static bool hasObjCCategory(StringRef Name)
@ DWARF_VERSION
Other constants.
const SmallVectorImpl< std::unique_ptr< DwarfCompileUnit > > & getUnits()
ArrayRef< std::string > getComments(const Entry &E) const
StringRef RangeListEncodingString(unsigned Encoding)
ArrayRef< char > getBytes(const Entry &E) const
void addAccelObjC(const DICompileUnit &CU, StringRef Name, const DIE &Die)
void requestLabelAfterInsn(const MachineInstr *MI)
Ensure that a label will be emitted after MI.
MCSection * getDwarfLocSection() const
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const
Emit something like ".long Label + Offset" or ".quad Label + Offset" depending on the DWARF format.
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
void endModule() override
Emit all Dwarf sections that should come after the content.
This class implements a map that also provides access to all stored values in a deterministic order.
const StringMap< const DIE * > & getGlobalTypes() const
Encoding
Size and signedness of expression operations' operands.
A structured debug information entry.
MCSection * getDwarfStrOffSection() const
void emitLabelReference(const MCSymbol *Label, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label" where the size in bytes of the directive is specified by Size and L...
virtual bool isCalleeSavedPhysReg(MCRegister PhysReg, const MachineFunction &MF) const
This is a wrapper around getCallPreservedMask().
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
dwarf::Tag getTag() const
@ GDB
Tune debug info for gdb.
EntryRef getIndexedEntry(AsmPrinter &Asm, StringRef Str)
Same as getEntry, except that you can use EntryRef::getIndex to obtain a unique ID of this entry (e....
void setSym(MCSymbol *Sym)
MCSection * getDwarfGnuPubTypesSection() const
bool useSectionsAsReferences() const
Returns whether to use sections as labels rather than temp symbols.
std::pair< iterator, bool > insert(const ValueT &V)
SmallVectorImpl< InsnRange > & getRanges()
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
unsigned const TargetRegisterInfo * TRI
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
#define clEnumVal(ENUMVAL, DESC)
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
virtual void emitSLEB128(uint64_t DWord, const Twine &Comment="")=0
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.
MCSection * getDwarfInfoSection() const
String pool entry reference.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
MCSection * getDwarfLoclistsDWOSection() const
StringRef GnuMacroString(unsigned Encoding)
static DebugLoc findPrologueEndLoc(const MachineFunction *MF)
MCSection * getDwarfPubNamesSection() const
void setRnglistsTableBaseSym(MCSymbol *Sym)
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Base class containing the logic for constructing DWARF expressions independently of whether they are ...
void setLabel(MCSymbol *Sym)
void insertSectionLabel(const MCSymbol *S)
An object containing the capability of hashing and adding hash attributes onto a DIE.
void addAccelNamespace(const DICompileUnit &CU, StringRef Name, const DIE &Die)
void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)
Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null.
static DbgValueLoc getDebugLocValue(const MachineInstr *MI)
Get .debug_loc entry for the instruction range starting at MI.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
SmallVector< RangeSpan, 2 > takeRanges()
#define DWARF2_FLAG_IS_STMT
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
const bool GenerateComments
Only verbose textual output needs comments.
bool isCall(QueryType Type=AnyInBundle) const
TargetInstrInfo - Interface to description of machine instruction set.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
DebugLoc PrologEndLoc
This location indicates end of function prologue and beginning of function body.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
@ Ref
The access may reference the value stored in memory.
static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))
void emitUnit(DwarfUnit *TheU, bool UseOffsets)
Emit the given unit to its section.
static void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params)
Interpret values loaded into registers by CurMI.
static StringRef getObjCMethodName(StringRef In)
Optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const
If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.
void constructContainingTypeDIEs()
Construct DIEs for types that contain vtables.
MCSection * getDwarfARangesSection() const
AsmPrinter * Asm
Target of debug info emission.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Optional< StringRef > getSource() const
void setDWOId(uint64_t DwoId)
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
void addSubprogramNames(const DICompileUnit &CU, const DISubprogram *SP, DIE &Die)
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
void finalize()
This needs to be called last to commit any pending changes.
MCSection * getDwarfMacinfoSection() const
std::string SplitDwarfFile
MCSection * getDwarfInfoDWOSection() const
MCTargetOptions MCOptions
Machine level options.
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)
std::array< uint8_t, 16 > Bytes
bool isBefore(const MachineInstr *A, const MachineInstr *B) const
Check if instruction A comes before B, where A and B both belong to the MachineFunction passed to ini...
const HexagonInstrInfo * TII
unsigned ParamReg
The described parameter register.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
void setMemoryLocationKind()
Lock this down to become a memory location description.
uint16_t getDwarfVersion() const
MCSection * getDwarfLocDWOSection() const
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
const DICompileUnit * getCUNode() const
void requestLabelBeforeInsn(const MachineInstr *MI)
Ensure that a label will be emitted before MI.
bool getSplitDebugInlining() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
STATISTIC(NumFunctions, "Total number of functions")
static Optional< DebugEmissionKind > getEmissionKind(StringRef Str)
bool regsOverlap(Register regA, Register regB) const
Returns true if the two registers are equal or alias each other.
bool hasNonEmptyLocation(const Entries &Entries) const
Test whether a vector of entries features any non-empty locations.
void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)
Emit all of the strings to the section given.
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
MCSection * getDwarfStrDWOSection() const
void emitDwarfSymbolReference(const MCSymbol *Label, bool ForceOffset=false) const
Emit a reference to a symbol for use in dwarf.
DenseMap< LexicalScope *, LabelList > & getScopeLabels()
ArrayRef< List > getLists() const
This class is used to track local variable information.
void emitInt8(int Value) const
Emit a byte directive and value.
This struct is a compact representation of a valid (non-zero power of two) alignment.
StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)
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.
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
MCSection * getDwarfAccelNamespaceSection() const
bool empty() const
Determine if the SetVector is empty or not.
MCSection * getDwarfRnglistsSection() const
void erase_value(Container &C, ValueType V)
Wrapper function to remove a value from a container:
Record instruction ordering so we can query their relative positions within a function.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope)
Used for tracking debug info about call site parameters.
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.
unsigned getSectionIDNum() const
Returns the unique section ID number of this basic block.
Builder for DebugLocStream lists.
static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
uint64_t computeCUSignature(StringRef DWOName, const DIE &Die)
Computes the CU signature.
void setSkeleton(DwarfCompileUnit &Skel)
Set the skeleton unit associated with this unit.
bool isImplicit() const
Return whether this is an implicit location description.
Implements a dense probed hash-table based set.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
GDBIndexEntryLinkage Linkage
static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))
void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
uint64_t getDWOId() const
const MachineBasicBlock * PrevInstBB
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getSourceLanguage() const
LexicalScope * findAbstractScope(const DILocalScope *N)
findAbstractScope - Find an abstract scope or return null.
A pair of GlobalVariable and DIExpression.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
MCSymbol * getMacroLabelBegin() const
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD)
bool hasDwarfPubSections() const
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
Collects and handles dwarf debug information.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
AccelTableKind getAccelTableKind() const
Returns what kind (if any) of accelerator tables to emit.
DwarfDebug(AsmPrinter *A)
DIE::value_iterator addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)
addSectionDelta - Add a label delta attribute data and value.
bool isLittleEndian() const
Layout endianness...
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
MCSection * getDwarfAccelNamesSection() const
bool useSplitDwarf() const
Returns whether or not to change the current debug info for the split dwarf proposal support.
const CallSiteInfoMap & getCallSitesInfo() const
unsigned getOrCreateSourceID(const DIFile *File) override
Look up the source ID for the given file.
void addStringOffsetsStart()
Add the DW_AT_str_offsets_base attribute to the unit DIE.
initializer< Ty > init(const Ty &Val)
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
An imported module (C++ using directive or similar).
DebugLoc emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
iterator find(const_arg_type_t< KeyT > Val)
bool ShouldEmitDebugEntryValues() const
NOTE: There are targets that still do not support the debug entry values production.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const
Emit a unit length field.
bool isDebugDirectivesOnly() const
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
void finishEntityDefinition(const DbgEntity *Entity)
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
MachineFunction * MF
The current machine function.
MCContext & OutContext
This is the context for the output file that we are streaming.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
bool hasDelaySlot(QueryType Type=AnyInBundle) const
Returns true if the specified instruction has a delay slot which must be filled by the code generator...
Register getReg() const
getReg - Returns the register number.
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
A Module instance is used to store all the information related to an LLVM module.
DbgLabelInstrMap DbgLabels
Mapping of inlined labels and DBG_LABEL machine instruction.
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
DIE * constructImportedEntityDIE(const DIImportedEntity *Module)
Construct import_module DIE.
const MachineInstr * CurMI
If nonnull, stores the current machine instruction we're processing.
void emitDwarfLengthOrOffset(uint64_t Value) const
Emit 32- or 64-bit value depending on the DWARF format.
virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=0
Basic type, like 'int' or 'float'.
void addSignedConstant(int64_t Value)
Emit a signed constant.
MCSymbol * emitListsTableHeaderStart(MCStreamer &S)
unsigned computeSizeAndOffsetsForUnit(DwarfUnit *TheU)
Compute the size and offset of all the DIEs in the given unit.
const DILocalVariable * getDebugVariable() const
Return the debug variable referenced by this DBG_VALUE instruction.
void emit(AsmPrinter &Asm, MCSection *AddrSection)
void addScopeLabel(LexicalScope *LS, DbgLabel *Label)
bool empty()
empty - Return true if there is any lexical scope information available.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const DebugLocStream & getDebugLocs() const
Returns the entries for the .debug_loc section.
ArrayRef< LexicalScope * > getAbstractScopesList() const
getAbstractScopesList - Return a reference to list of abstract scopes.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
StringRef - Represent a constant reference to a string, i.e.
@ Default
No specific tuning requested.
Tagged DWARF-like metadata node.
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))
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void addRange(RangeSpan Range)
addRange - Add an address range to the list of ranges for this unit.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params)
if(llvm_vc STREQUAL "") set(fake_version_inc "$
static bool isObjCClass(StringRef Name)
MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)
Returns an iterator to the first instruction in the bundle containing I.
static void forBothCUs(DwarfCompileUnit &CU, Func F)
self_iterator getIterator()
void addAddrTableBase()
Add the DW_AT_addr_base attribute to the unit DIE.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Instances of this class represent a uniqued identifier for a section in the current translation unit.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
StringRef getSplitDebugFilename() const
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
StringRef getDirectory() const
Builder for DebugLocStream entries.
unsigned int getUnitLengthFieldByteSize() const
Returns 4 for DWARF32 and 12 for DWARF64.
const MachineBasicBlock * getParent() const
Linkage
Describes symbol linkage.
StringRef getName() const
Return a constant reference to the value's name.
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::insert std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void addUnit(std::unique_ptr< DwarfCompileUnit > U)
Add a unit to the list of CUs.
bool shareAcrossDWOCUs() const
void maybeSetRootFile(StringRef Directory, StringRef FileName, Optional< MD5::MD5Result > Checksum, Optional< StringRef > Source)
Wrapper class representing virtual and physical registers.
virtual void emitULEB128(uint64_t DWord, const Twine &Comment="", unsigned PadTo=0)=0
void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const
NonTypeUnitContext enterNonTypeUnitContext()
const MCSymbol * getSectionLabel(const MCSection *S)
static Optional< DebugNameTableKind > getNameTableKind(StringRef Str)
DwarfStringPool & getStringPool()
Returns the string pool.
static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)
Try to interpret values loaded into registers that forward parameters for CallMI.
ArrayRef< FrameIndexExpr > getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
MCSymbol * getStringOffsetsStartSym() const
static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
void setBaseAddress(const MCSymbol *Base)
bool useLocSection() const
Returns whether .debug_loc section should be emitted.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool useAppleExtensionAttributes() const
const DILocalScope * getScopeNode() const
const InstructionOrdering & getInstOrdering() const
void stable_sort(R &&Range)
void computeSizeAndOffsets()
Compute the size and offset of all the DIEs.
DebuggerKind DebuggerTuning
Which debugger to tune for.
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Function & getFunction()
Return the LLVM function that this machine code represents.
StringRef getProducer() const
bool isFragment() const
Return whether this is a piece of an aggregate variable.
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...
const DIExpression * Expr
Debug expression that has been built up when walking through the instruction chain that produces the ...
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))
MCSymbol * getSymbol() const
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))
void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, Optional< dwarf::Form > Form, uint64_t Integer)
Add an unsigned integer attribute data and value.
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU)
Lower this entry into a DWARF expression.
MCSection * getDwarfMacroDWOSection() const
@ DW_PUBNAMES_VERSION
Section version number for .debug_pubnames.
unsigned getIndex() const
A single location or constant within a variable location description, with either a single entry (wit...
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
uint16_t getDwarfVersion() const
MCSection * getDwarfTypesDWOSection() const
bool getDebugInfoForProfiling() const
bool useSegmentedStringOffsetsTable() const
Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...
@ Default
Dwarf for DWARF5 or later, Apple otherwise.
void sort(IteratorTy Start, IteratorTy End)
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...
ArrayRef< uint64_t > getElements() const
static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
MCSection * getDwarfTypesSection(uint64_t Hash) const
unsigned getDwarfVersion() const
Returns the Dwarf Version by checking module flags.
This class is intended to be used as a driving class for all asm writers.
void setTypeSignature(uint64_t Signature)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
bool isCPlusPlus(SourceLanguage S)
DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)
Creates type DIE with specific context.
MCSection * getDwarfLineDWOSection() const
MCSection * getDwarfAbbrevSection() const
Describes an entry of the various gnu_pub* debug sections.
void emitUnits(bool UseOffsets)
Emit all of the units to the section listed with the given abbreviation section.
DenseMap< LexicalScope *, ScopeVars > & getScopeVariables()
DwarfCompileUnit * getSkeleton() const
DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
void addImportedEntity(const DIImportedEntity *IE)
MapVector< unsigned, MBBSectionRange > MBBSectionRanges
DIMacroNodeArray getElements() const
static uint64_t makeTypeSignature(StringRef Identifier)
Perform an MD5 checksum of Identifier and return the lower 64 bits.
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))
MCSymbol * getRnglistsTableBaseSym() const
TargetMachine & TM
Target machine description.
unsigned getRuntimeVersion() const
virtual const TargetLowering * getTargetLowering() const
StringRef MacinfoString(unsigned Encoding)
void emitInt8(uint8_t Byte, const Twine &Comment) override
MCSection * getDwarfAbbrevDWOSection() const
DwarfExpression implementation for .debug_loc entries.
Holds a DIExpression and keeps track of how many operands have been consumed so far.
static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))
void addExpression(DIExpressionCursor &&Expr, unsigned FragmentOffsetInBits=0)
Emit all remaining operations in the DIExpressionCursor.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
unsigned getNumOperands() const
Retuns the total number of operands.
const DILocalVariable * getVariable() const
const Triple & getTargetTriple() const
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
Align max(MaybeAlign Lhs, Align Rhs)
MCSection * getDwarfStrSection() const
void addAccelType(const DICompileUnit &CU, StringRef Name, const DIE &Die, char Flags)
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
MCSection * getDwarfMacinfoDWOSection() const
MachineModuleInfo * MMI
Collected machine module information.
const DataLayout & getDataLayout() const
Return information about data layout.
Base class for debug information backends.
MCSection * getDwarfAccelTypesSection() const
#define DWARF2_FLAG_PROLOGUE_END
A SetVector that performs no allocations if smaller than a certain size.
MCSection * getDwarfRnglistsDWOSection() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
This dwarf writer support class manages information associated with a source file.
Represents a parameter whose call site value can be described by applying a debug expression to a reg...
MDNode * getScope() const
bool useRangesSection() const
Returns whether ranges section should be emitted.
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
DIImportedEntityArray getImportedEntities() const
void emitAbbrevs(MCSection *)
Emit a set of abbreviations to the specific section.
void addMMIEntry(const DbgVariable &V)
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
bool hasRangeLists() const
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))
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
@ SCE
Tune debug info for SCE targets (e.g. PS4).
const SmallVectorImpl< RangeSpanList > & getRangeLists() const
getRangeLists - Get the vector of range lists.
std::vector< T > vec() const
bool isWasm() const
Tests whether the target is wasm (32- and 64-bit).
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i....
@ LLDB
Tune debug info for lldb.
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
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)
Register a source line with debug info.
Helper used to pair up a symbol and its DWARF compile unit.
unsigned getUniqueID() const
MCSymbol * getSym() const
const Module * getModule() const
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...
LLVM Value Representation.
void emitInt16(int Value) const
Emit a short directive and value.
const SmallVectorImpl< RangeSpan > & getRanges() const
getRanges - Get the list of ranges for this unit.
Instrumentation for Order File
MCSection * getDwarfStrOffDWOSection() const
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
StringRef getFlags() const
StringRef OperationEncodingString(unsigned Encoding)
StringRef LocListEncodingString(unsigned Encoding)
AccelTableKind
The kind of accelerator tables we should emit.
MCSection * getDwarfGnuPubNamesSection() const
StringRef getSysRoot() const
ArrayRef< Entry > getEntries(const List &L) const
Optional< std::vector< StOtherPiece > > Other
const DIType * getType() const
reference emplace_back(ArgTypes &&... Args)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
void emitDWARF5AccelTable(AsmPrinter *Asm, AccelTable< DWARF5AccelTableData > &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit >> CUs)