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 BECommon {
39 public:
40 explicit BECommon(MIRModule &mod);
41
42 ~BECommon() = default;
43
44 void ComputeTypeSizesAligns(MIRType &type, uint8 align = 0);
45
46 void AddNewTypeAfterBecommon(uint32 oldTypeTableSize, uint32 newTypeTableSize);
47
HasFuncReturnType(MIRFunction &func) const48 bool HasFuncReturnType(MIRFunction &func) const
49 {
50 return (funcReturnType.find(&func) != funcReturnType.end());
51 }
52
GetFuncReturnType(MIRFunction &func) const53 const TyIdx GetFuncReturnType(MIRFunction &func) const
54 {
55 return (funcReturnType.at(&func));
56 }
57
58 void AddElementToFuncReturnType(MIRFunction &func, const TyIdx tyIdx);
59
60 MIRType *BeGetOrCreatePointerType(const MIRType &pointedType);
61
62 MIRType *BeGetOrCreateFunctionType(TyIdx tyIdx, const std::vector<TyIdx> &vecTy,
63 const std::vector<TypeAttrs> &vecAt);
64
GetAddressPrimType() const65 PrimType GetAddressPrimType() const
66 {
67 return GetLoweredPtrType();
68 }
69
70 /* update typeSizeTable and typeAlignTable when new type is created */
UpdateTypeTable(MIRType &ty)71 void UpdateTypeTable(MIRType &ty)
72 {
73 if (!TyIsInSizeAlignTable(ty)) {
74 AddAndComputeSizeAlign(ty);
75 }
76 }
77
78 /* Global type table might be updated during lowering for C/C++. */
79 void FinalizeTypeTable(const MIRType &ty);
80
GetFieldIdxIncrement(const MIRType &ty) const81 uint32 GetFieldIdxIncrement(const MIRType &ty) const
82 {
83 return 1;
84 }
85
GetMIRModule() const86 MIRModule &GetMIRModule() const
87 {
88 return mirModule;
89 }
90
GetTypeSize(uint32 idx) const91 uint64 GetTypeSize(uint32 idx) const
92 {
93 return typeSizeTable.at(idx);
94 }
GetSizeOfTypeSizeTable() const95 uint32 GetSizeOfTypeSizeTable() const
96 {
97 return typeSizeTable.size();
98 }
IsEmptyOfTypeSizeTable() const99 bool IsEmptyOfTypeSizeTable() const
100 {
101 return typeSizeTable.empty();
102 }
SetTypeSize(uint32 idx, uint64 value)103 void SetTypeSize(uint32 idx, uint64 value)
104 {
105 typeSizeTable.at(idx) = value;
106 }
AddTypeSize(uint64 value)107 void AddTypeSize(uint64 value)
108 {
109 typeSizeTable.emplace_back(value);
110 }
111
AddTypeSizeAndAlign(const TyIdx tyIdx, uint64 value)112 void AddTypeSizeAndAlign(const TyIdx tyIdx, uint64 value)
113 {
114 if (typeSizeTable.size() == tyIdx) {
115 typeSizeTable.emplace_back(value);
116 typeAlignTable.emplace_back(value);
117 } else {
118 CHECK_FATAL(typeSizeTable.size() > tyIdx, "there are some types haven't set type size and align, %d");
119 }
120 }
121
GetTypeAlign(uint32 idx) const122 uint8 GetTypeAlign(uint32 idx) const
123 {
124 return typeAlignTable.at(idx);
125 }
GetSizeOfTypeAlignTable() const126 size_t GetSizeOfTypeAlignTable() const
127 {
128 return typeAlignTable.size();
129 }
IsEmptyOfTypeAlignTable() const130 bool IsEmptyOfTypeAlignTable() const
131 {
132 return typeAlignTable.empty();
133 }
SetTypeAlign(uint32 idx, uint8 value)134 void SetTypeAlign(uint32 idx, uint8 value)
135 {
136 typeAlignTable.at(idx) = value;
137 }
AddTypeAlign(uint8 value)138 void AddTypeAlign(uint8 value)
139 {
140 typeAlignTable.emplace_back(value);
141 }
142
GetHasFlexibleArray(uint32 idx) const143 bool GetHasFlexibleArray(uint32 idx) const
144 {
145 return typeHasFlexibleArray.at(idx);
146 }
SetHasFlexibleArray(uint32 idx, bool value)147 void SetHasFlexibleArray(uint32 idx, bool value)
148 {
149 typeHasFlexibleArray.at(idx) = value;
150 }
151
GetStructFieldCount(uint32 idx) const152 FieldID GetStructFieldCount(uint32 idx) const
153 {
154 return structFieldCountTable.at(idx);
155 }
GetSizeOfStructFieldCountTable() const156 uint32 GetSizeOfStructFieldCountTable() const
157 {
158 return structFieldCountTable.size();
159 }
SetStructFieldCount(uint32 idx, FieldID value)160 void SetStructFieldCount(uint32 idx, FieldID value)
161 {
162 structFieldCountTable.at(idx) = value;
163 }
AppendStructFieldCount(uint32 idx, FieldID value)164 void AppendStructFieldCount(uint32 idx, FieldID value)
165 {
166 structFieldCountTable.at(idx) += value;
167 }
168
169 private:
170 bool TyIsInSizeAlignTable(const MIRType &) const;
171 void AddAndComputeSizeAlign(MIRType &);
172
173 MIRModule &mirModule;
174 MapleVector<uint64> typeSizeTable; /* index is TyIdx */
175 MapleVector<uint8> typeAlignTable; /* index is TyIdx */
176 MapleVector<bool> typeHasFlexibleArray; /* struct with flexible array */
177 /*
178 * gives number of fields inside
179 * each struct inclusive of nested structs, for speeding up
180 * traversal for locating the field for a given fieldID
181 */
182 MapleVector<FieldID> structFieldCountTable;
183 MapleUnorderedMap<MIRFunction *, TyIdx> funcReturnType;
184 }; /* class BECommon */
185 } /* namespace maplebe */
186
187 #endif /* MAPLEBE_INCLUDE_BE_BECOMMON_H */