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 #include "becommon.h"
17 #include "mir_builder.h"
18
19 namespace maplebe {
20 using namespace maple;
21
BECommon(MIRModule & mod)22 BECommon::BECommon(MIRModule &mod)
23 : mirModule(mod),
24 typeSizeTable(GlobalTables::GetTypeTable().GetTypeTable().size(), 0, mirModule.GetMPAllocator().Adapter()),
25 typeAlignTable(GlobalTables::GetTypeTable().GetTypeTable().size(), static_cast<uint8>(mirModule.IsCModule()),
26 mirModule.GetMPAllocator().Adapter()),
27 typeHasFlexibleArray(GlobalTables::GetTypeTable().GetTypeTable().size(), 0, mirModule.GetMPAllocator().Adapter()),
28 structFieldCountTable(GlobalTables::GetTypeTable().GetTypeTable().size(), 0,
29 mirModule.GetMPAllocator().Adapter()),
30 funcReturnType(mirModule.GetMPAllocator().Adapter())
31 {
32 for (uint32 i = 1; i < GlobalTables::GetTypeTable().GetTypeTable().size(); ++i) {
33 MIRType *ty = GlobalTables::GetTypeTable().GetTypeTable()[i];
34 ComputeTypeSizesAligns(*ty);
35 }
36 }
37
AddNewTypeAfterBecommon(uint32 oldTypeTableSize,uint32 newTypeTableSize)38 void BECommon::AddNewTypeAfterBecommon(uint32 oldTypeTableSize, uint32 newTypeTableSize)
39 {
40 for (auto i = oldTypeTableSize; i < newTypeTableSize; ++i) {
41 MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(i);
42 CHECK_NULL_FATAL(ty);
43 typeSizeTable.emplace_back(0);
44 typeAlignTable.emplace_back(static_cast<uint8>(mirModule.IsCModule()));
45 typeHasFlexibleArray.emplace_back(0);
46 structFieldCountTable.emplace_back(0);
47 ComputeTypeSizesAligns(*ty);
48 }
49 }
50
ComputeTypeSizesAligns(MIRType & ty,uint8 align)51 void BECommon::ComputeTypeSizesAligns(MIRType &ty, uint8 align)
52 {
53 TyIdx tyIdx = ty.GetTypeIndex();
54 if ((structFieldCountTable.size() > tyIdx) && (GetStructFieldCount(tyIdx) != 0)) {
55 return; /* processed before */
56 }
57
58 if ((ty.GetPrimType() == PTY_ptr) || (ty.GetPrimType() == PTY_ref)) {
59 ty.SetPrimType(GetLoweredPtrType());
60 }
61
62 switch (ty.GetKind()) {
63 case kTypeScalar:
64 case kTypePointer:
65 case kTypeFunction:
66 SetTypeSize(tyIdx, GetPrimTypeSize(ty.GetPrimType()));
67 SetTypeAlign(tyIdx, GetTypeSize(tyIdx));
68 break;
69 case kTypeArray:
70 CHECK_FATAL(false, "unsupported type");
71 break;
72 case kTypeByName:
73 case kTypeVoid:
74 default:
75 SetTypeSize(tyIdx, 0);
76 break;
77 }
78 /* there may be passed-in align attribute declared with the symbol */
79 SetTypeAlign(tyIdx, std::max(GetTypeAlign(tyIdx), align));
80 }
81
TyIsInSizeAlignTable(const MIRType & ty) const82 bool BECommon::TyIsInSizeAlignTable(const MIRType &ty) const
83 {
84 if (typeSizeTable.size() != typeAlignTable.size()) {
85 return false;
86 }
87 return ty.GetTypeIndex() < typeSizeTable.size();
88 }
89
AddAndComputeSizeAlign(MIRType & ty)90 void BECommon::AddAndComputeSizeAlign(MIRType &ty)
91 {
92 FinalizeTypeTable(ty);
93 typeAlignTable.emplace_back(mirModule.IsCModule());
94 typeSizeTable.emplace_back(0);
95 ComputeTypeSizesAligns(ty);
96 }
97
AddElementToFuncReturnType(MIRFunction & func,const TyIdx tyIdx)98 void BECommon::AddElementToFuncReturnType(MIRFunction &func, const TyIdx tyIdx)
99 {
100 funcReturnType[&func] = tyIdx;
101 }
102
BeGetOrCreatePointerType(const MIRType & pointedType)103 MIRType *BECommon::BeGetOrCreatePointerType(const MIRType &pointedType)
104 {
105 MIRType *newType = GlobalTables::GetTypeTable().GetOrCreatePointerType(pointedType, GetLoweredPtrType());
106 if (TyIsInSizeAlignTable(*newType)) {
107 return newType;
108 }
109 AddAndComputeSizeAlign(*newType);
110 return newType;
111 }
112
BeGetOrCreateFunctionType(TyIdx tyIdx,const std::vector<TyIdx> & vecTy,const std::vector<TypeAttrs> & vecAt)113 MIRType *BECommon::BeGetOrCreateFunctionType(TyIdx tyIdx, const std::vector<TyIdx> &vecTy,
114 const std::vector<TypeAttrs> &vecAt)
115 {
116 MIRType *newType = GlobalTables::GetTypeTable().GetOrCreateFunctionType(tyIdx, vecTy, vecAt);
117 if (TyIsInSizeAlignTable(*newType)) {
118 return newType;
119 }
120 AddAndComputeSizeAlign(*newType);
121 return newType;
122 }
123
FinalizeTypeTable(const MIRType & ty)124 void BECommon::FinalizeTypeTable(const MIRType &ty)
125 {
126 if (ty.GetTypeIndex() > GetSizeOfTypeSizeTable()) {
127 if (mirModule.GetSrcLang() == kSrcLangC) {
128 for (uint32 i = GetSizeOfTypeSizeTable(); i < ty.GetTypeIndex(); ++i) {
129 MIRType *tyTmp = GlobalTables::GetTypeTable().GetTypeFromTyIdx(i);
130 AddAndComputeSizeAlign(*tyTmp);
131 }
132 } else {
133 CHECK_FATAL(ty.GetTypeIndex() == typeSizeTable.size(), "make sure the ty idx is exactly the table size");
134 }
135 }
136 }
137 } /* namespace maplebe */
138