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 
18 using namespace llvm;
19 using namespace llvm::remarks;
20 
21 // Use the same keys whether we use a string table or not (respectively, T is an
22 // unsigned or a StringRef).
23 template <typename T>
24 static void mapRemarkHeader(yaml::IO &io, T PassName, T RemarkName,
25  Optional<RemarkLocation> RL, T FunctionName,
26  Optional<uint64_t> Hotness,
28  io.mapRequired("Pass", PassName);
29  io.mapRequired("Name", RemarkName);
30  io.mapOptional("DebugLoc", RL);
31  io.mapRequired("Function", FunctionName);
32  io.mapOptional("Hotness", Hotness);
33  io.mapOptional("Args", Args);
34 }
35 
36 namespace llvm {
37 namespace yaml {
38 
39 template <> struct MappingTraits<remarks::Remark *> {
40  static void mapping(IO &io, remarks::Remark *&Remark) {
41  assert(io.outputting() && "input not yet implemented");
42 
43  if (io.mapTag("!Passed", (Remark->RemarkType == Type::Passed)))
44  ;
45  else if (io.mapTag("!Missed", (Remark->RemarkType == Type::Missed)))
46  ;
47  else if (io.mapTag("!Analysis", (Remark->RemarkType == Type::Analysis)))
48  ;
49  else if (io.mapTag("!AnalysisFPCommute",
51  ;
52  else if (io.mapTag("!AnalysisAliasing",
54  ;
55  else if (io.mapTag("!Failure", (Remark->RemarkType == Type::Failure)))
56  ;
57  else
58  llvm_unreachable("Unknown remark type");
59 
60  if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
61  reinterpret_cast<RemarkSerializer *>(io.getContext()))) {
62  assert(Serializer->StrTab && "YAMLStrTabSerializer with no StrTab.");
63  StringTable &StrTab = *Serializer->StrTab;
64  unsigned PassID = StrTab.add(Remark->PassName).first;
65  unsigned NameID = StrTab.add(Remark->RemarkName).first;
66  unsigned FunctionID = StrTab.add(Remark->FunctionName).first;
67  mapRemarkHeader(io, PassID, NameID, Remark->Loc, FunctionID,
69  } else {
72  }
73  }
74 };
75 
76 template <> struct MappingTraits<RemarkLocation> {
77  static void mapping(IO &io, RemarkLocation &RL) {
78  assert(io.outputting() && "input not yet implemented");
79 
80  StringRef File = RL.SourceFilePath;
81  unsigned Line = RL.SourceLine;
82  unsigned Col = RL.SourceColumn;
83 
84  if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
85  reinterpret_cast<RemarkSerializer *>(io.getContext()))) {
86  assert(Serializer->StrTab && "YAMLStrTabSerializer with no StrTab.");
87  StringTable &StrTab = *Serializer->StrTab;
88  unsigned FileID = StrTab.add(File).first;
89  io.mapRequired("File", FileID);
90  } else {
91  io.mapRequired("File", File);
92  }
93 
94  io.mapRequired("Line", Line);
95  io.mapRequired("Column", Col);
96  }
97 
98  static const bool flow = true;
99 };
100 
101 /// Helper struct for multiline string block literals. Use this type to preserve
102 /// newlines in strings.
106 };
107 
108 template <> struct BlockScalarTraits<StringBlockVal> {
109  static void output(const StringBlockVal &S, void *Ctx, raw_ostream &OS) {
110  return ScalarTraits<StringRef>::output(S.Value, Ctx, OS);
111  }
112 
113  static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S) {
114  return ScalarTraits<StringRef>::input(Scalar, Ctx, S.Value);
115  }
116 };
117 
118 /// ArrayRef is not really compatible with the YAMLTraits. Everything should be
119 /// immutable in an ArrayRef, while the SequenceTraits expect a mutable version
120 /// for inputting, but we're only using the outputting capabilities here.
121 /// This is a hack, but still nicer than having to manually call the YAMLIO
122 /// internal methods.
123 /// Keep this in this file so that it doesn't get misused from YAMLTraits.h.
124 template <typename T> struct SequenceTraits<ArrayRef<T>> {
125  static size_t size(IO &io, ArrayRef<T> &seq) { return seq.size(); }
126  static Argument &element(IO &io, ArrayRef<T> &seq, size_t index) {
127  assert(io.outputting() && "input not yet implemented");
128  // The assert above should make this "safer" to satisfy the YAMLTraits.
129  return const_cast<T &>(seq[index]);
130  }
131 };
132 
133 /// Implement this as a mapping for now to get proper quotation for the value.
134 template <> struct MappingTraits<Argument> {
135  static void mapping(IO &io, Argument &A) {
136  assert(io.outputting() && "input not yet implemented");
137 
138  if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
139  reinterpret_cast<RemarkSerializer *>(io.getContext()))) {
140  assert(Serializer->StrTab && "YAMLStrTabSerializer with no StrTab.");
141  StringTable &StrTab = *Serializer->StrTab;
142  auto ValueID = StrTab.add(A.Val).first;
143  io.mapRequired(A.Key.data(), ValueID);
144  } else if (StringRef(A.Val).count('\n') > 1) {
145  StringBlockVal S(A.Val);
146  io.mapRequired(A.Key.data(), S);
147  } else {
148  io.mapRequired(A.Key.data(), A.Val);
149  }
150  io.mapOptional("DebugLoc", A.Loc);
151  }
152 };
153 
154 } // end namespace yaml
155 } // end namespace llvm
156 
158 
160  Optional<StringTable> StrTabIn)
161  : YAMLRemarkSerializer(Format::YAML, OS, Mode, std::move(StrTabIn)) {}
162 
165  Optional<StringTable> StrTabIn)
166  : RemarkSerializer(SerializerFormat, OS, Mode),
167  YAMLOutput(OS, reinterpret_cast<void *>(this)) {
168  StrTab = std::move(StrTabIn);
169 }
170 
172  // Again, YAMLTraits expect a non-const object for inputting, but we're not
173  // using that here.
174  auto R = const_cast<remarks::Remark *>(&Remark);
175  YAMLOutput << R;
176 }
177 
178 std::unique_ptr<MetaSerializer>
180  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=*/None);
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, 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 
220  // Emit the string table in the section.
221  uint64_t StrTabSize = StrTab ? (*StrTab)->SerializedSize : 0;
222  // Emit the total size of the string table (the size itself excluded):
223  // little-endian uint64_t.
224  // Note: even if no string table is used, emit 0.
225  std::array<char, 8> StrTabSizeBuf;
226  support::endian::write64le(StrTabSizeBuf.data(), StrTabSize);
227  OS.write(StrTabSizeBuf.data(), StrTabSizeBuf.size());
228  if (StrTab)
229  (*StrTab)->serialize(OS);
230 }
231 
232 static void emitExternalFile(raw_ostream &OS, StringRef Filename) {
233  // Emit the null-terminated absolute path to the remark file.
234  SmallString<128> FilenameBuf = Filename;
235  sys::fs::make_absolute(FilenameBuf);
236  assert(!FilenameBuf.empty() && "The filename can't be empty.");
237  OS.write(FilenameBuf.data(), FilenameBuf.size());
238  OS.write('\0');
239 }
240 
242  emitMagic(OS);
243  emitVersion(OS);
244  emitStrTab(OS, None);
245  if (ExternalFilename)
247 }
248 
250  emitMagic(OS);
251  emitVersion(OS);
252  emitStrTab(OS, &StrTab);
253  if (ExternalFilename)
255 }
llvm::remarks::SerializerMode
SerializerMode
Definition: RemarkSerializer.h:27
emitExternalFile
static void emitExternalFile(raw_ostream &OS, StringRef Filename)
Definition: YAMLRemarkSerializer.cpp:232
llvm::remarks::Remark::Args
SmallVector< Argument, 5 > Args
Arguments collected via the streaming interface.
Definition: Remark.h:90
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::remarks::YAMLStrTabRemarkSerializer::metaSerializer
std::unique_ptr< MetaSerializer > metaSerializer(raw_ostream &OS, Optional< StringRef > ExternalFilename=None) override
Return the corresponding metadata serializer.
Definition: YAMLRemarkSerializer.cpp:198
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:70
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
llvm::yaml::BlockScalarTraits< StringBlockVal >::input
static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S)
Definition: YAMLRemarkSerializer.cpp:113
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:30
llvm::remarks::Remark::Hotness
Optional< uint64_t > Hotness
If profile information is available, this is the number of times the corresponding code was executed ...
Definition: Remark.h:87
llvm::remarks::Remark::PassName
StringRef PassName
Name of the pass that triggers the emission of this remark.
Definition: Remark.h:72
LLVM_YAML_IS_SEQUENCE_VECTOR
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
llvm::remarks::RemarkSerializer::StrTab
Optional< StringTable > StrTab
The string table containing all the unique strings used in the output.
Definition: RemarkSerializer.h:50
llvm::remarks::YAMLRemarkSerializer::YAMLOutput
yaml::Output YAMLOutput
The YAML streamer.
Definition: YAMLRemarkSerializer.h:35
llvm::remarks::Magic
constexpr StringLiteral Magic("REMARKS")
llvm::remarks::Type::Missed
@ Missed
llvm::Optional
Definition: APInt.h:33
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::remarks::RemarkSerializer::OS
raw_ostream & OS
The open raw_ostream that the remark diagnostics are emitted to.
Definition: RemarkSerializer.h:45
llvm::yaml::MappingTraits
Definition: ModuleSummaryIndex.h:51
llvm::remarks::RemarkSerializer::Mode
SerializerMode Mode
The serialization mode.
Definition: RemarkSerializer.h:47
llvm::remarks::YAMLStrTabMetaSerializer::emit
void emit() override
Definition: YAMLRemarkSerializer.cpp:249
emitStrTab
static void emitStrTab(raw_ostream &OS, Optional< const StringTable * > StrTab)
Definition: YAMLRemarkSerializer.cpp:219
llvm::remarks::Remark::FunctionName
StringRef FunctionName
Mangled name of the function that triggers the emssion of this remark.
Definition: Remark.h:80
llvm::remarks::RemarkLocation::SourceLine
unsigned SourceLine
Definition: Remark.h:33
Remark.h
remarks
annotation remarks
Definition: AnnotationRemarks.cpp:114
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:219
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1027
llvm::remarks::Remark
A remark type used for both emission and parsing.
Definition: Remark.h:67
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::YAMLRemarkSerializer::YAMLRemarkSerializer
YAMLRemarkSerializer(raw_ostream &OS, SerializerMode Mode, Optional< StringTable > StrTab=None)
Definition: YAMLRemarkSerializer.cpp:159
llvm::remarks::MetaSerializer::emit
virtual void emit()=0
llvm::yaml::MappingTraits< RemarkLocation >::mapping
static void mapping(IO &io, RemarkLocation &RL)
Definition: YAMLRemarkSerializer.cpp:77
llvm::None
const NoneType None
Definition: None.h:24
llvm::remarks::RemarkSerializer
This is the base class for a remark serializer.
Definition: RemarkSerializer.h:41
llvm::SmallString< 128 >
YAMLRemarkSerializer.h
llvm::remarks
Definition: AsmPrinter.h:77
llvm::remarks::StringTable::SerializedSize
size_t SerializedSize
Total size of the string table when serialized.
Definition: RemarkStringTable.h:41
llvm::remarks::YAMLMetaSerializer::emit
void emit() override
Definition: YAMLRemarkSerializer.cpp:241
llvm::remarks::Type::Passed
@ Passed
llvm::remarks::Type::Analysis
@ Analysis
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:125
llvm::yaml::StringBlockVal::Value
StringRef Value
Definition: YAMLRemarkSerializer.cpp:104
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:109
llvm::remarks::RemarkLocation::SourceFilePath
StringRef SourceFilePath
Absolute path of the source file corresponding to this remark.
Definition: Remark.h:32
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:1676
Mode
SI Whole Quad Mode
Definition: SIWholeQuadMode.cpp:262
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:103
llvm::remarks::MetaSerializer::OS
raw_ostream & OS
The open raw_ostream that the metadata is emitted to.
Definition: RemarkSerializer.h:69
llvm::remarks::YAMLStrTabMetaSerializer::StrTab
const StringTable & StrTab
The string table is part of the metadata.
Definition: YAMLRemarkSerializer.h:95
llvm::remarks::YAMLRemarkSerializer::metaSerializer
std::unique_ptr< MetaSerializer > metaSerializer(raw_ostream &OS, Optional< StringRef > ExternalFilename=None) override
Return the corresponding metadata serializer.
Definition: YAMLRemarkSerializer.cpp:179
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
llvm::remarks::RemarkLocation::SourceColumn
unsigned SourceColumn
Definition: Remark.h:34
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:126
llvm::StringRef::count
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:434
llvm::remarks::MetaSerializer
This is the base class for a remark metadata serializer.
Definition: RemarkSerializer.h:67
std
Definition: BitVector.h:851
mapRemarkHeader
static void mapRemarkHeader(yaml::IO &io, T PassName, T RemarkName, Optional< RemarkLocation > RL, T FunctionName, Optional< uint64_t > Hotness, ArrayRef< Argument > Args)
Definition: YAMLRemarkSerializer.cpp:24
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:171
llvm::yaml::StringBlockVal::StringBlockVal
StringBlockVal(StringRef R)
Definition: YAMLRemarkSerializer.cpp:105
llvm::remarks::YAMLRemarkSerializer
Serialize the remarks to YAML.
Definition: YAMLRemarkSerializer.h:33
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:69
llvm::remarks::Type::Failure
@ Failure
llvm::yaml::MappingTraits< remarks::Remark * >::mapping
static void mapping(IO &io, remarks::Remark *&Remark)
Definition: YAMLRemarkSerializer.cpp:40
llvm::remarks::Remark::RemarkName
StringRef RemarkName
Textual identifier for the remark (single-word, camel-case).
Definition: Remark.h:77
llvm::remarks::CurrentRemarkVersion
constexpr uint64_t CurrentRemarkVersion
The current version of the remark entry.
Definition: Remark.h:27
llvm::remarks::Remark::Loc
Optional< RemarkLocation > Loc
The location in the source file of the remark.
Definition: Remark.h:83
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:135
llvm::remarks::Type::AnalysisFPCommute
@ AnalysisFPCommute
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
PassName
static const char PassName[]
Definition: X86LowerAMXIntrinsics.cpp:671
llvm::remarks::YAMLMetaSerializer::ExternalFilename
Optional< StringRef > ExternalFilename
Definition: YAMLRemarkSerializer.h:56
llvm::remarks::Format
Format
The format used for serializing/deserializing remarks.
Definition: RemarkFormat.h:25