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