ckissane updated this revision to Diff 453803.
ckissane added a comment.
- shorten compression related variable names
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D131992/new/
https://reviews.llvm.org/D131992
Files:
clang-tools-extra/clangd/index/Serialization.cpp
clang-tools-extra/clangd/unittests/SerializationTests.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
lld/ELF/Driver.cpp
lld/ELF/InputSection.cpp
llvm/include/llvm/Object/Decompressor.h
llvm/include/llvm/ProfileData/InstrProf.h
llvm/include/llvm/Support/Compression.h
llvm/lib/MC/ELFObjectWriter.cpp
llvm/lib/ObjCopy/ELF/ELFObject.cpp
llvm/lib/Object/Decompressor.cpp
llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
llvm/lib/ProfileData/InstrProf.cpp
llvm/lib/ProfileData/InstrProfCorrelator.cpp
llvm/lib/ProfileData/SampleProfReader.cpp
llvm/lib/ProfileData/SampleProfWriter.cpp
llvm/lib/Support/Compression.cpp
llvm/tools/llvm-mc/llvm-mc.cpp
llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
llvm/unittests/ProfileData/InstrProfTest.cpp
llvm/unittests/Support/CompressionTest.cpp
Index: llvm/unittests/Support/CompressionTest.cpp
===================================================================
--- llvm/unittests/Support/CompressionTest.cpp
+++ llvm/unittests/Support/CompressionTest.cpp
@@ -22,31 +22,44 @@
namespace {
-#if LLVM_ENABLE_ZLIB
-static void testZlibCompression(StringRef Input, int Level) {
+static void testCompressionAlgorithm(
+ StringRef Input, int Level, CompressionSpec *CSpec,
+ std::string ExpectedDestinationBufferTooSmallErrorMessage) {
SmallVector<uint8_t, 0> Compressed;
SmallVector<uint8_t, 0> Uncompressed;
- zlib::compress(arrayRefFromStringRef(Input), Compressed, Level);
+ CSpec->Implementation->compress(arrayRefFromStringRef(Input), Compressed,
+ Level);
// Check that uncompressed buffer is the same as original.
- Error E = zlib::uncompress(Compressed, Uncompressed, Input.size());
+ Error E =
+ CSpec->Implementation->decompress(Compressed, Uncompressed, Input.size());
consumeError(std::move(E));
EXPECT_EQ(Input, toStringRef(Uncompressed));
if (Input.size() > 0) {
// Uncompression fails if expected length is too short.
- E = zlib::uncompress(Compressed, Uncompressed, Input.size() - 1);
- EXPECT_EQ("zlib error: Z_BUF_ERROR", llvm::toString(std::move(E)));
+ E = CSpec->Implementation->decompress(Compressed, Uncompressed,
+ Input.size() - 1);
+ EXPECT_EQ(ExpectedDestinationBufferTooSmallErrorMessage,
+ llvm::toString(std::move(E)));
}
}
+#if LLVM_ENABLE_ZLIB
+static void testZlibCompression(StringRef Input, int Level) {
+ testCompressionAlgorithm(Input, Level,
+ getCompressionSpec(CompressionKind::Zlib),
+ "zlib error: Z_BUF_ERROR");
+}
+
TEST(CompressionTest, Zlib) {
- testZlibCompression("", zlib::DefaultCompression);
+ CompressionSpec *CSpec = getCompressionSpec(CompressionKind::Zlib);
+ CompressionImpl *CImpl = CSpec->Implementation;
+ testZlibCompression("", CImpl->DefaultLevel);
- testZlibCompression("hello, world!", zlib::NoCompression);
- testZlibCompression("hello, world!", zlib::BestSizeCompression);
- testZlibCompression("hello, world!", zlib::BestSpeedCompression);
- testZlibCompression("hello, world!", zlib::DefaultCompression);
+ testZlibCompression("hello, world!", CImpl->BestSizeLevel);
+ testZlibCompression("hello, world!", CImpl->BestSpeedLevel);
+ testZlibCompression("hello, world!", CImpl->DefaultLevel);
const size_t kSize = 1024;
char BinaryData[kSize];
@@ -54,38 +67,27 @@
BinaryData[i] = i & 255;
StringRef BinaryDataStr(BinaryData, kSize);
- testZlibCompression(BinaryDataStr, zlib::NoCompression);
- testZlibCompression(BinaryDataStr, zlib::BestSizeCompression);
- testZlibCompression(BinaryDataStr, zlib::BestSpeedCompression);
- testZlibCompression(BinaryDataStr, zlib::DefaultCompression);
+ testZlibCompression(BinaryDataStr, CImpl->BestSizeLevel);
+ testZlibCompression(BinaryDataStr, CImpl->BestSpeedLevel);
+ testZlibCompression(BinaryDataStr, CImpl->DefaultLevel);
}
#endif
#if LLVM_ENABLE_ZSTD
-static void testZstdCompression(StringRef Input, int Level) {
- SmallVector<uint8_t, 0> Compressed;
- SmallVector<uint8_t, 0> Uncompressed;
- zstd::compress(arrayRefFromStringRef(Input), Compressed, Level);
-
- // Check that uncompressed buffer is the same as original.
- Error E = zstd::uncompress(Compressed, Uncompressed, Input.size());
- consumeError(std::move(E));
-
- EXPECT_EQ(Input, toStringRef(Uncompressed));
- if (Input.size() > 0) {
- // Uncompression fails if expected length is too short.
- E = zstd::uncompress(Compressed, Uncompressed, Input.size() - 1);
- EXPECT_EQ("Destination buffer is too small", llvm::toString(std::move(E)));
- }
+static void testZStdCompression(StringRef Input, int Level) {
+ testCompressionAlgorithm(Input, Level,
+ getCompressionSpec(CompressionKind::ZStd),
+ "Destination buffer is too small");
}
-TEST(CompressionTest, Zstd) {
- testZstdCompression("", zstd::DefaultCompression);
+TEST(CompressionTest, ZStd) {
+ CompressionSpec *CSpec = getCompressionSpec(CompressionKind::ZStd);
+ CompressionImpl *CImpl = CSpec->Implementation;
+ testZStdCompression("", CImpl->DefaultLevel);
- testZstdCompression("hello, world!", zstd::NoCompression);
- testZstdCompression("hello, world!", zstd::BestSizeCompression);
- testZstdCompression("hello, world!", zstd::BestSpeedCompression);
- testZstdCompression("hello, world!", zstd::DefaultCompression);
+ testZStdCompression("hello, world!", CImpl->BestSizeLevel);
+ testZStdCompression("hello, world!", CImpl->BestSpeedLevel);
+ testZStdCompression("hello, world!", CImpl->DefaultLevel);
const size_t kSize = 1024;
char BinaryData[kSize];
@@ -93,10 +95,9 @@
BinaryData[i] = i & 255;
StringRef BinaryDataStr(BinaryData, kSize);
- testZstdCompression(BinaryDataStr, zstd::NoCompression);
- testZstdCompression(BinaryDataStr, zstd::BestSizeCompression);
- testZstdCompression(BinaryDataStr, zstd::BestSpeedCompression);
- testZstdCompression(BinaryDataStr, zstd::DefaultCompression);
+ testZStdCompression(BinaryDataStr, CImpl->BestSizeLevel);
+ testZStdCompression(BinaryDataStr, CImpl->BestSpeedLevel);
+ testZStdCompression(BinaryDataStr, CImpl->DefaultLevel);
}
#endif
-}
+} // namespace
Index: llvm/unittests/ProfileData/InstrProfTest.cpp
===================================================================
--- llvm/unittests/ProfileData/InstrProfTest.cpp
+++ llvm/unittests/ProfileData/InstrProfTest.cpp
@@ -22,6 +22,7 @@
#include <cstdarg>
using namespace llvm;
+using namespace llvm::compression;
LLVM_NODISCARD static ::testing::AssertionResult
ErrorEquals(instrprof_error Expected, Error E) {
@@ -1146,19 +1147,29 @@
for (bool DoCompression : {false, true}) {
// Compressing:
std::string FuncNameStrings1;
- EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
- FuncNames1,
- (DoCompression && compression::zlib::isAvailable()),
- FuncNameStrings1),
- Succeeded());
+ EXPECT_THAT_ERROR(
+ collectPGOFuncNameStrings(
+ FuncNames1,
+ DoCompression &&
+ (getCompressionSpec(CompressionKind::Zlib) &&
+ getCompressionSpec(CompressionKind::Zlib)->Implementation)
+ ? getCompressionSpec(CompressionKind::Zlib)
+ : nullptr,
+ FuncNameStrings1),
+ Succeeded());
// Compressing:
std::string FuncNameStrings2;
- EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
- FuncNames2,
- (DoCompression && compression::zlib::isAvailable()),
- FuncNameStrings2),
- Succeeded());
+ EXPECT_THAT_ERROR(
+ collectPGOFuncNameStrings(
+ FuncNames2,
+ DoCompression &&
+ (getCompressionSpec(CompressionKind::Zlib) &&
+ getCompressionSpec(CompressionKind::Zlib)->Implementation)
+ ? getCompressionSpec(CompressionKind::Zlib)
+ : nullptr,
+ FuncNameStrings2),
+ Succeeded());
for (int Padding = 0; Padding < 2; Padding++) {
// Join with paddings :
Index: llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
===================================================================
--- llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -25,6 +25,7 @@
#include "llvm/Support/MemoryBuffer.h"
using namespace llvm;
+using namespace llvm::compression;
using namespace llvm::objcopy;
namespace {
@@ -723,15 +724,19 @@
Config.CompressionType = StringSwitch<DebugCompressionType>(A->getValue())
.Case("zlib", DebugCompressionType::Z)
.Default(DebugCompressionType::None);
- if (Config.CompressionType == DebugCompressionType::None)
+ switch (Config.CompressionType) {
+ case DebugCompressionType::None:
return createStringError(
errc::invalid_argument,
"invalid or unsupported --compress-debug-sections format: %s",
A->getValue());
- if (!compression::zlib::isAvailable())
- return createStringError(
- errc::invalid_argument,
- "LLVM was not compiled with LLVM_ENABLE_ZLIB: can not compress");
+ case DebugCompressionType::Z:
+ if (!getCompressionSpec(CompressionKind::Zlib)->Implementation)
+ return createStringError(
+ errc::invalid_argument,
+ "LLVM was not compiled with LLVM_ENABLE_ZLIB: can not compress");
+ break;
+ }
}
Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink);
@@ -993,7 +998,8 @@
"--decompress-debug-sections");
}
- if (Config.DecompressDebugSections && !compression::zlib::isAvailable())
+ if (Config.DecompressDebugSections &&
+ !getCompressionSpec(CompressionKind::Zlib)->Implementation)
return createStringError(
errc::invalid_argument,
"LLVM was not compiled with LLVM_ENABLE_ZLIB: cannot decompress");
Index: llvm/tools/llvm-mc/llvm-mc.cpp
===================================================================
--- llvm/tools/llvm-mc/llvm-mc.cpp
+++ llvm/tools/llvm-mc/llvm-mc.cpp
@@ -40,6 +40,7 @@
#include "llvm/Support/WithColor.h"
using namespace llvm;
+using namespace llvm::compression;
static mc::RegisterMCTargetOptionsFlags MOF;
@@ -401,7 +402,7 @@
MAI->setRelaxELFRelocations(RelaxELFRel);
if (CompressDebugSections != DebugCompressionType::None) {
- if (!compression::zlib::isAvailable()) {
+ if (!getCompressionSpec(CompressionKind::Zlib)->Implementation) {
WithColor::error(errs(), ProgName)
<< "build tools with zlib to enable -compress-debug-sections";
return 1;
Index: llvm/lib/Support/Compression.cpp
===================================================================
--- llvm/lib/Support/Compression.cpp
+++ llvm/lib/Support/Compression.cpp
@@ -27,6 +27,10 @@
using namespace llvm;
using namespace llvm::compression;
+namespace llvm {
+
+namespace compression {
+
#if LLVM_ENABLE_ZLIB
static StringRef convertZlibCodeToString(int Code) {
@@ -44,124 +48,141 @@
llvm_unreachable("unknown or unexpected zlib status code");
}
}
+#endif
+struct ZlibCompressionAlgorithm : public CompressionImpl {
+#if LLVM_ENABLE_ZLIB
-bool zlib::isAvailable() { return true; }
-
-void zlib::compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
- unsigned long CompressedSize = ::compressBound(Input.size());
- CompressedBuffer.resize_for_overwrite(CompressedSize);
- int Res = ::compress2((Bytef *)CompressedBuffer.data(), &CompressedSize,
- (const Bytef *)Input.data(), Input.size(), Level);
- if (Res == Z_MEM_ERROR)
- report_bad_alloc_error("Allocation failed");
- assert(Res == Z_OK);
- // Tell MemorySanitizer that zlib output buffer is fully initialized.
- // This avoids a false report when running LLVM with uninstrumented ZLib.
- __msan_unpoison(CompressedBuffer.data(), CompressedSize);
- if (CompressedSize < CompressedBuffer.size())
- CompressedBuffer.truncate(CompressedSize);
-}
+ void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
+ unsigned long CompressedSize = ::compressBound(Input.size());
+ CompressedBuffer.resize_for_overwrite(CompressedSize);
+ int Res = ::compress2((Bytef *)CompressedBuffer.data(), &CompressedSize,
+ (const Bytef *)Input.data(), Input.size(), Level);
+ if (Res == Z_MEM_ERROR)
+ report_bad_alloc_error("Allocation failed");
+ assert(Res == Z_OK);
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(CompressedBuffer.data(), CompressedSize);
+ if (CompressedSize < CompressedBuffer.size())
+ CompressedBuffer.truncate(CompressedSize);
+ };
+ Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ int Res =
+ ::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize,
+ (const Bytef *)Input.data(), Input.size());
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(UncompressedBuffer, UncompressedSize);
+ return Res ? make_error<StringError>(convertZlibCodeToString(Res),
+ inconvertibleErrorCode())
+ : Error::success();
+ };
-Error zlib::uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize) {
- int Res =
- ::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize,
- (const Bytef *)Input.data(), Input.size());
- // Tell MemorySanitizer that zlib output buffer is fully initialized.
- // This avoids a false report when running LLVM with uninstrumented ZLib.
- __msan_unpoison(UncompressedBuffer, UncompressedSize);
- return Res ? make_error<StringError>(convertZlibCodeToString(Res),
- inconvertibleErrorCode())
- : Error::success();
-}
+#else
-Error zlib::uncompress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &UncompressedBuffer,
- size_t UncompressedSize) {
- UncompressedBuffer.resize_for_overwrite(UncompressedSize);
- Error E =
- zlib::uncompress(Input, UncompressedBuffer.data(), UncompressedSize);
- if (UncompressedSize < UncompressedBuffer.size())
- UncompressedBuffer.truncate(UncompressedSize);
- return E;
-}
+ void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
+ llvm_unreachable("method:\"compress\" is unsupported for compression "
+ "algorithm:\"zlib\", "
+ "reason:\"llvm not compiled with zlib support\"");
+ };
+ Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ llvm_unreachable(
+ "method:\"decompress\" is unsupported for compression "
+ "algorithm:\"zlib\", reason:\"llvm not compiled with zlib support\"");
+ };
-#else
-bool zlib::isAvailable() { return false; }
-void zlib::compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
- llvm_unreachable("zlib::compress is unavailable");
-}
-Error zlib::uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize) {
- llvm_unreachable("zlib::uncompress is unavailable");
-}
-Error zlib::uncompress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &UncompressedBuffer,
- size_t UncompressedSize) {
- llvm_unreachable("zlib::uncompress is unavailable");
-}
#endif
+protected:
+ friend CompressionSpec *getCompressionSpec(uint8_t Kind);
+ ZlibCompressionAlgorithm()
+ : CompressionImpl(CompressionKind::Zlib, 1, 6, 9) {}
+};
+
+struct ZStdCompressionAlgorithm : public CompressionImpl {
#if LLVM_ENABLE_ZSTD
-bool zstd::isAvailable() { return true; }
-
-void zstd::compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
- unsigned long CompressedBufferSize = ::ZSTD_compressBound(Input.size());
- CompressedBuffer.resize_for_overwrite(CompressedBufferSize);
- unsigned long CompressedSize =
- ::ZSTD_compress((char *)CompressedBuffer.data(), CompressedBufferSize,
- (const char *)Input.data(), Input.size(), Level);
- if (ZSTD_isError(CompressedSize))
- report_bad_alloc_error("Allocation failed");
- // Tell MemorySanitizer that zstd output buffer is fully initialized.
- // This avoids a false report when running LLVM with uninstrumented ZLib.
- __msan_unpoison(CompressedBuffer.data(), CompressedSize);
- if (CompressedSize < CompressedBuffer.size())
- CompressedBuffer.truncate(CompressedSize);
-}
+ void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
+ unsigned long CompressedBufferSize = ::ZSTD_compressBound(Input.size());
+ CompressedBuffer.resize_for_overwrite(CompressedBufferSize);
+ unsigned long CompressedSize =
+ ::ZSTD_compress((char *)CompressedBuffer.data(), CompressedBufferSize,
+ (const char *)Input.data(), Input.size(), Level);
+ if (ZSTD_isError(CompressedSize))
+ report_bad_alloc_error("Allocation failed");
+ // Tell MemorySanitizer that zstd output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(CompressedBuffer.data(), CompressedSize);
+ if (CompressedSize < CompressedBuffer.size())
+ CompressedBuffer.truncate(CompressedSize);
+ };
+ Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ const size_t Res =
+ ::ZSTD_decompress(UncompressedBuffer, UncompressedSize,
+ (const uint8_t *)Input.data(), Input.size());
+ UncompressedSize = Res;
+ // Tell MemorySanitizer that zstd output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(UncompressedBuffer, UncompressedSize);
+ return ZSTD_isError(Res) ? make_error<StringError>(ZSTD_getErrorName(Res),
+ inconvertibleErrorCode())
+ : Error::success();
+ };
-Error zstd::uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize) {
- const size_t Res =
- ::ZSTD_decompress(UncompressedBuffer, UncompressedSize,
- (const uint8_t *)Input.data(), Input.size());
- UncompressedSize = Res;
- // Tell MemorySanitizer that zstd output buffer is fully initialized.
- // This avoids a false report when running LLVM with uninstrumented ZLib.
- __msan_unpoison(UncompressedBuffer, UncompressedSize);
- return ZSTD_isError(Res) ? make_error<StringError>(ZSTD_getErrorName(Res),
- inconvertibleErrorCode())
- : Error::success();
-}
+#else
-Error zstd::uncompress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &UncompressedBuffer,
- size_t UncompressedSize) {
- UncompressedBuffer.resize_for_overwrite(UncompressedSize);
- Error E =
- zstd::uncompress(Input, UncompressedBuffer.data(), UncompressedSize);
- if (UncompressedSize < UncompressedBuffer.size())
- UncompressedBuffer.truncate(UncompressedSize);
- return E;
-}
+ void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
+ llvm_unreachable("method:\"compress\" is unsupported for compression "
+ "algorithm:\"zstd\", "
+ "reason:\"llvm not compiled with zstd support\"");
+ };
+ Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ llvm_unreachable(
+ "method:\"decompress\" is unsupported for compression "
+ "algorithm:\"zstd\", reason:\"llvm not compiled with zstd support\"");
+ };
-#else
-bool zstd::isAvailable() { return false; }
-void zstd::compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
- llvm_unreachable("zstd::compress is unavailable");
-}
-Error zstd::uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize) {
- llvm_unreachable("zstd::uncompress is unavailable");
-}
-Error zstd::uncompress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &UncompressedBuffer,
- size_t UncompressedSize) {
- llvm_unreachable("zstd::uncompress is unavailable");
-}
#endif
+
+protected:
+ friend CompressionSpec *getCompressionSpec(uint8_t Kind);
+ ZStdCompressionAlgorithm()
+ : CompressionImpl(CompressionKind::ZStd, 1, 5, 12) {}
+};
+
+CompressionSpec *getCompressionSpec(uint8_t Kind) {
+ static ZlibCompressionAlgorithm ZlibI;
+ static CompressionSpec ZlibD = CompressionSpec(
+ CompressionKind::Zlib, &ZlibI, "zlib", bool(LLVM_ENABLE_ZLIB),
+ "unsupported: either llvm was compiled without LLVM_ENABLE_ZLIB "
+ "enabled, or could not find zlib at compile time");
+ static ZStdCompressionAlgorithm ZStdI;
+ static CompressionSpec ZStdD = CompressionSpec(
+ CompressionKind::ZStd, &ZStdI, "zstd", bool(LLVM_ENABLE_ZSTD),
+ "unsupported: either llvm was compiled without LLVM_ENABLE_ZSTD "
+ "enabled, or could not find zstd at compile time");
+ static CompressionSpec UnknownD =
+ CompressionSpec(CompressionKind::Unknown, nullptr, "unknown", false,
+ "unsupported: scheme of unknown kind");
+ switch (Kind) {
+ case uint8_t(0):
+ return nullptr;
+ case uint8_t(CompressionKind::Zlib):
+ return &ZlibD;
+ case uint8_t(CompressionKind::ZStd):
+ return &ZStdD;
+ default:
+ return &UnknownD;
+ }
+}
+
+} // namespace compression
+} // namespace llvm
Index: llvm/lib/ProfileData/SampleProfWriter.cpp
===================================================================
--- llvm/lib/ProfileData/SampleProfWriter.cpp
+++ llvm/lib/ProfileData/SampleProfWriter.cpp
@@ -38,6 +38,7 @@
#include <vector>
using namespace llvm;
+using namespace llvm::compression;
using namespace sampleprof;
std::error_code
@@ -78,22 +79,25 @@
}
std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() {
- if (!llvm::compression::zlib::isAvailable())
- return sampleprof_error::zlib_unavailable;
- std::string &UncompressedStrings =
- static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
- if (UncompressedStrings.size() == 0)
- return sampleprof_error::success;
- auto &OS = *OutputStream;
- SmallVector<uint8_t, 128> CompressedStrings;
- compression::zlib::compress(arrayRefFromStringRef(UncompressedStrings),
- CompressedStrings,
- compression::zlib::BestSizeCompression);
- encodeULEB128(UncompressedStrings.size(), OS);
- encodeULEB128(CompressedStrings.size(), OS);
- OS << toStringRef(CompressedStrings);
- UncompressedStrings.clear();
- return sampleprof_error::success;
+
+ if (CompressionSpec *CSpec = getCompressionSpec(CompressionKind::Zlib)) {
+ if (CompressionImpl *CImpl = CSpec->Implementation) {
+ std::string &UncompressedStrings =
+ static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
+ if (UncompressedStrings.size() == 0)
+ return sampleprof_error::success;
+ auto &OS = *OutputStream;
+ SmallVector<uint8_t, 128> CompressedStrings;
+ CImpl->compress(arrayRefFromStringRef(UncompressedStrings),
+ CompressedStrings, CImpl->BestSizeLevel);
+ encodeULEB128(UncompressedStrings.size(), OS);
+ encodeULEB128(CompressedStrings.size(), OS);
+ OS << toStringRef(CompressedStrings);
+ UncompressedStrings.clear();
+ return sampleprof_error::success;
+ }
+ }
+ return sampleprof_error::zlib_unavailable;
}
/// Add a new section into section header table given the section type
Index: llvm/lib/ProfileData/SampleProfReader.cpp
===================================================================
--- llvm/lib/ProfileData/SampleProfReader.cpp
+++ llvm/lib/ProfileData/SampleProfReader.cpp
@@ -44,6 +44,7 @@
#include <vector>
using namespace llvm;
+using namespace llvm::compression;
using namespace sampleprof;
#define DEBUG_TYPE "samplepgo-reader"
@@ -877,17 +878,19 @@
if (std::error_code EC = CompressSize.getError())
return EC;
- if (!llvm::compression::zlib::isAvailable())
- return sampleprof_error::zlib_unavailable;
+ if (CompressionImpl *CImpl =
+ getCompressionSpec(CompressionKind::Zlib)->Implementation) {
- uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
- size_t UCSize = DecompressBufSize;
- llvm::Error E = compression::zlib::uncompress(
- makeArrayRef(Data, *CompressSize), Buffer, UCSize);
- if (E)
- return sampleprof_error::uncompress_failed;
- DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
- return sampleprof_error::success;
+ uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
+ size_t UCSize = DecompressBufSize;
+ llvm::Error E =
+ CImpl->decompress(makeArrayRef(Data, *CompressSize), Buffer, UCSize);
+ if (E)
+ return sampleprof_error::uncompress_failed;
+ DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
+ return sampleprof_error::success;
+ }
+ return sampleprof_error::zlib_unavailable;
}
std::error_code SampleProfileReaderExtBinaryBase::readImpl() {
Index: llvm/lib/ProfileData/InstrProfCorrelator.cpp
===================================================================
--- llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -15,6 +15,7 @@
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Object/MachO.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "correlator"
@@ -148,8 +149,8 @@
return make_error<InstrProfError>(
instrprof_error::unable_to_correlate_profile,
"could not find any profile metadata in debug info");
- auto Result =
- collectPGOFuncNameStrings(NamesVec, /*doCompression=*/false, Names);
+ auto Result = collectPGOFuncNameStrings(NamesVec,
+ /*CSpec=*/nullptr, Names);
CounterOffsets.clear();
NamesVec.clear();
return Result;
Index: llvm/lib/ProfileData/InstrProf.cpp
===================================================================
--- llvm/lib/ProfileData/InstrProf.cpp
+++ llvm/lib/ProfileData/InstrProf.cpp
@@ -55,6 +55,7 @@
#include <vector>
using namespace llvm;
+using namespace llvm::compression;
static cl::opt<bool> StaticFuncFullModulePrefix(
"static-func-full-module-prefix", cl::init(true), cl::Hidden,
@@ -436,7 +437,7 @@
}
Error collectPGOFuncNameStrings(ArrayRef<std::string> NameStrs,
- bool doCompression, std::string &Result) {
+ CompressionSpec *CSpec, std::string &Result) {
assert(!NameStrs.empty() && "No name data to emit");
uint8_t Header[16], *P = Header;
@@ -460,14 +461,12 @@
return Error::success();
};
- if (!doCompression) {
+ if ((!CSpec) || (!(CSpec->Implementation)))
return WriteStringToResult(0, UncompressedNameStrings);
- }
-
+ CompressionImpl *CImpl = CSpec->Implementation;
SmallVector<uint8_t, 128> CompressedNameStrings;
- compression::zlib::compress(arrayRefFromStringRef(UncompressedNameStrings),
- CompressedNameStrings,
- compression::zlib::BestSizeCompression);
+ CImpl->compress(arrayRefFromStringRef(UncompressedNameStrings),
+ CompressedNameStrings, CImpl->BestSizeLevel);
return WriteStringToResult(CompressedNameStrings.size(),
toStringRef(CompressedNameStrings));
@@ -486,8 +485,9 @@
for (auto *NameVar : NameVars) {
NameStrs.push_back(std::string(getPGOFuncNameVarInitializer(NameVar)));
}
- return collectPGOFuncNameStrings(
- NameStrs, compression::zlib::isAvailable() && doCompression, Result);
+ CompressionSpec *CSpec = getCompressionSpec(CompressionKind::Zlib);
+ return collectPGOFuncNameStrings(NameStrs, doCompression ? CSpec : nullptr,
+ Result);
}
Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) {
@@ -503,17 +503,19 @@
SmallVector<uint8_t, 128> UncompressedNameStrings;
StringRef NameStrings;
if (isCompressed) {
- if (!llvm::compression::zlib::isAvailable())
+ CompressionSpec *CSpec = getCompressionSpec(CompressionKind::Zlib);
+ if (CompressionImpl *CImpl = CSpec->Implementation) {
+
+ if (Error E =
+ CImpl->decompress(makeArrayRef(P, CompressedSize),
+ UncompressedNameStrings, UncompressedSize)) {
+ consumeError(std::move(E));
+ return make_error<InstrProfError>(instrprof_error::uncompress_failed);
+ }
+ P += CompressedSize;
+ NameStrings = toStringRef(UncompressedNameStrings);
+ } else
return make_error<InstrProfError>(instrprof_error::zlib_unavailable);
-
- if (Error E = compression::zlib::uncompress(
- makeArrayRef(P, CompressedSize), UncompressedNameStrings,
- UncompressedSize)) {
- consumeError(std::move(E));
- return make_error<InstrProfError>(instrprof_error::uncompress_failed);
- }
- P += CompressedSize;
- NameStrings = toStringRef(UncompressedNameStrings);
} else {
NameStrings =
StringRef(reinterpret_cast<const char *>(P), UncompressedSize);
Index: llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
===================================================================
--- llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -11,10 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ProfileData/InstrProf.h"
#include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
@@ -24,6 +24,7 @@
#include <vector>
using namespace llvm;
+using namespace llvm::compression;
using namespace coverage;
CoverageFilenamesSectionWriter::CoverageFilenamesSectionWriter(
@@ -47,12 +48,14 @@
}
SmallVector<uint8_t, 128> CompressedStr;
- bool doCompression = Compress && compression::zlib::isAvailable() &&
- DoInstrProfNameCompression;
- if (doCompression)
- compression::zlib::compress(arrayRefFromStringRef(FilenamesStr),
- CompressedStr,
- compression::zlib::BestSizeCompression);
+ CompressionSpec *CSpec = getCompressionSpec(CompressionKind::Zlib);
+ bool DoCompression = Compress && DoInstrProfNameCompression &&
+ (CSpec && CSpec->Implementation);
+ if (DoCompression) {
+ CSpec->Implementation->compress(arrayRefFromStringRef(FilenamesStr),
+ CompressedStr,
+ CSpec->Implementation->BestSizeLevel);
+ }
// ::= <num-filenames>
// <uncompressed-len>
@@ -60,8 +63,8 @@
// (<compressed-filenames> | <uncompressed-filenames>)
encodeULEB128(Filenames.size(), OS);
encodeULEB128(FilenamesStr.size(), OS);
- encodeULEB128(doCompression ? CompressedStr.size() : 0U, OS);
- OS << (doCompression ? toStringRef(CompressedStr) : StringRef(FilenamesStr));
+ encodeULEB128(DoCompression ? CompressedStr.size() : 0U, OS);
+ OS << (DoCompression ? toStringRef(CompressedStr) : StringRef(FilenamesStr));
}
namespace {
Index: llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
===================================================================
--- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -39,6 +39,7 @@
#include <vector>
using namespace llvm;
+using namespace llvm::compression;
using namespace coverage;
using namespace object;
@@ -119,28 +120,29 @@
return Err;
if (CompressedLen > 0) {
- if (!compression::zlib::isAvailable())
- return make_error<CoverageMapError>(
- coveragemap_error::decompression_failed);
-
- // Allocate memory for the decompressed filenames.
- SmallVector<uint8_t, 0> StorageBuf;
-
- // Read compressed filenames.
- StringRef CompressedFilenames = Data.substr(0, CompressedLen);
- Data = Data.substr(CompressedLen);
- auto Err = compression::zlib::uncompress(
- arrayRefFromStringRef(CompressedFilenames), StorageBuf,
- UncompressedLen);
- if (Err) {
- consumeError(std::move(Err));
- return make_error<CoverageMapError>(
- coveragemap_error::decompression_failed);
- }
+ if (CompressionImpl *CImpl =
+ getCompressionSpec(CompressionKind::Zlib)->Implementation) {
+
+ // Allocate memory for the decompressed filenames.
+ SmallVector<uint8_t, 0> StorageBuf;
+
+ // Read compressed filenames.
+ StringRef CompressedFilenames = Data.substr(0, CompressedLen);
+ Data = Data.substr(CompressedLen);
+ auto Err = CImpl->decompress(arrayRefFromStringRef(CompressedFilenames),
+ StorageBuf, UncompressedLen);
+ if (Err) {
+ consumeError(std::move(Err));
+ return make_error<CoverageMapError>(
+ coveragemap_error::decompression_failed);
+ }
- RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
- CompilationDir);
- return Delegate.readUncompressed(Version, NumFilenames);
+ RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
+ CompilationDir);
+ return Delegate.readUncompressed(Version, NumFilenames);
+ }
+ return make_error<CoverageMapError>(
+ coveragemap_error::decompression_failed);
}
return readUncompressed(Version, NumFilenames);
Index: llvm/lib/Object/Decompressor.cpp
===================================================================
--- llvm/lib/Object/Decompressor.cpp
+++ llvm/lib/Object/Decompressor.cpp
@@ -14,16 +14,15 @@
#include "llvm/Support/Endian.h"
using namespace llvm;
+using namespace llvm::compression;
using namespace llvm::support::endian;
using namespace object;
Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
bool IsLE, bool Is64Bit) {
- if (!compression::zlib::isAvailable())
- return createError("zlib is not available");
Decompressor D(Data);
- if (Error Err = D.consumeCompressedZLibHeader(Is64Bit, IsLE))
+ if (Error Err = D.consumeCompressedSectionHeader(Is64Bit, IsLE))
return std::move(Err);
return D;
}
@@ -31,8 +30,8 @@
Decompressor::Decompressor(StringRef Data)
: SectionData(Data), DecompressedSize(0) {}
-Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
- bool IsLittleEndian) {
+Error Decompressor::consumeCompressedSectionHeader(bool Is64Bit,
+ bool IsLittleEndian) {
using namespace ELF;
uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
if (SectionData.size() < HdrSize)
@@ -40,10 +39,17 @@
DataExtractor Extractor(SectionData, IsLittleEndian, 0);
uint64_t Offset = 0;
- if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
- : sizeof(Elf32_Word)) !=
- ELFCOMPRESS_ZLIB)
+ uint64_t ELFCompressionSchemeId = Extractor.getUnsigned(
+ &Offset, Is64Bit ? sizeof(Elf64_Word) : sizeof(Elf32_Word));
+ CompressionSpec *CSpec = nullptr;
+ if (ELFCompressionSchemeId == ELFCOMPRESS_ZLIB)
+ CSpec = getCompressionSpec(CompressionKind::Zlib);
+
+ if (!CSpec)
return createError("unsupported compression type");
+ if (!CSpec->Implementation)
+ return createError(CSpec->Name + " is not available");
+ CImpl = CSpec->Implementation;
// Skip Elf64_Chdr::ch_reserved field.
if (Is64Bit)
@@ -57,6 +63,6 @@
Error Decompressor::decompress(MutableArrayRef<uint8_t> Buffer) {
size_t Size = Buffer.size();
- return compression::zlib::uncompress(arrayRefFromStringRef(SectionData),
- Buffer.data(), Size);
+ return CImpl->decompress(arrayRefFromStringRef(SectionData), Buffer.data(),
+ Size);
}
Index: llvm/lib/ObjCopy/ELF/ELFObject.cpp
===================================================================
--- llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -31,6 +31,7 @@
using namespace llvm;
using namespace llvm::ELF;
+using namespace llvm::compression;
using namespace llvm::objcopy::elf;
using namespace llvm::object;
@@ -439,10 +440,27 @@
ArrayRef<uint8_t> Compressed =
Sec.OriginalData.slice(sizeof(Elf_Chdr_Impl<ELFT>));
SmallVector<uint8_t, 128> DecompressedContent;
- if (Error Err = compression::zlib::uncompress(Compressed, DecompressedContent,
- static_cast<size_t>(Sec.Size)))
- return createStringError(errc::invalid_argument,
- "'" + Sec.Name + "': " + toString(std::move(Err)));
+ DebugCompressionType CompressionType =
+ reinterpret_cast<const Elf_Chdr_Impl<ELFT> *>(Sec.OriginalData.data())
+ ->ch_type == ELF::ELFCOMPRESS_ZLIB
+ ? DebugCompressionType::Z
+ : DebugCompressionType::None;
+
+ switch (CompressionType) {
+ case DebugCompressionType::Z:
+ if (Error Err1 =
+ getCompressionSpec(CompressionKind::Zlib)
+ ->Implementation->decompress(Compressed, DecompressedContent,
+ static_cast<size_t>(Sec.Size))) {
+ return createStringError(errc::invalid_argument,
+ "'" + Sec.Name +
+ "': " + toString(std::move(Err1)));
+ }
+ break;
+ case DebugCompressionType::None:
+ llvm_unreachable("unexpected DebugCompressionType::None");
+ break;
+ }
uint8_t *Buf = reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
std::copy(DecompressedContent.begin(), DecompressedContent.end(), Buf);
@@ -512,7 +530,14 @@
DebugCompressionType CompressionType)
: SectionBase(Sec), CompressionType(CompressionType),
DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) {
- compression::zlib::compress(OriginalData, CompressedData);
+ switch (CompressionType) {
+ case DebugCompressionType::Z:
+ getCompressionSpec(CompressionKind::Zlib)
+ ->Implementation->compress(OriginalData, CompressedData);
+ break;
+ case DebugCompressionType::None:
+ break;
+ }
assert(CompressionType != DebugCompressionType::None);
Flags |= ELF::SHF_COMPRESSED;
Index: llvm/lib/MC/ELFObjectWriter.cpp
===================================================================
--- llvm/lib/MC/ELFObjectWriter.cpp
+++ llvm/lib/MC/ELFObjectWriter.cpp
@@ -59,6 +59,7 @@
#include <vector>
using namespace llvm;
+using namespace llvm::compression;
#undef DEBUG_TYPE
#define DEBUG_TYPE "reloc-info"
@@ -847,15 +848,14 @@
auto &MC = Asm.getContext();
const auto &MAI = MC.getAsmInfo();
-
- bool CompressionEnabled =
- MAI->compressDebugSections() != DebugCompressionType::None;
+ const DebugCompressionType CompressionType = MAI->compressDebugSections();
+ bool CompressionEnabled = CompressionType != DebugCompressionType::None;
if (!CompressionEnabled || !SectionName.startswith(".debug_")) {
Asm.writeSectionData(W.OS, &Section, Layout);
return;
}
- assert(MAI->compressDebugSections() == DebugCompressionType::Z &&
+ assert(CompressionType == DebugCompressionType::Z &&
"expected zlib style compression");
SmallVector<char, 128> UncompressedData;
@@ -864,13 +864,20 @@
SmallVector<uint8_t, 128> Compressed;
const uint32_t ChType = ELF::ELFCOMPRESS_ZLIB;
- compression::zlib::compress(
- makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
- UncompressedData.size()),
- Compressed);
- if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
- Sec.getAlignment())) {
+ if (CompressionImpl *CImpl =
+ getCompressionSpec(CompressionKind::Zlib)->Implementation) {
+ CImpl->compress(
+ makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
+ UncompressedData.size()),
+ Compressed);
+
+ if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
+ Sec.getAlignment())) {
+ W.OS << UncompressedData;
+ return;
+ }
+ } else {
W.OS << UncompressedData;
return;
}
Index: llvm/include/llvm/Support/Compression.h
===================================================================
--- llvm/include/llvm/Support/Compression.h
+++ llvm/include/llvm/Support/Compression.h
@@ -14,56 +14,70 @@
#define LLVM_SUPPORT_COMPRESSION_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
namespace llvm {
template <typename T> class SmallVectorImpl;
class Error;
namespace compression {
-namespace zlib {
-constexpr int NoCompression = 0;
-constexpr int BestSpeedCompression = 1;
-constexpr int DefaultCompression = 6;
-constexpr int BestSizeCompression = 9;
-
-bool isAvailable();
-
-void compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer,
- int Level = DefaultCompression);
-
-Error uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize);
-
-Error uncompress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &UncompressedBuffer,
- size_t UncompressedSize);
-
-} // End of namespace zlib
-
-namespace zstd {
-
-constexpr int NoCompression = -5;
-constexpr int BestSpeedCompression = 1;
-constexpr int DefaultCompression = 5;
-constexpr int BestSizeCompression = 12;
-
-bool isAvailable();
-
-void compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer,
- int Level = DefaultCompression);
-
-Error uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize);
-
-Error uncompress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &UncompressedBuffer,
- size_t UncompressedSize);
-
-} // End of namespace zstd
+enum CompressionKind : uint8_t { Zlib = 1, ZStd = 2, Unknown = 255 };
+
+struct CompressionSpec;
+struct CompressionImpl;
+
+CompressionSpec *getCompressionSpec(uint8_t Kind);
+
+struct CompressionSpec {
+ const CompressionKind Kind;
+ CompressionImpl *Implementation;
+ const StringRef Name;
+ const StringRef Status; // either "supported", or "unsupported: REASON"
+
+protected:
+ friend CompressionSpec *getCompressionSpec(uint8_t Kind);
+ CompressionSpec(CompressionKind Kind, CompressionImpl *Implementation,
+ StringRef Name, bool Supported, StringRef Status)
+ : Kind(Kind), Implementation(Supported ? Implementation : nullptr),
+ Name(Name), Status(Supported ? "supported" : Status) {}
+};
+
+struct CompressionImpl {
+ const CompressionKind Kind;
+ const int BestSpeedLevel;
+ const int DefaultLevel;
+ const int BestSizeLevel;
+ virtual void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer,
+ int Level) = 0;
+ virtual Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) = 0;
+ void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer) {
+ return compress(Input, CompressedBuffer, DefaultLevel);
+ }
+
+ Error decompress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ UncompressedBuffer.resize_for_overwrite(UncompressedSize);
+ Error E = decompress(Input, UncompressedBuffer.data(), UncompressedSize);
+ if (UncompressedSize < UncompressedBuffer.size())
+ UncompressedBuffer.truncate(UncompressedSize);
+ return E;
+ }
+
+protected:
+ CompressionImpl(CompressionKind Kind, int BestSpeedLevel, int DefaultLevel,
+ int BestSizeLevel)
+ : Kind(Kind), BestSpeedLevel(BestSpeedLevel), DefaultLevel(DefaultLevel),
+ BestSizeLevel(BestSizeLevel) {}
+};
} // End of namespace compression
Index: llvm/include/llvm/ProfileData/InstrProf.h
===================================================================
--- llvm/include/llvm/ProfileData/InstrProf.h
+++ llvm/include/llvm/ProfileData/InstrProf.h
@@ -26,6 +26,7 @@
#include "llvm/ProfileData/InstrProfData.inc"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
@@ -215,7 +216,8 @@
/// compressed string. When the string compression is off, the
/// second field will have value zero.
Error collectPGOFuncNameStrings(ArrayRef<std::string> NameStrs,
- bool doCompression, std::string &Result);
+ compression::CompressionSpec *CSpec,
+ std::string &Result);
/// Produce \c Result string with the same format described above. The input
/// is vector of PGO function name variables that are referenced.
Index: llvm/include/llvm/Object/Decompressor.h
===================================================================
--- llvm/include/llvm/Object/Decompressor.h
+++ llvm/include/llvm/Object/Decompressor.h
@@ -11,8 +11,11 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Error.h"
+using namespace llvm::compression;
+
namespace llvm {
namespace object {
@@ -44,10 +47,11 @@
private:
Decompressor(StringRef Data);
- Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
+ Error consumeCompressedSectionHeader(bool Is64Bit, bool IsLittleEndian);
StringRef SectionData;
uint64_t DecompressedSize;
+ CompressionImpl *CImpl = nullptr;
};
} // end namespace object
Index: lld/ELF/InputSection.cpp
===================================================================
--- lld/ELF/InputSection.cpp
+++ lld/ELF/InputSection.cpp
@@ -28,6 +28,7 @@
using namespace llvm::ELF;
using namespace llvm::object;
using namespace llvm::support;
+using namespace llvm::compression;
using namespace llvm::support::endian;
using namespace llvm::sys;
using namespace lld;
@@ -119,7 +120,9 @@
uncompressedBuf = bAlloc().Allocate<uint8_t>(size);
}
- if (Error e = compression::zlib::uncompress(rawData, uncompressedBuf, size))
+ if (Error e =
+ getCompressionSpec(CompressionKind::Zlib)
+ ->Implementation->decompress(rawData, uncompressedBuf, size))
fatal(toString(this) +
": uncompress failed: " + llvm::toString(std::move(e)));
rawData = makeArrayRef(uncompressedBuf, size);
@@ -209,7 +212,7 @@
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(rawData.data());
if (hdr->ch_type == ELFCOMPRESS_ZLIB) {
- if (!compression::zlib::isAvailable())
+ if (!getCompressionSpec(CompressionKind::Zlib)->Implementation)
error(toString(this) + " is compressed with ELFCOMPRESS_ZLIB, but lld is "
"not built with zlib support");
} else {
@@ -1220,7 +1223,8 @@
// to the buffer.
if (uncompressedSize >= 0) {
size_t size = uncompressedSize;
- if (Error e = compression::zlib::uncompress(rawData, buf, size))
+ if (Error e = getCompressionSpec(CompressionKind::Zlib)
+ ->Implementation->decompress(rawData, buf, size))
fatal(toString(this) +
": uncompress failed: " + llvm::toString(std::move(e)));
uint8_t *bufEnd = buf + size;
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -70,6 +70,7 @@
using namespace llvm::object;
using namespace llvm::sys;
using namespace llvm::support;
+using namespace llvm::compression;
using namespace lld;
using namespace lld::elf;
@@ -954,12 +955,15 @@
static bool getCompressDebugSections(opt::InputArgList &args) {
StringRef s = args.getLastArgValue(OPT_compress_debug_sections, "none");
- if (s == "none")
+ if (s == "none") {
return false;
- if (s != "zlib")
+ } else if (s == "zlib") {
+ if (!getCompressionSpec(CompressionKind::Zlib)->Implementation)
+ error("--compress-debug-sections: zlib is not available");
+ } else {
error("unknown --compress-debug-sections value: " + s);
- if (!compression::zlib::isAvailable())
- error("--compress-debug-sections: zlib is not available");
+ }
+
return true;
}
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -118,6 +118,7 @@
using namespace clang;
using namespace clang::serialization;
+using namespace llvm::compression;
template <typename T, typename Allocator>
static StringRef bytes(const std::vector<T, Allocator> &v) {
@@ -1999,10 +2000,12 @@
// Compress the buffer if possible. We expect that almost all PCM
// consumers will not want its contents.
- SmallVector<uint8_t, 0> CompressedBuffer;
- if (llvm::compression::zlib::isAvailable()) {
- llvm::compression::zlib::compress(
- llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer);
+ if (CompressionImpl *CImpl =
+ getCompressionSpec(CompressionKind::Zlib)->Implementation) {
+ SmallVector<uint8_t, 0> CompressedBuffer;
+
+ CImpl->compress(llvm::arrayRefFromStringRef(Blob.drop_back(1)),
+ CompressedBuffer);
RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, Blob.size() - 1};
Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
llvm::toStringRef(CompressedBuffer));
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -144,6 +144,7 @@
using namespace clang::serialization;
using namespace clang::serialization::reader;
using llvm::BitstreamCursor;
+using namespace llvm::compression;
//===----------------------------------------------------------------------===//
// ChainedASTReaderListener implementation
@@ -1462,19 +1463,22 @@
unsigned RecCode = MaybeRecCode.get();
if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
- if (!llvm::compression::zlib::isAvailable()) {
- Error("zlib is not available");
- return nullptr;
- }
- SmallVector<uint8_t, 0> Uncompressed;
- if (llvm::Error E = llvm::compression::zlib::uncompress(
- llvm::arrayRefFromStringRef(Blob), Uncompressed, Record[0])) {
- Error("could not decompress embedded file contents: " +
- llvm::toString(std::move(E)));
+ CompressionSpec *CSpec = getCompressionSpec(CompressionKind::Zlib);
+
+ if (CompressionImpl *CImpl = CSpec->Implementation) {
+ SmallVector<uint8_t, 0> Uncompressed;
+ if (llvm::Error E = CImpl->decompress(llvm::arrayRefFromStringRef(Blob),
+ Uncompressed, Record[0])) {
+ Error("could not decompress embedded file contents: " +
+ llvm::toString(std::move(E)));
+ return nullptr;
+ }
+ return llvm::MemoryBuffer::getMemBufferCopy(
+ llvm::toStringRef(Uncompressed), Name);
+ } else {
+ Error("compression class " + (CSpec->Name + " is not available").str());
return nullptr;
}
- return llvm::MemoryBuffer::getMemBufferCopy(
- llvm::toStringRef(Uncompressed), Name);
} else if (RecCode == SM_SLOC_BUFFER_BLOB) {
return llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name, true);
} else {
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -58,6 +58,7 @@
using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+using namespace llvm::compression;
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_C, options::OPT_CC,
@@ -1139,7 +1140,7 @@
if (Value == "none") {
CmdArgs.push_back("--compress-debug-sections=none");
} else if (Value == "zlib") {
- if (llvm::compression::zlib::isAvailable()) {
+ if (getCompressionSpec(CompressionKind::Zlib)->Implementation) {
CmdArgs.push_back(
Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
} else {
Index: clang-tools-extra/clangd/unittests/SerializationTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/SerializationTests.cpp
+++ clang-tools-extra/clangd/unittests/SerializationTests.cpp
@@ -25,6 +25,7 @@
using ::testing::Pair;
using ::testing::UnorderedElementsAre;
using ::testing::UnorderedElementsAreArray;
+using namespace llvm::compression;
namespace clang {
namespace clangd {
@@ -391,7 +392,7 @@
// Check we detect invalid string table size size without allocating it first.
// If this detection fails, the test should allocate a huge array and crash.
TEST(SerializationTest, NoCrashOnBadStringTableSize) {
- if (!llvm::compression::zlib::isAvailable()) {
+ if (!getCompressionSpec(CompressionKind::Zlib)->Implementation) {
log("skipping test, no zlib");
return;
}
Index: clang-tools-extra/clangd/index/Serialization.cpp
===================================================================
--- clang-tools-extra/clangd/index/Serialization.cpp
+++ clang-tools-extra/clangd/index/Serialization.cpp
@@ -25,6 +25,8 @@
#include <cstdint>
#include <vector>
+using namespace llvm::compression;
+
namespace clang {
namespace clangd {
namespace {
@@ -190,10 +192,10 @@
RawTable.append(std::string(S));
RawTable.push_back(0);
}
- if (llvm::compression::zlib::isAvailable()) {
+ if (CompressionImpl *CImpl =
+ getCompressionSpec(CompressionKind::Zlib)->Implementation) {
llvm::SmallVector<uint8_t, 0> Compressed;
- llvm::compression::zlib::compress(llvm::arrayRefFromStringRef(RawTable),
- Compressed);
+ CImpl->compress(llvm::arrayRefFromStringRef(RawTable), Compressed);
write32(RawTable.size(), OS);
OS << llvm::toStringRef(Compressed);
} else {
@@ -224,23 +226,30 @@
llvm::SmallVector<uint8_t, 0> UncompressedStorage;
if (UncompressedSize == 0) // No compression
Uncompressed = R.rest();
- else if (llvm::compression::zlib::isAvailable()) {
- // Don't allocate a massive buffer if UncompressedSize was corrupted
- // This is effective for sharded index, but not big monolithic ones, as
- // once compressed size reaches 4MB nothing can be ruled out.
- // Theoretical max ratio from https://zlib.net/zlib_tech.html
- constexpr int MaxCompressionRatio = 1032;
- if (UncompressedSize / MaxCompressionRatio > R.rest().size())
- return error("Bad stri table: uncompress {0} -> {1} bytes is implausible",
- R.rest().size(), UncompressedSize);
-
- if (llvm::Error E = llvm::compression::zlib::uncompress(
- llvm::arrayRefFromStringRef(R.rest()), UncompressedStorage,
- UncompressedSize))
- return std::move(E);
- Uncompressed = toStringRef(UncompressedStorage);
- } else
- return error("Compressed string table, but zlib is unavailable");
+ else {
+ // Don't extratc to a CompressionKind CSpec variable
+ // as ratio check is zlib specific
+ if (CompressionImpl *CImpl =
+ getCompressionSpec(CompressionKind::Zlib)->Implementation) {
+ // Don't allocate a massive buffer if UncompressedSize was corrupted
+ // This is effective for sharded index, but not big monolithic ones, as
+ // once compressed size reaches 4MB nothing can be ruled out.
+ // Theoretical max ratio from https://zlib.net/zlib_tech.html
+ constexpr int MaxCompressionRatio = 1032;
+ if (UncompressedSize / MaxCompressionRatio > R.rest().size())
+ return error(
+ "Bad stri table: uncompress {0} -> {1} bytes is implausible",
+ R.rest().size(), UncompressedSize);
+
+ if (llvm::Error E =
+ CImpl->decompress(llvm::arrayRefFromStringRef(R.rest()),
+ UncompressedStorage, UncompressedSize))
+ return std::move(E);
+ Uncompressed = toStringRef(UncompressedStorage);
+ } else
+ return error("Compressed string table, but {0} is unavailable",
+ getCompressionSpec(CompressionKind::Zlib)->Name);
+ }
StringTableIn Table;
llvm::StringSaver Saver(Table.Arena);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits