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

Merge remote-tracking branch 'origin/main' into ckissane.compression-class

[MC] fix merge issues with removal of GNU compression

Merge remote-tracking branch 'origin/main' into ckissane.compression-class

feat: compression class + clang ast serial zstd option + zstd elf + ztsd 
objcopy support

[MC] fix merge issues with removal of GNU compression

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

fix compression class inheritence and passing + elf zstd support + ast writer 
and profiledata have configurable compression + command line opt compression 
support (see usage in InstrProf.cpp)

update usages of -enable-name-compression=false to be -name-compression=none

do not exit on parse of bad compression cl::opt

Merge remote-tracking branch 'origin/main' into ckissane.compression-class

fix compression class usage in some profile data tests

tiny cleanup of using NoneCompressionAlgorithm::AlgorithmId

Merge remote-tracking branch 'origin/ckissane.compression-class-simple' into 
ckissane.compression-class


Repository:
  rG LLVM Github Monorepo

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, new compression::ZlibCompressionAlgorithm());
     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,11 @@
     {
       raw_string_ostream OS(EncodedFilenames);
       CoverageFilenamesSectionWriter Writer(Paths);
-      Writer.write(OS, Compress);
+      Writer.write(
+          OS, Compress ? (compression::CompressionAlgorithm
+                              *)new compression::ZlibCompressionAlgorithm()
+                       : (compression::CompressionAlgorithm
+                              *)new compression::NoneCompressionAlgorithm());
     }
 
     std::vector<std::string> ReadFilenames;
@@ -956,7 +960,11 @@
     {
       raw_string_ostream OS(EncodedFilenames);
       CoverageFilenamesSectionWriter Writer(Paths);
-      Writer.write(OS, Compress);
+      Writer.write(
+          OS, Compress ? (compression::CompressionAlgorithm
+                              *)new compression::ZlibCompressionAlgorithm()
+                       : (compression::CompressionAlgorithm
+                              *)new compression::NoneCompressionAlgorithm());
     }
 
     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,9 @@
 }
 
 void ProfileGeneratorBase::write() {
-  auto WriterOrErr = SampleProfileWriter::create(OutputFilename, OutputFormat);
+  auto WriterOrErr =
+      SampleProfileWriter::create(OutputFilename, OutputFormat,
+                                  new compression::ZlibCompressionAlgorithm());
   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],
+                                  new compression::ZlibCompressionAlgorithm());
   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::ZStdCompressionAlgorithm().supported())
+        return createStringError(
+            errc::invalid_argument,
+            "LLVM was not compiled with LLVM_ENABLE_ZSTD: can not compress");
+      break;
     }
   }
 
@@ -999,12 +1007,6 @@
         "--decompress-debug-sections");
   }
 
-  if (Config.DecompressDebugSections &&
-      !compression::ZlibCompressionAlgorithm().supported())
-    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::ZlibCompressionAlgorithm().supported()) {
-      WithColor::error(errs(), ProgName)
-          << "build tools with zlib to enable -compress-debug-sections";
-      return 1;
+    if (CompressDebugSections == DebugCompressionType::Z) {
+      if (!compression::ZlibCompressionAlgorithm().supported()) {
+        WithColor::error(errs(), ProgName)
+            << "build tools with zlib to enable -compress-debug-sections=zlib";
+        return 1;
+      }
+    } else if (CompressDebugSections == DebugCompressionType::ZStd) {
+      if (!compression::ZStdCompressionAlgorithm().supported()) {
+        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::CompressionAlgorithm *>;
 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::CompressionAlgorithm *>;
 } // namespace cl
 } // namespace llvm
 
@@ -95,6 +99,7 @@
 void parser<float>::anchor() {}
 void parser<std::string>::anchor() {}
 void parser<char>::anchor() {}
+void parser<compression::CompressionAlgorithm *>::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,34 @@
                  "' is invalid value for boolean argument! Try 0 or 1");
 }
 
