|
15 | 15 | #include "llvm/ADT/StringMap.h" |
16 | 16 | #include "llvm/Bitstream/BitstreamWriter.h" |
17 | 17 | #include "llvm/Support/Allocator.h" |
| 18 | +#include "llvm/Support/Compression.h" |
18 | 19 | #include "llvm/Support/Errc.h" |
19 | 20 | #include "llvm/Support/FileSystem.h" |
20 | 21 | #include "llvm/Support/Path.h" |
@@ -116,21 +117,14 @@ class IndexUnitWriter::PathStorage { |
116 | 117 | } |
117 | 118 | }; |
118 | 119 |
|
119 | | -IndexUnitWriter::IndexUnitWriter(FileManager &FileMgr, |
120 | | - StringRef StorePath, |
121 | | - StringRef ProviderIdentifier, |
122 | | - StringRef ProviderVersion, |
123 | | - StringRef OutputFile, |
124 | | - StringRef ModuleName, |
125 | | - OptionalFileEntryRef MainFile, |
126 | | - bool IsSystem, |
127 | | - bool IsModuleUnit, |
128 | | - bool IsDebugCompilation, |
129 | | - StringRef TargetTriple, |
130 | | - StringRef SysrootPath, |
131 | | - const PathRemapper &Remapper, |
132 | | - writer::ModuleInfoWriterCallback GetInfoForModule) |
133 | | -: FileMgr(FileMgr), Remapper(Remapper) { |
| 120 | +IndexUnitWriter::IndexUnitWriter( |
| 121 | + FileManager &FileMgr, StringRef StorePath, StringRef ProviderIdentifier, |
| 122 | + StringRef ProviderVersion, bool Compress, StringRef OutputFile, |
| 123 | + StringRef ModuleName, OptionalFileEntryRef MainFile, bool IsSystem, |
| 124 | + bool IsModuleUnit, bool IsDebugCompilation, StringRef TargetTriple, |
| 125 | + StringRef SysrootPath, const PathRemapper &Remapper, |
| 126 | + writer::ModuleInfoWriterCallback GetInfoForModule) |
| 127 | + : FileMgr(FileMgr), Compress(Compress), Remapper(Remapper) { |
134 | 128 | this->UnitsPath = StorePath; |
135 | 129 | store::appendUnitSubDir(this->UnitsPath); |
136 | 130 | this->ProviderIdentifier = std::string(ProviderIdentifier); |
@@ -393,7 +387,34 @@ bool IndexUnitWriter::write(std::string &Error) { |
393 | 387 | } |
394 | 388 |
|
395 | 389 | raw_fd_ostream OS(TempFD, /*shouldClose=*/true); |
396 | | - OS.write(Buffer.data(), Buffer.size()); |
| 390 | + if (Compress) { |
| 391 | + if (!llvm::compression::zlib::isAvailable()) { |
| 392 | + Error = "Zlib not available to compress record file"; |
| 393 | + return true; |
| 394 | + } |
| 395 | + |
| 396 | + // See comment in `IndexRecordWriter::endRecord` for a rational why we use |
| 397 | + // `BestSpeed`. |
| 398 | + auto compressionLevel = compression::zlib::BestSpeedCompression; |
| 399 | + ArrayRef<uint8_t> bufferRef = llvm::arrayRefFromStringRef(Buffer); |
| 400 | + llvm::SmallVector<uint8_t, 0> compressed; |
| 401 | + llvm::compression::zlib::compress(bufferRef, compressed, compressionLevel); |
| 402 | + |
| 403 | + // Write the `CIDXU` (compressed index unit) marker to indicate that this |
| 404 | + // is a compressed unit file. |
| 405 | + OS << "CIDXU"; |
| 406 | + |
| 407 | + // Write the size of the uncompressed unit so that we can allocate a |
| 408 | + // buffer of the corresponding size when decompressing it. |
| 409 | + char Buf[4]; |
| 410 | + llvm::support::endian::write32le(Buf, bufferRef.size()); |
| 411 | + OS.write(Buf, sizeof(Buf)); |
| 412 | + |
| 413 | + // Write the acutal compressed data |
| 414 | + OS << llvm::toStringRef(compressed); |
| 415 | + } else { |
| 416 | + OS << Buffer; |
| 417 | + } |
397 | 418 | OS.close(); |
398 | 419 |
|
399 | 420 | if (OS.has_error()) { |
|
0 commit comments