ckissane updated this revision to Diff 448469.
ckissane added a comment.
- make compression singletons
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D130516/new/
https://reviews.llvm.org/D130516
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,43 @@
namespace {
-#if LLVM_ENABLE_ZLIB
-static void testZlibCompression(StringRef Input, int Level) {
+static void testCompressionAlgorithm(
+ StringRef Input, int Level,
+ compression::CompressionAlgorithm *CompressionScheme,
+ std::string ExpectedDestinationBufferTooSmallErrorMessage) {
SmallVector<uint8_t, 0> Compressed;
SmallVector<uint8_t, 0> Uncompressed;
- zlib::compress(arrayRefFromStringRef(Input), Compressed, Level);
+ CompressionScheme->compress(arrayRefFromStringRef(Input), Compressed, Level);
// Check that uncompressed buffer is the same as original.
- Error E = zlib::uncompress(Compressed, Uncompressed, Input.size());
+ Error E =
+ CompressionScheme->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 = CompressionScheme->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, ZlibCompression,
+ "zlib error: Z_BUF_ERROR");
+}
+
TEST(CompressionTest, Zlib) {
- testZlibCompression("", zlib::DefaultCompression);
+ compression::CompressionAlgorithm *CompressionScheme =
+ compression::ZlibCompression;
+ testZlibCompression("", CompressionScheme->getDefaultLevel());
- testZlibCompression("hello, world!", zlib::NoCompression);
- testZlibCompression("hello, world!", zlib::BestSizeCompression);
- testZlibCompression("hello, world!", zlib::BestSpeedCompression);
- testZlibCompression("hello, world!", zlib::DefaultCompression);
+ testZlibCompression("hello, world!", CompressionScheme->getBestSizeLevel());
+ testZlibCompression("hello, world!", CompressionScheme->getBestSpeedLevel());
+ testZlibCompression("hello, world!", CompressionScheme->getDefaultLevel());
const size_t kSize = 1024;
char BinaryData[kSize];
@@ -54,38 +66,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, CompressionScheme->getBestSizeLevel());
+ testZlibCompression(BinaryDataStr, CompressionScheme->getBestSpeedLevel());
+ testZlibCompression(BinaryDataStr, CompressionScheme->getDefaultLevel());
}
#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, ZStdCompression,
+ "Destination buffer is too small");
}
TEST(CompressionTest, Zstd) {
- testZstdCompression("", zstd::DefaultCompression);
+ compression::CompressionAlgorithm *CompressionScheme =
+ compression::ZStdCompression;
+ testZStdCompression("", CompressionScheme->getDefaultLevel());
- testZstdCompression("hello, world!", zstd::NoCompression);
- testZstdCompression("hello, world!", zstd::BestSizeCompression);
- testZstdCompression("hello, world!", zstd::BestSpeedCompression);
- testZstdCompression("hello, world!", zstd::DefaultCompression);
+ testZStdCompression("hello, world!", CompressionScheme->getBestSizeLevel());
+ testZStdCompression("hello, world!", CompressionScheme->getBestSpeedLevel());
+ testZStdCompression("hello, world!", CompressionScheme->getDefaultLevel());
const size_t kSize = 1024;
char BinaryData[kSize];
@@ -93,10 +94,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, CompressionScheme->getBestSizeLevel());
+ testZStdCompression(BinaryDataStr, CompressionScheme->getBestSpeedLevel());
+ testZStdCompression(BinaryDataStr, CompressionScheme->getDefaultLevel());
}
#endif
}
Index: llvm/unittests/ProfileData/InstrProfTest.cpp
===================================================================
--- llvm/unittests/ProfileData/InstrProfTest.cpp
+++ llvm/unittests/ProfileData/InstrProfTest.cpp
@@ -1146,18 +1146,20 @@
for (bool DoCompression : {false, true}) {
// Compressing:
std::string FuncNameStrings1;
- EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
- FuncNames1,
- (DoCompression && compression::zlib::isAvailable()),
- FuncNameStrings1),
+ EXPECT_THAT_ERROR(collectPGOFuncNameStrings(FuncNames1,
+ (compression::ZlibCompression)
+ ->when(DoCompression)
+ ->whenSupported(),
+ FuncNameStrings1),
Succeeded());
// Compressing:
std::string FuncNameStrings2;
- EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
- FuncNames2,
- (DoCompression && compression::zlib::isAvailable()),
- FuncNameStrings2),
+ EXPECT_THAT_ERROR(collectPGOFuncNameStrings(FuncNames2,
+ (compression::ZlibCompression)
+ ->when(DoCompression)
+ ->whenSupported(),
+ FuncNameStrings2),
Succeeded());
for (int Padding = 0; Padding < 2; Padding++) {
Index: llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
===================================================================
--- llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -728,10 +728,16 @@
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");
+ switch (Config.CompressionType) {
+ case DebugCompressionType::None:
+ break;
+ case DebugCompressionType::Z:
+ if (!compression::ZlibCompression->supported())
+ 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 +999,8 @@
"--decompress-debug-sections");
}
- if (Config.DecompressDebugSections && !compression::zlib::isAvailable())
+ if (Config.DecompressDebugSections &&
+ !compression::ZlibCompression->supported())
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
@@ -401,7 +401,7 @@
MAI->setRelaxELFRelocations(RelaxELFRel);
if (CompressDebugSections != DebugCompressionType::None) {
- if (!compression::zlib::isAvailable()) {
+ if (!compression::ZlibCompression->supported()) {
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,101 @@
using namespace llvm;
using namespace llvm::compression;
+ZStdCompressionAlgorithm
+ *llvm::compression::ZStdCompressionAlgorithm::Instance =
+ new ZStdCompressionAlgorithm();
+ZlibCompressionAlgorithm
+ *llvm::compression::ZlibCompressionAlgorithm::Instance =
+ new ZlibCompressionAlgorithm();
+UnknownCompressionAlgorithm
+ *llvm::compression::UnknownCompressionAlgorithm::Instance =
+ new UnknownCompressionAlgorithm();
+NoneCompressionAlgorithm
+ *llvm::compression::NoneCompressionAlgorithm::Instance =
+ new NoneCompressionAlgorithm();
+
+// const static NoneCompressionAlgorithm* llvm::compression::NoneCompression =
+// NoneCompressionAlgorithm::Instance; const static UnknownCompressionAlgorithm*
+// llvm::compression::UnknownCompression =
+// UnknownCompressionAlgorithm::Instance; const static ZStdCompressionAlgorithm*
+// llvm::compression::ZStdCompression = ZStdCompressionAlgorithm::Instance;
+// const static ZlibCompressionAlgorithm* llvm::compression::ZlibCompression =
+// ZlibCompressionAlgorithm::Instance;
+
+template <class CompressionAlgorithmType>
+CompressionAlgorithm *
+CompressionAlgorithmImpl<CompressionAlgorithmType>::when(bool useCompression) {
+ if (useCompression) {
+ return this;
+ }
+ return (CompressionAlgorithm *)NoneCompression;
+}
+
+constexpr SupportCompressionType UnknownCompressionAlgorithm::AlgorithmId;
+constexpr StringRef UnknownCompressionAlgorithm::Name;
+constexpr int UnknownCompressionAlgorithm::BestSpeedCompression;
+constexpr int UnknownCompressionAlgorithm::DefaultCompression;
+constexpr int UnknownCompressionAlgorithm::BestSizeCompression;
+
+bool UnknownCompressionAlgorithm::Supported() { return false; };
+
+void UnknownCompressionAlgorithm::Compress(
+ ArrayRef<uint8_t> Input, SmallVectorImpl<uint8_t> &CompressedBuffer,
+ int Level) {
+ llvm_unreachable("method:\"compress\" is unsupported for compression "
+ "algorithm:\"unknown\", reason:\"can't call on unknown\"");
+};
+Error UnknownCompressionAlgorithm::Decompress(ArrayRef<uint8_t> Input,
+ uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ llvm_unreachable("method:\"decompress\" is unsupported for compression "
+ "algorithm:\"unknown\", reason:\"can't call on unknown\"");
+}
+
+constexpr SupportCompressionType NoneCompressionAlgorithm::AlgorithmId;
+constexpr StringRef NoneCompressionAlgorithm::Name;
+constexpr int NoneCompressionAlgorithm::BestSpeedCompression;
+constexpr int NoneCompressionAlgorithm::DefaultCompression;
+constexpr int NoneCompressionAlgorithm::BestSizeCompression;
+
+bool NoneCompressionAlgorithm::Supported() { return true; };
+
+void NoneCompressionAlgorithm::Compress(
+ ArrayRef<uint8_t> Input, SmallVectorImpl<uint8_t> &CompressedBuffer,
+ int Level) {
+ unsigned long CompressedSize = Input.size();
+ CompressedBuffer.resize_for_overwrite(CompressedSize);
+ // SmallVectorImpl<uint8_t>()
+ CompressedBuffer.assign(SmallVector<uint8_t>(Input.begin(), Input.end()));
+
+ // 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 NoneCompressionAlgorithm::Decompress(ArrayRef<uint8_t> Input,
+ uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ if (UncompressedSize < Input.size()) {
+ return make_error<StringError>("decompressed buffer target size too small",
+ inconvertibleErrorCode());
+ }
+ UncompressedSize = Input.size();
+ memcpy(UncompressedBuffer, Input.data(), UncompressedSize);
+
+ __msan_unpoison(UncompressedBuffer, UncompressedSize);
+ return Error::success();
+}
+
+constexpr SupportCompressionType ZlibCompressionAlgorithm::AlgorithmId;
+constexpr StringRef ZlibCompressionAlgorithm::Name;
+constexpr int ZlibCompressionAlgorithm::BestSpeedCompression;
+constexpr int ZlibCompressionAlgorithm::DefaultCompression;
+constexpr int ZlibCompressionAlgorithm::BestSizeCompression;
+
#if LLVM_ENABLE_ZLIB
static StringRef convertZlibCodeToString(int Code) {
@@ -45,10 +140,11 @@
}
}
-bool zlib::isAvailable() { return true; }
+bool ZlibCompressionAlgorithm::Supported() { return true; };
-void zlib::compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
+void ZlibCompressionAlgorithm::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,
@@ -61,10 +157,10 @@
__msan_unpoison(CompressedBuffer.data(), CompressedSize);
if (CompressedSize < CompressedBuffer.size())
CompressedBuffer.truncate(CompressedSize);
-}
-
-Error zlib::uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize) {
+};
+Error ZlibCompressionAlgorithm::Decompress(ArrayRef<uint8_t> Input,
+ uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
int Res =
::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize,
(const Bytef *)Input.data(), Input.size());
@@ -74,42 +170,41 @@
return Res ? make_error<StringError>(convertZlibCodeToString(Res),
inconvertibleErrorCode())
: Error::success();
-}
-
-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;
-}
+};
#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");
-}
+bool ZlibCompressionAlgorithm::Supported() { return false; };
+
+void ZlibCompressionAlgorithm::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 ZlibCompressionAlgorithm::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\"");
+};
+
#endif
+constexpr SupportCompressionType ZStdCompressionAlgorithm::AlgorithmId;
+constexpr StringRef ZStdCompressionAlgorithm::Name;
+constexpr int ZStdCompressionAlgorithm::BestSpeedCompression;
+constexpr int ZStdCompressionAlgorithm::DefaultCompression;
+constexpr int ZStdCompressionAlgorithm::BestSizeCompression;
+
#if LLVM_ENABLE_ZSTD
-bool zstd::isAvailable() { return true; }
+bool ZStdCompressionAlgorithm::Supported() { return true; };
-void zstd::compress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
+void ZStdCompressionAlgorithm::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 =
@@ -122,10 +217,10 @@
__msan_unpoison(CompressedBuffer.data(), CompressedSize);
if (CompressedSize < CompressedBuffer.size())
CompressedBuffer.truncate(CompressedSize);
-}
-
-Error zstd::uncompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
- size_t &UncompressedSize) {
+};
+Error ZStdCompressionAlgorithm::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());
@@ -136,32 +231,57 @@
return ZSTD_isError(Res) ? make_error<StringError>(ZSTD_getErrorName(Res),
inconvertibleErrorCode())
: Error::success();
-}
-
-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;
-}
+};
#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");
+bool ZStdCompressionAlgorithm::Supported() { return false; };
+
+void ZStdCompressionAlgorithm::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 ZStdCompressionAlgorithm::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\"");
+};
+
+#endif
+
+llvm::compression::CompressionAlgorithm *
+llvm::compression::getCompressionAlgorithm(uint8_t CompressionSchemeId) {
+ llvm::compression::CompressionAlgorithm *CompressionScheme =
+ (llvm::compression::CompressionAlgorithm *)
+ llvm::compression::UnknownCompression;
+ switch (CompressionSchemeId) {
+ case static_cast<uint8_t>(
+ llvm::compression::NoneCompressionAlgorithm::AlgorithmId):
+ CompressionScheme = (llvm::compression::CompressionAlgorithm *)
+ llvm::compression::NoneCompression;
+ break;
+ case static_cast<uint8_t>(
+ llvm::compression::ZlibCompressionAlgorithm::AlgorithmId):
+ CompressionScheme = (llvm::compression::CompressionAlgorithm *)
+ llvm::compression::ZlibCompression;
+ break;
+ case static_cast<uint8_t>(
+ llvm::compression::ZStdCompressionAlgorithm::AlgorithmId):
+ CompressionScheme = (llvm::compression::CompressionAlgorithm *)
+ llvm::compression::ZStdCompression;
+ break;
+ default:
+ break;
+ }
+ return CompressionScheme;
}
-Error zstd::uncompress(ArrayRef<uint8_t> Input,
- SmallVectorImpl<uint8_t> &UncompressedBuffer,
- size_t UncompressedSize) {
- llvm_unreachable("zstd::uncompress is unavailable");
+
+llvm::compression::CompressionAlgorithm *
+llvm::compression::getCompressionAlgorithm(
+ llvm::compression::SupportCompressionType CompressionSchemeId) {
+ return getCompressionAlgorithm(static_cast<uint8_t>(CompressionSchemeId));
}
-#endif
Index: llvm/lib/ProfileData/SampleProfWriter.cpp
===================================================================
--- llvm/lib/ProfileData/SampleProfWriter.cpp
+++ llvm/lib/ProfileData/SampleProfWriter.cpp
@@ -78,7 +78,9 @@
}
std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() {
- if (!llvm::compression::zlib::isAvailable())
+ compression::CompressionAlgorithm *CompressionScheme =
+ compression::ZlibCompression;
+ if (!CompressionScheme->supported())
return sampleprof_error::zlib_unavailable;
std::string &UncompressedStrings =
static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
@@ -86,9 +88,9 @@
return sampleprof_error::success;
auto &OS = *OutputStream;
SmallVector<uint8_t, 128> CompressedStrings;
- compression::zlib::compress(arrayRefFromStringRef(UncompressedStrings),
+ CompressionScheme->compress(arrayRefFromStringRef(UncompressedStrings),
CompressedStrings,
- compression::zlib::BestSizeCompression);
+ CompressionScheme->getBestSizeLevel());
encodeULEB128(UncompressedStrings.size(), OS);
encodeULEB128(CompressedStrings.size(), OS);
OS << toStringRef(CompressedStrings);
Index: llvm/lib/ProfileData/SampleProfReader.cpp
===================================================================
--- llvm/lib/ProfileData/SampleProfReader.cpp
+++ llvm/lib/ProfileData/SampleProfReader.cpp
@@ -877,12 +877,12 @@
if (std::error_code EC = CompressSize.getError())
return EC;
- if (!llvm::compression::zlib::isAvailable())
+ if (!llvm::compression::ZlibCompression->supported())
return sampleprof_error::zlib_unavailable;
uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
size_t UCSize = DecompressBufSize;
- llvm::Error E = compression::zlib::uncompress(
+ llvm::Error E = compression::ZlibCompression->decompress(
makeArrayRef(Data, *CompressSize), Buffer, UCSize);
if (E)
return sampleprof_error::uncompress_failed;
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,9 @@
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,
+ /*CompressionScheme=*/compression::NoneCompression, Names);
CounterOffsets.clear();
NamesVec.clear();
return Result;
Index: llvm/lib/ProfileData/InstrProf.cpp
===================================================================
--- llvm/lib/ProfileData/InstrProf.cpp
+++ llvm/lib/ProfileData/InstrProf.cpp
@@ -435,8 +435,9 @@
return 0;
}
-Error collectPGOFuncNameStrings(ArrayRef<std::string> NameStrs,
- bool doCompression, std::string &Result) {
+Error collectPGOFuncNameStrings(
+ ArrayRef<std::string> NameStrs,
+ compression::CompressionAlgorithm *CompressionScheme, std::string &Result) {
assert(!NameStrs.empty() && "No name data to emit");
uint8_t Header[16], *P = Header;
@@ -460,14 +461,13 @@
return Error::success();
};
- if (!doCompression) {
+ if (!CompressionScheme->notNone())
return WriteStringToResult(0, UncompressedNameStrings);
- }
SmallVector<uint8_t, 128> CompressedNameStrings;
- compression::zlib::compress(arrayRefFromStringRef(UncompressedNameStrings),
+ CompressionScheme->compress(arrayRefFromStringRef(UncompressedNameStrings),
CompressedNameStrings,
- compression::zlib::BestSizeCompression);
+ CompressionScheme->getBestSizeLevel());
return WriteStringToResult(CompressedNameStrings.size(),
toStringRef(CompressedNameStrings));
@@ -486,8 +486,11 @@
for (auto *NameVar : NameVars) {
NameStrs.push_back(std::string(getPGOFuncNameVarInitializer(NameVar)));
}
+ compression::CompressionAlgorithm *CompressionScheme =
+ compression::ZlibCompression;
return collectPGOFuncNameStrings(
- NameStrs, compression::zlib::isAvailable() && doCompression, Result);
+ NameStrs, CompressionScheme->when(doCompression)->whenSupported(),
+ Result);
}
Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) {
@@ -503,10 +506,12 @@
SmallVector<uint8_t, 128> UncompressedNameStrings;
StringRef NameStrings;
if (isCompressed) {
- if (!llvm::compression::zlib::isAvailable())
+ compression::CompressionAlgorithm *CompressionScheme =
+ compression::ZlibCompression;
+ if (!CompressionScheme->supported())
return make_error<InstrProfError>(instrprof_error::zlib_unavailable);
- if (Error E = compression::zlib::uncompress(
+ if (Error E = CompressionScheme->decompress(
makeArrayRef(P, CompressedSize), UncompressedNameStrings,
UncompressedSize)) {
consumeError(std::move(E));
Index: llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
===================================================================
--- llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -47,12 +47,18 @@
}
SmallVector<uint8_t, 128> CompressedStr;
- bool doCompression = Compress && compression::zlib::isAvailable() &&
- DoInstrProfNameCompression;
+ compression::CompressionAlgorithm *CompressionScheme =
+ compression::ZlibCompression;
+
+ CompressionScheme =
+ CompressionScheme->when(Compress && DoInstrProfNameCompression)
+ ->whenSupported();
+ bool doCompression = CompressionScheme->notNone();
+
if (doCompression)
- compression::zlib::compress(arrayRefFromStringRef(FilenamesStr),
+ CompressionScheme->compress(arrayRefFromStringRef(FilenamesStr),
CompressedStr,
- compression::zlib::BestSizeCompression);
+ CompressionScheme->getBestSizeLevel());
// ::= <num-filenames>
// <uncompressed-len>
Index: llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
===================================================================
--- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -119,7 +119,7 @@
return Err;
if (CompressedLen > 0) {
- if (!compression::zlib::isAvailable())
+ if (!compression::ZlibCompression->supported())
return make_error<CoverageMapError>(
coveragemap_error::decompression_failed);
@@ -129,7 +129,7 @@
// Read compressed filenames.
StringRef CompressedFilenames = Data.substr(0, CompressedLen);
Data = Data.substr(CompressedLen);
- auto Err = compression::zlib::uncompress(
+ auto Err = compression::ZlibCompression->decompress(
arrayRefFromStringRef(CompressedFilenames), StorageBuf,
UncompressedLen);
if (Err) {
Index: llvm/lib/Object/Decompressor.cpp
===================================================================
--- llvm/lib/Object/Decompressor.cpp
+++ llvm/lib/Object/Decompressor.cpp
@@ -19,11 +19,9 @@
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 +29,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 +38,15 @@
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));
+ if (ELFCompressionSchemeId == ELFCOMPRESS_ZLIB) {
+ CompressionScheme = compression::ZlibCompression;
+ } else {
return createError("unsupported compression type");
+ }
+ if (!CompressionScheme->supported())
+ return createError(CompressionScheme->getName() + " is not available");
// Skip Elf64_Chdr::ch_reserved field.
if (Is64Bit)
@@ -57,6 +60,6 @@
Error Decompressor::decompress(MutableArrayRef<uint8_t> Buffer) {
size_t Size = Buffer.size();
- return compression::zlib::uncompress(arrayRefFromStringRef(SectionData),
+ return CompressionScheme->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
@@ -439,10 +439,25 @@
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 = compression::ZlibCompression->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 +527,13 @@
DebugCompressionType CompressionType)
: SectionBase(Sec), CompressionType(CompressionType),
DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) {
- compression::zlib::compress(OriginalData, CompressedData);
+ switch (CompressionType) {
+ case DebugCompressionType::Z:
+ compression::ZlibCompression->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
@@ -847,15 +847,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,7 +863,7 @@
SmallVector<uint8_t, 128> Compressed;
const uint32_t ChType = ELF::ELFCOMPRESS_ZLIB;
- compression::zlib::compress(
+ compression::ZlibCompression->compress(
makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
UncompressedData.size()),
Compressed);
Index: llvm/include/llvm/Support/Compression.h
===================================================================
--- llvm/include/llvm/Support/Compression.h
+++ llvm/include/llvm/Support/Compression.h
@@ -15,55 +15,214 @@
#include "llvm/ADT/ArrayRef.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 class SupportCompressionType : uint8_t {
+ Unknown = 255, ///< Abstract compression
+ None = 0, ///< No compression
+ Zlib = 1, ///< zlib style complession
+ ZStd = 2, ///< zstd style complession
+};
+
+// This is the base class of all compression algorithms that llvm support
+// handles.
+class CompressionAlgorithm {
+public:
+ virtual SupportCompressionType getAlgorithmId() = 0;
+
+ virtual StringRef getName() = 0;
+
+ virtual bool supported() = 0;
+
+ virtual int getBestSpeedLevel() = 0;
+ virtual int getDefaultLevel() = 0;
+ virtual int getBestSizeLevel() = 0;
+
+ virtual void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer,
+ int Level) = 0;
+ virtual void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer) = 0;
+
+ virtual Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) = 0;
+ virtual Error decompress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &UncompressedBuffer,
+ size_t UncompressedSize) = 0;
+
+ virtual CompressionAlgorithm *when(bool useCompression) = 0;
+ virtual CompressionAlgorithm *whenSupported() = 0;
+
+ virtual bool notNone() = 0;
+};
+class NoneCompressionAlgorithm;
+class UnknownCompressionAlgorithm;
+class ZStdCompressionAlgorithm;
+class ZlibCompressionAlgorithm;
+
+template <class CompressionAlgorithmType>
+class CompressionAlgorithmImpl : public CompressionAlgorithm {
+public:
+ virtual SupportCompressionType getAlgorithmId() {
+ return CompressionAlgorithmType::AlgorithmId;
+ }
+
+ virtual StringRef getName() { return CompressionAlgorithmType::Name; }
+
+ virtual bool supported() { return CompressionAlgorithmType::Supported(); }
+
+ virtual int getBestSpeedLevel() {
+ return CompressionAlgorithmType::BestSpeedCompression;
+ }
+ virtual int getDefaultLevel() {
+ return CompressionAlgorithmType::DefaultCompression;
+ }
+ virtual int getBestSizeLevel() {
+ return CompressionAlgorithmType::BestSizeCompression;
+ }
+
+ virtual void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level) {
+
+ return CompressionAlgorithmType::Compress(Input, CompressedBuffer, Level);
+ }
+ virtual void compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer) {
+ return CompressionAlgorithmType::Compress(
+ Input, CompressedBuffer, CompressionAlgorithmType::DefaultCompression);
+ }
+
+ virtual Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ return CompressionAlgorithmType::Decompress(Input, UncompressedBuffer,
+ UncompressedSize);
+ }
+ virtual Error decompress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ UncompressedBuffer.resize_for_overwrite(UncompressedSize);
+ Error E = CompressionAlgorithmType::Decompress(
+ Input, UncompressedBuffer.data(), UncompressedSize);
+ if (UncompressedSize < UncompressedBuffer.size())
+ UncompressedBuffer.truncate(UncompressedSize);
+ return E;
+ }
+
+ virtual CompressionAlgorithm *when(bool useCompression);
+ virtual CompressionAlgorithm *whenSupported() {
+ return this->when(CompressionAlgorithmType::Supported());
+ }
+
+ virtual bool notNone() {
+ return CompressionAlgorithmType::AlgorithmId !=
+ SupportCompressionType::None;
+ }
+};
+
+class ZStdCompressionAlgorithm
+ : public CompressionAlgorithmImpl<ZStdCompressionAlgorithm> {
+public:
+ constexpr static SupportCompressionType AlgorithmId =
+ SupportCompressionType::ZStd;
+ constexpr static StringRef Name = "zstd";
+ constexpr static int BestSpeedCompression = 1;
+ constexpr static int DefaultCompression = 5;
+ constexpr static int BestSizeCompression = 12;
+ static void Compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level);
+ static Error Decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize);
+ static bool Supported();
+
+ static ZStdCompressionAlgorithm *Instance;
+
+protected:
+ constexpr ZStdCompressionAlgorithm(){};
+};
+
+class ZlibCompressionAlgorithm
+ : public CompressionAlgorithmImpl<ZlibCompressionAlgorithm> {
+public:
+ constexpr static SupportCompressionType AlgorithmId =
+ SupportCompressionType::Zlib;
+ constexpr static StringRef Name = "zlib";
+ constexpr static int BestSpeedCompression = 1;
+ constexpr static int DefaultCompression = 6;
+ constexpr static int BestSizeCompression = 9;
+ static void Compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level);
+ static Error Decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize);
+ static bool Supported();
+
+ static ZlibCompressionAlgorithm *Instance;
+
+protected:
+ constexpr ZlibCompressionAlgorithm(){};
+};
+
+class UnknownCompressionAlgorithm
+ : public CompressionAlgorithmImpl<UnknownCompressionAlgorithm> {
+public:
+ constexpr static SupportCompressionType AlgorithmId =
+ SupportCompressionType::Unknown;
+ constexpr static StringRef Name = "unknown";
+ constexpr static int BestSpeedCompression = -999;
+ constexpr static int DefaultCompression = -999;
+ constexpr static int BestSizeCompression = -999;
+ static void Compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level);
+ static Error Decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize);
+ static bool Supported();
+
+ static UnknownCompressionAlgorithm *Instance;
+
+protected:
+ constexpr UnknownCompressionAlgorithm(){};
+};
+class NoneCompressionAlgorithm
+ : public CompressionAlgorithmImpl<NoneCompressionAlgorithm> {
+
+public:
+ constexpr static SupportCompressionType AlgorithmId =
+ SupportCompressionType::None;
+ constexpr static StringRef Name = "none";
+ constexpr static int BestSpeedCompression = 0;
+ constexpr static int DefaultCompression = 0;
+ constexpr static int BestSizeCompression = 0;
+ static void Compress(ArrayRef<uint8_t> Input,
+ SmallVectorImpl<uint8_t> &CompressedBuffer, int Level);
+ static Error Decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+ size_t &UncompressedSize);
+ static bool Supported();
+
+ static NoneCompressionAlgorithm *Instance;
+
+protected:
+ constexpr NoneCompressionAlgorithm(){};
+};
+
+static NoneCompressionAlgorithm *NoneCompression =
+ NoneCompressionAlgorithm::Instance;
+static UnknownCompressionAlgorithm *UnknownCompression =
+ UnknownCompressionAlgorithm::Instance;
+static ZStdCompressionAlgorithm *ZStdCompression =
+ ZStdCompressionAlgorithm::Instance;
+static ZlibCompressionAlgorithm *ZlibCompression =
+ ZlibCompressionAlgorithm::Instance;
+
+llvm::compression::CompressionAlgorithm *
+getCompressionAlgorithm(SupportCompressionType CompressionSchemeId);
+llvm::compression::CompressionAlgorithm *
+getCompressionAlgorithm(uint8_t CompressionSchemeId);
} // 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"
@@ -214,8 +215,9 @@
/// third field is the uncompressed strings; otherwise it is the
/// 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);
+Error collectPGOFuncNameStrings(
+ ArrayRef<std::string> NameStrs,
+ compression::CompressionAlgorithm *CompressionScheme, 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,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compression.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -44,10 +45,11 @@
private:
Decompressor(StringRef Data);
- Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
+ Error consumeCompressedSectionHeader(bool Is64Bit, bool IsLittleEndian);
StringRef SectionData;
uint64_t DecompressedSize;
+ compression::CompressionAlgorithm *CompressionScheme;
};
} // end namespace object
Index: lld/ELF/InputSection.cpp
===================================================================
--- lld/ELF/InputSection.cpp
+++ lld/ELF/InputSection.cpp
@@ -118,7 +118,8 @@
uncompressedBuf = bAlloc().Allocate<uint8_t>(size);
}
- if (Error e = compression::zlib::uncompress(rawData, uncompressedBuf, size))
+ if (Error e = compression::ZlibCompression->decompress(rawData,
+ uncompressedBuf, size))
fatal(toString(this) +
": uncompress failed: " + llvm::toString(std::move(e)));
rawData = makeArrayRef(uncompressedBuf, size);
@@ -208,7 +209,7 @@
auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(rawData.data());
if (hdr->ch_type == ELFCOMPRESS_ZLIB) {
- if (!compression::zlib::isAvailable())
+ if (!compression::ZlibCompression->supported())
error(toString(this) + " is compressed with ELFCOMPRESS_ZLIB, but lld is "
"not built with zlib support");
} else {
@@ -219,7 +220,6 @@
uncompressedSize = hdr->ch_size;
alignment = std::max<uint32_t>(hdr->ch_addralign, 1);
- rawData = rawData.slice(sizeof(*hdr));
}
InputSection *InputSectionBase::getLinkOrderDep() const {
@@ -1217,10 +1217,24 @@
// If this is a compressed section, uncompress section contents directly
// to the buffer.
if (uncompressedSize >= 0) {
+ auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(rawData.data());
size_t size = uncompressedSize;
- if (Error e = compression::zlib::uncompress(rawData, buf, size))
- fatal(toString(this) +
- ": uncompress failed: " + llvm::toString(std::move(e)));
+ if (hdr->ch_type == ELFCOMPRESS_ZLIB) {
+ if (!compression::ZlibCompression->supported()) {
+ error(toString(this) +
+ " is compressed with ELFCOMPRESS_ZLIB, but lld is "
+ "not built with zlib support");
+ } else {
+ if (Error e = compression::ZlibCompression->decompress(
+ rawData.slice(sizeof(typename ELFT::Chdr)), buf, size))
+ fatal(toString(this) +
+ ": uncompress failed: " + llvm::toString(std::move(e)));
+ }
+ } else {
+ error(toString(this) + ": unsupported compression type (" +
+ Twine(hdr->ch_type) + ")");
+ return;
+ }
uint8_t *bufEnd = buf + size;
relocate<ELFT>(buf, bufEnd);
return;
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -953,12 +953,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 (!compression::ZlibCompressionAlgorithm::Supported())
+ 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
@@ -2000,10 +2000,16 @@
// 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);
+ llvm::compression::CompressionAlgorithm *CompressionScheme =
+ llvm::compression::ZlibCompression;
+
+ CompressionScheme = CompressionScheme->whenSupported();
+ if (CompressionScheme->notNone()) {
+
+ SmallVector<uint8_t, 0> CompressedBuffer;
+
+ CompressionScheme->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
@@ -1462,12 +1462,17 @@
unsigned RecCode = MaybeRecCode.get();
if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
- if (!llvm::compression::zlib::isAvailable()) {
- Error("zlib is not available");
+ uint8_t CompressionSchemeId = static_cast<uint8_t>(
+ llvm::compression::ZlibCompressionAlgorithm::AlgorithmId);
+ llvm::compression::CompressionAlgorithm *CompressionScheme =
+ llvm::compression::CompressionAlgorithmFromId(CompressionSchemeId);
+ if (!CompressionScheme->supported()) {
+ Error("compression class " +
+ (CompressionScheme->getName() + " is not available").str());
return nullptr;
}
SmallVector<uint8_t, 0> Uncompressed;
- if (llvm::Error E = llvm::compression::zlib::uncompress(
+ if (llvm::Error E = CompressionScheme->decompress(
llvm::arrayRefFromStringRef(Blob), Uncompressed, Record[0])) {
Error("could not decompress embedded file contents: " +
llvm::toString(std::move(E)));
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1139,7 +1139,7 @@
if (Value == "none") {
CmdArgs.push_back("--compress-debug-sections=none");
} else if (Value == "zlib") {
- if (llvm::compression::zlib::isAvailable()) {
+ if (llvm::compression::ZlibCompressionAlgorithm::Supported()) {
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
@@ -391,7 +391,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 (!llvm::compression::ZlibCompressionAlgorithm::Supported()) {
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
@@ -190,10 +190,13 @@
RawTable.append(std::string(S));
RawTable.push_back(0);
}
- if (llvm::compression::zlib::isAvailable()) {
+ llvm::compression::CompressionAlgorithm *CompressionScheme =
+ llvm::compression::ZlibCompression;
+ CompressionScheme = CompressionScheme->whenSupported();
+ if (CompressionScheme->notNone()) {
llvm::SmallVector<uint8_t, 0> Compressed;
- llvm::compression::zlib::compress(llvm::arrayRefFromStringRef(RawTable),
- Compressed);
+ CompressionScheme->compress(llvm::arrayRefFromStringRef(RawTable),
+ Compressed);
write32(RawTable.size(), OS);
OS << llvm::toStringRef(Compressed);
} else {
@@ -224,23 +227,29 @@
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 {
+ llvm::compression::CompressionAlgorithm *CompressionScheme =
+ llvm::compression::ZlibCompression;
+ if (CompressionScheme->supported()) {
+ // 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 = CompressionScheme->decompress(
+ llvm::arrayRefFromStringRef(R.rest()), UncompressedStorage,
+ UncompressedSize))
+ return std::move(E);
+ Uncompressed = toStringRef(UncompressedStorage);
+ } else
+ return error("Compressed string table, but " +
+ (CompressionScheme->getName() + " is unavailable").str());
+ }
StringTableIn Table;
llvm::StringSaver Saver(Table.Arena);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits