1 /* 2 * Copyright (c) 2021-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 #ifndef PANDA_COMPILER_CODE_INFO_VREG_INFO_H 17 #define PANDA_COMPILER_CODE_INFO_VREG_INFO_H 18 19 #include "utils/bit_field.h" 20 21 namespace ark::compiler { 22 23 class VRegInfo final { 24 public: 25 enum class Location : int8_t { NONE, SLOT, REGISTER, FP_REGISTER, CONSTANT, COUNT = CONSTANT }; 26 27 static constexpr size_t INVALID_LOCATION = (1U << MinimumBitsToStore(static_cast<size_t>(Location::COUNT))) - 1; 28 29 enum class Type : uint8_t { UNDEFINED, OBJECT, INT32, INT64, FLOAT32, FLOAT64, BOOL, ANY, COUNT = ANY }; 30 31 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 32 #define VREGS_ENV_TYPE_DEFS(V) \ 33 V(THIS_FUNC) \ 34 V(CONST_POOL) \ 35 V(LEX_ENV) 36 37 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 38 #define VREG_ENV_TYPE(ENV_TYPE) ENV_TYPE, // CC-OFF(G.PRE.02) list generation 39 enum VRegType : uint8_t { VREG, ACC, VREGS_ENV_TYPE_DEFS(VREG_ENV_TYPE) COUNT, ENV_BEGIN = THIS_FUNC }; 40 #undef VREG_ENV_TYPE 41 42 static constexpr uint8_t ENV_COUNT = VRegType::COUNT - VRegType::ENV_BEGIN; 43 VRegInfo()44 VRegInfo() 45 { 46 FieldLocation::Set(Location::NONE, &info_); 47 ASSERT(!IsLive()); 48 } VRegInfo(uint32_t value,VRegInfo::Location location,Type type,VRegType vregType)49 VRegInfo(uint32_t value, VRegInfo::Location location, Type type, VRegType vregType) 50 : value_(value), 51 info_(FieldLocation::Encode(location) | FieldType::Encode(type) | FieldVRegType::Encode(vregType)) 52 { 53 } VRegInfo(uint32_t value,VRegInfo::Location location,Type type,VRegType vregType,uint32_t index)54 VRegInfo(uint32_t value, VRegInfo::Location location, Type type, VRegType vregType, uint32_t index) 55 : VRegInfo(value, location, type, vregType) 56 { 57 FieldVRegIndex::Set(index, &info_); 58 } VRegInfo(uint32_t value,uint32_t packedInfo)59 VRegInfo(uint32_t value, uint32_t packedInfo) : value_(value), info_(packedInfo) {} 60 Invalid()61 static VRegInfo Invalid() 62 { 63 return VRegInfo(0, static_cast<Location>(INVALID_LOCATION), Type::UNDEFINED, VRegType::VREG); 64 } 65 66 ~VRegInfo() = default; 67 68 DEFAULT_COPY_SEMANTIC(VRegInfo); 69 DEFAULT_MOVE_SEMANTIC(VRegInfo); 70 GetValue()71 uint32_t GetValue() const 72 { 73 return value_; 74 } 75 SetValue(uint32_t value)76 void SetValue(uint32_t value) 77 { 78 value_ = value; 79 } 80 GetLocation()81 Location GetLocation() const 82 { 83 return FieldLocation::Get(info_); 84 } 85 GetType()86 Type GetType() const 87 { 88 return FieldType::Get(info_); 89 } 90 GetIndex()91 uint16_t GetIndex() const 92 { 93 return FieldVRegIndex::Get(info_); 94 } SetIndex(uint16_t value)95 void SetIndex(uint16_t value) 96 { 97 FieldVRegIndex::Set(value, &info_); 98 } 99 GetVRegType()100 VRegType GetVRegType() const 101 { 102 return FieldVRegType::Get(info_); 103 } 104 IsAccumulator()105 bool IsAccumulator() const 106 { 107 return FieldVRegType::Get(info_) == VRegType::ACC; 108 } 109 IsSpecialVReg()110 bool IsSpecialVReg() const 111 { 112 return GetVRegType() != VRegType::VREG; 113 } 114 IsLive()115 bool IsLive() const 116 { 117 return GetLocation() != Location::NONE; 118 } 119 IsObject()120 bool IsObject() const 121 { 122 return GetType() == Type::OBJECT; 123 } 124 IsFloat()125 bool IsFloat() const 126 { 127 return GetType() == Type::FLOAT32 || GetType() == Type::FLOAT64; 128 } 129 Has64BitValue()130 bool Has64BitValue() const 131 { 132 return GetType() == VRegInfo::Type::FLOAT64 || GetType() == VRegInfo::Type::INT64; 133 } 134 IsLocationRegister()135 bool IsLocationRegister() const 136 { 137 auto location = GetLocation(); 138 return location == Location::REGISTER || location == Location::FP_REGISTER; 139 } 140 GetConstantLowIndex()141 uint32_t GetConstantLowIndex() const 142 { 143 ASSERT(GetLocation() == Location::CONSTANT); 144 return GetValue() & ((1U << BITS_PER_UINT16) - 1); 145 } 146 GetConstantHiIndex()147 uint32_t GetConstantHiIndex() const 148 { 149 ASSERT(GetLocation() == Location::CONSTANT); 150 return (GetValue() >> BITS_PER_UINT16) & ((1U << BITS_PER_UINT16) - 1); 151 } 152 SetConstantIndices(uint16_t low,uint16_t hi)153 void SetConstantIndices(uint16_t low, uint16_t hi) 154 { 155 value_ = low | (static_cast<uint32_t>(hi) << BITS_PER_UINT16); 156 } 157 158 bool operator==(const VRegInfo &rhs) const 159 { 160 return value_ == rhs.value_ && info_ == rhs.info_; 161 } 162 bool operator!=(const VRegInfo &rhs) const 163 { 164 return !(*this == rhs); 165 } 166 GetInfo()167 uint32_t GetInfo() 168 { 169 return info_; 170 } 171 GetTypeString()172 const char *GetTypeString() const 173 { 174 switch (GetType()) { 175 case Type::OBJECT: 176 return "OBJECT"; 177 case Type::INT64: 178 return "INT64"; 179 case Type::INT32: 180 return "INT32"; 181 case Type::FLOAT32: 182 return "FLOAT32"; 183 case Type::FLOAT64: 184 return "FLOAT64"; 185 case Type::BOOL: 186 return "BOOL"; 187 case Type::ANY: 188 return "ANY"; 189 default: 190 break; 191 } 192 UNREACHABLE(); 193 } 194 GetLocationString()195 const char *GetLocationString() const 196 { 197 switch (GetLocation()) { 198 case Location::NONE: 199 return "NONE"; 200 case Location::SLOT: 201 return "SLOT"; 202 case Location::REGISTER: 203 return "REGISTER"; 204 case Location::FP_REGISTER: 205 return "FP_REGISTER"; 206 case Location::CONSTANT: 207 return "CONSTANT"; 208 default: 209 break; 210 } 211 UNREACHABLE(); 212 } 213 VRegTypeToString(VRegType type)214 static inline const char *VRegTypeToString(VRegType type) 215 { 216 static constexpr auto N = static_cast<uint8_t>(VRegType::COUNT); 217 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 218 #define VREG_ENV_TYPE_TO_STR(ENV_TYPE) #ENV_TYPE, 219 static constexpr std::array<const char *, N> VREG_TYPE_NAMES = {"VREG", "ACC", 220 VREGS_ENV_TYPE_DEFS(VREG_ENV_TYPE_TO_STR)}; 221 #undef VREG_ENV_TYPE_TO_STR 222 auto idx = static_cast<uint8_t>(type); 223 ASSERT(idx < N); 224 return VREG_TYPE_NAMES[idx]; 225 } 226 Dump(std::ostream & os)227 void Dump(std::ostream &os) const 228 { 229 os << "VReg #" << GetIndex() << ":" << GetTypeString() << ", " << VRegTypeToString(GetVRegType()) << ", " 230 << GetLocationString() << "=" << helpers::ToSigned(GetValue()); 231 } 232 233 private: 234 uint32_t value_ {0}; 235 uint32_t info_ {0}; 236 237 using FieldLocation = BitField<Location, 0, MinimumBitsToStore(static_cast<uint32_t>(Location::COUNT))>; 238 using FieldType = FieldLocation::NextField<Type, MinimumBitsToStore(static_cast<uint32_t>(Type::COUNT))>; 239 using FieldVRegType = FieldType::NextField<VRegType, MinimumBitsToStore(static_cast<uint32_t>(VRegType::COUNT))>; 240 using FieldVRegIndex = FieldVRegType::NextField<uint16_t, BITS_PER_UINT16>; 241 }; 242 243 static_assert(sizeof(VRegInfo) <= sizeof(uint64_t)); 244 245 inline std::ostream &operator<<(std::ostream &os, const VRegInfo &vreg) 246 { 247 vreg.Dump(os); 248 return os; 249 } 250 251 } // namespace ark::compiler 252 253 #endif // PANDA_COMPILER_CODE_INFO_VREG_INFO_H 254