LLVM  10.0.0svn
RemarkStreamer.cpp
Go to the documentation of this file.
1 //===- llvm/IR/RemarkStreamer.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 remark outputting as part of
10 // LLVMContext.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/IR/RemarkStreamer.h"
15 #include "llvm/IR/DiagnosticInfo.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/GlobalValue.h"
21 
22 using namespace llvm;
23 
25  std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer,
26  Optional<StringRef> FilenameIn)
27  : PassFilter(), RemarkSerializer(std::move(RemarkSerializer)),
28  Filename(FilenameIn ? Optional<std::string>(FilenameIn->str()) : None) {}
29 
31  Regex R = Regex(Filter);
32  std::string RegexError;
33  if (!R.isValid(RegexError))
34  return createStringError(std::make_error_code(std::errc::invalid_argument),
35  RegexError.data());
36  PassFilter = std::move(R);
37  return Error::success();
38 }
39 
40 /// DiagnosticKind -> remarks::Type
42  switch (Kind) {
43  default:
47  return remarks::Type::Passed;
50  return remarks::Type::Missed;
60  }
61 }
62 
63 /// DiagnosticLocation -> remarks::RemarkLocation.
66  if (!DL.isValid())
67  return None;
69  unsigned Line = DL.getLine();
70  unsigned Col = DL.getColumn();
71  return remarks::RemarkLocation{File, Line, Col};
72 }
73 
74 /// LLVM Diagnostic -> Remark
76 RemarkStreamer::toRemark(const DiagnosticInfoOptimizationBase &Diag) {
77  remarks::Remark R; // The result.
78  R.RemarkType = toRemarkType(static_cast<DiagnosticKind>(Diag.getKind()));
79  R.PassName = Diag.getPassName();
80  R.RemarkName = Diag.getRemarkName();
81  R.FunctionName =
83  R.Loc = toRemarkLocation(Diag.getLocation());
84  R.Hotness = Diag.getHotness();
85 
87  R.Args.emplace_back();
88  R.Args.back().Key = Arg.Key;
89  R.Args.back().Val = Arg.Val;
90  R.Args.back().Loc = toRemarkLocation(Arg.Loc);
91  }
92 
93  return R;
94 }
95 
97  if (Optional<Regex> &Filter = PassFilter)
98  if (!Filter->match(Diag.getPassName()))
99  return;
100 
101  // First, convert the diagnostic to a remark.
102  remarks::Remark R = toRemark(Diag);
103  // Then, emit the remark through the serializer.
104  RemarkSerializer->emit(R);
105 }
106 
107 char RemarkSetupFileError::ID = 0;
110 
114  bool RemarksWithHotness,
115  unsigned RemarksHotnessThreshold) {
116  if (RemarksWithHotness)
117  Context.setDiagnosticsHotnessRequested(true);
118 
119  if (RemarksHotnessThreshold)
120  Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
121 
122  if (RemarksFilename.empty())
123  return nullptr;
124 
125  std::error_code EC;
126  auto RemarksFile =
127  std::make_unique<ToolOutputFile>(RemarksFilename, EC, sys::fs::OF_None);
128  // We don't use llvm::FileError here because some diagnostics want the file
129  // name separately.
130  if (EC)
131  return make_error<RemarkSetupFileError>(errorCodeToError(EC));
132 
134  if (Error E = Format.takeError())
135  return make_error<RemarkSetupFormatError>(std::move(E));
136 
139  *Format, remarks::SerializerMode::Separate, RemarksFile->os());
140  if (Error E = RemarkSerializer.takeError())
141  return make_error<RemarkSetupFormatError>(std::move(E));
142 
143  Context.setRemarkStreamer(std::make_unique<RemarkStreamer>(
144  std::move(*RemarkSerializer), RemarksFilename));
145 
146  if (!RemarksPasses.empty())
147  if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))
148  return make_error<RemarkSetupPatternError>(std::move(E));
149 
150  return std::move(RemarksFile);
151 }
152 
156  bool RemarksWithHotness,
157  unsigned RemarksHotnessThreshold) {
158  if (RemarksWithHotness)
159  Context.setDiagnosticsHotnessRequested(true);
160 
161  if (RemarksHotnessThreshold)
162  Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
163 
165  if (Error E = Format.takeError())
166  return make_error<RemarkSetupFormatError>(std::move(E));
167 
171  if (Error E = RemarkSerializer.takeError())
172  return make_error<RemarkSetupFormatError>(std::move(E));
173 
174  Context.setRemarkStreamer(
175  std::make_unique<RemarkStreamer>(std::move(*RemarkSerializer)));
176 
177  if (!RemarksPasses.empty())
178  if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))
179  return make_error<RemarkSetupPatternError>(std::move(E));
180 
181  return Error::success();
182 }
const NoneType None
Definition: None.h:23
Error setFilter(StringRef Filter)
Set a pass filter based on a regex Filter.
DiagnosticKind
Defines the different supported kind of a diagnostic.
void setRemarkStreamer(std::unique_ptr< RemarkStreamer > RemarkStreamer)
Set the diagnostics output used for optimization diagnostics.
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
StringRef PassName
Name of the pass that triggers the emission of this remark.
Definition: Remark.h:72
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
RemarkStreamer * getRemarkStreamer()
Return the streamer used by the backend to save remark diagnostics.
unsigned getLine() const
Optional< uint64_t > Hotness
If profile information is available, this is the number of times the corresponding code was executed ...
Definition: Remark.h:87
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
static remarks::Type toRemarkType(enum DiagnosticKind Kind)
DiagnosticKind -> remarks::Type.
void setDiagnosticsHotnessThreshold(uint64_t Threshold)
Set the minimum hotness value a diagnostic needs in order to be included in optimization diagnostics...
cl::opt< std::string > RemarksPasses("lto-pass-remarks-filter", cl::desc("Only record optimization remarks from passes whose " "names match the given regular expression"), cl::value_desc("regex"))
Definition: BitVector.h:937
A remark type used for both emission and parsing.
Definition: Remark.h:67
std::error_code make_error_code(BitcodeError E)
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
Definition: Remark.h:77
Expected< Format > parseFormat(StringRef FormatStr)
Parse and validate a string for the remark format.
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
void setDiagnosticsHotnessRequested(bool Requested)
Set if a code hotness metric should be included in optimization diagnostics.
Optional< RemarkLocation > Loc
The location in the source file of the remark.
Definition: Remark.h:83
Type
The type of the remark.
Definition: Remark.h:54
const Function & getFunction() const
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:64
Instrumentation for Order File
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
The debug location used to track a remark back to the source file.
Definition: Remark.h:30
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
void getLocation(StringRef &RelativePath, unsigned &Line, unsigned &Column) const
Return location information for this diagnostic in three parts: the relative source file path...
Used in the streaming interface as the general argument type.
static Optional< remarks::RemarkLocation > toRemarkLocation(const DiagnosticLocation &DL)
DiagnosticLocation -> remarks::RemarkLocation.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
Common features for diagnostics dealing with optimization remarks that are used by both IR and MIR pa...
bool isValid(std::string &Error) const
isValid - returns the error encountered during regex compilation, or matching, if any...
Definition: Regex.cpp:55
StringRef getRelativePath() const
Return the file name relative to the compilation directory.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character &#39;\1&#39;, drop it.
Definition: GlobalValue.h:481
Type RemarkType
The type of the remark.
Definition: Remark.h:69
StringRef FunctionName
Mangled name of the function that triggers the emssion of this remark.
Definition: Remark.h:80
Expected< std::unique_ptr< ToolOutputFile > > setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, unsigned RemarksHotnessThreshold=0)
Setup optimization remarks that output to a file.
ArrayRef< Argument > getArgs() const
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
Expected< std::unique_ptr< RemarkSerializer > > createRemarkSerializer(Format RemarksFormat, SerializerMode Mode, raw_ostream &OS)
Create a remark serializer.
RemarkStreamer(std::unique_ptr< remarks::RemarkSerializer > RemarkSerializer, Optional< StringRef > Filename=None)
Optional< uint64_t > getHotness() const
cl::opt< std::string > RemarksFormat("lto-pass-remarks-format", cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml"))
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
SmallVector< Argument, 5 > Args
Arguments collected via the streaming interface.
Definition: Remark.h:90
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1177
void emit(const DiagnosticInfoOptimizationBase &Diag)
Emit a diagnostic through the streamer.
unsigned getColumn() const