Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/IR/LLVMRemarkStreamer.cpp
35233 views
1
//===- llvm/IR/LLVMRemarkStreamer.cpp - Remark Streamer -*- 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 contains the implementation of the conversion between IR
10
// Diagnostics and serializable remarks::Remark objects.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/IR/LLVMRemarkStreamer.h"
15
#include "llvm/IR/DiagnosticInfo.h"
16
#include "llvm/IR/Function.h"
17
#include "llvm/IR/GlobalValue.h"
18
#include "llvm/Remarks/RemarkStreamer.h"
19
#include "llvm/Support/FileSystem.h"
20
#include "llvm/Support/ToolOutputFile.h"
21
#include <optional>
22
23
using namespace llvm;
24
25
/// DiagnosticKind -> remarks::Type
26
static remarks::Type toRemarkType(enum DiagnosticKind Kind) {
27
switch (Kind) {
28
default:
29
return remarks::Type::Unknown;
30
case DK_OptimizationRemark:
31
case DK_MachineOptimizationRemark:
32
return remarks::Type::Passed;
33
case DK_OptimizationRemarkMissed:
34
case DK_MachineOptimizationRemarkMissed:
35
return remarks::Type::Missed;
36
case DK_OptimizationRemarkAnalysis:
37
case DK_MachineOptimizationRemarkAnalysis:
38
return remarks::Type::Analysis;
39
case DK_OptimizationRemarkAnalysisFPCommute:
40
return remarks::Type::AnalysisFPCommute;
41
case DK_OptimizationRemarkAnalysisAliasing:
42
return remarks::Type::AnalysisAliasing;
43
case DK_OptimizationFailure:
44
return remarks::Type::Failure;
45
}
46
}
47
48
/// DiagnosticLocation -> remarks::RemarkLocation.
49
static std::optional<remarks::RemarkLocation>
50
toRemarkLocation(const DiagnosticLocation &DL) {
51
if (!DL.isValid())
52
return std::nullopt;
53
StringRef File = DL.getRelativePath();
54
unsigned Line = DL.getLine();
55
unsigned Col = DL.getColumn();
56
return remarks::RemarkLocation{File, Line, Col};
57
}
58
59
/// LLVM Diagnostic -> Remark
60
remarks::Remark
61
LLVMRemarkStreamer::toRemark(const DiagnosticInfoOptimizationBase &Diag) const {
62
remarks::Remark R; // The result.
63
R.RemarkType = toRemarkType(static_cast<DiagnosticKind>(Diag.getKind()));
64
R.PassName = Diag.getPassName();
65
R.RemarkName = Diag.getRemarkName();
66
R.FunctionName =
67
GlobalValue::dropLLVMManglingEscape(Diag.getFunction().getName());
68
R.Loc = toRemarkLocation(Diag.getLocation());
69
R.Hotness = Diag.getHotness();
70
71
for (const DiagnosticInfoOptimizationBase::Argument &Arg : Diag.getArgs()) {
72
R.Args.emplace_back();
73
R.Args.back().Key = Arg.Key;
74
R.Args.back().Val = Arg.Val;
75
R.Args.back().Loc = toRemarkLocation(Arg.Loc);
76
}
77
78
return R;
79
}
80
81
void LLVMRemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) {
82
if (!RS.matchesFilter(Diag.getPassName()))
83
return;
84
85
// First, convert the diagnostic to a remark.
86
remarks::Remark R = toRemark(Diag);
87
// Then, emit the remark through the serializer.
88
RS.getSerializer().emit(R);
89
}
90
91
char LLVMRemarkSetupFileError::ID = 0;
92
char LLVMRemarkSetupPatternError::ID = 0;
93
char LLVMRemarkSetupFormatError::ID = 0;
94
95
Expected<std::unique_ptr<ToolOutputFile>> llvm::setupLLVMOptimizationRemarks(
96
LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses,
97
StringRef RemarksFormat, bool RemarksWithHotness,
98
std::optional<uint64_t> RemarksHotnessThreshold) {
99
if (RemarksWithHotness || RemarksHotnessThreshold.value_or(1))
100
Context.setDiagnosticsHotnessRequested(true);
101
102
Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
103
104
if (RemarksFilename.empty())
105
return nullptr;
106
107
Expected<remarks::Format> Format = remarks::parseFormat(RemarksFormat);
108
if (Error E = Format.takeError())
109
return make_error<LLVMRemarkSetupFormatError>(std::move(E));
110
111
std::error_code EC;
112
auto Flags = *Format == remarks::Format::YAML ? sys::fs::OF_TextWithCRLF
113
: sys::fs::OF_None;
114
auto RemarksFile =
115
std::make_unique<ToolOutputFile>(RemarksFilename, EC, Flags);
116
// We don't use llvm::FileError here because some diagnostics want the file
117
// name separately.
118
if (EC)
119
return make_error<LLVMRemarkSetupFileError>(errorCodeToError(EC));
120
121
Expected<std::unique_ptr<remarks::RemarkSerializer>> RemarkSerializer =
122
remarks::createRemarkSerializer(
123
*Format, remarks::SerializerMode::Separate, RemarksFile->os());
124
if (Error E = RemarkSerializer.takeError())
125
return make_error<LLVMRemarkSetupFormatError>(std::move(E));
126
127
// Create the main remark streamer.
128
Context.setMainRemarkStreamer(std::make_unique<remarks::RemarkStreamer>(
129
std::move(*RemarkSerializer), RemarksFilename));
130
131
// Create LLVM's optimization remarks streamer.
132
Context.setLLVMRemarkStreamer(
133
std::make_unique<LLVMRemarkStreamer>(*Context.getMainRemarkStreamer()));
134
135
if (!RemarksPasses.empty())
136
if (Error E = Context.getMainRemarkStreamer()->setFilter(RemarksPasses))
137
return make_error<LLVMRemarkSetupPatternError>(std::move(E));
138
139
return std::move(RemarksFile);
140
}
141
142
Error llvm::setupLLVMOptimizationRemarks(
143
LLVMContext &Context, raw_ostream &OS, StringRef RemarksPasses,
144
StringRef RemarksFormat, bool RemarksWithHotness,
145
std::optional<uint64_t> RemarksHotnessThreshold) {
146
if (RemarksWithHotness || RemarksHotnessThreshold.value_or(1))
147
Context.setDiagnosticsHotnessRequested(true);
148
149
Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
150
151
Expected<remarks::Format> Format = remarks::parseFormat(RemarksFormat);
152
if (Error E = Format.takeError())
153
return make_error<LLVMRemarkSetupFormatError>(std::move(E));
154
155
Expected<std::unique_ptr<remarks::RemarkSerializer>> RemarkSerializer =
156
remarks::createRemarkSerializer(*Format,
157
remarks::SerializerMode::Separate, OS);
158
if (Error E = RemarkSerializer.takeError())
159
return make_error<LLVMRemarkSetupFormatError>(std::move(E));
160
161
// Create the main remark streamer.
162
Context.setMainRemarkStreamer(
163
std::make_unique<remarks::RemarkStreamer>(std::move(*RemarkSerializer)));
164
165
// Create LLVM's optimization remarks streamer.
166
Context.setLLVMRemarkStreamer(
167
std::make_unique<LLVMRemarkStreamer>(*Context.getMainRemarkStreamer()));
168
169
if (!RemarksPasses.empty())
170
if (Error E = Context.getMainRemarkStreamer()->setFilter(RemarksPasses))
171
return make_error<LLVMRemarkSetupPatternError>(std::move(E));
172
173
return Error::success();
174
}
175
176