• 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 #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