forked from OSchip/llvm-project
[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
This commit is contained in:
parent
1c03cc5a39
commit
7531a5039f
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
// 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 @@ public:
|
|||
/// 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ public:
|
|||
|
||||
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;
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
/// 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 @@ public:
|
|||
// 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()
|
||||
|
|
|
@ -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 @@ public:
|
|||
/// 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;
|
||||
/// 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.
|
||||
///
|
||||
/// 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);
|
||||
|
||||
/// 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 "LLVM remark streamer" used by LLVM to serialize remark diagnostics
|
||||
/// comming from IR and MIR passes.
|
||||
///
|
||||
/// If a remark streamer is already set, it will be replaced with
|
||||
/// \p RemarkStreamer.
|
||||
///
|
||||
/// 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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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>>
|
||||
|
|
|
@ -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
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 @@ public:
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
char LLVMRemarkSetupFileError::ID = 0;
|
||||
char LLVMRemarkSetupPatternError::ID = 0;
|
||||
char LLVMRemarkSetupFormatError::ID = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
Context.setRemarkStreamer(
|
||||
std::make_unique<RemarkStreamer>(std::move(*RemarkSerializer)));
|
||||
// Create the main remark streamer.
|
||||
Context.setMainRemarkStreamer(
|
||||
std::make_unique<remarks::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();
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -6,6 +6,7 @@ add_llvm_component_library(LLVMRemarks
|
|||
RemarkLinker.cpp
|
||||
RemarkParser.cpp
|
||||
RemarkSerializer.cpp
|
||||
RemarkStreamer.cpp
|
||||
RemarkStringTable.cpp
|
||||
YAMLRemarkParser.cpp
|
||||
YAMLRemarkSerializer.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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue