[llvm] 7531a50 - [Remarks] Extend the RemarkStreamer to support other emitters

Francis Visoiu Mistrih via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 4 17:19:38 PST 2020


Author: Francis Visoiu Mistrih
Date: 2020-02-04T17:16:02-08:00
New Revision: 7531a5039fd7ee9b48eb8a0d0770e8dfb9fa8bdf

URL: https://github.com/llvm/llvm-project/commit/7531a5039fd7ee9b48eb8a0d0770e8dfb9fa8bdf
DIFF: https://github.com/llvm/llvm-project/commit/7531a5039fd7ee9b48eb8a0d0770e8dfb9fa8bdf.diff

LOG: [Remarks] Extend the RemarkStreamer to support other emitters

This extends the RemarkStreamer to allow for other emitters (e.g.
frontends, SIL, etc.) to emit remarks through a common interface.

See changes in llvm/docs/Remarks.rst for motivation and design choices.

Differential Revision: https://reviews.llvm.org/D73676

Added: 
    llvm/include/llvm/IR/LLVMRemarkStreamer.h
    llvm/include/llvm/Remarks/RemarkStreamer.h
    llvm/lib/IR/LLVMRemarkStreamer.cpp
    llvm/lib/Remarks/RemarkStreamer.cpp

Modified: 
    clang/lib/CodeGen/CodeGenAction.cpp
    llvm/docs/Remarks.rst
    llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
    llvm/include/llvm/CodeGen/AsmPrinter.h
    llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
    llvm/include/llvm/IR/LLVMContext.h
    llvm/include/llvm/LTO/LTO.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/IR/CMakeLists.txt
    llvm/lib/IR/LLVMContext.cpp
    llvm/lib/IR/LLVMContextImpl.h
    llvm/lib/LTO/LTO.cpp
    llvm/lib/LTO/LTOBackend.cpp
    llvm/lib/LTO/LTOCodeGenerator.cpp
    llvm/lib/LTO/ThinLTOCodeGenerator.cpp
    llvm/lib/Remarks/CMakeLists.txt
    llvm/tools/llc/llc.cpp
    llvm/tools/opt/opt.cpp

Removed: 
    llvm/include/llvm/IR/RemarkStreamer.h
    llvm/lib/IR/RemarkStreamer.cpp


################################################################################
diff  --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index b89b080bb3eb..5ebc34cd2700 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -32,8 +32,8 @@
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/Module.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/Linker/Linker.h"
 #include "llvm/Pass.h"
