ckissane created this revision.
ckissane added a reviewer: dblaikie.
Herald added subscribers: wenlei, usaxena95, kadircet, arphaman, hiraditya, 
arichardson, emaste.
Herald added a reviewer: alexander-shaposhnikov.
Herald added a reviewer: rupprecht.
Herald added a reviewer: jhenderson.
Herald added a reviewer: MaskRay.
Herald added a project: All.
ckissane requested review of this revision.
Herald added subscribers: cfe-commits, llvm-commits, StephenFan.
Herald added projects: clang, LLVM, clang-tools-extra.

compression algorithm base class, two (or three, if it's useful to have a 
default implementation for "None") derived classes, singleton instances of each 
and a function that takes the algorithm type and returns the handler - which 
can then be queried for "is available" and provides compress/decompress 
actions. That'd mean having only one switch instead of three, but the three are 
now so close together that it's not hugely painful to maintain (though having a 
class hierarchy would ensure the APIs were actually identical, whereas 
currently they're only identical by convention).


Repository:
  rG LLVM Github Monorepo

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/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/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, ZlibCompressionAlgorithm(),
+                           "zlib error: Z_BUF_ERROR");
+}
+
 TEST(CompressionTest, Zlib) {
-  testZlibCompression("", zlib::DefaultCompression);
+  compression::CompressionAlgorithm CompressionScheme =
+      compression::ZlibCompressionAlgorithm();
+  testZlibCompression("", CompressionScheme.DefaultCompression);
 
-  testZlibCompression("hello, world!", zlib::NoCompression);
-  testZlibCompression("hello, world!", zlib::BestSizeCompression);
-  testZlibCompression("hello, world!", zlib::BestSpeedCompression);
-  testZlibCompression("hello, world!", zlib::DefaultCompression);
+  testZlibCompression("hello, world!", CompressionScheme.BestSizeCompression);
+  testZlibCompression("hello, world!", CompressionScheme.BestSpeedCompression);
+  testZlibCompression("hello, world!", CompressionScheme.DefaultCompression);
 
   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.BestSizeCompression);
+  testZlibCompression(BinaryDataStr, CompressionScheme.BestSpeedCompression);
+  testZlibCompression(BinaryDataStr, CompressionScheme.DefaultCompression);
 }
 #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, ZStdCompressionAlgorithm(),
+                           "Destination buffer is too small");
 }
 
 TEST(CompressionTest, Zstd) {
-  testZstdCompression("", zstd::DefaultCompression);
+  compression::CompressionAlgorithm CompressionScheme =
+      compression::ZStdCompressionAlgorithm();
+  testZStdCompression("", CompressionScheme.DefaultCompression);
 
-  testZstdCompression("hello, world!", zstd::NoCompression);
-  testZstdCompression("hello, world!", zstd::BestSizeCompression);
-  testZstdCompression("hello, world!", zstd::BestSpeedCompression);
-  testZstdCompression("hello, world!", zstd::DefaultCompression);
+  testZStdCompression("hello, world!", CompressionScheme.BestSizeCompression);
+  testZStdCompression("hello, world!", CompressionScheme.BestSpeedCompression);
+  testZStdCompression("hello, world!", CompressionScheme.DefaultCompression);
 
   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.BestSizeCompression);
+  testZStdCompression(BinaryDataStr, CompressionScheme.BestSpeedCompression);
+  testZStdCompression(BinaryDataStr, CompressionScheme.DefaultCompression);
 }
 #endif
 }
Index: llvm/unittests/ProfileData/InstrProfTest.cpp
===================================================================
--- llvm/unittests/ProfileData/InstrProfTest.cpp
+++ llvm/unittests/ProfileData/InstrProfTest.cpp
@@ -1148,7 +1148,8 @@
     std::string FuncNameStrings1;
     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
                           FuncNames1,
-                          (DoCompression && compression::zlib::isAvailable()),
+                          (DoCompression &&
+                           compression::ZlibCompressionAlgorithm().supported()),
                           FuncNameStrings1),
                       Succeeded());
 