+// parser<compression::CompressionAlgorithm *> implementation
+//
+bool parser<compression::CompressionAlgorithm *>::parse(
+    Option &O, StringRef, StringRef Arg,
+    compression::CompressionAlgorithm *&Value) {
+  Value = llvm::StringSwitch<compression::CompressionAlgorithm *>(Arg.str())
+              .Case("none", new compression::NoneCompressionAlgorithm())
+              .Case("zlib", new compression::ZlibCompressionAlgorithm())
+              .Case("zstd", new compression::ZStdCompressionAlgorithm())
+              .Default(new compression::UnknownCompressionAlgorithm());
+  if (Value->getAlgorithmId() ==
+      compression::UnknownCompressionAlgorithm::AlgorithmId) {
+
+    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 +2196,7 @@
 PRINT_OPT_DIFF(unsigned long long)
 PRINT_OPT_DIFF(double)
 PRINT_OPT_DIFF(float)
+PRINT_OPT_DIFF(compression::CompressionAlgorithm *)
 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,8 +78,6 @@
 }
 
 std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() {
-  compression::CompressionAlgorithm *CompressionScheme =
-      new compression::ZlibCompressionAlgorithm();
   if (!CompressionScheme->supported())
     return sampleprof_error::zlib_unavailable;
   std::string &UncompressedStrings =
@@ -93,6 +91,7 @@
                               CompressionScheme->getBestSizeLevel());
   encodeULEB128(UncompressedStrings.size(), OS);
   encodeULEB128(CompressedStrings.size(), OS);
+  encodeULEB128(static_cast<uint8_t>(CompressionScheme->getAlgorithmId()), OS);
   OS << toStringRef(CompressedStrings);
   UncompressedStrings.clear();
   return sampleprof_error::success;
@@ -842,8 +841,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::CompressionAlgorithm *CompressionScheme) {
   std::error_code EC;
   std::unique_ptr<raw_ostream> OS;
   if (Format == SPF_Binary || Format == SPF_Ext_Binary ||
@@ -854,7 +854,7 @@
   if (EC)
     return EC;
 
-  return create(OS, Format);
+  return create(OS, Format, CompressionScheme);
 }
 
 /// Create a sample profile stream writer based on the specified format.
@@ -864,9 +864,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::CompressionAlgorithm *CompressionScheme) {
   std::error_code EC;
   std::unique_ptr<SampleProfileWriter> Writer;
 
@@ -876,13 +876,13 @@
     return sampleprof_error::unsupported_writing_format;
 
   if (Format == SPF_Binary)
-    Writer.reset(new SampleProfileWriterRawBinary(OS));
+    Writer.reset(new SampleProfileWriterRawBinary(OS, CompressionScheme));
   else if (Format == SPF_Ext_Binary)
-    Writer.reset(new SampleProfileWriterExtBinary(OS));
+    Writer.reset(new SampleProfileWriterExtBinary(OS, CompressionScheme));
   else if (Format == SPF_Compact_Binary)
-    Writer.reset(new SampleProfileWriterCompactBinary(OS));
+    Writer.reset(new SampleProfileWriterCompactBinary(OS, CompressionScheme));
   else if (Format == SPF_Text)
-    Writer.reset(new SampleProfileWriterText(OS));
+    Writer.reset(new SampleProfileWriterText(OS, CompressionScheme));
   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,12 +877,18 @@
   if (std::error_code EC = CompressSize.getError())
     return EC;
 
-  if (!llvm::compression::ZlibCompressionAlgorithm().supported())
+  auto CompressionSchemeId = readNumber<uint64_t>();
+  if (std::error_code EC = CompressionSchemeId.getError())
+    return EC;
+
+  compression::CompressionAlgorithm *CompressionScheme =
+      compression::CompressionAlgorithmFromId(*CompressionSchemeId);
+  if (!CompressionScheme->supported())
     return sampleprof_error::zlib_unavailable;
 
   uint8_t *Buffer = Allocator.Allocate<uint8_t>(DecompressBufSize);
   size_t UCSize = DecompressBufSize;
-  llvm::Error E = compression::ZlibCompressionAlgorithm().decompress(
+  llvm::Error E = CompressionScheme->decompress(
       makeArrayRef(Data, *CompressSize), Buffer, UCSize);
   if (E)
     return sampleprof_error::uncompress_failed;
Index: llvm/lib/ProfileData/InstrProf.cpp
===================================================================
--- llvm/lib/ProfileData/InstrProf.cpp
+++ llvm/lib/ProfileData/InstrProf.cpp
@@ -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::CompressionAlgorithm *> InstrProfNameCompressionScheme(
+    "name-compression",
+    cl::desc("Scheme for name/filename string compression (none/zlib/ztsd), "
+             "defaults to zstd"),
+    cl::init(new compression::ZStdCompressionAlgorithm()));
 
 std::string getInstrProfSectionName(InstrProfSectKind IPSK,
                                     Triple::ObjectFormatType OF,
@@ -451,18 +453,34 @@
   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,
+          compression::SupportCompressionType 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(static_cast<uint8_t>(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 (!CompressionScheme->notNone())
-    return WriteStringToResult(0, UncompressedNameStrings);
+    return WriteStringToResult(0, compression::SupportCompressionType::None,
+                               UncompressedNameStrings);
 
   SmallVector<uint8_t, 128> CompressedNameStrings;
   CompressionScheme->compress(arrayRefFromStringRef(UncompressedNameStrings),
@@ -470,6 +488,7 @@
                               CompressionScheme->getBestSizeLevel());
 
   return WriteStringToResult(CompressedNameStrings.size(),
+                             CompressionScheme->getAlgorithmId(),
                              toStringRef(CompressedNameStrings));
 }
 
@@ -480,17 +499,15 @@
   return NameStr;
 }
 
-Error collectPGOFuncNameStrings(ArrayRef<GlobalVariable *> NameVars,
-                                std::string &Result, bool doCompression) {
+Error collectPGOFuncNameStrings(
+    ArrayRef<GlobalVariable *> NameVars, std::string &Result,
+    compression::CompressionAlgorithm *CompressionScheme) {
   std::vector<std::string> NameStrs;
   for (auto *NameVar : NameVars) {
     NameStrs.push_back(std::string(getPGOFuncNameVarInitializer(NameVar)));
   }
-  compression::CompressionAlgorithm *CompressionScheme =
-      new compression::ZlibCompressionAlgorithm();
-  return collectPGOFuncNameStrings(
-      NameStrs, CompressionScheme->when(doCompression)->whenSupported(),
-      Result);
+  return collectPGOFuncNameStrings(NameStrs, CompressionScheme->whenSupported(),
+                                   Result);
 }
 
 Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) {
@@ -503,11 +520,17 @@
     uint64_t CompressedSize = decodeULEB128(P, &N);
     P += N;
     bool isCompressed = (CompressedSize != 0);
+    compression::CompressionAlgorithm *CompressionScheme =
+        new compression::NoneCompressionAlgorithm();
+    if (isCompressed) {
+      uint64_t CompressionSchemeId = decodeULEB128(P, &N);
+      P += N;
+      CompressionScheme =
+          compression::CompressionAlgorithmFromId(CompressionSchemeId);
+    }
     SmallVector<uint8_t, 128> UncompressedNameStrings;
     StringRef NameStrings;
     if (isCompressed) {
-      compression::CompressionAlgorithm *CompressionScheme =
-          new compression::ZlibCompressionAlgorithm();
       if (!CompressionScheme->supported())
         return make_error<InstrProfError>(instrprof_error::zlib_unavailable);
 
@@ -1349,7 +1372,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:
@@ -1368,7 +1391,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
@@ -36,7 +36,8 @@
 #endif
 }
 
-void CoverageFilenamesSectionWriter::write(raw_ostream &OS, bool Compress) {
+void CoverageFilenamesSectionWriter::write(
+    raw_ostream &OS, compression::CompressionAlgorithm *CompressionScheme) {
   std::string FilenamesStr;
   {
     raw_string_ostream FilenamesOS{FilenamesStr};
@@ -47,12 +48,8 @@
   }
 
   SmallVector<uint8_t, 128> CompressedStr;
-  compression::CompressionAlgorithm *CompressionScheme =
-      new compression::ZlibCompressionAlgorithm();
 
-  CompressionScheme =
-      CompressionScheme->when(Compress && DoInstrProfNameCompression)
-          ->whenSupported();
+  CompressionScheme = CompressionScheme->whenSupported();
   bool doCompression = CompressionScheme->notNone();
 
   if (doCompression)
@@ -63,10 +60,15 @@
   // ::= <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(static_cast<uint8_t>(CompressionScheme->getAlgorithmId()),
+                  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,7 +119,16 @@
     return Err;
 
   if (CompressedLen > 0) {
-    if (!compression::ZlibCompressionAlgorithm().supported())
+    compression::CompressionAlgorithm *CompressionScheme =
+        new compression::ZlibCompressionAlgorithm();
+    if (Version >= CovMapVersion::Version7) {
+      uint64_t CompressionSchemeId;
+      if (auto Err = readULEB128(CompressionSchemeId))
+        return Err;
+      CompressionScheme =
+          compression::CompressionAlgorithmFromId(CompressionSchemeId);
+    }
+    if (!CompressionScheme->supported())
       return make_error<CoverageMapError>(
           coveragemap_error::decompression_failed);
 
@@ -129,7 +138,7 @@
     // Read compressed filenames.
     StringRef CompressedFilenames = Data.substr(0, CompressedLen);
     Data = Data.substr(CompressedLen);
-    auto Err = compression::ZlibCompressionAlgorithm().decompress(
+    auto Err = CompressionScheme->decompress(
         arrayRefFromStringRef(CompressedFilenames), StorageBuf,
         UncompressedLen);
     if (Err) {
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 = new compression::ZlibCompressionAlgorithm();
+  } else if (ELFCompressionSchemeId == ELFCOMPRESS_ZSTD) {
+    CompressionScheme = new compression::ZStdCompressionAlgorithm();
   } 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::ZStdCompressionAlgorithm().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;
@@ -532,6 +543,10 @@
     compression::ZlibCompressionAlgorithm().compress(OriginalData,
                                                      CompressedData);
     break;
+  case DebugCompressionType::ZStd:
+    compression::ZStdCompressionAlgorithm().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::ZlibCompressionAlgorithm().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::ZlibCompressionAlgorithm().compress(
+        makeArrayRef(reinterpret_cast<uint8_t *>(UncompressedData.data()),
+                     UncompressedData.size()),
+        Compressed);
+    break;
+  case DebugCompressionType::ZStd:
+    compression::ZStdCompressionAlgorithm().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::CompressionAlgorithm *CompressionScheme;
 };
 
 } // 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::CompressionAlgorithm *CompressionScheme;
+
   InstrProfOptions() = default;
 };
 
Index: llvm/include/llvm/Support/Compression.h
===================================================================
--- llvm/include/llvm/Support/Compression.h
+++ llvm/include/llvm/Support/Compression.h
@@ -33,6 +33,7 @@
 
 // This is the base class of all compression algorithms that llvm support
 // handles.
+
 class CompressionAlgorithm {
 public:
   virtual SupportCompressionType getAlgorithmId() = 0;
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::CompressionAlgorithm *>;
+
+template <>
+class parser<compression::CompressionAlgorithm *>
+    : public basic_parser<compression::CompressionAlgorithm *> {
+public:
+  parser(Option &O) : basic_parser(O) {}
+
+  // Return true on error.
+  bool parse(Option &, StringRef, StringRef Arg,
+             compression::CompressionAlgorithm *&Value);
+
+  // Overload in subclass to provide a better default value.
+  StringRef getValueName() const override { return "compression scheme"; }
+
+  void printOptionDiff(const Option &O, compression::CompressionAlgorithm *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::CompressionAlgorithm *CompressionScheme);
 
   /// 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::CompressionAlgorithm *CompressionScheme);
 
   virtual void setProfileSymbolList(ProfileSymbolList *PSL) {}
   virtual void setToCompressAllSections() {}
@@ -70,8 +73,9 @@
   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::CompressionAlgorithm *CompressionScheme)
+      : OutputStream(std::move(OS)), CompressionScheme(CompressionScheme) {}
 
   /// Write a file header for the profile file.
   virtual std::error_code writeHeader(const SampleProfileMap &ProfileMap) = 0;
@@ -90,6 +94,9 @@
 
   /// Profile format.
   SampleProfileFormat Format = SPF_None;
+
+  /// Compression scheme;
+  compression::CompressionAlgorithm *CompressionScheme;
 };
 
 /// Sample-based profile writer (text format).
@@ -98,8 +105,9 @@
   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::CompressionAlgorithm *CompressionScheme)
+      : SampleProfileWriter(OS, CompressionScheme), Indent(0) {}
 
   std::error_code writeHeader(const SampleProfileMap &ProfileMap) override {
     return sampleprof_error::success;
@@ -112,15 +120,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::CompressionAlgorithm *CompressionScheme);
 };
 
 /// 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::CompressionAlgorithm *CompressionScheme)
+      : SampleProfileWriter(OS, CompressionScheme) {}
 
   std::error_code writeSample(const FunctionSamples &S) override;
 
@@ -144,8 +155,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::CompressionAlgorithm *CompressionScheme);
 };
 
 class SampleProfileWriterRawBinary : public SampleProfileWriterBinary {
@@ -324,8 +336,10 @@
 
 class SampleProfileWriterExtBinary : public SampleProfileWriterExtBinaryBase {
 public:
-  SampleProfileWriterExtBinary(std::unique_ptr<raw_ostream> &OS)
-      : SampleProfileWriterExtBinaryBase(OS) {}
+  SampleProfileWriterExtBinary(
+      std::unique_ptr<raw_ostream> &OS,
+      compression::CompressionAlgorithm *CompressionScheme)
+      : SampleProfileWriterExtBinaryBase(OS, CompressionScheme) {}
 
 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
@@ -221,8 +221,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::CompressionAlgorithm *CompressionScheme);
 
 /// \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
@@ -1023,7 +1024,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;
@@ -1200,7 +1203,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::CompressionAlgorithm *>
+    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::CompressionAlgorithm *CompressionScheme);
 };
 
 /// 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
