LLVM  13.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 
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.hasValue() &&
63  "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 
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.hasValue() &&
88  "YAMLStrTabSerializer with no StrTab.");
89  StringTable &StrTab = *Serializer->StrTab;
90  unsigned FileID = StrTab.add(File).first;
91  io.mapRequired("File", FileID);
92  } else {
93  io.mapRequired("File", File);
94  }
95 
96  io.mapRequired("Line", Line);
97  io.mapRequired("Column", Col);
98  }
99 
100  static const bool flow = true;
101 };
102 
103 /// Helper struct for multiline string block literals. Use this type to preserve
104 /// newlines in strings.
108 };
109 
110 template <> struct BlockScalarTraits<StringBlockVal> {
111  static void output(const StringBlockVal &S, void *Ctx, raw_ostream &OS) {
112  return ScalarTraits<StringRef>::output(S.Value, Ctx, OS);
113  }
114 
115  static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S) {
116  return ScalarTraits<StringRef>::input(Scalar, Ctx, S.Value);
117  }
118 };
119 
120 /// ArrayRef is not really compatible with the YAMLTraits. Everything should be
121 /// immutable in an ArrayRef, while the SequenceTraits expect a mutable version
122 /// for inputting, but we're only using the outputting capabilities here.
123 /// This is a hack, but still nicer than having to manually call the YAMLIO
124 /// internal methods.
125 /// Keep this in this file so that it doesn't get misused from YAMLTraits.h.
126 template <typename T> struct SequenceTraits<ArrayRef<T>> {
127  static size_t size(IO &io, ArrayRef<T> &seq) { return seq.size(); }
128  static Argument &element(IO &io, ArrayRef<T> &seq, size_t index) {
129  assert(io.outputting() && "input not yet implemented");
130  // The assert above should make this "safer" to satisfy the YAMLTraits.
131  return const_cast<T &>(seq[index]);
132  }
133 };
134 
135 /// Implement this as a mapping for now to get proper quotation for the value.
136 template <> struct MappingTraits<Argument> {
137  static void mapping(IO &io, Argument &A) {
138  assert(io.outputting() && "input not yet implemented");
139 
140  if (auto *Serializer = dyn_cast<YAMLStrTabRemarkSerializer>(
141  reinterpret_cast<RemarkSerializer *>(io.getContext()))) {
142  assert(Serializer->StrTab.hasValue() &&
143  "YAMLStrTabSerializer with no StrTab.");
144  StringTable &StrTab = *Serializer->StrTab;
145  auto ValueID = StrTab.add(A.Val).first;
146  io.mapRequired(A.Key.data(), ValueID);
147  } else if (StringRef(A.Val).count('\n') > 1) {
148  StringBlockVal S(A.Val);
149  io.mapRequired(A.Key.data(), S);
150  } else {
151  io.mapRequired(A.Key.data(), A.Val);
152  }
153  io.mapOptional("DebugLoc", A.Loc);
154  }
155 };
156 
157 } // end namespace yaml
158 } // end namespace llvm
159 
161 
163  Optional<StringTable> StrTabIn)
164  : YAMLRemarkSerializer(Format::YAML, OS, Mode, std::move(StrTabIn)) {}
165 
168  Optional<StringTable> StrTabIn)
169  : RemarkSerializer(SerializerFormat, OS, Mode),
170  YAMLOutput(OS, reinterpret_cast<void *>(this)) {
171  StrTab = std::move(StrTabIn);
172 }
173 
175  // Again, YAMLTraits expect a non-const object for inputting, but we're not
176  // using that here.
177  auto R = const_cast<remarks::Remark *>(&Remark);
178  YAMLOutput << R;
179 }
180 
181 std::unique_ptr<MetaSerializer>
183  Optional<StringRef> ExternalFilename) {
184  return std::make_unique<YAMLMetaSerializer>(OS, ExternalFilename);
185 }
186 
188  // In standalone mode, for the serializer with a string table, emit the
189  // metadata first and set DidEmitMeta to avoid emitting it again.
191  std::unique_ptr<MetaSerializer> MetaSerializer =
192  metaSerializer(OS, /*ExternalFilename=*/None);
193  MetaSerializer->emit();
194  DidEmitMeta = true;
195  }
196 
197  // Then do the usual remark emission.
199 }
200 
201 std::unique_ptr<MetaSerializer> YAMLStrTabRemarkSerializer::metaSerializer(
202  raw_ostream &OS, Optional<StringRef> ExternalFilename) {
203  assert(StrTab);
204  return std::make_unique<YAMLStrTabMetaSerializer>(OS, ExternalFilename,
205  *StrTab);
206 }
207 
208 static void emitMagic(raw_ostream &OS) {
209  // Emit the magic number.
210  OS << remarks::Magic;
211  // Explicitly emit a '\0'.
212  OS.write('\0');
213 }
214 
215 static void emitVersion(raw_ostream &OS) {
216  // Emit the version number: little-endian uint64_t.
217  std::array<char, 8> Version;
219  OS.write(Version.data(), Version.size());
220 }
221 
223  // Emit the string table in the section.
224  uint64_t StrTabSize = StrTab ? (*StrTab)->SerializedSize : 0;
225  // Emit the total size of the string table (the size itself excluded):
226  // little-endian uint64_t.
227  // Note: even if no string table is used, emit 0.
228  std::array<char, 8> StrTabSizeBuf;
229  support::endian::write64le(StrTabSizeBuf.data(), StrTabSize);
230  OS.write(StrTabSizeBuf.data(), StrTabSizeBuf.size());
231  if (StrTab)
232  (*StrTab)->serialize(OS);
233 }
234 
235 static void emitExternalFile(raw_ostream &OS, StringRef Filename) {
236  // Emit the null-terminated absolute path to the remark file.
237  SmallString<128> FilenameBuf = Filename;
238  sys::fs::make_absolute(FilenameBuf);
239  assert(!FilenameBuf.empty() && "The filename can't be empty.");
240  OS.write(FilenameBuf.data(), FilenameBuf.size());
241  OS.write('\0');
242 }
243 
245  emitMagic(OS);
246  emitVersion(OS);
247  emitStrTab(OS, None);
248  if (ExternalFilename)
250 }
251 
253  emitMagic(OS);
254  emitVersion(OS);
255  emitStrTab(OS, &StrTab);
256  if (ExternalFilename)
258 }
llvm::remarks::SerializerMode
SerializerMode
Definition: RemarkSerializer.h:24
emitExternalFile
static void emitExternalFile(raw_ostream &OS, StringRef Filename)
Definition: YAMLRemarkSerializer.cpp:235
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:29
llvm
Definition: AllocatorList.h:23
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:201
llvm::remarks::StringTable
The string table used for serializing remarks.
Definition: RemarkStringTable.h:36
FileSystem.h
llvm::StringRef::count
LLVM_NODISCARD size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:487
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:215
llvm::yaml::BlockScalarTraits< StringBlockVal >::input
static StringRef input(StringRef Scalar, void *Ctx, StringBlockVal &S)
Definition: YAMLRemarkSerializer.cpp:115
output
Current output
Definition: README.txt:1350
emitMagic
static void emitMagic(raw_ostream &OS)
Definition: YAMLRemarkSerializer.cpp:208
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:47
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:42
llvm::yaml::MappingTraits
Definition: ModuleSummaryIndex.h:50
llvm::remarks::RemarkSerializer::Mode
SerializerMode Mode
The serialization mode.
Definition: RemarkSerializer.h:44
llvm::remarks::YAMLStrTabMetaSerializer::emit
void emit() override
Definition: YAMLRemarkSerializer.cpp:252
CommandLine.h
emitStrTab
static void emitStrTab(raw_ostream &OS, Optional< const StringTable * > StrTab)
Definition: YAMLRemarkSerializer.cpp:222
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
remarks
annotation remarks
Definition: AnnotationRemarks.cpp:117
llvm::raw_ostream::write
raw_ostream & write(unsigned char C)
Definition: raw_ostream.cpp:220
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:50
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:991
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:162
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::None
const NoneType None
Definition: None.h:23
llvm::remarks::RemarkSerializer
This is the base class for a remark serializer.
Definition: RemarkSerializer.h:38
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:244
llvm::remarks::Type::Passed
@ Passed
llvm::remarks::Type::Analysis
@ Analysis
index
splat index
Definition: README_ALTIVEC.txt:181
llvm::yaml::SequenceTraits< ArrayRef< T > >::size
static size_t size(IO &io, ArrayRef< T > &seq)
Definition: YAMLRemarkSerializer.cpp:127
llvm::yaml::StringBlockVal::Value
StringRef Value
Definition: YAMLRemarkSerializer.cpp:106
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:111
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:1540
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:901
llvm::yaml::StringBlockVal
Helper struct for multiline string block literals.
Definition: YAMLRemarkSerializer.cpp:105
llvm::remarks::MetaSerializer::OS
raw_ostream & OS
The open raw_ostream that the metadata is emitted to.
Definition: RemarkSerializer.h:66
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:182
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:58
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:136
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:187
llvm::yaml::SequenceTraits< ArrayRef< T > >::element
static Argument & element(IO &io, ArrayRef< T > &seq, size_t index)
Definition: YAMLRemarkSerializer.cpp:128
llvm::remarks::MetaSerializer
This is the base class for a remark metadata serializer.
Definition: RemarkSerializer.h:64
std
Definition: BitVector.h:838
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:174
llvm::yaml::StringBlockVal::StringBlockVal
StringBlockVal(StringRef R)
Definition: YAMLRemarkSerializer.cpp:107
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:389
llvm::seq
iterator_range< detail::value_sequence_iterator< ValueT > > seq(ValueT Begin, ValueT End)
Definition: Sequence.h:79
llvm::yaml::MappingTraits< Argument >::mapping
static void mapping(IO &io, Argument &A)
Definition: YAMLRemarkSerializer.cpp:137
llvm::remarks::Type::AnalysisFPCommute
@ AnalysisFPCommute
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
File
Instrumentation for Order File
Definition: InstrOrderFile.cpp:206
PassName
static const char PassName[]
Definition: X86LowerAMXIntrinsics.cpp:669
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