LLVM: lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

23#include

24#include

25

26using namespace llvm;

30

32 : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) {

33}

34

36

39}

40

41void TpiStreamBuilder::updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes) {

42

44 size_t NewSize = TypeRecordBytes + Size;

45 constexpr size_t EightKB = 8 * 1024;

46 if (NewSize / EightKB > TypeRecordBytes / EightKB || TypeRecordCount == 0) {

47 TypeIndexOffsets.push_back(

49 TypeRecordCount),

51 }

52 ++TypeRecordCount;

53 TypeRecordBytes = NewSize;

54 }

55}

56

58 std::optional<uint32_t> Hash) {

60 "The type record's size is not a multiple of 4 bytes which will "

61 "cause misalignment in the output TPI stream!");

64 updateTypeIndexOffsets(ArrayRef(&OneSize, 1));

65

66 TypeRecBuffers.push_back(Record);

67

68 if (Hash)

69 TypeHashes.push_back(*Hash);

70}

71

75

76 if (Types.empty()) {

78 return;

79 }

80

81 assert(((Types.size() & 3) == 0) &&

82 "The type record's size is not a multiple of 4 bytes which will "

83 "cause misalignment in the output TPI stream!");

84 assert(Sizes.size() == Hashes.size() && "sizes and hashes should be in sync");

85 assert(std::accumulate(Sizes.begin(), Sizes.end(), 0U) == Types.size() &&

86 "sizes of type records should sum to the size of the types");

87 updateTypeIndexOffsets(Sizes);

88

89 TypeRecBuffers.push_back(Types);

91}

92

93Error TpiStreamBuilder::finalize() {

94 if (Header)

96

98

99 H->Version = VerHeader;

102 H->TypeIndexEnd = H->TypeIndexBegin + TypeRecordCount;

103 H->TypeRecordBytes = TypeRecordBytes;

104

105 H->HashStreamIndex = HashStreamIndex;

109

110

111

112

113 H->HashValueBuffer.Off = 0;

114 H->HashValueBuffer.Length = calculateHashBufferSize();

115

116

117

118 H->HashAdjBuffer.Off = H->HashValueBuffer.Off + H->HashValueBuffer.Length;

119 H->HashAdjBuffer.Length = 0;

120

121 H->IndexOffsetBuffer.Off = H->HashAdjBuffer.Off + H->HashAdjBuffer.Length;

122 H->IndexOffsetBuffer.Length = calculateIndexOffsetSize();

123

124 Header = H;

126}

127

130}

131

132uint32_t TpiStreamBuilder::calculateHashBufferSize() const {

133 assert((TypeRecordCount == TypeHashes.size() || TypeHashes.empty()) &&

134 "either all or no type records should have hashes");

135 return TypeHashes.size() * sizeof(ulittle32_t);

136}

137

138uint32_t TpiStreamBuilder::calculateIndexOffsetSize() const {

140}

141

145 return EC;

146

148 calculateHashBufferSize() + calculateIndexOffsetSize();

149

150 if (HashStreamSize == 0)

152

153 auto ExpectedIndex = Msf.addStream(HashStreamSize);

154 if (!ExpectedIndex)

155 return ExpectedIndex.takeError();

156 HashStreamIndex = *ExpectedIndex;

157 if (!TypeHashes.empty()) {

160 for (uint32_t I = 0; I < TypeHashes.size(); ++I) {

162 }

164 reinterpret_cast<const uint8_t *>(HashBuffer.data()),

165 calculateHashBufferSize());

166 HashValueStream =

168 }

170}

171

175 if (auto EC = finalize())

176 return EC;

177

179 Idx, Allocator);

180

182 if (auto EC = Writer.writeObject(*Header))

183 return EC;

184

185 for (auto Rec : TypeRecBuffers) {

186 assert(!Rec.empty() && "Attempting to write an empty type record shifts "

187 "all offsets in the TPI stream!");

188 assert(((Rec.size() & 3) == 0) &&

189 "The type record's size is not a multiple of 4 bytes which will "

190 "cause misalignment in the output TPI stream!");

191 if (auto EC = Writer.writeBytes(Rec))

192 return EC;

193 }

194

197 Layout, Buffer, HashStreamIndex, Allocator);

199 if (HashValueStream) {

201 return EC;

202 }

203

204 for (auto &IndexOffset : TypeIndexOffsets) {

205 if (auto EC = HW.writeObject(IndexOffset))

206 return EC;

207 }

208 }

209

211}

This file defines the BumpPtrAllocator interface.

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

Provides write only access to a subclass of WritableBinaryStream.

Error writeStreamRef(BinaryStreamRef Ref)

Efficiently reads all data from Ref, and writes it to this stream.

Error writeBytes(ArrayRef< uint8_t > Buffer)

Write the bytes specified in Buffer to the underlying stream.

Error writeObject(const T &Obj)

Writes the object Obj to the underlying stream, as if by using memcpy.

LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)

Allocate space at the specified alignment.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.

static const uint32_t FirstNonSimpleIndex

Error setStreamSize(uint32_t Idx, uint32_t Size)

Update the size of an existing stream.

Expected< uint32_t > addStream(uint32_t Size, ArrayRef< uint32_t > Blocks)

Add a stream to the MSF file with the given size, occupying the given list of blocks.

static std::unique_ptr< WritableMappedBlockStream > createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, uint32_t StreamIndex, BumpPtrAllocator &Allocator)

Error finalizeMsfLayout()

void addTypeRecord(ArrayRef< uint8_t > Type, std::optional< uint32_t > Hash)

Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer)

void addTypeRecords(ArrayRef< uint8_t > Types, ArrayRef< uint16_t > Sizes, ArrayRef< uint32_t > Hashes)

TpiStreamBuilder(msf::MSFBuilder &Msf, uint32_t StreamIdx)

uint32_t calculateSerializedLength()

void setVersionHeader(PdbRaw_TpiVer Version)

const uint16_t kInvalidStreamIndex

const uint32_t MaxTpiHashBuckets

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

This is an optimization pass for GlobalISel generic memory operations.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.