LLVM: lib/CodeGen/AsmPrinter/DwarfDebug.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
57#include
58#include
59#include
60#include
61
62using namespace llvm;
63
64#define DEBUG_TYPE "dwarfdebug"
65
66STATISTIC(NumCSParams, "Number of dbg call site params created");
67
69 "use-dwarf-ranges-base-address-specifier", cl::Hidden,
70 cl::desc("Use base address specifiers in debug_ranges"), cl::init(false));
71
74 cl::desc("Generate dwarf aranges"),
76
79 cl::desc("Generate DWARF4 type units."),
81
83 "split-dwarf-cross-cu-references", cl::Hidden,
84 cl::desc("Enable cross-cu references in DWO files"), cl::init(false));
85
87
90 cl::desc("Make an absence of debug location information explicit."),
94
96 "accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."),
98 "Default for platform"),
103
106 cl::desc("Use inlined strings rather than string section."),
111
114 cl::desc("Disable emission .debug_ranges section."),
116
118 "dwarf-sections-as-references", cl::Hidden,
119 cl::desc("Use sections+offset as references rather than labels."),
123
126 cl::desc("Emit the GNU .debug_macro format with DWARF <5"),
128
131 cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"),
135
141
144 cl::desc("Which DWARF linkage-name attributes to emit."),
146 "Default for platform"),
149 "Abstract subprograms")),
151
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"),
162 "Expressions",
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"),
169 "Stuff")),
171
172
175 cl::desc("Set to false to ignore Key Instructions metadata"));
176
178
179void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) {
180 getActiveStreamer().emitInt8(
183}
184
185void DebugLocDwarfExpression::emitSigned(int64_t Value) {
186 getActiveStreamer().emitSLEB128(Value, Twine(Value));
187}
188
189void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) {
190 getActiveStreamer().emitULEB128(Value, Twine(Value));
191}
192
193void DebugLocDwarfExpression::emitData1(uint8_t Value) {
194 getActiveStreamer().emitInt8(Value, Twine(Value));
195}
196
197void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
199 getActiveStreamer().emitULEB128(Idx, Twine(Idx), ULEB128PadSize);
200}
201
204
205 return false;
206}
207
209 assert(!IsBuffering && "Already buffering?");
210 if (!TmpBuf)
211 TmpBuf = std::make_unique(OutBS.GenerateComments);
212 IsBuffering = true;
213}
214
216
218 return TmpBuf ? TmpBuf->Bytes.size() : 0;
219}
220
222 if (!TmpBuf)
223 return;
224 for (auto Byte : enumerate(TmpBuf->Bytes)) {
225 const char *Comment = (Byte.index() < TmpBuf->Comments.size())
226 ? TmpBuf->Comments[Byte.index()].c_str()
227 : "";
228 OutBS.emitInt8(Byte.value(), Comment);
229 }
230 TmpBuf->Bytes.clear();
231 TmpBuf->Comments.clear();
232}
233
237
238
242 const bool IsVariadic = !SingleLocExprOpt;
243
244
245 if (!IsVariadic && ->isNonListDebugValue()) {
246 assert(MI->getNumDebugOperands() == 1 &&
247 "Mismatched DIExpression and debug operands for debug instruction.");
248 Expr = *SingleLocExprOpt;
249 }
250 assert(MI->getNumOperands() >= 3);
253 if (Op.isReg()) {
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())
266 else
267 llvm_unreachable("Unexpected debug operand in DBG_VALUE* instruction!");
268 }
269 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
270}
271
273 std::optionalDIExpression::FragmentInfo Fragment = Expr.getFragmentInfo();
274 return Fragment ? Fragment->OffsetInBits : 0;
275}
276
280}
281
284}
285
288 Expr(ValueLoc.getExpression()) {
289 if (!Expr->getNumElements())
290 Expr = nullptr;
291}
292
295
299
305 return FIE.Expr && FIE.Expr->isFragment();
306 })) &&
307 "conflicting locations for variable");
308}
309
311 bool GenerateTypeUnits,
314
317
318
319
320 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))
322
323
324
325
326 if (DwarfVersion >= 5)
332}
333
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();
340
341
342
344 DebuggerTuning = Asm->TM.Options.DebuggerTuning;
345 else if (IsDarwin)
347 else if (TT.isPS())
349 else if (TT.isOSAIX())
351 else
353
355 UseInlineStrings = TT.isNVPTX() || tuneForDBX();
356 else
358
359
361
362 HasAppleExtensionAttributes = tuneForLLDB();
363
364
365 HasSplitDwarf = ->TM.Options.MCOptions.SplitDwarfFile.empty();
366
367
370 else
372
373 unsigned DwarfVersionNumber = Asm->TM.Options.MCOptions.DwarfVersion;
374 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
375 : MMI->getModule()->getDwarfVersion();
376
377 DwarfVersion =
379
380 bool Dwarf64 = DwarfVersion >= 3 &&
381 TT.isArch64Bit();
382
383
384
385
386
387
388 Dwarf64 &=
389 ((Asm->TM.Options.MCOptions.Dwarf64 || MMI->getModule()->isDwarf64()) &&
390 TT.isOSBinFormatELF()) ||
391 TT.isOSBinFormatXCOFF();
392
393 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())
395
397
398
400 UseSectionsAsReferences = TT.isNVPTX();
401 else
403
404
405 GenerateTypeUnits = (A->TM.getTargetTriple().isOSBinFormatELF() ||
406 A->TM.getTargetTriple().isOSBinFormatWasm()) &&
408
410 DwarfVersion, GenerateTypeUnits, DebuggerTuning, A->TM.getTargetTriple());
411
412
413
414
415
416
417 UseGNUTLSOpcode = tuneForGDB() || DwarfVersion < 3;
418
419 UseDWARF2Bitfields = DwarfVersion < 4;
420
421
422
423
424
425 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
426
427
428
429 EmitDebugEntryValues = Asm->TM.Options.ShouldEmitDebugEntryValues();
430
431
432
433 UseDebugMacroSection =
437 else
439
440
441
442 if (DwarfVersion >= 5)
444
445 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
446 Asm->OutStreamer->getContext().setDwarfFormat(Dwarf64 ? dwarf::DWARF64
448}
449
450
452
454 return Name.starts_with("+") || Name.starts_with("-");
455}
456
459 return false;
460
461 return Name.contains(") ");
462}
463
467 Class = In.slice(In.find('[') + 1, In.find(' '));
468 Category = "";
469 return;
470 }
471
472 Class = In.slice(In.find('[') + 1, In.find('('));
473 Category = In.slice(In.find('[') + 1, In.find(' '));
474}
475
477 return In.slice(In.find(' ') + 1, In.find(']'));
478}
479
480
488 return;
489
490 if (!SP->isDefinition())
491 return;
492
493 if (SP->getName() != "")
494 addAccelName(Unit, NameTableKind, SP->getName(), Die);
495
496
497
500
501
502
503
505 (useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(SP)))
507
508
509
513 addAccelObjC(Unit, NameTableKind, Class, Die);
514 if (Category != "")
515 addAccelObjC(Unit, NameTableKind, Category, Die);
516
518 }
519}
520
521
522
524 if (Scope->isAbstractScope())
525 return false;
526
527
530 return true;
531
532 if (Ranges.size() > 1)
533 return false;
534
535
536
538}
539
542 if (auto *SkelCU = CU.getSkeleton())
543 if (CU.getCUNode()->getSplitDebugInlining())
544 F(*SkelCU);
545}
546
550
554 auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
555 if (CU.getSkeleton())
557
558 return CU;
559}
560
561void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
563 assert(Scope && Scope->getScopeNode());
564 assert(Scope->isAbstractScope());
565 assert(!Scope->getInlinedAt());
566
568
569
570
571 auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());
573 TargetCU.constructAbstractSubprogramScopeDIE(Scope);
574 if (auto *SkelCU = CU.getSkeleton())
575 if (CU.getCUNode()->getSplitDebugInlining())
576 SkelCU->constructAbstractSubprogramScopeDIE(Scope);
577}
578
579
580
589
590
592
593
595
596
599 std::vector<uint64_t> Elts = Addition->getElements().vec();
600
602 llvm::erase(Elts, dwarf::DW_OP_stack_value);
605 return CombinedExpr;
606}
607
608
609
610template
614 for (auto Param : DescribedParams) {
615 bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0;
616
617
618
619 if (ShouldCombineExpressions && Expr->isEntryValue())
620 continue;
621
622
623
624
625
628 : Expr;
629 assert((!CombinedExpr || CombinedExpr->isValid()) &&
630 "Combined debug expression is invalid");
631
635 ++NumCSParams;
636 }
637}
638
639
640
641
645 auto &ParamsForFwdReg = Worklist[Reg];
646 for (auto Param : ParamsToAdd) {
649 return D.ParamReg == Param.ParamReg;
650 }) &&
651 "Same parameter described twice by forwarding reg");
652
653
654
655
656
658 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});
659 }
660}
661
662
667
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
695
696
697
699 auto getForwardingRegsDefinedByMI = [&](const MachineInstr &MI,
701 if (MI.isDebugInstr())
702 return;
703
705 if (MO.getReg().isPhysical()) {
706 for (auto &FwdReg : ForwardedRegWorklist)
707 if (TRI.regsOverlap(FwdReg.first, MO.getReg()))
708 Defs.insert(FwdReg.first);
709 NewClobberedRegUnits.insert_range(TRI.regunits(MO.getReg()));
710 }
711 }
712 };
713
714
716
717 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);
718 if (FwdRegDefs.empty()) {
719
720 ClobberedRegUnits.insert_range(NewClobberedRegUnits);
721 return;
722 }
723
724
725
726
727 auto IsRegClobberedInMeantime = [&](Register Reg) -> bool {
728 for (auto &RegUnit : ClobberedRegUnits)
729 if (TRI.hasRegUnit(Reg, RegUnit))
730 return true;
731 return false;
732 };
733
734 for (auto ParamFwdReg : FwdRegDefs) {
735 if (auto ParamValue = TII.describeLoadedValue(*CurMI, ParamFwdReg)) {
736 if (ParamValue->first.isImm()) {
737 int64_t Val = ParamValue->first.getImm();
739 ForwardedRegWorklist[ParamFwdReg], Params);
740 } else if (ParamValue->first.isReg()) {
741 Register RegLoc = ParamValue->first.getReg();
742 Register SP = TLI.getStackPointerRegisterToSaveRestore();
744 bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP);
745 if (!IsRegClobberedInMeantime(RegLoc) &&
746 (TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {
749 ForwardedRegWorklist[ParamFwdReg], Params);
750 } else {
751
752
753
754
755
756
758 ForwardedRegWorklist[ParamFwdReg]);
759 }
760 }
761 }
762 }
763
764
765 for (auto ParamFwdReg : FwdRegDefs)
766 ForwardedRegWorklist.erase(ParamFwdReg);
767
768
769 ClobberedRegUnits.insert_range(NewClobberedRegUnits);
770
771
772
773 for (auto &New : TmpWorklistItems)
774 addToFwdRegWorklist(ForwardedRegWorklist, New.first, EmptyExpr, New.second);
775 TmpWorklistItems.clear();
776}
777
782
784 return true;
785
786
787
788
790 return false;
791
792 if (ForwardedRegWorklist.empty())
793 return false;
794
795
797 return true;
798
799 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);
800
801 return true;
802}
803
804
805
810 auto CSInfo = CalleesMap.find(CallMI);
811
812
813 if (CSInfo == CalleesMap.end())
814 return;
815
817
818
820
822
825
826
827 for (const auto &ArgReg : CSInfo->second.ArgRegPairs) {
828 bool InsertedReg =
829 ForwardedRegWorklist.insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})
830 .second;
831 assert(InsertedReg && "Single register used to forward two arguments?");
832 (void)InsertedReg;
833 }
834
835
836 for (const auto &MO : CallMI->uses())
837 if (MO.isReg() && MO.isUndef())
838 ForwardedRegWorklist.erase(MO.getReg());
839
840
841
842
843
844
845
846
847
848 bool ShouldTryEmitEntryVals = MBB->getIterator() == MF->begin();
849
850
853 auto Suc = std::next(CallMI->getIterator());
854
856 (void)BundleEnd;
857 assert(std::next(Suc) == BundleEnd &&
858 "More than one instruction in call delay slot");
859
860 if ((&*Suc, ForwardedRegWorklist, Params, ClobberedRegUnits))
861 return;
862 }
863
864
865 for (; I != MBB->rend(); ++I) {
866
867 if ((&*I, ForwardedRegWorklist, Params, ClobberedRegUnits))
868 return;
869 }
870
871
872 if (ShouldTryEmitEntryVals) {
873
876 for (auto &RegEntry : ForwardedRegWorklist) {
879 }
880 }
881}
882
883void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
886
887
888 if (.areAllCallsDescribed() ||
.isDefinition())
889 return;
890
891
892
893
894
895 CU.addFlag(ScopeDIE, CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));
896
898 assert(TII && "TargetInstrInfo not found: cannot label tail calls");
899
900
901 auto delaySlotSupported = [&](const MachineInstr &MI) {
902 if (.isBundledWithSucc())
903 return false;
904 auto Suc = std::next(MI.getIterator());
906 (void)CallInstrBundle;
908 (void)DelaySlotBundle;
909
910
911
912
915 "Call and its successor instruction don't have same label after.");
916 return true;
917 };
918
919
920 for (const MachineBasicBlock &MBB : MF) {
921 for (const MachineInstr &MI : MBB.instrs()) {
922
923
924
925 if (MI.isBundle())
926 continue;
927
928
929
930 if (.isCandidateForAdditionalCallInfo())
931 continue;
932
933
934
936 continue;
937
938
939 if (MI.hasDelaySlot() && !delaySlotSupported(*&MI))
940 return;
941
943
944
945
946
948 bool PhysRegCalleeOperand =
950
951
952 if (CalleeOp.getOperandNo() < MI.getDesc().operands().size()) {
953 const MCOperandInfo &MCOI =
955 PhysRegCalleeOperand =
957 }
958
959 unsigned CallReg = 0;
960 const DISubprogram *CalleeSP = nullptr;
961 const Function *CalleeDecl = nullptr;
962 if (PhysRegCalleeOperand) {
963 CallReg = CalleeOp.getReg();
964 } else if (CalleeOp.isGlobal()) {
966 if (CalleeDecl)
967 CalleeSP = CalleeDecl->getSubprogram();
968 }
969
970
971
972 if (CalleeSP == nullptr && CallReg == 0 && AllocSiteTy == nullptr)
973 continue;
974
975
976
978
979
980
981
982 const MachineInstr *TopLevelCallMI =
984
985
986
987
988
989 const MCSymbol *PCAddr = (!IsTail || CU.useGNUAnalogForDwarf5Feature())
991 : nullptr;
992
993
994
997
998 assert((IsTail || PCAddr) && "Non-tail call without return PC");
999
1000 LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> "
1001 << (CalleeDecl ? CalleeDecl->getName()
1002 : StringRef(MF.getSubtarget()
1003 .getRegisterInfo()
1004 ->getName(CallReg)))
1005 << (IsTail ? " [IsTail]" : "") << "\n");
1006
1007 DIE &CallSiteDIE =
1008 CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, CalleeDecl, IsTail,
1009 PCAddr, CallAddr, CallReg, AllocSiteTy);
1010
1011
1014
1016 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);
1017 }
1018 }
1019 }
1020}
1021
1023 if (.hasDwarfPubSections())
1024 return;
1025
1026 U.addFlag(D, dwarf::DW_AT_GNU_pubnames);
1027}
1028
1029void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,
1033
1037 std::string ProducerWithFlags = Producer.str() + " " + Flags.str();
1038 NewCU.addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);
1039 } else
1040 NewCU.addString(Die, dwarf::DW_AT_producer, Producer);
1041
1043 NewCU.addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,
1044 Lang.getName());
1045
1046 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)
1047 NewCU.addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,
1048 LangVersion);
1049 } else {
1050 NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
1051 Lang.getName());
1052 }
1053
1054 NewCU.addString(Die, dwarf::DW_AT_name, FN);
1055 StringRef SysRoot = DIUnit->getSysRoot();
1056 if (!SysRoot.empty())
1057 NewCU.addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);
1058 StringRef SDK = DIUnit->getSDK();
1059 if (!SDK.empty())
1060 NewCU.addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);
1061
1063
1066
1068
1069
1070
1071 if (!CompilationDir.empty())
1072 NewCU.addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
1073 addGnuPubAttributes(NewCU, Die);
1074 }
1075
1078 NewCU.addFlag(Die, dwarf::DW_AT_APPLE_optimized);
1079
1081 if (.empty())
1082 NewCU.addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
1083
1085 NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
1086 dwarf::DW_FORM_data1, RVer);
1087 }
1088
1090
1091 NewCU.addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,
1094
1096 ? dwarf::DW_AT_dwo_name
1097 : dwarf::DW_AT_GNU_dwo_name;
1099 }
1100 }
1101}
1102
1103
1105DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
1106 if (auto *CU = CUMap.lookup(DIUnit))
1107 return *CU;
1108
1113 !CUMap.empty()) {
1114 return *CUMap.begin()->second;
1115 }
1117
1118 auto OwnedUnit = std::make_unique(
1119 InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);
1120 DwarfCompileUnit &NewCU = *OwnedUnit;
1121 InfoHolder.addUnit(std::move(OwnedUnit));
1122
1123
1124
1125
1126
1127 if (->OutStreamer->hasRawTextSupport() || SingleCU)
1128 Asm->OutStreamer->emitDwarfFile0Directive(
1131
1133 NewCU.setSkeleton(constructSkeletonCU(NewCU));
1134 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());
1135 } else {
1136 finishUnitAttributes(DIUnit, NewCU);
1137 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
1138 }
1139
1140 CUMap.insert({DIUnit, &NewCU});
1141 CUDieMap.insert({&NewCU.getUnitDie(), &NewCU});
1142 return NewCU;
1143}
1144
1145
1150
1151
1152
1153
1154
1155 if (.Expr ||
.Expr)
1156 return !.Expr;
1157 auto FragmentA = A.Expr->getFragmentInfo();
1158 auto FragmentB = B.Expr->getFragmentInfo();
1159 if (!FragmentA || !FragmentB)
1160 return !!FragmentB;
1161 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
1162 });
1167 }),
1168 GVEs.end());
1169 return GVEs;
1170}
1171
1172
1173
1174
1177
1178 if ()
1179 return;
1180
1181 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),
1182 M->debug_compile_units_end());
1183 if (NumDebugCUs == 0)
1184 return;
1185
1186 assert(NumDebugCUs > 0 && "Asm unexpectedly initialized");
1187 SingleCU = NumDebugCUs == 1;
1189 GVMap;
1192 Global.getDebugInfo(GVs);
1193 for (auto *GVE : GVs)
1194 GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()});
1195 }
1196
1197
1198
1199
1202 .setStringOffsetsStartSym(Asm->createTempSymbol("str_offsets_base"));
1203
1204
1205
1206
1210 Asm->createTempSymbol("rnglists_table_base"));
1211
1213 InfoHolder.setRnglistsTableBaseSym(
1214 Asm->createTempSymbol("rnglists_dwo_table_base"));
1215 }
1216
1217
1218
1219 AddrPool.setLabel(Asm->createTempSymbol("addr_table_base"));
1220 DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base"));
1221
1222 for (DICompileUnit *CUNode : M->debug_compile_units()) {
1223 if (CUNode->getImportedEntities().empty() &&
1224 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
1225 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
1226 continue;
1227
1229
1230
1231 for (auto *GVE : CUNode->getGlobalVariables()) {
1232
1233
1234
1235 auto &GVMapEntry = GVMap[GVE->getVariable()];
1236 auto *Expr = GVE->getExpression();
1237 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
1238 GVMapEntry.push_back({nullptr, Expr});
1239 }
1240
1242 for (auto *GVE : CUNode->getGlobalVariables()) {
1244 if (Processed.insert(GV).second)
1245 CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV]));
1246 }
1247
1248 for (auto *Ty : CUNode->getEnumTypes())
1250
1251 for (auto *Ty : CUNode->getRetainedTypes()) {
1252
1253
1255
1256 CU.getOrCreateTypeDIE(RT);
1257 }
1258 }
1259}
1260
1261void DwarfDebug::finishEntityDefinitions() {
1262 for (const auto &Entity : ConcreteEntities) {
1263 DIE *Die = Entity->getDIE();
1265
1266
1267
1270 Unit->finishEntityDefinition(Entity.get());
1271 }
1272}
1273
1274void DwarfDebug::finishSubprogramDefinitions() {
1275 for (const DISubprogram *SP : ProcessedSPNodes) {
1278 getOrCreateDwarfCompileUnit(SP->getUnit()),
1279 [&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); });
1280 }
1281}
1282
1283void DwarfDebug::finalizeModuleInfo() {
1284 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
1285
1286 finishSubprogramDefinitions();
1287
1288 finishEntityDefinitions();
1289
1290 bool HasEmittedSplitCU = false;
1291
1292
1293
1294 for (const auto &P : CUMap) {
1295 auto &TheCU = *P.second;
1296 if (TheCU.getCUNode()->isDebugDirectivesOnly())
1297 continue;
1298 TheCU.attachLexicalScopesAbstractOrigins();
1299
1300
1301 TheCU.constructContainingTypeDIEs();
1302
1303
1304
1305
1306 auto *SkCU = TheCU.getSkeleton();
1307
1308 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();
1309
1310 if (HasSplitUnit) {
1311 (void)HasEmittedSplitCU;
1313 "Multiple CUs emitted into a single dwo file");
1314 HasEmittedSplitCU = true;
1316 ? dwarf::DW_AT_dwo_name
1317 : dwarf::DW_AT_GNU_dwo_name;
1318 finishUnitAttributes(TheCU.getCUNode(), TheCU);
1319 StringRef DWOName = Asm->TM.Options.MCOptions.SplitDwarfFile;
1320 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);
1321 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);
1322
1323
1324
1325
1326 uint64_t ID =
1327 DIEHash(Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());
1329 TheCU.setDWOId(ID);
1330 SkCU->setDWOId(ID);
1331 } else {
1332 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1333 dwarf::DW_FORM_data8, ID);
1334 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
1335 dwarf::DW_FORM_data8, ID);
1336 }
1337
1338 if (getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {
1340 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,
1341 Sym, Sym);
1342 }
1343 } else if (SkCU) {
1344 finishUnitAttributes(SkCU->getCUNode(), *SkCU);
1345 }
1346
1347
1348
1349
1350
1351
1352
1353 DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
1354
1355 if (unsigned NumRanges = TheCU.getRanges().size()) {
1356
1357
1358
1359
1360 if (!(Asm->TM.getTargetTriple().isNVPTX() && tuneForGDB())) {
1362
1363
1364
1365
1366 U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1367 0);
1368 else
1369 U.setBaseAddress(TheCU.getRanges().front().Begin);
1370 U.attachRangesOrLowHighPC(U.getUnitDie(), TheCU.takeRanges());
1371 }
1372 }
1373
1374
1375
1376 if ((HasSplitUnit || getDwarfVersion() >= 5) && !AddrPool.isEmpty())
1377 U.addAddrTableBase();
1378
1380 if (U.hasRangeLists())
1381 U.addRnglistsBase();
1382
1383 if (!DebugLocs.getLists().empty() && ()) {
1384 U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base,
1385 DebugLocs.getSym(),
1387 }
1388 }
1389
1391
1392
1393 if (CUNode->getMacros()) {
1394 if (UseDebugMacroSection) {
1396 TheCU.addSectionDelta(
1397 TheCU.getUnitDie(), dwarf::DW_AT_macros, U.getMacroLabelBegin(),
1399 else {
1401 ? dwarf::DW_AT_macros
1402 : dwarf::DW_AT_GNU_macros;
1403 U.addSectionLabel(U.getUnitDie(), MacrosAttr, U.getMacroLabelBegin(),
1405 }
1406 } else {
1408 TheCU.addSectionDelta(
1409 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1410 U.getMacroLabelBegin(),
1412 else
1413 U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
1414 U.getMacroLabelBegin(),
1416 }
1417 }
1418 }
1419
1420
1421 for (auto *CUNode : MMI->getModule()->debug_compile_units())
1422 if (CUNode->getDWOId())
1423 getOrCreateDwarfCompileUnit(CUNode);
1424
1425
1426 InfoHolder.computeSizeAndOffsets();
1428 SkeletonHolder.computeSizeAndOffsets();
1429
1430
1431
1432 AccelDebugNames.convertDieToOffset();
1433}
1434
1435
1437
1438 if (PrevCU)
1440 PrevCU = nullptr;
1441 assert(CurFn == nullptr);
1443
1444 for (const auto &P : CUMap) {
1447
1448
1449 for (auto *IE : CUNode->getImportedEntities()) {
1451 "Unexpected function-local entity in 'imports' CU field.");
1452 CU->getOrCreateImportedEntityDIE(IE);
1453 }
1454 for (const auto *D : CU->getDeferredLocalDecls()) {
1456 CU->getOrCreateImportedEntityDIE(IE);
1457 else
1459 }
1460
1461
1462 CU->createBaseTypeDIEs();
1463 }
1464
1465
1466
1467 if ( ||
->hasDebugInfo())
1468 return;
1469
1470
1471 finalizeModuleInfo();
1472
1474
1475 emitDebugLocDWO();
1476 else
1477
1478 emitDebugLoc();
1479
1480
1481 emitAbbreviations();
1482
1483
1484 emitDebugInfo();
1485
1486
1487 if (UseARangesSection)
1488 emitDebugARanges();
1489
1490
1491 emitDebugRanges();
1492
1494
1495 emitDebugMacinfoDWO();
1496 else
1497
1498 emitDebugMacinfo();
1499
1500 emitDebugStr();
1501
1503 emitDebugStrDWO();
1504 emitDebugInfoDWO();
1505 emitDebugAbbrevDWO();
1506 emitDebugLineDWO();
1507 emitDebugRangesDWO();
1508 }
1509
1510 emitDebugAddr();
1511
1512
1515 emitAccelNames();
1516 emitAccelObjC();
1517 emitAccelNamespaces();
1518 emitAccelTypes();
1519 break;
1521 emitAccelDebugNames();
1522 break;
1524 break;
1526 llvm_unreachable("Default should have already been resolved.");
1527 }
1528
1529
1530 emitDebugPubSections();
1531
1532
1533
1534}
1535
1536void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
1538 if (CU.getExistingAbstractEntity(Node))
1539 return;
1540
1543 CU.createAbstractEntity(Node, Scope);
1544}
1545
1550
1551
1552void DwarfDebug::collectVariableInfoFromMFTable(
1554 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;
1555 LLVM_DEBUG(dbgs() << "DwarfDebug: collecting variables from MF side table\n");
1556 for (const auto &VI : Asm->MF->getVariableDbgInfo()) {
1557 if (.Var)
1558 continue;
1559 assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
1560 "Expected inlined-at fields to agree");
1561
1562 InlinedEntity Var(VI.Var, VI.Loc->getInlinedAt());
1563 Processed.insert(Var);
1564 LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
1565
1566
1567 if (!Scope) {
1568 LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()
1569 << ", no variable scope found\n");
1570 continue;
1571 }
1572
1573 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());
1574
1575
1576
1577 if (DbgVariable *PreviousLoc = MFVars.lookup(Var)) {
1578 auto *PreviousMMI = std::get_ifLoc::MMI(PreviousLoc);
1579 auto *PreviousEntryValue = std::get_ifLoc::EntryValue(PreviousLoc);
1580
1581 if (PreviousMMI && VI.inStackSlot())
1582 PreviousMMI->addFrameIndexExpr(VI.Expr, VI.getStackSlot());
1583
1584 else if (PreviousEntryValue && VI.inEntryValueRegister())
1585 PreviousEntryValue->addExpr(VI.getEntryValueRegister(), *VI.Expr);
1586 else {
1587
1588
1589
1590 if (PreviousLoc->holdsLoc::MMI())
1591 PreviousLoc->emplaceLoc::EntryValue(VI.getEntryValueRegister(),
1592 *VI.Expr);
1593 LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()
1594 << ", conflicting fragment location types\n");
1595 }
1596 continue;
1597 }
1598
1599 auto RegVar = std::make_unique(
1601 if (VI.inStackSlot())
1602 RegVar->emplaceLoc::MMI(VI.Expr, VI.getStackSlot());
1603 else
1604 RegVar->emplaceLoc::EntryValue(VI.getEntryValueRegister(), *VI.Expr);
1605 LLVM_DEBUG(dbgs() << "Created DbgVariable for " << VI.Var->getName()
1606 << "\n");
1607 InfoHolder.addScopeVariable(Scope, RegVar.get());
1608 MFVars.insert({Var, RegVar.get()});
1609 ConcreteEntities.push_back(std::move(RegVar));
1610 }
1611}
1612
1613
1614
1615
1616
1621 assert(DbgValue->getDebugLoc() && "DBG_VALUE without a debug location");
1625
1626 if (!LScope)
1627 return false;
1628 auto &LSRange = LScope->getRanges();
1629 if (LSRange.size() == 0)
1630 return false;
1631
1632 const MachineInstr *LScopeBegin = LSRange.front().first;
1633
1634
1635
1636 if (!Ordering.isBefore(DbgValue, LScopeBegin)) {
1637
1639 return false;
1640
1642 for (++Pred; Pred != MBB->rend(); ++Pred) {
1644 break;
1645 auto PredDL = Pred->getDebugLoc();
1646 if (!PredDL || Pred->isMetaInstruction())
1647 continue;
1648
1649
1650 if (DL->getScope() == PredDL->getScope())
1651 return false;
1653 if (!PredScope || LScope->dominates(PredScope))
1654 return false;
1655 }
1656 }
1657
1658
1659 if (!RangeEnd)
1660 return true;
1661
1662
1663
1664
1665
1666 if (MBB->pred_empty() &&
1669 return true;
1670
1671
1672 const MachineInstr *LScopeEnd = LSRange.back().second;
1673 if (Ordering.isBefore(RangeEnd, LScopeEnd))
1674 return false;
1675
1676
1677
1678 return true;
1679}
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1716 using OpenRange =
1717 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;
1719 bool isSafeForSingleLocation = true;
1720 const MachineInstr *StartDebugMI = nullptr;
1721 const MachineInstr *EndMI = nullptr;
1722
1723 for (auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {
1724 const MachineInstr *Instr = EI->getInstr();
1725
1726
1727 size_t Index = std::distance(EB, EI);
1728 erase_if(OpenRanges, [&](OpenRange &R) { return R.first <= Index; });
1729
1730
1731
1732 const MCSymbol *StartLabel =
1734 assert(StartLabel &&
1735 "Forgot label before/after instruction starting a range!");
1736
1738 if (std::next(EI) == Entries.end()) {
1739 const MachineBasicBlock &EndMBB = Asm->MF->back();
1740 EndLabel = Asm->MBBSectionRanges[EndMBB.getSectionID()].EndLabel;
1741 if (EI->isClobber())
1742 EndMI = EI->getInstr();
1743 }
1744 else if (std::next(EI)->isClobber())
1746 else
1748 assert(EndLabel && "Forgot label after instruction ending a range!");
1749
1750 if (EI->isDbgValue())
1751 LLVM_DEBUG(dbgs() << "DotDebugLoc: " << *Instr << "\n");
1752
1753
1754
1755
1756 if (EI->isDbgValue()) {
1757
1758
1759
1760
1761
1762
1763 if (->isUndefDebugValue()) {
1766
1767
1768 if (Instr->getDebugExpression()->isFragment())
1769 isSafeForSingleLocation = false;
1770
1771 if (!StartDebugMI)
1772 StartDebugMI = Instr;
1773 } else {
1774 isSafeForSingleLocation = false;
1775 }
1776 }
1777
1778
1779
1780 if (OpenRanges.empty())
1781 continue;
1782
1783
1784 if (StartLabel == EndLabel) {
1785 LLVM_DEBUG(dbgs() << "Omitting location list entry with empty range.\n");
1786 continue;
1787 }
1788
1790 for (auto &R : OpenRanges)
1792
1793
1794
1795
1796
1797
1798 if (Asm->MF->hasBBSections() && StartLabel == Asm->getFunctionBegin() &&
1799 ->getParent()->sameSection(&Asm->MF->front())) {
1800 for (const auto &[MBBSectionId, MBBSectionRange] :
1801 Asm->MBBSectionRanges) {
1802 if (Instr->getParent()->getSectionID() == MBBSectionId) {
1803 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);
1804 break;
1805 }
1806 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,
1807 MBBSectionRange.EndLabel, Values);
1808 }
1809 } else {
1810 DebugLoc.emplace_back(StartLabel, EndLabel, Values);
1811 }
1812
1813
1814
1815 auto CurEntry = DebugLoc.rbegin();
1817 dbgs() << CurEntry->getValues().size() << " Values:\n";
1818 for (auto &Value : CurEntry->getValues())
1820 dbgs() << "-----\n";
1821 });
1822
1823 auto PrevEntry = std::next(CurEntry);
1824 if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))
1826 }
1827
1828 if (!isSafeForSingleLocation ||
1830 return false;
1831
1833 return true;
1834
1835 if (->MF->hasBBSections())
1836 return false;
1837
1838
1839
1840
1841
1842
1843 const MachineBasicBlock *RangeMBB = nullptr;
1844 if (DebugLoc[0].getBeginSym() == Asm->getFunctionBegin())
1845 RangeMBB = &Asm->MF->front();
1846 else
1847 RangeMBB = Entries.begin()->getInstr()->getParent();
1848 auto RangeIt = Asm->MBBSectionRanges.find(RangeMBB->getSectionID());
1849 assert(RangeIt != Asm->MBBSectionRanges.end() &&
1850 "Range MBB not found in MBBSectionRanges!");
1851 auto *CurEntry = DebugLoc.begin();
1852 auto *NextEntry = std::next(CurEntry);
1853 auto NextRangeIt = std::next(RangeIt);
1854 while (NextEntry != DebugLoc.end()) {
1855 if (NextRangeIt == Asm->MBBSectionRanges.end())
1856 return false;
1857
1858
1859
1860
1861
1862 if ((RangeIt->second.EndLabel != Asm->getFunctionEnd() &&
1863 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||
1864 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||
1865 CurEntry->getValues() != NextEntry->getValues())
1866 return false;
1867 RangeIt = NextRangeIt;
1868 NextRangeIt = std::next(RangeIt);
1869 CurEntry = NextEntry;
1870 NextEntry = std::next(CurEntry);
1871 }
1872 return true;
1873}
1874
1880 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node, Scope.getScopeNode());
1882 ConcreteEntities.push_back(
1884 Location));
1885 InfoHolder.addScopeVariable(&Scope,
1888 ConcreteEntities.push_back(
1890 Location, Sym));
1891 InfoHolder.addScopeLabel(&Scope,
1893 }
1894 return ConcreteEntities.back().get();
1895}
1896
1897
1901
1902 collectVariableInfoFromMFTable(TheCU, Processed);
1903
1905 InlinedEntity IV = I.first;
1907 continue;
1908
1909
1910 const auto &HistoryMapEntries = I.second;
1911
1912
1913
1914 if (.hasNonEmptyLocation(HistoryMapEntries))
1915 continue;
1916
1917 LexicalScope *Scope = nullptr;
1919 if (const DILocation *IA = IV.second)
1921 else
1923
1924 if (!Scope)
1925 continue;
1926
1928 DbgVariable *RegVar = cast(createConcreteEntity(TheCU,
1929 *Scope, LocalVar, IV.second));
1930
1931 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
1932 assert(MInsn->isDebugValue() && "History must begin with debug value");
1933
1934
1935
1936
1937 size_t HistSize = HistoryMapEntries.size();
1938 bool SingleValueWithClobber =
1939 HistSize == 2 && HistoryMapEntries[1].isClobber();
1940 if (HistSize == 1 || SingleValueWithClobber) {
1941 const auto *End =
1942 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr;
1944 RegVar->emplaceLoc::Single(MInsn);
1945 continue;
1946 }
1947 }
1948
1949
1950 DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar);
1951
1952
1954 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);
1955
1956
1957
1958
1959 if (isValidSingleLocation) {
1960 RegVar->emplaceLoc::Single(Entries[0].getValues()[0]);
1961 continue;
1962 }
1963
1964
1965
1966
1969
1970
1971 for (auto &Entry : Entries)
1973 }
1974
1975
1976
1978 InlinedEntity IL = I.first;
1979 const MachineInstr *MI = I.second;
1980 if (MI == nullptr)
1981 continue;
1982
1983 LexicalScope *Scope = nullptr;
1985
1986 const DILocalScope *LocalScope =
1987 Label->getScope()->getNonLexicalBlockFileScope();
1988
1989 if (const DILocation *IA = IL.second)
1990 Scope = LScopes.findInlinedScope(LocalScope, IA);
1991 else
1992 Scope = LScopes.findLexicalScope(LocalScope);
1993
1994 if (!Scope)
1995 continue;
1996
1997 Processed.insert(IL);
1998
1999
2000
2002 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
2003 }
2004
2005
2006 for (const DINode *DN : SP->getRetainedNodes()) {
2009 if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
2010 continue;
2011 LexicalScope *LexS = LScopes.findLexicalScope(LS);
2012 if (LexS)
2013 createConcreteEntity(TheCU, *LexS, DN, nullptr);
2014 } else {
2015 LocalDeclsPerLS[LS].insert(DN);
2016 }
2017 }
2018}
2019
2020
2024 bool NoDebug =
2026
2027
2028 auto delaySlotSupported = [](const MachineInstr &MI) {
2029 if (.isBundledWithSucc())
2030 return false;
2031 auto Suc = std::next(MI.getIterator());
2032 (void)Suc;
2033
2034
2035
2036 assert(Suc->isBundledWithPred() &&
2037 "Call bundle instructions are out of order");
2038 return true;
2039 };
2040
2041
2042 if (!NoDebug && SP->areAllCallsDescribed() &&
2044 (->hasDelaySlot() || delaySlotSupported(*MI))) {
2046 bool IsTail = TII->isTailCall(*MI);
2047
2048
2049 if (IsTail)
2051
2052
2053
2055 }
2056
2059 return;
2060
2061 if (NoDebug)
2062 return;
2063
2064 auto RecordLineZero = [&]() {
2065
2066
2067
2068 const MDNode *Scope = nullptr;
2069 unsigned Column = 0;
2073 }
2074 recordSourceLine(0, Column, Scope, 0);
2075 };
2076
2077
2078
2079 unsigned LastAsmLine =
2080 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
2081
2082
2083
2084
2085 if (MI->isMetaInstruction())
2086 return;
2088
2090 RecordLineZero();
2091 return;
2092 }
2093
2095 unsigned Flags = 0;
2096
2100
2103 }
2104 }
2105
2106 auto RecordSourceLine = [this](auto &DL, auto Flags) {
2108 if (Asm->OutStreamer->isVerboseAsm()) {
2110 DL.print(OS);
2111 }
2112 recordSourceLine(DL.getLine(), DL.getCol(), DL.getScope(), Flags,
2113 LocationString);
2114 };
2115
2116
2117
2118
2119
2120
2121 bool ScopeUsesKeyInstructions =
2123 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();
2124
2125 bool IsKey = false;
2126 if (ScopeUsesKeyInstructions && DL && DL.getLine())
2127 IsKey = KeyInstructions.contains(MI);
2128
2130
2131
2132
2133 assert(MI->getParent() == &*MI->getMF()->begin());
2134 recordSourceLine(SP->getScopeLine(), 0, SP,
2136 return;
2137 }
2138
2139 bool PrevInstInSameSection =
2141 PrevInstBB->getSectionID() == MI->getParent()->getSectionID());
2142 bool ForceIsStmt = ForceIsStmtInstrs.contains(MI);
2143 if (PrevInstInSameSection && !ForceIsStmt && DL.isSameSourceLocation(PrevInstLoc)) {
2144
2145 if ()
2146 return;
2147
2148
2149
2150 if (!IsKey) {
2151
2152
2153 if ((LastAsmLine == 0 && DL.getLine() != 0) || Flags) {
2154
2155 RecordSourceLine(DL, Flags);
2156 }
2157 return;
2158 }
2159 }
2160
2161 if () {
2162
2163
2164
2165
2166
2167
2168 if (LastAsmLine == 0)
2169 return;
2170
2172 return;
2173
2174
2175
2176
2177
2178
2179
2182 RecordLineZero();
2183 return;
2184 }
2185
2186
2187
2188
2189 if (DL.getLine() == 0 && LastAsmLine == 0)
2190 return;
2194 }
2195
2196 if (ScopeUsesKeyInstructions) {
2197 if (IsKey)
2199 } else {
2200
2201
2203 if (DL.getLine() && (DL.getLine() != OldLine || ForceIsStmt))
2205 }
2206
2207 RecordSourceLine(DL, Flags);
2208
2209
2210 if (DL.getLine())
2212}
2213
2214
2215
2216
2217
2218
2219static std::pair<const MachineInstr *, bool>
2221
2222
2224 const MachineInstr *NonTrivialInst = nullptr;
2227
2228
2229
2230 bool IsEmptyPrologue =
2231 !(F.hasPrologueData() || F.getMetadata(LLVMContext::MD_func_sanitize));
2232
2233
2234
2236 -> std::optional<std::pair<const MachineInstr *, bool>> {
2237
2238 bool isCopy = (TII.isCopyInstr(MI) ? true : false);
2239 bool isTrivRemat = TII.isTriviallyReMaterializable(MI);
2241
2242 if (!isFrameSetup && MI.getDebugLoc()) {
2243
2244
2245
2246
2247
2248 if (MI.getDebugLoc().getLine())
2249 return std::make_pair(&MI, IsEmptyPrologue);
2250 }
2251
2252
2253
2254 if ( && !isTrivRemat && !isFrameSetup && !NonTrivialInst)
2255 NonTrivialInst = &MI;
2256
2257 IsEmptyPrologue = false;
2258 return std::nullopt;
2259 };
2260
2261
2262
2263
2264
2265
2266 auto CurBlock = MF->begin();
2267 auto CurInst = CurBlock->begin();
2268
2269
2270
2271 while (CurBlock->empty())
2272 CurInst = (++CurBlock)->begin();
2273 assert(CurInst != CurBlock->end());
2274
2275
2276
2277 auto getNextInst = [&CurBlock, &CurInst, MF]() -> bool {
2278
2279 if (CurInst->isTerminator()) {
2280
2281
2282
2283 return false;
2284 }
2285
2286
2287
2288 if (CurBlock->pred_size() > 1)
2289 return false;
2290
2291
2292
2293
2294
2295
2296
2297 do {
2298 ++CurBlock;
2299 if (CurBlock == MF->end())
2300 return false;
2301 } while (CurBlock->empty());
2302 CurInst = CurBlock->begin();
2303 return true;
2304 };
2305
2306 while (true) {
2307
2308 if (!CurInst->isMetaInstruction()) {
2309 auto FoundInst = ExamineInst(*CurInst);
2310 if (FoundInst)
2311 return *FoundInst;
2312 }
2313
2314
2315
2316
2317
2318
2319
2320 if (CurInst->isCall()) {
2321 if (const DILocation *Loc = CurInst->getDebugLoc().get();
2322 Loc && Loc->getLine() == 0) {
2323
2324 unsigned ScopeLine = SP->getScopeLine();
2327 const_cast<MachineInstr *>(&*CurInst)->setDebugLoc(ScopeLineDILoc);
2328
2329
2330 return std::make_pair(&*CurInst, false);
2331 }
2332 }
2333
2334
2335
2336 auto NextInst = std::next(CurInst);
2337 if (NextInst != CurInst->getParent()->end()) {
2338
2339 CurInst = NextInst;
2340 continue;
2341 }
2342
2343 if (!getNextInst())
2344 break;
2345 }
2346
2347
2348
2349
2350
2351
2352
2353
2354 if (NonTrivialInst && NonTrivialInst->getParent() == &*MF->begin()) {
2355 IsEmptyPrologue = NonTrivialInst == &*MF->begin()->begin();
2356 return std::make_pair(NonTrivialInst, IsEmptyPrologue);
2357 }
2358
2359
2360 return std::make_pair(nullptr, IsEmptyPrologue);
2361}
2362
2363
2364
2366 const MDNode *S, unsigned Flags, unsigned CUID,
2368 ArrayRef<std::unique_ptr> DCUs,
2371 unsigned FileNo = 1;
2374 Fn = Scope->getFilename();
2375 if (Line != 0 && DwarfVersion >= 4)
2378
2380 .getOrCreateSourceID(Scope->getFile());
2381 }
2382 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,
2383 Discriminator, Fn, Comment);
2384}
2385
2388
2390 return nullptr;
2391
2392 std::pair<const MachineInstr *, bool> PrologEnd = findPrologueEndLoc(&MF);
2394 bool IsEmptyPrologue = PrologEnd.second;
2395
2396
2397 if (IsEmptyPrologue) {
2398
2399
2401
2402
2403
2405 if ( || DL->getLine() != 0)
2407
2408
2410 }
2411 }
2412
2413
2414
2416 (void)getOrCreateDwarfCompileUnit(SP->getUnit());
2417
2418
2422}
2423
2424void DwarfDebug::computeKeyInstructions(const MachineFunction *MF) {
2425
2426 KeyInstructions.clear();
2427
2428
2429
2430
2431
2433 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>
2434 GroupCandidates;
2435
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450 for (auto &MBB : *MF) {
2451
2452
2453
2454
2455
2457
2458
2459
2461
2463 if (MI.isMetaInstruction())
2464 continue;
2465
2467 if ( ||
->getLine())
2468 continue;
2469
2470
2472 Buoy = &MI;
2473 BuoyAtom = 0;
2474 }
2475
2476
2477
2478 bool IsCallLike = MI.isCall() || TII.isTailCall(MI);
2479 if (IsCallLike) {
2480
2481
2482
2483 KeyInstructions.insert(Buoy);
2484
2485
2486 Buoy = nullptr;
2487 BuoyAtom = 0;
2488
2489 if (->getAtomGroup() ||
->getAtomRank())
2490 continue;
2491 }
2492
2493 auto *InlinedAt = Loc->getInlinedAt();
2496 if (!Group || !Rank)
2497 continue;
2498
2499
2500 if (BuoyAtom && BuoyAtom != Group) {
2501 Buoy = &MI;
2502 BuoyAtom = Group;
2503 }
2504
2505 auto &[CandidateRank, CandidateInsts] =
2506 GroupCandidates[{InlinedAt, Group}];
2507
2508
2509
2510
2511
2512 assert((CandidateRank == 0 && CandidateInsts.empty()) ||
2513 (CandidateRank != 0 && !CandidateInsts.empty()));
2514
2515 assert(Rank && "expected nonzero rank");
2516
2517
2518 if (CandidateRank && CandidateRank < Rank)
2519 continue;
2520
2521
2522
2523
2524
2525 if (CandidateRank == Rank)
2526 llvm::remove_if(CandidateInsts, [&MI](const MachineInstr *Candidate) {
2527 return MI.getParent() == Candidate->getParent();
2528 });
2529 else if (CandidateRank > Rank)
2530 CandidateInsts.clear();
2531
2532 if (Buoy) {
2533
2534 CandidateInsts.push_back(Buoy);
2535 CandidateRank = Rank;
2536
2539 } else {
2540
2541
2543 if (CandidateInsts.empty())
2544 CandidateRank = 0;
2545 }
2546 }
2547 }
2548
2549 for (const auto &[_, Insts] : GroupCandidates.values())
2550 for (auto *I : Insts)
2551 KeyInstructions.insert(I);
2552}
2553
2554
2555
2556
2557
2558void DwarfDebug::findForceIsStmtInstrs(const MachineFunction *MF) {
2559 ForceIsStmtInstrs.clear();
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2588
2589
2590
2591 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;
2592 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;
2593
2594
2595 for (auto &MBB : *const_cast<MachineFunction *>(MF)) {
2597 continue;
2599 if (MI.getDebugLoc() && MI.getDebugLoc()->getLine()) {
2601 PotentialIsStmtMBBInstrs.insert({&MBB, &MI});
2602 break;
2603 }
2604 }
2605 }
2606
2607
2608
2609
2610
2611
2612 for (auto *MBB : PredMBBsToExamine) {
2613 auto CheckMBBEdge = [&](MachineBasicBlock *Succ, unsigned OutgoingLine) {
2614 auto MBBInstrIt = PotentialIsStmtMBBInstrs.find(Succ);
2615 if (MBBInstrIt == PotentialIsStmtMBBInstrs.end())
2616 return;
2617 MachineInstr *MI = MBBInstrIt->second;
2618 if (MI->getDebugLoc()->getLine() == OutgoingLine)
2619 return;
2620 PotentialIsStmtMBBInstrs.erase(MBBInstrIt);
2621 ForceIsStmtInstrs.insert(MI);
2622 };
2623
2624
2625
2628 CheckMBBEdge(Succ, 0);
2629 continue;
2630 }
2631
2632
2634 return PotentialIsStmtMBBInstrs.contains(SuccMBB);
2635 }))
2636 continue;
2637
2638
2641 {
2642 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
2645
2646
2647
2648
2649 if (!AnalyzeFailed && .empty() && FBB != nullptr &&
2652 assert(MIIt->isBranch() && "Bad result from analyzeBranch?");
2653 CheckMBBEdge(FBB, FBBLine);
2654 ++MIIt;
2656 } else {
2657
2659 }
2660 }
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677 unsigned LastLine = 0;
2678 while (MIIt != MBB->rend()) {
2679 if (auto DL = MIIt->getDebugLoc(); DL && DL->getLine()) {
2680 LastLine = DL->getLine();
2681 break;
2682 }
2683 ++MIIt;
2684 }
2685 for (auto *Succ : SuccessorBBs)
2686 CheckMBBEdge(Succ, LastLine);
2687 }
2688}
2689
2690
2691
2693 CurFn = MF;
2694
2696 assert(LScopes.empty() || SP == LScopes.getCurrentFunctionScope()->getScopeNode());
2698 return;
2699
2701 FunctionLineTableLabel = CU.emitFuncLineTableOffsets()
2702 ? Asm->OutStreamer->emitLineTableLabel()
2703 : nullptr;
2704
2705 Asm->OutStreamer->getContext().setDwarfCompileUnitID(
2707
2708
2710 *MF, Asm->OutStreamer->getContext().getDwarfCompileUnitID());
2711
2712
2713
2714
2716 computeKeyInstructions(MF);
2717 findForceIsStmtInstrs(MF);
2718}
2719
2720unsigned
2722
2723
2724
2725 if (Asm->OutStreamer->hasRawTextSupport())
2726
2727 return 0;
2728 else
2729 return CU.getUniqueID();
2730}
2731
2733 const auto &CURanges = CU->getRanges();
2734 auto &LineTable = Asm->OutStreamer->getContext().getMCDwarfLineTable(
2736
2737 LineTable.getMCLineSections().addEndEntry(
2738 const_cast<MCSymbol *>(CURanges.back().End));
2739}
2740
2742
2743
2744
2745
2746 if (PrevCU)
2748 PrevCU = nullptr;
2749 CurFn = nullptr;
2750}
2751
2752
2756
2757 assert(CurFn == MF &&
2758 "endFunction should be called with the same function as beginFunction");
2759
2760
2761 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
2762
2765 DwarfCompileUnit &TheCU = getOrCreateDwarfCompileUnit(SP->getUnit());
2768 CurFn = nullptr;
2769 return;
2770 }
2771
2773 collectEntityInfo(TheCU, SP, Processed);
2774
2775
2776
2777 for (const auto &R : Asm->MBBSectionRanges)
2778 TheCU.addRange({R.second.BeginLabel, R.second.EndLabel});
2779
2780
2781
2782
2785 LScopes.getAbstractScopesList().empty() && !IsDarwin) {
2786 for (const auto &R : Asm->MBBSectionRanges)
2788
2789 assert(InfoHolder.getScopeVariables().empty());
2791 CurFn = nullptr;
2792 return;
2793 }
2794
2795#ifndef NDEBUG
2796 size_t NumAbstractSubprograms = LScopes.getAbstractScopesList().size();
2797#endif
2800 for (const DINode *DN : SP->getRetainedNodes()) {
2802
2803 auto *LexS = LScopes.getOrCreateAbstractScope(LS);
2804 assert(LexS && "Expected the LexicalScope to be created.");
2806
2807 if (!Processed.insert(InlinedEntity(DN, nullptr)).second ||
2809 continue;
2811 } else {
2812
2813 LocalDeclsPerLS[LS].insert(DN);
2814 }
2816 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
2817 "getOrCreateAbstractScope() inserted an abstract subprogram scope");
2818 }
2819 constructAbstractSubprogramScopeDIE(TheCU, AScope);
2820 }
2821
2822 ProcessedSPNodes.insert(SP);
2823 DIE &ScopeDIE =
2826 if (.getAbstractScopesList().empty() &&
2828 SkelCU->constructSubprogramScopeDIE(SP, F, FnScope,
2829 FunctionLineTableLabel);
2830
2831 FunctionLineTableLabel = nullptr;
2832
2833
2834 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);
2835
2836
2837
2838
2839
2840 InfoHolder.getScopeVariables().clear();
2841 InfoHolder.getScopeLabels().clear();
2842 LocalDeclsPerLS.clear();
2844 CurFn = nullptr;
2845}
2846
2847
2848
2849void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
2850 unsigned Flags, StringRef Location) {
2852 Asm->OutStreamer->getContext().getDwarfCompileUnitID(),
2854}
2855
2856
2857
2858
2859
2860
2861void DwarfDebug::emitDebugInfo() {
2863 Holder.emitUnits( false);
2864}
2865
2866
2867void DwarfDebug::emitAbbreviations() {
2868 DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
2869
2870 Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection());
2871}
2872
2873void DwarfDebug::emitStringOffsetsTableHeader() {
2874 DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
2876 *Asm, Asm->getObjFileLowering().getDwarfStrOffSection(),
2878}
2879
2880template
2881void DwarfDebug::emitAccel(AccelTableT &Accel, MCSection *Section,
2883 Asm->OutStreamer->switchSection(Section);
2884
2885
2887}
2888
2889void DwarfDebug::emitAccelDebugNames() {
2890
2891 if (getUnits().empty())
2892 return;
2893
2895}
2896
2897
2898void DwarfDebug::emitAccelNames() {
2899 emitAccel(AccelNames, Asm->getObjFileLowering().getDwarfAccelNamesSection(),
2900 "Names");
2901}
2902
2903
2904
2905void DwarfDebug::emitAccelObjC() {
2906 emitAccel(AccelObjC, Asm->getObjFileLowering().getDwarfAccelObjCSection(),
2907 "ObjC");
2908}
2909
2910
2911void DwarfDebug::emitAccelNamespaces() {
2912 emitAccel(AccelNamespace,
2913 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),
2914 "namespac");
2915}
2916
2917
2918void DwarfDebug::emitAccelTypes() {
2919 emitAccel(AccelTypes, Asm->getObjFileLowering().getDwarfAccelTypesSection(),
2920 "types");
2921}
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2939 const DIE *Die) {
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949 if (Die->getTag() == dwarf::DW_TAG_compile_unit)
2953
2954
2955
2957 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();
2958 if (SpecDIE.findAttribute(dwarf::DW_AT_external))
2960 } else if (Die->findAttribute(dwarf::DW_AT_external))
2962
2963 switch (Die->getTag()) {
2964 case dwarf::DW_TAG_class_type:
2965 case dwarf::DW_TAG_structure_type:
2966 case dwarf::DW_TAG_union_type:
2967 case dwarf::DW_TAG_enumeration_type:
2972 case dwarf::DW_TAG_typedef:
2973 case dwarf::DW_TAG_base_type:
2974 case dwarf::DW_TAG_subrange_type:
2975 case dwarf::DW_TAG_template_alias:
2977 case dwarf::DW_TAG_namespace:
2979 case dwarf::DW_TAG_subprogram:
2981 case dwarf::DW_TAG_variable:
2983 case dwarf::DW_TAG_enumerator:
2986 default:
2988 }
2989}
2990
2991
2992
2993void DwarfDebug::emitDebugPubSections() {
2994 for (const auto &NU : CUMap) {
2995 DwarfCompileUnit *TheU = NU.second;
2997 continue;
2998
3001
3002 Asm->OutStreamer->switchSection(
3003 GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
3004 : Asm->getObjFileLowering().getDwarfPubNamesSection());
3005 emitDebugPubSection(GnuStyle, "Names", TheU, TheU->getGlobalNames());
3006
3007 Asm->OutStreamer->switchSection(
3008 GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
3009 : Asm->getObjFileLowering().getDwarfPubTypesSection());
3010 emitDebugPubSection(GnuStyle, "Types", TheU, TheU->getGlobalTypes());
3011 }
3012}
3013
3014void DwarfDebug::emitSectionReference(const DwarfCompileUnit &CU) {
3016 Asm->emitDwarfOffset(CU.getSection()->getBeginSymbol(),
3017 CU.getDebugSectionOffset());
3018 else
3019 Asm->emitDwarfSymbolReference(CU.getLabelBegin());
3020}
3021
3022void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
3027
3028
3029 MCSymbol *EndLabel = Asm->emitDwarfUnitLength(
3030 "pub" + Name, "Length of Public " + Name + " Info");
3031
3032 Asm->OutStreamer->AddComment("DWARF Version");
3034
3035 Asm->OutStreamer->AddComment("Offset of Compilation Unit Info");
3036 emitSectionReference(*TheU);
3037
3038 Asm->OutStreamer->AddComment("Compilation Unit Length");
3039 Asm->emitDwarfLengthOrOffset(TheU->getLength());
3040
3041
3043 for (const auto &GI : Globals)
3046 return A.second->getOffset() < B.second->getOffset();
3047 });
3048 for (const auto &[Name, Entity] : Vec) {
3049 Asm->OutStreamer->AddComment("DIE offset");
3050 Asm->emitDwarfLengthOrOffset(Entity->getOffset());
3051
3052 if (GnuStyle) {
3054 Asm->OutStreamer->AddComment(
3057 Asm->emitInt8(Desc.toBits());
3058 }
3059
3060 Asm->OutStreamer->AddComment("External Name");
3061 Asm->OutStreamer->emitBytes(StringRef(Name.data(), Name.size() + 1));
3062 }
3063
3064 Asm->OutStreamer->AddComment("End Mark");
3065 Asm->emitDwarfLengthOrOffset(0);
3066 Asm->OutStreamer->emitLabel(EndLabel);
3067}
3068
3069
3070void DwarfDebug::emitDebugStr() {
3071 MCSection *StringOffsetsSection = nullptr;
3073 emitStringOffsetsTableHeader();
3074 StringOffsetsSection = Asm->getObjFileLowering().getDwarfStrOffSection();
3075 }
3076 DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
3077 Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection(),
3078 StringOffsetsSection, true);
3079}
3080
3084 auto &&Comments = DebugLocs.getComments(Entry);
3085 auto Comment = Comments.begin();
3086 auto End = Comments.end();
3087
3088
3089
3090
3091
3092
3093 unsigned PtrSize = Asm->MAI->getCodePointerSize();
3095 DebugLocs.getBytes(Entry).size()),
3096 Asm->getDataLayout().isLittleEndian(), PtrSize);
3098
3101 for (const auto &Op : Expr) {
3102 assert(Op.getCode() != dwarf::DW_OP_const_type &&
3103 "3 operand ops not yet supported");
3104 assert(.getSubCode() && "SubOps not yet supported");
3105 Streamer.emitInt8(Op.getCode(), Comment != End ? *(Comment++) : "");
3107 for (unsigned I = 0; I < Op.getDescription().Op.size(); ++I) {
3108 if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) {
3110 Streamer.emitDIERef(*CU->ExprRefedBaseTypes[Op.getRawOperand(I)].Die);
3111
3112 for (unsigned J = 0; J < Length; ++J)
3113 if (Comment != End)
3114 Comment++;
3115 } else {
3117 Streamer.emitInt8(Data.getData()[J], Comment != End ? *(Comment++) : "");
3118 }
3119 Offset = Op.getOperandEndOffset(I);
3120 }
3122 }
3123}
3124
3128 auto *DIExpr = Value.getExpression();
3131
3132
3133
3134 if (DIExpr && DIExpr->isEntryValue()) {
3135
3136
3137 assert(Value.getLocEntries().size() == 1);
3138 assert(Value.getLocEntries()[0].isLocation());
3140 DwarfExpr.setLocation(Location, DIExpr);
3141
3143
3146 return;
3147 return DwarfExpr.addExpression(std::move(ExprCursor));
3148 }
3149
3150
3151 auto EmitValueLocEntry = [&DwarfExpr, &BT,
3154 if (Entry.isInt()) {
3155 if (BT && (BT->getEncoding() == dwarf::DW_ATE_boolean))
3157 else if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
3158 BT->getEncoding() == dwarf::DW_ATE_signed_char))
3160 else
3162 } else if (Entry.isLocation()) {
3164 if (Location.isIndirect())
3166
3169 return false;
3170 } else if (Entry.isTargetIndexLocation()) {
3172
3173
3176 } else if (Entry.isConstantFP()) {
3178 !Cursor) {
3179 DwarfExpr.addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
3180 } else if (Entry.getConstantFP()
3181 ->getValueAPF()
3182 .bitcastToAPInt()
3183 .getBitWidth() <= 64 ) {
3185 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
3186 } else {
3188 dbgs() << "Skipped DwarfExpression creation for ConstantFP of size"
3189 << Entry.getConstantFP()
3190 ->getValueAPF()
3191 .bitcastToAPInt()
3192 .getBitWidth()
3193 << " bits\n");
3194 return false;
3195 }
3196 }
3197 return true;
3198 };
3199
3200 if (.isVariadic()) {
3201 if (!EmitValueLocEntry(Value.getLocEntries()[0], ExprCursor))
3202 return;
3204 return;
3205 }
3206
3207
3208
3210 return Entry.isLocation() && !Entry.getLoc().getReg();
3211 }))
3212 return;
3213
3215 std::move(ExprCursor),
3216 [EmitValueLocEntry, &Value](unsigned Idx,
3218 return EmitValueLocEntry(Value.getLocEntries()[Idx], Cursor);
3219 });
3220}
3221
3226 assert(!Values.empty() &&
3227 "location list entries without values are redundant");
3228 assert(Begin != End && "unexpected location list entry with empty range");
3233 if (Value.isFragment()) {
3234
3236 return P.isFragment();
3237 }) && "all values are expected to be fragments");
3239
3240 for (const auto &Fragment : Values)
3242
3243 } else {
3244 assert(Values.size() == 1 && "only fragments may have >1 value");
3246 }
3250}
3251
3254
3255 Asm->OutStreamer->AddComment("Loc expr size");
3257 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());
3258 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())
3259 Asm->emitInt16(DebugLocs.getBytes(Entry).size());
3260 else {
3261
3262
3263 Asm->emitInt16(0);
3264 return;
3265 }
3266
3269}
3270
3271
3272
3273
3277
3278 Asm->OutStreamer->AddComment("Offset entry count");
3281
3284 Asm->getDwarfOffsetByteSize());
3285
3286 return TableEnd;
3287}
3288
3289
3290
3291
3295
3297
3298 Asm->OutStreamer->AddComment("Offset entry count");
3299 Asm->emitInt32(DebugLocs.getLists().size());
3300 Asm->OutStreamer->emitLabel(DebugLocs.getSym());
3301
3302 for (const auto &List : DebugLocs.getLists())
3303 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),
3304 Asm->getDwarfOffsetByteSize());
3305
3306 return TableEnd;
3307}
3308
3309template <typename Ranges, typename PayloadEmitter>
3310static void
3313 unsigned OffsetPair, unsigned StartxLength, unsigned StartxEndx,
3315 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {
3316 auto Size = Asm->MAI->getCodePointerSize();
3318
3319
3320 Asm->OutStreamer->emitLabel(Sym);
3321
3322
3323
3325 SectionRanges;
3326
3327 for (const auto &Range : R)
3328 SectionRanges[&Range.Begin->getSection()].push_back(&Range);
3329
3330 const MCSymbol *CUBase = CU.getBaseAddress();
3331 bool BaseIsSet = false;
3332 for (const auto &P : SectionRanges) {
3333 auto *Base = CUBase;
3334 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.tuneForGDB()) ||
3335 (DD.useSplitDwarf() && UseDwarf5 && P.first->isLinkerRelaxable())) {
3336
3337
3338
3339
3340
3341
3342
3343 BaseIsSet = false;
3344 Base = nullptr;
3345 } else if ( && ShouldUseBaseAddress) {
3346 const MCSymbol *Begin = P.second.front()->Begin;
3348 if (!UseDwarf5) {
3349 Base = NewBase;
3350 BaseIsSet = true;
3351 Asm->OutStreamer->emitIntValue(-1, Size);
3352 Asm->OutStreamer->AddComment(" base address");
3353 Asm->OutStreamer->emitSymbolValue(Base, Size);
3354 } else if (NewBase != Begin || P.second.size() > 1) {
3355
3356
3357
3358 Base = NewBase;
3359 BaseIsSet = true;
3360 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));
3361 Asm->emitInt8(BaseAddressx);
3362 Asm->OutStreamer->AddComment(" base address index");
3364 }
3365 } else if (BaseIsSet && !UseDwarf5) {
3366 BaseIsSet = false;
3368 Asm->OutStreamer->emitIntValue(-1, Size);
3369 Asm->OutStreamer->emitIntValue(0, Size);
3370 }
3371
3372 for (const auto *RS : P.second) {
3373 const MCSymbol *Begin = RS->Begin;
3374 const MCSymbol *End = RS->End;
3375 assert(Begin && "Range without a begin symbol?");
3376 assert(End && "Range without an end symbol?");
3378 if (UseDwarf5) {
3379
3380 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));
3381 Asm->emitInt8(OffsetPair);
3382 Asm->OutStreamer->AddComment(" starting offset");
3383 Asm->emitLabelDifferenceAsULEB128(Begin, Base);
3384 Asm->OutStreamer->AddComment(" ending offset");
3385 Asm->emitLabelDifferenceAsULEB128(End, Base);
3386 } else {
3387 Asm->emitLabelDifference(Begin, Base, Size);
3388 Asm->emitLabelDifference(End, Base, Size);
3389 }
3390 } else if (UseDwarf5) {
3391
3392
3393
3394
3395
3396
3398 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));
3399 Asm->emitInt8(StartxEndx);
3400 Asm->OutStreamer->AddComment(" start index");
3402 Asm->OutStreamer->AddComment(" end index");
3404 } else {
3405 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));
3406 Asm->emitInt8(StartxLength);
3407 Asm->OutStreamer->AddComment(" start index");
3409 Asm->OutStreamer->AddComment(" length");
3410 Asm->emitLabelDifferenceAsULEB128(End, Begin);
3411 }
3412 } else {
3413 Asm->OutStreamer->emitSymbolValue(Begin, Size);
3414 Asm->OutStreamer->emitSymbolValue(End, Size);
3415 }
3416 EmitPayload(*RS);
3417 }
3418 }
3419
3420 if (UseDwarf5) {
3421 Asm->OutStreamer->AddComment(StringifyEnum(EndOfList));
3423 } else {
3424
3425 Asm->OutStreamer->emitIntValue(0, Size);
3426 Asm->OutStreamer->emitIntValue(0, Size);
3427 }
3428}
3429
3430
3434 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,
3435 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,
3438 DD.emitDebugLocEntryLocation(E, List.CU);
3439 });
3440}
3441
3442void DwarfDebug::emitDebugLocImpl(MCSection *Sec) {
3443 if (DebugLocs.getLists().empty())
3444 return;
3445
3446 Asm->OutStreamer->switchSection(Sec);
3447
3448 MCSymbol *TableEnd = nullptr;
3451
3452 for (const auto &List : DebugLocs.getLists())
3454
3455 if (TableEnd)
3456 Asm->OutStreamer->emitLabel(TableEnd);
3457}
3458
3459
3460void DwarfDebug::emitDebugLoc() {
3461 emitDebugLocImpl(
3463 ? Asm->getObjFileLowering().getDwarfLoclistsSection()
3464 : Asm->getObjFileLowering().getDwarfLocSection());
3465}
3466
3467
3468void DwarfDebug::emitDebugLocDWO() {
3470 emitDebugLocImpl(
3471 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());
3472
3473 return;
3474 }
3475
3476 for (const auto &List : DebugLocs.getLists()) {
3477 Asm->OutStreamer->switchSection(
3478 Asm->getObjFileLowering().getDwarfLocDWOSection());
3479 Asm->OutStreamer->emitLabel(List.Label);
3480
3481 for (const auto &Entry : DebugLocs.getEntries(List)) {
3482
3483
3484
3485
3486
3487
3488
3489
3490 Asm->emitInt8(dwarf::DW_LLE_startx_length);
3491 unsigned idx = AddrPool.getIndex(Entry.Begin);
3492 Asm->emitULEB128(idx);
3493
3494
3495 Asm->emitLabelDifference(Entry.End, Entry.Begin, 4);
3497 }
3498 Asm->emitInt8(dwarf::DW_LLE_end_of_list);
3499 }
3500}
3501
3505
3506
3507
3508void DwarfDebug::emitDebugARanges() {
3509 if (ArangeLabels.empty())
3510 return;
3511
3512
3514
3515
3516 for (const SymbolCU &SCU : ArangeLabels) {
3517 if (SCU.Sym->isInSection()) {
3518
3519 MCSection *Section = &SCU.Sym->getSection();
3520 SectionMap[Section].push_back(SCU);
3521 } else {
3522
3523
3524
3525 SectionMap[nullptr].push_back(SCU);
3526 }
3527 }
3528
3529 DenseMap<DwarfCompileUnit *, std::vector> Spans;
3530
3531 for (auto &I : SectionMap) {
3532 MCSection *Section = I.first;
3535
3536
3537
3538 if (!Section) {
3539 for (const SymbolCU &Cur : List) {
3540 ArangeSpan Span;
3541 Span.Start = Cur.Sym;
3542 Span.End = nullptr;
3544 Spans[Cur.CU].push_back(Span);
3545 }
3546 continue;
3547 }
3548
3549
3550 List.push_back(SymbolCU(nullptr, Asm->OutStreamer->endSection(Section)));
3551
3552
3554 for (size_t n = 1, e = List.size(); n < e; n++) {
3555 const SymbolCU &Prev = List[n - 1];
3556 const SymbolCU &Cur = List[n];
3557
3558
3560 ArangeSpan Span;
3561 Span.Start = StartSym;
3564 Spans[Prev.CU].push_back(Span);
3565 StartSym = Cur.Sym;
3566 }
3567 }
3568 }
3569
3570
3571 Asm->OutStreamer->switchSection(
3572 Asm->getObjFileLowering().getDwarfARangesSection());
3573
3574 unsigned PtrSize = Asm->MAI->getCodePointerSize();
3575
3576
3577 std::vector<DwarfCompileUnit *> CUs;
3578 for (const auto &it : Spans) {
3579 DwarfCompileUnit *CU = it.first;
3580 CUs.push_back(CU);
3581 }
3582
3583
3584 llvm::sort(CUs, [](const DwarfCompileUnit *A, const DwarfCompileUnit *B) {
3585 return A->getUniqueID() < B->getUniqueID();
3586 });
3587
3588
3589 for (DwarfCompileUnit *CU : CUs) {
3590 std::vector &List = Spans[CU];
3591
3592
3593 if (auto *Skel = CU->getSkeleton())
3594 CU = Skel;
3595
3596
3597 unsigned ContentSize =
3598 sizeof(int16_t) +
3599 Asm->getDwarfOffsetByteSize() +
3600
3601 sizeof(int8_t) +
3602 sizeof(int8_t);
3603
3604 unsigned TupleSize = PtrSize * 2;
3605
3606
3608 Asm->getUnitLengthFieldByteSize() + ContentSize, Align(TupleSize));
3609
3611 ContentSize += (List.size() + 1) * TupleSize;
3612
3613
3614 Asm->emitDwarfUnitLength(ContentSize, "Length of ARange Set");
3615 Asm->OutStreamer->AddComment("DWARF Arange version number");
3617 Asm->OutStreamer->AddComment("Offset Into Debug Info Section");
3618 emitSectionReference(*CU);
3619 Asm->OutStreamer->AddComment("Address Size (in bytes)");
3620 Asm->emitInt8(PtrSize);
3621 Asm->OutStreamer->AddComment("Segment Size (in bytes)");
3622 Asm->emitInt8(0);
3623
3624 Asm->OutStreamer->emitFill(Padding, 0xff);
3625
3626 for (const ArangeSpan &Span : List) {
3627 Asm->emitLabelReference(Span.Start, PtrSize);
3628
3629
3630
3631
3632
3633
3634 auto SizeRef = SymSize.find(Span.Start);
3635 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {
3636 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);
3637 } else {
3638
3639
3640 uint64_t Size;
3641 if (SizeRef == SymSize.end() || SizeRef->second == 0)
3643 else
3644 Size = SizeRef->second;
3645
3646 Asm->OutStreamer->emitIntValue(Size, PtrSize);
3647 }
3648 }
3649
3650 Asm->OutStreamer->AddComment("ARange terminator");
3651 Asm->OutStreamer->emitIntValue(0, PtrSize);
3652 Asm->OutStreamer->emitIntValue(0, PtrSize);
3653 }
3654}
3655
3656
3659 emitRangeList(DD, Asm, List.Label, List.Ranges, *List.CU,
3660 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,
3661 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,
3663 List.CU->getCUNode()->getRangesBaseAddress() ||
3665 [](auto) {});
3666}
3667
3668void DwarfDebug::emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section) {
3670 return;
3671
3673 assert(!CUMap.empty());
3674 assert(llvm::any_of(CUMap, [](const decltype(CUMap)::value_type &Pair) {
3675 return !Pair.second->getCUNode()->isDebugDirectivesOnly();
3676 }));
3677
3678 Asm->OutStreamer->switchSection(Section);
3679
3680 MCSymbol *TableEnd = nullptr;
3683
3686
3687 if (TableEnd)
3688 Asm->OutStreamer->emitLabel(TableEnd);
3689}
3690
3691
3692
3693void DwarfDebug::emitDebugRanges() {
3694 const auto &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
3695
3696 emitDebugRangesImpl(Holder,
3698 ? Asm->getObjFileLowering().getDwarfRnglistsSection()
3699 : Asm->getObjFileLowering().getDwarfRangesSection());
3700}
3701
3702void DwarfDebug::emitDebugRangesDWO() {
3703 emitDebugRangesImpl(InfoHolder,
3704 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
3705}
3706
3707
3708
3711 enum HeaderFlagMask {
3712#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
3713#include "llvm/BinaryFormat/Dwarf.def"
3714 };
3715 Asm->OutStreamer->AddComment("Macro information version");
3716 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
3717
3718
3719 if (Asm->isDwarf64()) {
3720 Asm->OutStreamer->AddComment("Flags: 64 bit, debug_line_offset present");
3721 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);
3722 } else {
3723 Asm->OutStreamer->AddComment("Flags: 32 bit, debug_line_offset present");
3724 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);
3725 }
3726 Asm->OutStreamer->AddComment("debug_line_offset");
3728 Asm->emitDwarfLengthOrOffset(0);
3729 else
3730 Asm->emitDwarfSymbolReference(CU.getLineTableStartSym());
3731}
3732
3733void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
3734 for (auto *MN : Nodes) {
3736 emitMacro(*M);
3738 emitMacroFile(*F, U);
3739 else
3741 }
3742}
3743
3744void DwarfDebug::emitMacro(DIMacro &M) {
3745 StringRef Name = M.getName();
3746 StringRef Value = M.getValue();
3747
3748
3749
3750 std::string Str = Value.empty() ? Name.str() : (Name + " " + Value).str();
3751
3752 if (UseDebugMacroSection) {
3755 ? dwarf::DW_MACRO_define_strx
3756 : dwarf::DW_MACRO_undef_strx;
3759 Asm->OutStreamer->AddComment("Line Number");
3760 Asm->emitULEB128(M.getLine());
3761 Asm->OutStreamer->AddComment("Macro String");
3762 Asm->emitULEB128(
3763 InfoHolder.getStringPool().getIndexedEntry(*Asm, Str).getIndex());
3764 } else {
3766 ? dwarf::DW_MACRO_GNU_define_indirect
3767 : dwarf::DW_MACRO_GNU_undef_indirect;
3770 Asm->OutStreamer->AddComment("Line Number");
3771 Asm->emitULEB128(M.getLine());
3772 Asm->OutStreamer->AddComment("Macro String");
3773 Asm->emitDwarfSymbolReference(
3774 InfoHolder.getStringPool().getEntry(*Asm, Str).getSymbol());
3775 }
3776 } else {
3778 Asm->emitULEB128(M.getMacinfoType());
3779 Asm->OutStreamer->AddComment("Line Number");
3780 Asm->emitULEB128(M.getLine());
3781 Asm->OutStreamer->AddComment("Macro String");
3782 Asm->OutStreamer->emitBytes(Str);
3783 Asm->emitInt8('\0');
3784 }
3785}
3786
3787void DwarfDebug::emitMacroFileImpl(
3789 StringRef (*MacroFormToString)(unsigned Form)) {
3790
3791 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
3792 Asm->emitULEB128(StartFile);
3793 Asm->OutStreamer->AddComment("Line Number");
3795 Asm->OutStreamer->AddComment("File Number");
3798 Asm->emitULEB128(getDwoLineTable(U)->getFile(
3800 Asm->OutContext.getDwarfVersion(), F.getSource()));
3801 else
3802 Asm->emitULEB128(U.getOrCreateSourceID(&F));
3804 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
3805 Asm->emitULEB128(EndFile);
3806}
3807
3809
3810
3812 if (UseDebugMacroSection)
3813 emitMacroFileImpl(
3814 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
3816 else
3819}
3820
3821void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
3822 for (const auto &P : CUMap) {
3823 auto &TheCU = *P.second;
3825 DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
3827 DIMacroNodeArray Macros = CUNode->getMacros();
3828 if (Macros.empty())
3829 continue;
3830 Asm->OutStreamer->switchSection(Section);
3831 Asm->OutStreamer->emitLabel(U.getMacroLabelBegin());
3832 if (UseDebugMacroSection)
3834 handleMacroNodes(Macros, U);
3835 Asm->OutStreamer->AddComment("End Of Macro List Mark");
3836 Asm->emitInt8(0);
3837 }
3838}
3839
3840
3841void DwarfDebug::emitDebugMacinfo() {
3842 auto &ObjLower = Asm->getObjFileLowering();
3843 emitDebugMacinfoImpl(UseDebugMacroSection
3844 ? ObjLower.getDwarfMacroSection()
3845 : ObjLower.getDwarfMacinfoSection());
3846}
3847
3848void DwarfDebug::emitDebugMacinfoDWO() {
3849 auto &ObjLower = Asm->getObjFileLowering();
3850 emitDebugMacinfoImpl(UseDebugMacroSection
3851 ? ObjLower.getDwarfMacroDWOSection()
3852 : ObjLower.getDwarfMacinfoDWOSection());
3853}
3854
3855
3856
3857void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
3858 std::unique_ptr NewU) {
3859
3860 if (!CompilationDir.empty())
3861 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
3862 addGnuPubAttributes(*NewU, Die);
3863
3864 SkeletonHolder.addUnit(std::move(NewU));
3865}
3866
3868
3869 auto OwnedUnit = std::make_unique(
3870 CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder,
3872 DwarfCompileUnit &NewCU = *OwnedUnit;
3873 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
3874
3876
3879
3880 initSkeletonUnit(CU, NewCU.getUnitDie(), std::move(OwnedUnit));
3881
3882 return NewCU;
3883}
3884
3885
3886
3887void DwarfDebug::emitDebugInfoDWO() {
3889
3890 InfoHolder.emitUnits( true);
3891}
3892
3893
3894
3895void DwarfDebug::emitDebugAbbrevDWO() {
3897 InfoHolder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevDWOSection());
3898}
3899
3900void DwarfDebug::emitDebugLineDWO() {
3902 SplitTypeUnitFileTable.Emit(
3903 *Asm->OutStreamer, MCDwarfLineTableParams(),
3904 Asm->getObjFileLowering().getDwarfLineDWOSection());
3905}
3906
3907void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
3909 InfoHolder.getStringPool().emitStringOffsetsTableHeader(
3910 *Asm, Asm->getObjFileLowering().getDwarfStrOffDWOSection(),
3911 InfoHolder.getStringOffsetsStartSym());
3912}
3913
3914
3915
3916
3917void DwarfDebug::emitDebugStrDWO() {
3919 emitStringOffsetsTableHeaderDWO();
3921 MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection();
3922 InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
3923 OffSec, false);
3924}
3925
3926
3927void DwarfDebug::emitDebugAddr() {
3928 AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection());
3929}
3930
3933 return nullptr;
3934 const DICompileUnit *DIUnit = CU.getCUNode();
3935 SplitTypeUnitFileTable.maybeSetRootFile(
3938 return &SplitTypeUnitFileTable;
3939}
3940
3942 MD5 Hash;
3943 Hash.update(Identifier);
3944
3945
3946
3948 Hash.final(Result);
3949 return Result.high();
3950}
3951
3955
3956
3957
3958 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
3959 return;
3960
3961 auto Ins = TypeSignatures.try_emplace(CTy);
3962 if (!Ins.second) {
3963 CU.addDIETypeSignature(RefDie, Ins.first->second);
3964 return;
3965 }
3966
3968 bool TopLevelType = TypeUnitsUnderConstruction.empty();
3969 AddrPool.resetUsedFlag();
3970
3971 auto OwnedUnit = std::make_unique(
3972 CU, Asm, this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(CU));
3975 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
3976
3977 NewTU.addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
3978 CU.getSourceLanguage());
3979
3982 Ins.first->second = Signature;
3983
3985
3986
3987
3988
3990 if (!CompilationDir.empty())
3991 NewTU.addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);
3992 NewTU.addString(UnitDie, dwarf::DW_AT_dwo_name,
3993 Asm->TM.Options.MCOptions.SplitDwarfFile);
3994 }
3997 ? Asm->getObjFileLowering().getDwarfTypesDWOSection()
3998 : Asm->getObjFileLowering().getDwarfInfoDWOSection();
4000 } else {
4003 ? Asm->getObjFileLowering().getDwarfTypesSection(Signature)
4004 : Asm->getObjFileLowering().getDwarfInfoSection(Signature);
4006
4007 CU.applyStmtList(UnitDie);
4008 }
4009
4010
4011
4014
4016
4017 if (TopLevelType) {
4018 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
4019 TypeUnitsUnderConstruction.clear();
4020
4021
4022
4023 if (AddrPool.hasBeenUsed()) {
4024 AccelTypeUnitsDebugNames.clear();
4025
4026
4027
4028 for (const auto &TU : TypeUnitsToAdd)
4029 TypeSignatures.erase(TU.second);
4030
4031
4032
4033
4034
4037 CU.updateAcceleratorTables(CTy->getScope(), CTy, RefDie);
4038 return;
4039 }
4040
4041
4042
4043 for (auto &TU : TypeUnitsToAdd) {
4044 InfoHolder.computeSizeAndOffsetsForUnit(TU.first.get());
4049 AccelDebugNames.addTypeUnitSignature(*TU.first);
4050 else
4051 AccelDebugNames.addTypeUnitSymbol(*TU.first);
4052 }
4053 }
4054 AccelTypeUnitsDebugNames.convertDieToOffset();
4055 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);
4056 AccelTypeUnitsDebugNames.clear();
4058 }
4059 CU.addDIETypeSignature(RefDie, Signature);
4060}
4061
4062
4063
4064
4065
4066template
4067void DwarfDebug::addAccelNameImpl(
4072 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())
4073 return;
4074
4078 return;
4079
4082
4086 break;
4089 assert(((&Current == &AccelTypeUnitsDebugNames) ||
4090 ((&Current == &AccelDebugNames) &&
4091 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&
4092 "Kind is CU but TU is being processed.");
4093 assert(((&Current == &AccelDebugNames) ||
4094 ((&Current == &AccelTypeUnitsDebugNames) &&
4095 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&
4096 "Kind is TU but CU is being processed.");
4097
4098
4099 Current.addName(Ref, Die, Unit.getUniqueID(),
4100 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);
4101 break;
4102 }
4104 llvm_unreachable("Default should have already been resolved.");
4107 }
4108}
4109
4113 const DIE &Die) {
4114 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);
4115}
4116
4120 const DIE &Die) {
4121
4123 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);
4124}
4125
4129 const DIE &Die) {
4130 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);
4131}
4132
4136 const DIE &Die, char Flags) {
4137 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);
4138}
4139
4141 return Asm->OutStreamer->getContext().getDwarfVersion();
4142}
4143
4145 if (Asm->getDwarfVersion() >= 4)
4146 return dwarf::Form::DW_FORM_sec_offset;
4147 assert((->isDwarf64() || (Asm->getDwarfVersion() == 3)) &&
4148 "DWARF64 is not defined prior DWARFv3");
4149 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8
4150 : dwarf::Form::DW_FORM_data4;
4151}
4152
4154 return SectionLabels.lookup(S);
4155}
4156
4158 if (SectionLabels.insert(std::make_pair(&S->getSection(), S)).second)
4161}
4162
4163std::optionalMD5::MD5Result
4167 return std::nullopt;
4168 std::optional<DIFile::ChecksumInfo> Checksum = File->getChecksum();
4170 return std::nullopt;
4171
4172
4173
4174
4175 std::string ChecksumString = fromHex(Checksum->Value);
4177 llvm::copy(ChecksumString, CKMem.data());
4178 return CKMem;
4179}
4180
4183 return true;
4185 return false;
4187 return true;
4188 return false;
4189}
4190
4192 if (MBB.getAlignment() == Align(1))
4193 return;
4194
4195 auto *SP = MBB.getParent()->getFunction().getSubprogram();
4196 bool NoDebug =
4198
4199 if (NoDebug)
4200 return;
4201
4202 auto PrevLoc = Asm->OutStreamer->getContext().getCurrentDwarfLoc();
4203 if (PrevLoc.getLine()) {
4204 Asm->OutStreamer->emitDwarfLocDirective(
4205 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0, StringRef());
4207 Asm->OutStreamer->getCurrentSectionOnly());
4208 }
4209}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
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)
Definition DwarfDebug.cpp:453
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.
Definition DwarfDebug.cpp:611
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.
Definition DwarfDebug.cpp:1617
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...
Definition DwarfDebug.cpp:642
static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))
SmallSet< MCRegUnit, 16 > ClobberedRegUnitSet
Container for the set of register units known to be clobbered on the path to a call site.
Definition DwarfDebug.cpp:594
static cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))
Set to false to ignore Key Instructions metadata.
static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
Definition DwarfDebug.cpp:778
static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)
Sort and unique GVEs by comparing their fragment offset.
Definition DwarfDebug.cpp:1147
LinkageNameOption
Definition DwarfDebug.cpp:136
@ DefaultLinkageNames
Definition DwarfDebug.cpp:137
@ AbstractLinkageNames
Definition DwarfDebug.cpp:139
@ AllLinkageNames
Definition DwarfDebug.cpp:138
static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)
computeIndexValue - Compute the gdb index value for the DIE and CU.
Definition DwarfDebug.cpp:2938
static uint64_t getFragmentOffsetInBits(const DIExpression &Expr)
Definition DwarfDebug.cpp:272
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)
Definition DwarfDebug.cpp:2220
static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)
Try to interpret values loaded into registers that forward parameters for CallMI.
Definition DwarfDebug.cpp:806
static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)
Definition DwarfDebug.cpp:3274
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.
Definition DwarfDebug.cpp:591
static cl::opt< bool > UseDwarfRangesBaseAddressSpecifier("use-dwarf-ranges-base-address-specifier", cl::Hidden, cl::desc("Use base address specifiers in debug_ranges"), cl::init(false))
static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)
Definition DwarfDebug.cpp:3431
static const DILocalScope * getRetainedNodeScope(const MDNode *N)
Definition DwarfDebug.cpp:1546
static constexpr unsigned ULEB128PadSize
Definition DwarfDebug.cpp:177
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))
DefaultOnOff
Definition DwarfDebug.cpp:86
@ Default
Definition DwarfDebug.cpp:86
@ Enable
Definition DwarfDebug.cpp:86
@ Disable
Definition DwarfDebug.cpp:86
static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)
Definition DwarfDebug.cpp:310
static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, unsigned StartxLength, unsigned StartxEndx, unsigned EndOfList, StringRef(*StringifyEnum)(unsigned), bool ShouldUseBaseAddress, PayloadEmitter EmitPayload)
Definition DwarfDebug.cpp:3311
static void forBothCUs(DwarfCompileUnit &CU, Func F)
Definition DwarfDebug.cpp:540
static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD)
Definition DwarfDebug.cpp:3292
static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)
Append the expression Addition to Original and return the result.
Definition DwarfDebug.cpp:597
static void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)
Interpret values loaded into registers by CurMI.
Definition DwarfDebug.cpp:663
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.
Definition DwarfDebug.cpp:2365
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.
Definition DwarfDebug.cpp:3709
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)
Definition DwarfDebug.cpp:476
static DbgValueLoc getDebugLocValue(const MachineInstr *MI)
Get .debug_loc entry for the instruction range starting at MI.
Definition DwarfDebug.cpp:239
static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)
Definition DwarfDebug.cpp:464
Module.h This file contains the declarations for the Module class.
#define DWARF2_FLAG_IS_STMT
#define DWARF2_FLAG_PROLOGUE_END
#define DWARF2_FLAG_EPILOGUE_BEGIN
Register const TargetRegisterInfo * TRI
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
static bool isCopy(MachineInstr *MI)
static const uint32_t IV[8]
Class recording the (high level) value of a variable.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
void addName(DwarfStringPoolEntryRef Name, Types &&... Args)
unsigned getIndex(const MCSymbol *Sym, bool TLS=false)
Returns the index into the address pool with the given label/symbol.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::vector< T > vec() const
This class is intended to be used as a driving class for all asm writers.
DwarfDebug * getDwarfDebug()
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
uint16_t getDwarfVersion() const
virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=0
virtual unsigned emitDIERef(const DIE &D)=0
Basic type, like 'int' or 'float'.
bool getDebugInfoForProfiling() const
bool isDebugDirectivesOnly() const
StringRef getFlags() const
static LLVM_ABI std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)
unsigned getRuntimeVersion() const
bool getSplitDebugInlining() const
StringRef getSysRoot() const
StringRef getProducer() const
DISourceLanguageName getSourceLanguage() const
uint64_t getDWOId() const
StringRef getSplitDebugFilename() const
static LLVM_ABI std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)
void setSection(MCSection *Section)
Set the section that this DIEUnit will be emitted into.
A structured debug information entry.
LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const
Find a value in the DIE with the attribute given.
LLVM_ABI const DIE * getUnitDie() const
Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.
dwarf::Tag getTag() const
Holds a DIExpression and keeps track of how many operands have been consumed so far.
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
ArrayRef< uint64_t > getElements() const
LLVM_ABI bool isValid() const
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
uint64_t getAtomGroup() const
uint8_t getAtomRank() const
DIMacroNodeArray getElements() const
Tagged DWARF-like metadata node.
StringRef getFilename() const
StringRef getDirectory() const
std::optional< StringRef > getSource() const
bool hasVersionedName() const
Subprogram description. Uses SubclassData1.
DIScope * getScope() const
Encoding
Size and signedness of expression operations' operands.
Used for tracking debug info about call site parameters.
This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...
SmallVector< Entry, 4 > Entries
A single location or constant within a variable location description, with either a single entry (wit...
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
const DILocalVariable * getVariable() const
const DIType * getType() const
Definition DwarfDebug.cpp:234
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.
Definition DwarfDebug.cpp:3222
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.
Definition DwarfDebug.cpp:4164
bool emitDebugEntryValues() const
uint16_t getDwarfVersion() const
Returns the Dwarf Version.
Definition DwarfDebug.cpp:4140
void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit an entry for the debug loc section.
Definition DwarfDebug.cpp:3081
void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
Definition DwarfDebug.cpp:4126
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.
Definition DwarfDebug.cpp:4181
void beginModule(Module *M) override
Emit all Dwarf sections that should come prior to the content.
Definition DwarfDebug.cpp:1175
void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)
Definition DwarfDebug.cpp:481
bool useAllLinkageNames() const
Returns whether we should emit all DW_AT_[MIPS_]linkage_name.
void insertSectionLabel(const MCSymbol *S)
Definition DwarfDebug.cpp:4157
void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
Definition DwarfDebug.cpp:4117
dwarf::Form getDwarfSectionOffsetForm() const
Returns a suitable DWARF form to represent a section offset, i.e.
Definition DwarfDebug.cpp:4144
bool useAppleExtensionAttributes() const
void skippedNonDebugFunction() override
Definition DwarfDebug.cpp:2741
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.
Definition DwarfDebug.cpp:2021
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
Definition DwarfDebug.cpp:547
void terminateLineTable(const DwarfCompileUnit *CU)
Terminate the line table by adding the last range label.
Definition DwarfDebug.cpp:2732
void endFunctionImpl(const MachineFunction *MF) override
Gather and emit post-function debug information.
Definition DwarfDebug.cpp:2753
DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)
Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.
Definition DwarfDebug.cpp:552
void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)
Emit the location for a debug loc entry, including the size header.
Definition DwarfDebug.cpp:3252
const MCSymbol * getSectionLabel(const MCSection *S)
Definition DwarfDebug.cpp:4153
static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)
Definition DwarfDebug.cpp:3125
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.
Definition DwarfDebug.cpp:2721
const MachineInstr * emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)
Emits inital debug location directive.
Definition DwarfDebug.cpp:2387
bool useRangesSection() const
Returns whether ranges section should be emitted.
void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)
Definition DwarfDebug.cpp:4110
bool isLexicalScopeDIENull(LexicalScope *Scope)
A helper function to check whether the DIE for a given Scope is going to be null.
Definition DwarfDebug.cpp:523
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.
Definition DwarfDebug.cpp:3952
void endModule() override
Emit all Dwarf sections that should come after the content.
Definition DwarfDebug.cpp:1436
void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)
Definition DwarfDebug.cpp:4133
void beginCodeAlignment(const MachineBasicBlock &MBB) override
Process beginning of code alignment.
Definition DwarfDebug.cpp:4191
DwarfDebug(AsmPrinter *A)
Definition DwarfDebug.cpp:334
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
Definition DwarfDebug.cpp:2692
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.
Definition DwarfDebug.cpp:3941
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',...
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)
Definition DwarfDebug.cpp:286
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.
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
virtual bool isTailCall(const MachineInstr &Inst) const
Determines whether Inst is a tail call instruction.
virtual const MachineOperand & getCalleeOperand(const MachineInstr &MI) const
Returns the callee operand from the given MI.
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 - Return the argument parameter cast to the specified type.
bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)
auto cast_or_null(const Y &Val)
auto unique(Range &&R, Predicate P)
bool isa_and_nonnull(const Y &Val)
SmallVector< DbgCallSiteParam, 4 > ParamSet
Collection used for storing debug call site parameters.
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
AccelTableKind
The kind of accelerator tables we should emit.
@ Default
Platform default.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
@ Dwarf
DWARF v5 .debug_names.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - 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 - 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.
Definition DwarfDebug.cpp:3502
const MCSymbol * Start
Definition DwarfDebug.cpp:3503
const MCSymbol * End
Definition DwarfDebug.cpp:3503
Represents a parameter whose call site value can be described by applying a debug expression to a reg...
Definition DwarfDebug.cpp:581
uint64_t ParamReg
The described parameter register.
Definition DwarfDebug.cpp:583
const DIExpression * Expr
Debug expression that has been built up when walking through the instruction chain that produces the ...
Definition DwarfDebug.cpp:587
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)
Definition DwarfDebug.cpp:300
std::set< FrameIndexExpr > FrameIndexExprs
const std::set< FrameIndexExpr > & getFrameIndexExprs() const
Get the FI entries, sorted by fragment offset.
Definition DwarfDebug.cpp:296
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.