@@ -86,15 +86,15 @@ namespace clang {
                                    const CodeGenOptions CodeGenOpts) {
     handleAllErrors(
         std::move(E),
-      [&](const RemarkSetupFileError &E) {
+      [&](const LLVMRemarkSetupFileError &E) {
           Diags.Report(diag::err_cannot_open_file)
               << CodeGenOpts.OptRecordFile << E.message();
         },
-      [&](const RemarkSetupPatternError &E) {
+      [&](const LLVMRemarkSetupPatternError &E) {
           Diags.Report(diag::err_drv_optimization_remark_pattern)
               << E.message() << CodeGenOpts.OptRecordPasses;
         },
-      [&](const RemarkSetupFormatError &E) {
+      [&](const LLVMRemarkSetupFormatError &E) {
           Diags.Report(diag::err_drv_optimization_remark_format)
               << CodeGenOpts.OptRecordFormat;
         });
@@ -309,7 +309,7 @@ namespace clang {
         CodeGenOpts, this));
 
       Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
-          setupOptimizationRemarks(
+          setupLLVMOptimizationRemarks(
               Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
               CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
               CodeGenOpts.DiagnosticsHotnessThreshold);
@@ -1150,7 +1150,7 @@ void CodeGenAction::ExecuteAction() {
         std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result));
 
     Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
-        setupOptimizationRemarks(
+        setupLLVMOptimizationRemarks(
             Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
             CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
             CodeGenOpts.DiagnosticsHotnessThreshold);

diff  --git a/llvm/docs/Remarks.rst b/llvm/docs/Remarks.rst
index 653b418e6fd2..b6cec12b326f 100644
--- a/llvm/docs/Remarks.rst
+++ b/llvm/docs/Remarks.rst
@@ -612,6 +612,38 @@ The typical usage through the C API is like the following:
     bool HasError = LLVMRemarkParserHasError(Parser);
     LLVMRemarkParserDispose(Parser);
 
+Remark streamers
+================
+
+The ``RemarkStreamer`` interface is used to unify the serialization
+capabilities of remarks across all the components that can generate remarks.
+
+All remark serialization should go through the main remark streamer, the
+``llvm::remarks::RemarkStreamer`` set up in the ``LLVMContext``. The interface
+takes remark objects converted to ``llvm::remarks::Remark``, and takes care of
+serializing it to the requested format, using the requested type of metadata,
+etc.
+
+Typically, a specialized remark streamer will hold a reference to the one set
+up in the ``LLVMContext``, and will operate on its own type of diagnostics.
+
+For example, LLVM IR passes will emit ``llvm::DiagnosticInfoOptimization*``
+that get converted to ``llvm::remarks::Remark`` objects.  Then, clang could set
+up its own specialized remark streamer that takes ``clang::Diagnostic``
+objects. This can allow various components of the frontend to emit remarks
+using the same techniques as the LLVM remarks.
+
+This gives us the following advantages:
+
+* Composition: during the compilation pipeline, multiple components can set up
+  their specialized remark streamers that all emit remarks through the same
+  main streamer.
+* Re-using the remark infrastructure in ``lib/Remarks``.
+* Using the same file and format for the remark emitters created throughout the
+  compilation.
+
+at the cost of an extra layer of abstraction.
+
 .. FIXME: add documentation for llvm-opt-report.
 .. FIXME: add documentation for Passes supporting optimization remarks
 .. FIXME: add documentation for IR Passes

diff  --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 7b8404404ce7..e2c50dd69e84 100644
--- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -77,7 +77,7 @@ class OptimizationRemarkEmitter {
     // remarks enabled. We can't currently check whether remarks are requested
     // for the calling pass since that requires actually building the remark.
 
-    if (F->getContext().getRemarkStreamer() ||
+    if (F->getContext().getLLVMRemarkStreamer() ||
         F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
       auto R = RemarkBuilder();
       emit((DiagnosticInfoOptimizationBase &)R);
@@ -92,7 +92,7 @@ class OptimizationRemarkEmitter {
   /// provide more context so that non-trivial false positives can be quickly
   /// detected by the user.
   bool allowExtraAnalysis(StringRef PassName) const {
-    return (F->getContext().getRemarkStreamer() ||
+    return (F->getContext().getLLVMRemarkStreamer() ||
             F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
   }
 

diff  --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 8add1a38f48a..a5c0925cc1d6 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -71,11 +71,14 @@ class MDNode;
 class Module;
 class ProfileSummaryInfo;
 class raw_ostream;
-class RemarkStreamer;
 class StackMaps;
 class TargetLoweringObjectFile;
 class TargetMachine;
 
+namespace remarks {
+class RemarkStreamer;
+};
+
 /// This class is intended to be used as a driving class for all asm writers.
 class AsmPrinter : public MachineFunctionPass {
 public:
@@ -337,7 +340,7 @@ class AsmPrinter : public MachineFunctionPass {
 
   void emitStackSizeSection(const MachineFunction &MF);
 
-  void emitRemarksSection(RemarkStreamer &RS);
+  void emitRemarksSection(remarks::RemarkStreamer &RS);
 
   enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
   CFIMoveType needsCFIMoves() const;

diff  --git a/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
index b2f8ad55fbd8..8cc5909c40b7 100644
--- a/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
@@ -159,7 +159,7 @@ class MachineOptimizationRemarkEmitter {
   /// that non-trivial false positives can be quickly detected by the user.
   bool allowExtraAnalysis(StringRef PassName) const {
     return (
-        MF.getFunction().getContext().getRemarkStreamer() ||
+        MF.getFunction().getContext().getLLVMRemarkStreamer() ||
         MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
             PassName));
   }
@@ -172,7 +172,7 @@ class MachineOptimizationRemarkEmitter {
     // remarks enabled. We can't currently check whether remarks are requested
     // for the calling pass since that requires actually building the remark.
 
-    if (MF.getFunction().getContext().getRemarkStreamer() ||
+    if (MF.getFunction().getContext().getLLVMRemarkStreamer() ||
         MF.getFunction()
             .getContext()
             .getDiagHandlerPtr()

diff  --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h
index 39d19b7cffd9..e93b1a4e517e 100644
--- a/llvm/include/llvm/IR/LLVMContext.h
+++ b/llvm/include/llvm/IR/LLVMContext.h
@@ -34,9 +34,13 @@ template <typename T> class SmallVectorImpl;
 class SMDiagnostic;
 class StringRef;
 class Twine;
-class RemarkStreamer;
+class LLVMRemarkStreamer;
 class raw_ostream;
 
+namespace remarks {
+class RemarkStreamer;
+};
+
 namespace SyncScope {
 
 typedef uint8_t ID;
@@ -218,23 +222,27 @@ class LLVMContext {
   /// included in optimization diagnostics.
   void setDiagnosticsHotnessThreshold(uint64_t Threshold);
 
-  /// Return the streamer used by the backend to save remark diagnostics. If it
-  /// does not exist, diagnostics are not saved in a file but only emitted via
-  /// the diagnostic handler.
-  RemarkStreamer *getRemarkStreamer();
-  const RemarkStreamer *getRemarkStreamer() const;
-
-  /// Set the diagnostics output used for optimization diagnostics.
-  /// This filename may be embedded in a section for tools to find the
-  /// diagnostics whenever they're needed.
+  /// The "main remark streamer" used by all the specialized remark streamers.
+  /// This streamer keeps generic remark metadata in memory throughout the life
+  /// of the LLVMContext. This metadata may be emitted in a section in object
+  /// files depending on the format requirements.
   ///
-  /// If a remark streamer is already set, it will be replaced with
-  /// \p RemarkStreamer.
+  /// All specialized remark streamers should convert remarks to
+  /// llvm::remarks::Remark and emit them through this streamer.
+  remarks::RemarkStreamer *getMainRemarkStreamer();
+  const remarks::RemarkStreamer *getMainRemarkStreamer() const;
+  void setMainRemarkStreamer(
+      std::unique_ptr<remarks::RemarkStreamer> LLVMRemarkStreamer);
+
+  /// The "LLVM remark streamer" used by LLVM to serialize remark diagnostics
+  /// comming from IR and MIR passes.
   ///
-  /// By default, diagnostics are not saved in a file but only emitted via the
-  /// diagnostic handler.  Even if an output file is set, the handler is invoked
-  /// for each diagnostic message.
-  void setRemarkStreamer(std::unique_ptr<RemarkStreamer> RemarkStreamer);
+  /// If it does not exist, diagnostics are not saved in a file but only emitted
+  /// via the diagnostic handler.
+  LLVMRemarkStreamer *getLLVMRemarkStreamer();
+  const LLVMRemarkStreamer *getLLVMRemarkStreamer() const;
+  void
+  setLLVMRemarkStreamer(std::unique_ptr<LLVMRemarkStreamer> LLVMRemarkStreamer);
 
   /// Get the prefix that should be printed in front of a diagnostic of
   ///        the given \p Severity

diff  --git a/llvm/include/llvm/IR/LLVMRemarkStreamer.h b/llvm/include/llvm/IR/LLVMRemarkStreamer.h
new file mode 100644
index 000000000000..97082a44e62f
--- /dev/null
+++ b/llvm/include/llvm/IR/LLVMRemarkStreamer.h
@@ -0,0 +1,95 @@
+//===- llvm/IR/LLVMRemarkStreamer.h - Streamer for LLVM remarks--*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the conversion between IR Diagnostics and
+// serializable remarks::Remark objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_LLVMREMARKSTREAMER_H
+#define LLVM_IR_LLVMREMARKSTREAMER_H
+
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/Remarks/RemarkStreamer.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+/// Streamer for LLVM remarks which has logic for dealing with DiagnosticInfo
+/// objects.
+class LLVMRemarkStreamer {
+  remarks::RemarkStreamer &RS;
+  /// Convert diagnostics into remark objects.
+  /// The lifetime of the members of the result is bound to the lifetime of
+  /// the LLVM diagnostics.
+  remarks::Remark toRemark(const DiagnosticInfoOptimizationBase &Diag) const;
+
+public:
+  LLVMRemarkStreamer(remarks::RemarkStreamer &RS) : RS(RS) {}
+  /// Emit a diagnostic through the streamer.
+  void emit(const DiagnosticInfoOptimizationBase &Diag);
+};
+
+template <typename ThisError>
+struct LLVMRemarkSetupErrorInfo : public ErrorInfo<ThisError> {
+  std::string Msg;
+  std::error_code EC;
+
+  LLVMRemarkSetupErrorInfo(Error E) {
+    handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) {
+      Msg = EIB.message();
+      EC = EIB.convertToErrorCode();
+    });
+  }
+
+  void log(raw_ostream &OS) const override { OS << Msg; }
+  std::error_code convertToErrorCode() const override { return EC; }
+};
+
+struct LLVMRemarkSetupFileError
+    : LLVMRemarkSetupErrorInfo<LLVMRemarkSetupFileError> {
+  static char ID;
+  using LLVMRemarkSetupErrorInfo<
+      LLVMRemarkSetupFileError>::LLVMRemarkSetupErrorInfo;
+};
+
+struct LLVMRemarkSetupPatternError
+    : LLVMRemarkSetupErrorInfo<LLVMRemarkSetupPatternError> {
+  static char ID;
+  using LLVMRemarkSetupErrorInfo<
+      LLVMRemarkSetupPatternError>::LLVMRemarkSetupErrorInfo;
+};
+
+struct LLVMRemarkSetupFormatError
+    : LLVMRemarkSetupErrorInfo<LLVMRemarkSetupFormatError> {
+  static char ID;
+  using LLVMRemarkSetupErrorInfo<
+      LLVMRemarkSetupFormatError>::LLVMRemarkSetupErrorInfo;
+};
+
+/// Setup optimization remarks that output to a file.
+Expected<std::unique_ptr<ToolOutputFile>>
+setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
+                             StringRef RemarksPasses, StringRef RemarksFormat,
+                             bool RemarksWithHotness,
+                             unsigned RemarksHotnessThreshold = 0);
+
+/// Setup optimization remarks that output directly to a raw_ostream.
+/// \p OS is managed by the caller and should be open for writing as long as \p
+/// Context is streaming remarks to it.
+Error setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
+                                   StringRef RemarksPasses,
+                                   StringRef RemarksFormat,
+                                   bool RemarksWithHotness,
+                                   unsigned RemarksHotnessThreshold = 0);
+
+} // end namespace llvm
+
+#endif // LLVM_IR_LLVMREMARKSTREAMER_H

diff  --git a/llvm/include/llvm/IR/RemarkStreamer.h b/llvm/include/llvm/IR/RemarkStreamer.h
deleted file mode 100644
index 9ea12e8389f0..000000000000
--- a/llvm/include/llvm/IR/RemarkStreamer.h
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- llvm/IR/RemarkStreamer.h - Remark Streamer ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the main interface for outputting remarks.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_REMARKSTREAMER_H
-#define LLVM_IR_REMARKSTREAMER_H
-
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/Remarks/RemarkSerializer.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-/// Streamer for remarks.
-class RemarkStreamer {
-  /// The regex used to filter remarks based on the passes that emit them.
-  Optional<Regex> PassFilter;
-  /// The object used to serialize the remarks to a specific format.
-  std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer;
-  /// The filename that the remark diagnostics are emitted to.
-  const Optional<std::string> Filename;
-
-  /// Convert diagnostics into remark objects.
-  /// The lifetime of the members of the result is bound to the lifetime of
-  /// the LLVM diagnostics.
-  remarks::Remark toRemark(const DiagnosticInfoOptimizationBase &Diag);
-
-public:
-  RemarkStreamer(std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer,
-                 Optional<StringRef> Filename = None);
-  /// Return the filename that the remark diagnostics are emitted to.
-  Optional<StringRef> getFilename() const {
-    return Filename ? Optional<StringRef>(*Filename) : None;
-  }
-  /// Return stream that the remark diagnostics are emitted to.
-  raw_ostream &getStream() { return RemarkSerializer->OS; }
-  /// Return the serializer used for this stream.
-  remarks::RemarkSerializer &getSerializer() { return *RemarkSerializer; }
-  /// Set a pass filter based on a regex \p Filter.
-  /// Returns an error if the regex is invalid.
-  Error setFilter(StringRef Filter);
-  /// Emit a diagnostic through the streamer.
-  void emit(const DiagnosticInfoOptimizationBase &Diag);
-  /// Check if the remarks also need to have associated metadata in a section.
-  bool needsSection() const;
-};
-
-template <typename ThisError>
-struct RemarkSetupErrorInfo : public ErrorInfo<ThisError> {
-  std::string Msg;
-  std::error_code EC;
-
-  RemarkSetupErrorInfo(Error E) {
-    handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) {
-      Msg = EIB.message();
-      EC = EIB.convertToErrorCode();
-    });
-  }
-
-  void log(raw_ostream &OS) const override { OS << Msg; }
-  std::error_code convertToErrorCode() const override { return EC; }
-};
-
-struct RemarkSetupFileError : RemarkSetupErrorInfo<RemarkSetupFileError> {
-  static char ID;
-  using RemarkSetupErrorInfo<RemarkSetupFileError>::RemarkSetupErrorInfo;
-};
-
-struct RemarkSetupPatternError : RemarkSetupErrorInfo<RemarkSetupPatternError> {
-  static char ID;
-  using RemarkSetupErrorInfo<RemarkSetupPatternError>::RemarkSetupErrorInfo;
-};
-
-struct RemarkSetupFormatError : RemarkSetupErrorInfo<RemarkSetupFormatError> {
-  static char ID;
-  using RemarkSetupErrorInfo<RemarkSetupFormatError>::RemarkSetupErrorInfo;
-};
-
-/// Setup optimization remarks that output to a file.
-Expected<std::unique_ptr<ToolOutputFile>>
-setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
-                         StringRef RemarksPasses, StringRef RemarksFormat,
-                         bool RemarksWithHotness,
-                         unsigned RemarksHotnessThreshold = 0);
-
-/// Setup optimization remarks that output directly to a raw_ostream.
-/// \p OS is managed by the caller and should be open for writing as long as \p
-/// Context is streaming remarks to it.
-Error setupOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
-                               StringRef RemarksPasses, StringRef RemarksFormat,
-                               bool RemarksWithHotness,
-                               unsigned RemarksHotnessThreshold = 0);
-
-} // end namespace llvm
-
-#endif // LLVM_IR_REMARKSTREAMER_H

diff  --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index aa21f963d3a8..e864e05df340 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -19,8 +19,8 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/ModuleSummaryIndex.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/LTO/Config.h"
 #include "llvm/Linker/IRMover.h"
 #include "llvm/Object/IRSymtab.h"
@@ -87,9 +87,9 @@ std::string getThinLTOOutputFile(const std::string &Path,
 
 /// Setup optimization remarks.
 Expected<std::unique_ptr<ToolOutputFile>>
-setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
-                         StringRef RemarksPasses, StringRef RemarksFormat,
-                         bool RemarksWithHotness, int Count = -1);
+setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
+                             StringRef RemarksPasses, StringRef RemarksFormat,
+                             bool RemarksWithHotness, int Count = -1);
 
 /// Setups the output file for saving statistics.
 Expected<std::unique_ptr<ToolOutputFile>>

diff  --git a/llvm/include/llvm/Remarks/RemarkStreamer.h b/llvm/include/llvm/Remarks/RemarkStreamer.h
new file mode 100644
index 000000000000..7741cb45b72c
--- /dev/null
+++ b/llvm/include/llvm/Remarks/RemarkStreamer.h
@@ -0,0 +1,73 @@
+//===- llvm/Remarks/RemarkStreamer.h ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the main interface for streaming remarks.
+//
+// This is used to stream any llvm::remarks::Remark to an open file taking
+// advantage of all the serialization capabilities developed for remarks (e.g.
+// metadata in a section, bitstream format, etc.).
+//
+// Typically, a specialized remark emitter should hold a reference to the main
+// remark streamer set up in the LLVMContext, and should convert specialized
+// diagnostics to llvm::remarks::Remark objects as they get emitted.
+//
+// Specialized remark emitters can be components like:
+// * Remarks from LLVM (M)IR passes
+// * Remarks from the frontend
+// * Remarks from an intermediate IR
+//
+// This allows for composition between specialized remark emitters throughout
+// the compilation pipeline, that end up in the same file, using the same format
+// and serialization techniques.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_REMARKS_REMARKSTREAMER_H
+#define LLVM_REMARKS_REMARKSTREAMER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Remarks/RemarkSerializer.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+namespace llvm {
+namespace remarks {
+class RemarkStreamer final {
+  /// The regex used to filter remarks based on the passes that emit them.
+  Optional<Regex> PassFilter;
+  /// The object used to serialize the remarks to a specific format.
+  std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer;
+  /// The filename that the remark diagnostics are emitted to.
+  const Optional<std::string> Filename;
+
+public:
+  RemarkStreamer(std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer,
+                 Optional<StringRef> Filename = None);
+
+  /// Return the filename that the remark diagnostics are emitted to.
+  Optional<StringRef> getFilename() const {
+    return Filename ? Optional<StringRef>(*Filename) : None;
+  }
+  /// Return stream that the remark diagnostics are emitted to.
+  raw_ostream &getStream() { return RemarkSerializer->OS; }
+  /// Return the serializer used for this stream.
+  remarks::RemarkSerializer &getSerializer() { return *RemarkSerializer; }
+  /// Set a pass filter based on a regex \p Filter.
+  /// Returns an error if the regex is invalid.
+  Error setFilter(StringRef Filter);
+  /// Check wether the string matches the filter.
+  bool matchesFilter(StringRef Str);
+  /// Check if the remarks also need to have associated metadata in a section.
+  bool needsSection() const;
+};
+} // end namespace remarks
+} // end namespace llvm
+
+#endif // LLVM_REMARKS_REMARKSTREAMER_H

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index cce61d800969..bb6d705c696e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -81,7 +81,6 @@
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Operator.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Value.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -106,6 +105,7 @@
 #include "llvm/Pass.h"
 #include "llvm/Remarks/Remark.h"
 #include "llvm/Remarks/RemarkFormat.h"
+#include "llvm/Remarks/RemarkStreamer.h"
 #include "llvm/Remarks/RemarkStringTable.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
@@ -1400,7 +1400,7 @@ void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
   }
 }
 
-void AsmPrinter::emitRemarksSection(RemarkStreamer &RS) {
+void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
   if (!RS.needsSection())
     return;
 
@@ -1462,7 +1462,7 @@ bool AsmPrinter::doFinalization(Module &M) {
   // Emit the remarks section contents.
   // FIXME: Figure out when is the safest time to emit this section. It should
   // not come after debug info.
-  if (RemarkStreamer *RS = M.getContext().getRemarkStreamer())
+  if (remarks::RemarkStreamer *RS = M.getContext().getMainRemarkStreamer())
     emitRemarksSection(*RS);
 
   const TargetLoweringObjectFile &TLOF = getObjFileLowering();

diff  --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 1a36acd8bbe1..8fcc10fa38af 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -30,6 +30,7 @@ add_llvm_component_library(LLVMCore
   IntrinsicInst.cpp
   LLVMContext.cpp
   LLVMContextImpl.cpp
+  LLVMRemarkStreamer.cpp
   LegacyPassManager.cpp
   MDBuilder.cpp
   Mangler.cpp
@@ -43,7 +44,6 @@ add_llvm_component_library(LLVMCore
   PassManager.cpp
   PassRegistry.cpp
   PassTimingInfo.cpp
-  RemarkStreamer.cpp
   SafepointIRVerifier.cpp
   ProfileSummary.cpp
   Statepoint.cpp

diff  --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index cb13b27aa50f..30b17ebdd7d5 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -19,9 +19,10 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
-#include "llvm/IR/RemarkStreamer.h"
+#include "llvm/Remarks/RemarkStreamer.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
@@ -142,15 +143,26 @@ uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
   return pImpl->DiagnosticsHotnessThreshold;
 }
 
-RemarkStreamer *LLVMContext::getRemarkStreamer() {
-  return pImpl->RemarkDiagStreamer.get();
+remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {
+  return pImpl->MainRemarkStreamer.get();
 }
-const RemarkStreamer *LLVMContext::getRemarkStreamer() const {
-  return const_cast<LLVMContext *>(this)->getRemarkStreamer();
+const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const {
+  return const_cast<LLVMContext *>(this)->getMainRemarkStreamer();
 }
-void LLVMContext::setRemarkStreamer(
-    std::unique_ptr<RemarkStreamer> RemarkStreamer) {
-  pImpl->RemarkDiagStreamer = std::move(RemarkStreamer);
+void LLVMContext::setMainRemarkStreamer(
+    std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {
+  pImpl->MainRemarkStreamer = std::move(RemarkStreamer);
+}
+
+LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() {
+  return pImpl->LLVMRemarkStreamer.get();
+}
+const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const {
+  return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();
+}
+void LLVMContext::setLLVMRemarkStreamer(
+    std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {
+  pImpl->LLVMRemarkStreamer = std::move(RemarkStreamer);
 }
 
 DiagnosticHandler::DiagnosticHandlerTy
@@ -214,7 +226,7 @@ LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
 
 void LLVMContext::diagnose(const DiagnosticInfo &DI) {
   if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
-    if (RemarkStreamer *RS = getRemarkStreamer())
+    if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer())
       RS->emit(*OptDiagBase);
 
   // If there is a report handler, use it.

diff  --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index bcdb50e4c326..c18ca4ac642c 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -35,8 +35,8 @@
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/Metadata.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IR/TrackingMDRef.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
@@ -1245,11 +1245,17 @@ class LLVMContextImpl {
   LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler = nullptr;
   void *InlineAsmDiagContext = nullptr;
 
+  /// The main remark streamer used by all the other streamers (e.g. IR, MIR,
+  /// frontends, etc.). This should only be used by the specific streamers, and
+  /// never directly.
+  std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer;
+
   std::unique_ptr<DiagnosticHandler> DiagHandler;
   bool RespectDiagnosticFilters = false;
   bool DiagnosticsHotnessRequested = false;
   uint64_t DiagnosticsHotnessThreshold = 0;
-  std::unique_ptr<RemarkStreamer> RemarkDiagStreamer;
+  /// The specialized remark streamer used by LLVM's OptimizationRemarkEmitter.
+  std::unique_ptr<LLVMRemarkStreamer> LLVMRemarkStreamer;
 
   LLVMContext::YieldCallbackTy YieldCallback = nullptr;
   void *YieldOpaqueHandle = nullptr;

diff  --git a/llvm/lib/IR/RemarkStreamer.cpp b/llvm/lib/IR/LLVMRemarkStreamer.cpp
similarity index 52%
rename from llvm/lib/IR/RemarkStreamer.cpp
rename to llvm/lib/IR/LLVMRemarkStreamer.cpp
index cdbcc4f456c5..326523eaa102 100644
--- a/llvm/lib/IR/RemarkStreamer.cpp
+++ b/llvm/lib/IR/LLVMRemarkStreamer.cpp
@@ -1,4 +1,4 @@
-//===- llvm/IR/RemarkStreamer.cpp - Remark Streamer -*- C++ -------------*-===//
+//===- llvm/IR/LLVMRemarkStreamer.cpp - Remark Streamer -*- C++ ---------*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,45 +6,18 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file contains the implementation of the remark outputting as part of
-// LLVMContext.
+// This file contains the implementation of the conversion between IR
+// Diagnostics and serializable remarks::Remark objects.
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/IR/RemarkStreamer.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalValue.h"
-#include "llvm/Remarks/BitstreamRemarkSerializer.h"
-#include "llvm/Remarks/RemarkFormat.h"
-#include "llvm/Remarks/RemarkSerializer.h"
-#include "llvm/Support/CommandLine.h"
 
 using namespace llvm;
 
-static cl::opt<cl::boolOrDefault> EnableRemarksSection(
-    "remarks-section",
-    cl::desc(
-        "Emit a section containing remark diagnostics metadata. By default, "
-        "this is enabled for the following formats: yaml-strtab, bitstream."),
-    cl::init(cl::BOU_UNSET), cl::Hidden);
-
-RemarkStreamer::RemarkStreamer(
-    std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer,
-    Optional<StringRef> FilenameIn)
-    : PassFilter(), RemarkSerializer(std::move(RemarkSerializer)),
-      Filename(FilenameIn ? Optional<std::string>(FilenameIn->str()) : None) {}
-
-Error RemarkStreamer::setFilter(StringRef Filter) {
-  Regex R = Regex(Filter);
-  std::string RegexError;
-  if (!R.isValid(RegexError))
-    return createStringError(std::make_error_code(std::errc::invalid_argument),
-                             RegexError.data());
-  PassFilter = std::move(R);
-  return Error::success();
-}
-
 /// DiagnosticKind -> remarks::Type
 static remarks::Type toRemarkType(enum DiagnosticKind Kind) {
   switch (Kind) {
@@ -81,7 +54,7 @@ toRemarkLocation(const DiagnosticLocation &DL) {
 
 /// LLVM Diagnostic -> Remark
 remarks::Remark
-RemarkStreamer::toRemark(const DiagnosticInfoOptimizationBase &Diag) {
+LLVMRemarkStreamer::toRemark(const DiagnosticInfoOptimizationBase &Diag) const {
   remarks::Remark R; // The result.
   R.RemarkType = toRemarkType(static_cast<DiagnosticKind>(Diag.getKind()));
   R.PassName = Diag.getPassName();
@@ -101,51 +74,24 @@ RemarkStreamer::toRemark(const DiagnosticInfoOptimizationBase &Diag) {
   return R;
 }
 
-void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) {
-  if (Optional<Regex> &Filter = PassFilter)
-    if (!Filter->match(Diag.getPassName()))
+void LLVMRemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) {
+  if (!RS.matchesFilter(Diag.getPassName()))
       return;
 
   // First, convert the diagnostic to a remark.
   remarks::Remark R = toRemark(Diag);
   // Then, emit the remark through the serializer.
-  RemarkSerializer->emit(R);
+  RS.getSerializer().emit(R);
 }
 
-bool RemarkStreamer::needsSection() const {
-  if (EnableRemarksSection == cl::BOU_TRUE)
-    return true;
-
-  if (EnableRemarksSection == cl::BOU_FALSE)
-    return false;
+char LLVMRemarkSetupFileError::ID = 0;
+char LLVMRemarkSetupPatternError::ID = 0;
+char LLVMRemarkSetupFormatError::ID = 0;
 
-  assert(EnableRemarksSection == cl::BOU_UNSET);
-
-  // We only need a section if we're in separate mode.
-  if (RemarkSerializer->Mode != remarks::SerializerMode::Separate)
-    return false;
-
-  // Only some formats need a section:
-  // * bitstream
-  // * yaml-strtab
-  switch (RemarkSerializer->SerializerFormat) {
-  case remarks::Format::YAMLStrTab:
-  case remarks::Format::Bitstream:
-    return true;
-  default:
-    return false;
-  }
-}
-
-char RemarkSetupFileError::ID = 0;
-char RemarkSetupPatternError::ID = 0;
-char RemarkSetupFormatError::ID = 0;
-
-Expected<std::unique_ptr<ToolOutputFile>>
-llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
-                               StringRef RemarksPasses, StringRef RemarksFormat,
-                               bool RemarksWithHotness,
-                               unsigned RemarksHotnessThreshold) {
+Expected<std::unique_ptr<ToolOutputFile>> llvm::setupLLVMOptimizationRemarks(
+    LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
+    StringRef RemarksFormat, bool RemarksWithHotness,
+    unsigned RemarksHotnessThreshold) {
   if (RemarksWithHotness)
     Context.setDiagnosticsHotnessRequested(true);
 
@@ -157,7 +103,7 @@ llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
 
   Expected<remarks::Format> Format = remarks::parseFormat(RemarksFormat);
   if (Error E = Format.takeError())
-    return make_error<RemarkSetupFormatError>(std::move(E));
+    return make_error<LLVMRemarkSetupFormatError>(std::move(E));
 
   std::error_code EC;
   auto Flags = *Format == remarks::Format::YAML ? sys::fs::OF_Text
@@ -167,29 +113,34 @@ llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
   // We don't use llvm::FileError here because some diagnostics want the file
   // name separately.
   if (EC)
-    return make_error<RemarkSetupFileError>(errorCodeToError(EC));
+    return make_error<LLVMRemarkSetupFileError>(errorCodeToError(EC));
 
   Expected<std::unique_ptr<remarks::RemarkSerializer>> RemarkSerializer =
       remarks::createRemarkSerializer(
           *Format, remarks::SerializerMode::Separate, RemarksFile->os());
   if (Error E = RemarkSerializer.takeError())
-    return make_error<RemarkSetupFormatError>(std::move(E));
+    return make_error<LLVMRemarkSetupFormatError>(std::move(E));
 
-  Context.setRemarkStreamer(std::make_unique<RemarkStreamer>(
+  // Create the main remark streamer.
+  Context.setMainRemarkStreamer(std::make_unique<remarks::RemarkStreamer>(
       std::move(*RemarkSerializer), RemarksFilename));
 
+  // Create LLVM's optimization remarks streamer.
+  Context.setLLVMRemarkStreamer(
+      std::make_unique<LLVMRemarkStreamer>(*Context.getMainRemarkStreamer()));
+
   if (!RemarksPasses.empty())
-    if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))
-      return make_error<RemarkSetupPatternError>(std::move(E));
+    if (Error E = Context.getMainRemarkStreamer()->setFilter(RemarksPasses))
+      return make_error<LLVMRemarkSetupPatternError>(std::move(E));
 
   return std::move(RemarksFile);
 }
 
-Error llvm::setupOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
-                                     StringRef RemarksPasses,
-                                     StringRef RemarksFormat,
-                                     bool RemarksWithHotness,
-                                     unsigned RemarksHotnessThreshold) {
+Error llvm::setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
+                                         StringRef RemarksPasses,
+                                         StringRef RemarksFormat,
+                                         bool RemarksWithHotness,
+                                         unsigned RemarksHotnessThreshold) {
   if (RemarksWithHotness)
     Context.setDiagnosticsHotnessRequested(true);
 
@@ -198,20 +149,25 @@ Error llvm::setupOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
 
   Expected<remarks::Format> Format = remarks::parseFormat(RemarksFormat);
   if (Error E = Format.takeError())
-    return make_error<RemarkSetupFormatError>(std::move(E));
+    return make_error<LLVMRemarkSetupFormatError>(std::move(E));
 
   Expected<std::unique_ptr<remarks::RemarkSerializer>> RemarkSerializer =
       remarks::createRemarkSerializer(*Format,
                                       remarks::SerializerMode::Separate, OS);
   if (Error E = RemarkSerializer.takeError())
-    return make_error<RemarkSetupFormatError>(std::move(E));
+    return make_error<LLVMRemarkSetupFormatError>(std::move(E));
+
+  // Create the main remark streamer.
+  Context.setMainRemarkStreamer(
+      std::make_unique<remarks::RemarkStreamer>(std::move(*RemarkSerializer)));
 
-  Context.setRemarkStreamer(
-      std::make_unique<RemarkStreamer>(std::move(*RemarkSerializer)));
+  // Create LLVM's optimization remarks streamer.
+  Context.setLLVMRemarkStreamer(
+      std::make_unique<LLVMRemarkStreamer>(*Context.getMainRemarkStreamer()));
 
   if (!RemarksPasses.empty())
-    if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))
-      return make_error<RemarkSetupPatternError>(std::move(E));
+    if (Error E = Context.getMainRemarkStreamer()->setFilter(RemarksPasses))
+      return make_error<LLVMRemarkSetupPatternError>(std::move(E));
 
   return Error::success();
 }

diff  --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 5029bd851b31..ea0e297c641f 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -22,10 +22,10 @@
 #include "llvm/IR/AutoUpgrade.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Mangler.h"
 #include "llvm/IR/Metadata.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/LTO/LTOBackend.h"
 #include "llvm/LTO/SummaryBasedOptimizations.h"
 #include "llvm/Linker/IRMover.h"
@@ -951,7 +951,7 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) {
 
 Error LTO::runRegularLTO(AddStreamFn AddStream) {
   // Setup optimization remarks.
-  auto DiagFileOrErr = lto::setupOptimizationRemarks(
+  auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
       RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename,
       Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness);
   if (!DiagFileOrErr)
@@ -1409,10 +1409,9 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
   return BackendProc->wait();
 }
 
-Expected<std::unique_ptr<ToolOutputFile>>
-lto::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
-                              StringRef RemarksPasses, StringRef RemarksFormat,
-                              bool RemarksWithHotness, int Count) {
+Expected<std::unique_ptr<ToolOutputFile>> lto::setupLLVMOptimizationRemarks(
+    LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
+    StringRef RemarksFormat, bool RemarksWithHotness, int Count) {
   std::string Filename = std::string(RemarksFilename);
   // For ThinLTO, file.opt.<format> becomes
   // file.opt.<format>.thin.<num>.<format>.
@@ -1421,7 +1420,7 @@ lto::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
         (Twine(Filename) + ".thin." + llvm::utostr(Count) + "." + RemarksFormat)
             .str();
 
-  auto ResultOrErr = llvm::setupOptimizationRemarks(
+  auto ResultOrErr = llvm::setupLLVMOptimizationRemarks(
       Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness);
   if (Error E = ResultOrErr.takeError())
     return std::move(E);

diff  --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 14ed0cc1836d..b85471555b09 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -20,9 +20,9 @@
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/PassManager.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/LTO/LTO.h"
 #include "llvm/MC/SubtargetFeature.h"
@@ -503,7 +503,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
   std::unique_ptr<TargetMachine> TM = createTargetMachine(Conf, *TOrErr, Mod);
 
   // Setup optimization remarks.
-  auto DiagFileOrErr = lto::setupOptimizationRemarks(
+  auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
       Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
       Conf.RemarksFormat, Conf.RemarksWithHotness, Task);
   if (!DiagFileOrErr)

diff  --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index bbc1f4040e90..a79a52311c27 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -29,11 +29,11 @@
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Mangler.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassTimingInfo.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/LTO/LTO.h"
@@ -527,8 +527,8 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
     return false;
 
   auto DiagFileOrErr =
-      lto::setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
-                                    RemarksFormat, RemarksWithHotness);
+      lto::setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
+                                        RemarksFormat, RemarksWithHotness);
   if (!DiagFileOrErr) {
     errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
     report_fatal_error("Can't get an output file for the remarks");

diff  --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 2fa1cddad596..a4f270240005 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -27,10 +27,10 @@
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Mangler.h"
 #include "llvm/IR/PassTimingInfo.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/LTO/LTO.h"
@@ -1079,7 +1079,7 @@ void ThinLTOCodeGenerator::run() {
         LLVMContext Context;
         Context.setDiscardValueNames(LTODiscardValueNames);
         Context.enableDebugTypeODRUniquing();
-        auto DiagFileOrErr = lto::setupOptimizationRemarks(
+        auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
             Context, RemarksFilename, RemarksPasses, RemarksFormat,
             RemarksWithHotness, count);
         if (!DiagFileOrErr) {

diff  --git a/llvm/lib/Remarks/CMakeLists.txt b/llvm/lib/Remarks/CMakeLists.txt
index c0e67f6ab951..c49d32197189 100644
--- a/llvm/lib/Remarks/CMakeLists.txt
+++ b/llvm/lib/Remarks/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMRemarks
   RemarkLinker.cpp
   RemarkParser.cpp
   RemarkSerializer.cpp
+  RemarkStreamer.cpp
   RemarkStringTable.cpp
   YAMLRemarkParser.cpp
   YAMLRemarkSerializer.cpp

diff  --git a/llvm/lib/Remarks/RemarkStreamer.cpp b/llvm/lib/Remarks/RemarkStreamer.cpp
new file mode 100644
index 000000000000..2f00b8e73670
--- /dev/null
+++ b/llvm/lib/Remarks/RemarkStreamer.cpp
@@ -0,0 +1,72 @@
+//===- llvm/Remarks/RemarkStreamer.cpp - Remark Streamer -*- C++ --------*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation of the main remark streamer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Remarks/RemarkStreamer.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+using namespace llvm::remarks;
+
+static cl::opt<cl::boolOrDefault> EnableRemarksSection(
+    "remarks-section",
+    cl::desc(
+        "Emit a section containing remark diagnostics metadata. By default, "
+        "this is enabled for the following formats: yaml-strtab, bitstream."),
+    cl::init(cl::BOU_UNSET), cl::Hidden);
+
+RemarkStreamer::RemarkStreamer(
+    std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer,
+    Optional<StringRef> FilenameIn)
+    : PassFilter(), RemarkSerializer(std::move(RemarkSerializer)),
+      Filename(FilenameIn ? Optional<std::string>(FilenameIn->str()) : None) {}
+
+Error RemarkStreamer::setFilter(StringRef Filter) {
+  Regex R = Regex(Filter);
+  std::string RegexError;
+  if (!R.isValid(RegexError))
+    return createStringError(std::make_error_code(std::errc::invalid_argument),
+                             RegexError.data());
+  PassFilter = std::move(R);
+  return Error::success();
+}
+
+bool RemarkStreamer::matchesFilter(StringRef Str) {
+  if (PassFilter)
+    return PassFilter->match(Str);
+  // No filter means all strings pass.
+  return true;
+}
+
+bool RemarkStreamer::needsSection() const {
+  if (EnableRemarksSection == cl::BOU_TRUE)
+    return true;
+
+  if (EnableRemarksSection == cl::BOU_FALSE)
+    return false;
+
+  assert(EnableRemarksSection == cl::BOU_UNSET);
+
+  // We only need a section if we're in separate mode.
+  if (RemarkSerializer->Mode != remarks::SerializerMode::Separate)
+    return false;
+
+  // Only some formats need a section:
+  // * bitstream
+  // * yaml-strtab
+  switch (RemarkSerializer->SerializerFormat) {
+  case remarks::Format::YAMLStrTab:
+  case remarks::Format::Bitstream:
+    return true;
+  default:
+    return false;
+  }
+}

diff  --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index 50942df302c5..66102f0d795f 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -29,9 +29,9 @@
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/InitializePasses.h"
@@ -334,9 +334,9 @@ int main(int argc, char **argv) {
   Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError);
 
   Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
-      setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
-                               RemarksFormat, RemarksWithHotness,
-                               RemarksHotnessThreshold);
+      setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
+                                   RemarksFormat, RemarksWithHotness,
+                                   RemarksHotnessThreshold);
   if (Error E = RemarksFileOrErr.takeError()) {
     WithColor::error(errs(), argv[0]) << toString(std::move(E)) << '\n';
     return 1;

diff  --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp
index 82cf47d9ebd6..6e1c5793cb9b 100644
--- a/llvm/tools/opt/opt.cpp
+++ b/llvm/tools/opt/opt.cpp
@@ -29,10 +29,10 @@
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/LLVMRemarkStreamer.h"
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/LegacyPassNameParser.h"
 #include "llvm/IR/Module.h"
-#include "llvm/IR/RemarkStreamer.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/InitializePasses.h"
@@ -583,9 +583,9 @@ int main(int argc, char **argv) {
     Context.enableDebugTypeODRUniquing();
 
   Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
-      setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
-                               RemarksFormat, RemarksWithHotness,
-                               RemarksHotnessThreshold);
+      setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
+                                   RemarksFormat, RemarksWithHotness,
+                                   RemarksHotnessThreshold);
   if (Error E = RemarksFileOrErr.takeError()) {
     errs() << toString(std::move(E)) << '\n';
     return 1;


        


More information about the llvm-commits mailing list