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