@@ -109,6 +109,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::ZlibCompressionAlgorithm().decompress(
+                           compressed, out, size)
+                     : compression::ZStdCompressionAlgorithm().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;
@@ -117,11 +133,7 @@
     std::lock_guard<std::mutex> lock(mu);
     uncompressedBuf = bAlloc().Allocate<uint8_t>(size);
   }
-
-  if (Error e = compression::ZlibCompressionAlgorithm().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;
 }
@@ -196,7 +208,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;
@@ -212,6 +224,10 @@
     if (!compression::ZlibCompressionAlgorithm().supported())
       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::ZStdCompressionAlgorithm().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) + ")");
@@ -1230,6 +1246,17 @@
           fatal(toString(this) +
                 ": uncompress failed: " + llvm::toString(std::move(e)));
       }
+    } else if (hdr->ch_type == ELFCOMPRESS_ZSTD) {
+      if (!compression::ZStdCompressionAlgorithm().supported()) {
+        error(toString(this) +
+              " is compressed with ELFCOMPRESS_ZSTD, but lld is "
+              "not built with zstd support");
+      } else {
+        if (Error e = compression::ZStdCompressionAlgorithm().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
@@ -958,6 +958,9 @@
   } else if (s == "zlib") {
     if (!compression::ZlibCompressionAlgorithm::Supported())
       error("--compress-debug-sections: zlib is not available");
+  } else if (s == "zstd") {
+    if (!compression::ZStdCompressionAlgorithm().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,6 +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,
+             new llvm::compression::ZlibCompressionAlgorithm(),
              IncludeTimestamps),
       AllowASTWithErrors(AllowASTWithErrors),
       ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
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);
@@ -1694,14 +1695,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));
 }
