Update clang to r339409.

Change-Id: I800772d2d838223be1f6b40d490c4591b937fca2
diff --git a/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMapping.h b/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMapping.h
index 5a4098c..94f8174 100644
--- a/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/StringRef.h"
@@ -206,7 +207,7 @@
     /// A CodeRegion associates some code with a counter
     CodeRegion,
 
-    /// An ExpansionRegion represents a file expansion region that associates 
+    /// An ExpansionRegion represents a file expansion region that associates
     /// a source range with the expansion of a virtual source file, such as
     /// for a macro instantiation or #include file.
     ExpansionRegion,
@@ -506,10 +507,9 @@
 /// This is the main interface to get coverage information, using a profile to
 /// fill out execution counts.
 class CoverageMapping {
-  StringSet<> FunctionNames;
+  DenseMap<size_t, DenseSet<size_t>> RecordProvenance;
   std::vector<FunctionRecord> Functions;
   std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
-  std::vector<std::pair<std::string, uint64_t>> FuncCounterMismatches;
 
   CoverageMapping() = default;
 
@@ -536,9 +536,7 @@
   ///
   /// This is a count of functions whose profile is out of date or otherwise
   /// can't be associated with any coverage information.
-  unsigned getMismatchedCount() const {
-    return FuncHashMismatches.size() + FuncCounterMismatches.size();
-  }
+  unsigned getMismatchedCount() const { return FuncHashMismatches.size(); }
 
   /// A hash mismatch occurs when a profile record for a symbol does not have
   /// the same hash as a coverage mapping record for the same symbol. This
@@ -548,14 +546,6 @@
     return FuncHashMismatches;
   }
 
-  /// A counter mismatch occurs when there is an error when evaluating the
-  /// counter expressions in a coverage mapping record. This returns a list of
-  /// counter mismatches, where each mismatch is a pair of the symbol name and
-  /// the number of valid evaluated counter expressions.
-  ArrayRef<std::pair<std::string, uint64_t>> getCounterMismatches() const {
-    return FuncCounterMismatches;
-  }
-
   /// Returns a lexicographically sorted, unique list of files that are
   /// covered.
   std::vector<StringRef> getUniqueSourceFiles() const;
diff --git a/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
index 633e515..c88c71a 100644
--- a/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
+++ b/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
@@ -32,7 +32,7 @@
 
 class CoverageMappingReader;
 
-/// \brief Coverage mapping information for a single function.
+/// Coverage mapping information for a single function.
 struct CoverageMappingRecord {
   StringRef FunctionName;
   uint64_t FunctionHash;
@@ -41,7 +41,7 @@
   ArrayRef<CounterMappingRegion> MappingRegions;
 };
 
-/// \brief A file format agnostic iterator over coverage mapping data.
+/// A file format agnostic iterator over coverage mapping data.
 class CoverageMappingIterator
     : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
   CoverageMappingReader *Reader;
@@ -101,7 +101,7 @@
   CoverageMappingIterator end() { return CoverageMappingIterator(); }
 };
 
-/// \brief Base class for the raw coverage mapping and filenames data readers.
+/// Base class for the raw coverage mapping and filenames data readers.
 class RawCoverageReader {
 protected:
   StringRef Data;
@@ -114,7 +114,7 @@
   Error readString(StringRef &Result);
 };
 
-/// \brief Reader for the raw coverage filenames.
+/// Reader for the raw coverage filenames.
 class RawCoverageFilenamesReader : public RawCoverageReader {
   std::vector<StringRef> &Filenames;
 
@@ -128,7 +128,7 @@
   Error read();
 };
 
-/// \brief Checks if the given coverage mapping data is exported for
+/// Checks if the given coverage mapping data is exported for
 /// an unused function.
 class RawCoverageMappingDummyChecker : public RawCoverageReader {
 public:
@@ -138,7 +138,7 @@
   Expected<bool> isDummy();
 };
 
-/// \brief Reader for the raw coverage mapping data.
+/// Reader for the raw coverage mapping data.
 class RawCoverageMappingReader : public RawCoverageReader {
   ArrayRef<StringRef> TranslationUnitFilenames;
   std::vector<StringRef> &Filenames;
@@ -169,7 +169,7 @@
                              unsigned InferredFileID, size_t NumFileIDs);
 };
 
