• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #ifndef MAPLEBE_INCLUDE_CG_STACKMAP_H
17 #define MAPLEBE_INCLUDE_CG_STACKMAP_H
18 /* Maple IR header */
19 #include "operand.h"
20 #include "mempool.h"
21 #include "mempool_allocator.h"
22 
23 namespace maplebe {
24 using namespace maple;
25 enum VregLocationKind {
26     kUnknownDeoptKind,
27     kOnStack,
28     kInRegister,
29     kInConstValue,
30 };
31 
32 struct LocationInfo {
33     VregLocationKind locationKind;
34     int64 value;  // physical registerNO, stack frame offset, or immediate value
35 };
36 
37 struct DeoptVregLocationInfo {
38     int32 deoptVreg;
39     LocationInfo locationInfo;
40 
DeoptVregLocationInfoDeoptVregLocationInfo41     DeoptVregLocationInfo(int32 vreg, LocationInfo info) : deoptVreg(vreg), locationInfo(info) {}
42 };
43 
44 class DataEncoder {
45 public:
EncodeLEB128(int64 value,std::vector<uint8_t> & res)46     void EncodeLEB128(int64 value, std::vector<uint8_t> &res) const
47     {
48         bool needDecodeNextByte = true;
49         while (needDecodeNextByte) {
50             uint8 byte = static_cast<uint8>(static_cast<uint64_t>(value) & LOW_7_BITS_MASK);
51             value >>= DATA_BITS_SHIFT;
52             if ((value == 0 && (byte & FLAG_MASK) == 0) ||
53                 (value == -1 && (byte & FLAG_MASK) != 0)) {
54                 needDecodeNextByte = false;
55             } else {
56                 byte |= NEXT_BYTE_FLAG_MASK;
57             }
58             res.push_back(byte);
59         }
60     }
61 private:
62     const uint8 FLAG_MASK = 0x40;
63     const uint8 LOW_7_BITS_MASK = 0x7f;
64     const uint8 NEXT_BYTE_FLAG_MASK = 0x80;
65     const uint8 DATA_BITS_SHIFT = 7;
66 };
67 
68 class DeoptInfo : public DataEncoder {
69 public:
DeoptInfo(MapleAllocator & alloc)70     DeoptInfo(MapleAllocator &alloc) : deoptVreg2Opnd(alloc.Adapter()), deoptVreg2LocationInfo(alloc.Adapter()) {}
71     ~DeoptInfo() = default;
72 
AddDeoptBundleInfo(int32 deoptVreg,Operand & opnd)73     void AddDeoptBundleInfo(int32 deoptVreg, Operand &opnd)
74     {
75         deoptVreg2Opnd.insert(std::pair<int32, Operand *>(deoptVreg, &opnd));
76     }
77 
ReplaceDeoptBundleInfo(int32 deoptVreg,Operand & opnd)78     void ReplaceDeoptBundleInfo(int32 deoptVreg, Operand &opnd)
79     {
80         deoptVreg2Opnd.insert_or_assign(deoptVreg, &opnd);
81     }
82 
GetDeoptBundleInfo()83     const MapleUnorderedMap<int32, Operand *> &GetDeoptBundleInfo() const
84     {
85         return deoptVreg2Opnd;
86     }
87 
RecordDeoptVreg2LocationInfo(int32 deoptVregNO,LocationInfo locationInfo)88     void RecordDeoptVreg2LocationInfo(int32 deoptVregNO, LocationInfo locationInfo)
89     {
90         deoptVreg2LocationInfo.emplace_back(deoptVregNO, locationInfo);
91     }
92 
GetDeoptVreg2LocationInfo()93     const MapleVector<DeoptVregLocationInfo> &GetDeoptVreg2LocationInfo() const
94     {
95         return deoptVreg2LocationInfo;
96     }
97 
Dump()98     void Dump() const
99     {
100         for (const auto &elem : deoptVreg2LocationInfo) {
101             LogInfo::MapleLogger() << "    deoptVreg: " << elem.deoptVreg;
102             if (elem.locationInfo.locationKind == kInRegister) {
103                 LogInfo::MapleLogger() << "  in register: " << elem.locationInfo.value << "\n";
104             } else if (elem.locationInfo.locationKind == kOnStack) {
105                 LogInfo::MapleLogger() << "  on stack: " << elem.locationInfo.value << "\n";
106             } else {
107                 LogInfo::MapleLogger() << "  in const value: " << elem.locationInfo.value << "\n";
108             }
109         }
110     }
111 
SerializeInfo()112     std::vector<uint8> SerializeInfo() const
113     {
114         std::vector<uint8> info;
115         for (const auto &elem : deoptVreg2LocationInfo) {
116             EncodeLEB128(static_cast<int64_t>(elem.deoptVreg), info);
117             EncodeLEB128(static_cast<int64_t>(elem.locationInfo.locationKind), info);
118             EncodeLEB128(static_cast<int64_t>(elem.locationInfo.value), info);
119         }
120         return info;
121     }
122 
123 private:
124     // info before RA
125     MapleUnorderedMap<int32, Operand *> deoptVreg2Opnd;
126     MapleVector<DeoptVregLocationInfo> deoptVreg2LocationInfo;
127 };
128 
129 class ReferenceMap : public DataEncoder {
130 public:
ReferenceMap(MapleAllocator & alloc)131     ReferenceMap(MapleAllocator &alloc) : referenceLocations(alloc.Adapter()) {}
132     ~ReferenceMap() = default;
ReocordRegisterRoots(uint32 regNO)133     void ReocordRegisterRoots(uint32 regNO)
134     {
135         referenceLocations.push_back({kInRegister, regNO});
136     }
137 
ReocordStackRoots(int64 offset)138     void ReocordStackRoots(int64 offset)
139     {
140         referenceLocations.push_back({kOnStack, offset});
141     }
142 
GetReferenceLocations()143     const MapleVector<LocationInfo> &GetReferenceLocations() const
144     {
145         return referenceLocations;
146     }
147 
Dump()148     void Dump() const
149     {
150         for (const auto &elem : referenceLocations) {
151             if (elem.locationKind == kInRegister) {
152                 LogInfo::MapleLogger() << "    in register: " << elem.value << "\n";
153             } else {
154                 LogInfo::MapleLogger() << "    on stack: " << elem.value << "\n";
155             }
156         }
157     }
158 
SerializeInfo()159     std::vector<uint8> SerializeInfo() const
160     {
161         std::vector<uint8> info;
162         for (const auto &elem : referenceLocations) {
163             EncodeLEB128(static_cast<int64_t>(elem.locationKind), info);
164             EncodeLEB128(static_cast<int64_t>(elem.value), info);
165         }
166         return info;
167     }
168 
169 private:
170     MapleVector<LocationInfo> referenceLocations;
171 };
172 
173 class StackMap {
174 public:
StackMap(MapleAllocator & alloc)175     StackMap(MapleAllocator &alloc) : deoptInfo(alloc), referenceMap(alloc) {}
176     ~StackMap() = default;
177 
GetDeoptInfo()178     DeoptInfo &GetDeoptInfo()
179     {
180         return deoptInfo;
181     }
182 
GetDeoptInfo()183     const DeoptInfo &GetDeoptInfo() const
184     {
185         return deoptInfo;
186     }
187 
GetReferenceMap()188     ReferenceMap &GetReferenceMap()
189     {
190         return referenceMap;
191     }
192 
GetReferenceMap()193     const ReferenceMap &GetReferenceMap() const
194     {
195         return referenceMap;
196     }
197 
198 private:
199     DeoptInfo deoptInfo;
200     ReferenceMap referenceMap;
201 };
202 } /* namespace maplebe */
203 
204 #endif /* MAPLEBE_INCLUDE_CG_STACKMAP_H */
205