@@ -215,7 +215,46 @@ template <typename T> struct DebugLiveContainer {
215215 SmallVector<T> Values;
216216 SmallVector<size_t > BackIdx;
217217};
218-
218+ // / @class LiveRepository
219+ // / @brief Container for the connection graph between newly emitted Debug
220+ // / instructions.
221+ // /
222+ // / The architecture consists of two tiers:
223+ // / - The **Main tier**, represented by an array of `Instructions`.
224+ // / - The **Concrete Type tier**, represented by separate arrays for each
225+ // / corresponding debug type.
226+ // /
227+ // / The `Instructions` array contains records that include:
228+ // / - `Type`: An enum value pointing to the specific debug type array in the
229+ // / Concrete Type tier.
230+ // / - `Id`: An index into the corresponding array in the Concrete Type tier.
231+ // /
232+ // / The class is designed to ensure safe and controlled access to its internal
233+ // / state. All interactions with the repository are done through the
234+ // / `getOrCreateIdx` function, which restricts direct manipulation of the
235+ // / underlying data structures, thus minimizing the risk of memory errors or
236+ // / logical mistakes.
237+ // /
238+ // / Users of this class interact exclusively with the indexes of the
239+ // / `Instructions` array and never directly access the internal concrete type
240+ // / arrays. This property flattens the instruction access,
241+ // making it easily retrievable.
242+ // /
243+ // /
244+ // / getOrCreateIdx() <--+ Iidx
245+ // / V |
246+ // / +-------------------------+-+
247+ // / |[Instructions]--{Cidx,Type}|<----+
248+ // / +------+--------------+-----+ |
249+ // / v v |
250+ // / [PrimitiveType] [ConcreteType_0] |
251+ // / {Data} {Instruction} |
252+ // / (i32)(i32) (Iidx) (Iidx) |
253+ // / | | |
254+ // / +----+-----+
255+ // /
256+ // / Class is designed to be easily removable by simply replacing the
257+ // / `getOrConstructIdx` method with another mechanism.
219258class LiveRepository {
220259 DebugLiveContainer<int64_t > PrimitiveInts;
221260 DebugLiveContainer<StringRef> PrimitiveStrings;
@@ -317,8 +356,26 @@ class LiveRepository {
317356 }
318357
319358public:
320- size_t push (const int64_t Val, MachineIRBuilder &MIRBuilder,
321- const SPIRVTargetMachine *TM) {
359+ // / @brief Retrieves or creates an index for the int64_t primitive type.
360+ // /
361+ // / It's backed by OpConstantI instruction.
362+ // / It either retrieves an existing index or creates a new one based on the
363+ // / provided parameters. The function currently has a linear, cache-friendly
364+ // / search time for duplicate entries. It assumes that no single type of
365+ // / instruction will become so dominant in the module and every entry of that
366+ // / type will be unique.
367+ // /
368+ // / @param[in] Val A int64_t value to retreive or construct.
369+ // / @param[in] MIRBuilder A reference to the `MachineIRBuilder` used for
370+ // / constructing IR.
371+ // / @param[in] TM A pointer to the target machine (`SPIRVTargetMachine`) used
372+ // / for this operation.
373+ // /
374+ // / @return The index (`size_t`) of the retrieved duplicate or newly created
375+ // / entry.
376+ // /
377+ size_t getOrCreateIdx (const int64_t Val, MachineIRBuilder &MIRBuilder,
378+ const SPIRVTargetMachine *TM) {
322379 auto &SV = values<int64_t >();
323380 const auto [ConcreteIdx, IsDuplicate] = emplaceOrReturnDuplicate (Val, SV);
324381 if (IsDuplicate) {
@@ -333,7 +390,25 @@ class LiveRepository {
333390 return Instructions.size () - 1 ;
334391 }
335392
336- size_t push (const StringRef Val, MachineIRBuilder &MIRBuilder) {
393+ // / @brief Retrieves or creates an index for the StringRef primitive type.
394+ // /
395+ // / It's backed by OpString instruction.
396+ // / It either retrieves an existing index or creates a new one based on the
397+ // / provided parameters. The function currently has a linear, cache-friendly
398+ // / search time for duplicate entries. It assumes that no single type of
399+ // / instruction will become so dominant in the module and every entry of that
400+ // / type will be unique.
401+ // /
402+ // / @param[in] Val A StringRef value to retreive or construct.
403+ // / @param[in] MIRBuilder A reference to the `MachineIRBuilder` used for
404+ // / constructing IR.
405+ // / @param[in] TM A pointer to the target machine (`SPIRVTargetMachine`) used
406+ // / for this operation.
407+ // /
408+ // / @return The index (`size_t`) of the retrieved duplicate or newly created
409+ // / entry.
410+ // /
411+ size_t getOrCreateIdx (const StringRef Val, MachineIRBuilder &MIRBuilder) {
337412 auto &SV = values<StringRef>();
338413 const auto [ConcreteIdx, IsDuplicate] = emplaceOrReturnDuplicate (Val, SV);
339414 if (IsDuplicate) {
@@ -345,9 +420,29 @@ class LiveRepository {
345420 return Instructions.size () - 1 ;
346421 }
347422
423+ // / @brief Retrieves or creates an index for the specified type.
424+ // / It either retrieves an existing index or creates a new one based on the
425+ // / provided parameters. The function currently has a linear, cache-friendly
426+ // / search time for duplicate entries. It assumes that no single type of
427+ // / instruction will become so dominant in the module and every entry of that
428+ // / type will be unique.:w
429+ // /
430+ // / @tparam T The specific type being used for this instantiation.
431+ // /
432+ // / @param[in] arrayRef A reference to an array containing indices (of type
433+ // / `size_t`).
434+ // / @param[in] MIRBuilder A reference to the `MachineIRBuilder` used for
435+ // / constructing IR.
436+ // / @param[in] TM A pointer to the target machine (`SPIRVTargetMachine`) used
437+ // / for this operation.
438+ // /
439+ // / @return The index (`size_t`) of the retrieved duplicate or newly created
440+ // / entry.
441+ // /
348442 template <typename T>
349- constexpr size_t push (ArrayRef<size_t > Args, MachineIRBuilder &MIRBuilder,
350- const SPIRVTargetMachine *TM) {
443+ constexpr size_t getOrCreateIdx (ArrayRef<size_t > Args,
444+ MachineIRBuilder &MIRBuilder,
445+ const SPIRVTargetMachine *TM) {
351446 auto &SV = values<T>();
352447 const auto [ConcreteIdx, IsDuplicate] =
353448 emplaceOrReturnDuplicate (T (Args), SV);
@@ -363,9 +458,10 @@ class LiveRepository {
363458};
364459
365460template <>
366- size_t LiveRepository::push<DebugInfoNone>(ArrayRef<size_t >,
367- MachineIRBuilder &MIRBuilder,
368- const SPIRVTargetMachine *TM) {
461+ size_t
462+ LiveRepository::getOrCreateIdx<DebugInfoNone>(ArrayRef<size_t >,
463+ MachineIRBuilder &MIRBuilder,
464+ const SPIRVTargetMachine *TM) {
369465 static std::optional<size_t > DebugInfoNoneIdx = std::nullopt ;
370466 if (!DebugInfoNoneIdx.has_value ()) {
371467 Instructions.emplace_back (DebugTypeContainer<DebugInfoNone>::TM, 0 );
@@ -380,8 +476,9 @@ size_t emitDebugSource(const DIFile *File, MachineIRBuilder &MIRBuilder,
380476 SPIRVTargetMachine *TM, LiveRepository &LR) {
381477 SmallString<128 > FilePath;
382478 sys::path::append (FilePath, File->getDirectory (), File->getFilename ());
383- const size_t FilePathId = LR.push (StringRef (FilePath.c_str ()), MIRBuilder);
384- return LR.push <DebugSource>({FilePathId}, MIRBuilder, TM);
479+ const size_t FilePathId =
480+ LR.getOrCreateIdx (StringRef (FilePath.c_str ()), MIRBuilder);
481+ return LR.getOrCreateIdx <DebugSource>({FilePathId}, MIRBuilder, TM);
385482}
386483
387484size_t emitDebugCompilationUnits (const Module *M, MachineIRBuilder &MIRBuilder,
@@ -397,13 +494,13 @@ size_t emitDebugCompilationUnits(const Module *M, MachineIRBuilder &MIRBuilder,
397494 cast<ConstantInt>(
398495 cast<ConstantAsMetadata>(Op->getOperand (2 ))->getValue ())
399496 ->getSExtValue ();
400- DwarfVersionId = LR.push (DwarfVersion, MIRBuilder, TM);
497+ DwarfVersionId = LR.getOrCreateIdx (DwarfVersion, MIRBuilder, TM);
401498 } else if (MaybeStrOp.equalsStr (" Debug Info Version" )) {
402499 const int64_t DebugInfoVersion =
403500 cast<ConstantInt>(
404501 cast<ConstantAsMetadata>(Op->getOperand (2 ))->getValue ())
405502 ->getSExtValue ();
406- DebugInfoVersionId = LR.push (DebugInfoVersion, MIRBuilder, TM);
503+ DebugInfoVersionId = LR.getOrCreateIdx (DebugInfoVersion, MIRBuilder, TM);
407504 }
408505 }
409506 assert (DwarfVersionId.has_value () && DebugInfoVersionId.has_value ());
@@ -415,9 +512,9 @@ size_t emitDebugCompilationUnits(const Module *M, MachineIRBuilder &MIRBuilder,
415512 sys::path::append (FilePath, File->getDirectory (), File->getFilename ());
416513
417514 const size_t FilePathId =
418- LR.push (StringRef (FilePath.c_str ()), MIRBuilder);
515+ LR.getOrCreateIdx (StringRef (FilePath.c_str ()), MIRBuilder);
419516 const size_t DebugSourceId =
420- LR.push <DebugSource>({FilePathId}, MIRBuilder, TM);
517+ LR.getOrCreateIdx <DebugSource>({FilePathId}, MIRBuilder, TM);
421518
422519 SourceLanguage SpirvSourceLanguage;
423520 switch (CompileUnit->getSourceLanguage ()) {
@@ -447,11 +544,11 @@ size_t emitDebugCompilationUnits(const Module *M, MachineIRBuilder &MIRBuilder,
447544 }
448545
449546 const size_t SpirvSourceLanguageId =
450- LR.push (SpirvSourceLanguage, MIRBuilder, TM);
451- LR.push <DebugCompilationUnit>({DebugInfoVersionId. value (),
452- DwarfVersionId.value (), DebugSourceId,
453- SpirvSourceLanguageId},
454- MIRBuilder, TM);
547+ LR.getOrCreateIdx (SpirvSourceLanguage, MIRBuilder, TM);
548+ LR.getOrCreateIdx <DebugCompilationUnit>(
549+ {DebugInfoVersionId. value (), DwarfVersionId.value (), DebugSourceId,
550+ SpirvSourceLanguageId},
551+ MIRBuilder, TM);
455552 }
456553 }
457554 return 0 ;
@@ -461,10 +558,10 @@ size_t emitDebugTypeBasic(const DIBasicType *BT, size_t I32ZeroIdx,
461558 MachineIRBuilder &MIRBuilder,
462559 const SPIRVTargetMachine *TM, LiveRepository &LR) {
463560
464- const size_t BasicTypeStrId = LR.push (BT->getName (), MIRBuilder);
561+ const size_t BasicTypeStrId = LR.getOrCreateIdx (BT->getName (), MIRBuilder);
465562
466563 const size_t ConstIntBitWidthId =
467- LR.push (BT->getSizeInBits (), MIRBuilder, TM);
564+ LR.getOrCreateIdx (BT->getSizeInBits (), MIRBuilder, TM);
468565
469566 uint64_t AttributeEncoding;
470567 switch (BT->getEncoding ()) {
@@ -493,9 +590,10 @@ size_t emitDebugTypeBasic(const DIBasicType *BT, size_t I32ZeroIdx,
493590 AttributeEncoding = BaseTypeAttributeEncoding::Unspecified;
494591 }
495592
496- const size_t AttributeEncodingId = LR.push (AttributeEncoding, MIRBuilder, TM);
593+ const size_t AttributeEncodingId =
594+ LR.getOrCreateIdx (AttributeEncoding, MIRBuilder, TM);
497595
498- return LR.push <DebugTypeBasic>(
596+ return LR.getOrCreateIdx <DebugTypeBasic>(
499597 {BasicTypeStrId, ConstIntBitWidthId, AttributeEncodingId, I32ZeroIdx},
500598 MIRBuilder, TM);
501599}
@@ -506,26 +604,27 @@ size_t emitDebugTypePointer(const DIDerivedType *DT, const size_t BasicTypeIdx,
506604 const SPIRVTargetMachine *TM, LiveRepository &LR) {
507605 assert (DT->getDWARFAddressSpace ().has_value ());
508606
509- size_t StorageClassIdx =
510- LR. push ( addressSpaceToStorageClass (DT->getDWARFAddressSpace ().value (),
511- *TM->getSubtargetImpl ()),
512- MIRBuilder, TM);
607+ size_t StorageClassIdx = LR. getOrCreateIdx (
608+ addressSpaceToStorageClass (DT->getDWARFAddressSpace ().value (),
609+ *TM->getSubtargetImpl ()),
610+ MIRBuilder, TM);
513611
514- return LR.push <DebugTypePointer>({BasicTypeIdx, StorageClassIdx, I32ZeroIdx},
515- MIRBuilder, TM);
612+ return LR.getOrCreateIdx <DebugTypePointer>(
613+ {BasicTypeIdx, StorageClassIdx, I32ZeroIdx}, MIRBuilder, TM);
516614}
517615
518616size_t emitDebugTypePointer (const DIDerivedType *DT, const size_t I32ZeroIdx,
519617 MachineIRBuilder &MIRBuilder,
520618 const SPIRVTargetMachine *TM, LiveRepository &LR) {
521619 assert (DT->getDWARFAddressSpace ().has_value ());
522620
523- size_t StorageClassIdx =
524- LR.push (addressSpaceToStorageClass (DT->getDWARFAddressSpace ().value (),
525- *TM->getSubtargetImpl ()),
526- MIRBuilder, TM);
527- size_t DebugInfoNoneIdx = LR.push <DebugInfoNone>({}, MIRBuilder, TM);
528- return LR.push <DebugTypePointer>(
621+ size_t StorageClassIdx = LR.getOrCreateIdx (
622+ addressSpaceToStorageClass (DT->getDWARFAddressSpace ().value (),
623+ *TM->getSubtargetImpl ()),
624+ MIRBuilder, TM);
625+ size_t DebugInfoNoneIdx =
626+ LR.getOrCreateIdx <DebugInfoNone>({}, MIRBuilder, TM);
627+ return LR.getOrCreateIdx <DebugTypePointer>(
529628 {DebugInfoNoneIdx, StorageClassIdx, I32ZeroIdx}, MIRBuilder, TM);
530629}
531630} // namespace
@@ -588,14 +687,14 @@ bool SPIRVEmitNonSemanticDI::emitGlobalDI(MachineFunction &MF, const Module *M,
588687 dyn_cast<DIBasicType>(LocalVariable->getType ())) {
589688 // Currently, we are not extracting any DebugInfoFlags,
590689 // so we emit zero as the <id>Flags argument for DebugBasicType.
591- const size_t I32ZeroIdx = LR.push (0 , MIRBuilder, TM);
690+ const size_t I32ZeroIdx = LR.getOrCreateIdx (0 , MIRBuilder, TM);
592691 emitDebugTypeBasic (BasicType, I32ZeroIdx, MIRBuilder, TM, LR);
593692 continue ;
594693 }
595694 if (const auto *DerivedType =
596695 dyn_cast<DIDerivedType>(LocalVariable->getType ())) {
597696 if (DerivedType->getTag () == dwarf::DW_TAG_pointer_type) {
598- const size_t I32ZeroIdx = LR.push (0 , MIRBuilder, TM);
697+ const size_t I32ZeroIdx = LR.getOrCreateIdx (0 , MIRBuilder, TM);
599698 // DIBasicType may be unreachable from DbgRecord and can only be
600699 // referenced by other Debug Information (DI) types. Note:
601700 // DerivedType->getBaseType returns null when the pointer
@@ -630,10 +729,10 @@ bool SPIRVEmitNonSemanticDI::emitLineDI(MachineFunction &MF,
630729 assert (DL.getScope () && " DL.getScope() must exist and be DISubprogram" );
631730 const auto *File = cast<DISubprogram>(DL.getScope ())->getFile ();
632731 const size_t ScopeIdx = emitDebugSource (File, MIRBuilder, TM, LR);
633- const size_t LineIdx = LR.push (DL.getLine (), MIRBuilder, TM);
634- const size_t ColIdx = LR.push (DL.getCol (), MIRBuilder, TM);
635- LR.push <DebugLine>({ScopeIdx, LineIdx, LineIdx, ColIdx, ColIdx},
636- MIRBuilder, TM);
732+ const size_t LineIdx = LR.getOrCreateIdx (DL.getLine (), MIRBuilder, TM);
733+ const size_t ColIdx = LR.getOrCreateIdx (DL.getCol (), MIRBuilder, TM);
734+ LR.getOrCreateIdx <DebugLine>(
735+ {ScopeIdx, LineIdx, LineIdx, ColIdx, ColIdx}, MIRBuilder, TM);
637736 IsModified = true ;
638737 }
639738 }
0 commit comments