@@ -1156,7 +1157,8 @@
     std::string FuncNameStrings2;
     EXPECT_THAT_ERROR(collectPGOFuncNameStrings(
                           FuncNames2,
-                          (DoCompression && compression::zlib::isAvailable()),
+                          (DoCompression &&
+                           compression::ZlibCompressionAlgorithm().supported()),
                           FuncNameStrings2),
                       Succeeded());
 
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::ZlibCompressionAlgorithm().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::ZlibCompressionAlgorithm().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::ZlibCompressionAlgorithm().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,71 @@
 using namespace llvm;
 using namespace llvm::compression;
 
+constexpr SupportCompressionType CompressionAlgorithm::AlgorithmId;
+constexpr StringRef CompressionAlgorithm::name;
+constexpr int CompressionAlgorithm::BestSpeedCompression;
+constexpr int CompressionAlgorithm::DefaultCompression;
+constexpr int CompressionAlgorithm::BestSizeCompression;
+
+bool CompressionAlgorithm::supported() { return false; };
+
+void CompressionAlgorithm::compress(ArrayRef<uint8_t> Input,
+                                    SmallVectorImpl<uint8_t> &CompressedBuffer,
+                                    int Level) {
+  llvm_unreachable("method:\"compress\" is unsupported for compression "
+                   "algorithm:\"base\", reason:\"can't call on base\"");
+};
+Error CompressionAlgorithm::decompress(ArrayRef<uint8_t> Input,
+                                       uint8_t *UncompressedBuffer,
+                                       size_t &UncompressedSize) {
+  llvm_unreachable("method:\"decompress\" is unsupported for compression "
+                   "algorithm:\"base\", reason:\"can't call on base\"");
+}
+
+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 +110,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 +127,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 +140,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 +187,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 +201,47 @@
   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");
-}
-Error zstd::uncompress(ArrayRef<uint8_t> Input,
-                       SmallVectorImpl<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::CompressionAlgorithmFromId(uint8_t CompressionSchemeId) {
+  llvm::compression::CompressionAlgorithm CompressionScheme =
+      llvm::compression::CompressionAlgorithm();
+  switch (CompressionSchemeId) {
+  case static_cast<uint8_t>(
+      llvm::compression::NoneCompressionAlgorithm().AlgorithmId):
+    CompressionScheme = llvm::compression::NoneCompressionAlgorithm();
+    break;
+  case static_cast<uint8_t>(
+      llvm::compression::ZlibCompressionAlgorithm().AlgorithmId):
+    CompressionScheme = llvm::compression::ZlibCompressionAlgorithm();
+    break;
+  case static_cast<uint8_t>(
+      llvm::compression::ZStdCompressionAlgorithm().AlgorithmId):
+    CompressionScheme = llvm::compression::ZStdCompressionAlgorithm();
+    break;
+  default:
+    break;
+  }
+  return CompressionScheme;
+}
\ No newline at end of file
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::ZlibCompressionAlgorithm();
+  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),
-                              CompressedStrings,
-                              compression::zlib::BestSizeCompression);
+  CompressionScheme.compress(arrayRefFromStringRef(UncompressedStrings),
+                             CompressedStrings,
+                             CompressionScheme.BestSizeCompression);
   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::ZlibCompressionAlgorithm().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::ZlibCompressionAlgorithm().decompress(
       makeArrayRef(Data, *CompressSize), Buffer, UCSize);
   if (E)
     return sampleprof_error::uncompress_failed;
Index: llvm/lib/ProfileData/InstrProf.cpp
===================================================================
--- llvm/lib/ProfileData/InstrProf.cpp
+++ llvm/lib/ProfileData/InstrProf.cpp
@@ -463,11 +463,12 @@
   if (!doCompression) {
     return WriteStringToResult(0, UncompressedNameStrings);
   }
-
+  compression::CompressionAlgorithm CompressionScheme =
+      compression::ZlibCompressionAlgorithm();
   SmallVector<uint8_t, 128> CompressedNameStrings;
-  compression::zlib::compress(arrayRefFromStringRef(UncompressedNameStrings),
-                              CompressedNameStrings,
-                              compression::zlib::BestSizeCompression);
+  CompressionScheme.compress(arrayRefFromStringRef(UncompressedNameStrings),
+                             CompressedNameStrings,
+                             CompressionScheme.BestSizeCompression);
 
   return WriteStringToResult(CompressedNameStrings.size(),
                              toStringRef(CompressedNameStrings));
