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