LLVM: lib/DebugInfo/MSF/MappedBlockStream.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15#include

16#include

17#include

18#include

19#include

20#include

21

22using namespace llvm;

24

25namespace {

26

27template class MappedBlockStreamImpl : public Base {

28public:

29 template <typename... Args>

30 MappedBlockStreamImpl(Args &&... Params)

32};

33

34}

35

36using Interval = std::pair<uint64_t, uint64_t>;

37

39 return std::make_pair(std::max(I1.first, I2.first),

40 std::min(I1.second, I2.second));

41}

42

49

53 return std::make_unique<MappedBlockStreamImpl>(

54 BlockSize, Layout, MsfData, Allocator);

55}

56

60 assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");

64 return std::make_unique<MappedBlockStreamImpl>(

66}

67

68std::unique_ptr

76}

77

78std::unique_ptr

84}

85

88

90 return EC;

91

92 if (tryReadContiguously(Offset, Size, Buffer))

94

95 auto CacheIter = CacheMap.find(Offset);

96 if (CacheIter != CacheMap.end()) {

97

98 for (auto &Entry : CacheIter->second) {

99 if (Entry.size() >= Size) {

100 Buffer = Entry.slice(0, Size);

102 }

103 }

104 }

105

106

107

108

109 for (auto &CacheItem : CacheMap) {

111

112

113 if (CacheItem.first == Offset)

114 continue;

115

116

117 if (CacheItem.first >= Offset + Size)

118 continue;

119

120

121

122 if (CacheItem.second.empty())

123 continue;

124

125 auto CachedAlloc = CacheItem.second.back();

126

127

129 std::make_pair(CacheItem.first, CacheItem.first + CachedAlloc.size());

130 if (RequestExtent.first >= CachedExtent.first + CachedExtent.second)

131 continue;

132

134

135

136 if (Intersection != RequestExtent)

137 continue;

138

141 Buffer = CachedAlloc.slice(CacheRangeOffset, Size);

143 }

144

145

146

147

148

151 return EC;

152

153 if (CacheIter != CacheMap.end()) {

154 CacheIter->second.emplace_back(WriteBuffer, Size);

155 } else {

156 std::vector List;

157 List.emplace_back(WriteBuffer, Size);

158 CacheMap.insert(std::make_pair(Offset, List));

159 }

162}

163

166

168 return EC;

169

172

175 break;

177 }

178

180 uint64_t BytesFromFirstBlock = BlockSize - OffsetInFirstBlock;

182 uint64_t ByteSpan = BytesFromFirstBlock + (BlockSpan - 1) * BlockSize;

183

186 if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData))

187 return EC;

188

189 BlockData = BlockData.drop_front(OffsetInFirstBlock);

192}

193

195

198 if (Size == 0) {

200 return true;

201 }

202

203

204

205

206

209 uint64_t BytesFromFirstBlock = std::min(Size, BlockSize - OffsetInBlock);

210 uint64_t NumAdditionalBlocks =

211 alignTo(Size - BytesFromFirstBlock, BlockSize) / BlockSize;

212

213 uint64_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;

215 for (uint64_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {

216 if (StreamLayout.Blocks[I + BlockNum] != E)

217 return false;

218 }

219

220

221

222

223

224

226 uint64_t FirstBlockAddr = StreamLayout.Blocks[BlockNum];

230 return false;

231 }

234 return true;

235}

236

241

242

244 return EC;

245

249 while (BytesLeft > 0) {

250 uint64_t StreamBlockAddr = StreamLayout.Blocks[BlockNum];

251

255 return EC;

256

257 const uint8_t *ChunkStart = BlockData.data() + OffsetInBlock;

258 uint64_t BytesInChunk = std::min(BytesLeft, BlockSize - OffsetInBlock);

259 ::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);

260

261 BytesWritten += BytesInChunk;

262 BytesLeft -= BytesInChunk;

263 ++BlockNum;

264 OffsetInBlock = 0;

265 }

266

268}

269

271

272void MappedBlockStream::fixCacheAfterWrite(uint64_t Offset,

274

275

276

277

278 for (const auto &MapEntry : CacheMap) {

279

280

281 if (Offset + Data.size() < MapEntry.first)

282 continue;

283 for (const auto &Alloc : MapEntry.second) {

284

285

286 if (MapEntry.first + Alloc.size() < Offset)

287 continue;

288

289

292 std::make_pair(MapEntry.first, MapEntry.first + Alloc.size());

293

294

295 auto Intersection = intersect(WriteInterval, CachedInterval);

296 assert(Intersection.first <= Intersection.second);

297

298 uint64_t Length = Intersection.second - Intersection.first;

303 ::memcpy(Alloc.data() + DestOffset, Data.data() + SrcOffset, Length);

304 }

305 }

306}

307

312 WriteInterface(MsfData) {}

313

314std::unique_ptr

319 return std::make_unique<MappedBlockStreamImpl>(

321}

