Skip to content

Commit 4c123a7

Browse files
author
git apple-llvm automerger
committed
Merge commit '7531a5039fd7' from llvm.org/master into apple/master
2 parents 83b72cd + 961da13 commit 4c123a7

23 files changed

+412
-263
lines changed

clang/lib/CodeGen/CodeGenAction.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
#include "llvm/IR/DiagnosticPrinter.h"
3333
#include "llvm/IR/GlobalValue.h"
3434
#include "llvm/IR/LLVMContext.h"
35+
#include "llvm/IR/LLVMRemarkStreamer.h"
3536
#include "llvm/IR/Module.h"
36-
#include "llvm/IR/RemarkStreamer.h"
3737
#include "llvm/IRReader/IRReader.h"
3838
#include "llvm/Linker/Linker.h"
3939
#include "llvm/Pass.h"
@@ -86,15 +86,15 @@ namespace clang {
8686
const CodeGenOptions CodeGenOpts) {
8787
handleAllErrors(
8888
std::move(E),
89-
[&](const RemarkSetupFileError &E) {
89+
[&](const LLVMRemarkSetupFileError &E) {
9090
Diags.Report(diag::err_cannot_open_file)
9191
<< CodeGenOpts.OptRecordFile << E.message();
9292
},
93-
[&](const RemarkSetupPatternError &E) {
93+
[&](const LLVMRemarkSetupPatternError &E) {
9494
Diags.Report(diag::err_drv_optimization_remark_pattern)
9595
<< E.message() << CodeGenOpts.OptRecordPasses;
9696
},
97-
[&](const RemarkSetupFormatError &E) {
97+
[&](const LLVMRemarkSetupFormatError &E) {
9898
Diags.Report(diag::err_drv_optimization_remark_format)
9999
<< CodeGenOpts.OptRecordFormat;
100100
});
@@ -309,7 +309,7 @@ namespace clang {
309309
CodeGenOpts, this));
310310

311311
Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
312-
setupOptimizationRemarks(
312+
setupLLVMOptimizationRemarks(
313313
Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
314314
CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
315315
CodeGenOpts.DiagnosticsHotnessThreshold);
@@ -1150,7 +1150,7 @@ void CodeGenAction::ExecuteAction() {
11501150
std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result));
11511151

11521152
Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
1153-
setupOptimizationRemarks(
1153+
setupLLVMOptimizationRemarks(
11541154
Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses,
11551155
CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness,
11561156
CodeGenOpts.DiagnosticsHotnessThreshold);

llvm/docs/Remarks.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,38 @@ The typical usage through the C API is like the following:
612612
bool HasError = LLVMRemarkParserHasError(Parser);
613613
LLVMRemarkParserDispose(Parser);
614614
615+
Remark streamers
616+
================
617+
618+
The ``RemarkStreamer`` interface is used to unify the serialization
619+
capabilities of remarks across all the components that can generate remarks.
620+
621+
All remark serialization should go through the main remark streamer, the
622+
``llvm::remarks::RemarkStreamer`` set up in the ``LLVMContext``. The interface
623+
takes remark objects converted to ``llvm::remarks::Remark``, and takes care of
624+
serializing it to the requested format, using the requested type of metadata,
625+
etc.
626+
627+
Typically, a specialized remark streamer will hold a reference to the one set
628+
up in the ``LLVMContext``, and will operate on its own type of diagnostics.
629+
630+
For example, LLVM IR passes will emit ``llvm::DiagnosticInfoOptimization*``
631+
that get converted to ``llvm::remarks::Remark`` objects. Then, clang could set
632+
up its own specialized remark streamer that takes ``clang::Diagnostic``
633+
objects. This can allow various components of the frontend to emit remarks
634+
using the same techniques as the LLVM remarks.
635+
636+
This gives us the following advantages:
637+
638+
* Composition: during the compilation pipeline, multiple components can set up
639+
their specialized remark streamers that all emit remarks through the same
640+
main streamer.
641+
* Re-using the remark infrastructure in ``lib/Remarks``.
642+
* Using the same file and format for the remark emitters created throughout the
643+
compilation.
644+
645+
at the cost of an extra layer of abstraction.
646+
615647
.. FIXME: add documentation for llvm-opt-report.
616648
.. FIXME: add documentation for Passes supporting optimization remarks
617649
.. FIXME: add documentation for IR Passes

llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class OptimizationRemarkEmitter {
7777
// remarks enabled. We can't currently check whether remarks are requested
7878
// for the calling pass since that requires actually building the remark.
7979

80-
if (F->getContext().getRemarkStreamer() ||
80+
if (F->getContext().getLLVMRemarkStreamer() ||
8181
F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
8282
auto R = RemarkBuilder();
8383
emit((DiagnosticInfoOptimizationBase &)R);
@@ -92,7 +92,7 @@ class OptimizationRemarkEmitter {
9292
/// provide more context so that non-trivial false positives can be quickly
9393
/// detected by the user.
9494
bool allowExtraAnalysis(StringRef PassName) const {
95-
return (F->getContext().getRemarkStreamer() ||
95+
return (F->getContext().getLLVMRemarkStreamer() ||
9696
F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
9797
}
9898

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ class MDNode;
7171
class Module;
7272
class ProfileSummaryInfo;
7373
class raw_ostream;
74-
class RemarkStreamer;
7574
class StackMaps;
7675
class TargetLoweringObjectFile;
7776
class TargetMachine;
7877

7978
class GlobalPtrAuthInfo;
8079

80+
namespace remarks {
81+
class RemarkStreamer;
82+
};
83+
8184
/// This class is intended to be used as a driving class for all asm writers.
8285
class AsmPrinter : public MachineFunctionPass {
8386
public:
@@ -339,7 +342,7 @@ class AsmPrinter : public MachineFunctionPass {
339342

340343
void emitStackSizeSection(const MachineFunction &MF);
341344

342-
void emitRemarksSection(RemarkStreamer &RS);
345+
void emitRemarksSection(remarks::RemarkStreamer &RS);
343346

344347
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
345348
CFIMoveType needsCFIMoves() const;

llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class MachineOptimizationRemarkEmitter {
159159
/// that non-trivial false positives can be quickly detected by the user.
160160
bool allowExtraAnalysis(StringRef PassName) const {
161161
return (
162-
MF.getFunction().getContext().getRemarkStreamer() ||
162+
MF.getFunction().getContext().getLLVMRemarkStreamer() ||
163163
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
164164
PassName));
165165
}
@@ -172,7 +172,7 @@ class MachineOptimizationRemarkEmitter {
172172
// remarks enabled. We can't currently check whether remarks are requested
173173
// for the calling pass since that requires actually building the remark.
174174

175-
if (MF.getFunction().getContext().getRemarkStreamer() ||
175+
if (MF.getFunction().getContext().getLLVMRemarkStreamer() ||
176176
MF.getFunction()
177177
.getContext()
178178
.getDiagHandlerPtr()

llvm/include/llvm/IR/LLVMContext.h

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ template <typename T> class SmallVectorImpl;
3434
class SMDiagnostic;
3535
class StringRef;
3636
class Twine;
37-
class RemarkStreamer;
37+
class LLVMRemarkStreamer;
3838
class raw_ostream;
3939

40+
namespace remarks {
41+
class RemarkStreamer;
42+
};
43+
4044
namespace SyncScope {
4145

4246
typedef uint8_t ID;
@@ -219,23 +223,27 @@ class LLVMContext {
219223
/// included in optimization diagnostics.
220224
void setDiagnosticsHotnessThreshold(uint64_t Threshold);
221225

222-
/// Return the streamer used by the backend to save remark diagnostics. If it
223-
/// does not exist, diagnostics are not saved in a file but only emitted via
224-
/// the diagnostic handler.
225-
RemarkStreamer *getRemarkStreamer();
226-
const RemarkStreamer *getRemarkStreamer() const;
227-
228-
/// Set the diagnostics output used for optimization diagnostics.
229-
/// This filename may be embedded in a section for tools to find the
230-
/// diagnostics whenever they're needed.
226+
/// The "main remark streamer" used by all the specialized remark streamers.
227+
/// This streamer keeps generic remark metadata in memory throughout the life
228+
/// of the LLVMContext. This metadata may be emitted in a section in object
229+
/// files depending on the format requirements.
231230
///
232-
/// If a remark streamer is already set, it will be replaced with
233-
/// \p RemarkStreamer.
231+
/// All specialized remark streamers should convert remarks to
232+
/// llvm::remarks::Remark and emit them through this streamer.
233+
remarks::RemarkStreamer *getMainRemarkStreamer();
234+
const remarks::RemarkStreamer *getMainRemarkStreamer() const;
235+
void setMainRemarkStreamer(
236+
std::unique_ptr<remarks::RemarkStreamer> LLVMRemarkStreamer);
237+
238+
/// The "LLVM remark streamer" used by LLVM to serialize remark diagnostics
239+
/// comming from IR and MIR passes.
234240
///
235-
/// By default, diagnostics are not saved in a file but only emitted via the
236-
/// diagnostic handler. Even if an output file is set, the handler is invoked
237-
/// for each diagnostic message.
238-
void setRemarkStreamer(std::unique_ptr<RemarkStreamer> RemarkStreamer);
241+
/// If it does not exist, diagnostics are not saved in a file but only emitted
242+
/// via the diagnostic handler.
243+
LLVMRemarkStreamer *getLLVMRemarkStreamer();
244+
const LLVMRemarkStreamer *getLLVMRemarkStreamer() const;
245+
void
246+
setLLVMRemarkStreamer(std::unique_ptr<LLVMRemarkStreamer> LLVMRemarkStreamer);
239247

240248
/// Get the prefix that should be printed in front of a diagnostic of
241249
/// the given \p Severity
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//===- llvm/IR/LLVMRemarkStreamer.h - Streamer for LLVM remarks--*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements the conversion between IR Diagnostics and
10+
// serializable remarks::Remark objects.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_IR_LLVMREMARKSTREAMER_H
15+
#define LLVM_IR_LLVMREMARKSTREAMER_H
16+
17+
#include "llvm/IR/DiagnosticInfo.h"
18+
#include "llvm/Remarks/RemarkStreamer.h"
19+
#include "llvm/Support/Error.h"
20+
#include "llvm/Support/ToolOutputFile.h"
21+
#include <memory>
22+
#include <string>
23+
24+
namespace llvm {
25+
/// Streamer for LLVM remarks which has logic for dealing with DiagnosticInfo
26+
/// objects.
27+
class LLVMRemarkStreamer {
28+
remarks::RemarkStreamer &RS;
29+
/// Convert diagnostics into remark objects.
30+
/// The lifetime of the members of the result is bound to the lifetime of
31+
/// the LLVM diagnostics.
32+
remarks::Remark toRemark(const DiagnosticInfoOptimizationBase &Diag) const;
33+
34+
public:
35+
LLVMRemarkStreamer(remarks::RemarkStreamer &RS) : RS(RS) {}
36+
/// Emit a diagnostic through the streamer.
37+
void emit(const DiagnosticInfoOptimizationBase &Diag);
38+
};
39+
40+
template <typename ThisError>
41+
struct LLVMRemarkSetupErrorInfo : public ErrorInfo<ThisError> {
42+
std::string Msg;
43+
std::error_code EC;
44+
45+
LLVMRemarkSetupErrorInfo(Error E) {
46+
handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) {
47+
Msg = EIB.message();
48+
EC = EIB.convertToErrorCode();
49+
});
50+
}
51+
52+
void log(raw_ostream &OS) const override { OS << Msg; }
53+
std::error_code convertToErrorCode() const override { return EC; }
54+
};
55+
56+
struct LLVMRemarkSetupFileError
57+
: LLVMRemarkSetupErrorInfo<LLVMRemarkSetupFileError> {
58+
static char ID;
59+
using LLVMRemarkSetupErrorInfo<
60+
LLVMRemarkSetupFileError>::LLVMRemarkSetupErrorInfo;
61+
};
62+
63+
struct LLVMRemarkSetupPatternError
64+
: LLVMRemarkSetupErrorInfo<LLVMRemarkSetupPatternError> {
65+
static char ID;
66+
using LLVMRemarkSetupErrorInfo<
67+
LLVMRemarkSetupPatternError>::LLVMRemarkSetupErrorInfo;
68+
};
69+
70+
struct LLVMRemarkSetupFormatError
71+
: LLVMRemarkSetupErrorInfo<LLVMRemarkSetupFormatError> {
72+
static char ID;
73+
using LLVMRemarkSetupErrorInfo<
74+
LLVMRemarkSetupFormatError>::LLVMRemarkSetupErrorInfo;
75+
};
76+
77+
/// Setup optimization remarks that output to a file.
78+
Expected<std::unique_ptr<ToolOutputFile>>
79+
setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
80+
StringRef RemarksPasses, StringRef RemarksFormat,
81+
bool RemarksWithHotness,
82+
unsigned RemarksHotnessThreshold = 0);
83+
84+
/// Setup optimization remarks that output directly to a raw_ostream.
85+
/// \p OS is managed by the caller and should be open for writing as long as \p
86+
/// Context is streaming remarks to it.
87+
Error setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
88+
StringRef RemarksPasses,
89+
StringRef RemarksFormat,
90+
bool RemarksWithHotness,
91+
unsigned RemarksHotnessThreshold = 0);
92+
93+
} // end namespace llvm
94+
95+
#endif // LLVM_IR_LLVMREMARKSTREAMER_H

0 commit comments

Comments
 (0)