ckissane updated this revision to Diff 450172.
ckissane added a comment.

- Merge branch 'ckissane.compression-class' of github.com:ckissane/llvm-project 
into ckissane.compression-class
- Merge remote-tracking branch 'origin/ckissane.compression-class-simple' into 
ckissane.compression-class
- Merge remote-tracking branch 'origin/ckissane.compression-class-simple' into 
ckissane.compression-class
- Merge remote-tracking branch 'origin/ckissane.compression-class-simple' into 
ckissane.compression-class


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130667/new/

https://reviews.llvm.org/D130667

Files:
  clang-tools-extra/clangd/index/Serialization.cpp
  clang-tools-extra/clangd/index/Serialization.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/CodeGen/CoverageMappingGen.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/ASTUnit.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/GeneratePCH.cpp
  clang/test/CodeGen/coverage-compilation-dir.c
  clang/test/CoverageMapping/abspath.cpp
  clang/test/CoverageMapping/ir.c
  clang/test/Profile/coverage-prefix-map.c
  compiler-rt/include/profile/InstrProfData.inc
  compiler-rt/test/profile/instrprof-darwin-dead-strip.c
  compiler-rt/test/profile/instrprof-gc-sections.c
  lld/ELF/Driver.cpp
  lld/ELF/InputSection.cpp
  lld/test/CMakeLists.txt
  lld/test/ELF/compressed-debug-input-zstd.s
  lld/test/ELF/compressed-input-err-zstd.s
  lld/test/lit.site.cfg.py.in
  llvm/include/llvm/BinaryFormat/ELF.h
  llvm/include/llvm/MC/MCTargetOptions.h
  llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
  llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
  llvm/include/llvm/ProfileData/InstrProf.h
  llvm/include/llvm/ProfileData/InstrProfData.inc
  llvm/include/llvm/ProfileData/SampleProfWriter.h
  llvm/include/llvm/Support/CommandLine.h
  llvm/include/llvm/Support/Compression.h
  llvm/include/llvm/Transforms/Instrumentation.h
  llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.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/CommandLine.cpp
  llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
  llvm/test/tools/llvm-cov/coverage-prefix-map.test
  llvm/test/tools/llvm-cov/multiple-objects-not-all-instrumented.test
  llvm/test/tools/llvm-cov/multiple-objects.test
  llvm/test/tools/llvm-cov/multithreaded-report.test
  llvm/test/tools/llvm-cov/sources-specified.test
  llvm/test/tools/llvm-profdata/c-general.test
  llvm/test/tools/llvm-profdata/memprof-merge.test
  llvm/tools/llvm-mc/llvm-mc.cpp
  llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
  llvm/tools/llvm-objcopy/ObjcopyOpts.td
  llvm/tools/llvm-profdata/llvm-profdata.cpp
  llvm/tools/llvm-profgen/ProfileGenerator.cpp
  llvm/unittests/ProfileData/CoverageMappingTest.cpp
  llvm/unittests/ProfileData/SampleProfTest.cpp

Index: llvm/unittests/ProfileData/SampleProfTest.cpp
===================================================================
--- llvm/unittests/ProfileData/SampleProfTest.cpp
+++ llvm/unittests/ProfileData/SampleProfTest.cpp
@@ -50,7 +50,8 @@
     std::error_code EC;
     std::unique_ptr<raw_ostream> OS(
         new raw_fd_ostream(Profile, EC, sys::fs::OF_None));
-    auto WriterOrErr = SampleProfileWriter::create(OS, Format);
+    auto WriterOrErr = SampleProfileWriter::create(
+        OS, Format, compression::CompressionKind::Zlib);
     ASSERT_TRUE(NoError(WriterOrErr.getError()));
     Writer = std::move(WriterOrErr.get());
   }
Index: llvm/unittests/ProfileData/CoverageMappingTest.cpp
===================================================================
--- llvm/unittests/ProfileData/CoverageMappingTest.cpp
+++ llvm/unittests/ProfileData/CoverageMappingTest.cpp
@@ -932,7 +932,9 @@
     {
       raw_string_ostream OS(EncodedFilenames);
       CoverageFilenamesSectionWriter Writer(Paths);
-      Writer.write(OS, Compress);
+      Writer.write(OS, Compress ? (compression::OptionalCompressionKind)
+                                      compression::CompressionKind::Zlib
+                                : NoneType());
     }
 
     std::vector<std::string> ReadFilenames;
@@ -956,7 +958,9 @@
     {
       raw_string_ostream OS(EncodedFilenames);
       CoverageFilenamesSectionWriter Writer(Paths);
-      Writer.write(OS, Compress);
+      Writer.write(OS, Compress ? (compression::OptionalCompressionKind)
+                                      compression::CompressionKind::Zlib
+                                : NoneType());
     }
 
     StringRef CompilationDir = "out";
Index: llvm/tools/llvm-profgen/ProfileGenerator.cpp
===================================================================
--- llvm/tools/llvm-profgen/ProfileGenerator.cpp
+++ llvm/tools/llvm-profgen/ProfileGenerator.cpp
@@ -160,7 +160,8 @@
 }
 
 void ProfileGeneratorBase::write() {
-  auto WriterOrErr = SampleProfileWriter::create(OutputFilename, OutputFormat);
+  auto WriterOrErr = SampleProfileWriter::create(
+      OutputFilename, OutputFormat, compression::CompressionKind::Zlib);
   if (std::error_code EC = WriterOrErr.getError())
     exitWithError(EC, OutputFilename);
 
Index: llvm/tools/llvm-profdata/llvm-profdata.cpp
===================================================================
--- llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -25,6 +25,7 @@
 #include "llvm/ProfileData/SampleProfReader.h"
 #include "llvm/ProfileData/SampleProfWriter.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/Discriminator.h"
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
@@ -829,7 +830,8 @@
   }
 
   auto WriterOrErr =
-      SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]);
+      SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat],
+                                  compression::CompressionKind::Zlib);
   if (std::error_code EC = WriterOrErr.getError())
     exitWithErrorCode(EC, OutputFilename);
 
Index: llvm/tools/llvm-objcopy/ObjcopyOpts.td
===================================================================
--- llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -33,7 +33,7 @@
     : Joined<["--"], "compress-debug-sections=">,
       MetaVarName<"format">,
       HelpText<"Compress DWARF debug sections using specified format. Supported "
-               "formats: zlib">;
+               "formats: zlib, zstd">;
 def : Flag<["--"], "compress-debug-sections">, Alias<compress_debug_sections>,
       AliasArgs<["zlib"]>;
 def decompress_debug_sections : Flag<["--"], "decompress-debug-sections">,
Index: llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
===================================================================
--- llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -722,7 +722,9 @@
   if (const auto *A = InputArgs.getLastArg(OBJCOPY_compress_debug_sections)) {
     Config.CompressionType = StringSwitch<DebugCompressionType>(A->getValue())
                                  .Case("zlib", DebugCompressionType::Z)
+                                 .Case("zstd", DebugCompressionType::ZStd)
                                  .Default(DebugCompressionType::None);
+
     if (Config.CompressionType == DebugCompressionType::None)
       return createStringError(
           errc::invalid_argument,
@@ -737,6 +739,12 @@
             errc::invalid_argument,
             "LLVM was not compiled with LLVM_ENABLE_ZLIB: can not compress");
       break;
+    case DebugCompressionType::ZStd:
+      if (!compression::CompressionKind::ZStd)
+        return createStringError(
+            errc::invalid_argument,
+            "LLVM was not compiled with LLVM_ENABLE_ZSTD: can not compress");
+      break;
     }
   }
 
@@ -999,11 +1007,6 @@
         "--decompress-debug-sections");
   }
 
