LLVM  16.0.0git
YAMLRemarkSerializer.cpp
Go to the documentation of this file.
1 //===- YAMLRemarkSerializer.cpp -------------------------------------------===//
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 provides the implementation of the YAML remark serializer using
10 // LLVM's YAMLTraits.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/Remarks/Remark.h"
17 #include <optional>
18 
19 using namespace llvm;
20 using namespace llvm::remarks;
21 
22 // Use the same keys whether we use a string table or not (respectively, T is an
23 // unsigned or a StringRef).
24 template <typename T>
25 static void mapRemarkHeader(yaml::IO &io, T PassName, T RemarkName,
26  std::optional<RemarkLocation> RL, T FunctionName,
27  std::optional<uint64_t> Hotness,
29  io.mapRequired("Pass", PassName);
30  io.mapRequired("Name", RemarkName);
31  io.mapOptional("DebugLoc", RL);
32  io.mapRequired("Function", FunctionName);
33  io.mapOptional("Hotness", Hotness);
34  io.mapOptional("Args", Args);
35 }
36 
37 namespace llvm {
38 namespace yaml {
39 
40 template <> struct MappingTraits<remarks::Remark *> {
41  static void mapping(IO &io, remarks::Remark *&Remark) {
42  assert(io.outputting() && "input not yet implemented");
43 
44  if (io.mapTag("!Passed", (Remark->RemarkType == Type::Passed)))
45  ;
46  else if (io.mapTag("!Missed", (Remark->RemarkType == Type::Missed)))
47  ;
48  else if (io.mapTag("!Analysis", (Remark->RemarkType == Type::Analysis)))
49  ;
50  else if (io.mapTag("!AnalysisFPCommute",
52  ;
53  else if (io.mapTag("!AnalysisAliasing",
55  ;
56  else if (io.mapTag("!Failure", (Remark->RemarkType == Type::Failure)))
57  ;
58  else
59  llvm_unreachable("Unknown remark type");
60 
61  if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
62  reinterpret_cast<RemarkSerializer *>(io.getContext()))) {
63  assert(Serializer->StrTab && "YAMLStrTabSerializer with no StrTab.");
64  StringTable &StrTab = *Serializer->StrTab;
65  unsigned PassID = StrTab.add(Remark->PassName).first;
66  unsigned NameID = StrTab.add(Remark->RemarkName).first;
67  unsigned FunctionID = StrTab.add(Remark->FunctionName).first;
68  mapRemarkHeader(io, PassID, NameID, Remark->Loc, FunctionID,
70  } else {
73  }
74  }
75 };
76 
77 template <> struct MappingTraits<RemarkLocation> {
78  static void mapping(IO &io, RemarkLocation &RL) {
79  assert(io.outputting() && "input not yet implemented");
80 
81  StringRef File = RL.SourceFilePath;
82  unsigned Line = RL.SourceLine;
83  unsigned Col = RL.SourceColumn;
84 
85  if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
86  reinterpret_cast<RemarkSerializer *>(io.getContext()))) {
87  assert(Serializer->StrTab && "YAMLStrTabSerializer with no StrTab.");
88  StringTable &StrTab = *Serializer->StrTab;
89  unsigned FileID = StrTab.add(File).first;
90  io.mapRequired("File", FileID);
91  } else {
92  io.mapRequired("File", File);
93  }
94 
95  io.mapRequired("Line", Line);
96  io.mapRequired("Column", Col);
97  }
98 
99  static const bool flow = true;
100 };
101 
102 /// Helper struct for multiline string block literals. Use this type to preserve
103 /// newlines in strings.
107 };
108 
109 template <> struct BlockScalarTraits<StringBlockVal> {
110  static void output(const StringBlockVal &S, void *Ctx, raw_ostream &OS) {
111  return ScalarTraits<StringRef>::output(S.Value, Ctx, OS);
112  }
113 
114  static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S) {
115  return ScalarTraits<StringRef>::input(Scalar, Ctx, S.Value);
116  }
117 };
118 
119 /// ArrayRef is not really compatible with the YAMLTraits. Everything should be
120 /// immutable in an ArrayRef, while the SequenceTraits expect a mutable version
121 /// for inputting, but we're only using the outputting capabilities here.
122 /// This is a hack, but still nicer than having to manually call the YAMLIO
123 /// internal methods.
124 /// Keep this in this file so that it doesn't get misused from YAMLTraits.h.
125 template <typename T> struct SequenceTraits<ArrayRef<T>> {
126  static size_t size(IO &io, ArrayRef<T> &seq) { return seq.size(); }
127  static Argument &element(IO &io, ArrayRef<T> &seq, size_t index) {
128  assert(io.outputting() && "input not yet implemented");
129  // The assert above should make this "safer" to satisfy the YAMLTraits.
130  return const_cast<T &>(seq[index]);
131  }
132 };
133 
134 /// Implement this as a mapping for now to get proper quotation for the value.
135 template <> struct MappingTraits<Argument> {
136  static void mapping(IO &io, Argument &A) {
137  assert(io.outputting() && "input not yet implemented");
138 
139  if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
140  reinterpret_cast<RemarkSerializer *>(io.getContext()))) {
141  assert(Serializer->StrTab && "YAMLStrTabSerializer with no StrTab.");
142  StringTable &StrTab = *Serializer->StrTab;
143  auto ValueID = StrTab.add(A.Val).first;
144  io.mapRequired(A.Key.data(), ValueID);
145  } else if (StringRef(A.Val).count('\n') > 1) {
146  StringBlockVal S(A.Val);
147  io.mapRequired(A.Key.data(), S);
148  } else {
149  io.mapRequired(A.Key.data(), A.Val);
150  }
151  io.mapOptional("DebugLoc", A.Loc);
152  }
153 };
154 
155 } // end namespace yaml
156 } // end namespace llvm
157 
159 
161  std::optional<StringTable> StrTabIn)
162  : YAMLRemarkSerializer(Format::YAML, OS, Mode, std::move(StrTabIn)) {}
163 
166  std::optional<StringTable> StrTabIn)
167  : RemarkSerializer(SerializerFormat, OS, Mode),
168  YAMLOutput(OS, reinterpret_cast<void *>(this)) {
169  StrTab = std::move(StrTabIn);
170 }
171 
173  // Again, YAMLTraits expect a non-const object for inputting, but we're not
174  // using that here.
175  auto R = const_cast<remarks::Remark *>(&Remark);
176  YAMLOutput << R;
177 }
178 
179 std::unique_ptr<MetaSerializer> YAMLRemarkSerializer::metaSerializer(
180  raw_ostream &OS, std::optional<StringRef> ExternalFilename) {
181  return std::make_unique<YAMLMetaSerializer>(OS, ExternalFilename);
182 }
183 
185  // In standalone mode, for the serializer with a string table, emit the
186  // metadata first and set DidEmitMeta to avoid emitting it again.
188  std::unique_ptr<MetaSerializer> MetaSerializer =
189  metaSerializer(OS, /*ExternalFilename=*/std::nullopt);
190  MetaSerializer->emit();
191  DidEmitMeta = true;
192  }
193 
194  // Then do the usual remark emission.
196 }
197 
198 std::unique_ptr<MetaSerializer> YAMLStrTabRemarkSerializer::metaSerializer(
199  raw_ostream &OS, std::optional<StringRef> ExternalFilename) {
200  assert(StrTab);
201  return std::make_unique<YAMLStrTabMetaSerializer>(OS, ExternalFilename,
202  *StrTab);
203 }
204 
205 static void emitMagic(raw_ostream &OS) {
206  // Emit the magic number.
207  OS << remarks::Magic;
208  // Explicitly emit a '\0'.
209  OS.write('\0');
210 }
211 
212 static void emitVersion(raw_ostream &OS) {
213  // Emit the version number: little-endian uint64_t.
214  std::array<char, 8> Version;
216  OS.write(Version.data(), Version.size());
217 }
218 
219 static void emitStrTab(raw_ostream &OS,
220  std::optional<const StringTable *> StrTab) {
221  // Emit the string table in the section.
222  uint64_t StrTabSize = StrTab ? (*StrTab)->SerializedSize : 0;
223  // Emit the total size of the string table (the size itself excluded):
224  // little-endian uint64_t.
225  // Note: even if no string table is used, emit 0.
226  std::array<char, 8> StrTabSizeBuf;
227  support::endian::write64le(StrTabSizeBuf.data(), StrTabSize);
228  OS.write(StrTabSizeBuf.data(), StrTabSizeBuf.size());
229  if (StrTab)
230  (*StrTab)->serialize(OS);
231 }
232 
233 static void emitExternalFile(raw_ostream &OS, StringRef Filename) {
234  // Emit the null-terminated absolute path to the remark file.
235  SmallString<128> FilenameBuf = Filename;
236  sys::fs::make_absolute(FilenameBuf);
237  assert(!FilenameBuf.empty() && "The filename can't be empty.");
238  OS.write(FilenameBuf.data(), FilenameBuf.size());
239  OS.write('\0');
240 }
241 
243  emitMagic(OS);
244  emitVersion(OS);
245  emitStrTab(OS, std::nullopt);
246  if (ExternalFilename)
248 }
249 
251  emitMagic(OS);
252  emitVersion(OS);
253  emitStrTab(OS, &StrTab);
254  if (ExternalFilename)
256 }
llvm::remarks::SerializerMode
SerializerMode
Definition: RemarkSerializer.h:28
emitExternalFile
static void emitExternalFile(raw_ostream &OS, StringRef Filename)
Definition: YAMLRemarkSerializer.cpp:233
llvm::remarks::Remark::Args
SmallVector< Argument, 5 > Args
Arguments collected via the streaming interface.
Definition: Remark.h:91
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
llvm::remarks::YAMLStrTabRemarkSerializer::metaSerializer
std::unique_ptr< MetaSerializer > metaSerializer(raw_ostream &OS, std::optional< StringRef > ExternalFilename=std::nullopt) override
Return the corresponding metadata serializer.
Definition: YAMLRemarkSerializer.cpp:198
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::remarks::StringTable
The string table used for serializing remarks.
Definition: RemarkStringTable.h:36
FileSystem.h
llvm::remarks::YAMLStrTabRemarkSerializer::DidEmitMeta
bool DidEmitMeta
Wether we already emitted the metadata in standalone mode.
Definition: YAMLRemarkSerializer.h:71
llvm::remarks::StringTable::StrTab
StringMap< unsigned, BumpPtrAllocator > StrTab
The string table containing all the unique strings used in the output.
Definition: RemarkStringTable.h:39
llvm::remarks::SerializerMode::Standalone
@ Standalone
emitVersion
static void emitVersion(raw_ostream &OS)
Definition: YAMLRemarkSerializer.cpp:212
T
llvm::yaml::BlockScalarTraits< StringBlockVal >::input
static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S)
Definition: YAMLRemarkSerializer.cpp:114
output
Current output
Definition: README.txt:1350
emitMagic
static void emitMagic(raw_ostream &OS)
Definition: YAMLRemarkSerializer.cpp:205
llvm::remarks::RemarkLocation
The debug location used to track a remark back to the source file.
Definition: Remark.h:31
llvm::remarks::Remark::PassName
StringRef PassName
Name of the pass that triggers the emission of this remark.
Definition: Remark.h:73
LLVM_YAML_IS_SEQUENCE_VECTOR
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
llvm::remarks::YAMLRemarkSerializer::YAMLOutput
yaml::Output YAMLOutput
The YAML streamer.
Definition: YAMLRemarkSerializer.h:36
llvm::remarks::Magic
constexpr StringLiteral Magic("REMARKS")
llvm::remarks::Type::Missed
@ Missed
llvm::remarks::RemarkSerializer::OS
raw_ostream & OS
The open raw_ostream that the remark diagnostics are emitted to.
Definition: RemarkSerializer.h:46
llvm::yaml::MappingTraits
Definition: ModuleSummaryIndex.h:53
llvm::remarks::RemarkSerializer::Mode
SerializerMode Mode
The serialization mode.
Definition: RemarkSerializer.h:48
llvm::remarks::YAMLStrTabMetaSerializer::emit
void emit() override
Definition: YAMLRemarkSerializer.cpp:250
llvm::remarks::Remark::FunctionName
StringRef FunctionName
Mangled name of the function that triggers the emssion of this remark.
Definition: Remark.h:81
llvm::remarks::Remark::Loc
std::optional< RemarkLocation > Loc
The location in the source file of the remark.
Definition: Remark.h:84
llvm::remarks::RemarkLocation::SourceLine
unsigned SourceLine
Definition: Remark.h:34
llvm::remarks::YAMLMetaSerializer::ExternalFilename
std::optional< StringRef > ExternalFilename
Definition: YAMLRemarkSerializer.h:57
llvm::remarks::YAMLRemarkSerializer::YAMLRemarkSerializer
YAMLRemarkSerializer(raw_ostream &OS, SerializerMode Mode, std::optional< StringTable > StrTab=std::nullopt)
Definition: YAMLRemarkSerializer.cpp:160
Remark.h
llvm::seq
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition: Sequence.h:305
llvm::raw_ostream::write
raw_ostream & write(unsigned char C)
Definition: raw_ostream.cpp:218
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
llvm::remarks::Remark
A remark type used for both emission and parsing.
Definition: Remark.h:68
input
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 input
Definition: README.txt:10
llvm::remarks::MetaSerializer::emit
virtual void emit()=0
llvm::yaml::MappingTraits< RemarkLocation >::mapping
static void mapping(IO &io, RemarkLocation &RL)
Definition: YAMLRemarkSerializer.cpp:78
llvm::remarks::RemarkSerializer
This is the base class for a remark serializer.
Definition: RemarkSerializer.h:42
llvm::SmallString< 128 >
YAMLRemarkSerializer.h
llvm::remarks
Definition: AsmPrinter.h:79
llvm::remarks::YAMLMetaSerializer::emit
void emit() override
Definition: YAMLRemarkSerializer.cpp:242
llvm::remarks::Type::Passed
@ Passed
llvm::remarks::Type::Analysis
@ Analysis
llvm::remarks::YAMLRemarkSerializer::metaSerializer
std::unique_ptr< MetaSerializer > metaSerializer(raw_ostream &OS, std::optional< StringRef > ExternalFilename=std::nullopt) override
Return the corresponding metadata serializer.
Definition: YAMLRemarkSerializer.cpp:179
index
splat index
Definition: README_ALTIVEC.txt:181
uint64_t
llvm::yaml::SequenceTraits< ArrayRef< T > >::size
static size_t size(IO &io, ArrayRef< T > &seq)
Definition: YAMLRemarkSerializer.cpp:126
llvm::yaml::StringBlockVal::Value
StringRef Value
Definition: YAMLRemarkSerializer.cpp:105
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::yaml::BlockScalarTraits< StringBlockVal >::output
static void output(const StringBlockVal &S, void *Ctx, raw_ostream &OS)
Definition: YAMLRemarkSerializer.cpp:110
llvm::remarks::Remark::Hotness
std::optional< uint64_t > Hotness
If profile information is available, this is the number of times the corresponding code was executed ...
Definition: Remark.h:88
llvm::remarks::RemarkLocation::SourceFilePath
StringRef SourceFilePath
Absolute path of the source file corresponding to this remark.
Definition: Remark.h:33
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1861
Mode
SI Whole Quad Mode
Definition: SIWholeQuadMode.cpp:264
llvm::sys::fs::make_absolute
void make_absolute(const Twine &current_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
Definition: Path.cpp:906
llvm::yaml::StringBlockVal
Helper struct for multiline string block literals.
Definition: YAMLRemarkSerializer.cpp:104
llvm::remarks::MetaSerializer::OS
raw_ostream & OS
The open raw_ostream that the metadata is emitted to.
Definition: RemarkSerializer.h:70
llvm::remarks::YAMLStrTabMetaSerializer::StrTab
const StringTable & StrTab
The string table is part of the metadata.
Definition: YAMLRemarkSerializer.h:96
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
mapRemarkHeader
static void mapRemarkHeader(yaml::IO &io, T PassName, T RemarkName, std::optional< RemarkLocation > RL, T FunctionName, std::optional< uint64_t > Hotness, ArrayRef< Argument > Args)
Definition: YAMLRemarkSerializer.cpp:25
llvm::remarks::RemarkLocation::SourceColumn
unsigned SourceColumn
Definition: Remark.h:35
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::remarks::YAMLStrTabRemarkSerializer::emit
void emit(const Remark &Remark) override
Override to emit the metadata if necessary.
Definition: YAMLRemarkSerializer.cpp:184
llvm::yaml::SequenceTraits< ArrayRef< T > >::element
static Argument & element(IO &io, ArrayRef< T > &seq, size_t index)
Definition: YAMLRemarkSerializer.cpp:127
llvm::StringRef::count
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:455
llvm::remarks::MetaSerializer
This is the base class for a remark metadata serializer.
Definition: RemarkSerializer.h:68
std
Definition: BitVector.h:851
emitStrTab
static void emitStrTab(raw_ostream &OS, std::optional< const StringTable * > StrTab)
Definition: YAMLRemarkSerializer.cpp:219
llvm::remarks::StringTable::add
std::pair< unsigned, StringRef > add(StringRef Str)
Add a string to the table. It returns an unique ID of the string.
Definition: RemarkStringTable.cpp:31
llvm::remarks::YAMLRemarkSerializer::emit
void emit(const Remark &Remark) override
Emit a remark to the stream.
Definition: YAMLRemarkSerializer.cpp:172
llvm::yaml::StringBlockVal::StringBlockVal
StringBlockVal(StringRef R)
Definition: YAMLRemarkSerializer.cpp:106
llvm::remarks::YAMLRemarkSerializer
Serialize the remarks to YAML.
Definition: YAMLRemarkSerializer.h:34
llvm::support::endian::write64le
void write64le(void *P, uint64_t V)
Definition: Endian.h:417
llvm::remarks::Remark::RemarkType
Type RemarkType
The type of the remark.
Definition: Remark.h:70
llvm::remarks::Type::Failure
@ Failure
llvm::yaml::MappingTraits< remarks::Remark * >::mapping
static void mapping(IO &io, remarks::Remark *&Remark)
Definition: YAMLRemarkSerializer.cpp:41
llvm::remarks::Remark::RemarkName
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
Definition: Remark.h:78
llvm::remarks::CurrentRemarkVersion
constexpr uint64_t CurrentRemarkVersion
The current version of the remark entry.
Definition: Remark.h:28
llvm::remarks::Type::AnalysisAliasing
@ AnalysisAliasing
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::yaml::MappingTraits< Argument >::mapping
static void mapping(IO &io, Argument &A)
Definition: YAMLRemarkSerializer.cpp:136
llvm::remarks::Type::AnalysisFPCommute
@ AnalysisFPCommute
llvm::remarks::RemarkSerializer::StrTab
std::optional< StringTable > StrTab
The string table containing all the unique strings used in the output.
Definition: RemarkSerializer.h:51
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
PassName
static const char PassName[]
Definition: X86LowerAMXIntrinsics.cpp:671
llvm::remarks::Format
Format
The format used for serializing/deserializing remarks.
Definition: RemarkFormat.h:25