-/// \brief Reader for the coverage mapping data that is emitted by the
+/// Reader for the coverage mapping data that is emitted by the
 /// frontend and stored in an object file.
 class BinaryCoverageReader : public CoverageMappingReader {
 public:
diff --git a/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h b/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
index b6f864a..86fb1bd 100644
--- a/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
+++ b/linux-x64/clang/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
@@ -25,7 +25,7 @@
 
 namespace coverage {
 
-/// \brief Writer of the filenames section for the instrumentation
+/// Writer of the filenames section for the instrumentation
 /// based code coverage.
 class CoverageFilenamesSectionWriter {
   ArrayRef<StringRef> Filenames;
@@ -34,11 +34,11 @@
   CoverageFilenamesSectionWriter(ArrayRef<StringRef> Filenames)
       : Filenames(Filenames) {}
 
-  /// \brief Write encoded filenames to the given output stream.
+  /// Write encoded filenames to the given output stream.
   void write(raw_ostream &OS);
 };
 
-/// \brief Writer for instrumentation based coverage mapping data.
+/// Writer for instrumentation based coverage mapping data.
 class CoverageMappingWriter {
   ArrayRef<unsigned> VirtualFileMapping;
   ArrayRef<CounterExpression> Expressions;
@@ -51,7 +51,7 @@
       : VirtualFileMapping(VirtualFileMapping), Expressions(Expressions),
         MappingRegions(MappingRegions) {}
 
-  /// \brief Write encoded coverage mapping data to the given output stream.
+  /// Write encoded coverage mapping data to the given output stream.
   void write(raw_ostream &OS);
 };
 
diff --git a/linux-x64/clang/include/llvm/ProfileData/GCOV.h b/linux-x64/clang/include/llvm/ProfileData/GCOV.h
index 497f80b..8500401 100644
--- a/linux-x64/clang/include/llvm/ProfileData/GCOV.h
+++ b/linux-x64/clang/include/llvm/ProfileData/GCOV.h
@@ -41,7 +41,7 @@
 
 enum GCOVVersion { V402, V404, V704 };
 
-/// \brief A struct for passing gcov options between functions.
+/// A struct for passing gcov options between functions.
 struct Options {
   Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N)
       : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
@@ -376,6 +376,7 @@
 };
 
 class FileInfo {
+protected:
   // It is unlikely--but possible--for multiple functions to be on the same
   // line.
   // Therefore this typedef allows LineData.Functions to store multiple
@@ -428,7 +429,7 @@
   void print(raw_ostream &OS, StringRef MainFilename, StringRef GCNOFile,
              StringRef GCDAFile);
 
-private:
+protected:
   std::string getCoveragePath(StringRef Filename, StringRef MainFilename);
   std::unique_ptr<raw_ostream> openCoveragePath(StringRef CoveragePath);
   void printFunctionSummary(raw_ostream &OS, const FunctionVector &Funcs) const;
diff --git a/linux-x64/clang/include/llvm/ProfileData/InstrProf.h b/linux-x64/clang/include/llvm/ProfileData/InstrProf.h
index 88ae0f0..206142b 100644
--- a/linux-x64/clang/include/llvm/ProfileData/InstrProf.h
+++ b/linux-x64/clang/include/llvm/ProfileData/InstrProf.h
@@ -544,9 +544,9 @@
 void InstrProfSymtab::finalizeSymtab() {
   if (Sorted)
     return;
-  std::sort(MD5NameMap.begin(), MD5NameMap.end(), less_first());
-  std::sort(MD5FuncMap.begin(), MD5FuncMap.end(), less_first());
-  std::sort(AddrToMD5Map.begin(), AddrToMD5Map.end(), less_first());
+  llvm::sort(MD5NameMap.begin(), MD5NameMap.end(), less_first());
+  llvm::sort(MD5FuncMap.begin(), MD5FuncMap.end(), less_first());
+  llvm::sort(AddrToMD5Map.begin(), AddrToMD5Map.end(), less_first());
   AddrToMD5Map.erase(std::unique(AddrToMD5Map.begin(), AddrToMD5Map.end()),
                      AddrToMD5Map.end());
   Sorted = true;
@@ -1021,7 +1021,7 @@
 // compiler-rt/lib/profile/InstrProfiling.h.
 // It should also match the synthesized type in
 // Transforms/Instrumentation/InstrProfiling.cpp:getOrCreateRegionCounters.
-template <class IntPtrT> struct LLVM_ALIGNAS(8) ProfileData {
+template <class IntPtrT> struct alignas(8) ProfileData {
   #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Type Name;
   #include "llvm/ProfileData/InstrProfData.inc"
 };
diff --git a/linux-x64/clang/include/llvm/ProfileData/InstrProfData.inc b/linux-x64/clang/include/llvm/ProfileData/InstrProfData.inc
index bac8cce..454620e 100644
--- a/linux-x64/clang/include/llvm/ProfileData/InstrProfData.inc
+++ b/linux-x64/clang/include/llvm/ProfileData/InstrProfData.inc
@@ -308,11 +308,11 @@
 
 #ifdef __cplusplus
   /*!
-   * \brief Return the number of value sites.
+   * Return the number of value sites.
    */
   uint32_t getNumValueSites() const { return NumValueSites; }
   /*!
-   * \brief Read data from this record and save it to Record.
+   * Read data from this record and save it to Record.
    */
   void deserializeTo(InstrProfRecord &Record,
                      InstrProfSymtab *SymTab);
@@ -458,7 +458,7 @@
 #endif
 
 /*!
- * \brief Return the \c ValueProfRecord header size including the
+ * Return the \c ValueProfRecord header size including the
  * padding bytes.
  */
 INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
@@ -471,7 +471,7 @@
 }
 
 /*!
- * \brief Return the total size of the value profile record including the
+ * Return the total size of the value profile record including the
  * header and the value data.
  */
 INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
@@ -482,7 +482,7 @@
 }
 
 /*!
- * \brief Return the pointer to the start of value data array.
+ * Return the pointer to the start of value data array.
  */
 INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
 InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) {
@@ -491,7 +491,7 @@
 }
 
 /*!
- * \brief Return the total number of value data for \c This record.
+ * Return the total number of value data for \c This record.
  */
 INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
 uint32_t getValueProfRecordNumValueData(ValueProfRecord *This) {
@@ -503,7 +503,7 @@
 }
 
 /*!
- * \brief Use this method to advance to the next \c This \c ValueProfRecord.
+ * Use this method to advance to the next \c This \c ValueProfRecord.
  */
 INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
 ValueProfRecord *getValueProfRecordNext(ValueProfRecord *This) {
@@ -514,7 +514,7 @@
 }
 
 /*!
- * \brief Return the first \c ValueProfRecord instance.
+ * Return the first \c ValueProfRecord instance.
  */
 INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
 ValueProfRecord *getFirstValueProfRecord(ValueProfData *This) {
diff --git a/linux-x64/clang/include/llvm/ProfileData/ProfileCommon.h b/linux-x64/clang/include/llvm/ProfileData/ProfileCommon.h
index 51b065b..087588f 100644
--- a/linux-x64/clang/include/llvm/ProfileData/ProfileCommon.h
+++ b/linux-x64/clang/include/llvm/ProfileData/ProfileCommon.h
@@ -61,7 +61,7 @@
   void computeDetailedSummary();
 
 public:
-  /// \brief A vector of useful cutoff values for detailed summary.
+  /// A vector of useful cutoff values for detailed summary.
   static const ArrayRef<uint32_t> DefaultCutoffs;
 };
 
diff --git a/linux-x64/clang/include/llvm/ProfileData/SampleProf.h b/linux-x64/clang/include/llvm/ProfileData/SampleProf.h
index d79ef3b..0cd6dd2 100644
--- a/linux-x64/clang/include/llvm/ProfileData/SampleProf.h
+++ b/linux-x64/clang/include/llvm/ProfileData/SampleProf.h
@@ -78,11 +78,29 @@
 namespace llvm {
 namespace sampleprof {
 
-static inline uint64_t SPMagic() {
+enum SampleProfileFormat {
+  SPF_None = 0,
+  SPF_Text = 0x1,
+  SPF_Compact_Binary = 0x2,
+  SPF_GCC = 0x3,
+  SPF_Binary = 0xff
+};
+
+static inline uint64_t SPMagic(SampleProfileFormat Format = SPF_Binary) {
   return uint64_t('S') << (64 - 8) | uint64_t('P') << (64 - 16) |
          uint64_t('R') << (64 - 24) | uint64_t('O') << (64 - 32) |
          uint64_t('F') << (64 - 40) | uint64_t('4') << (64 - 48) |
-         uint64_t('2') << (64 - 56) | uint64_t(0xff);
+         uint64_t('2') << (64 - 56) | uint64_t(Format);
+}
+
+// Get the proper representation of a string in the input Format.
+static inline StringRef getRepInFormat(StringRef Name,
+                                       SampleProfileFormat Format,
+                                       std::string &GUIDBuf) {
+  if (Name.empty())
+    return Name;
+  GUIDBuf = std::to_string(Function::getGUID(Name));
+  return (Format == SPF_Compact_Binary) ? StringRef(GUIDBuf) : Name;
 }
 
 static inline uint64_t SPVersion() { return 103; }
@@ -359,7 +377,7 @@
   /// GUID to \p S. Also traverse the BodySamples to add hot CallTarget's GUID
   /// to \p S.
   void findInlinedFunctions(DenseSet<GlobalValue::GUID> &S, const Module *M,
-                            uint64_t Threshold) const {
+                            uint64_t Threshold, bool isCompact) const {
     if (TotalSamples <= Threshold)
       return;
     S.insert(Function::getGUID(Name));
@@ -370,11 +388,12 @@
         if (TS.getValue() > Threshold) {
           Function *Callee = M->getFunction(TS.getKey());
           if (!Callee || !Callee->getSubprogram())
-            S.insert(Function::getGUID(TS.getKey()));
+            S.insert(isCompact ? std::stol(TS.getKey().data())
+                               : Function::getGUID(TS.getKey()));
         }
     for (const auto &CS : CallsiteSamples)
       for (const auto &NameFS : CS.second)
-        NameFS.second.findInlinedFunctions(S, M, Threshold);
+        NameFS.second.findInlinedFunctions(S, M, Threshold, isCompact);
   }
 
   /// Set the name of the function.
@@ -387,7 +406,7 @@
   /// We assume that a single function will not exceed 65535 LOC.
   static unsigned getOffset(const DILocation *DIL);
 
-  /// \brief Get the FunctionSamples of the inline instance where DIL originates
+  /// Get the FunctionSamples of the inline instance where DIL originates
   /// from.
   ///
   /// The FunctionSamples of the instruction (Machine or IR) associated to
diff --git a/linux-x64/clang/include/llvm/ProfileData/SampleProfReader.h b/linux-x64/clang/include/llvm/ProfileData/SampleProfReader.h
index 0e9ab2d..0617b05 100644
--- a/linux-x64/clang/include/llvm/ProfileData/SampleProfReader.h
+++ b/linux-x64/clang/include/llvm/ProfileData/SampleProfReader.h
@@ -235,7 +235,7 @@
 
 namespace sampleprof {
 
-/// \brief Sample-based profile reader.
+/// Sample-based profile reader.
 ///
 /// Each profile contains sample counts for all the functions
 /// executed. Inside each function, statements are annotated with the
@@ -264,105 +264,113 @@
 /// compact and I/O efficient. They can both be used interchangeably.
 class SampleProfileReader {
 public:
-  SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
-      : Profiles(0), Ctx(C), Buffer(std::move(B)) {}
+  SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C,
+                      SampleProfileFormat Format = SPF_None)
+      : Profiles(0), Ctx(C), Buffer(std::move(B)), Format(Format) {}
 
   virtual ~SampleProfileReader() = default;
 
-  /// \brief Read and validate the file header.
+  /// Read and validate the file header.
   virtual std::error_code readHeader() = 0;
 
-  /// \brief Read sample profiles from the associated file.
+  /// Read sample profiles from the associated file.
   virtual std::error_code read() = 0;
 
-  /// \brief Print the profile for \p FName on stream \p OS.
+  /// Print the profile for \p FName on stream \p OS.
   void dumpFunctionProfile(StringRef FName, raw_ostream &OS = dbgs());
 
-  /// \brief Print all the profiles on stream \p OS.
+  /// Print all the profiles on stream \p OS.
   void dump(raw_ostream &OS = dbgs());
 
-  /// \brief Return the samples collected for function \p F.
+  /// Return the samples collected for function \p F.
   FunctionSamples *getSamplesFor(const Function &F) {
     // The function name may have been updated by adding suffix. In sample
     // profile, the function names are all stripped, so we need to strip
     // the function name suffix before matching with profile.
-    if (Profiles.count(F.getName().split('.').first))
-      return &Profiles[(F.getName().split('.').first)];
+    StringRef Fname = F.getName().split('.').first;
+    std::string FGUID;
+    Fname = getRepInFormat(Fname, getFormat(), FGUID);
+    if (Profiles.count(Fname))
+      return &Profiles[Fname];
     return nullptr;
   }
 
-  /// \brief Return all the profiles.
+  /// Return all the profiles.
   StringMap<FunctionSamples> &getProfiles() { return Profiles; }
 
-  /// \brief Report a parse error message.
+  /// Report a parse error message.
   void reportError(int64_t LineNumber, Twine Msg) const {
     Ctx.diagnose(DiagnosticInfoSampleProfile(Buffer->getBufferIdentifier(),
                                              LineNumber, Msg));
   }
 
-  /// \brief Create a sample profile reader appropriate to the file format.
+  /// Create a sample profile reader appropriate to the file format.
   static ErrorOr<std::unique_ptr<SampleProfileReader>>
   create(const Twine &Filename, LLVMContext &C);
 
-  /// \brief Create a sample profile reader from the supplied memory buffer.
+  /// Create a sample profile reader from the supplied memory buffer.
   static ErrorOr<std::unique_ptr<SampleProfileReader>>
   create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C);
 
-  /// \brief Return the profile summary.
+  /// Return the profile summary.
   ProfileSummary &getSummary() { return *(Summary.get()); }
 
+  /// \brief Return the profile format.
+  SampleProfileFormat getFormat() { return Format; }
+
 protected:
-  /// \brief Map every function to its associated profile.
+  /// Map every function to its associated profile.
   ///
   /// The profile of every function executed at runtime is collected
   /// in the structure FunctionSamples. This maps function objects
   /// to their corresponding profiles.
   StringMap<FunctionSamples> Profiles;
 
-  /// \brief LLVM context used to emit diagnostics.
+  /// LLVM context used to emit diagnostics.
   LLVMContext &Ctx;
 
-  /// \brief Memory buffer holding the profile file.
+  /// Memory buffer holding the profile file.
   std::unique_ptr<MemoryBuffer> Buffer;
 
-  /// \brief Profile summary information.
+  /// Profile summary information.
   std::unique_ptr<ProfileSummary> Summary;
 
-  /// \brief Compute summary for this profile.
+  /// Compute summary for this profile.
   void computeSummary();
+
+  /// \brief The format of sample.
+  SampleProfileFormat Format = SPF_None;
 };
 
 class SampleProfileReaderText : public SampleProfileReader {
 public:
   SampleProfileReaderText(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
-      : SampleProfileReader(std::move(B), C) {}
+      : SampleProfileReader(std::move(B), C, SPF_Text) {}
 
-  /// \brief Read and validate the file header.
+  /// Read and validate the file header.
   std::error_code readHeader() override { return sampleprof_error::success; }
 
-  /// \brief Read sample profiles from the associated file.
+  /// Read sample profiles from the associated file.
   std::error_code read() override;
 
-  /// \brief Return true if \p Buffer is in the format supported by this class.
+  /// Return true if \p Buffer is in the format supported by this class.
   static bool hasFormat(const MemoryBuffer &Buffer);
 };
 
 class SampleProfileReaderBinary : public SampleProfileReader {
 public:
-  SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
-      : SampleProfileReader(std::move(B), C) {}
+  SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C,
+                            SampleProfileFormat Format = SPF_None)
+      : SampleProfileReader(std::move(B), C, Format) {}
 
-  /// \brief Read and validate the file header.
+  /// Read and validate the file header.
   std::error_code readHeader() override;
 
-  /// \brief Read sample profiles from the associated file.
+  /// Read sample profiles from the associated file.
   std::error_code read() override;
 
-  /// \brief Return true if \p Buffer is in the format supported by this class.
-  static bool hasFormat(const MemoryBuffer &Buffer);
-
 protected:
-  /// \brief Read a numeric value of type T from the profile.
+  /// Read a numeric value of type T from the profile.
   ///
   /// If an error occurs during decoding, a diagnostic message is emitted and
   /// EC is set.
@@ -370,7 +378,7 @@
   /// \returns the read value.
   template <typename T> ErrorOr<T> readNumber();
 
-  /// \brief Read a string from the profile.
+  /// Read a string from the profile.
   ///
   /// If an error occurs during decoding, a diagnostic message is emitted and
   /// EC is set.
@@ -378,29 +386,68 @@
   /// \returns the read value.
   ErrorOr<StringRef> readString();
 
-  /// Read a string indirectly via the name table.
-  ErrorOr<StringRef> readStringFromTable();
+  /// Read the string index and check whether it overflows the table.
+  template <typename T> inline ErrorOr<uint32_t> readStringIndex(T &Table);
 
-  /// \brief Return true if we've reached the end of file.
+  /// Return true if we've reached the end of file.
   bool at_eof() const { return Data >= End; }
 
   /// Read the contents of the given profile instance.
   std::error_code readProfile(FunctionSamples &FProfile);
 
-  /// \brief Points to the current location in the buffer.
+  /// Points to the current location in the buffer.
   const uint8_t *Data = nullptr;
 
-  /// \brief Points to the end of the buffer.
+  /// Points to the end of the buffer.
   const uint8_t *End = nullptr;
 
-  /// Function name table.
-  std::vector<StringRef> NameTable;
-
 private:
   std::error_code readSummaryEntry(std::vector<ProfileSummaryEntry> &Entries);
+  virtual std::error_code verifySPMagic(uint64_t Magic) = 0;
 
-  /// \brief Read profile summary.
+  /// Read profile summary.
   std::error_code readSummary();
+
+  /// Read the whole name table.
+  virtual std::error_code readNameTable() = 0;
+
+  /// Read a string indirectly via the name table.
+  virtual ErrorOr<StringRef> readStringFromTable() = 0;
+};
+
+class SampleProfileReaderRawBinary : public SampleProfileReaderBinary {
+private:
+  /// Function name table.
+  std::vector<StringRef> NameTable;
+  virtual std::error_code verifySPMagic(uint64_t Magic) override;
+  virtual std::error_code readNameTable() override;
+  /// Read a string indirectly via the name table.
+  virtual ErrorOr<StringRef> readStringFromTable() override;
+
+public:
+  SampleProfileReaderRawBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
+      : SampleProfileReaderBinary(std::move(B), C, SPF_Binary) {}
+
+  /// \brief Return true if \p Buffer is in the format supported by this class.
+  static bool hasFormat(const MemoryBuffer &Buffer);
+};
+
+class SampleProfileReaderCompactBinary : public SampleProfileReaderBinary {
+private:
+  /// Function name table.
+  std::vector<std::string> NameTable;
+  virtual std::error_code verifySPMagic(uint64_t Magic) override;
+  virtual std::error_code readNameTable() override;
+  /// Read a string indirectly via the name table.
+  virtual ErrorOr<StringRef> readStringFromTable() override;
+
+public:
+  SampleProfileReaderCompactBinary(std::unique_ptr<MemoryBuffer> B,
+                                   LLVMContext &C)
+      : SampleProfileReaderBinary(std::move(B), C, SPF_Compact_Binary) {}
+
+  /// \brief Return true if \p Buffer is in the format supported by this class.
+  static bool hasFormat(const MemoryBuffer &Buffer);
 };
 
 using InlineCallStack = SmallVector<FunctionSamples *, 10>;
@@ -421,15 +468,16 @@
 class SampleProfileReaderGCC : public SampleProfileReader {
 public:
   SampleProfileReaderGCC(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)
-      : SampleProfileReader(std::move(B), C), GcovBuffer(Buffer.get()) {}
+      : SampleProfileReader(std::move(B), C, SPF_GCC),
+        GcovBuffer(Buffer.get()) {}
 
-  /// \brief Read and validate the file header.
+  /// Read and validate the file header.
   std::error_code readHeader() override;
 
-  /// \brief Read sample profiles from the associated file.
+  /// Read sample profiles from the associated file.
   std::error_code read() override;
 
-  /// \brief Return true if \p Buffer is in the format supported by this class.
+  /// Return true if \p Buffer is in the format supported by this class.
   static bool hasFormat(const MemoryBuffer &Buffer);
 
 protected:
@@ -441,7 +489,7 @@
   template <typename T> ErrorOr<T> readNumber();
   ErrorOr<StringRef> readString();
 
-  /// \brief Read the section tag and check that it's the same as \p Expected.
+  /// Read the section tag and check that it's the same as \p Expected.
   std::error_code readSectionTag(uint32_t Expected);
 
   /// GCOV buffer containing the profile.
diff --git a/linux-x64/clang/include/llvm/ProfileData/SampleProfWriter.h b/linux-x64/clang/include/llvm/ProfileData/SampleProfWriter.h
index 86af103..74dc839 100644
--- a/linux-x64/clang/include/llvm/ProfileData/SampleProfWriter.h
+++ b/linux-x64/clang/include/llvm/ProfileData/SampleProfWriter.h
@@ -23,14 +23,13 @@
 #include <algorithm>
 #include <cstdint>
 #include <memory>
+#include <set>
 #include <system_error>
 
 namespace llvm {
 namespace sampleprof {
 
-enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC };
-
-/// \brief Sample-based profile writer. Base class.
+/// Sample-based profile writer. Base class.
 class SampleProfileWriter {
 public:
   virtual ~SampleProfileWriter() = default;
@@ -62,21 +61,21 @@
   SampleProfileWriter(std::unique_ptr<raw_ostream> &OS)
       : OutputStream(std::move(OS)) {}
 
-  /// \brief Write a file header for the profile file.
+  /// Write a file header for the profile file.
   virtual std::error_code
   writeHeader(const StringMap<FunctionSamples> &ProfileMap) = 0;
 
-  /// \brief Output stream where to emit the profile to.
+  /// Output stream where to emit the profile to.
   std::unique_ptr<raw_ostream> OutputStream;
 
-  /// \brief Profile summary.
+  /// Profile summary.
   std::unique_ptr<ProfileSummary> Summary;
 
-  /// \brief Compute summary for this profile.
+  /// Compute summary for this profile.
   void computeSummary(const StringMap<FunctionSamples> &ProfileMap);
 };
 
-/// \brief Sample-based profile writer (text format).
+/// Sample-based profile writer (text format).
 class SampleProfileWriterText : public SampleProfileWriter {
 public:
   std::error_code write(const FunctionSamples &S) override;
@@ -101,32 +100,49 @@
                               SampleProfileFormat Format);
 };
 
-/// \brief Sample-based profile writer (binary format).
+/// Sample-based profile writer (binary format).
 class SampleProfileWriterBinary : public SampleProfileWriter {
 public:
   std::error_code write(const FunctionSamples &S) override;
-
-protected:
   SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS)
       : SampleProfileWriter(OS) {}
 
-  std::error_code
-  writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
+protected:
+  virtual std::error_code writeNameTable() = 0;
+  virtual std::error_code writeMagicIdent() = 0;
+  std::error_code writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
   std::error_code writeSummary();
   std::error_code writeNameIdx(StringRef FName);
   std::error_code writeBody(const FunctionSamples &S);
+  inline void stablizeNameTable(std::set<StringRef> &V);
+
+  MapVector<StringRef, uint32_t> NameTable;
 
 private:
   void addName(StringRef FName);
   void addNames(const FunctionSamples &S);
 
-  MapVector<StringRef, uint32_t> NameTable;
-
   friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
   SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
                               SampleProfileFormat Format);
 };
 
+class SampleProfileWriterRawBinary : public SampleProfileWriterBinary {
+  using SampleProfileWriterBinary::SampleProfileWriterBinary;
+
+protected:
+  virtual std::error_code writeNameTable() override;
+  virtual std::error_code writeMagicIdent() override;
+};
+
+class SampleProfileWriterCompactBinary : public SampleProfileWriterBinary {
+  using SampleProfileWriterBinary::SampleProfileWriterBinary;
+
+protected:
+  virtual std::error_code writeNameTable() override;
+  virtual std::error_code writeMagicIdent() override;
+};
+
 } // end namespace sampleprof
 } // end namespace llvm