-  if (Config.DecompressDebugSections && !compression::CompressionKind::Zlib)
-    return createStringError(
-        errc::invalid_argument,
-        "LLVM was not compiled with LLVM_ENABLE_ZLIB: cannot decompress");
-
   if (Config.ExtractPartition && Config.ExtractMainPartition)
     return createStringError(errc::invalid_argument,
                              "cannot specify --extract-partition together with "
Index: llvm/tools/llvm-mc/llvm-mc.cpp
===================================================================
--- llvm/tools/llvm-mc/llvm-mc.cpp
+++ llvm/tools/llvm-mc/llvm-mc.cpp
@@ -401,10 +401,18 @@
   MAI->setRelaxELFRelocations(RelaxELFRel);
 
   if (CompressDebugSections != DebugCompressionType::None) {
-    if (!compression::CompressionKind::Zlib) {
-      WithColor::error(errs(), ProgName)
-          << "build tools with zlib to enable -compress-debug-sections";
-      return 1;
+    if (CompressDebugSections == DebugCompressionType::Z) {
+      if (!compression::CompressionKind::Zlib) {
+        WithColor::error(errs(), ProgName)
+            << "build tools with zlib to enable -compress-debug-sections=zlib";
+        return 1;
+      }
+    } else if (CompressDebugSections == DebugCompressionType::ZStd) {
+      if (!compression::CompressionKind::ZStd) {
+        WithColor::error(errs(), ProgName)
+            << "build tools with zstd to enable -compress-debug-sections=zstd";
+        return 1;
+      }
     }
     MAI->setCompressDebugSections(CompressDebugSections);
   }
Index: llvm/test/tools/llvm-profdata/memprof-merge.test
===================================================================
--- llvm/test/tools/llvm-profdata/memprof-merge.test
+++ llvm/test/tools/llvm-profdata/memprof-merge.test
@@ -21,7 +21,7 @@
 ```
 # Collect instrprof profile with name compression disabled since some buildbots
 # do not have zlib.
-clang -mllvm -enable-name-compression=false -fprofile-generate source.c -o instr.out
+clang -mllvm -name-compression=none -fprofile-generate source.c -o instr.out
 ./instr.out
 mv *.profraw basic.profraw
 
Index: llvm/test/tools/llvm-profdata/c-general.test
===================================================================
--- llvm/test/tools/llvm-profdata/c-general.test
+++ llvm/test/tools/llvm-profdata/c-general.test
@@ -5,7 +5,7 @@
 $ CFE=$SRC/tools/clang
 $ TESTDIR=$SRC/test/tools/llvm-profdata
 $ CFE_TESTDIR=$CFE/test/Profile
-$ clang -o a.out -fprofile-instr-generate $CFE_TESTDIR/c-general.c -mllvm -enable-name-compression=false
+$ clang -o a.out -fprofile-instr-generate $CFE_TESTDIR/c-general.c -mllvm -name-compression=none
 $ LLVM_PROFILE_FILE=$TESTDIR/Inputs/c-general.profraw ./a.out
 
 RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - | FileCheck %s
Index: llvm/test/tools/llvm-cov/sources-specified.test
===================================================================
--- llvm/test/tools/llvm-cov/sources-specified.test
+++ llvm/test/tools/llvm-cov/sources-specified.test
@@ -53,7 +53,7 @@
 # cd %S/Inputs/sources_specified
 cp -r . /tmp/sources_specified
 
-clang -mllvm -enable-name-compression=false -fprofile-instr-generate \
+clang -mllvm -name-compression=none -fprofile-instr-generate \
     -fcoverage-mapping /tmp/sources_specified/main.cc -o main
 
 LLVM_PROFILE_FILE="main.raw" ./main
Index: llvm/test/tools/llvm-cov/multithreaded-report.test
===================================================================
--- llvm/test/tools/llvm-cov/multithreaded-report.test
+++ llvm/test/tools/llvm-cov/multithreaded-report.test
@@ -84,7 +84,7 @@
 
 cp -r . /tmp/multithreaded_report
 
-clang++ -std=c++11 -mllvm -enable-name-compression=false \
+clang++ -std=c++11 -mllvm -name-compression=none \
     -fprofile-instr-generate -fcoverage-mapping \
     /tmp/multithreaded_report/*.cc -o main
 
Index: llvm/test/tools/llvm-cov/multiple-objects.test
===================================================================
--- llvm/test/tools/llvm-cov/multiple-objects.test
+++ llvm/test/tools/llvm-cov/multiple-objects.test
@@ -13,8 +13,8 @@
 
 Instructions for regenerating the test:
 
-clang -std=c++11 -mllvm -enable-name-compression=false -fprofile-instr-generate -fcoverage-mapping use_1.cc -o use_1
-clang -std=c++11 -mllvm -enable-name-compression=false -fprofile-instr-generate -fcoverage-mapping use_2.cc -o use_2
+clang -std=c++11 -mllvm -name-compression=none -fprofile-instr-generate -fcoverage-mapping use_1.cc -o use_1
+clang -std=c++11 -mllvm -name-compression=none -fprofile-instr-generate -fcoverage-mapping use_2.cc -o use_2
 LLVM_PROFILE_FILE="use_1.raw" ./use_1
 LLVM_PROFILE_FILE="use_2.raw" ./use_2
 llvm-profdata merge use_{1,2}.raw -o merged.profdata
Index: llvm/test/tools/llvm-cov/multiple-objects-not-all-instrumented.test
===================================================================
--- llvm/test/tools/llvm-cov/multiple-objects-not-all-instrumented.test
+++ llvm/test/tools/llvm-cov/multiple-objects-not-all-instrumented.test
@@ -7,6 +7,6 @@
 Instructions for regenerating the test:
 
 clang -std=c++11 not_instrumented.cc -o not_instrumented
-clang -std=c++11 -mllvm -enable-name-compression=false -fprofile-instr-generate -fcoverage-mapping instrumented.cc -o instrumented
+clang -std=c++11 -mllvm -name-compression=none -fprofile-instr-generate -fcoverage-mapping instrumented.cc -o instrumented
 LLVM_PROFILE_FILE="instrumented.raw" ./instrumented
 llvm-profdata merge instrumented.raw -o instrumented.profdata
Index: llvm/test/tools/llvm-cov/coverage-prefix-map.test
===================================================================
--- llvm/test/tools/llvm-cov/coverage-prefix-map.test
+++ llvm/test/tools/llvm-cov/coverage-prefix-map.test
@@ -20,7 +20,7 @@
 # cd %S/Inputs/coverage_prefix_map
 cp -r . /tmp/coverage_prefix_map
 
-clang -fprofile-instr-generate -mllvm -enable-name-compression=false -fcoverage-mapping -fcoverage-prefix-map=$PWD=. main.cc -o main
+clang -fprofile-instr-generate -mllvm -name-compression=none -fcoverage-mapping -fcoverage-prefix-map=$PWD=. main.cc -o main
 LLVM_PROFILE_FILE="main.raw" ./main
 llvm-profdata merge main.raw -o main.profdata
 llvm-cov convert-for-testing ./main -o ./main.covmapping
Index: llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -1118,7 +1118,7 @@
 
   std::string CompressedNameStr;
   if (Error E = collectPGOFuncNameStrings(ReferencedNames, CompressedNameStr,
-                                          DoInstrProfNameCompression)) {
+                                          InstrProfNameCompressionScheme)) {
     report_fatal_error(Twine(toString(std::move(E))), false);
   }
 
Index: llvm/lib/Support/CommandLine.cpp
===================================================================
--- llvm/lib/Support/CommandLine.cpp
+++ llvm/lib/Support/CommandLine.cpp
@@ -31,6 +31,7 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Config/config.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
@@ -43,6 +44,7 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/StringSaver.h"
 #include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdlib>
 #include <string>
@@ -67,6 +69,7 @@
 template class basic_parser<double>;
 template class basic_parser<float>;
 template class basic_parser<std::string>;
+template class basic_parser<compression::OptionalCompressionKind>;
 template class basic_parser<char>;
 
 template class opt<unsigned>;
@@ -74,6 +77,7 @@
 template class opt<std::string>;
 template class opt<char>;
 template class opt<bool>;
+template class opt<compression::OptionalCompressionKind>;
 } // namespace cl
 } // namespace llvm
 
@@ -95,6 +99,7 @@
 void parser<float>::anchor() {}
 void parser<std::string>::anchor() {}
 void parser<char>::anchor() {}
+void parser<compression::OptionalCompressionKind>::anchor() {}
 
 //===----------------------------------------------------------------------===//
 
@@ -1767,7 +1772,12 @@
   else
     Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName, 0);
 
-  Errs << " option: " << Message << "\n";
+  Errs << " option:\n";
+  Errs << "- ";
+  Errs.changeColor(raw_ostream::RED, true);
+  Errs << "error:";
+  Errs.resetColor();
+  Errs << " " << Message << "\n";
   return true;
 }
 
@@ -1913,6 +1923,33 @@
                  "' is invalid value for boolean argument! Try 0 or 1");
 }
 
+// parser<compression::OptionalCompressionKind> implementation
+//
+bool parser<compression::OptionalCompressionKind>::parse(
+    Option &O, StringRef, StringRef Arg,
+    compression::OptionalCompressionKind &Value) {
+  Value = llvm::StringSwitch<compression::OptionalCompressionKind>(Arg.str())
+              .Case("none", NoneType())
+              .Case("zlib", compression::CompressionKind::Zlib)
+              .Case("zstd", compression::CompressionKind::ZStd)
+              .Default(compression::CompressionKind::Unknown);
+  if (bool(Value) && ((*Value) == compression::CompressionKind::Unknown)) {
+
+    StringRef ArgName = O.ArgStr;
+    errs() << GlobalParser->ProgramName << ": ";
+    errs() << "for the " << PrintArg(ArgName, 0) << " option:\n";
+    errs() << "- ";
+    WithColor::error() << ("'" + Arg.str() +
+                           "' is not a recognized compression scheme!")
+                       << "\n";
+    outs() << "- ";
+    WithColor::note() << "Try one of none, zstd, or zlib"
+                      << "\n";
+    return true;
+  }
+  return false;
+}
+
 // parser<int> implementation
 //
 bool parser<int>::parse(Option &O, StringRef ArgName, StringRef Arg,
@@ -2158,6 +2195,7 @@
 PRINT_OPT_DIFF(unsigned long long)
 PRINT_OPT_DIFF(double)
 PRINT_OPT_DIFF(float)
+PRINT_OPT_DIFF(compression::OptionalCompressionKind)
 PRINT_OPT_DIFF(char)
 
 void parser<std::string>::printOptionDiff(const Option &O, StringRef V,
Index: llvm/lib/ProfileData/SampleProfWriter.cpp
===================================================================
--- llvm/lib/ProfileData/SampleProfWriter.cpp
+++ llvm/lib/ProfileData/SampleProfWriter.cpp
@@ -78,24 +78,39 @@
 }
 
 std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() {
-  compression::CompressionKind CompressionScheme =
-      compression::CompressionKind::Zlib;
-  if (!CompressionScheme)
-    return sampleprof_error::zlib_unavailable;
-  std::string &UncompressedStrings =
-      static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
-  if (UncompressedStrings.size() == 0)
+  if (!OptionalCompressionScheme) {
+    std::string &UncompressedStrings =
+        static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
+    if (UncompressedStrings.size() == 0)
+      return sampleprof_error::success;
+    auto &OS = *OutputStream;
+    encodeULEB128(UncompressedStrings.size(), OS);
+    encodeULEB128(UncompressedStrings.size(), OS);
+    encodeULEB128(uint8_t(0), OS);
+    OS << UncompressedStrings;
+    UncompressedStrings.clear();
     return sampleprof_error::success;
-  auto &OS = *OutputStream;
-  SmallVector<uint8_t, 128> CompressedStrings;
-  CompressionScheme->compress(arrayRefFromStringRef(UncompressedStrings),
-                              CompressedStrings,
-                              CompressionScheme->BestSizeLevel);
-  encodeULEB128(UncompressedStrings.size(), OS);
-  encodeULEB128(CompressedStrings.size(), OS);
-  OS << toStringRef(CompressedStrings);
-  UncompressedStrings.clear();
-  return sampleprof_error::success;
+  } else {
+    compression::CompressionKind CompressionScheme = *OptionalCompressionScheme;
+
+    if (!CompressionScheme)
+      return sampleprof_error::zlib_unavailable;
+    std::string &UncompressedStrings =
+        static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
+    if (UncompressedStrings.size() == 0)
+      return sampleprof_error::success;
+    auto &OS = *OutputStream;
+    SmallVector<uint8_t, 128> CompressedStrings;
+    CompressionScheme->compress(arrayRefFromStringRef(UncompressedStrings),
+                                CompressedStrings,
+                                CompressionScheme->BestSizeLevel);
+    encodeULEB128(UncompressedStrings.size(), OS);
+    encodeULEB128(CompressedStrings.size(), OS);
+    encodeULEB128(uint8_t(CompressionScheme), OS);
+    OS << toStringRef(CompressedStrings);
+    UncompressedStrings.clear();
+    return sampleprof_error::success;
+  }
 }
 
 /// Add a new section into section header table given the section type
@@ -842,8 +857,9 @@
 /// \param Format Encoding format for the profile file.
 ///
 /// \returns an error code indicating the status of the created writer.
-ErrorOr<std::unique_ptr<SampleProfileWriter>>
-SampleProfileWriter::create(StringRef Filename, SampleProfileFormat Format) {
+ErrorOr<std::unique_ptr<SampleProfileWriter>> SampleProfileWriter::create(
+    StringRef Filename, SampleProfileFormat Format,
+    compression::OptionalCompressionKind OptionalCompressionScheme) {
   std::error_code EC;
   std::unique_ptr<raw_ostream> OS;
   if (Format == SPF_Binary || Format == SPF_Ext_Binary ||
@@ -854,7 +870,7 @@
   if (EC)
     return EC;
 
-  return create(OS, Format);
+  return create(OS, Format, OptionalCompressionScheme);
 }
 
 /// Create a sample profile stream writer based on the specified format.
@@ -864,9 +880,9 @@
 /// \param Format Encoding format for the profile file.
 ///
 /// \returns an error code indicating the status of the created writer.
-ErrorOr<std::unique_ptr<SampleProfileWriter>>
-SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
-                            SampleProfileFormat Format) {
+ErrorOr<std::unique_ptr<SampleProfileWriter>> SampleProfileWriter::create(
+    std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format,
+    compression::OptionalCompressionKind OptionalCompressionScheme) {
   std::error_code EC;
   std::unique_ptr<SampleProfileWriter> Writer;
 
@@ -876,13 +892,16 @@
     return sampleprof_error::unsupported_writing_format;
 
   if (Format == SPF_Binary)
-    Writer.reset(new SampleProfileWriterRawBinary(OS));
+    Writer.reset(
+        new SampleProfileWriterRawBinary(OS, OptionalCompressionScheme));
   else if (Format == SPF_Ext_Binary)
-    Writer.reset(new SampleProfileWriterExtBinary(OS));
+    Writer.reset(
+        new SampleProfileWriterExtBinary(OS, OptionalCompressionScheme));
   else if (Format == SPF_Compact_Binary)
-    Writer.reset(new SampleProfileWriterCompactBinary(OS));
+    Writer.reset(
+        new SampleProfileWriterCompactBinary(OS, OptionalCompressionScheme));
   else if (Format == SPF_Text)
-    Writer.reset(new SampleProfileWriterText(OS));
+    Writer.reset(new SampleProfileWriterText(OS, OptionalCompressionScheme));
   else if (Format == SPF_GCC)
     EC = sampleprof_error::unsupported_writing_format;
   else
Index: llvm/lib/ProfileData/SampleProfReader.cpp
===================================================================
--- llvm/lib/ProfileData/SampleProfReader.cpp
+++ llvm/lib/ProfileData/SampleProfReader.cpp
@@ -877,17 +877,32 @@
   if (std::error_code EC = CompressSize.getError())
     return EC;
 
-  if (!llvm::compression::CompressionKind::Zlib)
-    return sampleprof_error::zlib_unavailable;
-
-  uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
-  size_t UCSize = DecompressBufSize;
-  llvm::Error E = compression::CompressionKind::Zlib->decompress(
-      makeArrayRef(Data, *CompressSize), Buffer, UCSize);
-  if (E)
-    return sampleprof_error::uncompress_failed;
-  DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
-  return sampleprof_error::success;
+  auto CompressionSchemeId = readNumber<uint64_t>();
+  if (std::error_code EC = CompressionSchemeId.getError())
+    return EC;
+  compression::OptionalCompressionKind OptionalCompressionScheme =
+      compression::getOptionalCompressionKind(*CompressionSchemeId);
+  if (OptionalCompressionScheme) {
+    compression::CompressionKind CompressionScheme = *OptionalCompressionScheme;
+    if (!CompressionScheme)
+      return sampleprof_error::zlib_unavailable;
+
+    uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
+    size_t UCSize = DecompressBufSize;
+    llvm::Error E = CompressionScheme->decompress(
+        makeArrayRef(Data, *CompressSize), Buffer, UCSize);
+    if (E)
+      return sampleprof_error::uncompress_failed;
+    DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
+    return sampleprof_error::success;
+  } else {
+
+    DecompressBufSize = *CompressSize;
+    uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
+    memcpy(Buffer, Data, DecompressBufSize);
+    DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
+    return sampleprof_error::success;
+  }
 }
 
 std::error_code SampleProfileReaderExtBinaryBase::readImpl() {
Index: llvm/lib/ProfileData/InstrProf.cpp
===================================================================
--- llvm/lib/ProfileData/InstrProf.cpp
+++ llvm/lib/ProfileData/InstrProf.cpp
@@ -205,9 +205,11 @@
 
 namespace llvm {
 
-cl::opt<bool> DoInstrProfNameCompression(
-    "enable-name-compression",
-    cl::desc("Enable name/filename string compression"), cl::init(true));
+cl::opt<compression::OptionalCompressionKind> InstrProfNameCompressionScheme(
+    "name-compression",
+    cl::desc("Scheme for name/filename string compression (none/zlib/ztsd), "
+             "defaults to zstd"),
+    cl::init(compression::CompressionKind::ZStd));
 
 std::string getInstrProfSectionName(InstrProfSectKind IPSK,
                                     Triple::ObjectFormatType OF,
@@ -452,25 +454,39 @@
   unsigned EncLen = encodeULEB128(UncompressedNameStrings.length(), P);
   P += EncLen;
 
-  auto WriteStringToResult = [&](size_t CompressedLen, StringRef InputStr) {
-    EncLen = encodeULEB128(CompressedLen, P);
-    P += EncLen;
-    char *HeaderStr = reinterpret_cast<char *>(&Header[0]);
-    unsigned HeaderLen = P - &Header[0];
-    Result.append(HeaderStr, HeaderLen);
-    Result += InputStr;
-    return Error::success();
+  auto WriteStringToResult = [&](size_t CompressedLen,
+                                 uint8_t CompressionSchemeId,
+                                 StringRef InputStr) {
+    if (CompressedLen == 0) {
+      EncLen = encodeULEB128(CompressedLen, P);
+      P += EncLen;
+      char *HeaderStr = reinterpret_cast<char *>(&Header[0]);
+      unsigned HeaderLen = P - &Header[0];
+      Result.append(HeaderStr, HeaderLen);
+      Result += InputStr;
+      return Error::success();
+    } else {
+      EncLen = encodeULEB128(CompressedLen, P);
+      P += EncLen;
+      EncLen = encodeULEB128(CompressionSchemeId, P);
+      P += EncLen;
+      char *HeaderStr = reinterpret_cast<char *>(&Header[0]);
+      unsigned HeaderLen = P - &Header[0];
+      Result.append(HeaderStr, HeaderLen);
+      Result += InputStr;
+      return Error::success();
+    }
   };
 
   if ((!OptionalCompressionScheme) || (!(*OptionalCompressionScheme)))
-    return WriteStringToResult(0, UncompressedNameStrings);
+    return WriteStringToResult(0, 0, UncompressedNameStrings);
   compression::CompressionKind CompressionScheme = *OptionalCompressionScheme;
   SmallVector<uint8_t, 128> CompressedNameStrings;
   CompressionScheme->compress(arrayRefFromStringRef(UncompressedNameStrings),
                               CompressedNameStrings,
                               CompressionScheme->BestSizeLevel);
 
-  return WriteStringToResult(CompressedNameStrings.size(),
+  return WriteStringToResult(CompressedNameStrings.size(), CompressionScheme,
                              toStringRef(CompressedNameStrings));
 }
 
@@ -481,18 +497,16 @@
   return NameStr;
 }
 
-Error collectPGOFuncNameStrings(ArrayRef<GlobalVariable *> NameVars,
-                                std::string &Result, bool doCompression) {
+Error collectPGOFuncNameStrings(
+    ArrayRef<GlobalVariable *> NameVars, std::string &Result,
+    compression::OptionalCompressionKind OptionalCompressionScheme) {
   std::vector<std::string> NameStrs;
   for (auto *NameVar : NameVars) {
     NameStrs.push_back(std::string(getPGOFuncNameVarInitializer(NameVar)));
   }
-  compression::OptionalCompressionKind OptionalCompressionScheme =
-      compression::CompressionKind::Zlib;
+
   return collectPGOFuncNameStrings(
-      NameStrs,
-      compression::noneIfUnsupported(doCompression ? OptionalCompressionScheme
-                                                   : llvm::NoneType()),
+      NameStrs, compression::noneIfUnsupported(OptionalCompressionScheme),
       Result);
 }
 
@@ -506,11 +520,19 @@
     uint64_t CompressedSize = decodeULEB128(P, &N);
     P += N;
     bool isCompressed = (CompressedSize != 0);
+    compression::OptionalCompressionKind OptionalCompressionScheme =
+        llvm::NoneType();
+    if (isCompressed) {
+      uint64_t CompressionSchemeId = decodeULEB128(P, &N);
+      P += N;
+      OptionalCompressionScheme =
+          compression::getOptionalCompressionKind(CompressionSchemeId);
+    }
     SmallVector<uint8_t, 128> UncompressedNameStrings;
     StringRef NameStrings;
-    if (isCompressed) {
+    if (isCompressed && bool(OptionalCompressionScheme)) {
       compression::CompressionKind CompressionScheme =
-          compression::CompressionKind::Zlib;
+          *OptionalCompressionScheme;
       if (!CompressionScheme)
         return make_error<InstrProfError>(instrprof_error::zlib_unavailable);
 
@@ -522,6 +544,7 @@
       }
       P += CompressedSize;
       NameStrings = toStringRef(UncompressedNameStrings);
+
     } else {
       NameStrings =
           StringRef(reinterpret_cast<const char *>(P), UncompressedSize);
@@ -1352,7 +1375,7 @@
     // When a new field is added in the header add a case statement here to
     // populate it.
     static_assert(
-        IndexedInstrProf::ProfVersion::CurrentVersion == Version8,
+        IndexedInstrProf::ProfVersion::CurrentVersion == Version9,
         "Please update the reading code below if a new field has been added, "
         "if not add a case statement to fall through to the latest version.");
   case 8ull:
@@ -1371,7 +1394,7 @@
     // When a new field is added to the header add a case statement here to
     // compute the size as offset of the new field + size of the new field. This
     // relies on the field being added to the end of the list.
-    static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version8,
+    static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version9,
                   "Please update the size computation below if a new field has "
                   "been added to the header, if not add a case statement to "
                   "fall through to the latest version.");
Index: llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
===================================================================
--- llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -37,7 +37,9 @@
 #endif
 }
 
-void CoverageFilenamesSectionWriter::write(raw_ostream &OS, bool Compress) {
+void CoverageFilenamesSectionWriter::write(
+    raw_ostream &OS,
+    compression::OptionalCompressionKind OptionalCompressionScheme) {
   std::string FilenamesStr;
   {
     raw_string_ostream FilenamesOS{FilenamesStr};
@@ -48,17 +50,15 @@
   }
 
   SmallVector<uint8_t, 128> CompressedStr;
-  compression::OptionalCompressionKind OptionalCompressionScheme =
-      compression::CompressionKind::Zlib;
-
-  OptionalCompressionScheme = compression::noneIfUnsupported(
-      (Compress && DoInstrProfNameCompression) ? OptionalCompressionScheme
-                                               : llvm::NoneType());
 
+  OptionalCompressionScheme =
+      compression::noneIfUnsupported(OptionalCompressionScheme);
+  compression::CompressionKind CompressionScheme =
+      compression::CompressionKind::Unknown;
   bool doCompression = bool(OptionalCompressionScheme);
 
   if (doCompression) {
-    compression::CompressionKind CompressionScheme = *OptionalCompressionScheme;
+    CompressionScheme = *OptionalCompressionScheme;
     CompressionScheme->compress(arrayRefFromStringRef(FilenamesStr),
                                 CompressedStr,
                                 CompressionScheme->BestSizeLevel);
@@ -67,10 +67,14 @@
   // ::= <num-filenames>
   //     <uncompressed-len>
   //     <compressed-len-or-zero>
+  //     IF compressed:
+  //       <compressed-alg-id>
   //     (<compressed-filenames> | <uncompressed-filenames>)
   encodeULEB128(Filenames.size(), OS);
   encodeULEB128(FilenamesStr.size(), OS);
   encodeULEB128(doCompression ? CompressedStr.size() : 0U, OS);
+  if (doCompression)
+    encodeULEB128(uint8_t(CompressionScheme), OS);
   OS << (doCompression ? toStringRef(CompressedStr) : StringRef(FilenamesStr));
 }
 
Index: llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
===================================================================
--- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -119,28 +119,47 @@
     return Err;
 
   if (CompressedLen > 0) {
-    if (!compression::CompressionKind::Zlib)
-      return make_error<CoverageMapError>(
-          coveragemap_error::decompression_failed);
-
-    // Allocate memory for the decompressed filenames.
-    SmallVector<uint8_t, 0> StorageBuf;
-
-    // Read compressed filenames.
-    StringRef CompressedFilenames = Data.substr(0, CompressedLen);
-    Data = Data.substr(CompressedLen);
-    auto Err = compression::CompressionKind::Zlib->decompress(
-        arrayRefFromStringRef(CompressedFilenames), StorageBuf,
-        UncompressedLen);
-    if (Err) {
-      consumeError(std::move(Err));
-      return make_error<CoverageMapError>(
-          coveragemap_error::decompression_failed);
+    compression::OptionalCompressionKind OptionalCompressionScheme =
+        compression::CompressionKind::Zlib;
+    if (Version >= CovMapVersion::Version7) {
+      uint64_t CompressionSchemeId;
+      if (auto Err = readULEB128(CompressionSchemeId))
+        return Err;
+      OptionalCompressionScheme =
+          compression::getOptionalCompressionKind(CompressionSchemeId);
     }
+    if (OptionalCompressionScheme) {
+      compression::CompressionKind CompressionScheme =
+          *OptionalCompressionScheme;
+      if (!CompressionScheme)
+        return make_error<CoverageMapError>(
+            coveragemap_error::decompression_failed);
+
+      // Allocate memory for the decompressed filenames.
+      SmallVector<uint8_t, 0> StorageBuf;
+
+      // Read compressed filenames.
+      StringRef CompressedFilenames = Data.substr(0, CompressedLen);
+      Data = Data.substr(CompressedLen);
+      auto Err = CompressionScheme->decompress(
+          arrayRefFromStringRef(CompressedFilenames), StorageBuf,
+          UncompressedLen);
+      if (Err) {
+        consumeError(std::move(Err));
+        return make_error<CoverageMapError>(
+            coveragemap_error::decompression_failed);
+      }
 
-    RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
-                                        CompilationDir);
-    return Delegate.readUncompressed(Version, NumFilenames);
+      RawCoverageFilenamesReader Delegate(toStringRef(StorageBuf), Filenames,
+                                          CompilationDir);
+      return Delegate.readUncompressed(Version, NumFilenames);
+    } else {
+      StringRef CompressedFilenames = Data.substr(0, CompressedLen);
+      Data = Data.substr(CompressedLen);
+      RawCoverageFilenamesReader Delegate(CompressedFilenames, Filenames,
+                                          CompilationDir);
+      return Delegate.readUncompressed(Version, NumFilenames);
+    }
   }
 
   return readUncompressed(Version, NumFilenames);
Index: llvm/lib/Object/Decompressor.cpp
===================================================================
--- llvm/lib/Object/Decompressor.cpp
+++ llvm/lib/Object/Decompressor.cpp
@@ -42,6 +42,8 @@
       &Offset, Is64Bit ? sizeof(Elf64_Word) : sizeof(Elf32_Word));
   if (ELFCompressionSchemeId == ELFCOMPRESS_ZLIB) {
     CompressionScheme = compression::CompressionKind::Zlib;
+  } else if (ELFCompressionSchemeId == ELFCOMPRESS_ZSTD) {
+    CompressionScheme = compression::CompressionKind::ZStd;
   } else {
     return createError("unsupported compression type");
   }
Index: llvm/lib/ObjCopy/ELF/ELFObject.cpp
===================================================================
--- llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -441,9 +441,9 @@
   SmallVector<uint8_t, 128> DecompressedContent;
   DebugCompressionType CompressionType =
       reinterpret_cast<const Elf_Chdr_Impl<ELFT> *>(Sec.OriginalData.data())
-                  ->ch_type == ELF::ELFCOMPRESS_ZLIB
-          ? DebugCompressionType::Z
-          : DebugCompressionType::None;
+                  ->ch_type == ELF::ELFCOMPRESS_ZSTD
+          ? DebugCompressionType::ZStd
+          : DebugCompressionType::Z;
 
   switch (CompressionType) {
   case DebugCompressionType::Z:
@@ -454,6 +454,14 @@
                                    "': " + toString(std::move(Err1)));
     }
     break;
+  case DebugCompressionType::ZStd:
+    if (Error Err = compression::CompressionKind::ZStd->decompress(
+            Compressed, DecompressedContent, static_cast<size_t>(Sec.Size))) {
+      return createStringError(errc::invalid_argument,
+                               "'" + Sec.Name +
+                                   "': " + toString(std::move(Err)));
+    }
+    break;
   case DebugCompressionType::None:
     llvm_unreachable("unexpected DebugCompressionType::None");
     break;
@@ -513,6 +521,9 @@
   case DebugCompressionType::Z:
     Chdr.ch_type = ELF::ELFCOMPRESS_ZLIB;
     break;
+  case DebugCompressionType::ZStd:
+    Chdr.ch_type = ELF::ELFCOMPRESS_ZSTD;
+    break;
   }
   Chdr.ch_size = Sec.DecompressedSize;
   Chdr.ch_addralign = Sec.DecompressedAlign;
@@ -531,6 +542,9 @@
   case DebugCompressionType::Z:
     compression::CompressionKind::Zlib->compress(OriginalData, CompressedData);
     break;
+  case DebugCompressionType::ZStd:
+    compression::CompressionKind::ZStd->compress(OriginalData, CompressedData);
+    break;
   case DebugCompressionType::None:
     break;
   }
Index: llvm/lib/MC/ELFObjectWriter.cpp
===================================================================
--- llvm/lib/MC/ELFObjectWriter.cpp
+++ llvm/lib/MC/ELFObjectWriter.cpp
@@ -144,7 +144,8 @@
 
   uint64_t align(unsigned Alignment);
 
-  bool maybeWriteCompression(uint32_t ChType, uint64_t Size,
+  bool maybeWriteCompression(DebugCompressionType CompressionType,
+                             uint64_t Size,
                              SmallVectorImpl<uint8_t> &CompressedContents,
                              unsigned Alignment);
 
@@ -818,12 +819,24 @@
 
 // Include the debug info compression header.
 bool ELFWriter::maybeWriteCompression(
-    uint32_t ChType, uint64_t Size,
+    DebugCompressionType CompressionType, uint64_t Size,
     SmallVectorImpl<uint8_t> &CompressedContents, unsigned Alignment) {
   uint64_t HdrSize =
       is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
   if (Size <= HdrSize + CompressedContents.size())
     return false;
+  uint64_t ChType;
+  switch (CompressionType) {
+  case DebugCompressionType::Z:
+    ChType = ELF::ELFCOMPRESS_ZLIB;
+    break;
+  case DebugCompressionType::ZStd:
+    ChType = ELF::ELFCOMPRESS_ZSTD;
+    break;
+  default:
+    return false;
+  }
+
   // Platform specific header is followed by compressed data.
   if (is64Bit()) {
     // Write Elf64_Chdr header.
@@ -854,22 +867,34 @@
     return;
   }
 
-  assert(CompressionType == DebugCompressionType::Z &&
-         "expected zlib style compression");
+  assert((CompressionType == DebugCompressionType::Z ||
+          CompressionType == DebugCompressionType::ZStd) &&
+         "expected zlib or zstd style compression");
 
   SmallVector<char, 128> UncompressedData;
   raw_svector_ostream VecOS(UncompressedData);
   Asm.writeSectionData(VecOS, &Section, Layout);
 
   SmallVector<uint8_t, 128> Compressed;
-  const uint32_t ChType = ELF::ELFCOMPRESS_ZLIB;
-  compression::CompressionKind::Zlib->compress(
-      makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
-                   UncompressedData.size()),
-      Compressed);
-
-  if (!maybeWriteCompression(ChType, UncompressedData.size(), Compressed,
-                             Sec.getAlignment())) {
+  switch (CompressionType) {
+  case DebugCompressionType::Z:
+    compression::CompressionKind::Zlib->compress(
+        makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
+                     UncompressedData.size()),
+        Compressed);
+    break;
+  case DebugCompressionType::ZStd:
+    compression::CompressionKind::ZStd->compress(
+        makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
+                     UncompressedData.size()),
+        Compressed);
+    break;
+  case DebugCompressionType::None:
+    break;
+  }
+
+  if (!maybeWriteCompression(CompressionType, UncompressedData.size(),
+                             Compressed, Sec.getAlignment())) {
     W.OS << UncompressedData;
     return;
   }
Index: llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
===================================================================
--- llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
+++ llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
@@ -18,6 +18,7 @@
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include <cstdint>
 #include <cstring>
@@ -134,6 +135,7 @@
   /// Create a static initializer for our data, on platforms that need it,
   /// and for any profile output file that was specified.
   void emitInitialization();
+  compression::OptionalCompressionKind OptionalCompressionScheme;
 };
 
 } // end namespace llvm
Index: llvm/include/llvm/Transforms/Instrumentation.h
===================================================================
--- llvm/include/llvm/Transforms/Instrumentation.h
+++ llvm/include/llvm/Transforms/Instrumentation.h
@@ -19,6 +19,7 @@
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instruction.h"
+#include "llvm/Support/Compression.h"
 #include <cassert>
 #include <cstdint>
 #include <limits>
@@ -120,6 +121,8 @@
   // Name of the profile file to use as output
   std::string InstrProfileOutput;
 
+  compression::OptionalCompressionKind OptionalCompressionScheme;
+
   InstrProfOptions() = default;
 };
 
Index: llvm/include/llvm/Support/Compression.h
===================================================================
--- llvm/include/llvm/Support/Compression.h
+++ llvm/include/llvm/Support/Compression.h
@@ -64,11 +64,9 @@
 protected:
   friend constexpr llvm::Optional<CompressionKind>
   getOptionalCompressionKind(uint8_t y);
-  constexpr CompressionKind(uint8_t y) : x(y) {
-    if (!(y == 1 || y == 2 || y == 255)) {
-      llvm_unreachable("unknown compression id");
-    }
-  }
+  // because getOptionalCompressionKind is the only friend:
+  // we can trust the value of y is valid
+  constexpr CompressionKind(uint8_t y) : x(y) {}
 
 public:
   constexpr operator uint8_t() const { return x; }
@@ -76,6 +74,8 @@
 
   constexpr operator bool() const;
 
+  constexpr operator StringRef() const;
+
   static const llvm::compression::CompressionKind Unknown, Zlib, ZStd;
 };
 constexpr inline const llvm::compression::CompressionKind
@@ -87,22 +87,21 @@
 constexpr CompressionKind::operator bool() const {
   switch (uint8_t(x)) {
   case uint8_t(CompressionKind::Zlib):
-#if LLVM_ENABLE_ZLIB
-    return true;
-#else
-    return false;
-#endif
+    return LLVM_ENABLE_ZLIB;
   case uint8_t(CompressionKind::ZStd):
-#if LLVM_ENABLE_ZSTD
-    return true;
-#else
-    return false;
-#endif
+    return LLVM_ENABLE_ZSTD;
   default:
     return false;
   }
 }
 
+// so that commanbd line option implementation works
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     const CompressionKind &B) {
+  OS << (B->Name);
+  return OS;
+}
+
 constexpr bool operator==(CompressionKind left, CompressionKind right) {
   return uint8_t(left) == uint8_t(right);
 }
@@ -112,10 +111,15 @@
 OptionalCompressionKind noneIfUnsupported(OptionalCompressionKind left);
 
 constexpr OptionalCompressionKind getOptionalCompressionKind(uint8_t y) {
-  if (y == 0) {
+  switch (y) {
+  case uint8_t(0):
     return NoneType();
+  case uint8_t(CompressionKind::Zlib):
+  case uint8_t(CompressionKind::ZStd):
+    return CompressionKind(y);
+  default:
+    return CompressionKind::Unknown;
   }
-  return CompressionKind(y);
 }
 
 } // End of namespace compression
Index: llvm/include/llvm/Support/CommandLine.h
===================================================================
--- llvm/include/llvm/Support/CommandLine.h
+++ llvm/include/llvm/Support/CommandLine.h
@@ -27,8 +27,10 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/raw_ostream.h"
@@ -1157,6 +1159,30 @@
 
 //--------------------------------------------------
 
+extern template class basic_parser<compression::OptionalCompressionKind>;
+
+template <>
+class parser<compression::OptionalCompressionKind>
+    : public basic_parser<compression::OptionalCompressionKind> {
+public:
+  parser(Option &O) : basic_parser(O) {}
+
+  // Return true on error.
+  bool parse(Option &, StringRef, StringRef Arg,
+             compression::OptionalCompressionKind &Value);
+
+  // Overload in subclass to provide a better default value.
+  StringRef getValueName() const override { return "compression scheme"; }
+
+  void printOptionDiff(const Option &O, compression::OptionalCompressionKind V,
+                       OptVal Default, size_t GlobalWidth) const;
+
+  // An out-of-line virtual method to provide a 'home' for this class.
+  void anchor() override;
+};
+
+//--------------------------------------------------
+
 extern template class basic_parser<char>;
 
 template <> class parser<char> : public basic_parser<char> {
Index: llvm/include/llvm/ProfileData/SampleProfWriter.h
===================================================================
--- llvm/include/llvm/ProfileData/SampleProfWriter.h
+++ llvm/include/llvm/ProfileData/SampleProfWriter.h
@@ -16,6 +16,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/ProfileSummary.h"
 #include "llvm/ProfileData/SampleProf.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdint>
@@ -56,12 +57,14 @@
   ///
   /// Create a new file writer based on the value of \p Format.
   static ErrorOr<std::unique_ptr<SampleProfileWriter>>
-  create(StringRef Filename, SampleProfileFormat Format);
+  create(StringRef Filename, SampleProfileFormat Format,
+         compression::OptionalCompressionKind OptionalCompressionScheme);
 
   /// Create a new stream writer based on the value of \p Format.
   /// For testing.
   static ErrorOr<std::unique_ptr<SampleProfileWriter>>
-  create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format);
+  create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format,
+         compression::OptionalCompressionKind OptionalCompressionScheme);
 
   virtual void setProfileSymbolList(ProfileSymbolList *PSL) {}
   virtual void setToCompressAllSections() {}
@@ -70,8 +73,11 @@
   virtual void resetSecLayout(SectionLayout SL) {}
 
 protected:
-  SampleProfileWriter(std::unique_ptr<raw_ostream> &OS)
-      : OutputStream(std::move(OS)) {}
+  SampleProfileWriter(
+      std::unique_ptr<raw_ostream> &OS,
+      compression::OptionalCompressionKind OptionalCompressionScheme)
+      : OutputStream(std::move(OS)),
+        OptionalCompressionScheme(OptionalCompressionScheme) {}
 
   /// Write a file header for the profile file.
   virtual std::error_code writeHeader(const SampleProfileMap &ProfileMap) = 0;
@@ -90,6 +96,9 @@
 
   /// Profile format.
   SampleProfileFormat Format = SPF_None;
+
+  /// Compression scheme;
+  compression::OptionalCompressionKind OptionalCompressionScheme;
 };
 
 /// Sample-based profile writer (text format).
@@ -98,8 +107,10 @@
   std::error_code writeSample(const FunctionSamples &S) override;
 
 protected:
-  SampleProfileWriterText(std::unique_ptr<raw_ostream> &OS)
-      : SampleProfileWriter(OS), Indent(0) {}
+  SampleProfileWriterText(
+      std::unique_ptr<raw_ostream> &OS,
+      compression::OptionalCompressionKind OptionalCompressionScheme)
+      : SampleProfileWriter(OS, OptionalCompressionScheme), Indent(0) {}
 
   std::error_code writeHeader(const SampleProfileMap &ProfileMap) override {
     return sampleprof_error::success;
@@ -112,15 +123,18 @@
   unsigned Indent;
 
   friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
-  SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
-                              SampleProfileFormat Format);
+  SampleProfileWriter::create(
+      std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format,
+      compression::OptionalCompressionKind OptionalCompressionScheme);
 };
 
 /// Sample-based profile writer (binary format).
 class SampleProfileWriterBinary : public SampleProfileWriter {
 public:
-  SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
-      : SampleProfileWriter(OS) {}
+  SampleProfileWriterBinary(
+      std::unique_ptr<raw_ostream> &OS,
+      compression::OptionalCompressionKind OptionalCompressionScheme)
+      : SampleProfileWriter(OS, OptionalCompressionScheme) {}
 
   std::error_code writeSample(const FunctionSamples &S) override;
 
@@ -144,8 +158,9 @@
 
 private:
   friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
-  SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
-                              SampleProfileFormat Format);
+  SampleProfileWriter::create(
+      std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format,
+      compression::OptionalCompressionKind OptionalCompressionScheme);
 };
 
 class SampleProfileWriterRawBinary : public SampleProfileWriterBinary {
@@ -324,8 +339,10 @@
 
 class SampleProfileWriterExtBinary : public SampleProfileWriterExtBinaryBase {
 public:
-  SampleProfileWriterExtBinary(std::unique_ptr<raw_ostream> &OS)
-      : SampleProfileWriterExtBinaryBase(OS) {}
+  SampleProfileWriterExtBinary(
+      std::unique_ptr<raw_ostream> &OS,
+      compression::OptionalCompressionKind OptionalCompressionScheme)
+      : SampleProfileWriterExtBinaryBase(OS, OptionalCompressionScheme) {}
 
 private:
   std::error_code writeDefaultLayout(const SampleProfileMap &ProfileMap);
Index: llvm/include/llvm/ProfileData/InstrProfData.inc
===================================================================
--- llvm/include/llvm/ProfileData/InstrProfData.inc
+++ llvm/include/llvm/ProfileData/InstrProfData.inc
@@ -648,11 +648,11 @@
 
 /* FIXME: Please remedy the fixme in the header before bumping the version. */
 /* Raw profile format version (start from 1). */
-#define INSTR_PROF_RAW_VERSION 8
+#define INSTR_PROF_RAW_VERSION 9
 /* Indexed profile format version (start from 1). */
-#define INSTR_PROF_INDEX_VERSION 8
+#define INSTR_PROF_INDEX_VERSION 9
 /* Coverage mapping format version (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 5
+#define INSTR_PROF_COVMAP_VERSION 6
 
 /* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
  * version for other variants of profile. We set the lowest bit of the upper 8
Index: llvm/include/llvm/ProfileData/InstrProf.h
===================================================================
--- llvm/include/llvm/ProfileData/InstrProf.h
+++ llvm/include/llvm/ProfileData/InstrProf.h
@@ -222,8 +222,9 @@
 
 /// Produce \c Result string with the same format described above. The input
 /// is vector of PGO function name variables that are referenced.
-Error collectPGOFuncNameStrings(ArrayRef<GlobalVariable *> NameVars,
-                                std::string &Result, bool doCompression = true);
+Error collectPGOFuncNameStrings(
+    ArrayRef<GlobalVariable *> NameVars, std::string &Result,
+    compression::OptionalCompressionKind OptionalCompressionScheme);
 
 /// \c NameStrings is a string composed of one of more sub-strings encoded in
 /// the format described above. The substrings are separated by 0 or more zero
@@ -1024,7 +1025,9 @@
   Version7 = 7,
   // An additional (optional) memory profile type is added.
   Version8 = 8,
-  // The current version is 8.
+  // more compression types
+  Version9 = 9,
+  // The current version is 9.
   CurrentVersion = INSTR_PROF_INDEX_VERSION
 };
 const uint64_t Version = ProfVersion::CurrentVersion;
@@ -1201,7 +1204,8 @@
 
 // Whether to compress function names in profile records, and filenames in
 // code coverage mappings. Used by the Instrumentation library and unit tests.
-extern cl::opt<bool> DoInstrProfNameCompression;
+extern cl::opt<compression::OptionalCompressionKind>
+    InstrProfNameCompressionScheme;
 
 } // end namespace llvm
 #endif // LLVM_PROFILEDATA_INSTRPROF_H
Index: llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
===================================================================
--- llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
+++ llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
+#include "llvm/Support/Compression.h"
 
 namespace llvm {
 
@@ -32,9 +33,12 @@
 public:
   CoverageFilenamesSectionWriter(ArrayRef<std::string> Filenames);
 
-  /// Write encoded filenames to the given output stream. If \p Compress is
-  /// true, attempt to compress the filenames.
-  void write(raw_ostream &OS, bool Compress = true);
+  /// Write encoded filenames to the given output stream. If \p
+  /// CompressionScheme is not an instance of
+  /// llvm::compression::NoneCompressionAlgorithm, attempt to compress the
+  /// filenames.
+  void write(raw_ostream &OS,
+             compression::OptionalCompressionKind OptionalCompressionScheme);
 };
 
 /// Writer for instrumentation based coverage mapping data.
Index: llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
===================================================================
--- llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -1005,7 +1005,9 @@
   // Compilation directory is stored separately and combined with relative
   // filenames to produce an absolute file path.
   Version6 = 5,
-  // The current version is Version6.
+  // not just zlib compression
+  Version7 = 6,
+  // The current version is Version7.
   CurrentVersion = INSTR_PROF_COVMAP_VERSION
 };
 
Index: llvm/include/llvm/MC/MCTargetOptions.h
===================================================================
--- llvm/include/llvm/MC/MCTargetOptions.h
+++ llvm/include/llvm/MC/MCTargetOptions.h
@@ -28,6 +28,7 @@
 enum class DebugCompressionType {
   None, ///< No compression
   Z,    ///< zlib style complession
+  ZStd, ///< zstd style complession
 };
 
 enum class EmitDwarfUnwindType {
Index: llvm/include/llvm/BinaryFormat/ELF.h
===================================================================
--- llvm/include/llvm/BinaryFormat/ELF.h
+++ llvm/include/llvm/BinaryFormat/ELF.h
@@ -1798,6 +1798,7 @@
 // Legal values for ch_type field of compressed section header.
 enum {
   ELFCOMPRESS_ZLIB = 1,            // ZLIB/DEFLATE algorithm.
+  ELFCOMPRESS_ZSTD = 2,            // ZStandard algorithm.
   ELFCOMPRESS_LOOS = 0x60000000,   // Start of OS-specific.
   ELFCOMPRESS_HIOS = 0x6fffffff,   // End of OS-specific.
   ELFCOMPRESS_LOPROC = 0x70000000, // Start of processor-specific.
Index: lld/test/lit.site.cfg.py.in
===================================================================
--- lld/test/lit.site.cfg.py.in
+++ lld/test/lit.site.cfg.py.in
@@ -18,6 +18,7 @@
 config.target_triple = "@LLVM_TARGET_TRIPLE@"
 config.python_executable = "@Python3_EXECUTABLE@"
 config.have_zlib = @LLVM_ENABLE_ZLIB@
+config.have_zstd = @LLVM_ENABLE_ZSTD@
 config.have_libxar = @LLVM_HAVE_LIBXAR@
 config.have_libxml2 = @LLVM_ENABLE_LIBXML2@
 config.sizeof_void_p = @CMAKE_SIZEOF_VOID_P@
Index: lld/test/ELF/compressed-input-err-zstd.s
===================================================================
--- /dev/null
+++ lld/test/ELF/compressed-input-err-zstd.s
@@ -0,0 +1,18 @@
+# UNSUPPORTED: zstd
+# RUN: yaml2obj %s -o %t.o
+# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK: error: {{.*}}.o:(.debug_info) is compressed with ELFCOMPRESS_ZSTD, but lld is not built with zstd support
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type:         SHT_PROGBITS
+    Name:         .debug_info
+    Flags:        [ SHF_COMPRESSED ]
+    AddressAlign: 8
+    Content:      "020000000000000000000000000000000100000000000000789c030000000001"
Index: lld/test/ELF/compressed-debug-input-zstd.s
===================================================================
--- /dev/null
+++ lld/test/ELF/compressed-debug-input-zstd.s
@@ -0,0 +1,42 @@
+# REQUIRES: x86, zstd
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 --compress-debug-sections=zstd %s -o %t.o
+
+# RUN: ld.lld %t.o -o %t.so -shared
+# RUN: llvm-readobj --sections --section-data %t.so | FileCheck -check-prefix=DATA %s
+
+# DATA:      Section {
+# DATA:        Index: 6
+# DATA:        Name: .debug_str
+# DATA-NEXT:   Type: SHT_PROGBITS
+# DATA-NEXT:   Flags [
+# DATA-NEXT:     SHF_MERGE (0x10)
+# DATA-NEXT:     SHF_STRINGS (0x20)
+# DATA-NEXT:   ]
+# DATA-NEXT:   Address: 0x0
+# DATA-NEXT:   Offset:
+# DATA-NEXT:   Size: 69
+# DATA-NEXT:   Link: 0
+# DATA-NEXT:   Info: 0
+# DATA-NEXT:   AddressAlignment: 1
+# DATA-NEXT:   EntrySize: 1
+# DATA-NEXT:   SectionData (
+# DATA-NEXT:     0000: 756E7369 676E6564 20696E74 00636861  |unsigned int.cha|
+# DATA-NEXT:     0010: 7200756E 7369676E 65642063 68617200  |r.unsigned char.|
+# DATA-NEXT:     0020: 73686F72 7420756E 7369676E 65642069  |short unsigned i|
+# DATA-NEXT:     0030: 6E74006C 6F6E6720 756E7369 676E6564  |nt.long unsigned|
+# DATA-NEXT:     0040: 20696E74 00                          | int.|
+# DATA-NEXT:   )
+# DATA-NEXT: }
+
+.section .debug_str,"MS",@progbits,1
+.LASF2:
+ .string "short unsigned int"
+.LASF3:
+ .string "unsigned int"
+.LASF0:
+ .string "long unsigned int"
+.LASF8:
+ .string "char"
+.LASF1:
+ .string "unsigned char"
Index: lld/test/CMakeLists.txt
===================================================================
--- lld/test/CMakeLists.txt
+++ lld/test/CMakeLists.txt
@@ -1,6 +1,7 @@
 llvm_canonicalize_cmake_booleans(
   ENABLE_BACKTRACES
   LLVM_ENABLE_ZLIB
+  LLVM_ENABLE_ZSTD
   LLVM_ENABLE_LIBXML2
   LLD_DEFAULT_LD_LLD_IS_MINGW
   LLVM_HAVE_LIBXAR
Index: lld/ELF/InputSection.cpp
===================================================================
--- lld/ELF/InputSection.cpp
+++ lld/ELF/InputSection.cpp
@@ -110,6 +110,22 @@
   return rawData.size() - bytesDropped;
 }
 
+template <class ELFT>
+static void uncompressAux(const InputSectionBase *sec, uint8_t *out,
+                          size_t size) {
+  auto *hdr =
+      reinterpret_cast<const typename ELFT::Chdr *>(sec->rawData.data());
+  ArrayRef<uint8_t> compressed =
+      sec->rawData.slice(sizeof(typename ELFT::Chdr));
+  if (Error e = (hdr->ch_type == ELFCOMPRESS_ZLIB
+                     ? compression::CompressionKind::Zlib->decompress(
+                           compressed, out, size)
+                     : compression::CompressionKind::ZStd->decompress(
+                           compressed, out, size)))
+    fatal(toString(sec) +
+          ": uncompress failed: " + llvm::toString(std::move(e)));
+}
+
 void InputSectionBase::uncompress() const {
   size_t size = uncompressedSize;
   uint8_t *uncompressedBuf;
@@ -118,11 +134,7 @@
     std::lock_guard<std::mutex> lock(mu);
     uncompressedBuf = bAlloc().Allocate<uint8_t>(size);
   }
-
-  if (Error e = compression::CompressionKind::Zlib->decompress(
-          rawData, uncompressedBuf, size))
-    fatal(toString(this) +
-          ": uncompress failed: " + llvm::toString(std::move(e)));
+  invokeELFT(uncompressAux, this, uncompressedBuf, size);
   rawData = makeArrayRef(uncompressedBuf, size);
   uncompressedSize = -1;
 }
@@ -197,7 +209,7 @@
 }
 
 // When a section is compressed, `rawData` consists with a header followed
-// by zlib-compressed data. This function parses a header to initialize
+// by zlib or zstd-compressed data. This function parses a header to initialize
 // `uncompressedSize` member and remove the header from `rawData`.
 template <typename ELFT> void InputSectionBase::parseCompressedHeader() {
   flags &= ~(uint64_t)SHF_COMPRESSED;
@@ -213,6 +225,10 @@
     if (!compression::CompressionKind::Zlib)
       error(toString(this) + " is compressed with ELFCOMPRESS_ZLIB, but lld is "
                              "not built with zlib support");
+  } else if (hdr->ch_type == ELFCOMPRESS_ZSTD) {
+    if (!compression::CompressionKind::ZStd->supported())
+      error(toString(this) + " is compressed with ELFCOMPRESS_ZSTD, but lld is "
+                             "not built with zstd support");
   } else {
     error(toString(this) + ": unsupported compression type (" +
           Twine(hdr->ch_type) + ")");
@@ -1231,6 +1247,17 @@
           fatal(toString(this) +
                 ": uncompress failed: " + llvm::toString(std::move(e)));
       }
+    } else if (hdr->ch_type == ELFCOMPRESS_ZSTD) {
+      if (!compression::CompressionKind::ZStd->supported()) {
+        error(toString(this) +
+              " is compressed with ELFCOMPRESS_ZSTD, but lld is "
+              "not built with zstd support");
+      } else {
+        if (Error e = compression::CompressionKind::ZStd->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) + ")");
Index: lld/ELF/Driver.cpp
===================================================================
--- lld/ELF/Driver.cpp
+++ lld/ELF/Driver.cpp
@@ -959,6 +959,9 @@
   } else if (s == "zlib") {
     if (!compression::CompressionKind::Zlib)
       error("--compress-debug-sections: zlib is not available");
+  } else if (s == "zstd") {
+    if (!compression::CompressionKind::ZStd->supported())
+      error("--compress-debug-sections: zstd is not available");
   } else {
     error("unknown --compress-debug-sections value: " + s);
   }
Index: compiler-rt/test/profile/instrprof-gc-sections.c
===================================================================
--- compiler-rt/test/profile/instrprof-gc-sections.c
+++ compiler-rt/test/profile/instrprof-gc-sections.c
@@ -1,7 +1,7 @@
 // REQUIRES: linux, lld-available
 
 // RUN: rm -rf %t.profraw
-// RUN: %clang_profgen=%t.profraw -fuse-ld=lld -fcoverage-mapping -mllvm -enable-name-compression=false -DCODE=1 -ffunction-sections -fdata-sections -Wl,--gc-sections -o %t %s
+// RUN: %clang_profgen=%t.profraw -fuse-ld=lld -fcoverage-mapping -mllvm -name-compression=none -DCODE=1 -ffunction-sections -fdata-sections -Wl,--gc-sections -o %t %s
 // RUN: %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: llvm-profdata show --all-functions %t.profdata | FileCheck %s -check-prefix=PROF
@@ -11,7 +11,7 @@
 // RUN: llvm-size -A %t | FileCheck %s -check-prefix=PRF_CNTS
 
 // RUN: rm -rf %t.lto.profraw
-// RUN: %clang_lto_profgen=%t.lto.profraw -fuse-ld=lld -fcoverage-mapping -mllvm -enable-name-compression=false -DCODE=1 -ffunction-sections -fdata-sections -Wl,--gc-sections -flto -o %t.lto %s
+// RUN: %clang_lto_profgen=%t.lto.profraw -fuse-ld=lld -fcoverage-mapping -mllvm -name-compression=none -DCODE=1 -ffunction-sections -fdata-sections -Wl,--gc-sections -flto -o %t.lto %s
 // RUN: %run %t.lto
 // RUN: llvm-profdata merge -o %t.lto.profdata %t.lto.profraw
 // RUN: llvm-profdata show --all-functions %t.lto.profdata | FileCheck %s -check-prefix=PROF
Index: compiler-rt/test/profile/instrprof-darwin-dead-strip.c
===================================================================
--- compiler-rt/test/profile/instrprof-darwin-dead-strip.c
+++ compiler-rt/test/profile/instrprof-darwin-dead-strip.c
@@ -1,7 +1,7 @@
 // REQUIRES: osx-ld64-live_support
 // REQUIRES: lto
 
-// RUN: %clang_profgen=%t.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -DCODE=1 -Wl,-dead_strip -o %t %s
+// RUN: %clang_profgen=%t.profraw -fcoverage-mapping -mllvm -name-compression=none -DCODE=1 -Wl,-dead_strip -o %t %s
 // RUN: %run %t
 // RUN: llvm-profdata merge -o %t.profdata %t.profraw
 // RUN: llvm-profdata show --all-functions %t.profdata | FileCheck %s -check-prefix=PROF
@@ -10,7 +10,7 @@
 // RUN: otool -V -s __DATA __llvm_prf_names %t | FileCheck %s -check-prefix=PRF_NAMES
 // RUN: otool -V -s __DATA __llvm_prf_cnts %t | FileCheck %s -check-prefix=PRF_CNTS
 
-// RUN: %clang_lto_profgen=%t.lto.profraw -fcoverage-mapping -mllvm -enable-name-compression=false -DCODE=1 -Wl,-dead_strip -flto -o %t.lto %s
+// RUN: %clang_lto_profgen=%t.lto.profraw -fcoverage-mapping -mllvm -name-compression=none -DCODE=1 -Wl,-dead_strip -flto -o %t.lto %s
 // RUN: %run %t.lto
 // RUN: llvm-profdata merge -o %t.lto.profdata %t.lto.profraw
 // RUN: llvm-profdata show --all-functions %t.lto.profdata | FileCheck %s -check-prefix=PROF
Index: compiler-rt/include/profile/InstrProfData.inc
===================================================================
--- compiler-rt/include/profile/InstrProfData.inc
+++ compiler-rt/include/profile/InstrProfData.inc
@@ -648,11 +648,11 @@
 
 /* FIXME: Please remedy the fixme in the header before bumping the version. */
 /* Raw profile format version (start from 1). */
-#define INSTR_PROF_RAW_VERSION 8
+#define INSTR_PROF_RAW_VERSION 9
 /* Indexed profile format version (start from 1). */
-#define INSTR_PROF_INDEX_VERSION 8
+#define INSTR_PROF_INDEX_VERSION 9
 /* Coverage mapping format version (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 5
+#define INSTR_PROF_COVMAP_VERSION 6
 
 /* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
  * version for other variants of profile. We set the lowest bit of the upper 8
Index: clang/test/Profile/coverage-prefix-map.c
===================================================================
--- clang/test/Profile/coverage-prefix-map.c
+++ clang/test/Profile/coverage-prefix-map.c
@@ -5,17 +5,17 @@
 // RUN: echo "void f1(void) {}" > %t/root/nested/coverage-prefix-map.c
 // RUN: cd %t/root
 
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -enable-name-compression=false -main-file-name coverage-prefix-map.c %t/root/nested/coverage-prefix-map.c -o - | FileCheck --check-prefix=ABSOLUTE %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -name-compression=none -main-file-name coverage-prefix-map.c %t/root/nested/coverage-prefix-map.c -o - | FileCheck --check-prefix=ABSOLUTE %s
 //
 // ABSOLUTE: @__llvm_coverage_mapping = {{.*"\\02.*root.*nested.*coverage-prefix-map\.c}}
 
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -enable-name-compression=false -main-file-name coverage-prefix-map.c ../root/nested/coverage-prefix-map.c -o - | FileCheck --check-prefix=RELATIVE %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -name-compression=none -main-file-name coverage-prefix-map.c ../root/nested/coverage-prefix-map.c -o - | FileCheck --check-prefix=RELATIVE %s
 //
 // RELATIVE: @__llvm_coverage_mapping = {{.*"\\02.*}}..{{/|\\+}}root{{/|\\+}}nested{{.*coverage-prefix-map\.c}}
 
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -enable-name-compression=false -main-file-name coverage-prefix-map.c %t/root/nested/coverage-prefix-map.c -fcoverage-prefix-map=%/t/root=. -o - | FileCheck --check-prefix=COVERAGE-PREFIX-MAP %s
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -enable-name-compression=false -main-file-name coverage-prefix-map.c ../root/nested/coverage-prefix-map.c -fcoverage-prefix-map=../root=. -o - | FileCheck --check-prefix=COVERAGE-PREFIX-MAP %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -name-compression=none -main-file-name coverage-prefix-map.c %t/root/nested/coverage-prefix-map.c -fcoverage-prefix-map=%/t/root=. -o - | FileCheck --check-prefix=COVERAGE-PREFIX-MAP %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -name-compression=none -main-file-name coverage-prefix-map.c ../root/nested/coverage-prefix-map.c -fcoverage-prefix-map=../root=. -o - | FileCheck --check-prefix=COVERAGE-PREFIX-MAP %s
 // COVERAGE-PREFIX-MAP: @__llvm_coverage_mapping = {{.*"\\02.*}}.{{/|\\+}}nested{{.*coverage-prefix-map\.c}}
 
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -enable-name-compression=false -main-file-name coverage-prefix-map.c %t/root/nested/coverage-prefix-map.c -fcoverage-compilation-dir=/custom -fcoverage-prefix-map=/custom=/nonsense -o - | FileCheck --check-prefix=COVERAGE-COMPILATION-DIR %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -emit-llvm -mllvm -name-compression=none -main-file-name coverage-prefix-map.c %t/root/nested/coverage-prefix-map.c -fcoverage-compilation-dir=/custom -fcoverage-prefix-map=/custom=/nonsense -o - | FileCheck --check-prefix=COVERAGE-COMPILATION-DIR %s
 // COVERAGE-COMPILATION-DIR: @__llvm_coverage_mapping = {{.*"\\02.*}}nonsense
Index: clang/test/CoverageMapping/ir.c
===================================================================
--- clang/test/CoverageMapping/ir.c
+++ clang/test/CoverageMapping/ir.c
@@ -1,7 +1,7 @@
 // Check the data structures emitted by coverage mapping
-// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -triple x86_64-apple-macosx10.9 -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -no-opaque-pointers | FileCheck %s -check-prefixes=COMMON,DARWIN
-// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -triple x86_64-apple-macosx10.9 -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -opaque-pointers | FileCheck %s -check-prefixes=COMMON,DARWIN
-// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -triple x86_64--windows-msvc -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false | FileCheck %s -check-prefixes=COMMON,WINDOWS
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -triple x86_64-apple-macosx10.9 -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -name-compression=none -no-opaque-pointers | FileCheck %s -check-prefixes=COMMON,DARWIN
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -triple x86_64-apple-macosx10.9 -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -name-compression=none -opaque-pointers | FileCheck %s -check-prefixes=COMMON,DARWIN
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -triple x86_64--windows-msvc -main-file-name ir.c %s -o - -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -mllvm -name-compression=none | FileCheck %s -check-prefixes=COMMON,WINDOWS
 
 static inline void unused(void) {}
 
Index: clang/test/CoverageMapping/abspath.cpp
===================================================================
--- clang/test/CoverageMapping/abspath.cpp
+++ clang/test/CoverageMapping/abspath.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -emit-llvm -main-file-name abspath.cpp %S/Inputs/../abspath.cpp -o - | FileCheck -check-prefix=RMDOTS %s
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -mllvm -name-compression=none -emit-llvm -main-file-name abspath.cpp %S/Inputs/../abspath.cpp -o - | FileCheck -check-prefix=RMDOTS %s
 
 // RMDOTS: @__llvm_coverage_mapping = {{.*}}"\02
 // RMDOTS-NOT: Inputs
@@ -6,7 +6,7 @@
 
 // RUN: mkdir -p %t/test && cd %t/test
 // RUN: echo "void f1(void) {}" > f1.c
-// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -emit-llvm -main-file-name abspath.cpp %t/test/f1.c -o - | FileCheck -check-prefix=ABSPATH %s
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -fprofile-instrument=clang -fcoverage-mapping -mllvm -name-compression=none -emit-llvm -main-file-name abspath.cpp %t/test/f1.c -o - | FileCheck -check-prefix=ABSPATH %s
 
 // RELPATH: @__llvm_coverage_mapping = {{.*}}"\02
 // RELPATH: {{..(/|\\\\)test(/|\\\\)f1}}.c
Index: clang/test/CodeGen/coverage-compilation-dir.c
===================================================================
--- clang/test/CodeGen/coverage-compilation-dir.c
+++ clang/test/CodeGen/coverage-compilation-dir.c
@@ -1,6 +1,6 @@
 // RUN: mkdir -p %t.dir && cd %t.dir
 // RUN: cp %s rel.c
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-compilation-dir=/nonsense -fcoverage-mapping -emit-llvm -mllvm -enable-name-compression=false rel.c -o - | FileCheck -check-prefix=CHECK-NONSENSE %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-compilation-dir=/nonsense -fcoverage-mapping -emit-llvm -mllvm -name-compression=none rel.c -o - | FileCheck -check-prefix=CHECK-NONSENSE %s
 
 // CHECK-NONSENSE: nonsense
 
Index: clang/lib/Serialization/GeneratePCH.cpp
===================================================================
--- clang/lib/Serialization/GeneratePCH.cpp
+++ clang/lib/Serialization/GeneratePCH.cpp
@@ -17,6 +17,7 @@
 #include "clang/Sema/SemaConsumer.h"
 #include "clang/Serialization/ASTWriter.h"
 #include "llvm/Bitstream/BitstreamWriter.h"
+#include "llvm/Support/Compression.h"
 
 using namespace clang;
 
@@ -29,7 +30,7 @@
     : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
       SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
       Writer(Stream, this->Buffer->Data, ModuleCache, Extensions,
-             IncludeTimestamps),
+             llvm::compression::ZlibCompression, IncludeTimestamps),
       AllowASTWithErrors(AllowASTWithErrors),
       ShouldCacheASTInMemory(ShouldCacheASTInMemory),
       OutputPathIndependent(OutputPathIndependent) {
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -866,6 +866,7 @@
   RECORD(SM_SLOC_BUFFER_BLOB);
   RECORD(SM_SLOC_BUFFER_BLOB_COMPRESSED);
   RECORD(SM_SLOC_EXPANSION_ENTRY);
+  RECORD(SM_SLOC_BUFFER_BLOB_COMPRESSED_DYNAMIC);
 
   // Preprocessor Block.
   BLOCK(PREPROCESSOR_BLOCK);
@@ -1693,14 +1694,21 @@
 /// Create an abbreviation for the SLocEntry that refers to a
 /// buffer's blob.
 static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream,
-                                           bool Compressed) {
+                                           bool Compressed,
+                                           bool CompressedDynamic) {
   using namespace llvm;
 
   auto Abbrev = std::make_shared<BitCodeAbbrev>();
-  Abbrev->Add(BitCodeAbbrevOp(Compressed ? SM_SLOC_BUFFER_BLOB_COMPRESSED
-                                         : SM_SLOC_BUFFER_BLOB));
-  if (Compressed)
+  Abbrev->Add(BitCodeAbbrevOp(CompressedDynamic
+                                  ? SM_SLOC_BUFFER_BLOB_COMPRESSED_DYNAMIC
+                                  : (Compressed ? SM_SLOC_BUFFER_BLOB_COMPRESSED
+                                                : SM_SLOC_BUFFER_BLOB)));
+
+  if (Compressed || CompressedDynamic)
     Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Uncompressed size
+  if (CompressedDynamic) {
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Compression Scheme
+  }
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
   return Stream.EmitAbbrev(std::move(Abbrev));
 }
@@ -1992,15 +2000,16 @@
     free(const_cast<char *>(SavedStrings[I]));
 }
 
-static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
-                     unsigned SLocBufferBlobCompressedAbbrv,
-                     unsigned SLocBufferBlobAbbrv) {
+static void
+emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
+         unsigned SLocBufferBlobCompressedAbbrv,
+         unsigned SLocBufferBlobCompressedDynamicAbbrv,
+         unsigned SLocBufferBlobAbbrv,
+         llvm::compression::OptionalCompressionKind OptionalCompressionScheme) {
   using RecordDataType = ASTWriter::RecordData::value_type;
 
   // Compress the buffer if possible. We expect that almost all PCM
   // consumers will not want its contents.
-  llvm::compression::OptionalCompressionKind OptionalCompressionScheme =
-      llvm::compression::CompressionKind::Zlib;
 
   OptionalCompressionScheme =
       compression::noneIfUnsupported(OptionalCompressionScheme);
@@ -2011,8 +2020,19 @@
 
     CompressionScheme->compress(llvm::arrayRefFromStringRef(Blob.drop_back(1)),
                                 CompressedBuffer);
-    RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, Blob.size() - 1};
-    Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
+    // if our chosen CompressionAlgorithm happens to be zlib output old format
+    // for extra back compat
+    if (CompressionScheme == llvm::compression::CompressionKind::Zlib) {
+
+      RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED,
+                                 Blob.size() - 1};
+      Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
+                                llvm::toStringRef(CompressedBuffer));
+      return;
+    }
+    RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED_DYNAMIC,
+                               Blob.size() - 1, uint8_t(CompressionScheme)};
+    Stream.EmitRecordWithBlob(SLocBufferBlobCompressedDynamicAbbrv, Record,
                               llvm::toStringRef(CompressedBuffer));
     return;
   }
@@ -2040,9 +2060,12 @@
   // Abbreviations for the various kinds of source-location entries.
   unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
   unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
-  unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream, false);
+  unsigned SLocBufferBlobAbbrv =
+      CreateSLocBufferBlobAbbrev(Stream, false, false);
   unsigned SLocBufferBlobCompressedAbbrv =
-      CreateSLocBufferBlobAbbrev(Stream, true);
+      CreateSLocBufferBlobAbbrev(Stream, true, false);
+  unsigned SLocBufferBlobCompressedDynamicAbbrv =
+      CreateSLocBufferBlobAbbrev(Stream, true, true);
   unsigned SLocExpansionAbbrv = CreateSLocExpansionAbbrev(Stream);
 
   // Write out the source location entry table. We skip the first
@@ -2142,7 +2165,8 @@
           Buffer = llvm::MemoryBufferRef("<<<INVALID BUFFER>>>", "");
         StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1);
         emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv,
-                 SLocBufferBlobAbbrv);
+                 SLocBufferBlobCompressedDynamicAbbrv, SLocBufferBlobAbbrv,
+                 CompressionScheme);
       }
     } else {
       // The source location entry is a macro expansion.
@@ -4464,12 +4488,14 @@
   SelectorOffsets[ID - FirstSelectorID] = Offset;
 }
 
-ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
-                     SmallVectorImpl<char> &Buffer,
-                     InMemoryModuleCache &ModuleCache,
-                     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
-                     bool IncludeTimestamps)
+ASTWriter::ASTWriter(
+    llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
+    InMemoryModuleCache &ModuleCache,
+    ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+    llvm::compression::OptionalCompressionKind OptionalCompressionScheme,
+    bool IncludeTimestamps)
     : Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache),
+      CompressionScheme(CompressionScheme),
       IncludeTimestamps(IncludeTimestamps) {
   for (const auto &Ext : Extensions) {
     if (auto Writer = Ext->createExtensionWriter(*this))
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -1461,8 +1461,12 @@
     }
     unsigned RecCode = MaybeRecCode.get();
 
-    if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
-      uint8_t CompressionSchemeId = llvm::compression::CompressionKind::Zlib;
+    if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED ||
+        RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED_DYNAMIC) {
+      uint8_t CompressionSchemeId =
+          RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED
+              ? uint8_t(llvm::compression::CompressionKind::Zlib)
+              : Record[1];
       llvm::compression::OptionalCompressionKind OptionalCompressionScheme =
           llvm::compression::getOptionalCompressionKind(CompressionSchemeId);
       if (!OptionalCompressionScheme) {
@@ -1484,6 +1488,7 @@
       }
       return llvm::MemoryBuffer::getMemBufferCopy(
           llvm::toStringRef(Uncompressed), Name);
+
     } else if (RecCode == SM_SLOC_BUFFER_BLOB) {
       return llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name, true);
     } else {
Index: clang/lib/Frontend/ASTUnit.cpp
===================================================================
--- clang/lib/Frontend/ASTUnit.cpp
+++ clang/lib/Frontend/ASTUnit.cpp
@@ -80,6 +80,7 @@
 #include "llvm/Bitstream/BitstreamWriter.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/DJB.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -221,7 +222,8 @@
   ASTWriter Writer;
 
   ASTWriterData(InMemoryModuleCache &ModuleCache)
-      : Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {}
+      : Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {},
+                               llvm::compression::ZlibCompression) {}
 };
 
 void ASTUnit::clearFileLevelDecls() {
@@ -2323,7 +2325,8 @@
   SmallString<128> Buffer;
   llvm::BitstreamWriter Stream(Buffer);
   InMemoryModuleCache ModuleCache;
-  ASTWriter Writer(Stream, Buffer, ModuleCache, {});
+  ASTWriter Writer(Stream, Buffer, ModuleCache, {},
+                   llvm::compression::ZlibCompression);
   return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
 }
 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1145,6 +1145,13 @@
       } else {
         D.Diag(diag::warn_debug_compression_unavailable);
       }
+    } else if (Value == "zstd") {
+      if (llvm::compression::CompressionKind::ZStd->supported()) {
+        CmdArgs.push_back(
+            Args.MakeArgString("--compress-debug-sections=" + Twine(Value)));
+      } else {
+        D.Diag(diag::warn_debug_compression_unavailable);
+      }
     } else {
       D.Diag(diag::err_drv_unsupported_option_argument)
           << A->getOption().getName() << Value;
Index: clang/lib/CodeGen/CoverageMappingGen.cpp
===================================================================
--- clang/lib/CodeGen/CoverageMappingGen.cpp
+++ clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -24,6 +24,7 @@
 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
 #include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
@@ -1704,7 +1705,8 @@
   std::string Filenames;
   {
     llvm::raw_string_ostream OS(Filenames);
-    CoverageFilenamesSectionWriter(FilenameStrs).write(OS);
+    CoverageFilenamesSectionWriter(FilenameStrs)
+        .write(OS, llvm::compression::ZlibCompression);
   }
   auto *FilenamesVal =
       llvm::ConstantDataArray::getString(Ctx, Filenames, false);
Index: clang/include/clang/Serialization/ASTWriter.h
===================================================================
--- clang/include/clang/Serialization/ASTWriter.h
+++ clang/include/clang/Serialization/ASTWriter.h
@@ -35,6 +35,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Bitstream/BitstreamWriter.h"
+#include "llvm/Support/Compression.h"
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
@@ -93,6 +94,7 @@
   using RecordDataRef = ArrayRef<uint64_t>;
 
 private:
+  llvm::compression::OptionalCompressionKind OptionalCompressionScheme;
   /// Map that provides the ID numbers of each type within the
   /// output stream, plus those deserialized from a chained PCH.
   ///
@@ -538,10 +540,12 @@
 public:
   /// Create a new precompiled header writer that outputs to
   /// the given bitstream.
-  ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
-            InMemoryModuleCache &ModuleCache,
-            ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
-            bool IncludeTimestamps = true);
+  ASTWriter(
+      llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
+      InMemoryModuleCache &ModuleCache,
+      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+      llvm::compression::OptionalCompressionKind OptionalCompressionScheme,
+      bool IncludeTimestamps = true);
   ~ASTWriter() override;
 
   ASTContext &getASTContext() const {
Index: clang/include/clang/Serialization/ASTBitCodes.h
===================================================================
--- clang/include/clang/Serialization/ASTBitCodes.h
+++ clang/include/clang/Serialization/ASTBitCodes.h
@@ -726,7 +726,12 @@
 
   /// Describes a source location entry (SLocEntry) for a
   /// macro expansion.
-  SM_SLOC_EXPANSION_ENTRY = 5
+  SM_SLOC_EXPANSION_ENTRY = 5,
+
+  /// Describes a compressed blob that contains the data for
+  /// a buffer entry with a size header (like SM_SLOC_BUFFER_BLOB_COMPRESSED)
+  /// but also a part in the record to indicate which compression algorithm.
+  SM_SLOC_BUFFER_BLOB_COMPRESSED_DYNAMIC = 6,
 };
 
 /// Record types used within a preprocessor block.
Index: clang-tools-extra/clangd/index/Serialization.h
===================================================================
--- clang-tools-extra/clangd/index/Serialization.h
+++ clang-tools-extra/clangd/index/Serialization.h
@@ -28,11 +28,14 @@
 #include "index/Index.h"
 #include "index/Symbol.h"
 #include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/Error.h"
 
 namespace clang {
 namespace clangd {
 
+extern llvm::compression::OptionalCompressionKind StringTableCompressionScheme;
+
 enum class IndexFileFormat {
   RIFF, // Versioned binary format, suitable for production use.
   YAML, // Human-readable format, suitable for experiments and debugging.
Index: clang-tools-extra/clangd/index/Serialization.cpp
===================================================================
--- clang-tools-extra/clangd/index/Serialization.cpp
+++ clang-tools-extra/clangd/index/Serialization.cpp
@@ -28,6 +28,10 @@
 
 namespace clang {
 namespace clangd {
+
+llvm::compression::OptionalCompressionKind StringTableCompressionScheme =
+    llvm::compression::CompressionKind::Zlib;
+
 namespace {
 
 // IO PRIMITIVES
@@ -192,9 +196,7 @@
       RawTable.push_back(0);
     }
     llvm::compression::OptionalCompressionKind OptionalCompressionScheme =
-        llvm::compression::CompressionKind::Zlib;
-    OptionalCompressionScheme =
-        compression::noneIfUnsupported(OptionalCompressionScheme);
+        compression::noneIfUnsupported(StringTableCompressionScheme);
     if (OptionalCompressionScheme) {
       llvm::compression::CompressionKind CompressionScheme =
           *OptionalCompressionScheme;
@@ -232,28 +234,34 @@
   if (UncompressedSize == 0) // No compression
     Uncompressed = R.rest();
   else {
-    llvm::compression::CompressionKind CompressionScheme =
-        llvm::compression::CompressionKind::Zlib;
-    if (CompressionScheme) {
-      // 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 ((CompressionScheme == llvm::compression::CompressionKind::Zlib) &&
-          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->Name + " is unavailable").str());
+    llvm::compression::OptionalCompressionKind OptionalCompressionScheme =
+        StringTableCompressionScheme;
+    if (!OptionalCompressionScheme) {
+      Uncompressed = R.rest();
+    } else {
+      llvm::compression::CompressionKind CompressionScheme =
+          *OptionalCompressionScheme;
+      if (CompressionScheme) {
+        // 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 ((CompressionScheme == llvm::compression::CompressionKind::Zlib) &&
+            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->Name + " is unavailable").str());
   }
 
   StringTableIn Table;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D130667: feat: use co... Cole Kissane via Phabricator via cfe-commits

Reply via email to