@@ -486,11 +487,16 @@
   for (auto *NameVar : NameVars) {
     NameStrs.push_back(std::string(getPGOFuncNameVarInitializer(NameVar)));
   }
+  compression::CompressionAlgorithm CompressionScheme =
+      compression::ZlibCompressionAlgorithm();
   return collectPGOFuncNameStrings(
-      NameStrs, compression::zlib::isAvailable() && doCompression, Result);
+      NameStrs, CompressionScheme.supported() && doCompression, Result);
 }
 
 Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) {
+  compression::CompressionAlgorithm CompressionScheme =
+      compression::ZlibCompressionAlgorithm();
+
   const uint8_t *P = NameStrings.bytes_begin();
   const uint8_t *EndP = NameStrings.bytes_end();
   while (P < EndP) {
@@ -503,10 +509,10 @@
     SmallVector<uint8_t, 128> UncompressedNameStrings;
     StringRef NameStrings;
     if (isCompressed) {
-      if (!llvm::compression::zlib::isAvailable())
+      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,14 @@
   }
 
   SmallVector<uint8_t, 128> CompressedStr;
-  bool doCompression = Compress && compression::zlib::isAvailable() &&
-                       DoInstrProfNameCompression;
+  compression::CompressionAlgorithm CompressionScheme =
+      compression::ZlibCompressionAlgorithm();
+  bool doCompression =
+      Compress && CompressionScheme.supported() && DoInstrProfNameCompression;
   if (doCompression)
-    compression::zlib::compress(arrayRefFromStringRef(FilenamesStr),
-                                CompressedStr,
-                                compression::zlib::BestSizeCompression);
+    CompressionScheme.compress(arrayRefFromStringRef(FilenamesStr),
+                               CompressedStr,
+                               CompressionScheme.BestSizeCompression);
 
   // ::= <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::ZlibCompressionAlgorithm().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::ZlibCompressionAlgorithm().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::ZlibCompressionAlgorithm();
+  } else {
     return createError("unsupported compression type");
+  }
+  if (!CompressionScheme.supported())
+    return createError(CompressionScheme.name + " 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),
-                                       Buffer.data(), Size);
+  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::ZlibCompressionAlgorithm().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,14 @@
                                      DebugCompressionType CompressionType)
     : SectionBase(Sec), CompressionType(CompressionType),
       DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) {
-  compression::zlib::compress(OriginalData, CompressedData);
+  switch (CompressionType) {
+  case DebugCompressionType::Z:
+    compression::ZlibCompressionAlgorithm().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
@@ -848,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;
@@ -865,7 +864,7 @@
 
   SmallVector<uint8_t, 128> Compressed;
   const uint32_t ChType = ELF::ELFCOMPRESS_ZLIB;
-  compression::zlib::compress(
+  compression::ZlibCompressionAlgorithm().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,154 @@
 
 #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 {
+  Base = 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:
+  static constexpr SupportCompressionType AlgorithmId =
+      SupportCompressionType::Base;
+  static constexpr StringRef name = "base";
+  static constexpr int BestSpeedCompression = -999;
+  static constexpr int DefaultCompression = -999;
+  static constexpr int BestSizeCompression = -999;
+
+  // // estimates level to achive compression speed around scale*(speed at level
+  // which has max (speed*ratio) on mozilla-unified Bundle) int
+  // levelToTargetCompressionSpeed(float scale){
+  //   return 1;
+  // };
+  bool supported();
+
+  void compress(ArrayRef<uint8_t> Input,
+                SmallVectorImpl<uint8_t> &CompressedBuffer,
+                int Level = DefaultCompression);
+
+  Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+                   size_t &UncompressedSize);
+
+  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;
+  }
+  constexpr CompressionAlgorithm(){};
+};
+
+class NoneCompressionAlgorithm : public CompressionAlgorithm {
+  using super = CompressionAlgorithm;
+
+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;
+
+  bool supported();
+  void compress(ArrayRef<uint8_t> Input,
+                SmallVectorImpl<uint8_t> &CompressedBuffer,
+                int Level = DefaultCompression);
+
+  Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+                   size_t &UncompressedSize);
+
+  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;
+  }
+
+  constexpr NoneCompressionAlgorithm() : super(){};
+};
+
+class ZlibCompressionAlgorithm : public CompressionAlgorithm {
+  using super = CompressionAlgorithm;
+
+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;
+
+  bool supported();
+  void compress(ArrayRef<uint8_t> Input,
+                SmallVectorImpl<uint8_t> &CompressedBuffer,
+                int Level = DefaultCompression);
+
+  Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+                   size_t &UncompressedSize);
+
+  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;
+  }
+  constexpr ZlibCompressionAlgorithm() : super(){};
+};
+
+class ZStdCompressionAlgorithm : public CompressionAlgorithm {
+  using super = CompressionAlgorithm;
+
+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;
+
+  bool supported();
+  void compress(ArrayRef<uint8_t> Input,
+                SmallVectorImpl<uint8_t> &CompressedBuffer,
+                int Level = DefaultCompression);
+
+  Error decompress(ArrayRef<uint8_t> Input, uint8_t *UncompressedBuffer,
+                   size_t &UncompressedSize);
+
+  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;
+  }
+  constexpr ZStdCompressionAlgorithm() : super(){};
+};
+llvm::compression::CompressionAlgorithm
+CompressionAlgorithmFromId(uint8_t CompressionSchemeId);
 
 } // End of namespace compression
 
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,7 @@
     uncompressedBuf = bAlloc().Allocate<uint8_t>(size);
   }
 
