• 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_BE_BECOMMON_H
17 #define MAPLEBE_INCLUDE_BE_BECOMMON_H
18 /* C++ headers. */
19 #include <cstddef>
20 #include <utility>
21 /* Basic Maple-independent utility functions */
22 #include "common_utils.h"
23 /* MapleIR headers. */
24 #include "mir_nodes.h"  /* maple_ir/include, for BaseNode */
25 #include "mir_type.h"   /* maple_ir/include, for MIRType */
26 #include "mir_module.h" /* maple_ir/include, for mirModule */
27 
28 namespace maplebe {
29 using namespace maple;
30 
31 enum BitsPerByte : uint8 { kBitsPerByte = 8, kLog2BitsPerByte = 3 };
32 
GetPointerBitSize()33 inline uint32 GetPointerBitSize()
34 {
35     return GetPointerSize() * kBitsPerByte;
36 }
37 
38 class JClassFieldInfo {
39 public:
40     /* constructors */
JClassFieldInfo()41     JClassFieldInfo() : isRef(false), isUnowned(false), isWeak(false), offset(0) {}
42 
JClassFieldInfo(bool isRef,bool isUnowned,bool isWeak,uint32 offset)43     JClassFieldInfo(bool isRef, bool isUnowned, bool isWeak, uint32 offset)
44         : isRef(isRef), isUnowned(isUnowned), isWeak(isWeak), offset(offset)
45     {
46     }
47 
48     ~JClassFieldInfo() = default;
49 
IsRef()50     bool IsRef() const
51     {
52         return isRef;
53     }
54 
IsUnowned()55     bool IsUnowned() const
56     {
57         return isUnowned;
58     }
59 
IsWeak()60     bool IsWeak() const
61     {
62         return isWeak;
63     }
64 
GetOffset()65     uint32 GetOffset() const
66     {
67         return offset;
68     }
69 
70 private:
71     bool isRef;     /* used to generate object-map */
72     bool isUnowned; /* used to mark unowned fields for RC */
73     bool isWeak;    /* used to mark weak fields for RC */
74     uint32 offset;
75 };
76 
77 using JClassLayout = MapleVector<JClassFieldInfo>;
78 
79 class BECommon {
80 public:
81     explicit BECommon(MIRModule &mod);
82 
83     ~BECommon() = default;
84 
85     void ComputeTypeSizesAligns(MIRType &type, uint8 align = 0);
86 
87     void GenFieldOffsetMap(const std::string &className);
88 
89     void GenFieldOffsetMap(MIRClassType &classType, FILE &outFile);
90 
91     void GenObjSize(const MIRClassType &classType, FILE &outFile);
92 
93     std::pair<int32, int32> GetFieldOffset(MIRStructType &structType, FieldID fieldID);
94 
95     FieldInfo GetJClassFieldOffset(MIRStructType &classType, FieldID fieldID) const;
96 
97     bool IsRefField(MIRStructType &structType, FieldID fieldID) const;
98 
99     /* some class may has incomplete type definition. provide an interface to check them. */
HasJClassLayout(MIRClassType & klass)100     bool HasJClassLayout(MIRClassType &klass) const
101     {
102         return (jClassLayoutTable.find(&klass) != jClassLayoutTable.end());
103     }
104 
GetJClassLayout(MIRClassType & klass)105     const JClassLayout &GetJClassLayout(MIRClassType &klass) const
106     {
107         return *(jClassLayoutTable.at(&klass));
108     }
109 
110     void AddNewTypeAfterBecommon(uint32 oldTypeTableSize, uint32 newTypeTableSize);
111 
112     void AddElementToJClassLayout(MIRClassType &klass, JClassFieldInfo info);
113 
HasFuncReturnType(MIRFunction & func)114     bool HasFuncReturnType(MIRFunction &func) const
115     {
116         return (funcReturnType.find(&func) != funcReturnType.end());
117     }
118 
GetFuncReturnType(MIRFunction & func)119     const TyIdx GetFuncReturnType(MIRFunction &func) const
120     {
121         return (funcReturnType.at(&func));
122     }
123 
124     void AddElementToFuncReturnType(MIRFunction &func, const TyIdx tyIdx);
125 
126     MIRType *BeGetOrCreatePointerType(const MIRType &pointedType);
127 
128     MIRType *BeGetOrCreateFunctionType(TyIdx tyIdx, const std::vector<TyIdx> &vecTy,
129                                        const std::vector<TypeAttrs> &vecAt);
130 
131     BaseNode *GetAddressOfNode(const BaseNode &node);
132 
133     bool CallIsOfAttr(FuncAttrKind attr, const StmtNode *narynode) const;
134 
GetAddressPrimType()135     PrimType GetAddressPrimType() const
136     {
137         return GetLoweredPtrType();
138     }
139 
140     /* update typeSizeTable and typeAlignTable when new type is created */
UpdateTypeTable(MIRType & ty)141     void UpdateTypeTable(MIRType &ty)
142     {
143         if (!TyIsInSizeAlignTable(ty)) {
144             AddAndComputeSizeAlign(ty);
145         }
146     }
147 
148     /* Global type table might be updated during lowering for C/C++. */
149     void FinalizeTypeTable(const MIRType &ty);
150 
GetFieldIdxIncrement(const MIRType & ty)151     uint32 GetFieldIdxIncrement(const MIRType &ty) const
152     {
153         if (ty.GetKind() == kTypeClass) {
154             /* number of fields + 2 */
155             return static_cast<const MIRClassType &>(ty).GetFieldsSize() + 2;
156         } else if (ty.GetKind() == kTypeStruct) {
157             /* number of fields + 1 */
158             return static_cast<const MIRStructType &>(ty).GetFieldsSize() + 1;
159         }
160         return 1;
161     }
162 
GetMIRModule()163     MIRModule &GetMIRModule() const
164     {
165         return mirModule;
166     }
167 
GetTypeSize(uint32 idx)168     uint64 GetTypeSize(uint32 idx) const
169     {
170         return typeSizeTable.at(idx);
171     }
GetSizeOfTypeSizeTable()172     uint32 GetSizeOfTypeSizeTable() const
173     {
174         return typeSizeTable.size();
175     }
IsEmptyOfTypeSizeTable()176     bool IsEmptyOfTypeSizeTable() const
177     {
178         return typeSizeTable.empty();
179     }
SetTypeSize(uint32 idx,uint64 value)180     void SetTypeSize(uint32 idx, uint64 value)
181     {
182         typeSizeTable.at(idx) = value;
183     }
AddTypeSize(uint64 value)184     void AddTypeSize(uint64 value)
185     {
186         typeSizeTable.emplace_back(value);
187     }
188 
AddTypeSizeAndAlign(const TyIdx tyIdx,uint64 value)189     void AddTypeSizeAndAlign(const TyIdx tyIdx, uint64 value)
190     {
191         if (typeSizeTable.size() == tyIdx) {
192             typeSizeTable.emplace_back(value);
193             typeAlignTable.emplace_back(value);
194         } else {
195             CHECK_FATAL(typeSizeTable.size() > tyIdx, "there are some types haven't set type size and align, %d");
196         }
197     }
198 
GetTypeAlign(uint32 idx)199     uint8 GetTypeAlign(uint32 idx) const
200     {
201         return typeAlignTable.at(idx);
202     }
GetSizeOfTypeAlignTable()203     size_t GetSizeOfTypeAlignTable() const
204     {
205         return typeAlignTable.size();
206     }
IsEmptyOfTypeAlignTable()207     bool IsEmptyOfTypeAlignTable() const
208     {
209         return typeAlignTable.empty();
210     }
SetTypeAlign(uint32 idx,uint8 value)211     void SetTypeAlign(uint32 idx, uint8 value)
212     {
213         typeAlignTable.at(idx) = value;
214     }
AddTypeAlign(uint8 value)215     void AddTypeAlign(uint8 value)
216     {
217         typeAlignTable.emplace_back(value);
218     }
219 
GetHasFlexibleArray(uint32 idx)220     bool GetHasFlexibleArray(uint32 idx) const
221     {
222         return typeHasFlexibleArray.at(idx);
223     }
SetHasFlexibleArray(uint32 idx,bool value)224     void SetHasFlexibleArray(uint32 idx, bool value)
225     {
226         typeHasFlexibleArray.at(idx) = value;
227     }
228 
GetStructFieldCount(uint32 idx)229     FieldID GetStructFieldCount(uint32 idx) const
230     {
231         return structFieldCountTable.at(idx);
232     }
GetSizeOfStructFieldCountTable()233     uint32 GetSizeOfStructFieldCountTable() const
234     {
235         return structFieldCountTable.size();
236     }
SetStructFieldCount(uint32 idx,FieldID value)237     void SetStructFieldCount(uint32 idx, FieldID value)
238     {
239         structFieldCountTable.at(idx) = value;
240     }
AppendStructFieldCount(uint32 idx,FieldID value)241     void AppendStructFieldCount(uint32 idx, FieldID value)
242     {
243         structFieldCountTable.at(idx) += value;
244     }
245 
246 private:
247     bool TyIsInSizeAlignTable(const MIRType &) const;
248     void AddAndComputeSizeAlign(MIRType &);
249     void ComputeStructTypeSizesAligns(MIRType &ty, const TyIdx &tyIdx);
250     void ComputeClassTypeSizesAligns(MIRType &ty, const TyIdx &tyIdx, uint8 align = 0);
251     void ComputeArrayTypeSizesAligns(MIRType &ty, const TyIdx &tyIdx);
252     void ComputeFArrayOrJArrayTypeSizesAligns(MIRType &ty, const TyIdx &tyIdx);
253 
254     MIRModule &mirModule;
255     MapleVector<uint64> typeSizeTable;      /* index is TyIdx */
256     MapleVector<uint8> typeAlignTable;      /* index is TyIdx */
257     MapleVector<bool> typeHasFlexibleArray; /* struct with flexible array */
258     /*
259      * gives number of fields inside
260      * each struct inclusive of nested structs, for speeding up
261      * traversal for locating the field for a given fieldID
262      */
263     MapleVector<FieldID> structFieldCountTable;
264     /*
265      * a lookup table for class layout. the vector is indexed by field-id
266      */
267     MapleUnorderedMap<MIRClassType *, JClassLayout *> jClassLayoutTable;
268     MapleUnorderedMap<MIRFunction *, TyIdx> funcReturnType;
269 }; /* class BECommon */
270 } /* namespace maplebe */
271 
272 #endif /* MAPLEBE_INCLUDE_BE_BECOMMON_H */
273