322

323std::unique_ptr

328 assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");

333}

334

335std::unique_ptr

343}

344

345std::unique_ptr

349 bool AltFpm) {

350

351

352

353

354

355

356

358

360 auto Result =

362 if (!Result)

363 return Result;

364 std::vector<uint8_t> InitData(Layout.SB->BlockSize, 0xFF);

369}

370

374}

375

379}

380

382 return ReadInterface.getLength();

383}

384

387

389 return EC;

390

393

396 while (BytesLeft > 0) {

398 uint64_t BytesToWriteInChunk =

399 std::min(BytesLeft, getBlockSize() - OffsetInBlock);

400

401 const uint8_t *Chunk = Buffer.data() + BytesWritten;

404 MsfOffset += OffsetInBlock;

405 if (auto EC = WriteInterface.writeBytes(MsfOffset, ChunkData))

406 return EC;

407

408 BytesLeft -= BytesToWriteInChunk;

409 BytesWritten += BytesToWriteInChunk;

410 ++BlockNum;

411 OffsetInBlock = 0;

412 }

413

414 ReadInterface.fixCacheAfterWrite(Offset, Buffer);

415

417}

418

std::pair< uint64_t, uint64_t > Interval

static Interval intersect(const Interval &I1, const Interval &I2)

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

static const int BlockSize

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

size_t size() const

size - Get the array size.

ArrayRef< T > slice(size_t N, size_t M) const

slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.

BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.

Error readBytes(uint64_t Offset, uint64_t Size, ArrayRef< uint8_t > &Buffer) const

Given an Offset into this StreamRef and a Size, return a reference to a buffer owned by the stream.

Provides write only access to a subclass of WritableBinaryStream.

uint64_t bytesRemaining() const

Error writeBytes(ArrayRef< uint8_t > Buffer)

Write the bytes specified in Buffer to the underlying stream.

Error checkOffsetForRead(uint64_t Offset, uint64_t DataSize)

Allocate memory in an ever growing pool, as if by bump-pointer.

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...

Error writeBytes(uint64_t Offset, ArrayRef< uint8_t > Data) const

Given an Offset into this WritableBinaryStreamRef and some input data, writes the data to the underly...

Error commit()

For buffered streams, commits changes to the backing store.

Error checkOffsetForWrite(uint64_t Offset, uint64_t DataSize)

Describes the layout of a stream in an MSF layout.

std::vector< support::ulittle32_t > Blocks

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

Error readBytes(uint64_t Offset, uint64_t Size, ArrayRef< uint8_t > &Buffer) override

Given an offset into the stream and a number of bytes, attempt to read the bytes and set the output A...

Error readLongestContiguousChunk(uint64_t Offset, ArrayRef< uint8_t > &Buffer) override

Given an offset into the stream, read as much as possible without copying any data.

static std::unique_ptr< MappedBlockStream > createStream(uint32_t BlockSize, const MSFStreamLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

uint32_t getNumBlocks() const

MappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

static std::unique_ptr< MappedBlockStream > createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

static std::unique_ptr< MappedBlockStream > createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

uint64_t getLength() override

Return the number of bytes of data in this stream.

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

static std::unique_ptr< WritableMappedBlockStream > createStream(uint32_t BlockSize, const MSFStreamLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

Error commit() override

For buffered streams, commits changes to the backing store.

WritableMappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)

Error readBytes(uint64_t Offset, uint64_t Size, ArrayRef< uint8_t > &Buffer) override

Given an offset into the stream and a number of bytes, attempt to read the bytes and set the output A...

static std::unique_ptr< WritableMappedBlockStream > createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator, bool AltFpm=false)

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

uint64_t getLength() override

Return the number of bytes of data in this stream.

uint32_t getBlockSize() const

const MSFStreamLayout & getStreamLayout() const

Error readLongestContiguousChunk(uint64_t Offset, ArrayRef< uint8_t > &Buffer) override

Given an offset into the stream, read as much as possible without copying any data.

Error writeBytes(uint64_t Offset, ArrayRef< uint8_t > Buffer) override

Attempt to write the given bytes into the stream at the desired offset.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize)

MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf, bool IncludeUnusedFpmData=false, bool AltFpm=false)

Determine the layout of the FPM stream, given the MSF layout.

This is an optimization pass for GlobalISel generic memory operations.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

constexpr T AbsoluteDifference(U X, V Y)

Subtract two unsigned integers, X and Y, of type T and return the absolute value of the result.

void consumeError(Error Err)

Consume a Error without doing anything.

Implement std::hash so that hash_code can be used in STL containers.

ArrayRef< support::ulittle32_t > StreamSizes

ArrayRef< support::ulittle32_t > DirectoryBlocks

std::vector< ArrayRef< support::ulittle32_t > > StreamMap

support::ulittle32_t BlockSize

support::ulittle32_t NumDirectoryBytes