-  if (Error e = compression::zlib::uncompress(rawData, uncompressedBuf, size))
+  if (Error e = compression::ZlibCompressionAlgorithm().decompress(rawData, uncompressedBuf, size))
     fatal(toString(this) +
           ": uncompress failed: " + llvm::toString(std::move(e)));
   rawData = makeArrayRef(uncompressedBuf, size);
@@ -208,7 +208,7 @@
 
   auto *hdr = reinterpret_cast<const typename ELFT::Chdr *>(rawData.data());
   if (hdr->ch_type == ELFCOMPRESS_ZLIB) {
-    if (!compression::zlib::isAvailable())
+    if (!compression::ZlibCompressionAlgorithm().supported())
       error(toString(this) + " is compressed with ELFCOMPRESS_ZLIB, but lld is "
                              "not built with zlib support");
   } else {
@@ -219,7 +219,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 +1216,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::ZlibCompressionAlgorithm().supported()) {
+        error(toString(this) +
+              " is compressed with ELFCOMPRESS_ZLIB, but lld is "
+              "not built with zlib support");
+      } else {
+        if (Error e = compression::ZlibCompressionAlgorithm().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,11 +2000,17 @@
 
   // Compress the buffer if possible. We expect that almost all PCM
   // consumers will not want its contents.
+  llvm::compression::CompressionAlgorithm CompressionScheme =
+      llvm::compression::ZlibCompressionAlgorithm();
+
+  if (CompressionScheme.supported()) {
+
   SmallVector<uint8_t, 0> CompressedBuffer;
-  if (llvm::compression::zlib::isAvailable()) {
-    llvm::compression::zlib::compress(
-        llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer);
-    RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, Blob.size() - 1};
+
+    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));
     return;
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.name + " 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,12 @@
       RawTable.append(std::string(S));
       RawTable.push_back(0);
     }
-    if (llvm::compression::zlib::isAvailable()) {
+    llvm::compression::CompressionAlgorithm CompressionScheme =
+        llvm::compression::ZlibCompressionAlgorithm();
+    if (CompressionScheme.supported()) {
       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,7 +226,10 @@
   llvm::SmallVector<uint8_t, 0> UncompressedStorage;
   if (UncompressedSize == 0) // No compression
     Uncompressed = R.rest();
-  else if (llvm::compression::zlib::isAvailable()) {
+  else {
+    llvm::compression::CompressionAlgorithm CompressionScheme =
+        llvm::compression::ZlibCompressionAlgorithm();
+    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.
@@ -234,13 +239,16 @@
       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))
+    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 zlib is unavailable");
+    return error("Compressed string table, but " +
+              (CompressionScheme.name + " is unavailable").str());
+  }
 
   StringTableIn Table;
   llvm::StringSaver Saver(Table.Arena);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to