• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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