LLVM  14.0.0git
MSFBuilder.cpp
Go to the documentation of this file.
1 //===- MSFBuilder.cpp -----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/Support/Endian.h"
16 #include "llvm/Support/Error.h"
19 #include <algorithm>
20 #include <cassert>
21 #include <cstdint>
22 #include <cstring>
23 #include <memory>
24 #include <utility>
25 #include <vector>
26 
27 using namespace llvm;
28 using namespace llvm::msf;
29 using namespace llvm::support;
30 
31 static const uint32_t kSuperBlockBlock = 0;
32 static const uint32_t kFreePageMap0Block = 1;
33 static const uint32_t kFreePageMap1Block = 2;
34 static const uint32_t kNumReservedPages = 3;
35 
38 
39 MSFBuilder::MSFBuilder(uint32_t BlockSize, uint32_t MinBlockCount, bool CanGrow,
41  : Allocator(Allocator), IsGrowable(CanGrow),
43  BlockMapAddr(kDefaultBlockMapAddr), FreeBlocks(MinBlockCount, true) {
44  FreeBlocks[kSuperBlockBlock] = false;
45  FreeBlocks[kFreePageMap0Block] = false;
46  FreeBlocks[kFreePageMap1Block] = false;
47  FreeBlocks[BlockMapAddr] = false;
48 }
49 
52  uint32_t MinBlockCount, bool CanGrow) {
53  if (!isValidBlockSize(BlockSize))
54  return make_error<MSFError>(msf_error_code::invalid_format,
55  "The requested block size is unsupported");
56 
57  return MSFBuilder(BlockSize,
58  std::max(MinBlockCount, msf::getMinimumBlockCount()),
59  CanGrow, Allocator);
60 }
61 
63  if (Addr == BlockMapAddr)
64  return Error::success();
65 
66  if (Addr >= FreeBlocks.size()) {
67  if (!IsGrowable)
68  return make_error<MSFError>(msf_error_code::insufficient_buffer,
69  "Cannot grow the number of blocks");
70  FreeBlocks.resize(Addr + 1, true);
71  }
72 
73  if (!isBlockFree(Addr))
74  return make_error<MSFError>(
76  "Requested block map address is already in use");
77  FreeBlocks[BlockMapAddr] = true;
78  FreeBlocks[Addr] = false;
79  BlockMapAddr = Addr;
80  return Error::success();
81 }
82 
83 void MSFBuilder::setFreePageMap(uint32_t Fpm) { FreePageMap = Fpm; }
84 
85 void MSFBuilder::setUnknown1(uint32_t Unk1) { Unknown1 = Unk1; }
86 
88  for (auto B : DirectoryBlocks)
89  FreeBlocks[B] = true;
90  for (auto B : DirBlocks) {
91  if (!isBlockFree(B)) {
92  return make_error<MSFError>(msf_error_code::unspecified,
93  "Attempt to reuse an allocated block");
94  }
95  FreeBlocks[B] = false;
96  }
97 
98  DirectoryBlocks = DirBlocks;
99  return Error::success();
100 }
101 
102 Error MSFBuilder::allocateBlocks(uint32_t NumBlocks,
103  MutableArrayRef<uint32_t> Blocks) {
104  if (NumBlocks == 0)
105  return Error::success();
106 
107  uint32_t NumFreeBlocks = FreeBlocks.count();
108  if (NumFreeBlocks < NumBlocks) {
109  if (!IsGrowable)
110  return make_error<MSFError>(msf_error_code::insufficient_buffer,
111  "There are no free Blocks in the file");
112  uint32_t AllocBlocks = NumBlocks - NumFreeBlocks;
113  uint32_t OldBlockCount = FreeBlocks.size();
114  uint32_t NewBlockCount = AllocBlocks + OldBlockCount;
115  uint32_t NextFpmBlock = alignTo(OldBlockCount, BlockSize) + 1;
116  FreeBlocks.resize(NewBlockCount, true);
117  // If we crossed over an fpm page, we actually need to allocate 2 extra
118  // blocks for each FPM group crossed and mark both blocks from the group as
119  // used. FPM blocks are marked as allocated regardless of whether or not
120  // they ultimately describe the status of blocks in the file. This means
121  // that not only are extraneous blocks at the end of the main FPM marked as
122  // allocated, but also blocks from the alternate FPM are always marked as
123  // allocated.
124  while (NextFpmBlock < NewBlockCount) {
125  NewBlockCount += 2;
126  FreeBlocks.resize(NewBlockCount, true);
127  FreeBlocks.reset(NextFpmBlock, NextFpmBlock + 2);
128  NextFpmBlock += BlockSize;
129  }
130  }
131 
132  int I = 0;
133  int Block = FreeBlocks.find_first();
134  do {
135  assert(Block != -1 && "We ran out of Blocks!");
136 
137  uint32_t NextBlock = static_cast<uint32_t>(Block);
138  Blocks[I++] = NextBlock;
139  FreeBlocks.reset(NextBlock);
140  Block = FreeBlocks.find_next(Block);
141  } while (--NumBlocks > 0);
142  return Error::success();
143 }
144 
147 }
148 
149 uint32_t MSFBuilder::getNumFreeBlocks() const { return FreeBlocks.count(); }
150 
151 uint32_t MSFBuilder::getTotalBlockCount() const { return FreeBlocks.size(); }
152 
153 bool MSFBuilder::isBlockFree(uint32_t Idx) const { return FreeBlocks[Idx]; }
154 
156  ArrayRef<uint32_t> Blocks) {
157  // Add a new stream mapped to the specified blocks. Verify that the specified
158  // blocks are both necessary and sufficient for holding the requested number
159  // of bytes, and verify that all requested blocks are free.
160  uint32_t ReqBlocks = bytesToBlocks(Size, BlockSize);
161  if (ReqBlocks != Blocks.size())
162  return make_error<MSFError>(
164  "Incorrect number of blocks for requested stream size");
165  for (auto Block : Blocks) {
166  if (Block >= FreeBlocks.size())
167  FreeBlocks.resize(Block + 1, true);
168 
169  if (!FreeBlocks.test(Block))
170  return make_error<MSFError>(
172  "Attempt to re-use an already allocated block");
173  }
174  // Mark all the blocks occupied by the new stream as not free.
175  for (auto Block : Blocks) {
176  FreeBlocks.reset(Block);
177  }
178  StreamData.push_back(std::make_pair(Size, Blocks));
179  return StreamData.size() - 1;
180 }
181 
183  uint32_t ReqBlocks = bytesToBlocks(Size, BlockSize);
184  std::vector<uint32_t> NewBlocks;
185  NewBlocks.resize(ReqBlocks);
186  if (auto EC = allocateBlocks(ReqBlocks, NewBlocks))
187  return std::move(EC);
188  StreamData.push_back(std::make_pair(Size, NewBlocks));
189  return StreamData.size() - 1;
190 }
191 
193  uint32_t OldSize = getStreamSize(Idx);
194  if (OldSize == Size)
195  return Error::success();
196 
197  uint32_t NewBlocks = bytesToBlocks(Size, BlockSize);
198  uint32_t OldBlocks = bytesToBlocks(OldSize, BlockSize);
199 
200  if (NewBlocks > OldBlocks) {
201  uint32_t AddedBlocks = NewBlocks - OldBlocks;
202  // If we're growing, we have to allocate new Blocks.
203  std::vector<uint32_t> AddedBlockList;
204  AddedBlockList.resize(AddedBlocks);
205  if (auto EC = allocateBlocks(AddedBlocks, AddedBlockList))
206  return EC;
207  auto &CurrentBlocks = StreamData[Idx].second;
208  llvm::append_range(CurrentBlocks, AddedBlockList);
209  } else if (OldBlocks > NewBlocks) {
210  // For shrinking, free all the Blocks in the Block map, update the stream
211  // data, then shrink the directory.
212  uint32_t RemovedBlocks = OldBlocks - NewBlocks;
213  auto CurrentBlocks = ArrayRef<uint32_t>(StreamData[Idx].second);
214  auto RemovedBlockList = CurrentBlocks.drop_front(NewBlocks);
215  for (auto P : RemovedBlockList)
216  FreeBlocks[P] = true;
217  StreamData[Idx].second = CurrentBlocks.drop_back(RemovedBlocks);
218  }
219 
220  StreamData[Idx].first = Size;
221  return Error::success();
222 }
223 
224 uint32_t MSFBuilder::getNumStreams() const { return StreamData.size(); }
225 
227  return StreamData[StreamIdx].first;
228 }
229 
231  return StreamData[StreamIdx].second;
232 }
233 
234 uint32_t MSFBuilder::computeDirectoryByteSize() const {
235  // The directory has the following layout, where each item is a ulittle32_t:
236  // NumStreams
237  // StreamSizes[NumStreams]
238  // StreamBlocks[NumStreams][]
239  uint32_t Size = sizeof(ulittle32_t); // NumStreams
240  Size += StreamData.size() * sizeof(ulittle32_t); // StreamSizes
241  for (const auto &D : StreamData) {
242  uint32_t ExpectedNumBlocks = bytesToBlocks(D.first, BlockSize);
243  assert(ExpectedNumBlocks == D.second.size() &&
244  "Unexpected number of blocks");
245  Size += ExpectedNumBlocks * sizeof(ulittle32_t);
246  }
247  return Size;
248 }
249 
251  SuperBlock *SB = Allocator.Allocate<SuperBlock>();
252  MSFLayout L;
253  L.SB = SB;
254 
255  std::memcpy(SB->MagicBytes, Magic, sizeof(Magic));
256  SB->BlockMapAddr = BlockMapAddr;
257  SB->BlockSize = BlockSize;
258  SB->NumDirectoryBytes = computeDirectoryByteSize();
259  SB->FreeBlockMapBlock = FreePageMap;
260  SB->Unknown1 = Unknown1;
261 
262  uint32_t NumDirectoryBlocks = bytesToBlocks(SB->NumDirectoryBytes, BlockSize);
263  if (NumDirectoryBlocks > DirectoryBlocks.size()) {
264  // Our hint wasn't enough to satisfy the entire directory. Allocate
265  // remaining pages.
266  std::vector<uint32_t> ExtraBlocks;
267  uint32_t NumExtraBlocks = NumDirectoryBlocks - DirectoryBlocks.size();
268  ExtraBlocks.resize(NumExtraBlocks);
269  if (auto EC = allocateBlocks(NumExtraBlocks, ExtraBlocks))
270  return std::move(EC);
271  llvm::append_range(DirectoryBlocks, ExtraBlocks);
272  } else if (NumDirectoryBlocks < DirectoryBlocks.size()) {
273  uint32_t NumUnnecessaryBlocks = DirectoryBlocks.size() - NumDirectoryBlocks;
274  for (auto B :
275  ArrayRef<uint32_t>(DirectoryBlocks).drop_back(NumUnnecessaryBlocks))
276  FreeBlocks[B] = true;
277  DirectoryBlocks.resize(NumDirectoryBlocks);
278  }
279 
280  // Don't set the number of blocks in the file until after allocating Blocks
281  // for the directory, since the allocation might cause the file to need to
282  // grow.
283  SB->NumBlocks = FreeBlocks.size();
284 
285  ulittle32_t *DirBlocks = Allocator.Allocate<ulittle32_t>(NumDirectoryBlocks);
286  std::uninitialized_copy_n(DirectoryBlocks.begin(), NumDirectoryBlocks,
287  DirBlocks);
288  L.DirectoryBlocks = ArrayRef<ulittle32_t>(DirBlocks, NumDirectoryBlocks);
289 
290  // The stream sizes should be re-allocated as a stable pointer and the stream
291  // map should have each of its entries allocated as a separate stable pointer.
292  if (!StreamData.empty()) {
293  ulittle32_t *Sizes = Allocator.Allocate<ulittle32_t>(StreamData.size());
294  L.StreamSizes = ArrayRef<ulittle32_t>(Sizes, StreamData.size());
295  L.StreamMap.resize(StreamData.size());
296  for (uint32_t I = 0; I < StreamData.size(); ++I) {
297  Sizes[I] = StreamData[I].first;
298  ulittle32_t *BlockList =
299  Allocator.Allocate<ulittle32_t>(StreamData[I].second.size());
300  std::uninitialized_copy_n(StreamData[I].second.begin(),
301  StreamData[I].second.size(), BlockList);
302  L.StreamMap[I] =
303  ArrayRef<ulittle32_t>(BlockList, StreamData[I].second.size());
304  }
305  }
306 
307  L.FreePageMap = FreeBlocks;
308 
309  return L;
310 }
311 
312 static void commitFpm(WritableBinaryStream &MsfBuffer, const MSFLayout &Layout,
314  auto FpmStream =
316 
317  // We only need to create the alt fpm stream so that it gets initialized.
319  true);
320 
321  uint32_t BI = 0;
322  BinaryStreamWriter FpmWriter(*FpmStream);
323  while (BI < Layout.SB->NumBlocks) {
324  uint8_t ThisByte = 0;
325  for (uint32_t I = 0; I < 8; ++I) {
326  bool IsFree =
327  (BI < Layout.SB->NumBlocks) ? Layout.FreePageMap.test(BI) : true;
328  uint8_t Mask = uint8_t(IsFree) << I;
329  ThisByte |= Mask;
330  ++BI;
331  }
332  cantFail(FpmWriter.writeObject(ThisByte));
333  }
334  assert(FpmWriter.bytesRemaining() == 0);
335 }
336 
338  MSFLayout &Layout) {
340  if (!L)
341  return L.takeError();
342 
343  Layout = std::move(*L);
344 
345  uint64_t FileSize = uint64_t(Layout.SB->BlockSize) * Layout.SB->NumBlocks;
346  if (FileSize > UINT32_MAX) {
347  // FIXME: Changing the BinaryStream classes to use 64-bit numbers lets
348  // us create PDBs larger than 4 GiB successfully. The file format is
349  // block-based and as long as each stream is small enough, PDBs larger than
350  // 4 GiB might work. Check if tools can handle these large PDBs, and if so
351  // add support for writing them.
352  return make_error<MSFError>(
354  formatv("File size would have been {0,1:N}", FileSize));
355  }
356 
357  auto OutFileOrError = FileOutputBuffer::create(Path, FileSize);
358  if (auto EC = OutFileOrError.takeError())
359  return std::move(EC);
360 
361  FileBufferByteStream Buffer(std::move(*OutFileOrError),
363  BinaryStreamWriter Writer(Buffer);
364 
365  if (auto EC = Writer.writeObject(*Layout.SB))
366  return std::move(EC);
367 
368  commitFpm(Buffer, Layout, Allocator);
369 
370  uint32_t BlockMapOffset =
371  msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
372  Writer.setOffset(BlockMapOffset);
373  if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
374  return std::move(EC);
375 
377  Layout, Buffer, Allocator);
378  BinaryStreamWriter DW(*DirStream);
379  if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size()))
380  return std::move(EC);
381 
382  if (auto EC = DW.writeArray(Layout.StreamSizes))
383  return std::move(EC);
384 
385  for (const auto &Blocks : Layout.StreamMap) {
386  if (auto EC = DW.writeArray(Blocks))
387  return std::move(EC);
388  }
389 
390  return std::move(Buffer);
391 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:148
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::msf::MSFBuilder::generateLayout
Expected< MSFLayout > generateLayout()
Finalize the layout and build the headers and structures that describe the MSF layout and can be writ...
Definition: MSFBuilder.cpp:250
llvm::BinaryStreamWriter::writeInteger
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
Definition: BinaryStreamWriter.h:64
BlockSize
static const int BlockSize
Definition: TarWriter.cpp:33
commitFpm
static void commitFpm(WritableBinaryStream &MsfBuffer, const MSFLayout &Layout, BumpPtrAllocator &Allocator)
Definition: MSFBuilder.cpp:312
llvm::msf::MSFLayout::DirectoryBlocks
ArrayRef< support::ulittle32_t > DirectoryBlocks
Definition: MSFCommon.h:66
llvm::msf::bytesToBlocks
uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize)
Definition: MSFCommon.h:108
llvm::msf::msf_error_code::insufficient_buffer
@ insufficient_buffer
llvm::support::detail::packed_endian_specific_integral
Definition: Endian.h:206
llvm::msf::MSFBuilder::setBlockMapAddr
Error setBlockMapAddr(uint32_t Addr)
Request the block map to be at a specific block address.
Definition: MSFBuilder.cpp:62
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
BinaryByteStream.h
llvm::msf::getMinimumBlockCount
uint32_t getMinimumBlockCount()
Definition: MSFCommon.h:102
llvm::BinaryStreamWriter
Provides write only access to a subclass of WritableBinaryStream.
Definition: BinaryStreamWriter.h:31
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::msf::SuperBlock::NumDirectoryBytes
support::ulittle32_t NumDirectoryBytes
Definition: MSFCommon.h:44
llvm::msf::blockToOffset
uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize)
Definition: MSFCommon.h:112
Error.h
llvm::msf::MSFLayout::FreePageMap
BitVector FreePageMap
Definition: MSFCommon.h:65
llvm::msf::isValidBlockSize
bool isValidBlockSize(uint32_t Size)
Definition: MSFCommon.h:90
llvm::BitVector::resize
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Definition: BitVector.h:333
kSuperBlockBlock
static const uint32_t kSuperBlockBlock
Definition: MSFBuilder.cpp:31
llvm::BinaryStreamWriter::setOffset
void setOffset(uint64_t Off)
Definition: BinaryStreamWriter.h:183
FileOutputBuffer.h
llvm::msf::MSFBuilder::addStream
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.
Definition: MSFBuilder.cpp:155
llvm::BinaryStreamWriter::writeArray
Error writeArray(ArrayRef< T > Array)
Writes an array of objects of type T to the underlying stream, as if by using memcpy.
Definition: BinaryStreamWriter.h:151
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::BitmaskEnumDetail::Mask
std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::msf
Definition: IMSFFile.h:18
llvm::msf::MSFBuilder
Definition: MSFBuilder.h:26
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
llvm::BumpPtrAllocatorImpl::Allocate
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:145
llvm::msf::WritableMappedBlockStream::createFpmStream
static std::unique_ptr< WritableMappedBlockStream > createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator, bool AltFpm=false)
Definition: MappedBlockStream.cpp:348
llvm::support::little
@ little
Definition: Endian.h:27
llvm::msf::MSFLayout
Definition: MSFCommon.h:51
llvm::msf::MSFBuilder::commit
Expected< FileBufferByteStream > commit(StringRef Path, MSFLayout &Layout)
Write the MSF layout to the underlying file.
Definition: MSFBuilder.cpp:337
llvm::BitVector::count
size_type count() const
count - Returns the number of bits which are set.
Definition: BitVector.h:154
llvm::BitVector::size
size_type size() const
size - Returns the number of bits in this bitvector.
Definition: BitVector.h:151
llvm::msf::MSFBuilder::isBlockFree
bool isBlockFree(uint32_t Idx) const
Check whether a particular block is allocated or free.
Definition: MSFBuilder.cpp:153
kDefaultBlockMapAddr
static const uint32_t kDefaultBlockMapAddr
Definition: MSFBuilder.cpp:37
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::msf::SuperBlock
Definition: MSFCommon.h:31
llvm::msf::MSFBuilder::getNumFreeBlocks
uint32_t getNumFreeBlocks() const
Get the total number of blocks that exist in the MSF file but are not allocated to any valid data.
Definition: MSFBuilder.cpp:149
MSFBuilder.h
llvm::msf::MSFBuilder::setDirectoryBlocksHint
Error setDirectoryBlocksHint(ArrayRef< uint32_t > DirBlocks)
Definition: MSFBuilder.cpp:87
FormatVariadic.h
kDefaultFreePageMap
static const uint32_t kDefaultFreePageMap
Definition: MSFBuilder.cpp:36
llvm::msf::SuperBlock::NumBlocks
support::ulittle32_t NumBlocks
Definition: MSFCommon.h:42
llvm::msf::MSFBuilder::getStreamSize
uint32_t getStreamSize(uint32_t StreamIdx) const
Get the size of a stream by index.
Definition: MSFBuilder.cpp:226
llvm::msf::MSFLayout::StreamSizes
ArrayRef< support::ulittle32_t > StreamSizes
Definition: MSFCommon.h:67
llvm::msf::MSFBuilder::getStreamBlocks
ArrayRef< uint32_t > getStreamBlocks(uint32_t StreamIdx) const
Get the list of blocks allocated to a particular stream.
Definition: MSFBuilder.cpp:230
llvm::support::ulittle32_t
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
Definition: Endian.h:272
kNumReservedPages
static const uint32_t kNumReservedPages
Definition: MSFBuilder.cpp:34
llvm::BinaryStreamWriter::bytesRemaining
uint64_t bytesRemaining() const
Definition: BinaryStreamWriter.h:186
llvm::msf::MSFBuilder::getNumUsedBlocks
uint32_t getNumUsedBlocks() const
Get the total number of blocks that will be allocated to actual data in this MSF file.
Definition: MSFBuilder.cpp:145
uint64_t
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::msf::MSFBuilder::setUnknown1
void setUnknown1(uint32_t Unk1)
Definition: MSFBuilder.cpp:85
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::msf::SuperBlock::FreeBlockMapBlock
support::ulittle32_t FreeBlockMapBlock
Definition: MSFCommon.h:38
ArrayRef.h
MappedBlockStream.h
llvm::msf::msf_error_code::unspecified
@ unspecified
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::msf::MSFBuilder::getTotalBlockCount
uint32_t getTotalBlockCount() const
Get the total number of blocks in the MSF file.
Definition: MSFBuilder.cpp:151
llvm::msf::MSFBuilder::setStreamSize
Error setStreamSize(uint32_t Idx, uint32_t Size)
Update the size of an existing stream.
Definition: MSFBuilder.cpp:192
llvm::ArrayRef< uint32_t >
llvm::BinaryStreamWriter::writeObject
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
Definition: BinaryStreamWriter.h:135
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
kFreePageMap1Block
static const uint32_t kFreePageMap1Block
Definition: MSFBuilder.cpp:33
llvm::msf::Magic
static const char Magic[]
Definition: MSFCommon.h:23
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:737
uint32_t
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:1748
llvm::msf::SuperBlock::MagicBytes
char MagicBytes[sizeof(Magic)]
Definition: MSFCommon.h:32
llvm::FileOutputBuffer::create
static Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
Definition: FileOutputBuffer.cpp:158
llvm::msf::msf_error_code::size_overflow
@ size_overflow
llvm::BitVector::test
bool test(unsigned Idx) const
Definition: BitVector.h:447
llvm::FileBufferByteStream
An implementation of WritableBinaryStream backed by an llvm FileOutputBuffer.
Definition: BinaryByteStream.h:205
llvm::msf::SuperBlock::BlockSize
support::ulittle32_t BlockSize
Definition: MSFCommon.h:36
llvm::msf::SuperBlock::Unknown1
support::ulittle32_t Unknown1
Definition: MSFCommon.h:46
llvm::msf::MSFBuilder::getNumStreams
uint32_t getNumStreams() const
Get the total number of streams in the MSF layout.
Definition: MSFBuilder.cpp:224
MSFError.h
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::support
Definition: Endian.h:25
llvm::msf::MSFLayout::StreamMap
std::vector< ArrayRef< support::ulittle32_t > > StreamMap
Definition: MSFCommon.h:68
llvm::BitVector::find_next
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
Definition: BitVector.h:300
kFreePageMap0Block
static const uint32_t kFreePageMap0Block
Definition: MSFBuilder.cpp:32
llvm::BitVector::reset
BitVector & reset()
Definition: BitVector.h:384
llvm::msf::MSFBuilder::setFreePageMap
void setFreePageMap(uint32_t Fpm)
Definition: MSFBuilder.cpp:83
llvm::msf::msf_error_code::invalid_format
@ invalid_format
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:589
Allocator
Basic Register Allocator
Definition: RegAllocBasic.cpp:146
llvm::msf::WritableMappedBlockStream::createDirectoryStream
static std::unique_ptr< WritableMappedBlockStream > createDirectoryStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
Definition: MappedBlockStream.cpp:338
llvm::BitVector::find_first
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
Definition: BitVector.h:292
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::msf::msf_error_code::block_in_use
@ block_in_use
llvm::msf::MSFLayout::SB
const SuperBlock * SB
Definition: MSFCommon.h:64
BinaryStreamWriter.h
Endian.h
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1815
llvm::msf::SuperBlock::BlockMapAddr
support::ulittle32_t BlockMapAddr
Definition: MSFCommon.h:48
llvm::WritableBinaryStream
A BinaryStream which can be read from as well as written to.
Definition: BinaryStream.h:73