@@ -1993,15 +2001,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::CompressionAlgorithm *CompressionScheme) {
   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::CompressionAlgorithm *CompressionScheme =
-      new llvm::compression::ZlibCompressionAlgorithm();
 
   CompressionScheme = CompressionScheme->whenSupported();
   if (CompressionScheme->notNone()) {
@@ -2010,8 +2019,21 @@
 
     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->getAlgorithmId() ==
+        llvm::compression::SupportCompressionType::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,
+        static_cast<uint8_t>(CompressionScheme->getAlgorithmId())};
+    Stream.EmitRecordWithBlob(SLocBufferBlobCompressedDynamicAbbrv, Record,
                               llvm::toStringRef(CompressedBuffer));
     return;
   }
@@ -2039,9 +2061,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
@@ -2141,7 +2166,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.
@@ -4467,8 +4493,10 @@
                      SmallVectorImpl<char> &Buffer,
                      InMemoryModuleCache &ModuleCache,
                      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+                     llvm::compression::CompressionAlgorithm *CompressionScheme,
                      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,9 +1461,13 @@
     }
     unsigned RecCode = MaybeRecCode.get();
 
-    if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) {
-      uint8_t CompressionSchemeId = static_cast<uint8_t>(
-          llvm::compression::ZlibCompressionAlgorithm::AlgorithmId);
+    if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED ||
+        RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED_DYNAMIC) {
+      uint8_t CompressionSchemeId =
+          RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED
+              ? static_cast<uint8_t>(
+                    llvm::compression::SupportCompressionType::Zlib)
+              : Record[1];
       llvm::compression::CompressionAlgorithm *CompressionScheme =
           llvm::compression::CompressionAlgorithmFromId(CompressionSchemeId);
       if (!CompressionScheme->supported()) {
@@ -1480,6 +1484,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,9 @@
   ASTWriter Writer;
 
   ASTWriterData(InMemoryModuleCache &ModuleCache)
-      : Stream(Buffer), Writer(Stream, Buffer, ModuleCache, {}) {}
+      : Stream(Buffer),
+        Writer(Stream, Buffer, ModuleCache, {},
+               new llvm::compression::ZlibCompressionAlgorithm()) {}
 };
 
 void ASTUnit::clearFileLevelDecls() {
@@ -2323,7 +2326,8 @@
   SmallString<128> Buffer;
   llvm::BitstreamWriter Stream(Buffer);
   InMemoryModuleCache ModuleCache;
-  ASTWriter Writer(Stream, Buffer, ModuleCache, {});
+  ASTWriter Writer(Stream, Buffer, ModuleCache, {},
+                   new llvm::compression::ZlibCompressionAlgorithm());
   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::ZStdCompressionAlgorithm().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, new llvm::compression::ZlibCompressionAlgorithm());
   }
   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::CompressionAlgorithm *CompressionScheme;
   /// Map that provides the ID numbers of each type within the
   /// output stream, plus those deserialized from a chained PCH.
   ///
