1 /*
2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "llvm_aot_compiler.h"
17
18 namespace ark::llvmbackend {
19
DumpStackMap(const std::unique_ptr<const LLVMStackMap> & stackmap,std::ostream & stream)20 void CodeInfoProducer::DumpStackMap(const std::unique_ptr<const LLVMStackMap> &stackmap, std::ostream &stream)
21 {
22 stream << "Header {" << std::endl;
23 stream << " Stack Map Version (current version is 3) [uint8]: " << stackmap->getVersion() << std::endl;
24 stream << "}" << std::endl;
25
26 stream << "StkSizeRecord [" << stackmap->getNumFunctions() << "]: [" << std::endl;
27 for (const auto &rec : stackmap->functions()) {
28 stream << " {" << std::endl;
29 DumpStackMapFunction(rec, stream, " ");
30 stream << " }" << std::endl;
31 }
32 stream << ']' << std::endl;
33
34 stream << "Constants [" << stackmap->getNumConstants() << "]: [" << std::endl;
35 for (const auto &cst : stackmap->constants()) {
36 stream << " LargeConstant [uint64] : " << cst.getValue() << std::endl;
37 }
38 stream << ']' << std::endl;
39
40 stream << "StkMapRecord [" << stackmap->getNumRecords() << "]: [" << std::endl;
41 for (const auto &rec : stackmap->records()) {
42 stream << " {" << std::endl;
43 DumpStackMapRecord(rec, stream, " ");
44 stream << " }" << std::endl;
45 }
46 stream << ']' << std::endl;
47 }
48
DumpStackMapFunction(const LLVMStackMap::FunctionAccessor & function,std::ostream & stream,const std::string & prefix)49 void CodeInfoProducer::DumpStackMapFunction(const LLVMStackMap::FunctionAccessor &function, std::ostream &stream,
50 const std::string &prefix)
51 {
52 stream << prefix << "Function Address [uint64]: 0x" << std::hex << function.getFunctionAddress() << std::dec
53 << std::endl;
54 stream << prefix << "Stack Size [uint64]: 0x" << std::hex << function.getStackSize() << std::dec << std::endl;
55 stream << prefix << "Record Count [uint64]: " << function.getRecordCount() << std::endl;
56 }
57
DumpStackMapRecord(const LLVMStackMap::RecordAccessor & record,std::ostream & stream,const std::string & prefix)58 void CodeInfoProducer::DumpStackMapRecord(const LLVMStackMap::RecordAccessor &record, std::ostream &stream,
59 const std::string &prefix)
60 {
61 stream << prefix << "PatchPoint ID [uint64]: " << record.getID() << std::endl;
62 stream << prefix << "Instruction Offset [uint32]: 0x" << std::hex << record.getInstructionOffset() << std::dec
63 << std::endl;
64 stream << prefix << "Location [" << record.getNumLocations() << "]: [" << std::endl;
65 for (const auto &loc : record.locations()) {
66 stream << prefix << " {" << std::endl;
67 DumpStackMapLocation(loc, stream, prefix + " ");
68 stream << prefix << " }" << std::endl;
69 }
70 stream << prefix << "]" << std::endl;
71
72 stream << prefix << "LiveOuts [" << record.getNumLiveOuts() << "]: [" << std::endl;
73 for (const auto &liveout : record.liveouts()) {
74 stream << prefix << " {" << std::endl;
75 stream << prefix << " Dwarf RegNum [uint16]: " << liveout.getDwarfRegNum() << std::endl;
76 stream << prefix << " Size in Bytes [uint8_t]: " << liveout.getSizeInBytes() << std::endl;
77 stream << prefix << " }" << std::endl;
78 }
79 stream << prefix << "]" << std::endl;
80 }
81
DumpStackMapLocation(const LLVMStackMap::LocationAccessor & location,std::ostream & stream,const std::string & prefix)82 void CodeInfoProducer::DumpStackMapLocation(const LLVMStackMap::LocationAccessor &location, std::ostream &stream,
83 const std::string &prefix)
84 {
85 const char *kind;
86 switch (location.getKind()) {
87 case LLVMStackMap::LocationKind::Register:
88 kind = "0x1 | Register | Reg | Value in a register";
89 break;
90 case LLVMStackMap::LocationKind::Direct:
91 kind = "0x2 | Direct | Reg + Offset | Frame index value";
92 break;
93 case LLVMStackMap::LocationKind::Indirect:
94 kind = "0x3 | Indirect | [Reg + Offset] | Spilled value";
95 break;
96 case LLVMStackMap::LocationKind::Constant:
97 kind = "0x4 | Constant | Offset | Small constant";
98 break;
99 case LLVMStackMap::LocationKind::ConstantIndex:
100 kind = "0x5 | ConstIndex | Constants[Offset] | Large constant";
101 break;
102 default:
103 kind = "Unknown";
104 break;
105 }
106 stream << prefix << "Kind [uint8]: " << kind << std::endl;
107 stream << prefix << "Location Size [uint16]: " << location.getSizeInBytes() << std::endl;
108 stream << prefix << "Dwarf RegNum [uint16]: " << location.getDwarfRegNum() << std::endl;
109 switch (location.getKind()) {
110 case LLVMStackMap::LocationKind::Register:
111 stream << 0;
112 break;
113 case LLVMStackMap::LocationKind::Direct:
114 case LLVMStackMap::LocationKind::Indirect:
115 stream << prefix << "Offset [int32]: " << location.getOffset();
116 break;
117 case LLVMStackMap::LocationKind::Constant:
118 stream << prefix << "SmallConstant [int32]: " << location.getSmallConstant();
119 break;
120 case LLVMStackMap::LocationKind::ConstantIndex:
121 stream << prefix << "ConstantIndex [int32]: " << location.getConstantIndex();
122 break;
123 default:
124 stream << "Unknown";
125 break;
126 }
127 stream << std::endl;
128 }
129
130 } // namespace ark::llvmbackend
131