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