@@ -542,6 +544,7 @@
   ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
             InMemoryModuleCache &ModuleCache,
             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+            llvm::compression::CompressionAlgorithm *CompressionScheme,
             bool IncludeTimestamps = true);
   ~ASTWriter() override;
 
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::CompressionAlgorithm *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
@@ -27,6 +27,10 @@
 
 namespace clang {
 namespace clangd {
+
+llvm::compression::CompressionAlgorithm *StringTableCompressionScheme =
+    new llvm::compression::ZlibCompressionAlgorithm();
+
 namespace {
 
 // IO PRIMITIVES
@@ -191,7 +195,7 @@
       RawTable.push_back(0);
     }
     llvm::compression::CompressionAlgorithm *CompressionScheme =
-        new llvm::compression::ZlibCompressionAlgorithm();
+        StringTableCompressionScheme;
     CompressionScheme = CompressionScheme->whenSupported();
     if (CompressionScheme->notNone()) {
       llvm::SmallVector<uint8_t, 0> Compressed;
@@ -229,7 +233,7 @@
     Uncompressed = R.rest();
   else {
     llvm::compression::CompressionAlgorithm *CompressionScheme =
-        new llvm::compression::ZlibCompressionAlgorithm();
+        StringTableCompressionScheme;
     if (CompressionScheme->supported()) {
       // Don't allocate a massive buffer if UncompressedSize was corrupted
       // This is effective for sharded index, but not big monolithic ones, as
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to