Skip to content

Commit d951b81

Browse files
committed
class and method descriptions
1 parent c2c97f0 commit d951b81

File tree

1 file changed

+141
-42
lines changed

1 file changed

+141
-42
lines changed

llvm/lib/Target/SPIRV/SPIRVEmitNonSemanticDI.cpp

Lines changed: 141 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
219258
class LiveRepository {
220259
DebugLiveContainer<int64_t> PrimitiveInts;
221260
DebugLiveContainer<StringRef> PrimitiveStrings;
@@ -317,8 +356,26 @@ class LiveRepository {
317356
}
318357

319358
public:
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

365460
template <>
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

387484
size_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

518616
size_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

Comments
 (0)