LLVM  15.0.0git
LinePrinter.cpp
Go to the documentation of this file.
1 //===- LinePrinter.cpp ------------------------------------------*- 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 
10 
11 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/Object/COFF.h"
22 #include "llvm/Support/Format.h"
25 #include "llvm/Support/Regex.h"
26 
27 #include <algorithm>
28 
29 using namespace llvm;
30 using namespace llvm::msf;
31 using namespace llvm::pdb;
32 
33 namespace {
34 bool IsItemExcluded(llvm::StringRef Item,
35  std::list<llvm::Regex> &IncludeFilters,
36  std::list<llvm::Regex> &ExcludeFilters) {
37  if (Item.empty())
38  return false;
39 
40  auto match_pred = [Item](llvm::Regex &R) { return R.match(Item); };
41 
42  // Include takes priority over exclude. If the user specified include
43  // filters, and none of them include this item, them item is gone.
44  if (!IncludeFilters.empty() && !any_of(IncludeFilters, match_pred))
45  return true;
46 
47  if (any_of(ExcludeFilters, match_pred))
48  return true;
49 
50  return false;
51 }
52 } // namespace
53 
54 using namespace llvm;
55 
56 LinePrinter::LinePrinter(int Indent, bool UseColor, llvm::raw_ostream &Stream,
57  const FilterOptions &Filters)
58  : OS(Stream), IndentSpaces(Indent), CurrentIndent(0), UseColor(UseColor),
59  Filters(Filters) {
60  SetFilters(ExcludeTypeFilters, Filters.ExcludeTypes.begin(),
61  Filters.ExcludeTypes.end());
62  SetFilters(ExcludeSymbolFilters, Filters.ExcludeSymbols.begin(),
63  Filters.ExcludeSymbols.end());
64  SetFilters(ExcludeCompilandFilters, Filters.ExcludeCompilands.begin(),
65  Filters.ExcludeCompilands.end());
66 
67  SetFilters(IncludeTypeFilters, Filters.IncludeTypes.begin(),
68  Filters.IncludeTypes.end());
69  SetFilters(IncludeSymbolFilters, Filters.IncludeSymbols.begin(),
70  Filters.IncludeSymbols.end());
71  SetFilters(IncludeCompilandFilters, Filters.IncludeCompilands.begin(),
72  Filters.IncludeCompilands.end());
73 }
74 
76  if (Amount == 0)
77  Amount = IndentSpaces;
78  CurrentIndent += Amount;
79 }
80 
82  if (Amount == 0)
83  Amount = IndentSpaces;
84  CurrentIndent = std::max<int>(0, CurrentIndent - Amount);
85 }
86 
88  OS << "\n";
89  OS.indent(CurrentIndent);
90 }
91 
92 void LinePrinter::print(const Twine &T) { OS << T; }
93 
95  NewLine();
96  OS << T;
97 }
98 
100  if (IsTypeExcluded(Class.getName(), Class.getSize()))
101  return true;
102  if (Class.deepPaddingSize() < Filters.PaddingThreshold)
103  return true;
104  return false;
105 }
106 
108  uint64_t StartOffset) {
109  NewLine();
110  OS << Label << " (";
111  if (!Data.empty()) {
112  OS << "\n";
113  OS << format_bytes_with_ascii(Data, StartOffset, 32, 4,
114  CurrentIndent + IndentSpaces, true);
115  NewLine();
116  }
117  OS << ")";
118 }
119 
121  uint64_t Base, uint64_t StartOffset) {
122  NewLine();
123  OS << Label << " (";
124  if (!Data.empty()) {
125  OS << "\n";
126  Base += StartOffset;
127  OS << format_bytes_with_ascii(Data, Base, 32, 4,
128  CurrentIndent + IndentSpaces, true);
129  NewLine();
130  }
131  OS << ")";
132 }
133 
134 namespace {
135 struct Run {
136  Run() = default;
137  explicit Run(uint32_t Block) : Block(Block) {}
138  uint32_t Block = 0;
139  uint64_t ByteLen = 0;
140 };
141 } // namespace
142 
143 static std::vector<Run> computeBlockRuns(uint32_t BlockSize,
144  const msf::MSFStreamLayout &Layout) {
145  std::vector<Run> Runs;
146  if (Layout.Length == 0)
147  return Runs;
148 
149  ArrayRef<support::ulittle32_t> Blocks = Layout.Blocks;
150  assert(!Blocks.empty());
151  uint64_t StreamBytesRemaining = Layout.Length;
152  uint32_t CurrentBlock = Blocks[0];
153  Runs.emplace_back(CurrentBlock);
154  while (!Blocks.empty()) {
155  Run *CurrentRun = &Runs.back();
156  uint32_t NextBlock = Blocks.front();
157  if (NextBlock < CurrentBlock || (NextBlock - CurrentBlock > 1)) {
158  Runs.emplace_back(NextBlock);
159  CurrentRun = &Runs.back();
160  }
161  uint64_t Used =
162  std::min(static_cast<uint64_t>(BlockSize), StreamBytesRemaining);
163  CurrentRun->ByteLen += Used;
164  StreamBytesRemaining -= Used;
165  CurrentBlock = NextBlock;
166  Blocks = Blocks.drop_front();
167  }
168  return Runs;
169 }
170 
171 static std::pair<Run, uint64_t> findRun(uint64_t Offset, ArrayRef<Run> Runs) {
172  for (const auto &R : Runs) {
173  if (Offset < R.ByteLen)
174  return std::make_pair(R, Offset);
175  Offset -= R.ByteLen;
176  }
177  llvm_unreachable("Invalid offset!");
178 }
179 
181  uint32_t StreamIdx,
182  StringRef StreamPurpose, uint64_t Offset,
183  uint64_t Size) {
184  if (StreamIdx >= File.getNumStreams()) {
185  formatLine("Stream {0}: Not present", StreamIdx);
186  return;
187  }
188  if (Size + Offset > File.getStreamByteSize(StreamIdx)) {
189  formatLine(
190  "Stream {0}: Invalid offset and size, range out of stream bounds",
191  StreamIdx);
192  return;
193  }
194 
195  auto S = File.createIndexedStream(StreamIdx);
196  if (!S) {
197  NewLine();
198  formatLine("Stream {0}: Not present", StreamIdx);
199  return;
200  }
201 
202  uint64_t End =
203  (Size == 0) ? S->getLength() : std::min(Offset + Size, S->getLength());
204  Size = End - Offset;
205 
206  formatLine("Stream {0}: {1} (dumping {2:N} / {3:N} bytes)", StreamIdx,
207  StreamPurpose, Size, S->getLength());
208  AutoIndent Indent(*this);
209  BinaryStreamRef Slice(*S);
210  BinarySubstreamRef Substream;
211  Substream.Offset = Offset;
212  Substream.StreamData = Slice.drop_front(Offset).keep_front(Size);
213 
214  auto Layout = File.getStreamLayout(StreamIdx);
215  formatMsfStreamData(Label, File, Layout, Substream);
216 }
217 
219  const msf::MSFStreamLayout &Stream,
220  BinarySubstreamRef Substream) {
221  BinaryStreamReader Reader(Substream.StreamData);
222 
223  auto Runs = computeBlockRuns(File.getBlockSize(), Stream);
224 
225  NewLine();
226  OS << Label << " (";
227  while (Reader.bytesRemaining() > 0) {
228  OS << "\n";
229 
230  Run FoundRun;
231  uint64_t RunOffset;
232  std::tie(FoundRun, RunOffset) = findRun(Substream.Offset, Runs);
233  assert(FoundRun.ByteLen >= RunOffset);
234  uint64_t Len = FoundRun.ByteLen - RunOffset;
235  Len = std::min(Len, Reader.bytesRemaining());
236  uint64_t Base = FoundRun.Block * File.getBlockSize() + RunOffset;
238  consumeError(Reader.readBytes(Data, Len));
239  OS << format_bytes_with_ascii(Data, Base, 32, 4,
240  CurrentIndent + IndentSpaces, true);
241  if (Reader.bytesRemaining() > 0) {
242  NewLine();
243  OS << formatv(" {0}",
244  fmt_align("<discontinuity>", AlignStyle::Center, 114, '-'));
245  }
246  Substream.Offset += Len;
247  }
248  NewLine();
249  OS << ")";
250 }
251 
253  PDBFile &File, const msf::MSFStreamLayout &StreamLayout) {
254  auto Blocks = makeArrayRef(StreamLayout.Blocks);
255  uint64_t L = StreamLayout.Length;
256 
257  while (L > 0) {
258  NewLine();
259  assert(!Blocks.empty());
260  OS << formatv("Block {0} (\n", uint32_t(Blocks.front()));
261  uint64_t UsedBytes =
262  std::min(L, static_cast<uint64_t>(File.getBlockSize()));
263  ArrayRef<uint8_t> BlockData =
264  cantFail(File.getBlockData(Blocks.front(), File.getBlockSize()));
265  uint64_t BaseOffset = Blocks.front();
266  BaseOffset *= File.getBlockSize();
267  OS << format_bytes_with_ascii(BlockData, BaseOffset, 32, 4,
268  CurrentIndent + IndentSpaces, true);
269  NewLine();
270  OS << ")";
271  NewLine();
272  L -= UsedBytes;
273  Blocks = Blocks.drop_front();
274  }
275 }
276 
278  if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters))
279  return true;
280  if (Size < Filters.SizeThreshold)
281  return true;
282  return false;
283 }
284 
286  return IsItemExcluded(SymbolName, IncludeSymbolFilters, ExcludeSymbolFilters);
287 }
288 
290  return IsItemExcluded(CompilandName, IncludeCompilandFilters,
291  ExcludeCompilandFilters);
292 }
293 
295  : OS(P.OS), UseColor(P.hasColor()) {
296  if (UseColor)
297  applyColor(C);
298 }
299 
301  if (UseColor)
302  OS.resetColor();
303 }
304 
305 void WithColor::applyColor(PDB_ColorItem C) {
306  switch (C) {
307  case PDB_ColorItem::None:
308  OS.resetColor();
309  return;
311  OS.changeColor(raw_ostream::GREEN, false);
312  return;
314  OS.changeColor(raw_ostream::YELLOW, /*bold=*/true);
315  return;
318  return;
321  OS.changeColor(raw_ostream::YELLOW, false);
322  return;
323  case PDB_ColorItem::Type:
324  OS.changeColor(raw_ostream::CYAN, true);
325  return;
327  OS.changeColor(raw_ostream::CYAN, false);
328  return;
329  case PDB_ColorItem::Path:
330  OS.changeColor(raw_ostream::CYAN, false);
331  return;
334  OS.changeColor(raw_ostream::RED, true);
335  return;
338  return;
339  }
340 }
UseColor
static ManagedStatic< cl::opt< cl::boolOrDefault >, CreateUseColor > UseColor
Definition: WithColor.cpp:33
BinaryStreamReader.h
FilterOptions::PaddingThreshold
uint32_t PaddingThreshold
Definition: LinePrinter.h:31
llvm::msf::MSFStreamLayout::Blocks
std::vector< support::ulittle32_t > Blocks
Definition: MSFCommon.h:80
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
BlockSize
static const int BlockSize
Definition: TarWriter.cpp:33
llvm::BinaryStreamReader::readBytes
Error readBytes(ArrayRef< uint8_t > &Buffer, uint32_t Size)
Read Size bytes from the underlying stream at the current offset and and set Buffer to the resulting ...
Definition: BinaryStreamReader.cpp:37
T
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::pdb::LinePrinter
Definition: LinePrinter.h:50
FilterOptions::IncludeTypes
std::list< std::string > IncludeTypes
Definition: LinePrinter.h:28
llvm::pdb::PDB_ColorItem::SectionHeader
@ SectionHeader
llvm::pdb::WithColor::WithColor
WithColor(LinePrinter &P, PDB_ColorItem C)
Definition: LinePrinter.cpp:294
llvm::pdb::PDB_ColorItem::Comment
@ Comment
llvm::raw_ostream::GREEN
static constexpr Colors GREEN
Definition: raw_ostream.h:113
UDTLayout.h
llvm::BinaryStreamReader::bytesRemaining
uint64_t bytesRemaining() const
Definition: BinaryStreamReader.h:250
FilterOptions::ExcludeSymbols
std::list< std::string > ExcludeSymbols
Definition: LinePrinter.h:26
llvm::raw_ostream::RED
static constexpr Colors RED
Definition: raw_ostream.h:112
STLExtras.h
findRun
static std::pair< Run, uint64_t > findRun(uint64_t Offset, ArrayRef< Run > Runs)
Definition: LinePrinter.cpp:171
Format.h
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::msf
Definition: IMSFFile.h:18
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:159
llvm::pdb::WithColor::~WithColor
~WithColor()
Definition: LinePrinter.cpp:300
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:241
llvm::pdb::LinePrinter::IsCompilandExcluded
bool IsCompilandExcluded(llvm::StringRef CompilandName)
Definition: LinePrinter.cpp:289
llvm::pdb::LinePrinter::print
void print(const Twine &T)
Definition: LinePrinter.cpp:92
llvm::raw_ostream::MAGENTA
static constexpr Colors MAGENTA
Definition: raw_ostream.h:116
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
llvm::raw_ostream::changeColor
virtual raw_ostream & changeColor(enum Colors Color, bool Bold=false, bool BG=false)
Changes the foreground color of text that will be output from this point forward.
Definition: raw_ostream.cpp:521
IPDBLineNumber.h
llvm::ArrayRef::back
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:173
FilterOptions
Definition: LinePrinter.h:24
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
LazyRandomTypeCollection.h
llvm::BinarySubstreamRef
Definition: BinaryStreamRef.h:199
FilterOptions::IncludeCompilands
std::list< std::string > IncludeCompilands
Definition: LinePrinter.h:30
llvm::BinarySubstreamRef::StreamData
BinaryStreamRef StreamData
Definition: BinaryStreamRef.h:201
llvm::pdb::LinePrinter::Indent
void Indent(uint32_t Amount=0)
Definition: LinePrinter.cpp:75
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::pdb::LinePrinter::IsTypeExcluded
bool IsTypeExcluded(llvm::StringRef TypeName, uint64_t Size)
Definition: LinePrinter.cpp:277
llvm::pdb::LinePrinter::formatBinary
void formatBinary(StringRef Label, ArrayRef< uint8_t > Data, uint64_t StartOffset)
Definition: LinePrinter.cpp:107
llvm::pdb::AutoIndent
Definition: LinePrinter.h:132
llvm::BinaryStreamRefBase::keep_front
RefType keep_front(uint64_t N) const
Return a new BinaryStreamRef with only the first N elements remaining.
Definition: BinaryStreamRef.h:98
llvm::pdb::PDB_ColorItem::Path
@ Path
FormatVariadic.h
llvm::pdb::LinePrinter::formatMsfStreamBlocks
void formatMsfStreamBlocks(PDBFile &File, const msf::MSFStreamLayout &Stream)
Definition: LinePrinter.cpp:252
llvm::pdb
Definition: ConcreteSymbolEnumerator.h:20
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition: BinaryStreamReader.h:29
llvm::pdb::LinePrinter::formatMsfStreamData
void formatMsfStreamData(StringRef Label, PDBFile &File, uint32_t StreamIdx, StringRef StreamPurpose, uint64_t Offset, uint64_t Size)
Definition: LinePrinter.cpp:180
llvm::pdb::LinePrinter::IsSymbolExcluded
bool IsSymbolExcluded(llvm::StringRef SymbolName)
Definition: LinePrinter.cpp:285
llvm::pdb::PDB_ColorItem::Address
@ Address
llvm::ArrayRef::drop_front
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:203
llvm::AlignStyle::Center
@ Center
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::pdb::PDB_ColorItem::Register
@ Register
uint64_t
llvm::pdb::PDB_ColorItem::None
@ None
llvm::pdb::LinePrinter::formatLine
void formatLine(const char *Fmt, Ts &&...Items)
Definition: LinePrinter.h:63
llvm::pdb::PDB_ColorItem::Type
@ Type
MappedBlockStream.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Regex.h
llvm::pdb::LinePrinter::Unindent
void Unindent(uint32_t Amount=0)
Definition: LinePrinter.cpp:81
llvm::pdb::LinePrinter::printLine
void printLine(const Twine &T)
Definition: LinePrinter.cpp:94
llvm::pdb::LinePrinter::IsClassExcluded
bool IsClassExcluded(const ClassLayout &Class)
Definition: LinePrinter.cpp:99
FilterOptions::ExcludeCompilands
std::list< std::string > ExcludeCompilands
Definition: LinePrinter.h:27
llvm::raw_ostream::CYAN
static constexpr Colors CYAN
Definition: raw_ostream.h:117
FilterOptions::ExcludeTypes
std::list< std::string > ExcludeTypes
Definition: LinePrinter.h:25
llvm::pdb::PDB_ColorItem::Offset
@ Offset
llvm::ArrayRef< uint8_t >
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1624
InputFile.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:745
uint32_t
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
MSFCommon.h
llvm::pdb::PDB_ColorItem::LiteralValue
@ LiteralValue
llvm::msf::MSFStreamLayout::Length
uint32_t Length
Definition: MSFCommon.h:79
llvm::ArrayRef::front
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:167
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition: AMDGPUMetadata.h:386
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::pdb::PDB_SymType::Label
@ Label
llvm::pdb::LinePrinter::NewLine
void NewLine()
Definition: LinePrinter.cpp:87
llvm::AMDGPU::HSAMD::Kernel::Arg::Key::TypeName
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
Definition: AMDGPUMetadata.h:175
LinePrinter.h
llvm::pdb::PDB_ColorItem::Padding
@ Padding
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:475
llvm::pdb::PDB_ColorItem::Identifier
@ Identifier
FormatAdapters.h
FilterOptions::IncludeSymbols
std::list< std::string > IncludeSymbols
Definition: LinePrinter.h:29
COFF.h
llvm::pdb::PDBFile
Definition: PDBFile.h:40
PDBFile.h
llvm::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Definition: raw_ostream.cpp:496
llvm::pdb::PDB_ColorItem
PDB_ColorItem
Definition: LinePrinter.h:155
llvm::raw_ostream::resetColor
virtual raw_ostream & resetColor()
Resets the colors to terminal defaults.
Definition: raw_ostream.cpp:534
FilterOptions::SizeThreshold
uint32_t SizeThreshold
Definition: LinePrinter.h:32
computeBlockRuns
static std::vector< Run > computeBlockRuns(uint32_t BlockSize, const msf::MSFStreamLayout &Layout)
Definition: LinePrinter.cpp:143
llvm::pdb::PDB_ColorItem::Keyword
@ Keyword
llvm::raw_ostream::YELLOW
static constexpr Colors YELLOW
Definition: raw_ostream.h:114
llvm::Regex
Definition: Regex.h:28
llvm::format_bytes_with_ascii
FormattedBytes format_bytes_with_ascii(ArrayRef< uint8_t > Bytes, Optional< uint64_t > FirstByteOffset=None, uint32_t NumPerLine=16, uint8_t ByteGroupSize=4, uint32_t IndentLevel=0, bool Upper=false)
Definition: Format.h:247
llvm::fmt_align
detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
Definition: FormatAdapters.h:86
llvm::BinarySubstreamRef::Offset
uint64_t Offset
Definition: BinaryStreamRef.h:200
llvm::pdb::PDB_SymType::Block
@ Block
llvm::BinaryStreamRefBase::drop_front
RefType drop_front(uint64_t N) const
Return a new BinaryStreamRef with the first N elements removed.
Definition: BinaryStreamRef.h:60
llvm::pdb::ClassLayout
Definition: UDTLayout.h:161
llvm::BinaryStreamRef
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
Definition: BinaryStreamRef.h:155
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::msf::MSFStreamLayout
Describes the layout of a stream in an MSF layout.
Definition: MSFCommon.h:77
NativeSession.h