1 | //===-------- StackMapPrinter.h - Pretty-print stackmaps --------*- 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 | #ifndef LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H |
10 | #define LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H |
11 | |
12 | #include "llvm/Object/StackMapParser.h" |
13 | #include "llvm/Support/ScopedPrinter.h" |
14 | |
15 | namespace llvm { |
16 | |
17 | // Pretty print a stackmap to the given ostream. |
18 | template <typename StackMapParserT> |
19 | void prettyPrintStackMap(ScopedPrinter &W, const StackMapParserT &SMP) { |
20 | |
21 | W.printNumber("LLVM StackMap Version" , SMP.getVersion()); |
22 | W.printNumber("Num Functions" , SMP.getNumFunctions()); |
23 | |
24 | // Functions: |
25 | for (const auto &F : SMP.functions()) |
26 | W.startLine() << " Function address: " << F.getFunctionAddress() |
27 | << ", stack size: " << F.getStackSize() |
28 | << ", callsite record count: " << F.getRecordCount() << "\n" ; |
29 | |
30 | // Constants: |
31 | W.printNumber("Num Constants" , SMP.getNumConstants()); |
32 | unsigned ConstantIndex = 0; |
33 | for (const auto &C : SMP.constants()) |
34 | W.startLine() << " #" << ++ConstantIndex << ": " << C.getValue() << "\n" ; |
35 | |
36 | // Records: |
37 | W.printNumber("Num Records" , SMP.getNumRecords()); |
38 | for (const auto &R : SMP.records()) { |
39 | W.startLine() << " Record ID: " << R.getID() |
40 | << ", instruction offset: " << R.getInstructionOffset() |
41 | << "\n" ; |
42 | W.startLine() << " " << R.getNumLocations() << " locations:\n" ; |
43 | |
44 | unsigned LocationIndex = 0; |
45 | for (const auto &Loc : R.locations()) { |
46 | raw_ostream &OS = W.startLine(); |
47 | OS << " #" << ++LocationIndex << ": " ; |
48 | switch (Loc.getKind()) { |
49 | case StackMapParserT::LocationKind::Register: |
50 | OS << "Register R#" << Loc.getDwarfRegNum(); |
51 | break; |
52 | case StackMapParserT::LocationKind::Direct: |
53 | OS << "Direct R#" << Loc.getDwarfRegNum() << " + " << Loc.getOffset(); |
54 | break; |
55 | case StackMapParserT::LocationKind::Indirect: |
56 | OS << "Indirect [R#" << Loc.getDwarfRegNum() << " + " << Loc.getOffset() |
57 | << "]" ; |
58 | break; |
59 | case StackMapParserT::LocationKind::Constant: |
60 | OS << "Constant " << Loc.getSmallConstant(); |
61 | break; |
62 | case StackMapParserT::LocationKind::ConstantIndex: |
63 | OS << "ConstantIndex #" << Loc.getConstantIndex() << " (" |
64 | << SMP.getConstant(Loc.getConstantIndex()).getValue() << ")" ; |
65 | break; |
66 | } |
67 | OS << ", size: " << Loc.getSizeInBytes() << "\n" ; |
68 | } |
69 | |
70 | raw_ostream &OS = W.startLine(); |
71 | OS << " " << R.getNumLiveOuts() << " live-outs: [ " ; |
72 | for (const auto &LO : R.liveouts()) |
73 | OS << "R#" << LO.getDwarfRegNum() << " (" |
74 | << LO.getSizeInBytes() << "-bytes) " ; |
75 | OS << "]\n" ; |
76 | } |
77 | } |
78 | |
79 | } |
80 | |
81 | #endif |
82 | |