diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h --- a/llvm/include/llvm/MC/MCTargetOptions.h +++ b/llvm/include/llvm/MC/MCTargetOptions.h @@ -10,6 +10,7 @@ #define LLVM_MC_MCTARGETOPTIONS_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Compression.h" #include #include @@ -25,11 +26,6 @@ AIX, ///< AIX Exception Handling }; -enum class DebugCompressionType { - None, ///< No compression - Z, ///< zlib style complession -}; - enum class EmitDwarfUnwindType { Always, // Always emit dwarf unwind NoCompactUnwind, // Only emit if compact unwind isn't available diff --git a/llvm/include/llvm/Support/Compression.h b/llvm/include/llvm/Support/Compression.h --- a/llvm/include/llvm/Support/Compression.h +++ b/llvm/include/llvm/Support/Compression.h @@ -23,6 +23,8 @@ template class SmallVectorImpl; class Error; +enum class DebugCompressionType { None, Z, Zstd }; + namespace compression { struct CompressionAlgorithm { @@ -30,19 +32,20 @@ const int BestSpeedLevel; const int DefaultLevel; const int BestSizeLevel; + const bool Available; virtual void compress(ArrayRef Input, SmallVectorImpl &CompressedBuffer, - int Level) = 0; + int Level) const = 0; virtual Error decompress(ArrayRef Input, uint8_t *UncompressedBuffer, - size_t &UncompressedSize) = 0; + size_t &UncompressedSize) const = 0; void compress(ArrayRef Input, - SmallVectorImpl &CompressedBuffer) { + SmallVectorImpl &CompressedBuffer) const { return compress(Input, CompressedBuffer, this->DefaultLevel); } Error decompress(ArrayRef Input, SmallVectorImpl &UncompressedBuffer, - size_t UncompressedSize) { + size_t UncompressedSize) const { UncompressedBuffer.resize_for_overwrite(UncompressedSize); Error E = decompress(Input, UncompressedBuffer.data(), UncompressedSize); if (UncompressedSize < UncompressedBuffer.size()) @@ -50,66 +53,62 @@ return E; } + explicit operator bool() const { return Available; } + protected: CompressionAlgorithm(StringRef Name, int BestSpeedLevel, int DefaultLevel, - int BestSizeLevel) + int BestSizeLevel, bool Available) : Name(Name), BestSpeedLevel(BestSpeedLevel), DefaultLevel(DefaultLevel), - BestSizeLevel(BestSizeLevel) {} + BestSizeLevel(BestSizeLevel), Available(Available) {} + ~CompressionAlgorithm() = default; }; -class CompressionKind { -private: - uint8_t CompressionID; +const CompressionAlgorithm &getCompressionAlgorithm(DebugCompressionType Kind); -protected: - friend constexpr llvm::Optional - getOptionalCompressionKind(uint8_t OptionalCompressionID); - // because getOptionalCompressionKind is the only friend: - // we can trust the value of y is valid - constexpr CompressionKind(uint8_t CompressionID) - : CompressionID(CompressionID) {} +// deprecated API +namespace zlib { -public: - constexpr operator uint8_t() const { return CompressionID; } - CompressionAlgorithm *operator->() const; +constexpr int NoCompression = 0; +constexpr int BestSpeedCompression = 1; +constexpr int DefaultCompression = 6; +constexpr int BestSizeCompression = 9; - constexpr operator bool() const; +bool isAvailable(); - static const llvm::compression::CompressionKind Unknown, Zlib, ZStd; -}; -constexpr inline const llvm::compression::CompressionKind - llvm::compression::CompressionKind::Unknown{255}, ///< Abstract compression - llvm::compression::CompressionKind::Zlib{1}, ///< zlib style complession - llvm::compression::CompressionKind::ZStd{2}; ///< zstd style complession -typedef llvm::Optional OptionalCompressionKind; - -constexpr CompressionKind::operator bool() const { - switch (uint8_t(CompressionID)) { - case uint8_t(CompressionKind::Zlib): - return LLVM_ENABLE_ZLIB; - case uint8_t(CompressionKind::ZStd): - return LLVM_ENABLE_ZSTD; - default: - return false; - } -} - -constexpr bool operator==(CompressionKind Left, CompressionKind Right) { - return uint8_t(Left) == uint8_t(Right); -} - -constexpr OptionalCompressionKind -getOptionalCompressionKind(uint8_t OptionalCompressionID) { - switch (OptionalCompressionID) { - case uint8_t(0): - return NoneType(); - case uint8_t(CompressionKind::Zlib): - case uint8_t(CompressionKind::ZStd): - return CompressionKind(OptionalCompressionID); - default: - return CompressionKind::Unknown; - } -} +void compress(ArrayRef Input, + SmallVectorImpl &CompressedBuffer, + int Level = DefaultCompression); + +Error uncompress(ArrayRef Input, uint8_t *UncompressedBuffer, + size_t &UncompressedSize); + +Error uncompress(ArrayRef Input, + SmallVectorImpl &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 Input, + SmallVectorImpl &CompressedBuffer, + int Level = DefaultCompression); + +Error uncompress(ArrayRef Input, uint8_t *UncompressedBuffer, + size_t &UncompressedSize); + +Error uncompress(ArrayRef Input, + SmallVectorImpl &UncompressedBuffer, + size_t UncompressedSize); + +} // End of namespace zstd } // End of namespace compression diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp --- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp +++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp @@ -498,6 +498,8 @@ case DebugCompressionType::Z: Chdr.ch_type = ELF::ELFCOMPRESS_ZLIB; break; + case DebugCompressionType::Zstd: + llvm_unreachable("unsupported"); } Chdr.ch_size = Sec.DecompressedSize; Chdr.ch_addralign = Sec.DecompressedAlign; diff --git a/llvm/lib/Support/Compression.cpp b/llvm/lib/Support/Compression.cpp --- a/llvm/lib/Support/Compression.cpp +++ b/llvm/lib/Support/Compression.cpp @@ -21,7 +21,7 @@ #include #endif #if LLVM_ENABLE_ZSTD -#include +#include #endif using namespace llvm; @@ -47,11 +47,12 @@ } } #endif -struct ZlibCompressionAlgorithm : public CompressionAlgorithm { +namespace { +struct ZlibCompressionAlgorithm final : public CompressionAlgorithm { #if LLVM_ENABLE_ZLIB - void compress(ArrayRef Input, - SmallVectorImpl &CompressedBuffer, int Level) { + SmallVectorImpl &CompressedBuffer, + int Level) const override { unsigned long CompressedSize = ::compressBound(Input.size()); CompressedBuffer.resize_for_overwrite(CompressedSize); int Res = ::compress2((Bytef *)CompressedBuffer.data(), &CompressedSize, @@ -66,7 +67,7 @@ CompressedBuffer.truncate(CompressedSize); }; Error decompress(ArrayRef Input, uint8_t *UncompressedBuffer, - size_t &UncompressedSize) { + size_t &UncompressedSize) const override { int Res = ::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize, (const Bytef *)Input.data(), Input.size()); @@ -77,34 +78,30 @@ inconvertibleErrorCode()) : Error::success(); }; - #else - void compress(ArrayRef Input, - SmallVectorImpl &CompressedBuffer, int Level) { + SmallVectorImpl &CompressedBuffer, + int Level) const override { llvm_unreachable("method:\"compress\" is unsupported for compression " "algorithm:\"zlib\", " "reason:\"llvm not compiled with zlib support\""); }; Error decompress(ArrayRef Input, uint8_t *UncompressedBuffer, - size_t &UncompressedSize) { + size_t &UncompressedSize) const override { llvm_unreachable( "method:\"decompress\" is unsupported for compression " "algorithm:\"zlib\", reason:\"llvm not compiled with zlib support\""); }; - #endif - -protected: - friend CompressionAlgorithm *CompressionKind::operator->() const; - ZlibCompressionAlgorithm() : CompressionAlgorithm("zlib", 1, 6, 9) {} + ZlibCompressionAlgorithm() + : CompressionAlgorithm("zlib", 1, 6, 9, LLVM_ENABLE_ZLIB) {} }; -struct ZStdCompressionAlgorithm : public CompressionAlgorithm { +struct ZStdCompressionAlgorithm final : public CompressionAlgorithm { #if LLVM_ENABLE_ZSTD - void compress(ArrayRef Input, - SmallVectorImpl &CompressedBuffer, int Level) { + SmallVectorImpl &CompressedBuffer, + int Level) const override { unsigned long CompressedBufferSize = ::ZSTD_compressBound(Input.size()); CompressedBuffer.resize_for_overwrite(CompressedBufferSize); unsigned long CompressedSize = @@ -112,79 +109,95 @@ (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. + // 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 Input, uint8_t *UncompressedBuffer, - size_t &UncompressedSize) { + size_t &UncompressedSize) const override { 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. + // 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 ZSTD_isError(Res) ? make_error(ZSTD_getErrorName(Res), inconvertibleErrorCode()) : Error::success(); }; - #else - void compress(ArrayRef Input, - SmallVectorImpl &CompressedBuffer, int Level) { - llvm_unreachable("method:\"compress\" is unsupported for compression " - "algorithm:\"zstd\", " - "reason:\"llvm not compiled with zstd support\""); - }; - Error decompress(ArrayRef 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 - -protected: - friend CompressionAlgorithm *CompressionKind::operator->() const; - ZStdCompressionAlgorithm() : CompressionAlgorithm("zstd", 1, 5, 12) {} -}; - -struct UnknownCompressionAlgorithm : public CompressionAlgorithm { - - void compress(ArrayRef Input, - SmallVectorImpl &CompressedBuffer, int Level) { - llvm_unreachable("method:\"compress\" is unsupported for compression " - "algorithm:\"unknown\", reason:\"can't call on unknown\""); - }; + SmallVectorImpl &CompressedBuffer, + int Level) const override { + llvm_unreachable("zstd compression unsupported"); + } Error decompress(ArrayRef Input, uint8_t *UncompressedBuffer, - size_t &UncompressedSize) { - llvm_unreachable("method:\"decompress\" is unsupported for compression " - "algorithm:\"unknown\", reason:\"can't call on unknown\""); + size_t &UncompressedSize) const override { + llvm_unreachable("zstd decompression unsupported"); } +#endif -protected: - friend CompressionAlgorithm *CompressionKind::operator->() const; - UnknownCompressionAlgorithm() - : CompressionAlgorithm("unknown", -999, -999, -999) {} + ZStdCompressionAlgorithm() + : CompressionAlgorithm("zlib", 1, 5, 12, LLVM_ENABLE_ZSTD) {} }; +} // namespace } // namespace -CompressionAlgorithm *CompressionKind::operator->() const { - switch (uint8_t(CompressionID)) { - case uint8_t(CompressionKind::Zlib): +const CompressionAlgorithm & +compression::getCompressionAlgorithm(DebugCompressionType Kind) { + switch (Kind) { + case DebugCompressionType::Z: static ZlibCompressionAlgorithm ZlibI; - return &ZlibI; - case uint8_t(CompressionKind::ZStd): + return ZlibI; + case DebugCompressionType::Zstd: static ZStdCompressionAlgorithm ZStdI; - return &ZStdI; - default: - static UnknownCompressionAlgorithm UnknownI; - return &UnknownI; + return ZStdI; + case DebugCompressionType::None: + llvm_unreachable("Only query for actual compression types."); } -} \ No newline at end of file + llvm_unreachable("Unknown compression kind"); +} + +// Deprecated implementation +bool zstd::isAvailable() { + return !!getCompressionAlgorithm(DebugCompressionType::Zstd); +} +void zstd::compress(ArrayRef Input, + SmallVectorImpl &CompressedBuffer, int Level) { + getCompressionAlgorithm(DebugCompressionType::Zstd) + .compress(Input, CompressedBuffer, Level); +} +Error zstd::uncompress(ArrayRef Input, uint8_t *UncompressedBuffer, + size_t &UncompressedSize) { + return getCompressionAlgorithm(DebugCompressionType::Zstd) + .decompress(Input, UncompressedBuffer, UncompressedSize); +} +Error zstd::uncompress(ArrayRef Input, + SmallVectorImpl &UncompressedBuffer, + size_t UncompressedSize) { + return getCompressionAlgorithm(DebugCompressionType::Zstd) + .decompress(Input, UncompressedBuffer, UncompressedSize); +} +bool zlib::isAvailable() { + return !!getCompressionAlgorithm(DebugCompressionType::Z); +} +void zlib::compress(ArrayRef Input, + SmallVectorImpl &CompressedBuffer, int Level) { + getCompressionAlgorithm(DebugCompressionType::Z) + .compress(Input, CompressedBuffer, Level); +} +Error zlib::uncompress(ArrayRef Input, uint8_t *UncompressedBuffer, + size_t &UncompressedSize) { + return getCompressionAlgorithm(DebugCompressionType::Z) + .decompress(Input, UncompressedBuffer, UncompressedSize); +} +Error zlib::uncompress(ArrayRef Input, + SmallVectorImpl &UncompressedBuffer, + size_t UncompressedSize) { + return getCompressionAlgorithm(DebugCompressionType::Z) + .decompress(Input, UncompressedBuffer, UncompressedSize); +}