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 */