[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